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.EndpointLifecycleManager;
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.axis2.GeronimoFactoryRegistry;
042 import org.apache.geronimo.jaxws.JAXWSAnnotationProcessor;
043 import org.apache.geronimo.jaxws.PortInfo;
044 import org.apache.geronimo.jaxws.annotations.AnnotationHolder;
045
046 /**
047 * @version $Rev$ $Date$
048 */
049 public class POJOWebServiceContainer extends Axis2WebServiceContainer {
050
051 private static final Log LOG = LogFactory.getLog(POJOWebServiceContainer.class);
052
053 private Object endpointInstance;
054 private String contextRoot;
055 private AnnotationHolder holder;
056
057 public POJOWebServiceContainer(PortInfo portInfo,
058 String endpointClassName,
059 ClassLoader classLoader,
060 Context context,
061 URL configurationBaseUrl,
062 AnnotationHolder holder,
063 String contextRoot) {
064 super(portInfo, endpointClassName, classLoader, context, configurationBaseUrl);
065 this.holder = holder;
066 this.contextRoot = contextRoot;
067 }
068
069 @Override
070 public void init() throws Exception {
071 super.init();
072
073 String servicePath = trimContext(getServicePath(this.contextRoot));
074 this.configurationContext.setServicePath(servicePath);
075 //need to setContextRoot after servicePath as cachedServicePath is only built
076 //when setContextRoot is called.
077 String rootContext = trimContext(this.contextRoot);
078 this.configurationContext.setContextRoot(rootContext);
079
080 // instantiate and inject resources into service
081 try {
082 this.endpointInstance = this.holder.newInstance(this.endpointClass.getName(),
083 this.endpointClass.getClassLoader(),
084 this.context);
085 } catch (Exception e) {
086 throw new WebServiceException("Service resource injection failed", e);
087 }
088
089 this.annotationProcessor =
090 new JAXWSAnnotationProcessor(this.jndiResolver, new POJOWebServiceContext());
091
092 // configure and inject handlers
093 try {
094 configureHandlers();
095 injectHandlers();
096 } catch (Exception e) {
097 throw new WebServiceException("Error configuring handlers", e);
098 }
099
100 this.factoryRegistry = new GeronimoFactoryRegistry();
101 this.factoryRegistry.put(EndpointLifecycleManager.class, new POJOEndpointLifecycleManager());
102 }
103
104 @Override
105 protected void processXMLRequest(Request request,
106 Response response,
107 AxisService service,
108 MessageContext msgContext) throws Exception {
109 String contentType = request.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);
110 String soapAction = request.getHeader(HTTPConstants.HEADER_SOAP_ACTION);
111 if (soapAction == null) {
112 soapAction = "\"\"";
113 }
114
115 ConfigurationContext configurationContext = msgContext.getConfigurationContext();
116 configurationContext.fillServiceContextAndServiceGroupContext(msgContext);
117
118 setMsgContextProperties(request, response, service, msgContext);
119
120 ServiceContext serviceContext = msgContext.getServiceContext();
121 serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, this.endpointInstance);
122
123 try {
124 if (!HTTPTransportUtils.isRESTRequest(contentType)) {
125 HTTPTransportUtils.processHTTPPostRequest(msgContext,
126 request.getInputStream(),
127 response.getOutputStream(),
128 contentType,
129 soapAction,
130 request.getURI().getPath());
131 } else {
132 RESTUtil.processXMLRequest(msgContext,
133 request.getInputStream(),
134 response.getOutputStream(),
135 contentType);
136 }
137 } finally {
138 // de-associate JAX-WS MessageContext with the thread
139 // (association happens in POJOEndpointLifecycleManager.createService() call)
140 POJOWebServiceContext.clear();
141 }
142 }
143
144 @Override
145 protected void processURLRequest(Request request,
146 Response response,
147 AxisService service,
148 MessageContext msgContext) throws Exception {
149 String contentType = request.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);
150
151 ConfigurationContext configurationContext = msgContext.getConfigurationContext();
152 configurationContext.fillServiceContextAndServiceGroupContext(msgContext);
153
154 setMsgContextProperties(request, response, service, msgContext);
155
156 ServiceContext serviceContext = msgContext.getServiceContext();
157 serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, this.endpointInstance);
158
159 InvocationResponse processed = null;
160 try {
161 processed = RESTUtil.processURLRequest(msgContext,
162 response.getOutputStream(),
163 contentType);
164 } finally {
165 // de-associate JAX-WS MessageContext with the thread
166 // (association happens in POJOEndpointLifecycleManager.createService() call)
167 POJOWebServiceContext.clear();
168 }
169
170 if (!processed.equals(InvocationResponse.CONTINUE)) {
171 response.setStatusCode(HttpURLConnection.HTTP_OK);
172 String s = HTTPTransportReceiver.getServicesHTML(configurationContext);
173 PrintWriter pw = new PrintWriter(response.getOutputStream());
174 pw.write(s);
175 pw.flush();
176 }
177 }
178
179 @Override
180 public void destroy() {
181 // call handler preDestroy
182 destroyHandlers();
183
184 // call service preDestroy
185 if (this.endpointInstance != null) {
186 try {
187 this.holder.destroyInstance(this.endpointInstance);
188 } catch (Exception e) {
189 LOG.warn("Error calling @PreDestroy method", e);
190 }
191 }
192
193 super.destroy();
194 }
195 }