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

Reply via email to