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

Gavin King gavin.king at jboss.com
Mon Sep 25 20:29:53 EDT 2006


  User: gavin   
  Date: 06/09/25 20:29:53

  Modified:    src/main/org/jboss/seam/interceptors    
                        AbstractInterceptor.java Interceptor.java
  Added:       src/main/org/jboss/seam/interceptors    
                        ManagedEntityIdentityInterceptor.java
  Removed:     src/main/org/jboss/seam/interceptors    
                        PassivationInterceptor.java
  Log:
  fix bugs in PC handling
  
  Revision  Changes    Path
  1.6       +4 -2      jboss-seam/src/main/org/jboss/seam/interceptors/AbstractInterceptor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: AbstractInterceptor.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/interceptors/AbstractInterceptor.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -b -r1.5 -r1.6
  --- AbstractInterceptor.java	3 Aug 2006 14:44:53 -0000	1.5
  +++ AbstractInterceptor.java	26 Sep 2006 00:29:53 -0000	1.6
  @@ -1,6 +1,8 @@
  -//$Id: AbstractInterceptor.java,v 1.5 2006/08/03 14:44:53 gavin Exp $
  +//$Id: AbstractInterceptor.java,v 1.6 2006/09/26 00:29:53 gavin Exp $
   package org.jboss.seam.interceptors;
   
  +import java.io.Serializable;
  +
   import javax.ejb.PostActivate;
   import javax.ejb.PrePassivate;
   import javax.interceptor.InvocationContext;
  @@ -12,7 +14,7 @@
    * 
    * @author Gavin King
    */
  -class AbstractInterceptor
  +class AbstractInterceptor implements Serializable
   {
      protected transient Component component;
      private String componentName;
  
  
  
  1.14      +2 -2      jboss-seam/src/main/org/jboss/seam/interceptors/Interceptor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Interceptor.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/interceptors/Interceptor.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -b -r1.13 -r1.14
  --- Interceptor.java	27 Jul 2006 19:07:08 -0000	1.13
  +++ Interceptor.java	26 Sep 2006 00:29:53 -0000	1.14
  @@ -1,4 +1,4 @@
  -//$Id: Interceptor.java,v 1.13 2006/07/27 19:07:08 gavin Exp $
  +//$Id: Interceptor.java,v 1.14 2006/09/26 00:29:53 gavin Exp $
   package org.jboss.seam.interceptors;
   
   import java.lang.annotation.Annotation;
  @@ -80,7 +80,7 @@
      {
         for (Method method : userInterceptor.getClass().getMethods())
         {
  -         method.setAccessible(true);
  +         if ( !method.isAccessible() ) method.setAccessible(true);
            if ( method.isAnnotationPresent(AroundInvoke.class) )
            {
               aroundInvokeMethod = method;
  
  
  
  1.1      date: 2006/09/26 00:29:53;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/interceptors/ManagedEntityIdentityInterceptor.java
  
  Index: ManagedEntityIdentityInterceptor.java
  ===================================================================
  package org.jboss.seam.interceptors;
  
  import java.io.Serializable;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Set;
  
  import javax.interceptor.AroundInvoke;
  import javax.interceptor.InvocationContext;
  import javax.persistence.EntityManager;
  import javax.persistence.Id;
  
  import org.hibernate.Session;
  import org.jboss.seam.Component;
  import org.jboss.seam.Seam;
  import org.jboss.seam.core.TouchedContexts;
  import org.jboss.seam.util.Reflections;
  
  /**
   * Swizzles entity references around each invocation, maintaining
   * referential even across passivation of the stateful bean or
   * Seam-managed extended persistence context, and allowing for
   * more efficient replication.
   * 
   * @author Gavin King
   *
   */
  public class ManagedEntityIdentityInterceptor extends AbstractInterceptor
  {
     
     //TODO: cache much more - the list of fields, PassivatedEntity obects, etc
     
     private List<PassivatedEntity> list = new ArrayList<PassivatedEntity>();
     
     static class PassivatedEntity implements Serializable
     {
        private Object id;
        private String persistenceContext;
        private String fieldName;
        private Class<?> entityClass;
        
        PassivatedEntity(Object id, Class<?> entityClass, String fieldName, String persistenceContext)
        {
           super();
           this.id = id;
           this.persistenceContext = persistenceContext;
           this.fieldName = fieldName;
           this.entityClass = entityClass;
        }
        String getPersistenceContext()
        {
           return persistenceContext;
        }
        Object getId()
        {
           return id;
        }
        String getFieldName()
        {
           return fieldName;
        }
        Class<?> getEntityClass()
        {
           return entityClass;
        }
     }
     
     @AroundInvoke
     public Object aroundInvoke(InvocationContext ctx) throws Exception
     {
        entityRefsToIds(ctx);
        Object result = ctx.proceed();
        entityIdsToRefs(ctx);
        return result;
     }
     
     public void entityRefsToIds(InvocationContext ctx) throws Exception
     {      
        Set<String> pcs = TouchedContexts.instance();
        if ( pcs.size()>0 )
        {
           Object bean = ctx.getTarget();
           Class beanClass = Seam.getBeanClass( bean.getClass() );
           for (; beanClass!=Object.class; beanClass=beanClass.getSuperclass())
           {
              Field[] fields = beanClass.getDeclaredFields();
              for (Field field: fields)
              {
                 if ( !Modifier.isTransient( field.getModifiers() ) && !Modifier.isStatic( field.getModifiers() ) )
                 {
                    if ( !field.isAccessible() ) field.setAccessible(true);
                    Object value = Reflections.get(field, bean);
                    if (value!=null)
                    {
                       Class entityClass = Seam.getEntityClass( value.getClass() );
                       if (entityClass!=null)
                       {
                          for (String persistenceContextName: pcs)
                          {
                             Object persistenceContext = Component.getInstance(persistenceContextName);
                             boolean managed = false;
                             if (persistenceContext instanceof EntityManager)
                             {
                                EntityManager em = (EntityManager) persistenceContext;
                                managed = em.contains(value);
                             }
                             else
                             {
                                Session session = (Session) persistenceContext;
                                managed = session.contains(value);
                             }
                             if (managed)
                             {
                                Object id = getId(value, entityClass);
                                list.add( new PassivatedEntity( id, entityClass, field.getName(), persistenceContextName ) );
                                Reflections.set(field, bean, null);
                                break;
                             }
                          }
                       }
                    }
                 }
              }
           }
        }
     }
     
     public void entityIdsToRefs(InvocationContext ctx) throws Exception
     {
        if ( list.size()>0 )
        {
           Object bean = ctx.getTarget();
           Class beanClass = Seam.getBeanClass( bean.getClass() );
           for (PassivatedEntity pe: list)
           {
              Object persistenceContext = Component.getInstance( pe.getPersistenceContext() );
              Object reference;
              if (persistenceContext instanceof EntityManager)
              {
                 EntityManager em = (EntityManager) persistenceContext;
                 reference = em.getReference( pe.getEntityClass(), pe.getId() );
              }
              else
              {
                 Session session = (Session) persistenceContext;
                 reference = session.load( pe.getEntityClass(), (Serializable) pe.getId() );
              }
              for (; beanClass!=Object.class; beanClass=beanClass.getSuperclass())
              {
                 try
                 {
                    Field field = beanClass.getDeclaredField( pe.getFieldName() );
                    field.set(bean, reference);
                    break;
                 }
                 catch (NoSuchFieldException nsfe) {}
              }
           }
           list.clear();
        }
     }
  
     private static Object getId(Object bean, Class beanClass) throws Exception
     {
        for (; beanClass!=Object.class; beanClass=beanClass.getSuperclass() )
        {
           for (Field field: beanClass.getFields()) //TODO: superclasses
           {
              if ( field.isAnnotationPresent(Id.class) )
              {
                 return Reflections.get(field, bean);
              }
           }
           for (Method method: beanClass.getMethods())
           {
              if ( method.isAnnotationPresent(Id.class) )
              {
                 return Reflections.invoke(method, bean);
              }
           }
        }
        throw new IllegalArgumentException("no id property found for entity class: " + beanClass.getName());
     }
     
  }
  
  
  



More information about the jboss-cvs-commits mailing list