FELIX-4546 - Implement HttpServiceRuntime service
- applied the patch from ThomasB.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1669088 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java
index 39bfc7a..e8b545b 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ErrorsMapping.java
@@ -16,7 +16,7 @@
*/
package org.apache.felix.http.base.internal.handler;
-import static org.apache.felix.http.base.internal.util.CollectionUtils.union;
+import static org.apache.felix.http.base.internal.util.CollectionUtils.sortedUnion;
import java.util.ArrayList;
import java.util.Collection;
@@ -30,7 +30,7 @@
import javax.servlet.Servlet;
import javax.servlet.ServletException;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.ErrorPageRuntime;
public final class ErrorsMapping
{
@@ -126,14 +126,14 @@
@SuppressWarnings("unchecked")
public Collection<ServletHandler> getMappedHandlers()
{
- return union(errorCodesMap.values(), exceptionsMap.values());
+ return sortedUnion(errorCodesMap.values(), exceptionsMap.values());
}
- public HandlerRuntime.ErrorPage getErrorPage(ServletHandler servletHandler)
+ public ErrorPageRuntime getErrorPage(ServletHandler servletHandler)
{
Collection<Integer> errorCodes = getCopy(servletHandler, invertedErrorCodesMap);
Collection<String> exceptions = getCopy(servletHandler, invertedExceptionsMap);
- return new HandlerRuntime.ErrorPage(servletHandler, errorCodes, exceptions);
+ return new ErrorPageRuntime(servletHandler, errorCodes, exceptions);
}
private static <T> List<T> getCopy(ServletHandler key, Map<Servlet, Collection<T>> map)
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
index c7b0e6c..951c2ec 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
@@ -33,9 +33,10 @@
import org.apache.felix.http.base.internal.context.ExtServletContext;
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.dto.FilterRuntime;
import org.apache.felix.http.base.internal.util.PatternUtil;
-public final class FilterHandler extends AbstractHandler<FilterHandler>
+public final class FilterHandler extends AbstractHandler<FilterHandler> implements FilterRuntime
{
private final Filter filter;
private final FilterInfo filterInfo;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
index 58002db..e872de1 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
@@ -24,8 +24,9 @@
import javax.annotation.Nonnull;
import javax.servlet.DispatcherType;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.FailureRuntime;
import org.osgi.framework.BundleContext;
/**
@@ -225,12 +226,12 @@
return null;
}
- public synchronized List<HandlerRuntime> getRuntime()
+ public synchronized List<ContextRuntime> getRuntime(FailureRuntime.Builder failureRuntimeBuilder)
{
- List<HandlerRuntime> handlerRuntimes = new ArrayList<HandlerRuntime>();
+ List<ContextRuntime> handlerRuntimes = new ArrayList<ContextRuntime>();
for (PerContextHandlerRegistry contextRegistry : this.registrations)
{
- handlerRuntimes.add(contextRegistry.getRuntime());
+ handlerRuntimes.add(contextRegistry.getRuntime(failureRuntimeBuilder));
}
return handlerRuntimes;
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
index e7b3a22..3ead1b6 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
@@ -16,6 +16,10 @@
*/
package org.apache.felix.http.base.internal.handler;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SERVICE_ALREAY_USED;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -23,6 +27,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
@@ -35,30 +40,32 @@
import javax.servlet.Servlet;
import javax.servlet.ServletException;
-import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime.ErrorPage;
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.service.ResourceServlet;
+import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.ErrorPageRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.FailureRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.FilterRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.ServletRuntime;
+import org.apache.felix.http.base.internal.whiteboard.ResourceServlet;
import org.apache.felix.http.base.internal.util.PatternUtil;
-import org.apache.felix.http.base.internal.whiteboard.ContextHandler;
+import org.apache.felix.http.base.internal.whiteboard.RegistrationFailureException;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceObjects;
public final class PerContextHandlerRegistry implements Comparable<PerContextHandlerRegistry>
{
- private final BundleContext bundleContext;
+ private final BundleContext bundleContext;
private final Map<Filter, FilterHandler> filterMap = new HashMap<Filter, FilterHandler>();
private volatile HandlerMapping<ServletHandler> servletMapping = new HandlerMapping<ServletHandler>();
private volatile HandlerMapping<FilterHandler> filterMapping = new HandlerMapping<FilterHandler>();
private final ErrorsMapping errorsMapping = new ErrorsMapping();
-
- private SortedMap<Pattern, SortedSet<ServletHandler>> patternToServletHandler = new TreeMap<Pattern, SortedSet<ServletHandler>>(PatternUtil.PatternComparator.INSTANCE);
- private Map<ServletHandler, Integer> servletHandlerToUses = new HashMap<ServletHandler, Integer>();
+
+ private final SortedMap<Pattern, SortedSet<ServletHandler>> patternToServletHandler = new TreeMap<Pattern, SortedSet<ServletHandler>>(PatternUtil.PatternComparator.INSTANCE);
+ private final Map<ServletHandler, Integer> servletHandlerToUses = new HashMap<ServletHandler, Integer>();
private final SortedSet<ServletHandler> allServletHandlers = new TreeSet<ServletHandler>();
private final long serviceId;
@@ -69,7 +76,8 @@
private final String prefix;
- public PerContextHandlerRegistry(BundleContext bundleContext) {
+ public PerContextHandlerRegistry(BundleContext bundleContext)
+ {
this.serviceId = 0;
this.ranking = Integer.MAX_VALUE;
this.path = "/";
@@ -83,22 +91,22 @@
this.ranking = info.getRanking();
this.path = info.getPath();
this.bundleContext = bundleContext;
- if ( this.path.equals("/") )
+ if (this.path.equals("/"))
{
- prefix = null;
+ prefix = null;
}
else
{
- prefix = this.path + "/";
+ prefix = this.path + "/";
}
}
public synchronized void addFilter(FilterHandler handler) throws ServletException
{
- if(this.filterMapping.contains(handler))
- {
- throw new ServletException("Filter instance already registered");
- }
+ if (this.filterMapping.contains(handler))
+ {
+ throw new RegistrationFailureException(handler.getFilterInfo(), FAILURE_REASON_SERVICE_ALREAY_USED, "Filter instance " + handler.getName() + " already registered");
+ }
handler.init();
this.filterMapping = this.filterMapping.add(handler);
@@ -109,11 +117,12 @@
public int compareTo(final PerContextHandlerRegistry other)
{
final int result = Integer.compare(other.path.length(), this.path.length());
- if ( result == 0 ) {
+ if (result == 0)
+ {
if (this.ranking == other.ranking)
{
// Service id's can be negative. Negative id's follow the reverse natural ordering of integers.
- int reverseOrder = ( this.serviceId >= 0 && other.serviceId >= 0 ) ? 1 : -1;
+ int reverseOrder = (this.serviceId >= 0 && other.serviceId >= 0) ? 1 : -1;
return reverseOrder * Long.compare(this.serviceId, other.serviceId);
}
@@ -127,63 +136,64 @@
*/
public synchronized void addServlet(final ServletHandler handler) throws ServletException
{
- Pattern[] patterns = handler.getPatterns();
- String[] errorPages = handler.getServletInfo().getErrorPage();
-
- if(patterns.length > 0 && errorPages != null)
- {
- throw new ServletException("Servlet instance " + handler.getName() + " has both patterns and errorPage set");
- }
-
- SortedMap<Pattern, ServletHandler> toAdd = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
- SortedMap<Pattern, ServletHandler> toRemove = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
-
- this.servletHandlerToUses.put(handler, new Integer(0));
-
- for (Pattern p : patterns)
- {
- ServletHandler prevHandler = null;
+ Pattern[] patterns = handler.getPatterns();
+ String[] errorPages = handler.getServletInfo().getErrorPage();
- if( !this.patternToServletHandler.containsKey(p))
- {
- this.patternToServletHandler.put(p, new TreeSet<ServletHandler>());
- }
- else
- {
- prevHandler = this.patternToServletHandler.get(p).first();
- }
-
- this.patternToServletHandler.get(p).add(handler);
-
- if ( handler.equals(this.patternToServletHandler.get(p).first()))
+ if (patterns.length > 0 && errorPages != null)
+ {
+ throw new ServletException("Servlet instance " + handler.getName() + " has both patterns and errorPage set");
+ }
+
+ SortedMap<Pattern, ServletHandler> toAdd = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
+ SortedMap<Pattern, ServletHandler> toRemove = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
+
+ this.servletHandlerToUses.put(handler, new Integer(0));
+
+ for (Pattern p : patterns)
+ {
+ ServletHandler prevHandler = null;
+
+ if (!this.patternToServletHandler.containsKey(p))
{
- useServletHandler(handler);
- if (!handler.isWhiteboardService())
- {
- handler.init();
- }
- increaseUseCount(handler);
-
- if (prevHandler != null)
- {
- decreaseUseCount(prevHandler);
- toRemove.put(p, prevHandler);
- }
- toAdd.put(p, handler);
+ this.patternToServletHandler.put(p, new TreeSet<ServletHandler>());
}
- }
-
- this.servletMapping = this.servletMapping.remove(toRemove);
- this.servletMapping = this.servletMapping.add(toAdd);
- this.allServletHandlers.add(handler);
-
- if(errorPages != null)
- {
- for(String errorPage : errorPages)
- {
- this.errorsMapping.addErrorServlet(errorPage, handler);
- }
- }
+ else
+ {
+ prevHandler = this.patternToServletHandler.get(p).first();
+ }
+
+ this.patternToServletHandler.get(p).add(handler);
+
+ if (handler.equals(this.patternToServletHandler.get(p).first()))
+ {
+ useServletHandler(handler);
+ if (!handler.isWhiteboardService())
+ {
+ handler.init();
+ }
+ increaseUseCount(handler);
+
+ if (prevHandler != null)
+ {
+ decreaseUseCount(prevHandler);
+ toRemove.put(p, prevHandler);
+ }
+ toAdd.put(p, handler);
+ }
+ }
+
+ this.servletMapping = this.servletMapping.remove(toRemove);
+ this.servletMapping = this.servletMapping.add(toAdd);
+ this.allServletHandlers.add(handler);
+
+ if (errorPages != null)
+ {
+ for (String errorPage : errorPages)
+ {
+ useServletHandler(handler);
+ this.errorsMapping.addErrorServlet(errorPage, handler);
+ }
+ }
}
/**
@@ -194,80 +204,83 @@
* @param handler
* @throws ServletException
*/
- private void useServletHandler(ServletHandler handler) throws ServletException
+ private void useServletHandler(ServletHandler handler) throws ServletException
{
- if( (!handler.isWhiteboardService()) || (handler.getServlet() != null) )
- {
- return;
- }
-
- // isWhiteboardService && servlet == null
- boolean isResource = handler.getServletInfo().isResource();
- final ServiceObjects<Servlet> so = this.bundleContext.getServiceObjects(handler.getServletInfo().getServiceReference());
-
- Servlet servlet = getServiceObject(so, handler, isResource);
- handler.setServlet(servlet);
-
- try {
- handler.init();
- } catch (ServletException e) {
- ungetServiceObject(so, servlet, isResource);
- throw e;
- }
- }
-
- private Servlet getServiceObject(ServiceObjects<Servlet> so, ServletHandler handler, boolean isResource)
- {
- if(isResource)
- {
- return new ResourceServlet(handler.getServletInfo().getPrefix());
- }
- if(so != null)
- {
- return so.getService();
- }
- return null;
- }
-
- private void ungetServiceObject(ServiceObjects<Servlet> so, Servlet servlet, boolean isResource)
- {
- if(isResource || (so == null))
- {
- return;
- }
- so.ungetService(servlet);
- }
+ if ((!handler.isWhiteboardService()) || (handler.getServlet() != null))
+ {
+ return;
+ }
- private void increaseUseCount(ServletHandler handler)
- {
- Integer uses = this.servletHandlerToUses.get(handler);
- if(uses != null)
- {
- int newUsesValue = uses.intValue() + 1;
- this.servletHandlerToUses.put(handler, new Integer(newUsesValue));
- }
- }
-
- private void decreaseUseCount(@Nonnull ServletHandler handler)
- {
- Integer uses = this.servletHandlerToUses.get(handler);
- if(uses != null)
- {
- int newUsesValue = uses.intValue() - 1;
- if(newUsesValue == 0 && handler.isWhiteboardService())
- {
- // if the servlet is no longer used and it is registered as a whiteboard service
- // call destroy, unget the service object and set the servlet in the handler to null
- handler.destroy();
- ServiceObjects<Servlet> so = this.bundleContext.getServiceObjects(handler.getServletInfo().getServiceReference());
- ungetServiceObject(so, handler.getServlet(), handler.getServletInfo().isResource());
- handler.setServlet(null);
- }
- this.servletHandlerToUses.put(handler, new Integer(newUsesValue));
- }
- }
+ // isWhiteboardService && servlet == null
+ boolean isResource = handler.getServletInfo().isResource();
+ final ServiceObjects<Servlet> so = this.bundleContext.getServiceObjects(handler.getServletInfo().getServiceReference());
- public ErrorsMapping getErrorsMapping()
+ Servlet servlet = getServiceObject(so, handler, isResource);
+ handler.setServlet(servlet);
+
+ try
+ {
+ handler.init();
+ }
+ catch (ServletException e)
+ {
+ ungetServiceObject(so, servlet, isResource);
+ throw e;
+ }
+ }
+
+ private Servlet getServiceObject(ServiceObjects<Servlet> so, ServletHandler handler, boolean isResource)
+ {
+ if (isResource)
+ {
+ return new ResourceServlet(handler.getServletInfo().getPrefix());
+ }
+ if (so != null)
+ {
+ return so.getService();
+ }
+ return null;
+ }
+
+ private void ungetServiceObject(ServiceObjects<Servlet> so, Servlet servlet, boolean isResource)
+ {
+ if (isResource || (so == null))
+ {
+ return;
+ }
+ so.ungetService(servlet);
+ }
+
+ private void increaseUseCount(ServletHandler handler)
+ {
+ Integer uses = this.servletHandlerToUses.get(handler);
+ if (uses != null)
+ {
+ int newUsesValue = uses.intValue() + 1;
+ this.servletHandlerToUses.put(handler, new Integer(newUsesValue));
+ }
+ }
+
+ private void decreaseUseCount(@Nonnull ServletHandler handler)
+ {
+ Integer uses = this.servletHandlerToUses.get(handler);
+ if (uses != null)
+ {
+ int newUsesValue = uses.intValue() - 1;
+ if (newUsesValue == 0 && handler.isWhiteboardService())
+ {
+ // if the servlet is no longer used and it is registered as a whiteboard service
+ // call destroy, unget the service object and set the servlet in the handler to null
+ handler.destroy();
+ ServiceObjects<Servlet> so = this.bundleContext.getServiceObjects(handler.getServletInfo().getServiceReference());
+ ungetServiceObject(so, handler.getServlet(), handler.getServletInfo().isResource());
+ handler.setServlet(null);
+ }
+ this.servletHandlerToUses.put(handler, new Integer(newUsesValue));
+ }
+ }
+
+ public ErrorsMapping getErrorsMapping()
{
return this.errorsMapping;
}
@@ -300,10 +313,10 @@
// TODO - we should already check for the context when building up the result set
final Iterator<FilterHandler> i = result.iterator();
- while ( i.hasNext() )
+ while (i.hasNext())
{
final FilterHandler handler = i.next();
- if ( handler.getContextServiceId() != servletHandler.getContextServiceId() )
+ if (handler.getContextServiceId() != servletHandler.getContextServiceId())
{
i.remove();
}
@@ -378,105 +391,107 @@
private FilterHandler getFilterHandler(final FilterInfo filterInfo)
{
- for(final FilterHandler handler : this.filterMap.values())
+ for (final FilterHandler handler : this.filterMap.values())
{
- if ( handler.getFilterInfo().compareTo(filterInfo) == 0)
+ if (handler.getFilterInfo().compareTo(filterInfo) == 0)
{
return handler;
}
}
return null;
}
-
- public synchronized Servlet removeServlet(ServletInfo servletInfo, final boolean destroy)
+
+ public synchronized Servlet removeServlet(ServletInfo servletInfo, final boolean destroy) throws RegistrationFailureException
{
- ServletHandler handler = getServletHandler(servletInfo);
-
- Pattern[] patterns = (handler == null) ? new Pattern[0] : handler.getPatterns();
- SortedMap<Pattern, ServletHandler> toAdd = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
- SortedMap<Pattern, ServletHandler> toRemove = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
+ ServletHandler handler = getServletHandler(servletInfo);
- for(Pattern p : patterns)
- {
- SortedSet<ServletHandler> handlers = this.patternToServletHandler.get(p);
- if(handlers != null && (!handlers.isEmpty()))
- {
- if(handlers.first().equals(handler))
- {
- toRemove.put(p, handler);
- }
- handlers.remove(handler);
-
- ServletHandler activeHandler = null;
- if( !handlers.isEmpty() )
- {
- activeHandler = handlers.first();
-
- try {
- useServletHandler(activeHandler);
- increaseUseCount(activeHandler);
- toAdd.put(p, activeHandler);
- } catch (ServletException e) {
- // TODO: next servlet handling this pattern could not be initialized, it belongs to failure DTOs
- }
- }
- else
- {
- this.patternToServletHandler.remove(p);
- }
- }
- }
-
- Servlet servlet = null;
- if(handler != null)
- {
- servlet = handler.getServlet();
- if(destroy)
- {
- servlet.destroy();
- }
- if(handler.isWhiteboardService())
- {
- ServiceObjects<Servlet> so = this.bundleContext.getServiceObjects(handler.getServletInfo().getServiceReference());
- ungetServiceObject(so, servlet, servletInfo.isResource());
- }
- }
-
- this.servletHandlerToUses.remove(handler);
-
- this.servletMapping = this.servletMapping.remove(toRemove);
- this.servletMapping = this.servletMapping.add(toAdd);
+ Pattern[] patterns = (handler == null) ? new Pattern[0] : handler.getPatterns();
+ SortedMap<Pattern, ServletHandler> toAdd = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
+ SortedMap<Pattern, ServletHandler> toRemove = new TreeMap<Pattern, ServletHandler>(PatternUtil.PatternComparator.INSTANCE);
- return servlet;
+ for (Pattern p : patterns)
+ {
+ SortedSet<ServletHandler> handlers = this.patternToServletHandler.get(p);
+ if (handlers != null && (!handlers.isEmpty()))
+ {
+ if (handlers.first().equals(handler))
+ {
+ toRemove.put(p, handler);
+ }
+ handlers.remove(handler);
+
+ ServletHandler activeHandler = null;
+ if (!handlers.isEmpty())
+ {
+ activeHandler = handlers.first();
+
+ try
+ {
+ useServletHandler(activeHandler);
+ increaseUseCount(activeHandler);
+ toAdd.put(p, activeHandler);
+ }
+ catch (ServletException e)
+ {
+ throw new RegistrationFailureException(activeHandler.getServletInfo(), FAILURE_REASON_EXCEPTION_ON_INIT, e);
+ }
+ }
+ else
+ {
+ this.patternToServletHandler.remove(p);
+ }
+ }
+ }
+
+ Servlet servlet = null;
+ if (handler != null && handler.getServlet() != null)
+ {
+ servlet = handler.getServlet();
+ if (destroy)
+ {
+ servlet.destroy();
+ }
+ if (handler.isWhiteboardService())
+ {
+ ServiceObjects<Servlet> so = this.bundleContext.getServiceObjects(handler.getServletInfo().getServiceReference());
+ ungetServiceObject(so, servlet, servletInfo.isResource());
+ }
+ }
+
+ this.servletHandlerToUses.remove(handler);
+
+ this.servletMapping = this.servletMapping.remove(toRemove);
+ this.servletMapping = this.servletMapping.add(toAdd);
+
+ return servlet;
}
private ServletHandler getServletHandler(final ServletInfo servletInfo)
{
- Iterator<ServletHandler> it = this.allServletHandlers.iterator();
- while(it.hasNext())
- {
- ServletHandler handler = it.next();
- if(handler.getServletInfo().compareTo(servletInfo) == 0)
- {
- return handler;
- }
- }
- return null;
+ Iterator<ServletHandler> it = this.allServletHandlers.iterator();
+ while (it.hasNext())
+ {
+ ServletHandler handler = it.next();
+ if (handler.getServletInfo().compareTo(servletInfo) == 0)
+ {
+ return handler;
+ }
+ }
+ return null;
}
-
- public synchronized void removeServlet(Servlet servlet, final boolean destroy)
+
+ public synchronized void removeServlet(Servlet servlet, final boolean destroy) throws RegistrationFailureException
{
- Iterator<ServletHandler> it = this.allServletHandlers.iterator();
- while(it.hasNext())
- {
- ServletHandler handler = it.next();
- if(handler.getServlet() == servlet)
- {
- removeServlet(handler.getServletInfo(), destroy);
- }
- }
+ Iterator<ServletHandler> it = this.allServletHandlers.iterator();
+ while (it.hasNext())
+ {
+ ServletHandler handler = it.next();
+ if (handler.getServlet() == servlet)
+ {
+ removeServlet(handler.getServletInfo(), destroy);
+ }
+ }
}
-
private boolean referencesDispatcherType(FilterHandler handler, DispatcherType dispatcherType)
{
@@ -499,17 +514,17 @@
public String isMatching(final String requestURI)
{
- if ( requestURI.equals(this.path) )
+ if (requestURI.equals(this.path))
{
- return "";
+ return "";
}
- if ( this.prefix == null )
+ if (this.prefix == null)
{
- return requestURI;
+ return requestURI;
}
- if ( requestURI.startsWith(this.prefix) )
+ if (requestURI.startsWith(this.prefix))
{
- return requestURI.substring(this.prefix.length() - 1);
+ return requestURI.substring(this.prefix.length() - 1);
}
return null;
}
@@ -519,34 +534,42 @@
return this.serviceId;
}
- public synchronized HandlerRuntime getRuntime() {
- Collection<ErrorPage> errorPages = new ArrayList<HandlerRuntime.ErrorPage>();
+ public synchronized ContextRuntime getRuntime(FailureRuntime.Builder failureRuntimeBuilder)
+ {
+ Collection<ErrorPageRuntime> errorPages = new TreeSet<ErrorPageRuntime>(ServletRuntime.COMPARATOR);
Collection<ServletHandler> errorHandlers = errorsMapping.getMappedHandlers();
for (ServletHandler servletHandler : errorHandlers)
{
errorPages.add(errorsMapping.getErrorPage(servletHandler));
}
- List<FilterHandler> filterHandlers = new ArrayList<FilterHandler>(filterMap.values());
-
- List<ServletHandler> servletHandlers = new ArrayList<ServletHandler>();
- List<ServletHandler> resourceHandlers = new ArrayList<ServletHandler>();
-
- Iterator<ServletHandler> it = this.allServletHandlers.iterator();
- while(it.hasNext())
+ Collection<FilterRuntime> filterRuntimes = new TreeSet<FilterRuntime>(FilterRuntime.COMPARATOR);
+ for (FilterRuntime filterRuntime : filterMap.values())
{
- ServletHandler servletHandler = it.next();
-
- if (servletHandler.getServletInfo().isResource())
+ filterRuntimes.add(filterRuntime);
+ }
+
+ Collection<ServletRuntime> servletRuntimes = new TreeSet<ServletRuntime>(ServletRuntime.COMPARATOR);
+ Collection<ServletRuntime> resourceRuntimes = new TreeSet<ServletRuntime>(ServletRuntime.COMPARATOR);
+
+ for (Set<ServletHandler> patternHandlers : patternToServletHandler.values())
+ {
+ Iterator<ServletHandler> itr = patternHandlers.iterator();
+ ServletHandler activeHandler = itr.next();
+ if (activeHandler.getServletInfo().isResource())
{
- resourceHandlers.add(servletHandler);
+ resourceRuntimes.add(activeHandler);
}
- else if (!errorHandlers.contains(servletHandler))
+ else
{
- servletHandlers.add(servletHandler);
+ servletRuntimes.add(activeHandler);
+ }
+ while (itr.hasNext())
+ {
+ failureRuntimeBuilder.add(itr.next().getServletInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
}
}
- return new HandlerRuntime(servletHandlers, filterHandlers, resourceHandlers, errorPages, serviceId);
- }
+ return new ContextRuntime(servletRuntimes, filterRuntimes, resourceRuntimes, errorPages, serviceId);
+ }
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
index d640c0a..feeb3e7 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
@@ -31,12 +31,13 @@
import org.apache.felix.http.base.internal.context.ExtServletContext;
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.ServletRuntime;
import org.apache.felix.http.base.internal.util.PatternUtil;
/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public class ServletHandler extends AbstractHandler<ServletHandler>
+public final class ServletHandler extends AbstractHandler<ServletHandler> implements ServletRuntime
{
private final ServletInfo servletInfo;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java
index 8f3d549..e30517a 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java
@@ -49,11 +49,11 @@
public AbstractInfo(final ServiceReference<T> ref)
{
- this.serviceId = (Long)ref.getProperty(Constants.SERVICE_ID);
+ this.serviceId = (Long) ref.getProperty(Constants.SERVICE_ID);
final Object rankingObj = ref.getProperty(Constants.SERVICE_RANKING);
- if ( rankingObj instanceof Integer )
+ if (rankingObj instanceof Integer)
{
- this.ranking = (Integer)rankingObj;
+ this.ranking = (Integer) rankingObj;
}
else
{
@@ -88,7 +88,7 @@
int reverseOrder = ( this.serviceId >= 0 && other.serviceId >= 0 ) ? 1 : -1;
return reverseOrder * Long.compare(this.serviceId, other.serviceId);
}
-
+
return Integer.compare(other.ranking, this.ranking);
}
@@ -105,7 +105,7 @@
protected String getStringProperty(final ServiceReference<T> ref, final String key)
{
final Object value = ref.getProperty(key);
- return (value instanceof String) ? ((String) value).trim(): null;
+ return (value instanceof String) ? ((String) value).trim() : null;
}
protected String[] getStringArrayProperty(ServiceReference<T> ref, String key)
@@ -118,12 +118,12 @@
}
else if (value instanceof String[])
{
- final String[] arr = (String[]) value;
- String[] values = new String[arr.length];
-
- for(int i=0, j=0; i<arr.length; i++)
+ final String[] arr = (String[]) value;
+ String[] values = new String[arr.length];
+
+ for (int i = 0, j = 0; i < arr.length; i++)
{
- if ( arr[i] != null )
+ if (arr[i] != null)
{
values[j++] = arr[i].trim();
}
@@ -169,7 +169,7 @@
final Map<String, String> result = new HashMap<String, String>();
for (final String key : ref.getPropertyKeys())
{
- if ( key.startsWith(prefix))
+ if (key.startsWith(prefix))
{
final String paramKey = key.substring(prefix.length());
final String paramValue = getStringProperty(ref, key);
@@ -205,10 +205,10 @@
public T getService(final Bundle bundle)
{
- if ( this.serviceReference != null )
+ if (this.serviceReference != null)
{
final ServiceObjects<T> so = bundle.getBundleContext().getServiceObjects(this.serviceReference);
- if ( so != null )
+ if (so != null)
{
return so.getService();
}
@@ -218,10 +218,10 @@
public void ungetService(final Bundle bundle, final T service)
{
- if ( this.serviceReference != null )
+ if (this.serviceReference != null)
{
final ServiceObjects<T> so = bundle.getBundleContext().getServiceObjects(this.serviceReference);
- if ( so != null )
+ if (so != null)
{
so.ungetService(service);
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
index 147e858..b9173e1 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
@@ -157,7 +157,7 @@
@Override
public boolean isValid()
{
- return super.isValid() && (!isEmpty(this.patterns) || !isEmpty(this.errorPage));
+ return super.isValid() && (isEmpty(this.patterns) ^ isEmpty(this.errorPage));
}
public String getName()
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseDTOBuilder.java
index 86fe97b..99361f8 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseDTOBuilder.java
@@ -29,7 +29,14 @@
abstract class BaseDTOBuilder<T, U extends DTO>
{
- public Collection<U> build(Collection<T> whiteboardServices, long servletContextId)
+ private DTOFactory<U> dtoFactory;
+
+ BaseDTOBuilder(DTOFactory<U> dtoFactory)
+ {
+ this.dtoFactory = dtoFactory;
+ }
+
+ Collection<U> build(Collection<T> whiteboardServices, long servletContextId)
{
List<U> dtoList = new ArrayList<U>();
for (T whiteboardService : whiteboardServices)
@@ -41,7 +48,12 @@
abstract U buildDTO(T whiteboardService, long servletContextId);
- protected <V> V[] copyWithDefault(V[] array, V[] defaultArray)
+ DTOFactory<U> getDTOFactory()
+ {
+ return dtoFactory;
+ }
+
+ <V> V[] copyWithDefault(V[] array, V[] defaultArray)
{
return array == null ? defaultArray : copyOf(array, array.length);
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java
index 34a26d4..f975e3a 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java
@@ -20,23 +20,45 @@
import javax.servlet.Servlet;
-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.BaseServletDTO;
-abstract class BaseServletDTOBuilder<T, U extends BaseServletDTO> extends BaseDTOBuilder<T, U>
+abstract class BaseServletDTOBuilder<T extends ServletRuntime, U extends BaseServletDTO> extends BaseDTOBuilder<T, U>
{
- final U setBaseFields(U dto, ServletHandler servletHandler, long servletContextId)
+ BaseServletDTOBuilder(DTOFactory<U> servletDTOFactory)
{
- ServletInfo info = servletHandler.getServletInfo();
- Servlet servlet = servletHandler.getServlet();
+ super(servletDTOFactory);
+ }
+ @Override
+ U buildDTO(T servletRuntime, long servletContextId)
+ {
+ ServletInfo info = servletRuntime.getServletInfo();
+ Servlet servlet = servletRuntime.getServlet();
+
+ U dto = getDTOFactory().get();
dto.asyncSupported = info.isAsyncSupported();
dto.initParams = info.getInitParameters();
- dto.name = info.getName();
- dto.serviceId = servletHandler.getServletInfo().getServiceId();
+ dto.name = getName(info, servlet);
+ dto.serviceId = servletRuntime.getServletInfo().getServiceId();
dto.servletContextId = servletContextId;
- dto.servletInfo = servlet.getServletInfo();
+ 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;
+ }
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java
index ae9cb15..c6c3edb 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BuilderConstants.java
@@ -19,6 +19,12 @@
package org.apache.felix.http.base.internal.runtime.dto;
import org.osgi.service.http.runtime.dto.ErrorPageDTO;
+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.FilterDTO;
import org.osgi.service.http.runtime.dto.ListenerDTO;
import org.osgi.service.http.runtime.dto.ResourceDTO;
@@ -37,4 +43,12 @@
public static final FilterDTO[] 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];
+
+ public static final FailedServletContextDTO[] CONTEXT_FAILURE_DTO_ARRAY = new FailedServletContextDTO[0];
+
+ public static final FailedServletDTO[] SERVLET_FAILURE_DTO_ARRAY = new FailedServletDTO[0];
+ public static final FailedFilterDTO[] FILTER_FAILURE_DTO_ARRAY = new FailedFilterDTO[0];
+ 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];
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ContextRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ContextRuntime.java
new file mode 100644
index 0000000..083dcc2
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ContextRuntime.java
@@ -0,0 +1,78 @@
+/*
+ * 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.Collection;
+import java.util.Collections;
+
+public final class ContextRuntime
+{
+ private final Collection<ServletRuntime> servletRuntimes;
+ private final Collection<FilterRuntime> filterRuntimes;
+ private final Collection<ServletRuntime> resourceRuntimes;
+ private final Collection<ErrorPageRuntime> errorPageRuntimes;
+ private final long serviceId;
+
+ public ContextRuntime(Collection<ServletRuntime> servletRuntimes,
+ Collection<FilterRuntime> filterRuntimes,
+ Collection<ServletRuntime> resourceRuntimes,
+ Collection<ErrorPageRuntime> errorPageRuntimes,
+ long serviceId)
+ {
+ this.servletRuntimes = servletRuntimes;
+ this.filterRuntimes = filterRuntimes;
+ this.resourceRuntimes = resourceRuntimes;
+ this.errorPageRuntimes = errorPageRuntimes;
+ this.serviceId = serviceId;
+ }
+
+ public static ContextRuntime empty(long serviceId)
+ {
+ return new ContextRuntime(Collections.<ServletRuntime>emptyList(),
+ Collections.<FilterRuntime>emptyList(),
+ Collections.<ServletRuntime>emptyList(),
+ Collections.<ErrorPageRuntime> emptyList(),
+ serviceId);
+ }
+
+ public Collection<ServletRuntime> getServletRuntimes()
+ {
+ return servletRuntimes;
+ }
+
+ public Collection<FilterRuntime> getFilterRuntimes()
+ {
+ return filterRuntimes;
+ }
+
+ public Collection<ServletRuntime> getResourceRuntimes()
+ {
+ return resourceRuntimes;
+ }
+
+ public Collection<ErrorPageRuntime> getErrorPageRuntimes()
+ {
+ return errorPageRuntimes;
+ }
+
+ public long getServiceId()
+ {
+ return serviceId;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactories.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactories.java
new file mode 100644
index 0000000..1333f7b
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactories.java
@@ -0,0 +1,123 @@
+/*
+ * 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 org.osgi.service.http.runtime.dto.ErrorPageDTO;
+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.FailedServletDTO;
+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.ServletDTO;
+
+final class DTOFactories
+{
+ static final DTOFactory<ServletDTO> SERVLET = new DTOFactory<ServletDTO>()
+ {
+ @Override
+ public ServletDTO get()
+ {
+ return new ServletDTO();
+ }
+ };
+
+ static final DTOFactory<FailedServletDTO> FAILED_SERVLET = new DTOFactory<FailedServletDTO>()
+ {
+ @Override
+ public FailedServletDTO get()
+ {
+ return new FailedServletDTO();
+ }
+ };
+
+ static final DTOFactory<FilterDTO> FILTER = new DTOFactory<FilterDTO>()
+ {
+ @Override
+ public FilterDTO get()
+ {
+ return new FilterDTO();
+ }
+ };
+
+ static final DTOFactory<FailedFilterDTO> FAILED_FILTER = new DTOFactory<FailedFilterDTO>()
+ {
+ @Override
+ public FailedFilterDTO get()
+ {
+ return new FailedFilterDTO();
+ }
+ };
+
+ static final DTOFactory<ResourceDTO> RESOURCE = new DTOFactory<ResourceDTO>()
+ {
+ @Override
+ public ResourceDTO get()
+ {
+ return new ResourceDTO();
+ }
+ };
+
+ static final DTOFactory<FailedResourceDTO> FAILED_RESOURCE = new DTOFactory<FailedResourceDTO>()
+ {
+ @Override
+ public FailedResourceDTO get()
+ {
+ return new FailedResourceDTO();
+ }
+ };
+
+ static final DTOFactory<ListenerDTO> LISTENER = new DTOFactory<ListenerDTO>()
+ {
+ @Override
+ public ListenerDTO get()
+ {
+ return new ListenerDTO();
+ }
+ };
+
+ static final DTOFactory<FailedListenerDTO> FAILED_LISTENER = new DTOFactory<FailedListenerDTO>()
+ {
+ @Override
+ public FailedListenerDTO get()
+ {
+ return new FailedListenerDTO();
+ }
+ };
+
+ static final DTOFactory<ErrorPageDTO> ERROR_PAGE = new DTOFactory<ErrorPageDTO>()
+ {
+ @Override
+ public ErrorPageDTO get()
+ {
+ return new ErrorPageDTO();
+ }
+ };
+
+ static final DTOFactory<FailedErrorPageDTO> FAILED_ERROR_PAGE = new DTOFactory<FailedErrorPageDTO>()
+ {
+ @Override
+ public FailedErrorPageDTO get()
+ {
+ return new FailedErrorPageDTO();
+ }
+ };
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactory.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactory.java
new file mode 100644
index 0000000..011da27
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/DTOFactory.java
@@ -0,0 +1,24 @@
+/*
+ * 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;
+
+interface DTOFactory<T>
+{
+ T get();
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java
index b17d320..cbe71e7 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.java
@@ -21,16 +21,24 @@
import java.util.Collection;
import java.util.Iterator;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime.ErrorPage;
import org.osgi.service.http.runtime.dto.ErrorPageDTO;
-final class ErrorPageDTOBuilder extends BaseServletDTOBuilder<ErrorPage, ErrorPageDTO>
+final class ErrorPageDTOBuilder<T extends ErrorPageDTO> extends BaseServletDTOBuilder<ErrorPageRuntime, T>
{
- @Override
- ErrorPageDTO buildDTO(ErrorPage errorPage, long servletConextId)
+ static ErrorPageDTOBuilder<ErrorPageDTO> create()
{
- ErrorPageDTO errorPageDTO = new ErrorPageDTO();
- setBaseFields(errorPageDTO, errorPage.getServletHandler(), servletConextId);
+ return new ErrorPageDTOBuilder<ErrorPageDTO>(DTOFactories.ERROR_PAGE);
+ }
+
+ ErrorPageDTOBuilder(DTOFactory<T> dtoFactory)
+ {
+ super(dtoFactory);
+ }
+
+ @Override
+ T buildDTO(ErrorPageRuntime errorPage, long servletConextId)
+ {
+ T errorPageDTO = super.buildDTO(errorPage, servletConextId);
errorPageDTO.errorCodes = getErrorCodes(errorPage.getErrorCodes());
errorPageDTO.exceptions = errorPage.getExceptions().toArray(BuilderConstants.STRING_ARRAY);
return errorPageDTO;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageRuntime.java
new file mode 100644
index 0000000..3155ede
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageRuntime.java
@@ -0,0 +1,94 @@
+/*
+ * 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.List;
+import java.util.regex.Pattern;
+
+import javax.servlet.Servlet;
+
+import org.apache.felix.http.base.internal.runtime.ServletInfo;
+
+public class ErrorPageRuntime implements ServletRuntime
+{
+ private static final Pattern ERROR_CODE_PATTERN = Pattern.compile("\\d{3}");
+
+ private final ServletRuntime servletRuntime;
+ private final Collection<Integer> errorCodes;
+ private final Collection<String> exceptions;
+
+ public ErrorPageRuntime(ServletRuntime servletRuntime,
+ Collection<Integer> errorCodes,
+ Collection<String> exceptions)
+ {
+ this.servletRuntime = servletRuntime;
+ this.errorCodes = errorCodes;
+ this.exceptions = exceptions;
+ }
+
+ public static ErrorPageRuntime fromRuntime(ServletRuntime servletRuntime)
+ {
+ List<Integer> errorCodes = new ArrayList<Integer>();
+ List<String> exceptions = new ArrayList<String>();
+
+ for (String string : servletRuntime.getServletInfo().getErrorPage())
+ {
+ if (ERROR_CODE_PATTERN.matcher(string).matches())
+ {
+ errorCodes.add(Integer.valueOf(string));
+ }
+ else
+ {
+ exceptions.add(string);
+ }
+ }
+
+ return new ErrorPageRuntime(servletRuntime, errorCodes, exceptions);
+ }
+
+ public Collection<Integer> getErrorCodes()
+ {
+ return errorCodes;
+ }
+
+ public Collection<String> getExceptions()
+ {
+ return exceptions;
+ }
+
+ @Override
+ public long getContextServiceId()
+ {
+ return servletRuntime.getContextServiceId();
+ }
+
+ @Override
+ public Servlet getServlet()
+ {
+ return servletRuntime.getServlet();
+ }
+
+ @Override
+ public ServletInfo getServletInfo()
+ {
+ return servletRuntime.getServletInfo();
+ }
+}
\ No newline at end of file
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureFilterRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureFilterRuntime.java
new file mode 100644
index 0000000..52feeb3
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureFilterRuntime.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.apache.felix.http.base.internal.runtime.FilterInfo;
+
+
+
+public class FailureFilterRuntime implements FilterRuntime
+{
+ private final FilterInfo filterInfo;
+
+ FailureFilterRuntime(FilterInfo FilterInfo)
+ {
+ this.filterInfo = FilterInfo;
+ }
+
+ @Override
+ public FilterInfo getFilterInfo()
+ {
+ return filterInfo;
+ }
+
+ @Override
+ public long getContextServiceId()
+ {
+ return 0L;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureRuntime.java
new file mode 100644
index 0000000..d156f83
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureRuntime.java
@@ -0,0 +1,318 @@
+/*
+ * 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 static org.apache.felix.http.base.internal.runtime.dto.BuilderConstants.CONTEXT_FAILURE_DTO_ARRAY;
+import static org.apache.felix.http.base.internal.runtime.dto.BuilderConstants.ERROR_PAGE_FAILURE_DTO_ARRAY;
+import static org.apache.felix.http.base.internal.runtime.dto.BuilderConstants.FILTER_FAILURE_DTO_ARRAY;
+import static org.apache.felix.http.base.internal.runtime.dto.BuilderConstants.LISTENER_FAILURE_DTO_ARRAY;
+import static org.apache.felix.http.base.internal.runtime.dto.BuilderConstants.RESOURCE_FAILURE_DTO_ARRAY;
+import static org.apache.felix.http.base.internal.runtime.dto.BuilderConstants.SERVLET_FAILURE_DTO_ARRAY;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+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.framework.ServiceReference;
+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 FailureRuntime
+{
+ private static final FailureComparator<ErrorPageRuntime> ERROR_PAGE_COMPARATOR = FailureComparator.<ErrorPageRuntime>create(ServletRuntime.COMPARATOR);
+ private static final FailureComparator<FilterRuntime> FILTER_COMPARATOR = FailureComparator.create(FilterRuntime.COMPARATOR);
+ private static final FailureComparator<ServletContextHelperRuntime> CONTEXT_COMPARATOR = FailureComparator.create(ServletContextHelperRuntime.COMPARATOR);
+ private static final FailureComparator<ServletRuntime> SERVLET_COMPARATOR = FailureComparator.create(ServletRuntime.COMPARATOR);
+ private static final Comparator<Failure<ServiceReference<?>>> REFERENCE_COMPARATOR = new Comparator<Failure<ServiceReference<?>>>()
+ {
+ @Override
+ public int compare(Failure<ServiceReference<?>> o1, Failure<ServiceReference<?>> o2)
+ {
+ return o1.service.compareTo(o2.service);
+ }
+ };
+
+ private final List<Failure<ServletContextHelperRuntime>> contextRuntimes;
+ private final List<Failure<ServletRuntime>> servletRuntimes;
+ private final List<Failure<FilterRuntime>> filterRuntimes;
+ private final List<Failure<ServletRuntime>> resourceRuntimes;
+ private final List<Failure<ErrorPageRuntime>> errorPageRuntimes;
+ private final List<Failure<ServiceReference<?>>> listenerRuntimes;
+
+ private FailureRuntime(List<Failure<ServletContextHelperRuntime>> contextRuntimes,
+ List<Failure<ServiceReference<?>>> listenerRuntimes,
+ List<Failure<ServletRuntime>> servletRuntimes,
+ List<Failure<FilterRuntime>> filterRuntimes,
+ List<Failure<ServletRuntime>> resourceRuntimes,
+ List<Failure<ErrorPageRuntime>> errorPageRuntimes)
+ {
+ this.contextRuntimes = contextRuntimes;
+ this.servletRuntimes = servletRuntimes;
+ this.filterRuntimes = filterRuntimes;
+ this.resourceRuntimes = resourceRuntimes;
+ this.listenerRuntimes = listenerRuntimes;
+ this.errorPageRuntimes = errorPageRuntimes;
+ }
+
+ public static FailureRuntime empty()
+ {
+ return new FailureRuntime(Collections.<Failure<ServletContextHelperRuntime>>emptyList(),
+ Collections.<Failure<ServiceReference<?>>>emptyList(),
+ Collections.<Failure<ServletRuntime>>emptyList(),
+ Collections.<Failure<FilterRuntime>>emptyList(),
+ Collections.<Failure<ServletRuntime>>emptyList(),
+ Collections.<Failure<ErrorPageRuntime>>emptyList());
+ }
+
+ public static FailureRuntime.Builder builder()
+ {
+ return new Builder();
+ }
+
+ public FailedServletDTO[] getServletDTOs()
+ {
+ List<FailedServletDTO> servletDTOs = new ArrayList<FailedServletDTO>();
+ for (Failure<ServletRuntime> failure : servletRuntimes)
+ {
+ servletDTOs.add(getServletDTO(failure.service, failure.failureCode));
+ }
+ return servletDTOs.toArray(SERVLET_FAILURE_DTO_ARRAY);
+ }
+
+ private FailedServletDTO getServletDTO(ServletRuntime failedServlet, int failureCode)
+ {
+ ServletDTOBuilder<FailedServletDTO> dtoBuilder = new ServletDTOBuilder<FailedServletDTO>(DTOFactories.FAILED_SERVLET);
+ FailedServletDTO servletDTO = dtoBuilder.buildDTO(failedServlet, 0);
+ servletDTO.failureReason = failureCode;
+ return servletDTO;
+ }
+
+ public FailedFilterDTO[] getFilterDTOs()
+ {
+ List<FailedFilterDTO> filterDTOs = new ArrayList<FailedFilterDTO>();
+ for (Failure<FilterRuntime> failure : filterRuntimes)
+ {
+ filterDTOs.add(getFilterDTO(failure.service, failure.failureCode));
+ }
+ return filterDTOs.toArray(FILTER_FAILURE_DTO_ARRAY);
+ }
+
+ private FailedFilterDTO getFilterDTO(FilterRuntime failedFilter, int failureCode)
+ {
+ FilterDTOBuilder<FailedFilterDTO> dtoBuilder = new FilterDTOBuilder<FailedFilterDTO>(DTOFactories.FAILED_FILTER);
+ FailedFilterDTO filterDTO = dtoBuilder.buildDTO(failedFilter, 0);
+ filterDTO.failureReason = failureCode;
+ return filterDTO;
+ }
+
+ public FailedResourceDTO[] getResourceDTOs()
+ {
+ List<FailedResourceDTO> resourceDTOs = new ArrayList<FailedResourceDTO>();
+ for (Failure<ServletRuntime> failure : resourceRuntimes)
+ {
+ resourceDTOs.add(getResourceDTO(failure.service, failure.failureCode));
+ }
+ return resourceDTOs.toArray(RESOURCE_FAILURE_DTO_ARRAY);
+ }
+
+ private FailedResourceDTO getResourceDTO(ServletRuntime failedResource, int failureCode)
+ {
+ ResourceDTOBuilder<FailedResourceDTO> dtoBuilder = new ResourceDTOBuilder<FailedResourceDTO>(DTOFactories.FAILED_RESOURCE);
+ FailedResourceDTO resourceDTO = dtoBuilder.buildDTO(failedResource, 0);
+ resourceDTO.failureReason = failureCode;
+ return resourceDTO;
+ }
+
+ public FailedErrorPageDTO[] getErrorPageDTOs()
+ {
+ List<FailedErrorPageDTO> errorPageDTOs = new ArrayList<FailedErrorPageDTO>();
+ for (Failure<ErrorPageRuntime> failure : errorPageRuntimes)
+ {
+ errorPageDTOs.add(getErrorPageDTO(failure.service, failure.failureCode));
+ }
+ return errorPageDTOs.toArray(ERROR_PAGE_FAILURE_DTO_ARRAY);
+ }
+
+ private FailedErrorPageDTO getErrorPageDTO(ErrorPageRuntime failedErrorPage, int failureCode)
+ {
+ ErrorPageDTOBuilder<FailedErrorPageDTO> dtoBuilder = new ErrorPageDTOBuilder<FailedErrorPageDTO>(DTOFactories.FAILED_ERROR_PAGE);
+ FailedErrorPageDTO errorPageDTO = dtoBuilder.buildDTO(failedErrorPage, 0);
+ errorPageDTO.failureReason = failureCode;
+ return errorPageDTO;
+ }
+
+ public FailedListenerDTO[] getListenerDTOs()
+ {
+ List<FailedListenerDTO> listenerDTOs = new ArrayList<FailedListenerDTO>();
+ for (Failure<ServiceReference<?>> failure : listenerRuntimes)
+ {
+ listenerDTOs.add(getListenerDTO(failure.service, failure.failureCode));
+ }
+ return listenerDTOs.toArray(LISTENER_FAILURE_DTO_ARRAY);
+ }
+
+ private FailedListenerDTO getListenerDTO(ServiceReference<?> failedListener, int failureCode)
+ {
+ ListenerDTOBuilder<FailedListenerDTO> dtoBuilder = new ListenerDTOBuilder<FailedListenerDTO>(DTOFactories.FAILED_LISTENER);
+ FailedListenerDTO errorPageDTO = dtoBuilder.buildDTO(failedListener, 0);
+ errorPageDTO.failureReason = failureCode;
+ return errorPageDTO;
+ }
+
+ public FailedServletContextDTO[] getServletContextDTOs()
+ {
+ List<FailedServletContextDTO> contextDTOs = new ArrayList<FailedServletContextDTO>();
+ for (Failure<ServletContextHelperRuntime> failure : contextRuntimes)
+ {
+ contextDTOs.add(getServletContextDTO(failure.service, failure.failureCode));
+ }
+ return contextDTOs.toArray(CONTEXT_FAILURE_DTO_ARRAY);
+ }
+
+ private FailedServletContextDTO getServletContextDTO(ServletContextHelperRuntime failedContext, int failureCode)
+ {
+ ServletContextDTOBuilder dtoBuilder = new ServletContextDTOBuilder(new FailedServletContextDTO(), failedContext);
+ FailedServletContextDTO servletContextDTO = (FailedServletContextDTO) dtoBuilder.build();
+ servletContextDTO.failureReason = failureCode;
+ return servletContextDTO;
+ }
+
+ public static class Builder
+ {
+ private final List<Failure<ServletContextHelperRuntime>> contextRuntimes = new ArrayList<FailureRuntime.Failure<ServletContextHelperRuntime>>();
+ private final List<Failure<ServletRuntime>> servletRuntimes = new ArrayList<Failure<ServletRuntime>>();
+ private final List<Failure<FilterRuntime>> filterRuntimes = new ArrayList<Failure<FilterRuntime>>();
+ private final List<Failure<ServletRuntime>> resourceRuntimes = new ArrayList<Failure<ServletRuntime>>();
+ private final List<Failure<ErrorPageRuntime>> errorPageRuntimes = new ArrayList<Failure<ErrorPageRuntime>>();
+ private final List<Failure<ServiceReference<?>>> listenerRuntimes = new ArrayList<Failure<ServiceReference<?>>>();
+
+ public FailureRuntime.Builder add(Map<AbstractInfo<?>, Integer> failureInfos)
+ {
+ for (Map.Entry<AbstractInfo<?>, Integer> failureEntry : failureInfos.entrySet())
+ {
+ add(failureEntry.getKey(), failureEntry.getValue());
+ }
+ return this;
+ }
+
+ public FailureRuntime.Builder add(AbstractInfo<?> info, int failureCode)
+ {
+ if (info instanceof ServletContextHelperInfo)
+ {
+ ServletContextHelperRuntime servletRuntime = new FailureServletContextHelperRuntime((ServletContextHelperInfo) info);
+ contextRuntimes.add(new Failure<ServletContextHelperRuntime>(servletRuntime, failureCode));
+ }
+ else if (info instanceof ServletInfo && ((ServletInfo) info).getErrorPage() != null)
+ {
+ FailureServletRuntime servletRuntime = new FailureServletRuntime((ServletInfo) info);
+ ErrorPageRuntime errorPageRuntime = ErrorPageRuntime.fromRuntime(servletRuntime);
+ errorPageRuntimes.add(new Failure<ErrorPageRuntime>(errorPageRuntime, failureCode));
+ }
+ else if (info instanceof ServletInfo)
+ {
+ ServletRuntime servletRuntime = new FailureServletRuntime((ServletInfo) info);
+ servletRuntimes.add(new Failure<ServletRuntime>(servletRuntime, failureCode));
+ }
+ else if (info instanceof FilterInfo)
+ {
+ FilterRuntime filterRuntime = new FailureFilterRuntime((FilterInfo) info);
+ filterRuntimes.add(new Failure<FilterRuntime>(filterRuntime, failureCode));
+ }
+ else if (info instanceof ResourceInfo)
+ {
+ ServletRuntime servletRuntime = new FailureServletRuntime(new ServletInfo((ResourceInfo) info));
+ resourceRuntimes.add(new Failure<ServletRuntime>(servletRuntime, failureCode));
+ }
+ else if (info instanceof ListenerInfo)
+ {
+ ServiceReference<?> serviceReference = ((ListenerInfo<?>) info).getServiceReference();
+ listenerRuntimes.add(new Failure<ServiceReference<?>>(serviceReference, failureCode));
+ }
+ else
+ {
+ throw new IllegalArgumentException("Unsupported info type: " + info.getClass());
+ }
+ return this;
+ }
+
+ public FailureRuntime build()
+ {
+ Collections.sort(contextRuntimes, CONTEXT_COMPARATOR);
+ Collections.sort(listenerRuntimes, REFERENCE_COMPARATOR);
+ Collections.sort(servletRuntimes, SERVLET_COMPARATOR);
+ Collections.sort(filterRuntimes, FILTER_COMPARATOR);
+ Collections.sort(resourceRuntimes, SERVLET_COMPARATOR);
+ Collections.sort(errorPageRuntimes, ERROR_PAGE_COMPARATOR);
+
+ return new FailureRuntime(contextRuntimes,
+ listenerRuntimes,
+ servletRuntimes,
+ filterRuntimes,
+ resourceRuntimes,
+ errorPageRuntimes);
+ }
+ }
+
+ private static class Failure<T>
+ {
+
+ final T service;
+ final int failureCode;
+
+ Failure(T service, int failureCode)
+ {
+ this.service = service;
+ this.failureCode = failureCode;
+ }
+ }
+
+ private static class FailureComparator<T> implements Comparator<Failure<T>>
+ {
+ final Comparator<? super T> serviceComparator;
+
+ FailureComparator(Comparator<? super T> serviceComparator)
+ {
+ this.serviceComparator = serviceComparator;
+ }
+
+ static <T> FailureComparator<T> create(Comparator<? super T> serviceComparator)
+ {
+ return new FailureComparator<T>(serviceComparator);
+ }
+
+ @Override
+ public int compare(Failure<T> o1, Failure<T> o2)
+ {
+ return serviceComparator.compare(o1.service, o2.service);
+ }
+ }
+}
+
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureServletContextHelperRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureServletContextHelperRuntime.java
new file mode 100644
index 0000000..11b3f75
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureServletContextHelperRuntime.java
@@ -0,0 +1,51 @@
+/*
+ * 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 javax.servlet.ServletContext;
+
+import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+
+public class FailureServletContextHelperRuntime implements ServletContextHelperRuntime, Comparable<FailureServletContextHelperRuntime>
+{
+ private final ServletContextHelperInfo info;
+
+ public FailureServletContextHelperRuntime(ServletContextHelperInfo info)
+ {
+ this.info = info;
+ }
+
+ @Override
+ public ServletContext getSharedContext()
+ {
+ return null;
+ }
+
+ @Override
+ public ServletContextHelperInfo getContextInfo()
+ {
+ return info;
+ }
+
+ @Override
+ public int compareTo(FailureServletContextHelperRuntime other)
+ {
+ return info.compareTo(other.info);
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureServletRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureServletRuntime.java
new file mode 100644
index 0000000..2f4383f
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FailureServletRuntime.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.base.internal.runtime.dto;
+
+import javax.servlet.Servlet;
+
+import org.apache.felix.http.base.internal.runtime.ServletInfo;
+
+
+
+public class FailureServletRuntime implements ServletRuntime
+{
+ private final ServletInfo servletInfo;
+
+ FailureServletRuntime(ServletInfo servletInfo)
+ {
+ this.servletInfo = servletInfo;
+ }
+
+ @Override
+ public ServletInfo getServletInfo()
+ {
+ return servletInfo;
+ }
+
+ @Override
+ public long getContextServiceId()
+ {
+ return 0L;
+ }
+
+ @Override
+ public Servlet getServlet()
+ {
+ return null;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
index 1023f5b..902e079 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
@@ -20,25 +20,34 @@
import javax.servlet.DispatcherType;
-import org.apache.felix.http.base.internal.handler.FilterHandler;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.osgi.service.http.runtime.dto.FilterDTO;
-final class FilterDTOBuilder extends BaseDTOBuilder<FilterHandler, FilterDTO>
+final class FilterDTOBuilder<T extends FilterDTO> extends BaseDTOBuilder<FilterRuntime, T>
{
- @Override
- FilterDTO buildDTO(FilterHandler filterHandler, long servletContextId)
+ static FilterDTOBuilder<FilterDTO> create()
{
- FilterInfo info = filterHandler.getFilterInfo();
+ return new FilterDTOBuilder<FilterDTO>(DTOFactories.FILTER);
+ }
- FilterDTO filterDTO = new FilterDTO();
+ FilterDTOBuilder(DTOFactory<T> dtoFactory)
+ {
+ super(dtoFactory);
+ }
+
+ @Override
+ T buildDTO(FilterRuntime filterRuntime, long servletContextId)
+ {
+ FilterInfo info = filterRuntime.getFilterInfo();
+
+ 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.serviceId = filterHandler.getFilterInfo().getServiceId();
+ filterDTO.serviceId = info.getServiceId();
filterDTO.servletContextId = servletContextId;
filterDTO.servletNames = copyWithDefault(info.getServletNames(), BuilderConstants.STRING_ARRAY);
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterRuntime.java
new file mode 100644
index 0000000..501402e
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterRuntime.java
@@ -0,0 +1,39 @@
+/*
+ * 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.Comparator;
+
+import org.apache.felix.http.base.internal.runtime.FilterInfo;
+
+
+
+public interface FilterRuntime extends WhiteboardServiceRuntime
+{
+ static final Comparator<FilterRuntime> COMPARATOR = new Comparator<FilterRuntime>()
+ {
+ @Override
+ public int compare(FilterRuntime o1, FilterRuntime o2)
+ {
+ return o1.getFilterInfo().compareTo(o2.getFilterInfo());
+ }
+ };
+
+ FilterInfo getFilterInfo();
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
index 34d2989..00f8bd7 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
@@ -22,12 +22,22 @@
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.runtime.dto.ListenerDTO;
-final class ListenerDTOBuilder extends BaseDTOBuilder<ServiceReference<?>, ListenerDTO>
+final class ListenerDTOBuilder<T extends ListenerDTO> extends BaseDTOBuilder<ServiceReference<?>, T>
{
- @Override
- ListenerDTO buildDTO(ServiceReference<?> listenerRef, long servletContextId)
+ static ListenerDTOBuilder<ListenerDTO> create()
{
- ListenerDTO listenerDTO = new ListenerDTO();
+ return new ListenerDTOBuilder<ListenerDTO>(DTOFactories.LISTENER);
+ }
+
+ ListenerDTOBuilder(DTOFactory<T> dtoFactory)
+ {
+ super(dtoFactory);
+ }
+
+ @Override
+ T buildDTO(ServiceReference<?> listenerRef, long servletContextId)
+ {
+ T listenerDTO = getDTOFactory().get();
listenerDTO.serviceId = (Long) listenerRef.getProperty(Constants.SERVICE_ID);
listenerDTO.servletContextId = servletContextId;
// TODO Is this the desired value?
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java
new file mode 100644
index 0000000..cfd2621
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RegistryRuntime.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.base.internal.runtime.dto;
+
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.ServiceReference;
+
+public final class RegistryRuntime
+{
+ private final Collection<ServletContextHelperRuntime> contexts;
+ private final Map<Long, Collection<ServiceReference<?>>> listenerRuntimes;
+ private final Map<Long, ContextRuntime> handlerRuntimes;
+ private final FailureRuntime failureRuntime;
+
+ public RegistryRuntime(Collection<ServletContextHelperRuntime> contexts,
+ Collection<ContextRuntime> contextRuntimes,
+ Map<Long, Collection<ServiceReference<?>>> listenerRuntimes,
+ FailureRuntime failureRuntime)
+ {
+ this.contexts = contexts;
+ this.failureRuntime = failureRuntime;
+ this.handlerRuntimes = createServiceIdMap(contextRuntimes);
+ this.listenerRuntimes = listenerRuntimes;
+ }
+
+ private static Map<Long, ContextRuntime> createServiceIdMap(Collection<ContextRuntime> contextRuntimes)
+ {
+ Map<Long, ContextRuntime> runtimesMap = new HashMap<Long, ContextRuntime>();
+ for (ContextRuntime contextRuntime : contextRuntimes)
+ {
+ runtimesMap.put(contextRuntime.getServiceId(), contextRuntime);
+ }
+ return runtimesMap;
+ }
+
+ public ContextRuntime getHandlerRuntime(ServletContextHelperRuntime contextRuntime)
+ {
+ long serviceId = contextRuntime.getContextInfo().getServiceId();
+
+ if (handlerRuntimes.containsKey(serviceId) && isDefaultContext(contextRuntime))
+ {
+ // TODO Merge with the default context of the HttpService ( handlerRuntimes.get(0) )
+ return handlerRuntimes.get(serviceId);
+ }
+ else if (handlerRuntimes.containsKey(serviceId))
+ {
+ return handlerRuntimes.get(serviceId);
+ }
+ return ContextRuntime.empty(serviceId);
+ }
+
+ private boolean isDefaultContext(ServletContextHelperRuntime contextRuntime)
+ {
+ return contextRuntime.getContextInfo().getName().equals(HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME);
+ }
+
+ public Collection<ServiceReference<?>> getListenerRuntimes(ServletContextHelperRuntime contextRuntime)
+ {
+ if (listenerRuntimes.containsKey(contextRuntime.getContextInfo().getServiceId()))
+ {
+ return listenerRuntimes.get(contextRuntime.getContextInfo().getServiceId());
+ }
+ return Collections.emptyList();
+ }
+
+ public Collection<ServletContextHelperRuntime> getContexts()
+ {
+ return contexts;
+ }
+
+ public FailureRuntime getFailureRuntime()
+ {
+ return failureRuntime;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java
index e9b7e09..9aac097 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java
@@ -18,18 +18,27 @@
*/
package org.apache.felix.http.base.internal.runtime.dto;
-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.ResourceDTO;
-final class ResourceDTOBuilder extends BaseDTOBuilder<ServletHandler, ResourceDTO>
+final class ResourceDTOBuilder<T extends ResourceDTO> extends BaseDTOBuilder<ServletRuntime, T>
{
- @Override
- ResourceDTO buildDTO(ServletHandler handler, long servletContextId)
+ static ResourceDTOBuilder<ResourceDTO> create()
{
- ServletInfo servletInfo = handler.getServletInfo();
+ return new ResourceDTOBuilder<ResourceDTO>(DTOFactories.RESOURCE);
+ }
- ResourceDTO resourceDTO = new ResourceDTO();
+ ResourceDTOBuilder(DTOFactory<T> dtoFactory)
+ {
+ super(dtoFactory);
+ }
+
+ @Override
+ T buildDTO(ServletRuntime runtime, long servletContextId)
+ {
+ ServletInfo servletInfo = runtime.getServletInfo();
+
+ T resourceDTO = getDTOFactory().get();
resourceDTO.patterns = copyWithDefault(servletInfo.getPatterns(), BuilderConstants.STRING_ARRAY);
resourceDTO.prefix = servletInfo.getPrefix();
resourceDTO.serviceId = servletInfo.getServiceId();
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
index 2e8b320..b381af6 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
@@ -20,28 +20,12 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-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.AbstractInfo;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime.ErrorPage;
-import org.apache.felix.http.base.internal.runtime.RegistryRuntime;
-import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
-import org.apache.felix.http.base.internal.whiteboard.ContextHandler;
import org.osgi.framework.ServiceReference;
-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.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.FilterDTO;
import org.osgi.service.http.runtime.dto.ListenerDTO;
import org.osgi.service.http.runtime.dto.ResourceDTO;
@@ -52,12 +36,6 @@
public final class RuntimeDTOBuilder
{
- private static final ServletDTOBuilder SERVLET_DTO_BUILDER = new ServletDTOBuilder();
- private static final ResourceDTOBuilder RESOURCE_DTO_BUILDER = new ResourceDTOBuilder();
- private static final FilterDTOBuilder FILTER_DTO_BUILDER = new FilterDTOBuilder();
- private static final ErrorPageDTOBuilder ERROR_PAGE_DTO_BUILDER = new ErrorPageDTOBuilder();
- private static final ListenerDTOBuilder LISTENER_DTO_BUILDER = new ListenerDTOBuilder();
-
private final RegistryRuntime registry;
private final Map<String, Object> serviceProperties;
@@ -69,44 +47,16 @@
public RuntimeDTO build()
{
+ FailureRuntime failureRuntime = registry.getFailureRuntime();
+
RuntimeDTO runtimeDTO = new RuntimeDTO();
runtimeDTO.attributes = createAttributes();
- final List<FailedErrorPageDTO> failedErrorPageDTOs = new ArrayList<FailedErrorPageDTO>();
- final List<FailedFilterDTO> failedFilterDTOs = new ArrayList<FailedFilterDTO>();
- final List<FailedListenerDTO> failedListenerDTOs = new ArrayList<FailedListenerDTO>();
- final List<FailedResourceDTO> failedResourceDTOs = new ArrayList<FailedResourceDTO>();
- final List<FailedServletContextDTO> failedServletContextDTOs = new ArrayList<FailedServletContextDTO>();
- final List<FailedServletDTO> failedServletDTOs = new ArrayList<FailedServletDTO>();
-
- for(final AbstractInfo<?> info : this.registry.getInvalidServices())
- {
- if ( info instanceof ServletContextHelperInfo )
- {
- final ServletContextHelperInfo sch = (ServletContextHelperInfo)info;
- final FailedServletContextDTO dto = new FailedServletContextDTO();
- dto.attributes = Collections.emptyMap();
- dto.contextPath = sch.getPath();
- dto.errorPageDTOs = BuilderConstants.ERROR_PAGE_DTO_ARRAY;
- dto.failureReason = DTOConstants.FAILURE_REASON_VALIDATION_FAILED;
- dto.filterDTOs = BuilderConstants.FILTER_DTO_ARRAY;
- dto.initParams = sch.getInitParameters();
- dto.listenerDTOs = BuilderConstants.LISTENER_DTO_ARRAY;
- dto.name = sch.getName();
- dto.resourceDTOs = BuilderConstants.RESOURCE_DTO_ARRAY;
- dto.serviceId = sch.getServiceId();
- dto.servletDTOs = BuilderConstants.SERVLET_DTO_ARRAY;
-
- failedServletContextDTOs.add(dto);
- }
- }
- //TODO <**
- runtimeDTO.failedErrorPageDTOs = failedErrorPageDTOs.toArray(new FailedErrorPageDTO[failedErrorPageDTOs.size()]);
- runtimeDTO.failedFilterDTOs = failedFilterDTOs.toArray(new FailedFilterDTO[failedFilterDTOs.size()]);
- runtimeDTO.failedListenerDTOs = failedListenerDTOs.toArray(new FailedListenerDTO[failedListenerDTOs.size()]);
- runtimeDTO.failedResourceDTOs = failedResourceDTOs.toArray(new FailedResourceDTO[failedResourceDTOs.size()]);
- runtimeDTO.failedServletContextDTOs = failedServletContextDTOs.toArray(new FailedServletContextDTO[failedServletContextDTOs.size()]);
- runtimeDTO.failedServletDTOs = failedServletDTOs.toArray(new FailedServletDTO[failedServletDTOs.size()]);
- //**>
+ 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.servletContextDTOs = createContextDTOs();
return runtimeDTO;
}
@@ -124,37 +74,37 @@
private ServletContextDTO[] createContextDTOs()
{
List<ServletContextDTO> contextDTOs = new ArrayList<ServletContextDTO>();
- for (ContextHandler context : registry.getContexts())
+ for (ServletContextHelperRuntime context : registry.getContexts())
{
contextDTOs.add(createContextDTO(context,
registry.getHandlerRuntime(context),
- registry.getListenerRuntime(context)));
+ registry.getListenerRuntimes(context)));
}
return contextDTOs.toArray(BuilderConstants.CONTEXT_DTO_ARRAY);
}
- private ServletContextDTO createContextDTO(ContextHandler context,
- HandlerRuntime handlerRuntime,
- Collection<ServiceReference<?>> listenerRefs)
+ private ServletContextDTO createContextDTO(ServletContextHelperRuntime context,
+ ContextRuntime contextRuntime,
+ Collection<ServiceReference<?>> listenerRuntimes)
{
- Collection<ServletHandler> servletHandlers = handlerRuntime.getServletHandlers();
- Collection<ServletHandler> resourceHandlers = handlerRuntime.getResourceHandlers();
- Collection<FilterHandler> filterHandlers = handlerRuntime.getFilterHandlers();
- Collection<ErrorPage> errorPages = handlerRuntime.getErrorPages();
- long servletContextId = handlerRuntime.getServiceId();
+ Collection<ServletRuntime> servletRuntimes = contextRuntime.getServletRuntimes();
+ Collection<ServletRuntime> resourceRuntimes = contextRuntime.getResourceRuntimes();
+ Collection<FilterRuntime> filterRuntimes = contextRuntime.getFilterRuntimes();
+ Collection<ErrorPageRuntime> errorPageRuntimes = contextRuntime.getErrorPageRuntimes();
+ long servletContextId = contextRuntime.getServiceId();
- Collection<ServletDTO> servletDTOs = SERVLET_DTO_BUILDER.build(servletHandlers, servletContextId);
- Collection<ResourceDTO> resourcesDTOs = RESOURCE_DTO_BUILDER.build(resourceHandlers, servletContextId);
- Collection<FilterDTO> filtersDTOs = FILTER_DTO_BUILDER.build(filterHandlers, servletContextId);
- Collection<ErrorPageDTO> errorsDTOs = ERROR_PAGE_DTO_BUILDER.build(errorPages, servletContextId);
- Collection<ListenerDTO> listenersDTOs = LISTENER_DTO_BUILDER.build(listenerRefs, servletContextId);
+ Collection<ServletDTO> servletDTOs = ServletDTOBuilder.create().build(servletRuntimes, servletContextId);
+ Collection<ResourceDTO> resourceDTOs = ResourceDTOBuilder.create().build(resourceRuntimes, servletContextId);
+ Collection<FilterDTO> filterDTOs = FilterDTOBuilder.create().build(filterRuntimes, servletContextId);
+ Collection<ErrorPageDTO> errorDTOs = ErrorPageDTOBuilder.create().build(errorPageRuntimes, servletContextId);
+ Collection<ListenerDTO> listenerDTOs = ListenerDTOBuilder.create().build(listenerRuntimes, servletContextId);
return new ServletContextDTOBuilder(context,
servletDTOs,
- resourcesDTOs,
- filtersDTOs,
- errorsDTOs,
- listenersDTOs)
+ resourceDTOs,
+ filterDTOs,
+ errorDTOs,
+ listenerDTOs)
.build();
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java
index f32f815..34d5bc4 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java
@@ -21,13 +21,13 @@
import static java.util.Collections.list;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
-import org.apache.felix.http.base.internal.whiteboard.ContextHandler;
import org.osgi.dto.DTO;
import org.osgi.service.http.runtime.dto.ErrorPageDTO;
import org.osgi.service.http.runtime.dto.FilterDTO;
@@ -39,21 +39,24 @@
final class ServletContextDTOBuilder
{
- private final ContextHandler contextHandler;
+ 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;
- public ServletContextDTOBuilder(ContextHandler contextHandler,
+ ServletContextDTOBuilder(ServletContextDTO contextDTO,
+ ServletContextHelperRuntime contextRuntime,
Collection<ServletDTO> servletDTOs,
Collection<ResourceDTO> resourceDTOs,
Collection<FilterDTO> filterDTOs,
Collection<ErrorPageDTO> errorPageDTOs,
Collection<ListenerDTO> listenerDTOs)
{
- this.contextHandler = contextHandler;
+ this.contextDTO = contextDTO;
+ this.contextRuntime = contextRuntime;
this.servletDTOs = servletDTOs != null ?
servletDTOs.toArray(BuilderConstants.SERVLET_DTO_ARRAY) : BuilderConstants.SERVLET_DTO_ARRAY;
this.resourceDTOs = resourceDTOs != null ?
@@ -66,20 +69,34 @@
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);
+ }
+
ServletContextDTO build()
{
- ServletContext context = contextHandler.getSharedContext();
- ServletContextHelperInfo contextInfo = contextHandler.getContextInfo();
+ ServletContext context = contextRuntime.getSharedContext();
+ ServletContextHelperInfo contextInfo = contextRuntime.getContextInfo();
long contextId = contextInfo.getServiceId();
- ServletContextDTO contextDTO = new ServletContextDTO();
contextDTO.attributes = getAttributes(context);
- contextDTO.contextPath = context.getContextPath();
+ contextDTO.contextPath = context == null ? contextInfo.getPath() : context.getContextPath();
contextDTO.errorPageDTOs = errorPageDTOs;
contextDTO.filterDTOs = filterDTOs;
contextDTO.initParams = contextInfo.getInitParameters();
contextDTO.listenerDTOs = listenerDTOs;
- contextDTO.name = context.getServletContextName();
+ contextDTO.name = contextInfo.getName();
contextDTO.resourceDTOs = resourceDTOs;
contextDTO.servletDTOs = servletDTOs;
contextDTO.serviceId = contextId;
@@ -89,6 +106,11 @@
private Map<String, Object> getAttributes(ServletContext context)
{
+ if (context == null)
+ {
+ return Collections.emptyMap();
+ }
+
Map<String, Object> attributes = new HashMap<String, Object>();
for (String name : list(context.getAttributeNames()))
{
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextHelperRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextHelperRuntime.java
new file mode 100644
index 0000000..b597e45
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextHelperRuntime.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.base.internal.runtime.dto;
+
+import java.util.Comparator;
+
+import javax.servlet.ServletContext;
+
+import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+
+public interface ServletContextHelperRuntime
+{
+ static final Comparator<ServletContextHelperRuntime> COMPARATOR = new Comparator<ServletContextHelperRuntime>()
+ {
+ @Override
+ public int compare(ServletContextHelperRuntime o1, ServletContextHelperRuntime o2)
+ {
+ return o1.getContextInfo().compareTo(o2.getContextInfo());
+ }
+ };
+
+ ServletContext getSharedContext();
+
+ ServletContextHelperInfo getContextInfo();
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
index 0444837..107d683 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
@@ -18,19 +18,27 @@
*/
package org.apache.felix.http.base.internal.runtime.dto;
-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.ServletDTO;
-final class ServletDTOBuilder extends BaseServletDTOBuilder<ServletHandler, ServletDTO>
+final class ServletDTOBuilder<T extends ServletDTO> extends BaseServletDTOBuilder<ServletRuntime, T>
{
- @Override
- ServletDTO buildDTO(ServletHandler servletHandler, long servletContextId)
+ static ServletDTOBuilder<ServletDTO> create()
{
- ServletInfo info = servletHandler.getServletInfo();
+ return new ServletDTOBuilder<ServletDTO>(DTOFactories.SERVLET);
+ }
- ServletDTO servletDTO = new ServletDTO();
- setBaseFields(servletDTO, servletHandler, servletContextId);
+ ServletDTOBuilder(DTOFactory<T> dtoFactory)
+ {
+ super(dtoFactory);
+ }
+
+ @Override
+ T buildDTO(ServletRuntime servletRuntime, long servletContextId)
+ {
+ ServletInfo info = servletRuntime.getServletInfo();
+
+ T servletDTO = super.buildDTO(servletRuntime, servletContextId);
servletDTO.patterns = copyWithDefault(checkNotEmpty(info.getPatterns()), null);
return servletDTO;
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletRuntime.java
new file mode 100644
index 0000000..e994be3
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletRuntime.java
@@ -0,0 +1,43 @@
+/*
+ * 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.Comparator;
+
+import javax.servlet.Servlet;
+
+import org.apache.felix.http.base.internal.runtime.ServletInfo;
+
+
+
+public interface ServletRuntime extends WhiteboardServiceRuntime
+{
+ static final Comparator<ServletRuntime> COMPARATOR = new Comparator<ServletRuntime>()
+ {
+ @Override
+ public int compare(ServletRuntime o1, ServletRuntime o2)
+ {
+ return o1.getServletInfo().compareTo(o2.getServletInfo());
+ }
+ };
+
+ Servlet getServlet();
+
+ ServletInfo getServletInfo();
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/WhiteboardServiceRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/WhiteboardServiceRuntime.java
new file mode 100644
index 0000000..3fb16d5
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/WhiteboardServiceRuntime.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+
+
+interface WhiteboardServiceRuntime
+{
+ long getContextServiceId();
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
index 096ae72..83262cc 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
@@ -22,7 +22,7 @@
import java.util.Hashtable;
import org.apache.felix.http.base.internal.handler.HandlerRegistry;
-import org.apache.felix.http.base.internal.runtime.RegistryRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.RegistryRuntime;
import org.apache.felix.http.base.internal.runtime.dto.RuntimeDTOBuilder;
import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
import org.osgi.service.http.runtime.HttpServiceRuntime;
@@ -36,7 +36,6 @@
private final HandlerRegistry registry;
private final ServletContextHelperManager contextManager;
-
public HttpServiceRuntimeImpl(HandlerRegistry registry,
ServletContextHelperManager contextManager)
{
@@ -54,7 +53,6 @@
@Override
public RequestInfoDTO calculateRequestInfoDTO(String path)
{
- // TODO Auto-generated method stub
return null;
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/SharedHttpServiceImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/SharedHttpServiceImpl.java
index fc20fe8..9f58a64 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/SharedHttpServiceImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/SharedHttpServiceImpl.java
@@ -31,6 +31,7 @@
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.ServletInfo;
+import org.apache.felix.http.base.internal.whiteboard.RegistrationFailureException;
import org.osgi.service.http.NamespaceException;
public final class SharedHttpServiceImpl
@@ -103,7 +104,15 @@
{
throw new IllegalArgumentException("Nothing registered at " + alias);
}
- return this.handlerRegistry.removeServlet(handler.getServletInfo(), true);
+
+ try
+ {
+ return this.handlerRegistry.removeServlet(handler.getServletInfo(), true);
+ } catch (RegistrationFailureException e)
+ {
+ // TODO create FailureDTO
+ return null;
+ }
}
}
@@ -111,7 +120,14 @@
{
if (servlet != null)
{
- this.handlerRegistry.removeServlet(servlet, destroy);
+ try
+ {
+ this.handlerRegistry.removeServlet(servlet, destroy);
+ } catch (RegistrationFailureException e)
+ {
+ // TODO create FailureDTO
+ }
+
synchronized (this.aliasMap)
{
final Iterator<Map.Entry<String, ServletHandler>> i = this.aliasMap.entrySet().iterator();
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/util/CollectionUtils.java b/http/base/src/main/java/org/apache/felix/http/base/internal/util/CollectionUtils.java
index 2f3b45f..0a2d00a 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/util/CollectionUtils.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/util/CollectionUtils.java
@@ -17,13 +17,19 @@
package org.apache.felix.http.base.internal.util;
import java.util.Collection;
-import java.util.Set;
+import java.util.Comparator;
+import java.util.SortedSet;
import java.util.TreeSet;
public class CollectionUtils {
- public static <T extends Comparable<?>> Set<T> union(Collection<? extends T>... collections)
+ public static <T extends Comparable<?>> SortedSet<T> sortedUnion(Collection<? extends T>... collections)
{
- Set<T> union = new TreeSet<T>();
+ return sortedUnion(null, collections);
+ }
+
+ public static <T> SortedSet<T> sortedUnion(Comparator<T> comparator, Collection<? extends T>... collections)
+ {
+ SortedSet<T> union = comparator == null ? new TreeSet<T>() : new TreeSet<T>(comparator);
for (Collection<? extends T> collection : collections)
{
union.addAll(collection);
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
index 31a286a..16dd573 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
@@ -24,11 +24,12 @@
import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+import org.apache.felix.http.base.internal.runtime.dto.ServletContextHelperRuntime;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceObjects;
import org.osgi.service.http.context.ServletContextHelper;
-public final class ContextHandler implements Comparable<ContextHandler>
+public final class ContextHandler implements Comparable<ContextHandler>, ServletContextHelperRuntime
{
/** The info object for the context. */
private final ServletContextHelperInfo info;
@@ -59,6 +60,7 @@
eventListener);
}
+ @Override
public ServletContextHelperInfo getContextInfo()
{
return this.info;
@@ -80,6 +82,7 @@
this.ungetServletContext(bundle);
}
+ @Override
public ServletContext getSharedContext()
{
return sharedContext;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java
index 43d26c2..979423a 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java
@@ -23,9 +23,13 @@
import javax.annotation.Nonnull;
-import org.apache.felix.http.base.internal.runtime.ListenerInfo;
+import org.apache.felix.http.base.internal.runtime.HttpSessionAttributeListenerInfo;
+import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletRequestListenerInfo;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceReference;
@@ -40,40 +44,6 @@
this.bundle = bundle;
}
- public void initialized(@Nonnull final ServletContextListenerInfo listenerInfo,
- ContextHandler contextHandler)
- {
- registriesByContext.get(contextHandler.getContextInfo()).initialized(listenerInfo, contextHandler);
- }
-
- public void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo,
- ContextHandler contextHandler)
- {
- registriesByContext.get(contextHandler.getContextInfo()).destroyed(listenerInfo, contextHandler);
- }
-
- public <T extends ListenerInfo<?>> void addListener(@Nonnull final T info,
- final ContextHandler contextHandler)
- {
- getRegistryForContext(contextHandler).addListener(info);
- }
-
- public <T extends ListenerInfo<?>> void removeListener(@Nonnull final T info,
- final ContextHandler contextHandler)
- {
- getRegistryForContext(contextHandler).removeListener(info);
- }
-
- private PerContextEventListener getRegistryForContext(ContextHandler contextHandler)
- {
- PerContextEventListener contextRegistry = registriesByContext.get(contextHandler.getContextInfo());
- if (contextRegistry == null)
- {
- throw new IllegalArgumentException("ContextHandler " + contextHandler.getContextInfo().getName() + " is not registered");
- }
- return contextRegistry;
- }
-
public PerContextEventListener addContext(ServletContextHelperInfo info)
{
if (registriesByContext.containsKey(info))
@@ -91,12 +61,95 @@
registriesByContext.remove(info);
}
+ public void initialized(@Nonnull final ServletContextListenerInfo listenerInfo,
+ ContextHandler contextHandler)
+ {
+ registriesByContext.get(contextHandler.getContextInfo()).initialized(listenerInfo, contextHandler);
+ }
+
+ public void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo,
+ ContextHandler contextHandler)
+ {
+ registriesByContext.get(contextHandler.getContextInfo()).destroyed(listenerInfo, contextHandler);
+ }
+
+ void addListener(@Nonnull final ServletContextAttributeListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).addListener(info);
+ }
+
+ void removeListener(@Nonnull final ServletContextAttributeListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).removeListener(info);
+ }
+
+ void addListener(@Nonnull final HttpSessionAttributeListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).addListener(info);
+ }
+
+ void removeListener(@Nonnull final HttpSessionAttributeListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).removeListener(info);
+ }
+
+ void addListener(@Nonnull final HttpSessionListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).addListener(info);
+ }
+
+ void removeListener(@Nonnull final HttpSessionListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).removeListener(info);
+ }
+
+ void addListener(@Nonnull final ServletRequestListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).addListener(info);
+ }
+
+ void removeListener(@Nonnull final ServletRequestListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).removeListener(info);
+ }
+
+ void addListener(@Nonnull final ServletRequestAttributeListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).addListener(info);
+ }
+
+ void removeListener(@Nonnull final ServletRequestAttributeListenerInfo info,
+ final ContextHandler contextHandler)
+ {
+ getRegistryForContext(contextHandler).removeListener(info);
+ }
+
+ private PerContextEventListener getRegistryForContext(ContextHandler contextHandler)
+ {
+ PerContextEventListener contextRegistry = registriesByContext.get(contextHandler.getContextInfo());
+ if (contextRegistry == null)
+ {
+ throw new IllegalArgumentException("ContextHandler " + contextHandler.getContextInfo().getName() + " is not registered");
+ }
+ return contextRegistry;
+ }
+
public Map<Long, Collection<ServiceReference<?>>> getContextRuntimes()
{
Map<Long, Collection<ServiceReference<?>>> listenersByContext = new HashMap<Long, Collection<ServiceReference<?>>>();
for (ServletContextHelperInfo contextInfo : registriesByContext.keySet())
{
- listenersByContext.put(contextInfo.getServiceId(), registriesByContext.get(contextInfo).getRuntime());
+ long serviceId = contextInfo.getServiceId();
+ listenersByContext.put(serviceId, registriesByContext.get(contextInfo).getRuntime());
}
return listenersByContext;
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
index d572666..19244a3 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
@@ -17,6 +17,7 @@
package org.apache.felix.http.base.internal.whiteboard;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
@@ -37,7 +38,6 @@
import org.apache.felix.http.base.internal.runtime.HttpSessionAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
@@ -262,19 +262,6 @@
}
}
- // Make calling from ListenerRegistry easier
- <T extends ListenerInfo<?>> void addListener(@Nonnull T info)
- {
- throw new UnsupportedOperationException("Listeners of type "
- + info.getClass() + "are not supported");
- }
-
- <T extends ListenerInfo<?>> void removeListener(@Nonnull T info)
- {
- throw new UnsupportedOperationException("Listeners of type "
- + info.getClass() + "are not supported");
- }
-
@Override
public void attributeReplaced(final HttpSessionBindingEvent event)
{
@@ -404,7 +391,8 @@
@SuppressWarnings("unchecked")
Collection<ServiceReference<?>> getRuntime()
{
- return CollectionUtils.<ServiceReference<?>> union(
+ return CollectionUtils.<ServiceReference<?>>sortedUnion(
+ Collections.<ServiceReference<?>>reverseOrder(),
contextListeners.keySet(),
contextAttributeListeners.keySet(),
sessionAttributeListeners.keySet(),
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/RegistrationFailureException.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/RegistrationFailureException.java
new file mode 100644
index 0000000..46a60e8
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/RegistrationFailureException.java
@@ -0,0 +1,59 @@
+/*
+ * 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.whiteboard;
+
+import javax.servlet.ServletException;
+
+import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
+
+@SuppressWarnings("serial")
+public class RegistrationFailureException extends ServletException
+{
+ private final WhiteboardServiceInfo<?> info;
+ private final int errorCode;
+
+ public RegistrationFailureException(WhiteboardServiceInfo<?> info, int errorCode)
+ {
+ super();
+ this.info = info;
+ this.errorCode = errorCode;
+ }
+
+ public RegistrationFailureException(WhiteboardServiceInfo<?> info, int errorCode, String message)
+ {
+ super(message);
+ this.info = info;
+ this.errorCode = errorCode;
+ }
+
+ public RegistrationFailureException(WhiteboardServiceInfo<?> info, int errorCode, Throwable exception)
+ {
+ super(exception);
+ this.info = info;
+ this.errorCode = errorCode;
+ }
+
+ public WhiteboardServiceInfo<?> getInfo()
+ {
+ return info;
+ }
+
+ public int getErrorCode()
+ {
+ return errorCode;
+ }
+}
\ No newline at end of file
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java
index 6ef65dc..84da0b9 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java
@@ -16,6 +16,11 @@
*/
package org.apache.felix.http.base.internal.whiteboard;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_UNKNOWN;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_VALIDATION_FAILED;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -25,10 +30,9 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
-import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.ConcurrentSkipListMap;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
@@ -38,14 +42,20 @@
import org.apache.felix.http.base.internal.logger.SystemLogger;
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.HandlerRuntime;
-import org.apache.felix.http.base.internal.runtime.ListenerInfo;
-import org.apache.felix.http.base.internal.runtime.RegistryRuntime;
+import org.apache.felix.http.base.internal.runtime.HttpSessionAttributeListenerInfo;
+import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
import org.apache.felix.http.base.internal.runtime.ResourceInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
+import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletRequestListenerInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
+import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.FailureRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.RegistryRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.ServletContextHelperRuntime;
import org.apache.felix.http.base.internal.util.MimeTypes;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -73,7 +83,7 @@
private final BundleContext bundleContext;
- private final Set<AbstractInfo<?>> invalidRegistrations = new ConcurrentSkipListSet<AbstractInfo<?>>();
+ private final Map<AbstractInfo<?>, Integer> serviceFailures = new ConcurrentSkipListMap<AbstractInfo<?>, Integer>();
private volatile ServletContext webContext;
@@ -176,6 +186,7 @@
{
services.add(entry.getKey());
}
+ removeFailure(entry.getKey(), FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING);
}
}
// context listeners first
@@ -222,7 +233,6 @@
handler.deactivate();
this.httpService.unregisterContext(handler);
-
}
/**
@@ -257,17 +267,24 @@
// check for deactivate
if ( handlerList.size() > 1 )
{
- this.deactivate(handlerList.get(1));
+ ContextHandler oldHead = handlerList.get(1);
+ this.deactivate(oldHead);
+ this.serviceFailures.put(oldHead.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
}
+ removeFailure(handler.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
this.activate(handler);
}
+ else
+ {
+ this.serviceFailures.put(handler.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
}
}
else
{
final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
SystemLogger.debug("Ignoring " + type + " service " + info.getServiceReference());
- this.invalidRegistrations.add(info);
+ this.serviceFailures.put(info, FAILURE_REASON_VALIDATION_FAILED);
}
}
}
@@ -312,16 +329,15 @@
}
else if ( activateNext )
{
- this.activate(handlerList.get(0));
+ ContextHandler newHead = handlerList.get(0);
+ this.activate(newHead);
+ removeFailure(newHead.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
}
listenerRegistry.removeContext(info);
}
}
}
- else
- {
- this.invalidRegistrations.remove(info);
- }
+ this.serviceFailures.remove(info);
}
}
@@ -360,13 +376,17 @@
{
this.registerWhiteboardService(h, info);
}
+ if (handlerList.isEmpty())
+ {
+ this.serviceFailures.put(info, FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING);
+ }
}
}
else
{
final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
SystemLogger.debug("Ignoring " + type + " service " + info.getServiceReference());
- this.invalidRegistrations.add(info);
+ this.serviceFailures.put(info, FAILURE_REASON_VALIDATION_FAILED);
}
}
}
@@ -393,10 +413,7 @@
}
}
}
- else
- {
- this.invalidRegistrations.remove(info);
- }
+ this.serviceFailures.remove(info);
}
}
@@ -407,21 +424,51 @@
*/
private void registerWhiteboardService(final ContextHandler handler, final WhiteboardServiceInfo<?> info)
{
- if ( info instanceof ServletInfo )
+ try
{
- this.httpService.registerServlet(handler, (ServletInfo)info);
+ if ( info instanceof ServletInfo )
+ {
+ this.httpService.registerServlet(handler, (ServletInfo)info);
+ }
+ else if ( info instanceof FilterInfo )
+ {
+ this.httpService.registerFilter(handler, (FilterInfo)info);
+ }
+ else if ( info instanceof ResourceInfo )
+ {
+ this.httpService.registerResource(handler, (ResourceInfo)info);
+ }
+
+ else if ( info instanceof ServletContextAttributeListenerInfo )
+ {
+ this.listenerRegistry.addListener((ServletContextAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionListenerInfo )
+ {
+ this.listenerRegistry.addListener((HttpSessionListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionAttributeListenerInfo )
+ {
+ this.listenerRegistry.addListener((HttpSessionAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestListenerInfo )
+ {
+ this.listenerRegistry.addListener((ServletRequestListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestAttributeListenerInfo )
+ {
+ this.listenerRegistry.addListener((ServletRequestAttributeListenerInfo) info, handler);
+ }
}
- else if ( info instanceof FilterInfo )
+ catch (RegistrationFailureException e)
{
- this.httpService.registerFilter(handler, (FilterInfo)info);
+ serviceFailures.put(e.getInfo(), e.getErrorCode());
+ SystemLogger.error("Exception while adding servlet", e);
}
- else if ( info instanceof ResourceInfo )
+ catch (RuntimeException e)
{
- this.httpService.registerResource(handler, (ResourceInfo)info);
- }
- else if ( info instanceof ListenerInfo )
- {
- this.listenerRegistry.addListener((ListenerInfo<?>)info, handler);
+ serviceFailures.put(info, FAILURE_REASON_UNKNOWN);
+ throw e;
}
}
@@ -432,21 +479,56 @@
*/
private void unregisterWhiteboardService(final ContextHandler handler, final WhiteboardServiceInfo<?> info)
{
- if ( info instanceof ServletInfo )
+ try
{
- this.httpService.unregisterServlet(handler, (ServletInfo)info);
+ if ( info instanceof ServletInfo )
+ {
+ this.httpService.unregisterServlet(handler, (ServletInfo)info);
+ }
+ else if ( info instanceof FilterInfo )
+ {
+ this.httpService.unregisterFilter(handler, (FilterInfo)info);
+ }
+ else if ( info instanceof ResourceInfo )
+ {
+ this.httpService.unregisterResource(handler, (ResourceInfo)info);
+ }
+
+ else if ( info instanceof ServletContextAttributeListenerInfo )
+ {
+ this.listenerRegistry.removeListener((ServletContextAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionListenerInfo )
+ {
+ this.listenerRegistry.removeListener((HttpSessionListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionAttributeListenerInfo )
+ {
+ this.listenerRegistry.removeListener((HttpSessionAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestListenerInfo )
+ {
+ this.listenerRegistry.removeListener((ServletRequestListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestAttributeListenerInfo )
+ {
+ this.listenerRegistry.removeListener((ServletRequestAttributeListenerInfo) info, handler);
+ }
}
- else if ( info instanceof FilterInfo )
+ catch (RegistrationFailureException e)
{
- this.httpService.unregisterFilter(handler, (FilterInfo)info);
+ serviceFailures.put(e.getInfo(), e.getErrorCode());
+ SystemLogger.error("Exception while removing servlet", e);
}
- else if ( info instanceof ResourceInfo )
+ serviceFailures.remove(info);
+ }
+
+ private void removeFailure(AbstractInfo<?> info, int failureCode)
+ {
+ Integer registeredFailureCode = this.serviceFailures.get(info);
+ if (registeredFailureCode != null && registeredFailureCode == failureCode)
{
- this.httpService.unregisterResource(handler, (ResourceInfo)info);
- }
- else if ( info instanceof ListenerInfo )
- {
- this.listenerRegistry.removeListener((ListenerInfo<?>)info, handler);
+ this.serviceFailures.remove(info);
}
}
@@ -506,21 +588,23 @@
public RegistryRuntime getRuntime(HandlerRegistry registry)
{
- List<HandlerRuntime> handlerRuntimes;
+ Collection<ServletContextHelperRuntime> contextRuntimes = new TreeSet<ServletContextHelperRuntime>(ServletContextHelperRuntime.COMPARATOR);
+ List<ContextRuntime> handlerRuntimes;
Map<Long, Collection<ServiceReference<?>>> listenerRuntimes;
- Set<ContextHandler> contextHandlers = new TreeSet<ContextHandler>();
+ FailureRuntime.Builder failureRuntime = FailureRuntime.builder();
synchronized ( this.contextMap )
{
for (List<ContextHandler> contextHandlerList : this.contextMap.values())
{
if ( !contextHandlerList.isEmpty() )
{
- contextHandlers.add(contextHandlerList.get(0));
+ contextRuntimes.add(contextHandlerList.get(0));
}
}
- handlerRuntimes = registry.getRuntime();
+ handlerRuntimes = registry.getRuntime(failureRuntime);
listenerRuntimes = listenerRegistry.getContextRuntimes();
+ failureRuntime.add(serviceFailures);
}
- return new RegistryRuntime(contextHandlers, handlerRuntimes, listenerRuntimes, this.invalidRegistrations);
+ return new RegistryRuntime(contextRuntimes, handlerRuntimes, listenerRuntimes, failureRuntime.build());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
index 10a6d40..f31a463 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
@@ -16,9 +16,11 @@
*/
package org.apache.felix.http.base.internal.whiteboard;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+
import javax.annotation.Nonnull;
import javax.servlet.Filter;
-import javax.servlet.Servlet;
import javax.servlet.ServletException;
import org.apache.felix.http.base.internal.handler.FilterHandler;
@@ -27,9 +29,9 @@
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.ResourceInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceObjects;
public final class WhiteboardHttpService
{
@@ -53,33 +55,47 @@
* Register a servlet.
* @param contextInfo The servlet context helper info
* @param servletInfo The servlet info
+ * @throws RegistrationFailureException
*/
public void registerServlet(@Nonnull final ContextHandler contextHandler,
@Nonnull final ServletInfo servletInfo)
+ throws RegistrationFailureException
{
- final PerContextHandlerRegistry registry = this.handlerRegistry.getRegistry(contextHandler.getContextInfo());
- if (registry != null)
- {
- try {
- ServletHandler handler = new ServletHandler(contextHandler.getContextInfo(),
- contextHandler.getServletContext(servletInfo.getServiceReference().getBundle()),
- servletInfo,
- null,
- true);
-
- registry.addServlet(handler);
- } catch (ServletException e) {
- // TODO create failure DTO
- }
- }
+ ServletContextHelperInfo contextInfo = contextHandler.getContextInfo();
+ final PerContextHandlerRegistry registry = this.handlerRegistry.getRegistry(contextInfo);
+ if (registry != null)
+ {
+ try
+ {
+ ServletHandler handler = new ServletHandler(contextHandler.getContextInfo(),
+ contextHandler.getServletContext(servletInfo.getServiceReference().getBundle()),
+ servletInfo,
+ null,
+ true);
+
+ registry.addServlet(handler);
+ }
+ catch (final RegistrationFailureException e)
+ {
+ throw e;
+ }
+ catch (final ServletException e)
+ {
+ throw new RegistrationFailureException(servletInfo, FAILURE_REASON_EXCEPTION_ON_INIT, e);
+ }
+ } else
+ {
+ throw new RegistrationFailureException(servletInfo, FAILURE_REASON_SERVICE_NOT_GETTABLE);
+ }
}
/**
* Unregister a servlet
* @param contextInfo The servlet context helper info
* @param servletInfo The servlet info
+ * @throws RegistrationFailureException
*/
- public void unregisterServlet(@Nonnull final ContextHandler contextHandler, @Nonnull final ServletInfo servletInfo)
+ public void unregisterServlet(@Nonnull final ContextHandler contextHandler, @Nonnull final ServletInfo servletInfo) throws RegistrationFailureException
{
final PerContextHandlerRegistry registry = this.handlerRegistry.getRegistry(contextHandler.getContextInfo());
if (registry != null )
@@ -93,12 +109,12 @@
* Register a filter
* @param contextInfo The servlet context helper info
* @param filterInfo The filter info
+ * @throws RegistrationFailureException
*/
public void registerFilter(@Nonnull final ContextHandler contextHandler,
- @Nonnull final FilterInfo filterInfo)
+ @Nonnull final FilterInfo filterInfo) throws RegistrationFailureException
{
final Filter filter = this.bundleContext.getServiceObjects(filterInfo.getServiceReference()).getService();
- // TODO create failure DTO if null
if ( filter != null )
{
final FilterHandler handler = new FilterHandler(contextHandler.getContextInfo(),
@@ -111,9 +127,19 @@
{
registry.addFilter(handler);
}
- } catch (final ServletException e) {
- // TODO create failure DTO
}
+ catch (final RegistrationFailureException e)
+ {
+ throw e;
+ }
+ catch (final ServletException e)
+ {
+ throw new RegistrationFailureException(filterInfo, FAILURE_REASON_EXCEPTION_ON_INIT, e);
+ }
+ }
+ else
+ {
+ throw new RegistrationFailureException(filterInfo, FAILURE_REASON_SERVICE_NOT_GETTABLE);
}
}
@@ -140,9 +166,10 @@
* Register a resource.
* @param contextInfo The servlet context helper info
* @param resourceInfo The resource info
+ * @throws RegistrationFailureException
*/
public void registerResource(@Nonnull final ContextHandler contextHandler,
- @Nonnull final ResourceInfo resourceInfo)
+ @Nonnull final ResourceInfo resourceInfo) throws RegistrationFailureException
{
final ServletInfo servletInfo = new ServletInfo(resourceInfo);
@@ -159,7 +186,7 @@
registry.addServlet(handler);
}
} catch (ServletException e) {
- // TODO create failure DTO
+ throw new RegistrationFailureException(resourceInfo, FAILURE_REASON_EXCEPTION_ON_INIT, e);
}
}
@@ -167,8 +194,9 @@
* Unregister a resource.
* @param contextInfo The servlet context helper info
* @param resourceInfo The resource info
+ * @throws RegistrationFailureException
*/
- public void unregisterResource(@Nonnull final ContextHandler contextHandler, @Nonnull final ResourceInfo resourceInfo)
+ public void unregisterResource(@Nonnull final ContextHandler contextHandler, @Nonnull final ResourceInfo resourceInfo) throws RegistrationFailureException
{
final ServletInfo servletInfo = new ServletInfo(resourceInfo);
final PerContextHandlerRegistry registry = this.handlerRegistry.getRegistry(contextHandler.getContextInfo());
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
index 624d2d3..00096af 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
@@ -19,7 +19,7 @@
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static javax.servlet.http.HttpServletResponse.SC_PAYMENT_REQUIRED;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -59,14 +59,14 @@
FilterHandler h2 = createHandler(10, "b");
FilterHandler h3 = createHandler(10, "c");
- assertEquals(0, h1.compareTo(h1));
+ assertTrue(h1.compareTo(h1) == 0);
- assertEquals(1, h1.compareTo(h2));
- assertEquals(-1, h2.compareTo(h1));
+ assertTrue(h1.compareTo(h2) > 0);
+ assertTrue(h2.compareTo(h1) < 0);
// h2 is actually registered first, so should be called first...
- assertEquals(-1, h2.compareTo(h3));
- assertEquals(1, h3.compareTo(h2));
+ assertTrue(h2.compareTo(h3) < 0);
+ assertTrue(h3.compareTo(h2) > 0);
}
@Test
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistryTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistryTest.java
index 9dfdc84..a2d767c 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistryTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistryTest.java
@@ -17,6 +17,7 @@
package org.apache.felix.http.base.internal.handler;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Collections;
@@ -32,7 +33,8 @@
public class PerContextHandlerRegistryTest
{
- @Test public void testPathOrdering()
+ @Test
+ public void testPathOrdering()
{
final List<PerContextHandlerRegistry> list = new ArrayList<PerContextHandlerRegistry>();
list.add(new PerContextHandlerRegistry(createServletContextHelperInfo("/", 1L, 0), null));
@@ -48,7 +50,8 @@
assertEquals(3L, list.get(3).getContextServiceId());
}
- @Test public void testRankingOrdering()
+ @Test
+ public void testRankingOrdering()
{
final List<PerContextHandlerRegistry> list = new ArrayList<PerContextHandlerRegistry>();
list.add(new PerContextHandlerRegistry(createServletContextHelperInfo("/", 1L, 0), null));
@@ -64,7 +67,8 @@
assertEquals(3L, list.get(3).getContextServiceId());
}
- @Test public void testOrderingSymetry()
+ @Test
+ public void testOrderingSymetry()
{
testSymetry("/", "/foo", 1L, 2L, 0, 0);
testSymetry("/", "/", 1L, 2L, 0, 10);
@@ -83,7 +87,8 @@
assertEquals(handlerRegistry.compareTo(other), -other.compareTo(handlerRegistry));
}
- @Test public void testOrderingTransitivity()
+ @Test
+ public void testOrderingTransitivity()
{
testTransitivity("/", "/foo", "/barrr", 1L, 2L, 3L, 0, 0, 0);
testTransitivity("/", "/", "/", 0L, 1L, 2L, 1, 2, 3);
@@ -92,22 +97,18 @@
testTransitivity("/", "/", "/", -2L, -1L, 0L, 0, 0, 0);
}
- private void testTransitivity(String highPath, String midPath, String lowPath,
- long highId, long midId, long lowId,
- int highRanking, int midRanking, int lowRanking)
+ private void testTransitivity(String highPath, String midPath, String lowPath, long highId, long midId, long lowId, int highRanking, int midRanking, int lowRanking)
{
PerContextHandlerRegistry high = new PerContextHandlerRegistry(createServletContextHelperInfo(highPath, highId, highRanking), null);
PerContextHandlerRegistry mid = new PerContextHandlerRegistry(createServletContextHelperInfo(midPath, midId, midRanking), null);
PerContextHandlerRegistry low = new PerContextHandlerRegistry(createServletContextHelperInfo(lowPath, lowId, lowRanking), null);
- assertEquals(1, high.compareTo(mid));
- assertEquals(1, mid.compareTo(low));
- assertEquals(1, high.compareTo(low));
+ assertTrue(high.compareTo(mid) > 0);
+ assertTrue(mid.compareTo(low) > 0);
+ assertTrue(high.compareTo(low) > 0);
}
- private ServletContextHelperInfo createServletContextHelperInfo(final String path,
- final long serviceId,
- final int ranking)
+ private ServletContextHelperInfo createServletContextHelperInfo(final String path, final long serviceId, final int ranking)
{
return WhiteboardServiceHelper.createContextInfo(ranking, serviceId, "", path, null);
}
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java
index 2108ee4..8e01e05 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java
@@ -34,25 +34,28 @@
import org.apache.felix.http.base.internal.context.ExtServletContext;
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.HandlerRuntime.ErrorPage;
+import org.apache.felix.http.base.internal.runtime.dto.ErrorPageRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.FilterRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.ServletRuntime;
+import org.osgi.framework.ServiceReference;
public final class WhiteboardServiceHelper
{
public static final AtomicLong ID_COUNTER = new AtomicLong();
- public static FilterHandler createTestFilterWithServiceId(String identifier,
+ public static FilterRuntime createTestFilterWithServiceId(String identifier,
ExtServletContext context)
{
return createTestFilter(identifier, context, ID_COUNTER.incrementAndGet());
}
- public static FilterHandler createTestFilter(String identifier,
+ public static FilterRuntime createTestFilter(String identifier,
ExtServletContext context)
{
return createTestFilter(identifier, context, -ID_COUNTER.incrementAndGet());
}
- private static FilterHandler createTestFilter(String identifier,
+ private static FilterRuntime createTestFilter(String identifier,
ExtServletContext context,
Long serviceId)
{
@@ -94,18 +97,18 @@
return info;
}
- public static ServletHandler createTestServletWithServiceId(String identifier,
+ public static ServletRuntime createTestServletWithServiceId(String identifier,
ExtServletContext context)
{
return createTestServlet(identifier, context, ID_COUNTER.incrementAndGet());
}
- public static ServletHandler createTestServlet(String identifier, ExtServletContext context)
+ public static ServletRuntime createTestServlet(String identifier, ExtServletContext context)
{
return createTestServlet(identifier, context, -ID_COUNTER.incrementAndGet());
}
- private static ServletHandler createTestServlet(String identifier,
+ private static ServletRuntime createTestServlet(String identifier,
ExtServletContext context,
Long serviceId)
{
@@ -136,7 +139,7 @@
serviceId,
name,
patterns,
- null,
+ errorPages,
asyncSupported,
initParams);
}
@@ -153,25 +156,25 @@
};
}
- public static ErrorPage createErrorPageWithServiceId(String identifier, ExtServletContext context)
+ public static ErrorPageRuntime createErrorPageWithServiceId(String identifier, ExtServletContext context)
{
return createErrorPage(identifier, context, ID_COUNTER.incrementAndGet());
}
- public static ErrorPage createErrorPage(String identifier, ExtServletContext context)
+ public static ErrorPageRuntime createErrorPage(String identifier, ExtServletContext context)
{
return createErrorPage(identifier, context, -ID_COUNTER.incrementAndGet());
}
- private static ErrorPage createErrorPage(String identifier,
+ private static ErrorPageRuntime createErrorPage(String identifier,
ExtServletContext context,
Long serviceId)
{
- ServletHandler servletHandler = createTestServlet(identifier, context, serviceId);
+ ServletRuntime servletHandler = createTestServlet(identifier, context, serviceId);
Collection<Integer> errorCodes = Arrays.asList(400, 500);
Collection<String> exceptions = Arrays.asList("Bad request", "Error");
- return new ErrorPage(servletHandler, errorCodes, exceptions);
+ return new ErrorPageRuntime(servletHandler, errorCodes, exceptions);
}
public static ServletContextHelperInfo createContextInfo(int serviceRanking,
@@ -186,4 +189,9 @@
path,
initParams);
}
+
+ public static ResourceInfo createContextInfo(ServiceReference<Object> ref)
+ {
+ return new ResourceInfo(ref);
+ }
}
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
index d495076..4d1a59d 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
@@ -58,10 +58,8 @@
import org.apache.felix.http.base.internal.context.ExtServletContext;
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.AbstractInfo;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime;
-import org.apache.felix.http.base.internal.runtime.HandlerRuntime.ErrorPage;
-import org.apache.felix.http.base.internal.runtime.RegistryRuntime;
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.whiteboard.ContextHandler;
@@ -85,6 +83,7 @@
import org.osgi.service.http.runtime.dto.RuntimeDTO;
import org.osgi.service.http.runtime.dto.ServletContextDTO;
import org.osgi.service.http.runtime.dto.ServletDTO;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
@RunWith(MockitoJUnitRunner.class)
public class RuntimeDTOBuilderTest
@@ -95,6 +94,8 @@
private static final Long ID_0 = -ID_COUNTER.incrementAndGet();
private static final Long ID_A = ID_COUNTER.incrementAndGet();
private static final Long ID_B = ID_COUNTER.incrementAndGet();
+ private static final Long ID_C = ID_COUNTER.incrementAndGet();
+ private static final Long ID_D = ID_COUNTER.incrementAndGet();
private static final Long ID_LISTENER_1 = ID_COUNTER.incrementAndGet();
private static final Long ID_LISTENER_2 = ID_COUNTER.incrementAndGet();
@@ -111,6 +112,15 @@
}
};
+ @SuppressWarnings("serial")
+ private static final Map<String, Object> RUNTIME_ATTRIBUTES = new HashMap<String, Object>()
+ {
+ {
+ put("attr_1", "val_1");
+ put("attr_2", "val_2");
+ }
+ };
+
@Mock private Bundle bundle;
@Mock private DTO testDTO;
@@ -118,10 +128,14 @@
@Mock private ExtServletContext context_0;
@Mock private ExtServletContext context_A;
@Mock private ExtServletContext context_B;
+ @Mock private ExtServletContext context_C;
+ @Mock private ExtServletContext context_D;
@Mock private ServiceReference<?> listener_1;
@Mock private ServiceReference<?> listener_2;
+ @Mock private ServiceReference<Object> resource;
+
private RegistryRuntime registry;
private Map<String, Object> runtimeAttributes;
private ListenerRegistry listenerRegistry;
@@ -130,11 +144,11 @@
public void setUp()
{
registry = null;
- runtimeAttributes = Collections.emptyMap();
+ runtimeAttributes = RUNTIME_ATTRIBUTES;
listenerRegistry = new ListenerRegistry(bundle);
}
- public ContextHandler setupContext(ServletContext context, String name, long serviceId)
+ public ServletContextHelperRuntime setupContext(ServletContext context, String name, long serviceId)
{
when(context.getServletContextName()).thenReturn(name);
@@ -146,13 +160,11 @@
when(context.getInitParameter("param_1")).thenReturn("init_val_1");
when(context.getInitParameter("param_2")).thenReturn("init_val_2");
- Map<String, String> initParemters = new HashMap<String, String>();
- initParemters.put("param_1", "init_val_1");
- initParemters.put("param_2", "init_val_2");
- ServletContextHelperInfo contextInfo = createContextInfo(0, serviceId, name, path, initParemters);
+ Map<String, String> initParameters = createInitParameterMap();
+ ServletContextHelperInfo contextInfo = createContextInfo(0, serviceId, name, path, initParameters);
PerContextEventListener eventListener = listenerRegistry.addContext(contextInfo);
- ContextHandler contextHandler = new ContextHandler(contextInfo, context, eventListener, bundle);
+ ServletContextHelperRuntime contextHandler = new ContextHandler(contextInfo, context, eventListener, bundle);
ServletContext sharedContext = contextHandler.getSharedContext();
sharedContext.setAttribute("intAttr", 1);
@@ -163,12 +175,21 @@
return contextHandler;
}
+ private Map<String, String> createInitParameterMap()
+ {
+ Map<String, String> initParameters = new HashMap<String, String>();
+ initParameters.put("param_1", "init_val_1");
+ initParameters.put("param_2", "init_val_2");
+ return initParameters;
+ }
+
@SuppressWarnings("unchecked")
public Map<Long, Collection<ServiceReference<?>>> setupListeners()
{
Map<Long, Collection<ServiceReference<?>>> listenerRuntimes = new HashMap<Long, Collection<ServiceReference<?>>>();
+
listenerRuntimes.put(ID_0, asList(listener_1, listener_2));
- listenerRuntimes.put(ID_A, Arrays.<ServiceReference<?>> asList(listener_1));
+ listenerRuntimes.put(ID_A, Arrays.<ServiceReference<?>>asList(listener_1));
listenerRuntimes.put(ID_B, asList(listener_1, listener_2));
when(listener_1.getProperty(Constants.SERVICE_ID)).thenReturn(ID_LISTENER_1);
@@ -182,50 +203,65 @@
return listenerRuntimes;
}
- public void setupRegistry(List<ContextHandler> contexts,
- List<HandlerRuntime> contextRuntimes,
- Map<Long, Collection<ServiceReference<?>>> listenerRuntimes)
+ public void setupResource()
{
- registry = new RegistryRuntime(contexts, contextRuntimes, listenerRuntimes, Collections.EMPTY_SET);
+ when(resource.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN)).thenReturn(new String[] { "/" });
+ when(resource.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX)).thenReturn("prefix");
+ }
+
+ public void setupRegistry(List<ServletContextHelperRuntime> contexts,
+ List<ContextRuntime> contextRuntimes,
+ Map<Long, Collection<ServiceReference<?>>> listenerRuntimes,
+ FailureRuntime failures)
+ {
+ registry = new RegistryRuntime(contexts, contextRuntimes, listenerRuntimes, failures);
}
@Test
public void buildRuntimeDTO()
{
- ContextHandler contextHelper_0 = setupContext(context_0, "0", ID_0);
- ContextHandler contextHelper_A = setupContext(context_A, "A", ID_A);
- ContextHandler contextHelper_B = setupContext(context_B, "B", ID_B);
+ ServletContextHelperRuntime contextHelper_0 = setupContext(context_0, "0", ID_0);
+ ServletContextHelperRuntime contextHelper_A = setupContext(context_A, "A", ID_A);
+ ServletContextHelperRuntime contextHelper_B = setupContext(context_B, "B", ID_B);
- List<ServletHandler> servlets_0 = asList(createTestServlet("1", context_0));
- List<FilterHandler> filters_0 = asList(createTestFilter("1", context_0));
- List<ServletHandler> resources_0 = asList(createTestServlet("1", context_0));
- List<ErrorPage> errorPages_0 = asList(createErrorPage("E_1", context_0));
- HandlerRuntime contextRuntime_0 = new HandlerRuntime(servlets_0, filters_0, resources_0, errorPages_0, ID_0);
+ List<ServletRuntime> servlets_0 = asList(createTestServlet("1", context_0));
+ List<FilterRuntime> filters_0 = asList(createTestFilter("1", context_0));
+ List<ServletRuntime> resources_0 = asList(createTestServlet("1", context_0));
+ List<ErrorPageRuntime> errorPages_0 = asList(createErrorPage("E_1", context_0));
+ ContextRuntime contextRuntime_0 = new ContextRuntime(servlets_0, filters_0, resources_0, errorPages_0, ID_0);
- List<ServletHandler> servlets_A = asList(createTestServlet("A_1", context_A));
- List<FilterHandler> filters_A = asList(createTestFilter("A_1", context_A));
- List<ServletHandler> resources_A = asList(createTestServlet("A_1", context_A));
- List<ErrorPage> errorPages_A = asList(createErrorPage("E_A_1", context_A));
- HandlerRuntime contextRuntime_A = new HandlerRuntime(servlets_A, filters_A, resources_A, errorPages_A, ID_A);
+ List<ServletRuntime> servlets_A = asList(createTestServlet("A_1", context_A));
+ List<FilterRuntime> filters_A = asList(createTestFilter("A_1", context_A));
+ List<ServletRuntime> resources_A = asList(createTestServlet("A_1", context_A));
+ List<ErrorPageRuntime> errorPages_A = asList(createErrorPage("E_A_1", context_A));
+ ContextRuntime contextRuntime_A = new ContextRuntime(servlets_A, filters_A, resources_A, errorPages_A, ID_A);
- List<ServletHandler> servlets_B = asList(createTestServletWithServiceId("B_1", context_B),
+ List<ServletRuntime> servlets_B = asList(createTestServletWithServiceId("B_1", context_B),
createTestServletWithServiceId("B_2", context_B));
- List<FilterHandler> filters_B = asList(createTestFilterWithServiceId("B_1", context_B),
+ List<FilterRuntime> filters_B = asList(createTestFilterWithServiceId("B_1", context_B),
createTestFilterWithServiceId("B_2", context_B));
- List<ServletHandler> resources_B = asList(createTestServletWithServiceId("B_1", context_B),
+ List<ServletRuntime> resources_B = asList(createTestServletWithServiceId("B_1", context_B),
createTestServletWithServiceId("B_2", context_B));
- List<ErrorPage> errorPages_B = asList(createErrorPageWithServiceId("E_B_1", context_B),
+ List<ErrorPageRuntime> errorPages_B = asList(createErrorPageWithServiceId("E_B_1", context_B),
createErrorPageWithServiceId("E_B_2", context_B));
- HandlerRuntime contextRuntime_B = new HandlerRuntime(servlets_B, filters_B, resources_B, errorPages_B, ID_B);
+ ContextRuntime contextRuntime_B = new ContextRuntime(servlets_B, filters_B, resources_B, errorPages_B, ID_B);
Map<Long, Collection<ServiceReference<?>>> listenerRuntimes = setupListeners();
setupRegistry(asList(contextHelper_0, contextHelper_A, contextHelper_B),
asList(contextRuntime_0, contextRuntime_A, contextRuntime_B),
- listenerRuntimes);
+ listenerRuntimes,
+ FailureRuntime.empty());
RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+ assertEquals(0, runtimeDTO.failedErrorPageDTOs.length);
+ assertEquals(0, runtimeDTO.failedFilterDTOs.length);
+ assertEquals(0, runtimeDTO.failedListenerDTOs.length);
+ assertEquals(0, runtimeDTO.failedResourceDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+
assertServletContextDTOs(runtimeDTO);
}
@@ -522,7 +558,7 @@
@Test
public void nullValuesInEntities() {
- ContextHandler contextHandler = setupContext(context_0, "0", ID_0);
+ ServletContextHelperRuntime contextHandler = setupContext(context_0, "0", ID_0);
ServletInfo servletInfo = createServletInfo(0,
ID_COUNTER.incrementAndGet(),
@@ -532,7 +568,7 @@
true,
Collections.<String, String>emptyMap());
Servlet servlet = mock(Servlet.class);
- ServletHandler servletHandler = new ServletHandler(null, context_0, servletInfo, servlet);
+ ServletRuntime servletHandler = new ServletHandler(null, context_0, servletInfo, servlet);
when(servlet.getServletInfo()).thenReturn("info_0");
FilterInfo filterInfo = createFilterInfo(0,
@@ -544,7 +580,7 @@
true,
null,
Collections.<String, String>emptyMap());
- FilterHandler filterHandler = new FilterHandler(null, context_0, mock(Filter.class), filterInfo);
+ FilterRuntime filterHandler = new FilterHandler(null, context_0, mock(Filter.class), filterInfo);
ServletInfo resourceInfo = createServletInfo(0,
ID_COUNTER.incrementAndGet(),
@@ -554,15 +590,16 @@
true,
Collections.<String, String>emptyMap());
Servlet resource = mock(Servlet.class);
- ServletHandler resourceHandler = new ServletHandler(null, context_0, resourceInfo, resource);
+ ServletRuntime resourceHandler = new ServletHandler(null, context_0, resourceInfo, resource);
- HandlerRuntime contextRuntime = new HandlerRuntime(asList(servletHandler),
+ ContextRuntime contextRuntime = new ContextRuntime(asList(servletHandler),
asList(filterHandler),
asList(resourceHandler),
- Collections.<ErrorPage>emptyList(),
+ Collections.<ErrorPageRuntime>emptyList(),
ID_0);
setupRegistry(asList(contextHandler), asList(contextRuntime),
- Collections.<Long, Collection<ServiceReference<?>>>emptyMap());
+ Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
+ FailureRuntime.empty());
RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
@@ -579,12 +616,13 @@
@Test
public void contextWithNoEntities() {
- ContextHandler contextHandler_0 = setupContext(context_0, "0", ID_0);
- ContextHandler contextHandler_A = setupContext(context_A, "A", ID_A);
+ ServletContextHelperRuntime contextHandler_0 = setupContext(context_0, "0", ID_0);
+ ServletContextHelperRuntime contextHandler_A = setupContext(context_A, "A", ID_A);
setupRegistry(asList(contextHandler_0, contextHandler_A),
- asList(HandlerRuntime.empty(ID_0), HandlerRuntime.empty(ID_A)),
- Collections.<Long, Collection<ServiceReference<?>>>emptyMap());
+ asList(ContextRuntime.empty(ID_0), ContextRuntime.empty(ID_A)),
+ Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
+ FailureRuntime.empty());
RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
@@ -601,7 +639,7 @@
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("patterns");
- ContextHandler contextHandler = setupContext(context_0, "0", ID_0);
+ ServletContextHelperRuntime contextHandler = setupContext(context_0, "0", ID_0);
ServletInfo servletInfo = createServletInfo(0,
ID_COUNTER.incrementAndGet(),
@@ -611,17 +649,144 @@
true,
Collections.<String, String>emptyMap());
Servlet servlet = mock(Servlet.class);
- ServletHandler servletHandler = new ServletHandler(null, context_0, servletInfo, servlet);
+ ServletRuntime servletHandler = new ServletHandler(null, context_0, servletInfo, servlet);
when(servlet.getServletInfo()).thenReturn("info_0");
- HandlerRuntime contextRuntime = new HandlerRuntime(asList(servletHandler),
- Collections.<FilterHandler>emptyList(),
- Collections.<ServletHandler>emptyList(),
- Collections.<ErrorPage>emptyList(),
+ ContextRuntime contextRuntime = new ContextRuntime(asList(servletHandler),
+ Collections.<FilterRuntime>emptyList(),
+ Collections.<ServletRuntime>emptyList(),
+ Collections.<ErrorPageRuntime>emptyList(),
ID_0);
setupRegistry(asList(contextHandler), asList(contextRuntime),
- Collections.<Long, Collection<ServiceReference<?>>> emptyMap());
+ Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
+ FailureRuntime.empty());
new RuntimeDTOBuilder(registry, runtimeAttributes).build();
}
+
+ public FailureRuntime setupFailures()
+ {
+ Map<AbstractInfo<?>, Integer> serviceFailures = new HashMap<AbstractInfo<?>, Integer>();
+
+ ServletContextHelperInfo contextInfo = createContextInfo(0,
+ ID_C,
+ "context_failure_1",
+ "/",
+ createInitParameterMap());
+ serviceFailures.put(contextInfo, 1);
+
+ contextInfo = createContextInfo(0,
+ ID_D,
+ "context_failure_2",
+ "/",
+ createInitParameterMap());
+ serviceFailures.put(contextInfo, 2);
+
+ ServletInfo servletInfo = createServletInfo(0, ID_COUNTER.incrementAndGet(),
+ "servlet_failure_1",
+ new String[] {"/"},
+ null,
+ false,
+ createInitParameterMap());
+ serviceFailures.put(servletInfo, 3);
+
+ servletInfo = createServletInfo(0, ID_COUNTER.incrementAndGet(),
+ "servlet_failure_2",
+ new String[] {"/"},
+ null,
+ false,
+ createInitParameterMap());
+ serviceFailures.put(servletInfo, 4);
+
+ FilterInfo filterInfo = createFilterInfo(0,
+ ID_COUNTER.incrementAndGet(),
+ "filter_failure_1",
+ new String[] {"/"},
+ null,
+ null,
+ false,
+ null,
+ createInitParameterMap());
+ serviceFailures.put(filterInfo, 5);
+
+ ServletInfo errorPageInfo = createServletInfo(0,
+ ID_COUNTER.incrementAndGet(),
+ "error_failure_1",
+ null,
+ new String[] { "405", "TestException" },
+ false,
+ createInitParameterMap());
+ serviceFailures.put(errorPageInfo, 6);
+
+ ServletInfo invalidErrorPageInfo = createServletInfo(0,
+ ID_COUNTER.incrementAndGet(),
+ "error_failure_2",
+ new String[] { "/" },
+ new String[] { "405", "TestException" },
+ false,
+ createInitParameterMap());
+ serviceFailures.put(invalidErrorPageInfo, 7);
+
+ return FailureRuntime.builder().add(serviceFailures).build();
+ }
+
+ @Test
+ public void testFailureDTOs()
+ {
+ setupRegistry(Collections.<ServletContextHelperRuntime>emptyList(),
+ Collections.<ContextRuntime>emptyList(),
+ Collections.<Long, Collection<ServiceReference<?>>>emptyMap(),
+ setupFailures());
+
+ RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+
+ assertEquals(0, runtimeDTO.servletContextDTOs.length);
+
+ assertEquals(2, runtimeDTO.failedErrorPageDTOs.length);
+ assertEquals(1, runtimeDTO.failedFilterDTOs.length);
+ // ListenerInfo is hard to setup
+ assertEquals(0, runtimeDTO.failedListenerDTOs.length);
+ // ResourceInfo is hard to setup
+ assertEquals(0, runtimeDTO.failedResourceDTOs.length);
+ assertEquals(2, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(2, runtimeDTO.failedServletDTOs.length);
+
+ assertEquals(1, runtimeDTO.failedServletContextDTOs[0].failureReason);
+ assertEquals(2, runtimeDTO.failedServletContextDTOs[1].failureReason);
+ assertEquals(3, runtimeDTO.failedServletDTOs[0].failureReason);
+ assertEquals(4, runtimeDTO.failedServletDTOs[1].failureReason);
+ assertEquals(5, runtimeDTO.failedFilterDTOs[0].failureReason);
+ assertEquals(6, runtimeDTO.failedErrorPageDTOs[0].failureReason);
+ assertEquals(7, runtimeDTO.failedErrorPageDTOs[1].failureReason);
+
+ assertEquals("context_failure_1", runtimeDTO.failedServletContextDTOs[0].name);
+ assertEquals("context_failure_2", runtimeDTO.failedServletContextDTOs[1].name);
+ assertEquals("servlet_failure_1", runtimeDTO.failedServletDTOs[0].name);
+ assertEquals("servlet_failure_2", runtimeDTO.failedServletDTOs[1].name);
+ assertEquals("filter_failure_1", runtimeDTO.failedFilterDTOs[0].name);
+ assertEquals("error_failure_1", runtimeDTO.failedErrorPageDTOs[0].name);
+ assertEquals("error_failure_2", runtimeDTO.failedErrorPageDTOs[1].name);
+
+ assertEquals(ID_C.longValue(), runtimeDTO.failedServletContextDTOs[0].serviceId);
+ assertEquals(ID_D.longValue(), runtimeDTO.failedServletContextDTOs[1].serviceId);
+ assertEquals(0, runtimeDTO.failedServletDTOs[0].servletContextId);
+ assertEquals(0, runtimeDTO.failedServletDTOs[1].servletContextId);
+ assertEquals(0, runtimeDTO.failedFilterDTOs[0].servletContextId);
+ assertEquals(0, runtimeDTO.failedErrorPageDTOs[0].servletContextId);
+ assertEquals(0, runtimeDTO.failedErrorPageDTOs[1].servletContextId);
+
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[0].errorPageDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[0].filterDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[0].listenerDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[0].resourceDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[0].servletDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[1].errorPageDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[1].filterDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[1].listenerDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[1].resourceDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs[1].servletDTOs.length);
+
+ assertTrue(runtimeDTO.failedServletContextDTOs[0].attributes.isEmpty());
+ assertTrue(runtimeDTO.failedServletContextDTOs[1].attributes.isEmpty());
+ }
}
\ No newline at end of file
diff --git a/http/bundle/pom.xml b/http/bundle/pom.xml
index 8323112..e73b008 100644
--- a/http/bundle/pom.xml
+++ b/http/bundle/pom.xml
@@ -123,7 +123,7 @@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>org.apache.felix.http.jetty</artifactId>
- <version>3.0.1-SNAPSHOT</version>
+ <version>3.0.3-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
diff --git a/http/itest/pom.xml b/http/itest/pom.xml
index d21661c..1d80cdb 100644
--- a/http/itest/pom.xml
+++ b/http/itest/pom.xml
@@ -79,8 +79,14 @@
</dependency>
<dependency>
<groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.8.2</version>
+ <artifactId>mockito-core</artifactId>
+ <version>1.10.19</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.objenesis</groupId>
+ <artifactId>objenesis</artifactId>
+ <version>2.1</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/http/itest/src/test/java/org/apache/felix/http/itest/BaseIntegrationTest.java b/http/itest/src/test/java/org/apache/felix/http/itest/BaseIntegrationTest.java
index e2998a2..562f09a 100644
--- a/http/itest/src/test/java/org/apache/felix/http/itest/BaseIntegrationTest.java
+++ b/http/itest/src/test/java/org/apache/felix/http/itest/BaseIntegrationTest.java
@@ -173,7 +173,7 @@
}
}
- private static final int DEFAULT_TIMEOUT = 10000;
+ protected static final int DEFAULT_TIMEOUT = 10000;
protected static final String ORG_APACHE_FELIX_HTTP_JETTY = "org.apache.felix.http.jetty";
@@ -334,6 +334,9 @@
mavenBundle("org.apache.felix", ORG_APACHE_FELIX_HTTP_JETTY).versionAsInProject().startLevel(START_LEVEL_SYSTEM_BUNDLES),
mavenBundle("org.apache.felix", "org.apache.felix.configadmin").versionAsInProject().startLevel(START_LEVEL_SYSTEM_BUNDLES),
+ mavenBundle("org.mockito", "mockito-core").versionAsInProject().startLevel(START_LEVEL_SYSTEM_BUNDLES),
+ mavenBundle("org.objenesis", "objenesis").versionAsInProject().startLevel(START_LEVEL_SYSTEM_BUNDLES),
+
junitBundles(), frameworkStartLevel(START_LEVEL_TEST_BUNDLE), felix());
}
@@ -373,18 +376,37 @@
*/
protected <T> T awaitService(String serviceName) throws Exception
{
- ServiceTracker<?, ?> tracker = null;
+ ServiceTracker<T, T> tracker = null;
+ tracker = getTracker(serviceName);
+ return tracker.waitForService(DEFAULT_TIMEOUT);
+ }
+
+ /**
+ * Return an array of {@code ServiceReference}s for all services for the
+ * given serviceName
+ * @param serviceName
+ * @return Array of {@code ServiceReference}s or {@code null} if no services
+ * are being tracked.
+ */
+ protected <T> ServiceReference<T>[] getServiceReferences(String serviceName)
+ {
+ ServiceTracker<T, T> tracker = getTracker(serviceName);
+ return tracker.getServiceReferences();
+ }
+
+ private <T> ServiceTracker<T, T> getTracker(String serviceName)
+ {
synchronized ( this.trackers )
{
- tracker = trackers.get(serviceName);
+ ServiceTracker<?, ?> tracker = trackers.get(serviceName);
if ( tracker == null )
{
- tracker = new ServiceTracker(m_context, serviceName, null);
+ tracker = new ServiceTracker<T, T>(m_context, serviceName, null);
trackers.put(serviceName, tracker);
tracker.open();
}
+ return (ServiceTracker<T, T>) tracker;
}
- return (T) tracker.waitForService(DEFAULT_TIMEOUT);
}
protected void configureHttpService(Dictionary<?, ?> props) throws Exception
diff --git a/http/itest/src/test/java/org/apache/felix/http/itest/EventListenerTest.java b/http/itest/src/test/java/org/apache/felix/http/itest/EventListenerTest.java
index 6fa9d37..fc8d1f9 100644
--- a/http/itest/src/test/java/org/apache/felix/http/itest/EventListenerTest.java
+++ b/http/itest/src/test/java/org/apache/felix/http/itest/EventListenerTest.java
@@ -18,8 +18,9 @@
*/
package org.apache.felix.http.itest;
-import static javax.servlet.http.HttpServletResponse.*;
-import static org.junit.Assert.*;
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+import static javax.servlet.http.HttpServletResponse.SC_SERVICE_UNAVAILABLE;
+import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.URL;
diff --git a/http/itest/src/test/java/org/apache/felix/http/itest/HttpServiceRuntimeTest.java b/http/itest/src/test/java/org/apache/felix/http/itest/HttpServiceRuntimeTest.java
new file mode 100644
index 0000000..98f20c0
--- /dev/null
+++ b/http/itest/src/test/java/org/apache/felix/http/itest/HttpServiceRuntimeTest.java
@@ -0,0 +1,1072 @@
+/*
+ * 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.itest;
+
+import static java.util.Arrays.asList;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.osgi.framework.Constants.SERVICE_ID;
+import static org.osgi.framework.Constants.SERVICE_RANKING;
+import static org.osgi.service.http.runtime.HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT_ATTRIBUTE;
+import static org.osgi.service.http.runtime.HttpServiceRuntimeConstants.HTTP_SERVICE_ID_ATTRIBUTE;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_VALIDATION_FAILED;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_NAME;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ERROR_PAGE;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_TARGET;
+
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionListener;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.context.ServletContextHelper;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
+import org.osgi.service.http.runtime.dto.FailedServletDTO;
+import org.osgi.service.http.runtime.dto.RuntimeDTO;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
+
+@RunWith(JUnit4TestRunner.class)
+public class HttpServiceRuntimeTest extends BaseIntegrationTest
+{
+ private static final long DEFAULT_SLEEP = 100;
+
+ private void registerServlet(String name, String path) throws InterruptedException
+ {
+ CountDownLatch initLatch = new CountDownLatch(1);
+ registerServlet(name, path, null, initLatch);
+ awaitServiceRegistration(initLatch);
+ }
+
+ private void registerServlet(String name, String path, CountDownLatch initLatch)
+ {
+ registerServlet(name, path, null, initLatch);
+ }
+
+ private void registerServlet(String name, String path, String context, CountDownLatch initLatch)
+ {
+ List<Object> propertyEntries = Arrays.<Object>asList(
+ HTTP_WHITEBOARD_SERVLET_PATTERN, path,
+ HTTP_WHITEBOARD_SERVLET_NAME, name,
+ HTTP_WHITEBOARD_CONTEXT_SELECT, context);
+
+ Dictionary<String, ?> properties = createDictionary(context == null ?
+ propertyEntries.subList(0, 4).toArray() : propertyEntries.toArray());
+
+ m_context.registerService(Servlet.class.getName(), new TestServlet(initLatch, null), properties);
+ }
+
+ private void registerFilter(String name, String path) throws InterruptedException
+ {
+ CountDownLatch initLatch = new CountDownLatch(1);
+ registerFilter(name, path, initLatch);
+ awaitServiceRegistration(initLatch);
+ }
+
+ private void registerFilter(String name, String path, CountDownLatch initLatch)
+ {
+ registerFilter(name, path, null, initLatch);
+ }
+
+ private void registerFilter(String name, String path, String context, CountDownLatch initLatch)
+ {
+ List<Object> propertyEntries = Arrays.<Object>asList(
+ HTTP_WHITEBOARD_FILTER_PATTERN, path,
+ HTTP_WHITEBOARD_FILTER_NAME, name,
+ HTTP_WHITEBOARD_CONTEXT_SELECT, context);
+
+ Dictionary<String, ?> properties = createDictionary(context == null ?
+ propertyEntries.subList(0, 4).toArray() : propertyEntries.toArray());
+
+ m_context.registerService(Filter.class.getName(), new TestFilter(initLatch, null), properties);
+ }
+
+ private void registerResource(String prefix, String path) throws InterruptedException
+ {
+ registerResource(prefix, path, null);
+ }
+
+ private void registerResource(String prefix, String path, String context) throws InterruptedException
+ {
+ List<Object> propertyEntries = Arrays.<Object>asList(
+ HTTP_WHITEBOARD_RESOURCE_PATTERN, path,
+ HTTP_WHITEBOARD_RESOURCE_PREFIX, prefix,
+ HTTP_WHITEBOARD_CONTEXT_SELECT, context);
+
+ Dictionary<String, ?> properties = createDictionary(context == null ?
+ propertyEntries.subList(0, 4).toArray() : propertyEntries.toArray());
+
+ m_context.registerService(TestResource.class.getName(), new TestResource(), properties);
+ awaitServiceRegistration();
+ }
+
+ private void registerErrorPage(String name, List<String> errors) throws InterruptedException
+ {
+ CountDownLatch initLatch = new CountDownLatch(1);
+ registerErrorPage(name, errors, initLatch);
+ awaitServiceRegistration(initLatch);
+ }
+
+ private void registerErrorPage(String name, List<String> errors, CountDownLatch initLatch)
+ {
+ registerErrorPage(name, errors, null, initLatch);
+ }
+
+ private void registerErrorPage(String name, List<String> errors, String context, CountDownLatch initLatch)
+ {
+ List<Object> propertyEntries = Arrays.<Object>asList(
+ HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, errors,
+ HTTP_WHITEBOARD_SERVLET_NAME, name,
+ HTTP_WHITEBOARD_CONTEXT_SELECT, context);
+
+ Dictionary<String, ?> properties = createDictionary(context == null ?
+ propertyEntries.subList(0, 4).toArray() : propertyEntries.toArray());
+
+ m_context.registerService(Servlet.class.getName(), new TestServlet(initLatch, null), properties);
+ }
+
+ private void registerListener(Class<?> listenerClass, boolean useWithWhiteboard) throws InterruptedException
+ {
+ registerListener(listenerClass, useWithWhiteboard, null);
+ }
+
+ private void registerListener(Class<?> listenerClass, boolean useWithWhiteboard, String context) throws InterruptedException
+ {
+ List<Object> propertyEntries = Arrays.<Object>asList(
+ HTTP_WHITEBOARD_LISTENER, useWithWhiteboard ? "true" : "false",
+ HTTP_WHITEBOARD_CONTEXT_SELECT, context);
+
+ Dictionary<String, ?> properties = createDictionary(context == null ?
+ propertyEntries.subList(0, 2).toArray() : propertyEntries.toArray());
+
+ m_context.registerService(listenerClass.getName(), mock(listenerClass), properties);
+ awaitServiceRegistration();
+ }
+
+ private ServiceRegistration<?> registerContext(String name, String path) throws InterruptedException
+ {
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_CONTEXT_NAME, name,
+ HTTP_WHITEBOARD_CONTEXT_PATH, path);
+
+ ServiceRegistration<?> contextRegistration = m_context.registerService(ServletContextHelper.class.getName(), mock(ServletContextHelper.class), properties);
+ awaitServiceRegistration();
+ return contextRegistration;
+ }
+
+ @Before
+ public void awaitServiceRuntime() throws Exception
+ {
+ awaitService(HttpServiceRuntime.class.getName());
+ }
+
+ @Test
+ public void httpRuntimeServiceIsAvailableAfterBundleActivation() throws Exception
+ {
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+ Map<String, String> runtimeDTOAttributes = runtimeDTO.attributes;
+
+ assertNotNull(runtimeDTOAttributes);
+ assertTrue(runtimeDTOAttributes.containsKey(HTTP_SERVICE_ID_ATTRIBUTE));
+ assertTrue(runtimeDTOAttributes.containsKey(HTTP_SERVICE_ENDPOINT_ATTRIBUTE));
+ assertTrue(0 < Integer.valueOf(runtimeDTOAttributes.get(HTTP_SERVICE_ID_ATTRIBUTE)));
+
+ assertEquals(0, runtimeDTO.failedErrorPageDTOs.length);
+ assertEquals(0, runtimeDTO.failedFilterDTOs.length);
+ assertEquals(0, runtimeDTO.failedListenerDTOs.length);
+ assertEquals(0, runtimeDTO.failedResourceDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+
+ assertEquals(1, runtimeDTO.servletContextDTOs.length);
+ assertEquals("default", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].attributes.size());
+
+ // TODO The default context should have a negative service Id
+// assertTrue(0 > runtimeDTO.servletContextDTOs[0].serviceId);
+ assertEquals("", runtimeDTO.servletContextDTOs[0].contextPath);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].initParams.size());
+
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].filterDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].resourceDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].errorPageDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].listenerDTOs.length);
+ }
+
+ @Test
+ public void dtosForSuccesfullyRegisteredServlets() throws Exception
+ {
+ //register first servlet
+ registerServlet("testServlet 1", "/servlet_1");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTOWithFirstSerlvet = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithFirstSerlvet.failedServletDTOs.length);
+
+ ServletContextDTO contextDTO = assertDefaultContext(runtimeDTOWithFirstSerlvet);
+ assertEquals(1, contextDTO.servletDTOs.length);
+ assertEquals("testServlet 1", contextDTO.servletDTOs[0].name);
+
+ //register second servlet
+ registerServlet("testServlet 2", "/servlet_2");
+
+ RuntimeDTO runtimeDTOWithBothSerlvets = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithBothSerlvets.failedServletDTOs.length);
+
+ contextDTO = assertDefaultContext(runtimeDTOWithBothSerlvets);
+ assertEquals(2, contextDTO.servletDTOs.length);
+ assertEquals("testServlet 1", contextDTO.servletDTOs[0].name);
+ assertEquals("testServlet 2", contextDTO.servletDTOs[1].name);
+ }
+
+ @Test
+ public void dtosForSuccesfullyRegisteredFilters() throws Exception
+ {
+ //register first filter
+ registerFilter("testFilter 1", "/servlet_1");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTOWithFirstFilter = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithFirstFilter.failedFilterDTOs.length);
+
+ ServletContextDTO contextDTO = assertDefaultContext(runtimeDTOWithFirstFilter);
+ assertEquals(1, contextDTO.filterDTOs.length);
+ assertEquals("testFilter 1", contextDTO.filterDTOs[0].name);
+
+ //register second filter
+ registerFilter("testFilter 2", "/servlet_1");
+
+ RuntimeDTO runtimeDTOWithBothFilters = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithBothFilters.failedFilterDTOs.length);
+
+ contextDTO = assertDefaultContext(runtimeDTOWithBothFilters);
+ assertEquals(2, contextDTO.filterDTOs.length);
+ assertEquals("testFilter 1", contextDTO.filterDTOs[0].name);
+ assertEquals("testFilter 2", contextDTO.filterDTOs[1].name);
+ }
+
+ @Test
+ public void dtosForSuccesfullyRegisteredResources() throws Exception
+ {
+ // register first resource service
+ registerResource("/resources", "/resource_1/*");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTOWithFirstResource = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithFirstResource.failedResourceDTOs.length);
+
+ ServletContextDTO contextDTO = assertDefaultContext(runtimeDTOWithFirstResource);
+ assertEquals(1, contextDTO.resourceDTOs.length);
+ assertEquals("/resources", contextDTO.resourceDTOs[0].prefix);
+ assertArrayEquals(new String[] { "/resource_1/*" }, contextDTO.resourceDTOs[0].patterns);
+
+ // register second resource service
+ registerResource("/resources", "/resource_2/*");
+
+ RuntimeDTO runtimeDTOWithBothResources = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithBothResources.failedResourceDTOs.length);
+
+ contextDTO = assertDefaultContext(runtimeDTOWithBothResources);
+ assertEquals(2, contextDTO.resourceDTOs.length);
+ assertEquals("/resources", contextDTO.resourceDTOs[0].prefix);
+ assertArrayEquals(new String[] { "/resource_1/*" }, contextDTO.resourceDTOs[0].patterns);
+ assertEquals("/resources", contextDTO.resourceDTOs[1].prefix);
+ assertArrayEquals(new String[] { "/resource_2/*" }, contextDTO.resourceDTOs[1].patterns);
+ }
+
+ @Test
+ public void dtosForSuccesfullyRegisteredErrorPages() throws Exception
+ {
+ // register first error page
+ registerErrorPage("error page 1", asList("404", NoSuchElementException.class.getName()));
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTOWithFirstErrorPage = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithFirstErrorPage.failedServletDTOs.length);
+ assertEquals(0, runtimeDTOWithFirstErrorPage.failedErrorPageDTOs.length);
+
+ ServletContextDTO contextDTO = runtimeDTOWithFirstErrorPage.servletContextDTOs[0];
+ assertEquals(1, contextDTO.errorPageDTOs.length);
+ assertEquals("error page 1", contextDTO.errorPageDTOs[0].name);
+ assertArrayEquals(new String[] { NoSuchElementException.class.getName() }, contextDTO.errorPageDTOs[0].exceptions);
+ assertArrayEquals(new long[] { 404 }, contextDTO.errorPageDTOs[0].errorCodes);
+
+ // register second error page
+ registerErrorPage("error page 2", asList("500", ServletException.class.getName()));
+
+ RuntimeDTO runtimeDTOWithBothErrorPages = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithBothErrorPages.failedServletDTOs.length);
+ assertEquals(0, runtimeDTOWithBothErrorPages.failedErrorPageDTOs.length);
+
+ contextDTO = assertDefaultContext(runtimeDTOWithBothErrorPages);
+ assertEquals(2, contextDTO.errorPageDTOs.length);
+ assertEquals("error page 1", contextDTO.errorPageDTOs[0].name);
+ assertEquals("error page 2", contextDTO.errorPageDTOs[1].name);
+ assertArrayEquals(new String[] { ServletException.class.getName() }, contextDTO.errorPageDTOs[1].exceptions);
+ assertArrayEquals(new long[] { 500 }, contextDTO.errorPageDTOs[1].errorCodes);
+ }
+
+ @Test
+ public void dtosForSuccesfullyRegisteredListeners() throws Exception
+ {
+ // register a servlet context listenere as first listener
+ registerListener(ServletContextListener.class, true);
+ awaitService(ServletContextListener.class.getName());
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTOWithFirstListener = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithFirstListener.failedListenerDTOs.length);
+ assertEquals(1, runtimeDTOWithFirstListener.servletContextDTOs.length);
+
+ ServletContextDTO contextDTO = runtimeDTOWithFirstListener.servletContextDTOs[0];
+ // TODO fix : servlet context listener is only added when registerd before context activation
+ assertEquals(0, contextDTO.listenerDTOs.length);
+ // TODO
+// assertEquals(ServletContextListener.class.getName(), contextDTO.listenerDTOs[0].types[0]);
+
+ // register all other listener types
+ registerListener(ServletContextAttributeListener.class, true);
+ registerListener(ServletRequestListener.class, true);
+ registerListener(ServletRequestAttributeListener.class, true);
+ registerListener(HttpSessionListener.class, true);
+ registerListener(HttpSessionAttributeListener.class, true);
+
+ awaitService(ServletContextAttributeListener.class.getName());
+ awaitService(ServletRequestListener.class.getName());
+ awaitService(ServletRequestAttributeListener.class.getName());
+ awaitService(HttpSessionListener.class.getName());
+ awaitService(HttpSessionAttributeListener.class.getName());
+
+ RuntimeDTO runtimeDTOWithAllListeners = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithAllListeners.failedListenerDTOs.length);
+ assertEquals(1, runtimeDTOWithAllListeners.servletContextDTOs.length);
+
+ contextDTO = runtimeDTOWithAllListeners.servletContextDTOs[0];
+ // TODO
+ assertEquals(5, contextDTO.listenerDTOs.length);
+// assertEquals(ServletContextListener.class.getName(), contextDTO.listenerDTOs[0].types[0]);
+ assertEquals(ServletContextAttributeListener.class.getName(), contextDTO.listenerDTOs[0].types[0]);
+ assertEquals(ServletRequestListener.class.getName(), contextDTO.listenerDTOs[1].types[0]);
+ assertEquals(ServletRequestAttributeListener.class.getName(), contextDTO.listenerDTOs[2].types[0]);
+ assertEquals(HttpSessionListener.class.getName(), contextDTO.listenerDTOs[3].types[0]);
+ assertEquals(HttpSessionAttributeListener.class.getName(), contextDTO.listenerDTOs[4].types[0]);
+ }
+
+ @Test
+ public void dtosForSuccesfullyRegisteredContexts() throws Exception
+ {
+ // register first additional context
+ registerContext("contextA", "/contextA");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTOWithAdditionalContext = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithAdditionalContext.failedServletContextDTOs.length);
+ assertEquals(2, runtimeDTOWithAdditionalContext.servletContextDTOs.length);
+
+ // default context is last, as it has the lowest service ranking
+ assertEquals("contextA", runtimeDTOWithAdditionalContext.servletContextDTOs[0].name);
+ assertEquals("/contextA", runtimeDTOWithAdditionalContext.servletContextDTOs[0].contextPath);
+ assertEquals("default", runtimeDTOWithAdditionalContext.servletContextDTOs[1].name);
+ // TODO should this be "/" ?
+ assertEquals("", runtimeDTOWithAdditionalContext.servletContextDTOs[1].contextPath);
+
+ // register second additional context
+ registerContext("contextB", "/contextB");
+
+ RuntimeDTO runtimeDTOWithAllContexts = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTOWithAllContexts.failedServletContextDTOs.length);
+ assertEquals(3, runtimeDTOWithAllContexts.servletContextDTOs.length);
+
+ // default context is last, as it has the lowest service ranking
+ assertEquals("contextA", runtimeDTOWithAllContexts.servletContextDTOs[0].name);
+ assertEquals("/contextA", runtimeDTOWithAllContexts.servletContextDTOs[0].contextPath);
+ assertEquals("contextB", runtimeDTOWithAllContexts.servletContextDTOs[1].name);
+ assertEquals("/contextB", runtimeDTOWithAllContexts.servletContextDTOs[1].contextPath);
+ assertEquals("default", runtimeDTOWithAllContexts.servletContextDTOs[2].name);
+ assertEquals("", runtimeDTOWithAllContexts.servletContextDTOs[2].contextPath);
+ }
+
+ @Test
+ public void successfulSetup() throws InterruptedException
+ {
+ CountDownLatch initLatch = new CountDownLatch(6);
+
+ registerContext("test-context", "/test-context");
+
+ registerServlet("default servlet", "/default", initLatch);
+ registerFilter("default filter", "/default", initLatch);
+ registerErrorPage("default error page", asList(Exception.class.getName()), initLatch);
+ registerResource("/", "/default/resource");
+ registerListener(ServletRequestListener.class, true);
+
+ registerServlet("context servlet", "/default", "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=test-context)", initLatch);
+ registerFilter("context filter", "/default", "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=test-context)", initLatch);
+ registerErrorPage("context error page", asList("500"), "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=test-context)", initLatch);
+ registerResource("/", "/test-contextd/resource", "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=test-context)");
+ registerListener(ServletRequestListener.class, true, "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=test-context)");
+
+ awaitServiceRegistration(initLatch);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedErrorPageDTOs.length);
+ assertEquals(0, runtimeDTO.failedFilterDTOs.length);
+ assertEquals(0, runtimeDTO.failedListenerDTOs.length);
+ assertEquals(0, runtimeDTO.failedResourceDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+ assertEquals("test-context", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals("default", runtimeDTO.servletContextDTOs[1].name);
+
+ ServletContextDTO defaultContextDTO = runtimeDTO.servletContextDTOs[1];
+ long contextServiceId = defaultContextDTO.serviceId;
+
+ assertEquals(1, defaultContextDTO.servletDTOs.length);
+ assertEquals("default servlet", defaultContextDTO.servletDTOs[0].name);
+ assertEquals(contextServiceId, defaultContextDTO.servletDTOs[0].servletContextId);
+ assertEquals(1, defaultContextDTO.filterDTOs.length);
+ assertEquals("default filter", defaultContextDTO.filterDTOs[0].name);
+ assertEquals(contextServiceId, defaultContextDTO.filterDTOs[0].servletContextId);
+ assertEquals(1, defaultContextDTO.errorPageDTOs.length);
+ assertEquals(Exception.class.getName(), defaultContextDTO.errorPageDTOs[0].exceptions[0]);
+ assertEquals(contextServiceId, defaultContextDTO.errorPageDTOs[0].servletContextId);
+ assertEquals(1, defaultContextDTO.listenerDTOs.length);
+ assertEquals(ServletRequestListener.class.getName(), defaultContextDTO.listenerDTOs[0].types[0]);
+ assertEquals(contextServiceId, defaultContextDTO.listenerDTOs[0].servletContextId);
+
+ ServletContextDTO testContextDTO = runtimeDTO.servletContextDTOs[0];
+ contextServiceId = testContextDTO.serviceId;
+
+ assertEquals(1, testContextDTO.servletDTOs.length);
+ assertEquals("context servlet", testContextDTO.servletDTOs[0].name);
+ assertEquals(contextServiceId, testContextDTO.servletDTOs[0].servletContextId);
+ assertEquals(1, testContextDTO.filterDTOs.length);
+ assertEquals("context filter", testContextDTO.filterDTOs[0].name);
+ assertEquals(contextServiceId, testContextDTO.filterDTOs[0].servletContextId);
+ assertEquals(1, testContextDTO.errorPageDTOs.length);
+ assertEquals(500L, testContextDTO.errorPageDTOs[0].errorCodes[0]);
+ assertEquals(contextServiceId, testContextDTO.errorPageDTOs[0].servletContextId);
+ assertEquals(1, testContextDTO.listenerDTOs.length);
+ assertEquals(ServletRequestListener.class.getName(), testContextDTO.listenerDTOs[0].types[0]);
+ assertEquals(contextServiceId, testContextDTO.listenerDTOs[0].servletContextId);
+ }
+
+ @Test
+ public void exceptionInServletInitAppearsAsFailure() throws ServletException, InterruptedException
+ {
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_SERVLET_PATTERN, "/servlet",
+ HTTP_WHITEBOARD_SERVLET_NAME, "servlet");
+
+ CountDownLatch initLatch = new CountDownLatch(1);
+
+ @SuppressWarnings("serial")
+ Servlet failingServlet = new TestServlet(initLatch, null) {
+ @Override
+ public void init() throws ServletException
+ {
+ super.init();
+ throw new ServletException();
+ }
+ };
+
+ m_context.registerService(Servlet.class.getName(), failingServlet, properties);
+ awaitServiceRegistration(initLatch);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+ assertEquals(1, runtimeDTO.failedServletDTOs.length);
+ assertEquals("servlet", runtimeDTO.failedServletDTOs[0].name);
+ assertEquals(FAILURE_REASON_EXCEPTION_ON_INIT, runtimeDTO.failedServletDTOs[0].failureReason);
+ }
+
+ @Test
+ public void exceptionInFilterInitAppearsAsFailure() throws ServletException, InterruptedException
+ {
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_FILTER_PATTERN, "/filter",
+ HTTP_WHITEBOARD_FILTER_NAME, "filter");
+
+ CountDownLatch initLatch = new CountDownLatch(1);
+
+ Filter failingFilter = new TestFilter(initLatch, null) {
+ @Override
+ public void init(FilterConfig config) throws ServletException
+ {
+ super.init(config);
+ throw new ServletException();
+ }
+ };
+
+ m_context.registerService(Filter.class.getName(), failingFilter, properties);
+ awaitServiceRegistration(initLatch);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+ assertEquals(1, runtimeDTO.failedFilterDTOs.length);
+ assertEquals("filter", runtimeDTO.failedFilterDTOs[0].name);
+ assertEquals(FAILURE_REASON_EXCEPTION_ON_INIT, runtimeDTO.failedFilterDTOs[0].failureReason);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.1 (TODO : exact version)
+ @Test
+ public void hiddenDefaultContextAppearsAsFailure() throws InterruptedException
+ {
+ registerContext("default", "");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+ assertEquals(1, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals("default", runtimeDTO.failedServletContextDTOs[0].name);
+ assertDefaultContext(runtimeDTO);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.1
+ @Test
+ public void contextHelperWithDuplicateNameAppearsAsFailure() throws InterruptedException
+ {
+ ServiceRegistration<?> firstContextReg = registerContext("contextA", "/first");
+ registerContext("contextA", "/second");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals("contextA", runtimeDTO.failedServletContextDTOs[0].name);
+ assertEquals("/second", runtimeDTO.failedServletContextDTOs[0].contextPath);
+ assertEquals(FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, runtimeDTO.failedServletContextDTOs[0].failureReason);
+
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+ assertEquals("default", runtimeDTO.servletContextDTOs[1].name);
+
+ assertEquals("contextA", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals("/first", runtimeDTO.servletContextDTOs[0].contextPath);
+
+ firstContextReg.unregister();
+
+ runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
+
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+ assertEquals("default", runtimeDTO.servletContextDTOs[1].name);
+
+ assertEquals("contextA", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals("/second", runtimeDTO.servletContextDTOs[0].contextPath);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.1
+ @Test
+ public void missingContextHelperNameAppearsAsFailure()
+ {
+ Dictionary<String, ?> properties = createDictionary(HTTP_WHITEBOARD_CONTEXT_PATH, "");
+
+ m_context.registerService(ServletContextHelper.class.getName(), mock(ServletContextHelper.class), properties);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(null, runtimeDTO.failedServletContextDTOs[0].name);
+ assertEquals(FAILURE_REASON_VALIDATION_FAILED, runtimeDTO.failedServletContextDTOs[0].failureReason);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.1
+ @Test
+ public void invalidContextHelperNameAppearsAsFailure() throws InterruptedException
+ {
+ registerContext("context A", "");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals("context A", runtimeDTO.failedServletContextDTOs[0].name);
+ assertEquals(FAILURE_REASON_VALIDATION_FAILED, runtimeDTO.failedServletContextDTOs[0].failureReason);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.1
+ @Test
+ public void invalidContextHelperPathAppearsAsFailure() throws InterruptedException
+ {
+ registerContext("contextA", "#");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals("#", runtimeDTO.failedServletContextDTOs[0].contextPath);
+ assertEquals(FAILURE_REASON_VALIDATION_FAILED, runtimeDTO.failedServletContextDTOs[0].failureReason);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.3
+ @Test
+ public void selectionOfNonExistingContextHelperAppearsAsFailure() throws InterruptedException
+ {
+ registerServlet("servlet 1", "/", "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=contextA)", null);
+ awaitServiceRegistration();
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.failedServletDTOs.length);
+ assertEquals("servlet 1", runtimeDTO.failedServletDTOs[0].name);
+ assertEquals(FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING, runtimeDTO.failedServletDTOs[0].failureReason);
+
+ registerContext("contextA", "/contextA");
+
+ runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+ assertEquals("contextA", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals(1, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertEquals("servlet 1", runtimeDTO.servletContextDTOs[0].servletDTOs[0].name);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.3
+ @Test
+ public void differentTargetIsIgnored() throws InterruptedException
+ {
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_SERVLET_PATTERN, "/servlet",
+ HTTP_WHITEBOARD_SERVLET_NAME, "servlet",
+ HTTP_WHITEBOARD_TARGET, "(org.osgi.service.http.port=8282)");
+
+ m_context.registerService(Servlet.class.getName(), new TestServlet(), properties);
+ awaitServiceRegistration();
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+
+ ServletContextDTO defaultContext = assertDefaultContext(runtimeDTO);
+ assertEquals(0, defaultContext.servletDTOs.length);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.4
+ @Test
+ public void servletWithoutNameGetsFullyQualifiedName() throws InterruptedException
+ {
+ Dictionary<String, ?> properties = createDictionary(HTTP_WHITEBOARD_SERVLET_PATTERN, "/servlet");
+
+ CountDownLatch initLatch = new CountDownLatch(1);
+ m_context.registerService(Servlet.class.getName(), new TestServlet(initLatch, null), properties);
+ awaitServiceRegistration(initLatch);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+
+ ServletContextDTO defaultContext = assertDefaultContext(serviceRuntime.getRuntimeDTO());
+ assertEquals(1, defaultContext.servletDTOs.length);
+ assertEquals(TestServlet.class.getName(), defaultContext.servletDTOs[0].name);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.4.1
+ @Test
+ public void patternAndErrorPageSpecifiedInvalidAndAppearsAsFailure() throws InterruptedException
+ {
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_SERVLET_PATTERN, "/servlet",
+ HTTP_WHITEBOARD_SERVLET_NAME, "servlet",
+ HTTP_WHITEBOARD_SERVLET_ERROR_PAGE, asList("400"));
+
+ m_context.registerService(Servlet.class.getName(), new TestServlet(), properties);
+ awaitServiceRegistration();
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ ServletContextDTO defaultContext = assertDefaultContext(serviceRuntime.getRuntimeDTO());
+ assertEquals(0, defaultContext.servletDTOs.length);
+ assertEquals(0, defaultContext.errorPageDTOs.length);
+
+ assertEquals(0, serviceRuntime.getRuntimeDTO().failedServletDTOs.length);
+ assertEquals(1, serviceRuntime.getRuntimeDTO().failedErrorPageDTOs.length);
+ assertEquals("servlet", serviceRuntime.getRuntimeDTO().failedErrorPageDTOs[0].name);
+ assertEquals(FAILURE_REASON_VALIDATION_FAILED, serviceRuntime.getRuntimeDTO().failedErrorPageDTOs[0].failureReason);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.4.1
+ @Test
+ public void multipleServletsForSamePatternChoosenByServiceRankingRules() throws InterruptedException
+ {
+ registerServlet("servlet 1", "/pathcollision");
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+ ServletContextDTO defaultContext = assertDefaultContext(runtimeDTO);
+ assertEquals(1, defaultContext.servletDTOs.length);
+
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_SERVLET_PATTERN, "/pathcollision",
+ HTTP_WHITEBOARD_SERVLET_NAME, "servlet 2",
+ SERVICE_RANKING, Integer.MAX_VALUE);
+
+ CountDownLatch initLatch = new CountDownLatch(1);
+ CountDownLatch destroyLatch = new CountDownLatch(1);
+ TestServlet testServlet = new TestServlet(initLatch, destroyLatch);
+ ServiceRegistration<?> higherRankingServlet = m_context.registerService(Servlet.class.getName(), testServlet, properties);
+
+ RuntimeDTO runtimeWithShadowedServlet = serviceRuntime.getRuntimeDTO();
+ awaitServiceRegistration(initLatch);
+
+ defaultContext = assertDefaultContext(runtimeWithShadowedServlet);
+ assertEquals(1, defaultContext.servletDTOs.length);
+
+ assertEquals(1, runtimeWithShadowedServlet.failedServletDTOs.length);
+ FailedServletDTO failedServletDTO = runtimeWithShadowedServlet.failedServletDTOs[0];
+ assertEquals("servlet 1", failedServletDTO.name);
+ assertEquals(FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE, failedServletDTO.failureReason);
+
+ higherRankingServlet.unregister();
+ awaitServiceRegistration(destroyLatch);
+
+ runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletDTOs.length);
+ defaultContext = assertDefaultContext(runtimeDTO);
+ assertEquals(1, defaultContext.servletDTOs.length);
+ assertEquals("servlet 1", defaultContext.servletDTOs[0].name);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.4.1
+ @Test
+ @Ignore
+ public void multipleErrorPagesForSameExceptionsChoosenByServiceRankingRules()
+ {
+ // TODO
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.4
+ @Test
+ @Ignore
+ public void mulitpleServletsWithSamePatternHttpServiceRegistrationWins()
+ {
+ // TODO
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.7
+ @Test
+ public void invalidListenerPopertyValueAppearsAsFailure() throws Exception
+ {
+ Dictionary<String, ?> properties = createDictionary(HTTP_WHITEBOARD_LISTENER, "invalid");
+
+ m_context.registerService(ServletRequestListener.class.getName(), mock(ServletRequestListener.class), properties);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.failedListenerDTOs.length);
+ assertEquals(FAILURE_REASON_VALIDATION_FAILED, runtimeDTO.failedListenerDTOs[0].failureReason);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.8
+ @Test
+ public void contextReplacedWithHigherRankingContext() throws Exception
+ {
+ ServiceRegistration<?> firstContext = registerContext("test-context", "/first");
+ Long firstContextId = (Long) firstContext.getReference().getProperty(Constants.SERVICE_ID);
+
+ CountDownLatch initLatch = new CountDownLatch(1);
+ registerServlet("servlet", "/servlet", "(" + HTTP_WHITEBOARD_CONTEXT_NAME + "=test-context)", initLatch);
+ awaitServiceRegistration(initLatch);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+ assertEquals(firstContextId.longValue(), runtimeDTO.servletContextDTOs[0].serviceId);
+ assertEquals("test-context", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals("/first", runtimeDTO.servletContextDTOs[0].contextPath);
+ assertEquals("default", runtimeDTO.servletContextDTOs[1].name);
+
+ assertEquals(1, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertEquals("servlet", runtimeDTO.servletContextDTOs[0].servletDTOs[0].name);
+
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_CONTEXT_NAME, "test-context",
+ HTTP_WHITEBOARD_CONTEXT_PATH, "/second",
+ SERVICE_RANKING, Integer.MAX_VALUE);
+
+ ServiceRegistration<?> secondContext = m_context.registerService(ServletContextHelper.class.getName(), mock(ServletContextHelper.class), properties);
+ Long secondContextId = (Long) secondContext.getReference().getProperty(Constants.SERVICE_ID);
+
+ runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(firstContextId.longValue(), runtimeDTO.failedServletContextDTOs[0].serviceId);
+ assertEquals("test-context", runtimeDTO.failedServletContextDTOs[0].name);
+ assertEquals("/first", runtimeDTO.failedServletContextDTOs[0].contextPath);
+
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+
+ assertEquals(secondContextId.longValue(), runtimeDTO.servletContextDTOs[0].serviceId);
+ assertEquals("test-context", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals("/second", runtimeDTO.servletContextDTOs[0].contextPath);
+ assertEquals("default", runtimeDTO.servletContextDTOs[1].name);
+
+ assertEquals(1, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertEquals("servlet", runtimeDTO.servletContextDTOs[0].servletDTOs[0].name);
+
+ secondContext.unregister();
+
+ runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+ assertEquals(firstContextId.longValue(), runtimeDTO.servletContextDTOs[0].serviceId);
+ assertEquals("test-context", runtimeDTO.servletContextDTOs[0].name);
+ assertEquals("/first", runtimeDTO.servletContextDTOs[0].contextPath);
+ assertEquals("default", runtimeDTO.servletContextDTOs[1].name);
+
+ assertEquals(1, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertEquals("servlet", runtimeDTO.servletContextDTOs[0].servletDTOs[0].name);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.9
+ @Test
+ public void httServiceIdIsSet()
+ {
+ ServiceReference<?> httpServiceRef = m_context.getServiceReference(HttpService.class.getName());
+ ServiceReference<?> httpServiceRuntimeRef = m_context.getServiceReference(HttpServiceRuntime.class.getName());
+
+ Long expectedId = (Long) httpServiceRef.getProperty(SERVICE_ID);
+ Long actualId = (Long) httpServiceRuntimeRef.getProperty(HTTP_SERVICE_ID_ATTRIBUTE);
+
+ assertEquals(expectedId, actualId);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.9
+ @Test
+ @Ignore // This is still broken
+ public void serviceRegisteredWithHttpServiceHasNegativeServiceId() throws Exception
+ {
+ CountDownLatch initLatch = new CountDownLatch(1);
+ register("/test", new TestServlet(initLatch, null));
+ awaitServiceRegistration(initLatch);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(1, runtimeDTO.servletContextDTOs.length);
+ assertEquals(1, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertTrue(0 > runtimeDTO.servletContextDTOs[0].servletDTOs[0].serviceId);
+ }
+
+ // As specified in OSGi Compendium Release 6, Chapter 140.9
+ @Test
+ public void serviceWithoutRequiredPropertiesIsIgnored() throws InterruptedException
+ {
+ // Neither pattern nor error page specified
+ Dictionary<String, ?> properties = createDictionary(HTTP_WHITEBOARD_SERVLET_NAME, "servlet");
+
+ m_context.registerService(Servlet.class.getName(), new TestServlet(), properties);
+ awaitServiceRegistration();
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTO = serviceRuntime.getRuntimeDTO();
+
+ assertEquals(0, runtimeDTO.failedServletContextDTOs.length);
+ ServletContextDTO defaultContext = assertDefaultContext(runtimeDTO);
+ assertEquals(0, defaultContext.servletDTOs.length);
+ }
+
+ @Test
+ public void dtosAreIndependentCopies() throws Exception
+ {
+ //register first servlet
+ Dictionary<String, ?> properties = createDictionary(
+ HTTP_WHITEBOARD_SERVLET_PATTERN, "/test",
+ HTTP_WHITEBOARD_SERVLET_NAME, "servlet 1",
+ HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + "test", "testValue");
+
+ CountDownLatch initLatch = new CountDownLatch(1);
+ m_context.registerService(Servlet.class.getName(), new TestServlet(initLatch, null), properties);
+ awaitServiceRegistration(initLatch);
+
+ HttpServiceRuntime serviceRuntime = (HttpServiceRuntime) getService(HttpServiceRuntime.class.getName());
+ assertNotNull("HttpServiceRuntime unavailable", serviceRuntime);
+
+ RuntimeDTO runtimeDTOWithFirstSerlvet = serviceRuntime.getRuntimeDTO();
+
+ //register second servlet
+ registerServlet("testServlet 2", "/servlet_2");
+
+ RuntimeDTO runtimeDTOWithTwoSerlvets = serviceRuntime.getRuntimeDTO();
+
+ assertNotSame(runtimeDTOWithFirstSerlvet, runtimeDTOWithTwoSerlvets);
+
+ ServletContextDTO defaultContextFirstServlet = assertDefaultContext(runtimeDTOWithFirstSerlvet);
+ ServletContextDTO defaultContextTwoServlets = assertDefaultContext(runtimeDTOWithTwoSerlvets);
+ assertNotSame(defaultContextFirstServlet.servletDTOs[0].patterns,
+ defaultContextTwoServlets.servletDTOs[0].patterns);
+
+ boolean mapsModifiable = true;
+ try
+ {
+ runtimeDTOWithTwoSerlvets.servletContextDTOs[0].servletDTOs[0].initParams.clear();
+ } catch (UnsupportedOperationException e)
+ {
+ mapsModifiable = false;
+ }
+
+ if (mapsModifiable)
+ {
+ assertNotSame(defaultContextFirstServlet.servletDTOs[0].initParams,
+ defaultContextTwoServlets.servletDTOs[0].initParams);
+ }
+ }
+
+ private ServletContextDTO assertDefaultContext(RuntimeDTO runtimeDTO)
+ {
+ assertTrue(0 < runtimeDTO.servletContextDTOs.length);
+ assertEquals("default", runtimeDTO.servletContextDTOs[0].name);
+ return runtimeDTO.servletContextDTOs[0];
+ }
+
+ private void awaitServiceRegistration() throws InterruptedException
+ {
+ // Wait some time until the whiteboard (hopefully) picked up the service
+ Thread.sleep(DEFAULT_SLEEP);
+ }
+
+ private void awaitServiceRegistration(CountDownLatch initLatch) throws InterruptedException
+ {
+ if (!initLatch.await(5, TimeUnit.SECONDS))
+ {
+ fail("Service was not initialized in time!");
+ };
+ awaitServiceRegistration();
+ }
+
+ public static class TestResource
+ {
+ // Tagging class
+ }
+}