You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2015/01/29 18:16:58 UTC

svn commit: r1655753 - in /felix/trunk/http/base/src: main/java/org/apache/felix/http/base/internal/handler/ main/java/org/apache/felix/http/base/internal/runtime/ main/java/org/apache/felix/http/base/internal/service/ main/java/org/apache/felix/http/b...

Author: cziegeler
Date: Thu Jan 29 17:16:57 2015
New Revision: 1655753

URL: http://svn.apache.org/r1655753
Log:
FELIX-4060 : Implement HTTP Service Update (RFC-189)

Removed:
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/FilterMapping.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletMapping.java
Modified:
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ExtenderManager.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/HandlerRegistryTest.java

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java?rev=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java Thu Jan 29 17:16:57 2015
@@ -34,35 +34,28 @@ import org.apache.felix.http.base.intern
 public final class FilterHandler extends AbstractHandler implements Comparable<FilterHandler>
 {
     private final Filter filter;
-    private final Pattern regex;
-    private final int ranking;
-
-    public FilterHandler(ExtServletContext context, Filter filter, String pattern, int ranking, String name)
-    {
-        super(context, name);
-        this.filter = filter;
-        this.ranking = ranking;
-        this.regex = Pattern.compile(pattern);
-    }
+    private final FilterInfo filterInfo;
 
     public FilterHandler(ExtServletContext context, Filter filter, FilterInfo filterInfo)
     {
-        // TODO
         super(context, filterInfo.name);
         this.filter = filter;
-        this.ranking = filterInfo.ranking;
-        this.regex = Pattern.compile(filterInfo.regexs[0]);
+        this.filterInfo = filterInfo;
     }
 
     @Override
     public int compareTo(FilterHandler other)
     {
-        if (other.ranking == this.ranking)
+        if (other.filterInfo.ranking == this.filterInfo.ranking)
         {
-            return 0;
+            if (other.filterInfo.serviceId == this.filterInfo.serviceId)
+            {
+                return 0;
+            }
+            return other.filterInfo.serviceId > this.filterInfo.serviceId ? -1 : 1;
         }
 
-        return (other.ranking > this.ranking) ? 1 : -1;
+        return (other.filterInfo.ranking > this.filterInfo.ranking) ? 1 : -1;
     }
 
     @Override
@@ -78,12 +71,44 @@ public final class FilterHandler extends
 
     public String getPattern()
     {
-        return regex.toString();
+        final StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        if ( this.filterInfo.regexs != null )
+        {
+            for(final String p : this.filterInfo.regexs)
+            {
+                if ( first )
+                {
+                    first = false;
+                }
+                else
+                {
+                    sb.append(", ");
+                }
+                sb.append(p);
+            }
+        }
+        if ( this.filterInfo.patterns != null )
+        {
+            for(final String p : this.filterInfo.patterns)
+            {
+                if ( first )
+                {
+                    first = false;
+                }
+                else
+                {
+                    sb.append(", ");
+                }
+                sb.append(p);
+            }
+        }
+        return sb.toString();
     }
 
     public int getRanking()
     {
-        return ranking;
+        return filterInfo.ranking;
     }
 
     public void handle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException
@@ -113,7 +138,30 @@ public final class FilterHandler extends
             uri = "/";
         }
 
-        return this.regex.matcher(uri).matches();
+        if ( this.filterInfo.patterns != null )
+        {
+            for(final String p : this.filterInfo.patterns)
+            {
+                if ( Pattern.compile(p.replace(".", "\\.").replace("*", ".*")).matcher(uri).matches() )
+                {
+                    return true;
+                }
+            }
+        }
+        if ( this.filterInfo.regexs != null )
+        {
+            for(final String p : this.filterInfo.regexs)
+            {
+                if ( Pattern.compile(p).matcher(uri).matches() )
+                {
+                    return true;
+                }
+            }
+        }
+
+        // TODO implement servlet name matching
+
+        return false;
     }
 
     final void doHandle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException

Modified: 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=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java Thu Jan 29 17:16:57 2015
@@ -31,6 +31,7 @@ import static javax.servlet.http.HttpSer
 import static org.apache.felix.http.base.internal.util.UriUtils.concat;
 
 import java.io.IOException;
+import java.util.regex.Pattern;
 
 import javax.servlet.DispatcherType;
 import javax.servlet.RequestDispatcher;
@@ -236,6 +237,7 @@ public final class ServletHandler extend
 
     private final String alias;
     private final Servlet servlet;
+    private final Pattern pattern;
 
     public ServletHandler(final ExtServletContext context,
             final Servlet servlet,
@@ -245,6 +247,7 @@ public final class ServletHandler extend
         super(context, servletInfo.name);
         this.servlet = servlet;
         this.alias = alias;
+        this.pattern = Pattern.compile(alias.replace(".", "\\.").replace("*", ".*"));
     }
 
     @Override
@@ -330,10 +333,11 @@ public final class ServletHandler extend
         {
             return uri.startsWith(this.alias);
         }
-        else
+        else if ( uri.equals(this.alias) || uri.startsWith(this.alias + "/") )
         {
-            return uri.equals(this.alias) || uri.startsWith(this.alias + "/");
+            return true;
         }
+        return this.pattern.matcher(uri).matches();
     }
 
     final void doHandle(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java?rev=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java Thu Jan 29 17:16:57 2015
@@ -35,7 +35,6 @@ import aQute.bnd.annotation.ConsumerType
  * This class only provides information used at registration time, and as such differs slightly from {@link DTO}s like, {@link FilterDTO}.
  * </p>
  *
- * TODO - we should move this to the same place as {@link ExtHttpServiceRuntime}.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 @ConsumerType
@@ -81,6 +80,7 @@ public final class FilterInfo
      * Specifies the ranking order in which this filter should be called. Higher rankings are called first.
      */
     public int ranking = 0;
+    public long serviceId;
 
     /**
      * The dispatcher associations for the servlet filter.

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java?rev=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java Thu Jan 29 17:16:57 2015
@@ -34,7 +34,6 @@ import aQute.bnd.annotation.ConsumerType
  * This class only provides information used at registration time, and as such differs slightly from {@link DTO}s like, {@link ServletDTO}.
  * </p>
  *
- * TODO - we should move this to the same place as {@link ExtHttpServiceRuntime}.
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 @ConsumerType
@@ -72,4 +71,7 @@ public final class ServletInfo
      * The {@link HttpContext} for the servlet.
      */
     public HttpContext context;
+
+    public int ranking = 0;
+    public long serviceId;
 }

Modified: 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=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java Thu Jan 29 17:16:57 2015
@@ -21,6 +21,7 @@ import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
 
 import javax.servlet.Filter;
 import javax.servlet.Servlet;
@@ -49,6 +50,8 @@ public final class HttpServiceImpl imple
     private final HashSet<Filter> localFilters;
     private final ServletContextManager contextManager;
 
+    private final AtomicLong serviceIdCounter = new AtomicLong(-1);
+
     public HttpServiceImpl(Bundle bundle, ServletContext context, HandlerRegistry handlerRegistry, ServletContextAttributeListener servletAttributeListener, boolean sharedContextAttributes)
     {
         this.bundle = bundle;
@@ -90,7 +93,18 @@ public final class HttpServiceImpl imple
         return new DefaultHttpContext(this.bundle);
     }
 
-    public void registerFilter(Filter filter, FilterInfo filterInfo) throws ServletException
+    /**
+     * TODO As the filter can be registered with multiple patterns
+     *      we shouldn't pass the filter object around in order to
+     *      be able to get different instances (prototype scope).
+     *      Or we do the splitting into single pattern registrations
+     *      already before calling registerFilter()
+     * @param servlet
+     * @param servletInfo
+     * @throws ServletException
+     * @throws NamespaceException
+     */
+    public void registerFilter(final Filter filter, final FilterInfo filterInfo)
     {
         if (filter == null)
         {
@@ -111,10 +125,17 @@ public final class HttpServiceImpl imple
 
         FilterHandler handler = new FilterHandler(getServletContext(filterInfo.context), filter, filterInfo);
         handler.setInitParams(filterInfo.initParams);
-        this.handlerRegistry.addFilter(handler);
+        try {
+            this.handlerRegistry.addFilter(handler);
+        } catch (ServletException e) {
+            // TODO create failure DTO
+        }
         this.localFilters.add(filter);
     }
 
+    /**
+     * @see org.apache.felix.http.api.ExtHttpService#registerFilter(javax.servlet.Filter, java.lang.String, java.util.Dictionary, int, org.osgi.service.http.HttpContext)
+     */
     @Override
     public void registerFilter(Filter filter, String pattern, Dictionary initParams, int ranking, HttpContext context) throws ServletException
     {
@@ -122,11 +143,28 @@ public final class HttpServiceImpl imple
         {
             throw new IllegalArgumentException("Filter must not be null");
         }
-        String filterName = null; // XXX
-        FilterHandler handler = new FilterHandler(getServletContext(context), filter, pattern, ranking, filterName);
-        handler.setInitParams(initParams);
-        this.handlerRegistry.addFilter(handler);
-        this.localFilters.add(filter);
+        final FilterInfo info = new FilterInfo();
+        if ( initParams != null && initParams.size() > 0 )
+        {
+            info.initParams = new HashMap<String, String>();
+            Enumeration e = initParams.keys();
+            while (e.hasMoreElements())
+            {
+                Object key = e.nextElement();
+                Object value = initParams.get(key);
+
+                if ((key instanceof String) && (value instanceof String))
+                {
+                    info.initParams.put((String) key, (String) value);
+                }
+            }
+        }
+        info.patterns = new String[] {pattern};
+        info.context = context;
+        info.ranking = ranking;
+        info.serviceId = serviceIdCounter.getAndDecrement();
+
+        this.registerFilter(filter, info);
     }
 
     @Override
@@ -159,7 +197,7 @@ public final class HttpServiceImpl imple
      * @throws ServletException
      * @throws NamespaceException
      */
-    public void registerServlet(Servlet servlet, ServletInfo servletInfo) throws ServletException, NamespaceException
+    public void registerServlet(Servlet servlet, ServletInfo servletInfo)
     {
         if (servlet == null)
         {
@@ -181,11 +219,40 @@ public final class HttpServiceImpl imple
         for(final String pattern : servletInfo.patterns) {
             final ServletHandler handler = new ServletHandler(getServletContext(servletInfo.context), servlet, servletInfo, pattern);
             handler.setInitParams(servletInfo.initParams);
-            this.handlerRegistry.addServlet(handler);
+            try {
+                this.handlerRegistry.addServlet(handler);
+            } catch (ServletException e) {
+                // TODO create failure DTO
+            } catch (NamespaceException e) {
+                // TODO create failure DTO
+            }
             this.localServlets.add(servlet);
         }
     }
 
+    public void unregisterServlet(final Servlet servlet, final ServletInfo servletInfo)
+    {
+        if (servletInfo == null)
+        {
+            throw new IllegalArgumentException("ServletInfo cannot be null!");
+        }
+        if ( servletInfo.patterns != null )
+        {
+            this.handlerRegistry.removeServlet(servlet, true);
+            this.localServlets.remove(servlet);
+        }
+    }
+
+    public void unregisterFilter(final Filter filter, final FilterInfo filterInfo)
+    {
+        if (filterInfo == null)
+        {
+            throw new IllegalArgumentException("FilterInfo cannot be null!");
+        }
+        this.handlerRegistry.removeFilter(filter, true);
+        this.localFilters.remove(filter);
+    }
+
     /**
      * @see org.osgi.service.http.HttpService#registerServlet(java.lang.String, javax.servlet.Servlet, java.util.Dictionary, org.osgi.service.http.HttpContext)
      */
@@ -213,6 +280,8 @@ public final class HttpServiceImpl imple
                 }
             }
         }
+        info.ranking = 0;
+        info.serviceId = serviceIdCounter.getAndDecrement();
         info.patterns = new String[] {alias};
         info.context = context;
 
@@ -253,12 +322,20 @@ public final class HttpServiceImpl imple
         }
     }
 
+    /**
+     * Old whiteboard support
+     * @see org.apache.felix.http.api.ExtHttpService#unregisterFilter(javax.servlet.Filter)
+     */
     @Override
     public void unregisterFilter(Filter filter)
     {
         unregisterFilter(filter, true);
     }
 
+    /**
+     * Old whiteboard support
+     * @see org.apache.felix.http.api.ExtHttpService#unregisterServlet(javax.servlet.Servlet)
+     */
     @Override
     public void unregisterServlet(Servlet servlet)
     {

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ExtenderManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ExtenderManager.java?rev=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ExtenderManager.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ExtenderManager.java Thu Jan 29 17:16:57 2015
@@ -29,6 +29,7 @@ import javax.servlet.Servlet;
 import org.apache.felix.http.base.internal.logger.SystemLogger;
 import org.apache.felix.http.base.internal.runtime.FilterInfo;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
+import org.apache.felix.http.base.internal.service.HttpServiceImpl;
 import org.apache.felix.http.base.internal.whiteboard.HttpContextManager.HttpContextHolder;
 import org.apache.felix.http.base.internal.whiteboard.tracker.FilterTracker;
 import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextHelperTracker;
@@ -37,7 +38,6 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
-import org.osgi.service.http.HttpContext;
 import org.osgi.service.http.HttpService;
 import org.osgi.service.http.context.ServletContextHelper;
 import org.osgi.service.http.runtime.dto.ResourceDTO;
@@ -47,8 +47,6 @@ import org.osgi.util.tracker.ServiceTrac
 @SuppressWarnings({ "deprecation" })
 public final class ExtenderManager
 {
-    static final String TYPE_FILTER = "f";
-    static final String TYPE_SERVLET = "s";
     static final String TYPE_RESOURCE = "r";
 
     /**
@@ -173,32 +171,30 @@ public final class ExtenderManager
         }
     }
 
-    private void addInitParams(ServiceReference ref, AbstractMapping mapping)
+    /**
+     * Get the init parameters.
+     */
+    private Map<String, String> getInitParams(final ServiceReference<?> ref, final String prefix)
     {
-        for (String key : ref.getPropertyKeys())
+        Map<String, String> result = null;
+        for (final String key : ref.getPropertyKeys())
         {
-            String prefixKey = null;
-
-            if (mapping instanceof FilterMapping && key.startsWith(FILTER_INIT_PREFIX))
-            {
-                prefixKey = FILTER_INIT_PREFIX;
-            }
-            else if (mapping instanceof ServletMapping && key.startsWith(SERVLET_INIT_PREFIX))
+            if ( key.startsWith(prefix))
             {
-                prefixKey = SERVLET_INIT_PREFIX;
-            }
-
-            if (prefixKey != null)
-            {
-                String paramKey = key.substring(prefixKey.length());
-                String paramValue = getStringProperty(ref, key);
+                final String paramKey = key.substring(prefix.length());
+                final String paramValue = getStringProperty(ref, key);
 
                 if (paramValue != null)
                 {
-                    mapping.getInitParams().put(paramKey, paramValue);
+                    if ( result == null )
+                    {
+                        result = new HashMap<String, String>();
+                    }
+                    result.put(paramKey, paramValue);
                 }
             }
         }
+        return result;
     }
 
     public void add(ServletContextHelper service, ServiceReference ref)
@@ -268,17 +264,6 @@ public final class ExtenderManager
         }
     }
 
-    private HttpContext getHttpContext(AbstractMapping mapping, ServiceReference ref)
-    {
-        Bundle bundle = ref.getBundle();
-        String contextName = getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT);
-        if (!isEmpty(contextName))
-        {
-            return this.contextManager.getHttpContext(bundle, contextName, mapping, true);
-        }
-        return this.contextManager.getHttpContext(bundle, null, mapping);
-    }
-
     private void ungetHttpContext(AbstractMapping mapping, ServiceReference ref)
     {
         Bundle bundle = ref.getBundle();
@@ -293,18 +278,24 @@ public final class ExtenderManager
 
     public void add(final Filter service, final ServiceReference ref)
     {
-        FilterInfo filterInfo = new FilterInfo();
-        filterInfo.name = getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME);
-        if ( filterInfo.name == null || filterInfo.name.isEmpty() )
-        {
-            filterInfo.name = service.getClass().getName();
-        }
-        filterInfo.asyncSupported = getBooleanProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED);
-        filterInfo.servletNames = getStringArrayProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_SERVLET);
-        filterInfo.patterns = getStringArrayProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN);
-        filterInfo.ranking = getIntProperty(ref, Constants.SERVICE_RANKING, 0);
+        final FilterInfo filterInfo = createFilterInfo(ref, true);
+        if ( filterInfo != null )
+        {
+            ((HttpServiceImpl)this.httpService).registerFilter(service, filterInfo);
+        }
+    }
 
-        String[] dispatcherNames = getStringArrayProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_DISPATCHER);
+    private FilterInfo createFilterInfo(final ServiceReference<?> filterRef, final boolean log)
+    {
+        final FilterInfo filterInfo = new FilterInfo();
+        filterInfo.name = getStringProperty(filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME);
+        filterInfo.asyncSupported = getBooleanProperty(filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED);
+        filterInfo.servletNames = getStringArrayProperty(filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_SERVLET);
+        filterInfo.patterns = getStringArrayProperty(filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN);
+        filterInfo.ranking = getIntProperty(filterRef, Constants.SERVICE_RANKING, 0);
+        filterInfo.serviceId = (Long)filterRef.getProperty(Constants.SERVICE_ID);
+        filterInfo.initParams = getInitParams(filterRef, FILTER_INIT_PREFIX);
+        String[] dispatcherNames = getStringArrayProperty(filterRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_DISPATCHER);
         if (dispatcherNames != null && dispatcherNames.length > 0)
         {
             DispatcherType[] dispatchers = new DispatcherType[dispatcherNames.length];
@@ -317,50 +308,64 @@ public final class ExtenderManager
 
         if (isEmpty(filterInfo.patterns))
         {
-            SystemLogger.debug("Ignoring Filter Service " + ref + ", " + HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN +
-                    " is missing or empty");
-            return;
+            if ( log )
+            {
+                SystemLogger.debug("Ignoring Filter Service " + filterRef + ", " + HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN +
+                        " is missing or empty");
+            }
+            return null;
         }
 
-        FilterMapping mapping = new FilterMapping(ref.getBundle(), service, filterInfo);
-        filterInfo.context = getHttpContext(mapping, ref); // XXX
-        addInitParams(ref, mapping);
-        addMapping(TYPE_FILTER, ref, mapping);
+        return filterInfo;
     }
 
-    public void add(Servlet service, ServiceReference ref)
+    private ServletInfo createServletInfo(final ServiceReference<?> servletRef, final boolean log)
     {
-        ServletInfo servletInfo = new ServletInfo();
-        servletInfo.name = getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
-        if ( servletInfo.name == null || servletInfo.name.isEmpty() )
-        {
-            servletInfo.name = service.getClass().getName();
-        }
-        servletInfo.errorPage = getStringArrayProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE);
-        servletInfo.patterns = getStringArrayProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN);
-        servletInfo.asyncSupported = getBooleanProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED);
+        final ServletInfo servletInfo = new ServletInfo();
+        servletInfo.name = getStringProperty(servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME);
+        servletInfo.errorPage = getStringArrayProperty(servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE);
+        servletInfo.patterns = getStringArrayProperty(servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN);
+        servletInfo.asyncSupported = getBooleanProperty(servletRef, HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED);
+        servletInfo.initParams = getInitParams(servletRef, SERVLET_INIT_PREFIX);
+        servletInfo.ranking = getIntProperty(servletRef, Constants.SERVICE_RANKING, 0);
+        servletInfo.serviceId = (Long)servletRef.getProperty(Constants.SERVICE_ID);
 
         if (isEmpty(servletInfo.patterns))
         {
-            SystemLogger.debug("Ignoring Servlet Service " + ref + ", " + HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN +
-                    "is missing or empty");
-            return;
+            if ( log ) {
+                SystemLogger.debug("Ignoring Servlet Service " + servletRef + ", " + HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN +
+                        "is missing or empty");
+            }
+            return null;
         }
+        return servletInfo;
+    }
 
-        final ServletMapping mapping = new ServletMapping(ref.getBundle(), service, servletInfo);
-        servletInfo.context = getHttpContext(mapping, ref); // XXX
-        addInitParams(ref, mapping);
-        addMapping(TYPE_SERVLET, ref, mapping);
+    public void add(Servlet service, ServiceReference<?> ref)
+    {
+        final ServletInfo servletInfo = createServletInfo(ref, true);
+        if ( servletInfo != null )
+        {
+            ((HttpServiceImpl)this.httpService).registerServlet(service, servletInfo);
+        }
     }
 
-    public void removeFilter(ServiceReference ref)
+    public void removeFilter(final Filter service, ServiceReference ref)
     {
-        removeMapping(TYPE_FILTER, ref);
+        final FilterInfo filterInfo = createFilterInfo(ref, false);
+        if ( filterInfo != null )
+        {
+            ((HttpServiceImpl)this.httpService).unregisterFilter(service, filterInfo);
+        }
     }
 
-    public void removeServlet(ServiceReference ref)
+    public void removeServlet(Servlet service, ServiceReference ref)
     {
-        removeMapping(TYPE_SERVLET, ref);
+        final ServletInfo servletInfo = createServletInfo(ref, false);
+        if ( servletInfo != null )
+        {
+            ((HttpServiceImpl)this.httpService).unregisterServlet(service, servletInfo);
+        }
     }
 
     private synchronized void unregisterAll()

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java?rev=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java Thu Jan 29 17:16:57 2015
@@ -67,6 +67,6 @@ public final class FilterTracker extends
     @Override
     protected void removed(Filter service, ServiceReference ref)
     {
-        this.manager.removeFilter(ref);
+        this.manager.removeFilter(service, ref);
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java?rev=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java Thu Jan 29 17:16:57 2015
@@ -65,6 +65,6 @@ public final class ServletTracker extend
     @Override
     protected void removed(Servlet service, ServiceReference ref)
     {
-        this.manager.removeServlet(ref);
+        this.manager.removeServlet(service, ref);
     }
 }

Modified: 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=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java (original)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java Thu Jan 29 17:16:57 2015
@@ -34,6 +34,7 @@ import javax.servlet.FilterConfig;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.felix.http.base.internal.runtime.FilterInfo;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -41,6 +42,7 @@ public class FilterHandlerTest extends A
 {
     private Filter filter;
 
+    @Override
     @Before
     public void setUp()
     {
@@ -237,6 +239,7 @@ public class FilterHandlerTest extends A
         assertTrue(h4.matches("/a/b/"));
     }
 
+    @Override
     protected AbstractHandler createHandler()
     {
         return createHandler("dummy", 0);
@@ -244,6 +247,9 @@ public class FilterHandlerTest extends A
 
     private FilterHandler createHandler(String pattern, int ranking)
     {
-        return new FilterHandler(this.context, this.filter, pattern, ranking, null /* name */);
+        final FilterInfo info = new FilterInfo();
+        info.regexs = new String[] {pattern};
+        info.ranking = ranking;
+        return new FilterHandler(this.context, this.filter, info);
     }
 }

Modified: felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/HandlerRegistryTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/HandlerRegistryTest.java?rev=1655753&r1=1655752&r2=1655753&view=diff
==============================================================================
--- felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/HandlerRegistryTest.java (original)
+++ felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/HandlerRegistryTest.java Thu Jan 29 17:16:57 2015
@@ -27,6 +27,7 @@ import javax.servlet.Servlet;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
 
+import org.apache.felix.http.base.internal.runtime.FilterInfo;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -181,14 +182,23 @@ public class HandlerRegistryTest
         HandlerRegistry hr = new HandlerRegistry();
 
         Filter filter = Mockito.mock(Filter.class);
-        FilterHandler handler = new FilterHandler(null, filter, "/aha", 1, "oho");
+        final FilterInfo info = new FilterInfo();
+        info.name = "oho";
+        info.patterns = new String[] {"/aha"};
+        info.ranking = 1;
+
+        FilterHandler handler = new FilterHandler(null, filter, info);
         assertEquals("Precondition", 0, hr.getFilters().length);
         hr.addFilter(handler);
         Mockito.verify(filter, Mockito.times(1)).init(Mockito.any(FilterConfig.class));
         assertEquals(1, hr.getFilters().length);
         assertSame(handler, hr.getFilters()[0]);
 
-        FilterHandler handler2 = new FilterHandler(null, filter, "/hihi", 2, "haha");
+        final FilterInfo info2 = new FilterInfo();
+        info2.name = "haha";
+        info2.patterns = new String[] {"/hihi"};
+        info2.ranking = 2;
+        FilterHandler handler2 = new FilterHandler(null, filter, info2);
         try
         {
             hr.addFilter(handler2);
@@ -212,7 +222,11 @@ public class HandlerRegistryTest
         final HandlerRegistry hr = new HandlerRegistry();
 
         Filter filter = Mockito.mock(Filter.class);
-        final FilterHandler otherHandler = new FilterHandler(null, filter, "/two", 99, "two");
+        final FilterInfo info = new FilterInfo();
+        info.name = "two";
+        info.patterns = new String[] {"/two"};
+        info.ranking = 99;
+        final FilterHandler otherHandler = new FilterHandler(null, filter, info);
 
         Mockito.doAnswer(new Answer<Void>()
         {
@@ -231,7 +245,11 @@ public class HandlerRegistryTest
             }
         }).when(filter).init(Mockito.any(FilterConfig.class));
 
-        FilterHandler handler = new FilterHandler(null, filter, "/one", 1, "one");
+        final FilterInfo info2 = new FilterInfo();
+        info2.name = "one";
+        info2.patterns = new String[] {"/one"};
+        info2.ranking = 1;
+        FilterHandler handler = new FilterHandler(null, filter, info2);
 
         try
         {
@@ -262,7 +280,11 @@ public class HandlerRegistryTest
         ServletHandler servletHandler2 = new ServletHandler(null, servlet2, info2, "/ff");
         hr.addServlet(servletHandler2);
         Filter filter = Mockito.mock(Filter.class);
-        FilterHandler filterHandler = new FilterHandler(null, filter, "/f", 0, "f");
+        final FilterInfo fi = new FilterInfo();
+        fi.name = "f";
+        fi.patterns = new String[] {"/f"};
+        fi.ranking = 0;
+        FilterHandler filterHandler = new FilterHandler(null, filter, fi);
         hr.addFilter(filterHandler);
 
         assertEquals(2, hr.getServlets().length);