Home » openejb-3.1.2-src » org.apache » openejb » server » cxf » ejb » [javadoc | source]

    1   /**
    2    *
    3    * Licensed to the Apache Software Foundation (ASF) under one or more
    4    * contributor license agreements.  See the NOTICE file distributed with
    5    * this work for additional information regarding copyright ownership.
    6    * The ASF licenses this file to You under the Apache License, Version 2.0
    7    * (the "License"); you may not use this file except in compliance with
    8    * the License.  You may obtain a copy of the License at
    9    *
   10    *     http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    *  Unless required by applicable law or agreed to in writing, software
   13    *  distributed under the License is distributed on an "AS IS" BASIS,
   14    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15    *  See the License for the specific language governing permissions and
   16    *  limitations under the License.
   17    */
   18   package org.apache.openejb.server.cxf.ejb;
   19   
   20   import java.lang.reflect.InvocationTargetException;
   21   import java.lang.reflect.Method;
   22   import java.util.ArrayList;
   23   import java.util.List;
   24   
   25   import javax.interceptor.InvocationContext;
   26   import javax.xml.ws.WebFault;
   27   import javax.xml.ws.handler.MessageContext;
   28   
   29   import org.apache.cxf.Bus;
   30   import org.apache.cxf.interceptor.Fault;
   31   import org.apache.cxf.jaxws.context.WebServiceContextImpl;
   32   import org.apache.cxf.jaxws.support.ContextPropertiesMapping;
   33   import org.apache.cxf.message.Exchange;
   34   import org.apache.cxf.message.FaultMode;
   35   import org.apache.cxf.service.invoker.AbstractInvoker;
   36   import org.apache.openejb.ApplicationException;
   37   import org.apache.openejb.DeploymentInfo;
   38   import org.apache.openejb.RpcContainer;
   39   import org.apache.openejb.InterfaceType;
   40   import org.apache.openejb.util.LogCategory;
   41   import org.apache.openejb.util.Logger;
   42   
   43   public class EjbMethodInvoker extends AbstractInvoker {
   44       private static final Logger log = Logger.getInstance(LogCategory.CXF, EjbMethodInvoker.class);
   45   
   46       private DeploymentInfo deploymentInfo;
   47       private Bus bus;
   48   
   49       public EjbMethodInvoker(Bus bus, DeploymentInfo deploymentInfo) {
   50           this.bus = bus;
   51           this.deploymentInfo = deploymentInfo;
   52       }
   53   
   54       public Object getServiceObject(Exchange context) {
   55           return null;
   56       }
   57   
   58       protected Object invoke(Exchange exchange, Object serviceObject, Method m, List<Object> params) {
   59           Object result = null;
   60   
   61           InvocationContext invContext = exchange.get(InvocationContext.class);
   62           if (invContext == null) {
   63               log.debug("PreEJBInvoke");
   64               result = preEjbInvoke(exchange, m, params);
   65           } else {
   66               log.debug("EJBInvoke");
   67               result = ejbInvoke(exchange, m, params);
   68           }
   69   
   70           return result;
   71       }
   72   
   73       private Object preEjbInvoke(Exchange exchange, Method method, List<Object> params) {
   74   
   75           MessageContext ctx = ContextPropertiesMapping.createWebServiceContext(exchange);
   76           WebServiceContextImpl.setMessageContext(ctx);
   77           
   78           try {
   79               
   80               EjbInterceptor interceptor = new EjbInterceptor(params, method, this.bus, exchange);
   81               Object[] arguments = {ctx, interceptor};
   82   
   83               RpcContainer container = (RpcContainer) this.deploymentInfo.getContainer();
   84   
   85               Class callInterface = this.deploymentInfo.getServiceEndpointInterface();
   86               method = getMostSpecificMethod(method, callInterface);
   87               Object res = container.invoke(this.deploymentInfo.getDeploymentID(), InterfaceType.SERVICE_ENDPOINT, callInterface, method, arguments, null);
   88   
   89               if (exchange.isOneWay()) {
   90                   return null;
   91               }
   92   
   93               List<Object> retList = new ArrayList<Object>(1);
   94               if (!method.getReturnType().getName().equals("void")) {
   95                   retList.add(res);
   96               }
   97               
   98               return retList;
   99            
  100           // OPENEJB-965: must check if the application exception is a web fault.
  101           } catch (ApplicationException e) {
  102               // when no handler is defined, EjbInterceptor will directly delegate
  103               // to #directEjbInvoke. So if an application exception is thrown by
  104               // the end user, when must consider the ApplicationException as a 
  105               // web fault if it contains the @WebFault exception
  106               Throwable t = e.getCause();
  107               if (t != null) {
  108           	if (	t.getClass().isAssignableFrom(RuntimeException.class) &&
  109           		t.getClass().isAnnotationPresent(javax.ejb.ApplicationException.class)) {
  110           	    // it's not a checked exception so it can not be a WebFault 
  111   		    throw (RuntimeException)t;
  112   		    
  113   		} else if (!t.getClass().isAnnotationPresent(WebFault.class)) {
  114   		    // not a web fault even if it's an EJB ApplicationException
  115   		    exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
  116   	            throw new Fault(t);
  117   		}
  118           	
  119               } else { // may not occurs ...
  120           	t = e;
  121               }
  122               // TODO may be we can change to FaultMode.CHECKED_APPLICATION_FAULT
  123               exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
  124               throw new Fault(t);
  125           } catch (Exception e) {
  126               exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
  127               throw new Fault(e);
  128           } finally {
  129               WebServiceContextImpl.clear();
  130           }
  131       }
  132   
  133       private Object ejbInvoke(Exchange exchange, Method m, List<Object> params) {
  134           try {
  135               Object res = directEjbInvoke(exchange, m, params);
  136   
  137               if (exchange.isOneWay()) {
  138                   return null;
  139               }
  140   
  141               List<Object> retList = new ArrayList<Object>(1);
  142               if (!m.getReturnType().getName().equals("void")) {
  143                   retList.add(res);
  144               }
  145   
  146               return retList;
  147           } catch (InvocationTargetException e) {
  148               Throwable t = e.getCause();
  149               if (t == null) {
  150                   t = e;
  151               }
  152               exchange.getInMessage().put(FaultMode.class, FaultMode.CHECKED_APPLICATION_FAULT);
  153               throw new Fault(t);
  154           } catch (Exception e) {
  155               exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
  156               throw new Fault(e);
  157           }
  158       }
  159   
  160       public Object directEjbInvoke(Exchange exchange, Method m, List<Object> params) throws Exception {
  161           InvocationContext invContext = exchange.get(InvocationContext.class);
  162           Object[] paramArray;
  163           if (params != null) {
  164               paramArray = params.toArray();
  165           } else {
  166               paramArray = new Object[]{};
  167           }
  168   
  169           invContext.setParameters(paramArray);
  170           Object res = invContext.proceed();
  171   
  172           ContextPropertiesMapping.updateWebServiceContext(exchange, (MessageContext) invContext.getContextData());
  173   
  174           return res;
  175       }
  176   }

Home » openejb-3.1.2-src » org.apache » openejb » server » cxf » ejb » [javadoc | source]