[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