Hi,
I'm trying to write a custom converter that converts the casing of text.
Therefor I want a "type" attribute that let's me choose if I want to convert
to lower case, UPPER CASE or Title Case. This is what I've done so far:
*Created converter class*
I've created a class, CaseConverter.java:
package my.company.conversion;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
public class CaseConverter implements Converter {
private String type = "lower";
public Object getAsObject(FacesContext context, UIComponent component,
String string) {
String result = "";
if ("upper".equals(getType())){
return string.toUpperCase();
} else if ("title".equals(getType())) {
return toTitleCase(string);
} else {
return string.toLowerCase();
}
return result;
}
private String toTitleCase(String string){
// left out for brevity
}
public synchronized String getAsString(FacesContext context, UIComponent
component, Object object) {
return object.toString();
}
public void setType(String type) {
if (type != null) {
this.type = type.toLowerCase();
}
}
public String getType() {
return type;
}
}
*Registered converter in faces-config.xml*
As follows:
<converter>
<description>Case converter for text values</description>
<converter-id>convertCase</converter-id>
<converter-class>my.company.conversion.CaseConverter</converter-class>
</converter>
*Added to Facelets taglib*
I already had a my.taglib.xml file for some composition components, so I
added my converter there:
<tag>
<tag-name>convertCase</tag-name>
<converter>
<converter-id>convertCase</converter-id>
</converter>
</tag>
*Used the converter in a page*
I added the converter to a page, like this:
<my:field id="jobTitle" bean="#{pageFlowScope.selectedEmployee}" >
<my:convertCase type="title"/>
</my:field>
The <my:field> component is a Facelets Composition Component, defined as
follows:
<ui:composition>
<c:if test="#{empty autoComplete}">
<c:set var="autoComplete" value="on" />
</c:if>
<c:if test="#{empty simple}">
<c:set var="simple" value="false" />
</c:if>
<!-- This is a work around for bug TRINIDAD-1390. -->
<c:if test="#{empty maximumLength}">
<c:if test="#{columns gt 1}">
<c:set var="maximumLength" value="2147483647" />
</c:if>
</c:if>
<!-- This is a work around for bug TRINIDAD-1417. -->
<c:if test="#{not empty partialTriggers}">
<c:set var="partialTriggers"
value="#{my:getStringArray(partialTriggers)}" />
</c:if>
<tr:inputText value="#{bean[id]}" id="#{id}" required="#{required}"
readOnly="#{readOnly}"
label="#{msg[id]}:" secret="#{secret}"
maximumLength="#{maximumLength}" columns="#{columns}"
rows="#{rows}" wrap="#{wrap}" autoComplete="#{autoComplete}"
simple="#{simple}"
partialTriggers="#{partialTriggers}" >
<ui:insert/>
</tr:inputText>
</ui:composition>
*Versions used:*
Apache MyFaces 1.2.4
Apache MyFaces Trinidad 1.2.10
Facelets 1.1.14
*Problem description:
*Everything works fine, except that the method setType() is only called
before a call to getAsString(). I figured out that:
- Everytime the converter is needed, a new instance of the class is
constructed.
- Before every call to getAsString() the setType() is called with the
value set in the tag attribute ("title" in this case).
- Before a call to getAsObject() the setType() method is *not *called.
This causes the strings to always be converted to lower case, which is de
default.
Is this normal behaviour? What should I do to get it right? I hope someine
can help...
Best regards,
Bart Kummel