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/05/19 15:50:39 UTC

svn commit: r1680291 [1/2] - in /felix/trunk/http/base/src: main/java/org/apache/felix/http/base/internal/handler/ main/java/org/apache/felix/http/base/internal/registry/ main/java/org/apache/felix/http/base/internal/runtime/dto/ main/java/org/apache/f...

Author: cziegeler
Date: Tue May 19 13:50:39 2015
New Revision: 1680291

URL: http://svn.apache.org/r1680291
Log:
FELIX-4888 : ServletHandler's are not sorted by longest matching path. DTO handling (WiP)

Added:
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterHandlerMapping.java
      - copied, changed from r1679975, felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java   (with props)
Removed:
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ContextRuntime.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactories.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactory.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureRuntime.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextHelperRuntime.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/WhiteboardServiceRuntime.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/state/
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/registry/ErrorPageRegistry.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/registry/HandlerRegistryTest.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.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=1680291&r1=1680290&r2=1680291&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 Tue May 19 13:50:39 2015
@@ -31,14 +31,13 @@ import javax.servlet.ServletResponse;
 import org.apache.felix.http.base.internal.context.ExtServletContext;
 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.dto.state.FilterState;
 import org.apache.felix.http.base.internal.util.PatternUtil;
 import org.osgi.service.http.runtime.dto.DTOConstants;
 
 /**
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class FilterHandler implements Comparable<FilterHandler>, FilterState
+public class FilterHandler implements Comparable<FilterHandler>
 {
     private final long contextServiceId;
 
@@ -119,7 +118,6 @@ public class FilterHandler implements Co
         this.filter = f;
     }
 
-    @Override
     public FilterInfo getFilterInfo()
     {
         return this.filterInfo;
@@ -128,7 +126,7 @@ public class FilterHandler implements Co
     public String getName()
     {
         String name = this.filterInfo.getName();
-        if (name == null)
+        if (name == null && filter != null )
         {
             name = filter.getClass().getName();
         }

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=1680291&r1=1680290&r2=1680291&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 Tue May 19 13:50:39 2015
@@ -92,7 +92,7 @@ public abstract class ServletHandler imp
     public String getName()
     {
         String name = this.servletInfo.getName();
-        if (name == null)
+        if (name == null && servlet != null )
         {
             name = servlet.getClass().getName();
         }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java Tue May 19 13:50:39 2015
@@ -17,6 +17,7 @@
 package org.apache.felix.http.base.internal.registry;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -31,12 +32,16 @@ import javax.annotation.Nonnull;
 
 import org.apache.felix.http.base.internal.handler.ServletHandler;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.dto.state.FailureServletState;
-import org.apache.felix.http.base.internal.runtime.dto.state.ServletState;
+import org.apache.felix.http.base.internal.runtime.dto.ErrorPageDTOBuilder;
 import org.osgi.service.http.runtime.dto.DTOConstants;
+import org.osgi.service.http.runtime.dto.ErrorPageDTO;
+import org.osgi.service.http.runtime.dto.FailedErrorPageDTO;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
 
 /**
- * TODO - check if add/remove needs syncing
+ * The error page registry keeps tracks of the active/inactive servlets handling
+ * error pages (error code and/or exception).
+ * This registry is per servlet context.
  */
 public final class ErrorPageRegistry
 {
@@ -116,7 +121,7 @@ public final class ErrorPageRegistry
      * Add the servlet for error handling
      * @param handler The servlet handler.
      */
-    public void addServlet(@Nonnull final ServletHandler handler)
+    public synchronized void addServlet(@Nonnull final ServletHandler handler)
     {
         final ErrorRegistration reg = getErrorRegistration(handler.getServletInfo());
         if ( reg != null )
@@ -205,7 +210,7 @@ public final class ErrorPageRegistry
      * Remove the servlet from error handling
      * @param info The servlet info.
      */
-    public void removeServlet(@Nonnull final ServletInfo info, final boolean destroy)
+    public synchronized void removeServlet(@Nonnull final ServletInfo info, final boolean destroy)
     {
         final ErrorRegistration reg = getErrorRegistration(info);
         if ( reg != null )
@@ -311,7 +316,10 @@ public final class ErrorPageRegistry
     }
 
     /**
-     * Get the servlet handling the error
+     * Get the servlet handling the error (error code or exception).
+     * If an exception is provided, a handler for the exception is searched first.
+     * If no handler is found (or no exception provided) a handler for the error
+     * code is searched.
      * @param exception Optional exception
      * @param errorCode Error code
      * @return The servlet handling the error or {@code null}
@@ -327,6 +335,11 @@ public final class ErrorPageRegistry
         return get(errorCode);
     }
 
+    /**
+     * Get the servlet handling the error code
+     * @param errorCode Error code
+     * @return The servlet handling the error or {@code null}
+     */
     private ServletHandler get(final int errorCode)
     {
         final List<ServletHandler> list = this.errorCodesMap.get(errorCode);
@@ -337,6 +350,11 @@ public final class ErrorPageRegistry
         return null;
     }
 
+    /**
+     * Get the servlet handling the exception
+     * @param exception Error exception
+     * @return The servlet handling the error or {@code null}
+     */
     private ServletHandler get(final Throwable exception)
     {
         if (exception == null)
@@ -348,7 +366,7 @@ public final class ErrorPageRegistry
         Class<?> throwableClass = exception.getClass();
         while ( servletHandler == null && throwableClass != null )
         {
-            final List<ServletHandler> list = this.errorCodesMap.get(throwableClass.getName());
+            final List<ServletHandler> list = this.exceptionsMap.get(throwableClass.getName());
             if ( list != null )
             {
                 servletHandler = list.get(0);
@@ -366,6 +384,13 @@ public final class ErrorPageRegistry
         return servletHandler;
     }
 
+    /**
+     * Try to activate a servlet for an error code
+     * @param code The error code
+     * @param handler The servlet handler
+     * @param status The status to keep track of activation
+     * @return {@code -1} if activation was successful, failure code otherwise
+     */
     private boolean tryToActivate(final Long code, final ServletHandler handler, final ErrorRegistrationStatus status)
     {
         // add to active
@@ -375,6 +400,13 @@ public final class ErrorPageRegistry
         return result == -1;
     }
 
+    /**
+     * Try to activate a servlet for an exception
+     * @param exception The exception
+     * @param handler The servlet handler
+     * @param status The status to keep track of activation
+     * @return {@code -1} if activation was successful, failure code otherwise
+     */
     private boolean tryToActivate(final String exception, final ServletHandler handler, final ErrorRegistrationStatus status)
     {
         // add to active
@@ -384,9 +416,11 @@ public final class ErrorPageRegistry
         return result == -1;
     }
 
-    public void getRuntimeInfo(final Map<Long, ServletState> servletStates,
-            final Map<Long, Map<Integer, FailureServletState>> failureServletStates)
+    public void getRuntimeInfo(final ServletContextDTO dto,
+            final Collection<FailedErrorPageDTO> failedErrorPageDTOs)
     {
+        final Collection<ErrorPageDTO> errorPageDTOs = new ArrayList<ErrorPageDTO>();
+
         for(final ErrorRegistrationStatus status : this.statusMapping.values())
         {
             // TODO - we could do this calculation already when generating the status object
@@ -427,14 +461,11 @@ public final class ErrorPageRegistry
                     set.exceptions.add(codeEntry.getKey());
                 }
             }
+
+            // create DTOs
             if ( !active.errorCodes.isEmpty() || !active.exceptions.isEmpty() )
             {
-                ServletState state = servletStates.get(status.handler.getServletInfo().getServiceId());
-                if ( state == null )
-                {
-                    state = new ServletState(status.handler);
-                    servletStates.put(status.handler.getServletInfo().getServiceId(), state);
-                }
+                final ErrorPageDTO state = ErrorPageDTOBuilder.build(status.handler, -1);
                 if ( !active.errorCodes.isEmpty() )
                 {
                     final long[] codes = new long[active.errorCodes.size()];
@@ -443,28 +474,17 @@ public final class ErrorPageRegistry
                     {
                         codes[i] = iter.next();
                     }
-                    state.setErrorCodes(codes);
+                    state.errorCodes = codes;
                 }
                 if ( !active.exceptions.isEmpty() )
                 {
-                    state.setErrorExceptions(active.exceptions.toArray(new String[active.exceptions.size()]));
+                    state.exceptions = active.exceptions.toArray(new String[active.exceptions.size()]);
                 }
+                errorPageDTOs.add(state);
             }
             for(final Map.Entry<Integer, ErrorRegistration> entry : inactive.entrySet())
             {
-                Map<Integer, FailureServletState> failureStates = failureServletStates.get(status.handler.getServletInfo().getServiceId());
-                if ( failureStates == null )
-                {
-                    failureStates = new HashMap<Integer, FailureServletState>();
-                    failureServletStates.put(status.handler.getServletInfo().getServiceId(), failureStates);
-                }
-
-                FailureServletState state = failureStates.get(entry.getKey());
-                if ( state == null )
-                {
-                    state = new FailureServletState(status.handler, entry.getKey());
-                    failureStates.put(entry.getKey(), state);
-                }
+                final FailedErrorPageDTO state = (FailedErrorPageDTO)ErrorPageDTOBuilder.build(status.handler, entry.getKey());
                 if ( !entry.getValue().errorCodes.isEmpty() )
                 {
                     final long[] codes = new long[entry.getValue().errorCodes.size()];
@@ -473,13 +493,18 @@ public final class ErrorPageRegistry
                     {
                         codes[i] = iter.next();
                     }
-                    state.setErrorCodes(codes);
+                    state.errorCodes = codes;
                 }
                 if ( !entry.getValue().exceptions.isEmpty() )
                 {
-                    state.setErrorExceptions(entry.getValue().exceptions.toArray(new String[entry.getValue().exceptions.size()]));
+                    state.exceptions = entry.getValue().exceptions.toArray(new String[entry.getValue().exceptions.size()]);
                 }
+                failedErrorPageDTOs.add(state);
             }
         }
+        if ( !errorPageDTOs.isEmpty() )
+        {
+            dto.errorPageDTOs = errorPageDTOs.toArray(new ErrorPageDTO[errorPageDTOs.size()]);
+        }
     }
 }

Copied: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterHandlerMapping.java (from r1679975, felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java)
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterHandlerMapping.java?p2=felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterHandlerMapping.java&p1=felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java&r1=1679975&r2=1680291&rev=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterHandlerMapping.java Tue May 19 13:50:39 2015
@@ -44,30 +44,30 @@ import org.apache.felix.http.base.intern
  * for easy access to those handlers, based on the match rules defined in section 12.1 of Servlet
  * 3.0 specification.
  * <p>
- * {@link HandlerMapping} instances are immutable.
+ * {@link FilterHandlerMapping} instances are immutable.
  *
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public final class HandlerMapping
+public final class FilterHandlerMapping
 {
     private final SortedMap<Pattern, Set<FilterHandler>> exactMap;
     private final SortedMap<Pattern, Set<FilterHandler>> wildcardMap;
     private final Set<FilterHandler> mappedHandlers;
 
     /**
-     * Creates a new, empty, {@link HandlerMapping} instance.
+     * Creates a new, empty, {@link FilterHandlerMapping} instance.
      */
-    public HandlerMapping()
+    public FilterHandlerMapping()
     {
         this(Collections.<Pattern, Collection<FilterHandler>>emptyMap());
     }
 
     /**
-     * Creates a new {@link HandlerMapping} instance for the given elements.
+     * Creates a new {@link FilterHandlerMapping} instance for the given elements.
      *
      * @param mappings the elements to map.
      */
-    private HandlerMapping(@Nonnull final Map<Pattern, Collection<FilterHandler>> mappings)
+    private FilterHandlerMapping(@Nonnull final Map<Pattern, Collection<FilterHandler>> mappings)
     {
         this.exactMap = new TreeMap<Pattern, Set<FilterHandler>>(PatternComparator.INSTANCE);
         this.wildcardMap = new TreeMap<Pattern, Set<FilterHandler>>(PatternComparator.INSTANCE);
@@ -104,14 +104,14 @@ public final class HandlerMapping
     }
 
     /**
-     * Returns a new {@link HandlerMapping} instance with a mapping for the
+     * Returns a new {@link FilterHandlerMapping} instance with a mapping for the
      * given handler.
      *
      * @param handler the handler to be added to the mapping.
-     * @return a new {@link HandlerMapping} instance with a mapping for the
+     * @return a new {@link FilterHandlerMapping} instance with a mapping for the
      *         given handler.
      */
-    public HandlerMapping add(@Nonnull final FilterHandler handler)
+    public FilterHandlerMapping add(@Nonnull final FilterHandler handler)
     {
         final Map<Pattern, FilterHandler> mappings = new TreeMap<Pattern, FilterHandler>(PatternComparator.INSTANCE);
         for (final Pattern pattern : handler.getPatterns())
@@ -121,22 +121,22 @@ public final class HandlerMapping
         return add(mappings);
     }
 
-    HandlerMapping add(@Nonnull final Map<Pattern, FilterHandler> mappings)
+    FilterHandlerMapping add(@Nonnull final Map<Pattern, FilterHandler> mappings)
     {
         final Map<Pattern, Collection<FilterHandler>> newMappings = getAllMappings();
         addMappings(mappings, newMappings);
-        return new HandlerMapping(newMappings);
+        return new FilterHandlerMapping(newMappings);
     }
 
     /**
-     * Returns a new {@link HandlerMapping} instance without a mapping for the
+     * Returns a new {@link FilterHandlerMapping} instance without a mapping for the
      * given handler.
      *
      * @param subject the handled element to be removed from the mapping
-     * @return a new {@link HandlerMapping} instance without a mapping for the
+     * @return a new {@link FilterHandlerMapping} instance without a mapping for the
      *         given handler.
      */
-    public HandlerMapping remove(FilterHandler handler)
+    public FilterHandlerMapping remove(FilterHandler handler)
     {
         Map<Pattern, FilterHandler> mappings = new TreeMap<Pattern, FilterHandler>(PatternComparator.INSTANCE);
         for (Pattern pattern : handler.getPatterns())
@@ -146,19 +146,19 @@ public final class HandlerMapping
         return remove(mappings);
     }
 
-    HandlerMapping remove(Map<Pattern, FilterHandler> mappings)
+    FilterHandlerMapping remove(Map<Pattern, FilterHandler> mappings)
     {
         Map<Pattern, Collection<FilterHandler>> newMappings = getAllMappings();
         removeMappings(mappings, newMappings);
-        return new HandlerMapping(newMappings);
+        return new FilterHandlerMapping(newMappings);
     }
 
-    HandlerMapping update(Map<Pattern, FilterHandler> add, Map<Pattern, FilterHandler> remove)
+    FilterHandlerMapping update(Map<Pattern, FilterHandler> add, Map<Pattern, FilterHandler> remove)
     {
         Map<Pattern, Collection<FilterHandler>> newMappings = getAllMappings();
         removeMappings(remove, newMappings);
         addMappings(add, newMappings);
-        return new HandlerMapping(newMappings);
+        return new FilterHandlerMapping(newMappings);
     }
 
     private void addMappings(Map<Pattern, FilterHandler> mappings, Map<Pattern, Collection<FilterHandler>> target)

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java Tue May 19 13:50:39 2015
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 
 import javax.annotation.CheckForNull;
@@ -31,34 +32,27 @@ import javax.servlet.DispatcherType;
 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.runtime.FilterInfo;
-import org.apache.felix.http.base.internal.runtime.dto.state.FailureFilterState;
-import org.apache.felix.http.base.internal.runtime.dto.state.FilterState;
+import org.apache.felix.http.base.internal.runtime.dto.FilterDTOBuilder;
+import org.osgi.service.http.runtime.dto.FailedFilterDTO;
+import org.osgi.service.http.runtime.dto.FilterDTO;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
 
 /**
- * TODO - check if add/remove needs syncing
+ * The filter registry keeps track of all filter mappings for a single servlet context.
  */
 public final class FilterRegistry
 {
-    private volatile HandlerMapping filterMapping = new HandlerMapping();
+    private volatile FilterHandlerMapping filterMapping = new FilterHandlerMapping();
 
     private final Map<FilterInfo, FilterRegistrationStatus> statusMapping = new ConcurrentHashMap<FilterInfo, FilterRegistrationStatus>();
 
-    private static final class FilterRegistrationStatus implements FailureFilterState
+    private static final class FilterRegistrationStatus
     {
         public int result;
         public FilterHandler handler;
-
-        @Override
-        public FilterInfo getFilterInfo() {
-            return handler.getFilterInfo();
-        }
-        @Override
-        public int getReason() {
-            return result;
-        }
     }
 
-    public void addFilter(@Nonnull final FilterHandler handler)
+    public synchronized void addFilter(@Nonnull final FilterHandler handler)
     {
         final int result = handler.init();
         if ( result == -1 )
@@ -72,7 +66,7 @@ public final class FilterRegistry
         statusMapping.put(handler.getFilterInfo(), status);
     }
 
-    public void removeFilter(@Nonnull final FilterInfo filterInfo, final boolean destroy)
+    public synchronized void removeFilter(@Nonnull final FilterInfo filterInfo, final boolean destroy)
     {
         final FilterRegistrationStatus status = statusMapping.remove(filterInfo);
         if ( status != null )
@@ -142,21 +136,30 @@ public final class FilterRegistry
         return false;
     }
 
-    public void getRuntimeInfo(final Collection<FilterState> filterRuntimes,
-            final Collection<FailureFilterState> failureFilterRuntimes)
+    public void getRuntimeInfo(final ServletContextDTO servletContextDTO,
+                               final Collection<FailedFilterDTO> failedFilterDTOs)
     {
-        final HandlerMapping mapping = this.filterMapping;
-        for (final FilterState filterRuntime : mapping.values())
-        {
-            filterRuntimes.add(filterRuntime);
-        }
+        // we create a map to sort filter DTOs by ranking/service id
+        final Map<FilterInfo, FilterDTO> filterDTOs = new TreeMap<FilterInfo, FilterDTO>();
+        final Map<FilterInfo, FailedFilterDTO> failureFilterDTOs = new TreeMap<FilterInfo, FailedFilterDTO>();
 
-        for(final Map.Entry<FilterInfo, FilterRegistrationStatus> status : this.statusMapping.entrySet())
+        for(final Map.Entry<FilterInfo, FilterRegistrationStatus> entry : this.statusMapping.entrySet())
         {
-            if ( status.getValue().result != -1 )
+            if ( entry.getValue().result != -1 )
             {
-                failureFilterRuntimes.add(status.getValue());
+                failureFilterDTOs.put(entry.getKey(), FilterDTOBuilder.buildFailed(entry.getValue().handler, entry.getValue().result));
             }
+            else
+            {
+                filterDTOs.put(entry.getKey(), FilterDTOBuilder.build(entry.getValue().handler));
+            }
+        }
+
+        final Collection<FilterDTO> filterDTOArray = filterDTOs.values();
+        if ( !filterDTOArray.isEmpty() )
+        {
+            servletContextDTO.filterDTOs = filterDTOArray.toArray(new FilterDTO[filterDTOArray.size()]);
         }
+        failedFilterDTOs.addAll(failureFilterDTOs.values());
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java Tue May 19 13:50:39 2015
@@ -29,7 +29,8 @@ import org.apache.felix.http.base.intern
 import org.apache.felix.http.base.internal.runtime.FilterInfo;
 import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.FailedDTOHolder;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
 
 /**
  * Registry for all services.
@@ -276,13 +277,15 @@ public final class HandlerRegistry
         return null;
     }
 
-    public ContextRuntime getRuntime(final long contextId)
+    public boolean getRuntime(final ServletContextDTO dto,
+            final FailedDTOHolder failedDTOHolder)
     {
-        final PerContextHandlerRegistry reg = this.getRegistry(contextId);
+        final PerContextHandlerRegistry reg = this.getRegistry(dto.serviceId);
         if ( reg != null )
         {
-            return reg.getRuntime();
+            reg.getRuntime(dto, failedDTOHolder);
+            return true;
         }
-        return null;
+        return false;
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java Tue May 19 13:50:39 2015
@@ -16,11 +16,6 @@
  */
 package org.apache.felix.http.base.internal.registry;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeSet;
-
 import javax.annotation.Nonnull;
 import javax.servlet.DispatcherType;
 
@@ -29,11 +24,8 @@ import org.apache.felix.http.base.intern
 import org.apache.felix.http.base.internal.runtime.FilterInfo;
 import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime;
-import org.apache.felix.http.base.internal.runtime.dto.state.FailureFilterState;
-import org.apache.felix.http.base.internal.runtime.dto.state.FailureServletState;
-import org.apache.felix.http.base.internal.runtime.dto.state.FilterState;
-import org.apache.felix.http.base.internal.runtime.dto.state.ServletState;
+import org.apache.felix.http.base.internal.runtime.dto.FailedDTOHolder;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
 
 /**
  * This registry keeps track of all processing components per context:
@@ -192,32 +184,21 @@ public final class PerContextHandlerRegi
         return this.errorPageRegistry.get(exception, code);
     }
 
-    public ContextRuntime getRuntime()
+    /**
+     * Create all DTOs for servlets, filters, resources and error pages
+     * @param dto The servlet context DTO
+     * @param failedDTOHolder The container for all failed DTOs
+     */
+    public void getRuntime(final ServletContextDTO dto,
+            final FailedDTOHolder failedDTOHolder)
     {
         // collect filters
-        final Collection<FilterState> filterRuntimes = new TreeSet<FilterState>(FilterState.COMPARATOR);
-        final Collection<FailureFilterState> failureFilterRuntimes = new TreeSet<FailureFilterState>(FailureFilterState.COMPARATOR);
-        this.filterRegistry.getRuntimeInfo(filterRuntimes, failureFilterRuntimes);
+        this.filterRegistry.getRuntimeInfo(dto, failedDTOHolder.failedFilterDTOs);
 
         // collect error pages
-        final Map<Long, ServletState> servletStates = new HashMap<Long, ServletState>();
-        final Map<Long, Map<Integer, FailureServletState>> failureServletStates = new HashMap<Long, Map<Integer,FailureServletState>>();
-        this.errorPageRegistry.getRuntimeInfo(servletStates, failureServletStates);
+        this.errorPageRegistry.getRuntimeInfo(dto, failedDTOHolder.failedErrorPageDTOs);
 
         // collect servlets and resources
-        this.servletRegistry.getRuntimeInfo(servletStates, failureServletStates);
-
-        final Collection<ServletState> sortedServletStates = new TreeSet<ServletState>(ServletState.COMPARATOR);
-        sortedServletStates.addAll(servletStates.values());
-        final Collection<FailureServletState> sortedFailureServletStates = new TreeSet<FailureServletState>(ServletState.COMPARATOR);
-        for(final Map<Integer, FailureServletState> val : failureServletStates.values())
-        {
-            sortedFailureServletStates.addAll(val.values());
-        }
-
-        return new ContextRuntime(filterRuntimes,
-                sortedServletStates,
-                failureFilterRuntimes,
-                sortedFailureServletStates);
+        this.servletRegistry.getRuntimeInfo(dto, failedDTOHolder.failedServletDTOs, failedDTOHolder.failedResourceDTOs);
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java Tue May 19 13:50:39 2015
@@ -17,6 +17,7 @@
 package org.apache.felix.http.base.internal.registry;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -29,10 +30,15 @@ import javax.annotation.Nonnull;
 
 import org.apache.felix.http.base.internal.handler.ServletHandler;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.dto.state.FailureServletState;
-import org.apache.felix.http.base.internal.runtime.dto.state.ServletState;
+import org.apache.felix.http.base.internal.runtime.dto.ResourceDTOBuilder;
+import org.apache.felix.http.base.internal.runtime.dto.ServletDTOBuilder;
 import org.apache.felix.http.base.internal.util.PatternUtil;
 import org.osgi.service.http.runtime.dto.DTOConstants;
+import org.osgi.service.http.runtime.dto.FailedResourceDTO;
+import org.osgi.service.http.runtime.dto.FailedServletDTO;
+import org.osgi.service.http.runtime.dto.ResourceDTO;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
+import org.osgi.service.http.runtime.dto.ServletDTO;
 
 /**
  * The servlet registry keeps the mappings for all servlets (by using their pattern)
@@ -42,8 +48,6 @@ import org.osgi.service.http.runtime.dto
  *
  * TODO - sort active servlet mappings by pattern length, longest first (avoids looping over all)
  *
- * TODO - check if add/remove needs syncing
- *
  * TODO - replace patterns with own matchers
  */
 public final class ServletRegistry
@@ -156,7 +160,7 @@ public final class ServletRegistry
         this.servletsByName.put(servletName, list);
     }
 
-    private void removeFromNameMapping(final String servletName, final ServletHandler handler)
+    private synchronized void removeFromNameMapping(final String servletName, final ServletHandler handler)
     {
         List<ServletHandler> list = this.servletsByName.get(servletName);
         if ( list != null )
@@ -187,7 +191,7 @@ public final class ServletRegistry
      * Remove a servlet
      * @param info The servlet info
      */
-    public void removeServlet(@Nonnull final ServletInfo info, final boolean destroy)
+    public synchronized void removeServlet(@Nonnull final ServletInfo info, final boolean destroy)
     {
         if ( info.getPatterns() != null )
         {
@@ -314,63 +318,93 @@ public final class ServletRegistry
         return null;
     }
 
-    public void getRuntimeInfo(final Map<Long, ServletState> servletStates,
-            final Map<Long, Map<Integer, FailureServletState>> failureServletStates)
+    public void getRuntimeInfo(
+            final ServletContextDTO servletContextDTO,
+            final Collection<FailedServletDTO> allFailedServletDTOs,
+            final Collection<FailedResourceDTO> allFailedResourceDTOs)
     {
+        final Map<Long, ServletDTO> servletDTOs = new HashMap<Long, ServletDTO>();
+        final Map<Long, ResourceDTO> resourceDTOs = new HashMap<Long, ResourceDTO>();
+
+        final Map<Long, FailedServletDTO> failedServletDTOs = new HashMap<Long, FailedServletDTO>();
+        final Map<Long, FailedResourceDTO> failedResourceDTOs = new HashMap<Long, FailedResourceDTO>();
+
         // TODO we could already do some pre calculation in the ServletRegistrationStatus
         for(final Map.Entry<ServletInfo, ServletRegistrationStatus> entry : statusMapping.entrySet())
         {
             final long serviceId = entry.getKey().getServiceId();
             for(final Map.Entry<String, Integer> map : entry.getValue().pathToStatus.entrySet())
             {
-                if ( map.getValue() == - 1)
+                if ( entry.getKey().isResource() )
                 {
-                    ServletState state = servletStates.get(serviceId);
+                    ServletDTO state = (map.getValue() == -1 ? servletDTOs.get(serviceId) : failedServletDTOs.get(serviceId));
                     if ( state == null )
                     {
-                        state = new ServletState(entry.getValue().handler);
-                        servletStates.put(serviceId, state);
+                        state = ServletDTOBuilder.build(entry.getValue().handler, map.getValue());
+                        if ( map.getValue() == -1 )
+                        {
+                            servletDTOs.put(serviceId, state);
+                        }
+                        else
+                        {
+                            failedServletDTOs.put(serviceId, (FailedServletDTO)state);
+                        }
                     }
-                    String[] patterns = state.getPatterns();
+                    String[] patterns = state.patterns;
                     if ( patterns.length ==  0 )
                     {
-                        state.setPatterns(new String[] {map.getKey()});
+                        state.patterns = new String[] {map.getKey()};
                     }
                     else
                     {
                         patterns = new String[patterns.length + 1];
-                        System.arraycopy(state.getPatterns(), 0, patterns, 0, patterns.length - 1);
+                        System.arraycopy(state.patterns, 0, patterns, 0, patterns.length - 1);
                         patterns[patterns.length - 1] = map.getKey();
+                        state.patterns = patterns;
                     }
                 }
                 else
                 {
-                    Map<Integer, FailureServletState> fmap = failureServletStates.get(serviceId);
-                    if ( fmap == null )
-                    {
-                        fmap = new HashMap<Integer, FailureServletState>();
-                        failureServletStates.put(serviceId, fmap);
-                    }
-                    FailureServletState state = fmap.get(map.getValue());
+                    ResourceDTO state = (map.getValue() == -1 ? resourceDTOs.get(serviceId) : failedResourceDTOs.get(serviceId));
                     if ( state == null )
                     {
-                        state = new FailureServletState(entry.getValue().handler, map.getValue());
-                        fmap.put(map.getValue(), state);
+                        state = ResourceDTOBuilder.build(entry.getValue().handler, map.getValue());
+                        if ( map.getValue() == -1 )
+                        {
+                            resourceDTOs.put(serviceId, state);
+                        }
+                        else
+                        {
+                            failedResourceDTOs.put(serviceId, (FailedResourceDTO)state);
+                        }
                     }
-                    String[] patterns = state.getPatterns();
+                    String[] patterns = state.patterns;
                     if ( patterns.length ==  0 )
                     {
-                        state.setPatterns(new String[] {map.getKey()});
+                        state.patterns = new String[] {map.getKey()};
                     }
                     else
                     {
                         patterns = new String[patterns.length + 1];
-                        System.arraycopy(state.getPatterns(), 0, patterns, 0, patterns.length - 1);
+                        System.arraycopy(state.patterns, 0, patterns, 0, patterns.length - 1);
                         patterns[patterns.length - 1] = map.getKey();
+                        state.patterns = patterns;
                     }
                 }
-
             }
         }
+
+        final Collection<ServletDTO> servletDTOsArray = servletDTOs.values();
+        if ( !servletDTOsArray.isEmpty() )
+        {
+            servletContextDTO.servletDTOs = servletDTOsArray.toArray(new ServletDTO[servletDTOsArray.size()]);
+        }
+        final Collection<ResourceDTO> resourceDTOsArray = resourceDTOs.values();
+        if ( !resourceDTOsArray.isEmpty() )
+        {
+            servletContextDTO.resourceDTOs = resourceDTOsArray.toArray(new ResourceDTO[resourceDTOsArray.size()]);
+        }
+        allFailedResourceDTOs.addAll(failedResourceDTOs.values());
+        allFailedServletDTOs.addAll(failedServletDTOs.values());
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java Tue May 19 13:50:39 2015
@@ -18,48 +18,37 @@
  */
 package org.apache.felix.http.base.internal.runtime.dto;
 
-import javax.servlet.Servlet;
-
+import org.apache.felix.http.base.internal.handler.ServletHandler;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.dto.state.ServletState;
 import org.osgi.service.http.runtime.dto.BaseServletDTO;
 
-abstract class BaseServletDTOBuilder<T extends ServletState, U extends BaseServletDTO> extends BaseDTOBuilder<T, U>
+abstract class BaseServletDTOBuilder
 {
-    BaseServletDTOBuilder(DTOFactory<U> servletDTOFactory)
+    /**
+     * Build a servlet DTO from a servlet info
+     * @param info The servlet info
+     * @return A servlet DTO
+     */
+    public static void fill(final BaseServletDTO dto, final ServletHandler handler)
     {
-        super(servletDTOFactory);
+        dto.name = handler.getName();
+        if ( handler.getServlet() != null )
+        {
+            dto.servletInfo = handler.getServlet().getServletInfo();
+        }
+        dto.servletContextId = handler.getContextServiceId();
     }
 
-    @Override
-    U buildDTO(T servletRuntime, long servletContextId)
+    /**
+     * Build a servlet DTO from a servlet info
+     * @param info The servlet info
+     * @return A servlet DTO
+     */
+    public static void fill(final BaseServletDTO dto, final ServletInfo info)
     {
-        ServletInfo info = servletRuntime.getServletInfo();
-        Servlet servlet = servletRuntime.getServlet();
-
-        U dto = getDTOFactory().get();
         dto.asyncSupported = info.isAsyncSupported();
         dto.initParams = info.getInitParameters();
-        dto.name = getName(info, servlet);
-        dto.serviceId = servletRuntime.getServletInfo().getServiceId();
-        dto.servletContextId = servletContextId;
-        dto.servletInfo = servlet != null ? servlet.getServletInfo() : null;
-        return dto;
-    }
-
-    private String getName(ServletInfo info, Servlet servlet)
-    {
-        String name = info.getName();
-        if (name != null)
-        {
-            return name;
-        }
-
-        if (servlet != null)
-        {
-            return servlet.getServletConfig().getServletName();
-        }
-
-        return null;
+        dto.name = info.getName();
+        dto.serviceId = info.getServiceId();
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java Tue May 19 13:50:39 2015
@@ -18,6 +18,8 @@
  */
 package org.apache.felix.http.base.internal.runtime.dto;
 
+import static java.util.Arrays.copyOf;
+
 import org.osgi.service.http.runtime.dto.ErrorPageDTO;
 import org.osgi.service.http.runtime.dto.FailedErrorPageDTO;
 import org.osgi.service.http.runtime.dto.FailedFilterDTO;
@@ -34,13 +36,14 @@ import org.osgi.service.http.runtime.dto
 public abstract class BuilderConstants
 {
 
-    public static final String[] STRING_ARRAY = new String[0];
+    public static final String[] EMPTY_STRING_ARRAY = new String[0];
+    public static final long[] EMPTY_LONG_ARRAY = new long[0];
 
     public static final ServletContextDTO[] CONTEXT_DTO_ARRAY = new ServletContextDTO[0];
 
     public static final ServletDTO[] SERVLET_DTO_ARRAY = new ServletDTO[0];
     public static final ResourceDTO[] RESOURCE_DTO_ARRAY = new ResourceDTO[0];
-    public static final FilterDTO[] FILTER_DTO_ARRAY = new FilterDTO[0];
+    public static final FilterDTO[] EMPTY_FILTER_DTO_ARRAY = new FilterDTO[0];
     public static final ErrorPageDTO[] ERROR_PAGE_DTO_ARRAY = new ErrorPageDTO[0];
     public static final ListenerDTO[] LISTENER_DTO_ARRAY = new ListenerDTO[0];
 
@@ -51,4 +54,10 @@ public abstract class BuilderConstants
     public static final FailedResourceDTO[] RESOURCE_FAILURE_DTO_ARRAY = new FailedResourceDTO[0];
     public static final FailedErrorPageDTO[] ERROR_PAGE_FAILURE_DTO_ARRAY = new FailedErrorPageDTO[0];
     public static final FailedListenerDTO[] LISTENER_FAILURE_DTO_ARRAY = new FailedListenerDTO[0];
+
+    public static <V> V[] copyWithDefault(V[] array, V[] defaultArray)
+    {
+        return array == null ? defaultArray : copyOf(array, array.length);
+    }
+
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java Tue May 19 13:50:39 2015
@@ -18,45 +18,47 @@
  */
 package org.apache.felix.http.base.internal.runtime.dto;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.felix.http.base.internal.runtime.dto.state.ServletState;
+import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.runtime.ServletInfo;
 import org.osgi.service.http.runtime.dto.ErrorPageDTO;
+import org.osgi.service.http.runtime.dto.FailedErrorPageDTO;
 
-final class ErrorPageDTOBuilder<T extends ErrorPageDTO> extends BaseServletDTOBuilder<ServletState, T>
+public final class ErrorPageDTOBuilder extends BaseServletDTOBuilder
 {
-    static ErrorPageDTOBuilder<ErrorPageDTO> create()
+    /**
+     * Build a servlet DTO from a servlet handler
+     * @param handler The servlet handler
+     * @param reason If reason is -1, a servlet DTO is created, otherwise a failed servlet DTO is returned
+     * @return A servlet DTO
+     */
+    public static ErrorPageDTO build(final ServletHandler handler, final int reason)
     {
-        return new ErrorPageDTOBuilder<ErrorPageDTO>(DTOFactories.ERROR_PAGE);
-    }
+        final ErrorPageDTO dto = build(handler.getServletInfo(), reason != -1);
 
-    ErrorPageDTOBuilder(DTOFactory<T> dtoFactory)
-    {
-        super(dtoFactory);
-    }
+        BaseServletDTOBuilder.fill(dto, handler);
 
-    @Override
-    Collection<T> build(Collection<? extends ServletState> whiteboardServices,
-            long servletContextId) {
-        List<T> dtoList = new ArrayList<T>();
-        for (ServletState whiteboardService : whiteboardServices)
+        if ( reason != -1 )
         {
-            if ( whiteboardService.getErrorCodes().length > 0 || whiteboardService.getErrorExceptions().length > 0 )
-            {
-                dtoList.add(buildDTO(whiteboardService, servletContextId));
-            }
+            ((FailedErrorPageDTO)dto).failureReason = reason;
         }
-        return dtoList;
+
+        return dto;
     }
 
-    @Override
-    T buildDTO(ServletState errorPage, long servletConextId)
+    /**
+     * Build a servlet DTO from a servlet info
+     * @param info The servlet info
+     * @return A servlet DTO
+     */
+    public static ErrorPageDTO build(final ServletInfo info, final boolean failed)
     {
-        T errorPageDTO = super.buildDTO(errorPage, servletConextId);
-        errorPageDTO.errorCodes = errorPage.getErrorCodes();
-        errorPageDTO.exceptions = errorPage.getErrorExceptions();
-        return errorPageDTO;
+        final ErrorPageDTO dto = (failed ? new FailedErrorPageDTO() : new ErrorPageDTO());
+
+        BaseServletDTOBuilder.fill(dto, info);
+
+        dto.errorCodes = BuilderConstants.EMPTY_LONG_ARRAY;
+        dto.exceptions = BuilderConstants.EMPTY_STRING_ARRAY;
+
+        return dto;
     }
 }

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java?rev=1680291&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java Tue May 19 13:50:39 2015
@@ -0,0 +1,133 @@
+/*
+ * 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.runtime.dto;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.felix.http.base.internal.logger.SystemLogger;
+import org.apache.felix.http.base.internal.registry.ErrorPageRegistry;
+import org.apache.felix.http.base.internal.runtime.AbstractInfo;
+import org.apache.felix.http.base.internal.runtime.FilterInfo;
+import org.apache.felix.http.base.internal.runtime.ListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ResourceInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+import org.apache.felix.http.base.internal.runtime.ServletInfo;
+import org.osgi.service.http.runtime.dto.FailedErrorPageDTO;
+import org.osgi.service.http.runtime.dto.FailedFilterDTO;
+import org.osgi.service.http.runtime.dto.FailedListenerDTO;
+import org.osgi.service.http.runtime.dto.FailedResourceDTO;
+import org.osgi.service.http.runtime.dto.FailedServletContextDTO;
+import org.osgi.service.http.runtime.dto.FailedServletDTO;
+
+public final class FailedDTOHolder
+{
+
+    public Collection<FailedFilterDTO> failedFilterDTOs = new ArrayList<FailedFilterDTO>();
+
+    public Collection<FailedListenerDTO> failedListenerDTOs = new ArrayList<FailedListenerDTO>();
+
+    public Collection<FailedServletDTO> failedServletDTOs = new ArrayList<FailedServletDTO>();
+
+    public Collection<FailedResourceDTO> failedResourceDTOs = new ArrayList<FailedResourceDTO>();
+
+    public Collection<FailedErrorPageDTO> failedErrorPageDTOs = new ArrayList<FailedErrorPageDTO>();
+
+    public Collection<FailedServletContextDTO> failedServletContextDTO = new ArrayList<FailedServletContextDTO>();
+
+    public void add(Map<AbstractInfo<?>, Integer> failureInfos)
+    {
+        for (Map.Entry<AbstractInfo<?>, Integer> failureEntry : failureInfos.entrySet())
+        {
+            add(failureEntry.getKey(), failureEntry.getValue());
+        }
+    }
+
+    private void add(final AbstractInfo<?> info, final int failureCode)
+    {
+        if (info instanceof ServletContextHelperInfo)
+        {
+            final FailedServletContextDTO dto = (FailedServletContextDTO)ServletContextDTOBuilder.build((ServletContextHelperInfo)info, null, failureCode);
+            this.failedServletContextDTO.add(dto);
+        }
+        else if (info instanceof ServletInfo )
+        {
+            boolean isError = false;
+            if ( ((ServletInfo) info).getErrorPage() != null)
+            {
+                isError = true;
+                final FailedErrorPageDTO dto = (FailedErrorPageDTO)ErrorPageDTOBuilder.build((ServletInfo)info, true);
+                dto.failureReason = failureCode;
+                final ErrorPageRegistry.ErrorRegistration  reg = ErrorPageRegistry.getErrorRegistration((ServletInfo)info);
+                if ( !reg.errorCodes.isEmpty() )
+                {
+                    final long[] codes = new long[reg.errorCodes.size()];
+                    int index = 0;
+                    final Iterator<Long> i = reg.errorCodes.iterator();
+                    while ( i.hasNext() )
+                    {
+                        codes[index++] = i.next();
+                    }
+                    dto.errorCodes = codes;
+                }
+                if ( !reg.exceptions.isEmpty() )
+                {
+                    dto.exceptions = reg.exceptions.toArray(new String[reg.exceptions.size()]);
+                }
+                this.failedErrorPageDTOs.add(dto);
+            }
+
+            if ( ((ServletInfo) info).getPatterns() != null || !isError )
+            {
+                final FailedServletDTO dto = (FailedServletDTO)ServletDTOBuilder.build((ServletInfo) info, true);
+                dto.failureReason = failureCode;
+                if ( ((ServletInfo) info).getPatterns() != null )
+                {
+                    dto.patterns = ((ServletInfo) info).getPatterns();
+                }
+                this.failedServletDTOs.add(dto);
+            }
+        }
+        else if (info instanceof FilterInfo)
+        {
+            final FailedFilterDTO dto = (FailedFilterDTO)FilterDTOBuilder.build((FilterInfo) info, true);
+            dto.failureReason = failureCode;
+
+            this.failedFilterDTOs.add(dto);
+        }
+        else if (info instanceof ResourceInfo)
+        {
+            final FailedResourceDTO dto = (FailedResourceDTO)ResourceDTOBuilder.build((ResourceInfo) info, true);
+            dto.failureReason = failureCode;
+            this.failedResourceDTOs.add(dto);
+        }
+        else if (info instanceof ListenerInfo)
+        {
+            final FailedListenerDTO dto = (FailedListenerDTO)ListenerDTOBuilder.build((ListenerInfo<?>)info, failureCode);
+            this.failedListenerDTOs.add(dto);
+        }
+        else
+        {
+            SystemLogger.error("Unsupported info type: " + info.getClass(), null);
+        }
+    }
+}
+

Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java
------------------------------------------------------------------------------
    svn:keywords = author date id revision rev url

Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailedDTOHolder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java Tue May 19 13:50:39 2015
@@ -20,46 +20,90 @@ package org.apache.felix.http.base.inter
 
 import javax.servlet.DispatcherType;
 
+import org.apache.felix.http.base.internal.handler.FilterHandler;
 import org.apache.felix.http.base.internal.runtime.FilterInfo;
-import org.apache.felix.http.base.internal.runtime.dto.state.FilterState;
+import org.osgi.service.http.runtime.dto.FailedFilterDTO;
 import org.osgi.service.http.runtime.dto.FilterDTO;
 
-final class FilterDTOBuilder<T extends FilterDTO> extends BaseDTOBuilder<FilterState, T>
+public final class FilterDTOBuilder
 {
-    static FilterDTOBuilder<FilterDTO> create()
+    /**
+     * Build an array of filter DTO from a filter handler array
+     * @param handlers The filter handler array
+     * @return The filter DTO array
+     */
+    public static FilterDTO[] build(final FilterHandler[] handlers)
     {
-        return new FilterDTOBuilder<FilterDTO>(DTOFactories.FILTER);
+        if ( handlers.length == 0 )
+        {
+            return BuilderConstants.EMPTY_FILTER_DTO_ARRAY;
+        }
+        final FilterDTO[] array = new FilterDTO[handlers.length];
+        for(int i=0; i<handlers.length; i++)
+        {
+            array[i] = build(handlers[i]);
+        }
+
+        return array;
     }
 
-    FilterDTOBuilder(DTOFactory<T> dtoFactory)
+    /**
+     * Build a filter DTO from a filter handler
+     * @param handler The filter handler
+     * @return A filter DTO
+     */
+    public static FilterDTO build(final FilterHandler handler)
     {
-        super(dtoFactory);
+        final FilterDTO filterDTO = build(handler.getFilterInfo(), false);
+
+        filterDTO.name = handler.getName();
+        filterDTO.servletContextId = handler.getContextServiceId();
+
+        return filterDTO;
     }
 
-    @Override
-    T buildDTO(FilterState filterRuntime, long servletContextId)
+    /**
+     * Build a filter DTO from a filter info
+     * @param info The filter info
+     * @return A filter DTO
+     */
+    public static FilterDTO build(final FilterInfo info, final boolean failed)
     {
-        FilterInfo info = filterRuntime.getFilterInfo();
+        final FilterDTO filterDTO = (failed ? new FailedFilterDTO() : new FilterDTO());
 
-        T filterDTO = getDTOFactory().get();
         filterDTO.asyncSupported = info.isAsyncSupported();
         filterDTO.dispatcher = getNames(info.getDispatcher());
         filterDTO.initParams = info.getInitParameters();
         filterDTO.name = info.getName();
-        filterDTO.patterns = copyWithDefault(info.getPatterns(), BuilderConstants.STRING_ARRAY);
-        filterDTO.regexs = copyWithDefault(info.getRegexs(), BuilderConstants.STRING_ARRAY);
+        filterDTO.patterns = BuilderConstants.copyWithDefault(info.getPatterns(), BuilderConstants.EMPTY_STRING_ARRAY);
+        filterDTO.regexs = BuilderConstants.copyWithDefault(info.getRegexs(), BuilderConstants.EMPTY_STRING_ARRAY);
         filterDTO.serviceId = info.getServiceId();
-        filterDTO.servletContextId = servletContextId;
-        filterDTO.servletNames = copyWithDefault(info.getServletNames(), BuilderConstants.STRING_ARRAY);
+        filterDTO.servletNames = BuilderConstants.copyWithDefault(info.getServletNames(), BuilderConstants.EMPTY_STRING_ARRAY);
+
+        return filterDTO;
+    }
+
+    /**
+     * Build a filter failed DTO from a filter handler
+     * @param handler The filter handler
+     * @return A filter DTO
+     */
+    public static FailedFilterDTO buildFailed(final FilterHandler handler, final int reason)
+    {
+        final FailedFilterDTO filterDTO = (FailedFilterDTO)build(handler.getFilterInfo(), true);
+
+        filterDTO.name = handler.getName();
+        filterDTO.servletContextId = handler.getContextServiceId();
+        filterDTO.failureReason = reason;
 
         return filterDTO;
     }
 
-    private String[] getNames(DispatcherType[] dispatcher)
+    private static String[] getNames(final DispatcherType[] dispatcher)
     {
         if (dispatcher == null)
         {
-            return BuilderConstants.STRING_ARRAY;
+            return BuilderConstants.EMPTY_STRING_ARRAY;
         }
 
         String[] names = new String[dispatcher.length];

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java Tue May 19 13:50:39 2015
@@ -18,30 +18,67 @@
  */
 package org.apache.felix.http.base.internal.runtime.dto;
 
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionIdListener;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.felix.http.base.internal.runtime.ListenerInfo;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.runtime.dto.FailedListenerDTO;
 import org.osgi.service.http.runtime.dto.ListenerDTO;
 
-final class ListenerDTOBuilder<T extends ListenerDTO> extends BaseDTOBuilder<ServiceReference<?>, T>
+public final class ListenerDTOBuilder
 {
-    static ListenerDTOBuilder<ListenerDTO> create()
-    {
-        return new ListenerDTOBuilder<ListenerDTO>(DTOFactories.LISTENER);
+    private static final Set<String> ALLOWED_INTERFACES;
+    static {
+        ALLOWED_INTERFACES = new HashSet<String>();
+        ALLOWED_INTERFACES.add(HttpSessionAttributeListener.class.getName());
+        ALLOWED_INTERFACES.add(HttpSessionIdListener.class.getName());
+        ALLOWED_INTERFACES.add(HttpSessionListener.class.getName());
+        ALLOWED_INTERFACES.add(ServletContextAttributeListener.class.getName());
+        ALLOWED_INTERFACES.add(ServletContextListener.class.getName());
+        ALLOWED_INTERFACES.add(ServletRequestAttributeListener.class.getName());
+        ALLOWED_INTERFACES.add(ServletRequestListener.class.getName());
     }
 
-    ListenerDTOBuilder(DTOFactory<T> dtoFactory)
+    public static ListenerDTO build(final ListenerInfo<?> info, final int reason)
     {
-        super(dtoFactory);
+        final ListenerDTO dto = (reason == -1 ? new ListenerDTO() : new FailedListenerDTO());
+
+        dto.serviceId = info.getServiceId();
+
+        if ( reason != -1 )
+        {
+            ((FailedListenerDTO)dto).failureReason = reason;
+        }
+
+        return dto;
     }
 
-    @Override
-    T buildDTO(ServiceReference<?> listenerRef, long servletContextId)
+    public static ListenerDTO build(final ServiceReference<?> listenerRef, final long servletContextId)
     {
-        T listenerDTO = getDTOFactory().get();
+        final ListenerDTO listenerDTO = new ListenerDTO();
         listenerDTO.serviceId = (Long) listenerRef.getProperty(Constants.SERVICE_ID);
         listenerDTO.servletContextId = servletContextId;
-        // TODO Is this the desired value?
-        listenerDTO.types = (String[]) listenerRef.getProperty(Constants.OBJECTCLASS);
+
+        final String[] objectClass = (String[])listenerRef.getProperty(Constants.OBJECTCLASS);
+        final Set<String> names = new HashSet<String>();
+        for(final String name : objectClass)
+        {
+            if ( ALLOWED_INTERFACES.contains(name) )
+            {
+                names.add(name);
+            }
+        }
+        listenerDTO.types = names.toArray(new String[names.size()]);
         return listenerDTO;
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java Tue May 19 13:50:39 2015
@@ -20,25 +20,27 @@ package org.apache.felix.http.base.inter
 
 import java.util.Collection;
 
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
+
 public final class RegistryRuntime
 {
-    private final Collection<ServletContextHelperRuntime> contexts;
-    private final FailureRuntime failureRuntime;
+    private final Collection<ServletContextDTO> contextDTOs;
+    private final FailedDTOHolder failedDTOHolder;
 
-    public RegistryRuntime(Collection<ServletContextHelperRuntime> contexts,
-            FailureRuntime failureRuntime)
+    public RegistryRuntime(final FailedDTOHolder failedDTOHolder,
+            final Collection<ServletContextDTO> contextDTOs)
     {
-        this.contexts = contexts;
-        this.failureRuntime = failureRuntime;
+        this.failedDTOHolder = failedDTOHolder;
+        this.contextDTOs = contextDTOs;
     }
 
-    public Collection<ServletContextHelperRuntime> getContexts()
+    public FailedDTOHolder getFailedDTOHolder()
     {
-        return contexts;
+        return this.failedDTOHolder;
     }
 
-    public FailureRuntime getFailureRuntime()
+    public Collection<ServletContextDTO> getServletContextDTOs()
     {
-        return failureRuntime;
+        return this.contextDTOs;
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java Tue May 19 13:50:39 2015
@@ -16,12 +16,9 @@
  */
 package org.apache.felix.http.base.internal.runtime.dto;
 
-import static java.util.Arrays.asList;
-
 import org.apache.felix.http.base.internal.handler.FilterHandler;
 import org.apache.felix.http.base.internal.registry.HandlerRegistry;
 import org.apache.felix.http.base.internal.registry.PathResolution;
-import org.apache.felix.http.base.internal.runtime.dto.state.ServletState;
 import org.osgi.service.http.runtime.dto.FilterDTO;
 import org.osgi.service.http.runtime.dto.RequestInfoDTO;
 
@@ -53,24 +50,17 @@ public final class RequestInfoDTOBuilder
         requestInfoDTO.servletContextId = pr.handler.getContextServiceId();
         if (pr.handler.getServletInfo().isResource())
         {
-            final ServletState state = new ServletState(pr.handler);
-            state.setPatterns(pr.handler.getServletInfo().getPatterns());
-            requestInfoDTO.resourceDTO = ResourceDTOBuilder.create()
-                    .buildDTO(state,
-                            pr.handler.getContextServiceId());
+            requestInfoDTO.resourceDTO = ResourceDTOBuilder.build(pr.handler, -1);
+            requestInfoDTO.resourceDTO.patterns = pr.handler.getServletInfo().getPatterns();
         }
         else
         {
-            final ServletState state = new ServletState(pr.handler);
-            state.setPatterns(pr.handler.getServletInfo().getPatterns());
-            requestInfoDTO.servletDTO = ServletDTOBuilder.create()
-                    .buildDTO(state, pr.handler.getContextServiceId());
+            requestInfoDTO.servletDTO = ServletDTOBuilder.build(pr.handler, -1);
+            requestInfoDTO.servletDTO.patterns = pr.handler.getServletInfo().getPatterns();
         }
 
         final FilterHandler[] filterHandlers = registry.getFilters(pr, null, path);
-        requestInfoDTO.filterDTOs = FilterDTOBuilder.create()
-                .build(asList(filterHandlers), pr.handler.getContextServiceId())
-                .toArray(FILTER_DTO_ARRAY);
+        requestInfoDTO.filterDTOs = FilterDTOBuilder.build(filterHandlers);
 
         return requestInfoDTO;
     }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java Tue May 19 13:50:39 2015
@@ -18,50 +18,63 @@
  */
 package org.apache.felix.http.base.internal.runtime.dto;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
+import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.runtime.ResourceInfo;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.dto.state.ServletState;
+import org.osgi.service.http.runtime.dto.FailedResourceDTO;
 import org.osgi.service.http.runtime.dto.ResourceDTO;
 
-final class ResourceDTOBuilder<T extends ResourceDTO> extends BaseDTOBuilder<ServletState, T>
+public final class ResourceDTOBuilder
 {
-    static ResourceDTOBuilder<ResourceDTO> create()
+    /**
+     * Build a servlet DTO from a servlet handler
+     * @param handler The servlet handler
+     * @param reason If reason is -1, a servlet DTO is created, otherwise a failed servlet DTO is returned
+     * @return A servlet DTO
+     */
+    public static ResourceDTO build(final ServletHandler handler, final int reason)
     {
-        return new ResourceDTOBuilder<ResourceDTO>(DTOFactories.RESOURCE);
-    }
+        final ResourceDTO dto = build(handler.getServletInfo(), reason != -1);
 
-    ResourceDTOBuilder(DTOFactory<T> dtoFactory)
-    {
-        super(dtoFactory);
-    }
+        dto.servletContextId = handler.getContextServiceId();
 
-    @Override
-    Collection<T> build(Collection<? extends ServletState> whiteboardServices,
-            long servletContextId) {
-        List<T> dtoList = new ArrayList<T>();
-        for (ServletState whiteboardService : whiteboardServices)
+        if ( reason != -1 )
         {
-            if ( whiteboardService.getPatterns().length > 0 && whiteboardService.getServletInfo().isResource() )
-            {
-                dtoList.add(buildDTO(whiteboardService, servletContextId));
-            }
+            ((FailedResourceDTO)dto).failureReason = reason;
         }
-        return dtoList;
+
+        return dto;
     }
 
-    @Override
-    T buildDTO(ServletState runtime, long servletContextId)
+    /**
+     * Build a servlet DTO from a servlet info
+     * @param info The servlet info
+     * @return A servlet DTO
+     */
+    public static ResourceDTO build(final ServletInfo info, final boolean failed)
     {
-        ServletInfo servletInfo = runtime.getServletInfo();
+        final ResourceDTO dto = (failed ? new FailedResourceDTO() : new ResourceDTO());
+
+        dto.patterns = BuilderConstants.EMPTY_STRING_ARRAY;
+        dto.prefix = info.getPrefix();
+        dto.serviceId = info.getServiceId();
+
+        return dto;
+    }
+
+    /**
+     * Build a servlet DTO from a servlet info
+     * @param info The servlet info
+     * @return A servlet DTO
+     */
+    public static ResourceDTO build(final ResourceInfo info, final boolean failed)
+    {
+        final ResourceDTO dto = (failed ? new FailedResourceDTO() : new ResourceDTO());
+
+        dto.patterns = BuilderConstants.copyWithDefault(info.getPatterns(), BuilderConstants.EMPTY_STRING_ARRAY);
+        dto.prefix = info.getPrefix();
+        dto.serviceId = info.getServiceId();
 
-        T resourceDTO = getDTOFactory().get();
-        resourceDTO.patterns = copyWithDefault(servletInfo.getPatterns(), BuilderConstants.STRING_ARRAY);
-        resourceDTO.prefix = servletInfo.getPrefix();
-        resourceDTO.serviceId = servletInfo.getServiceId();
-        resourceDTO.servletContextId = servletContextId;
-        return resourceDTO;
+        return dto;
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java Tue May 19 13:50:39 2015
@@ -27,13 +27,14 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.dto.ServiceReferenceDTO;
 import org.osgi.service.http.runtime.HttpServiceRuntime;
-import org.osgi.service.http.runtime.dto.ErrorPageDTO;
-import org.osgi.service.http.runtime.dto.FilterDTO;
-import org.osgi.service.http.runtime.dto.ListenerDTO;
-import org.osgi.service.http.runtime.dto.ResourceDTO;
+import org.osgi.service.http.runtime.dto.FailedErrorPageDTO;
+import org.osgi.service.http.runtime.dto.FailedFilterDTO;
+import org.osgi.service.http.runtime.dto.FailedListenerDTO;
+import org.osgi.service.http.runtime.dto.FailedResourceDTO;
+import org.osgi.service.http.runtime.dto.FailedServletContextDTO;
+import org.osgi.service.http.runtime.dto.FailedServletDTO;
 import org.osgi.service.http.runtime.dto.RuntimeDTO;
 import org.osgi.service.http.runtime.dto.ServletContextDTO;
-import org.osgi.service.http.runtime.dto.ServletDTO;
 
 public final class RuntimeDTOBuilder
 {
@@ -49,16 +50,14 @@ public final class RuntimeDTOBuilder
 
     public RuntimeDTO build()
     {
-        final FailureRuntime failureRuntime = registry.getFailureRuntime();
-
         final RuntimeDTO runtimeDTO = new RuntimeDTO();
         runtimeDTO.serviceDTO = createServiceDTO();
-        runtimeDTO.failedErrorPageDTOs = failureRuntime.getErrorPageDTOs();
-        runtimeDTO.failedFilterDTOs = failureRuntime.getFilterDTOs();
-        runtimeDTO.failedListenerDTOs = failureRuntime.getListenerDTOs();
-        runtimeDTO.failedResourceDTOs = failureRuntime.getResourceDTOs();
-        runtimeDTO.failedServletContextDTOs = failureRuntime.getServletContextDTOs();
-        runtimeDTO.failedServletDTOs = failureRuntime.getServletDTOs();
+        runtimeDTO.failedErrorPageDTOs = registry.getFailedDTOHolder().failedErrorPageDTOs.toArray(new FailedErrorPageDTO[registry.getFailedDTOHolder().failedErrorPageDTOs.size()]);
+        runtimeDTO.failedFilterDTOs = registry.getFailedDTOHolder().failedFilterDTOs.toArray(new FailedFilterDTO[registry.getFailedDTOHolder().failedFilterDTOs.size()]);
+        runtimeDTO.failedListenerDTOs = registry.getFailedDTOHolder().failedListenerDTOs.toArray(new FailedListenerDTO[registry.getFailedDTOHolder().failedListenerDTOs.size()]);
+        runtimeDTO.failedResourceDTOs = registry.getFailedDTOHolder().failedResourceDTOs.toArray(new FailedResourceDTO[registry.getFailedDTOHolder().failedResourceDTOs.size()]);
+        runtimeDTO.failedServletContextDTOs = registry.getFailedDTOHolder().failedServletContextDTO.toArray(new FailedServletContextDTO[registry.getFailedDTOHolder().failedServletContextDTO.size()]);
+        runtimeDTO.failedServletDTOs = registry.getFailedDTOHolder().failedServletDTOs.toArray(new FailedServletDTO[registry.getFailedDTOHolder().failedServletDTOs.size()]);
         runtimeDTO.servletContextDTOs = createContextDTOs();
         return runtimeDTO;
     }
@@ -94,36 +93,7 @@ public final class RuntimeDTOBuilder
 
     private ServletContextDTO[] createContextDTOs()
     {
-        final Collection<ServletContextHelperRuntime> contexts = registry.getContexts();
-        final ServletContextDTO[] result = new ServletContextDTO[contexts.size()];
-        int index = 0;
-        for (final ServletContextHelperRuntime context : contexts)
-        {
-            result[index++] = createContextDTO(context,
-                    context.getContextRuntime(),
-                    context.getListeners());
-        }
-        return result;
-    }
-
-    private ServletContextDTO createContextDTO(final ServletContextHelperRuntime context,
-            final ContextRuntime contextRuntime,
-            final Collection<ServiceReference<?>> listenerRuntimes)
-    {
-        final long servletContextId = context.getContextInfo().getServiceId();
-
-        Collection<ServletDTO> servletDTOs = ServletDTOBuilder.create().build(contextRuntime.getServletRuntimes(), servletContextId);
-        Collection<ResourceDTO> resourceDTOs = ResourceDTOBuilder.create().build(contextRuntime.getServletRuntimes(), servletContextId);
-        Collection<FilterDTO> filterDTOs = FilterDTOBuilder.create().build(contextRuntime.getFilterRuntimes(), servletContextId);
-        Collection<ErrorPageDTO> errorDTOs = ErrorPageDTOBuilder.create().build(contextRuntime.getServletRuntimes(), servletContextId);
-        Collection<ListenerDTO> listenerDTOs = ListenerDTOBuilder.create().build(listenerRuntimes, servletContextId);
-
-        return new ServletContextDTOBuilder(context,
-                    servletDTOs,
-                    resourceDTOs,
-                    filterDTOs,
-                    errorDTOs,
-                    listenerDTOs)
-                .build();
+        final Collection<ServletContextDTO> contexts = registry.getServletContextDTOs();
+        return contexts.toArray(new ServletContextDTO[contexts.size()]);
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java?rev=1680291&r1=1680290&r2=1680291&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java Tue May 19 13:50:39 2015
@@ -20,7 +20,6 @@ package org.apache.felix.http.base.inter
 
 import static java.util.Collections.list;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -29,82 +28,30 @@ import javax.servlet.ServletContext;
 
 import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
 import org.osgi.dto.DTO;
-import org.osgi.service.http.runtime.dto.ErrorPageDTO;
-import org.osgi.service.http.runtime.dto.FilterDTO;
-import org.osgi.service.http.runtime.dto.ListenerDTO;
-import org.osgi.service.http.runtime.dto.ResourceDTO;
+import org.osgi.service.http.runtime.dto.FailedServletContextDTO;
 import org.osgi.service.http.runtime.dto.ServletContextDTO;
-import org.osgi.service.http.runtime.dto.ServletDTO;
 
-final class ServletContextDTOBuilder
+public final class ServletContextDTOBuilder
 {
 
-    private final ServletContextDTO contextDTO;
-    private final ServletContextHelperRuntime contextRuntime;
-    private final ServletDTO[] servletDTOs;
-    private final ResourceDTO[] resourceDTOs;
-    private final FilterDTO[] filterDTOs;
-    private final ErrorPageDTO[] errorPageDTOs;
-    private final ListenerDTO[] listenerDTOs;
-
-    ServletContextDTOBuilder(ServletContextDTO contextDTO,
-            ServletContextHelperRuntime contextRuntime,
-            Collection<ServletDTO> servletDTOs,
-            Collection<ResourceDTO> resourceDTOs,
-            Collection<FilterDTO> filterDTOs,
-            Collection<ErrorPageDTO> errorPageDTOs,
-            Collection<ListenerDTO> listenerDTOs)
+    public static ServletContextDTO build(final ServletContextHelperInfo info, final ServletContext context, final int reason)
     {
-        this.contextDTO = contextDTO;
-        this.contextRuntime = contextRuntime;
-        this.servletDTOs = servletDTOs != null ?
-                servletDTOs.toArray(BuilderConstants.SERVLET_DTO_ARRAY) : BuilderConstants.SERVLET_DTO_ARRAY;
-        this.resourceDTOs = resourceDTOs != null ?
-                resourceDTOs.toArray(BuilderConstants.RESOURCE_DTO_ARRAY) : BuilderConstants.RESOURCE_DTO_ARRAY;
-        this.filterDTOs = filterDTOs != null ?
-                filterDTOs.toArray(BuilderConstants.FILTER_DTO_ARRAY) : BuilderConstants.FILTER_DTO_ARRAY;
-        this.errorPageDTOs = errorPageDTOs != null ?
-                errorPageDTOs.toArray(BuilderConstants.ERROR_PAGE_DTO_ARRAY) : BuilderConstants.ERROR_PAGE_DTO_ARRAY;
-        this.listenerDTOs = listenerDTOs != null ?
-                listenerDTOs.toArray(BuilderConstants.LISTENER_DTO_ARRAY) : BuilderConstants.LISTENER_DTO_ARRAY;
-    }
-
-    ServletContextDTOBuilder(ServletContextHelperRuntime contextRuntime,
-            Collection<ServletDTO> servletDTOs,
-            Collection<ResourceDTO> resourceDTOs,
-            Collection<FilterDTO> filterDTOs,
-            Collection<ErrorPageDTO> errorPageDTOs,
-            Collection<ListenerDTO> listenerDTOs)
-    {
-        this(new ServletContextDTO(), contextRuntime, servletDTOs, resourceDTOs, filterDTOs, errorPageDTOs, listenerDTOs);
-    }
-
-    ServletContextDTOBuilder(ServletContextDTO contextDTO, ServletContextHelperRuntime contextRuntime)
-    {
-        this(contextDTO, contextRuntime, null, null, null, null, null);
-    }
+        final ServletContextDTO dto = (reason == -1 ? new ServletContextDTO() : new FailedServletContextDTO());
 
-    ServletContextDTO build()
-    {
-        final ServletContext context  = contextRuntime.getSharedContext();
-        final ServletContextHelperInfo contextInfo = contextRuntime.getContextInfo();
-        final long contextId = contextInfo.getServiceId();
-
-        contextDTO.attributes = getAttributes(context);
-        contextDTO.contextPath = context != null ? context.getContextPath() : contextInfo.getPath();
-        contextDTO.errorPageDTOs = errorPageDTOs;
-        contextDTO.filterDTOs = filterDTOs;
-        contextDTO.initParams = contextInfo.getInitParameters();
-        contextDTO.listenerDTOs = listenerDTOs;
-        contextDTO.name = contextInfo.getName();
-        contextDTO.resourceDTOs = resourceDTOs;
-        contextDTO.servletDTOs = servletDTOs;
-        contextDTO.serviceId = contextId;
+        dto.attributes = getAttributes(context);
+        dto.contextPath = context != null ? context.getContextPath() : info.getPath();
+        dto.initParams = info.getInitParameters();
+        dto.name = info.getName();
+        dto.serviceId = info.getServiceId();
 
-        return contextDTO;
+        if ( reason != -1 )
+        {
+            ((FailedServletContextDTO)dto).failureReason = reason;
+        }
+        return dto;
     }
 
-    private Map<String, Object> getAttributes(ServletContext context)
+    private static Map<String, Object> getAttributes(final ServletContext context)
     {
         if (context == null)
         {
@@ -123,7 +70,7 @@ final class ServletContextDTOBuilder
         return attributes;
     }
 
-    private boolean isSupportedType(Object attribute)
+    private static boolean isSupportedType(Object attribute)
     {
         Class<?> attributeClass = attribute.getClass();
         Class<?> type = !attributeClass.isArray() ?