[jboss-cvs] JBossCache/src/org/jboss/cache/pojo/interceptors ...

Ben Wang bwang at jboss.com
Sat Jan 13 10:55:07 EST 2007


  User: bwang   
  Date: 07/01/13 10:55:07

  Added:       src/org/jboss/cache/pojo/interceptors            
                        PojoTxLockInterceptor.java
                        CheckNonSerializableInterceptor.java
                        AbstractInterceptor.java PojoTxUndoInterceptor.java
                        PojoFailedTxMockupInterceptor.java
                        MethodReentrancyStopperInterceptor.java
                        StaticFieldInterceptor.java
                        PojoTxUndoSynchronizationInterceptor.java
                        PojoEventInterceptor.java PojoBeginInterceptor.java
                        CheckIdInterceptor.java PojoTxInterceptor.java
  Log:
  JBCACHE-922 Merged src-50 and tests-50 into src and tests, respectively.
  
  Revision  Changes    Path
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/PojoTxLockInterceptor.java
  
  Index: PojoTxLockInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.pojo.PojoCacheException;
  import org.jboss.cache.pojo.PojoTreeCache;
  import org.jboss.cache.pojo.InternalConstant;
  import org.jboss.cache.lock.UpgradeException;
  import org.jboss.cache.CacheException;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.CacheSPI;
  
  /** Interceptor that handles the parent node lock associated with transaction.
   *
   * @author Ben Wang
   * @version $Id: PojoTxLockInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class PojoTxLockInterceptor extends AbstractInterceptor
  {
     private final String LOCK = "_lock_";
     // retry times for lockPojo just in case there is upgrade exception during concurrent access.
     private final int RETRY = 5;
  
     public Object invoke(Invocation in) throws Throwable
     {
        MethodInvocation invocation = (MethodInvocation)in;
        try {
           handleLock(invocation);
           return invocation.invokeNext(); // proceed to next advice or actual call
        } finally {
  //         handleUnLock(invocation);
        }
     }
  
     private void handleLock(MethodInvocation invocation) throws Throwable
     {
        Fqn id = (Fqn)invocation.getArguments()[0];
        CacheSPI cache = getCache(invocation);
  //      Object owner = cache.getLockOwner();
        Object owner = null;
        if (!lockPojo(owner, id, cache))
        {
           throw new PojoCacheException("PojoCache.removeObject(): Can't obtain the pojo lock under id: " + id);
        }
     }
  
     private boolean lockPojo(Object owner, Fqn id, CacheSPI cache) throws CacheException
     {
        if (log.isDebugEnabled())
        {
           log.debug("lockPojo(): id:" + id + " Owner: " + owner);
        }
  
        boolean isNeeded = true;
        int retry = 0;
        // If this is an internal id and also it has three levels, we are saying this is
        // Collection, and we need to lock the parent as well.
        // TODO Still a bit ad hoc.
        Fqn realId = id;
        if(id.isChildOrEquals(InternalConstant.JBOSS_INTERNAL) && id.size() > 2)
        {
           realId = id.getParent();
           if (log.isDebugEnabled())
           {
              log.debug("lockPojo(): will lock parent id instead:" + realId);
           }
        }
  
        while (isNeeded)
        {
           try
           {
              cache.put(realId, LOCK, "LOCK");
              isNeeded = false;
           } catch (UpgradeException upe)
           {
              log.warn("lockPojo(): can't upgrade the lock during lockPojo. Will re-try. id: " + realId
                      + " retry times: " + retry);
  // TODO is this really ok to comment out??
  //            cache.get(realId).release(owner);
              if (retry++ > RETRY)
              {
                 return false;
              }
              // try to sleep a little as well.
              try
              {
                 Thread.sleep(10);
              } catch (InterruptedException e)
              {
                 ;
              }
           }
        }
  
        return true;
     }
  
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/CheckNonSerializableInterceptor.java
  
  Index: CheckNonSerializableInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.pojo.util.AopUtil;
  import org.jboss.cache.Fqn;
  
  /** Interceptor (done via aop advice) to check the validity of the id specified by the user.
   * @version $Id: CheckNonSerializableInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class CheckNonSerializableInterceptor extends AbstractInterceptor
  {
     private boolean marshallNonSerializable_ = false;
  
     public Object invoke(Invocation in) throws Throwable
     {
        if(!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException("CheckIdInterceptor.invoke(): invocation not MethodInvocation");
        }
  
        MethodInvocation invocation = (MethodInvocation)in;
        Fqn id = (Fqn) invocation.getArguments()[0];
        Object obj = invocation.getArguments()[1];
        if (!marshallNonSerializable_)
        {
           AopUtil.checkObjectType(obj);
        } else
        {
           log.debug("invoke(): marshallNonSerializable is set to true. We will skip object type checking for id:"
           + id.toString());
        }
  
        try {
           return invocation.invokeNext(); // proceed to next advice or actual call
        } finally {
        }
     }
  
     public void setMarshallNonSerializable(boolean isTrue)
     {
        marshallNonSerializable_ = isTrue;
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/AbstractInterceptor.java
  
  Index: AbstractInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.advice.Interceptor;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.pojo.PojoTreeCache;
  import org.jboss.cache.pojo.impl.PojoCacheImpl;
  import org.jboss.cache.CacheSPI;
  import org.jboss.cache.InvocationContext;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /** Base interceptor class for PojoCache interceptor stack.
   *
   * @author Ben Wang
   * @version $Id: AbstractInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public abstract class AbstractInterceptor implements Interceptor
  {
     protected final Log log = LogFactory.getLog(AbstractInterceptor.this.getClass());
  
     protected InvocationContext getInvocationContext(MethodInvocation in)
     {
        return ((PojoCacheImpl)in.getTargetObject()).getUnderlyingCache().getInvocationContext();
     }
  
     protected CacheSPI getCache(MethodInvocation in)
     {
        return ((PojoCacheImpl)in.getTargetObject()).getUnderlyingCache();      
     }
  
     public String getName()
     {
        return this.getClass().getName();
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/PojoTxUndoInterceptor.java
  
  Index: PojoTxUndoInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.cache.pojo.MethodDeclarations;
  import org.jboss.cache.pojo.PojoTxSynchronizationHandler;
  import org.jboss.cache.pojo.PojoCacheException;
  import org.jboss.cache.pojo.util.MethodCall;
  import org.jboss.cache.Fqn;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import java.lang.reflect.Method;
  import java.lang.reflect.Field;
  import java.util.List;
  
  /**
   * Interceptor (done via aop advice) for transaction rollback. This is is attached to the
   * operation that needs a corresponding rollback, e.g., attachInterceptor.
   *
   * @author Ben Wang
   * @version $Id: PojoTxUndoInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class PojoTxUndoInterceptor extends AbstractInterceptor
  {
     /// Just that AOP requires an extra key.
     public static final String TAG = "PojoCache";
  
     public Object invoke(Invocation in) throws Throwable
     {
        if (!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException("TxUndoInterceptor.invoke(): invocation not MethodInvocation");
        }
        MethodInvocation invocation = (MethodInvocation) in;
  
        PojoTxSynchronizationHandler handler =
                PojoTxUndoSynchronizationInterceptor.getSynchronizationHandler();
  
        if(handler == null)
        {
           return invocation.invokeNext();
  // TODO handler is null can mean we are not calling the right interceptor stack. Need to revisit.
  // E.g., a fresh getObject or find will trigger this.
  //         throw new IllegalStateException("PojoTxUndoInterceptor.invoke(): PojoTxSynchronizationHandler is null");
        }
  
        // Add to the rollback list
        String methodName = invocation.getMethod().getName();
        // TODO Needs to handle Collection interceptor as well.
        if( methodName.equals(MethodDeclarations.attachInterceptor.getName()))
        {
           Method method = MethodDeclarations.undoAttachInterceptor;
           MethodCall mc = new MethodCall(method, invocation.getArguments(), invocation.getTargetObject());
           handler.addToList(mc);
        } else if ( methodName.equals(MethodDeclarations.detachInterceptor.getName()))
        {
           Method method = MethodDeclarations.undoDetachInterceptor;
           MethodCall mc = new MethodCall(method, invocation.getArguments(), invocation.getTargetObject());
           handler.addToList(mc);
        } else if ( methodName.equals(MethodDeclarations.inMemorySubstitution.getName()))
        {
           Method method = MethodDeclarations.undoInMemorySubstitution;
           Object obj = invocation.getArguments()[0];
           Field field = (Field)invocation.getArguments()[1];
           Object oldValue = field.get(obj);
           Object[] args = new Object[] { obj, field, oldValue };
           MethodCall mc = new MethodCall(method, args, invocation.getTargetObject());
           handler.addToList(mc);
        } else if ( methodName.equals(MethodDeclarations.incrementReferenceCount.getName()))
        {
           Method method = MethodDeclarations.undoIncrementReferenceCount;
           Fqn fqn = (Fqn)invocation.getArguments()[0];
           int count = (Integer)invocation.getArguments()[1];
           List referenceList = (List)invocation.getArguments()[2];
           Object[] args = new Object[] { fqn, count, referenceList };
           MethodCall mc = new MethodCall(method, args, invocation.getTargetObject());
           handler.addToList(mc);
        } else if ( methodName.equals(MethodDeclarations.decrementReferenceCount.getName()))
        {
           Method method = MethodDeclarations.undoDecrementReferenceCount;
           Fqn fqn = (Fqn)invocation.getArguments()[0];
           int count = (Integer)invocation.getArguments()[1];
           List referenceList = (List)invocation.getArguments()[2];
           Object[] args = new Object[] { fqn, count, referenceList };
           MethodCall mc = new MethodCall(method, args, invocation.getTargetObject());
           handler.addToList(mc);
        } else
        {
           throw new PojoCacheException("PojoTxUndoInterceptor: invalid invocation name: " +methodName);
        }
  
        return invocation.invokeNext();
     }
  
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/PojoFailedTxMockupInterceptor.java
  
  Index: PojoFailedTxMockupInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.InternalConstant;
  
  import javax.transaction.Transaction;
  
  /**
   * Interceptor to mockup tx failure that resulting in rollback. User can simulate a rollback
   * by setting the static method <code>setRollback</code>. Note that you will need to use
   * setRollback for every method call, that is, it will reset itself after a rollback
   * has been performed.
   *
   * @author Ben Wang
   * @version $Id: PojoFailedTxMockupInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class PojoFailedTxMockupInterceptor extends AbstractInterceptor
  {
     public static boolean TX_ROLLBACK = false;
  
     public static void setTxRollback(boolean isTrue)
     {
        TX_ROLLBACK = isTrue;
     }
  
     public Object invoke(Invocation in) throws Throwable
     {
        if (!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException(
                   "PojoFailedTxMockupInterceptor.invoke(): invocation not MethodInvocation");
        }
        MethodInvocation invocation = (MethodInvocation) in;
        try
        {
           Object obj = null;
           obj = invocation.invokeNext(); // proceed to next advice or actual call
           if(TX_ROLLBACK)
           {
              Transaction tx = (Transaction)
                      invocation.getMetaData().getMetaData(PojoTxInterceptor.TAG, PojoTxInterceptor.TX);
  
              Fqn id = (Fqn) invocation.getArguments()[0];
  
              if(!id.isChildOrEquals(InternalConstant.JBOSS_INTERNAL))
              {
                 tx.setRollbackOnly();
                 TX_ROLLBACK = false;
              }
           }
           return obj;
        } finally
        {
        }
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/MethodReentrancyStopperInterceptor.java
  
  Index: MethodReentrancyStopperInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.advice.Interceptor;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.pojo.PojoCacheException;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import java.lang.reflect.Method;
  
  /**
   *
   * @author Ben Wang
   */
  
  public class MethodReentrancyStopperInterceptor implements Interceptor
  {
     private final Log log_ = LogFactory.getLog(MethodReentrancyStopperInterceptor.class);
     private ThreadLocal<Boolean> done;
     private String methodName;
  
     public MethodReentrancyStopperInterceptor()
     {
        done = new ThreadLocal<Boolean>();
        done.set(false);
     }
  
     public void setMethodName(String mname)
     {
        methodName = mname;
     }
  
     public String getName()
     {
        return MethodReentrancyStopperInterceptor.class.getName() + "-" +methodName;
     }
  
     public Object invoke(Invocation invocation) throws Throwable
     {
        boolean wasDone = done.get();
  
        try
        {
           if (!wasDone)
           {
              done.set(true);
              return invocation.invokeNext();
           } else
           {
              //Needs adding, and will invoke target joinpoint skipping the rest of the chain
              if(log_.isDebugEnabled())
              {
                 Method method = ((MethodInvocation)invocation).getMethod();
                 log_.debug("Detect recursive interception. Will call the target directly: " +method.getName());
              }
  
              if(methodName.equals("toString"))
              {
                 return invocation.getTargetObject().getClass().getName();
              } else
              if(methodName.equals("hashCode"))
              {
                 return 0;
              } else
              {
                 throw new PojoCacheException("MethodReentrancyStopperInterceptor.invoke(): unknown method name"
                         +methodName);
              }
           }
        }
        finally
        {
           if (!wasDone)
           {
              done.set(false);
           }
        }
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/StaticFieldInterceptor.java
  
  Index: StaticFieldInterceptor.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.pojo.interceptors;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jboss.aop.Advisor;
  import org.jboss.aop.advice.Interceptor;
  import org.jboss.aop.joinpoint.FieldInvocation;
  import org.jboss.aop.joinpoint.FieldReadInvocation;
  import org.jboss.aop.joinpoint.FieldWriteInvocation;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.CacheSPI;
  import org.jboss.cache.pojo.CachedType;
  import org.jboss.cache.pojo.PojoCacheFactory;
  import org.jboss.cache.pojo.InternalConstant;
  import org.jboss.cache.pojo.PojoCacheException;
  import org.jboss.cache.pojo.impl.PojoCacheImpl;
  
  import java.lang.reflect.Field;
  
  /**
   * interceptor to intercept for static field replication.
   *
   * @author Ben Wang
   */
  
  public class StaticFieldInterceptor implements Interceptor
  {
     private final Log log_ = LogFactory.getLog(StaticFieldInterceptor.class);
     private CacheSPI cache_;
     private PojoCacheImpl pCache_;
     private Fqn fqn_;
     private String name_;
     private String key_;
  
     public StaticFieldInterceptor()
     {
     }
  
     public String getName()
     {
        if (name_ == null)
        {
           this.name_ = "StaticFieldInterceptor on [" + fqn_ + "]";
        }
        return name_;
     }
  
     public Object invoke(Invocation invocation) throws Throwable
     {
        /*
        // Kind of ad hoc now. MethodInvocation should not invoke this.
        if(invocation instanceof MethodInvocation)
           return invocation.invokeNext();
  
        needInit(((FieldInvocation)invocation).getField());
        if (invocation instanceof FieldWriteInvocation)
        {
           FieldInvocation fieldInvocation =
                   (FieldInvocation) invocation;
  
           Advisor advisor = fieldInvocation.getAdvisor();
           Field field = fieldInvocation.getField();
           if(log_.isTraceEnabled())
           {
              log_.trace("invoke(): field write interception for fqn: " +fqn_ + " and field: " +field);
           }
  
           // Only if this field is replicatable. static, transient and final are not.
           Object value = ((FieldWriteInvocation) fieldInvocation).getValue();
  
           cache_.put(fqn_, key_, value);
           Object obj = fieldInvocation.getTargetObject();
        } else if (invocation instanceof FieldReadInvocation)
        {
           FieldInvocation fieldInvocation =
                   (FieldInvocation) invocation;
           Field field = fieldInvocation.getField();
           Advisor advisor = fieldInvocation.getAdvisor();
           return cache_.get(fqn_, key_);
        }
        */
        return invocation.invokeNext();
  
     }
  
     private void needInit(Field field)
     {
        if(pCache_ == null)
        {
           String cn = field.getDeclaringClass().getName();
           fqn_ = Fqn.fromString(InternalConstant.JBOSS_INTERNAL_STATIC + "/" + cn);
           key_ = field.getName();
        }
     }
  
     boolean isChildOf(Fqn parentFqn)
     {
        return fqn_.isChildOf(parentFqn);
     }
  
     public Fqn getFqn()
     {
        return fqn_;
     }
  
     public void setFqn(Fqn fqn)
     {
        this.fqn_ = fqn;
     }
  
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/PojoTxUndoSynchronizationInterceptor.java
  
  Index: PojoTxUndoSynchronizationInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.pojo.PojoTxSynchronizationHandler;
  import org.jboss.cache.pojo.PojoCacheException;
  
  import javax.transaction.Transaction;
  import javax.transaction.RollbackException;
  import javax.transaction.SystemException;
  
  /** Interceptor that handles registration of tx synchronization for rollback
   * operations.
   *
   * @author Ben Wang
   * @version $Id: PojoTxUndoSynchronizationInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class PojoTxUndoSynchronizationInterceptor extends AbstractInterceptor
  {
     // We stores the handler in thread local since the afterCompletion won't be
     // called untill tx.commit(). Note that this is static since it can be
     // recursive call to attach/detach.
     private static ThreadLocal synchronizationHandler_ = new ThreadLocal();
  
     public Object invoke(Invocation in) throws Throwable
     {
        if(!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException("TxSyncrhonizationInterceptor.invoke(): invocation not MethodInvocation");
        }
        MethodInvocation invocation = (MethodInvocation)in;
        try {
           registerTxHandler(invocation);
           return invocation.invokeNext(); // proceed to next advice or actual call
        } finally {
        }
     }
  
     private void registerTxHandler(MethodInvocation invocation) throws PojoCacheException
     {
        try
        {
           // Need to have this in case of rollback
           PojoTxSynchronizationHandler handler = (PojoTxSynchronizationHandler) synchronizationHandler_.get();
           if (handler == null)
           {
              // First entry point for this transaction scope.
              Transaction tx = (Transaction)invocation.getMetaData(PojoTxInterceptor.TAG, PojoTxInterceptor.TX);
              if (tx == null)
              {
                 throw new IllegalStateException("PojoCache.registerTxHanlder(). Can't have null tx handle.");
              }
  
              handler = new PojoTxSynchronizationHandler();
  
              log.debug("Registering PojoTxSynchronizationHandler for rollback if ncessary " +handler);
              // Register so we can rollback if necessary
              tx.registerSynchronization(handler);
  
              synchronizationHandler_.set(handler);
           }
        } catch (RollbackException e)
        {
           throw new PojoCacheException("PojoTxUndoSynchronizationInterceptor.registerTxHandler(): Exception: " + e);
        } catch (SystemException e)
        {
           throw new PojoCacheException("PojoTxUndoSynchronizationInterceptor.registerTxHandler(): Exception: " + e);
        }
     }
  
     public static PojoTxSynchronizationHandler getSynchronizationHandler()
     {
        return (PojoTxSynchronizationHandler)synchronizationHandler_.get();
     }
  
     public static void reset()
     {
        synchronizationHandler_.set(null);
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/PojoEventInterceptor.java
  
  Index: PojoEventInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.advice.Interceptor;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  
  /** Handles the POJO event notification.
   *
   * @author Ben Wang
   * @version $Id: PojoEventInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class PojoEventInterceptor extends AbstractInterceptor
  {
     public Object invoke(Invocation in) throws Throwable
     {
        if(!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException("PojoEventInterceptor.invoke(): invocation not MethodInvocation");
        }
        MethodInvocation invocation = (MethodInvocation)in;
        try {
           System.out.println("**** Entering method: **** " + invocation.getMethod());
           return invocation.invokeNext(); // proceed to next advice or actual call
        } finally {
           System.out.println("Leaving method: " + invocation.getMethod());
        }
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/PojoBeginInterceptor.java
  
  Index: PojoBeginInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.advice.Interceptor;
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.aop.metadata.SimpleMetaData;
  
  /** The first interceptor that deals initialization.
   *
   * @author Ben Wang
   * @version $Id: PojoBeginInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class PojoBeginInterceptor extends AbstractInterceptor
  {
     private static ThreadLocal REPLICATE_FINAL = new ThreadLocal() ;
  
     public void setReplicateFinalField(String isTrue)
     {
        REPLICATE_FINAL.set(Boolean.valueOf(isTrue));   
     }
  
     private static void reset()
     {
        REPLICATE_FINAL.set(Boolean.FALSE);
     }
  
     public static boolean getReplicateFinalField()
     {
        if(REPLICATE_FINAL.get() == null) return false;
  
        return (Boolean)REPLICATE_FINAL.get();
     }
  
     public Object invoke(Invocation in) throws Throwable
     {
        if(!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException("BeginInterceptor.invoke(): invocation not MethodInvocation");
        }
        MethodInvocation invocation = (MethodInvocation)in;
        // Let's initialize the metadata
        SimpleMetaData simple = new SimpleMetaData();
        invocation.setMetaData(simple);
  
        try {
           log.debug("**** Entering method: **** " + invocation.getMethod());
           return invocation.invokeNext(); // proceed to next advice or actual call
        } finally {
  //         reset(); // reset
           log.debug("Leaving method: " + invocation.getMethod());
        }
     }
  }
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/CheckIdInterceptor.java
  
  Index: CheckIdInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.pojo.InternalConstant;
  import org.jboss.cache.pojo.util.AopUtil;
  
  /** Interceptor (done via aop advice) to check the validity of the id specified by the user.
   * @version $Id: CheckIdInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class CheckIdInterceptor extends AbstractInterceptor
  {
     public Object invoke(Invocation in) throws Throwable
     {
        if(!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException("CheckIdInterceptor.invoke(): invocation not MethodInvocation");
        }
  
        MethodInvocation invocation = (MethodInvocation)in;
        invocation.getAdvisor();
        try {
           checkFqnValidity((Fqn)invocation.getArguments()[0]);
           return invocation.invokeNext(); // proceed to next advice or actual call
        } finally {
        }
     }
  
  
     private static void checkFqnValidity(Fqn id)
     {
        // throws exception is fqn is JBossInternal
  //      if (id.hasElement(InternalConstant.JBOSS_INTERNAL_STRING))
  //      {
  //         throw new IllegalArgumentException("CheckIdIntercepto.checkFqnValidity(): fqn is not valid: " + id);
  //      }
     }
  }
  
  
  
  
  1.1      date: 2007/01/13 15:55:06;  author: bwang;  state: Exp;JBossCache/src/org/jboss/cache/pojo/interceptors/PojoTxInterceptor.java
  
  Index: PojoTxInterceptor.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.cache.pojo.interceptors;
  
  import org.jboss.aop.joinpoint.Invocation;
  import org.jboss.aop.joinpoint.MethodInvocation;
  import org.jboss.cache.pojo.PojoCacheException;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.transaction.BatchModeTransactionManager;
  
  import javax.transaction.RollbackException;
  import javax.transaction.Status;
  import javax.transaction.Transaction;
  import javax.transaction.TransactionManager;
  
  /**
   * Interceptor (done via aop advice) for transaction
   *
   * @author Ben Wang
   * @version $Id: PojoTxInterceptor.java,v 1.1 2007/01/13 15:55:06 bwang Exp $
   */
  public class PojoTxInterceptor extends AbstractInterceptor
  {
     private TransactionManager localTm_ = null;
     private TransactionManager txManager_;
     public static final String TAG = "PC";
     public static final String TX = "TX";
  
  
     public Object invoke(Invocation in) throws Throwable
     {
        if (!(in instanceof MethodInvocation))
        {
           throw new IllegalArgumentException("TxInterceptor.invoke(): invocation not MethodInvocation");
        }
        MethodInvocation invocation = (MethodInvocation) in;
  
        if(txManager_ == null)
        {
           txManager_ = getCache(invocation).getTransactionManager();
        }
  
        Transaction tx = null;
        if(txManager_ != null)
        {
           // Use the configured one if so setup.
           localTm_ = txManager_;
        } else
        {
           localTm_ = BatchModeTransactionManager.getInstance();
        }
  
        tx = localTm_.getTransaction();
  
        boolean needTx = false;
        if (tx == null) needTx = true;
        Fqn id = null;
        try
        {
           if (needTx)
           {
              id = (Fqn) invocation.getArguments()[0];
              log.debug("Initiating a local transaction for batch processing with id: " +id.toString());
              // Start one of our own as batch processing.
              try
              {
                 localTm_.begin();
                 tx = localTm_.getTransaction();
                 // Stuff tx context into the metadata
                 invocation.getMetaData().addMetaData(TAG, TX, tx);
                 return invocation.invokeNext(); // proceed to next advice or actual call
              }
              catch (Exception e)
              {
                 log.warn(invocation.getMethod().getName() + ": exception occurred: " + e);
                 try
                 {
                    localTm_.setRollbackOnly();
                 }
                 catch (Exception exn)
                 {
                    exn.printStackTrace();
                 }
  
                 throw new PojoCacheException("PojoCache operation will be rollback. id: " + id
                         + ". Operation: " +invocation.getMethod().getName(), e);
              }
           } else
           {
              invocation.getMetaData().addMetaData(TAG, TX, tx);
              return invocation.invokeNext(); // proceed to next advice or actual call
           }
        } finally
        {
           if (needTx)
           {
              endTransaction(id);
           }
        }
     }
  
     private void endTransaction(Fqn id)
     {
        if (localTm_ == null)
        {
           log.warn("endTransaction(): tm is null for id: " + id);
           return;
        }
  
  
        try
        {
           if (localTm_.getTransaction().getStatus() != Status.STATUS_MARKED_ROLLBACK)
           {
              localTm_.commit();
           } else if (localTm_.getTransaction().getStatus() == Status.STATUS_ROLLEDBACK)
           {
              log.info("endTransaction(): has been rolled back for id: " + id);
           } else
           {
              log.info("endTransaction(): rolling back tx for id: " + id);
              localTm_.rollback();
           }
        }
        catch (RollbackException re)
        {
           // Do nothing here since cache may rollback automatically.
           log.warn("endTransaction(): rolling back transaction with exception: " + re);
        }
        catch (Exception e)
        {
           log.warn("endTransaction(): Failed with exception: " + e);
        }
     }
  }
  
  
  



More information about the jboss-cvs-commits mailing list