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

Gavin King gavin.king at jboss.com
Sat Sep 23 11:41:39 EDT 2006


  User: gavin   
  Date: 06/09/23 11:41:39

  Modified:    src/main/org/jboss/seam/interceptors  
                        JavaBeanInterceptor.java
  Added:       src/main/org/jboss/seam/interceptors  
                        PassivationInterceptor.java
  Log:
  support @PrePassivate, @PostActivate, @PostConstruct for JavaBean components
  fix bug in replication of Seam-managed PC used by SFSB
  more efficient replication of extended Seam-managed PCs
  
  Revision  Changes    Path
  1.9       +112 -10   jboss-seam/src/main/org/jboss/seam/interceptors/JavaBeanInterceptor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: JavaBeanInterceptor.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/interceptors/JavaBeanInterceptor.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -b -r1.8 -r1.9
  --- JavaBeanInterceptor.java	8 Sep 2006 00:12:17 -0000	1.8
  +++ JavaBeanInterceptor.java	23 Sep 2006 15:41:39 -0000	1.9
  @@ -1,4 +1,4 @@
  -//$Id: JavaBeanInterceptor.java,v 1.8 2006/09/08 00:12:17 gavin Exp $
  +//$Id: JavaBeanInterceptor.java,v 1.9 2006/09/23 15:41:39 gavin Exp $
   package org.jboss.seam.interceptors;
   
   import java.io.Serializable;
  @@ -25,31 +25,133 @@
      
      private final SeamInterceptor seamInterceptor;
      private boolean recursive = false;
  +   private final Component component;
      
      public JavaBeanInterceptor(Component component)
      {
         seamInterceptor = new SeamInterceptor(InterceptorType.ANY, component);
  +      this.component = component;
      }
   
      public Object intercept(final Object target, final Method method, final Object[] params,
            final MethodProxy methodProxy) throws Throwable
      {
  -      if ( recursive || "finalize".equals( method.getName() ) ) 
  +      if (recursive) 
         {
            return methodProxy.invokeSuper(target, params);
         }
  -      else
  -      {
  +      
            recursive = true;
            try
            {
  +         String methodName = method.getName();
  +         if ( "finalize".equals(methodName) ) 
  +         {
  +            return methodProxy.invokeSuper(target, params);
  +         }
  +         else if ( "sessionDidActivate".equals(methodName) )
  +         {
  +            callPostActivate(target);
  +            return null;
  +         }
  +         else if ( "sessionWillPassivate".equals(methodName) )
  +         {
  +            callPrePassivate(target);
  +            return null;
  +         }
  +         else
  +         {
               return interceptInvocation(target, method, params, methodProxy);
            }
  +      }
            finally
            {
               recursive = false;
            }
         }
  +
  +   private void callPrePassivate(final Object target)
  +   {
  +      seamInterceptor.prePassivate( new InvocationContext() {
  +         
  +         final Object[] params = {};
  +         final Method passivateMethod = component.getPrePassivateMethod();
  +         final Map contextData = new HashMap();
  +         
  +         public Object getTarget()
  +         {
  +            return target;
  +         }
  +         
  +         public Map getContextData()
  +         {
  +            return contextData;
  +         }
  +
  +         public Method getMethod()
  +         {
  +            return passivateMethod;
  +         }
  +
  +         public Object[] getParameters()
  +         {
  +            return params;
  +         }
  +
  +         public Object proceed() throws Exception
  +         {
  +            component.callPrePassivateMethod(target);
  +            return null;
  +         }
  +
  +         public void setParameters(Object[] newParams)
  +         {
  +            throw new IllegalArgumentException();
  +         }
  +         
  +      } );
  +   }
  +
  +   private void callPostActivate( final Object target)
  +   {
  +      seamInterceptor.postActivate( new InvocationContext() {
  +         
  +         final Object[] params = {};
  +         final Method activateMethod = component.getPostActivateMethod();
  +         final Map contextData = new HashMap();
  +         
  +         public Object getTarget()
  +         {
  +            return target;
  +         }
  +         
  +         public Map getContextData()
  +         {
  +            return contextData;
  +         }
  +
  +         public Method getMethod()
  +         {
  +            return activateMethod;
  +         }
  +
  +         public Object[] getParameters()
  +         {
  +            return params;
  +         }
  +
  +         public Object proceed() throws Exception
  +         {
  +            component.callPostActivateMethod(target);
  +            return null;
  +         }
  +
  +         public void setParameters(Object[] newParams)
  +         {
  +            throw new IllegalArgumentException();
  +         }
  +         
  +      } );
      }
   
      private Object interceptInvocation(final Object target, final Method method, final Object[] params, 
  @@ -77,7 +179,7 @@
   
            public Object[] getParameters()
            {
  -            return params;
  +            return resultParams;
            }
   
            public Object proceed() throws Exception
  @@ -106,7 +208,7 @@
               resultParams = newParams;
            }
            
  -      });
  +      } );
      }
   
   }
  
  
  
  1.1      date: 2006/09/23 15:41:39;  author: gavin;  state: Exp;jboss-seam/src/main/org/jboss/seam/interceptors/PassivationInterceptor.java
  
  Index: PassivationInterceptor.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.ejb.PostActivate;
  import javax.ejb.PrePassivate;
  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;
  
  public class PassivationInterceptor extends AbstractInterceptor
  {
     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;
        }
     }
     
     @PrePassivate
     public void passivate(InvocationContext ctx) throws Exception
     {      
        proceed(ctx);
  
        Set<String> pcs = TouchedContexts.instance();
        if ( pcs.size()>0 )
        {
           Object bean = ctx.getTarget();
           Class beanClass = Seam.getBeanClass( bean.getClass() );
           Field[] fields = beanClass.getFields(); //TODO: what about inherited fields!
           for (Field field: fields)
           {
              if ( !Modifier.isTransient( field.getModifiers() ) && !Modifier.isStatic( field.getModifiers() ) )
              {
                 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;
                          }
                       }
                    }
                 }
              }
           }
        }
     }
     
     @PostActivate
     public void activate(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() );
              }
              beanClass.getField( pe.getFieldName() ).set( bean, reference );
           }
           list.clear();
        }
        
        proceed(ctx);
     }
  
     private static Object getId(Object bean, Class beanClass) throws Exception
     {
        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());
     }
  
     private static void proceed(InvocationContext ctx)
     {
        try
        {
           ctx.proceed();
        }
        catch (RuntimeException e)
        {
           throw e;
        }
        catch (Exception e)
        {
           throw new RuntimeException("exception in EJB lifecycle callback", e);
        }
     }
     
  }
  
  
  



More information about the jboss-cvs-commits mailing list