-----Original Message-----
From: Mike Kienenberger [mailto:[EMAIL PROTECTED] 
Sent: Thursday, April 06, 2006 2:03 PM

> String converters aren't allowed in JSF 1.1, but they are in 1.2. 
> Otherwise a converter would be a good choice.

Not sure what you meant by "String converters aren't allowed" I saw 
several examples in books so I wrote one and it works great.
(It's not a true "converter" since it only handles output.)


I call it truncateOutput and it takes two attributes a truncateAt
position 
and an optional continuationMark.

<h:outputText value="#{var.description}">
        <xxx:truncateOutput truncateAt="35" continuationMark="..." />
</h:outputText>

Here are all the pieces, if anyone want to package them up 
for contribution to tomahawk that would be great!
I don't have the time (or knowledge how) to do it right now.
 

TruncateConverter.java
----------------------
public class TruncateConverter implements Converter, StateHolder
{
    private int     truncateAt = 0;
    private String  continuationMark;
    private boolean transientFlag;

    public Object getAsObject(FacesContext context,
                              UIComponent component,
                              String value) throws ConverterException
    {
        // Should never happend - TruncateConverter is only usable for
output.
        throw new AssertionError(getClass().getName()
            + " does not support Input conversion.");
    }

    public String getAsString(FacesContext context,
                              UIComponent component,
                              Object value) throws ConverterException
    {
        if (value == null)
        {
            return null;
        }

        StringBuffer buff = new StringBuffer();
        buff.append(value);

        if (getTruncateAt() > 0 && buff.length() > getTruncateAt())
        {
            buff.setLength(getTruncateAt());
            if (getContinuationMark() != null)
            {
                buff.append(getContinuationMark());
            }
        }

        return buff.toString();
    }

    /**
     * @return Returns the continuationMark.
     */
    public String getContinuationMark()
    {
        return continuationMark;
    }

    /**
     * @param continuationMark The continuationMark to set.
     */
    public void setContinuationMark(String continuationMark)
    {
        this.continuationMark = continuationMark;
    }

    /**
     * @return Returns the truncateAt.
     */
    public int getTruncateAt()
    {
        return truncateAt;
    }

    /**
     * @param truncateAt The truncateAt to set.
     */
    public void setTruncateAt(int truncateAt)
    {
        this.truncateAt = truncateAt;
    }

    // STATE SAVE/RESTORE
    public void restoreState(FacesContext facesContext, Object state)
    {
        Object[] values = (Object[]) state;
        this.truncateAt = ((Integer) values[0]).intValue();
        this.continuationMark = (String) values[1];
    }

    public Object saveState(FacesContext facesContext)
    {
        Object[] values = new Object[2];
        values[0] = new Integer(getTruncateAt());
        values[1] = getContinuationMark();
        return values;
    }

    public boolean isTransient()
    {
        return transientFlag;
    }

    public void setTransient(boolean aTransient)
    {
        transientFlag = aTransient;
    }
}

TruncateConverterTag.java
--------------------------
public class TruncateConverterTag extends ConverterTag
{
    private static final long serialVersionUID = -5486065206529786966L;

    public TruncateConverterTag()
    {
        setConverterId("xxx.TruncateConverter");
    }

    private String truncateAt;
    private String continuationMark;

    protected Converter createConverter() throws JspException
    {
        TruncateConverter converter = (TruncateConverter)
super.createConverter();

        FacesContext facesContext = FacesContext.getCurrentInstance();
        setConverterTruncateAt(facesContext, converter, truncateAt);
        setContinuationMark(facesContext, converter, continuationMark);
        return converter;
    }

    public void release()
    {
        truncateAt = null;
        continuationMark = null;
    }

    /**
     * Set the continuation mark to be used if the value is truncated.
(E.g. "...")
     * @param continuationMark expression that evaluates to a String.
     */
    public void setContinuationMark(String continuationMark)
    {
        this.continuationMark = continuationMark;
    }

    /**
     * Set the position to truncate the value.
     * @param truncateAt expression that evaluates to an int.
     */
    public void setTruncateAt(String truncateAt)
    {
        this.truncateAt = truncateAt;

    }

    private static void setConverterTruncateAt(FacesContext
facesContext,
                                               TruncateConverter
converter,
                                               String value)
    {
        if (value == null)
        {
            converter.setTruncateAt(0);
        }
        else if (UIComponentTag.isValueReference(value))
        {
            ValueBinding vb =
facesContext.getApplication().createValueBinding(
                value);
            Object o = vb.getValue(facesContext);
            if (o instanceof Number)
            {
                converter.setTruncateAt(((Number) o).intValue());
            }
            else
            {
                converter.setTruncateAt(Integer.parseInt(o.toString()));
            }
        }
        else
        {
            converter.setTruncateAt(Integer.parseInt(value));
        }
    }

    private static void setContinuationMark(FacesContext facesContext,
                                            TruncateConverter converter,
                                            String value)
    {
        if (value == null)
        {
            converter.setContinuationMark(null);
        }
        else if (UIComponentTag.isValueReference(value))
        {
            ValueBinding vb =
facesContext.getApplication().createValueBinding(
                value);
            converter.setContinuationMark((String)
vb.getValue(facesContext));
        }
        else
        {
            converter.setContinuationMark(value);
        }
    }
}

>From the TLD
------------
<taglib>
        <tlib-version>1.0</tlib-version>
        <jsp-version>1.2</jsp-version>
        <short-name>xxx</short-name>
        <tag>
                <name>truncateOutput</name>
                <tag-class>xxx.TruncateConverterTag</tag-class>
                <body-content>empty</body-content>
                <attribute>
                        <name>truncateAt</name>
                        <required>true</required>
                        <rtexprvalue>false</rtexprvalue>
                        <description>position to truncate
at</description>
                </attribute>
                <attribute>
                        <name>continuationMark</name>
                        <required>false</required>
                        <rtexprvalue>false</rtexprvalue>
                        <description>String to append when trancated
(eg. "...")</description>
                </attribute>
        </tag>
</taglib>

>From the Faces Config file
--------------------------
<faces-config>

        <converter>
                <converter-id>xxx.TruncateConverter</converter-id>
                <converter-class>xxx.TruncateConverter</converter-class>
        </converter>
        
</faces-config>

Reply via email to