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    package org.apache.geronimo.cxf;
018    
019    import java.io.OutputStream;
020    import java.io.PrintWriter;
021    import java.net.URI;
022    import java.net.URL;
023    import java.util.ArrayList;
024    import java.util.List;
025    
026    import org.apache.commons.logging.Log;
027    import org.apache.commons.logging.LogFactory;
028    import org.apache.cxf.Bus;
029    import org.apache.cxf.BusFactory;
030    import org.apache.cxf.bus.extension.ExtensionManagerBus;
031    import org.apache.cxf.service.model.EndpointInfo;
032    import org.apache.cxf.transport.DestinationFactoryManager;
033    import org.apache.geronimo.webservices.WebServiceContainer;
034    import org.apache.geronimo.webservices.saaj.SAAJUniverse;
035    
036    public abstract class CXFWebServiceContainer implements WebServiceContainer {
037    
038        private static final Log LOG = LogFactory.getLog(CXFWebServiceContainer.class);
039        
040        protected final GeronimoDestination destination;
041    
042        protected final Bus bus;
043    
044        protected final CXFEndpoint endpoint;
045    
046        protected URL configurationBaseUrl;
047    
048        public CXFWebServiceContainer(Bus bus,
049                                      URL configurationBaseUrl,
050                                      Object target) {
051            this.bus = bus;
052            this.configurationBaseUrl = configurationBaseUrl;
053                
054            List ids = new ArrayList();
055            ids.add("http://schemas.xmlsoap.org/wsdl/soap/");
056                   
057            DestinationFactoryManager destinationFactoryManager = bus
058                    .getExtension(DestinationFactoryManager.class);
059            GeronimoDestinationFactory factory = new GeronimoDestinationFactory(bus);
060            factory.setTransportIds(ids);
061                    
062            destinationFactoryManager.registerDestinationFactory(
063                    "http://cxf.apache.org/transports/http/configuration", factory);
064            destinationFactoryManager.registerDestinationFactory(
065                    "http://cxf.apache.org/bindings/xformat", factory);
066            destinationFactoryManager.registerDestinationFactory(
067                    "http://www.w3.org/2003/05/soap/bindings/HTTP/", factory);
068            destinationFactoryManager.registerDestinationFactory(
069                    "http://schemas.xmlsoap.org/soap/http", factory);
070            destinationFactoryManager.registerDestinationFactory(
071                    "http://schemas.xmlsoap.org/wsdl/http/", factory);
072            destinationFactoryManager.registerDestinationFactory(
073                    "http://schemas.xmlsoap.org/wsdl/soap/http", factory);
074    
075            endpoint = publishEndpoint(target);
076            destination = (GeronimoDestination) endpoint.getServer().getDestination();
077        }
078    
079        public void invoke(Request request, Response response) throws Exception {
080            if (request.getMethod() == Request.GET) {
081                processGET(request, response);
082            } else {
083                processPOST(request, response);
084            }
085        }
086        
087        protected void processGET(Request request, Response response) throws Exception {
088            if (request.getParameter("wsdl") != null || request.getParameter("WSDL") != null ||
089                       request.getParameter("xsd") != null || request.getParameter("XSD") != null) {
090                GeronimoQueryHandler queryHandler = new GeronimoQueryHandler(this.bus);
091                URI requestURI = request.getURI();
092                EndpointInfo ei = this.destination.getEndpointInfo();
093                OutputStream out = response.getOutputStream();
094                String baseUri = requestURI.toString();
095                response.setContentType("text/xml");
096                queryHandler.writeResponse(baseUri, null, ei, out);
097            } else if (endpoint.isSOAP11()) {
098                EndpointInfo ei = this.destination.getEndpointInfo();
099                response.setContentType("text/html");
100                PrintWriter pw = new PrintWriter(response.getOutputStream());
101                pw.write("<html><title>Web Service</title><body>");
102                pw.write("Hi, this is '" + ei.getService().getName().getLocalPart() + "' web service.");
103                pw.write("</body></html>");
104                pw.flush();
105            } else {
106                processPOST(request, response);
107            }
108        }
109        
110        protected void processPOST(Request request, Response response) throws Exception {
111            SAAJUniverse universe = new SAAJUniverse();
112            universe.set(SAAJUniverse.DEFAULT);
113            try {
114                destination.invoke(request, response);
115            } finally {
116                universe.unset();
117            }
118        }
119       
120        public void getWsdl(Request request, Response response) throws Exception {
121            invoke(request, response);
122        }    
123            
124        public void destroy() {
125            if (this.endpoint != null) {
126                this.endpoint.stop();
127            }
128        }
129    
130        abstract protected CXFEndpoint publishEndpoint(Object target);
131            
132        /*
133         * Ensure the bus created is unqiue and non-shared. 
134         * The very first bus created is set as a default bus which then can
135         * be (re)used in other places.
136         */
137        public static Bus getBus() {        
138            getDefaultBus();
139            return new ExtensionManagerBus();
140        }
141        
142        /*
143         * Ensure the Spring bus is initialized with the CXF module classloader
144         * instead of the application classloader. 
145         */
146        public static Bus getDefaultBus() {
147            ClassLoader cl = Thread.currentThread().getContextClassLoader();
148            Thread.currentThread().setContextClassLoader(CXFEndpoint.class.getClassLoader());
149            try {
150                return BusFactory.getDefaultBus();
151            } finally {
152                Thread.currentThread().setContextClassLoader(cl);
153            }
154        }
155        
156    }