001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.axis2.pojo; 019 020 import java.io.PrintWriter; 021 import java.net.HttpURLConnection; 022 import java.net.URL; 023 024 import javax.naming.Context; 025 import javax.xml.ws.WebServiceException; 026 027 import org.apache.axis2.context.ConfigurationContext; 028 import org.apache.axis2.context.MessageContext; 029 import org.apache.axis2.context.ServiceContext; 030 import org.apache.axis2.description.AxisService; 031 import org.apache.axis2.engine.Handler.InvocationResponse; 032 import org.apache.axis2.jaxws.registry.FactoryRegistry; 033 import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory; 034 import org.apache.axis2.transport.http.HTTPConstants; 035 import org.apache.axis2.transport.http.HTTPTransportReceiver; 036 import org.apache.axis2.transport.http.HTTPTransportUtils; 037 import org.apache.axis2.transport.http.util.RESTUtil; 038 import org.apache.commons.logging.Log; 039 import org.apache.commons.logging.LogFactory; 040 import org.apache.geronimo.axis2.Axis2WebServiceContainer; 041 import org.apache.geronimo.jaxws.JAXWSAnnotationProcessor; 042 import org.apache.geronimo.jaxws.PortInfo; 043 import org.apache.geronimo.jaxws.annotations.AnnotationHolder; 044 045 /** 046 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 047 */ 048 public class POJOWebServiceContainer extends Axis2WebServiceContainer { 049 050 private static final Log LOG = LogFactory.getLog(POJOWebServiceContainer.class); 051 052 private Object endpointInstance; 053 private String contextRoot; 054 private AnnotationHolder holder; 055 056 public POJOWebServiceContainer(PortInfo portInfo, 057 String endpointClassName, 058 ClassLoader classLoader, 059 Context context, 060 URL configurationBaseUrl, 061 AnnotationHolder holder, 062 String contextRoot) { 063 super(portInfo, endpointClassName, classLoader, context, configurationBaseUrl); 064 this.holder = holder; 065 this.contextRoot = contextRoot; 066 } 067 068 @Override 069 public void init() throws Exception { 070 super.init(); 071 072 /* 073 * This replaces EndpointLifecycleManagerFactory for all web services. 074 * This should be ok as we do our own endpoint instance management and injection. 075 */ 076 FactoryRegistry.setFactory(EndpointLifecycleManagerFactory.class, 077 new POJOEndpointLifecycleManagerFactory()); 078 079 String servicePath = trimContext(getServicePath(this.contextRoot)); 080 this.configurationContext.setServicePath(servicePath); 081 //need to setContextRoot after servicePath as cachedServicePath is only built 082 //when setContextRoot is called. 083 String rootContext = trimContext(this.contextRoot); 084 this.configurationContext.setContextRoot(rootContext); 085 086 // instantiate and inject resources into service 087 try { 088 this.endpointInstance = this.holder.newInstance(this.endpointClass.getName(), 089 this.endpointClass.getClassLoader(), 090 this.context); 091 } catch (Exception e) { 092 throw new WebServiceException("Service resource injection failed", e); 093 } 094 095 this.annotationProcessor = 096 new JAXWSAnnotationProcessor(this.jndiResolver, new POJOWebServiceContext()); 097 098 // configure and inject handlers 099 try { 100 configureHandlers(); 101 injectHandlers(); 102 } catch (Exception e) { 103 throw new WebServiceException("Error configuring handlers", e); 104 } 105 106 } 107 108 @Override 109 protected void processXMLRequest(Request request, 110 Response response, 111 AxisService service, 112 MessageContext msgContext) throws Exception { 113 String contentType = request.getHeader(HTTPConstants.HEADER_CONTENT_TYPE); 114 String soapAction = request.getHeader(HTTPConstants.HEADER_SOAP_ACTION); 115 if (soapAction == null) { 116 soapAction = "\"\""; 117 } 118 119 ConfigurationContext configurationContext = msgContext.getConfigurationContext(); 120 configurationContext.fillServiceContextAndServiceGroupContext(msgContext); 121 122 setMsgContextProperties(request, response, service, msgContext); 123 124 ServiceContext serviceContext = msgContext.getServiceContext(); 125 serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, this.endpointInstance); 126 127 try { 128 if (!HTTPTransportUtils.isRESTRequest(contentType)) { 129 HTTPTransportUtils.processHTTPPostRequest(msgContext, 130 request.getInputStream(), 131 response.getOutputStream(), 132 contentType, 133 soapAction, 134 request.getURI().getPath()); 135 } else { 136 RESTUtil.processXMLRequest(msgContext, 137 request.getInputStream(), 138 response.getOutputStream(), 139 contentType); 140 } 141 } finally { 142 // de-associate JAX-WS MessageContext with the thread 143 // (association happens in POJOEndpointLifecycleManager.createService() call) 144 POJOWebServiceContext.clear(); 145 } 146 } 147 148 @Override 149 protected void processURLRequest(Request request, 150 Response response, 151 AxisService service, 152 MessageContext msgContext) throws Exception { 153 String contentType = request.getHeader(HTTPConstants.HEADER_CONTENT_TYPE); 154 155 ConfigurationContext configurationContext = msgContext.getConfigurationContext(); 156 configurationContext.fillServiceContextAndServiceGroupContext(msgContext); 157 158 setMsgContextProperties(request, response, service, msgContext); 159 160 ServiceContext serviceContext = msgContext.getServiceContext(); 161 serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, this.endpointInstance); 162 163 InvocationResponse processed = null; 164 try { 165 processed = RESTUtil.processURLRequest(msgContext, 166 response.getOutputStream(), 167 contentType); 168 } finally { 169 // de-associate JAX-WS MessageContext with the thread 170 // (association happens in POJOEndpointLifecycleManager.createService() call) 171 POJOWebServiceContext.clear(); 172 } 173 174 if (!processed.equals(InvocationResponse.CONTINUE)) { 175 response.setStatusCode(HttpURLConnection.HTTP_OK); 176 String s = HTTPTransportReceiver.getServicesHTML(configurationContext); 177 PrintWriter pw = new PrintWriter(response.getOutputStream()); 178 pw.write(s); 179 pw.flush(); 180 } 181 } 182 183 @Override 184 public void destroy() { 185 // call handler preDestroy 186 destroyHandlers(); 187 188 // call service preDestroy 189 if (this.endpointInstance != null) { 190 try { 191 this.holder.destroyInstance(this.endpointInstance); 192 } catch (Exception e) { 193 LOG.warn("Error calling @PreDestroy method", e); 194 } 195 } 196 197 super.destroy(); 198 } 199 }