Skip to content

Instantly share code, notes, and snippets.

@LightGuard
Created March 24, 2011 21:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LightGuard/885926 to your computer and use it in GitHub Desktop.
Save LightGuard/885926 to your computer and use it in GitHub Desktop.
EntityConverter for Seam 3
package org.jboss.seam.faces.conversion;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.el.ValueExpression;
import javax.enterprise.inject.Any;
import javax.faces.component.PartialStateHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.*;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.metamodel.EntityType;
import org.jboss.seam.solder.properties.Properties;
import org.jboss.seam.solder.properties.Property;
/**
* Converter for JPA entities. Uses the id of the entity for the key.
* @author <a href="http://community.jboss.org/people/LightGuard">Jason Porter</a>
*/
@FacesConverter("org.jboss.seam.EntityCOnverter")
public class EntityConverter implements javax.faces.convert.Converter, PartialStateHolder {
private static final Object[] ZERO_ARGS = new Object[] {};
@Inject @Any
private EntityManager entityManager;
private Map<String, Serializable> stateMap = new ConcurrentHashMap<String, Serializable>();
private boolean initialStateMarked;
private boolean isTransient;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
final ValueExpression ve = component.getValueExpression("value");
final Class<?> entityType = ve.getExpectedType();
return this.entityManager.find(entityType, this.stateMap.get(value));
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
final Serializable id = this.findId(value);
final String idKey = value.getClass().getSimpleName() + id.hashCode();
if (!this.stateMap.containsKey(idKey)) {
this.stateMap.put(value.getClass().getSimpleName() + id.hashCode(), id);
}
return idKey;
}
private Serializable findId(Object entity) {
final EntityType<?> entityType = this.entityManager.getMetamodel().entity(entity.getClass());
final Member idAttribute = entityType.getId(entity.getClass()).getJavaMember();
Property p = Properties.createProperty(idAttribute);
return (Serializable) p.getValue(entity);
}
// ---------- State saving --------------
@Override
public void markInitialState() {
this.initialStateMarked = true;
}
@Override
public boolean initialStateMarked() {
return this.initialStateMarked;
}
@Override
public void clearInitialState() {
this.stateMap = new ConcurrentHashMap<String, Serializable>();
this.initialStateMarked = false;
}
@Override
public Object saveState(FacesContext context) {
if (context == null)
{
throw new IllegalArgumentException("FacesContext must not be null");
}
return Collections.unmodifiableMap(this.stateMap);
}
@Override
public void restoreState(FacesContext context, Object state) {
if (state != null)
{
this.stateMap = new ConcurrentHashMap<String, Serializable>((Map<? extends String,? extends Serializable>) state);
return;
}
this.stateMap.clear();
}
@Override
public boolean isTransient() {
return this.isTransient;
}
@Override
public void setTransient(boolean newTransientValue) {
this.isTransient = newTransientValue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment