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 }