cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a.@apache.org
Subject [2/2] git commit: refactor websocket (CXF-5339) into a seprate transport component
Date Mon, 10 Mar 2014 15:50:40 GMT
refactor websocket (CXF-5339) into a seprate transport component


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/8fe4fc13
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/8fe4fc13
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/8fe4fc13

Branch: refs/heads/master
Commit: 8fe4fc13a8652912315fae881aaf3066f823def5
Parents: c9c4430
Author: Akitoshi Yoshida <ay@apache.org>
Authored: Mon Mar 10 16:48:13 2014 +0100
Committer: Akitoshi Yoshida <ay@apache.org>
Committed: Mon Mar 10 16:49:53 2014 +0100

----------------------------------------------------------------------
 rt/pom.xml                                      |    1 +
 rt/transports/http-jetty/pom.xml                |    7 -
 .../http_jetty/JettyHTTPDestination.java        |   31 +-
 .../http_jetty/JettyHTTPExtendedHandler.java    |   60 -
 .../transport/http_jetty/JettyWebSocket.java    | 1085 -----------------
 .../transport/servlet/CXFNonSpringServlet.java  |    2 +-
 rt/transports/websocket/pom.xml                 |  168 +++
 .../websocket/WebSocketDestinationFactory.java  |   49 +
 .../websocket/WebSocketTransportFactory.java    |  135 +++
 .../jetty/CXFJettyWebSocketServlet.java         |  110 ++
 .../jetty/CXFJettyWebSocketServletService.java  |   33 +
 .../CXFNonSpringJettyWebSocketServlet.java      |  116 ++
 .../websocket/jetty/JettyWebSocket.java         | 1111 ++++++++++++++++++
 .../jetty/JettyWebSocketDestination.java        |   66 ++
 .../websocket/jetty/JettyWebSocketHandler.java  |   63 +
 .../websocket/jetty/JettyWebSocketManager.java  |  114 ++
 .../resources/META-INF/cxf/bus-extensions.txt   |    4 +
 .../WebSocketTransportFactoryTest.java          |   43 +
 .../jetty/JettyWebSocketManagerTest.java        |   84 ++
 systests/jaxrs/pom.xml                          |    5 +
 .../jaxrs/websocket/BookServerWebSocket.java    |   18 +-
 .../JAXRSClientServerWebSocketSpringTest.java   |   43 +
 ...RSClientServerWebSocketSpringWebAppTest.java |   65 +
 .../JAXRSClientServerWebSocketTest.java         |    9 +-
 .../resources/jaxrs_websocket/WEB-INF/beans.xml |   45 +
 .../resources/jaxrs_websocket/WEB-INF/web.xml   |   41 +
 .../jaxrs_websocket/beans-embedded.xml          |   45 +
 27 files changed, 2353 insertions(+), 1200 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/pom.xml
----------------------------------------------------------------------
diff --git a/rt/pom.xml b/rt/pom.xml
index 1a7b0ad..8472491 100644
--- a/rt/pom.xml
+++ b/rt/pom.xml
@@ -50,6 +50,7 @@
         <module>transports/http-netty/netty-client</module>
         <module>transports/jms</module>
         <module>transports/udp</module>
+        <module>transports/websocket</module>
         <module>ws/policy</module>
         <module>ws/addr</module>
         <module>ws/security</module>

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/http-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/rt/transports/http-jetty/pom.xml b/rt/transports/http-jetty/pom.xml
index cb2c4e3..06df9ca 100644
--- a/rt/transports/http-jetty/pom.xml
+++ b/rt/transports/http-jetty/pom.xml
@@ -34,7 +34,6 @@
         <cxf.bundle.activator>org.apache.cxf.transport.http_jetty.osgi.HTTPJettyTransportActivator</cxf.bundle.activator>
         <cxf.osgi.import>
             javax.servlet*;version="${cxf.osgi.javax.servlet.version}",
-            org.eclipse.jetty.websocket;version="${cxf.jetty.osgi.version}";resolution:=optional,
             org.eclipse.jetty*;version="${cxf.jetty.osgi.version}",
             org.apache.aries*;version="${cxf.aries.version.range}";resolution:=optional,
             org.springframework*;resolution:="optional";version="${cxf.osgi.spring.version}"
@@ -101,12 +100,6 @@
         </dependency>
         <dependency>
             <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-websocket</artifactId>
-            <version>${cxf.jetty.version}</version>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-jmx</artifactId>
             <version>${cxf.jetty.version}</version>
             <optional>true</optional>

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java
----------------------------------------------------------------------
diff --git a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java
index 02a678d..c82a9ba 100644
--- a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java
+++ b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPDestination.java
@@ -23,7 +23,6 @@ import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.security.GeneralSecurityException;
@@ -63,7 +62,6 @@ public class JettyHTTPDestination extends AbstractHTTPDestination {
     
     private static final Logger LOG =
         LogUtils.getL7dLogger(JettyHTTPDestination.class);
-    private static Constructor<?> handlerConstructor;
 
     protected JettyHTTPServerEngine engine;
     protected JettyHTTPServerEngineFactory serverEngineFactory;
@@ -71,17 +69,6 @@ public class JettyHTTPDestination extends AbstractHTTPDestination {
     protected URL nurl;
     protected ClassLoader loader;
 
-
-    static {
-        try {
-            Class<?> cls = ClassUtils.forName("org.apache.cxf.transport.http_jetty.JettyHTTPExtendedHandler",
-                                              JettyHTTPDestination.class.getClassLoader());
-            handlerConstructor = cls.getDeclaredConstructor(new Class<?>[]{JettyHTTPDestination.class, boolean.class});
-        } catch (Throwable t) {
-            //ignore
-        }
-    }
-    
     /**
      * This variable signifies that finalizeConfig() has been called.
      * It gets called after this object has been spring configured.
@@ -108,7 +95,7 @@ public class JettyHTTPDestination extends AbstractHTTPDestination {
         //Add the default port if the address is missing it
         super(bus, registry, ei, getAddressValue(ei, true).getAddress(), true);
         this.serverEngineFactory = serverEngineFactory;
-        nurl = new URL(endpointInfo.getAddress());
+        nurl = new URL(getAddress(endpointInfo));
         loader = bus.getExtension(ClassLoader.class);
     }
 
@@ -169,6 +156,10 @@ public class JettyHTTPDestination extends AbstractHTTPDestination {
         }
         configFinalized = true;
     }
+
+    protected String getAddress(EndpointInfo endpointInfo) {
+        return endpointInfo.getAddress();
+    }
     
     /**
      * Activate receipt of incoming messages.
@@ -178,7 +169,7 @@ public class JettyHTTPDestination extends AbstractHTTPDestination {
         LOG.log(Level.FINE, "Activating receipt of incoming messages");
         URL url = null;
         try {
-            url = new URL(endpointInfo.getAddress());
+            url = new URL(getAddress(endpointInfo));
         } catch (Exception e) {
             throw new Fault(e);
         }
@@ -188,16 +179,8 @@ public class JettyHTTPDestination extends AbstractHTTPDestination {
 
     }
 
-    private JettyHTTPHandler createJettyHTTPHandler(JettyHTTPDestination jhd,
+    protected JettyHTTPHandler createJettyHTTPHandler(JettyHTTPDestination jhd,
                                                     boolean cmExact) {
-        if (handlerConstructor != null) {
-            try {
-                return (JettyHTTPHandler)handlerConstructor.newInstance(new Object[]{jhd, cmExact});
-            } catch (Exception e) {
-                //ignore
-            }
-        }
-        // use the default handler
         return new JettyHTTPHandler(jhd, cmExact);
     }
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPExtendedHandler.java
----------------------------------------------------------------------
diff --git a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPExtendedHandler.java b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPExtendedHandler.java
deleted file mode 100644
index a15c5ff..0000000
--- a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPExtendedHandler.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * 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.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.websocket.WebSocket;
-import org.eclipse.jetty.websocket.WebSocketFactory;
-
-/**
- * The extended version of JettyHTTPHandler that can support websocket.
- */
-class JettyHTTPExtendedHandler extends JettyHTTPHandler implements WebSocketFactory.Acceptor {
-    private final WebSocketFactory webSocketFactory = new WebSocketFactory(this);
-
-    public JettyHTTPExtendedHandler(JettyHTTPDestination jhd, boolean cmExact) {
-        super(jhd, cmExact);
-    }
-
-    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
-        return new JettyWebSocket(jettyHTTPDestination, servletContext, request, protocol);
-    }
-    
-    @Override
-    public void handle(String target, Request baseRequest, HttpServletRequest request,
-                       HttpServletResponse response) throws IOException, ServletException {
-        // only switch to websocket if websocket is enabled for this destination 
-        if (jettyHTTPDestination != null && jettyHTTPDestination.isEnableWebSocket()
-            && (webSocketFactory.acceptWebSocket(request, response) || response.isCommitted())) {
-            baseRequest.setHandled(true);
-        } else {
-            super.handle(target, baseRequest, request, response);
-        }
-    }
-
-    public boolean checkOrigin(HttpServletRequest request, String protocol) {
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyWebSocket.java
----------------------------------------------------------------------
diff --git a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyWebSocket.java b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyWebSocket.java
deleted file mode 100644
index 247545d..0000000
--- a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyWebSocket.java
+++ /dev/null
@@ -1,1085 +0,0 @@
-/**
- * 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.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.security.Principal;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.servlet.AsyncContext;
-import javax.servlet.DispatcherType;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.Part;
-
-import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.helpers.CastUtils;
-import org.eclipse.jetty.websocket.WebSocket;
-
-class JettyWebSocket implements WebSocket.OnBinaryMessage, WebSocket.OnTextMessage {
-    private static final Logger LOG = LogUtils.getL7dLogger(JettyWebSocket.class);
-    private static final String CRLF = "\r\n";
-    
-    private JettyHTTPDestination jettyHTTPDestination;
-    private ServletContext servletContext;
-    private Connection webSocketConnection;
-    private Map<String, Object> requestProperties;
-    private String protocol;
-    
-    public JettyWebSocket(JettyHTTPDestination jettyHTTPDestination, ServletContext servletContext,
-                          HttpServletRequest request, String protocol) {
-        this.jettyHTTPDestination = jettyHTTPDestination;
-        this.servletContext = servletContext;
-        this.protocol = protocol;
-        this.requestProperties = readProperties(request);
-    }
-    
-    private Map<String, Object> readProperties(HttpServletRequest request) {
-        Map<String, Object> properties = new HashMap<String, Object>();
-        properties.put("servletPath", request.getServletPath());
-        properties.put("requestURI", request.getRequestURI());
-        properties.put("requestURL", request.getRequestURL().toString());
-        properties.put("contextPath", request.getContextPath());
-        properties.put("servletPath", request.getServletPath());
-        properties.put("pathInfo", request.getPathInfo());
-        properties.put("protocol", protocol);
-        // some additional ones
-        properties.put("localAddr", request.getLocalAddr());
-        properties.put("localName", request.getLocalName());
-        properties.put("localPort", request.getLocalPort());
-        properties.put("locale", request.getLocale());
-        properties.put("locales", request.getLocales());
-        properties.put("remoteHost", request.getRemoteHost());
-        properties.put("remoteAddr", request.getRemoteAddr());
-        properties.put("serverName", request.getServerName());
-        properties.put("secure", request.isSecure());
-        
-        return properties;
-    }
-
-    @Override
-    public void onClose(int closeCode, String message) {
-        if (LOG.isLoggable(Level.INFO)) {
-            LOG.log(Level.INFO, "onClose({0}, {1})", new Object[]{closeCode, message});
-        }
-    }
-
-    @Override
-    public void onOpen(Connection connection) {
-        if (LOG.isLoggable(Level.INFO)) {
-            LOG.log(Level.INFO, "onOpen({0}))", connection);
-        }
-        this.webSocketConnection = connection;
-    }
-
-    @Override
-    public void onMessage(String data) {
-        if (LOG.isLoggable(Level.INFO)) {
-            LOG.log(Level.INFO, "onMessage({0})", data);
-        }
-        try {
-            byte[] bdata = data.getBytes("utf-8");
-            jettyHTTPDestination.invoke(null, servletContext, 
-                                        createServletRequest(bdata, 0, bdata.length),
-                                        createServletResponse());
-        } catch (Exception e) {
-            LOG.log(Level.WARNING, "Failed to invoke service", e);
-        }            
-    }
-
-    @Override
-    public void onMessage(byte[] data, int offset, int length) {
-        if (LOG.isLoggable(Level.INFO)) {
-            LOG.log(Level.INFO, "onMessage({0}, {1}, {2})", new Object[]{data, offset, length});
-        }
-        try {
-            jettyHTTPDestination.invoke(null, servletContext, 
-                                        createServletRequest(data, offset, length),
-                                        createServletResponse());
-        } catch (Exception e) {
-            LOG.log(Level.WARNING, "Failed to invoke service", e);
-        }
-    }
-    
-    private <T> T getRequestProperty(String name, Class<T> cls) {
-        return getValue(requestProperties, name, cls);
-    }
-    
-    private WebSocketVirtualServletRequest createServletRequest(byte[] data, int offset, int length) 
-        throws IOException {
-        return new WebSocketVirtualServletRequest(servletContext, this, new ByteArrayInputStream(data, offset, length));
-    }
-
-    private WebSocketVirtualServletResponse createServletResponse() throws IOException {
-        return new WebSocketVirtualServletResponse(this);
-    }
-    
-    /**
-     * Writes to the underlining socket.
-     * 
-     * @param data
-     * @param offset
-     * @param length
-     */
-    void write(byte[] data, int offset, int length) throws IOException {
-        LOG.log(Level.INFO, "write(byte[], offset, length)");
-        webSocketConnection.sendMessage(data, offset, length);
-    }
-
-    private static byte[] buildResponse(Map<String, String> headers, byte[] data, int offset, int length) {
-        StringBuilder sb = new StringBuilder();
-        String v = headers.get("$sc");
-        sb.append(v == null ? "200" : v).append(CRLF);
-        v = headers.get("Content-Type");
-        if (v != null) {
-            sb.append("Content-Type: ").append(v).append(CRLF);
-        }
-        sb.append(CRLF);
-        
-        byte[] hb = sb.toString().getBytes();
-        byte[] longdata = new byte[hb.length + length];
-        System.arraycopy(hb, 0, longdata, 0, hb.length);
-        if (data != null && length > 0) {
-            System.arraycopy(data, offset, longdata, hb.length, length);
-        }
-        return longdata;
-    }
-
-    private static byte[] buildResponse(byte[] data, int offset, int length) {
-        byte[] longdata = new byte[length + 2];
-        longdata[0] = 0x0d;
-        longdata[1] = 0x0a;
-        System.arraycopy(data, offset, longdata, 2, length);
-        return longdata;
-    }
-    
-    ServletOutputStream getServletOutputStream(final Map<String, String> headers) {
-        LOG.log(Level.INFO, "getServletOutputStream()");
-        return new ServletOutputStream() {
-
-            @Override
-            public void write(int b) throws IOException {
-                byte[] data = new byte[1];
-                data[0] = (byte)b;
-                write(data, 0, 1);
-            }
-
-            @Override
-            public void write(byte[] data, int offset, int length) throws IOException {
-                if (headers.get("$flushed") == null) {
-                    data = buildResponse(headers, data, offset, length);
-                    headers.put("$flushed", "true");
-                } else {
-                    data = buildResponse(data, offset, length);
-                }
-                webSocketConnection.sendMessage(data, 0, data.length);
-            }
-        };
-    }
-    
-    OutputStream getOutputStream(final Map<String, String> headers) {
-        LOG.log(Level.INFO, "getServletOutputStream()");
-        return new OutputStream() {
-
-            @Override
-            public void write(int b) throws IOException {
-                byte[] data = new byte[1];
-                data[0] = (byte)b;
-                write(data, 0, 1);
-            }
-            
-            @Override
-            public void write(byte[] data, int offset, int length) throws IOException {
-                if (headers.get("$flushed") == null) {
-                    data = buildResponse(headers, data, offset, length);
-                    headers.put("$flushed", "true");
-                } else {
-                    data = buildResponse(data, offset, length);
-                }
-                webSocketConnection.sendMessage(data, 0, data.length);
-            }
-        };
-        
-    }
-   
-    // 
-    static class WebSocketVirtualServletRequest implements HttpServletRequest {
-        private ServletContext context;
-        private JettyWebSocket websocket;
-        private InputStream in;
-        private Map<String, String> requestHeaders;
-        
-        public WebSocketVirtualServletRequest(ServletContext context, JettyWebSocket websocket, InputStream in) 
-            throws IOException {
-            this.context = context;
-            this.websocket = websocket;
-            this.in = in;
-
-            requestHeaders = readHeaders(in);
-            String path = requestHeaders.get("$path");
-            String origin = websocket.getRequestProperty("requestURI", String.class);
-            if (path.startsWith(origin)) {
-                //REVISIT for now, log it here and reject the request later.  
-                LOG.log(Level.WARNING, "invalid path: {0} not within {1}", new Object[]{path, origin});
-            }
-        }
-
-        @Override
-        public AsyncContext getAsyncContext() {
-            return null;
-        }
-
-        @Override
-        public Object getAttribute(String name) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "getAttribute({0})", name);
-            }
-            return null;
-        }
-
-        @Override
-        public Enumeration<String> getAttributeNames() {
-            LOG.log(Level.INFO, "getAttributeNames()");
-            return null;
-        }
-
-        @Override
-        public String getCharacterEncoding() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getCharacterEncoding()");
-            return null;
-        }
-
-        @Override
-        public int getContentLength() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getContentLength()");
-            return 0;
-        }
-
-        @Override
-        public String getContentType() {
-            LOG.log(Level.INFO, "getContentType()");
-            return requestHeaders.get("Content-Type");
-        }
-
-        @Override
-        public DispatcherType getDispatcherType() {
-            LOG.log(Level.INFO, "getDispatcherType()");
-            return null;
-        }
-
-        @Override
-        public ServletInputStream getInputStream() throws IOException {
-            return new ServletInputStream() {
-                @Override
-                public int read() throws IOException {
-                    return in.read();
-                }
-
-                @Override
-                public int read(byte[] b, int off, int len) throws IOException {
-                    return in.read(b, off, len);
-                }
-            };
-        }
-
-        @Override
-        public String getLocalAddr() {
-            LOG.log(Level.INFO, "getLocalAddr()");
-            return websocket.getRequestProperty("localAddr", String.class);
-        }
-
-        @Override
-        public String getLocalName() {
-            LOG.log(Level.INFO, "getLocalName()");
-            return websocket.getRequestProperty("localName", String.class);
-        }
-
-        @Override
-        public int getLocalPort() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getLocalPort()");
-            return 0;
-        }
-
-        @Override
-        public Locale getLocale() {
-            LOG.log(Level.INFO, "getLocale()");
-            return websocket.getRequestProperty("locale", Locale.class);
-        }
-
-        @Override
-        public Enumeration<Locale> getLocales() {
-            LOG.log(Level.INFO, "getLocales()");
-            return CastUtils.cast(websocket.getRequestProperty("locales", Enumeration.class));
-        }
-
-        @Override
-        public String getParameter(String name) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "getParameter({0})", name);
-            }
-            return null;
-        }
-
-        @Override
-        public Map<String, String[]> getParameterMap() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getParameterMap()");
-            return null;
-        }
-
-        @Override
-        public Enumeration<String> getParameterNames() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getParameterNames()");
-            return null;
-        }
-
-        @Override
-        public String[] getParameterValues(String name) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "getParameterValues({0})", name);
-            }
-            return null;
-        }
-
-        @Override
-        public String getProtocol() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getProtocol");
-            return null;
-        }
-
-        @Override
-        public BufferedReader getReader() throws IOException {
-            LOG.log(Level.INFO, "getReader");
-            return new BufferedReader(new InputStreamReader(in, "utf-8"));
-        }
-
-        @Override
-        public String getRealPath(String path) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getRealPath");
-            return null;
-        }
-
-        @Override
-        public String getRemoteAddr() {
-            LOG.log(Level.INFO, "getRemoteAddr");
-            return websocket.getRequestProperty("remoteAddr", String.class);
-        }
-
-        @Override
-        public String getRemoteHost() {
-            LOG.log(Level.INFO, "getRemoteHost");
-            return websocket.getRequestProperty("remoteHost", String.class);
-        }
-
-        @Override
-        public int getRemotePort() {
-            LOG.log(Level.INFO, "getRemotePort");
-            return websocket.getRequestProperty("remotePort", int.class);
-        }
-
-        @Override
-        public RequestDispatcher getRequestDispatcher(String path) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getRequestDispatcher");
-            return null;
-        }
-
-        @Override
-        public String getScheme() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getScheme");
-            return null;
-        }
-
-        @Override
-        public String getServerName() {
-            return websocket.getRequestProperty("serverName", String.class);
-        }
-
-        @Override
-        public int getServerPort() {
-            LOG.log(Level.INFO, "getServerPort");
-            return websocket.getRequestProperty("serverPoart", int.class);
-        }
-
-        @Override
-        public ServletContext getServletContext() {
-            LOG.log(Level.INFO, "getServletContext");
-            return context;
-        }
-
-        @Override
-        public boolean isAsyncStarted() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "isAsyncStarted");
-            return false;
-        }
-
-        @Override
-        public boolean isAsyncSupported() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "isAsyncSupported");
-            return false;
-        }
-
-        @Override
-        public boolean isSecure() {
-            LOG.log(Level.INFO, "isSecure");
-            return websocket.getRequestProperty("secure", boolean.class);
-        }
-
-        @Override
-        public void removeAttribute(String name) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "removeAttribute");
-        }
-
-        @Override
-        public void setAttribute(String name, Object o) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "setAttribute");
-        }
-
-        @Override
-        public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
-            LOG.log(Level.INFO, "setCharacterEncoding");
-            // ignore as we stick to utf-8.
-        }
-
-        @Override
-        public AsyncContext startAsync() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "startAsync");
-            return null;
-        }
-
-        @Override
-        public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "startAsync");
-            return null;
-        }
-
-        @Override
-        public boolean authenticate(HttpServletResponse servletResponse) throws IOException, ServletException {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "authenticate");
-            return false;
-        }
-
-        @Override
-        public String getAuthType() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getAuthType");
-            return null;
-        }
-
-        @Override
-        public String getContextPath() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getContextPath");
-            return null;
-        }
-
-        @Override
-        public Cookie[] getCookies() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getCookies");
-            return null;
-        }
-
-        @Override
-        public long getDateHeader(String name) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getDateHeader");
-            return 0;
-        }
-
-        @Override
-        public String getHeader(String name) {
-            LOG.log(Level.INFO, "getHeader");
-            return requestHeaders.get(name);
-        }
-
-        @Override
-        public Enumeration<String> getHeaderNames() {
-            LOG.log(Level.INFO, "getHeaderNames");
-            return Collections.enumeration(requestHeaders.keySet());
-        }
-
-        @Override
-        public Enumeration<String> getHeaders(String name) {
-            LOG.log(Level.INFO, "getHeaders");
-            // our protocol assumes no multiple headers
-            return Collections.enumeration(Arrays.asList(requestHeaders.get(name)));
-        }
-
-        @Override
-        public int getIntHeader(String name) {
-            LOG.log(Level.INFO, "getIntHeader");
-            String v = requestHeaders.get(name);
-            return v == null ? -1 : Integer.parseInt(v);
-        }
-
-        @Override
-        public String getMethod() {
-            LOG.log(Level.INFO, "getMethod");
-            return requestHeaders.get("$method");
-        }
-
-        @Override
-        public Part getPart(String name) throws IOException, ServletException {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getPart");
-            return null;
-        }
-
-        @Override
-        public Collection<Part> getParts() throws IOException, ServletException {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getParts");
-            return null;
-        }
-
-        @Override
-        public String getPathInfo() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getPathInfo");
-            return null;
-        }
-
-        @Override
-        public String getPathTranslated() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getPathTranslated");
-            return null;
-        }
-
-        @Override
-        public String getQueryString() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getQueryString");
-            return null;
-        }
-
-        @Override
-        public String getRemoteUser() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getRemoteUser");
-            return null;
-        }
-
-        @Override
-        public String getRequestURI() {
-            LOG.log(Level.INFO, "getRequestURI");
-            return requestHeaders.get("$path");
-        }
-
-        @Override
-        public StringBuffer getRequestURL() {
-            LOG.log(Level.INFO, "getRequestURL");
-            String url = websocket.getRequestProperty("requestURL", String.class);
-            String origin = websocket.getRequestProperty("requestURI", String.class);
-            StringBuffer sb = new StringBuffer();
-            String uri = getRequestURI();
-            //REVISIT the way to reject the requeist uri that does not match the original request
-            if (!uri.startsWith(origin)) {
-                sb.append(url).append("invalid").append(uri);
-            } else {
-                sb.append(url).append(uri.substring(origin.length()));
-            }
-            
-            return sb;
-        }
-
-        @Override
-        public String getRequestedSessionId() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getRequestedSessionId");
-            return null;
-        }
-
-        @Override
-        public String getServletPath() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getServletPath");
-            return null;
-        }
-
-        @Override
-        public HttpSession getSession() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getSession");
-            return null;
-        }
-
-        @Override
-        public HttpSession getSession(boolean create) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getSession");
-            return null;
-        }
-
-        @Override
-        public Principal getUserPrincipal() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getUserPrincipal");
-            return null;
-        }
-
-        @Override
-        public boolean isRequestedSessionIdFromCookie() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "isRequestedSessionIdFromCookie");
-            return false;
-        }
-
-        @Override
-        public boolean isRequestedSessionIdFromURL() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "isRequestedSessionIdFromURL");
-            return false;
-        }
-
-        @Override
-        public boolean isRequestedSessionIdFromUrl() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "isRequestedSessionIdFromUrl");
-            return false;
-        }
-
-        @Override
-        public boolean isRequestedSessionIdValid() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "isRequestedSessionIdValid");
-            return false;
-        }
-
-        @Override
-        public boolean isUserInRole(String role) {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "isUserInRole");
-            return false;
-        }
-
-        @Override
-        public void login(String username, String password) throws ServletException {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "login");
-            
-        }
-
-        @Override
-        public void logout() throws ServletException {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "logout");
-            
-        }
-    }
-
-    //TODO need to make the header setting to be written to the body (as symmetric to the request behavior)
-    static class WebSocketVirtualServletResponse implements HttpServletResponse {
-        private JettyWebSocket websocket;
-        private Map<String, String> responseHeaders;
-        private boolean flushed;
-
-        public WebSocketVirtualServletResponse(JettyWebSocket websocket) {
-            this.websocket = websocket;
-            this.responseHeaders = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
-        }
-
-        @Override
-        public void flushBuffer() throws IOException {
-            LOG.log(Level.INFO, "flushBuffer()");
-            if (!flushed) {
-                //REVISIT this mechanism to determine if the headers have been flushed
-                if (responseHeaders.get("$flushed") == null) {
-                    byte[] data = buildResponse(responseHeaders, null, 0, 0);
-                    websocket.write(data, 0, data.length);
-                    responseHeaders.put("$flushed", "true");
-                }
-                flushed = true;
-            }
-        }
-
-        @Override
-        public int getBufferSize() {
-            LOG.log(Level.INFO, "getBufferSize()");
-            return 0;
-        }
-
-        @Override
-        public String getCharacterEncoding() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getCharacterEncoding()");
-            return null;
-        }
-
-        @Override
-        public String getContentType() {
-            LOG.log(Level.INFO, "getContentType()");
-            return responseHeaders.get("Content-Type");
-        }
-
-        @Override
-        public Locale getLocale() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getLocale");
-            return null;
-        }
-
-        @Override
-        public ServletOutputStream getOutputStream() throws IOException {
-            LOG.log(Level.INFO, "getOutputStream()");
-            return websocket.getServletOutputStream(responseHeaders);
-        }
-
-        @Override
-        public PrintWriter getWriter() throws IOException {
-            LOG.log(Level.INFO, "getWriter()");
-            return new PrintWriter(websocket.getOutputStream(responseHeaders));
-        }
-
-        @Override
-        public boolean isCommitted() {
-            return false;
-        }
-
-        @Override
-        public void reset() {
-        }
-
-        @Override
-        public void resetBuffer() {
-            LOG.log(Level.INFO, "resetBuffer()");
-        }
-
-        @Override
-        public void setBufferSize(int size) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setBufferSize({0})", size);
-            }
-        }
-
-        @Override
-        public void setCharacterEncoding(String charset) {
-            // TODO 
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setCharacterEncoding({0})", charset);
-            }
-        }
-
-        @Override
-        public void setContentLength(int len) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setContentLength({0})", len);
-            }
-            responseHeaders.put("Content-Length", Integer.toString(len));
-        }
-
-        @Override
-        public void setContentType(String type) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setContentType({0})", type);
-            }
-            responseHeaders.put("Content-Type", type);
-        }
-
-        @Override
-        public void setLocale(Locale loc) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setLocale({0})", loc);
-            }
-        }
-
-        @Override
-        public void addCookie(Cookie cookie) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "addCookie({0})", cookie);
-            }
-        }
-
-        @Override
-        public void addDateHeader(String name, long date) {
-            // TODO
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "addDateHeader({0}, {1})", new Object[]{name, date});
-            }
-        }
-
-        @Override
-        public void addHeader(String name, String value) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "addHeader({0}, {1})", new Object[]{name, value});
-            }
-            responseHeaders.put(name, value);
-        }
-
-        @Override
-        public void addIntHeader(String name, int value) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "addIntHeader({0}, {1})", new Object[]{name, value});
-            }
-            responseHeaders.put(name, Integer.toString(value));
-        }
-
-        @Override
-        public boolean containsHeader(String name) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "containsHeader({0})", name);
-            }
-            return false;
-        }
-
-        @Override
-        public String encodeRedirectURL(String url) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "encodeRedirectURL({0})", url);
-            }
-            return null;
-        }
-
-        @Override
-        public String encodeRedirectUrl(String url) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "encodeRedirectUrl({0})", url);
-            }
-            return null;
-        }
-
-        @Override
-        public String encodeURL(String url) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "encodeURL({0})", url);
-            }
-            return null;
-        }
-
-        @Override
-        public String encodeUrl(String url) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "encodeUrl({0})", url);
-            }
-            return null;
-        }
-
-        @Override
-        public String getHeader(String name) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "getHeader({0})", name);
-            }
-            return null;
-        }
-
-        @Override
-        public Collection<String> getHeaderNames() {
-            // TODO Auto-generated method stub
-            LOG.log(Level.INFO, "getHeaderNames()");
-            return null;
-        }
-
-        @Override
-        public Collection<String> getHeaders(String name) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "getHeaders({0})", name);
-            }
-            return null;
-        }
-
-        @Override
-        public int getStatus() {
-            LOG.log(Level.INFO, "getStatus()");
-            String v = responseHeaders.get("$sc");
-            return v == null ? 200 : Integer.parseInt(v);
-        }
-
-        @Override
-        public void sendError(int sc) throws IOException {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "sendError{0}", sc);
-            }
-            responseHeaders.put("$sc", Integer.toString(sc));
-        }
-
-        @Override
-        public void sendError(int sc, String msg) throws IOException {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "sendError({0}, {1})", new Object[]{sc, msg});
-            }
-            responseHeaders.put("$sc", Integer.toString(sc));
-            responseHeaders.put("$sm", msg);
-        }
-
-        @Override
-        public void sendRedirect(String location) throws IOException {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "sendRedirect({0})", location);
-            }
-        }
-
-        @Override
-        public void setDateHeader(String name, long date) {
-            // ignore
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setDateHeader({0}, {1})", new Object[]{name, date});
-            }
-        }
-
-        @Override
-        public void setHeader(String name, String value) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setHeader({0}, {1})", new Object[]{name, value});
-            }
-        }
-
-        @Override
-        public void setIntHeader(String name, int value) {
-            // TODO Auto-generated method stub
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setIntHeader({0}, {1})", new Object[]{name, value});
-            }
-        }
-
-        @Override
-        public void setStatus(int sc) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setStatus({0})", sc);
-            }
-            responseHeaders.put("$sc", Integer.toString(sc));
-        }
-
-        @Override
-        public void setStatus(int sc, String sm) {
-            if (LOG.isLoggable(Level.INFO)) {
-                LOG.log(Level.INFO, "setStatus({0}, {1})", new Object[]{sc, sm});
-            }
-            responseHeaders.put("$sc", Integer.toString(sc));
-            responseHeaders.put("$sm", sm);
-        }
-    }
-
-    /*
-     * We accept only a restricted syntax as we have the syntax in our control.
-     * Do not allow multiline or line-wrapped headers.
-     * Do not allow charset other than utf-8. (although i would have preferred iso-8859-1 ;-)
-     */
-    private static Map<String, String> readHeaders(InputStream in) throws IOException {
-        Map<String, String> headers = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
-        // read the request line
-        String line = readLine(in);
-        int del = line.indexOf(' ');
-        if (del < 0) {
-            throw new IOException("invalid request: " + line);
-        }
-        headers.put("$method", line.substring(0, del).trim());
-        headers.put("$path", line.substring(del + 1).trim());
-        
-        // read headers
-        while ((line = readLine(in)) != null) {
-            if (line.length() > 0) {
-                del = line.indexOf(':');
-                if (del < 0) {
-                    headers.put(line.trim(), "");
-                } else {
-                    headers.put(line.substring(0, del).trim(), line.substring(del + 1).trim());
-                }
-            }
-        }
-
-        return headers;
-    }
-
-    @SuppressWarnings("unchecked")
-    private static <T> T getValue(Map<String, Object> properties, String name, Class<T> cls) {
-        return (T)properties.get(name);
-    }
-    
-
-    ///// this is copied from AttachmentDeserializer with a minor change. think about putting this method to IOUtils
-    private static String readLine(InputStream in) throws IOException {
-        StringBuilder buffer = new StringBuilder(128);
-
-        int c;
-
-        while ((c = in.read()) != -1) {
-            // a linefeed is a terminator, always.
-            if (c == '\n') {
-                break;
-            } else if (c == '\r') {
-                //just ignore the CR.  The next character SHOULD be an NL.  If not, we're
-                //just going to discard this
-                continue;
-            } else {
-                // just add to the buffer
-                buffer.append((char)c);
-            }
-        }
-
-        // no characters found...this was either an eof or a null line.
-        if (buffer.length() == 0) {
-            return null;
-        }
-
-        return buffer.toString();
-    }
-    ///// END
-}

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
----------------------------------------------------------------------
diff --git a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
index 2a6b8a2..e8e2c45 100644
--- a/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
+++ b/rt/transports/http/src/main/java/org/apache/cxf/transport/servlet/CXFNonSpringServlet.java
@@ -92,7 +92,7 @@ public class CXFNonSpringServlet extends AbstractHTTPServlet {
         return bus.getExtension(ClassLoader.class);
     }
     
-    private static DestinationRegistry getDestinationRegistryFromBus(Bus bus) {
+    protected DestinationRegistry getDestinationRegistryFromBus(Bus bus) {
         DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class);
         try {
             DestinationFactory df = dfm

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/websocket/pom.xml
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/pom.xml b/rt/transports/websocket/pom.xml
new file mode 100644
index 0000000..346c32e
--- /dev/null
+++ b/rt/transports/websocket/pom.xml
@@ -0,0 +1,168 @@
+<?xml version="1.0"?>
+<!--
+  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>
+    <artifactId>cxf-rt-transports-websocket</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache CXF Runtime WebSocket Transport</name>
+    <description>Apache CXF Runtime WebSocket Transport</description>
+    <url>http://cxf.apache.org</url>
+    <parent>
+        <groupId>org.apache.cxf</groupId>
+        <artifactId>cxf-parent</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+    <properties>
+<!--
+        <cxf.bundle.activator>org.apache.cxf.transport.websocket.osgi.WebSocketTransportActivator</cxf.bundle.activator>
+                    org.eclipse.jetty.websocket;version="${cxf.jetty.osgi.version}";resolution:=optional,
+        
+-->
+        <cxf.osgi.import>
+            javax.servlet*;version="${cxf.osgi.javax.servlet.version}",
+            org.eclipse.jetty*;version="${cxf.jetty.osgi.version}",
+            org.apache.aries*;version="${cxf.aries.version.range}";resolution:=optional,
+            org.springframework*;resolution:="optional";version="${cxf.osgi.spring.version}"
+        </cxf.osgi.import>
+        <cxf.osgi.dynamic.import>
+            org.eclipse.jetty.jmx
+        </cxf.osgi.dynamic.import>
+        <!-- keep in sync with services exported in activator -->
+        <cxf.export.service>
+            org.apache.aries.blueprint.NamespaceHandler;osgi.service.blueprint.namespace="http://cxf.apache.org/transports/websocket/configuration"
+        </cxf.export.service>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint.core</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-core</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-transports-http-jetty</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>${cxf.jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-security</artifactId>
+            <version>${cxf.jetty.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-websocket</artifactId>
+            <version>${cxf.jetty.version}</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jmx</artifactId>
+            <version>${cxf.jetty.version}</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>${cxf.servlet-api.group}</groupId>
+            <artifactId>${cxf.servlet-api.artifact}</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+            <scope>test</scope>
+        </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-rt-wsdl</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketDestinationFactory.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketDestinationFactory.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketDestinationFactory.java
new file mode 100644
index 0000000..1c539d6
--- /dev/null
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketDestinationFactory.java
@@ -0,0 +1,49 @@
+/**
+ * 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.websocket;
+
+import java.io.IOException;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.http.AbstractHTTPDestination;
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.http.HttpDestinationFactory;
+import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory;
+import org.apache.cxf.transport.servlet.ServletDestination;
+import org.apache.cxf.transport.websocket.jetty.JettyWebSocketDestination;
+
+@NoJSR250Annotations()
+public class WebSocketDestinationFactory implements HttpDestinationFactory {
+
+    public AbstractHTTPDestination createDestination(EndpointInfo endpointInfo, Bus bus,
+                                                     DestinationRegistry registry) throws IOException {
+
+        if (endpointInfo.getAddress().startsWith("ws")) {
+            //TODO for now jetty specific, 
+            JettyHTTPServerEngineFactory serverEngineFactory = bus
+                .getExtension(JettyHTTPServerEngineFactory.class);
+            return new JettyWebSocketDestination(bus, registry, endpointInfo, serverEngineFactory);
+        } else {
+            return new ServletDestination(bus, registry, endpointInfo, endpointInfo.getAddress());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketTransportFactory.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketTransportFactory.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketTransportFactory.java
new file mode 100644
index 0000000..b90aded
--- /dev/null
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/WebSocketTransportFactory.java
@@ -0,0 +1,135 @@
+/**
+ * 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.websocket;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.common.injection.NoJSR250Annotations;
+import org.apache.cxf.configuration.Configurer;
+import org.apache.cxf.service.model.EndpointInfo;
+import org.apache.cxf.transport.AbstractTransportFactory;
+import org.apache.cxf.transport.Conduit;
+import org.apache.cxf.transport.ConduitInitiator;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.http.AbstractHTTPDestination;
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.http.DestinationRegistryImpl;
+import org.apache.cxf.transport.http.HttpDestinationFactory;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+
+@NoJSR250Annotations
+public class WebSocketTransportFactory extends AbstractTransportFactory implements ConduitInitiator,
+    DestinationFactory {
+
+    public static final List<String> DEFAULT_NAMESPACES 
+        = Arrays.asList(
+            "http://cxf.apache.org/transports/websockt",
+            "http://cxf.apache.org/transports/websocket/configuration"
+        );
+
+    private static final Set<String> URI_PREFIXES = new HashSet<String>();
+    static {
+        URI_PREFIXES.add("ws://");
+        URI_PREFIXES.add("wss://");
+    }
+
+    protected final DestinationRegistry registry;
+
+    protected final HttpDestinationFactory factory = new WebSocketDestinationFactory();
+
+    public WebSocketTransportFactory() {
+        this(new DestinationRegistryImpl());
+    }
+    
+    public WebSocketTransportFactory(DestinationRegistry registry) {
+        super(DEFAULT_NAMESPACES);
+        if (registry == null) {
+            registry = new DestinationRegistryImpl();
+        }
+        this.registry = registry;
+    }
+    public DestinationRegistry getRegistry() {
+        return registry;
+    }
+
+    /**
+     * This call uses the Configurer from the bus to configure
+     * a bean.
+     * 
+     * @param bean
+     */
+    protected void configure(Bus b, Object bean) {
+        configure(b, bean, null, null);
+    }
+    
+    protected void configure(Bus bus, Object bean, String name, String extraName) {
+        Configurer configurer = bus.getExtension(Configurer.class);
+        if (null != configurer) {
+            configurer.configureBean(name, bean);
+            if (extraName != null) {
+                configurer.configureBean(extraName, bean);
+            }
+        }
+    }
+    
+    
+    public Conduit getConduit(EndpointInfo endpointInfo, Bus b) throws IOException {
+        return getConduit(endpointInfo, endpointInfo.getTarget(), b);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Conduit getConduit(EndpointInfo endpointInfo, EndpointReferenceType target, Bus bus)
+        throws IOException {
+        //TODO add on implementation using ning
+        throw new RuntimeException("not implemented yet");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Destination getDestination(EndpointInfo endpointInfo, Bus bus) throws IOException {
+        if (endpointInfo == null) {
+            throw new IllegalArgumentException("EndpointInfo cannot be null");
+        }
+        synchronized (registry) {
+            AbstractHTTPDestination d = registry.getDestinationForPath(endpointInfo.getAddress());
+            if (d == null) {
+                d = factory.createDestination(endpointInfo, bus, registry);
+                registry.addDestination(d);
+                configure(bus, d);
+                d.finalizeConfig();
+            }
+            return d;
+        }
+    }
+    
+    public Set<String> getUriPrefixes() {
+        return URI_PREFIXES;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServlet.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServlet.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServlet.java
new file mode 100644
index 0000000..a3e68df
--- /dev/null
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServlet.java
@@ -0,0 +1,110 @@
+/**
+ * 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.websocket.jetty;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusException;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.servlet.CXFServlet;
+import org.apache.cxf.transport.websocket.WebSocketTransportFactory;
+import org.eclipse.jetty.websocket.WebSocket;
+import org.eclipse.jetty.websocket.WebSocketFactory;
+
+/**
+ * 
+ */
+public class CXFJettyWebSocketServlet extends CXFServlet 
+    implements CXFJettyWebSocketServletService, WebSocketFactory.Acceptor {
+    private static final long serialVersionUID = 3955992016049976728L;
+    private JettyWebSocketManager websocketManager;
+    
+    public CXFJettyWebSocketServlet() {
+    }
+    
+    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
+        return new JettyWebSocket(websocketManager, request, protocol);
+    }
+
+
+    public boolean checkOrigin(HttpServletRequest request, String origin) {
+        return true;
+    }
+
+    @Override
+    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
+        if (websocketManager.acceptWebSocket(req, res)) {
+            return;
+        }
+        super.service(req, res);
+    }
+    
+    @Override
+    public void serviceInternal(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
+        super.service(req, resp);
+    }
+    
+    
+    @Override
+    public void init(ServletConfig sc) throws ServletException {
+        super.init(sc);
+        
+        websocketManager = new JettyWebSocketManager();
+        websocketManager.init(this, sc);
+    }
+    
+    @Override
+    protected DestinationRegistry getDestinationRegistryFromBus(Bus bus) {
+        DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class);
+        try {
+            DestinationFactory df = dfm
+                .getDestinationFactory("http://cxf.apache.org/transports/websocket/configuration");
+            if (df instanceof WebSocketTransportFactory) {
+                WebSocketTransportFactory transportFactory = (WebSocketTransportFactory)df;
+                return transportFactory.getRegistry();
+            }
+        } catch (BusException e) {
+            // why are we throwing a busexception if the DF isn't found?
+        }
+        return null;
+    }
+
+
+
+    @Override
+    public void destroy() {
+        try {
+            websocketManager.destroy();
+        } catch (Exception e) {
+            // ignore
+        } finally {
+            super.destroy();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServletService.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServletService.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServletService.java
new file mode 100644
index 0000000..89e18c2
--- /dev/null
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFJettyWebSocketServletService.java
@@ -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.websocket.jetty;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+/**
+ * 
+ */
+interface CXFJettyWebSocketServletService {
+    void serviceInternal(ServletRequest req, ServletResponse resp) throws ServletException, IOException;
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/8fe4fc13/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFNonSpringJettyWebSocketServlet.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFNonSpringJettyWebSocketServlet.java b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFNonSpringJettyWebSocketServlet.java
new file mode 100644
index 0000000..74dce02
--- /dev/null
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/CXFNonSpringJettyWebSocketServlet.java
@@ -0,0 +1,116 @@
+/**
+ * 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.websocket.jetty;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusException;
+import org.apache.cxf.transport.DestinationFactory;
+import org.apache.cxf.transport.DestinationFactoryManager;
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
+import org.apache.cxf.transport.websocket.WebSocketTransportFactory;
+import org.eclipse.jetty.websocket.WebSocket;
+import org.eclipse.jetty.websocket.WebSocketFactory;
+
+/**
+ * 
+ */
+public class CXFNonSpringJettyWebSocketServlet extends CXFNonSpringServlet 
+    implements CXFJettyWebSocketServletService, WebSocketFactory.Acceptor {
+    private static final long serialVersionUID = 6921073894009215482L;
+    private JettyWebSocketManager websocketManager;
+    
+    public CXFNonSpringJettyWebSocketServlet() {
+    }
+    
+    public CXFNonSpringJettyWebSocketServlet(DestinationRegistry destinationRegistry, boolean loadBus) {
+        super(destinationRegistry, loadBus);
+    }
+
+    public CXFNonSpringJettyWebSocketServlet(DestinationRegistry destinationRegistry) {
+        super(destinationRegistry);
+    }
+
+    public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
+        return new JettyWebSocket(websocketManager, request, protocol);
+    }
+
+
+    public boolean checkOrigin(HttpServletRequest request, String origin) {
+        return true;
+    }
+
+    @Override
+    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
+        if (websocketManager.acceptWebSocket(req, res)) {
+            return;
+        }
+        super.service(req, res);
+    }
+    
+    @Override
+    public void serviceInternal(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
+        super.service(req, resp);
+    }
+    
+    
+    @Override
+    public void init(ServletConfig sc) throws ServletException {
+        super.init(sc);
+        
+        websocketManager = new JettyWebSocketManager();
+        websocketManager.init(this, sc);
+    }
+
+    @Override
+    protected DestinationRegistry getDestinationRegistryFromBus(Bus bus) {
+        DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class);
+        try {
+            DestinationFactory df = dfm
+                .getDestinationFactory("http://cxf.apache.org/transports/websocket/configuration");
+            if (df instanceof WebSocketTransportFactory) {
+                WebSocketTransportFactory transportFactory = (WebSocketTransportFactory)df;
+                return transportFactory.getRegistry();
+            }
+        } catch (BusException e) {
+            // why are we throwing a busexception if the DF isn't found?
+        }
+        return null;
+    }
+
+    @Override
+    public void destroy() {
+        try {
+            websocketManager.destroy();
+        } catch (Exception e) {
+            // ignore
+        } finally {
+            super.destroy();
+        }
+    }
+}


Mime
View raw message