Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » invocation » [javadoc | source]
    1   /*
    2   * JBoss, Home of Professional Open Source
    3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
    4   * by the @authors tag. See the copyright.txt in the distribution for a
    5   * full listing of individual contributors.
    6   *
    7   * This is free software; you can redistribute it and/or modify it
    8   * under the terms of the GNU Lesser General Public License as
    9   * published by the Free Software Foundation; either version 2.1 of
   10   * the License, or (at your option) any later version.
   11   *
   12   * This software is distributed in the hope that it will be useful,
   13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   15   * Lesser General Public License for more details.
   16   *
   17   * You should have received a copy of the GNU Lesser General Public
   18   * License along with this software; if not, write to the Free
   19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   21   */
   22   package org.jboss.invocation;
   23   
   24   import java.io.Externalizable;
   25   import java.io.IOException;
   26   import java.io.ObjectInput;
   27   import java.io.ObjectOutput;
   28   import java.lang.reflect.UndeclaredThrowableException;
   29   
   30   import javax.transaction.Transaction;
   31   
   32   import org.jboss.invocation.Invocation;
   33   import org.jboss.invocation.Invoker;
   34   
   35   import org.jboss.proxy.Interceptor;
   36   
   37   import org.jboss.system.Registry;
   38   import org.jboss.util.id.GUID;
   39   
   40   /**
   41    * A very simple implementation of it that branches to the local stuff.
   42    * 
   43    * @author <a href="mailto:marc.fleury@jboss.org">Marc Fleury</a>
   44    * @author Scott.Stark@jboss.org
   45    * @version $Revision: 62554 $
   46    */
   47   public class InvokerInterceptor
   48      extends Interceptor
   49      implements Externalizable
   50   {
   51      /** Serial Version Identifier. @since 1.2 */
   52      private static final long serialVersionUID = 2548120545997920357L;
   53   
   54      /** The value of our local Invoker.ID to detect when we are local. */
   55      private GUID invokerID = Invoker.ID;
   56   
   57      /** Invoker to the remote JMX node. */
   58      protected Invoker remoteInvoker;
   59   
   60      /** Static references to local invokers. */
   61      protected static Invoker localInvoker; 
   62   
   63      /** The InvokerProxyHA class */
   64      protected static Class invokerProxyHA;
   65      
   66      static
   67      {
   68         try
   69         {
   70            // Using Class.forName() to avoid security problems in the client
   71            invokerProxyHA = Class.forName("org.jboss.invocation.InvokerProxyHA");
   72         }
   73         catch (Throwable ignored)
   74         {
   75         }
   76      }
   77      
   78      /**
   79       * Get the local invoker reference, useful for optimization.
   80       */
   81      public static Invoker getLocal()
   82      {
   83         return localInvoker;
   84      }
   85   
   86      /**
   87       * Set the local invoker reference, useful for optimization.
   88       */
   89      public static void setLocal(Invoker invoker)
   90      {
   91         localInvoker = invoker;
   92      }
   93   
   94      /**
   95       * Exposed for externalization.
   96       */
   97      public InvokerInterceptor()
   98      {
   99         super();
  100      }
  101   
  102      /**
  103       * Returns wether we are local to the originating container or not.
  104       * 
  105       * @return true when we have the same GUID 
  106       */
  107      public boolean isLocal()
  108      {
  109         return invokerID.equals(Invoker.ID);
  110      }
  111   
  112      /**
  113       * Whether the target is local
  114       * 
  115       * @param invocation the invocation
  116       * @return true when the target is local
  117       */
  118      public boolean isLocal(Invocation invocation)
  119      {
  120         // No local invoker, it must be remote
  121         if (localInvoker == null)
  122            return false;
  123   
  124         // The proxy was downloaded from a remote location
  125         if (isLocal() == false)
  126         {
  127            // It is not clustered so we go remote
  128            if (isClustered(invocation) == false)
  129               return false;
  130         }
  131         
  132         // See whether we have a local target
  133         return hasLocalTarget(invocation);
  134      }
  135      
  136      /**
  137       * Whether we are in a clustered environment<p>
  138       * 
  139       * NOTE: This should be future compatible under any
  140       * new design where a prior target chooser interceptor
  141       * picks a non HA target than that code being
  142       * inside a ha invoker.
  143       * 
  144       * @param invocation the invocation
  145       * @return true when a clustered invoker
  146       */
  147      public boolean isClustered(Invocation invocation)
  148      {
  149         // No clustering classes
  150         if (invokerProxyHA == null)
  151            return false;
  152         
  153         // Is the invoker a HA invoker?
  154         InvocationContext ctx = invocation.getInvocationContext();
  155         Invoker invoker = ctx.getInvoker();
  156         return invoker != null && invokerProxyHA.isAssignableFrom(invoker.getClass());
  157      }
  158      
  159      /**
  160       * Whether there is a local target
  161       * 
  162       * @param invocation
  163       * @return true when in the registry
  164       */
  165      public boolean hasLocalTarget(Invocation invocation)
  166      {
  167         return Registry.lookup(invocation.getObjectName()) != null;
  168      }
  169      
  170      /**
  171       * The invocation on the delegate, calls the right invoker.  
  172       * Remote if we are remote, local if we are local. 
  173       */
  174      public Object invoke(Invocation invocation)
  175         throws Exception
  176      {
  177         // optimize if calling another bean in same server VM
  178         if (isLocal(invocation))
  179            return invokeLocal(invocation);
  180         else
  181            return invokeInvoker(invocation);
  182      }
  183   
  184      /**
  185       * Invoke using local invoker
  186       * 
  187       * @param invocation the invocation
  188       * @return the result
  189       * @throws Exception for any error
  190       */
  191      protected Object invokeLocal(Invocation invocation) throws Exception
  192      {
  193         return localInvoker.invoke(invocation);
  194      }
  195   
  196      /**
  197       * Invoke using local invoker and marshalled
  198       * 
  199       * @param invocation the invocation
  200       * @return the result
  201       * @throws Exception for any error
  202       */
  203      protected Object invokeMarshalled(Invocation invocation) throws Exception
  204      {
  205         MarshalledInvocation mi = new MarshalledInvocation(invocation);
  206         MarshalledValue copy = new MarshalledValue(mi);
  207         Invocation invocationCopy = (Invocation) copy.get();
  208   
  209         // copy the Tx
  210         Transaction tx = invocation.getTransaction();
  211         invocationCopy.setTransaction(tx);
  212   
  213         try
  214         {
  215            Object rtnValue = localInvoker.invoke(invocationCopy);
  216            MarshalledValue mv = new MarshalledValue(rtnValue);
  217            return mv.get();
  218         }
  219         catch(Throwable t)
  220         {
  221            MarshalledValue mv = new MarshalledValue(t);
  222            Throwable t2 = (Throwable) mv.get();
  223            if( t2 instanceof Exception )
  224               throw (Exception) t2;
  225            else
  226               throw new UndeclaredThrowableException(t2);
  227         }
  228      }
  229   
  230      /**
  231       * Invoke using invoker
  232       * 
  233       * @param invocation the invocation
  234       * @return the result
  235       * @throws Exception for any error
  236       */
  237      protected Object invokeInvoker(Invocation invocation) throws Exception
  238      {
  239         //Specify that it is inter-vm on the invocation
  240         invocation.setInterVM(Boolean.TRUE);
  241         
  242         InvocationContext ctx = invocation.getInvocationContext();
  243         Invoker invoker = ctx.getInvoker();
  244         return invoker.invoke(invocation);
  245      }
  246      
  247      /**
  248       * Externalize this instance.
  249       *
  250       * <p>
  251       * If this instance lives in a different VM than its container
  252       * invoker, the remote interface of the container invoker is
  253       * not externalized.
  254       */
  255      public void writeExternal(final ObjectOutput out)
  256         throws IOException
  257      {
  258         out.writeObject(invokerID);
  259      }
  260   
  261      /**
  262       * Un-externalize this instance.
  263       *
  264       * <p>
  265       * We check timestamps of the interfaces to see if the instance is in the original
  266       * VM of creation
  267       */
  268      public void readExternal(final ObjectInput in)
  269         throws IOException, ClassNotFoundException
  270      {
  271         invokerID = (GUID)in.readObject();
  272      }
  273   }

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » invocation » [javadoc | source]