1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.geronimo.axis2.pojo; 19 20 import java.io.PrintWriter; 21 import java.net.HttpURLConnection; 22 import java.net.URL; 23 24 import javax.naming.Context; 25 import javax.xml.ws.WebServiceException; 26 27 import org.apache.axis2.context.ConfigurationContext; 28 import org.apache.axis2.context.MessageContext; 29 import org.apache.axis2.context.ServiceContext; 30 import org.apache.axis2.description.AxisService; 31 import org.apache.axis2.engine.Handler.InvocationResponse; 32 import org.apache.axis2.jaxws.registry.FactoryRegistry; 33 import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactory; 34 import org.apache.axis2.jaxws.server.endpoint.lifecycle.EndpointLifecycleManager; 35 import org.apache.axis2.transport.http.HTTPConstants; 36 import org.apache.axis2.transport.http.HTTPTransportReceiver; 37 import org.apache.axis2.transport.http.HTTPTransportUtils; 38 import org.apache.axis2.transport.http.util.RESTUtil; 39 import org.apache.geronimo.axis2.Axis2WebServiceContainer; 40 import org.apache.geronimo.axis2.AxisServiceGenerator; 41 import org.apache.geronimo.axis2.GeronimoFactoryRegistry; 42 import org.apache.geronimo.jaxws.JAXWSAnnotationProcessor; 43 import org.apache.geronimo.jaxws.JAXWSUtils; 44 import org.apache.geronimo.jaxws.PortInfo; 45 import org.apache.geronimo.jaxws.annotations.AnnotationHolder; 46 import org.slf4j.Logger; 47 import org.slf4j.LoggerFactory; 48 49 /** 50 * @version $Rev$ $Date$ 51 */ 52 public class POJOWebServiceContainer extends Axis2WebServiceContainer 53 { 54 private static final Logger LOG = LoggerFactory.getLogger(POJOWebServiceContainer.class); 55 56 private Object endpointInstance; 57 private String contextRoot; 58 private AnnotationHolder holder; 59 60 public POJOWebServiceContainer(PortInfo portInfo, 61 String endpointClassName, 62 ClassLoader classLoader, 63 Context context, 64 URL configurationBaseUrl, 65 AnnotationHolder holder, 66 String contextRoot) { 67 super(portInfo, endpointClassName, classLoader, context, configurationBaseUrl); 68 this.holder = holder; 69 this.contextRoot = contextRoot; 70 } 71 72 @Override 73 public void init() throws Exception { 74 super.init(); 75 76 /* 77 * This replaces EndpointDispatcherFactory for all web services. 78 * This is because we do our own endpoint instance management and injection. 79 * This does not affect EJB web services as the EJB container does not use the FactoryRegistry 80 * to lookup the EndpointDispatcherFactory. 81 */ 82 FactoryRegistry.setFactory(EndpointDispatcherFactory.class, 83 new POJOEndpointDispatcherFactory()); 84 85 String servicePath = trimContext(getServicePath(this.contextRoot)); 86 this.configurationContext.setServicePath(servicePath); 87 //need to setContextRoot after servicePath as cachedServicePath is only built 88 //when setContextRoot is called. 89 String rootContext = trimContext(this.contextRoot); 90 this.configurationContext.setContextRoot(rootContext); 91 92 // instantiate and inject resources into service 93 try { 94 this.endpointInstance = this.holder.newInstance(this.endpointClass.getName(), 95 this.endpointClass.getClassLoader(), 96 this.context); 97 } catch (Exception e) { 98 throw new WebServiceException("Service resource injection failed", e); 99 } 100 101 this.annotationProcessor = 102 new JAXWSAnnotationProcessor(this.jndiResolver, new POJOWebServiceContext()); 103 104 // configure and inject handlers 105 try { 106 configureHandlers(); 107 injectHandlers(); 108 } catch (Exception e) { 109 throw new WebServiceException("Error configuring handlers", e); 110 } 111 112 this.factoryRegistry = new GeronimoFactoryRegistry(); 113 this.factoryRegistry.put(EndpointLifecycleManager.class, new POJOEndpointLifecycleManager()); 114 } 115 116 @Override 117 protected AxisServiceGenerator createServiceGenerator() { 118 AxisServiceGenerator serviceGenerator = super.createServiceGenerator(); 119 serviceGenerator.setCatalogName(JAXWSUtils.DEFAULT_CATALOG_WEB); 120 return serviceGenerator; 121 } 122 123 @Override 124 protected void processXMLRequest(Request request, 125 Response response, 126 AxisService service, 127 MessageContext msgContext) throws Exception { 128 String contentType = request.getHeader(HTTPConstants.HEADER_CONTENT_TYPE); 129 String soapAction = request.getHeader(HTTPConstants.HEADER_SOAP_ACTION); 130 if (soapAction == null) { 131 soapAction = "\"\""; 132 } 133 134 ConfigurationContext configurationContext = msgContext.getConfigurationContext(); 135 configurationContext.fillServiceContextAndServiceGroupContext(msgContext); 136 137 setMsgContextProperties(request, response, service, msgContext); 138 139 ServiceContext serviceContext = msgContext.getServiceContext(); 140 serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, this.endpointInstance); 141 142 try { 143 if (!HTTPTransportUtils.isRESTRequest(contentType)) { 144 HTTPTransportUtils.processHTTPPostRequest(msgContext, 145 request.getInputStream(), 146 response.getOutputStream(), 147 contentType, 148 soapAction, 149 request.getURI().getPath()); 150 } else { 151 RESTUtil.processXMLRequest(msgContext, 152 request.getInputStream(), 153 response.getOutputStream(), 154 contentType); 155 } 156 } finally { 157 // de-associate JAX-WS MessageContext with the thread 158 // (association happens in POJOEndpointLifecycleManager.createService() call) 159 POJOWebServiceContext.clear(); 160 } 161 } 162 163 @Override 164 protected void processURLRequest(Request request, 165 Response response, 166 AxisService service, 167 MessageContext msgContext) throws Exception { 168 String contentType = request.getHeader(HTTPConstants.HEADER_CONTENT_TYPE); 169 170 ConfigurationContext configurationContext = msgContext.getConfigurationContext(); 171 configurationContext.fillServiceContextAndServiceGroupContext(msgContext); 172 173 setMsgContextProperties(request, response, service, msgContext); 174 175 ServiceContext serviceContext = msgContext.getServiceContext(); 176 serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, this.endpointInstance); 177 178 InvocationResponse processed = null; 179 try { 180 processed = RESTUtil.processURLRequest(msgContext, 181 response.getOutputStream(), 182 contentType); 183 } finally { 184 // de-associate JAX-WS MessageContext with the thread 185 // (association happens in POJOEndpointLifecycleManager.createService() call) 186 POJOWebServiceContext.clear(); 187 } 188 189 if (!processed.equals(InvocationResponse.CONTINUE)) { 190 response.setStatusCode(HttpURLConnection.HTTP_OK); 191 String s = HTTPTransportReceiver.getServicesHTML(configurationContext); 192 PrintWriter pw = new PrintWriter(response.getOutputStream()); 193 pw.write(s); 194 pw.flush(); 195 } 196 } 197 198 @Override 199 public void destroy() { 200 // call handler preDestroy 201 destroyHandlers(); 202 203 // call service preDestroy 204 if (this.endpointInstance != null) { 205 try { 206 this.holder.destroyInstance(this.endpointInstance); 207 } catch (Exception e) { 208 LOG.warn("Error calling @PreDestroy method", e); 209 } 210 } 211 212 super.destroy(); 213 } 214 }