[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