[jboss-cvs] jboss-seam/src/main/org/jboss/seam/persistence ...

Gavin King gavin.king at jboss.com
Mon Jun 25 19:59:31 EDT 2007


  User: gavin   
  Date: 07/06/25 19:59:31

  Added:       src/main/org/jboss/seam/persistence 
                        ManagedEntityIdentityInterceptor.java
  Log:
  move builtin interceptors to the packages they relate to
  
  Revision  Changes    Path
  1.1      date: 2007/06/25 23:59:31;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/persistence/ManagedEntityIdentityInterceptor.java
  
  Index: ManagedEntityIdentityInterceptor.java
  ===================================================================
  package org.jboss.seam.persistence;
  
  import static org.jboss.seam.util.JSF.DATA_MODEL;
  import static org.jboss.seam.util.JSF.getWrappedData;
  import static org.jboss.seam.util.JSF.setWrappedData;
  
  import java.lang.reflect.Field;
  import java.lang.reflect.Modifier;
  import java.util.List;
  
  import org.jboss.seam.Seam;
  import org.jboss.seam.annotations.In;
  import org.jboss.seam.annotations.intercept.AroundInvoke;
  import org.jboss.seam.annotations.intercept.Interceptor;
  import org.jboss.seam.contexts.Contexts;
  import org.jboss.seam.core.BijectionInterceptor;
  import org.jboss.seam.intercept.AbstractInterceptor;
  import org.jboss.seam.intercept.InvocationContext;
  import org.jboss.seam.transaction.Transaction;
  import org.jboss.seam.util.Reflections;
  
  /**
   * Swizzles entity references around each invocation, maintaining
   * referential integrity even across passivation of the stateful 
   * bean or Seam-managed extended persistence context, and allowing 
   * for more efficient replication.
   * 
   * @author Gavin King
   *
   */
  @Interceptor(around=BijectionInterceptor.class, stateless=true)
  public class ManagedEntityIdentityInterceptor extends AbstractInterceptor
  {
   
     //TODO: cache the non-ignored fields, probably on Component
     
     @AroundInvoke
     public Object aroundInvoke(InvocationContext ctx) throws Exception
     {
        entityIdsToRefs(ctx);
        try
        {
           return ctx.proceed();
        }
        finally
        {
           if ( !isTransactionRolledBackOrMarkedRollback() )
           {
              entityRefsToIds(ctx);
           }
        }
     }
     
     private static boolean isTransactionRolledBackOrMarkedRollback()
     {
        try
        {
           return Transaction.instance().isRolledBackOrMarkedRollback();
        }
        catch (Exception e)
        {
           return false;
        }
     }
     
     public void entityRefsToIds(InvocationContext ctx) throws Exception
     {
        if ( touchedContextsExist() )
        {
           Object bean = ctx.getTarget();
           Class beanClass = bean.getClass();
           for (; beanClass!=Object.class; beanClass=beanClass.getSuperclass())
           {
              for ( Field field: beanClass.getDeclaredFields() )
              {
                 if ( !ignore(field) )
                 {
                    Object value = getFieldValue(bean, field);
                    if (value!=null)
                    {
                       Object dataModel = null;
                       if ( DATA_MODEL.isInstance(value) )
                       {
                          dataModel = value;
                          value = getWrappedData(dataModel);
                       }
                       if ( isRef(value) )
                       {
                          saveWrapper(bean, field, dataModel, value);
                       }
                    }
                 }
              }
           }
        }
     }
  
     public void entityIdsToRefs(InvocationContext ctx) throws Exception
     {      
        if ( touchedContextsExist() )
        {
           Object bean = ctx.getTarget();
           Class beanClass = bean.getClass();
           for (; beanClass!=Object.class; beanClass=beanClass.getSuperclass())
           {
              for ( Field field: beanClass.getDeclaredFields() )
              {
                 if ( !ignore(field) )
                 {
                    Object value = getFieldValue(bean, field);
                    Object dataModel = null;
                    if (value!=null && DATA_MODEL.isInstance(value) )
                    {
                       dataModel = value;
                    }
                    //TODO: be more selective
                    getFromWrapper(bean, field, dataModel);
                 }
              }
           }
        }
     }
  
     private boolean isRef(Object value)
     {
        //TODO: can do better than this for lists!
        return value instanceof List || Seam.isEntityClass( value.getClass() );
     }
  
     private Object getFieldValue(Object bean, Field field) throws Exception
     {
        if ( !field.isAccessible() ) field.setAccessible(true);
        Object value = Reflections.get(field, bean);
        return value;
     }
  
     private boolean ignore(Field field)
     {
        return Modifier.isTransient( field.getModifiers() ) || 
              Modifier.isStatic( field.getModifiers() )
              || field.isAnnotationPresent(In.class);
     }
  
     private boolean touchedContextsExist()
     {
        PersistenceContexts touchedContexts = PersistenceContexts.instance();
        return touchedContexts!=null && touchedContexts.getTouchedContexts().size()>0;
     }
  
     private String getFieldId(Field field)
     {
        return getComponent().getName() + '.' + field.getName();
     }
  
     private void saveWrapper(Object bean, Field field, Object dataModel, Object value) throws Exception
     {
        Contexts.getConversationContext().set( getFieldId(field), value );
        if (dataModel==null)
        {
           Reflections.set(field, bean, null);
        }
        else
        {
           setWrappedData(dataModel, null);
        }
     }
  
     private void getFromWrapper(Object bean, Field field, Object dataModel) throws Exception
     {
        Object value = Contexts.getConversationContext().get( getFieldId(field) );
        if (value!=null)
        {
           if (dataModel==null)
           {
              Reflections.set(field, bean, value);
           }
           else
           {
              setWrappedData(dataModel, value);
           }
        }
     }
  
  }
  
  
  



More information about the jboss-cvs-commits mailing list