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    }