Package org.jboss.webservices.integration.invocation

Source Code of org.jboss.webservices.integration.invocation.InvocationHandlerEJB21

/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, 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.webservices.integration.invocation;

import java.lang.reflect.Method;
import java.security.Principal;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.ws.WebServiceException;

import org.jboss.ejb.EjbModule;
import org.jboss.ejb.Interceptor;
import org.jboss.ejb.StatelessSessionContainer;
import org.jboss.invocation.InvocationKey;
import org.jboss.invocation.InvocationType;
import org.jboss.invocation.PayloadKey;
import org.jboss.mx.util.MBeanServerLocator;
import org.jboss.wsf.common.ObjectNameFactory;
import org.jboss.wsf.common.integration.WSHelper;
import org.jboss.wsf.common.invocation.AbstractInvocationHandler;
import org.jboss.wsf.spi.SPIProvider;
import org.jboss.wsf.spi.SPIProviderResolver;
import org.jboss.wsf.spi.deployment.Deployment;
import org.jboss.wsf.spi.deployment.Endpoint;
import org.jboss.wsf.spi.invocation.HandlerCallback;
import org.jboss.wsf.spi.invocation.Invocation;
import org.jboss.wsf.spi.invocation.SecurityAdaptor;
import org.jboss.wsf.spi.invocation.SecurityAdaptorFactory;
import org.jboss.wsf.spi.metadata.j2ee.EJBArchiveMetaData;
import org.jboss.wsf.spi.metadata.j2ee.EJBMetaData;

/**
* Handles invocations on EJB21 endpoints.
*
* @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
* @author <a href="mailto:tdiesler@redhat.com">Thomas Diesler</a>
*/
final class InvocationHandlerEJB21 extends AbstractInvocationHandler
{
   /** EJB21 JNDI name. */
   private String jndiName;

   /** MBean server. */
   private MBeanServer server;

   /** Object name. */
   private ObjectName ejb21ContainerName;

   /**
    * Consctructor.
    */
   InvocationHandlerEJB21()
   {
      this.server = MBeanServerLocator.locateJBoss();
   }

   /**
    * Initializes EJB 21 endpoint.
    *
    * @param endpoint web service endpoint
    */
   public void init(final Endpoint endpoint)
   {
      final String ejbName = endpoint.getShortName();
      final Deployment dep = endpoint.getService().getDeployment();
      final EJBArchiveMetaData ejbArchiveMD = WSHelper.getRequiredAttachment(dep, EJBArchiveMetaData.class);
      final EJBMetaData ejbMD = (EJBMetaData) ejbArchiveMD.getBeanByEjbName(ejbName);

      if (ejbMD == null)
      {
         throw new WebServiceException("Cannot obtain ejb meta data for: " + ejbName);
      }

      // get the bean's JNDI name
      this.jndiName = ejbMD.getContainerObjectNameJndiName();

      if (this.jndiName == null)
      {
         throw new WebServiceException("Cannot obtain JNDI name for: " + ejbName);
      }
   }

   /**
    * Gets EJB 21 container name lazily.
    *
    * @param endpoint webservice endpoint
    * @return EJB21 container name
    */
   private synchronized ObjectName getEjb21ContainerName(final Endpoint endpoint)
   {
      final boolean ejb21ContainerNotInitialized = this.ejb21ContainerName == null;

      if (ejb21ContainerNotInitialized)
      {
         this.ejb21ContainerName = ObjectNameFactory.create("jboss.j2ee:jndiName=" + this.jndiName + ",service=EJB");
         final boolean ejb21NotRegistered = !this.server.isRegistered(this.ejb21ContainerName);
         if (ejb21NotRegistered)
         {
            throw new IllegalArgumentException("Cannot find service endpoint target: " + this.ejb21ContainerName);
         }

         // Inject the Service endpoint interceptor
         this.insertEJB21ServiceEndpointInterceptor(this.ejb21ContainerName, endpoint.getShortName());
      }

      return this.ejb21ContainerName;
   }

   /**
    * Invokes EJB 21 endpoint.
    *
    * @param endpoint EJB 21 endpoint
    * @param wsInvocation web service invocation
    * @throws Exception if any error occurs
    */
   public void invoke(final Endpoint endpoint, final Invocation wsInvocation) throws Exception
   {
      final ObjectName ejb21Name = this.getEjb21ContainerName(endpoint);

      try
      {
         // prepare for invocation
         final org.jboss.invocation.Invocation jbossInvocation = this.getMBeanInvocation(wsInvocation);
         final String[] signature =
         {org.jboss.invocation.Invocation.class.getName()};
         final Object[] args = new Object[]
         {jbossInvocation};

         // invoke method
         final Object retObj = this.server.invoke(ejb21Name, "invoke", args, signature);
         wsInvocation.setReturnValue(retObj);
      }
      catch (Exception e)
      {
         this.log.error("Method invocation failed with exception: " + e.getMessage(), e);
         this.handleInvocationException(e);
      }
   }

   /**
    * Returns configured EJB 21 JBoss MBean invocation.
    *
    * @param wsInvocation webservice invocation
    * @return configured JBoss invocation
    */
   private org.jboss.invocation.Invocation getMBeanInvocation(final Invocation wsInvocation)
   {
      // ensure preconditions
      final MessageContext msgContext = wsInvocation.getInvocationContext().getAttachment(MessageContext.class);
      if (msgContext == null)
      {
         throw new IllegalStateException("Cannot obtain MessageContext");
      }

      final HandlerCallback callback = wsInvocation.getInvocationContext().getAttachment(HandlerCallback.class);
      if (callback == null)
      {
         throw new IllegalStateException("Cannot obtain HandlerCallback");
      }

      // prepare security data
      final SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
      final SecurityAdaptor securityAdaptor = spiProvider.getSPI(SecurityAdaptorFactory.class).newSecurityAdapter();
      final Principal principal = securityAdaptor.getPrincipal();
      final Object credential = securityAdaptor.getCredential();

      // prepare invocation data
      final Method method = wsInvocation.getJavaMethod();
      final Object[] args = wsInvocation.getArgs();
      final org.jboss.invocation.Invocation jbossInvocation = new org.jboss.invocation.Invocation(null, method, args,
            null, principal, credential);

      // propagate values to JBoss invocation
      jbossInvocation.setValue(InvocationKey.SOAP_MESSAGE_CONTEXT, msgContext);
      jbossInvocation.setValue(InvocationKey.SOAP_MESSAGE, ((SOAPMessageContext) msgContext).getMessage());
      jbossInvocation.setType(InvocationType.SERVICE_ENDPOINT);
      jbossInvocation.setValue(HandlerCallback.class.getName(), callback, PayloadKey.TRANSIENT);
      jbossInvocation.setValue(Invocation.class.getName(), wsInvocation, PayloadKey.TRANSIENT);

      return jbossInvocation;
   }

   /**
    * This method dynamically inserts EJB 21 webservice endpoint interceptor
    * to the last but one position in EJB 21 processing chain. See [JBWS-756] for more info.
    *
    * @param objectName EJB 21 object name
    * @param ejbName EJB 21 short name
    */
   private void insertEJB21ServiceEndpointInterceptor(final ObjectName objectName, final String ejbName)
   {
      try
      {
         final EjbModule ejbModule = (EjbModule) this.server.getAttribute(objectName, "EjbModule");
         final StatelessSessionContainer container = (StatelessSessionContainer) ejbModule.getContainer(ejbName);

         Interceptor currentInterceptor = container.getInterceptor();
         while (currentInterceptor != null && currentInterceptor.getNext() != null)
         {
            final Interceptor nextInterceptor = currentInterceptor.getNext();

            if (nextInterceptor.getNext() == null)
            {
               final ServiceEndpointInterceptorEJB21 sepInterceptor = new ServiceEndpointInterceptorEJB21();
               currentInterceptor.setNext(sepInterceptor);
               sepInterceptor.setNext(nextInterceptor);
               this.log.debug("Injecting EJB 21 service endpoint interceptor after: "
                     + currentInterceptor.getClass().getName());

               return;
            }
            currentInterceptor = nextInterceptor;
         }

         this.log.warn("Cannot find EJB 21 service endpoint interceptor insert point");
      }
      catch (Exception ex)
      {
         this.log.warn("Cannot register EJB 21 service endpoint interceptor: ", ex);
      }
   }
}
TOP

Related Classes of org.jboss.webservices.integration.invocation.InvocationHandlerEJB21

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.