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.net.URL;
021    
022    import javax.naming.Context;
023    import javax.xml.ws.WebServiceException;
024    
025    import org.apache.axis2.context.ConfigurationContext;
026    import org.apache.axis2.context.MessageContext;
027    import org.apache.axis2.context.ServiceContext;
028    import org.apache.axis2.description.AxisService;
029    import org.apache.axis2.jaxws.registry.FactoryRegistry;
030    import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory;
031    import org.apache.axis2.transport.http.HTTPConstants;
032    import org.apache.axis2.transport.http.HTTPTransportUtils;
033    import org.apache.axis2.util.JavaUtils;
034    import org.apache.commons.logging.Log;
035    import org.apache.commons.logging.LogFactory;
036    import org.apache.geronimo.axis2.Axis2WebServiceContainer;
037    import org.apache.geronimo.jaxws.JAXWSAnnotationProcessor;
038    import org.apache.geronimo.jaxws.PortInfo;
039    import org.apache.geronimo.jaxws.annotations.AnnotationHolder;
040    
041    /**
042     * @version $Rev$ $Date$
043     */
044    public class POJOWebServiceContainer extends Axis2WebServiceContainer {
045    
046        private static final Log LOG = LogFactory.getLog(POJOWebServiceContainer.class);
047        
048        private Object endpointInstance;
049        private String contextRoot = null;
050        private AnnotationHolder holder;
051        
052        public POJOWebServiceContainer(PortInfo portInfo,
053                                       String endpointClassName,
054                                       ClassLoader classLoader,
055                                       Context context,
056                                       URL configurationBaseUrl,
057                                       AnnotationHolder holder) {
058            super(portInfo, endpointClassName, classLoader, context, configurationBaseUrl);
059            this.holder = holder;
060        }
061        
062        @Override
063        public void init() throws Exception { 
064            super.init();
065            
066            /*
067             * This replaces EndpointLifecycleManagerFactory for all web services.
068             * This should be ok as we do our own endpoint instance management and injection.       
069             */
070            FactoryRegistry.setFactory(EndpointLifecycleManagerFactory.class, 
071                                       new POJOEndpointLifecycleManagerFactory());
072                           
073            this.configurationContext.setServicePath(this.portInfo.getLocation());
074            
075            // instantiate and inject resources into service
076            try {
077                this.endpointInstance = this.holder.newInstance(this.endpointClass.getName(), 
078                                                                this.endpointClass.getClassLoader(), 
079                                                                this.context);
080            } catch (Exception e) {
081                throw new WebServiceException("Service resource injection failed", e);
082            }
083            
084            this.annotationProcessor = 
085                new JAXWSAnnotationProcessor(this.jndiResolver, new POJOWebServiceContext());
086    
087            // configure and inject handlers
088            try {
089                configureHandlers();
090                injectHandlers();
091            } catch (Exception e) {
092                throw new WebServiceException("Error configuring handlers", e);
093            }
094            
095        }
096        
097        @Override
098        protected void processPOSTRequest(Request request, Response response, AxisService service, MessageContext msgContext) throws Exception {
099            String contentType = request.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);
100            String soapAction = request.getHeader(HTTPConstants.HEADER_SOAP_ACTION);
101            if (soapAction == null) {
102                soapAction = "\"\"";
103            }
104    
105            ConfigurationContext configurationContext = msgContext.getConfigurationContext();
106            configurationContext.fillServiceContextAndServiceGroupContext(msgContext);
107            
108            setMsgContextProperties(request, response, service, msgContext);
109    
110            ServiceContext serviceContext = msgContext.getServiceContext();
111            serviceContext.setProperty(ServiceContext.SERVICE_OBJECT, this.endpointInstance);
112    
113            try {
114                HTTPTransportUtils.processHTTPPostRequest(msgContext,
115                                                          request.getInputStream(),
116                                                          response.getOutputStream(),
117                                                          contentType,
118                                                          soapAction,
119                                                          request.getURI().getPath());
120            } finally {                        
121                // de-associate JAX-WS MessageContext with the thread
122                // (association happens in POJOEndpointLifecycleManager.createService() call)
123                POJOWebServiceContext.clear();
124            } 
125        }
126        
127        protected void initContextRoot(Request request) {
128            if (contextRoot == null || "".equals(contextRoot)) {
129                String[] parts = JavaUtils.split(request.getContextPath(), '/');
130                if (parts != null) {
131                    for (int i = 0; i < parts.length; i++) {
132                        if (parts[i].length() > 0) {
133                            contextRoot = parts[i];
134                            break;
135                        }
136                    }
137                }
138                if (contextRoot == null || request.getContextPath().equals("/")) {
139                    contextRoot = "/";
140                }
141                //need to setContextRoot after servicePath as cachedServicePath is only built 
142                //when setContextRoot is called.
143                configurationContext.setContextRoot(contextRoot);  
144            }
145        }     
146        
147        @Override
148        public void destroy() {
149            // call handler preDestroy
150            destroyHandlers();
151            
152            // call service preDestroy
153            if (this.endpointInstance != null) {
154                try {
155                    this.holder.destroyInstance(this.endpointInstance);
156                } catch (Exception e) {
157                    LOG.warn("Error calling @PreDestroy method", e); 
158                }
159            }
160            
161            super.destroy();
162        }
163    }