[jbossws-commits] JBossWS SVN: r10888 - in stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws: core/server and 2 other directories.

jbossws-commits at lists.jboss.org jbossws-commits at lists.jboss.org
Mon Oct 12 09:08:35 EDT 2009


Author: richard.opalka at jboss.com
Date: 2009-10-12 09:08:34 -0400 (Mon, 12 Oct 2009)
New Revision: 10888

Added:
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java
Removed:
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java
Modified:
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java
   stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java
Log:
[JBWS-2674][JBWS-2754] refactoring (WIP)

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,208 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.jaxws.spi.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.management.ObjectName;
+import javax.xml.ws.WebServiceException;
+
+import org.jboss.logging.Logger;
+import org.jboss.ws.Constants;
+import org.jboss.ws.WSException;
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
+import org.jboss.ws.extensions.wsrm.transport.backchannel.RMCallbackHandlerImpl;
+import org.jboss.wsf.common.ObjectNameFactory;
+import org.jboss.wsf.common.injection.InjectionHelper;
+import org.jboss.wsf.common.injection.PreDestroyHolder;
+import org.jboss.wsf.spi.SPIProvider;
+import org.jboss.wsf.spi.SPIProviderResolver;
+import org.jboss.wsf.spi.deployment.Endpoint;
+import org.jboss.wsf.spi.invocation.EndpointAssociation;
+import org.jboss.wsf.spi.invocation.InvocationContext;
+import org.jboss.wsf.spi.invocation.RequestHandler;
+import org.jboss.wsf.spi.management.EndpointRegistry;
+import org.jboss.wsf.spi.management.EndpointRegistryFactory;
+import org.jboss.wsf.spi.management.EndpointResolver;
+import org.jboss.wsf.stack.jbws.WebAppResolver;
+
+/**
+ * TODO: javadoc
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+final class NettyCallbackHandlerImpl implements NettyCallbackHandler
+{
+   private static final Logger LOGGER = Logger.getLogger(RMCallbackHandlerImpl.class);
+
+   private final String handledPath;
+
+   private final SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
+
+   private EndpointRegistry epRegistry;
+
+   private Endpoint endpoint;
+
+   private List<PreDestroyHolder> preDestroyRegistry = new LinkedList<PreDestroyHolder>();
+
+   /**
+    * Request path to listen for incomming messages
+    * @param handledPath
+    */
+   public NettyCallbackHandlerImpl(String path, String context, String endpointRegistryPath)
+   {
+      super();
+      this.initRegistry();
+      this.initEndpoint(context, endpointRegistryPath);
+      this.handledPath = path;
+   }
+
+   /**
+    * Initializes endpoint registry
+    */
+   private void initRegistry()
+   {
+      epRegistry = spiProvider.getSPI(EndpointRegistryFactory.class).getEndpointRegistry();
+   }
+
+   /**
+    * Initialize the service endpoint
+    * @param contextPath context path
+    * @param servletName servlet name
+    */
+   private void initEndpoint(final String context, final String endpointRegistryPath)
+   {
+      final EndpointResolver resolver = new WebAppResolver(context, endpointRegistryPath);
+      this.endpoint = epRegistry.resolve(resolver);
+
+      if (this.endpoint == null)
+      {
+         ObjectName oname = ObjectNameFactory.create(Endpoint.SEPID_DOMAIN + ":" + Endpoint.SEPID_PROPERTY_CONTEXT
+               + "=" + context + "," + Endpoint.SEPID_PROPERTY_ENDPOINT + "=" + endpointRegistryPath);
+         throw new WebServiceException("Cannot obtain endpoint for: " + oname);
+      }
+   }
+
+   public int handle(String method, InputStream inputStream, OutputStream outputStream, InvocationContext invCtx)
+         throws IOException
+   {
+      Integer statusCode = null;
+      try
+      {
+         if (method.equals("POST"))
+         {
+            this.handle(inputStream, outputStream, invCtx, false);
+            statusCode = (Integer) invCtx.getProperty(Constants.NETTY_STATUS_CODE);
+         }
+         else if (method.equals("GET"))
+         {
+            this.handle(inputStream, outputStream, invCtx, true);
+         }
+         else
+         {
+            throw new WSException("Unsupported HTTP method: " + method);
+         }
+      }
+      catch (Exception e)
+      {
+         NettyCallbackHandlerImpl.LOGGER.error(e.getMessage(), e);
+         statusCode = 500;
+      }
+
+      return statusCode == null ? 200 : statusCode;
+   }
+
+   public String getPath()
+   {
+      return this.handledPath;
+   }
+
+   private void handle(final InputStream inputStream, final OutputStream outputStream, final InvocationContext invCtx, final boolean wsdlRequest) throws IOException
+   {
+      try
+      {
+         EndpointAssociation.setEndpoint(this.endpoint);
+         final RequestHandler requestHandler = this.endpoint.getRequestHandler();
+         
+         if (wsdlRequest)
+         {
+            requestHandler.handleWSDLRequest(this.endpoint, outputStream, invCtx);
+         }
+         else
+         {
+            requestHandler.handleRequest(this.endpoint, inputStream, outputStream, invCtx);
+         }
+      }
+      finally
+      {
+         this.registerForPreDestroy(this.endpoint);
+         EndpointAssociation.removeEndpoint();
+      }
+   }
+
+   private void registerForPreDestroy(final Endpoint ep)
+   {
+      final PreDestroyHolder holder = (PreDestroyHolder) ep.getAttachment(PreDestroyHolder.class);
+      if (holder != null)
+      {
+         synchronized (this.preDestroyRegistry)
+         {
+            if (!this.preDestroyRegistry.contains(holder))
+            {
+               this.preDestroyRegistry.add(holder);
+            }
+         }
+         ep.removeAttachment(PreDestroyHolder.class);
+      }
+   }
+   
+   public final void init()
+   {
+      // does nothing
+   }
+
+   public final void destroy()
+   {
+      synchronized (this.preDestroyRegistry)
+      {
+         for (final PreDestroyHolder holder : this.preDestroyRegistry)
+         {
+            try
+            {
+               final Object targetBean = holder.getObject();
+               InjectionHelper.callPreDestroyMethod(targetBean);
+            }
+            catch (Exception exception)
+            {
+               NettyCallbackHandlerImpl.LOGGER.error(exception.getMessage(), exception);
+            }
+         }
+         this.preDestroyRegistry.clear();
+         this.preDestroyRegistry = null;
+      }
+   }
+
+}

Deleted: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -1,259 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ws.core.jaxws.spi.http;
-
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.xml.ws.WebServiceException;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.ws.core.client.transport.WSServerPipelineFactory;
-
-/**
- * TODO: javadoc
- *
- * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
- */
-final class NettyHttpServer implements Runnable
-{
-
-   private static final Logger LOG = Logger.getLogger(NettyHttpServer.class);
-
-   private static final Lock CLASS_LOCK = new ReentrantLock();
-
-   private static final long WAIT_PERIOD = 100;
-
-   private static Map<String, NettyHttpServer> SERVERS = new HashMap<String, NettyHttpServer>();
-
-   static final ChannelGroup channelGroup = new DefaultChannelGroup("rmBackPortsServer");
-
-   private final Object instanceLock = new Object();
-
-   private final String scheme;
-
-   private final String host;
-
-   private final int port;
-
-   private boolean started;
-
-   private boolean stopped;
-
-   private boolean terminated;
-
-   private ChannelFactory factory;
-
-   private NettyInvocationHandler handler;
-
-   private NettyHttpServer(String scheme, String host, int port)
-   {
-      super();
-      this.scheme = scheme;
-      this.host = host;
-      this.port = port;
-      try
-      {
-         factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
-
-         ServerBootstrap bootstrap = new ServerBootstrap(factory);
-         this.handler = new NettyInvocationHandler();
-         WSServerPipelineFactory channelPipelineFactory = new WSServerPipelineFactory();
-         channelPipelineFactory.setRequestHandler(this.handler);
-         bootstrap.setPipelineFactory(channelPipelineFactory);
-         bootstrap.setOption("child.tcpNoDelay", true);
-         bootstrap.setOption("child.keepAlive", true);
-         // Bind and start to accept incoming connections.
-         Channel c = bootstrap.bind(new InetSocketAddress(this.port));
-         channelGroup.add(c);
-         if (LOG.isDebugEnabled())
-            LOG.debug("Netty http server started on port: " + this.port);
-      }
-      catch (Exception e)
-      {
-         LOG.warn(e.getMessage(), e);
-         throw new WebServiceException(e.getMessage(), e);
-      }
-   }
-
-   public final void registerCallback(NettyHttpServerCallbackHandler callbackHandler)
-   {
-      this.handler.registerCallback(callbackHandler);
-   }
-
-   public final void unregisterCallback(NettyHttpServerCallbackHandler callbackHandler)
-   {
-      this.handler.unregisterCallback(callbackHandler);
-      if (!this.hasMoreCallbacks())
-      {
-         this.terminate();
-      }
-   }
-
-   public final NettyHttpServerCallbackHandler getCallback(String requestPath)
-   {
-      return this.handler.getCallback(requestPath);
-   }
-
-   public final boolean hasMoreCallbacks()
-   {
-      return this.handler.hasMoreCallbacks();
-   }
-
-   public final String getScheme()
-   {
-      return this.scheme;
-   }
-
-   public final String getHost()
-   {
-      return this.host;
-   }
-
-   public final int getPort()
-   {
-      return this.port;
-   }
-
-   public final void run()
-   {
-      synchronized (this.instanceLock)
-      {
-         if (this.started)
-            return;
-
-         this.started = true;
-
-         while (this.stopped == false)
-         {
-            try
-            {
-               this.instanceLock.wait(WAIT_PERIOD);
-               LOG.debug("serving requests");
-            }
-            catch (InterruptedException ie)
-            {
-               LOG.warn(ie.getMessage(), ie);
-            }
-         }
-         try
-         {
-            //Close all connections and server sockets.
-            channelGroup.close().awaitUninterruptibly();
-            //Shutdown the selector loop (boss and worker).
-            if (factory != null)
-            {
-               factory.releaseExternalResources();
-            }
-         }
-         finally
-         {
-            LOG.debug("terminated");
-            this.terminated = true;
-         }
-      }
-   }
-
-   public final void terminate()
-   {
-      synchronized (this.instanceLock)
-      {
-         if (this.stopped == true)
-            return;
-
-         this.stopped = true;
-         LOG.debug("termination forced");
-         SERVERS.remove(scheme + "://" + host + ":" + port + "/");
-         while (this.terminated == false)
-         {
-            try
-            {
-               LOG.debug("waiting for termination");
-               this.instanceLock.wait(WAIT_PERIOD);
-            }
-            catch (InterruptedException ie)
-            {
-               LOG.warn(ie.getMessage(), ie);
-            }
-         }
-      }
-   }
-
-   /**
-    * Starts back ports server on the background if method is called for the first time
-    * @param scheme protocol
-    * @param host hostname
-    * @param port port
-    * @return netty http server
-    */
-   public static NettyHttpServer getInstance(String scheme, String host, int port)
-   {
-      CLASS_LOCK.lock();
-      try
-      {
-         String key = scheme + "://" + host + ":" + port + "/";
-         NettyHttpServer server = SERVERS.get(key);
-         if (server == null)
-         {
-            server = new NettyHttpServer(scheme, host, (port == -1) ? 80 : port);
-            SERVERS.put(key, server);
-            // forking back ports server
-            Thread t = new Thread(server, "NettyHttpServer listening on " + key);
-            t.setDaemon(true);
-            t.start();
-            // registering shutdown hook
-            final NettyHttpServer s = server;
-            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
-            {
-               public void run()
-               {
-                  s.terminate();
-               }
-            }, "NettyHttpServerShutdownHook(" + key + ")"));
-         }
-         else
-         {
-            boolean schemeEquals = server.getScheme().equals(scheme);
-            boolean hostEquals = server.getHost().equals(host);
-            boolean portEquals = server.getPort() == ((port == -1) ? 80 : port);
-            if ((schemeEquals == false) || (hostEquals == false) || (portEquals == false))
-               throw new IllegalArgumentException();
-         }
-         return server;
-      }
-      finally
-      {
-         CLASS_LOCK.unlock();
-      }
-   }
-
-}

Modified: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -27,6 +27,10 @@
 import javax.xml.ws.Endpoint;
 
 import org.jboss.ws.core.jaxws.spi.EndpointImpl;
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
+import org.jboss.ws.core.server.netty.NettyHttpServer;
+import org.jboss.ws.core.server.netty.NettyHttpServerFactory;
+import org.jboss.ws.core.server.netty.NettyRequestHandlerFactory;
 import org.jboss.wsf.common.ResourceLoaderAdapter;
 import org.jboss.wsf.framework.deployment.BackwardCompatibleContextRootDeploymentAspect;
 import org.jboss.wsf.framework.deployment.DeploymentAspectManagerImpl;
@@ -70,6 +74,8 @@
    /** Deployment model factory. */
    private static final DeploymentModelFactory DEPLOYMENT_FACTORY = NettyHttpServerAdapter.SPI_PROVIDER
          .getSPI(DeploymentModelFactory.class);
+   
+   private static final NettyRequestHandlerFactory requestHandlerFactory = NettyRequestHandlerFactoryImpl.getInstance();
 
    /**
     * Constructor.
@@ -88,8 +94,8 @@
    public void destroy(HttpContext context, Endpoint endpoint)
    {
       EndpointImpl epImpl = (EndpointImpl) endpoint;
-      NettyHttpServer server = NettyHttpServer.getInstance("http", "localhost", epImpl.getPort());
-      NettyHttpServerCallbackHandler callback = server.getCallback(epImpl.getPath());
+      NettyHttpServer server = NettyHttpServerFactory.getNettyHttpServer(epImpl.getPort(), this.requestHandlerFactory);
+      NettyCallbackHandler callback = server.getCallback(epImpl.getPath());
       server.unregisterCallback(callback);
 
       DeploymentAspectManagerImpl daManager = new DeploymentAspectManagerImpl();
@@ -108,8 +114,8 @@
       daManager.deploy(dep);
       epImpl.setDeployment(dep);
 
-      NettyHttpServer server = NettyHttpServer.getInstance("http", "localhost", epImpl.getPort());
-      NettyHttpServerCallbackHandler callback = new NettyHttpServerCallbackHandler(epImpl.getPath(), contextRoot, this
+      NettyHttpServer server = NettyHttpServerFactory.getNettyHttpServer(epImpl.getPort(), requestHandlerFactory);
+      NettyCallbackHandler callback = new NettyCallbackHandlerImpl(epImpl.getPath(), contextRoot, this
             .getEndpointRegistryPath(epImpl));
       server.registerCallback(callback);
    }

Deleted: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -1,202 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ws.core.jaxws.spi.http;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.management.ObjectName;
-import javax.xml.ws.WebServiceException;
-
-import org.jboss.logging.Logger;
-import org.jboss.ws.Constants;
-import org.jboss.ws.WSException;
-import org.jboss.ws.extensions.wsrm.transport.backchannel.RMCallbackHandlerImpl;
-import org.jboss.wsf.common.ObjectNameFactory;
-import org.jboss.wsf.common.injection.InjectionHelper;
-import org.jboss.wsf.common.injection.PreDestroyHolder;
-import org.jboss.wsf.spi.SPIProvider;
-import org.jboss.wsf.spi.SPIProviderResolver;
-import org.jboss.wsf.spi.deployment.Endpoint;
-import org.jboss.wsf.spi.invocation.EndpointAssociation;
-import org.jboss.wsf.spi.invocation.InvocationContext;
-import org.jboss.wsf.spi.invocation.RequestHandler;
-import org.jboss.wsf.spi.management.EndpointRegistry;
-import org.jboss.wsf.spi.management.EndpointRegistryFactory;
-import org.jboss.wsf.spi.management.EndpointResolver;
-import org.jboss.wsf.stack.jbws.WebAppResolver;
-
-/**
- * TODO: javadoc
- *
- * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
- */
-final class NettyHttpServerCallbackHandler // TODO: review class name
-{
-   private static final Logger LOGGER = Logger.getLogger(RMCallbackHandlerImpl.class);
-
-   private final String handledPath;
-
-   private final SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
-
-   private EndpointRegistry epRegistry;
-
-   private Endpoint endpoint;
-
-   private List<PreDestroyHolder> preDestroyRegistry = new LinkedList<PreDestroyHolder>();
-
-   /**
-    * Request path to listen for incomming messages
-    * @param handledPath
-    */
-   public NettyHttpServerCallbackHandler(String path, String context, String endpointRegistryPath)
-   {
-      super();
-      this.initRegistry();
-      this.initEndpoint(context, endpointRegistryPath);
-      this.handledPath = path;
-   }
-
-   /**
-    * Initializes endpoint registry
-    */
-   private void initRegistry()
-   {
-      epRegistry = spiProvider.getSPI(EndpointRegistryFactory.class).getEndpointRegistry();
-   }
-
-   /**
-    * Initialize the service endpoint
-    * @param contextPath context path
-    * @param servletName servlet name
-    */
-   private void initEndpoint(final String context, final String endpointRegistryPath)
-   {
-      final EndpointResolver resolver = new WebAppResolver(context, endpointRegistryPath);
-      this.endpoint = epRegistry.resolve(resolver);
-
-      if (this.endpoint == null)
-      {
-         ObjectName oname = ObjectNameFactory.create(Endpoint.SEPID_DOMAIN + ":" + Endpoint.SEPID_PROPERTY_CONTEXT
-               + "=" + context + "," + Endpoint.SEPID_PROPERTY_ENDPOINT + "=" + endpointRegistryPath);
-         throw new WebServiceException("Cannot obtain endpoint for: " + oname);
-      }
-   }
-
-   public int handle(String method, InputStream inputStream, OutputStream outputStream, InvocationContext invCtx)
-         throws IOException
-   {
-      Integer statusCode = null;
-      try
-      {
-         if (method.equals("POST"))
-         {
-            this.handle(inputStream, outputStream, invCtx, false);
-            statusCode = (Integer) invCtx.getProperty(Constants.NETTY_STATUS_CODE);
-         }
-         else if (method.equals("GET"))
-         {
-            this.handle(inputStream, outputStream, invCtx, true);
-         }
-         else
-         {
-            throw new WSException("Unsupported HTTP method: " + method);
-         }
-      }
-      catch (Exception e)
-      {
-         NettyHttpServerCallbackHandler.LOGGER.error(e.getMessage(), e);
-         statusCode = 500;
-      }
-
-      return statusCode == null ? 200 : statusCode;
-   }
-
-   public String getHandledPath()
-   {
-      return this.handledPath;
-   }
-
-   private void handle(final InputStream inputStream, final OutputStream outputStream, final InvocationContext invCtx, final boolean wsdlRequest) throws IOException
-   {
-      try
-      {
-         EndpointAssociation.setEndpoint(this.endpoint);
-         final RequestHandler requestHandler = this.endpoint.getRequestHandler();
-         
-         if (wsdlRequest)
-         {
-            requestHandler.handleWSDLRequest(this.endpoint, outputStream, invCtx);
-         }
-         else
-         {
-            requestHandler.handleRequest(this.endpoint, inputStream, outputStream, invCtx);
-         }
-      }
-      finally
-      {
-         this.registerForPreDestroy(this.endpoint);
-         EndpointAssociation.removeEndpoint();
-      }
-   }
-
-   private void registerForPreDestroy(final Endpoint ep)
-   {
-      final PreDestroyHolder holder = (PreDestroyHolder) ep.getAttachment(PreDestroyHolder.class);
-      if (holder != null)
-      {
-         synchronized (this.preDestroyRegistry)
-         {
-            if (!this.preDestroyRegistry.contains(holder))
-            {
-               this.preDestroyRegistry.add(holder);
-            }
-         }
-         ep.removeAttachment(PreDestroyHolder.class);
-      }
-   }
-
-   public final void destroy()
-   {
-      synchronized (this.preDestroyRegistry)
-      {
-         for (final PreDestroyHolder holder : this.preDestroyRegistry)
-         {
-            try
-            {
-               final Object targetBean = holder.getObject();
-               InjectionHelper.callPreDestroyMethod(targetBean);
-            }
-            catch (Exception exception)
-            {
-               NettyHttpServerCallbackHandler.LOGGER.error(exception.getMessage(), exception);
-            }
-         }
-         this.preDestroyRegistry.clear();
-         this.preDestroyRegistry = null;
-      }
-   }
-
-}

Deleted: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -1,333 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ws.core.jaxws.spi.http;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBufferInputStream;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFuture;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.http.Cookie;
-import org.jboss.netty.handler.codec.http.CookieDecoder;
-import org.jboss.netty.handler.codec.http.CookieEncoder;
-import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
-import org.jboss.netty.handler.codec.http.HttpHeaders;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.HttpResponse;
-import org.jboss.netty.handler.codec.http.HttpResponseStatus;
-import org.jboss.netty.handler.codec.http.HttpVersion;
-import org.jboss.ws.Constants;
-import org.jboss.ws.core.client.transport.NettyTransportOutputStream;
-import org.jboss.wsf.spi.invocation.InvocationContext;
-
-/**
- * TODO: javadoc
- *
- * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
- */
-final class NettyInvocationHandler extends SimpleChannelUpstreamHandler
-{
-   private static final Logger LOG = Logger.getLogger(NettyInvocationHandler.class);
-
-   private final List<NettyHttpServerCallbackHandler> callbacks = new LinkedList<NettyHttpServerCallbackHandler>();
-
-   private final Lock lock = new ReentrantLock();
-
-   public NettyInvocationHandler()
-   {
-      super();
-   }
-
-   @Override
-   public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
-   {
-      // HERE: Add all accepted channels to the group
-      //       so that they are closed properly on shutdown
-      //       If the added channel is closed before shutdown,
-      //       it will be removed from the group automatically.
-      NettyHttpServer.channelGroup.add(ctx.getChannel());
-   }
-
-   public boolean hasMoreCallbacks()
-   {
-      return this.callbacks.size() > 0;
-   }
-
-   @Override
-   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
-   {
-      HttpRequest request = (HttpRequest) e.getMessage();
-      ChannelBuffer content = request.getContent();
-      OutputStream baos = new ByteArrayOutputStream();
-      OutputStream outputStream = new BufferedOutputStream(baos);
-      Integer statusCode = null;
-
-      InvocationContext invCtx = new InvocationContext();
-      Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
-      Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
-      invCtx.setProperty(Constants.NETTY_REQUEST_HEADERS, requestHeaders);
-      invCtx.setProperty(Constants.NETTY_RESPONSE_HEADERS, responseHeaders);
-      for (String headerName : request.getHeaderNames())
-      {
-         requestHeaders.put(headerName, request.getHeaders(headerName));
-      }
-      try
-      {
-         String requestPath = request.getUri();
-         int paramIndex = requestPath.indexOf('?');
-         if (paramIndex != -1)
-         {
-            requestPath = requestPath.substring(0, paramIndex);
-         }
-         String httpMethod = request.getMethod().getName();
-         statusCode = handle(requestPath, httpMethod, getInputStream(content), outputStream, invCtx);
-      }
-      catch (Throwable t)
-      {
-         statusCode = 500;
-         LOG.error(t);
-      }
-      finally
-      {
-         writeResponse(e, request, baos.toString(), statusCode, responseHeaders, ctx.getChannel());
-      }
-   }
-
-   private InputStream getInputStream(ChannelBuffer content)
-   {
-      return new ChannelBufferInputStream(content);
-   }
-
-   private int handle(String requestPath, String httpMethod, InputStream inputStream, OutputStream outputStream,
-         InvocationContext invCtx) throws IOException
-   {
-      boolean handlerExists = false;
-      String handledPath = null;
-      requestPath = truncateHostName(requestPath);
-      for (NettyHttpServerCallbackHandler handler : this.callbacks)
-      {
-         handledPath = truncateHostName(handler.getHandledPath());
-         if (requestPath.equals(handledPath))
-         {
-            handlerExists = true;
-            if (LOG.isDebugEnabled())
-               LOG.debug("Handling request path: " + requestPath);
-            return handler.handle(httpMethod, inputStream, outputStream, invCtx);
-         }
-      }
-      if (handlerExists == false)
-         LOG.warn("No callback handler registered for path: " + requestPath);
-
-      return 500;
-   }
-
-   private String truncateHostName(String s)
-   {
-      String retVal = s;
-      if (s.startsWith("http"))
-      {
-         try
-         {
-            retVal = new URL(s).getPath();
-         }
-         catch (MalformedURLException mue)
-         {
-            LOG.error(mue.getMessage(), mue);
-         }
-      }
-
-      while (retVal.endsWith("/"))
-      {
-         retVal = retVal.substring(0, retVal.length() - 1);
-      }
-      return retVal;
-   }
-
-   private void writeResponse(MessageEvent e, HttpRequest request, String content, int statusCode,
-         Map<String, List<String>> responseHeaders, Channel channel) throws IOException
-   {
-      // Build the response object.
-      HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, getResponseStatus(statusCode));
-
-      Iterator<String> iterator = responseHeaders.keySet().iterator();
-      String key = null;
-      List<String> values = null;
-      while (iterator.hasNext())
-      {
-         key = iterator.next();
-         values = responseHeaders.get(key);
-         values = removeProhibitedCharacters(values);
-         response.setHeader(key, values);
-      }
-      if (!responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
-      {
-         response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/xml; charset=UTF-8");
-         response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(content.length()));
-         response.setContent(ChannelBuffers.copiedBuffer(content, "UTF-8"));
-      }
-      else
-      {
-         response.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, "chunked");
-      }
-
-      String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
-      if (cookieString != null)
-      {
-         CookieDecoder cookieDecoder = new CookieDecoder();
-         Set<Cookie> cookies = cookieDecoder.decode(cookieString);
-         if (!cookies.isEmpty())
-         {
-            // Reset the cookies if necessary.
-            CookieEncoder cookieEncoder = new CookieEncoder(true);
-            for (Cookie cookie : cookies)
-            {
-               cookieEncoder.addCookie(cookie);
-            }
-            response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
-         }
-      }
-
-      // Write the response.
-      ChannelFuture cf = e.getChannel().write(response);
-      if (responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
-      {
-         NettyTransportOutputStream out = new NettyTransportOutputStream(channel, 1024);
-         out.write(content.getBytes("UTF-8"));
-         out.close();
-         out.getChannelFuture().awaitUninterruptibly();
-      }
-      else
-      {
-         cf.awaitUninterruptibly();
-      }
-   }
-
-   private List<String> removeProhibitedCharacters(List<String> values)
-   {
-      List<String> retVal = new LinkedList<String>();
-      for (int i = 0; i < values.size(); i++)
-      {
-         retVal.add(i, removeProhibitedCharacters(values.get(i)));
-      }
-
-      return retVal;
-   }
-
-   private String removeProhibitedCharacters(String s)
-   {
-      String retVal = s;
-
-      retVal = retVal.replace('\r', ' ');
-      retVal = retVal.replace('\n', ' ');
-
-      return retVal;
-   }
-
-   private HttpResponseStatus getResponseStatus(int statusCode)
-   {
-      // TODO: https://jira.jboss.org/jira/browse/NETTY-233 
-      if (statusCode == 500)
-         return HttpResponseStatus.INTERNAL_SERVER_ERROR;
-      if (statusCode == 202)
-         return HttpResponseStatus.ACCEPTED;
-      if (statusCode == 204)
-         return HttpResponseStatus.NO_CONTENT;
-
-      return HttpResponseStatus.OK;
-   }
-
-   @Override
-   public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception
-   {
-      e.getCause().printStackTrace();
-      e.getChannel().close();
-   }
-
-   public NettyHttpServerCallbackHandler getCallback(String requestPath)
-   {
-      this.lock.lock();
-      try
-      {
-         for (NettyHttpServerCallbackHandler handler : this.callbacks)
-         {
-            if (handler.getHandledPath().equals(requestPath))
-               return handler;
-         }
-      }
-      finally
-      {
-         this.lock.unlock();
-      }
-
-      return null;
-   }
-
-   public void registerCallback(NettyHttpServerCallbackHandler callbackHandler)
-   {
-      this.lock.lock();
-      try
-      {
-         this.callbacks.add(callbackHandler);
-      }
-      finally
-      {
-         this.lock.unlock();
-      }
-   }
-
-   public void unregisterCallback(NettyHttpServerCallbackHandler callbackHandler)
-   {
-      this.lock.lock();
-      try
-      {
-         this.callbacks.remove(callbackHandler);
-         callbackHandler.destroy();
-      }
-      finally
-      {
-         this.lock.unlock();
-      }
-   }
-
-}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.jaxws.spi.http;
+
+import org.jboss.ws.core.server.netty.NettyRequestHandlerFactory;
+
+/**
+ * Netty request handler factory for endpoint publish API.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+final class NettyRequestHandlerFactoryImpl implements NettyRequestHandlerFactory<NettyRequestHandlerImpl>
+{
+   
+   private static final NettyRequestHandlerFactory<NettyRequestHandlerImpl> SINGLETON = new NettyRequestHandlerFactoryImpl();
+   
+   private NettyRequestHandlerFactoryImpl()
+   {
+      super();
+   }
+
+   public NettyRequestHandlerImpl newNettyRequestHandler()
+   {
+      return new NettyRequestHandlerImpl();
+   }
+   
+   public static NettyRequestHandlerFactory<NettyRequestHandlerImpl> getInstance()
+   {
+      return SINGLETON;
+   }
+
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,261 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.jaxws.spi.http;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.logging.Logger;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBufferInputStream;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.jboss.netty.handler.codec.http.Cookie;
+import org.jboss.netty.handler.codec.http.CookieDecoder;
+import org.jboss.netty.handler.codec.http.CookieEncoder;
+import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
+import org.jboss.netty.handler.codec.http.HttpHeaders;
+import org.jboss.netty.handler.codec.http.HttpRequest;
+import org.jboss.netty.handler.codec.http.HttpResponse;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.jboss.netty.handler.codec.http.HttpVersion;
+import org.jboss.ws.Constants;
+import org.jboss.ws.core.client.transport.NettyTransportOutputStream;
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
+import org.jboss.ws.core.server.netty.AbstractNettyRequestHandler;
+import org.jboss.wsf.spi.invocation.InvocationContext;
+
+/**
+ * Netty request handler for endpoint publish API.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+final class NettyRequestHandlerImpl extends AbstractNettyRequestHandler
+{
+   private static final Logger LOG = Logger.getLogger(NettyRequestHandlerImpl.class);
+
+   public NettyRequestHandlerImpl()
+   {
+      super();
+   }
+
+   @Override
+   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
+   {
+      HttpRequest request = (HttpRequest) e.getMessage();
+      ChannelBuffer content = request.getContent();
+      OutputStream baos = new ByteArrayOutputStream();
+      OutputStream outputStream = new BufferedOutputStream(baos);
+      Integer statusCode = null;
+
+      InvocationContext invCtx = new InvocationContext();
+      Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
+      Map<String, List<String>> responseHeaders = new HashMap<String, List<String>>();
+      invCtx.setProperty(Constants.NETTY_REQUEST_HEADERS, requestHeaders);
+      invCtx.setProperty(Constants.NETTY_RESPONSE_HEADERS, responseHeaders);
+      for (String headerName : request.getHeaderNames())
+      {
+         requestHeaders.put(headerName, request.getHeaders(headerName));
+      }
+      try
+      {
+         String requestPath = request.getUri();
+         int paramIndex = requestPath.indexOf('?');
+         if (paramIndex != -1)
+         {
+            requestPath = requestPath.substring(0, paramIndex);
+         }
+         String httpMethod = request.getMethod().getName();
+         statusCode = handle(requestPath, httpMethod, getInputStream(content), outputStream, invCtx);
+      }
+      catch (Throwable t)
+      {
+         statusCode = 500;
+         LOG.error(t);
+      }
+      finally
+      {
+         writeResponse(e, request, baos.toString(), statusCode, responseHeaders, ctx.getChannel());
+      }
+   }
+
+   private InputStream getInputStream(ChannelBuffer content)
+   {
+      return new ChannelBufferInputStream(content);
+   }
+
+   private int handle(String requestPath, String httpMethod, InputStream inputStream, OutputStream outputStream,
+         InvocationContext invCtx) throws IOException
+   {
+      boolean handlerExists = false;
+      String handledPath = null;
+      requestPath = truncateHostName(requestPath);
+      NettyCallbackHandlerImpl handler = (NettyCallbackHandlerImpl)this.getCallback(requestPath);
+      if (handler != null)
+      {
+         handlerExists = true;
+         if (LOG.isDebugEnabled())
+            LOG.debug("Handling request path: " + requestPath);
+         
+         return handler.handle(httpMethod, inputStream, outputStream, invCtx);
+      }
+      if (handlerExists == false)
+         LOG.warn("No callback handler registered for path: " + requestPath);
+
+      return 500;
+   }
+
+   private String truncateHostName(String s)
+   {
+      String retVal = s;
+      if (s.startsWith("http"))
+      {
+         try
+         {
+            retVal = new URL(s).getPath();
+         }
+         catch (MalformedURLException mue)
+         {
+            LOG.error(mue.getMessage(), mue);
+         }
+      }
+
+      while (retVal.endsWith("/"))
+      {
+         retVal = retVal.substring(0, retVal.length() - 1);
+      }
+      return retVal;
+   }
+
+   private void writeResponse(MessageEvent e, HttpRequest request, String content, int statusCode,
+         Map<String, List<String>> responseHeaders, Channel channel) throws IOException
+   {
+      // Build the response object.
+      HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, getResponseStatus(statusCode));
+
+      Iterator<String> iterator = responseHeaders.keySet().iterator();
+      String key = null;
+      List<String> values = null;
+      while (iterator.hasNext())
+      {
+         key = iterator.next();
+         values = responseHeaders.get(key);
+         values = removeProhibitedCharacters(values);
+         response.setHeader(key, values);
+      }
+      if (!responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
+      {
+         response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/xml; charset=UTF-8");
+         response.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(content.length()));
+         response.setContent(ChannelBuffers.copiedBuffer(content, "UTF-8"));
+      }
+      else
+      {
+         response.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, "chunked");
+      }
+
+      String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
+      if (cookieString != null)
+      {
+         CookieDecoder cookieDecoder = new CookieDecoder();
+         Set<Cookie> cookies = cookieDecoder.decode(cookieString);
+         if (!cookies.isEmpty())
+         {
+            // Reset the cookies if necessary.
+            CookieEncoder cookieEncoder = new CookieEncoder(true);
+            for (Cookie cookie : cookies)
+            {
+               cookieEncoder.addCookie(cookie);
+            }
+            response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
+         }
+      }
+
+      // Write the response.
+      ChannelFuture cf = e.getChannel().write(response);
+      if (responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
+      {
+         NettyTransportOutputStream out = new NettyTransportOutputStream(channel, 1024);
+         out.write(content.getBytes("UTF-8"));
+         out.close();
+         out.getChannelFuture().awaitUninterruptibly();
+      }
+      else
+      {
+         cf.awaitUninterruptibly();
+      }
+   }
+
+   private List<String> removeProhibitedCharacters(List<String> values)
+   {
+      List<String> retVal = new LinkedList<String>();
+      for (int i = 0; i < values.size(); i++)
+      {
+         retVal.add(i, removeProhibitedCharacters(values.get(i)));
+      }
+
+      return retVal;
+   }
+
+   private String removeProhibitedCharacters(String s)
+   {
+      String retVal = s;
+
+      retVal = retVal.replace('\r', ' ');
+      retVal = retVal.replace('\n', ' ');
+
+      return retVal;
+   }
+
+   private HttpResponseStatus getResponseStatus(int statusCode)
+   {
+      // TODO: https://jira.jboss.org/jira/browse/NETTY-233 
+      if (statusCode == 500)
+         return HttpResponseStatus.INTERNAL_SERVER_ERROR;
+      if (statusCode == 202)
+         return HttpResponseStatus.ACCEPTED;
+      if (statusCode == 204)
+         return HttpResponseStatus.NO_CONTENT;
+
+      return HttpResponseStatus.OK;
+   }
+
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelPipelineCoverage;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+
+/**
+ * Abstract Netty request handler.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:asoldano at redhat.com">Alessio Soldano</a>
+ */
+ at ChannelPipelineCoverage("one")
+public abstract class AbstractNettyRequestHandler extends SimpleChannelUpstreamHandler
+{
+
+   /** Callbacks registry. */
+   private final List<NettyCallbackHandler> callbacks = new LinkedList<NettyCallbackHandler>();
+   /** Callback registry lock. */
+   private final Lock callbackRegistryLock = new ReentrantLock();
+
+   /**
+    * Constructor.
+    */
+   protected AbstractNettyRequestHandler()
+   {
+      super();
+   }
+
+   /**
+    * Template method implementation.
+    * 
+    * @param ctx channel handler context
+    * @param e channel state event
+    */
+   @Override
+   public final void channelOpen(final ChannelHandlerContext ctx, final ChannelStateEvent e)
+   {
+      // HERE: Add all accepted channels to the group
+      //       so that they are closed properly on shutdown
+      //       If the added channel is closed before shutdown,
+      //       it will be removed from the group automatically.
+      NettyHttpServerImpl.channelGroup.add(ctx.getChannel());
+   }
+
+   /**
+    * Template method implementation.
+    * 
+    * @param ctx channel handler context
+    * @param e exception event
+    * @throws Exception if some error occurs
+    */
+   @Override
+   public final void exceptionCaught(final ChannelHandlerContext ctx, final ExceptionEvent e) throws Exception
+   {
+      e.getCause().printStackTrace();
+      e.getChannel().close();
+   }
+
+   /**
+    * Template method for processing incoming requests.
+    * 
+    * @param ctx channel handler context
+    * @param e message event
+    * @throws Exception if some error occurs
+    */
+   @Override
+   public abstract void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception;
+
+   /**
+    * Returns true if request handler have at least one callback registered, false otherwise.
+    *
+    * @return true if at least one callback is registered, false otherwise
+    */
+   public final boolean hasMoreCallbacks()
+   {
+      this.callbackRegistryLock.lock();
+      try
+      {
+         return this.callbacks.size() > 0;
+      }
+      finally
+      {
+         this.callbackRegistryLock.unlock();
+      }
+   }
+
+   /**
+    * Returns callback handler associated with request path.
+    * 
+    * @param requestPath to get handler for
+    * @return callback handler
+    */
+   public final NettyCallbackHandler getCallback(final String requestPath)
+   {
+      this.callbackRegistryLock.lock();
+      try
+      {
+         for (final NettyCallbackHandler handler : this.callbacks)
+         {
+            if (handler.getPath().equals(requestPath))
+            {
+               return handler;
+            }
+         }
+      }
+      finally
+      {
+         this.callbackRegistryLock.unlock();
+      }
+
+      return null;
+   }
+
+   /**
+    * Registers callback.
+    *
+    * @param callback netty callback
+    */
+   public final void registerCallback(final NettyCallbackHandler callback)
+   {
+      this.callbackRegistryLock.lock();
+      try
+      {
+         callback.init();
+         this.callbacks.add(callback);
+      }
+      finally
+      {
+         this.callbackRegistryLock.unlock();
+      }
+   }
+
+   /**
+    * Unregisters callback. 
+    *
+    * @param callback netty callback
+    */
+   public final void unregisterCallback(final NettyCallbackHandler callback)
+   {
+      this.callbackRegistryLock.lock();
+      try
+      {
+         this.callbacks.remove(callback);
+         callback.destroy();
+      }
+      finally
+      {
+         this.callbackRegistryLock.unlock();
+      }
+   }
+
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+/**
+ * Netty callback handler abstraction.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+public interface NettyCallbackHandler
+{
+
+   /**
+    * Template method to initialize callback handler.
+    */
+   void init();
+
+   /**
+    * Returns path callback handler operates on.
+    *
+    * @return callback working path
+    */
+   String getPath();
+
+   /**
+    * Template method to destroy callback handler.
+    */
+   void destroy();
+
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,68 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+/**
+ * Netty Http Server abstraction.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+public interface NettyHttpServer
+{
+
+   /**
+    * Registers new callback.
+    *
+    * @param callback netty callback
+    */
+   void registerCallback(NettyCallbackHandler callback);
+
+   /**
+    * Registers old callback.
+    *
+    * @param callback netty callback
+    */
+   void unregisterCallback(NettyCallbackHandler callback);
+
+   /**
+    * Returns registered callback associated with request path.
+    *
+    * @param requestPath request path to get associated callback for
+    * @return callback handler
+    */
+   NettyCallbackHandler getCallback(String requestPath);
+
+   /**
+    * Returns true if server has some callbacks registered, false otherwise.
+    *
+    * @return true if callbacks are available, false otherwise
+    */
+   boolean hasMoreCallbacks();
+
+   /**
+    * Returns port this server runs on.
+    *
+    * @return server port
+    */
+   int getPort();
+
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Netty based http server factory.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+public final class NettyHttpServerFactory
+{
+
+   /**
+    * Servers registry.
+    */
+   static final Map<Integer, NettyHttpServer> SERVERS = new HashMap<Integer, NettyHttpServer>();
+
+   /**
+    * Constructor.
+    */
+   private NettyHttpServerFactory()
+   {
+      super();
+   }
+
+   /**
+    * Starts Netty based http server on the background if method is called for the first time,
+    * otherwise returns already existing and running server instance.
+    * 
+    * @param port server port
+    * @param requestHandlerFactory request handle factory
+    * @param <T> factory type
+    * @return running Netty based http server
+    */
+   public static <T extends NettyRequestHandlerFactory<?>> NettyHttpServer getNettyHttpServer(final int port,
+         final T requestHandlerFactory)
+   {
+      if (port <= 0)
+      {
+         throw new IllegalArgumentException("Not positive port value");
+      }
+      if (requestHandlerFactory == null)
+      {
+         throw new NullPointerException("Factory cannot be null");
+      }
+
+      synchronized (NettyHttpServerFactory.SERVERS)
+      {
+         NettyHttpServer server = NettyHttpServerFactory.SERVERS.get(port);
+         if (server == null)
+         {
+            server = new NettyHttpServerImpl(port, requestHandlerFactory);
+            NettyHttpServerFactory.SERVERS.put(port, server);
+         }
+         return server;
+      }
+   }
+
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,251 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+
+import javax.xml.ws.WebServiceException;
+
+import org.jboss.logging.Logger;
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.group.ChannelGroup;
+import org.jboss.netty.channel.group.DefaultChannelGroup;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.jboss.ws.core.client.transport.WSServerPipelineFactory;
+
+/**
+ * Netty http server implementation.
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:asoldano at redhat.com">Alessio Soldano</a>
+ */
+final class NettyHttpServerImpl implements NettyHttpServer, Runnable
+{
+
+   private static final Logger LOG = Logger.getLogger(NettyHttpServerImpl.class);
+
+   private static final long WAIT_PERIOD = 100;
+
+   static final ChannelGroup channelGroup = new DefaultChannelGroup("NettyHttpServer");
+
+   private final Object instanceLock = new Object();
+
+   private final int port;
+
+   private boolean started;
+
+   private boolean stopped;
+
+   private boolean terminated;
+
+   private ChannelFactory factory;
+
+   private AbstractNettyRequestHandler handler;
+
+   NettyHttpServerImpl(int port, NettyRequestHandlerFactory<?> nettyRequestHandlerFactory)
+   {
+      super();
+      this.port = port;
+      try
+      {
+         factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
+
+         ServerBootstrap bootstrap = new ServerBootstrap(factory);
+         this.handler = nettyRequestHandlerFactory.newNettyRequestHandler();
+         WSServerPipelineFactory channelPipelineFactory = new WSServerPipelineFactory();
+         channelPipelineFactory.setRequestHandler(this.handler);
+         bootstrap.setPipelineFactory(channelPipelineFactory);
+         bootstrap.setOption("child.tcpNoDelay", true);
+         bootstrap.setOption("child.keepAlive", true);
+         // Bind and start to accept incoming connections.
+         Channel c = bootstrap.bind(new InetSocketAddress(this.port));
+         channelGroup.add(c);
+         // forking Netty server
+         Thread t = new Thread(this, "NettyHttpServer listening on port " + port);
+         t.setDaemon(true);
+         t.start();
+         // registering shutdown hook
+         Runnable shutdownHook = new NettyHttpServerShutdownHook(this);
+         Runtime.getRuntime().addShutdownHook(
+               new Thread(shutdownHook, "NettyHttpServerShutdownHook(port=" + port + ")"));
+         if (LOG.isDebugEnabled())
+            LOG.debug("Netty http server started on port: " + this.port);
+      }
+      catch (Exception e)
+      {
+         LOG.warn(e.getMessage(), e);
+         throw new WebServiceException(e.getMessage(), e);
+      }
+   }
+
+   public final void registerCallback(final NettyCallbackHandler callback)
+   {
+      if (callback == null)
+         throw new IllegalArgumentException("Null callback handler");
+
+      this.ensureUpAndRunning();
+
+      this.handler.registerCallback(callback);
+   }
+
+   public final void unregisterCallback(final NettyCallbackHandler callback)
+   {
+      if (callback == null)
+         throw new IllegalArgumentException("Null callback handler");
+
+      this.ensureUpAndRunning();
+
+      try
+      {
+         this.handler.unregisterCallback(callback);
+      }
+      finally
+      {
+         if (!this.hasMoreCallbacks())
+         {
+            this.terminate();
+         }
+      }
+   }
+
+   public final NettyCallbackHandler getCallback(final String requestPath)
+   {
+      if (requestPath == null)
+         throw new IllegalArgumentException("Null request path");
+
+      this.ensureUpAndRunning();
+
+      return this.handler.getCallback(requestPath);
+   }
+
+   public final boolean hasMoreCallbacks()
+   {
+      this.ensureUpAndRunning();
+
+      return this.handler.hasMoreCallbacks();
+   }
+
+   public final int getPort()
+   {
+      this.ensureUpAndRunning();
+
+      return this.port;
+   }
+
+   private void ensureUpAndRunning()
+   {
+      synchronized (this.instanceLock)
+      {
+         if (this.stopped)
+            throw new IllegalStateException("Server is down");
+      }
+   }
+
+   public final void run()
+   {
+      synchronized (this.instanceLock)
+      {
+         if (this.started)
+            return;
+
+         this.started = true;
+
+         while (this.stopped == false)
+         {
+            try
+            {
+               this.instanceLock.wait(WAIT_PERIOD);
+            }
+            catch (InterruptedException ie)
+            {
+               LOG.warn(ie.getMessage(), ie);
+            }
+         }
+         try
+         {
+            //Close all connections and server sockets.
+            channelGroup.close().awaitUninterruptibly();
+            //Shutdown the selector loop (boss and worker).
+            if (factory != null)
+            {
+               factory.releaseExternalResources();
+            }
+         }
+         finally
+         {
+            LOG.debug("terminated");
+            this.terminated = true;
+         }
+      }
+   }
+
+   public final void terminate()
+   {
+      synchronized (this.instanceLock)
+      {
+         if (this.stopped == true)
+            return;
+
+         this.stopped = true;
+         LOG.debug("termination forced");
+         while (this.terminated == false)
+         {
+            try
+            {
+               LOG.debug("waiting for termination");
+               this.instanceLock.wait(WAIT_PERIOD);
+            }
+            catch (InterruptedException ie)
+            {
+               LOG.warn(ie.getMessage(), ie);
+            }
+         }
+         synchronized (NettyHttpServerFactory.SERVERS)
+         {
+            NettyHttpServerFactory.SERVERS.remove(port);
+         }
+      }
+   }
+
+   private static final class NettyHttpServerShutdownHook implements Runnable
+   {
+
+      private final NettyHttpServerImpl nettyHttpServer;
+
+      private NettyHttpServerShutdownHook(final NettyHttpServerImpl nettyHttpServer)
+      {
+         super();
+
+         this.nettyHttpServer = nettyHttpServer;
+      }
+
+      public void run()
+      {
+         this.nettyHttpServer.terminate();
+      }
+
+   }
+
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+/**
+ * Netty request handler factory.
+ *
+ * @param <T> netty request handler type
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+public interface NettyRequestHandlerFactory<T extends AbstractNettyRequestHandler>
+{
+
+   /**
+    * Creates new Netty request handler instance.
+    * @return handler instance
+    */
+   T newNettyRequestHandler();
+
+}

Deleted: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -1,220 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ws.extensions.wsrm.transport.backchannel;
-
-import java.net.URL;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBufferInputStream;
-import org.jboss.netty.channel.ChannelFuture;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipelineCoverage;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.http.Cookie;
-import org.jboss.netty.handler.codec.http.CookieDecoder;
-import org.jboss.netty.handler.codec.http.CookieEncoder;
-import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
-import org.jboss.netty.handler.codec.http.HttpHeaders;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.HttpResponse;
-import org.jboss.netty.handler.codec.http.HttpResponseStatus;
-import org.jboss.netty.handler.codec.http.HttpVersion;
-import org.jboss.ws.extensions.wsrm.transport.RMMessage;
-import org.jboss.ws.extensions.wsrm.transport.RMUnMarshaller;
-
-/**
- * TODO: Add comment
- *
- * @author richard.opalka at jboss.com
- * @author alessio.soldano at jboss.com
- *
- * @since Nov 20, 2007
- */
- at ChannelPipelineCoverage("one")
-public final class RMBackPortsInvocationHandler extends SimpleChannelUpstreamHandler
-{
-   private static final Logger LOG = Logger.getLogger(RMBackPortsInvocationHandler.class);
-   private final List<RMCallbackHandler> callbacks = new LinkedList<RMCallbackHandler>();
-   private final Lock lock = new ReentrantLock();
-
-
-   public RMBackPortsInvocationHandler()
-   {
-   }
-   
-   @Override
-   public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
-   {
-      // HERE: Add all accepted channels to the group
-      //       so that they are closed properly on shutdown
-      //       If the added channel is closed before shutdown,
-      //       it will be removed from the group automatically.
-      RMBackPortsServer.channelGroup.add(ctx.getChannel());
-   } 
-
-   @Override
-   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
-   {
-      HttpRequest request = (HttpRequest)e.getMessage();
-      ChannelBuffer content = request.getContent();
-
-      Map<String, Object> requestHeaders = new HashMap<String, Object>();
-      for (String headerName : request.getHeaderNames())
-      {
-         requestHeaders.put(headerName, request.getHeaders(headerName));
-      }
-      boolean error = false;
-      try
-      {
-         String requestPath = new URL(request.getUri()).getPath();
-         RMMessage message = (RMMessage)RMUnMarshaller.getInstance().read(content.readable() ? new ChannelBufferInputStream(content) : null, requestHeaders);
-         handle(requestPath, message);
-      }
-      catch (Throwable t)
-      {
-         error = true;
-         LOG.error("Error decoding request to the backport", t);
-      }
-      finally
-      {
-         writeResponse(e, request, error);
-      }
-   }
-   
-   
-   private void handle(String requestPath, RMMessage message)
-   {
-      this.lock.lock();
-      try
-      {
-         boolean handlerExists = false;
-         for (RMCallbackHandler handler : this.callbacks)
-         {
-            if (handler.getHandledPath().equals(requestPath))
-            {
-               handlerExists = true;
-               if (LOG.isDebugEnabled())
-                  LOG.debug("Handling request path: " + requestPath);
-               handler.handle(message);
-               break;
-            }
-         }
-         if (handlerExists == false)
-            LOG.warn("No callback handler registered for path: " + requestPath);
-      }
-      finally
-      {
-         this.lock.unlock();
-      }
-   }
-   
-   private void writeResponse(MessageEvent e, HttpRequest request, boolean error)
-   {
-      // Build the response object.
-      HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, error ? HttpResponseStatus.INTERNAL_SERVER_ERROR : HttpResponseStatus.NO_CONTENT);
-      response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8");
-
-      String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
-      if (cookieString != null)
-      {
-         CookieDecoder cookieDecoder = new CookieDecoder();
-         Set<Cookie> cookies = cookieDecoder.decode(cookieString);
-         if (!cookies.isEmpty())
-         {
-            // Reset the cookies if necessary.
-            CookieEncoder cookieEncoder = new CookieEncoder(true);
-            for (Cookie cookie : cookies)
-            {
-               cookieEncoder.addCookie(cookie);
-            }
-            response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
-         }
-      }
-
-      // Write the response.
-      ChannelFuture cf = e.getChannel().write(response);
-      cf.awaitUninterruptibly();
-   }
-
-   @Override
-   public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception
-   {
-      e.getCause().printStackTrace();
-      e.getChannel().close();
-   }
-
-   public RMCallbackHandler getCallback(String requestPath)
-   {
-      this.lock.lock();
-      try
-      {
-         for (RMCallbackHandler handler : this.callbacks)
-         {
-            if (handler.getHandledPath().equals(requestPath))
-               return handler;
-         }
-      }
-      finally
-      {
-         this.lock.unlock();
-      }
-
-      return null;
-   }
-
-   public void registerCallback(RMCallbackHandler callbackHandler)
-   {
-      this.lock.lock();
-      try
-      {
-         this.callbacks.add(callbackHandler);
-      }
-      finally
-      {
-         this.lock.unlock();
-      }
-   }
-
-   public void unregisterCallback(RMCallbackHandler callbackHandler)
-   {
-      this.lock.lock();
-      try
-      {
-         this.callbacks.remove(callbackHandler);
-      }
-      finally
-      {
-         this.lock.unlock();
-      }
-   }
-}

Deleted: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -1,233 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.ws.extensions.wsrm.transport.backchannel;
-
-import java.net.InetSocketAddress;
-import java.util.concurrent.Executors;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.ws.core.client.transport.WSServerPipelineFactory;
-import org.jboss.ws.extensions.wsrm.api.RMException;
-
-/**
- * Back ports server used by addressable clients
- *
- * @author richard.opalka at jboss.com
- * @author alessio.soldano at jboss.com
- *
- * @since Nov 20, 2007
- */
-public final class RMBackPortsServer implements Runnable
-{
-   private static final Logger LOG = Logger.getLogger(RMBackPortsServer.class);
-   private static final Lock CLASS_LOCK = new ReentrantLock();
-   private static final long WAIT_PERIOD = 100;
-   private static RMBackPortsServer INSTANCE;
-   static final ChannelGroup channelGroup = new DefaultChannelGroup("rmBackPortsServer");
-
-   private final Object instanceLock = new Object();
-   private final String scheme;
-   private final String host;
-   private final int port;
-   private RMBackPortsInvocationHandler handler;
-   private boolean started;
-   private boolean stopped;
-   private boolean terminated;
-   private ChannelFactory factory;
-   
-   public final void registerCallback(RMCallbackHandler callbackHandler)
-   {
-      this.handler.registerCallback(callbackHandler);
-   }
-   
-   public final void unregisterCallback(RMCallbackHandler callbackHandler)
-   {
-      this.handler.unregisterCallback(callbackHandler);
-   }
-   
-   public final RMCallbackHandler getCallback(String requestPath)
-   {
-      return this.handler.getCallback(requestPath);
-   }
-   
-   private RMBackPortsServer(String scheme, String host, int port) throws RMException
-   {
-      super();
-      this.scheme = scheme;
-      this.host = host;
-      this.port = port;
-      try
-      {
-         factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
-
-         ServerBootstrap bootstrap = new ServerBootstrap(factory);
-         this.handler = new RMBackPortsInvocationHandler();
-         WSServerPipelineFactory channelPipelineFactory = new WSServerPipelineFactory();
-         channelPipelineFactory.setRequestHandler(this.handler);
-         bootstrap.setPipelineFactory(channelPipelineFactory);
-         bootstrap.setOption("child.tcpNoDelay", true);
-         bootstrap.setOption("child.keepAlive", true);
-         // Bind and start to accept incoming connections.
-         Channel c = bootstrap.bind(new InetSocketAddress(this.port));
-         channelGroup.add(c);
-         if (LOG.isDebugEnabled())
-            LOG.debug("WS-RM Backports Server started on port: " + this.port);
-      }
-      catch (Exception e)
-      {
-         LOG.warn(e.getMessage(), e);
-         throw new RMException(e.getMessage(), e);
-      }
-   }
-   
-   public final String getScheme()
-   {
-      return this.scheme;
-   }
-   
-   public final String getHost()
-   {
-      return this.host;
-   }
-   
-   public final int getPort()
-   {
-      return this.port;
-   }
-   
-   public final void run()
-   {
-      synchronized (this.instanceLock)
-      {
-         if (this.started)
-            return;
-         
-         this.started = true;
-         
-         while (this.stopped == false)
-         {
-            try
-            {
-               this.instanceLock.wait(WAIT_PERIOD);
-               LOG.debug("serving requests");
-            }
-            catch (InterruptedException ie)
-            {
-               LOG.warn(ie.getMessage(), ie);
-            }
-         }
-         try
-         {
-            //Close all connections and server sockets.
-            channelGroup.close().awaitUninterruptibly();
-            //Shutdown the selector loop (boss and worker).
-            if (factory != null)
-            {
-               factory.releaseExternalResources();
-            }
-         }
-         finally
-         {
-            LOG.debug("terminated");
-            this.terminated = true;
-         }
-      }
-   }
-   
-   public final void terminate()
-   {
-      synchronized (this.instanceLock)
-      {
-         if (this.stopped == true)
-            return;
-         
-         this.stopped = true;
-         LOG.debug("termination forced");
-         while (this.terminated == false)
-         {
-            try
-            {
-               LOG.debug("waiting for termination");
-               this.instanceLock.wait(WAIT_PERIOD);
-            }
-            catch (InterruptedException ie)
-            {
-               LOG.warn(ie.getMessage(), ie);
-            }
-         }
-      }
-   }
-   
-   /**
-    * Starts back ports server on the background if method is called for the first time
-    * @param scheme protocol
-    * @param host hostname
-    * @param port port
-    * @return WS-RM back ports server
-    * @throws RMException
-    */
-   public static RMBackPortsServer getInstance(String scheme, String host, int port) throws RMException
-   {
-      CLASS_LOCK.lock();
-      try
-      {
-         if (INSTANCE == null)
-         {
-            INSTANCE = new RMBackPortsServer(scheme, host, (port == -1) ? 80 : port);
-            // forking back ports server
-            Thread t  = new Thread(INSTANCE, "RMBackPortsServer");
-            t.setDaemon(true);
-            t.start();
-            // registering shutdown hook
-            final RMBackPortsServer server = INSTANCE;
-            Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
-               public void run()
-               {
-                  server.terminate();
-               }
-            }, "RMBackPortsServerShutdownHook"));
-         }
-         else
-         {
-            boolean schemeEquals = INSTANCE.getScheme().equals(scheme);
-            boolean hostEquals = INSTANCE.getHost().equals(host);
-            boolean portEquals = INSTANCE.getPort() == ((port == -1) ? 80 : port);
-            if ((schemeEquals == false) || (hostEquals == false) || (portEquals == false))
-               throw new IllegalArgumentException();
-         }
-         return INSTANCE;
-      }
-      finally
-      {
-         CLASS_LOCK.unlock();
-      }
-   }
-   
-}

Modified: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -21,6 +21,7 @@
  */
 package org.jboss.ws.extensions.wsrm.transport.backchannel;
 
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
 import org.jboss.ws.extensions.wsrm.transport.RMMessage;
 import org.jboss.ws.extensions.wsrm.transport.RMUnassignedMessageListener;
 
@@ -31,9 +32,8 @@
  *
  * @since Nov 21, 2007
  */
-public interface RMCallbackHandler
+public interface RMCallbackHandler extends NettyCallbackHandler
 {
-   String getHandledPath();
    void handle(RMMessage message);
    RMMessage getMessage(String messageId);
    Throwable getFault(String messageId);

Modified: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -25,6 +25,9 @@
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
+import org.jboss.ws.core.server.netty.NettyHttpServer;
+import org.jboss.ws.core.server.netty.NettyHttpServerFactory;
+
 /**
  * Callback factory
  *
@@ -34,7 +37,7 @@
  */
 public final class RMCallbackHandlerFactory
 {
-   private static RMBackPortsServer server;
+   private static NettyHttpServer server;
    private static Lock lock = new ReentrantLock();
    
    private RMCallbackHandlerFactory()
@@ -49,9 +52,9 @@
       {
          if (server == null)
          {
-            server = RMBackPortsServer.getInstance(backPort.getScheme(), backPort.getHost(), backPort.getPort());
+            server = NettyHttpServerFactory.getNettyHttpServer(backPort.getPort(), RMRequestHandlerFactory.getInstance());
          }
-         RMCallbackHandler callbackHandler = server.getCallback(backPort.getPath());
+         RMCallbackHandler callbackHandler = (RMCallbackHandler)server.getCallback(backPort.getPath());
          if (callbackHandler == null)
          {
             callbackHandler = new RMCallbackHandlerImpl(backPort.getPath());

Modified: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java	2009-10-12 05:48:22 UTC (rev 10887)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -59,13 +59,23 @@
          logger.debug("Registered callback handler listening on '" + handledPath + "' request path");
    }
    
+   public void init()
+   {
+      // does nothing
+   }
+   
+   public void destroy()
+   {
+      // does nothing
+   }
+   
    public Throwable getFault(String messageId)
    {
       // TODO implement
       return null;
    }
 
-   public final String getHandledPath()
+   public final String getPath()
    {
       return this.handledPath;
    }

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.extensions.wsrm.transport.backchannel;
+
+import org.jboss.ws.core.server.netty.NettyRequestHandlerFactory;
+
+/**
+ * TODO: javadoc
+ *
+ * @author <a href="mailto:ropalka at redhat.com">Richard Opalka</a>
+ */
+final class RMRequestHandlerFactory implements NettyRequestHandlerFactory<RMRequestHandlerImpl>
+{
+   private static final NettyRequestHandlerFactory<RMRequestHandlerImpl> SINGLETON = new RMRequestHandlerFactory();
+
+   public RMRequestHandlerImpl newNettyRequestHandler()
+   {
+      return new RMRequestHandlerImpl();
+   }
+   
+   public static NettyRequestHandlerFactory<RMRequestHandlerImpl> getInstance()
+   {
+      return SINGLETON;
+   }
+}

Added: stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java
===================================================================
--- stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java	                        (rev 0)
+++ stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java	2009-10-12 13:08:34 UTC (rev 10888)
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.ws.extensions.wsrm.transport.backchannel;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBufferInputStream;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.codec.http.Cookie;
+import org.jboss.netty.handler.codec.http.CookieDecoder;
+import org.jboss.netty.handler.codec.http.CookieEncoder;
+import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
+import org.jboss.netty.handler.codec.http.HttpHeaders;
+import org.jboss.netty.handler.codec.http.HttpRequest;
+import org.jboss.netty.handler.codec.http.HttpResponse;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.jboss.netty.handler.codec.http.HttpVersion;
+import org.jboss.ws.core.server.netty.AbstractNettyRequestHandler;
+import org.jboss.ws.extensions.wsrm.transport.RMMessage;
+import org.jboss.ws.extensions.wsrm.transport.RMUnMarshaller;
+
+/**
+ * RM backports server request handler.
+ *
+ * @author richard.opalka at jboss.com
+ * @author alessio.soldano at jboss.com
+ */
+public final class RMRequestHandlerImpl extends AbstractNettyRequestHandler
+{
+   private static final Logger LOG = Logger.getLogger(RMRequestHandlerImpl.class);
+
+   /**
+    * Constructor.
+    */
+   public RMRequestHandlerImpl()
+   {
+      super();
+   }
+   
+   @Override
+   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception
+   {
+      HttpRequest request = (HttpRequest)e.getMessage();
+      ChannelBuffer content = request.getContent();
+
+      Map<String, Object> requestHeaders = new HashMap<String, Object>();
+      for (String headerName : request.getHeaderNames())
+      {
+         requestHeaders.put(headerName, request.getHeaders(headerName));
+      }
+      boolean error = false;
+      try
+      {
+         String requestPath = new URL(request.getUri()).getPath();
+         RMMessage message = (RMMessage)RMUnMarshaller.getInstance().read(content.readable() ? new ChannelBufferInputStream(content) : null, requestHeaders);
+         handle(requestPath, message);
+      }
+      catch (Throwable t)
+      {
+         error = true;
+         LOG.error("Error decoding request to the backport", t);
+      }
+      finally
+      {
+         writeResponse(e, request, error);
+      }
+   }
+   
+   
+   private void handle(String requestPath, RMMessage message)
+   {
+      RMCallbackHandler handler = (RMCallbackHandler)this.getCallback(requestPath);
+      if (handler != null)
+      {
+         handler.handle(message);
+      }
+      else
+      {
+         LOG.warn("No callback handler registered for path: " + requestPath);
+      }
+   }
+   
+   private void writeResponse(MessageEvent e, HttpRequest request, boolean error)
+   {
+      // Build the response object.
+      HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, error ? HttpResponseStatus.INTERNAL_SERVER_ERROR : HttpResponseStatus.NO_CONTENT);
+      response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain; charset=UTF-8");
+
+      String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
+      if (cookieString != null)
+      {
+         CookieDecoder cookieDecoder = new CookieDecoder();
+         Set<Cookie> cookies = cookieDecoder.decode(cookieString);
+         if (!cookies.isEmpty())
+         {
+            // Reset the cookies if necessary.
+            CookieEncoder cookieEncoder = new CookieEncoder(true);
+            for (Cookie cookie : cookies)
+            {
+               cookieEncoder.addCookie(cookie);
+            }
+            response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
+         }
+      }
+
+      // Write the response.
+      ChannelFuture cf = e.getChannel().write(response);
+      cf.awaitUninterruptibly();
+   }
+
+}



More information about the jbossws-commits mailing list