cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ff...@apache.org
Subject svn commit: r448031 - in /incubator/cxf/trunk/rt/frontend/jaxws/src/main: java/org/apache/cxf/jaxws/servlet/ resources/META-INF/
Date Wed, 20 Sep 2006 02:16:40 GMT
Author: ffang
Date: Tue Sep 19 19:16:39 2006
New Revision: 448031

URL: http://svn.apache.org/viewvc?view=rev&rev=448031
Log:
[JIRA CXF-68] get servlet working - phase 1

Added:
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
  (with props)
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
  (with props)
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
  (with props)
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
  (with props)
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
  (with props)
    incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml 
 (with props)

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java?view=auto&rev=448031
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
(added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,196 @@
+/**
+ * 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.jaxws.servlet;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+public abstract class AbstractCachedOutputStream extends OutputStream {
+
+    protected OutputStream currentStream;
+
+    private long threshold = 8 * 1024;
+
+    private int totalLength;
+
+    private boolean inmem;
+
+    private File tempFile;
+
+    private File outputDir;
+
+    public AbstractCachedOutputStream(PipedInputStream stream) throws IOException {
+        currentStream = new PipedOutputStream(stream);
+        inmem = true;
+    }
+
+    public AbstractCachedOutputStream() {
+        currentStream = new ByteArrayOutputStream();
+        inmem = true;
+    }
+
+    /**
+     * Perform any actions required on stream flush (freeze headers, reset
+     * output stream ... etc.)
+     */
+    protected abstract void doFlush() throws IOException;
+
+    public void flush() throws IOException {
+        currentStream.flush();
+        doFlush();
+    }
+
+    /**
+     * Perform any actions required on stream closure (handle response etc.)
+     */
+    protected abstract void doClose() throws IOException;
+
+    public void close() throws IOException {
+        currentStream.close();
+        doClose();
+    }
+
+    public boolean equals(Object obj) {
+        return currentStream.equals(obj);
+    }
+
+    /**
+     * Replace the original stream with the new one, when with Attachment, needs
+     * to replace the xml writer stream with the stream used by
+     * AttachmentSerializer Or Copy the cached output stream to the "real"
+     * output stream, i.e. onto the wire.
+     * 
+     * @param realOS
+     *            the real output stream
+     * @throws IOException
+     */
+    public void resetOut(OutputStream out, boolean copyOldContent) throws IOException {
+        ByteArrayOutputStream bout = (ByteArrayOutputStream) currentStream;
+        if (copyOldContent && bout.size() > 0) {
+            bout.writeTo(out);
+        }
+        currentStream = out;
+    }
+
+    /**
+     * @return the underlying output stream
+     */
+    public OutputStream getOut() {
+        return currentStream;
+    }
+
+    public int hashCode() {
+        return currentStream.hashCode();
+    }
+
+    public String toString() {
+        return currentStream.toString();
+    }
+
+    protected abstract void onWrite() throws IOException;
+
+    public void write(byte[] b, int off, int len) throws IOException {
+        onWrite();
+        this.totalLength += len;
+        if (inmem && totalLength > threshold) {
+            createFileOutputStream();
+        }
+        currentStream.write(b, off, len);
+    }
+
+    public void write(byte[] b) throws IOException {
+        onWrite();
+        this.totalLength += b.length;
+        if (inmem && totalLength > threshold) {
+            createFileOutputStream();
+        }
+        currentStream.write(b);
+    }
+
+    public void write(int b) throws IOException {
+        onWrite();
+        this.totalLength++;
+        if (inmem && totalLength > threshold) {
+            createFileOutputStream();
+        }
+        currentStream.write(b);
+    }
+
+    private void createFileOutputStream() throws IOException {
+        byte[] bytes = ((ByteArrayOutputStream) currentStream).toByteArray();
+        if (outputDir == null) {
+            tempFile = File.createTempFile("att", "tmp");
+        } else {
+            tempFile = File.createTempFile("att", "tmp", outputDir);
+        }
+        currentStream = new BufferedOutputStream(new FileOutputStream(tempFile));
+        currentStream.write(bytes);
+        inmem = false;
+    }
+
+    public File getTempFile() {
+        return tempFile;
+    }
+
+    public InputStream getInputStream() throws IOException {
+        if (inmem) {
+            if (currentStream instanceof ByteArrayOutputStream) {
+                return new ByteArrayInputStream(((ByteArrayOutputStream)currentStream).toByteArray());
+            } else if (currentStream instanceof PipedOutputStream) {
+                return new PipedInputStream((PipedOutputStream)currentStream);          
     
+            } else {
+                return null;
+            }
+        } else {
+            try {
+                return new FileInputStream(tempFile);
+            } catch (FileNotFoundException e) {
+                throw new IOException("Cached file was deleted, " + e.toString());
+            }
+        }
+    }
+
+    public void dispose() {
+        if (!inmem) {
+            tempFile.delete();
+        }
+    }
+
+    public void setOutputDir(File outputDir) throws IOException {
+        this.outputDir = outputDir;
+        createFileOutputStream();
+    }
+
+    public void setThreshold(long threshold) {
+        this.threshold = threshold;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractCachedOutputStream.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java?view=auto&rev=448031
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
(added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,45 @@
+/**
+ * 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.jaxws.servlet;
+
+
+import org.apache.cxf.message.Message;
+
+public abstract class AbstractWrappedOutputStream extends AbstractCachedOutputStream {
+
+    protected Message outMessage;
+    private boolean flushed;
+    
+    AbstractWrappedOutputStream(Message m) {
+        super();
+        outMessage = m;
+    }
+
+    /**
+     * @return true if already flushed
+     */
+    protected boolean alreadyFlushed() {
+        boolean ret = flushed;
+        flushed = true;
+        return ret;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/AbstractWrappedOutputStream.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java?view=auto&rev=448031
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
(added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,288 @@
+/**
+ * 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.jaxws.servlet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.WeakReference;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import org.apache.cxf.Bus;
+
+import org.apache.cxf.bus.CXFBusFactory;
+import org.apache.cxf.jaxws.EndpointImpl;
+import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
+import org.apache.cxf.jaxws.support.JaxwsImplementorInfo;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+import org.apache.cxf.wsdl.EndpointReferenceUtils;
+
+
+
+
+public class CXFServlet extends HttpServlet {
+    static final String HTTP_REQUEST =
+        CXFServlet.class.getName() + ".REQUEST";
+    static final String HTTP_RESPONSE =
+        CXFServlet.class.getName() + ".RESPONSE";
+    
+    static final Map<String, WeakReference<Bus>> BUS_MAP = new Hashtable<String,
WeakReference<Bus>>();
+    
+    protected Bus bus;
+    protected Map<String, ServletDestination> servantMap 
+        = new HashMap<String, ServletDestination>();
+    
+    
+    EndpointReferenceType reference;
+    ServletTransportFactory servletTransportFactory;
+    EndpointImpl ep;
+    EndpointInfo ei;
+    
+    public void init(ServletConfig servletConfig) throws ServletException {
+        super.init(servletConfig);
+        
+        List<String> list = new ArrayList<String>();
+        String busid = servletConfig.getInitParameter("bus.id");
+        if (null != busid) {
+            list.add("-BUSid");
+            list.add(busid);
+            WeakReference<Bus> ref = BUS_MAP.get(busid);
+            if (null != ref) {
+                bus = ref.get();
+            }
+        }
+        if (null == bus) {
+            //bus = Bus.init(list.toArray(new String[list.size()]));
+            bus = new CXFBusFactory().createBus();
+
+        }
+        if (null != busid) {
+            BUS_MAP.put(busid, new WeakReference<Bus>(bus));
+        }
+
+        InputStream ins = servletConfig.getServletContext()
+            .getResourceAsStream("/WEB-INF/cxf-servlet.xml");
+        if (ins != null) {
+            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
+            builderFactory.setNamespaceAware(true);
+            builderFactory.setValidating(false);
+            
+            
+            try {
+                Document doc = builderFactory.newDocumentBuilder().parse(ins);
+                Node nd = doc.getDocumentElement().getFirstChild();
+                while (nd != null) {
+                    if ("endpoint".equals(nd.getLocalName())) {
+                        loadEndpoint(servletConfig, nd);
+                    }
+                    nd = nd.getNextSibling();
+                }
+            } catch (SAXException ex) {
+                // TODO Auto-generated catch block
+                ex.printStackTrace();
+            } catch (IOException ex) {
+                // TODO Auto-generated catch block
+                ex.printStackTrace();
+            } catch (ParserConfigurationException ex) {
+                // TODO Auto-generated catch block
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    private void deregisterTransport(String transportId) {
+        bus.getExtension(DestinationFactoryManager.class).deregisterDestinationFactory(transportId);
       
+    }
+
+    /**
+     * @return
+     */
+    protected DestinationFactory createServletTransportFactory() {
+        if (servletTransportFactory == null) {
+            servletTransportFactory = new ServletTransportFactory(bus, reference);
+        }
+        return servletTransportFactory;
+    }
+
+    private void registerTransport(DestinationFactory factory, String namespace) {
+        bus.getExtension(DestinationFactoryManager.class).registerDestinationFactory(
+                                                                  namespace,
+                                                                  factory);
+    }
+
+    public void loadEndpoint(String implName,
+                             String serviceName,
+                             String wsdlName,
+                             String portName,
+                             String urlPat) {
+
+        try {
+            
+            URL url = null;
+            if (wsdlName != null) {
+                try {
+                    url = getServletConfig().getServletContext().getResource(wsdlName);
+                } catch (MalformedURLException ex) {
+                    try {
+                        url = new URL(wsdlName);
+                    } catch (MalformedURLException ex2) {
+                        try {
+                            url = getServletConfig().getServletContext().getResource("/"
+ wsdlName);
+                        } catch (MalformedURLException ex3) {
+                            url = null;
+                        }
+                    }
+                }
+            }
+            Class cls = Class.forName(implName, false, Thread.currentThread().getContextClassLoader());
+            Object impl = cls.newInstance();
+            reference = EndpointReferenceUtils
+                    .getEndpointReference(url,
+                                      QName.valueOf(serviceName),
+                                      portName);
+            
+
+            
+            ep = new EndpointImpl(bus, impl, url.toString());
+            replaceDestionFactory();
+//          doesn't really matter what URL is used here
+            ep.publish("http://localhost" + (urlPat.charAt(0) == '/' ? "" : "/") + urlPat);
+            JaxwsImplementorInfo implInfo = new JaxwsImplementorInfo(impl.getClass());
+            // build up the Service model
+            JaxWsServiceFactoryBean serviceFactory = new JaxWsServiceFactoryBean(implInfo);
+            serviceFactory.setBus(bus);
+            serviceFactory.setServiceClass(impl.getClass());
+            Service service = serviceFactory.create();
+
+            // create the endpoint        
+            QName endpointName = implInfo.getEndpointName();
+            ei = service.getServiceInfo().getEndpoint(endpointName);
+
+        } catch (ClassNotFoundException ex) {
+            ex.printStackTrace();
+        } catch (InstantiationException ex) {
+            ex.printStackTrace();
+        } catch (IllegalAccessException ex) {
+            ex.printStackTrace();
+        }    
+    }
+
+    private void replaceDestionFactory() {
+        DestinationFactory factory = createServletTransportFactory();
+        deregisterTransport("http://schemas.xmlsoap.org/wsdl/soap/");
+        deregisterTransport("http://schemas.xmlsoap.org/wsdl/soap/http");
+        deregisterTransport("http://schemas.xmlsoap.org/wsdl/http/");
+        deregisterTransport("http://celtix.objectweb.org/bindings/xmlformat");
+        deregisterTransport("http://celtix.objectweb.org/transports/http/configuration");
+        registerTransport(factory, "http://schemas.xmlsoap.org/wsdl/soap/");
+        registerTransport(factory, "http://schemas.xmlsoap.org/wsdl/soap/http");
+        registerTransport(factory, "http://schemas.xmlsoap.org/wsdl/http/");
+        registerTransport(factory, "http://celtix.objectweb.org/bindings/xmlformat");
+        registerTransport(factory, "http://celtix.objectweb.org/transports/http/configuration");
+    }
+
+    public void loadEndpoint(ServletConfig servletConfig, Node node) {
+        Element el = (Element)node;
+        String implName = el.getAttribute("implementation");
+        String serviceName = el.getAttribute("service");
+        String wsdlName = el.getAttribute("wsdl");
+        String portName = el.getAttribute("port");
+        String urlPat = el.getAttribute("url-pattern");
+        
+        loadEndpoint(implName, serviceName, wsdlName, portName, urlPat);
+    }
+
+    public void destroy() {
+        String s = bus.getId();
+        BUS_MAP.remove(s);
+        
+        bus.shutdown(true);
+    }
+    
+    void addServant(URL url, ServletDestination servant) {
+        servantMap.put(url.getPath(), servant);
+    }
+    void removeServant(URL url, ServletDestination servant) {
+        servantMap.remove(url.getPath());
+    }
+    
+    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws
ServletException {
+        System.out.println("do post is invoked");
+        try {
+            ((ServletDestination)ep.getServer().getDestination()).doService(request, response);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        /*ServletServerTransport tp = servantMap.get(request.getPathInfo());
+        if (tp == null) {
+            throw new ServletException("Unknown servlet mapping " + request.getPathInfo());
+        }
+        try {
+            tp.doPost(request, response);
+        } catch (IOException ex) {
+            throw new ServletException(ex.getMessage());
+        }*/
+    }
+
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException {
+        System.out.println("do get is invoked");
+        try {
+            ((ServletDestination)servletTransportFactory.
+                getDestination(ei)).doService(request, response);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        /*ServletServerTransport tp = servantMap.get(request.getPathInfo());
+        if (tp == null) {
+            throw new ServletException("Unknown servlet mapping " + request.getPathInfo());
+        }
+        try {
+            tp.doGet(request, response);
+        } catch (IOException ex) {
+            throw new ServletException(ex.getMessage());
+        }*/
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/CXFServlet.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java?view=auto&rev=448031
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
(added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,471 @@
+/**
+ * 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.jaxws.servlet;
+
+
+
+
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.wsdl.Definition;
+import javax.wsdl.Port;
+import javax.wsdl.extensions.ExtensibilityElement;
+import javax.wsdl.extensions.soap.SOAPAddress;
+import javax.wsdl.factory.WSDLFactory;
+import javax.wsdl.xml.WSDLWriter;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.configuration.security.AuthorizationPolicy;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.transport.ConduitInitiator;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.MessageObserver;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+
+
+import org.apache.cxf.wsdl11.ServiceWSDLBuilder;
+import org.xmlsoap.schemas.wsdl.http.AddressType;
+
+
+public class ServletDestination implements Destination {
+
+    public static final String HTTP_REQUEST =
+        ServletDestination.class.getName() + ".REQUEST";
+    public static final String HTTP_RESPONSE =
+        ServletDestination.class.getName() + ".RESPONSE"; 
+    
+    static final Logger LOG = Logger.getLogger(ServletDestination.class.getName());
+        
+    private static final long serialVersionUID = 1L;        
+
+    protected final Bus bus;
+    protected final ConduitInitiator conduitInitiator;
+    //protected final HTTPDestinationConfiguration config;
+    protected final EndpointInfo endpointInfo;
+    protected final EndpointReferenceType reference;
+    protected String name;
+    protected URL nurl;
+    protected MessageObserver incomingObserver;
+    
+    
+    /**
+     * Constructor, allowing subsititution of configuration.
+     * 
+     * @param b the associated Bus
+     * @param ci the associated conduit initiator
+     * @param ei the endpoint info of the destination 
+     * @param cfg the configuration
+     * @throws IOException
+     */    
+    public ServletDestination(Bus b,
+                              ConduitInitiator ci,
+                              EndpointInfo ei,
+                              EndpointReferenceType ref)
+        throws IOException {
+        bus = b;
+        conduitInitiator = ci;
+        endpointInfo = ei;
+        
+        reference = ref;
+        
+        // get url (publish address) from endpoint reference
+        /*nurl = new URL(EndpointReferenceUtils.getAddress(ref));
+        
+        
+        name = nurl.getPath();*/
+
+        
+    }
+
+    /**
+     * @return the reference associated with this Destination
+     */    
+    public EndpointReferenceType getAddress() {
+        return reference;
+    }
+
+    /**
+     * Cache HTTP headers in message.
+     * 
+     * @param message the current message
+     */
+    protected void setHeaders(Message message) {
+        Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
+        copyRequestHeaders(message, requestHeaders);
+        message.put(Message.PROTOCOL_HEADERS, requestHeaders);
+
+        if (requestHeaders.containsKey("Authorization")) {
+            List<String> authorizationLines = requestHeaders.get("Authorization");

+            String credentials = authorizationLines.get(0);
+            String authType = credentials.split(" ")[0];
+            if ("Basic".equals(authType)) {
+                String authEncoded = credentials.split(" ")[1];
+                try {
+                    String authDecoded = new String(Base64Utility.decode(authEncoded));
+                    String authInfo[] = authDecoded.split(":");
+                    String username = authInfo[0];
+                    String password = authInfo[1];
+                    
+                    AuthorizationPolicy policy = new AuthorizationPolicy();
+                    policy.setUserName(username);
+                    policy.setPassword(password);
+                    
+                    message.put(AuthorizationPolicy.class, policy);
+                } catch (Base64Exception ex) {
+                    //ignore, we'll leave things alone.  They can try decoding it themselves
+                }
+            }
+        }
+           
+    }
+    
+    @SuppressWarnings("unchecked")
+    protected void updateResponseHeaders(Message message) {
+        Map<String, List<String>> responseHeaders =
+            (Map<String, List<String>>)message.get(Message.PROTOCOL_HEADERS);
+        if (responseHeaders == null) {
+            responseHeaders = new HashMap<String, List<String>>();
+            message.put(Message.PROTOCOL_HEADERS, responseHeaders);         
+        }
+    }
+    
+
+
+    /**
+     * Register a message observer for incoming messages.
+     * 
+     * @param observer the observer to notify on receipt of incoming
+     */
+    public synchronized void setMessageObserver(MessageObserver observer) {
+        incomingObserver = observer;
+    }
+    
+    /**
+     * Retreive a back-channel Conduit, which must be policy-compatible
+     * with the current Message and associated Destination. For example
+     * compatible Quality of Protection must be asserted on the back-channel.
+     * This would generally only be an issue if the back-channel is decoupled.
+     * 
+     * @param inMessage the current inbound message (null to indicate a 
+     * disassociated back-channel)
+     * @param partialResponse in the decoupled case, this is expected to be the
+     * outbound Message to be sent over the in-built back-channel. 
+     * @param address the backchannel address (null to indicate anonymous)
+     * @return a suitable Conduit
+     */
+    public Conduit getBackChannel(Message inMessage,
+                                  Message partialResponse,
+                                  EndpointReferenceType address) throws IOException {
+        HttpServletResponse response = (HttpServletResponse)inMessage.get(HTTP_RESPONSE);
+        Conduit backChannel = null;
+        if (address == null) {
+            backChannel = new BackChannelConduit(address, response);
+        } else {
+            if (partialResponse != null) {
+                // setup the outbound message to for 202 Accepted
+                partialResponse.put(Message.RESPONSE_CODE,
+                                    HttpURLConnection.HTTP_ACCEPTED);
+                backChannel = new BackChannelConduit(address, response);
+            } else {
+                backChannel = conduitInitiator.getConduit(endpointInfo, address);
+                // ensure decoupled back channel input stream is closed
+                backChannel.setMessageObserver(new MessageObserver() {
+                    public void onMessage(Message m) {
+                        if (m.getContentFormats().contains(InputStream.class)) {
+                            InputStream is = m.getContent(InputStream.class);
+                            try {
+                                is.close();
+                            } catch (Exception e) {
+                                // ignore
+                            }
+                        }
+                    }
+                });
+            }
+        }
+        return backChannel;
+    }
+
+    /**
+     * Shutdown the Destination, i.e. stop accepting incoming messages.
+     */
+    public void shutdown() {  
+    }
+        
+    /**
+     * Copy the request headers into the message.
+     * 
+     * @param message the current message
+     * @param headers the current set of headers
+     */
+    protected void copyRequestHeaders(Message message,
+                                      Map<String, List<String>> headers) {
+        
+    }
+    
+    /**
+     * Copy the response headers into the response.
+     * 
+     * @param message the current message
+     * @param headers the current set of headers
+     */
+    protected void copyResponseHeaders(Message message, HttpServletResponse response) {
+    }
+    
+    protected void doService(HttpServletRequest req, HttpServletResponse resp)
+        throws IOException {
+          
+         
+        if ("GET".equals(req.getMethod())) {
+            doGet(req, resp);
+        } else {
+            doPost(req, resp);
+        }
+        
+        
+        // REVISIT: service on executor if associated with endpoint
+        //serviceRequest(req, resp);
+    }
+    
+    private void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
+        try {
+            if (LOG.isLoggable(Level.INFO)) {
+                LOG.info("Service http request on thread: " + Thread.currentThread());
+            }
+            
+            MessageImpl inMessage = new MessageImpl();
+            inMessage.setContent(InputStream.class, req.getInputStream());
+            inMessage.put(HTTP_REQUEST, req);
+            inMessage.put(HTTP_RESPONSE, resp);
+            inMessage.put(Message.HTTP_REQUEST_METHOD, req.getMethod());
+            inMessage.put(Message.PATH_INFO, req.getPathInfo());
+            inMessage.put(Message.QUERY_STRING, req.getQueryString());
+
+            setHeaders(inMessage);
+            
+            inMessage.setDestination(this);            
+            
+            
+            incomingObserver.onMessage(inMessage);
+            
+        } finally {
+            if (LOG.isLoggable(Level.INFO)) {
+                LOG.info("Finished servicing http request on thread: " + Thread.currentThread());
+            }
+        }
+        
+    }
+
+    private void doGet(HttpServletRequest req, HttpServletResponse resp) {
+        try {
+                        
+            
+            resp.setHeader("Content-Type", "text/xml");
+            
+            OutputStream os = resp.getOutputStream();
+            
+            WSDLWriter wsdlWriter = WSDLFactory.newInstance().newWSDLWriter();
+            Definition def = 
+                ServiceWSDLBuilder.getServiceWSDLBuilder().buildDefinition(endpointInfo.getService());
+            Port port = def.getService(
+                                       endpointInfo.getService().getName()).getPort(
+                                       endpointInfo.getName().getLocalPart());
+            List<?> exts = port.getExtensibilityElements();
+            if (exts.size() > 0) {
+                ExtensibilityElement el = (ExtensibilityElement)exts.get(0);
+                if (el instanceof SOAPAddress) {
+                    SOAPAddress add = (SOAPAddress)el;
+                    add.setLocationURI(req.getRequestURL().toString());
+                }
+                if (el instanceof AddressType) {
+                    AddressType add = (AddressType)el;
+                    add.setLocation(req.getRequestURL().toString());
+                }
+            }
+            
+            wsdlWriter.writeWSDL(def, os);
+            resp.getOutputStream().flush();
+            return;
+        } catch (Exception ex) {
+            
+            ex.printStackTrace();
+        }
+    }
+    
+    protected class BackChannelConduit implements Conduit {
+        
+        protected HttpServletResponse response;
+        protected EndpointReferenceType target;
+        
+        BackChannelConduit(EndpointReferenceType ref, HttpServletResponse resp) {
+            response = resp;
+            target = ref;
+        }
+        public void close(Message msg) throws IOException {
+            msg.getContent(OutputStream.class).close();        
+        }
+
+        /**
+         * Register a message observer for incoming messages.
+         * 
+         * @param observer the observer to notify on receipt of incoming
+         */
+        public void setMessageObserver(MessageObserver observer) {
+            // shouldn't be called for a back channel conduit
+        }
+
+        /**
+         * Send an outbound message, assumed to contain all the name-value
+         * mappings of the corresponding input message (if any). 
+         * 
+         * @param message the message to be sent.
+         */
+        public void send(Message message) throws IOException {
+            message.put(HTTP_RESPONSE, response);
+            message.setContent(OutputStream.class,
+                               new WrappedOutputStream(message, response));
+        }
+        
+        /**
+         * @return the reference associated with the target Destination
+         */    
+        public EndpointReferenceType getTarget() {
+            return target;
+        }
+        
+        /**
+         * Retreive the back-channel Destination.
+         * 
+         * @return the backchannel Destination (or null if the backchannel is
+         * built-in)
+         */
+        public Destination getBackChannel() {
+            return null;
+        }
+        
+        /**
+         * Close the conduit
+         */
+        public void close() {
+        }
+    }
+    
+    private class WrappedOutputStream extends AbstractWrappedOutputStream {
+        
+        protected HttpServletResponse response;
+        
+        WrappedOutputStream(Message m, HttpServletResponse resp) {
+            super(m);
+            response = resp;
+        }
+
+        /**
+         * Perform any actions required on stream flush (freeze headers,
+         * reset output stream ... etc.)
+         */
+        protected void doFlush() throws IOException {
+            OutputStream responseStream = flushHeaders(outMessage);
+            if (null != responseStream && !alreadyFlushed()) {
+                resetOut(responseStream, true);
+            }
+        }
+
+        /**
+         * Perform any actions required on stream closure (handle response etc.)
+         */
+        protected void doClose() {
+            commitResponse();
+        }
+
+        protected void onWrite() throws IOException {            
+        }
+        
+        private void commitResponse() {
+            try {
+                response.flushBuffer();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    protected OutputStream flushHeaders(Message outMessage) throws IOException {
+        updateResponseHeaders(outMessage);
+        Object responseObj = outMessage.get(HTTP_RESPONSE);
+        OutputStream responseStream = null;
+        if (responseObj instanceof HttpServletResponse) {
+            HttpServletResponse response = (HttpServletResponse)responseObj;
+                
+            Integer i = (Integer)outMessage.get(Message.RESPONSE_CODE);
+            if (i != null) {
+                int status = i.intValue();
+                if (status == HttpURLConnection.HTTP_INTERNAL_ERROR) {
+                    response.setStatus(status, "Fault Occurred");
+                } else if (status == HttpURLConnection.HTTP_ACCEPTED) {
+                    response.setStatus(status, "Accepted");
+                } else {
+                    response.setStatus(status);
+                }
+            } else {
+                response.setStatus(HttpURLConnection.HTTP_OK);
+            }
+            
+            copyResponseHeaders(outMessage, response);
+            responseStream = response.getOutputStream();
+                    
+            if (isOneWay(outMessage)) {
+                response.flushBuffer();
+            }
+        } else {
+            LOG.log(Level.WARNING, "UNEXPECTED_RESPONSE_TYPE_MSG", responseObj.getClass());
+            throw new IOException("UNEXPECTED_RESPONSE_TYPE_MSG" + responseObj.getClass());
+        }
+    
+        if (isOneWay(outMessage)) {
+            outMessage.remove(HTTP_RESPONSE);
+        }
+        return responseStream;
+    }
+    
+    protected boolean isOneWay(Message message) {
+        Boolean oneway = (Boolean)message.get(org.apache.cxf.message.Message.ONEWAY_MESSAGE);
+        return oneway != null && oneway.booleanValue();
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletDestination.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java?view=auto&rev=448031
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
(added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
Tue Sep 19 19:16:39 2006
@@ -0,0 +1,93 @@
+/**
+ * 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.jaxws.servlet;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.transport.ConduitInitiator;
+import org.apache.cxf.transport.ConduitInitiatorManager;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+
+public class ServletTransportFactory implements ConduitInitiator, DestinationFactory {
+
+    Bus bus;
+    EndpointReferenceType reference;
+    @Resource
+    Collection<String> activationNamespaces;
+    
+    
+    public ServletTransportFactory(Bus b, EndpointReferenceType ref) {
+        bus = b;
+            
+        reference = ref;
+    }
+
+    public ServletTransportFactory() {
+        // TODO Auto-generated constructor stub
+    }
+
+    @PostConstruct
+    void registerWithBindingManager() {
+        ConduitInitiatorManager cim = bus.getExtension(ConduitInitiatorManager.class);
+        for (String ns : activationNamespaces) {
+            cim.registerConduitInitiator(ns, this);
+        }
+        DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class);
+        for (String ns : activationNamespaces) {
+            dfm.registerDestinationFactory(ns, this);
+        }
+    }
+
+    public Conduit getConduit(EndpointInfo endpointInfo)
+        throws IOException {
+        return null;
+    }
+
+    public Conduit getConduit(EndpointInfo endpointInfo, EndpointReferenceType target)
+        throws IOException {
+        return null;
+    }
+
+    public Destination getDestination(EndpointInfo endpointInfo)
+        throws IOException {
+        return new ServletDestination(bus, null, endpointInfo, reference);
+    }
+
+    public Bus getBus() {
+        return bus;
+    }
+
+    @Resource
+    public void setBus(Bus bus) {
+        this.bus = bus;
+    }
+
+}

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/servlet/ServletTransportFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml?view=auto&rev=448031
==============================================================================
--- incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml (added)
+++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml Tue
Sep 19 19:16:39 2006
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<extensions xmlns="http://cxf.apache.org/bus/extension">
+
+    <extension class="org.apache.cxf.jaxws.servlet.ServletTransportFactory" deferred="true">
+        <namespace>http://schemas.xmlsoap.org/wsdl/servlet</namespace>
+    </extension>
+</extensions>

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: incubator/cxf/trunk/rt/frontend/jaxws/src/main/resources/META-INF/bus-extensions.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml



Mime
View raw message