[jboss-cvs] jboss-seam/seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter ...

Peter Muir peter at bleepbleep.org.uk
Tue Mar 20 13:58:58 EDT 2007


  User: pmuir   
  Date: 07/03/20 13:58:58

  Added:       seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter      
                        EnumConverter.java EntityConverterStore.java
                        PrioritizableConverter.java EntityConverter.java
                        NoSelectionConverter.java ConverterChain.java
  Log:
  Port more tags to CDK
  
  Revision  Changes    Path
  1.1      date: 2007/03/20 17:58:58;  author: pmuir;  state: Exp;jboss-seam/seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter/EnumConverter.java
  
  Index: EnumConverter.java
  ===================================================================
  package org.jboss.seam.ui.converter;
  
  import javax.faces.component.*;
  import javax.faces.context.*;
  import javax.faces.convert.*;
  
  public class EnumConverter
      implements Converter
  {
      public Object getAsObject(FacesContext context,
                                UIComponent comp,
                                String value)
          throws ConverterException
      {
          Class enumType = comp.getValueBinding("value").getType(context);
          return Enum.valueOf(enumType, value);
      }
  
      public String getAsString(FacesContext context,
                                UIComponent component,
                                Object object)
          throws ConverterException
      {
          if (object == null) {
              return null;
          }
  
          return ((Enum) object).name();
      }
  
  }
  
  
  
  1.1      date: 2007/03/20 17:58:58;  author: pmuir;  state: Exp;jboss-seam/seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter/EntityConverterStore.java
  
  Index: EntityConverterStore.java
  ===================================================================
  package org.jboss.seam.ui.converter;
  
  import java.io.Serializable;
  import java.util.ArrayList;
  import java.util.List;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.InterceptionType;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.AbstractMutable;
  import org.jboss.seam.util.Proxy;
  
  @Name("org.jboss.seam.ui.entityConverterStore")
  @Scope(ScopeType.PAGE)
  @Intercept(InterceptionType.NEVER)
  public class EntityConverterStore extends AbstractMutable
  {
     
     private class Key implements Serializable
     {
        private Class clazz;
        private Object id;
        
        public Key(Class clazz, Object id)
        {
           this.clazz = clazz;
           this.id = id;
        }
        
        public Class getClazz()
        {
           return clazz;
        }
        
        public Object getId()
        {
           return id;
        }
        
        
        @Override
        public boolean equals(Object other)
        {
           if (other instanceof Key)
           {
              Key that = (Key) other;
              if (id == null || clazz == null)
              {
                 throw new IllegalArgumentException("Class and Id must not be null");
              }
              else 
              {
                 return this.getId().equals(that.getId()) && this.getClazz().equals(that.getClazz());
              }
           }
           return false;
        }
     }
  
     private List<Key> store = new ArrayList<Key>();
     
     public Class getClass(Integer key)
     {
        return store.get(key).getClazz();
     }
     
     public Object getId(Integer key)
     {
        return store.get(key).getId();
     }
     
     public Integer put(Class clazz, Object id)
     {
        clazz = Proxy.deproxy(clazz);
        Key key = new Key(clazz, id);
        if (!store.contains(key))
        {
           store.add(key);
           setDirty();
           
        }
        return store.indexOf(key);
     }
     
     public static EntityConverterStore instance() 
     {
        if (!Contexts.isPageContextActive())
        {
           throw new IllegalArgumentException("Page scope not active");
        }
        return (EntityConverterStore) Component.getInstance(EntityConverterStore.class);
     }
     
  }
  
  
  
  1.1      date: 2007/03/20 17:58:58;  author: pmuir;  state: Exp;jboss-seam/seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter/PrioritizableConverter.java
  
  Index: PrioritizableConverter.java
  ===================================================================
  package org.jboss.seam.ui.converter;
  
  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;
  
     }
  }
  
  
  1.1      date: 2007/03/20 17:58:58;  author: pmuir;  state: Exp;jboss-seam/seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter/EntityConverter.java
  
  Index: EntityConverter.java
  ===================================================================
  package org.jboss.seam.ui.converter;
  
  import static javax.faces.application.FacesMessage.SEVERITY_ERROR;
  import static org.jboss.seam.annotations.Install.BUILT_IN;
  import static org.jboss.seam.InterceptionType.NEVER;
  
  import java.io.Serializable;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  import java.util.List;
  
  import javax.faces.component.UIComponent;
  import javax.faces.context.FacesContext;
  import javax.faces.convert.ConverterException;
  import javax.persistence.EntityManager;
  import javax.persistence.Id;
  
  import org.jboss.seam.Component;
  import org.jboss.seam.ScopeType;
  import org.jboss.seam.annotations.Install;
  import org.jboss.seam.annotations.Intercept;
  import org.jboss.seam.annotations.Name;
  import org.jboss.seam.annotations.Scope;
  import org.jboss.seam.annotations.Transactional;
  import org.jboss.seam.annotations.jsf.Converter;
  import org.jboss.seam.core.FacesMessages;
  import org.jboss.seam.core.Expressions.ValueBinding;
  import org.jboss.seam.log.Log;
  import org.jboss.seam.log.Logging;
  import org.jboss.seam.util.Reflections;
  
  /**
   * This implementation of the EntityConverter is suitable for any Entity which
   * uses annotations
   * 
   * 
   */
  @Name("org.jboss.seam.ui.entityConverter")
  @Scope(ScopeType.CONVERSATION)
  @Install(precedence = BUILT_IN)
  @Converter
  @Intercept(NEVER)
  public class EntityConverter implements
           javax.faces.convert.Converter, Serializable
  {
     
     private ValueBinding<EntityManager> entityManager;
     
     private Log log = Logging.getLog(EntityConverter.class);
  
     private String errorMessage = "Error selecting object";
     
     public void setEntityManager(ValueBinding<EntityManager> entityManager)
     {
        this.entityManager = entityManager;
     }
     
     private EntityManager getEntityManager() {
        if (entityManager==null)
        {
          return (EntityManager) Component.getInstance( "entityManager" );
        }
        else
        {
           return entityManager.getValue();
        }
     }
  
     protected void errorGettingIdMessage(UIComponent cmp, FacesContext facesContext, Object entity)
     {
        log.error("@Id annotation not on #0", entity.getClass());
        throw new ConverterException(FacesMessages.createFacesMessage(SEVERITY_ERROR, getErrorMessageKey(), getErrorMessage()));
     }
  
     protected String getErrorMessage()
     {
        return errorMessage;
     }
  
     protected String getErrorMessageKey()
     {
        return getEntityConverterKeyPrefix() + "idNotFound";
     }
  
     protected void invalidSelectionMessage(Class clazz, Object id)
     {
        log.error("Cannot load entity (#0 with id #1) from persistence context", clazz.getName(), id);
        throw new ConverterException(FacesMessages.createFacesMessage(SEVERITY_ERROR, getErrorMessageKey(), getErrorMessage()));
     }
     
     protected void entityManagerNotFoundMessage()
     {
        log.error("Entity Manager not found");
        throw new ConverterException(FacesMessages.createFacesMessage(SEVERITY_ERROR, getErrorMessageKey(), getErrorMessage()));
     }
  
     protected String getEntityConverterKeyPrefix()
     {
        return "org.jboss.seam.ui.entityConverter.";
     }
  
     /**
      * @param entity
      *           The entity to use
      * @param cmp
      *           The UIComponent this converter is attached to
      * @param facesContext
      *           The current facesContext
      * @return The ID of the entity as a string or null if unable to determine it
      */
     protected Object getIdFromEntity(UIComponent cmp, FacesContext facesContext,
              Object entity)
     {
        Object id = null;
        List<Field> fields = Reflections.getFields(entity.getClass(), Id.class);
        if (fields.size() == 1)
        {
           Field field = fields.get(0);
           boolean accessible = field.isAccessible();
           field.setAccessible(true);
           
           try {
              id = Reflections.get(field, entity);
           }
           catch (Exception e)
           {
              errorGettingIdMessage(cmp, facesContext, entity);
           }
           finally
           {
              field.setAccessible(accessible);
           }
        }
        else
        {
           List<Method> methods = Reflections.getGetterMethods(entity.getClass(), Id.class);
           if (methods.size() == 1)
           {
              try
              {
                 id = Reflections.invoke(methods.get(0), entity, new Object[0]);
              }
              catch (Exception e)
              {
                errorGettingIdMessage(cmp, facesContext, entity);
              }
           }
        }
        if (id == null)
        {
           return NoSelectionConverter.NO_SELECTION_VALUE;
        } 
        else
        {
           return id;
        }
     }
  
     @SuppressWarnings("unchecked")
     @Transactional
     public String getAsString(FacesContext facesContext, UIComponent cmp, Object value) throws ConverterException
     {
        if (value == null)
        {
           return null;
        }
        if (value instanceof String) 
        {
           return (String) value;
        }
        return EntityConverterStore.instance().put(value.getClass(), getIdFromEntity(cmp, facesContext, value)).toString();
     }
  
     @Transactional
     public Object getAsObject(FacesContext facesContext, UIComponent cmp, String value) throws ConverterException
     {
        if (value == null)
        {
           return null;
        }
        Integer key = new Integer(value);
        Class clazz = EntityConverterStore.instance().getClass(key);
        Object id = EntityConverterStore.instance().getId(key);
        return loadEntityFromPersistenceContext(clazz, id);
     }
  
     /**
      * Retrieve the Entity from the PersistenceContext
      * 
      * @param clazz
      *           The class of the entity to load
      * @param id
      *           The id of the entity to load
      * @return The entity, null if not found
      */
     @SuppressWarnings("unchecked")
     protected Object loadEntityFromPersistenceContext(Class clazz, Object id)
     {
        if (id == null || clazz == null)
        {
           return null;
        }
        Object entity = null;
        if (getEntityManager() == null)
        {
           entityManagerNotFoundMessage();
        }
        entity = getEntityManager().find(clazz, id);
        if (entity == null)
        {
           invalidSelectionMessage(clazz, id);
           return null;
        }
        else
        {
           return entity;
        }
     }
  }
  
  
  1.1      date: 2007/03/20 17:58:58;  author: pmuir;  state: Exp;jboss-seam/seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter/NoSelectionConverter.java
  
  Index: NoSelectionConverter.java
  ===================================================================
  package org.jboss.seam.ui.converter;
  
  import javax.faces.component.UIComponent;
  import javax.faces.context.FacesContext;
  import javax.faces.convert.Converter;
  import javax.faces.convert.ConverterException;
  
  public class NoSelectionConverter implements Converter
  {
  	public static final String NO_SELECTION_VALUE = "org.jboss.seam.ui.NoSelectionConverter.noSelectionValue";
  
     public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException
     {
        if (value == null) {
      	  return null;
        } else if (value.equals(NO_SELECTION_VALUE)) {
      	  return null;
        } else {
      	  return ConverterChain.CONTINUE;
        }
     }
  
     public String getAsString(FacesContext context, UIComponent component, Object value) throws ConverterException
     {
        if (value == null) {
      	  return NO_SELECTION_VALUE;
        } else {
      	  return ConverterChain.CONTINUE;
        }
     }
  
  }
  
  
  
  1.1      date: 2007/03/20 17:58:58;  author: pmuir;  state: Exp;jboss-seam/seam-ui-cdk/jboss-seam-ui/src/main/java/org/jboss/seam/ui/converter/ConverterChain.java
  
  Index: ConverterChain.java
  ===================================================================
  package org.jboss.seam.ui.converter;
  
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.List;
  
  import javax.faces.component.StateHolder;
  import javax.faces.component.UIComponent;
  import javax.faces.component.UIComponentBase;
  import javax.faces.component.ValueHolder;
  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.
   * 
   * Any JSF converter can be placed at the end of the chain. A converter that is
   * placed higher up the chain should return ConverterChain.CONTINUE if
   * conversion has failed. If the all converters run return
   * ConverterChain.CONTINUE an unconverted value will be returned.
   * 
   * 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.
   * 
   */
  public class ConverterChain implements Converter, StateHolder
  {
  
     public static final String CONTINUE = "org.jboss.seam.ui.ConverterChain.continue";
  
     /**
      * 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
      */
     public static final int CHAIN_START = 0;
  
     private List<PrioritizableConverter> converters;
  
     private boolean dirty;
  
     public ConverterChain()
     {
        // 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
      * 
      * @param component
      */
     public ConverterChain(UIComponent component)
     {
        this();
        if (component instanceof ValueHolder)
        {
           ValueHolder valueHolder = (ValueHolder) component;
           if (!(valueHolder.getConverter() instanceof ConverterChain)) 
           {
              ValueBinding converterValueBinding = component.getValueBinding("converter");
              if (converterValueBinding != null)
              {
                 addConverterToChain(converterValueBinding);
              }
              else if (valueHolder.getConverter() != null)
              {
                 addConverterToChain(valueHolder.getConverter());
              }
              else
              {
                 ValueBinding valueBinding = component.getValueBinding("value");
                 FacesContext facesContext = FacesContext.getCurrentInstance();
                 if (valueBinding != null)
                 {
                    addConverterToChain(facesContext.getApplication().createConverter(
                             valueBinding.getType(facesContext)));
                 }
              }
              valueHolder.setConverter(this);
           }
        }
     }
  
     public Object getAsObject(FacesContext context, UIComponent component, String value)
              throws ConverterException
     {
        Object output = null;
        for (Converter converter : getConverters())
        {
           Object result = converter.getAsObject(context, component, value);
           if (!CONTINUE.equals(result))
           {
              output = result;
              break;
           }
        }
        return output;
     }
  
     public String getAsString(FacesContext context, UIComponent component, Object value)
              throws ConverterException
     {
        String output = null;
        for (Converter converter : getConverters())
        {
           String result = converter.getAsString(context, component, value);
           if (!CONTINUE.equals(result))
           {
              output = result;
              break;
           }
        }
        return output;
     }
  
     /**
      * Add a converter to the end of the chain
      */
     public boolean addConverterToChain(Converter c)
     {
        return addConverterToChain(c, CHAIN_END);
     }
  
     /**
      * 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)
     {
        if (c != null)
        {
           dirty = true;
           return converters.add(new PrioritizableConverter(c, priority));
        }
        else
        {
           return false;
        }
     }
  
     /**
      * Add a converter to the chain with a defined priority
      */
     public boolean addConverterToChain(ValueBinding c, int priority)
     {
        if (c != null)
        {
           dirty = true;
           return converters.add(new PrioritizableConverter(c, priority));
        }
        else
        {
           return false;
        }
     }
  
     private boolean _transient;
  
     public boolean isTransient()
     {
        return _transient;
     }
  
     public void restoreState(FacesContext context, Object state)
     {
        Object[] values = (Object[]) state;
        converters = (List<PrioritizableConverter>) UIComponentBase.restoreAttachedState(context,
                 values[0]);
     }
  
     public Object saveState(FacesContext context)
     {
        Object[] values = new Object[1];
        values[0] = UIComponentBase.saveAttachedState(context, converters);
        return values;
     }
  
     public void setTransient(boolean newTransientValue)
     {
        this._transient = newTransientValue;
  
     }
  
     private List<PrioritizableConverter> getConverters()
     {
        if (dirty)
        {
           Collections.sort(converters);
        }
        return converters;
     }
     
     public boolean containsConverterType(Converter converter) {
        // TODO Improve this
        for (Converter c : converters) {
           if (c.getClass().equals(converter)) {
              return true;
           }
        }
        return false;
     }
  }
  
  



More information about the jboss-cvs-commits mailing list