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];
}
}