[jboss-cvs] jboss-seam/src/ui/org/jboss/seam/ui ...
Peter Muir
peter at bleepbleep.org.uk
Wed Feb 7 09:51:18 EST 2007
User: pmuir
Date: 07/02/07 09:51:18
Modified: src/ui/org/jboss/seam/ui ConverterChain.java
Added: src/ui/org/jboss/seam/ui PrioritizableConverter.java
Log:
JBSEAM-755
Revision Changes Path
1.2 +65 -115 jboss-seam/src/ui/org/jboss/seam/ui/ConverterChain.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: ConverterChain.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/src/ui/org/jboss/seam/ui/ConverterChain.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- ConverterChain.java 5 Feb 2007 22:54:30 -0000 1.1
+++ ConverterChain.java 7 Feb 2007 14:51:18 -0000 1.2
@@ -1,7 +1,8 @@
package org.jboss.seam.ui;
-import java.util.PriorityQueue;
-import java.util.Queue;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
@@ -10,130 +11,54 @@
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
+import javax.faces.el.ValueBinding;
/**
* This class provides a chainable converter for JSF.
*
+ * This has been done to support noSelections on s:selectItems.
+ *
+ * Converters that are not first/last (the converter specfied on the component)
+ * need careful implementation
+ *
* A converter can be placed in the chain with a priority, the order in which
* converters with the same priority is run is not specified.
*
- * The chain will be processed in a priority order, with the getAs{String,Object},
- * with the result of each conversion being piped to the next. Every converter
- * will be run during getAsString, during getAsObject converters will be run until
- * the result of conversion is not a string
+ * The chain will be processed in ascending order for getAsString, descending order
+ * for getAsObject
*
*/
public class ConverterChain implements Converter, StateHolder
{
/**
- * Implementation of a prioritizable converter
- * Uses an int to indicate priority of the converter
- *
- */
- private class PrioritizableConverter implements Converter, Comparable<PrioritizableConverter>, StateHolder
- {
-
- private Converter delegate;
-
- private int priority;
-
- public PrioritizableConverter(Converter delegate, int priority)
- {
- this.delegate = delegate;
- this.priority = priority;
- }
-
- public Converter getDelegate()
- {
- return delegate;
- }
-
- public int getPriority()
- {
- return priority;
- }
-
- public Object getAsObject(FacesContext context, UIComponent component, String value)
- throws ConverterException
- {
- return delegate.getAsObject(context, component, value);
- }
-
- public String getAsString(FacesContext context, UIComponent component, Object value)
- throws ConverterException
- {
- return delegate.getAsString(context, component, value);
- }
-
- public int compareTo(PrioritizableConverter o)
- {
- return this.getPriority() - o.getPriority();
- }
-
- /*
- **********************************
- * Implementation of StateHolder *
- **********************************
- */
-
- private boolean _transient;
-
- public boolean isTransient()
- {
- return _transient;
- }
-
- public void restoreState(FacesContext context, Object state)
- {
- Object[] values = (Object[] ) state;
- delegate = (Converter) UIComponentBase.restoreAttachedState(context,values[0]);
- priority = (Integer) values[1];
-
- }
-
- public Object saveState(FacesContext context)
- {
- Object[] values = new Object[2];
- values[0] = UIComponentBase.saveAttachedState(context, delegate);
- values[1] = priority;
- return converters;
- }
-
- public void setTransient(boolean newTransientValue)
- {
- this._transient = newTransientValue;
-
- }
- }
-
- /**
- * This places the converter at the end of the chain.
- * No garuntee is made about the order converters which are placed
- * on the queue with this priority will be run
+ * This places the converter at the end of the chain. No garuntee is made
+ * about the order converters which are placed on the queue with this
+ * priority will be run
*/
public static final int CHAIN_END = Integer.MAX_VALUE;
/**
- * This places the converter at the head of the chain.
- * No garuntee is made about the order converters which are placed
- * on the queue with this priority will be run
+ * This places the converter at the head of the chain. No garuntee is made
+ * about the order converters which are placed on the queue with this
+ * priority will be run
*/
- public static final int CHAIN_START = Integer.MIN_VALUE;
-
- private Queue<PrioritizableConverter> converters;
+ public static final int CHAIN_START = 0;
+ private List<PrioritizableConverter> converters;
public ConverterChain()
{
- converters = new PriorityQueue<PrioritizableConverter>();
+ // A Priority Queue would be nice but JSF has issues serializing that
+ converters = new ArrayList<PrioritizableConverter>();
}
/**
* Set up a ConverterChain for this component.
*
- * This replaces any existing converter with a ConverterChain
- * with the existing Converter at the end of the chain
+ * This replaces any existing converter with a ConverterChain with the
+ * existing Converter at the end of the chain
+ *
* @param component
*/
public ConverterChain(UIComponent component)
@@ -142,7 +67,12 @@
if (component instanceof ValueHolder)
{
ValueHolder valueHolder = (ValueHolder) component;
+ ValueBinding vb =component.getValueBinding("converter");
+ if (vb != null) {
+ addConverterToChain(vb);
+ } else {
addConverterToChain(valueHolder.getConverter());
+ }
valueHolder.setConverter(this);
}
}
@@ -151,6 +81,8 @@
throws ConverterException
{
Object result = null;
+ Collections.sort(converters);
+ Collections.reverse(converters);
for (Converter converter : converters)
{
result = converter.getAsObject(context, component, value);
@@ -170,6 +102,7 @@
public String getAsString(FacesContext context, UIComponent component, Object value)
throws ConverterException
{
+ Collections.sort(converters);
for (Converter converter : converters)
{
value = converter.getAsString(context, component, value);
@@ -197,6 +130,14 @@
}
/**
+ * Add a converter to the end of the chain
+ */
+ public boolean addConverterToChain(ValueBinding c)
+ {
+ return addConverterToChain(c, CHAIN_END);
+ }
+
+ /**
* Add a converter to the chain with a defined priority
*/
public boolean addConverterToChain(Converter c, int priority)
@@ -211,11 +152,20 @@
}
}
- /*
- **********************************
- * Implementation of StateHolder *
- **********************************
+ /**
+ * Add a converter to the chain with a defined priority
*/
+ public boolean addConverterToChain(ValueBinding c, int priority)
+ {
+ if (c != null)
+ {
+ return converters.add(new PrioritizableConverter(c, priority));
+ }
+ else
+ {
+ return false;
+ }
+ }
private boolean _transient;
@@ -226,9 +176,9 @@
public void restoreState(FacesContext context, Object state)
{
- Object[] values = (Object[] ) state;
- converters = (Queue<PrioritizableConverter>) UIComponentBase.restoreAttachedState(context,values[0]);
-
+ Object[] values = (Object[]) state;
+ converters = (List<PrioritizableConverter>) UIComponentBase.restoreAttachedState(context,
+ values[0]);
}
public Object saveState(FacesContext context)
1.1 date: 2007/02/07 14:51:18; author: pmuir; state: Exp;jboss-seam/src/ui/org/jboss/seam/ui/PrioritizableConverter.java
Index: PrioritizableConverter.java
===================================================================
package org.jboss.seam.ui;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.el.ValueBinding;
/**
* Helper class for ConverterChain
*
*/
public class PrioritizableConverter implements Converter, Comparable<PrioritizableConverter>,
StateHolder
{
private ValueBinding vb;
private Converter delegate;
private int priority;
public PrioritizableConverter()
{
}
public PrioritizableConverter(ValueBinding vb, int priority)
{
this.vb = vb;
this.priority = priority;
}
public PrioritizableConverter(Converter delegate, int priority)
{
this.delegate = delegate;
this.priority = priority;
}
public Converter getDelegate()
{
if (vb != null)
{
return (Converter) vb.getValue(FacesContext.getCurrentInstance());
}
else
{
return delegate;
}
}
public int getPriority()
{
return priority;
}
public Object getAsObject(FacesContext context, UIComponent component, String value)
throws ConverterException
{
return getDelegate().getAsObject(context, component, value);
}
public String getAsString(FacesContext context, UIComponent component, Object value)
throws ConverterException
{
return getDelegate().getAsString(context, component, value);
}
public int compareTo(PrioritizableConverter o)
{
return this.getPriority() - o.getPriority();
}
private boolean _transient;
public boolean isTransient()
{
return _transient;
}
public void restoreState(FacesContext context, Object state)
{
Object[] values = (Object[]) state;
delegate = (Converter) UIComponentBase.restoreAttachedState(context, values[0]);
priority = (Integer) values[1];
vb = (ValueBinding) values[2];
}
public Object saveState(FacesContext context)
{
Object[] values = new Object[3];
values[0] = UIComponentBase.saveAttachedState(context, delegate);
values[1] = priority;
values[2] = vb;
return values;
}
public void setTransient(boolean newTransientValue)
{
this._transient = newTransientValue;
}
}
More information about the jboss-cvs-commits
mailing list