Save This Page
Home » jboss-5.0.0.CR1-src » org.jboss.invocation.jrmp » server » [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.jrmp.server;
   23   
   24   import java.util.ArrayList;
   25   import java.util.Iterator;
   26   import java.util.Map;
   27   import java.util.HashMap;
   28   import java.lang.reflect.Method;
   29   import javax.management.ObjectName;
   30   import javax.naming.InitialContext;
   31   
   32   import org.jboss.invocation.InvokerInterceptor;
   33   import org.jboss.invocation.Invocation;
   34   import org.jboss.invocation.MarshalledInvocation;
   35   import org.jboss.naming.Util;
   36   import org.jboss.proxy.ClientMethodInterceptor;
   37   import org.jboss.proxy.GenericProxyFactory;
   38   import org.jboss.system.Registry;
   39   import org.jboss.system.ServiceMBeanSupport;
   40   import org.jboss.metadata.MetaData;
   41   import org.w3c.dom.Element;
   42   
   43   /** Create an interface proxy that uses RMI/JRMP to communicate with the server
   44    * side object that exposes the corresponding JMX invoke operation. Requests
   45    * make through the proxy are sent to the JRMPInvoker instance the proxy
   46    * is bound to. 
   47    *
   48    * @author Scott.Stark@jboss.org
   49    * @version $Revision: 37459 $
   50    */
   51   public class JRMPProxyFactory extends ServiceMBeanSupport
   52      implements JRMPProxyFactoryMBean
   53   {
   54      /** The server side JRMPInvoker mbean that will handle RMI/JRMP transport */
   55      private ObjectName invokerName;
   56      /** The server side mbean that exposes the invoke operation for the
   57       exported interface */
   58      private ObjectName targetName;
   59      /** The Proxy object which uses the proxy as its handler */
   60      protected Object theProxy;
   61      /** The JNDI name under which the proxy will be bound */
   62      private String jndiName;
   63      /** The interface that the proxy implements */
   64      private Class[] exportedInterfaces;
   65      /** The optional definition */
   66      private Element interceptorConfig;
   67      /** The interceptor Classes defined in the interceptorConfig */
   68      private ArrayList interceptorClasses = new ArrayList();
   69      /** invoke target method */
   70      private boolean invokeTargetMethod;
   71      /** methods by their hash code */
   72      private final Map methodMap = new HashMap();
   73      /** signatures by method */
   74      private final Map signatureMap = new HashMap();
   75   
   76      public JRMPProxyFactory()
   77      {
   78         interceptorClasses.add(ClientMethodInterceptor.class);
   79         interceptorClasses.add(InvokerInterceptor.class);
   80      }
   81   
   82      public ObjectName getInvokerName()
   83      {
   84         return invokerName;
   85      }
   86      public void setInvokerName(ObjectName invokerName)
   87      {
   88         this.invokerName = invokerName;
   89      }
   90   
   91      public ObjectName getTargetName()
   92      {
   93         return targetName;
   94      }
   95      public void setTargetName(ObjectName targetName)
   96      {
   97         this.targetName = targetName;
   98      }
   99   
  100      public String getJndiName()
  101      {
  102         return jndiName;
  103      }
  104      public void setJndiName(String jndiName)
  105      {
  106         this.jndiName = jndiName;
  107      }
  108   
  109      public Class getExportedInterface()
  110      {
  111         return exportedInterfaces[0];
  112      }
  113      public void setExportedInterface(Class exportedInterface)
  114      {
  115         this.exportedInterfaces = new Class[] {exportedInterface};
  116      }
  117   
  118      public Class[] getExportedInterfaces()
  119      {
  120         return exportedInterfaces;
  121      }
  122      public void setExportedInterfaces(Class[] exportedInterfaces)
  123      {
  124         this.exportedInterfaces = exportedInterfaces;
  125      }
  126   
  127      public boolean getInvokeTargetMethod()
  128      {
  129         return invokeTargetMethod;
  130      }
  131   
  132      public void setInvokeTargetMethod(boolean invokeTargetMethod)
  133      {
  134         this.invokeTargetMethod = invokeTargetMethod;
  135      }
  136   
  137      public Element getClientInterceptors()
  138      {
  139         return interceptorConfig;
  140      }
  141      public void setClientInterceptors(Element config) throws Exception
  142      {
  143         this.interceptorConfig = config;
  144         Iterator interceptorElements = MetaData.getChildrenByTagName(interceptorConfig, "interceptor");
  145         ClassLoader loader = Thread.currentThread().getContextClassLoader();
  146         interceptorClasses.clear();
  147         while( interceptorElements != null && interceptorElements.hasNext() )
  148         {
  149            Element ielement = (Element) interceptorElements.next();
  150            String className = null;
  151            className = MetaData.getElementContent(ielement);
  152            Class clazz = loader.loadClass(className);
  153            interceptorClasses.add(clazz);
  154            log.debug("added interceptor type: "+clazz);
  155         }
  156      }
  157   
  158      public Object getProxy()
  159      {
  160         return theProxy;
  161      }
  162   
  163      public Object invoke(Invocation mi) throws Exception
  164      {
  165         final boolean remoteInvocation = mi instanceof MarshalledInvocation;
  166         if(remoteInvocation)
  167         {
  168            ((MarshalledInvocation)mi).setMethodMap(methodMap);
  169         }
  170   
  171         final Object result;
  172         if(invokeTargetMethod)
  173         {
  174            String signature[] = (String[])signatureMap.get(mi.getMethod());
  175            result = server.invoke(targetName, mi.getMethod().getName(), mi.getArguments(), signature);
  176         }
  177         else
  178         {
  179            result = server.invoke(targetName, "invoke", new Object[]{mi}, Invocation.INVOKE_SIGNATURE);
  180         }
  181   
  182         return result;
  183      }
  184   
  185      /** Initializes the servlet.
  186       */
  187      protected void startService() throws Exception
  188      {
  189         /* Create a binding between the invoker name hash and the jmx name
  190         This is used by the JRMPInvoker to map from the Invocation ObjectName
  191         hash value to the target JMX ObjectName.
  192         */
  193         Integer nameHash = new Integer(getServiceName().hashCode());
  194         Registry.bind(nameHash, getServiceName());
  195   
  196         // Create the service proxy
  197         Object cacheID = null;
  198         String proxyBindingName = null;
  199         Class[] ifaces = exportedInterfaces;
  200         ClassLoader loader = Thread.currentThread().getContextClassLoader();
  201         createProxy(cacheID, proxyBindingName, loader, ifaces);
  202         log.debug("Created JRMPPRoxy for service="+targetName
  203            +", nameHash="+nameHash+", invoker="+invokerName);
  204   
  205         if( jndiName != null )
  206         {
  207            InitialContext iniCtx = new InitialContext();
  208            Util.bind(iniCtx, jndiName, theProxy);
  209            log.debug("Bound proxy under jndiName="+jndiName);
  210         }
  211   
  212         for(int i = 0; i < exportedInterfaces.length; ++i)
  213         {
  214            final Method[] methods = exportedInterfaces[i].getMethods();
  215            for(int j = 0; j < methods.length; ++j)
  216            {
  217               methodMap.put(new Long(MarshalledInvocation.calculateHash(methods[j])), methods[j]);
  218   
  219               String signature[];
  220               final Class[] types = methods[j].getParameterTypes();
  221               if(types == null || types.length == 0)
  222               {
  223                  signature = null;
  224               }
  225               else
  226               {
  227                  signature = new String[types.length];
  228                  for(int typeInd = 0; typeInd < types.length; ++typeInd)
  229                  {
  230                     signature[typeInd] = types[typeInd].getName();
  231                  }
  232               }
  233               signatureMap.put(methods[j], signature);
  234            }
  235         }
  236      }
  237   
  238      protected void stopService() throws Exception
  239      {
  240         Integer nameHash = new Integer(getServiceName().hashCode());
  241         Registry.unbind(nameHash);
  242         if( jndiName != null )
  243         {
  244            InitialContext iniCtx = new InitialContext();
  245            Util.unbind(iniCtx, jndiName);
  246         }
  247         this.theProxy = null;
  248      }
  249   
  250      protected void destroyService() throws Exception
  251      {
  252         interceptorClasses.clear();
  253      }
  254   
  255      protected void createProxy
  256      (
  257         Object cacheID, 
  258         String proxyBindingName,
  259         ClassLoader loader,
  260         Class[] ifaces
  261      )
  262      {
  263         GenericProxyFactory proxyFactory = new GenericProxyFactory();
  264         theProxy = proxyFactory.createProxy(cacheID, getServiceName(), invokerName,
  265            jndiName, proxyBindingName, interceptorClasses, loader, ifaces);
  266      }
  267   
  268      protected void rebind() throws Exception
  269      {
  270         log.debug("(re-)Binding " + jndiName);
  271         Util.rebind(new InitialContext(), jndiName, theProxy);
  272      }
  273   
  274      protected ArrayList getInterceptorClasses()
  275      {
  276         return interceptorClasses;
  277      }
  278   }

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