You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by kindsol <ki...@hotpop.com> on 2007/06/19 20:18:35 UTC

Creating a custom converter tag

I want to create a custom converter as it's own tag (e.g. not using  
<f:converter> tag.  Is there any documentation online or elsewhere  
that you can point me to?

thanks in advance!

-Sol



Re: Creating a custom converter tag

Posted by kindsol <ki...@hotpop.com>.
Riiiiight.  Thanks for that.

-Sol


On Jun 19, 2007, at 1:30 PM, Mike Kienenberger wrote:

> You do realize that you just quoted the files that you claimed were
> stripped out of the message, don't you?
>
>


Re: Creating a custom converter tag

Posted by kindsol <ki...@hotpop.com>.
Thanks for the reply, Brian.

It looks like the MyFaces mailing list strips off attachments.  Can  
you send me those files directly?

Thank again!

-Sol


On Jun 19, 2007, at 12:34 PM, Bryan Basham wrote:

> Hello "kind sole" ;-)
>
> I have just created a converter with a tag.  Nice little exercise.
>
> My app has lots of "names" for Boolean values, such as
> "yes" / "no" and "enabled" / "disabled" and so on.  I used
> to create a separate accessor method to convert from the
> Boolean to a String, but I wanted something more generic
> so I created the BooleanConverter and BooleanConverterTag
> to handle this situation.
>
> So, for example in a JSF page you might want to display a
> boolean value as yes/no:
>
> <p>
> Did the student fill in the form?
> <h:outputText value='#{bean.formFilledIn}'>  // the bean  
> isFormFilledIn() method must return boolean
>   <my:booleanConverter type='YES/NO' />
> </h:outputText>
> </p>
>
> I have attached my classes for this converter and tag.
> Don't forget that you need to declare this tag in your own TLD file.
>
> HTH,
> Bryan
>
>
> kindsol wrote:
>> I want to create a custom converter as it's own tag (e.g. not  
>> using <f:converter> tag.  Is there any documentation online or  
>> elsewhere that you can point me to?
>>
>> thanks in advance!
>>
>> -Sol
>>
>>
>
> package org.stillsecure.cobia.web.converters.tags;
>
> import org.stillsecure.cobia.web.converters.BooleanConverter;
>
> import javax.faces.convert.Converter;
> import javax.faces.webapp.ConverterTag;
> import javax.servlet.jsp.JspException;
>
> public class BooleanConverterTag extends ConverterTag
> {
>     public BooleanConverterTag()
>     {
>         super();
>         setConverterId(BooleanConverter.CONVERTER_ID);
>     }
>
>     private String type;
>
>     public void setType(String type) throws JspException
>     {
>         // Check that this type is a valid Boolean type name
>         if ( type == null )
>             throw new JspException(NULL_TYPE_ERROR);
>         if ( ! BooleanConverter.isValidType(type) )
>             throw new JspException(String.format 
> (NOT_A_KNOWN_TYPE_ERROR, type));
>
>         this.type = type;
>     }
>     private static final String NULL_TYPE_ERROR
>         = "The 'type' attribute value must not be null.";
>     private static final String NOT_A_KNOWN_TYPE_ERROR
>         = "The 'type' attribute value (%s) is not a registered  
> Boolean type.";
>
>     //
>     // JSF methods
>     //
>
>     @Override
>     protected Converter createConverter() throws JspException
>     {
>         BooleanConverter converter = (BooleanConverter)  
> super.createConverter();
>         converter.setType(this.type);
>         return converter;
>     }
> }
> package org.stillsecure.cobia.web.converters;
>
> import org.stillsecure.cobia.web.util.WebContext;
>
> import java.util.HashMap;
> import java.util.Map;
>
> import javax.faces.application.FacesMessage;
> import javax.faces.component.StateHolder;
> import javax.faces.component.UIComponent;
> import javax.faces.context.FacesContext;
> import javax.faces.convert.Converter;
> import javax.faces.convert.ConverterException;
>
> /**
>  * This class implements a JSF converter to convert from boolean  
> values
>  * to specialized text strings, such as yes/no or enabled/disabled.
>  */
> public class BooleanConverter implements Converter, StateHolder
> {
>     /** The JSF id for this converter.  Must be the same as defined  
> in the framework-faces-config.xml file. */
>     public final static String CONVERTER_ID = "converter.Boolean";
>
>     //
>     // Registering Boolean "types"
>     //
>
>     public static void registerType(String type, String trueName,  
> String falseName)
>     {
>         BOOLEAN_NAME_PAIRS_MAP.put(type, new String[]  
> {trueName.toLowerCase(), falseName.toLowerCase()});
>     }
>     public static boolean isValidType(String type)
>     {
>         return BOOLEAN_NAME_PAIRS_MAP.containsKey(type);
>     }
>     public static String[] getType(String type)
>     {
>         return BOOLEAN_NAME_PAIRS_MAP.get(type);
>     }
>     private static final Map<String, String[]>  
> BOOLEAN_NAME_PAIRS_MAP = new HashMap<String, String[]>();
>
>     //
>     // Default Boolean name types
>     //
>
>     public static final String STANDARD = "STANDARD";
>     public static final String YES_NO = "YES/NO";
>     public static final String ENABLE = "OP-MODE";
>     public static final String UP_DOWN = "UP/DOWN";
>
>     static
>     {
>         registerType(STANDARD, "true", "false");
>         registerType(YES_NO, "yes", "no");
>         registerType(ENABLE, "enabled", "disabled");
>         registerType(UP_DOWN, "up", "down");
>     }
>
>     //
>     // Attributes
>     //
>
>     private String type;
>
>     /**
>      * Sets the type of Boolean conversion.
>      *
>      * @param type must be a registered Boolean type name
>      */
>     public void setType(String type)
>     {
>         this.type = type;
>     }
>
>     public void checkType(String type)
>     {
>         // Check converter state
>         if ( type == null )
>             throw new ConverterException 
> (WebContext.createFacesMessage(NO_TYPE_ERROR));
>         if ( ! isValidType(type) )
>             throw new ConverterException 
> (WebContext.createFacesMessage(BAD_TYPE_ERROR, this.type));
>     }
>     private static final String NO_TYPE_ERROR =  
> "BASE_BooleanConverter_noTypeError";
>     private static final String BAD_TYPE_ERROR =  
> "BASE_BooleanConverter_badTypeError";
>
>     //
>     // JSF methods
>     //
>
>     /**
>      * This method converts from the string representation to a  
> Boolean object.
>      */
>     public Object getAsObject(FacesContext ctx, UIComponent comp,  
> String displayString) throws ConverterException
>     {
>         checkType(this.type);
>
>         Boolean result = null;
>
>         String[] pair = getType(this.type);
>         if ( pair[0].equalsIgnoreCase(displayString) )
>         {
>             result = Boolean.TRUE;
>         }
>         else if ( pair[1].equalsIgnoreCase(displayString) )
>         {
>             result = Boolean.FALSE;
>         }
>         else
>         {
>             FacesMessage message
>                 = WebContext.createFacesMessage 
> (BOOLEAN_CONVERTER_TO_OBJECT_FAILED, displayString);
>             throw new ConverterException(message);
>         }
>
>         return result;
>     }
>     private static final String BOOLEAN_CONVERTER_TO_OBJECT_FAILED  
> = "BASE_BooleanConverter_getAsObjectFailed";
>
>     /**
>      * This method converts from the Boolean object to the string  
> representation.
>      */
>     public String getAsString(FacesContext ctx, UIComponent comp,  
> Object object) throws ConverterException
>     {
>         checkType(this.type);
>
>         String result = null;
>
>         String[] pair = getType(this.type);
>         try
>         {
>             Boolean o = (Boolean) object;
>             if ( o == null )
>                 result = "";
>             else if ( o.equals(Boolean.TRUE) )
>                 result = pair[0];
>             else if ( o.equals(Boolean.FALSE) )
>                 result = pair[1];
>             else
>                 assert false : "Unknown object" + o;
>         }
>         catch (ClassCastException e)
>         {
>             assert false : e;
>         }
>
>         return result;
>     }
>
>     //
>     // StateHolder methods
>     //
>
>     private boolean transientFlag;
>
>     public void setTransient(boolean transientValue)
>     {
>         this.transientFlag = transientValue;
>     }
>
>     public boolean isTransient()
>     {
>         return transientFlag;
>     }
>
>     public Object saveState(FacesContext context)
>     {
>         Object[] values = new Object[1];
>         values[0] = this.type;
>         return values;
>     }
>
>     public void restoreState(FacesContext context, Object state)
>     {
>         Object[] values = (Object[]) state;
>         this.type = (String) values[0];
>     }
>
> }


Re: Creating a custom converter tag

Posted by Bryan Basham <bb...@stillsecure.com>.
kindsol wrote:
> Bryan,
>
> Can you send me what you are using for your .tld, taglib.xml, and 
> faces-config.xml entries for this custom converter tag?  I think those 
> are the only three files required to register a custom tag -- no?
>
> Thanks :)
>
> -Sol

Here is the entry for the TLD file:
------------------
    <tag>
        <description>
            This tag specifies a converter for a generalized Boolean type.
        </description>
        <name>booleanConverter</name>
        <tag-class>
            org.stillsecure.cobia.web.converters.tags.BooleanConverterTag
        </tag-class>
        <body-content>empty</body-content>
        <attribute>
            <description>
                The type of names used to display the Boolean value.
                This is a symbolic name, such as 'STANDARD' or 'YES/NO'.
                These symbolic names are defined in code currently.
                TODO: make these names configurable and not hard-coded.
            </description>
            <name>type</name>
            <required>true</required>
        </attribute>
    </tag>
------------------

Here's the entry for the faces-config file:
------------------
    <converter>
        <description>
            Converts a java.lang.Boolean object.
        </description>
        <converter-id>converter.Boolean</converter-id>
        
<converter-class>org.stillsecure.cobia.web.converters.BooleanConverter</converter-class>
    </converter>
------------------

Do you still need the source code?  I could resend these files with a 
different
extension or group them in a ZIP file.  Let me know if you need these.

-Bryan



Re: Creating a custom converter tag

Posted by kindsol <ki...@hotpop.com>.
Thanks, Mike!

I was using <component> tags in the tablib.xml file when I should  
have been using <converter> tags.  I finally got it working.

Thanks again :)

-Sol


On Jun 19, 2007, at 2:10 PM, Mike Kienenberger wrote:

> This is for a different converter, but here's what the taglib.xml and
> faces-config.xml file entries would look like:
>
> ==================taglib.xml=================
>    <tag>
>        <tag-name>convertNumberToBigDecimal</tag-name>
>        <converter>
>            <converter- 
> id>com.xyz.utilities.web.jsf.converter.NumberAsBigDecimalConverter</ 
> converter-id>
>        </converter>
>    </tag>
> ==================taglib.xml=================
>
>
> --------------------------------------faces- 
> config.xml--------------------------------
> 	<converter>
> 		<description>NumberConverter that returns BigDecimals</description>
> 		<converter- 
> id>com.xyz.utilities.web.jsf.converter.NumberAsBigDecimalConverter</ 
> converter-id>
> 		<converter- 
> class>com.xyz.utilities.web.jsf.converter.NumberAsBigDecimalConverter< 
> /converter-class>
> 	</converter>
> --------------------------------------faces- 
> config.xml--------------------------------
>
> On 6/19/07, kindsol <ki...@hotpop.com> wrote:
>> Bryan,
>>
>> Can you send me what you are using for your .tld, taglib.xml, and
>> faces-config.xml entries for this custom converter tag?  I think  
>> those are
>> the only three files required to register a custom tag -- no?
>>
>> Thanks :)
>>
>>
>> -Sol
>>
>>
>> On Jun 19, 2007, at 12:34 PM, Bryan Basham wrote:
>>
>>
>>
>> Hello "kind sole" ;-)
>>
>>  I have just created a converter with a tag.  Nice little exercise.
>>
>>  My app has lots of "names" for Boolean values, such as
>>  "yes" / "no" and "enabled" / "disabled" and so on.  I used
>>  to create a separate accessor method to convert from the
>>  Boolean to a String, but I wanted something more generic
>>  so I created the BooleanConverter and BooleanConverterTag
>>  to handle this situation.
>>
>>  So, for example in a JSF page you might want to display a
>>  boolean value as yes/no:
>>
>>  <p>
>>  Did the student fill in the form?
>>  <h:outputText value='#{bean.formFilledIn}'>  // the bean  
>> isFormFilledIn()
>> method must return boolean
>>    <my:booleanConverter type='YES/NO' />
>>  </h:outputText>
>>  </p>
>>
>>  I have attached my classes for this converter and tag.
>>  Don't forget that you need to declare this tag in your own TLD file.
>>
>>  HTH,
>>  Bryan
>>
>>  kindsol wrote:
>> I want to create a custom converter as it's own tag (e.g. not using
>> <f:converter> tag.  Is there any documentation online or elsewhere  
>> that you
>> can point me to?
>>
>>
>> thanks in advance!
>>
>>
>>
>> -Sol
>>
>>
>>
>> package org.stillsecure.cobia.web.converters.tags;
>>
>> import org.stillsecure.cobia.web.converters.BooleanConverter;
>>
>> import javax.faces.convert.Converter;
>> import javax.faces.webapp.ConverterTag;
>> import javax.servlet.jsp.JspException;
>>
>> public class BooleanConverterTag extends ConverterTag
>> {
>>     public BooleanConverterTag()
>>     {
>>         super();
>>         setConverterId(BooleanConverter.CONVERTER_ID);
>>     }
>>
>>     private String type;
>>
>>     public void setType(String type) throws JspException
>>     {
>>         // Check that this type is a valid Boolean type name
>>         if ( type == null )
>>             throw new JspException(NULL_TYPE_ERROR);
>>         if ( ! BooleanConverter.isValidType(type) )
>>             throw new JspException(String.format 
>> (NOT_A_KNOWN_TYPE_ERROR,
>> type));
>>
>>         this.type = type;
>>     }
>>     private static final String NULL_TYPE_ERROR
>>         = "The 'type' attribute value must not be null.";
>>     private static final String NOT_A_KNOWN_TYPE_ERROR
>>         = "The 'type' attribute value (%s) is not a registered  
>> Boolean
>> type.";
>>
>>     //
>>     // JSF methods
>>     //
>>
>>     @Override
>>     protected Converter createConverter() throws JspException
>>     {
>>         BooleanConverter converter = (BooleanConverter)
>> super.createConverter();
>>         converter.setType(this.type);
>>         return converter;
>>     }
>> }
>> package org.stillsecure.cobia.web.converters;
>>
>> import org.stillsecure.cobia.web.util.WebContext;
>>
>> import java.util.HashMap;
>> import java.util.Map;
>>
>> import javax.faces.application.FacesMessage;
>> import javax.faces.component.StateHolder;
>> import javax.faces.component.UIComponent;
>> import javax.faces.context.FacesContext;
>> import javax.faces.convert.Converter;
>> import javax.faces.convert.ConverterException;
>>
>> /**
>>  * This class implements a JSF converter to convert from boolean  
>> values
>>  * to specialized text strings, such as yes/no or enabled/disabled.
>>  */
>> public class BooleanConverter implements Converter, StateHolder
>> {
>>     /** The JSF id for this converter.  Must be the same as  
>> defined in the
>> framework-faces-config.xml file. */
>>     public final static String CONVERTER_ID = "converter.Boolean";
>>
>>     //
>>     // Registering Boolean "types"
>>     //
>>
>>     public static void registerType(String type, String trueName,  
>> String
>> falseName)
>>     {
>>         BOOLEAN_NAME_PAIRS_MAP.put(type, new String[]
>> {trueName.toLowerCase(), falseName.toLowerCase()});
>>     }
>>     public static boolean isValidType(String type)
>>     {
>>         return BOOLEAN_NAME_PAIRS_MAP.containsKey(type);
>>     }
>>     public static String[] getType(String type)
>>     {
>>         return BOOLEAN_NAME_PAIRS_MAP.get(type);
>>     }
>>     private static final Map<String, String[]>  
>> BOOLEAN_NAME_PAIRS_MAP = new
>> HashMap<String, String[]>();
>>
>>     //
>>     // Default Boolean name types
>>     //
>>
>>     public static final String STANDARD = "STANDARD";
>>     public static final String YES_NO = "YES/NO";
>>     public static final String ENABLE = "OP-MODE";
>>     public static final String UP_DOWN = "UP/DOWN";
>>
>>     static
>>     {
>>         registerType(STANDARD, "true", "false");
>>         registerType(YES_NO, "yes", "no");
>>         registerType(ENABLE, "enabled", "disabled");
>>         registerType(UP_DOWN, "up", "down");
>>     }
>>
>>     //
>>     // Attributes
>>     //
>>
>>     private String type;
>>
>>     /**
>>      * Sets the type of Boolean conversion.
>>      *
>>      * @param type must be a registered Boolean type name
>>      */
>>     public void setType(String type)
>>     {
>>         this.type = type;
>>     }
>>
>>     public void checkType(String type)
>>     {
>>         // Check converter state
>>         if ( type == null )
>>             throw new
>> ConverterException(WebContext.createFacesMessage(NO_TYPE_ERROR));
>>         if ( ! isValidType(type) )
>>             throw new
>> ConverterException(WebContext.createFacesMessage(BAD_TYPE_ERROR,
>> this.type));
>>     }
>>     private static final String NO_TYPE_ERROR =
>> "BASE_BooleanConverter_noTypeError";
>>     private static final String BAD_TYPE_ERROR =
>> "BASE_BooleanConverter_badTypeError";
>>
>>     //
>>     // JSF methods
>>     //
>>
>>     /**
>>      * This method converts from the string representation to a  
>> Boolean
>> object.
>>      */
>>     public Object getAsObject(FacesContext ctx, UIComponent comp,  
>> String
>> displayString) throws ConverterException
>>     {
>>         checkType(this.type);
>>
>>         Boolean result = null;
>>
>>         String[] pair = getType(this.type);
>>         if ( pair[0].equalsIgnoreCase(displayString) )
>>         {
>>             result = Boolean.TRUE;
>>         }
>>         else if ( pair[1].equalsIgnoreCase(displayString) )
>>         {
>>             result = Boolean.FALSE;
>>         }
>>         else
>>         {
>>             FacesMessage message
>>                 =
>> WebContext.createFacesMessage(BOOLEAN_CONVERTER_TO_OBJECT_FAILED,
>> displayString);
>>             throw new ConverterException(message);
>>         }
>>
>>         return result;
>>     }
>>     private static final String
>> BOOLEAN_CONVERTER_TO_OBJECT_FAILED =
>> "BASE_BooleanConverter_getAsObjectFailed";
>>
>>     /**
>>      * This method converts from the Boolean object to the string
>> representation.
>>      */
>>     public String getAsString(FacesContext ctx, UIComponent comp,  
>> Object
>> object) throws ConverterException
>>     {
>>         checkType(this.type);
>>
>>         String result = null;
>>
>>         String[] pair = getType(this.type);
>>         try
>>         {
>>             Boolean o = (Boolean) object;
>>             if ( o == null )
>>                 result = "";
>>             else if ( o.equals(Boolean.TRUE) )
>>                 result = pair[0];
>>             else if ( o.equals(Boolean.FALSE) )
>>                 result = pair[1];
>>             else
>>                 assert false : "Unknown object" + o;
>>         }
>>         catch (ClassCastException e)
>>         {
>>             assert false : e;
>>         }
>>
>>         return result;
>>     }
>>
>>     //
>>     // StateHolder methods
>>     //
>>
>>     private boolean transientFlag;
>>
>>     public void setTransient(boolean transientValue)
>>     {
>>         this.transientFlag = transientValue;
>>     }
>>
>>     public boolean isTransient()
>>     {
>>         return transientFlag;
>>     }
>>
>>     public Object saveState(FacesContext context)
>>     {
>>         Object[] values = new Object[1];
>>         values[0] = this.type;
>>         return values;
>>     }
>>
>>     public void restoreState(FacesContext context, Object state)
>>     {
>>         Object[] values = (Object[]) state;
>>         this.type = (String) values[0];
>>     }
>>
>> }
>>


Re: Creating a custom converter tag

Posted by Mike Kienenberger <mk...@gmail.com>.
This is for a different converter, but here's what the taglib.xml and
faces-config.xml file entries would look like:

==================taglib.xml=================
    <tag>
        <tag-name>convertNumberToBigDecimal</tag-name>
        <converter>
            <converter-id>com.xyz.utilities.web.jsf.converter.NumberAsBigDecimalConverter</converter-id>
        </converter>
    </tag>
==================taglib.xml=================


--------------------------------------faces-config.xml--------------------------------
	<converter>
		<description>NumberConverter that returns BigDecimals</description>
		<converter-id>com.xyz.utilities.web.jsf.converter.NumberAsBigDecimalConverter</converter-id>
		<converter-class>com.xyz.utilities.web.jsf.converter.NumberAsBigDecimalConverter</converter-class>
	</converter>
--------------------------------------faces-config.xml--------------------------------

On 6/19/07, kindsol <ki...@hotpop.com> wrote:
> Bryan,
>
> Can you send me what you are using for your .tld, taglib.xml, and
> faces-config.xml entries for this custom converter tag?  I think those are
> the only three files required to register a custom tag -- no?
>
> Thanks :)
>
>
> -Sol
>
>
> On Jun 19, 2007, at 12:34 PM, Bryan Basham wrote:
>
>
>
> Hello "kind sole" ;-)
>
>  I have just created a converter with a tag.  Nice little exercise.
>
>  My app has lots of "names" for Boolean values, such as
>  "yes" / "no" and "enabled" / "disabled" and so on.  I used
>  to create a separate accessor method to convert from the
>  Boolean to a String, but I wanted something more generic
>  so I created the BooleanConverter and BooleanConverterTag
>  to handle this situation.
>
>  So, for example in a JSF page you might want to display a
>  boolean value as yes/no:
>
>  <p>
>  Did the student fill in the form?
>  <h:outputText value='#{bean.formFilledIn}'>  // the bean isFormFilledIn()
> method must return boolean
>    <my:booleanConverter type='YES/NO' />
>  </h:outputText>
>  </p>
>
>  I have attached my classes for this converter and tag.
>  Don't forget that you need to declare this tag in your own TLD file.
>
>  HTH,
>  Bryan
>
>  kindsol wrote:
> I want to create a custom converter as it's own tag (e.g. not using
> <f:converter> tag.  Is there any documentation online or elsewhere that you
> can point me to?
>
>
> thanks in advance!
>
>
>
> -Sol
>
>
>
> package org.stillsecure.cobia.web.converters.tags;
>
> import org.stillsecure.cobia.web.converters.BooleanConverter;
>
> import javax.faces.convert.Converter;
> import javax.faces.webapp.ConverterTag;
> import javax.servlet.jsp.JspException;
>
> public class BooleanConverterTag extends ConverterTag
> {
>     public BooleanConverterTag()
>     {
>         super();
>         setConverterId(BooleanConverter.CONVERTER_ID);
>     }
>
>     private String type;
>
>     public void setType(String type) throws JspException
>     {
>         // Check that this type is a valid Boolean type name
>         if ( type == null )
>             throw new JspException(NULL_TYPE_ERROR);
>         if ( ! BooleanConverter.isValidType(type) )
>             throw new JspException(String.format(NOT_A_KNOWN_TYPE_ERROR,
> type));
>
>         this.type = type;
>     }
>     private static final String NULL_TYPE_ERROR
>         = "The 'type' attribute value must not be null.";
>     private static final String NOT_A_KNOWN_TYPE_ERROR
>         = "The 'type' attribute value (%s) is not a registered Boolean
> type.";
>
>     //
>     // JSF methods
>     //
>
>     @Override
>     protected Converter createConverter() throws JspException
>     {
>         BooleanConverter converter = (BooleanConverter)
> super.createConverter();
>         converter.setType(this.type);
>         return converter;
>     }
> }
> package org.stillsecure.cobia.web.converters;
>
> import org.stillsecure.cobia.web.util.WebContext;
>
> import java.util.HashMap;
> import java.util.Map;
>
> import javax.faces.application.FacesMessage;
> import javax.faces.component.StateHolder;
> import javax.faces.component.UIComponent;
> import javax.faces.context.FacesContext;
> import javax.faces.convert.Converter;
> import javax.faces.convert.ConverterException;
>
> /**
>  * This class implements a JSF converter to convert from boolean values
>  * to specialized text strings, such as yes/no or enabled/disabled.
>  */
> public class BooleanConverter implements Converter, StateHolder
> {
>     /** The JSF id for this converter.  Must be the same as defined in the
> framework-faces-config.xml file. */
>     public final static String CONVERTER_ID = "converter.Boolean";
>
>     //
>     // Registering Boolean "types"
>     //
>
>     public static void registerType(String type, String trueName, String
> falseName)
>     {
>         BOOLEAN_NAME_PAIRS_MAP.put(type, new String[]
> {trueName.toLowerCase(), falseName.toLowerCase()});
>     }
>     public static boolean isValidType(String type)
>     {
>         return BOOLEAN_NAME_PAIRS_MAP.containsKey(type);
>     }
>     public static String[] getType(String type)
>     {
>         return BOOLEAN_NAME_PAIRS_MAP.get(type);
>     }
>     private static final Map<String, String[]> BOOLEAN_NAME_PAIRS_MAP = new
> HashMap<String, String[]>();
>
>     //
>     // Default Boolean name types
>     //
>
>     public static final String STANDARD = "STANDARD";
>     public static final String YES_NO = "YES/NO";
>     public static final String ENABLE = "OP-MODE";
>     public static final String UP_DOWN = "UP/DOWN";
>
>     static
>     {
>         registerType(STANDARD, "true", "false");
>         registerType(YES_NO, "yes", "no");
>         registerType(ENABLE, "enabled", "disabled");
>         registerType(UP_DOWN, "up", "down");
>     }
>
>     //
>     // Attributes
>     //
>
>     private String type;
>
>     /**
>      * Sets the type of Boolean conversion.
>      *
>      * @param type must be a registered Boolean type name
>      */
>     public void setType(String type)
>     {
>         this.type = type;
>     }
>
>     public void checkType(String type)
>     {
>         // Check converter state
>         if ( type == null )
>             throw new
> ConverterException(WebContext.createFacesMessage(NO_TYPE_ERROR));
>         if ( ! isValidType(type) )
>             throw new
> ConverterException(WebContext.createFacesMessage(BAD_TYPE_ERROR,
> this.type));
>     }
>     private static final String NO_TYPE_ERROR =
> "BASE_BooleanConverter_noTypeError";
>     private static final String BAD_TYPE_ERROR =
> "BASE_BooleanConverter_badTypeError";
>
>     //
>     // JSF methods
>     //
>
>     /**
>      * This method converts from the string representation to a Boolean
> object.
>      */
>     public Object getAsObject(FacesContext ctx, UIComponent comp, String
> displayString) throws ConverterException
>     {
>         checkType(this.type);
>
>         Boolean result = null;
>
>         String[] pair = getType(this.type);
>         if ( pair[0].equalsIgnoreCase(displayString) )
>         {
>             result = Boolean.TRUE;
>         }
>         else if ( pair[1].equalsIgnoreCase(displayString) )
>         {
>             result = Boolean.FALSE;
>         }
>         else
>         {
>             FacesMessage message
>                 =
> WebContext.createFacesMessage(BOOLEAN_CONVERTER_TO_OBJECT_FAILED,
> displayString);
>             throw new ConverterException(message);
>         }
>
>         return result;
>     }
>     private static final String
> BOOLEAN_CONVERTER_TO_OBJECT_FAILED =
> "BASE_BooleanConverter_getAsObjectFailed";
>
>     /**
>      * This method converts from the Boolean object to the string
> representation.
>      */
>     public String getAsString(FacesContext ctx, UIComponent comp, Object
> object) throws ConverterException
>     {
>         checkType(this.type);
>
>         String result = null;
>
>         String[] pair = getType(this.type);
>         try
>         {
>             Boolean o = (Boolean) object;
>             if ( o == null )
>                 result = "";
>             else if ( o.equals(Boolean.TRUE) )
>                 result = pair[0];
>             else if ( o.equals(Boolean.FALSE) )
>                 result = pair[1];
>             else
>                 assert false : "Unknown object" + o;
>         }
>         catch (ClassCastException e)
>         {
>             assert false : e;
>         }
>
>         return result;
>     }
>
>     //
>     // StateHolder methods
>     //
>
>     private boolean transientFlag;
>
>     public void setTransient(boolean transientValue)
>     {
>         this.transientFlag = transientValue;
>     }
>
>     public boolean isTransient()
>     {
>         return transientFlag;
>     }
>
>     public Object saveState(FacesContext context)
>     {
>         Object[] values = new Object[1];
>         values[0] = this.type;
>         return values;
>     }
>
>     public void restoreState(FacesContext context, Object state)
>     {
>         Object[] values = (Object[]) state;
>         this.type = (String) values[0];
>     }
>
> }
>

Re: Creating a custom converter tag

Posted by kindsol <ki...@hotpop.com>.
Bryan,

Can you send me what you are using for your .tld, taglib.xml, and  
faces-config.xml entries for this custom converter tag?  I think  
those are the only three files required to register a custom tag -- no?

Thanks :)

-Sol


On Jun 19, 2007, at 12:34 PM, Bryan Basham wrote:

> Hello "kind sole" ;-)
>
> I have just created a converter with a tag.  Nice little exercise.
>
> My app has lots of "names" for Boolean values, such as
> "yes" / "no" and "enabled" / "disabled" and so on.  I used
> to create a separate accessor method to convert from the
> Boolean to a String, but I wanted something more generic
> so I created the BooleanConverter and BooleanConverterTag
> to handle this situation.
>
> So, for example in a JSF page you might want to display a
> boolean value as yes/no:
>
> <p>
> Did the student fill in the form?
> <h:outputText value='#{bean.formFilledIn}'>  // the bean  
> isFormFilledIn() method must return boolean
>   <my:booleanConverter type='YES/NO' />
> </h:outputText>
> </p>
>
> I have attached my classes for this converter and tag.
> Don't forget that you need to declare this tag in your own TLD file.
>
> HTH,
> Bryan
>
>
> kindsol wrote:
>> I want to create a custom converter as it's own tag (e.g. not  
>> using <f:converter> tag.  Is there any documentation online or  
>> elsewhere that you can point me to?
>>
>> thanks in advance!
>>
>> -Sol
>>
>>
>
> package org.stillsecure.cobia.web.converters.tags;
>
> import org.stillsecure.cobia.web.converters.BooleanConverter;
>
> import javax.faces.convert.Converter;
> import javax.faces.webapp.ConverterTag;
> import javax.servlet.jsp.JspException;
>
> public class BooleanConverterTag extends ConverterTag
> {
>     public BooleanConverterTag()
>     {
>         super();
>         setConverterId(BooleanConverter.CONVERTER_ID);
>     }
>
>     private String type;
>
>     public void setType(String type) throws JspException
>     {
>         // Check that this type is a valid Boolean type name
>         if ( type == null )
>             throw new JspException(NULL_TYPE_ERROR);
>         if ( ! BooleanConverter.isValidType(type) )
>             throw new JspException(String.format 
> (NOT_A_KNOWN_TYPE_ERROR, type));
>
>         this.type = type;
>     }
>     private static final String NULL_TYPE_ERROR
>         = "The 'type' attribute value must not be null.";
>     private static final String NOT_A_KNOWN_TYPE_ERROR
>         = "The 'type' attribute value (%s) is not a registered  
> Boolean type.";
>
>     //
>     // JSF methods
>     //
>
>     @Override
>     protected Converter createConverter() throws JspException
>     {
>         BooleanConverter converter = (BooleanConverter)  
> super.createConverter();
>         converter.setType(this.type);
>         return converter;
>     }
> }
> package org.stillsecure.cobia.web.converters;
>
> import org.stillsecure.cobia.web.util.WebContext;
>
> import java.util.HashMap;
> import java.util.Map;
>
> import javax.faces.application.FacesMessage;
> import javax.faces.component.StateHolder;
> import javax.faces.component.UIComponent;
> import javax.faces.context.FacesContext;
> import javax.faces.convert.Converter;
> import javax.faces.convert.ConverterException;
>
> /**
>  * This class implements a JSF converter to convert from boolean  
> values
>  * to specialized text strings, such as yes/no or enabled/disabled.
>  */
> public class BooleanConverter implements Converter, StateHolder
> {
>     /** The JSF id for this converter.  Must be the same as defined  
> in the framework-faces-config.xml file. */
>     public final static String CONVERTER_ID = "converter.Boolean";
>
>     //
>     // Registering Boolean "types"
>     //
>
>     public static void registerType(String type, String trueName,  
> String falseName)
>     {
>         BOOLEAN_NAME_PAIRS_MAP.put(type, new String[]  
> {trueName.toLowerCase(), falseName.toLowerCase()});
>     }
>     public static boolean isValidType(String type)
>     {
>         return BOOLEAN_NAME_PAIRS_MAP.containsKey(type);
>     }
>     public static String[] getType(String type)
>     {
>         return BOOLEAN_NAME_PAIRS_MAP.get(type);
>     }
>     private static final Map<String, String[]>  
> BOOLEAN_NAME_PAIRS_MAP = new HashMap<String, String[]>();
>
>     //
>     // Default Boolean name types
>     //
>
>     public static final String STANDARD = "STANDARD";
>     public static final String YES_NO = "YES/NO";
>     public static final String ENABLE = "OP-MODE";
>     public static final String UP_DOWN = "UP/DOWN";
>
>     static
>     {
>         registerType(STANDARD, "true", "false");
>         registerType(YES_NO, "yes", "no");
>         registerType(ENABLE, "enabled", "disabled");
>         registerType(UP_DOWN, "up", "down");
>     }
>
>     //
>     // Attributes
>     //
>
>     private String type;
>
>     /**
>      * Sets the type of Boolean conversion.
>      *
>      * @param type must be a registered Boolean type name
>      */
>     public void setType(String type)
>     {
>         this.type = type;
>     }
>
>     public void checkType(String type)
>     {
>         // Check converter state
>         if ( type == null )
>             throw new ConverterException 
> (WebContext.createFacesMessage(NO_TYPE_ERROR));
>         if ( ! isValidType(type) )
>             throw new ConverterException 
> (WebContext.createFacesMessage(BAD_TYPE_ERROR, this.type));
>     }
>     private static final String NO_TYPE_ERROR =  
> "BASE_BooleanConverter_noTypeError";
>     private static final String BAD_TYPE_ERROR =  
> "BASE_BooleanConverter_badTypeError";
>
>     //
>     // JSF methods
>     //
>
>     /**
>      * This method converts from the string representation to a  
> Boolean object.
>      */
>     public Object getAsObject(FacesContext ctx, UIComponent comp,  
> String displayString) throws ConverterException
>     {
>         checkType(this.type);
>
>         Boolean result = null;
>
>         String[] pair = getType(this.type);
>         if ( pair[0].equalsIgnoreCase(displayString) )
>         {
>             result = Boolean.TRUE;
>         }
>         else if ( pair[1].equalsIgnoreCase(displayString) )
>         {
>             result = Boolean.FALSE;
>         }
>         else
>         {
>             FacesMessage message
>                 = WebContext.createFacesMessage 
> (BOOLEAN_CONVERTER_TO_OBJECT_FAILED, displayString);
>             throw new ConverterException(message);
>         }
>
>         return result;
>     }
>     private static final String BOOLEAN_CONVERTER_TO_OBJECT_FAILED  
> = "BASE_BooleanConverter_getAsObjectFailed";
>
>     /**
>      * This method converts from the Boolean object to the string  
> representation.
>      */
>     public String getAsString(FacesContext ctx, UIComponent comp,  
> Object object) throws ConverterException
>     {
>         checkType(this.type);
>
>         String result = null;
>
>         String[] pair = getType(this.type);
>         try
>         {
>             Boolean o = (Boolean) object;
>             if ( o == null )
>                 result = "";
>             else if ( o.equals(Boolean.TRUE) )
>                 result = pair[0];
>             else if ( o.equals(Boolean.FALSE) )
>                 result = pair[1];
>             else
>                 assert false : "Unknown object" + o;
>         }
>         catch (ClassCastException e)
>         {
>             assert false : e;
>         }
>
>         return result;
>     }
>
>     //
>     // StateHolder methods
>     //
>
>     private boolean transientFlag;
>
>     public void setTransient(boolean transientValue)
>     {
>         this.transientFlag = transientValue;
>     }
>
>     public boolean isTransient()
>     {
>         return transientFlag;
>     }
>
>     public Object saveState(FacesContext context)
>     {
>         Object[] values = new Object[1];
>         values[0] = this.type;
>         return values;
>     }
>
>     public void restoreState(FacesContext context, Object state)
>     {
>         Object[] values = (Object[]) state;
>         this.type = (String) values[0];
>     }
>
> }


Re: Creating a custom converter tag

Posted by Bryan Basham <bb...@stillsecure.com>.
Hello "kind sole" ;-)

I have just created a converter with a tag.  Nice little exercise.

My app has lots of "names" for Boolean values, such as
"yes" / "no" and "enabled" / "disabled" and so on.  I used
to create a separate accessor method to convert from the
Boolean to a String, but I wanted something more generic
so I created the BooleanConverter and BooleanConverterTag
to handle this situation.

So, for example in a JSF page you might want to display a
boolean value as yes/no:

<p>
Did the student fill in the form?
<h:outputText value='#{bean.formFilledIn}'>  // the bean 
isFormFilledIn() method must return boolean
  <my:booleanConverter type='YES/NO' />
</h:outputText>
</p>

I have attached my classes for this converter and tag.
Don't forget that you need to declare this tag in your own TLD file.

HTH,
Bryan



kindsol wrote:
> I want to create a custom converter as it's own tag (e.g. not using 
> <f:converter> tag.  Is there any documentation online or elsewhere 
> that you can point me to?
>
> thanks in advance!
>
> -Sol
>
>