FELIX-4546 - Implement HttpServiceRuntime service:
- initial patch from Thomas applied (thanks!);
- fixed a couple of failing itests that were trivial to fix.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1661116 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
index e08d0c7..c3af022 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
@@ -29,7 +29,7 @@
import org.apache.felix.http.base.internal.handler.HttpSessionWrapper;
import org.apache.felix.http.base.internal.service.HttpServiceFactory;
import org.apache.felix.http.base.internal.service.listener.ServletContextAttributeListenerManager;
-import org.apache.felix.http.base.internal.whiteboard.WhiteboardHttpService;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
public final class HttpServiceController
@@ -39,7 +39,7 @@
private final Dispatcher dispatcher;
private final HttpServicePlugin plugin;
private final HttpServiceFactory httpServiceFactory;
- private final WhiteboardHttpService whiteboardHttpService;
+ private final WhiteboardManager whiteboardManager;
public HttpServiceController(final BundleContext bundleContext)
{
@@ -48,7 +48,7 @@
this.dispatcher = new Dispatcher(this.registry);
this.plugin = new HttpServicePlugin(bundleContext, registry);
this.httpServiceFactory = new HttpServiceFactory(this.bundleContext, this.registry);
- this.whiteboardHttpService = new WhiteboardHttpService(this.bundleContext, this.registry, this.httpServiceFactory);
+ this.whiteboardManager = new WhiteboardManager(bundleContext, this.httpServiceFactory, this.registry);
}
Dispatcher getDispatcher()
@@ -68,7 +68,7 @@
@Override
public void sessionDestroyed(final HttpSessionEvent se) {
httpServiceFactory.getSessionListener().sessionDestroyed(se);
- whiteboardHttpService.sessionDestroyed(se.getSession(), HttpSessionWrapper.getSessionContextIds(se.getSession()));
+ whiteboardManager.sessionDestroyed(se.getSession(), HttpSessionWrapper.getSessionContextIds(se.getSession()));
}
@Override
@@ -86,7 +86,7 @@
public void setProperties(final Hashtable<String, Object> props)
{
this.httpServiceFactory.setProperties(props);
- this.whiteboardHttpService.setProperties(props);
+ this.whiteboardManager.setProperties(props);
}
public void register(final ServletContext servletContext)
@@ -94,20 +94,20 @@
this.plugin.register();
this.httpServiceFactory.start(servletContext);
- this.whiteboardHttpService.start(servletContext);
+ this.whiteboardManager.start(servletContext);
- this.dispatcher.setWhiteboardHttpService(this.whiteboardHttpService);
+ this.dispatcher.setWhiteboardManager(this.whiteboardManager);
}
public void unregister()
{
this.plugin.unregister();
- this.dispatcher.setWhiteboardHttpService(null);
+ this.dispatcher.setWhiteboardManager(null);
- if ( this.whiteboardHttpService != null )
+ if ( this.whiteboardManager != null )
{
- this.whiteboardHttpService.stop();
+ this.whiteboardManager.stop();
}
if ( this.httpServiceFactory != null )
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
index 8d73570..416069e 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
@@ -56,7 +56,7 @@
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.util.UriUtils;
-import org.apache.felix.http.base.internal.whiteboard.WhiteboardHttpService;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.service.http.HttpContext;
import org.osgi.service.useradmin.Authorization;
@@ -538,16 +538,16 @@
private final HandlerRegistry handlerRegistry;
- private WhiteboardHttpService whiteboardService;
+ private WhiteboardManager whiteboardManager;
public Dispatcher(final HandlerRegistry handlerRegistry)
{
this.handlerRegistry = handlerRegistry;
}
- public void setWhiteboardHttpService(final WhiteboardHttpService service)
+ public void setWhiteboardManager(final WhiteboardManager service)
{
- this.whiteboardService = service;
+ this.whiteboardManager = service;
}
/**
@@ -565,7 +565,7 @@
if ( session != null )
{
final Set<Long> ids = HttpSessionWrapper.getExpiredSessionContextIds(session);
- this.whiteboardService.sessionDestroyed(session, ids);
+ this.whiteboardManager.sessionDestroyed(session, ids);
}
String requestURI = getRequestURI(req);
if ( requestURI == null )
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 72dfd90..39bfc7a 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,15 +16,22 @@
*/
package org.apache.felix.http.base.internal.handler;
+import static org.apache.felix.http.base.internal.util.CollectionUtils.union;
+
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
+import org.apache.felix.http.base.internal.runtime.HandlerRuntime;
+
public final class ErrorsMapping
{
private static final Pattern ERROR_CODE_PATTERN = Pattern.compile("\\d{3}");
@@ -116,4 +123,27 @@
this.exceptionsMap.clear();
}
+ @SuppressWarnings("unchecked")
+ public Collection<ServletHandler> getMappedHandlers()
+ {
+ return union(errorCodesMap.values(), exceptionsMap.values());
+ }
+
+ public HandlerRuntime.ErrorPage getErrorPage(ServletHandler servletHandler)
+ {
+ Collection<Integer> errorCodes = getCopy(servletHandler, invertedErrorCodesMap);
+ Collection<String> exceptions = getCopy(servletHandler, invertedExceptionsMap);
+ return new HandlerRuntime.ErrorPage(servletHandler, errorCodes, exceptions);
+ }
+
+ private static <T> List<T> getCopy(ServletHandler key, Map<Servlet, Collection<T>> map)
+ {
+ Collection<T> result = map.get(key.getServlet());
+ if (result != null)
+ {
+ return new ArrayList<T>(result);
+ }
+
+ return Collections.emptyList();
+ }
}
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 7bc6984..3f65777 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,6 +24,7 @@
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;
/**
@@ -217,4 +218,14 @@
}
return null;
}
+
+ public synchronized List<HandlerRuntime> getRuntime()
+ {
+ List<HandlerRuntime> handlerRuntimes = new ArrayList<HandlerRuntime>();
+ for (PerContextHandlerRegistry contextRegistry : this.registrations)
+ {
+ handlerRuntimes.add(contextRegistry.getRuntime());
+ }
+ 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 6221f47..c0ade02 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
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -29,8 +30,11 @@
import javax.servlet.ServletException;
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.util.InternalIdFactory;
public final class PerContextHandlerRegistry implements Comparable<PerContextHandlerRegistry>
{
@@ -39,7 +43,7 @@
private final Map<String, Servlet> servletPatternMap = new HashMap<String, Servlet>();
private volatile HandlerMapping<ServletHandler> servletMapping = new HandlerMapping<ServletHandler>();
private volatile HandlerMapping<FilterHandler> filterMapping = new HandlerMapping<FilterHandler>();
- private volatile ErrorsMapping errorsMapping = new ErrorsMapping();
+ private final ErrorsMapping errorsMapping = new ErrorsMapping();
private final long serviceId;
@@ -364,4 +368,19 @@
{
return this.serviceId;
}
+
+ public synchronized HandlerRuntime getRuntime() {
+ List<ServletHandler> servletHandlers = new ArrayList<ServletHandler>(servletMap.values());
+ List<FilterHandler> filterHandlers = new ArrayList<FilterHandler>(filterMap.values());
+
+ Collection<ErrorPage> errorPages = new ArrayList<HandlerRuntime.ErrorPage>();
+ Collection<ServletHandler> errorHandlers = errorsMapping.getMappedHandlers();
+ for (ServletHandler servletHandler : errorHandlers)
+ {
+ errorPages.add(errorsMapping.getErrorPage(servletHandler));
+ }
+ servletHandlers.removeAll(errorHandlers);
+
+ return new HandlerRuntime(servletHandlers, filterHandlers, errorPages, serviceId);
+ }
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
index 8f11086..4ecc318 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
@@ -137,6 +137,26 @@
this.dispatcher = new DispatcherType[] {DispatcherType.REQUEST};
}
+ FilterInfo(int serviceRanking,
+ long serviceId,
+ String name,
+ String[] patterns,
+ String[] servletNames,
+ String[] regexs,
+ boolean asyncSupported,
+ DispatcherType[] dispatcher,
+ Map<String, String> initParams)
+ {
+ super(serviceRanking, serviceId);
+ this.name = name;
+ this.patterns = patterns;
+ this.servletNames = servletNames;
+ this.regexs = regexs;
+ this.asyncSupported = asyncSupported;
+ this.dispatcher = dispatcher;
+ this.initParams = initParams;
+ }
+
@Override
public boolean isValid()
{
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HandlerRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HandlerRuntime.java
new file mode 100644
index 0000000..ee86d25
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HandlerRuntime.java
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.felix.http.base.internal.handler.FilterHandler;
+import org.apache.felix.http.base.internal.handler.ServletHandler;
+
+public final class HandlerRuntime
+{
+ private final Collection<ServletHandler> servletHandlers;
+ private final Collection<FilterHandler> filterHandlers;
+ private final Collection<ErrorPage> errorPages;
+ private final long serviceId;
+
+ public HandlerRuntime(Collection<ServletHandler> servletHandlers,
+ Collection<FilterHandler> filterHandlers,
+ Collection<ErrorPage> errorPages,
+ long serviceId)
+ {
+ this.servletHandlers = servletHandlers;
+ this.filterHandlers = filterHandlers;
+ this.errorPages = errorPages;
+ this.serviceId = serviceId;
+ }
+
+ public static HandlerRuntime empty(long serviceId)
+ {
+ return new HandlerRuntime(Collections.<ServletHandler>emptyList(),
+ Collections.<FilterHandler>emptyList(),
+ Collections.<ErrorPage> emptyList(),
+ serviceId);
+ }
+
+ public Collection<ServletHandler> getServletHandlers()
+ {
+ return servletHandlers;
+ }
+
+ public Collection<FilterHandler> getFilterHandlers()
+ {
+ return filterHandlers;
+ }
+
+ public Collection<ErrorPage> getErrorPages()
+ {
+ return errorPages;
+ }
+
+ public long getServiceId()
+ {
+ return serviceId;
+ }
+
+ public static class ErrorPage {
+ private final ServletHandler servletHandler;
+ private final Collection<Integer> errorCodes;
+ private final Collection<String> exceptions;
+
+ public ErrorPage(ServletHandler servletHandler,
+ Collection<Integer> errorCodes,
+ Collection<String> exceptions)
+ {
+ this.servletHandler = servletHandler;
+ this.errorCodes = errorCodes;
+ this.exceptions = exceptions;
+ }
+
+ public ServletHandler getServletHandler()
+ {
+ return servletHandler;
+ }
+
+ public Collection<Integer> getErrorCodes()
+ {
+ return errorCodes;
+ }
+
+ public Collection<String> getExceptions()
+ {
+ return exceptions;
+ }
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/RegistryRuntime.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/RegistryRuntime.java
new file mode 100644
index 0000000..8f83d67
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/RegistryRuntime.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;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.http.base.internal.whiteboard.ContextHandler;
+import org.osgi.framework.ServiceReference;
+
+public final class RegistryRuntime
+{
+ private final Collection<ContextHandler> contexts;
+ private final Map<Long, Collection<ServiceReference<?>>> listenerRuntimes;
+ private final Map<Long, HandlerRuntime> handlerRuntimes;
+
+ public RegistryRuntime(Collection<ContextHandler> contexts,
+ Collection<HandlerRuntime> contextRuntimes,
+ Map<Long, Collection<ServiceReference<?>>> listenerRuntimes)
+ {
+ this.contexts = contexts;
+ this.handlerRuntimes = createServiceIdMap(contextRuntimes);
+ this.listenerRuntimes = listenerRuntimes;
+ }
+
+ private static Map<Long, HandlerRuntime> createServiceIdMap(Collection<HandlerRuntime> contextRuntimes)
+ {
+ Map<Long, HandlerRuntime> runtimesMap = new HashMap<Long, HandlerRuntime>();
+ for (HandlerRuntime contextRuntime : contextRuntimes)
+ {
+ runtimesMap.put(contextRuntime.getServiceId(), contextRuntime);
+ }
+ return runtimesMap;
+ }
+
+ public HandlerRuntime getHandlerRuntime(ContextHandler contextHandler)
+ {
+ long serviceId = contextHandler.getContextInfo().getServiceId();
+
+ if (handlerRuntimes.containsKey(serviceId))
+ {
+ return handlerRuntimes.get(serviceId);
+ }
+ return HandlerRuntime.empty(serviceId);
+ }
+
+ public Collection<ServiceReference<?>> getListenerRuntime(ContextHandler contextHandler)
+ {
+ if (listenerRuntimes.containsKey(contextHandler.getContextInfo().getServiceId()))
+ {
+ return listenerRuntimes.get(contextHandler.getContextInfo().getServiceId());
+ }
+ return Collections.emptyList();
+ }
+
+ public Collection<ContextHandler> getContexts()
+ {
+ return contexts;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
index 182e31c..9eaf2af 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
@@ -52,6 +52,18 @@
this.initParams = getInitParams(ref, CONTEXT_INIT_PREFIX);
}
+ ServletContextHelperInfo(int serviceRanking,
+ long serviceId,
+ String name,
+ String path,
+ Map<String, String> initParams)
+ {
+ super(serviceRanking, serviceId);
+ this.name = name;
+ this.path = path;
+ this.initParams = initParams;
+ }
+
private boolean isValidPath()
{
if ( !this.isEmpty(path) )
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 feed6a9..c24871a 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
@@ -93,7 +93,7 @@
this.initParams = Collections.emptyMap();
}
- private static ServiceReference getRef(final ServiceReference ref)
+ private static ServiceReference getRef(ServiceReference ref)
{
return ref;
}
@@ -114,6 +114,22 @@
this.errorPage = null;
}
+ ServletInfo(int serviceRanking,
+ long serviceId,
+ String name,
+ String[] patterns,
+ String[] errorPage,
+ boolean asyncSupported,
+ Map<String, String> initParams)
+ {
+ super(serviceRanking, serviceId);
+ this.name = name;
+ this.patterns = patterns;
+ this.errorPage = errorPage;
+ this.asyncSupported = asyncSupported;
+ this.initParams = initParams;
+ }
+
@Override
public boolean isValid()
{
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceInfo.java
index 08293e1..a523446 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceInfo.java
@@ -18,8 +18,7 @@
*/
package org.apache.felix.http.base.internal.runtime;
-import java.util.concurrent.atomic.AtomicLong;
-
+import org.apache.felix.http.base.internal.util.InternalIdFactory;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
@@ -31,9 +30,6 @@
*/
public abstract class WhiteboardServiceInfo<T> extends AbstractInfo<T>
{
- /** Service id for services not provided through the service registry. */
- private static final AtomicLong serviceIdCounter = new AtomicLong(-1);
-
/** The context selection. */
private final String contextSelection;
@@ -67,7 +63,7 @@
public WhiteboardServiceInfo(final int ranking)
{
- this(ranking, serviceIdCounter.getAndDecrement());
+ this(ranking, InternalIdFactory.INSTANCE.next());
}
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
new file mode 100644
index 0000000..9546e6a
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseDTOBuilder.java
@@ -0,0 +1,56 @@
+/*
+ * 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 java.util.Arrays.copyOf;
+
+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.osgi.dto.DTO;
+
+
+abstract class BaseDTOBuilder<T, U extends DTO>
+{
+ public Collection<U> build(Collection<T> whiteboardServices, long servletContextId)
+ {
+ List<U> dtoList = new ArrayList<U>();
+ for (T whiteboardService : whiteboardServices)
+ {
+ dtoList.add(buildDTO(whiteboardService, servletContextId));
+ }
+ return dtoList;
+ }
+
+ abstract U buildDTO(T whiteboardService, long servletContextId);
+
+ protected <K, V> Map<K, V> copyWithDefault(Map<K, V> map)
+ {
+ return map == null ? Collections.<K, V>emptyMap() : new HashMap<K, V>(map);
+ }
+
+ protected <V> V[] copyWithDefault(V[] array, V[] defaultArray)
+ {
+ return array == null ? defaultArray : copyOf(array, array.length);
+ }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..50d5d94
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/BaseServletDTOBuilder.java
@@ -0,0 +1,42 @@
+/*
+ * 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.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>
+{
+ final U setBaseFields(U dto, ServletHandler servletHandler, long servletContextId)
+ {
+ ServletInfo info = servletHandler.getServletInfo();
+ Servlet servlet = servletHandler.getServlet();
+
+ dto.asyncSupported = info.isAsyncSupported();
+ dto.initParams = copyWithDefault(info.getInitParameters());
+ dto.name = info.getName();
+ dto.serviceId = servletHandler.getServletInfo().getServiceId();
+ dto.servletContextId = servletContextId;
+ dto.servletInfo = servlet.getServletInfo();
+ return dto;
+ }
+}
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
new file mode 100644
index 0000000..5fef87e
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ErrorPageDTOBuilder.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 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>
+{
+ private static final String[] STRING_ARRAY = new String[0];
+
+ @Override
+ ErrorPageDTO buildDTO(ErrorPage errorPage, long servletConextId)
+ {
+ ErrorPageDTO errorPageDTO = new ErrorPageDTO();
+ setBaseFields(errorPageDTO, errorPage.getServletHandler(), servletConextId);
+ errorPageDTO.errorCodes = getErrorCodes(errorPage.getErrorCodes());
+ errorPageDTO.exceptions = errorPage.getExceptions().toArray(STRING_ARRAY);
+ return errorPageDTO;
+ }
+
+ private long[] getErrorCodes(Collection<Integer> errorCodes)
+ {
+ Iterator<Integer> itr = errorCodes.iterator();
+ long[] result = new long[errorCodes.size()];
+ for (int i = 0; i < result.length; i++)
+ {
+ result[i] = (long) itr.next();
+ }
+ return result;
+ }
+}
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
new file mode 100644
index 0000000..6c1f9a4
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/FilterDTOBuilder.java
@@ -0,0 +1,64 @@
+/*
+ * 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.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>
+{
+ private static final String[] STRING_ARRAY = new String[0];
+
+ @Override
+ FilterDTO buildDTO(FilterHandler filterHandler, long servletContextId)
+ {
+ FilterInfo info = filterHandler.getFilterInfo();
+
+ FilterDTO filterDTO = new FilterDTO();
+ filterDTO.asyncSupported = info.isAsyncSupported();
+ filterDTO.dispatcher = getNames(info.getDispatcher());
+ filterDTO.initParams = copyWithDefault(info.getInitParameters());
+ filterDTO.name = info.getName();
+ filterDTO.patterns = copyWithDefault(info.getPatterns(), STRING_ARRAY);
+ filterDTO.regexs = copyWithDefault(info.getRegexs(), STRING_ARRAY);
+ filterDTO.serviceId = filterHandler.getFilterInfo().getServiceId();
+ filterDTO.servletContextId = servletContextId;
+ filterDTO.servletNames = copyWithDefault(info.getServletNames(), STRING_ARRAY);
+
+ return filterDTO;
+ }
+
+ private String[] getNames(DispatcherType[] dispatcher)
+ {
+ if (dispatcher == null)
+ {
+ return STRING_ARRAY;
+ }
+
+ String[] names = new String[dispatcher.length];
+ for (int i = 0; i < dispatcher.length; i++)
+ {
+ names[i] = dispatcher[i].name();
+ }
+ return names;
+ }
+}
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
new file mode 100644
index 0000000..34d2989
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
@@ -0,0 +1,37 @@
+/*
+ * 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.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.runtime.dto.ListenerDTO;
+
+final class ListenerDTOBuilder extends BaseDTOBuilder<ServiceReference<?>, ListenerDTO>
+{
+ @Override
+ ListenerDTO buildDTO(ServiceReference<?> listenerRef, long servletContextId)
+ {
+ ListenerDTO listenerDTO = new ListenerDTO();
+ listenerDTO.serviceId = (Long) listenerRef.getProperty(Constants.SERVICE_ID);
+ listenerDTO.servletContextId = servletContextId;
+ // TODO Is this the desired value?
+ listenerDTO.types = (String[]) listenerRef.getProperty(Constants.OBJECTCLASS);
+ return listenerDTO;
+ }
+}
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
new file mode 100644
index 0000000..25a40da
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ResourceDTOBuilder.java
@@ -0,0 +1,37 @@
+/*
+ * 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.handler.ServletHandler;
+import org.osgi.service.http.runtime.dto.ResourceDTO;
+
+//TODO
+final class ResourceDTOBuilder extends BaseDTOBuilder<ServletHandler, ResourceDTO>
+{
+ @Override
+ ResourceDTO buildDTO(ServletHandler handler, long servletContextId)
+ {
+ ResourceDTO resourceDTO = new ResourceDTO();
+ resourceDTO.patterns = null;
+ resourceDTO.prefix = null;
+ resourceDTO.serviceId = handler.getServletInfo().getServiceId();
+ resourceDTO.servletContextId = servletContextId;
+ return resourceDTO;
+ }
+}
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
new file mode 100644
index 0000000..80792e6
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilder.java
@@ -0,0 +1,125 @@
+/*
+ * 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.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.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.whiteboard.ContextHandler;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.runtime.dto.ErrorPageDTO;
+import org.osgi.service.http.runtime.dto.FilterDTO;
+import org.osgi.service.http.runtime.dto.ListenerDTO;
+import org.osgi.service.http.runtime.dto.ResourceDTO;
+import org.osgi.service.http.runtime.dto.RuntimeDTO;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
+import org.osgi.service.http.runtime.dto.ServletDTO;
+
+public final class RuntimeDTOBuilder
+{
+ private static final ServletContextDTO[] CONTEXT_DTO_ARRAY = new ServletContextDTO[0];
+
+ 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;
+
+ public RuntimeDTOBuilder(RegistryRuntime registry, Map<String, Object> serviceProperties)
+ {
+ this.registry = registry;
+ this.serviceProperties = serviceProperties;
+ }
+
+ public RuntimeDTO build()
+ {
+ RuntimeDTO runtimeDTO = new RuntimeDTO();
+ runtimeDTO.attributes = createAttributes();
+ //TODO <**
+ runtimeDTO.failedErrorPageDTOs = null;
+ runtimeDTO.failedFilterDTOs = null;
+ runtimeDTO.failedListenerDTOs = null;
+ runtimeDTO.failedResourceDTOs = null;
+ runtimeDTO.failedServletContextDTOs = null;
+ runtimeDTO.failedServletDTOs = null;
+ //**>
+ runtimeDTO.servletContextDTOs = createContextDTOs();
+ return runtimeDTO;
+ }
+
+ private Map<String, String> createAttributes()
+ {
+ Map<String, String> attributes = new HashMap<String, String>();
+ for (Map.Entry<String, Object> entry : this.serviceProperties.entrySet())
+ {
+ attributes.put(entry.getKey(), entry.getValue().toString());
+ }
+ return attributes;
+ }
+
+ private ServletContextDTO[] createContextDTOs()
+ {
+ List<ServletContextDTO> contextDTOs = new ArrayList<ServletContextDTO>();
+ for (ContextHandler context : registry.getContexts())
+ {
+ contextDTOs.add(createContextDTO(context,
+ registry.getHandlerRuntime(context),
+ registry.getListenerRuntime(context)));
+ }
+ return contextDTOs.toArray(CONTEXT_DTO_ARRAY);
+ }
+
+ private ServletContextDTO createContextDTO(ContextHandler context,
+ HandlerRuntime handlerRuntime,
+ Collection<ServiceReference<?>> listenerRefs)
+ {
+ Collection<ServletHandler> servletHandlers = handlerRuntime.getServletHandlers();
+ //TODO missing functionality
+ Collection<ServletHandler> resourceHandlers = Collections.emptyList();
+ Collection<FilterHandler> filterHandlers = handlerRuntime.getFilterHandlers();
+ Collection<ErrorPage> errorPages = handlerRuntime.getErrorPages();
+ long servletContextId = handlerRuntime.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);
+
+ return new ServletContextDTOBuilder(context,
+ servletDTOs,
+ resourcesDTOs,
+ filtersDTOs,
+ errorsDTOs,
+ listenersDTOs)
+ .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
new file mode 100644
index 0000000..5ee0fa1
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletContextDTOBuilder.java
@@ -0,0 +1,138 @@
+/*
+ * 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 java.util.Collections.list;
+
+import java.util.Collection;
+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;
+import org.osgi.service.http.runtime.dto.ListenerDTO;
+import org.osgi.service.http.runtime.dto.ResourceDTO;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
+import org.osgi.service.http.runtime.dto.ServletDTO;
+
+final class ServletContextDTOBuilder
+{
+ private static final ServletDTO[] SERVLET_DTO_ARRAY = new ServletDTO[0];
+ private static final ResourceDTO[] RESOURCE_DTO_ARRAY = new ResourceDTO[0];
+ private static final FilterDTO[] FILTER_DTO_ARRAY = new FilterDTO[0];
+ private static final ErrorPageDTO[] ERROR_PAGE_DTO_ARRAY = new ErrorPageDTO[0];
+ private static final ListenerDTO[] LISTENER_DTO_ARRAY = new ListenerDTO[0];
+
+ private final ContextHandler contextHandler;
+ private final ServletDTO[] servletDTOs;
+ private final ResourceDTO[] resourceDTOs;
+ private final FilterDTO[] filterDTOs;
+ private final ErrorPageDTO[] errorPageDTOs;
+ private final ListenerDTO[] listenerDTOs;
+
+ public ServletContextDTOBuilder(ContextHandler contextHandler,
+ Collection<ServletDTO> servletDTOs,
+ Collection<ResourceDTO> resourceDTOs,
+ Collection<FilterDTO> filterDTOs,
+ Collection<ErrorPageDTO> errorPageDTOs,
+ Collection<ListenerDTO> listenerDTOs)
+ {
+ this.contextHandler = contextHandler;
+ this.servletDTOs = servletDTOs != null ?
+ servletDTOs.toArray(SERVLET_DTO_ARRAY) : SERVLET_DTO_ARRAY;
+ this.resourceDTOs = resourceDTOs != null ?
+ resourceDTOs.toArray(RESOURCE_DTO_ARRAY) : RESOURCE_DTO_ARRAY;
+ this.filterDTOs = filterDTOs != null ?
+ filterDTOs.toArray(FILTER_DTO_ARRAY) : FILTER_DTO_ARRAY;
+ this.errorPageDTOs = errorPageDTOs != null ?
+ errorPageDTOs.toArray(ERROR_PAGE_DTO_ARRAY) : ERROR_PAGE_DTO_ARRAY;
+ this.listenerDTOs = listenerDTOs != null ?
+ listenerDTOs.toArray(LISTENER_DTO_ARRAY) : LISTENER_DTO_ARRAY;
+ }
+
+ ServletContextDTO build()
+ {
+ ServletContext context = contextHandler.getSharedContext();
+ ServletContextHelperInfo contextInfo = contextHandler.getContextInfo();
+ long contextId = contextInfo.getServiceId();
+
+ ServletContextDTO contextDTO = new ServletContextDTO();
+ contextDTO.attributes = getAttributes(context);
+ contextDTO.contextName = context.getServletContextName();
+ contextDTO.contextPath = context.getContextPath();
+ contextDTO.errorPageDTOs = errorPageDTOs;
+ contextDTO.filterDTOs = filterDTOs;
+ contextDTO.initParams = getInitParameters(context);
+ contextDTO.listenerDTOs = listenerDTOs;
+ contextDTO.name = contextId >= 0 ? contextInfo.getName() : null;
+ contextDTO.resourceDTOs = resourceDTOs;
+ contextDTO.servletDTOs = servletDTOs;
+ contextDTO.serviceId = contextId;
+ return contextDTO;
+ }
+
+ private Map<String, Object> getAttributes(ServletContext context)
+ {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ for (String name : list(context.getAttributeNames()))
+ {
+ Object attribute = context.getAttribute(name);
+ if (isSupportedType(attribute))
+ {
+ attributes.put(name, attribute);
+ }
+ }
+ return attributes;
+ }
+
+ private boolean isSupportedType(Object attribute)
+ {
+ Class<?> attributeClass = attribute.getClass();
+ Class<?> type = !attributeClass.isArray() ?
+ attributeClass : attributeClass.getComponentType();
+
+ return Number.class.isAssignableFrom(type) ||
+ Boolean.class.isAssignableFrom(type) ||
+ String.class.isAssignableFrom(type) ||
+ DTO.class.isAssignableFrom(type) ||
+ boolean.class.isAssignableFrom(type) ||
+ int.class.isAssignableFrom(type) ||
+ double.class.isAssignableFrom(type) ||
+ float.class.isAssignableFrom(type) ||
+ long.class.isAssignableFrom(type) ||
+ short.class.isAssignableFrom(type) ||
+ byte.class.isAssignableFrom(type) ||
+ char.class.isAssignableFrom(type);
+ }
+
+ private Map<String, String> getInitParameters(ServletContext context)
+ {
+ Map<String, String> initParameters = new HashMap<String, String>();
+ for (String name : list(context.getInitParameterNames()))
+ {
+ initParameters.put(name, context.getInitParameter(name));
+ }
+ return initParameters;
+ }
+}
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
new file mode 100644
index 0000000..0444837
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ServletDTOBuilder.java
@@ -0,0 +1,46 @@
+/*
+ * 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.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>
+{
+ @Override
+ ServletDTO buildDTO(ServletHandler servletHandler, long servletContextId)
+ {
+ ServletInfo info = servletHandler.getServletInfo();
+
+ ServletDTO servletDTO = new ServletDTO();
+ setBaseFields(servletDTO, servletHandler, servletContextId);
+ servletDTO.patterns = copyWithDefault(checkNotEmpty(info.getPatterns()), null);
+ return servletDTO;
+ }
+
+ private String[] checkNotEmpty(String[] patterns)
+ {
+ if (patterns == null || patterns.length == 0)
+ {
+ throw new IllegalArgumentException("No patterns specified in servlet info");
+ }
+ return patterns;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
index 5021732..bb5a128 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
@@ -51,22 +51,26 @@
private final Set<Servlet> localServlets = new HashSet<Servlet>();
private final Set<Filter> localFilters = new HashSet<Filter>();
private final ServletContextManager contextManager;
-
private final Map<String, ServletHandler> aliasMap = new HashMap<String, ServletHandler>();
- public HttpServiceImpl(final Bundle bundle,
- final ServletContext context,
- final PerContextHandlerRegistry handlerRegistry,
- final ServletContextAttributeListener servletAttributeListener,
- final boolean sharedContextAttributes,
- final ServletRequestListener reqListener,
- final ServletRequestAttributeListener reqAttrListener)
+ public HttpServiceImpl(Bundle bundle, ServletContext context, PerContextHandlerRegistry handlerRegistry, ServletContextAttributeListener servletAttributeListener, boolean sharedContextAttributes, ServletRequestListener reqListener, ServletRequestAttributeListener reqAttrListener)
{
+ if (bundle == null)
+ {
+ throw new IllegalArgumentException("Bundle cannot be null!");
+ }
+ if (context == null)
+ {
+ throw new IllegalArgumentException("Context cannot be null!");
+ }
+ if (handlerRegistry == null)
+ {
+ throw new IllegalArgumentException("HandlerRegistry cannot be null!");
+ }
+
this.bundle = bundle;
this.handlerRegistry = handlerRegistry;
- this.contextManager = new ServletContextManager(this.bundle, context,
- servletAttributeListener, sharedContextAttributes,
- reqListener, reqAttrListener);
+ this.contextManager = new ServletContextManager(this.bundle, context, servletAttributeListener, sharedContextAttributes, reqListener, reqAttrListener);
}
@Override
@@ -87,7 +91,7 @@
}
final Map<String, String> paramMap = new HashMap<String, String>();
- if ( initParams != null && initParams.size() > 0 )
+ if (initParams != null && initParams.size() > 0)
{
Enumeration e = initParams.keys();
while (e.hasMoreElements())
@@ -102,9 +106,8 @@
}
}
- final FilterInfo filterInfo = new FilterInfo(String.format("%s_%d", filter.getClass(), this.hashCode()),
- pattern, ranking, paramMap);
- if ( !filterInfo.isValid() )
+ final FilterInfo filterInfo = new FilterInfo(String.format("%s_%d", filter.getClass(), this.hashCode()), pattern, ranking, paramMap);
+ if (!filterInfo.isValid())
{
throw new ServletException("Invalid registration information for filter.");
}
@@ -112,9 +115,12 @@
final ExtServletContext httpContext = getServletContext(context);
FilterHandler handler = new FilterHandler(null, httpContext, filter, filterInfo);
- try {
+ try
+ {
this.handlerRegistry.addFilter(handler);
- } catch (ServletException e) {
+ }
+ catch (ServletException e)
+ {
// TODO create failure DTO
}
this.localFilters.add(filter);
@@ -148,8 +154,7 @@
* @see org.osgi.service.http.HttpService#registerServlet(java.lang.String, javax.servlet.Servlet, java.util.Dictionary, org.osgi.service.http.HttpContext)
*/
@Override
- public void registerServlet(String alias, Servlet servlet, Dictionary initParams, HttpContext context)
- throws ServletException, NamespaceException
+ public void registerServlet(String alias, Servlet servlet, Dictionary initParams, HttpContext context) throws ServletException, NamespaceException
{
if (servlet == null)
{
@@ -161,7 +166,7 @@
}
final Map<String, String> paramMap = new HashMap<String, String>();
- if ( initParams != null && initParams.size() > 0 )
+ if (initParams != null && initParams.size() > 0)
{
Enumeration e = initParams.keys();
while (e.hasMoreElements())
@@ -176,25 +181,21 @@
}
}
- final ServletInfo servletInfo = new ServletInfo(String.format("%s_%d",servlet.getClass(), this.hashCode()),
- alias, 0, paramMap);
+ final ServletInfo servletInfo = new ServletInfo(String.format("%s_%d", servlet.getClass(), this.hashCode()), alias, 0, paramMap);
final ExtServletContext httpContext = getServletContext(context);
- final ServletHandler handler = new ServletHandler(null,
- httpContext,
- servletInfo,
- servlet);
+ final ServletHandler handler = new ServletHandler(null, httpContext, servletInfo, servlet);
- synchronized ( this.aliasMap )
+ synchronized (this.aliasMap)
{
- if ( this.aliasMap.containsKey(alias) )
- {
- throw new NamespaceException("Alias " + alias + " is already in use.");
- }
- if ( this.localServlets.contains(servlet) )
- {
+ if (this.aliasMap.containsKey(alias))
+ {
+ throw new NamespaceException("Alias " + alias + " is already in use.");
+ }
+ if (this.localServlets.contains(servlet))
+ {
throw new ServletException("Servlet instance " + handler.getName() + " already registered");
- }
+ }
this.handlerRegistry.addServlet(handler);
@@ -209,19 +210,19 @@
@Override
public void unregister(final String alias)
{
- synchronized ( this.aliasMap )
+ synchronized (this.aliasMap)
{
- final ServletHandler handler = this.aliasMap.remove(alias);
- if ( handler == null )
- {
- throw new IllegalArgumentException("Nothing registered at " + alias);
- }
- final Servlet servlet = this.handlerRegistry.removeServlet(handler.getServletInfo(), true);
- if (servlet != null)
- {
- this.localServlets.remove(servlet);
- }
- }
+ final ServletHandler handler = this.aliasMap.remove(alias);
+ if (handler == null)
+ {
+ throw new IllegalArgumentException("Nothing registered at " + alias);
+ }
+ final Servlet servlet = this.handlerRegistry.removeServlet(handler.getServletInfo(), true);
+ if (servlet != null)
+ {
+ this.localServlets.remove(servlet);
+ }
+ }
}
public void unregisterAll()
@@ -261,23 +262,23 @@
private void unregisterServlet(final Servlet servlet, final boolean destroy)
{
- if ( servlet != null )
+ if (servlet != null)
{
this.handlerRegistry.removeServlet(servlet, destroy);
- synchronized ( this.aliasMap )
+ synchronized (this.aliasMap)
{
- final Iterator<Map.Entry<String, ServletHandler>> i = this.aliasMap.entrySet().iterator();
- while ( i.hasNext() )
- {
- final Map.Entry<String, ServletHandler> entry = i.next();
- if ( entry.getValue().getServlet() == servlet )
- {
- i.remove();
- break;
- }
+ final Iterator<Map.Entry<String, ServletHandler>> i = this.aliasMap.entrySet().iterator();
+ while (i.hasNext())
+ {
+ final Map.Entry<String, ServletHandler> entry = i.next();
+ if (entry.getValue().getServlet() == servlet)
+ {
+ i.remove();
+ break;
+ }
- }
- this.localServlets.remove(servlet);
+ }
+ this.localServlets.remove(servlet);
}
}
}
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
new file mode 100644
index 0000000..096ae72
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.http.base.internal.service;
+
+import static java.util.Collections.list;
+
+import java.util.Dictionary;
+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.RuntimeDTOBuilder;
+import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
+import org.osgi.service.http.runtime.dto.RequestInfoDTO;
+import org.osgi.service.http.runtime.dto.RuntimeDTO;
+
+public final class HttpServiceRuntimeImpl implements HttpServiceRuntime
+{
+ private final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
+
+ private final HandlerRegistry registry;
+ private final ServletContextHelperManager contextManager;
+
+
+ public HttpServiceRuntimeImpl(HandlerRegistry registry,
+ ServletContextHelperManager contextManager)
+ {
+ this.registry = registry;
+ this.contextManager = contextManager;
+ }
+
+ public synchronized RuntimeDTO getRuntimeDTO()
+ {
+ RegistryRuntime runtime = contextManager.getRuntime(registry);
+ RuntimeDTOBuilder runtimeDTOBuilder = new RuntimeDTOBuilder(runtime, attributes);
+ return runtimeDTOBuilder.build();
+ }
+
+ @Override
+ public RequestInfoDTO calculateRequestInfoDTO(String path)
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public synchronized void setAttribute(String name, Object value)
+ {
+ attributes.put(name, value);
+ }
+
+ public synchronized void setAllAttributes(Dictionary<String, Object> attributes)
+ {
+ this.attributes.clear();
+ for (String key :list(attributes.keys()))
+ {
+ this.attributes.put(key, attributes.get(key));
+ }
+ }
+
+ public synchronized Dictionary<String, Object> getAttributes()
+ {
+ return attributes;
+ }
+}
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
new file mode 100644
index 0000000..2f3b45f
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/util/CollectionUtils.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.http.base.internal.util;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class CollectionUtils {
+ public static <T extends Comparable<?>> Set<T> union(Collection<? extends T>... collections)
+ {
+ Set<T> union = new TreeSet<T>();
+ for (Collection<? extends T> collection : collections)
+ {
+ union.addAll(collection);
+ }
+ return union;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/util/InternalIdFactory.java b/http/base/src/main/java/org/apache/felix/http/base/internal/util/InternalIdFactory.java
new file mode 100644
index 0000000..4d432d5
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/util/InternalIdFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.http.base.internal.util;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Provides service ids for services not provided through the service registry.
+ * <p>
+ * All provided ids are unique negative {@code long}s.
+ */
+public enum InternalIdFactory
+{
+ INSTANCE;
+
+ private final AtomicLong idCounter = new AtomicLong();
+
+ public long next()
+ {
+ return idCounter.decrementAndGet();
+ }
+}
\ No newline at end of file
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 15c344a..344b4b7 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
@@ -18,37 +18,19 @@
import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.ConcurrentSkipListSet;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
-import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
-import javax.servlet.ServletContextEvent;
-import javax.servlet.ServletContextListener;
-import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
-import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpSessionAttributeListener;
-import javax.servlet.http.HttpSessionBindingEvent;
-import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.felix.http.base.internal.context.ExtServletContext;
-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.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceObjects;
-import org.osgi.framework.ServiceReference;
import org.osgi.service.http.context.ServletContextHelper;
public final class ContextHandler implements Comparable<ContextHandler>
@@ -65,53 +47,41 @@
/** A map of all created servlet contexts. Each bundle gets it's own instance. */
private final Map<Long, ContextHolder> perBundleContextMap = new HashMap<Long, ContextHolder>();
- /** Servlet context listeners. */
- private final Map<Long, ServletContextListener> listeners = new HashMap<Long, ServletContextListener>();
+ private final HttpSessionListener sessionListener;
+ private final HttpSessionAttributeListener sessionAttributeListener;
+ private final ServletRequestListener requestListener;
+ private final ServletRequestAttributeListener requestAttributeListener;
- /** Servlet context attribute listeners. */
- private final Map<ServiceReference<ServletContextAttributeListener>, ServletContextAttributeListener> contextAttributeListeners =
- new ConcurrentSkipListMap<ServiceReference<ServletContextAttributeListener>, ServletContextAttributeListener>();
+ public ContextHandler(ServletContextHelperInfo info,
+ ServletContext webContext,
+ PerContextEventListener eventListener,
+ Bundle bundle)
+ {
+ this(info, webContext, eventListener, eventListener, eventListener, eventListener, eventListener, bundle);
+ }
- /** Session attribute listeners. */
- private final Map<ServiceReference<HttpSessionAttributeListener>, HttpSessionAttributeListener> sessionAttributeListeners =
- new ConcurrentSkipListMap<ServiceReference<HttpSessionAttributeListener>, HttpSessionAttributeListener>();
-
- /** Session listeners. */
- private final Map<ServiceReference<HttpSessionListener>, HttpSessionListener> sessionListeners =
- new ConcurrentSkipListMap<ServiceReference<HttpSessionListener>, HttpSessionListener>();
-
- /** Request listeners. */
- private final Map<ServiceReference<ServletRequestListener>, ServletRequestListener> requestListeners =
- new ConcurrentSkipListMap<ServiceReference<ServletRequestListener>, ServletRequestListener>();
-
- /** Request attribute listeners. */
- private final Map<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener> requestAttributeListeners =
- new ConcurrentSkipListMap<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener>();
-
- /** All whiteboard services - servlets, filters, resources. */
- private final Set<WhiteboardServiceInfo<?>> whiteboardServices = new ConcurrentSkipListSet<WhiteboardServiceInfo<?>>();
-
- /**
- * Create new handler.
- * @param info
- * @param webContext
- */
- public ContextHandler(final ServletContextHelperInfo info,
- final ServletContext webContext,
- final Bundle bundle)
+ public ContextHandler(ServletContextHelperInfo info,
+ ServletContext webContext,
+ ServletContextAttributeListener servletContextAttributeListener,
+ HttpSessionListener sessionListener,
+ HttpSessionAttributeListener sessionAttributeListener,
+ ServletRequestListener requestListener,
+ ServletRequestAttributeListener requestAttributeListener,
+ Bundle bundle)
{
this.info = info;
+ this.sessionListener = sessionListener;
+ this.sessionAttributeListener = sessionAttributeListener;
+ this.requestListener = requestListener;
+ this.requestAttributeListener = requestAttributeListener;
this.bundle = bundle;
this.sharedContext = new SharedServletContextImpl(webContext,
info.getName(),
info.getPath(),
info.getInitParameters(),
- getContextAttributeListener());
+ servletContextAttributeListener);
}
- /**
- * Get the context info
- */
public ServletContextHelperInfo getContextInfo()
{
return this.info;
@@ -131,36 +101,11 @@
public void deactivate()
{
this.ungetServletContext(bundle);
- this.whiteboardServices.clear();
}
- public void initialized(@Nonnull final ServletContextListenerInfo listenerInfo)
+ public ServletContext getSharedContext()
{
- final ServletContextListener listener = listenerInfo.getService(bundle);
- if ( listener != null)
- {
- // no need to sync map - initialized is called in sync
- this.listeners.put(listenerInfo.getServiceId(), listener);
-
- final ServletContext context = this.getServletContext(listenerInfo.getServiceReference().getBundle());
-
- listener.contextInitialized(new ServletContextEvent(context));
- }
- }
-
- public void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo)
- {
- // no need to sync map - destroyed is called in sync
- final ServletContextListener listener = this.listeners.remove(listenerInfo.getServiceId());
- if ( listener != null )
- {
- final ServletContext context = this.getServletContext(listenerInfo.getServiceReference().getBundle());
- listener.contextDestroyed(new ServletContextEvent(context));
- // call unget twice, once for the call in initialized and once for the call in this method(!)
- this.ungetServletContext(listenerInfo.getServiceReference().getBundle());
- this.ungetServletContext(listenerInfo.getServiceReference().getBundle());
- listenerInfo.ungetService(bundle, listener);
- }
+ return sharedContext;
}
public ExtServletContext getServletContext(@Nonnull final Bundle bundle)
@@ -180,10 +125,10 @@
holder.servletContext = new PerBundleServletContextImpl(bundle,
this.sharedContext,
holder.servletContextHelper,
- this.getSessionListener(),
- this.getSessionAttributeListener(),
- this.getServletRequestListener(),
- this.getServletRequestAttributeListener());
+ this.sessionListener,
+ this.sessionAttributeListener,
+ this.requestListener,
+ this.requestAttributeListener);
this.perBundleContextMap.put(key, holder);
}
// TODO - check null for so
@@ -226,289 +171,10 @@
}
}
- /**
- * Add servlet context attribute listener
- * @param info
- */
- public void addListener(@Nonnull final ServletContextAttributeListenerInfo info)
- {
- final ServletContextAttributeListener service = info.getService(bundle);
- if ( service != null )
- {
- this.contextAttributeListeners.put(info.getServiceReference(), service);
- }
- }
-
- /**
- * Remove servlet context attribute listener
- * @param info
- */
- public void removeListener(@Nonnull final ServletContextAttributeListenerInfo info)
- {
- final ServletContextAttributeListener service = this.contextAttributeListeners.remove(info.getServiceReference());
- if ( service != null )
- {
- info.ungetService(bundle, service);
- }
- }
-
- /**
- * Add session attribute listener
- * @param info
- */
- public void addListener(@Nonnull final HttpSessionAttributeListenerInfo info)
- {
- final HttpSessionAttributeListener service = info.getService(bundle);
- if ( service != null )
- {
- this.sessionAttributeListeners.put(info.getServiceReference(), service);
- }
- }
-
- /**
- * Remove session attribute listener
- * @param info
- */
- public void removeListener(@Nonnull final HttpSessionAttributeListenerInfo info)
- {
- final HttpSessionAttributeListener service = this.sessionAttributeListeners.remove(info.getServiceReference());
- if ( service != null )
- {
- info.ungetService(bundle, service);
- }
- }
-
- /**
- * Add session listener
- * @param info
- */
- public void addListener(@Nonnull final HttpSessionListenerInfo info)
- {
- final HttpSessionListener service = info.getService(bundle);
- if ( service != null )
- {
- this.sessionListeners.put(info.getServiceReference(), service);
- }
- }
-
- /**
- * Remove session listener
- * @param info
- */
- public void removeListener(@Nonnull final HttpSessionListenerInfo info)
- {
- final HttpSessionListener service = this.sessionListeners.remove(info.getServiceReference());
- if ( service != null )
- {
- info.ungetService(bundle, service);
- }
- }
-
- /**
- * Add request listener
- * @param info
- */
- public void addListener(@Nonnull final ServletRequestListenerInfo info)
- {
- final ServletRequestListener service = info.getService(bundle);
- if ( service != null )
- {
- this.requestListeners.put(info.getServiceReference(), service);
- }
- }
-
- /**
- * Remove request listener
- * @param info
- */
- public void removeListener(@Nonnull final ServletRequestListenerInfo info)
- {
- final ServletRequestListener service = this.requestListeners.remove(info.getServiceReference());
- if ( service != null )
- {
- info.ungetService(bundle, service);
- }
- }
-
- /**
- * Add request attribute listener
- * @param info
- */
- public void addListener(@Nonnull final ServletRequestAttributeListenerInfo info)
- {
- final ServletRequestAttributeListener service = info.getService(bundle);
- if ( service != null )
- {
- this.requestAttributeListeners.put(info.getServiceReference(), service);
- }
- }
-
- /**
- * Remove request attribute listener
- * @param info
- */
- public void removeListener(@Nonnull final ServletRequestAttributeListenerInfo info)
- {
- final ServletRequestAttributeListener service = this.requestAttributeListeners.remove(info.getServiceReference());
- if ( service != null )
- {
- info.ungetService(bundle, service);
- }
- }
-
private static final class ContextHolder
{
public long counter;
public ExtServletContext servletContext;
public ServletContextHelper servletContextHelper;
}
-
- public HttpSessionAttributeListener getSessionAttributeListener()
- {
- return new HttpSessionAttributeListener() {
-
- @Override
- public void attributeReplaced(final HttpSessionBindingEvent event) {
- for(final HttpSessionAttributeListener l : sessionAttributeListeners.values())
- {
- l.attributeReplaced(event);
- }
- }
-
- @Override
- public void attributeRemoved(final HttpSessionBindingEvent event) {
- for(final HttpSessionAttributeListener l : sessionAttributeListeners.values())
- {
- l.attributeReplaced(event);
- }
- }
-
- @Override
- public void attributeAdded(final HttpSessionBindingEvent event) {
- for(final HttpSessionAttributeListener l : sessionAttributeListeners.values())
- {
- l.attributeReplaced(event);
- }
- }
- };
- }
-
- private ServletContextAttributeListener getContextAttributeListener()
- {
- return new ServletContextAttributeListener() {
-
- @Override
- public void attributeReplaced(final ServletContextAttributeEvent event) {
- for(final ServletContextAttributeListener l : contextAttributeListeners.values())
- {
- l.attributeReplaced(event);
- }
- }
-
- @Override
- public void attributeRemoved(final ServletContextAttributeEvent event) {
- for(final ServletContextAttributeListener l : contextAttributeListeners.values())
- {
- l.attributeReplaced(event);
- }
- }
-
- @Override
- public void attributeAdded(final ServletContextAttributeEvent event) {
- for(final ServletContextAttributeListener l : contextAttributeListeners.values())
- {
- l.attributeReplaced(event);
- }
- }
- };
- }
-
- public HttpSessionListener getSessionListener()
- {
- return new HttpSessionListener() {
-
- @Override
- public void sessionCreated(final HttpSessionEvent se) {
- for(final HttpSessionListener l : sessionListeners.values())
- {
- l.sessionCreated(se);
- }
- }
-
- @Override
- public void sessionDestroyed(final HttpSessionEvent se) {
- for(final HttpSessionListener l : sessionListeners.values())
- {
- l.sessionDestroyed(se);
- }
- }
- };
- }
-
- private ServletRequestListener getServletRequestListener()
- {
- return new ServletRequestListener() {
-
- @Override
- public void requestDestroyed(final ServletRequestEvent sre) {
- for(final ServletRequestListener l : requestListeners.values())
- {
- l.requestDestroyed(sre);
- }
- }
-
- @Override
- public void requestInitialized(final ServletRequestEvent sre) {
- for(final ServletRequestListener l : requestListeners.values())
- {
- l.requestInitialized(sre);
- }
- }
- };
- }
-
- private ServletRequestAttributeListener getServletRequestAttributeListener()
- {
- return new ServletRequestAttributeListener() {
-
- @Override
- public void attributeAdded(final ServletRequestAttributeEvent srae) {
- for(final ServletRequestAttributeListener l : requestAttributeListeners.values())
- {
- l.attributeAdded(srae);
- }
- }
-
- @Override
- public void attributeRemoved(final ServletRequestAttributeEvent srae) {
- for(final ServletRequestAttributeListener l : requestAttributeListeners.values())
- {
- l.attributeRemoved(srae);
- }
- }
-
- @Override
- public void attributeReplaced(final ServletRequestAttributeEvent srae) {
- for(final ServletRequestAttributeListener l : requestAttributeListeners.values())
- {
- l.attributeReplaced(srae);
- }
- }
- };
- }
-
- public void addWhiteboardService(final WhiteboardServiceInfo<?> info)
- {
- this.whiteboardServices.add(info);
- }
-
- public void removeWhiteboardService(final WhiteboardServiceInfo<?> info)
- {
- this.whiteboardServices.remove(info);
- }
-
- public Set<WhiteboardServiceInfo<?>> getWhiteboardServices()
- {
- return this.whiteboardServices;
- }
}
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
new file mode 100644
index 0000000..43d26c2
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java
@@ -0,0 +1,103 @@
+/*
+ * 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 java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.annotation.Nonnull;
+
+import org.apache.felix.http.base.internal.runtime.ListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+public final class ListenerRegistry
+{
+ private final Map<ServletContextHelperInfo, PerContextEventListener> registriesByContext = new TreeMap<ServletContextHelperInfo, PerContextEventListener>();
+
+ private final Bundle bundle;
+
+ public ListenerRegistry(final Bundle bundle)
+ {
+ 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))
+ {
+ throw new IllegalArgumentException("Context with id " + info.getServiceId() + "is already registered");
+ }
+
+ PerContextEventListener contextRegistry = new PerContextEventListener(bundle);
+ registriesByContext.put(info, contextRegistry);
+ return contextRegistry;
+ }
+
+ public void removeContext(ServletContextHelperInfo info)
+ {
+ registriesByContext.remove(info);
+ }
+
+ 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());
+ }
+ 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
new file mode 100644
index 0000000..fd9e851
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
@@ -0,0 +1,416 @@
+/*
+ * 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 java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import javax.annotation.Nonnull;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextAttributeEvent;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+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;
+import org.apache.felix.http.base.internal.runtime.ServletRequestListenerInfo;
+import org.apache.felix.http.base.internal.util.CollectionUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+public final class PerContextEventListener implements
+ HttpSessionListener,
+ HttpSessionAttributeListener,
+ ServletContextAttributeListener,
+ ServletRequestListener,
+ ServletRequestAttributeListener
+{
+ /** Servlet context listeners. */
+ private final Map<ServiceReference<ServletContextListener>, ServletContextListener> listeners = new HashMap<ServiceReference<ServletContextListener>, ServletContextListener>();
+
+ /** Servlet context attribute listeners. */
+ private final Map<ServiceReference<ServletContextAttributeListener>, ServletContextAttributeListener> contextAttributeListeners = new ConcurrentSkipListMap<ServiceReference<ServletContextAttributeListener>, ServletContextAttributeListener>();
+
+ /** Session attribute listeners. */
+ private final Map<ServiceReference<HttpSessionAttributeListener>, HttpSessionAttributeListener> sessionAttributeListeners = new ConcurrentSkipListMap<ServiceReference<HttpSessionAttributeListener>, HttpSessionAttributeListener>();
+
+ /** Session listeners. */
+ private final Map<ServiceReference<HttpSessionListener>, HttpSessionListener> sessionListeners = new ConcurrentSkipListMap<ServiceReference<HttpSessionListener>, HttpSessionListener>();
+
+ /** Request listeners. */
+ private final Map<ServiceReference<ServletRequestListener>, ServletRequestListener> requestListeners = new ConcurrentSkipListMap<ServiceReference<ServletRequestListener>, ServletRequestListener>();
+
+ /** Request attribute listeners. */
+ private final Map<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener> requestAttributeListeners = new ConcurrentSkipListMap<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener>();
+
+ private final Bundle bundle;
+
+ PerContextEventListener(final Bundle bundle)
+ {
+ this.bundle = bundle;
+ }
+
+ void initialized(@Nonnull final ServletContextListenerInfo listenerInfo,
+ ContextHandler contextHandler)
+ {
+ final ServletContextListener listener = listenerInfo.getService(bundle);
+ if (listener != null)
+ {
+ // no need to sync map - initialized is called in sync
+ this.listeners.put(listenerInfo.getServiceReference(), listener);
+
+ final ServletContext context = contextHandler
+ .getServletContext(listenerInfo.getServiceReference()
+ .getBundle());
+
+ listener.contextInitialized(new ServletContextEvent(context));
+ }
+ }
+
+ void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo,
+ ContextHandler contextHandler)
+ {
+ final ServiceReference<ServletContextListener> listenerRef = listenerInfo
+ .getServiceReference();
+ final ServletContextListener listener = this.listeners
+ .remove(listenerRef);
+ if (listener != null)
+ {
+ final ServletContext context = contextHandler
+ .getServletContext(listenerRef.getBundle());
+ listener.contextDestroyed(new ServletContextEvent(context));
+ // call unget twice, once for the call in initialized and once for
+ // the call in this method(!)
+ contextHandler.ungetServletContext(listenerRef.getBundle());
+ contextHandler.ungetServletContext(listenerRef.getBundle());
+ listenerInfo.ungetService(bundle, listener);
+ }
+ }
+
+ /**
+ * Add servlet context attribute listener
+ *
+ * @param info
+ */
+ void addListener(@Nonnull final ServletContextAttributeListenerInfo info)
+ {
+ final ServletContextAttributeListener service = info.getService(bundle);
+ if (service != null)
+ {
+ this.contextAttributeListeners.put(info.getServiceReference(),
+ service);
+ }
+ }
+
+ /**
+ * Remove servlet context attribute listener
+ *
+ * @param info
+ */
+ void removeListener(@Nonnull final ServletContextAttributeListenerInfo info)
+ {
+ final ServletContextAttributeListener service = this.contextAttributeListeners
+ .remove(info.getServiceReference());
+ if (service != null)
+ {
+ info.ungetService(bundle, service);
+ }
+ }
+
+ /**
+ * Add session attribute listener
+ *
+ * @param info
+ */
+ void addListener(@Nonnull final HttpSessionAttributeListenerInfo info)
+ {
+ final HttpSessionAttributeListener service = info.getService(bundle);
+ if (service != null)
+ {
+ this.sessionAttributeListeners.put(info.getServiceReference(),
+ service);
+ }
+ }
+
+ /**
+ * Remove session attribute listener
+ *
+ * @param info
+ */
+ void removeListener(@Nonnull final HttpSessionAttributeListenerInfo info)
+ {
+ final HttpSessionAttributeListener service = this.sessionAttributeListeners
+ .remove(info.getServiceReference());
+ if (service != null)
+ {
+ info.ungetService(bundle, service);
+ }
+ }
+
+ /**
+ * Add session listener
+ *
+ * @param info
+ */
+ void addListener(@Nonnull final HttpSessionListenerInfo info)
+ {
+ final HttpSessionListener service = info.getService(bundle);
+ if (service != null)
+ {
+ this.sessionListeners.put(info.getServiceReference(), service);
+ }
+ }
+
+ /**
+ * Remove session listener
+ *
+ * @param info
+ */
+ void removeListener(@Nonnull final HttpSessionListenerInfo info)
+ {
+ final HttpSessionListener service = this.sessionListeners.remove(info
+ .getServiceReference());
+ if (service != null)
+ {
+ info.ungetService(bundle, service);
+ }
+ }
+
+ /**
+ * Add request listener
+ *
+ * @param info
+ */
+ void addListener(@Nonnull final ServletRequestListenerInfo info)
+ {
+ final ServletRequestListener service = info.getService(bundle);
+ if (service != null)
+ {
+ this.requestListeners.put(info.getServiceReference(), service);
+ }
+ }
+
+ /**
+ * Remove request listener
+ *
+ * @param info
+ */
+ void removeListener(@Nonnull final ServletRequestListenerInfo info)
+ {
+ final ServletRequestListener service = this.requestListeners
+ .remove(info.getServiceReference());
+ if (service != null)
+ {
+ info.ungetService(bundle, service);
+ }
+ }
+
+ /**
+ * Add request attribute listener
+ *
+ * @param info
+ */
+ void addListener(@Nonnull final ServletRequestAttributeListenerInfo info)
+ {
+ final ServletRequestAttributeListener service = info.getService(bundle);
+ if (service != null)
+ {
+ this.requestAttributeListeners.put(info.getServiceReference(),
+ service);
+ }
+ }
+
+ /**
+ * Remove request attribute listener
+ *
+ * @param info
+ */
+ void removeListener(@Nonnull final ServletRequestAttributeListenerInfo info)
+ {
+ final ServletRequestAttributeListener service = this.requestAttributeListeners
+ .remove(info.getServiceReference());
+ if (service != null)
+ {
+ info.ungetService(bundle, service);
+ }
+ }
+
+ // 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)
+ {
+ for (final HttpSessionAttributeListener l : sessionAttributeListeners
+ .values())
+ {
+ l.attributeReplaced(event);
+ }
+ }
+
+ @Override
+ public void attributeRemoved(final HttpSessionBindingEvent event)
+ {
+ for (final HttpSessionAttributeListener l : sessionAttributeListeners
+ .values())
+ {
+ l.attributeReplaced(event);
+ }
+ }
+
+ @Override
+ public void attributeAdded(final HttpSessionBindingEvent event)
+ {
+ for (final HttpSessionAttributeListener l : sessionAttributeListeners
+ .values())
+ {
+ l.attributeReplaced(event);
+ }
+ }
+
+ @Override
+ public void attributeReplaced(final ServletContextAttributeEvent event)
+ {
+ for (final ServletContextAttributeListener l : contextAttributeListeners
+ .values())
+ {
+ l.attributeReplaced(event);
+ }
+ }
+
+ @Override
+ public void attributeRemoved(final ServletContextAttributeEvent event)
+ {
+ for (final ServletContextAttributeListener l : contextAttributeListeners
+ .values())
+ {
+ l.attributeReplaced(event);
+ }
+ }
+
+ @Override
+ public void attributeAdded(final ServletContextAttributeEvent event)
+ {
+ for (final ServletContextAttributeListener l : contextAttributeListeners
+ .values())
+ {
+ l.attributeReplaced(event);
+ }
+ }
+
+ @Override
+ public void sessionCreated(final HttpSessionEvent se)
+ {
+ for (final HttpSessionListener l : sessionListeners.values())
+ {
+ l.sessionCreated(se);
+ }
+ }
+
+ @Override
+ public void sessionDestroyed(final HttpSessionEvent se)
+ {
+ for (final HttpSessionListener l : sessionListeners.values())
+ {
+ l.sessionDestroyed(se);
+ }
+ }
+
+ @Override
+ public void requestDestroyed(final ServletRequestEvent sre)
+ {
+ for (final ServletRequestListener l : requestListeners.values())
+ {
+ l.requestDestroyed(sre);
+ }
+ }
+
+ @Override
+ public void requestInitialized(final ServletRequestEvent sre)
+ {
+ for (final ServletRequestListener l : requestListeners.values())
+ {
+ l.requestInitialized(sre);
+ }
+ }
+
+ @Override
+ public void attributeAdded(final ServletRequestAttributeEvent srae)
+ {
+ for (final ServletRequestAttributeListener l : requestAttributeListeners
+ .values())
+ {
+ l.attributeAdded(srae);
+ }
+ }
+
+ @Override
+ public void attributeRemoved(final ServletRequestAttributeEvent srae)
+ {
+ for (final ServletRequestAttributeListener l : requestAttributeListeners
+ .values())
+ {
+ l.attributeRemoved(srae);
+ }
+ }
+
+ @Override
+ public void attributeReplaced(final ServletRequestAttributeEvent srae)
+ {
+ for (final ServletRequestAttributeListener l : requestAttributeListeners
+ .values())
+ {
+ l.attributeReplaced(srae);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ Collection<ServiceReference<?>> getRuntime()
+ {
+ return CollectionUtils.<ServiceReference<?>> union(
+ contextAttributeListeners.keySet(),
+ sessionAttributeListeners.keySet(),
+ sessionListeners.keySet(),
+ requestAttributeListeners.keySet(),
+ requestListeners.keySet());
+ }
+}
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 a600795..a31484d 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
@@ -27,24 +27,24 @@
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
+import java.util.TreeSet;
import java.util.concurrent.ConcurrentSkipListSet;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextListener;
+import org.apache.felix.http.base.internal.handler.HandlerRegistry;
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.HttpSessionAttributeListenerInfo;
-import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
+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.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.util.MimeTypes;
import org.osgi.framework.Bundle;
@@ -56,6 +56,7 @@
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.context.ServletContextHelper;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
public final class ServletContextHelperManager
@@ -68,42 +69,57 @@
private final WhiteboardHttpService httpService;
- private final ServiceRegistration<ServletContextHelper> defaultContextRegistration;
+ private final ListenerRegistry listenerRegistry;
- private final ServletContext webContext;
-
- private final Bundle bundle;
+ private final BundleContext bundleContext;
private final Set<AbstractInfo<?>> invalidRegistrations = new ConcurrentSkipListSet<AbstractInfo<?>>();
+ private volatile ServletContext webContext;
+
+ private volatile ServiceReference<HttpServiceRuntime> httpServiceRuntime;
+
+ private volatile ServiceRegistration<ServletContextHelper> defaultContextRegistration;
+
/**
* Create a new servlet context helper manager
* and the default context
*/
public ServletContextHelperManager(final BundleContext bundleContext,
- final ServletContext webContext,
- final WhiteboardHttpService httpService)
+ final WhiteboardHttpService httpService,
+ final ListenerRegistry listenerRegistry)
{
+ this.bundleContext = bundleContext;
this.httpService = httpService;
+ this.listenerRegistry = listenerRegistry;
+ }
+
+ public void start(ServletContext webContext, ServiceReference<HttpServiceRuntime> httpServiceRuntime)
+ {
this.webContext = webContext;
- this.bundle = bundleContext.getBundle();
+ this.httpServiceRuntime = httpServiceRuntime;
final Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, HttpWhiteboardConstants.HTTP_WHITEBOARD_DEFAULT_CONTEXT_NAME);
props.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, "/");
props.put(Constants.SERVICE_RANKING, Integer.MIN_VALUE);
- this.defaultContextRegistration = bundleContext.registerService(ServletContextHelper.class,
- new ServiceFactory<ServletContextHelper>() {
+ this.defaultContextRegistration = bundleContext.registerService(
+ ServletContextHelper.class,
+ new ServiceFactory<ServletContextHelper>()
+ {
@Override
public ServletContextHelper getService(
final Bundle bundle,
- final ServiceRegistration<ServletContextHelper> registration) {
- return new ServletContextHelper(bundle) {
+ final ServiceRegistration<ServletContextHelper> registration)
+ {
+ return new ServletContextHelper(bundle)
+ {
@Override
- public String getMimeType(final String file) {
+ public String getMimeType(final String file)
+ {
return MimeTypes.get().getByFile(file);
}
};
@@ -113,11 +129,11 @@
public void ungetService(
final Bundle bundle,
final ServiceRegistration<ServletContextHelper> registration,
- final ServletContextHelper service) {
+ final ServletContextHelper service)
+ {
// nothing to do
}
- },
- props);
+ }, props);
}
/**
@@ -126,8 +142,11 @@
public void close()
{
// TODO cleanup
-
- this.defaultContextRegistration.unregister();
+ if (this.defaultContextRegistration != null)
+ {
+ this.defaultContextRegistration.unregister();
+ this.defaultContextRegistration = null;
+ }
}
/**
@@ -162,7 +181,7 @@
// context listeners first
for(final ServletContextListenerInfo info : listeners.values())
{
- handler.initialized(info);
+ this.listenerRegistry.initialized(info, handler);
}
// now register services
for(final WhiteboardServiceInfo<?> info : services)
@@ -198,7 +217,7 @@
}
for(final ServletContextListenerInfo info : listeners.values())
{
- handler.destroyed(info);
+ this.listenerRegistry.destroyed(info, handler);
}
handler.deactivate();
@@ -216,9 +235,14 @@
{
if ( info.isValid() )
{
- final ContextHandler handler = new ContextHandler(info, this.webContext, this.bundle);
synchronized ( this.contextMap )
{
+ PerContextEventListener contextEventListener = listenerRegistry.addContext(info);
+ ContextHandler handler = new ContextHandler(info,
+ this.webContext,
+ contextEventListener,
+ this.bundleContext.getBundle());
+
List<ContextHandler> handlerList = this.contextMap.get(info.getName());
if ( handlerList == null )
{
@@ -290,6 +314,7 @@
{
this.activate(handlerList.get(0));
}
+ listenerRegistry.removeContext(info);
}
}
}
@@ -394,28 +419,9 @@
{
this.httpService.registerResource(handler, (ResourceInfo)info);
}
-
- else if ( info instanceof ServletContextAttributeListenerInfo )
+ else if ( info instanceof ListenerInfo )
{
- handler.addListener((ServletContextAttributeListenerInfo)info );
- }
-
- else if ( info instanceof HttpSessionListenerInfo )
- {
- handler.addListener((HttpSessionListenerInfo)info );
- }
- else if ( info instanceof HttpSessionAttributeListenerInfo )
- {
- handler.addListener((HttpSessionAttributeListenerInfo)info );
- }
-
- else if ( info instanceof ServletRequestListenerInfo )
- {
- handler.addListener((ServletRequestListenerInfo)info );
- }
- else if ( info instanceof ServletRequestAttributeListenerInfo )
- {
- handler.addListener((ServletRequestAttributeListenerInfo)info );
+ this.listenerRegistry.addListener((ListenerInfo<?>)info, handler);
}
}
@@ -438,28 +444,9 @@
{
this.httpService.unregisterResource(handler, (ResourceInfo)info);
}
-
- else if ( info instanceof ServletContextAttributeListenerInfo )
+ else if ( info instanceof ListenerInfo )
{
- handler.removeListener((ServletContextAttributeListenerInfo)info );
- }
-
- else if ( info instanceof HttpSessionListenerInfo )
- {
- handler.removeListener((HttpSessionListenerInfo)info );
- }
- else if ( info instanceof HttpSessionAttributeListenerInfo )
- {
- handler.removeListener((HttpSessionAttributeListenerInfo)info );
- }
-
- else if ( info instanceof ServletRequestListenerInfo )
- {
- handler.removeListener((ServletRequestListenerInfo)info );
- }
- else if ( info instanceof ServletRequestAttributeListenerInfo )
- {
- handler.removeListener((ServletRequestAttributeListenerInfo)info );
+ this.listenerRegistry.removeListener((ListenerInfo<?>)info, handler);
}
}
@@ -474,8 +461,8 @@
{
try
{
- final Filter f = this.bundle.getBundleContext().createFilter(target);
- return f.match(this.httpService.getServiceReference());
+ final Filter f = this.bundleContext.createFilter(target);
+ return f.match(this.httpServiceRuntime);
}
catch ( final InvalidSyntaxException ise)
{
@@ -516,4 +503,21 @@
}
return handlers;
}
+
+ public RegistryRuntime getRuntime(HandlerRegistry registry)
+ {
+ List<HandlerRuntime> handlerRuntimes;
+ Map<Long, Collection<ServiceReference<?>>> listenerRuntimes;
+ Set<ContextHandler> contextHandlers = new TreeSet<ContextHandler>();
+ synchronized ( this.contextMap )
+ {
+ for (List<ContextHandler> contextHandlerList : this.contextMap.values())
+ {
+ contextHandlers.addAll(contextHandlerList);
+ }
+ handlerRuntimes = registry.getRuntime();
+ listenerRuntimes = listenerRegistry.getContextRuntimes();
+ }
+ return new RegistryRuntime(contextHandlers, handlerRuntimes, listenerRuntimes);
+ }
}
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 918ea9e..b80ec80 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,154 +16,37 @@
*/
package org.apache.felix.http.base.internal.whiteboard;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import javax.annotation.Nonnull;
-import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.Servlet;
-import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-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.PerContextHandlerRegistry;
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.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.service.HttpServiceFactory;
-import org.apache.felix.http.base.internal.whiteboard.tracker.FilterTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.HttpSessionAttributeListenerTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.HttpSessionListenerTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.ResourceTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextAttributeListenerTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextHelperTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextListenerTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.ServletRequestAttributeListenerTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.ServletRequestListenerTracker;
-import org.apache.felix.http.base.internal.whiteboard.tracker.ServletTracker;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceObjects;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.http.runtime.HttpServiceRuntime;
-import org.osgi.service.http.runtime.HttpServiceRuntimeConstants;
-import org.osgi.service.http.runtime.dto.ErrorPageDTO;
-import org.osgi.service.http.runtime.dto.FilterDTO;
-import org.osgi.service.http.runtime.dto.ListenerDTO;
-import org.osgi.service.http.runtime.dto.RequestInfoDTO;
-import org.osgi.service.http.runtime.dto.ResourceDTO;
-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.util.tracker.ServiceTracker;
-public final class WhiteboardHttpService implements HttpServiceRuntime
+public final class WhiteboardHttpService
{
-
private final HandlerRegistry handlerRegistry;
private final BundleContext bundleContext;
- private volatile ServletContextHelperManager contextManager;
-
- private final List<ServiceTracker<?, ?>> trackers = new ArrayList<ServiceTracker<?, ?>>();
-
- private final Hashtable<String, Object> runtimeServiceProps = new Hashtable<String, Object>();;
-
- private final HttpServiceFactory httpServiceFactory;
-
- private volatile ServiceRegistration<HttpServiceRuntime> runtimeServiceReg;
-
/**
* Create a new whiteboard http service
* @param bundleContext
- * @param context
* @param handlerRegistry
*/
public WhiteboardHttpService(final BundleContext bundleContext,
- final HandlerRegistry handlerRegistry,
- final HttpServiceFactory httpServiceFactory)
+ final HandlerRegistry handlerRegistry)
{
this.handlerRegistry = handlerRegistry;
this.bundleContext = bundleContext;
- this.httpServiceFactory = httpServiceFactory;
- }
-
- public void start(final ServletContext context)
- {
- this.contextManager = new ServletContextHelperManager(bundleContext, context, this);
-
- addTracker(new FilterTracker(bundleContext, contextManager));
- addTracker(new ServletTracker(bundleContext, this.contextManager));
- addTracker(new ResourceTracker(bundleContext, this.contextManager));
-
- addTracker(new HttpSessionListenerTracker(bundleContext, this.contextManager));
- addTracker(new HttpSessionAttributeListenerTracker(bundleContext, this.contextManager));
-
- addTracker(new ServletContextHelperTracker(bundleContext, this.contextManager));
- addTracker(new ServletContextListenerTracker(bundleContext, this.contextManager));
- addTracker(new ServletContextAttributeListenerTracker(bundleContext, this.contextManager));
-
- addTracker(new ServletRequestListenerTracker(bundleContext, this.contextManager));
- addTracker(new ServletRequestAttributeListenerTracker(bundleContext, this.contextManager));
-
- this.runtimeServiceProps.put(HttpServiceRuntimeConstants.HTTP_SERVICE_ID_ATTRIBUTE,
- this.httpServiceFactory.getHttpServiceServiceId());
- this.runtimeServiceReg = this.bundleContext.registerService(HttpServiceRuntime.class,
- this,
- this.runtimeServiceProps);
- }
-
- public void stop()
- {
- if ( this.runtimeServiceReg != null )
- {
- this.runtimeServiceReg.unregister();
- this.runtimeServiceReg = null;
- }
-
- for(final ServiceTracker<?, ?> t : this.trackers)
- {
- t.close();
- }
- this.trackers.clear();
- if ( this.contextManager != null )
- {
- this.contextManager.close();
- this.contextManager = null;
- }
- }
-
- private void addTracker(ServiceTracker<?, ?> tracker)
- {
- this.trackers.add(tracker);
- tracker.open();
- }
-
- public void setProperties(final Hashtable<String, Object> props)
- {
- // runtime service gets the same props for now
- this.runtimeServiceProps.clear();
- this.runtimeServiceProps.putAll(props);
-
- if (this.runtimeServiceReg != null)
- {
- this.runtimeServiceProps.put(HttpServiceRuntimeConstants.HTTP_SERVICE_ID_ATTRIBUTE,
- this.httpServiceFactory.getHttpServiceServiceId());
- this.runtimeServiceReg.setProperties(this.runtimeServiceProps);
- }
}
/**
@@ -190,7 +73,6 @@
if (registry != null )
{
registry.addServlet(handler);
- contextHandler.addWhiteboardService(servletInfo);
}
} catch (final ServletException e) {
so.ungetService(servlet);
@@ -217,7 +99,6 @@
}
}
contextHandler.ungetServletContext(servletInfo.getServiceReference().getBundle());
- contextHandler.removeWhiteboardService(servletInfo);
}
/**
@@ -241,7 +122,6 @@
if (registry != null )
{
registry.addFilter(handler);
- contextHandler.addWhiteboardService(filterInfo);
}
} catch (final ServletException e) {
// TODO create failure DTO
@@ -266,7 +146,6 @@
}
}
contextHandler.ungetServletContext(filterInfo.getServiceReference().getBundle());
- contextHandler.removeWhiteboardService(filterInfo);
}
/**
@@ -289,7 +168,6 @@
if (registry != null )
{
registry.addServlet(handler);
- contextHandler.addWhiteboardService(resourceInfo);
}
} catch (ServletException e) {
// TODO create failure DTO
@@ -310,7 +188,6 @@
registry.removeServlet(servletInfo, true);
}
contextHandler.ungetServletContext(servletInfo.getServiceReference().getBundle());
- contextHandler.removeWhiteboardService(servletInfo);
}
public void registerContext(@Nonnull final ContextHandler contextHandler)
@@ -322,173 +199,4 @@
{
this.handlerRegistry.remove(contextHandler.getContextInfo());
}
-
- public void sessionDestroyed(@Nonnull final HttpSession session, final Set<Long> contextIds)
- {
- for(final Long contextId : contextIds)
- {
- // TODO - on shutdown context manager is already NULL which shouldn't be the case
- if ( this.contextManager != null )
- {
- final ContextHandler handler = this.contextManager.getContextHandler(contextId);
- if ( handler != null )
- {
- final ExtServletContext context = handler.getServletContext(this.bundleContext.getBundle());
- new HttpSessionWrapper(contextId, session, context, true).invalidate();
- handler.ungetServletContext(this.bundleContext.getBundle());
- }
- }
- }
- }
-
- public ServiceReference<HttpServiceRuntime> getServiceReference()
- {
- return this.runtimeServiceReg.getReference();
- }
-
- @Override
- public RuntimeDTO getRuntimeDTO()
- {
- // create new DTO on every call
- final RuntimeDTO runtime = new RuntimeDTO();
-
- // attributes
- runtime.attributes = new HashMap<String, String>();
- for(final Map.Entry<String, Object> entry : this.runtimeServiceProps.entrySet())
- {
- runtime.attributes.put(entry.getKey(), entry.getValue().toString());
- }
-
- // servlet context DTOs
- final List<ServletContextDTO> contextDTOs = new ArrayList<ServletContextDTO>();
- for(final ContextHandler handler : this.contextManager.getContextHandlers())
- {
- final ServletContextDTO dto = new ServletContextDTO();
-
- final ServletContext ctx = handler.getServletContext(this.bundleContext.getBundle());
- try
- {
- dto.name = handler.getContextInfo().getName();
- dto.contextPath = handler.getContextInfo().getPath();
- dto.initParams = new HashMap<String, String>(handler.getContextInfo().getInitParameters());
- dto.serviceId = handler.getContextInfo().getServiceId();
-
- dto.contextName = ctx.getServletContextName();
- dto.attributes = new HashMap<String, Object>();
- final Enumeration<String> e = ctx.getAttributeNames();
- while ( e.hasMoreElements() )
- {
- final String name = e.nextElement();
- final Object value = ctx.getAttribute(name);
- if ( value != null )
- {
- // TODO - check for appropriate value types
- }
- }
-
- final List<ErrorPageDTO> errorPages = new ArrayList<ErrorPageDTO>();
- final List<FilterDTO> filters = new ArrayList<FilterDTO>();
- final List<ServletDTO> servlets = new ArrayList<ServletDTO>();
- final List<ResourceDTO> resources = new ArrayList<ResourceDTO>();
- for(final WhiteboardServiceInfo<?> info : handler.getWhiteboardServices())
- {
- if ( info instanceof ServletInfo )
- {
- final ServletInfo si = (ServletInfo)info;
- if ( si.getErrorPage() != null )
- {
- final ErrorPageDTO page = new ErrorPageDTO();
- errorPages.add(page);
- page.asyncSupported = si.isAsyncSupported();
- page.errorCodes = new long[0]; // TODO
- page.exceptions = toStringArray(si.getErrorPage()); // TODO
- page.initParams = new HashMap<String, String>(si.getInitParameters());
- page.name = si.getName();
- page.serviceId = si.getServiceId();
- page.servletContextId = handler.getContextInfo().getServiceId();
- page.servletInfo = null; // TODO
- }
- if ( si.getPatterns() != null )
- {
- final ServletDTO servlet = new ServletDTO();
- servlets.add(servlet);
- servlet.asyncSupported = si.isAsyncSupported();
- servlet.initParams = new HashMap<String, String>(si.getInitParameters());
- servlet.name = si.getName();
- servlet.patterns = toStringArray(si.getPatterns());
- servlet.serviceId = si.getServiceId();
- servlet.servletContextId = handler.getContextInfo().getServiceId();
- servlet.servletInfo = null; // TODO
- }
- }
- else if ( info instanceof ResourceInfo )
- {
- final ResourceDTO rsrc = new ResourceDTO();
- resources.add(rsrc);
- rsrc.patterns = ((ResourceInfo)info).getPatterns();
- rsrc.prefix = ((ResourceInfo)info).getPrefix();
- rsrc.serviceId = info.getServiceId();
- rsrc.servletContextId = handler.getContextInfo().getServiceId();
- }
- else if ( info instanceof FilterInfo )
- {
- final FilterDTO filter = new FilterDTO();
- filters.add(filter);
- filter.asyncSupported = ((FilterInfo)info).isAsyncSupported();
- final DispatcherType[] dTypes = ((FilterInfo)info).getDispatcher();
- filter.dispatcher = new String[dTypes.length];
- int index = 0;
- for(final DispatcherType dt : dTypes)
- {
- filter.dispatcher[index++] = dt.name();
- }
- filter.initParams = new HashMap<String, String>(((FilterInfo)info).getInitParameters());
- filter.name = ((FilterInfo)info).getName();
- filter.patterns = toStringArray(((FilterInfo)info).getPatterns());
- filter.regexs = toStringArray(((FilterInfo)info).getRegexs());
- filter.serviceId = info.getServiceId();
- filter.servletContextId = handler.getContextInfo().getServiceId();
- filter.servletNames = toStringArray(((FilterInfo)info).getServletNames());
- }
- }
- dto.errorPageDTOs = errorPages.toArray(new ErrorPageDTO[errorPages.size()]);
- dto.filterDTOs = filters.toArray(new FilterDTO[filters.size()]);
- dto.resourceDTOs = resources.toArray(new ResourceDTO[resources.size()]);
- dto.servletDTOs = servlets.toArray(new ServletDTO[servlets.size()]);
-
- dto.listenerDTOs = new ListenerDTO[0]; // TODO
- }
- finally
- {
- handler.ungetServletContext(this.bundleContext.getBundle());
- }
- contextDTOs.add(dto);
- }
- runtime.servletContextDTOs = contextDTOs.toArray(new ServletContextDTO[contextDTOs.size()]);
-
- runtime.failedErrorPageDTOs = null; // TODO
- runtime.failedFilterDTOs = null; // TODO
- runtime.failedListenerDTOs = null; // TODO
- runtime.failedResourceDTOs = null; // TODO
- runtime.failedServletContextDTOs = null; // TODO
- runtime.failedServletDTOs = null; // TODO
-
- return runtime;
- }
-
- @Override
- public RequestInfoDTO calculateRequestInfoDTO(final String path) {
- // TODO
- return null;
- }
-
- private static final String[] EMPTY_ARRAY = new String[0];
- private String[] toStringArray(final String[] array)
- {
- if ( array == null )
- {
- return EMPTY_ARRAY;
- }
- return array;
- }
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
new file mode 100644
index 0000000..acf0a86
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
@@ -0,0 +1,163 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.handler.HandlerRegistry;
+import org.apache.felix.http.base.internal.handler.HttpSessionWrapper;
+import org.apache.felix.http.base.internal.service.HttpServiceFactory;
+import org.apache.felix.http.base.internal.service.HttpServiceRuntimeImpl;
+import org.apache.felix.http.base.internal.whiteboard.tracker.FilterTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.HttpSessionAttributeListenerTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.HttpSessionListenerTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.ResourceTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextAttributeListenerTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextHelperTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextListenerTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.ServletRequestAttributeListenerTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.ServletRequestListenerTracker;
+import org.apache.felix.http.base.internal.whiteboard.tracker.ServletTracker;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
+import org.osgi.service.http.runtime.HttpServiceRuntimeConstants;
+import org.osgi.util.tracker.ServiceTracker;
+
+public final class WhiteboardManager
+{
+ private final BundleContext bundleContext;
+
+ private final List<ServiceTracker<?, ?>> trackers = new ArrayList<ServiceTracker<?, ?>>();
+
+ private final HttpServiceFactory httpServiceFactory;
+
+ private final HttpServiceRuntimeImpl serviceRuntime;
+
+ private final ServletContextHelperManager contextManager;
+
+ private volatile ServiceRegistration<HttpServiceRuntime> runtimeServiceReg;
+
+ /**
+ * Create a new whiteboard http manager
+ * @param bundleContext
+ * @param httpServiceFactory
+ * @param registry
+ */
+ public WhiteboardManager(final BundleContext bundleContext,
+ final HttpServiceFactory httpServiceFactory,
+ final HandlerRegistry registry)
+ {
+ this.bundleContext = bundleContext;
+ this.httpServiceFactory = httpServiceFactory;
+ WhiteboardHttpService whiteboardHttpService = new WhiteboardHttpService(this.bundleContext, registry);
+ ListenerRegistry listenerRegistry = new ListenerRegistry(bundleContext.getBundle());
+ this.contextManager = new ServletContextHelperManager(bundleContext, whiteboardHttpService, listenerRegistry);
+ this.serviceRuntime = new HttpServiceRuntimeImpl(registry, this.contextManager);
+ }
+
+ public void start(final ServletContext context)
+ {
+ // TODO set Endpoint
+ this.serviceRuntime.setAttribute(HttpServiceRuntimeConstants.HTTP_SERVICE_ID_ATTRIBUTE,
+ this.httpServiceFactory.getHttpServiceServiceId());
+ this.runtimeServiceReg = this.bundleContext.registerService(HttpServiceRuntime.class,
+ serviceRuntime,
+ this.serviceRuntime.getAttributes());
+
+ this.contextManager.start(context, this.runtimeServiceReg.getReference());
+
+ addTracker(new FilterTracker(this.bundleContext, contextManager));
+ addTracker(new ServletTracker(this.bundleContext, this.contextManager));
+ addTracker(new ResourceTracker(this.bundleContext, this.contextManager));
+
+ addTracker(new HttpSessionListenerTracker(this.bundleContext, this.contextManager));
+ addTracker(new HttpSessionAttributeListenerTracker(this.bundleContext, this.contextManager));
+
+ addTracker(new ServletContextHelperTracker(this.bundleContext, this.contextManager));
+ addTracker(new ServletContextListenerTracker(this.bundleContext, this.contextManager));
+ addTracker(new ServletContextAttributeListenerTracker(this.bundleContext, this.contextManager));
+
+ addTracker(new ServletRequestListenerTracker(this.bundleContext, this.contextManager));
+ addTracker(new ServletRequestAttributeListenerTracker(this.bundleContext, this.contextManager));
+ }
+
+ public void stop()
+ {
+ for(final ServiceTracker<?, ?> t : this.trackers)
+ {
+ t.close();
+ }
+ this.trackers.clear();
+
+ if ( this.contextManager != null )
+ {
+ this.contextManager.close();
+ }
+
+ if ( this.runtimeServiceReg != null )
+ {
+ this.runtimeServiceReg.unregister();
+ this.runtimeServiceReg = null;
+ }
+ }
+
+ private void addTracker(ServiceTracker<?, ?> tracker)
+ {
+ this.trackers.add(tracker);
+ tracker.open();
+ }
+
+ public void setProperties(final Hashtable<String, Object> props)
+ {
+ // runtime service gets the same props for now
+ this.serviceRuntime.setAllAttributes(props);
+
+ if (this.runtimeServiceReg != null)
+ {
+ this.serviceRuntime.setAttribute(HttpServiceRuntimeConstants.HTTP_SERVICE_ID_ATTRIBUTE,
+ this.httpServiceFactory.getHttpServiceServiceId());
+ this.runtimeServiceReg.setProperties(this.serviceRuntime.getAttributes());
+ }
+ }
+
+ public void sessionDestroyed(@Nonnull final HttpSession session, final Set<Long> contextIds)
+ {
+ for(final Long contextId : contextIds)
+ {
+ // TODO - on shutdown context manager is already NULL which shouldn't be the case
+ if ( this.contextManager != null )
+ {
+ final ContextHandler handler = this.contextManager.getContextHandler(contextId);
+ if ( handler != null )
+ {
+ final ExtServletContext context = handler.getServletContext(this.bundleContext.getBundle());
+ new HttpSessionWrapper(contextId, session, context, true).invalidate();
+ handler.ungetServletContext(this.bundleContext.getBundle());
+ }
+ }
+ }
+ }
+}
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
new file mode 100644
index 0000000..2108ee4
--- /dev/null
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/WhiteboardServiceHelper.java
@@ -0,0 +1,189 @@
+/*
+ * 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;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+
+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;
+
+public final class WhiteboardServiceHelper
+{
+ public static final AtomicLong ID_COUNTER = new AtomicLong();
+
+ public static FilterHandler createTestFilterWithServiceId(String identifier,
+ ExtServletContext context)
+ {
+ return createTestFilter(identifier, context, ID_COUNTER.incrementAndGet());
+ }
+
+ public static FilterHandler createTestFilter(String identifier,
+ ExtServletContext context)
+ {
+ return createTestFilter(identifier, context, -ID_COUNTER.incrementAndGet());
+ }
+
+ private static FilterHandler createTestFilter(String identifier,
+ ExtServletContext context,
+ Long serviceId)
+ {
+ FilterInfo filterInfo = createFilterInfo(identifier, serviceId);
+ return new FilterHandler(null, context, mock(Filter.class), filterInfo);
+ }
+
+ private static FilterInfo createFilterInfo(String identifier,
+ Long serviceId)
+ {
+ boolean asyncSupported = true;
+ String name = identifier;
+ Map<String, String> initParams = createInitParameterMap(identifier);
+ String[] patterns = new String[]{ "/" + identifier };
+ String[] regexs = new String[]{ "." + identifier };
+ DispatcherType[] dispatcher = new DispatcherType[] { DispatcherType.ASYNC, DispatcherType.REQUEST };
+ return createFilterInfo(0, serviceId, name, patterns, null, regexs, asyncSupported, dispatcher, initParams);
+ }
+
+ public static FilterInfo createFilterInfo(int serviceRanking,
+ Long serviceId,
+ String name,
+ String[] patterns,
+ String[] servletNames,
+ String[] regexs,
+ boolean asyncSupported,
+ DispatcherType[] dispatcher,
+ Map<String, String> initParams)
+ {
+ FilterInfo info = new FilterInfo(0,
+ serviceId,
+ name,
+ patterns,
+ servletNames,
+ regexs,
+ asyncSupported,
+ dispatcher,
+ initParams);
+ return info;
+ }
+
+ public static ServletHandler createTestServletWithServiceId(String identifier,
+ ExtServletContext context)
+ {
+ return createTestServlet(identifier, context, ID_COUNTER.incrementAndGet());
+ }
+
+ public static ServletHandler createTestServlet(String identifier, ExtServletContext context)
+ {
+ return createTestServlet(identifier, context, -ID_COUNTER.incrementAndGet());
+ }
+
+ private static ServletHandler createTestServlet(String identifier,
+ ExtServletContext context,
+ Long serviceId)
+ {
+ ServletInfo servletInfo = createServletInfo(identifier, serviceId);
+ Servlet servlet = mock(Servlet.class);
+ when(servlet.getServletInfo()).thenReturn("info_" + identifier);
+ return new ServletHandler(null, context, servletInfo, servlet);
+ }
+
+ private static ServletInfo createServletInfo(String identifier, Long serviceId)
+ {
+ boolean asyncSupported = true;
+ String name = identifier;
+ Map<String, String> initParams = createInitParameterMap(identifier);
+ String[] patterns = new String[]{ "/" + identifier };
+ return createServletInfo(0, serviceId, name, patterns, null, asyncSupported, initParams);
+ }
+
+ public static ServletInfo createServletInfo(int serviceRanking,
+ Long serviceId,
+ String name,
+ String[] patterns,
+ String[] errorPages,
+ boolean asyncSupported,
+ Map<String, String> initParams)
+ {
+ return new ServletInfo(0,
+ serviceId,
+ name,
+ patterns,
+ null,
+ asyncSupported,
+ initParams);
+ }
+
+ @SuppressWarnings("serial")
+ private static HashMap<String, String> createInitParameterMap(final String identifier)
+ {
+ return new HashMap<String, String>()
+ {
+ {
+ put("paramOne_" + identifier, "valOne_" + identifier);
+ put("paramTwo_" + identifier, "valTwo_" + identifier);
+ }
+ };
+ }
+
+ public static ErrorPage createErrorPageWithServiceId(String identifier, ExtServletContext context)
+ {
+ return createErrorPage(identifier, context, ID_COUNTER.incrementAndGet());
+ }
+
+ public static ErrorPage createErrorPage(String identifier, ExtServletContext context)
+ {
+ return createErrorPage(identifier, context, -ID_COUNTER.incrementAndGet());
+ }
+
+ private static ErrorPage createErrorPage(String identifier,
+ ExtServletContext context,
+ Long serviceId)
+ {
+ ServletHandler 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);
+ }
+
+ public static ServletContextHelperInfo createContextInfo(int serviceRanking,
+ long serviceId,
+ String name,
+ String path,
+ Map<String, String> initParams)
+ {
+ return new ServletContextHelperInfo(serviceRanking,
+ serviceId,
+ name,
+ path,
+ initParams);
+ }
+}
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
new file mode 100644
index 0000000..31b3cab
--- /dev/null
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
@@ -0,0 +1,578 @@
+/*
+ * 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 java.util.Arrays.asList;
+import static java.util.Arrays.copyOf;
+import static java.util.Arrays.sort;
+import static java.util.Collections.emptyMap;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.ID_COUNTER;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createContextInfo;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createErrorPage;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createErrorPageWithServiceId;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createFilterInfo;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createServletInfo;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createTestFilter;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createTestFilterWithServiceId;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createTestServlet;
+import static org.apache.felix.http.base.internal.runtime.WhiteboardServiceHelper.createTestServletWithServiceId;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+
+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;
+import org.apache.felix.http.base.internal.runtime.HandlerRuntime.ErrorPage;
+import org.apache.felix.http.base.internal.runtime.FilterInfo;
+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;
+import org.apache.felix.http.base.internal.whiteboard.ListenerRegistry;
+import org.apache.felix.http.base.internal.whiteboard.PerContextEventListener;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.dto.DTO;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.http.runtime.dto.ErrorPageDTO;
+import org.osgi.service.http.runtime.dto.FilterDTO;
+import org.osgi.service.http.runtime.dto.ListenerDTO;
+import org.osgi.service.http.runtime.dto.RuntimeDTO;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
+import org.osgi.service.http.runtime.dto.ServletDTO;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RuntimeDTOBuilderTest
+{
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ 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_LISTENER_1 = ID_COUNTER.incrementAndGet();
+ private static final Long ID_LISTENER_2 = ID_COUNTER.incrementAndGet();
+
+ private static final List<String> CONTEXT_NAMES = Arrays.asList("0", "A", "B");
+
+ @SuppressWarnings("serial")
+ private static final Map<String, List<String>> CONTEXT_ENTITY_NAMES = new HashMap<String, List<String>>()
+ {
+ {
+ put("0", Arrays.asList("1"));
+ put("A", Arrays.asList("A_1"));
+ put("B", Arrays.asList("B_1", "B_2"));
+ }
+ };
+
+ @Mock private Bundle bundle;
+
+ @Mock private DTO testDTO;
+
+ @Mock private ExtServletContext context_0;
+ @Mock private ExtServletContext context_A;
+ @Mock private ExtServletContext context_B;
+
+ @Mock private ServiceReference<?> listener_1;
+ @Mock private ServiceReference<?> listener_2;
+
+ private RegistryRuntime registry;
+ private Map<String, Object> runtimeAttributes;
+ private ListenerRegistry listenerRegistry;
+
+ @Before
+ public void setUp()
+ {
+ registry = null;
+ runtimeAttributes = Collections.emptyMap();
+ listenerRegistry = new ListenerRegistry(bundle);
+ }
+
+ public ContextHandler setupContext(ServletContext context, String name, long serviceId)
+ {
+ when(context.getServletContextName()).thenReturn(name);
+
+ String path = "/" + name;
+ when(context.getContextPath()).thenReturn(path);
+
+ List<String> initParameterNames = asList("param_1", "param_2");
+ when(context.getInitParameterNames()).thenReturn(Collections.enumeration(initParameterNames));
+ 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);
+
+ PerContextEventListener eventListener = listenerRegistry.addContext(contextInfo);
+ ContextHandler contextHandler = new ContextHandler(contextInfo, context, eventListener, bundle);
+
+ ServletContext sharedContext = contextHandler.getSharedContext();
+ sharedContext.setAttribute("intAttr", 1);
+ sharedContext.setAttribute("dateAttr", new Date());
+ sharedContext.setAttribute("stringAttr", "one");
+ sharedContext.setAttribute("dtoAttr", testDTO);
+
+ return contextHandler;
+ }
+
+ @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_B, asList(listener_1, listener_2));
+
+ when(listener_1.getProperty(Constants.SERVICE_ID)).thenReturn(ID_LISTENER_1);
+ when(listener_1.getProperty(Constants.OBJECTCLASS))
+ .thenReturn(new String[] { "org.test.interface_1" });
+
+ when(listener_2.getProperty(Constants.SERVICE_ID)).thenReturn(ID_LISTENER_2);
+ when(listener_2.getProperty(Constants.OBJECTCLASS))
+ .thenReturn(new String[] { "org.test.interface_1", "org.test.interface_2" });
+
+ return listenerRuntimes;
+ }
+
+ public void setupRegistry(List<ContextHandler> contexts,
+ List<HandlerRuntime> contextRuntimes,
+ Map<Long, Collection<ServiceReference<?>>> listenerRuntimes)
+ {
+ registry = new RegistryRuntime(contexts, contextRuntimes, listenerRuntimes);
+ }
+
+ @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);
+
+ List<ServletHandler> servlets_0 = asList(createTestServlet("1", context_0));
+ List<FilterHandler> filters_0 = asList(createTestFilter("1", context_0));
+ List<ErrorPage> errorPages_0 = asList(createErrorPage("E_1", context_0));
+ HandlerRuntime contextRuntime_0 = new HandlerRuntime(servlets_0, filters_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<ErrorPage> errorPages_A = asList(createErrorPage("E_A_1", context_A));
+ HandlerRuntime contextRuntime_A = new HandlerRuntime(servlets_A, filters_A, errorPages_A, ID_A);
+
+ List<ServletHandler> servlets_B = asList(createTestServletWithServiceId("B_1", context_B),
+ createTestServletWithServiceId("B_2", context_B));
+ List<FilterHandler> filters_B = asList(createTestFilterWithServiceId("B_1", context_B),
+ createTestFilterWithServiceId("B_2", context_B));
+ List<ErrorPage> errorPages_B = asList(createErrorPageWithServiceId("E_B_1", context_B),
+ createErrorPageWithServiceId("E_B_2", context_B));
+ HandlerRuntime contextRuntime_B = new HandlerRuntime(servlets_B, filters_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);
+
+ RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+
+ assertServletContextDTOs(runtimeDTO);
+ }
+
+ private void assertServletContextDTOs(RuntimeDTO runtimeDTO)
+ {
+ SortedSet<Long> seenServiceIds = new TreeSet<Long>();
+
+ assertEquals(3, runtimeDTO.servletContextDTOs.length);
+
+ for (ServletContextDTO servletContextDTO : runtimeDTO.servletContextDTOs)
+ {
+ String contextName = servletContextDTO.contextName;
+ assertTrue(CONTEXT_NAMES.contains(contextName));
+ if (contextName.equals("0"))
+ {
+ assertNull(contextName,
+ servletContextDTO.name);
+ assertTrue(contextName,
+ servletContextDTO.serviceId < 0);
+ assertEquals(contextName,
+ 1, servletContextDTO.servletDTOs.length);
+ assertEquals(contextName,
+ 1, servletContextDTO.filterDTOs.length);
+ assertEquals(contextName,
+ 1, servletContextDTO.errorPageDTOs.length);
+ assertEquals(contextName,
+ 2, servletContextDTO.listenerDTOs.length);
+ }
+ else
+ {
+ assertEquals(contextName,
+ contextName, servletContextDTO.name);
+
+ int expectedId = CONTEXT_NAMES.indexOf(contextName) + 1;
+ assertEquals(contextName,
+ expectedId, servletContextDTO.serviceId);
+
+ int expectedChildren = CONTEXT_NAMES.indexOf(contextName);
+ assertEquals(contextName,
+ expectedChildren, servletContextDTO.servletDTOs.length);
+ assertEquals(contextName,
+ expectedChildren, servletContextDTO.filterDTOs.length);
+ assertEquals(contextName,
+ expectedChildren, servletContextDTO.errorPageDTOs.length);
+ assertEquals(contextName,
+ expectedChildren, servletContextDTO.listenerDTOs.length);
+ }
+ seenServiceIds.add(servletContextDTO.serviceId);
+
+ assertEquals(contextName,
+ 3, servletContextDTO.attributes.size());
+ assertEquals(contextName,
+ 1, servletContextDTO.attributes.get("intAttr"));
+ assertEquals(contextName,
+ "one", servletContextDTO.attributes.get("stringAttr"));
+ assertEquals(contextName,
+ testDTO, servletContextDTO.attributes.get("dtoAttr"));
+
+ assertEquals(contextName,
+ 2, servletContextDTO.initParams.size());
+ assertEquals(contextName,
+ "init_val_1", servletContextDTO.initParams.get("param_1"));
+ assertEquals(contextName,
+ "init_val_2", servletContextDTO.initParams.get("param_2"));
+
+ assertEquals(contextName,
+ "/" + contextName + "/" + contextName, servletContextDTO.contextPath);
+
+ Collection<Long> serviceIds = assertServletDTOs(contextName,
+ servletContextDTO.serviceId, servletContextDTO.servletDTOs);
+ seenServiceIds.addAll(serviceIds);
+
+ serviceIds = assertFilterDTOs(contextName,
+ servletContextDTO.serviceId, servletContextDTO.filterDTOs);
+ seenServiceIds.addAll(serviceIds);
+
+ serviceIds = assertErrorPageDTOs(contextName,
+ servletContextDTO.serviceId, servletContextDTO.errorPageDTOs);
+ seenServiceIds.addAll(serviceIds);
+
+ serviceIds = assertListenerDTOs(contextName,
+ servletContextDTO.serviceId, servletContextDTO.listenerDTOs);
+ seenServiceIds.addAll(serviceIds);
+ }
+ assertEquals(10, seenServiceIds.tailSet(0L).size());
+ assertEquals(7, seenServiceIds.headSet(0L).size());
+ }
+
+ private Collection<Long> assertServletDTOs(String contextName, long contextId, ServletDTO[] dtos) {
+ List<Long> serviceIds = new ArrayList<Long>();
+ for (ServletDTO servletDTO : dtos)
+ {
+ String name = servletDTO.name;
+ assertTrue(CONTEXT_ENTITY_NAMES.get(contextName).contains(name));
+
+ if (contextId != ID_B)
+ {
+ assertTrue(name,
+ servletDTO.serviceId < 0);
+ }
+ else
+ {
+ assertTrue(name,
+ servletDTO.serviceId > 0);
+ }
+ serviceIds.add(servletDTO.serviceId);
+
+ assertEquals(name,
+ contextId, servletDTO.servletContextId);
+
+ assertTrue(name,
+ servletDTO.asyncSupported);
+
+ assertEquals(name,
+ 2, servletDTO.initParams.size());
+ assertEquals(name,
+ "valOne_" + name, servletDTO.initParams.get("paramOne_" + name));
+ assertEquals(name,
+ "valTwo_" + name, servletDTO.initParams.get("paramTwo_" + name));
+
+ assertEquals(name,
+ 1, servletDTO.patterns.length);
+ assertEquals(name,
+ "/" + name, servletDTO.patterns[0]);
+
+ assertEquals(name,
+ "info_" + name, servletDTO.servletInfo);
+ }
+
+ return serviceIds;
+ }
+
+ private Collection<Long> assertFilterDTOs(String contextName, long contextId, FilterDTO[] dtos) {
+ List<Long> serviceIds = new ArrayList<Long>();
+ for (FilterDTO filterDTO : dtos)
+ {
+ String name = filterDTO.name;
+ assertTrue(CONTEXT_ENTITY_NAMES.get(contextName).contains(name));
+
+ if (contextId != ID_B)
+ {
+ assertTrue(name,
+ filterDTO.serviceId < 0);
+ }
+ else
+ {
+ assertTrue(name,
+ filterDTO.serviceId > 0);
+ }
+ serviceIds.add(filterDTO.serviceId);
+
+ assertEquals(name,
+ contextId, filterDTO.servletContextId);
+
+ assertTrue(name,
+ filterDTO.asyncSupported);
+
+ assertEquals(name,
+ 2, filterDTO.initParams.size());
+ assertEquals(name,
+ "valOne_" + name, filterDTO.initParams.get("paramOne_" + name));
+ assertEquals(name,
+ "valTwo_" + name, filterDTO.initParams.get("paramTwo_" + name));
+
+ assertEquals(name,
+ 1, filterDTO.patterns.length);
+ assertEquals(name,
+ "/" + name, filterDTO.patterns[0]);
+
+ assertEquals(name,
+ 1, filterDTO.regexs.length);
+ assertEquals(name,
+ "." + name, filterDTO.regexs[0]);
+
+ assertEquals(name,
+ 2, filterDTO.dispatcher.length);
+ assertEquals(name,
+ "ASYNC", filterDTO.dispatcher[0]);
+ assertEquals(name,
+ "REQUEST", filterDTO.dispatcher[1]);
+ }
+
+ return serviceIds;
+ }
+
+ private Collection<Long> assertErrorPageDTOs(String contextName, long contextId, ErrorPageDTO[] dtos)
+ {
+ List<Long> serviceIds = new ArrayList<Long>();
+ for (ErrorPageDTO errorPageDTO : dtos)
+ {
+ String name = errorPageDTO.name;
+ assertTrue(CONTEXT_ENTITY_NAMES.get(contextName).contains(name.substring(2)));
+
+ if (contextId != ID_B)
+ {
+ assertTrue(name,
+ errorPageDTO.serviceId < 0);
+ }
+ else
+ {
+ assertTrue(name,
+ errorPageDTO.serviceId > 0);
+ }
+ serviceIds.add(errorPageDTO.serviceId);
+
+ assertEquals(name,
+ contextId, errorPageDTO.servletContextId);
+
+ assertTrue(name,
+ errorPageDTO.asyncSupported);
+
+ assertEquals(name,
+ 2, errorPageDTO.initParams.size());
+ assertEquals(name,
+ "valOne_" + name, errorPageDTO.initParams.get("paramOne_" + name));
+ assertEquals(name,
+ "valTwo_" + name, errorPageDTO.initParams.get("paramTwo_" + name));
+
+ assertEquals(name,
+ "info_" + name, errorPageDTO.servletInfo);
+
+ assertEquals(name,
+ 2, errorPageDTO.errorCodes.length);
+ long[] errorCodes = copyOf(errorPageDTO.errorCodes, 2);
+ sort(errorCodes);
+ assertEquals(name,
+ 400, errorCodes[0]);
+ assertEquals(name,
+ 500, errorCodes[1]);
+
+ assertEquals(name,
+ 2, errorPageDTO.exceptions.length);
+ String[] exceptions = copyOf(errorPageDTO.exceptions, 2);
+ sort(exceptions);
+ assertEquals(name,
+ "Bad request", exceptions[0]);
+ assertEquals(name,
+ "Error", exceptions[1]);
+ }
+
+ return serviceIds;
+ }
+
+ private Collection<Long> assertListenerDTOs(String contextName, long contextId, ListenerDTO[] dtos)
+ {
+ Set<Long> serviceIds = new HashSet<Long>();
+ for (ListenerDTO listenerDTO : dtos)
+ {
+ assertEquals(contextId, listenerDTO.servletContextId);
+ serviceIds.add(listenerDTO.serviceId);
+ }
+
+ assertEquals(ID_LISTENER_1.longValue(), dtos[0].serviceId);
+ assertArrayEquals(new String[] { "org.test.interface_1" },
+ dtos[0].types);
+ if (dtos.length > 1)
+ {
+ assertEquals(ID_LISTENER_2.longValue(), dtos[1].serviceId);
+ assertArrayEquals(new String[] { "org.test.interface_1", "org.test.interface_2" }, dtos[1].types);
+ }
+
+ return serviceIds;
+ }
+
+ @Test
+ public void nullValuesInEntities() {
+ ContextHandler contextHandler = setupContext(context_0, "0", ID_0);
+
+ ServletInfo servletInfo = createServletInfo(0,
+ ID_COUNTER.incrementAndGet(),
+ "1",
+ new String[] { "/*" },
+ null,
+ true,
+ Collections.<String, String>emptyMap());
+ Servlet servlet = mock(Servlet.class);
+ ServletHandler servletHandler = new ServletHandler(null, context_0, servletInfo, servlet);
+ when(servlet.getServletInfo()).thenReturn("info_0");
+
+ FilterInfo filterInfo = createFilterInfo(0,
+ ID_COUNTER.incrementAndGet(),
+ "1",
+ null,
+ null,
+ null,
+ true,
+ null,
+ Collections.<String, String>emptyMap());
+ FilterHandler filterHandler = new FilterHandler(null, context_0, mock(Filter.class), filterInfo);
+
+ HandlerRuntime contextRuntime = new HandlerRuntime(asList(servletHandler), asList(filterHandler), Collections.<ErrorPage>emptyList(), ID_0);
+ setupRegistry(asList(contextHandler), asList(contextRuntime),
+ Collections.<Long, Collection<ServiceReference<?>>>emptyMap());
+
+ RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+
+ assertEquals(1, runtimeDTO.servletContextDTOs.length);
+ assertEquals(1, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertEquals(1, runtimeDTO.servletContextDTOs[0].filterDTOs.length);
+
+ assertEquals(emptyMap(), runtimeDTO.servletContextDTOs[0].servletDTOs[0].initParams);
+
+ assertEquals(emptyMap(), runtimeDTO.servletContextDTOs[0].filterDTOs[0].initParams);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].filterDTOs[0].patterns.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].filterDTOs[0].regexs.length);
+ }
+
+ @Test
+ public void contextWithNoEntities() {
+ ContextHandler contextHandler_0 = setupContext(context_0, "0", ID_0);
+ ContextHandler 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());
+
+ RuntimeDTO runtimeDTO = new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+
+ assertEquals(2, runtimeDTO.servletContextDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].servletDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[0].filterDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[1].servletDTOs.length);
+ assertEquals(0, runtimeDTO.servletContextDTOs[1].filterDTOs.length);
+ }
+
+ @Test
+ public void missingPatternInServletThrowsException()
+ {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("patterns");
+
+ ContextHandler contextHandler = setupContext(context_0, "0", ID_0);
+
+ ServletInfo servletInfo = createServletInfo(0,
+ ID_COUNTER.incrementAndGet(),
+ "1",
+ null,
+ null,
+ true,
+ Collections.<String, String>emptyMap());
+ Servlet servlet = mock(Servlet.class);
+ ServletHandler servletHandler = new ServletHandler(null, context_0, servletInfo, servlet);
+ when(servlet.getServletInfo()).thenReturn("info_0");
+
+ HandlerRuntime contextRuntime = new HandlerRuntime(asList(servletHandler),
+ Collections.<FilterHandler>emptyList(),
+ Collections.<ErrorPage>emptyList(),
+ ID_0);
+ setupRegistry(asList(contextHandler), asList(contextRuntime),
+ Collections.<Long, Collection<ServiceReference<?>>> emptyMap());
+
+ new RuntimeDTOBuilder(registry, runtimeAttributes).build();
+ }
+}
\ No newline at end of file
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 14840a2..cb7d720 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
@@ -20,7 +20,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.ops4j.pax.exam.Constants.START_LEVEL_SYSTEM_BUNDLES;
import static org.ops4j.pax.exam.Constants.START_LEVEL_TEST_BUNDLE;
import static org.ops4j.pax.exam.CoreOptions.bootDelegationPackage;
@@ -38,11 +38,11 @@
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Collection;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.servlet.Filter;
@@ -64,10 +64,10 @@
import org.ops4j.pax.exam.junit.Configuration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.cm.ConfigurationEvent;
-import org.osgi.service.cm.ConfigurationListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
@@ -89,7 +89,7 @@
{
this(null, null);
}
-
+
public TestFilter(CountDownLatch initLatch, CountDownLatch destroyLatch)
{
m_initLatch = initLatch;
@@ -134,7 +134,7 @@
{
this(null, null);
}
-
+
public TestServlet(CountDownLatch initLatch, CountDownLatch destroyLatch)
{
m_initLatch = initLatch;
@@ -308,7 +308,7 @@
bootDelegationPackage("sun.*"),
cleanCaches(),
CoreOptions.systemProperty("logback.configurationFile").value("file:src/test/resources/logback.xml"), //
-// CoreOptions.vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8787"),
+ // CoreOptions.vmOption("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8787"),
mavenBundle("org.slf4j", "slf4j-api").version("1.6.5").startLevel(START_LEVEL_SYSTEM_BUNDLES),
mavenBundle("ch.qos.logback", "logback-core").version("1.0.6").startLevel(START_LEVEL_SYSTEM_BUNDLES),
@@ -372,61 +372,28 @@
return result;
}
- protected org.osgi.service.cm.Configuration configureHttpService(Dictionary<?, ?> props) throws Exception
+ protected void configureHttpService(Dictionary<?, ?> props) throws Exception
{
final String pid = "org.apache.felix.http";
- ServiceTracker tracker = new ServiceTracker(m_context, ConfigurationAdmin.class.getName(), null);
- tracker.open();
- ServiceRegistration reg = null;
- org.osgi.service.cm.Configuration config = null;
+ Collection<ServiceReference<ManagedService>> serviceRefs = m_context.getServiceReferences(ManagedService.class, String.format("(%s=%s)", Constants.SERVICE_PID, pid));
+ assertNotNull("Unable to obtain managed configuration for " + pid, serviceRefs);
- try
+ for (ServiceReference<ManagedService> serviceRef : serviceRefs)
{
- ConfigurationAdmin configAdmin = (ConfigurationAdmin) tracker.waitForService(TimeUnit.SECONDS.toMillis(5));
- assertNotNull("No configuration admin service found?!", configAdmin);
-
- final CountDownLatch latch = new CountDownLatch(1);
- final int configEvent = (props != null) ? ConfigurationEvent.CM_UPDATED : ConfigurationEvent.CM_DELETED;
-
- config = configAdmin.getConfiguration(pid, null);
-
- reg = m_context.registerService(ConfigurationListener.class.getName(), new ConfigurationListener()
+ ManagedService service = m_context.getService(serviceRef);
+ try
{
- @Override
- public void configurationEvent(ConfigurationEvent event)
- {
- if (pid.equals(event.getPid()) && event.getType() == configEvent)
- {
- latch.countDown();
- }
- }
- }, null);
-
- if (props != null)
- {
- config.update(props);
+ service.updated(props);
}
- else
+ catch (ConfigurationException ex)
{
- config.delete();
+ fail("Invalid configuration provisioned: " + ex.getMessage());
}
-
- assertTrue("Configuration not provisioned in time!", latch.await(5, TimeUnit.SECONDS));
-
- // Needed to get Jetty restarted...
- TimeUnit.MILLISECONDS.sleep(150);
-
- return config;
- }
- finally
- {
- if (reg != null)
+ finally
{
- reg.unregister();
+ m_context.ungetService(serviceRef);
}
-
- tracker.close();
}
}
diff --git a/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java b/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java
index 5666360..1869ae3 100644
--- a/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java
+++ b/http/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java
@@ -226,23 +226,23 @@
}
};
- register("/test1", servlet1);
- register("/test2", servlet2);
- register("/test.*", filter);
+ register("/test/1", servlet1);
+ register("/test/2", servlet2);
+ register("/test/.*", filter);
assertTrue(initLatch.await(5, TimeUnit.SECONDS));
- assertContent("1.1", createURL("/test1"));
- assertContent("2.1", createURL("/test2"));
- assertContent("2.2", createURL("/test2"));
- assertContent("1.2", createURL("/test1"));
- assertContent("2.3", createURL("/test2"));
+ assertContent("1.1", createURL("/test/1"));
+ assertContent("2.1", createURL("/test/2"));
+ assertContent("2.2", createURL("/test/2"));
+ assertContent("1.2", createURL("/test/1"));
+ assertContent("2.3", createURL("/test/2"));
- assertResponseCode(SC_FORBIDDEN, createURL("/test2?param=forbidden"));
- assertResponseCode(SC_NOT_FOUND, createURL("/?test=forbidden"));
+ assertResponseCode(SC_FORBIDDEN, createURL("/test/2?param=forbidden"));
+ assertResponseCode(SC_NOT_FOUND, createURL("/test?param=not_recognized"));
- assertContent("2.4", createURL("/test2"));
- assertContent("1.3", createURL("/test1"));
+ assertContent("2.4", createURL("/test/2"));
+ assertContent("1.3", createURL("/test/1"));
assertResponseCode(SC_FORBIDDEN, createURL("/test?param=forbidden"));
@@ -259,8 +259,8 @@
@Test
public void testHandleSecurityInFilterOk() throws Exception
{
- CountDownLatch initLatch = new CountDownLatch(1);
- CountDownLatch destroyLatch = new CountDownLatch(1);
+ CountDownLatch initLatch = new CountDownLatch(2);
+ CountDownLatch destroyLatch = new CountDownLatch(2);
HttpContext context = new HttpContext()
{
@@ -286,15 +286,20 @@
}
else if (request.getParameter("commit") != null)
{
- response.getWriter().append("Not allowed!");
- response.flushBuffer();
+ if (!response.isCommitted())
+ {
+ response.getWriter().append("Not allowed!");
+ response.flushBuffer();
+ }
}
return false;
}
};
TestFilter filter = new TestFilter(initLatch, destroyLatch);
+ TestServlet servlet = new TestServlet(initLatch, destroyLatch);
+ register("/foo", servlet, context);
register("/.*", filter, context);
URL url1 = createURL("/foo");
@@ -310,6 +315,7 @@
assertContent(SC_OK, "Not allowed!", url4);
unregister(filter);
+ unregister(servlet);
assertTrue(destroyLatch.await(5, TimeUnit.SECONDS));
@@ -334,7 +340,7 @@
{
assertEquals("", request.getContextPath());
assertEquals("/foo", request.getServletPath());
- assertEquals("/a", request.getPathInfo()); // /a,b/c;d/e.f;g/h
+ assertEquals("/a;b/c;d/e;f;g/h", request.getPathInfo());
assertEquals("/foo/a;b/c;d/e;f;g/h", request.getRequestURI());
assertEquals("i=j+k&l=m", request.getQueryString());
}
diff --git a/http/itest/src/test/java/org/apache/felix/http/itest/RequestDispatchTest.java b/http/itest/src/test/java/org/apache/felix/http/itest/RequestDispatchTest.java
index 57cc6f7..5fba1f7 100644
--- a/http/itest/src/test/java/org/apache/felix/http/itest/RequestDispatchTest.java
+++ b/http/itest/src/test/java/org/apache/felix/http/itest/RequestDispatchTest.java
@@ -45,7 +45,6 @@
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
-import org.osgi.service.cm.Configuration;
import org.osgi.service.http.NamespaceException;
/**
@@ -152,7 +151,7 @@
{
assertEquals("", req.getContextPath());
assertEquals("/test", req.getServletPath());
- assertEquals("/test/forward", req.getPathInfo()); // XXX ?
+ assertEquals("/forward", req.getPathInfo());
assertEquals("/test/forward", req.getRequestURI());
assertEquals("bar=qux&quu", req.getQueryString());
@@ -349,7 +348,7 @@
public void testDispatchOnNonRootContextPathOk() throws Exception
{
// Configure HTTP on a different context path...
- Configuration config = configureHttpService(createDictionary("org.apache.felix.http.context_path", "/context", "org.osgi.service.http.port", "8080"));
+ configureHttpService(createDictionary("org.apache.felix.http.context_path", "/context", "org.osgi.service.http.port", "8080"));
try
{
@@ -359,7 +358,7 @@
}
finally
{
- config.delete();
+ configureHttpService(null);
}
}