You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by se...@apache.org on 2008/11/12 13:42:49 UTC

svn commit: r713355 [3/5] - in /cxf/sandbox/2.2.x-continuations: ./ api/ api/src/ api/src/main/ api/src/main/java/ api/src/main/java/org/ api/src/main/java/org/apache/ api/src/main/java/org/apache/cxf/ api/src/main/java/org/apache/cxf/continuations/ rt...

Added: cxf/sandbox/2.2.x-continuations/rt/core/src/main/java/org/apache/cxf/transport/http/WSDLQueryHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/core/src/main/java/org/apache/cxf/transport/http/WSDLQueryHandler.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/core/src/main/java/org/apache/cxf/transport/http/WSDLQueryHandler.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/core/src/main/java/org/apache/cxf/transport/http/WSDLQueryHandler.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,412 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.transport.http;
+
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.wsdl.Definition;
+import javax.wsdl.Import;
+import javax.wsdl.Port;
+import javax.wsdl.Service;
+import javax.wsdl.Types;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.schema.Schema;
+import javax.wsdl.extensions.schema.SchemaImport;
+import javax.wsdl.extensions.schema.SchemaReference;
+import javax.wsdl.extensions.soap.SOAPAddress;
+import javax.wsdl.extensions.soap12.SOAP12Address;
+import javax.wsdl.xml.WSDLWriter;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.xml.sax.InputSource;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.catalog.OASISCatalogManager;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.helpers.XMLUtils;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.transports.http.StemMatchingQueryHandler;
+import org.apache.cxf.wsdl.WSDLManager;
+import org.apache.cxf.wsdl11.ResourceManagerWSDLLocator;
+import org.apache.cxf.wsdl11.ServiceWSDLBuilder;
+
+
+public class WSDLQueryHandler implements StemMatchingQueryHandler {
+    private static final Logger LOG = LogUtils.getL7dLogger(WSDLQueryHandler.class, "QueryMessages");
+    private Bus bus;
+    
+    public WSDLQueryHandler() {
+    }
+    public WSDLQueryHandler(Bus b) {
+        bus = b;
+    }
+    
+    public String getResponseContentType(String baseUri, String ctx) {
+        if (baseUri.toLowerCase().contains("?wsdl")
+            || baseUri.toLowerCase().contains("?xsd=")) {
+            return "text/xml";
+        }
+        return null;
+    }
+
+    public boolean isRecognizedQuery(String baseUri, String ctx, 
+                                     EndpointInfo endpointInfo, boolean contextMatchExact) {
+        if (baseUri != null 
+            && (baseUri.contains("?") 
+                && (baseUri.toLowerCase().contains("wsdl")
+                || baseUri.toLowerCase().contains("xsd=")))) {
+            
+            int idx = baseUri.indexOf("?");
+            Map<String, String> map = UrlUtilities.parseQueryString(baseUri.substring(idx + 1));
+            if (map.containsKey("wsdl")
+                || map.containsKey("xsd")) {
+                if (contextMatchExact) {
+                    return endpointInfo.getAddress().contains(ctx);
+                } else {
+                    // contextMatchStrategy will be "stem"
+                    return endpointInfo.getAddress().
+                                contains(UrlUtilities.getStem(baseUri.substring(0, idx)));
+                }
+            }
+        }
+        return false;
+    }
+
+    public void writeResponse(String baseUri, String ctxUri,
+                              EndpointInfo endpointInfo, OutputStream os) {
+        try {
+            int idx = baseUri.toLowerCase().indexOf("?");
+            Map<String, String> params = UrlUtilities.parseQueryString(baseUri.substring(idx + 1));
+            String base = baseUri.substring(0, baseUri.toLowerCase().indexOf("?"));
+            String wsdl = params.get("wsdl");
+            String xsd =  params.get("xsd");
+            
+            Map<String, Definition> mp = CastUtils.cast((Map)endpointInfo.getService()
+                                                        .getProperty(WSDLQueryHandler.class.getName()));
+            Map<String, SchemaReference> smp = CastUtils.cast((Map)endpointInfo.getService()
+                                                        .getProperty(WSDLQueryHandler.class.getName() 
+                                                                     + ".Schemas"));
+
+            if (mp == null) {
+                endpointInfo.getService().setProperty(WSDLQueryHandler.class.getName(),
+                                                      new ConcurrentHashMap());
+                mp = CastUtils.cast((Map)endpointInfo.getService()
+                                    .getProperty(WSDLQueryHandler.class.getName()));
+            }
+            if (smp == null) {
+                endpointInfo.getService().setProperty(WSDLQueryHandler.class.getName()
+                                                      + ".Schemas",
+                                                      new ConcurrentHashMap());
+                smp = CastUtils.cast((Map)endpointInfo.getService()
+                                    .getProperty(WSDLQueryHandler.class.getName()
+                                                 + ".Schemas"));
+            }
+            
+            if (!mp.containsKey("")) {
+                Definition def = new ServiceWSDLBuilder(bus, endpointInfo.getService()).build();
+                mp.put("", def);
+                updateDefinition(def, mp, smp, base, endpointInfo);
+            }
+            
+            
+            Document doc;
+            if (xsd == null) {
+                Definition def = mp.get(wsdl);
+                if (def == null) {
+                    String wsdl2 = resolveWithCatalogs(OASISCatalogManager.getCatalogManager(bus),
+                                                       wsdl,
+                                                       base);
+                    if (wsdl2 != null) {
+                        def = mp.get(wsdl2);
+                    }
+                }
+                if (def == null) {
+                    throw new WSDLQueryException(new Message("WSDL_NOT_FOUND", LOG, wsdl), null);
+                }
+                
+                synchronized (def) {
+                    //writing a def is not threadsafe.  Sync on it to make sure
+                    //we don't get any ConcurrentModificationExceptions
+                    if (endpointInfo.getProperty("publishedEndpointUrl") != null) {
+                        String publishingUrl = 
+                            String.valueOf(endpointInfo.getProperty("publishedEndpointUrl"));
+                        updatePublishedEndpointUrl(publishingUrl, def, endpointInfo.getName());
+                    }
+        
+                    WSDLWriter wsdlWriter = bus.getExtension(WSDLManager.class)
+                        .getWSDLFactory().newWSDLWriter();
+                    def.setExtensionRegistry(bus.getExtension(WSDLManager.class).getExtensionRegistry());
+                    doc = wsdlWriter.getDocument(def);
+                }
+            } else {
+                SchemaReference si = smp.get(xsd);
+                if (si == null) {
+                    String xsd2 = resolveWithCatalogs(OASISCatalogManager.getCatalogManager(bus),
+                                                       xsd,
+                                                       base);
+                    if (xsd2 != null) { 
+                        si = smp.get(xsd2);
+                    }
+                }
+                if (si == null) {
+                    throw new WSDLQueryException(new Message("SCHEMA_NOT_FOUND", LOG, wsdl), null);
+                }
+                
+                String uri = si.getReferencedSchema().getDocumentBaseURI();
+                uri = resolveWithCatalogs(OASISCatalogManager.getCatalogManager(bus),
+                                          uri,
+                                          si.getReferencedSchema().getDocumentBaseURI());
+                if (uri == null) {
+                    uri = si.getReferencedSchema().getDocumentBaseURI();
+                }
+                ResourceManagerWSDLLocator rml = new ResourceManagerWSDLLocator(uri,
+                                                                                bus);
+                
+                InputSource src = rml.getBaseInputSource();
+                doc = XMLUtils.getParser().parse(src);
+            }
+            
+            updateDoc(doc, base, mp, smp);
+            String enc = doc.getXmlEncoding();
+            if (enc == null) {
+                enc = "utf-8";
+            }
+
+            XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(os,
+                                                                     enc);
+            StaxUtils.writeNode(doc, writer, true);
+            writer.flush();
+        } catch (WSDLQueryException wex) {
+            throw wex;
+        } catch (Exception wex) {
+            throw new WSDLQueryException(new Message("COULD_NOT_PROVIDE_WSDL",
+                                                     LOG,
+                                                     baseUri), wex);
+        }
+    }
+    
+    private void updateDoc(Document doc, String base,
+                           Map<String, Definition> mp,
+                           Map<String, SchemaReference> smp) {        
+        List<Element> elementList = DOMUtils.findAllElementsByTagNameNS(doc.getDocumentElement(),
+                                                                       "http://www.w3.org/2001/XMLSchema",
+                                                                       "import");
+        for (Element el : elementList) {
+            String sl = el.getAttribute("schemaLocation");
+            if (smp.containsKey(sl)) {
+                el.setAttribute("schemaLocation", base + "?xsd=" + sl);
+            }
+        }
+        
+        elementList = DOMUtils.findAllElementsByTagNameNS(doc.getDocumentElement(),
+                                                          "http://www.w3.org/2001/XMLSchema",
+                                                          "include");
+        for (Element el : elementList) {
+            String sl = el.getAttribute("schemaLocation");
+            if (smp.containsKey(sl)) {
+                el.setAttribute("schemaLocation", base + "?xsd=" + sl);
+            }
+        }
+        
+        elementList = DOMUtils.findAllElementsByTagNameNS(doc.getDocumentElement(),
+                                                          "http://schemas.xmlsoap.org/wsdl/",
+                                                          "import");
+        for (Element el : elementList) {
+            String sl = el.getAttribute("location");
+            if (mp.containsKey(sl)) {
+                el.setAttribute("location", base + "?wsdl=" + sl);
+            }
+        }
+        doc.setXmlStandalone(true);
+    }
+
+    static String resolveWithCatalogs(OASISCatalogManager catalogs, String start, String base) {
+        String resolvedSchemaLocation = null;
+        try {
+            resolvedSchemaLocation = catalogs.getCatalog().resolveSystem(start);
+            if (resolvedSchemaLocation == null) {
+                resolvedSchemaLocation = catalogs.getCatalog().resolveURI(start);
+            }
+            if (resolvedSchemaLocation == null) {
+                resolvedSchemaLocation = catalogs.getCatalog().resolvePublic(start, base);
+            }
+        } catch (Exception ex) {
+            //ignore
+        }
+        return resolvedSchemaLocation;
+    }
+    
+    protected void updateDefinition(Definition def, Map<String, Definition> done,
+                                  Map<String, SchemaReference> doneSchemas,
+                                  String base, EndpointInfo ei) {
+        OASISCatalogManager catalogs = OASISCatalogManager.getCatalogManager(bus);    
+        
+        Collection<List> imports = CastUtils.cast((Collection<?>)def.getImports().values());
+        for (List lst : imports) {
+            List<Import> impLst = CastUtils.cast(lst);
+            for (Import imp : impLst) {
+                String start = imp.getLocationURI();
+                String resolvedSchemaLocation = resolveWithCatalogs(catalogs, start, base);
+                
+                if (resolvedSchemaLocation == null) {
+                    try {
+                        //check to see if it's already in a URL format.  If so, leave it.
+                        new URL(start);
+                    } catch (MalformedURLException e) {
+                        if (done.put(start, imp.getDefinition()) == null) {
+                            updateDefinition(imp.getDefinition(), done, doneSchemas, base, ei);
+                        }
+                    }
+                } else {
+                    if (done.put(start, imp.getDefinition()) == null) {
+                        done.put(resolvedSchemaLocation, imp.getDefinition());
+                        updateDefinition(imp.getDefinition(), done, doneSchemas, base, ei);
+                    }
+                }
+            }
+        }      
+        
+        
+        /* This doesn't actually work.   Setting setSchemaLocationURI on the import
+        * for some reason doesn't actually result in the new URI being written
+        * */
+        Types types = def.getTypes();
+        if (types != null) {
+            for (ExtensibilityElement el 
+                : CastUtils.cast((List)types.getExtensibilityElements(), ExtensibilityElement.class)) {
+                if (el instanceof Schema) {
+                    Schema see = (Schema)el;
+                    updateSchemaImports(see, doneSchemas, base);
+                }
+            }
+        }
+    }    
+
+    protected void updatePublishedEndpointUrl(String publishingUrl, Definition def, QName name) {
+        Collection<Service> services = CastUtils.cast(def.getAllServices().values());
+        for (Service service : services) {
+            Collection<Port> ports = CastUtils.cast(service.getPorts().values());
+            if (ports.isEmpty()) {
+                continue;
+            }
+            
+            if (name == null) {
+                setSoapAddressLocationOn(ports.iterator().next(), publishingUrl);
+                break; // only update the first port since we don't target any specific port
+            } else {
+                for (Port port : ports) {
+                    if (name.getLocalPart().equals(port.getName())) {
+                        setSoapAddressLocationOn(port, publishingUrl);
+                    }
+                }
+            }
+        }
+    }
+    
+    private void setSoapAddressLocationOn(Port port, String url) {
+        List extensions = port.getExtensibilityElements();
+        for (Object extension : extensions) {
+            if (extension instanceof SOAP12Address) {
+                ((SOAP12Address)extension).setLocationURI(url);
+            } else if (extension instanceof SOAPAddress) {
+                ((SOAPAddress)extension).setLocationURI(url);
+            }
+        }
+    }
+    
+    protected void updateSchemaImports(Schema schema,
+                                           Map<String, SchemaReference> doneSchemas,
+                                           String base) {
+        OASISCatalogManager catalogs = OASISCatalogManager.getCatalogManager(bus);    
+        Collection<List>  imports = CastUtils.cast((Collection<?>)schema.getImports().values());
+        for (List lst : imports) {
+            List<SchemaImport> impLst = CastUtils.cast(lst);
+            for (SchemaImport imp : impLst) {
+                String start = imp.getSchemaLocationURI();
+                if (start != null && !doneSchemas.containsKey(start)) {
+                    String resolvedSchemaLocation = resolveWithCatalogs(catalogs, start, base);
+                    if (resolvedSchemaLocation == null) {
+                        try {
+                            //check to see if it's already in a URL format.  If so, leave it.
+                            new URL(start);
+                        } catch (MalformedURLException e) {
+                            if (doneSchemas.put(start, imp) == null) {
+                                updateSchemaImports(imp.getReferencedSchema(), doneSchemas, base);
+                            }
+                        }
+                    } else {
+                        if (doneSchemas.put(start, imp) == null) {
+                            doneSchemas.put(resolvedSchemaLocation, imp);
+                            updateSchemaImports(imp.getReferencedSchema(), doneSchemas, base);
+                        }
+                    }
+                }
+            }
+        }
+        List<SchemaReference> includes = CastUtils.cast(schema.getIncludes());
+        for (SchemaReference included : includes) {
+            String start = included.getSchemaLocationURI();
+
+            if (start != null) {
+                String resolvedSchemaLocation = resolveWithCatalogs(catalogs, start, base);
+                if (resolvedSchemaLocation == null) {
+                    if (!doneSchemas.containsKey(start)) {
+                        try {
+                            //check to see if it's aleady in a URL format.  If so, leave it.
+                            new URL(start);
+                        } catch (MalformedURLException e) {
+                            if (doneSchemas.put(start, included) == null) {
+                                updateSchemaImports(included.getReferencedSchema(), doneSchemas, base);
+                            }
+                        }
+                    }
+                } else if (!doneSchemas.containsKey(start) 
+                    || !doneSchemas.containsKey(resolvedSchemaLocation)) {
+                    doneSchemas.put(start, included);
+                    doneSchemas.put(resolvedSchemaLocation, included);
+                    updateSchemaImports(included.getReferencedSchema(), doneSchemas, base);
+                }
+            }
+        }
+    }
+    
+    public boolean isRecognizedQuery(String baseUri, String ctx, EndpointInfo endpointInfo) {
+        return isRecognizedQuery(baseUri, ctx, endpointInfo, false);
+    }
+
+    public void setBus(Bus bus) {
+        this.bus = bus;
+    }
+}

Propchange: cxf/sandbox/2.2.x-continuations/rt/core/src/main/java/org/apache/cxf/transport/http/WSDLQueryHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/core/src/main/java/org/apache/cxf/transport/http/WSDLQueryHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/pom.xml
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/pom.xml?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/pom.xml (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/pom.xml Wed Nov 12 04:42:46 2008
@@ -0,0 +1,146 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+ 
+  http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.cxf</groupId>
+    <artifactId>cxf-rt-transports-http-jetty</artifactId>
+    <packaging>jar</packaging>
+    <version>2.2-SNAPSHOT</version>
+    <name>Apache CXF Runtime HTTP Jetty Transport</name>
+    <url>http://cxf.apache.org</url>
+
+    <parent>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-parent</artifactId>
+        <version>2.2-SNAPSHOT</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymockclassextension</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-testutils</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-common-schemas</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty</artifactId>
+            <version>${jetty.version}</version>
+        </dependency>       
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+            <version>1.3.1</version>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-servlet_2.5_spec</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.cxf</groupId>
+                <artifactId>cxf-common-xsd</artifactId>
+                <version>${project.version}</version>
+                <executions>
+                    <execution>
+                        <id>generate-sources</id>
+                        <phase>generate-sources</phase>
+                        <configuration>
+                            <sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot>
+                            <xsdOptions>
+                                <xsdOption>
+                                    <xsd>${basedir}/src/main/resources/schemas/configuration/http-jetty.xsd</xsd>
+                                    <catalog>${basedir}/src/main/build-resources/catalog.cat</catalog>
+                                    <deleteDirs>
+                                        <deleteDir>${basedir}/target/generated/src/main/java/org/apache/cxf/wsdl</deleteDir>
+                                        <deleteDir>${basedir}/target/generated/src/main/java/org/apache/cxf/configuration/security</deleteDir>
+                                        <deleteDir>${basedir}/target/generated/src/main/java/org/apache/cxf/transports/http/configuration</deleteDir>
+                                    </deleteDirs>
+                                </xsdOption>
+                            </xsdOptions>
+                        </configuration>
+                        <goals>
+                            <goal>xsdtojava</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.apache.cxf</groupId>
+                        <artifactId>cxf-xjc-dv</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                    <dependency>
+                        <groupId>org.apache.cxf</groupId>
+                        <artifactId>cxf-common-utilities</artifactId>
+                        <version>${project.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/cxf/trunk/rt/transports/http-jetty</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/cxf/trunk/rt/transports/http-jetty</developerConnection>
+    </scm>
+
+</project>

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyConnectorFactory.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyConnectorFactory.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyConnectorFactory.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyConnectorFactory.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.transport.http_jetty;
+
+import org.mortbay.jetty.AbstractConnector;
+
+
+/**
+ * Encapsulates creation of Jetty listener.
+ */
+public interface JettyConnectorFactory {
+
+    /**
+     * Create a Listener.
+     * 
+     * @param port the listen port
+     */
+    AbstractConnector createConnector(int port);
+}

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyConnectorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyConnectorFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyContextInspector.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyContextInspector.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyContextInspector.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyContextInspector.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.transport.http_jetty;
+
+import org.apache.cxf.endpoint.ContextInspector;
+import org.mortbay.jetty.handler.ContextHandler;
+
+public class JettyContextInspector implements ContextInspector {
+    
+    public String getAddress(Object serverContext) {
+        if (ContextHandler.class.isAssignableFrom(serverContext.getClass())) {
+            return ((ContextHandler)serverContext).getContextPath();
+        } else {
+            return null;
+        }
+    }
+}

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyContextInspector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyContextInspector.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,357 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.transport.http_jetty;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.continuations.ContinuationInfo;
+import org.apache.cxf.continuations.ContinuationProvider;
+import org.apache.cxf.continuations.SuspendedInvocationException;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.http.AbstractHTTPDestination;
+import org.apache.cxf.transport.http.HTTPSession;
+import org.apache.cxf.transport.http_jetty.continuations.JettyContinuationProvider;
+import org.apache.cxf.transports.http.QueryHandler;
+import org.apache.cxf.transports.http.QueryHandlerRegistry;
+import org.apache.cxf.transports.http.StemMatchingQueryHandler;
+import org.mortbay.jetty.HttpConnection;
+import org.mortbay.jetty.Request;
+import org.mortbay.util.ajax.Continuation;
+import org.mortbay.util.ajax.ContinuationSupport;
+
+public class JettyHTTPDestination extends AbstractHTTPDestination {
+    
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(JettyHTTPDestination.class);
+
+    protected JettyHTTPServerEngine engine;
+    protected JettyHTTPTransportFactory transportFactory;
+    protected JettyHTTPServerEngineFactory serverEngineFactory;
+    protected ServletContext servletContext;
+    protected URL nurl;
+    
+    /**
+     * This variable signifies that finalizeConfig() has been called.
+     * It gets called after this object has been spring configured.
+     * It is used to automatically reinitialize things when resources
+     * are reset, such as setTlsServerParameters().
+     */
+    private boolean configFinalized;
+     
+    /**
+     * Constructor, using Jetty server engine.
+     * 
+     * @param b the associated Bus
+     * @param ci the associated conduit initiator
+     * @param endpointInfo the endpoint info of the destination
+     * @throws IOException
+     */
+    public JettyHTTPDestination(
+            Bus                       b,
+            JettyHTTPTransportFactory ci, 
+            EndpointInfo              endpointInfo
+    ) throws IOException {
+        
+        //Add the defualt port if the address is missing it
+        super(b, ci, endpointInfo, true);
+        this.transportFactory = ci;
+        this.serverEngineFactory = ci.getJettyHTTPServerEngineFactory();
+        nurl = new URL(endpointInfo.getAddress());
+    }
+
+    protected Logger getLogger() {
+        return LOG;
+    }
+    
+    public void setServletContext(ServletContext sc) {
+        servletContext = sc;
+    }
+    
+    /**
+     * Post-configure retreival of server engine.
+     */
+    protected void retrieveEngine()
+        throws GeneralSecurityException, 
+               IOException {
+        
+        engine = 
+            serverEngineFactory.retrieveJettyHTTPServerEngine(nurl.getPort());
+        if (engine == null) {
+            engine = serverEngineFactory.
+                createJettyHTTPServerEngine(nurl.getPort(), nurl.getProtocol());
+        }
+        
+        assert engine != null;
+        
+        // When configuring for "http", however, it is still possible that
+        // Spring configuration has configured the port for https. 
+        if (!nurl.getProtocol().equals(engine.getProtocol())) {
+            throw new IllegalStateException(
+                "Port " + engine.getPort() 
+                + " is configured with wrong protocol \"" 
+                + engine.getProtocol()
+                + "\" for \"" + nurl + "\"");
+        }
+    }
+    
+    /**
+     * This method is used to finalize the configuration
+     * after the configuration items have been set.
+     *
+     */
+    public void finalizeConfig() 
+        throws GeneralSecurityException,
+               IOException {
+        
+        assert !configFinalized;
+        
+        retrieveEngine();
+        configFinalized = true;
+    }
+    
+    /**
+     * Activate receipt of incoming messages.
+     */
+    protected void activate() {
+        LOG.log(Level.FINE, "Activating receipt of incoming messages");
+        URL url = null;
+        try {
+            url = new URL(endpointInfo.getAddress());
+        } catch (Exception e) {
+            throw new Fault(new Message("START_UP_SERVER_FAILED_MSG", LOG, e.getMessage()), e);
+        }
+        engine.addServant(url, 
+                          new JettyHTTPHandler(this, contextMatchOnExact()));
+    }
+
+    /**
+     * Deactivate receipt of incoming messages.
+     */
+    protected void deactivate() {
+        LOG.log(Level.FINE, "Deactivating receipt of incoming messages");
+        engine.removeServant(nurl);   
+    }   
+     
+
+    
+    protected String getBasePathForFullAddress(String addr) {
+        try {
+            return new URL(addr).getPath();
+        } catch (MalformedURLException e) {
+            return null;
+        }
+    }
+
+    private String removeTrailingSeparator(String addr) {
+        if (addr != null && addr.length() > 0 
+            && addr.lastIndexOf('/') == addr.length() - 1) {
+            return addr.substring(0, addr.length() - 1);
+        } else {
+            return addr;
+        }
+    }
+    
+    private synchronized String updateEndpointAddress(String addr) {
+        // only update the EndpointAddress if the base path is equal
+        // make sure we don't broke the get operation?parament query 
+        String address = removeTrailingSeparator(endpointInfo.getAddress());
+        if (getBasePathForFullAddress(address)
+            .equals(removeTrailingSeparator(getStem(getBasePathForFullAddress(addr))))) {
+            endpointInfo.setAddress(addr);
+        }
+        return address;
+    }
+   
+    protected void doService(HttpServletRequest req,
+                             HttpServletResponse resp) throws IOException {
+        doService(servletContext, req, resp);
+    }
+    protected void doService(ServletContext context,
+                             HttpServletRequest req,
+                             HttpServletResponse resp) throws IOException {
+        if (context == null) {
+            context = servletContext;
+        }
+        Request baseRequest = (req instanceof Request) 
+            ? (Request)req : HttpConnection.getCurrentConnection().getRequest();
+            
+        if (getServer().isSetRedirectURL()) {
+            resp.sendRedirect(getServer().getRedirectURL());
+            resp.flushBuffer();
+            baseRequest.setHandled(true);
+            return;
+        }
+        QueryHandlerRegistry queryHandlerRegistry = bus.getExtension(QueryHandlerRegistry.class);
+        
+        if (null != req.getQueryString() && queryHandlerRegistry != null) {   
+            String reqAddr = req.getRequestURL().toString();
+            String requestURL =  reqAddr + "?" + req.getQueryString();
+            String pathInfo = req.getPathInfo();                     
+            for (QueryHandler qh : queryHandlerRegistry.getHandlers()) {
+                boolean recognized =
+                    qh instanceof StemMatchingQueryHandler
+                    ? ((StemMatchingQueryHandler)qh).isRecognizedQuery(requestURL,
+                                                                       pathInfo,
+                                                                       endpointInfo,
+                                                                       contextMatchOnExact())
+                    : qh.isRecognizedQuery(requestURL, pathInfo, endpointInfo);
+                if (recognized) {
+                    //replace the endpointInfo address with request url only for get wsdl   
+                    synchronized (endpointInfo) {
+                        String oldAddress = updateEndpointAddress(reqAddr);   
+                        resp.setContentType(qh.getResponseContentType(requestURL, pathInfo));
+                        try {
+                            qh.writeResponse(requestURL, pathInfo, endpointInfo, resp.getOutputStream());
+                        } catch (Exception ex) {
+                            LOG.log(Level.WARNING, "writeResponse failed: ", ex);
+                            try {
+                                resp.sendError(500, ex.getMessage());
+                            } catch (IOException ioe) {
+                                //ignore
+                            }
+                        }
+                        endpointInfo.setAddress(oldAddress);
+                        resp.getOutputStream().flush();                     
+                        baseRequest.setHandled(true);
+                        return;    
+                    }
+                    
+                }
+            }
+        }
+
+        // REVISIT: service on executor if associated with endpoint
+        try {
+            BusFactory.setThreadDefaultBus(bus); 
+            serviceRequest(context, req, resp);
+        } finally {
+            BusFactory.setThreadDefaultBus(null);  
+        }    
+    }
+
+    protected void serviceRequest(final ServletContext context, 
+                                  final HttpServletRequest req, 
+                                  final HttpServletResponse resp)
+        throws IOException {
+        Request baseRequest = (req instanceof Request) 
+            ? (Request)req : HttpConnection.getCurrentConnection().getRequest();
+        
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Service http request on thread: " + Thread.currentThread());
+        }
+        MessageImpl inMessage = retrieveFromContinuation(req);
+        
+        
+        if (inMessage == null) {
+            
+            inMessage = new MessageImpl();
+            if (engine.getContinuationsEnabled()) {
+                inMessage.put(ContinuationProvider.class.getName(), 
+                          new JettyContinuationProvider(req, inMessage));
+            }
+            
+            setupMessage(inMessage, context, req, resp);
+            
+            inMessage.setDestination(this);
+    
+            ExchangeImpl exchange = new ExchangeImpl();
+            exchange.setInMessage(inMessage);
+            exchange.setSession(new HTTPSession(req));
+        }
+
+        try {    
+            incomingObserver.onMessage(inMessage);
+            
+            resp.flushBuffer();
+            baseRequest.setHandled(true);
+        } catch (SuspendedInvocationException ex) {
+            throw ex.getRuntimeException();
+        } catch (RuntimeException ex) {
+            throw ex;
+        } finally {
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Finished servicing http request on thread: " + Thread.currentThread());
+            }
+        }
+    }
+
+    protected MessageImpl retrieveFromContinuation(HttpServletRequest req) {
+        MessageImpl m = null;
+        
+        if (!engine.getContinuationsEnabled()) {
+            return null;
+        }
+        
+        Continuation cont = ContinuationSupport.getContinuation(req, null);
+        synchronized (cont) {
+            Object o = cont.getObject();
+            if (o instanceof ContinuationInfo) {
+                ContinuationInfo ci = (ContinuationInfo)o;
+                m = (MessageImpl)ci.getMessage();
+                
+                // now that we got the message we don't need ContinuationInfo
+                // as we don't know how continuation was suspended, by jetty wrapper
+                // or directly in which (latter) case we need to ensure that an original user object
+                // if any, need to be restored
+                cont.setObject(ci.getUserObject());
+            }
+            if (m == null && !cont.isNew()) {
+                String message = "No message for existing continuation, status : "
+                    + (cont.isPending() ? "Pending" : "Resumed");
+                if (!(o instanceof ContinuationInfo)) {
+                    message += ", ContinuationInfo object is unavailable";
+                }
+                LOG.warning(message);
+            }
+        }
+        
+        return m;
+    }
+    
+    @Override
+    public void shutdown() {
+        transportFactory.removeDestination(endpointInfo);
+        
+        super.shutdown();
+    }
+    
+    public ServerEngine getEngine() {
+        return engine;
+    }
+   
+    private String getStem(String baseURI) {    
+        return baseURI.substring(0, baseURI.lastIndexOf("/"));
+    }
+}

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPHandler.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPHandler.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPHandler.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPHandler.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.transport.http_jetty;
+
+import java.io.IOException;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.mortbay.jetty.handler.AbstractHandler;
+
+public class JettyHTTPHandler extends AbstractHandler {
+    private String urlName;
+    private boolean contextMatchExact;
+    private JettyHTTPDestination jettyHTTPDestination;
+    private ServletContext servletContext;
+
+    public JettyHTTPHandler(JettyHTTPDestination jhd, boolean cmExact) {
+        contextMatchExact = cmExact;
+        jettyHTTPDestination = jhd;
+    }
+
+    public void setServletContext(ServletContext sc) {
+        servletContext = sc;
+        if (jettyHTTPDestination != null) {
+            jettyHTTPDestination.setServletContext(sc);
+        }
+    }
+    public void setName(String name) {
+        urlName = name;
+    }
+
+    public String getName() {
+        return urlName;
+    }
+
+    boolean checkContextPath(String target) {
+        String pathString = urlName;
+        if (!pathString.endsWith("/")) {
+            pathString = pathString + "/";
+        }
+        return target.startsWith(pathString);
+    }
+
+    public void handle(String target, HttpServletRequest req,
+                       HttpServletResponse resp, int dispatch) throws IOException {
+        if (contextMatchExact) {
+            if (target.equals(urlName)) {
+                jettyHTTPDestination.doService(servletContext, req, resp);
+            }
+        } else {
+            if (target.equals(urlName) || checkContextPath(target)) {
+                jettyHTTPDestination.doService(servletContext, req, resp);
+            }
+        }
+    }
+
+
+
+}

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,615 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.transport.http_jetty;
+
+import java.io.IOException;
+import java.net.URL;
+
+import java.security.GeneralSecurityException;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.servlet.ServletContext;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.jsse.TLSServerParameters;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.transport.HttpUriMapper;
+import org.apache.cxf.transport.https_jetty.JettySslConnectorFactory;
+import org.mortbay.jetty.AbstractConnector;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.ContextHandler;
+import org.mortbay.jetty.handler.ContextHandlerCollection;
+import org.mortbay.jetty.handler.DefaultHandler;
+import org.mortbay.jetty.handler.HandlerList;
+import org.mortbay.jetty.nio.SelectChannelConnector;
+import org.mortbay.jetty.security.SslSocketConnector;
+import org.mortbay.jetty.servlet.HashSessionIdManager;
+import org.mortbay.jetty.servlet.HashSessionManager;
+import org.mortbay.jetty.servlet.SessionHandler;
+import org.mortbay.thread.BoundedThreadPool;
+
+
+/**
+ * This class is the Jetty HTTP Server Engine that is configured to
+ * work off of a designated port. The port will be enabled for 
+ * "http" or "https" depending upon its successful configuration.
+ */
+public class JettyHTTPServerEngine
+    implements ServerEngine {
+    private static final long serialVersionUID = 1L;
+    
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(JettyHTTPServerEngine.class);
+   
+
+    /**
+     * The bus.
+     */
+    private Bus bus;
+    
+    /**
+     * This is the Jetty HTTP Server Engine Factory. This factory caches some 
+     * engines based on port numbers.
+     */
+    private JettyHTTPServerEngineFactory factory;
+    
+    
+    /**
+     * This is the network port for which this engine is allocated.
+     */
+    private int port;
+    
+    /**
+     * This field holds the protocol for which this engine is 
+     * enabled, i.e. "http" or "https".
+     */
+    private String protocol = "http";    
+    
+    private Boolean isSessionSupport = false;
+    private Boolean isReuseAddress = true;
+    private Boolean continuationsEnabled = true;
+    private int servantCount;
+    private Server server;
+    private Connector connector;
+    private List<Handler> handlers;
+    private JettyConnectorFactory connectorFactory;
+    private ContextHandlerCollection contexts;
+    
+    
+    /**
+     * This field holds the TLS ServerParameters that are programatically
+     * configured. The tlsServerParamers (due to JAXB) holds the struct
+     * placed by SpringConfig.
+     */
+    private TLSServerParameters tlsServerParameters;
+    
+    /**
+     * This field hold the threading parameters for this particular engine.
+     */
+    private ThreadingParameters threadingParameters;
+    
+    /**
+     * This boolean signfies that SpringConfig is over. finalizeConfig
+     * has been called.
+     */
+    private boolean configFinalized;
+        
+    /**
+     * This constructor is called by the JettyHTTPServerEngineFactory.
+     */
+    public JettyHTTPServerEngine(
+        JettyHTTPServerEngineFactory fac, 
+        Bus bus,
+        int port) {
+        this.bus     = bus;
+        this.factory = fac;
+        this.port    = port;
+    }
+    
+    public JettyHTTPServerEngine() {
+        
+    }
+     
+    public void setJettyHTTPServerEngineFactory(JettyHTTPServerEngineFactory fac) {
+        factory = fac;
+    }
+    
+    public void setPort(int p) {
+        port = p;
+    }
+    
+    public void setContinuationsEnabled(boolean enabled) {
+        continuationsEnabled = enabled;
+    }
+    
+    public boolean getContinuationsEnabled() {
+        return continuationsEnabled;
+    }
+    
+    /**
+     * The bus.
+     */
+    @Resource(name = "cxf")
+    public void setBus(Bus b) {
+        bus = b;
+    }
+    
+    public Bus getBus() {
+        return bus;
+    }
+    
+    
+    /**
+     * Returns the protocol "http" or "https" for which this engine
+     * was configured.
+     */
+    public String getProtocol() {
+        return protocol;
+    }
+    
+    /**
+     * Returns the port number for which this server engine was configured.
+     * @return
+     */
+    public int getPort() {
+        return port;
+    }
+    
+    
+    /**
+     * This method will shut down the server engine and
+     * remove it from the factory's cache. 
+     */
+    public void shutdown() {
+        if (shouldDestroyPort()) {
+            if (factory != null && servantCount == 0) {
+                factory.destroyForPort(port);
+            } else {
+                LOG.log(Level.WARNING, "FAILED_TO_SHUTDOWN_ENGINE_MSG", port);
+            }
+        }
+    }
+    
+    private boolean shouldDestroyPort() {
+        //if we shutdown the port, on SOME OS's/JVM's, if a client
+        //in the same jvm had been talking to it at some point and keep alives
+        //are on, then the port is held open for about 60 seconds
+        //afterwards and if we restart, connections will then 
+        //get sent into the old stuff where there are 
+        //no longer any servant registered.   They pretty much just hang.
+        
+        //this is most often seen in our unit/system tests that 
+        //test things in the same VM.
+        
+        String s = System.getProperty("org.apache.cxf.transports.http_jetty.DontClosePort");
+        return !Boolean.valueOf(s);
+    }
+    
+    /**
+     * get the jetty server instance
+     * @return
+     */
+    public Server getServer() {
+        return server;
+    }
+    
+    /**
+     * Set the jetty server instance 
+     * @param s 
+     */
+    public void setServer(Server s) {
+        server = s;
+    }
+    
+    /**
+     * set the jetty server's connector
+     * @param c
+     */
+    public void setConnector(Connector c) {
+        connector = c;
+    }
+    
+    /**
+     * set the jetty server's handlers
+     * @param h
+     */
+    
+    public void setHandlers(List<Handler> h) {
+        handlers = h;
+    }
+    
+    public void setSessionSupport(boolean support) {
+        isSessionSupport = support;
+    }
+    
+    public boolean isSessionSupport() {
+        return isSessionSupport;
+    }
+    
+    public List<Handler> getHandlers() {
+        return handlers;
+    }
+    
+    public Connector getConnector() {
+        return connector;
+    }
+    
+    public boolean isReuseAddress() {
+        return isReuseAddress;
+    }
+    
+    public void setReuseAddress(boolean reuse) {
+        isReuseAddress = reuse;
+    }
+    
+    /**
+     * Register a servant.
+     * 
+     * @param url the URL associated with the servant
+     * @param handler notified on incoming HTTP requests
+     */
+    public synchronized void addServant(URL url, JettyHTTPHandler handler) {
+        if (server == null) {
+            DefaultHandler defaultHandler = null;
+            // create a new jetty server instance if there is no server there            
+            server = new Server();
+            if (connector == null) {
+                connector = connectorFactory.createConnector(port);
+            } 
+            server.addConnector(connector);            
+            if (handlers != null && handlers.size() > 0) {
+                HandlerList handlerList = new HandlerList();
+                for (Handler h : handlers) {
+                    // filting the jetty default handler 
+                    // which should not be added at this point
+                    if (h instanceof DefaultHandler) {
+                        defaultHandler = (DefaultHandler) h;
+                    } else {
+                        handlerList.addHandler(h);
+                    }
+                }
+                server.addHandler(handlerList);
+            }
+            contexts = new ContextHandlerCollection();
+            server.addHandler(contexts);
+            if (defaultHandler != null) {
+                server.addHandler(defaultHandler);
+            }
+            try {                
+                setReuseAddress(connector);
+                server.start();
+               
+                AbstractConnector aconn = (AbstractConnector) connector;
+                if (aconn.getThreadPool() instanceof BoundedThreadPool
+                    && isSetThreadingParameters()) {
+                    BoundedThreadPool pool = (BoundedThreadPool)aconn.getThreadPool();
+                    if (getThreadingParameters().isSetMinThreads()) {
+                        pool.setMinThreads(getThreadingParameters().getMinThreads());
+                    }
+                    if (getThreadingParameters().isSetMaxThreads()) {
+                        pool.setMaxThreads(getThreadingParameters().getMaxThreads());
+                    }
+                }
+            } catch (Exception e) {
+                LOG.log(Level.SEVERE, "START_UP_SERVER_FAILED_MSG", new Object[] {e.getMessage()});
+                //problem starting server
+                try {                    
+                    server.stop();
+                    server.destroy();
+                } catch (Exception ex) {
+                    //ignore - probably wasn't fully started anyway
+                }
+                server = null;
+                throw new Fault(new Message("START_UP_SERVER_FAILED_MSG", LOG, e.getMessage()), e);
+            }
+        }        
+        
+        String contextName = HttpUriMapper.getContextName(url.getPath());            
+        ContextHandler context = new ContextHandler();
+        context.setContextPath(contextName);
+        
+        // bind the jetty http handler with the context handler        
+        context.setHandler(handler);
+        if (isSessionSupport) {            
+            HashSessionManager sessionManager = new HashSessionManager();
+            SessionHandler sessionHandler = new SessionHandler(sessionManager);
+            HashSessionIdManager idManager = new HashSessionIdManager();
+            sessionManager.setIdManager(idManager);            
+            context.addHandler(sessionHandler);           
+        }
+        contexts.addHandler(context);
+        
+        ServletContext sc = context.getServletContext();
+        handler.setServletContext(sc);
+       
+        final String smap = HttpUriMapper.getResourceBase(url.getPath());
+        handler.setName(smap);
+        
+        if (contexts.isStarted()) {           
+            try {                
+                context.start();
+            } catch (Exception ex) {
+                LOG.log(Level.WARNING, "ADD_HANDLER_FAILED_MSG", new Object[] {ex.getMessage()});
+            }
+        }
+        
+            
+        ++servantCount;
+    }
+    
+    private void setReuseAddress(Connector conn) throws IOException {
+        if (conn instanceof AbstractConnector) {
+            ((AbstractConnector)conn).setReuseAddress(isReuseAddress());
+        } else {
+            LOG.log(Level.INFO, "UNKNOWN_CONNECTOR_MSG", new Object[] {conn});
+        }
+    }
+
+    /**
+     * Remove a previously registered servant.
+     * 
+     * @param url the URL the servant was registered against.
+     */
+    public synchronized void removeServant(URL url) {        
+        
+        final String contextName = HttpUriMapper.getContextName(url.getPath());
+        final String smap = HttpUriMapper.getResourceBase(url.getPath());
+        boolean found = false;
+        
+        if (server != null && server.isRunning()) {
+            for (Handler handler : contexts.getChildHandlersByClass(ContextHandler.class)) {
+                ContextHandler contextHandler = null;                
+                if (handler instanceof ContextHandler) {
+                    contextHandler = (ContextHandler) handler;
+                    Handler jh = contextHandler.getHandler();
+                    if (jh instanceof JettyHTTPHandler
+                        && contextName.equals(contextHandler.getContextPath())
+                        && ((JettyHTTPHandler)jh).getName().equals(smap)) {
+                        try {
+                            contexts.removeHandler(handler);                            
+                            handler.stop();
+                            handler.destroy();
+                        } catch (Exception ex) {
+                            LOG.log(Level.WARNING, "REMOVE_HANDLER_FAILED_MSG", 
+                                    new Object[] {ex.getMessage()}); 
+                        }
+                        found = true;
+                        break;                        
+                    }                    
+                }
+            }
+        }
+        if (!found) {
+            LOG.log(Level.WARNING, "CAN_NOT_FIND_HANDLER_MSG", new Object[]{url});
+        }
+        
+        --servantCount;
+       
+    }
+
+    /**
+     * Get a registered servant.
+     * 
+     * @param url the associated URL
+     * @return the HttpHandler if registered
+     */
+    public synchronized Handler getServant(URL url)  {
+        String contextName = HttpUriMapper.getContextName(url.getPath());       
+        //final String smap = HttpUriMapper.getResourceBase(url.getPath());
+        
+        Handler ret = null;
+        // After a stop(), the server is null, and therefore this 
+        // operation should return null.
+        if (server != null) {           
+            for (Handler handler : server.getChildHandlersByClass(ContextHandler.class)) {
+                ContextHandler contextHandler = null;
+                if (handler instanceof ContextHandler) {
+                    contextHandler = (ContextHandler) handler;
+                    if (contextName.equals(contextHandler.getContextPath())) {           
+                        ret = contextHandler.getHandler();
+                        break;
+                    }
+                }
+            }    
+        }
+        return ret;
+    }
+    
+    /**
+     * Get a registered context handler.
+     * 
+     * @param url the associated URL
+     * @return the HttpHandler if registered
+     */
+    public synchronized ContextHandler getContextHandler(URL url) {
+        String contextName = HttpUriMapper.getContextName(url.getPath());
+        ContextHandler ret = null;
+        // After a stop(), the server is null, and therefore this 
+        // operation should return null.
+        if (server != null) {           
+            for (Handler handler : server.getChildHandlersByClass(ContextHandler.class)) {
+                ContextHandler contextHandler = null;
+                if (handler instanceof ContextHandler) {
+                    contextHandler = (ContextHandler) handler;
+                    if (contextName.equals(contextHandler.getContextPath())) {           
+                        ret = contextHandler;
+                        break;
+                    }
+                }
+            }    
+        }
+        return ret;
+    }
+
+    protected void retrieveListenerFactory() {
+        if (tlsServerParameters != null) {
+            if (null != connector && !(connector instanceof SslSocketConnector)) {
+                LOG.warning("Connector " + connector + " for JettyServerEngine Port " 
+                        + port + " does not support SSL connections.");
+                return;
+            }
+            connectorFactory = 
+                getHTTPSConnectorFactory(tlsServerParameters);            
+            protocol = "https";
+            
+        } else {
+            if (connector instanceof SslSocketConnector) {
+                throw new RuntimeException("Connector " + connector + " for JettyServerEngine Port " 
+                      + port + " does not support non-SSL connections.");
+            }
+            connectorFactory = getHTTPConnectorFactory();            
+            protocol = "http";
+        }
+        LOG.fine("Configured port " + port + " for \"" + protocol + "\".");
+    }
+
+    /**
+     * This method creates a connector factory. If there are TLS parameters
+     * then it creates a TLS enabled one.
+     */
+    protected JettyConnectorFactory getHTTPConnectorFactory() {
+        return new JettyConnectorFactory() {                     
+            public AbstractConnector createConnector(int porto) {
+                // now we just use the SelectChannelConnector as the default connector
+                SelectChannelConnector result = 
+                    new SelectChannelConnector();
+                
+                // Regardless the port has to equal the one
+                // we are configured for.
+                assert porto == port;                
+                
+                result.setPort(porto);
+                return result;
+            }
+        };
+    }
+    
+    /**
+     * This method creates a connector factory enabled with the JSSE
+     */
+    protected JettyConnectorFactory getHTTPSConnectorFactory(
+            TLSServerParameters tlsParams
+    ) {
+        return new JettySslConnectorFactory(tlsParams);
+    }
+    
+    /**
+     * This method is called after configure on this object.
+     */
+    @PostConstruct
+    public void finalizeConfig() 
+        throws GeneralSecurityException,
+               IOException {
+        retrieveEngineFactory();
+        retrieveListenerFactory();
+        checkConnectorPort();
+        this.configFinalized = true;
+    }
+    
+    private void retrieveEngineFactory() {
+        if (null != bus && null == factory) {
+            factory = bus.getExtension(JettyHTTPServerEngineFactory.class);
+        }        
+    }
+
+    private void checkConnectorPort() throws IOException {
+        if (null != connector && port != connector.getPort()) {
+            throw new IOException("Error: Connector port " + connector.getPort() + " does not match"
+                        + " with the server engine port " + port);
+        }
+    }
+    
+
+    
+    /**
+     * This method is called by the ServerEngine Factory to destroy the 
+     * listener.
+     *
+     */
+    protected void stop() throws Exception {
+        if (server != null) {
+            try {
+                connector.stop();
+                connector.close();            
+            } finally {         
+                server.stop();
+                server.destroy();
+                server = null;
+            }
+        }
+    }
+    
+    /**
+     * This method is used to programmatically set the TLSServerParameters.
+     * This method may only be called by the factory.
+     * @throws IOException 
+     */
+    public void setTlsServerParameters(TLSServerParameters params) throws IOException {
+        
+        tlsServerParameters = params;
+        if (this.configFinalized) {
+            this.retrieveListenerFactory();
+        }
+    }
+    
+    /**
+     * This method returns the programmatically set TLSServerParameters, not
+     * the TLSServerParametersType, which is the JAXB generated type used 
+     * in SpringConfiguration.
+     * @return
+     */
+    public TLSServerParameters getTlsServerParameters() {
+        return tlsServerParameters;
+    } 
+
+    /**
+     * This method sets the threading parameters for this particular 
+     * server engine.
+     * This method may only be called by the factory.
+     */
+    public void setThreadingParameters(ThreadingParameters params) {        
+        threadingParameters = params;
+    }
+    
+    /**
+     * This method returns whether the threading parameters are set.
+     */
+    public boolean isSetThreadingParameters() {
+        return threadingParameters != null;
+    }
+    
+    /**
+     * This method returns the threading parameters that have been set.
+     * This method may return null, if the threading parameters have not
+     * been set.
+     */
+    public ThreadingParameters getThreadingParameters() {
+        return threadingParameters;
+    }
+    
+}

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngineFactory.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngineFactory.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngineFactory.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngineFactory.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,258 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.transport.http_jetty;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.buslifecycle.BusLifeCycleListener;
+import org.apache.cxf.buslifecycle.BusLifeCycleManager;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.configuration.jsse.TLSServerParameters;
+
+
+
+
+/**
+ * This Bus Extension handles the configuration of network port
+ * numbers for use with "http" or "https". This factory 
+ * caches the JettyHTTPServerEngines so that they may be 
+ * retrieved if already previously configured.
+ */
+public class JettyHTTPServerEngineFactory implements BusLifeCycleListener {
+    private static final Logger LOG =
+        LogUtils.getL7dLogger(JettyHTTPServerEngineFactory.class);    
+    
+    /**
+     * This map holds references for allocated ports.
+     */
+    // Still use the static map to hold the port information
+    // in the same JVM
+    private static Map<Integer, JettyHTTPServerEngine> portMap =
+        new HashMap<Integer, JettyHTTPServerEngine>();
+   
+    private BusLifeCycleManager lifeCycleManager;
+    /**
+     * This map holds the threading parameters that are to be applied
+     * to new Engines when bound to the reference id.
+     */
+    private Map<String, ThreadingParameters> threadingParametersMap =
+        new TreeMap<String, ThreadingParameters>();
+    
+    /**
+     * This map holds TLS Server Parameters that are to be used to
+     * configure a subsequently created JettyHTTPServerEngine.
+     */
+    private Map<String, TLSServerParameters> tlsParametersMap =
+        new TreeMap<String, TLSServerParameters>();
+    
+    
+    /**
+     * The bus.
+     */
+    private Bus bus;
+    
+    public JettyHTTPServerEngineFactory() {
+        // Empty
+    }    
+    
+    
+    /**
+     * This call is used to set the bus. It should only be called once.
+     * @param bus
+     */
+    @Resource(name = "cxf")
+    public void setBus(Bus bus) {
+        assert this.bus == null || this.bus == bus;
+        this.bus = bus;
+    }
+    
+    public Bus getBus() {
+        return bus;
+    }
+    
+    
+    @PostConstruct
+    public void registerWithBus() {
+        if (bus != null) {
+            bus.setExtension(this, JettyHTTPServerEngineFactory.class);
+        }
+        lifeCycleManager = bus.getExtension(BusLifeCycleManager.class);
+        if (null != lifeCycleManager) {
+            lifeCycleManager.registerLifeCycleListener(this);
+        }        
+    }
+    
+    
+    /**
+     * This call sets TLSParametersMap for a JettyHTTPServerEngine
+     * 
+     */
+    public void setTlsServerParametersMap(
+        Map<String, TLSServerParameters>  tlsParamsMap) {
+        
+        tlsParametersMap = tlsParamsMap;
+    }
+    
+    public Map<String, TLSServerParameters> getTlsServerParametersMap() {
+        return tlsParametersMap;
+    }
+    
+    public void setEnginesList(List<JettyHTTPServerEngine> enginesList) {
+        for (JettyHTTPServerEngine engine : enginesList) { 
+            portMap.put(engine.getPort(), engine);
+        }    
+    }
+    
+    /**
+     * This call sets the ThreadingParameters for a JettyHTTPServerEngine
+     * 
+     */
+    public void setThreadingParametersMap(
+        Map<String, ThreadingParameters> threadingParamsMap) {
+        
+        threadingParametersMap = threadingParamsMap;
+    }
+    
+    public Map<String, ThreadingParameters> getThreadingParametersMap() {
+        return threadingParametersMap;
+    }
+    
+    /**
+     * This call sets TLSServerParameters for a JettyHTTPServerEngine
+     * that will be subsequently created. It will not alter an engine
+     * that has already been created for that network port.
+     * @param port       The network port number to bind to the engine.
+     * @param tlsParams  The tls server parameters. Cannot be null.
+     * @throws IOException 
+     * @throws GeneralSecurityException 
+     */
+    public void setTLSServerParametersForPort(
+        int port, 
+        TLSServerParameters tlsParams) throws GeneralSecurityException, IOException {
+        if (tlsParams == null) {
+            throw new IllegalArgumentException("tlsParams cannot be null");
+        }
+        JettyHTTPServerEngine ref = retrieveJettyHTTPServerEngine(port);
+        if (null == ref) {
+            ref = new JettyHTTPServerEngine(this, bus, port);
+            ref.setTlsServerParameters(tlsParams);
+            portMap.put(port, ref);
+            ref.finalizeConfig();
+        } else {
+            if (ref.getConnector() != null && ref.getConnector().isRunning()) {
+                throw new IOException("can't set the TLS params on the opened connector");
+            }
+            ref.setTlsServerParameters(tlsParams);            
+        }
+    }
+            
+    
+    /**
+     * This call retrieves a previously configured JettyHTTPServerEngine for the
+     * given port. If none exists, this call returns null.
+     */
+    public synchronized JettyHTTPServerEngine retrieveJettyHTTPServerEngine(int port) {
+        return portMap.get(port);
+    }
+
+    /**
+     * This call creates a new JettyHTTPServerEngine initialized for "http"
+     * or "https" on the given port. The determination of "http" or "https"
+     * will depend on configuration of the engine's bean name.
+     * 
+     * If an JettyHTTPEngine already exists, or the port
+     * is already in use, a BindIOException will be thrown. If the 
+     * engine is being Spring configured for TLS a GeneralSecurityException
+     * may be thrown.
+     */
+    public synchronized JettyHTTPServerEngine createJettyHTTPServerEngine(int port, String protocol)
+        throws GeneralSecurityException, IOException {
+        LOG.fine("Creating Jetty HTTP Server Engine for port " + port + ".");        
+        JettyHTTPServerEngine ref = retrieveJettyHTTPServerEngine(port);
+        if (null == ref) {
+            ref = new JettyHTTPServerEngine(this, bus, port);            
+            portMap.put(port, ref);
+            ref.finalizeConfig();
+        } 
+        // checking the protocol    
+        if (!protocol.equals(ref.getProtocol())) {
+            throw new IOException("Protocol mismatch for port " + port + ": "
+                        + "engine's protocol is " + ref.getProtocol()
+                        + ", the url protocol is " + protocol);
+        }
+                
+        return ref;
+    }
+
+    
+    /**
+     * This method removes the Server Engine from the port map and stops it.
+     */
+    public synchronized void destroyForPort(int port) {
+        JettyHTTPServerEngine ref = portMap.remove(port);
+        if (ref != null) {
+            LOG.fine("Stopping Jetty HTTP Server Engine on port " + port + ".");
+            try {
+                ref.stop();
+            } catch (Exception e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }            
+        }
+    }
+
+    @PostConstruct
+    public void finalizeConfig() {
+        registerWithBus();
+    }
+
+    public void initComplete() {
+        // do nothing here
+        
+    }
+
+    public void postShutdown() {
+        //shut down the jetty server in the portMap
+        // To avoid the CurrentModificationException, 
+        // do not use portMap.vaules directly       
+        JettyHTTPServerEngine[] engines = portMap.values().toArray(new JettyHTTPServerEngine[0]);
+        for (JettyHTTPServerEngine engine : engines) {
+            engine.shutdown();
+        }
+        // clean up the collections
+        threadingParametersMap.clear();
+        tlsParametersMap.clear();
+    }
+
+    public void preShutdown() {
+        // do nothing here 
+        // just let server registry to call the server stop first
+    }
+    
+}

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngineFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngineFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPTransportFactory.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPTransportFactory.java?rev=713355&view=auto
==============================================================================
--- cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPTransportFactory.java (added)
+++ cxf/sandbox/2.2.x-continuations/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPTransportFactory.java Wed Nov 12 04:42:46 2008
@@ -0,0 +1,137 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.transport.http_jetty;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.imageio.IIOException;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.transport.http.AbstractHTTPTransportFactory;
+
+public class JettyHTTPTransportFactory extends AbstractHTTPTransportFactory
+    implements DestinationFactory {
+
+    private Map<String, JettyHTTPDestination> destinations = 
+        new ConcurrentHashMap<String, JettyHTTPDestination>();
+    
+    public JettyHTTPTransportFactory() {
+        super();
+    }
+    
+    @Resource(name = "cxf")
+    public void setBus(Bus b) {
+        super.setBus(b);
+    }
+
+    @PostConstruct
+    public void finalizeConfig() {
+        if (null == bus) {
+            return;
+        }
+        
+        if (getTransportIds() == null) {
+            setTransportIds(new ArrayList<String>(activationNamespaces));
+        }
+        if (activationNamespaces == null) {
+            activationNamespaces = getTransportIds();
+        }
+        DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class);
+        if (null != dfm && null != activationNamespaces) {
+            for (String ns : activationNamespaces) {
+                dfm.registerDestinationFactory(ns, this);
+            }
+        }
+
+        // This call will register the server engine factory
+        // with the Bus.
+        getJettyHTTPServerEngineFactory();
+    }
+    
+    /**
+     * This method returns the Jetty HTTP Server Engine Factory.
+     */
+    protected JettyHTTPServerEngineFactory getJettyHTTPServerEngineFactory() {
+        // We have got to *always* get this off the bus, because it may have 
+        // been overridden by Spring Configuration initially.
+        // Spring Configuration puts it on the correct bus.
+        JettyHTTPServerEngineFactory serverEngineFactory =
+                getBus().getExtension(JettyHTTPServerEngineFactory.class);
+        // If it's not there, then create it and register it.
+        // Spring may override it later, but we need it here for default
+        // with no spring configuration.
+        if (serverEngineFactory == null) {
+            serverEngineFactory = new JettyHTTPServerEngineFactory();
+            serverEngineFactory.setBus(getBus());
+            serverEngineFactory.finalizeConfig();
+        }
+        return serverEngineFactory;
+    }
+    
+    public Destination getDestination(EndpointInfo endpointInfo) 
+        throws IOException {
+        
+        String addr = endpointInfo.getAddress();
+        JettyHTTPDestination destination = addr == null ? null : destinations.get(addr);
+        if (destination == null) {
+            destination = createDestination(endpointInfo);
+        }
+           
+        return destination;
+    }
+    
+    private synchronized JettyHTTPDestination createDestination(
+        EndpointInfo endpointInfo
+    ) throws IOException {
+        
+        String addr = endpointInfo.getAddress();
+        JettyHTTPDestination destination = addr == null ? null : destinations.get(addr);
+        if (destination == null) {
+            destination = 
+                new JettyHTTPDestination(getBus(), this, endpointInfo);
+            
+            destinations.put(endpointInfo.getAddress(), destination);
+            
+            configure(destination);
+            try {
+                destination.finalizeConfig();
+            } catch (GeneralSecurityException ex) {
+                throw new IIOException("JSSE Security Exception ", ex);
+            }
+        }
+        return destination;
+    }
+    
+    /**
+     * This function removes the destination for a particular endpoint.
+     */
+    void removeDestination(EndpointInfo ei) {
+        destinations.remove(ei.getAddress());
+    }
+}