001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020 package org.apache.geronimo.cxf.ejb;
021
022 import java.lang.reflect.InvocationTargetException;
023 import java.lang.reflect.Method;
024 import java.util.ArrayList;
025 import java.util.List;
026
027 import javax.interceptor.InvocationContext;
028 import javax.xml.ws.handler.MessageContext;
029
030 import org.apache.commons.logging.Log;
031 import org.apache.commons.logging.LogFactory;
032 import org.apache.cxf.Bus;
033 import org.apache.cxf.interceptor.Fault;
034 import org.apache.cxf.jaxws.context.WebServiceContextImpl;
035 import org.apache.cxf.jaxws.support.ContextPropertiesMapping;
036 import org.apache.cxf.message.Exchange;
037 import org.apache.cxf.message.FaultMode;
038 import org.apache.cxf.service.invoker.AbstractInvoker;
039 import org.apache.openejb.DeploymentInfo;
040 import org.apache.openejb.RpcContainer;
041
042 public class EJBMethodInvoker extends AbstractInvoker {
043
044 private static final Log LOG = LogFactory.getLog(EJBMethodInvoker.class);
045
046 private DeploymentInfo deploymentInfo;
047 private Bus bus;
048 private EJBEndpoint endpoint;
049
050 public EJBMethodInvoker(EJBEndpoint endpoint, Bus bus, DeploymentInfo deploymentInfo) {
051 this.endpoint = endpoint;
052 this.bus = bus;
053 this.deploymentInfo = deploymentInfo;
054 }
055
056 public Object getServiceObject(Exchange context) {
057 return null;
058 }
059
060 protected Object invoke(Exchange exchange,
061 Object serviceObject,
062 Method m,
063 List<Object> params) {
064 Object result = null;
065
066 InvocationContext invContext = exchange.get(InvocationContext.class);
067 if (invContext == null) {
068 LOG.debug("PreEJBInvoke");
069 result = preEjbInvoke(exchange, serviceObject, m, params);
070 } else {
071 LOG.debug("EJBInvoke");
072 result = ejbInvoke(exchange, serviceObject, m, params);
073 }
074
075 return result;
076 }
077
078 private Object preEjbInvoke(Exchange exchange,
079 Object serviceObject,
080 Method method,
081 List<Object> params) {
082
083 MessageContext ctx = ContextPropertiesMapping.createWebServiceContext(exchange);
084 WebServiceContextImpl.setMessageContext(ctx);
085
086 try {
087 EJBInterceptor interceptor = new EJBInterceptor(params, method, this.endpoint, this.bus, exchange);
088 Object[] arguments = { ctx, interceptor };
089
090 RpcContainer container = (RpcContainer) this.deploymentInfo.getContainer();
091
092 Class callInterface = this.deploymentInfo.getServiceEndpointInterface();
093 method = getMostSpecificMethod(method, callInterface);
094 Object res = container.invoke(this.deploymentInfo.getDeploymentID(), callInterface, method, arguments, null);
095
096 if (exchange.isOneWay()) {
097 return null;
098 }
099
100 List<Object> retList = new ArrayList<Object>(1);
101 if (!((Class) method.getReturnType()).getName().equals("void")) {
102 retList.add(res);
103 }
104
105 return retList;
106 } catch (Exception e) {
107 exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
108 throw new Fault(e);
109 } finally {
110 WebServiceContextImpl.clear();
111 }
112 }
113
114 private Object ejbInvoke(Exchange exchange,
115 Object serviceObject,
116 Method m,
117 List<Object> params) {
118 try {
119 Object res = directEjbInvoke(exchange, m, params);
120
121 if (exchange.isOneWay()) {
122 return null;
123 }
124
125 List<Object> retList = new ArrayList<Object>(1);
126 if (!((Class)m.getReturnType()).getName().equals("void")) {
127 retList.add(res);
128 }
129
130 return retList;
131 } catch (InvocationTargetException e) {
132 Throwable t = e.getCause();
133 if (t == null) {
134 t = e;
135 }
136 exchange.getInMessage().put(FaultMode.class, FaultMode.CHECKED_APPLICATION_FAULT);
137 throw new Fault(t);
138 } catch (Exception e) {
139 exchange.getInMessage().put(FaultMode.class, FaultMode.UNCHECKED_APPLICATION_FAULT);
140 throw new Fault(e);
141 }
142 }
143
144 public Object directEjbInvoke(Exchange exchange,
145 Method m,
146 List<Object> params) throws Exception {
147 InvocationContext invContext = exchange.get(InvocationContext.class);
148 Object[] paramArray;
149 if (params != null) {
150 paramArray = params.toArray();
151 } else {
152 paramArray = new Object[]{};
153 }
154
155 invContext.setParameters(paramArray);
156 Object res = invContext.proceed();
157
158 ContextPropertiesMapping.updateWebServiceContext(exchange,
159 (MessageContext)invContext.getContextData());
160
161 return res;
162 }
163
164 }