You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Bart Kummel <ba...@kummelweb.nl> on 2009/03/21 12:41:00 UTC
Custom converter: attributes not set?
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
Re: Custom converter: attributes not set?
Posted by Matthias Wessendorf <ma...@apache.org>.
you have to implement stateholder interface:
http://myfaces.apache.org/core12/myfaces-api/apidocs/javax/faces/component/StateHolder.html
like here, for instance:
http://svn.apache.org/viewvc/myfaces/core/trunk_1.2.x/api/src/main/java/javax/faces/convert/DateTimeConverter.java?view=markup
http://svn.apache.org/viewvc/myfaces/core/trunk_1.2.x/api/src/main/java/javax/faces/convert/NumberConverter.java?view=markup
-Matthias
On Sat, Mar 21, 2009 at 12:41 PM, Bart Kummel <ba...@kummelweb.nl> wrote:
> 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
>
--
Matthias Wessendorf
blog: http://matthiaswessendorf.wordpress.com/
sessions: http://www.slideshare.net/mwessendorf
twitter: http://twitter.com/mwessendorf