Hi,

I created a prototype to demonstrate the usage of OSGi HttpService to register servlets for HTTP based bindings such as binding.ws and binding.jsonrpc. It's a bit similar with host-webapp as there is only one port for the HttpService in an OSGi runtime.

BTW, Jetty is moving into Eclipse: http://www.infoq.com/news/2009/03/jetty-eclipse.

Thanks,
Raymond
--------------------------------------------------
From: <[email protected]>
Sent: Friday, March 27, 2009 9:10 AM
To: <[email protected]>
Subject: svn commit: r759191 - in /tuscany/java/sca/modules/host-http-osgi: ./ META-INF/ src/main/java/org/apache/tuscany/sca/http/jetty/ src/main/java/org/apache/tuscany/sca/http/osgi/ src/test/java/org/apache/tuscany/sca/http/jetty/ src/test/java/org/apache/t...

Author: rfeng
Date: Fri Mar 27 16:10:18 2009
New Revision: 759191

URL: http://svn.apache.org/viewvc?rev=759191&view=rev
Log:
Add a module to host http based on OSGi Http Service

Added:
   tuscany/java/sca/modules/host-http-osgi/
     - copied from r758165, tuscany/java/sca/modules/host-jetty/

tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/

tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/HttpServiceWrapper.java (with props)

tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/OSGiServletHost.java (with props)

tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/ServletRequestDispatcher.java (with props)

tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/

tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/OSGiServletHostTestCase.java (with props)
Removed:

tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/jetty/

tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/jetty/
Modified:
   tuscany/java/sca/modules/host-http-osgi/META-INF/MANIFEST.MF
   tuscany/java/sca/modules/host-http-osgi/pom.xml

Modified: tuscany/java/sca/modules/host-http-osgi/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-http-osgi/META-INF/MANIFEST.MF?rev=759191&r1=758165&r2=759191&view=diff
==============================================================================
--- tuscany/java/sca/modules/host-http-osgi/META-INF/MANIFEST.MF (original) +++ tuscany/java/sca/modules/host-http-osgi/META-INF/MANIFEST.MF Fri Mar 27 16:10:18 2009
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
-Private-Package: org.apache.tuscany.sca.http.jetty;version="2.0.0"
+Private-Package: org.apache.tuscany.sca.http.osgi;version="2.0.0"
Tool: Bnd-0.0.255
Bundle-Name: Apache Tuscany SCA Jetty Servlet Host Extension
Created-By: 1.6.0_07 (Sun Microsystems Inc.)
@@ -11,20 +11,15 @@
Bundle-Description: Apache Tuscany SCA Jetty Servlet Host Extension
Import-Package: javax.net.ssl;resolution:=optional,
 javax.servlet,
- javax.servlet.http;resolution:=optional,
-
+ javax.servlet.http,
 org.apache.tuscany.sca.core;version="2.0.0",
 org.apache.tuscany.sca.host.http;version="2.0.0",
 org.apache.tuscany.sca.work;version="2.0.0",
- org.mortbay.component;version="6.1.7",
- org.mortbay.jetty;version="6.1.7",
- org.mortbay.jetty.handler;version="6.1.7",
- org.mortbay.jetty.nio;version="6.1.7",
- org.mortbay.jetty.security;version="6.1.7",
- org.mortbay.jetty.servlet;version="6.1.7",
- org.mortbay.log;version="6.1.7",
- org.mortbay.resource;version="6.1.7",
- org.mortbay.thread;version="6.1.7"
-Bundle-SymbolicName: org.apache.tuscany.sca.host.jetty
+ org.osgi.framework;version="1.4.0",
+ org.osgi.service.http;version="1.2",
+ org.osgi.util.tracker;version="1.3.3"
+Bundle-SymbolicName: org.apache.tuscany.sca.host.http.osgi
Bundle-DocURL: http://www.apache.org/
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.apache.tuscany.sca.http.osgi.OSGiServletHost


Modified: tuscany/java/sca/modules/host-http-osgi/pom.xml
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-http-osgi/pom.xml?rev=759191&r1=758165&r2=759191&view=diff
==============================================================================
--- tuscany/java/sca/modules/host-http-osgi/pom.xml (original)
+++ tuscany/java/sca/modules/host-http-osgi/pom.xml Fri Mar 27 16:10:18 2009
@@ -7,15 +7,15 @@
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
- *
+ *
 *   http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
- * under the License.
+ * under the License.
-->
<project>
    <modelVersion>4.0.0</modelVersion>
@@ -25,8 +25,8 @@
        <version>2.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
-    <artifactId>tuscany-host-jetty</artifactId>
-    <name>Apache Tuscany SCA Jetty Servlet Host Extension</name>
+    <artifactId>tuscany-host-http-osgi</artifactId>
+ <name>Apache Tuscany SCA OSGi HTTP Service Based Servlet Host Extension</name>

    <dependencies>
        <dependency>
@@ -34,36 +34,41 @@
            <artifactId>tuscany-host-http</artifactId>
            <version>2.0-SNAPSHOT</version>
        </dependency>
-
        <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty</artifactId>
-            <version>6.1.7</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.mortbay.jetty</groupId>
-                    <artifactId>servlet-api-2.5</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty-util</artifactId>
-            <version>6.1.7</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.mortbay.jetty</groupId>
-                    <artifactId>servlet-api-2.5</artifactId>
-                </exclusion>
-            </exclusions>
+            <groupId>org.eclipse</groupId>
+            <artifactId>osgi</artifactId>
+            <version>3.4.0-v20080605-1900</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.osgi</groupId>
+            <artifactId>services</artifactId>
+            <version>3.1.200-v20071203</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.equinox</groupId>
+            <artifactId>http</artifactId>
+            <version>1.0.200-v20080421-2006</version>
+            <scope>runtime</scope>
        </dependency>
-
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
+         <dependency>
+            <groupId>org.apache.tuscany.sca</groupId>
+            <artifactId>tuscany-extensibility-equinox</artifactId>
+            <version>2.0-SNAPSHOT</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tuscany.sca</groupId>
+            <artifactId>tuscany-node-launcher-equinox</artifactId>
+            <version>2.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
    </dependencies>

</project>

Added: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/HttpServiceWrapper.java URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/HttpServiceWrapper.java?rev=759191&view=auto
==============================================================================
--- tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/HttpServiceWrapper.java (added) +++ tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/HttpServiceWrapper.java Fri Mar 27 16:10:18 2009
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.http.osgi;
+
+import javax.servlet.Servlet;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.HttpService;
+import org.osgi.util.tracker.ServiceTracker;
+
+/**
+ * A whiteboard for HttpService and Servlet
+ */
+public class HttpServiceWrapper {
+
+    static final String SERVLET_URI = "servlet.uri";
+    private ServiceTracker httpTracker;
+    private BundleContext bc;
+
+    private class HttpServiceTracker extends ServiceTracker {
+        private HttpServiceTracker() {
+            super(bc, HttpService.class.getName(), null);
+        }
+
+        @Override
+        public Object addingService(ServiceReference reference) {
+ HttpService httpService = (HttpService)super.addingService(reference);
+            // Register existing servlets
+ String filter = "(objectclass=" + Servlet.class.getName() + ")";
+            ServiceReference[] servlets = null;
+            try {
+                servlets = bc.getServiceReferences(null, filter);
+            } catch (InvalidSyntaxException e) {
+                throw new IllegalStateException(e);
+            }
+ for (int i = 0; servlets != null && i < servlets.length; i++) {
+                Servlet servlet = (Servlet)bc.getService(servlets[i]);
+ String alias = (String)servlets[i].getProperty(SERVLET_URI);
+
+                try {
+ httpService.registerServlet(alias, servlet, null, null);
+                } catch (Exception e) {
+                    throw new IllegalStateException(e);
+                }
+            }
+            return httpService;
+        }
+    }
+
+    public HttpServiceWrapper(BundleContext bc) {
+        super();
+        this.bc = bc;
+    }
+
+    void open() {
+        httpTracker = new HttpServiceTracker();
+        httpTracker.open();
+
+        ServiceListener sl = new ServiceListener() {
+            public void serviceChanged(ServiceEvent ev) {
+                ServiceReference sr = ev.getServiceReference();
+                switch (ev.getType()) {
+                    case ServiceEvent.REGISTERED: {
+                        registerServlet(sr);
+                    }
+                        break;
+                    case ServiceEvent.UNREGISTERING: {
+                        unregisterServlet(sr);
+                    }
+                        break;
+                }
+            }
+        };
+
+        String filter = "(objectclass=" + Servlet.class.getName() + ")";
+        try {
+            bc.addServiceListener(sl, filter);
+ ServiceReference[] servlets = bc.getServiceReferences(null, filter); + for (int i = 0; servlets != null && i < servlets.length; i++) { + sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, servlets[i]));
+            }
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+    }
+
+    void close() {
+        if (httpTracker != null) {
+            httpTracker.close();
+        }
+    }
+
+    void registerServlet(ServiceReference sr) {
+        Servlet servlet = (Servlet)bc.getService(sr);
+        String alias = (String)sr.getProperty(SERVLET_URI);
+
+        Object[] httpServices = httpTracker.getServices();
+
+ for (int i = 0; httpServices != null && i < httpServices.length; i++) {
+            HttpService http = (HttpService)httpServices[i];
+            try {
+                http.registerServlet(alias, servlet, null, null);
+            } catch (Exception e) {
+                throw new IllegalStateException(e);
+            }
+        }
+    }
+
+    void unregisterServlet(ServiceReference sr) {
+        String alias = (String)sr.getProperty(SERVLET_URI);
+        Object[] httpServices = httpTracker.getServices();
+
+ for (int i = 0; httpServices != null && i < httpServices.length; i++) {
+            HttpService http = (HttpService)httpServices[i];
+            try {
+                http.unregister(alias);
+            } catch (Exception e) {
+                throw new IllegalStateException(e);
+            }
+            bc.ungetService(sr);
+        }
+    }
+
+}

Propchange: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/HttpServiceWrapper.java
------------------------------------------------------------------------------
   svn:eol-style = native

Propchange: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/HttpServiceWrapper.java
------------------------------------------------------------------------------
   svn:keywords = Rev Date

Added: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/OSGiServletHost.java URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/OSGiServletHost.java?rev=759191&view=auto
==============================================================================
--- tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/OSGiServletHost.java (added) +++ tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/OSGiServletHost.java Fri Mar 27 16:10:18 2009
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.http.osgi;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+
+import org.apache.tuscany.sca.host.http.ServletHost;
+import org.apache.tuscany.sca.host.http.ServletMappingException;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ *
+ */
+public class OSGiServletHost implements ServletHost, BundleActivator {
+    static final String DUMMY_URI = "/_tuscany";
+
+    /**
+     * Default servlet
+     */
+    private static class DefaultServlet extends HttpServlet {
+
+        @Override
+ public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+            PrintWriter pw = response.getWriter();
+ pw.println("<html><body><h1>Apache Tuscany</h1></body></html>");
+            pw.flush();
+        }
+    }
+
+ private Map<String, Servlet> servlets = new ConcurrentHashMap<String, Servlet>();
+
+ private static final Logger logger = Logger.getLogger(OSGiServletHost.class.getName());
+
+    private String contextPath = "/";
+    private int defaultPortNumber = 8080;
+
+    private ServletContext servletContext;
+ private Map<String, Object> attributes = new HashMap<String, Object>();
+    private HttpServiceWrapper wrapper;
+
+    private static BundleContext bundleContext;
+
+    public void start(BundleContext context) {
+        bundleContext = context;
+        wrapper = new HttpServiceWrapper(bundleContext);
+        wrapper.open();
+
+        HttpServlet defaultServlet = new DefaultServlet();
+        addServletMapping(DUMMY_URI, defaultServlet);
+        // this.servletContext = defaultServlet.getServletContext();
+    }
+
+    public void stop(BundleContext bundleContext) {
+        removeServletMapping(DUMMY_URI);
+        wrapper.close();
+    }
+
+    public void setDefaultPort(int port) {
+        defaultPortNumber = port;
+    }
+
+    public int getDefaultPort() {
+        return defaultPortNumber;
+    }
+
+ public void addServletMapping(String suri, Servlet servlet) throws ServletMappingException {
+        URI pathURI = URI.create(suri);
+
+        // Make sure that the path starts with a /
+        suri = pathURI.getPath();
+        if (!suri.startsWith("/")) {
+            suri = '/' + suri;
+        }
+
+        if (!suri.startsWith(contextPath)) {
+            suri = contextPath + suri;
+        }
+
+ // In a webapp just use the given path and ignore the host and port
+        // as they are fixed by the Web container
+        try {
+ Dictionary<String, Object> props = new Hashtable<String, Object>();
+            props.put(HttpServiceWrapper.SERVLET_URI, suri);
+ ServiceRegistration reg = bundleContext.registerService(Servlet.class.getName(), servlet, props);
+            servlets.put(suri, servlet);
+        } catch (Exception e) {
+            throw new ServletMappingException(e);
+        }
+
+        logger.info("Added Servlet mapping: " + suri);
+    }
+
+ public Servlet removeServletMapping(String suri) throws ServletMappingException {
+        URI pathURI = URI.create(suri);
+
+        // Make sure that the path starts with a /
+        suri = pathURI.getPath();
+        if (!suri.startsWith("/")) {
+            suri = '/' + suri;
+        }
+
+        if (!suri.startsWith(contextPath)) {
+            suri = contextPath + suri;
+        }
+
+ // In a webapp just use the given path and ignore the host and port
+        // as they are fixed by the Web container
+        try {
+            return servlets.remove(suri);
+        } catch (Exception e) {
+            throw new ServletMappingException(e);
+        }
+
+    }
+
+ public Servlet getServletMapping(String suri) throws ServletMappingException {
+        if (!suri.startsWith("/")) {
+            suri = '/' + suri;
+        }
+
+        if (!suri.startsWith(contextPath)) {
+            suri = contextPath + suri;
+        }
+
+        // Get the Servlet mapped to the given path
+        Servlet servlet = servlets.get(suri);
+        return servlet;
+    }
+
+ public URL getURLMapping(String suri) throws ServletMappingException {
+        URI uri = URI.create(suri);
+
+        // Get the URI scheme and port
+        String scheme = uri.getScheme();
+        if (scheme == null) {
+            scheme = "http";
+        }
+        int portNumber = uri.getPort();
+        if (portNumber == -1) {
+            portNumber = defaultPortNumber;
+        }
+
+        // Get the host
+        String host;
+        try {
+            host = InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException e) {
+            host = "localhost";
+        }
+
+        // Construct the URL
+        String path = uri.getPath();
+        if (!path.startsWith("/")) {
+            path = '/' + path;
+        }
+
+        if (contextPath != null && !path.startsWith(contextPath)) {
+            path = contextPath + path;
+        }
+
+        URL url;
+        try {
+            url = new URL(scheme, host, portNumber, path);
+        } catch (MalformedURLException e) {
+            throw new ServletMappingException(e);
+        }
+        return url;
+    }
+
+ public RequestDispatcher getRequestDispatcher(String suri) throws ServletMappingException {
+
+        // Make sure that the path starts with a /
+        if (!suri.startsWith("/")) {
+            suri = '/' + suri;
+        }
+
+        suri = contextPath + suri;
+
+        // Get the Servlet mapped to the given path
+        Servlet servlet = servlets.get(suri);
+        if (servlet != null) {
+            return new ServletRequestDispatcher(suri, servlet);
+        }
+
+        for (Map.Entry<String, Servlet> entry : servlets.entrySet()) {
+            String servletPath = entry.getKey();
+            if (servletPath.endsWith("*")) {
+ servletPath = servletPath.substring(0, servletPath.length() - 1);
+                if (suri.startsWith(servletPath)) {
+ // entry key is contextPath/servletPath, WebAppRequestDispatcher only wants servletPath + return new ServletRequestDispatcher(entry.getKey().substring(contextPath.length()), entry
+                        .getValue());
+                } else {
+                    if ((suri + "/").startsWith(servletPath)) {
+ return new ServletRequestDispatcher(entry.getKey().substring(contextPath.length()), entry
+                            .getValue());
+                    }
+                }
+            }
+        }
+
+        // No Servlet found
+        return null;
+    }
+
+    public String getContextPath() {
+        return contextPath;
+    }
+
+    public void setContextPath(String path) {
+    }
+
+    /**
+     * TODO: How context paths work is still up in the air so for now
+     *    this hacks in a path that gets some samples working
+     *    can't use setContextPath as NodeImpl calls that later
+     */
+    public void setContextPath2(String path) {
+        if (path != null && path.length() > 0) {
+            this.contextPath = path;
+        }
+    }
+
+    public void setAttribute(String name, Object value) {
+        if (servletContext != null) {
+            servletContext.setAttribute(name, value);
+        } else {
+            attributes.put(name, value);
+        }
+    }
+
+}

Propchange: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/OSGiServletHost.java
------------------------------------------------------------------------------
   svn:eol-style = native

Propchange: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/OSGiServletHost.java
------------------------------------------------------------------------------
   svn:keywords = Rev Date

Added: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/ServletRequestDispatcher.java URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/ServletRequestDispatcher.java?rev=759191&view=auto
==============================================================================
--- tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/ServletRequestDispatcher.java (added) +++ tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/ServletRequestDispatcher.java Fri Mar 27 16:10:18 2009
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.http.osgi;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+
+/**
+ * A Servlet request dispatcher that can be used to delegate requests to a
+ * Servlet registered with the Webapp Servlet host.
+ *
+ * @version $Rev$ $Date$
+ */
+class ServletRequestDispatcher implements RequestDispatcher {
+    private String servletPath;
+    private Servlet servlet;
+
+    public ServletRequestDispatcher(String mapping, Servlet servlet) {
+        if (mapping.endsWith("*")) {
+            mapping = mapping.substring(0, mapping.length()-1);
+        }
+        if (mapping.endsWith("/")) {
+            mapping = mapping.substring(0, mapping.length()-1);
+        }
+        this.servletPath = mapping;
+        this.servlet = servlet;
+    }
+
+    /**
+ * Returns a request wrapper which will return the correct Servlet path
+     * and path info.
+     *
+     * @param request
+     * @return
+     */
+ private HttpServletRequest createRequestWrapper(ServletRequest request) { + HttpServletRequest requestWrapper = new HttpServletRequestWrapper((HttpServletRequest)request) {
+
+            @Override
+            public String getServletPath() {
+                return servletPath;
+            }
+
+            @Override
+            public String getPathInfo() {
+                String path = super.getServletPath();
+                if (path.length() == 0) {
+                    path = super.getPathInfo();
+                }
+
+ // TODO: another context path hack, revisit when context path is sorted out
+                path = fiddlePath(path, servletPath);
+
+                return path;
+            }
+        };
+        return requestWrapper;
+    }
+
+    /**
+     * Remove any path suffix thats part of the Servlet context path
+     */
+    protected String fiddlePath(String path, String servletPath) {
+        StringTokenizer st = new StringTokenizer(path, "/");
+        if (st.countTokens() == 1) {
+            return path;
+        }
+        String root = "";
+        while (st.hasMoreTokens()){
+                String s = st.nextToken();
+                if (servletPath.endsWith((root + "/" + s))) {
+                        root += "/" + s;
+                } else {
+                        break;
+                }
+        }
+        String fiddlePath = path.substring(root.length());
+        return fiddlePath;
+    }
+
+ public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+        servlet.service(createRequestWrapper(request), response);
+    }
+
+ public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
+        servlet.service(createRequestWrapper(request), response);
+    }
+}
+

Propchange: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/ServletRequestDispatcher.java
------------------------------------------------------------------------------
   svn:eol-style = native

Propchange: tuscany/java/sca/modules/host-http-osgi/src/main/java/org/apache/tuscany/sca/http/osgi/ServletRequestDispatcher.java
------------------------------------------------------------------------------
   svn:keywords = Rev Date

Added: tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/OSGiServletHostTestCase.java URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/OSGiServletHostTestCase.java?rev=759191&view=auto
==============================================================================
--- tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/OSGiServletHostTestCase.java (added) +++ tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/OSGiServletHostTestCase.java Fri Mar 27 16:10:18 2009
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.http.osgi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+
+import org.apache.tuscany.sca.node.equinox.launcher.EquinoxHost;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ *
+ */
+public class OSGiServletHostTestCase {
+    /** Standard OSGi port property for HTTP service */
+    public static final String HTTP_PORT = "org.osgi.service.http.port";
+
+    /** Standard OSGi port property for HTTPS service */
+ public static final String HTTPS_PORT = "org.osgi.service.http.port.secure";
+
+    private static EquinoxHost host;
+    private static String port;
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        port = System.setProperty(HTTP_PORT, "8085");
+        host = new EquinoxHost();
+        BundleContext context = host.start();
+        for (Bundle b : context.getBundles()) {
+            System.out.println(b.getSymbolicName());
+            b.start();
+        }
+    }
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @AfterClass
+    public static void tearDownAfterClass() throws Exception {
+        if (host != null) {
+            host.stop();
+            if (port != null) {
+                System.setProperty(HTTP_PORT, port);
+            } else {
+                System.clearProperty(HTTP_PORT);
+            }
+        }
+    }
+
+    @Test
+    public void testHost() throws IOException {
+ URL url = new URL("http://localhost:8085"; + OSGiServletHost.DUMMY_URI);
+        InputStream is = url.openStream();
+        Reader reader = new InputStreamReader(is);
+        char[] content = new char[1024];
+        int len = 0;
+        while (true) {
+            int size = reader.read(content, len, 1024 - len);
+            if (size < 0) {
+                break;
+            }
+            len += size;
+        }
+        Assert.assertTrue(len > 0);
+        String str = new String(content, 0, len);
+        System.out.println(str);
+ Assert.assertEquals("<html><body><h1>Apache Tuscany</h1></body></html>", str.trim());
+    }
+}

Propchange: tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/OSGiServletHostTestCase.java
------------------------------------------------------------------------------
   svn:eol-style = native

Propchange: tuscany/java/sca/modules/host-http-osgi/src/test/java/org/apache/tuscany/sca/http/osgi/OSGiServletHostTestCase.java
------------------------------------------------------------------------------
   svn:keywords = Rev Date


Reply via email to