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 }