Package org.jboss.cache.interceptors

Source Code of org.jboss.cache.interceptors.InvocationContextInterceptor

/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.cache.interceptors;

import org.jboss.cache.InvocationContext;
import org.jboss.cache.config.Option;
import org.jboss.cache.marshall.MethodCall;
import org.jboss.cache.marshall.MethodDeclarations;
import org.jboss.cache.transaction.GlobalTransaction;

import javax.transaction.SystemException;
import javax.transaction.Transaction;

/**
* Always place this interceptor at the start of the interceptor chain to ensure invocation contexts and set up and cleaned up correctly.
*
* @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
*/
public class InvocationContextInterceptor extends BaseTransactionalContextInterceptor implements InvocationContextInterceptorMBean
{
   public InvocationContextInterceptor()
   {
      initLogger();
   }

   @Override
   public Object invoke(InvocationContext ctx) throws Throwable
   {
      MethodCall call = ctx.getMethodCall();
      Option optionOverride = ctx.getOptionOverrides();
      boolean suppressExceptions = false;
      Transaction suspendedTransaction = null;
      boolean resumeSuspended = false;

      if (trace)
         log.trace("Invoked with InvocationContext [" + ctx + "]");

      if (MethodDeclarations.isBlockUnblockMethod(call.getMethodId())) return nextInterceptor(ctx);

      try
      {
         Transaction tx = getTransaction();
         setTransactionalContext(tx, getGlobalTransaction(tx, call), ctx);

         if (optionOverride != null)
         {

            if (optionOverride.isFailSilently())
            {
               log.debug("FAIL_SILENTLY Option is present - suspending any ongoing transaction.");
               suppressExceptions = true;
               if (ctx.getTransaction() != null)
               {
                  suspendedTransaction = txManager.suspend();
                  setTransactionalContext(null, null, ctx);
                  if (trace) log.trace("Suspending transaction " + suspendedTransaction);
                  resumeSuspended = true;
               }
               else
               {
                  if (trace) log.trace("No ongoing transaction to suspend");
               }
            }
         }

         Object retval;
         try
         {
            retval = nextInterceptor(ctx);
         }
         catch (Throwable th)
         {
            retval = th;
         }
         // assume we're the first interceptor in the chain.  Handle the exception-throwing.
         if (retval instanceof Throwable)
         {
            // if fail silently return a null
            if (suppressExceptions) return null;

            Throwable t = (Throwable) retval;
            if (t instanceof RuntimeException && t.getCause() != null)
               throw t.getCause();
            else
               throw t;
         }
         return retval;
      }
      finally
      {
         // clean up any invocation-scope options set up
         if (trace) log.trace("Resetting invocation-scope options");
         ctx.getOptionOverrides().reset();

         if (resumeSuspended)
         {
            txManager.resume(suspendedTransaction);
         }
         else
         {
            if (ctx.getTransaction() != null && (isValid(ctx.getTransaction())))// || isRollingBack(ctx.getTransaction())))
            {
               copyInvocationScopeOptionsToTxScope(ctx);
            }
         }

         // JBCACHE-811 - backed out for now
//         ctx.wipePeekedNodes();
      }
   }

   private GlobalTransaction getGlobalTransaction(Transaction tx, MethodCall call)
   {
      GlobalTransaction gtx = findGlobalTransaction(call.getArgs());
      if (gtx == null) gtx = cache.getCurrentTransaction(tx, false);
      if (gtx != null) gtx.setRemote(isRemoteGlobalTx(gtx));

      return gtx;
   }

   private Transaction getTransaction() throws SystemException
   {
      // this creates a context if one did not exist.
      if (txManager == null)
      {
         if (trace) log.trace("no transaction manager configured, setting tx as null.");
         return null;
      }
      else
      {
         return txManager.getTransaction();
      }
   }

   protected GlobalTransaction findGlobalTransaction(Object[] params)
   {
      int clue = 0;

      if (params[clue] instanceof GlobalTransaction)
         return (GlobalTransaction) params[clue];
      else
         for (Object param : params) if (param instanceof GlobalTransaction) return (GlobalTransaction) param;
      return null;
   }

   /**
    * Tests if a global transaction originated from a different cache in the cluster
    *
    * @param gtx
    * @return true if the gtx is remote, false if it originated locally.
    */
   private boolean isRemoteGlobalTx(GlobalTransaction gtx)
   {
      return gtx != null && (gtx.getAddress() != null) && (!gtx.getAddress().equals(cache.getLocalAddress()));
   }
}
TOP

Related Classes of org.jboss.cache.interceptors.InvocationContextInterceptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.