You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by sr...@apache.org on 2009/09/14 11:59:16 UTC

svn commit: r814549 [2/4] - in /felix/trunk/http: ./ api/ api/src/ api/src/main/ api/src/main/java/ api/src/main/java/org/ api/src/main/java/org/apache/ api/src/main/java/org/apache/felix/ api/src/main/java/org/apache/felix/http/ api/src/main/java/org/...

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,143 @@
+/*
+ * 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.felix.http.base.internal.handler;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletRequestWrapper;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import java.io.IOException;
+
+public final class ServletHandler
+    extends AbstractHandler implements Comparable<ServletHandler>
+{
+    private final String alias;
+    private final Servlet servlet;
+
+    public ServletHandler(ExtServletContext context, Servlet servlet, String alias)
+    {
+        super(context);
+        this.alias = alias;
+        this.servlet = servlet;
+    }
+
+    public String getAlias()
+    {
+        return this.alias;
+    }
+
+    public Servlet getServlet()
+    {
+        return this.servlet;
+    }
+
+    public void init()
+        throws ServletException
+    {
+        String name = "servlet_" + getId();
+        ServletConfig config = new ServletConfigImpl(name, getContext(), getInitParams());
+        this.servlet.init(config);
+    }
+
+    public void destroy()
+    {
+        this.servlet.destroy();
+    }
+
+    public boolean matches(String uri)
+    {
+        if (this.alias.equals("/")) {
+            return uri.startsWith(this.alias);
+        } else {
+            return uri.equals(this.alias) || uri.startsWith(this.alias + "/");
+        }
+    }
+
+    public boolean handle(HttpServletRequest req, HttpServletResponse res)
+        throws ServletException, IOException
+    {
+        final boolean matches = matches(req.getPathInfo());
+        if (matches) {
+            doHandle(req, res);
+        }
+
+        return matches;
+    }
+
+    private void doHandle(HttpServletRequest req, HttpServletResponse res)
+        throws ServletException, IOException
+    {
+        if (!getContext().handleSecurity(req, res)) {
+            if (!res.isCommitted()) {
+                res.sendError(HttpServletResponse.SC_FORBIDDEN);
+            }
+        } else {
+            this.servlet.service(new RequestWrapper(req), res);
+        }
+    }
+
+    public int compareTo(ServletHandler other)
+    {
+        return other.alias.length() - this.alias.length();
+    }    
+
+    private final class RequestWrapper
+        extends HttpServletRequestWrapper
+    {
+        private String pathInfo;
+        private boolean pathInfoComputed = false;
+
+        public RequestWrapper(HttpServletRequest req)
+        {
+            super(req);
+        }
+
+        @Override
+        public String getPathInfo()
+        {
+            if (!this.pathInfoComputed) {
+                final int servletPathLength = getServletPath().length();
+                this.pathInfo = getRequestURI().substring(getContextPath().length()).replaceAll("[/]{2,}", "/")
+                    .substring(servletPathLength);
+
+                if ("".equals(this.pathInfo) && servletPathLength != 0) {
+                    this.pathInfo = null;
+                }
+
+                this.pathInfoComputed = true;
+            }
+
+            return this.pathInfo;
+        }
+
+        @Override
+        public String getPathTranslated()
+        {
+            final String info = getPathInfo();
+            return (null == info) ? null : getRealPath(info);
+        }
+
+        @Override
+        public String getServletPath()
+        {
+            return alias;
+        }
+    }
+}

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/DefaultHttpContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/DefaultHttpContext.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/DefaultHttpContext.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/DefaultHttpContext.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,53 @@
+/*
+ * 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.felix.http.base.internal.service;
+
+import org.osgi.service.http.HttpContext;
+import org.osgi.framework.Bundle;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.URL;
+
+public final class DefaultHttpContext 
+    implements HttpContext
+{
+    private Bundle bundle;
+
+    public DefaultHttpContext(Bundle bundle)
+    {
+        this.bundle = bundle;
+    }
+
+    public String getMimeType(String name)
+    {
+        return null;
+    }
+
+    public URL getResource(String name)
+    {
+        if (name.startsWith("/")) {
+            name = name.substring(1);
+        }
+
+        return this.bundle.getResource(name);
+    }
+
+    public boolean handleSecurity(HttpServletRequest req, HttpServletResponse res)
+    {
+        return true;
+    }
+}

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,47 @@
+/*
+ * 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.felix.http.base.internal.service;
+
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+import org.apache.felix.http.base.internal.handler.HandlerRegistry;
+
+import javax.servlet.ServletContext;
+
+public final class HttpServiceFactory
+    implements ServiceFactory
+{
+    private final ServletContext context;
+    private final HandlerRegistry handlerRegistry;
+
+    public HttpServiceFactory(ServletContext context, HandlerRegistry handlerRegistry)
+    {
+        this.context = context;
+        this.handlerRegistry = handlerRegistry;
+    }
+
+    public Object getService(Bundle bundle, ServiceRegistration reg)
+    {
+        return new HttpServiceImpl(this.context, this.handlerRegistry, bundle);
+    }
+
+    public void ungetService(Bundle bundle, ServiceRegistration reg, Object service)
+    {
+        ((HttpServiceImpl)service).unregisterAll();
+    }
+}

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,164 @@
+/*
+ * 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.felix.http.base.internal.service;
+
+import org.apache.felix.http.api.ExtHttpService;
+import org.apache.felix.http.base.internal.context.ServletContextManager;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.handler.HandlerRegistry;
+import org.apache.felix.http.base.internal.handler.FilterHandler;
+import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.util.SystemLogger;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.http.NamespaceException;
+import org.osgi.framework.Bundle;
+import javax.servlet.Filter;
+import javax.servlet.ServletException;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import java.util.Dictionary;
+import java.util.HashSet;
+
+public final class HttpServiceImpl
+    implements ExtHttpService
+{
+    private final Bundle bundle;
+    private final HandlerRegistry handlerRegistry;
+    private final HashSet<Servlet> localServlets;
+    private final HashSet<Filter> localFilters;
+    private final ServletContextManager contextManager;
+
+    public HttpServiceImpl(ServletContext context, HandlerRegistry handlerRegistry, Bundle bundle)
+    {
+        this.bundle = bundle;
+        this.handlerRegistry = handlerRegistry;
+        this.localServlets = new HashSet<Servlet>();
+        this.localFilters = new HashSet<Filter>();
+        this.contextManager = new ServletContextManager(bundle, context);
+    }
+
+    private ExtServletContext getServletContext(HttpContext context)
+    {
+        if (context == null) {
+            context = createDefaultHttpContext();
+        }
+
+        return this.contextManager.getServletContext(context);
+    }
+
+    public void registerFilter(Filter filter, String pattern, Dictionary initParams, int ranking, HttpContext context)
+        throws ServletException
+    {
+        FilterHandler handler = new FilterHandler(getServletContext(context), filter, pattern, ranking);
+        handler.setInitParams(initParams);
+        this.handlerRegistry.addFilter(handler);
+        this.localFilters.add(filter);
+    }
+
+    public void unregisterFilter(Filter filter)
+    {
+        if (filter != null) {
+            this.handlerRegistry.removeFilter(filter);
+            this.localFilters.remove(filter);
+        }
+    }
+
+    public void unregisterServlet(Servlet servlet)
+    {
+        if (servlet != null) {
+            this.handlerRegistry.removeServlet(servlet);
+            this.localServlets.remove(servlet);
+        }
+    }
+
+    public void registerServlet(String alias, Servlet servlet, Dictionary initParams, HttpContext context)
+        throws ServletException, NamespaceException
+    {
+        if (!isAliasValid(alias)) {
+            throw new IllegalArgumentException( "Malformed servlet alias [" + alias + "]");
+        }
+        
+        ServletHandler handler = new ServletHandler(getServletContext(context), servlet, alias);
+        handler.setInitParams(initParams);
+        this.handlerRegistry.addServlet(handler);
+        this.localServlets.add(servlet);
+    }
+
+    public void registerResources(String alias, String name, HttpContext context)
+        throws NamespaceException
+    {
+        if (!isNameValid(name)) {
+            throw new IllegalArgumentException( "Malformed resource name [" + name + "]");
+        }
+        
+        try {
+            Servlet servlet = new ResourceServlet(name);
+            registerServlet(alias, servlet, null, context);
+        } catch (ServletException e) {
+            SystemLogger.get().error("Failed to register resources", e);
+        }
+    }
+
+    public void unregister(String alias)
+    {
+        unregisterServlet(this.handlerRegistry.getServletByAlias(alias));
+    }
+
+    public HttpContext createDefaultHttpContext()
+    {
+        return new DefaultHttpContext(this.bundle);
+    }
+
+    public void unregisterAll()
+    {
+        HashSet<Servlet> servlets = new HashSet<Servlet>(this.localServlets);
+        for (Servlet servlet : servlets) {
+            unregisterServlet(servlet);
+        }
+
+        HashSet<Filter> filters = new HashSet<Filter>(this.localFilters);
+        for (Filter fiter : filters) {
+            unregisterFilter(fiter);
+        }
+    }
+
+    private boolean isNameValid(String name)
+    {
+        if (name == null) {
+            return false;
+        }
+
+        if (name.endsWith( "/" )) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean isAliasValid(String alias)
+    {
+        if (alias == null) {
+            return false;
+        }
+
+        if (!alias.equals("/") && ( !alias.startsWith("/") || alias.endsWith("/"))) {
+            return false;
+        }
+
+        return true;
+    }
+}

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/ResourceServlet.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/ResourceServlet.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/ResourceServlet.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/ResourceServlet.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.http.base.internal.service;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+public final class ResourceServlet 
+    extends HttpServlet
+{
+    private final String path;
+
+    public ResourceServlet(String path)
+    {
+        this.path = path;
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse res)
+        throws ServletException, IOException
+    {
+        String target = req.getPathInfo();
+        if (target == null) {
+            target = "";
+        }
+
+        if (!target.startsWith("/")) {
+            target += "/" + target;
+        }
+
+        String resName = this.path + target;
+        URL url = getServletContext().getResource(resName);
+        
+        if (url == null) {
+            res.sendError(HttpServletResponse.SC_NOT_FOUND);
+        } else {
+            handle(req, res, url, resName);
+        }
+    }
+
+    private void handle(HttpServletRequest req, HttpServletResponse res, URL url, String resName)
+        throws IOException
+    {
+        String contentType = getServletContext().getMimeType(resName);
+        if (contentType != null) {
+            res.setContentType(contentType);
+        }
+
+        long lastModified  = getLastModified(url);
+        if (lastModified != 0) {
+            res.setDateHeader("Last-Modified", lastModified);
+        }
+
+        if (!resourceModified(lastModified, req.getDateHeader("If-Modified-Since"))) {
+            res.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+        } else {
+            copyResource(url, res);
+        }
+    }
+
+    private long getLastModified(URL url)
+    {
+        long lastModified = 0;
+
+        try {
+            URLConnection conn = url.openConnection();
+            lastModified = conn.getLastModified();
+        } catch (Exception e)
+        {
+            // Do nothing
+        }
+
+        if (lastModified == 0) {
+            String filepath = url.getPath();
+            if (filepath != null) {
+                File f = new File(filepath);
+                if (f.exists()) {
+                    lastModified = f.lastModified();
+                }
+            }
+        }
+
+        return lastModified;
+    }
+
+    private boolean resourceModified(long resTimestamp, long modSince)
+    {
+        modSince /= 1000;
+        resTimestamp /= 1000;
+
+        return resTimestamp == 0 || modSince == -1 || resTimestamp > modSince;
+    }
+
+    private void copyResource(URL url, HttpServletResponse res)
+        throws IOException
+    {
+        OutputStream os = null;
+        InputStream is = null;
+
+        try {
+            os = res.getOutputStream();
+            is = url.openStream();
+
+            int len = 0;
+            byte[] buf = new byte[1024];
+            int n;
+
+            while ((n = is.read(buf, 0, buf.length)) >= 0) {
+                os.write( buf, 0, n );
+                len += n;
+            }
+
+            res.setContentLength(len);
+        } finally {
+            if (is != null) {
+                is.close();
+            }
+
+            if (os != null) {
+                os.close();
+            }
+        }
+    }
+}

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/MimeTypes.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/MimeTypes.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/MimeTypes.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/MimeTypes.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,211 @@
+/*
+ * 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.felix.http.base.internal.util;
+
+import java.util.Map;
+import java.util.HashMap;
+
+public final class MimeTypes
+{
+    private final static MimeTypes INSTANCE =
+            new MimeTypes();
+
+    private final Map<String, String> extMap;
+
+    private MimeTypes()
+    {
+        this.extMap = new HashMap<String, String>();
+        this.extMap.put("abs", "audio/x-mpeg");
+        this.extMap.put("ai", "application/postscript");
+        this.extMap.put("aif", "audio/x-aiff");
+        this.extMap.put("aifc", "audio/x-aiff");
+        this.extMap.put("aiff", "audio/x-aiff");
+        this.extMap.put("aim", "application/x-aim");
+        this.extMap.put("art", "image/x-jg");
+        this.extMap.put("asf", "video/x-ms-asf");
+        this.extMap.put("asx", "video/x-ms-asf");
+        this.extMap.put("au", "audio/basic");
+        this.extMap.put("avi", "video/x-msvideo");
+        this.extMap.put("avx", "video/x-rad-screenplay");
+        this.extMap.put("bcpio", "application/x-bcpio");
+        this.extMap.put("bin", "application/octet-stream");
+        this.extMap.put("bmp", "image/bmp");
+        this.extMap.put("body", "text/html");
+        this.extMap.put("cdf", "application/x-cdf");
+        this.extMap.put("cer", "application/x-x509-ca-cert");
+        this.extMap.put("class", "application/java");
+        this.extMap.put("cpio", "application/x-cpio");
+        this.extMap.put("csh", "application/x-csh");
+        this.extMap.put("css", "text/css");
+        this.extMap.put("dib", "image/bmp");
+        this.extMap.put("doc", "application/msword");
+        this.extMap.put("dtd", "application/xml-dtd");
+        this.extMap.put("dv", "video/x-dv");
+        this.extMap.put("dvi", "application/x-dvi");
+        this.extMap.put("eps", "application/postscript");
+        this.extMap.put("etx", "text/x-setext");
+        this.extMap.put("exe", "application/octet-stream");
+        this.extMap.put("gif", "image/gif");
+        this.extMap.put("gk", "application/octet-stream");
+        this.extMap.put("gtar", "application/x-gtar");
+        this.extMap.put("gz", "application/x-gzip");
+        this.extMap.put("hdf", "application/x-hdf");
+        this.extMap.put("hqx", "application/mac-binhex40");
+        this.extMap.put("htc", "text/x-component");
+        this.extMap.put("htm", "text/html");
+        this.extMap.put("html", "text/html");
+        this.extMap.put("hqx", "application/mac-binhex40");
+        this.extMap.put("ief", "image/ief");
+        this.extMap.put("jad", "text/vnd.sun.j2me.app-descriptor");
+        this.extMap.put("jar", "application/java-archive");
+        this.extMap.put("java", "text/plain");
+        this.extMap.put("jnlp", "application/x-java-jnlp-file");
+        this.extMap.put("jpe", "image/jpeg");
+        this.extMap.put("jpeg", "image/jpeg");
+        this.extMap.put("jpg", "image/jpeg");
+        this.extMap.put("js", "text/javascript");
+        this.extMap.put("kar", "audio/x-midi");
+        this.extMap.put("latex", "application/x-latex");
+        this.extMap.put("m3u", "audio/x-mpegurl");
+        this.extMap.put("mac", "image/x-macpaint");
+        this.extMap.put("man", "application/x-troff-man");
+        this.extMap.put("mathml", "application/mathml+xml");
+        this.extMap.put("me", "application/x-troff-me");
+        this.extMap.put("mid", "audio/x-midi");
+        this.extMap.put("midi", "audio/x-midi");
+        this.extMap.put("mif", "application/x-mif");
+        this.extMap.put("mov", "video/quicktime");
+        this.extMap.put("movie", "video/x-sgi-movie");
+        this.extMap.put("mp1", "audio/x-mpeg");
+        this.extMap.put("mp2", "audio/x-mpeg");
+        this.extMap.put("mp3", "audio/x-mpeg");
+        this.extMap.put("mpa", "audio/x-mpeg");
+        this.extMap.put("mpe", "video/mpeg");
+        this.extMap.put("mpeg", "video/mpeg");
+        this.extMap.put("mpega", "audio/x-mpeg");
+        this.extMap.put("mpg", "video/mpeg");
+        this.extMap.put("mpv2", "video/mpeg2");
+        this.extMap.put("ms", "application/x-wais-source");
+        this.extMap.put("nc", "application/x-netcdf");
+        this.extMap.put("oda", "application/oda");
+        this.extMap.put("ogg", "application/ogg");
+        this.extMap.put("pbm", "image/x-portable-bitmap");
+        this.extMap.put("pct", "image/pict");
+        this.extMap.put("pdf", "application/pdf");
+        this.extMap.put("pgm", "image/x-portable-graymap");
+        this.extMap.put("pic", "image/pict");
+        this.extMap.put("pict", "image/pict");
+        this.extMap.put("pls", "audio/x-scpls");
+        this.extMap.put("png", "image/png");
+        this.extMap.put("pnm", "image/x-portable-anymap");
+        this.extMap.put("pnt", "image/x-macpaint");
+        this.extMap.put("ppm", "image/x-portable-pixmap");
+        this.extMap.put("ppt", "application/powerpoint");
+        this.extMap.put("ps", "application/postscript");
+        this.extMap.put("psd", "image/x-photoshop");
+        this.extMap.put("qt", "video/quicktime");
+        this.extMap.put("qti", "image/x-quicktime");
+        this.extMap.put("qtif", "image/x-quicktime");
+        this.extMap.put("ras", "image/x-cmu-raster");
+        this.extMap.put("rdf", "application/rdf+xml");
+        this.extMap.put("rgb", "image/x-rgb");
+        this.extMap.put("rm", "application/vnd.rn-realmedia");
+        this.extMap.put("roff", "application/x-troff");
+        this.extMap.put("rtf", "application/rtf");
+        this.extMap.put("rtx", "text/richtext");
+        this.extMap.put("sh", "application/x-sh");
+        this.extMap.put("shar", "application/x-shar");
+        this.extMap.put("shtml", "text/x-server-parsed-html");
+        this.extMap.put("sit", "application/x-stuffit");
+        this.extMap.put("smf", "audio/x-midi");
+        this.extMap.put("snd", "audio/basic");
+        this.extMap.put("src", "application/x-wais-source");
+        this.extMap.put("sv4cpio", "application/x-sv4cpio");
+        this.extMap.put("sv4crc", "application/x-sv4crc");
+        this.extMap.put("svg", "image/svg+xml");
+        this.extMap.put("svgz", "image/svg+xml");
+        this.extMap.put("swf", "application/x-shockwave-flash");
+        this.extMap.put("t", "application/x-troff");
+        this.extMap.put("tar", "application/x-tar");
+        this.extMap.put("tcl", "application/x-tcl");
+        this.extMap.put("tex", "application/x-tex");
+        this.extMap.put("texi", "application/x-texinfo");
+        this.extMap.put("texinfo", "application/x-texinfo");
+        this.extMap.put("tif", "image/tiff");
+        this.extMap.put("tiff", "image/tiff");
+        this.extMap.put("tr", "application/x-troff");
+        this.extMap.put("tsv", "text/tab-separated-values");
+        this.extMap.put("txt", "text/plain");
+        this.extMap.put("ulw", "audio/basic");
+        this.extMap.put("ustar", "application/x-ustar");
+        this.extMap.put("xbm", "image/x-xbitmap");
+        this.extMap.put("xml", "text/xml");
+        this.extMap.put("xpm", "image/x-xpixmap");
+        this.extMap.put("xsl", "application/xml");
+        this.extMap.put("xslt", "application/xslt+xml");
+        this.extMap.put("xwd", "image/x-xwindowdump");
+        this.extMap.put("vsd", "application/x-visio");
+        this.extMap.put("vxml", "application/voicexml+xml");
+        this.extMap.put("wav", "audio/x-wav");
+        this.extMap.put("wbmp", "image/vnd.wap.wbmp");
+        this.extMap.put("wml", "text/vnd.wap.wml");
+        this.extMap.put("wmlc", "application/vnd.wap.wmlc");
+        this.extMap.put("wmls", "text/vnd.wap.wmls");
+        this.extMap.put("wmlscriptc", "application/vnd.wap.wmlscriptc");
+        this.extMap.put("wrl", "x-world/x-vrml");
+        this.extMap.put("xht", "application/xhtml+xml");
+        this.extMap.put("xhtml", "application/xhtml+xml");
+        this.extMap.put("xls", "application/vnd.ms-excel");
+        this.extMap.put("xul", "application/vnd.mozilla.xul+xml");
+        this.extMap.put("Z", "application/x-compress");
+        this.extMap.put("z", "application/x-compress");
+        this.extMap.put("zip", "application/zip");
+    }
+
+    public String getByFile(String file)
+    {
+        if (file == null) {
+            return null;
+        }
+
+        int dot = file.lastIndexOf(".");
+        if (dot < 0) {
+            return null;
+        }
+
+        String ext = file.substring(dot + 1);
+        if (ext.length() < 1) {
+            return null;
+        }
+
+        return getByExtension(ext);
+    }
+
+    public String getByExtension(String ext)
+    {
+        if (ext == null) {
+            return null;
+        }
+
+        return this.extMap.get(ext);
+    }
+
+    public static MimeTypes get()
+    {
+        return INSTANCE;
+    }
+}

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/SystemLogger.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/SystemLogger.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/SystemLogger.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/SystemLogger.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,87 @@
+/*
+ * 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.felix.http.base.internal.util;
+
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.log.LogService;
+
+public final class SystemLogger
+{
+    private final static SystemLogger INSTANCE =
+        new SystemLogger();
+
+    private ServiceTracker tracker;
+
+    private SystemLogger()
+    {
+    }
+
+    public void open(BundleContext context)
+    {
+        if (this.tracker != null) {
+            return;
+        }
+        
+        this.tracker = new ServiceTracker(context, LogService.class.getName(), null);
+        this.tracker.open();
+    }
+
+    public void close()
+    {
+        this.tracker.close();
+        this.tracker = null;
+    }
+
+    public void debug(String message)
+    {
+        log(LogService.LOG_DEBUG, message, null);
+    }
+
+    public void info(String message)
+    {
+        log(LogService.LOG_INFO, message, null);
+    }
+
+    public void warning(String message, Throwable cause)
+    {
+        log(LogService.LOG_WARNING, message, cause);
+    }
+
+    public void error(String message, Throwable cause)
+    {
+        log(LogService.LOG_ERROR, message, cause);
+    }
+
+    private void log(int level, String message, Throwable cause)
+    {
+        LogService log = (LogService)this.tracker.getService();
+        if (log != null) {
+            log.log(level, message, cause);
+        } else {
+            System.out.println(message);
+            if (cause != null) {
+                cause.printStackTrace(System.out);
+            }
+        }
+    }
+
+    public static SystemLogger get()
+    {
+        return INSTANCE;
+    }
+}
\ No newline at end of file

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,175 @@
+/*
+ * 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.felix.http.base.internal.context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.service.http.HttpContext;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletContext;
+import java.net.URL;
+import java.util.*;
+
+public class ServletContextImplTest
+{
+    private Bundle bundle;
+    private HttpContext httpContext;
+    private ServletContextImpl context;
+
+    @Before
+    public void setUp()
+    {
+        this.bundle = Mockito.mock(Bundle.class);
+        ServletContext globalContext = Mockito.mock(ServletContext.class);
+        this.httpContext = Mockito.mock(HttpContext.class);
+        this.context = new ServletContextImpl(this.bundle, globalContext, this.httpContext);
+    }
+
+    @Test
+    public void testGetResource()
+        throws Exception
+    {
+        URL url = getClass().getResource("resource.txt");
+        Assert.assertNotNull(url);
+        
+        Mockito.when(this.httpContext.getResource("resource.txt")).thenReturn(url);
+        Assert.assertNull(this.context.getResource("/notfound.txt"));
+        Assert.assertEquals(url, this.context.getResource("/resource.txt"));
+    }
+
+    @Test
+    public void testGetResourceAsStream()
+        throws Exception
+    {
+        URL url = getClass().getResource("resource.txt");
+        Assert.assertNotNull(url);
+
+        Mockito.when(this.httpContext.getResource("resource.txt")).thenReturn(url);
+        Assert.assertNull(this.context.getResourceAsStream("/notfound.txt"));
+        Assert.assertNotNull(this.context.getResourceAsStream("/resource.txt"));
+    }
+
+    @Test
+    public void testGetResourcePaths()
+    {
+        HashSet<String> paths = new HashSet<String>(Arrays.asList("/some/path/1", "/some/path/2"));
+        Mockito.when(this.bundle.getEntryPaths("some/path")).thenReturn(Collections.enumeration(paths));
+
+        Set set = this.context.getResourcePaths("/some/path");
+        Assert.assertNotNull(set);
+        Assert.assertEquals(2, set.size());
+        Assert.assertTrue(set.contains("/some/path/1"));
+        Assert.assertTrue(set.contains("/some/path/2"));
+    }
+
+    @Test
+    public void testGetRealPath()
+    {
+        Assert.assertNull(this.context.getRealPath("path"));
+    }
+
+    @Test
+    public void testGetInitParameter()
+    {
+        Assert.assertNull(this.context.getInitParameter("key1"));
+    }
+
+    @Test
+    public void testGetInitParameterNames()
+    {
+        Enumeration e = this.context.getInitParameterNames();
+        Assert.assertNotNull(e);
+        Assert.assertFalse(e.hasMoreElements());
+    }
+
+    @Test
+    public void testGetAttribute()
+    {
+        Assert.assertNull(this.context.getAttribute("key1"));
+
+        this.context.setAttribute("key1", "value1");
+        Assert.assertEquals("value1", this.context.getAttribute("key1"));
+
+        this.context.removeAttribute("key1");
+        Assert.assertNull(this.context.getAttribute("key1"));
+    }
+
+    @Test
+    public void testGetAttributeNames()
+    {
+        Enumeration e = this.context.getAttributeNames();
+        Assert.assertNotNull(e);
+        Assert.assertFalse(e.hasMoreElements());
+
+        this.context.setAttribute("key1", "value1");
+        e = this.context.getAttributeNames();
+        Assert.assertNotNull(e);
+        Assert.assertTrue(e.hasMoreElements());
+        Assert.assertEquals("key1", e.nextElement());
+        Assert.assertFalse(e.hasMoreElements());
+    }
+
+    @Test
+    public void testGetServlet()
+        throws Exception
+    {
+        Assert.assertNull(this.context.getServlet("test"));
+    }
+
+    @Test
+    public void testGetServletNames()
+    {
+        Enumeration e = this.context.getServletNames();
+        Assert.assertNotNull(e);
+        Assert.assertFalse(e.hasMoreElements());
+    }
+
+    @Test
+    public void testGetServlets()
+    {
+        Enumeration e = this.context.getServlets();
+        Assert.assertNotNull(e);
+        Assert.assertFalse(e.hasMoreElements());
+    }
+
+    @Test
+    public void testGetMimeType()
+    {
+        Mockito.when(this.httpContext.getMimeType("file.xml")).thenReturn("some-other-format");
+        Assert.assertEquals("some-other-format", this.context.getMimeType("file.xml"));
+        Assert.assertEquals("text/plain", this.context.getMimeType("file.txt"));
+    }
+
+    @Test
+    public void testHandleSecurity()
+        throws Exception
+    {
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+
+        Mockito.when(this.httpContext.handleSecurity(req, res)).thenReturn(true);
+        Assert.assertTrue(this.context.handleSecurity(req, res));
+
+        Mockito.when(this.httpContext.handleSecurity(req, res)).thenReturn(false);
+        Assert.assertFalse(this.context.handleSecurity(req, res));
+    }
+}

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextManagerTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextManagerTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextManagerTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextManagerTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,58 @@
+/*
+ * 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.felix.http.base.internal.context;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+import org.osgi.framework.Bundle;
+import org.osgi.service.http.HttpContext;
+import org.mockito.Mockito;
+
+import javax.servlet.ServletContext;
+
+public class ServletContextManagerTest
+{
+    private ServletContextManager manager;
+
+    @Before
+    public void setUp()
+    {
+        Bundle bundle = Mockito.mock(Bundle.class);
+        ServletContext globalContext = Mockito.mock(ServletContext.class);
+        this.manager = new ServletContextManager(bundle, globalContext);
+    }
+
+    @Test
+    public void testGetServletContext()
+    {
+        HttpContext httpCtx = Mockito.mock(HttpContext.class);
+        ServletContext result1 = this.manager.getServletContext(httpCtx);
+        ServletContext result2 = this.manager.getServletContext(httpCtx);
+
+        Assert.assertNotNull(result1);
+        Assert.assertNotNull(result2);
+        Assert.assertSame(result1, result2);
+
+        httpCtx = Mockito.mock(HttpContext.class);
+        result2 = this.manager.getServletContext(httpCtx);
+
+        Assert.assertNotNull(result2);
+        Assert.assertNotSame(result1, result2);
+    }
+    
+}

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,60 @@
+/*
+ * 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.felix.http.base.internal.handler;
+
+import org.junit.Test;
+import org.junit.Assert;
+import org.mockito.Mockito;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import java.util.Hashtable;
+
+public abstract class AbstractHandlerTest
+{
+    protected ExtServletContext context;
+
+    protected abstract AbstractHandler createHandler();
+
+    public void setUp()
+    {
+        this.context = Mockito.mock(ExtServletContext.class);
+    }
+    
+    @Test
+    public void testId()
+    {
+        AbstractHandler h1 = createHandler();
+        AbstractHandler h2 = createHandler();
+
+        Assert.assertNotNull(h1.getId());
+        Assert.assertNotNull(h2.getId());
+        Assert.assertFalse(h1.getId().equals(h2.getId()));
+    }
+
+    @Test
+    public void testInitParams()
+    {
+        AbstractHandler handler = createHandler();
+        Assert.assertEquals(0, handler.getInitParams().size());
+        
+        Hashtable<String, String> map = new Hashtable<String, String>();
+        map.put("key1", "value1");
+
+        handler.setInitParams(map);
+        Assert.assertEquals(1, handler.getInitParams().size());
+        Assert.assertEquals("value1", handler.getInitParams().get("key1"));
+    }
+}

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterConfigImplTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterConfigImplTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterConfigImplTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterConfigImplTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,70 @@
+/*
+ * 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.felix.http.base.internal.handler;
+
+import org.junit.Before;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import javax.servlet.ServletContext;
+import java.util.HashMap;
+import java.util.Enumeration;
+
+public class FilterConfigImplTest
+{
+    private ServletContext context;
+    private FilterConfigImpl config;
+
+    @Before
+    public void setUp()
+    {
+        HashMap<String, String> params = new HashMap<String, String>();
+        params.put("key1", "value1");
+        
+        this.context = Mockito.mock(ServletContext.class);
+        this.config = new FilterConfigImpl("myfilter", this.context, params);
+    }
+
+    @Test
+    public void testGetFilterName()
+    {
+        Assert.assertSame("myfilter", this.config.getFilterName());
+    }
+
+    @Test
+    public void testGetServletContext()
+    {
+        Assert.assertSame(this.context, this.config.getServletContext());
+    }
+
+    @Test
+    public void testGetInitParameter()
+    {
+        Assert.assertNull(this.config.getInitParameter("key2"));
+        Assert.assertEquals("value1", this.config.getInitParameter("key1"));
+    }
+
+    @Test
+    public void testGetInitParameterNames()
+    {
+        Enumeration e = this.config.getInitParameterNames();
+        Assert.assertNotNull(e);
+        Assert.assertTrue(e.hasMoreElements());
+        Assert.assertEquals("key1", e.nextElement());
+        Assert.assertFalse(e.hasMoreElements());
+    }
+}

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,144 @@
+/*
+ * 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.felix.http.base.internal.handler;
+
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.Assert;
+import org.mockito.Mockito;
+import org.mockito.MockSettings;
+import org.mockito.stubbing.Answer;
+import org.hamcrest.Matcher;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class FilterHandlerTest
+    extends AbstractHandlerTest
+{
+    private Filter filter;
+
+    @Before
+    public void setUp()
+    {
+        super.setUp();
+        this.filter = Mockito.mock(Filter.class);
+    }
+
+    protected AbstractHandler createHandler()
+    {
+        return createHandler("dummy", 0);
+    }
+
+    private FilterHandler createHandler(String pattern, int ranking)
+    {
+        return new FilterHandler(this.context, this.filter, pattern, ranking);
+    }
+
+    @Test
+    public void testCompare()
+    {
+        FilterHandler h1 = createHandler("a", 0);
+        FilterHandler h2 = createHandler("b", 10);
+
+        Assert.assertEquals(10, h1.compareTo(h2));
+        Assert.assertEquals(-10, h2.compareTo(h1));
+    }
+
+    @Test
+    public void testMatches()
+    {
+        FilterHandler h1 = createHandler("/a/b", 0);
+        FilterHandler h2 = createHandler("/a/b/.+", 0);
+
+        Assert.assertTrue(h1.matches("/a/b"));
+        Assert.assertFalse(h1.matches("/a/b/c"));
+        Assert.assertTrue(h2.matches("/a/b/c"));
+        Assert.assertFalse(h2.matches("/a/b/"));
+    }
+
+    @Test
+    public void testInit()
+        throws Exception
+    {
+        FilterHandler h1 = createHandler("/a", 0);
+        h1.init();
+        Mockito.verify(this.filter).init(Mockito.any(FilterConfig.class));
+    }
+
+    @Test
+    public void testDestroy()
+    {
+        FilterHandler h1 = createHandler("/a", 0);
+        h1.destroy();
+        Mockito.verify(this.filter).destroy();
+    }
+
+    @Test
+    public void testHandleNotFound()
+        throws Exception
+    {
+        FilterHandler h1 = createHandler("/a", 0);
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+        FilterChain chain = Mockito.mock(FilterChain.class);
+
+        Mockito.when(req.getPathInfo()).thenReturn("/");
+        h1.handle(req, res, chain);
+
+        Mockito.verify(this.filter, Mockito.never()).doFilter(req, res, chain);
+        Mockito.verify(chain).doFilter(req, res);
+    }
+
+    @Test
+    public void testHandleFound()
+        throws Exception
+    {
+        FilterHandler h1 = createHandler("/a", 0);
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+        FilterChain chain = Mockito.mock(FilterChain.class);
+        Mockito.when(this.context.handleSecurity(req, res)).thenReturn(true);
+
+        Mockito.when(req.getPathInfo()).thenReturn("/a");
+        h1.handle(req, res, chain);
+
+        Mockito.verify(this.filter).doFilter(req, res, chain);
+        Mockito.verify(chain, Mockito.never()).doFilter(req, res);
+    }
+
+    @Test
+    public void testHandleFoundForbidden()
+        throws Exception
+    {
+        FilterHandler h1 = createHandler("/a", 0);
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+        FilterChain chain = Mockito.mock(FilterChain.class);
+        Mockito.when(this.context.handleSecurity(req, res)).thenReturn(false);
+
+        Mockito.when(req.getPathInfo()).thenReturn("/a");
+        h1.handle(req, res, chain);
+
+        Mockito.verify(this.filter, Mockito.never()).doFilter(req, res, chain);
+        Mockito.verify(chain, Mockito.never()).doFilter(req, res);
+        Mockito.verify(res).sendError(HttpServletResponse.SC_FORBIDDEN);
+    }
+}

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletConfigImplTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletConfigImplTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletConfigImplTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletConfigImplTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,70 @@
+/*
+ * 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.felix.http.base.internal.handler;
+
+import org.junit.Before;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import javax.servlet.ServletContext;
+import java.util.HashMap;
+import java.util.Enumeration;
+
+public class ServletConfigImplTest
+{
+    private ServletContext context;
+    private ServletConfigImpl config;
+
+    @Before
+    public void setUp()
+    {
+        HashMap<String, String> params = new HashMap<String, String>();
+        params.put("key1", "value1");
+
+        this.context = Mockito.mock(ServletContext.class);
+        this.config = new ServletConfigImpl("myservlet", this.context, params);
+    }
+
+    @Test
+    public void testGetServletName()
+    {
+        Assert.assertSame("myservlet", this.config.getServletName());
+    }
+
+    @Test
+    public void testGetServletContext()
+    {
+        Assert.assertSame(this.context, this.config.getServletContext());
+    }
+
+    @Test
+    public void testGetInitParameter()
+    {
+        Assert.assertNull(this.config.getInitParameter("key2"));
+        Assert.assertEquals("value1", this.config.getInitParameter("key1"));
+    }
+
+    @Test
+    public void testGetInitParameterNames()
+    {
+        Enumeration e = this.config.getInitParameterNames();
+        Assert.assertNotNull(e);
+        Assert.assertTrue(e.hasMoreElements());
+        Assert.assertEquals("key1", e.nextElement());
+        Assert.assertFalse(e.hasMoreElements());
+    }
+}
\ No newline at end of file

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,136 @@
+/*
+ * 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.felix.http.base.internal.handler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Assert;
+import org.mockito.Mockito;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class ServletHandlerTest
+    extends AbstractHandlerTest
+{
+    private Servlet servlet;
+
+    @Before
+    public void setUp()
+    {
+        super.setUp();
+        this.servlet = Mockito.mock(Servlet.class);
+    }
+
+    protected AbstractHandler createHandler()
+    {
+        return createHandler("/dummy");
+    }
+    
+    private ServletHandler createHandler(String alias)
+    {
+        return new ServletHandler(this.context, this.servlet, alias);
+    }
+    
+    @Test
+    public void testCompare()
+    {
+        ServletHandler h1 = createHandler("/a");
+        ServletHandler h2 = createHandler("/a/b");
+
+        Assert.assertEquals(2, h1.compareTo(h2));
+        Assert.assertEquals(-2, h2.compareTo(h1));
+    }
+
+    @Test
+    public void testMatches()
+    {
+        ServletHandler h1 = createHandler("/a/b");
+
+        Assert.assertFalse(h1.matches("/a/"));
+        Assert.assertTrue(h1.matches("/a/b"));
+        Assert.assertTrue(h1.matches("/a/b/"));
+        Assert.assertTrue(h1.matches("/a/b/c"));
+    }
+
+    @Test
+    public void testInit()
+        throws Exception
+    {
+        ServletHandler h1 = createHandler("/a");
+        h1.init();
+        Mockito.verify(this.servlet).init(Mockito.any(ServletConfig.class));
+    }
+
+    @Test
+    public void testDestroy()
+    {
+        ServletHandler h1 = createHandler("/a");
+        h1.destroy();
+        Mockito.verify(this.servlet).destroy();
+    }
+
+    @Test
+    public void testHandleNotFound()
+        throws Exception
+    {
+        ServletHandler h1 = createHandler("/a");
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+
+        Mockito.when(req.getPathInfo()).thenReturn("/");
+        boolean result = h1.handle(req, res);
+
+        Assert.assertFalse(result);
+        Mockito.verify(this.servlet, Mockito.never()).service(req, res);
+    }
+
+    @Test
+    public void testHandleFound()
+        throws Exception
+    {
+        ServletHandler h1 = createHandler("/a");
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+        Mockito.when(this.context.handleSecurity(req, res)).thenReturn(true);
+
+        Mockito.when(req.getPathInfo()).thenReturn("/a/b");
+        boolean result = h1.handle(req, res);
+
+        Assert.assertTrue(result);
+        Mockito.verify(this.servlet).service(Mockito.any(HttpServletRequest.class),
+                Mockito.any(HttpServletResponse.class));
+    }
+
+    @Test
+    public void testHandleFoundForbidden()
+        throws Exception
+    {
+        ServletHandler h1 = createHandler("/a");
+        HttpServletRequest req = Mockito.mock(HttpServletRequest.class);
+        HttpServletResponse res = Mockito.mock(HttpServletResponse.class);
+        Mockito.when(this.context.handleSecurity(req, res)).thenReturn(false);
+
+        Mockito.when(req.getPathInfo()).thenReturn("/a/b");
+        boolean result = h1.handle(req, res);
+
+        Assert.assertTrue(result);
+        Mockito.verify(this.servlet, Mockito.never()).service(req, res);
+        Mockito.verify(res).sendError(HttpServletResponse.SC_FORBIDDEN);
+    }
+}

Added: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/util/MimeTypesTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/util/MimeTypesTest.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/util/MimeTypesTest.java (added)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/util/MimeTypesTest.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,53 @@
+/*
+ * 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.felix.http.base.internal.util;
+
+import org.junit.Test;
+import org.junit.Assert;
+
+public class MimeTypesTest
+{
+    @Test
+    public void testSingleton()
+    {
+        MimeTypes m1 = MimeTypes.get();
+        MimeTypes m2 = MimeTypes.get();
+
+        Assert.assertNotNull(m1);
+        Assert.assertSame(m1, m2);
+
+    }
+
+    @Test
+    public void testGetByFile()
+    {
+        Assert.assertNull(MimeTypes.get().getByFile(null));
+        Assert.assertEquals("text/plain", MimeTypes.get().getByFile("afile.txt"));
+        Assert.assertEquals("text/xml", MimeTypes.get().getByFile(".xml"));
+        Assert.assertNull(MimeTypes.get().getByFile("xml"));
+        Assert.assertNull(MimeTypes.get().getByFile("somefile.notfound"));
+    }
+
+    @Test
+    public void testGetByExtension()
+    {
+        Assert.assertNull(MimeTypes.get().getByExtension(null));
+        Assert.assertEquals("text/plain", MimeTypes.get().getByExtension("txt"));
+        Assert.assertEquals("text/xml", MimeTypes.get().getByExtension("xml"));
+        Assert.assertNull(MimeTypes.get().getByExtension("notfound"));
+    }
+}

Added: felix/trunk/http/base/src/test/resources/org/apache/felix/http/base/internal/context/resource.txt
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/resources/org/apache/felix/http/base/internal/context/resource.txt?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/base/src/test/resources/org/apache/felix/http/base/internal/context/resource.txt (added)
+++ felix/trunk/http/base/src/test/resources/org/apache/felix/http/base/internal/context/resource.txt Mon Sep 14 09:59:12 2009
@@ -0,0 +1 @@
+Dummy resource...

Added: felix/trunk/http/bridge/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/http/bridge/pom.xml?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/bridge/pom.xml (added)
+++ felix/trunk/http/bridge/pom.xml Mon Sep 14 09:59:12 2009
@@ -0,0 +1,87 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>org.apache.felix.http</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <name>Apache Felix Http Bridge</name>
+    <artifactId>org.apache.felix.http.bridge</artifactId>
+    <packaging>bundle</packaging>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>
+                            org.apache.felix.http.bridge.internal.BridgeActivator
+                        </Bundle-Activator>
+                        <Export-Package>
+                            org.apache.felix.http.api;version=${pom.version},
+                            org.osgi.service.http;version=1.2.0
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.felix.http.base.*,
+                            org.apache.felix.http.bridge.internal.*
+                        </Private-Package>
+                        <Import-Package>
+                            javax.servlet.*,
+                            *;resolution:=optional
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>org.apache.felix.http.api</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>org.apache.felix.http.base</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>

Added: felix/trunk/http/bridge/src/main/java/org/apache/felix/http/bridge/internal/BridgeActivator.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/bridge/src/main/java/org/apache/felix/http/bridge/internal/BridgeActivator.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/bridge/src/main/java/org/apache/felix/http/bridge/internal/BridgeActivator.java (added)
+++ felix/trunk/http/bridge/src/main/java/org/apache/felix/http/bridge/internal/BridgeActivator.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,41 @@
+/*
+ * 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.felix.http.bridge.internal;
+
+import javax.servlet.http.HttpServlet;
+import java.util.Hashtable;
+import org.apache.felix.http.base.internal.AbstractActivator;
+
+public final class BridgeActivator
+    extends AbstractActivator
+{
+    @Override
+    protected void doStart()
+        throws Exception
+    {
+        Hashtable<String, Object> props = new Hashtable<String, Object>();
+        props.put("http.felix.dispatcher", getDispatcherServlet().getClass().getName());
+        getBundleContext().registerService(HttpServlet.class.getName(), getDispatcherServlet(), props);
+    }
+
+    @Override
+    protected void doStop()
+        throws Exception
+    {
+        // Do nothing
+    }
+}

Added: felix/trunk/http/bundle/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/http/bundle/pom.xml?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/bundle/pom.xml (added)
+++ felix/trunk/http/bundle/pom.xml Mon Sep 14 09:59:12 2009
@@ -0,0 +1,98 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>org.apache.felix.http</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <name>Apache Felix Http Bridge</name>
+    <artifactId>org.apache.felix.http.bundle</artifactId>
+    <packaging>bundle</packaging>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>
+                            org.apache.felix.http.bundle.internal.CombinedActivator
+                        </Bundle-Activator>
+                        <Export-Package>
+                            org.apache.felix.http.api;version=${pom.version};-split-package:=merge-first,
+                            org.osgi.service.http;version=1.2.0;-split-package:=merge-first,
+                            javax.servlet.*;version=2.5;-split-package:=merge-first
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.felix.http.base.*;-split-package:=merge-first,
+                            org.apache.felix.http.bridge.*,
+                            org.apache.felix.http.bundle.*,
+                            org.apache.felix.http.jetty.*,
+                            org.apache.felix.http.whiteboard.*,
+                            org.mortbay.*;-split-package:=merge-first
+                        </Private-Package>
+                        <Import-Package>
+                            javax.servlet.*,
+                            *;resolution:=optional
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>org.apache.felix.http.bridge</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>org.apache.felix.http.jetty</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>org.apache.felix.http.whiteboard</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>

Added: felix/trunk/http/bundle/src/main/java/org/apache/felix/http/bundle/internal/CombinedActivator.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/bundle/src/main/java/org/apache/felix/http/bundle/internal/CombinedActivator.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/bundle/src/main/java/org/apache/felix/http/bundle/internal/CombinedActivator.java (added)
+++ felix/trunk/http/bundle/src/main/java/org/apache/felix/http/bundle/internal/CombinedActivator.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,76 @@
+/*
+ * 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.felix.http.bundle.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.apache.felix.http.bridge.internal.BridgeActivator;
+import org.apache.felix.http.whiteboard.internal.WhiteboardActivator;
+import org.apache.felix.http.jetty.internal.JettyActivator;
+
+public final class CombinedActivator
+    implements BundleActivator
+{
+    private final static String JETTY_ENABLED_PROP = "org.apache.felix.http.jettyEnabled";
+    private final static String WHITEBOARD_ENABLED_PROP = "org.apache.felix.http.whiteboardEnabled";
+
+    private BundleActivator jettyActivator;
+    private BundleActivator bridgeActivator;
+    private BundleActivator whiteboardActivator;
+
+    public void start(BundleContext context)
+        throws Exception
+    {
+        if ("true".equals(context.getProperty(JETTY_ENABLED_PROP))) {
+            this.jettyActivator = new JettyActivator();
+        } else {
+            this.bridgeActivator = new BridgeActivator();
+        }
+
+        if ("true".equals(context.getProperty(WHITEBOARD_ENABLED_PROP))) {
+            this.whiteboardActivator = new WhiteboardActivator();
+        }
+
+        if (this.jettyActivator != null) {
+            this.jettyActivator.start(context);
+        }
+
+        if (this.bridgeActivator != null) {
+            this.bridgeActivator.start(context);
+        }
+
+        if (this.whiteboardActivator != null) {
+            this.whiteboardActivator.start(context);
+        }
+    }
+
+    public void stop(BundleContext context)
+        throws Exception
+    {
+        if (this.whiteboardActivator != null) {
+            this.whiteboardActivator.stop(context);
+        }
+
+        if (this.jettyActivator != null) {
+            this.jettyActivator.stop(context);
+        }
+
+        if (this.bridgeActivator != null) {
+            this.bridgeActivator.stop(context);
+        }
+    }
+}

Added: felix/trunk/http/jetty/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/http/jetty/pom.xml?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/jetty/pom.xml (added)
+++ felix/trunk/http/jetty/pom.xml Mon Sep 14 09:59:12 2009
@@ -0,0 +1,107 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>org.apache.felix.http</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <name>Apache Felix Http Jetty</name>
+    <artifactId>org.apache.felix.http.jetty</artifactId>
+    <packaging>bundle</packaging>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>
+                            org.apache.felix.http.jetty.internal.JettyActivator
+                        </Bundle-Activator>
+                        <Export-Package>
+                            org.apache.felix.http.api;version=${pom.version},
+                            org.osgi.service.http,
+                            javax.servlet.*;version=2.5
+                        </Export-Package>
+                        <Private-Package>
+                            org.apache.felix.http.base.*,
+                            org.apache.felix.http.jetty.*,
+                            org.mortbay.*;-split-package:=merge-first                            
+                        </Private-Package>
+                        <Import-Package>
+                            javax.net.ssl; javax.security.cert;
+                            javax.xml.parsers; org.xml.sax;
+                            org.xml.sax.helpers;
+                            org.slf4j;resolution:=optional,
+                            *;resolution:=optional
+                        </Import-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>servlet-api-2.5</artifactId>
+            <version>6.1.14</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty</artifactId>
+            <version>6.1.14</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty-util</artifactId>
+            <version>6.1.14</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty-sslengine</artifactId>
+            <version>6.1.14</version>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>org.apache.felix.http.api</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>${pom.groupId}</groupId>
+            <artifactId>org.apache.felix.http.base</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>

Added: felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyActivator.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyActivator.java?rev=814549&view=auto
==============================================================================
--- felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyActivator.java (added)
+++ felix/trunk/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyActivator.java Mon Sep 14 09:59:12 2009
@@ -0,0 +1,38 @@
+/*
+ * 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.felix.http.jetty.internal;
+
+import org.apache.felix.http.base.internal.AbstractActivator;
+
+public final class JettyActivator
+    extends AbstractActivator 
+{
+    private JettyService jetty;
+
+    protected void doStart()
+        throws Exception
+    {
+        this.jetty = new JettyService(getBundleContext(), getDispatcherServlet());
+        this.jetty.start();
+    }
+
+    protected void doStop()
+        throws Exception
+    {
+        this.jetty.stop();
+    }
+}