You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2015/05/17 21:39:52 UTC
svn commit: r1679892 [1/2] - in /felix/trunk/http/base/src:
main/java/org/apache/felix/http/base/internal/dispatch/
main/java/org/apache/felix/http/base/internal/handler/
main/java/org/apache/felix/http/base/internal/handler/holder/
main/java/org/apach...
Author: cziegeler
Date: Sun May 17 19:39:51 2015
New Revision: 1679892
URL: http://svn.apache.org/r1679892
Log:
FELIX-4888 : ServletHandler's are not sorted by longest matching path. Implement new servlet and filter registry (WiP)
Added:
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java (with props)
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java (with props)
Modified:
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/FilterHolder.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceFilterHolder.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceServletHolder.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/ServletHolder.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardFilterHolder.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardServletHolder.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletHandler.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/PerBundleHttpServiceImpl.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/SharedHttpServiceImpl.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/SimpleServletHandlerTest.java
felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/registry/ServletRegistryTest.java
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java Sun May 17 19:39:51 2015
@@ -51,10 +51,11 @@ import javax.servlet.http.HttpServletRes
import javax.servlet.http.HttpSession;
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.HandlerRegistry;
import org.apache.felix.http.base.internal.handler.HttpSessionWrapper;
-import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.handler.holder.FilterHolder;
+import org.apache.felix.http.base.internal.handler.holder.ServletHolder;
+import org.apache.felix.http.base.internal.registry.PathResolution;
import org.apache.felix.http.base.internal.util.UriUtils;
import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.service.http.HttpContext;
@@ -68,11 +69,11 @@ public final class Dispatcher implements
final class RequestDispatcherImpl implements RequestDispatcher
{
private final RequestInfo requestInfo;
- private final ServletHandler handler;
+ private final ServletHolder holder;
- public RequestDispatcherImpl(ServletHandler handler, RequestInfo requestInfo)
+ public RequestDispatcherImpl(ServletHolder holder, RequestInfo requestInfo)
{
- this.handler = handler;
+ this.holder = holder;
this.requestInfo = requestInfo;
}
@@ -91,9 +92,9 @@ public final class Dispatcher implements
try
{
- ServletRequestWrapper req = new ServletRequestWrapper((HttpServletRequest) request, this.handler.getContext(), this.requestInfo, DispatcherType.FORWARD, this.handler.getContextServiceId(),
- handler.getServletInfo().isAsyncSupported());
- Dispatcher.this.forward(this.handler, req, (HttpServletResponse) response);
+ ServletRequestWrapper req = new ServletRequestWrapper((HttpServletRequest) request, this.holder.getContext(), this.requestInfo, DispatcherType.FORWARD, this.holder.getContextServiceId(),
+ this.holder.getServletInfo().isAsyncSupported());
+ Dispatcher.this.forward(this.holder, req, (HttpServletResponse) response);
}
finally
{
@@ -110,9 +111,9 @@ public final class Dispatcher implements
@Override
public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
{
- ServletRequestWrapper req = new ServletRequestWrapper((HttpServletRequest) request, this.handler.getContext(), this.requestInfo, DispatcherType.INCLUDE,
- this.handler.getContextServiceId(), handler.getServletInfo().isAsyncSupported());
- Dispatcher.this.include(this.handler, req, (HttpServletResponse) response);
+ ServletRequestWrapper req = new ServletRequestWrapper((HttpServletRequest) request, this.holder.getContext(), this.requestInfo, DispatcherType.INCLUDE,
+ this.holder.getContextServiceId(), holder.getServletInfo().isAsyncSupported());
+ Dispatcher.this.include(this.holder, req, (HttpServletResponse) response);
}
}
@@ -127,14 +128,15 @@ public final class Dispatcher implements
private final String servletName;
- public ServletResponseWrapper(final HttpServletRequest req, final HttpServletResponse res, final ServletHandler servletHandler)
+ public ServletResponseWrapper(final HttpServletRequest req, final HttpServletResponse res,
+ final ServletHolder servletHolder)
{
super(res);
this.request = req;
- if ( servletHandler != null )
+ if ( servletHolder != null )
{
- this.serviceId = servletHandler.getContextServiceId();
- this.servletName = servletHandler.getName();
+ this.serviceId = servletHolder.getContextServiceId();
+ this.servletName = servletHolder.getName();
}
else
{
@@ -167,7 +169,7 @@ public final class Dispatcher implements
code >= SC_OK)
{
final Throwable exception = (Throwable)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
- final ServletHandler errorHandler = handlerRegistry.getErrorsHandler(request.getRequestURI(), this.serviceId, code, exception);
+ final ServletHolder errorHandler = handlerRegistry.getErrorHandler(request.getRequestURI(), this.serviceId, code, exception);
if ( errorHandler != null )
{
@@ -190,10 +192,10 @@ public final class Dispatcher implements
final RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, queryString);
- final FilterHandler[] filterHandlers = handlerRegistry.getFilterHandlers(errorHandler, DispatcherType.ERROR, request.getRequestURI());
+ final FilterHolder[] filterHolders = handlerRegistry.getFilters(errorHandler, DispatcherType.ERROR, request.getRequestURI());
// TODO - is async = false correct?
- invokeChain(filterHandlers, errorHandler, new ServletRequestWrapper(request, errorHandler.getContext(), requestInfo, this.serviceId, false), this);
+ invokeChain(errorHandler, filterHolders, new ServletRequestWrapper(request, errorHandler.getContext(), requestInfo, this.serviceId, false), this);
invokeSuper = false;
}
@@ -578,29 +580,25 @@ public final class Dispatcher implements
requestURI = "";
}
- // Determine which servlets we should forward the request to...
- final ServletHandler servletHandler = this.handlerRegistry.getServletHandler(requestURI);
+ // Determine which servlet we should forward the request to...
+ final PathResolution pr = this.handlerRegistry.resolveServlet(requestURI);
- final HttpServletResponse wrappedResponse = new ServletResponseWrapper(req, res, servletHandler);
- if ( servletHandler == null )
+ final HttpServletResponse wrappedResponse = new ServletResponseWrapper(req, res,
+ pr == null ? null : pr.holder);
+ if ( pr == null )
{
wrappedResponse.sendError(404);
return;
}
- // strip of context path
- requestURI = requestURI.substring(servletHandler.getContext().getContextPath().length() - req.getContextPath().length());
- final String servletPath = servletHandler.determineServletPath(requestURI);
- String pathInfo = UriUtils.compactPath(UriUtils.relativePath(servletPath, requestURI));
- String queryString = null; // XXX
-
- final ExtServletContext servletContext = servletHandler.getContext();
- final RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, queryString);
-
- final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo, servletHandler.getContextServiceId(),
- servletHandler.getServletInfo().isAsyncSupported());
- final FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, req.getDispatcherType(), requestURI);
+ final ExtServletContext servletContext = pr.holder.getContext();
+ final RequestInfo requestInfo = new RequestInfo(pr.servletPath, pr.pathInfo, null);
+
+ final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo,
+ pr.holder.getContextServiceId(),
+ pr.holder.getServletInfo().isAsyncSupported());
+ final FilterHolder[] filterHolders = this.handlerRegistry.getFilters(pr.holder, req.getDispatcherType(), pr.requestURI);
try
{
@@ -608,7 +606,7 @@ public final class Dispatcher implements
{
servletContext.getServletRequestListener().requestInitialized(new ServletRequestEvent(servletContext, wrappedRequest));
}
- invokeChain(filterHandlers, servletHandler, wrappedRequest, wrappedResponse);
+ invokeChain(pr.holder, filterHolders, wrappedRequest, wrappedResponse);
}
catch ( final Exception e)
{
@@ -629,8 +627,8 @@ public final class Dispatcher implements
@Override
public RequestDispatcher getNamedDispatcher(final Long contextId, final String name)
{
- ServletHandler handler = this.handlerRegistry.getServletHandlerByName(contextId, name);
- return handler != null ? new RequestDispatcherImpl(handler, null) : null;
+ ServletHolder holder = this.handlerRegistry.resolveServletByName(contextId, name);
+ return holder != null ? new RequestDispatcherImpl(holder, null) : null;
}
@Override
@@ -656,17 +654,14 @@ public final class Dispatcher implements
requestURI = "";
}
- ServletHandler handler = this.handlerRegistry.getServletHandler(requestURI);
- if (handler == null)
+ final PathResolution pr = this.handlerRegistry.resolveServlet(requestURI);
+ if (pr == null)
{
return null;
}
- String servletPath = handler.determineServletPath(requestURI);
- String pathInfo = UriUtils.relativePath(servletPath, path);
-
- RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, query);
- return new RequestDispatcherImpl(handler, requestInfo);
+ final RequestInfo requestInfo = new RequestInfo(pr.servletPath, pr.pathInfo, query);
+ return new RequestDispatcherImpl(pr.holder, requestInfo);
}
/**
@@ -674,12 +669,12 @@ public final class Dispatcher implements
* @param request the {@link HttpServletRequest};
* @param response the {@link HttpServletResponse};
*/
- void forward(ServletHandler servletHandler, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ void forward(ServletHolder servletHolder, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String requestURI = getRequestURI(request);
- FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, DispatcherType.FORWARD, requestURI);
+ FilterHolder[] filterHolders = this.handlerRegistry.getFilters(servletHolder, DispatcherType.FORWARD, requestURI);
- invokeChain(filterHandlers, servletHandler, request, response);
+ invokeChain(servletHolder, filterHolders, request, response);
}
/**
@@ -687,12 +682,12 @@ public final class Dispatcher implements
* @param request the {@link HttpServletRequest};
* @param response the {@link HttpServletResponse};
*/
- void include(ServletHandler servletHandler, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ void include(ServletHolder servletHolder, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String requestURI = getRequestURI(request);
- FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, DispatcherType.INCLUDE, requestURI);
+ FilterHolder[] filterHolders = this.handlerRegistry.getFilters(servletHolder, DispatcherType.INCLUDE, requestURI);
- invokeChain(filterHandlers, servletHandler, request, response);
+ invokeChain(servletHolder, filterHolders, request, response);
}
private String getRequestURI(HttpServletRequest req)
@@ -700,9 +695,13 @@ public final class Dispatcher implements
return UriUtils.relativePath(req.getContextPath(), req.getRequestURI());
}
- private void invokeChain(FilterHandler[] filterHandlers, ServletHandler servletHandler, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ private void invokeChain(final ServletHolder servletHolder,
+ final FilterHolder[] filterHolders,
+ final HttpServletRequest request,
+ final HttpServletResponse response)
+ throws IOException, ServletException
{
- final FilterChain filterChain = new InvocationChain(servletHandler, filterHandlers);
+ final FilterChain filterChain = new InvocationChain(servletHolder, filterHolders);
filterChain.doFilter(request, response);
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationChain.java Sun May 17 19:39:51 2015
@@ -29,20 +29,20 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-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.handler.holder.FilterHolder;
+import org.apache.felix.http.base.internal.handler.holder.ServletHolder;
public class InvocationChain implements FilterChain
{
- private final ServletHandler servletHandler;
- private final FilterHandler[] filterHandlers;
+ private final ServletHolder servletHolder;
+ private final FilterHolder[] filterHolders;
private int index = -1;
- public InvocationChain(@Nonnull final ServletHandler servletHandler, @Nonnull final FilterHandler[] filterHandlers)
+ public InvocationChain(@Nonnull final ServletHolder servletHolder, @Nonnull final FilterHolder[] filterHolders)
{
- this.filterHandlers = filterHandlers;
- this.servletHandler = servletHandler;
+ this.filterHolders = filterHolders;
+ this.servletHolder = servletHolder;
}
@Override
@@ -54,7 +54,7 @@ public class InvocationChain implements
final HttpServletResponse hRes = (HttpServletResponse) res;
// invoke security
- if ( !servletHandler.getContext().handleSecurity(hReq, hRes))
+ if ( !servletHolder.getContext().handleSecurity(hReq, hRes))
{
// FELIX-3988: If the response is not yet committed and still has the default
// status, we're going to override this and send an error instead.
@@ -69,14 +69,14 @@ public class InvocationChain implements
}
this.index++;
- if (this.index < this.filterHandlers.length)
+ if (this.index < this.filterHolders.length)
{
- this.filterHandlers[this.index].handle(req, res, this);
+ this.filterHolders[this.index].handle(req, res, this);
}
else
{
// Last entry in the chain...
- this.servletHandler.handle(req, res);
+ this.servletHolder.handle(req, res);
}
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java Sun May 17 19:39:51 2015
@@ -16,29 +16,25 @@
*/
package org.apache.felix.http.base.internal.handler;
-import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
-
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.servlet.DispatcherType;
-import javax.servlet.Filter;
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
+import org.apache.felix.http.base.internal.handler.holder.FilterHolder;
+import org.apache.felix.http.base.internal.handler.holder.ServletHolder;
+import org.apache.felix.http.base.internal.registry.PathResolution;
+import org.apache.felix.http.base.internal.registry.PerContextHandlerRegistry;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.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.HandlerRegistryRuntime;
import org.apache.felix.http.base.internal.runtime.dto.ServletRegistryRuntime;
-import org.apache.felix.http.base.internal.whiteboard.RegistrationFailureException;
/**
* Registry for all services.
@@ -48,7 +44,7 @@ import org.apache.felix.http.base.intern
*/
public final class HandlerRegistry
{
- private static FilterHandler[] EMPTY_FILTER_HANDLER = new FilterHandler[0];
+ private static FilterHolder[] EMPTY_FILTER_HOLDER = new FilterHolder[0];
/** Current list of context registrations. */
private volatile List<PerContextHandlerRegistry> registrations = Collections.emptyList();
@@ -138,54 +134,26 @@ public final class HandlerRegistry
}
}
- public void addFilter(FilterHandler handler) throws ServletException
- {
- getRegistryChecked(null, null).addFilter(handler);
- }
-
- public void addFilter(ServletContextHelperInfo contextInfo, FilterHandler handler) throws ServletException
- {
- getRegistryChecked(contextInfo, handler.getFilterInfo()).addFilter(handler);
- }
-
- public void removeFilter(Filter filter, boolean destroy)
+ public void addFilter(@Nonnull final FilterHolder holder)
{
- try
- {
- getRegistryChecked(null, null).removeFilter(filter, destroy);
- }
- catch (RegistrationFailureException e)
+ final PerContextHandlerRegistry reg = this.getRegistry(holder.getContextServiceId());
+ // TODO - check whether we need to handle the null case as well
+ // it shouldn't be required as we only get here if the context exists
+ if ( reg != null )
{
- // TODO
+ reg.addFilter(holder);
}
}
- public Filter removeFilter(ServletContextHelperInfo contextInfo, FilterInfo filterInfo)
+ public void removeFilter(final long contextId, @Nonnull final FilterInfo info, final boolean destroy)
{
- return getRegistry(contextInfo).removeFilter(filterInfo, true);
- }
-
- private PerContextHandlerRegistry getRegistryChecked(ServletContextHelperInfo info, WhiteboardServiceInfo<?> serviceInfo)
- throws RegistrationFailureException
- {
- PerContextHandlerRegistry registry = getRegistry(info);
- if (registry == null)
+ final PerContextHandlerRegistry reg = this.getRegistry(contextId);
+ // TODO - check whether we need to handle the null case as well
+ // it shouldn't be required as we only get here if the context exists
+ if ( reg != null )
{
- throw new RegistrationFailureException(serviceInfo, FAILURE_REASON_SERVLET_CONTEXT_FAILURE);
+ reg.removeFilter(info, destroy);
}
- return registry;
- }
-
- /**
- * Get the per context registry.
- * @param info The servlet context helper info or {@code null} for the Http Service context.
- * @return A per context registry or {@code null}
- */
- private PerContextHandlerRegistry getRegistry(final ServletContextHelperInfo info)
- {
- final long key = (info == null ? 0 : info.getServiceId());
-
- return getRegistry(key);
}
private PerContextHandlerRegistry getRegistry(final long key)
@@ -203,7 +171,7 @@ public final class HandlerRegistry
return null;
}
- public ServletHandler getErrorsHandler(String requestURI, Long serviceId, int code, Throwable exception)
+ public ServletHolder getErrorHandler(String requestURI, Long serviceId, int code, Throwable exception)
{
ErrorsMapping errorsMapping = getErrorsMapping(requestURI, serviceId);
if (errorsMapping == null)
@@ -211,7 +179,9 @@ public final class HandlerRegistry
return null;
}
- return errorsMapping.get(exception, code);
+ // TODO
+ return null;
+ //return errorsMapping.get(exception, code);
}
private ErrorsMapping getErrorsMapping(final String requestURI, final Long serviceId)
@@ -232,73 +202,77 @@ public final class HandlerRegistry
return null;
}
- public FilterHandler[] getFilterHandlers(@Nonnull final ServletHandler servletHandler,
+ public FilterHolder[] getFilters(@Nonnull final ServletHolder servletHolder,
final DispatcherType dispatcherType,
@Nonnull final String requestURI)
{
- final long key = servletHandler.getContextServiceId();
- final List<PerContextHandlerRegistry> regs = this.registrations;
- for(final PerContextHandlerRegistry r : regs)
+ final long key = servletHolder.getContextServiceId();
+ final PerContextHandlerRegistry reg = this.getRegistry(key);
+ if ( reg != null )
{
- if ( key == r.getContextServiceId() )
- {
- return r.getFilterHandlers(servletHandler, dispatcherType, requestURI);
- }
+ return reg.getFilterHolders(servletHolder, dispatcherType, requestURI);
}
- return EMPTY_FILTER_HANDLER;
+ return EMPTY_FILTER_HOLDER;
}
- public synchronized void addServlet(ServletHandler handler) throws RegistrationFailureException
+ public void addServlet(final ServletHolder holder)
{
- Pattern[] patterns = handler.getPatterns();
- String[] errorPages = handler.getServletInfo().getErrorPage();
- if (patterns != null && patterns.length > 0)
- {
- servletRegistry.addServlet(handler);
- }
- if (errorPages != null && errorPages.length > 0)
+ final PerContextHandlerRegistry reg = this.getRegistry(holder.getContextServiceId());
+ // TODO - check whether we need to handle the null case as well
+ // it shouldn't be required as we only get here if the context exists
+ if ( reg != null )
{
- getRegistry(handler.getContextServiceId()).addErrorPage(handler, errorPages);
+ reg.addServlet(holder);
}
}
- public synchronized void removeServlet(Servlet servlet, boolean destroy)
+ public void removeServlet(final long contextId, final ServletInfo info, final boolean destroy)
{
- servletRegistry.removeServlet(servlet, destroy);
- }
+ final PerContextHandlerRegistry reg = this.getRegistry(contextId);
+ // TODO - check whether we need to handle the null case as well
+ // it shouldn't be required as we only get here if the context exists
+ if ( reg != null )
+ {
+ reg.removeServlet(info, destroy);
+ }
- public synchronized Servlet removeServlet(ServletInfo servletInfo)
- {
- return servletRegistry.removeServlet(servletInfo);
}
- public synchronized void removeServlet(long contextId, ServletInfo servletInfo)
+ public PathResolution resolveServlet(final String requestURI)
{
- String[] patterns = servletInfo.getPatterns();
- if (patterns != null && patterns.length > 0)
- {
- servletRegistry.removeServlet(contextId, servletInfo);
- }
- else
+ final List<PerContextHandlerRegistry> regs = this.registrations;
+ for(final PerContextHandlerRegistry r : regs)
{
- getRegistry(contextId).removeErrorPage(servletInfo);
+ final String path = r.isMatching(requestURI);
+ if ( path != null )
+ {
+ final PathResolution ps = r.resolve(path);
+ if ( ps != null )
+ {
+ // remove context path from request URI
+ ps.requestURI = path;
+ return ps;
+ }
+ }
}
- }
- public ServletHandler getServletHandler(String requestURI)
- {
- return servletRegistry.getServletHandler(requestURI);
+ return null;
}
/**
- * Get the servlet handler for a servlet by name
+ * Get the servlet holder for a servlet by name
* @param contextId The context id or {@code null}
* @param name The servlet name
- * @return The servlet handler or {@code null}
+ * @return The servlet holder or {@code null}
*/
- public ServletHandler getServletHandlerByName(final Long contextId, @Nonnull final String name)
+ public ServletHolder resolveServletByName(final Long contextId, @Nonnull final String name)
{
- return servletRegistry.getServletHandlerByName(contextId, name);
+ final PerContextHandlerRegistry reg = (contextId == null ? null : this.getRegistry(contextId));
+ if ( reg != null )
+ {
+ return reg.resolveServletByName(name);
+ }
+ return null;
}
public synchronized HandlerRegistryRuntime getRuntime(FailureRuntime.Builder failureRuntimeBuilder)
@@ -306,7 +280,8 @@ public final class HandlerRegistry
List<ContextRuntime> handlerRuntimes = new ArrayList<ContextRuntime>();
for (PerContextHandlerRegistry contextRegistry : this.registrations)
{
- handlerRuntimes.add(contextRegistry.getRuntime(failureRuntimeBuilder));
+ // TODO
+ // handlerRuntimes.add(contextRegistry.getRuntime(failureRuntimeBuilder));
}
ServletRegistryRuntime servletRegistryRuntime = servletRegistry.getRuntime(failureRuntimeBuilder);
return new HandlerRegistryRuntime(handlerRuntimes, servletRegistryRuntime);
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/FilterHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/FilterHolder.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/FilterHolder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/FilterHolder.java Sun May 17 19:39:51 2015
@@ -16,33 +16,81 @@
*/
package org.apache.felix.http.base.internal.handler.holder;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
import javax.servlet.Filter;
-import javax.servlet.ServletContext;
+import javax.servlet.FilterChain;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.handler.FilterConfigImpl;
import org.apache.felix.http.base.internal.logger.SystemLogger;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
+import org.apache.felix.http.base.internal.util.PatternUtil;
import org.osgi.service.http.runtime.dto.DTOConstants;
/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public abstract class FilterHolder implements Comparable<FilterHolder>
+public class FilterHolder implements Comparable<FilterHolder>
{
+ private final long contextServiceId;
+
private final FilterInfo filterInfo;
- private final ServletContext context;
+ private final ExtServletContext context;
private volatile Filter filter;
protected volatile int useCount;
- public FilterHolder(final ServletContext context,
+ private final Pattern[] patterns;
+
+ public FilterHolder(final long contextServiceId,
+ final ExtServletContext context,
final FilterInfo filterInfo)
{
+ this.contextServiceId = contextServiceId;
this.context = context;
this.filterInfo = filterInfo;
+ // Compose a single array of all patterns & regexs the filter must represent...
+ String[] patterns = getFilterPatterns(filterInfo);
+
+ this.patterns = new Pattern[patterns.length];
+ for (int i = 0; i < patterns.length; i++)
+ {
+ this.patterns[i] = Pattern.compile(patterns[i]);
+ }
+ }
+
+ private static String[] getFilterPatterns(FilterInfo filterInfo)
+ {
+ List<String> result = new ArrayList<String>();
+ if (filterInfo.getPatterns() != null)
+ {
+ for (int i = 0; i < filterInfo.getPatterns().length; i++)
+ {
+ result.add(PatternUtil.convertToRegEx(filterInfo.getPatterns()[i]));
+ }
+ }
+ if (filterInfo.getRegexs() != null)
+ {
+ for (int i = 0; i < filterInfo.getRegexs().length; i++)
+ {
+ result.add(filterInfo.getRegexs()[i]);
+ }
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ public Pattern[] getPatterns() {
+ return this.patterns;
}
@Override
@@ -51,12 +99,17 @@ public abstract class FilterHolder imple
return this.filterInfo.compareTo(other.filterInfo);
}
- protected ServletContext getContext()
+ public long getContextServiceId()
+ {
+ return this.contextServiceId;
+ }
+
+ public ExtServletContext getContext()
{
return this.context;
}
- protected Filter getFilter()
+ public Filter getFilter()
{
return filter;
}
@@ -71,7 +124,7 @@ public abstract class FilterHolder imple
return this.filterInfo;
}
- protected String getName()
+ public String getName()
{
String name = this.filterInfo.getName();
if (name == null)
@@ -89,6 +142,7 @@ public abstract class FilterHolder imple
{
if ( this.useCount > 0 )
{
+ this.useCount++;
return -1;
}
@@ -112,6 +166,12 @@ public abstract class FilterHolder imple
return -1;
}
+ public void handle(@Nonnull final ServletRequest req,
+ @Nonnull final ServletResponse res,
+ @Nonnull final FilterChain chain) throws ServletException, IOException
+ {
+ this.filter.doFilter(req, res, chain);
+ }
public boolean destroy()
{
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceFilterHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceFilterHolder.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceFilterHolder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceFilterHolder.java Sun May 17 19:39:51 2015
@@ -17,8 +17,8 @@
package org.apache.felix.http.base.internal.handler.holder;
import javax.servlet.Filter;
-import javax.servlet.ServletContext;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
/**
@@ -26,11 +26,12 @@ import org.apache.felix.http.base.intern
*/
public final class HttpServiceFilterHolder extends FilterHolder
{
- public HttpServiceFilterHolder(final ServletContext context,
+ public HttpServiceFilterHolder(final long contextServiceId,
+ final ExtServletContext context,
final FilterInfo filterInfo,
final Filter filter)
{
- super(context, filterInfo);
+ super(contextServiceId, context, filterInfo);
this.setFilter(filter);
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceServletHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceServletHolder.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceServletHolder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/HttpServiceServletHolder.java Sun May 17 19:39:51 2015
@@ -17,8 +17,8 @@
package org.apache.felix.http.base.internal.handler.holder;
import javax.servlet.Servlet;
-import javax.servlet.ServletContext;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
/**
@@ -26,11 +26,12 @@ import org.apache.felix.http.base.intern
*/
public final class HttpServiceServletHolder extends ServletHolder
{
- public HttpServiceServletHolder(final ServletContext context,
+ public HttpServiceServletHolder(final long contextServiceId,
+ final ExtServletContext context,
final ServletInfo servletInfo,
final Servlet servlet)
{
- super(context, servletInfo);
+ super(contextServiceId, context, servletInfo);
this.setServlet(servlet);
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/ServletHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/ServletHolder.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/ServletHolder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/ServletHolder.java Sun May 17 19:39:51 2015
@@ -19,11 +19,11 @@ package org.apache.felix.http.base.inter
import java.io.IOException;
import javax.servlet.Servlet;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.handler.ServletConfigImpl;
import org.apache.felix.http.base.internal.logger.SystemLogger;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
@@ -34,17 +34,21 @@ import org.osgi.service.http.runtime.dto
*/
public abstract class ServletHolder implements Comparable<ServletHolder>
{
+ private final long contextServiceId;
+
private final ServletInfo servletInfo;
- private final ServletContext context;
+ private final ExtServletContext context;
private volatile Servlet servlet;
protected volatile int useCount;
- public ServletHolder(final ServletContext context,
+ public ServletHolder(final long contextServiceId,
+ final ExtServletContext context,
final ServletInfo servletInfo)
{
+ this.contextServiceId = contextServiceId;
this.context = context;
this.servletInfo = servletInfo;
}
@@ -55,12 +59,17 @@ public abstract class ServletHolder impl
return this.servletInfo.compareTo(other.servletInfo);
}
- protected ServletContext getContext()
+ public long getContextServiceId()
+ {
+ return this.contextServiceId;
+ }
+
+ public ExtServletContext getContext()
{
return this.context;
}
- protected Servlet getServlet()
+ public Servlet getServlet()
{
return servlet;
}
@@ -81,7 +90,7 @@ public abstract class ServletHolder impl
return this.servletInfo;
}
- protected String getName()
+ public String getName()
{
String name = this.servletInfo.getName();
if (name == null)
@@ -99,6 +108,7 @@ public abstract class ServletHolder impl
{
if ( this.useCount > 0 )
{
+ this.useCount++;
return -1;
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardFilterHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardFilterHolder.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardFilterHolder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardFilterHolder.java Sun May 17 19:39:51 2015
@@ -17,8 +17,8 @@
package org.apache.felix.http.base.internal.handler.holder;
import javax.servlet.Filter;
-import javax.servlet.ServletContext;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceObjects;
@@ -31,11 +31,12 @@ public final class WhiteboardFilterHolde
{
private final BundleContext bundleContext;
- public WhiteboardFilterHolder(final ServletContext context,
+ public WhiteboardFilterHolder(final long contextServiceId,
+ final ExtServletContext context,
final FilterInfo filterInfo,
final BundleContext bundleContext)
{
- super(context, filterInfo);
+ super(contextServiceId, context, filterInfo);
this.bundleContext = bundleContext;
}
@@ -44,6 +45,7 @@ public final class WhiteboardFilterHolde
{
if ( this.useCount > 0 )
{
+ this.useCount++;
return -1;
}
@@ -58,7 +60,7 @@ public final class WhiteboardFilterHolde
so.ungetService(this.getFilter());
this.setFilter(null);
}
- return -reason;
+ return reason;
}
@Override
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardServletHolder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardServletHolder.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardServletHolder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/holder/WhiteboardServletHolder.java Sun May 17 19:39:51 2015
@@ -17,8 +17,8 @@
package org.apache.felix.http.base.internal.handler.holder;
import javax.servlet.Servlet;
-import javax.servlet.ServletContext;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceObjects;
@@ -31,11 +31,12 @@ public final class WhiteboardServletHold
{
private final BundleContext bundleContext;
- public WhiteboardServletHolder(final ServletContext context,
+ public WhiteboardServletHolder(final long contextServiceId,
+ final ExtServletContext context,
final ServletInfo servletInfo,
final BundleContext bundleContext)
{
- super(context, servletInfo);
+ super(contextServiceId, context, servletInfo);
this.bundleContext = bundleContext;
}
@@ -44,6 +45,7 @@ public final class WhiteboardServletHold
{
if ( this.useCount > 0 )
{
+ this.useCount++;
return -1;
}
@@ -58,7 +60,7 @@ public final class WhiteboardServletHold
so.ungetService(this.getServlet());
this.setServlet(null);
}
- return -reason;
+ return reason;
}
@Override
Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java?rev=1679892&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java Sun May 17 19:39:51 2015
@@ -0,0 +1,129 @@
+/*
+ * 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.registry;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.servlet.DispatcherType;
+
+import org.apache.felix.http.base.internal.handler.holder.FilterHolder;
+import org.apache.felix.http.base.internal.handler.holder.ServletHolder;
+import org.apache.felix.http.base.internal.runtime.FilterInfo;
+
+public final class FilterRegistry
+{
+ private volatile HandlerMapping filterMapping = new HandlerMapping();
+
+ private final Map<FilterInfo, FilterRegistrationStatus> statusMapping = new ConcurrentHashMap<FilterInfo, FilterRegistrationStatus>();
+
+ private static final class FilterRegistrationStatus
+ {
+ public int result;
+ public FilterHolder holder;
+ }
+
+ public void addFilter(@Nonnull final FilterHolder holder)
+ {
+ final int result = holder.init();
+ if ( result == -1 )
+ {
+ this.filterMapping = this.filterMapping.add(holder);
+ }
+ final FilterRegistrationStatus status = new FilterRegistrationStatus();
+ status.result = result;
+ status.holder = holder;
+
+ statusMapping.put(holder.getFilterInfo(), status);
+ }
+
+ public void removeFilter(@Nonnull final FilterInfo filterInfo, final boolean destroy)
+ {
+ final FilterRegistrationStatus status = statusMapping.remove(filterInfo);
+ if ( status != null )
+ {
+ if ( status.result == -1 )
+ {
+ this.filterMapping = this.filterMapping.remove(status.holder);
+ if (destroy)
+ {
+ status.holder.dispose();
+ }
+ }
+ }
+ }
+
+ public FilterHolder[] getFilterHolders(@CheckForNull final ServletHolder holder,
+ @CheckForNull DispatcherType dispatcherType,
+ @Nonnull String requestURI)
+ {
+ // See Servlet 3.0 specification, section 6.2.4...
+ final List<FilterHolder> result = new ArrayList<FilterHolder>();
+ result.addAll(this.filterMapping.getAllMatches(requestURI));
+
+ // TODO this is not the most efficient/fastest way of doing this...
+ Iterator<FilterHolder> iter = result.iterator();
+ while (iter.hasNext())
+ {
+ if (!referencesDispatcherType(iter.next(), dispatcherType))
+ {
+ iter.remove();
+ }
+ }
+
+ final String servletName = (holder != null) ? holder.getName() : null;
+ // TODO this is not the most efficient/fastest way of doing this...
+ for (FilterHolder filterHandler : this.filterMapping.values())
+ {
+ if (referencesServletByName(filterHandler, servletName))
+ {
+ result.add(filterHandler);
+ }
+ }
+
+ return result.toArray(new FilterHolder[result.size()]);
+ }
+
+ private boolean referencesDispatcherType(FilterHolder holder, DispatcherType dispatcherType)
+ {
+ if (dispatcherType == null)
+ {
+ return true;
+ }
+ return Arrays.asList(holder.getFilterInfo().getDispatcher()).contains(dispatcherType);
+ }
+
+ private boolean referencesServletByName(FilterHolder handler, String servletName)
+ {
+ if (servletName == null)
+ {
+ return false;
+ }
+ String[] names = handler.getFilterInfo().getServletNames();
+ if (names != null && names.length > 0)
+ {
+ return Arrays.asList(names).contains(servletName);
+ }
+ return false;
+ }
+}
Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java?rev=1679892&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java Sun May 17 19:39:51 2015
@@ -0,0 +1,342 @@
+/*
+ * 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.registry;
+
+import static java.util.Collections.unmodifiableCollection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
+
+import org.apache.felix.http.base.internal.handler.holder.FilterHolder;
+import org.apache.felix.http.base.internal.util.PatternUtil;
+import org.apache.felix.http.base.internal.util.PatternUtil.PatternComparator;
+
+/**
+ * Represents a Map-like structure that can map path-patterns to servlet/filter handlers, allowing
+ * for easy access to those handlers, based on the match rules defined in section 12.1 of Servlet
+ * 3.0 specification.
+ * <p>
+ * {@link HandlerMapping} instances are immutable.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final class HandlerMapping
+{
+ private final SortedMap<Pattern, Set<FilterHolder>> exactMap;
+ private final SortedMap<Pattern, Set<FilterHolder>> wildcardMap;
+ private final Set<FilterHolder> mappedHandlers;
+
+ /**
+ * Creates a new, empty, {@link HandlerMapping} instance.
+ */
+ public HandlerMapping()
+ {
+ this(Collections.<Pattern, Collection<FilterHolder>>emptyMap());
+ }
+
+ /**
+ * Creates a new {@link HandlerMapping} instance for the given elements.
+ *
+ * @param mappings the elements to map.
+ */
+ private HandlerMapping(@Nonnull final Map<Pattern, Collection<FilterHolder>> mappings)
+ {
+ this.exactMap = new TreeMap<Pattern, Set<FilterHolder>>(PatternComparator.INSTANCE);
+ this.wildcardMap = new TreeMap<Pattern, Set<FilterHolder>>(PatternComparator.INSTANCE);
+ this.mappedHandlers = new TreeSet<FilterHolder>();
+
+ for (Map.Entry<Pattern, Collection<FilterHolder>> mapping : mappings.entrySet())
+ {
+ Pattern pattern = mapping.getKey();
+ Collection<FilterHolder> handlers = mapping.getValue();
+
+ mappedHandlers.addAll(handlers);
+
+ if (PatternUtil.isWildcardPattern(pattern))
+ {
+ Set<FilterHolder> vs = this.wildcardMap.get(pattern);
+ if (vs == null)
+ {
+ vs = new TreeSet<FilterHolder>();
+ this.wildcardMap.put(pattern, vs);
+ }
+ vs.addAll(handlers);
+ }
+ else
+ {
+ Set<FilterHolder> vs = this.exactMap.get(pattern);
+ if (vs == null)
+ {
+ vs = new TreeSet<FilterHolder>();
+ this.exactMap.put(pattern, vs);
+ }
+ vs.addAll(handlers);
+ }
+ }
+ }
+
+ /**
+ * Returns a new {@link HandlerMapping} instance with a mapping for the
+ * given handler.
+ *
+ * @param handler the handler to be added to the mapping.
+ * @return a new {@link HandlerMapping} instance with a mapping for the
+ * given handler.
+ */
+ public HandlerMapping add(@Nonnull final FilterHolder handler)
+ {
+ final Map<Pattern, FilterHolder> mappings = new TreeMap<Pattern, FilterHolder>(PatternComparator.INSTANCE);
+ for (final Pattern pattern : handler.getPatterns())
+ {
+ mappings.put(pattern, handler);
+ }
+ return add(mappings);
+ }
+
+ HandlerMapping add(@Nonnull final Map<Pattern, FilterHolder> mappings)
+ {
+ final Map<Pattern, Collection<FilterHolder>> newMappings = getAllMappings();
+ addMappings(mappings, newMappings);
+ return new HandlerMapping(newMappings);
+ }
+
+ /**
+ * Returns a new {@link HandlerMapping} instance without a mapping for the
+ * given handler.
+ *
+ * @param subject the handled element to be removed from the mapping
+ * @return a new {@link HandlerMapping} instance without a mapping for the
+ * given handler.
+ */
+ public HandlerMapping remove(FilterHolder handler)
+ {
+ Map<Pattern, FilterHolder> mappings = new TreeMap<Pattern, FilterHolder>(PatternComparator.INSTANCE);
+ for (Pattern pattern : handler.getPatterns())
+ {
+ mappings.put(pattern, handler);
+ }
+ return remove(mappings);
+ }
+
+ HandlerMapping remove(Map<Pattern, FilterHolder> mappings)
+ {
+ Map<Pattern, Collection<FilterHolder>> newMappings = getAllMappings();
+ removeMappings(mappings, newMappings);
+ return new HandlerMapping(newMappings);
+ }
+
+ HandlerMapping update(Map<Pattern, FilterHolder> add, Map<Pattern, FilterHolder> remove)
+ {
+ Map<Pattern, Collection<FilterHolder>> newMappings = getAllMappings();
+ removeMappings(remove, newMappings);
+ addMappings(add, newMappings);
+ return new HandlerMapping(newMappings);
+ }
+
+ private void addMappings(Map<Pattern, FilterHolder> mappings, Map<Pattern, Collection<FilterHolder>> target)
+ {
+ for (Map.Entry<Pattern, FilterHolder> mapping : mappings.entrySet())
+ {
+ if (!target.containsKey(mapping.getKey()))
+ {
+ target.put(mapping.getKey(), new TreeSet<FilterHolder>());
+ }
+ target.get(mapping.getKey()).add(mapping.getValue());
+ }
+ }
+
+ private void removeMappings(Map<Pattern, FilterHolder> mappings, Map<Pattern, Collection<FilterHolder>> target)
+ {
+ for (Map.Entry<Pattern, FilterHolder> mapping : mappings.entrySet())
+ {
+ Collection<FilterHolder> mappedHandlers = target.get(mapping.getKey());
+ if (mappedHandlers == null)
+ {
+ continue;
+ }
+ mappedHandlers.remove(mapping.getValue());
+ if (mappedHandlers.isEmpty())
+ {
+ target.remove(mapping.getKey());
+ }
+ }
+ }
+
+ private Map<Pattern, Collection<FilterHolder>> getAllMappings()
+ {
+ Map<Pattern, Collection<FilterHolder>> newMappings = new TreeMap<Pattern, Collection<FilterHolder>>(PatternComparator.INSTANCE);
+ newMappings.putAll(exactMap);
+ newMappings.putAll(wildcardMap);
+ return newMappings;
+ }
+
+ /**
+ * Returns all mapped handlers.
+ *
+ * @return the handlers contained in this mapping. The returned
+ * <code>Collection</code> is unmodifiable and never
+ * <code>null</code>.
+ */
+ public Collection<FilterHolder> values()
+ {
+ return unmodifiableCollection(mappedHandlers);
+ }
+
+ /**
+ * Returns whether this mapping contains the specified handler.
+ *
+ * @return <code>true</code> if the handlers contains the specified handler,
+ * <code>false</code> otherwise
+ */
+ public boolean contains(FilterHolder handler)
+ {
+ return mappedHandlers.contains(handler);
+ }
+
+ /**
+ * Returns all matching handlers for the given path.
+ *
+ * @param path the path that should match, cannot be <code>null</code>.
+ * @return a {@link Collection} of all matching handlers, never <code>null</code>.
+ */
+ public List<FilterHolder> getAllMatches(String path)
+ {
+ return getAllMatches(path, false /* firstOnly */);
+ }
+
+ /**
+ * Returns the best matching handler for the given path, according to the rules defined in section 12.1 of Servlet 3.0 specification:
+ * <ul>
+ * <li>find an exact match of the path of the request to the path of the handler. A successful match selects the handler;</li>
+ * <li>recursively try to match the longest path-prefix. This is done by stepping down the path tree a directory at a time, using the
+ * '/' character as a path separator. The longest match determines the servlet selected;</li>
+ * <li>if the last segment in the URL path contains an extension (e.g. .jsp), the servlet container will try to match a servlet that
+ * handles requests for the extension. An extension is defined as the part of the last segment after the last '.' character.</li>
+ * </ul>
+ *
+ * @param path the path that should match, cannot be <code>null</code>.
+ * @return the best matching handler for the given path, or <code>null</code> in case no handler matched.
+ */
+ FilterHolder getBestMatch(String path)
+ {
+ List<FilterHolder> allMatches = getAllMatches(path, true /* firstOnly */);
+ return allMatches.isEmpty() ? null : allMatches.get(0);
+ }
+
+ /**
+ * Returns the (first) handler identified by the given name.
+ *
+ * @param name the name of the handler to return, can be <code>null</code> in which case this method will return <code>null</code>.
+ * @return the element with the given name, or <code>null</code> if not found, or the given argument was <code>null</code>.
+ */
+ FilterHolder getByName(String name)
+ {
+ if (name == null)
+ {
+ return null;
+ }
+
+ for (FilterHolder element : this.mappedHandlers)
+ {
+ if (name.equals(element.getName()))
+ {
+ return element;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Provides information on whether there are elements mapped or not.
+ *
+ * @return <code>false</code> if there is at least one element mapped, <code>true</code> otherwise.
+ */
+ boolean isEmpty()
+ {
+ return this.mappedHandlers.isEmpty();
+ }
+
+ /**
+ * Performs the actual matching, yielding a list of either the first or all matching patterns.
+ *
+ * @param path the path to match, can be <code>null</code> in which case an empty string is
+ * used;
+ * @param firstOnly <code>true</code> if only the first matching pattern should be returned,
+ * <code>false</code> if all matching patterns should be returned.
+ * @return a list with matching elements, never <code>null</code>.
+ */
+ private List<FilterHolder> getAllMatches(String path, boolean firstOnly)
+ {
+ path = (path == null) ? "" : path.trim();
+
+ Set<FilterHolder> result = new TreeSet<FilterHolder>();
+ // Look for exact matches only, that is, those patterns without wildcards...
+ for (Entry<Pattern, Set<FilterHolder>> entry : this.exactMap.entrySet())
+ {
+ Matcher matcher = entry.getKey().matcher(path);
+ // !!! we should always match the *entire* pattern, instead of the longest prefix...
+ if (matcher.matches())
+ {
+ Set<FilterHolder> vs = entry.getValue();
+ for (FilterHolder v : vs)
+ {
+ result.add(v);
+ if (firstOnly)
+ {
+ return new ArrayList<FilterHolder>(result);
+ }
+ }
+ }
+ }
+
+ // Try to apply the wildcard patterns...
+ for (Entry<Pattern, Set<FilterHolder>> entry : this.wildcardMap.entrySet())
+ {
+ Matcher matcher = entry.getKey().matcher(path);
+ if (matcher.find(0))
+ {
+ Set<FilterHolder> vs = entry.getValue();
+ for (FilterHolder v : vs)
+ {
+ result.add(v);
+
+ if (firstOnly)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ return new ArrayList<FilterHolder>(result);
+ }
+}
Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java
------------------------------------------------------------------------------
svn:keywords = author date id revision rev url
Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerMapping.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java Sun May 17 19:39:51 2015
@@ -25,4 +25,6 @@ public class PathResolution {
public String pathInfo;
public ServletHolder holder;
+
+ public String requestURI;
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java Sun May 17 19:39:51 2015
@@ -17,8 +17,13 @@
package org.apache.felix.http.base.internal.registry;
import javax.annotation.Nonnull;
+import javax.servlet.DispatcherType;
+import org.apache.felix.http.base.internal.handler.ErrorsMapping;
+import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.handler.holder.FilterHolder;
import org.apache.felix.http.base.internal.handler.holder.ServletHolder;
+import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
@@ -44,6 +49,8 @@ public final class PerContextHandlerRegi
private final ServletRegistry servletRegistry = new ServletRegistry();
+ private final FilterRegistry filterRegistry = new FilterRegistry();
+
/**
* Default http service registry
*/
@@ -74,15 +81,19 @@ public final class PerContextHandlerRegi
}
}
+ public long getContextServiceId()
+ {
+ return this.serviceId;
+ }
+
+ public void removeAll()
+ {
+ // TODO - implement
+ }
+
@Override
public int compareTo(@Nonnull final PerContextHandlerRegistry other)
{
- // the context of the HttpService is the least element
- if (this.serviceId == 0 ^ other.serviceId == 0)
- {
- return this.serviceId == 0 ? -1 : 1;
- }
-
final int result = Integer.compare(other.path.length(), this.path.length());
if ( result == 0 ) {
if (this.ranking == other.ranking)
@@ -119,6 +130,11 @@ public final class PerContextHandlerRegi
return this.servletRegistry.resolve(relativeRequestURI);
}
+ public ServletHolder resolveServletByName(final String name)
+ {
+ return this.servletRegistry.resolveByName(name);
+ }
+
/**
* Add a servlet
* @param holder The servlet holder
@@ -133,8 +149,39 @@ public final class PerContextHandlerRegi
* Remove a servlet
* @param info The servlet info
*/
- public void removeServlet(@Nonnull final ServletInfo info)
+ public void removeServlet(@Nonnull final ServletInfo info, final boolean destroy)
+ {
+ this.servletRegistry.removeServlet(info, destroy);
+ }
+
+ public void addFilter(@Nonnull final FilterHolder holder)
{
- this.servletRegistry.removeServlet(info);
+ this.filterRegistry.addFilter(holder);
}
+
+ public void removeFilter(@Nonnull final FilterInfo info, final boolean destroy)
+ {
+ this.filterRegistry.removeFilter(info, destroy);
+ }
+
+ public FilterHolder[] getFilterHolders(final ServletHolder servletHolder,
+ DispatcherType dispatcherType, String requestURI) {
+ return this.filterRegistry.getFilterHolders(servletHolder, dispatcherType, requestURI);
+ }
+
+ public void removeErrorPage(ServletInfo servletInfo) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void addErrorPage(ServletHandler handler, String[] errorPages) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public ErrorsMapping getErrorsMapping()
+ {
+ return new ErrorsMapping();
+ }
+
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletHandler.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletHandler.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletHandler.java Sun May 17 19:39:51 2015
@@ -52,6 +52,8 @@ public class ServletHandler
pr.servletPath = matcher.groupCount() > 0 ? matcher.group(1) : matcher.group();
pr.pathInfo = UriUtils.compactPath(UriUtils.relativePath(pr.servletPath, requestURI));
pr.holder = this.holder;
+
+ return pr;
}
return null;
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java Sun May 17 19:39:51 2015
@@ -35,15 +35,38 @@ import org.osgi.service.http.runtime.dto
/**
* The servlet registry keeps the mappings for all servlets (by using their pattern)
* for a single servlet context.
+ *
+ * TODO - servlet name handling
+ *
+ * TODO - sort active servlet mappings by pattern length, longest first (avoids looping over all)
*/
public final class ServletRegistry
{
- private final Map<String, ServletHandler> activateServletMapping = new ConcurrentHashMap<String, ServletHandler>();
+ private final Map<String, ServletHandler> activeServletMappings = new ConcurrentHashMap<String, ServletHandler>();
- private final Map<String, List<ServletHolder>> inactivateServletMapping = new HashMap<String, List<ServletHolder>>();
+ private final Map<String, List<ServletHolder>> inactiveServletMappings = new HashMap<String, List<ServletHolder>>();
private final Map<ServletInfo, ServletRegistrationStatus> statusMapping = new ConcurrentHashMap<ServletInfo, ServletRegistry.ServletRegistrationStatus>();
+ private final Map<String, List<ServletNameStatus>> servletsByName = new ConcurrentHashMap<String, List<ServletNameStatus>>();
+
+ private static final class ServletNameStatus implements Comparable<ServletNameStatus>
+ {
+ public volatile boolean isActive = false;
+ public final ServletHolder holder;
+
+ public ServletNameStatus(final ServletHolder h)
+ {
+ this.holder = h;
+ }
+
+ @Override
+ public int compareTo(final ServletNameStatus o)
+ {
+ return holder.compareTo(o.holder);
+ }
+ }
+
public static final class ServletRegistrationStatus
{
public final Map<String, Integer> pathToStatus = new ConcurrentHashMap<String, Integer>();
@@ -53,7 +76,7 @@ public final class ServletRegistry
{
int len = -1;
PathResolution candidate = null;
- for(final Map.Entry<String, ServletHandler> entry : this.activateServletMapping.entrySet())
+ for(final Map.Entry<String, ServletHandler> entry : this.activeServletMappings.entrySet())
{
final PathResolution pr = entry.getValue().resolve(relativeRequestURI);
if ( pr != null && entry.getKey().length() > len )
@@ -66,7 +89,8 @@ public final class ServletRegistry
}
/**
- * Add a servlet
+ * Add a servlet.
+ *
* @param holder The servlet holder
*/
public void addServlet(@Nonnull final ServletHolder holder)
@@ -79,7 +103,7 @@ public final class ServletRegistry
{
for(final String pattern : holder.getServletInfo().getPatterns())
{
- final ServletHandler regHandler = this.activateServletMapping.get(pattern);
+ final ServletHandler regHandler = this.activeServletMappings.get(pattern);
if ( regHandler != null )
{
if ( regHandler.getServletHolder().getServletInfo().getServiceReference().compareTo(holder.getServletInfo().getServiceReference()) < 0 )
@@ -87,6 +111,7 @@ public final class ServletRegistry
// replace if no error with new servlet
if ( this.tryToActivate(pattern, holder, status) )
{
+// nameStatus.isActive = true;
regHandler.getServletHolder().destroy();
this.addToInactiveList(pattern, regHandler.getServletHolder(), this.statusMapping.get(regHandler.getServletHolder().getServletInfo()));
@@ -101,7 +126,10 @@ public final class ServletRegistry
else
{
// add to active
- this.tryToActivate(pattern, holder, status);
+ if ( this.tryToActivate(pattern, holder, status) )
+ {
+// nameStatus.isActive = true;
+ }
}
}
this.statusMapping.put(holder.getServletInfo(), status);
@@ -112,7 +140,7 @@ public final class ServletRegistry
* Remove a servlet
* @param info The servlet info
*/
- public void removeServlet(@Nonnull final ServletInfo info)
+ public void removeServlet(@Nonnull final ServletInfo info, final boolean destroy)
{
if ( info.getPatterns() != null )
{
@@ -122,14 +150,14 @@ public final class ServletRegistry
for(final String pattern : info.getPatterns())
{
- final ServletHandler regHandler = this.activateServletMapping.get(pattern);
+ final ServletHandler regHandler = this.activeServletMappings.get(pattern);
if ( regHandler != null && regHandler.getServletHolder().getServletInfo().equals(info) )
{
cleanupHolder = regHandler.getServletHolder();
- final List<ServletHolder> inactiveList = this.inactivateServletMapping.get(pattern);
+ final List<ServletHolder> inactiveList = this.inactiveServletMappings.get(pattern);
if ( inactiveList == null )
{
- this.activateServletMapping.remove(pattern);
+ this.activeServletMappings.remove(pattern);
}
else
{
@@ -145,13 +173,13 @@ public final class ServletRegistry
}
if ( inactiveList.isEmpty() )
{
- this.inactivateServletMapping.remove(pattern);
+ this.inactiveServletMappings.remove(pattern);
}
}
}
else
{
- final List<ServletHolder> inactiveList = this.inactivateServletMapping.get(pattern);
+ final List<ServletHolder> inactiveList = this.inactiveServletMappings.get(pattern);
if ( inactiveList != null )
{
final Iterator<ServletHolder> i = inactiveList.iterator();
@@ -167,7 +195,7 @@ public final class ServletRegistry
}
if ( inactiveList.isEmpty() )
{
- this.inactivateServletMapping.remove(pattern);
+ this.inactiveServletMappings.remove(pattern);
}
}
}
@@ -182,11 +210,11 @@ public final class ServletRegistry
private void addToInactiveList(final String pattern, final ServletHolder holder, final ServletRegistrationStatus status)
{
- List<ServletHolder> inactiveList = this.inactivateServletMapping.get(pattern);
+ List<ServletHolder> inactiveList = this.inactiveServletMappings.get(pattern);
if ( inactiveList == null )
{
inactiveList = new ArrayList<ServletHolder>();
- this.inactivateServletMapping.put(pattern, inactiveList);
+ this.inactiveServletMappings.put(pattern, inactiveList);
}
inactiveList.add(holder);
Collections.sort(inactiveList);
@@ -201,7 +229,7 @@ public final class ServletRegistry
{
final Pattern p = Pattern.compile(PatternUtil.convertToRegEx(pattern));
final ServletHandler handler = new ServletHandler(holder, p);
- this.activateServletMapping.put(pattern, handler);
+ this.activeServletMappings.put(pattern, handler);
// add ok
status.pathToStatus.put(pattern, result);
@@ -219,4 +247,18 @@ public final class ServletRegistry
{
return this.statusMapping;
}
+
+ public ServletHolder resolveByName(@Nonnull String name)
+ {
+ final List<ServletNameStatus> holderList = this.servletsByName.get(name);
+ if ( holderList != null )
+ {
+ final ServletNameStatus status = holderList.get(0);
+ if ( status != null && status.isActive )
+ {
+ return status.holder;
+ }
+ }
+ return null;
+ }
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RequestInfoDTOBuilder.java Sun May 17 19:39:51 2015
@@ -16,11 +16,9 @@
*/
package org.apache.felix.http.base.internal.runtime.dto;
-import static java.util.Arrays.asList;
-
-import org.apache.felix.http.base.internal.handler.FilterHandler;
import org.apache.felix.http.base.internal.handler.HandlerRegistry;
-import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.handler.holder.FilterHolder;
+import org.apache.felix.http.base.internal.registry.PathResolution;
import org.osgi.service.http.runtime.dto.FilterDTO;
import org.osgi.service.http.runtime.dto.RequestInfoDTO;
@@ -39,19 +37,24 @@ public final class RequestInfoDTOBuilder
public RequestInfoDTO build()
{
- ServletHandler servletHandler = registry.getServletHandler(path);
- FilterHandler[] filterHandlers = registry.getFilterHandlers(servletHandler, null, path);
- Long contextServiceId = servletHandler.getContextServiceId();
+ PathResolution pr = registry.resolveServlet(path);
+ if ( pr == null )
+ {
+ // TODO what do we return?
+ return null;
+ }
+ FilterHolder[] filterHolders = registry.getFilters(pr.holder, null, path);
+ Long contextServiceId = pr.holder.getContextServiceId();
RequestInfoDTO requestInfoDTO = new RequestInfoDTO();
requestInfoDTO.path = path;
requestInfoDTO.servletContextId = contextServiceId;
+ /* TODO
requestInfoDTO.filterDTOs = FilterDTOBuilder.create()
- .build(asList(filterHandlers), contextServiceId)
+ .build(asList(filterHolders), contextServiceId)
.toArray(FILTER_DTO_ARRAY);
-
- if (servletHandler.getServletInfo().isResource())
+ if (pr.holder.getServletInfo().isResource())
{
requestInfoDTO.resourceDTO = ResourceDTOBuilder.create()
.buildDTO(servletHandler, contextServiceId);
@@ -61,6 +64,7 @@ public final class RequestInfoDTOBuilder
requestInfoDTO.servletDTO = ServletDTOBuilder.create()
.buildDTO(servletHandler, contextServiceId);
}
+ */
return requestInfoDTO;
}
}
Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/PerBundleHttpServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/PerBundleHttpServiceImpl.java?rev=1679892&r1=1679891&r2=1679892&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/PerBundleHttpServiceImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/PerBundleHttpServiceImpl.java Sun May 17 19:39:51 2015
@@ -20,6 +20,7 @@ import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -33,6 +34,8 @@ import javax.servlet.ServletRequestListe
import org.apache.felix.http.api.ExtHttpService;
import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.handler.holder.FilterHolder;
+import org.apache.felix.http.base.internal.handler.holder.HttpServiceFilterHolder;
import org.apache.felix.http.base.internal.logger.SystemLogger;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.apache.felix.http.base.internal.runtime.ServletInfo;
@@ -49,7 +52,7 @@ public final class PerBundleHttpServiceI
{
private final Bundle bundle;
private final Set<Servlet> localServlets = new HashSet<Servlet>();
- private final Set<Filter> localFilters = new HashSet<Filter>();
+ private final Set<FilterHolder> localFilters = new HashSet<FilterHolder>();
private final ServletContextManager contextManager;
private final SharedHttpServiceImpl sharedHttpService;
@@ -120,12 +123,13 @@ public final class PerBundleHttpServiceI
}
final ExtServletContext httpContext = getServletContext(context);
+ final FilterHolder holder = new HttpServiceFilterHolder(0, httpContext, filterInfo, filter);
- if ( this.sharedHttpService.registerFilter(httpContext, filter, filterInfo) )
+ if ( this.sharedHttpService.registerFilter(holder) )
{
synchronized ( this.localFilters )
{
- this.localFilters.add(filter);
+ this.localFilters.add(holder);
}
}
}
@@ -239,10 +243,10 @@ public final class PerBundleHttpServiceI
unregisterServlet(servlet, false);
}
- final Set<Filter> filters = new HashSet<Filter>(this.localFilters);
- for (final Filter fiter : filters)
+ final Set<FilterHolder> filters = new HashSet<FilterHolder>(this.localFilters);
+ for (final FilterHolder holder : filters)
{
- unregisterFilter(fiter, false);
+ this.sharedHttpService.unregisterFilter(holder, false);
}
}
@@ -288,15 +292,24 @@ public final class PerBundleHttpServiceI
return this.contextManager.getServletContext(context);
}
- private void unregisterFilter(Filter filter, final boolean destroy)
+ private void unregisterFilter(final Filter filter, final boolean destroy)
{
if (filter != null)
{
synchronized ( this.localFilters )
{
- this.localFilters.remove(filter);
+ final Iterator<FilterHolder> i = this.localFilters.iterator();
+ while ( i.hasNext() )
+ {
+ final FilterHolder h = i.next();
+ if ( h.getFilter() == filter )
+ {
+ this.sharedHttpService.unregisterFilter(h, destroy);
+ i.remove();
+ break;
+ }
+ }
}
- this.sharedHttpService.unregisterFilter(filter, destroy);
}
}