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("xsd") != null || request.getParameter("XSD") != null) {
089                getWsdl(request, response);
090            } else {
091                EndpointInfo ei = this.destination.getEndpointInfo();
092                response.setContentType("text/html");
093                PrintWriter pw = new PrintWriter(response.getOutputStream());
094                pw.write("<html><title>Web Service</title><body>");
095                pw.write("Hi, this is '" + ei.getService().getName().getLocalPart() + "' web service.");
096                pw.write("</body></html>");
097                pw.flush();
098            }
099        }
100        
101        protected void processPOST(Request request, Response response) throws Exception {
102            SAAJUniverse universe = new SAAJUniverse();
103            universe.set(SAAJUniverse.DEFAULT);
104            try {
105                destination.invoke(request, response);
106            } finally {
107                universe.unset();
108            }
109        }
110       
111        public void getWsdl(Request request, Response response) throws Exception {
112            GeronimoQueryHandler queryHandler = new GeronimoQueryHandler(this.bus);
113            URI requestURI = request.getURI();
114            EndpointInfo ei = this.destination.getEndpointInfo();
115            OutputStream out = response.getOutputStream();
116            String baseUri = requestURI.toString();
117            response.setContentType("text/xml");
118            queryHandler.writeResponse(baseUri, null, ei, out);
119        }    
120            
121        public void destroy() {
122            if (this.endpoint != null) {
123                this.endpoint.stop();
124            }
125        }
126    
127        abstract protected CXFEndpoint publishEndpoint(Object target);
128            
129        /*
130         * Ensure the bus created is unqiue and non-shared. 
131         * The very first bus created is set as a default bus which then can
132         * be (re)used in other places.
133         */
134        public static Bus getBus() {        
135            BusFactory.getDefaultBus();
136            return new ExtensionManagerBus();
137        }
138    
139    }