[jboss-cvs] jboss-seam/src/main/org/jboss/seam/interceptors ...
Gavin King
gavin.king at jboss.com
Sat Jun 16 05:08:57 EDT 2007
User: gavin
Date: 07/06/16 05:08:57
Modified: src/main/org/jboss/seam/interceptors
ManagedEntityIdentityInterceptor.java
Log:
JBSEAM-943
Revision Changes Path
1.22 +256 -12 jboss-seam/src/main/org/jboss/seam/interceptors/ManagedEntityIdentityInterceptor.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: ManagedEntityIdentityInterceptor.java
===================================================================
RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/interceptors/ManagedEntityIdentityInterceptor.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -b -r1.21 -r1.22
--- ManagedEntityIdentityInterceptor.java 13 Jun 2007 15:21:07 -0000 1.21
+++ ManagedEntityIdentityInterceptor.java 16 Jun 2007 09:08:57 -0000 1.22
@@ -1,8 +1,17 @@
package org.jboss.seam.interceptors;
+
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.model.DataModel;
+
import org.jboss.seam.annotations.AroundInvoke;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Interceptor;
@@ -10,6 +19,7 @@
import org.jboss.seam.core.PersistenceContexts;
import org.jboss.seam.intercept.InvocationContext;
import org.jboss.seam.util.Reflections;
+
/**
* Swizzles entity references around each invocation, maintaining
* referential integrity even across passivation of the stateful
@@ -27,6 +37,10 @@
//TODO: cache much more - the list of fields, PassivatedEntity obects, etc
//TODO: optimize serialization of this list
private List<PassivatedEntity> passivatedEntities = new ArrayList<PassivatedEntity>();
+ //TODO: keep the actual concrete class of the collection around, so that we can recreate it after nullifying
+ private Map<String, List<PassivatedEntity>> passivatedEntityLists = new HashMap<String, List<PassivatedEntity>>();
+ private Map<String, List<PassivatedEntity>> passivatedEntitySets = new HashMap<String, List<PassivatedEntity>>();
+ private Map<String, Map<Object, PassivatedEntity>> passivatedEntityMaps = new HashMap<String, Map<Object, PassivatedEntity>>();
@AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception
@@ -66,36 +80,266 @@
Object value = Reflections.get(field, bean);
if (value!=null)
{
- PassivatedEntity pi = PassivatedEntity.createPassivatedEntity( value, field.getName() );
- if (pi!=null)
+ DataModel dataModel = null;
+ if (value instanceof DataModel)
{
- passivatedEntities.add(pi);
- Reflections.set(field, bean, null);
+ dataModel = (DataModel) value;
+ value = dataModel.getWrappedData();
+ if ( !(value instanceof List) && !(value instanceof Map) )
+ {
+ //we can't handle DataModels that wrap a single entity directly!
+ continue;
+ }
+ }
+ entityRefsToIds(bean, field, value, dataModel);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void entityRefsToIds(Object bean, Field field, Object value, DataModel dataModel) throws Exception
+ {
+ if (value instanceof List)
+ {
+ List values = (List) value;
+ entityListToIdList(bean, field, values, dataModel);
+ }
+ else if (value instanceof Set)
+ {
+ Set values = (Set) value;
+ entitySetToIdSet(bean, field, values, dataModel);
+ }
+ else if (value instanceof Map)
+ {
+ Map values = (Map) value;
+ entityMapToIdMap(bean, field, values, dataModel);
+ }
+ else
+ {
+ entityRefToId(bean, field, value);
+ }
+ }
+
+ private void entityListToIdList(Object bean, Field field, List values, DataModel dataModel) throws Exception
+ {
+ int count = 0;
+ List<PassivatedEntity> list = new ArrayList<PassivatedEntity>();
+ for ( int i=0; i<values.size(); i++ )
+ {
+ PassivatedEntity pi = PassivatedEntity.createPassivatedEntity( values.get(i), field.getName() );
+ if (pi==null)
+ {
+ list.add(null);
+ }
+ else
+ {
+ list.add(pi);
+ //values.set(i, null);
+ count++;
+ }
+ }
+ if (count>0)
+ {
+ passivatedEntityLists.put( field.getName(), list );
+ if ( count==values.size() )
+ {
+ nullify(bean, field, dataModel);
+ }
+ }
+ }
+
+ private void entityMapToIdMap(Object bean, Field field, Map values, DataModel dataModel) throws Exception
+ {
+ int count = 0;
+ Map<Object, PassivatedEntity> map = new HashMap<Object, PassivatedEntity>();
+ for ( Map.Entry me: (Set<Map.Entry>) values.entrySet() )
+ {
+ PassivatedEntity pe = PassivatedEntity.createPassivatedEntity( me.getValue(), field.getName() );
+ if (pe!=null)
+ {
+ map.put( me.getKey(), pe );
+ //values.remove( me.getKey() );
+ count++;
+ }
+ }
+ if (count>0)
+ {
+ passivatedEntityMaps.put( field.getName(), map );
+ if ( count==values.size() )
+ {
+ nullify(bean, field, dataModel);
+ }
}
}
+
+ private void entitySetToIdSet(Object bean, Field field, Set values, DataModel dataModel) throws Exception
+ {
+ int count = 0;
+ List<PassivatedEntity> list = new ArrayList<PassivatedEntity>();
+ Iterator iter = values.iterator();
+ while ( iter.hasNext() )
+ {
+ PassivatedEntity pe = PassivatedEntity.createPassivatedEntity( iter.next(), field.getName() );
+ if (pe!=null)
+ {
+ list.add(pe);
+ //iter.remove();
+ count++;
}
}
+ if (count>0)
+ {
+ passivatedEntitySets.put( field.getName(), list );
+ if ( count==values.size() )
+ {
+ nullify(bean, field, dataModel);
}
}
}
+
+ private void entityRefToId(Object bean, Field field, Object value) throws Exception
+ {
+ PassivatedEntity pe = PassivatedEntity.createPassivatedEntity( value, field.getName() );
+ if (pe!=null)
+ {
+ passivatedEntities.add(pe);
+ Reflections.set(field, bean, null);
+ }
+ }
+
+ private void nullify(Object bean, Field field, DataModel dataModel) throws Exception
+ {
+ if (dataModel==null)
+ {
+ Reflections.set(field, bean, null);
+ }
+ /*else
+ {
+ //TODO: put back in, once we figure
+ // out how to reconstruct it
+ dataModel.setWrappedData(null);
+ }*/
+ }
+
public void entityIdsToRefs(InvocationContext ctx) throws Exception
{
- if ( passivatedEntities.size()>0 )
+ if ( passivatedEntities.size()>0 || passivatedEntityLists.size()>0 )
{
Object bean = ctx.getTarget();
Class beanClass = bean.getClass();
+
for (PassivatedEntity pe: passivatedEntities)
{
+ entityIdToRef(bean, beanClass, pe);
+ }
+ passivatedEntities.clear();
+
+ for ( Map.Entry<String, List<PassivatedEntity>> entry: passivatedEntityLists.entrySet() )
+ {
+ entityIdListToList(bean, beanClass, entry);
+ }
+ passivatedEntityLists.clear();
+
+ for ( Map.Entry<String, List<PassivatedEntity>> entry: passivatedEntitySets.entrySet() )
+ {
+ entityIdSetToSet(bean, beanClass, entry);
+ }
+ passivatedEntitySets.clear();
+
+ for ( Map.Entry<String, Map<Object, PassivatedEntity>> entry: passivatedEntityMaps.entrySet() )
+ {
+ entityIdMapToMap(bean, beanClass, entry);
+ }
+ passivatedEntityMaps.clear();
+ }
+ }
+
+ private void entityIdListToList(Object bean, Class beanClass, Map.Entry<String, List<PassivatedEntity>> entry) throws Exception
+ {
+ Field field = getField( beanClass, entry.getKey() );
+ List<PassivatedEntity> list = entry.getValue();
+ List values = (List) getFieldValues(bean, field);
+ if (values==null)
+ {
+ values = new ArrayList( list.size() );
+ //TODO: reconstruct a DataModel
+ Reflections.set(field, bean, values);
+ }
+ for ( int i=0; i<list.size(); i++ )
+ {
+ PassivatedEntity pe = list.get(i);
+ if ( pe!=null )
+ {
+ values.set( i, pe.toEntityReference() );
+ }
+ }
+ }
+
+ private void entityIdSetToSet(Object bean, Class beanClass, Map.Entry<String, List<PassivatedEntity>> entry) throws Exception
+ {
+ Field field = getField( beanClass, entry.getKey() );
+ List<PassivatedEntity> list = entry.getValue();
+ Set values = (Set) getFieldValues(bean, field);
+ if (values==null)
+ {
+ values = new HashSet( list.size() );
+ //TODO: reconstruct a DataModel
+ Reflections.set(field, bean, values);
+ }
+ for ( PassivatedEntity pe: list )
+ {
Object reference = pe.toEntityReference();
if (reference!=null)
{
- Field field = Reflections.getField( beanClass, pe.getFieldName() );
- if ( !field.isAccessible() ) field.setAccessible(true);
- field.set(bean, reference);
+ values.add(reference);
}
}
- passivatedEntities.clear();
}
+
+ private void entityIdMapToMap(Object bean, Class beanClass, Map.Entry<String, Map<Object, PassivatedEntity>> entry) throws Exception
+ {
+ Field field = getField( beanClass, entry.getKey() );
+ Map<Object, PassivatedEntity> map = entry.getValue();
+ Map values = (Map) getFieldValues(bean, field);
+ if (values==null)
+ {
+ values = new HashMap( map.size() );
+ //TODO: reconstruct a DataModel
+ Reflections.set(field, bean, values);
+ }
+ for ( Map.Entry<Object, PassivatedEntity> me: map.entrySet() )
+ {
+ Object reference = me.getValue().toEntityReference();
+ if (reference!=null)
+ {
+ values.put( me.getKey(), reference );
+ }
+ }
+ }
+
+ private void entityIdToRef(Object bean, Class beanClass, PassivatedEntity pe) throws IllegalAccessException
+ {
+ Object reference = pe.toEntityReference();
+ if (reference!=null)
+ {
+ getField( beanClass, pe.getFieldName() ).set(bean, reference);
+ }
+ }
+
+ private Field getField(Class beanClass, String fieldName)
+ {
+ Field field = Reflections.getField(beanClass, fieldName);
+ if ( !field.isAccessible() ) field.setAccessible(true);
+ return field;
+ }
+
+ private Object getFieldValues(Object bean, Field field) throws IllegalAccessException
+ {
+ Object value = field.get(bean);
+ return value!=null && value instanceof DataModel ?
+ ( (DataModel) value ).getWrappedData() : value;
}
}
More information about the jboss-cvs-commits
mailing list