跳过JSF自定义组件Tag类?

时间:2012-04-30 21:46:34

标签: jsf-2 facelets el

我已经设法让我的组件使用简单的字符串,现在我正在尝试添加解析ValueExpression的可能性。

为此,我正在编辑我的EmoticonOutputTextTag文件,在setProperties()中添加表达式的评估。

但我注意到这种方法永远不会被调用。

似乎这个类未被使用,我不知道为什么。

事实上,在我的setProperties()中我放了这一行:eot.setInputText("randomText");我希望我的组件能够显示...实际上,我的组件显示了在JSF页面中传递的值,所以我猜这个方法没有被调用。

我该怎么办?

以下是代码:

EmoticonOutputText.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.unilife.emoticonOutputText;

import javax.el.ValueExpression;
import javax.faces.component.UIOutput;

/**
 *
 * @author stefano
 */
public class EmoticonOutputText extends UIOutput {

    private static final String COMP_FAMILY = "javax.faces.Output";

    /**
     * Get the value of COMPONENT_FAMILY
     *
     * @return the value of COMPONENT_FAMILY
     */
    @Override
    public String getFamily() {
        return COMP_FAMILY;
    }
    private static final String RENDERER_TYPE = "EmoticonOutputTextRenderer";

    /**
     * Get the value of RENDERER_TYPE
     *
     * @return the value of RENDERER_TYPE
     */
    @Override
    public String getRendererType() {
        return RENDERER_TYPE;
    }
    private String style;

    /**
     * Get the value of style
     *
     * @return the value of style
     */
    public String getStyle() {
        return style;
    }

    /**
     * Set the value of style
     *
     * @param style new value of style
     */
    public void setStyle(String style) {
        this.style = style;
    }
    private String styleClass;

    /**
     * Get the value of styleClass
     *
     * @return the value of styleClass
     */
    public String getStyleClass() {
        return styleClass;
    }

    /**
     * Set the value of styleClass
     *
     * @param styleClass new value of styleClass
     */
    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }
    private String inputText;

    /**
     * Get the value of inputText
     *
     * @return the value of inputText
     */
    public String getInputText() {
        return inputText;
    }

    /**
     * Set the value of inputText
     *
     * @param inputText new value of inputText
     */
    public void setInputText(String inputText) {
        this.inputText = inputText;
    }
}

EmoticonOutputTextTag.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.unilife.emoticonOutputText;

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentELTag;

/**
 *
 * @author stefano
 */
public class EmoticonOutputTextTag extends UIComponentELTag {

    private static final String COMP_TYPE = "EmoticonOutputTextTag";
    private static final String RENDERER_TYPE = "EmoticonOutputTextRenderer";
    private String style;
    private String styleClass;
    private ValueExpression inputText;

    public void setStyle(String style) {
        this.style = style;
    }

    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    public void setInputText(ValueExpression inputText) {
        this.inputText = inputText;
    }

    @Override
    public String getComponentType() {
        return COMP_TYPE;
    }

    @Override
    public String getRendererType() {
        return RENDERER_TYPE;
    }

    @Override
    protected void setProperties(UIComponent component) {
        super.setProperties(component);
        EmoticonOutputText eot = (EmoticonOutputText)component;        
        if(style != null){
            eot.setStyle(style);
        }
        if(styleClass != null){
            eot.setStyleClass(styleClass);
        }
        if(inputText != null){
//            eot.setInputText(inputText.getExpressionString());
            eot.setInputText("randomText");
        }        
    }    
}

EmoticonOutputTextRenderer.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.unilife.emoticonOutputText;

import java.io.IOException;
import java.util.HashMap;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
import javax.servlet.ServletContext;

/**
 *
 * @author stefano
 */
public class EmoticonOutputTextRenderer extends Renderer {

    //Contiene la corrispondenza tra la stringa da sostituire e il nome dell'emoticon
    private static final HashMap<String, String> emoticons = new HashMap<>();
    //Contiene il percorso dei files delle emoticon
    private final String basePath = ((ServletContext) (FacesContext.getCurrentInstance().getExternalContext().getContext())).getContextPath() + "/resources/images/emoticons/";

    public EmoticonOutputTextRenderer() {
        parseEmoticons();
    }

    private void parseEmoticons(){
        //Not needed 
    }

    @Override
    public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
        EmoticonOutputText eot = (EmoticonOutputText) component;
        ResponseWriter writer = context.getResponseWriter();
        //Aggiungiamo l'eventuale stile CSS o direttamente la classe
        writer.startElement("span", null);
        if(eot.getStyle()!=null && !eot.getStyle().isEmpty()){
            writer.writeAttribute("style", eot.getStyle(), null);
        }
        if(eot.getStyleClass()!=null && !eot.getStyleClass().isEmpty()){
            writer.writeAttribute("class", eot.getStyleClass(), null);
        }
        //Andiamo ad effettuare il parse vero e proprio, sostituendo le emoticons come le immagini
        for(String str : eot.getInputText().split(" ")){
            if(emoticons.containsKey(str)){ //Se riconosco l'emoticon allora scrivo l'immagine
                writer.startElement("img", null);
                writer.writeAttribute("src", emoticons.get(str) + ".gif", null);
                writer.endElement("img");
                writer.writeText(" ", null);
            } else { //Altrimenti aggiungo semplicemente la parola
                writer.writeText(str + " ", null);
            }
        }
    }
}

unilife.taglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://unilife.it/tags</namespace>
    <tag>
        <tag-name>EmoticonOutputText</tag-name>
        <description>
            OutputText con la possibilità di mostrare Emoticons
        </description>
        <component>
            <component-type>EmoticonOutputText</component-type>
            <renderer-type>EmoticonOutputTextRenderer</renderer-type>
        </component>
        <attribute>
            <name>style</name>            
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>styleClass</name>            
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>inputText</name>
            <required>true</required>            
            <type>java.lang.String</type>
        </attribute>
    </tag>
</facelet-taglib>

faces-config.xml中

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2" 
                xmlns="http://java.sun.com/xml/ns/javaee" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
         http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
    <component>
        <component-type>
            EmoticonOutputText
        </component-type>
        <component-class>
            com.unilife.emoticonOutputText.EmoticonOutputText
        </component-class>
    </component>

    <render-kit>
        <renderer>
            <description>
                OutputText che permette il rendering di emoticons al posto delle combinazioni di tasti
            </description>
            <component-family>
                javax.faces.Output
            </component-family>
            <renderer-type>
                EmoticonOutputTextRenderer
            </renderer-type>
            <renderer-class>
                com.unilife.emoticonOutputText.EmoticonOutputTextRenderer
            </renderer-class>
        </renderer>
    </render-kit>  
</faces-config>

编辑: 我在lu4242的答案之后编辑了一些东西,但现在我有了ClassCastException!

EmoticonOutputTextTag.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.unilife.emoticonOutputText;

import java.io.IOException;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.ComponentConfig;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagHandler;

/**
 *
 * @author stefano
 */

public class EmoticonOutputTextTag extends TagHandler {

    private static final String COMP_TYPE = "EmoticonOutputTextTag";
    private static final String RENDERER_TYPE = "EmoticonOutputTextRenderer";
    private String style;
    private String styleClass;
    private ValueExpression inputText;

    public EmoticonOutputTextTag(ComponentConfig config) {
        super(config);
    }

    public void setStyle(String style) {
        this.style = style;
    }

    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    public void setInputText(ValueExpression inputText) {
        this.inputText = inputText;
    }

    @Override
    public void apply(FaceletContext fc, UIComponent uic) throws IOException {
        EmoticonOutputText eot = (EmoticonOutputText) uic;        
        TagAttribute ta = this.getRequiredAttribute("inputText");
        ValueExpression ve = ta.getValueExpression(fc, String.class);
        if(ve.isLiteralText()){
            eot.setInputText(ve.getExpressionString());
        } else {
            eot.setInputText((String)ve.getValue(fc));
        }
    }
}

unilife.taglib.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
    <namespace>http://unilife.it/tags</namespace>
    <tag>
        <tag-name>EmoticonOutputText</tag-name>
        <description>
            OutputText con la possibilità di mostrare Emoticons
        </description>
        <component>
            <component-type>EmoticonOutputText</component-type>
            <renderer-type>EmoticonOutputTextRenderer</renderer-type>
            <handler-class>com.unilife.emoticonOutputText.EmoticonOutputTextTag</handler-class>            
        </component>
        <attribute>
            <name>style</name>            
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>styleClass</name>            
            <type>java.lang.String</type>
        </attribute>
        <attribute>
            <name>inputText</name>
            <required>true</required>            
            <type>java.lang.String</type>
        </attribute>
    </tag>
</facelet-taglib>

现在的问题是uic无法转换为EmoticonOutputText ..但为什么?

1 个答案:

答案 0 :(得分:0)

标记类从错误的类扩展。 UIComponentELTag用于JSP。在Facelets中,可以为从javax.faces.view.facelets.ComponentHandler扩展的组件提供标记处理程序,并添加&lt; handler-class&gt;里面&lt;标签&gt;&lt;组件&gt;在.taglib.xml文件中。

如果您不想处理创建自定义组件的所有配置内容,请查看MyFaces Builder Plugin Site。它使用源代码注释来处理所有元数据并以最小的努力生成所有相关文件。它是用于Apache MyFaces CoreApache MyFaces Tomahawk和MyFaces Sandbox的工具。有一个原型有助于使用maven See Instructions设置环境。或者您可以采用“简单方法”并创建JSF 2.0复合组件。