Package org.jboss.tm.usertx.server

Source Code of org.jboss.tm.usertx.server.ClientUserTransactionService

/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.tm.usertx.server;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;

import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.Context;

import org.jboss.system.Registry;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.tm.usertx.client.ClientUserTransaction;
import org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory;
import org.jboss.tm.usertx.interfaces.UserTransactionSession;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.MarshalledInvocation;

/**
*  This is a JMX service handling the serverside of UserTransaction
*  usage for standalone clients.
*
* @author <a href="mailto:osh@sparre.dk">Ole Husgaard</a>
* @author Scott.Stark@jboss.org
* @author <a href="mailto:galder.zamarreno@jboss.com">Galder Zamarreno</a>
* @version $Revision: 81030 $
*/
public class ClientUserTransactionService
      extends ServiceMBeanSupport
      implements ClientUserTransactionServiceMBean
{
   // Constants -----------------------------------------------------
   /** The location where the javax.transaction.UserTransaction is bound on the server */
   public static String JNDI_NAME = "UserTransaction";

   // Attributes ----------------------------------------------------
   /** The UserTransactionSession and UserTransactionSessionFactory method hashes */
   private Map marshalledInvocationMapping = new HashMap();
   /** The proxy factory service used for the UserTransactionSession */
   private ObjectName txProxyName;
   /** The stateless proxy used for all UserTransactionSessions */
   private Object txProxy;

   /** Set the name of the proxy factory service used for the
    * UserTransactionSession
    * @param proxyName
    */
   public void setTxProxyName(ObjectName proxyName)
   {
      this.txProxyName = proxyName;     
   }

   /** Expose UserTransactionSession and UserTransactionSessionFactory
    * interfaces via JMX to invokers.
    *
    * @jmx:managed-operation
    *
    * @param invocation    A pointer to the invocation object
    * @return              Return value of method invocation.
    *
    * @throws Exception    Failed to invoke method.
    */
   public Object invoke(Invocation invocation) throws Exception
   {
      // Set the method hash to Method mapping
      if (invocation instanceof MarshalledInvocation)
      {
         MarshalledInvocation mi = (MarshalledInvocation) invocation;
         mi.setMethodMap(marshalledInvocationMapping);
      }
      // Invoke the method via reflection
      Method method = invocation.getMethod();
      Object[] args = invocation.getArguments();
      Object value = null;
      try
      {
         if( UserTransactionSessionFactory.class.isAssignableFrom(method.getDeclaringClass()) )
         {
            // Just return the UserTransactionSession proxy as its stateless
            value = txProxy;
         }
         else if( method.getName().equals("begin") )
         {
            // Begin a new transaction
            Integer timeout = (Integer) args[0];
            UserTransactionSession session = UserTransactionSessionImpl.getInstance();
            value = session.begin(timeout.intValue());
         }
         else if( method.getName().equals("destroy"))
         {
            /* We do nothing as the tx will timeout and the tx map is shared
            across all sessions as we have no association with the txs
            a given client has started.
            */
         }
         else
         {
            UserTransactionSession session = UserTransactionSessionImpl.getInstance();
            value = method.invoke(session, args);
         }
      }
      catch(InvocationTargetException e)
      {
         Throwable t = e.getTargetException();
         if( t instanceof Exception )
            throw (Exception) t;
         else
            throw new UndeclaredThrowableException(t, method.toString());
      }

      return value;
   }

   // ServiceMBeanSupport overrides ---------------------------------
  
   protected void startService()
         throws Exception
   {
      Context ctx = new InitialContext();
      // Bind the in VM UserTransaction interface
      ctx.bind(JNDI_NAME, ClientUserTransaction.getSingleton());

      // Get the UserTransactionSession proxy
      txProxy = getServer().getAttribute(txProxyName, "Proxy");

      // Build the UserTransactionSession interface method map
      HashMap tmpMap = new HashMap(13);
      Method[] methods = UserTransactionSession.class.getMethods();
      for(int m = 0; m < methods.length; m ++)
      {
         Method method = methods[m];
         Long hash = new Long(MarshalledInvocation.calculateHash(method));
         tmpMap.put(hash, method);
      }
      // Add the UserTransactionSessionFactory interface method map
      methods = UserTransactionSessionFactory.class.getMethods();
      for(int m = 0; m < methods.length; m ++)
      {
         Method method = methods[m];
         Long hash = new Long(MarshalledInvocation.calculateHash(method));
         tmpMap.put(hash, method);
      }
      marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
     
      // Place our ObjectName hash into the Registry so invokers can resolve it.
      // We need this for the HA Proxy case where the only the target service
      // is added to the registry, which is how it should be.
      // In the non HA Proxy case, JRMPProxyFactory acts both as a proxy factory
      // and proxy which is conceptually wrong, hence this is an extra step in
      // that case.
      Registry.bind(new Integer(serviceName.hashCode()), serviceName);
   }

   protected void stopService()
   {
      try
      {
         Context ctx = new InitialContext();
         ctx.unbind(JNDI_NAME);
      }
      catch (Exception e)
      {
         log.warn("Failed to unbind "+JNDI_NAME, e);
      }
     
      // Remove our ObjectName hash from Registry if the proxy factory had not 
      Registry.unbind(new Integer(serviceName.hashCode()));
   }

}
TOP

Related Classes of org.jboss.tm.usertx.server.ClientUserTransactionService

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.