FELIX-4060 : Implement HTTP Service Update (RFC-189) - merge two manager classes into single one
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1670916 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
index 83262cc..d6b2eab 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceRuntimeImpl.java
@@ -24,7 +24,7 @@
import org.apache.felix.http.base.internal.handler.HandlerRegistry;
import org.apache.felix.http.base.internal.runtime.dto.RegistryRuntime;
import org.apache.felix.http.base.internal.runtime.dto.RuntimeDTOBuilder;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.service.http.runtime.HttpServiceRuntime;
import org.osgi.service.http.runtime.dto.RequestInfoDTO;
import org.osgi.service.http.runtime.dto.RuntimeDTO;
@@ -34,15 +34,16 @@
private final Hashtable<String, Object> attributes = new Hashtable<String, Object>();
private final HandlerRegistry registry;
- private final ServletContextHelperManager contextManager;
+ private final WhiteboardManager contextManager;
public HttpServiceRuntimeImpl(HandlerRegistry registry,
- ServletContextHelperManager contextManager)
+ WhiteboardManager contextManager)
{
this.registry = registry;
this.contextManager = contextManager;
}
+ @Override
public synchronized RuntimeDTO getRuntimeDTO()
{
RegistryRuntime runtime = contextManager.getRuntime(registry);
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
deleted file mode 100644
index 546b2f4..0000000
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ServletContextHelperManager.java
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- * 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 static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING;
-import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE;
-import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_UNKNOWN;
-import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_VALIDATION_FAILED;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentSkipListMap;
-
-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.HttpSessionIdListenerInfo;
-import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ResourceInfo;
-import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
-import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ServletRequestListenerInfo;
-import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime;
-import org.apache.felix.http.base.internal.runtime.dto.FailureRuntime;
-import org.apache.felix.http.base.internal.runtime.dto.RegistryRuntime;
-import org.apache.felix.http.base.internal.runtime.dto.ServletContextHelperRuntime;
-import org.apache.felix.http.base.internal.util.MimeTypes;
-import org.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.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceFactory;
-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;
-import org.osgi.util.tracker.ServiceTracker;
-
-public final class ServletContextHelperManager
-{
- /** A map containing all servlet context registrations. Mapped by context name */
- private final Map<String, List<ContextHandler>> contextMap = new HashMap<String, List<ContextHandler>>();
-
- /** A map with all servlet/filter registrations, mapped by abstract info. */
- private final Map<WhiteboardServiceInfo<?>, List<ContextHandler>> servicesMap = new HashMap<WhiteboardServiceInfo<?>, List<ContextHandler>>();
-
- private final WhiteboardHttpService httpService;
-
- private final ListenerRegistry listenerRegistry;
-
- private final BundleContext bundleContext;
-
- private final Map<AbstractInfo<?>, Integer> serviceFailures = new ConcurrentSkipListMap<AbstractInfo<?>, Integer>();
-
- private volatile ServletContext webContext;
-
- private volatile ServiceReference<HttpServiceRuntime> httpServiceRuntime;
-
- private volatile ServiceRegistration<ServletContextHelper> defaultContextRegistration;
-
- private final List<ServiceTracker<?, ?>> trackers = new ArrayList<ServiceTracker<?, ?>>();
-
- /**
- * Create a new servlet context helper manager
- * and the default context
- */
- public ServletContextHelperManager(final BundleContext bundleContext,
- final HandlerRegistry registry)
- {
- this.bundleContext = bundleContext;
- this.httpService = new WhiteboardHttpService(this.bundleContext, registry);
- this.listenerRegistry = new ListenerRegistry(bundleContext.getBundle());
- }
-
- public void start(ServletContext webContext, ServiceReference<HttpServiceRuntime> httpServiceRuntime)
- {
- this.webContext = webContext;
- 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>()
- {
-
- @Override
- public ServletContextHelper getService(
- final Bundle bundle,
- final ServiceRegistration<ServletContextHelper> registration)
- {
- return new ServletContextHelper(bundle)
- {
-
- @Override
- public String getMimeType(final String file)
- {
- return MimeTypes.get().getByFile(file);
- }
- };
- }
-
- @Override
- public void ungetService(
- final Bundle bundle,
- final ServiceRegistration<ServletContextHelper> registration,
- final ServletContextHelper service)
- {
- // nothing to do
- }
- }, props);
- addTracker(new FilterTracker(this.bundleContext, this));
- addTracker(new ServletTracker(this.bundleContext, this));
- addTracker(new ResourceTracker(this.bundleContext, this));
-
- addTracker(new HttpSessionListenerTracker(this.bundleContext, this));
- addTracker(new HttpSessionAttributeListenerTracker(this.bundleContext, this));
-
- addTracker(new ServletContextHelperTracker(this.bundleContext, this));
- addTracker(new ServletContextListenerTracker(this.bundleContext, this));
- addTracker(new ServletContextAttributeListenerTracker(this.bundleContext, this));
-
- addTracker(new ServletRequestListenerTracker(this.bundleContext, this));
- addTracker(new ServletRequestAttributeListenerTracker(this.bundleContext, this));
- }
-
- private void addTracker(ServiceTracker<?, ?> tracker)
- {
- this.trackers.add(tracker);
- tracker.open();
- }
-
- /**
- * Stop the instance
- */
- public void stop()
- {
- for(final ServiceTracker<?, ?> t : this.trackers)
- {
- t.close();
- }
- this.trackers.clear();
-
- // TODO cleanup
- if (this.defaultContextRegistration != null)
- {
- this.defaultContextRegistration.unregister();
- this.defaultContextRegistration = null;
- }
- }
-
- /**
- * Activate a servlet context helper.
- * @param contextInfo A context info
- */
- private void activate(final ContextHandler handler)
- {
- handler.activate();
-
- this.httpService.registerContext(handler);
-
- final Map<ServiceReference<ServletContextListener>, ServletContextListenerInfo> listeners = new TreeMap<ServiceReference<ServletContextListener>, ServletContextListenerInfo>();
- final List<WhiteboardServiceInfo<?>> services = new ArrayList<WhiteboardServiceInfo<?>>();
-
- for(final Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>> entry : this.servicesMap.entrySet())
- {
- if ( entry.getKey().getContextSelectionFilter().match(handler.getContextInfo().getServiceReference()) )
- {
- entry.getValue().add(handler);
- if ( entry.getKey() instanceof ServletContextListenerInfo )
- {
- final ServletContextListenerInfo info = (ServletContextListenerInfo)entry.getKey();
- listeners.put(info.getServiceReference(), info);
- }
- else
- {
- services.add(entry.getKey());
- }
- removeFailure(entry.getKey(), FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING);
- }
- }
- // context listeners first
- for(final ServletContextListenerInfo info : listeners.values())
- {
- this.listenerRegistry.initialized(info, handler);
- }
- // now register services
- for(final WhiteboardServiceInfo<?> info : services)
- {
- this.registerWhiteboardService(handler, info);
- }
- }
-
- /**
- * Deactivate a servlet context helper.
- * @param contextInfo A context info
- */
- private void deactivate(final ContextHandler handler)
- {
- // context listeners last
- final Map<ServiceReference<ServletContextListener>, ServletContextListenerInfo> listeners = new TreeMap<ServiceReference<ServletContextListener>, ServletContextListenerInfo>();
- final Iterator<Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>>> i = this.servicesMap.entrySet().iterator();
- while ( i.hasNext() )
- {
- final Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>> entry = i.next();
- if ( entry.getValue().remove(handler) )
- {
- if ( entry.getKey() instanceof ServletContextListenerInfo )
- {
- final ServletContextListenerInfo info = (ServletContextListenerInfo)entry.getKey();
- listeners.put(info.getServiceReference(), info);
- }
- else
- {
- this.unregisterWhiteboardService(handler, entry.getKey());
- }
- }
- }
- for(final ServletContextListenerInfo info : listeners.values())
- {
- this.listenerRegistry.destroyed(info, handler);
- }
- handler.deactivate();
-
- this.httpService.unregisterContext(handler);
- }
-
- /**
- * Add a servlet context helper.
- */
- public void addContextHelper(final ServletContextHelperInfo info)
- {
- // no failure DTO and no logging if not matching
- if ( isMatchingService(info) )
- {
- if ( info.isValid() )
- {
- 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 )
- {
- handlerList = new ArrayList<ContextHandler>();
- this.contextMap.put(info.getName(), handlerList);
- }
- handlerList.add(handler);
- Collections.sort(handlerList);
- // check for activate/deactivate
- if ( handlerList.get(0) == handler )
- {
- // check for deactivate
- if ( handlerList.size() > 1 )
- {
- ContextHandler oldHead = handlerList.get(1);
- this.deactivate(oldHead);
- this.serviceFailures.put(oldHead.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
- }
- removeFailure(handler.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
- this.activate(handler);
- }
- else
- {
- this.serviceFailures.put(handler.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
- }
- }
- }
- else
- {
- final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
- SystemLogger.debug("Ignoring " + type + " service " + info.getServiceReference());
- this.serviceFailures.put(info, FAILURE_REASON_VALIDATION_FAILED);
- }
- }
- }
-
- /**
- * Remove a servlet context helper
- */
- public void removeContextHelper(final ServletContextHelperInfo info)
- {
- // no failure DTO and no logging if not matching
- if ( isMatchingService(info) )
- {
- if ( info.isValid() )
- {
- synchronized ( this.contextMap )
- {
- final List<ContextHandler> handlerList = this.contextMap.get(info.getName());
- if ( handlerList != null )
- {
- final Iterator<ContextHandler> i = handlerList.iterator();
- boolean first = true;
- boolean activateNext = false;
- while ( i.hasNext() )
- {
- final ContextHandler handler = i.next();
- if ( handler.getContextInfo().compareTo(info) == 0 )
- {
- i.remove();
- // check for deactivate
- if ( first )
- {
- this.deactivate(handler);
- activateNext = true;
- }
- break;
- }
- first = false;
- }
- if ( handlerList.isEmpty() )
- {
- this.contextMap.remove(info.getName());
- }
- else if ( activateNext )
- {
- ContextHandler newHead = handlerList.get(0);
- this.activate(newHead);
- removeFailure(newHead.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
- }
- listenerRegistry.removeContext(info);
- }
- }
- }
- this.serviceFailures.remove(info);
- }
- }
-
- /**
- * Find the list of matching contexts for the whiteboard service
- */
- private List<ContextHandler> getMatchingContexts(final WhiteboardServiceInfo<?> info)
- {
- final List<ContextHandler> result = new ArrayList<ContextHandler>();
- for(final List<ContextHandler> handlerList : this.contextMap.values()) {
- final ContextHandler h = handlerList.get(0);
- if ( info.getContextSelectionFilter().match(h.getContextInfo().getServiceReference()) )
- {
- result.add(h);
- }
- }
- return result;
- }
-
- /**
- * Add new whiteboard service to the registry
- * @param info Whiteboard service info
- */
- public void addWhiteboardService(@Nonnull final WhiteboardServiceInfo<?> info)
- {
- // no logging and no DTO if other target service
- if ( isMatchingService(info) )
- {
- if ( info.isValid() )
- {
- synchronized ( this.contextMap )
- {
- final List<ContextHandler> handlerList = this.getMatchingContexts(info);
- this.servicesMap.put(info, handlerList);
- if (handlerList.isEmpty())
- {
- this.serviceFailures.put(info, FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING);
- }
- else
- {
- for(final ContextHandler h : handlerList)
- {
- this.registerWhiteboardService(h, info);
- }
- }
- }
- }
- else
- {
- final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
- SystemLogger.debug("Ignoring invalid " + type + " service " + info.getServiceReference());
- this.serviceFailures.put(info, FAILURE_REASON_VALIDATION_FAILED);
- }
- }
- }
-
- /**
- * Remove whiteboard service from the registry
- * @param info Whiteboard service info
- */
- public void removeWhiteboardService(@Nonnull final WhiteboardServiceInfo<?> info)
- {
- // no logging and no DTO if other target service
- if ( isMatchingService(info) ) {
- if ( info.isValid() )
- {
- synchronized ( this.contextMap )
- {
- final List<ContextHandler> handlerList = this.servicesMap.remove(info);
- if ( handlerList != null )
- {
- for(final ContextHandler h : handlerList)
- {
- this.unregisterWhiteboardService(h, info);
- }
- }
- }
- }
- this.serviceFailures.remove(info);
- }
- }
-
- /**
- * Register whiteboard service in the http service
- * @param handler Context handler
- * @param info Whiteboard service info
- */
- private void registerWhiteboardService(final ContextHandler handler, final WhiteboardServiceInfo<?> info)
- {
- try
- {
- if ( info instanceof ServletInfo )
- {
- this.httpService.registerServlet(handler, (ServletInfo)info);
- }
- else if ( info instanceof FilterInfo )
- {
- this.httpService.registerFilter(handler, (FilterInfo)info);
- }
- else if ( info instanceof ResourceInfo )
- {
- this.httpService.registerResource(handler, (ResourceInfo)info);
- }
-
- else if ( info instanceof ServletContextAttributeListenerInfo )
- {
- this.listenerRegistry.addListener((ServletContextAttributeListenerInfo) info, handler);
- }
- else if ( info instanceof HttpSessionListenerInfo )
- {
- this.listenerRegistry.addListener((HttpSessionListenerInfo) info, handler);
- }
- else if ( info instanceof HttpSessionAttributeListenerInfo )
- {
- this.listenerRegistry.addListener((HttpSessionAttributeListenerInfo) info, handler);
- }
- else if ( info instanceof HttpSessionIdListenerInfo )
- {
- this.listenerRegistry.addListener((HttpSessionIdListenerInfo) info, handler);
- }
- else if ( info instanceof ServletRequestListenerInfo )
- {
- this.listenerRegistry.addListener((ServletRequestListenerInfo) info, handler);
- }
- else if ( info instanceof ServletRequestAttributeListenerInfo )
- {
- this.listenerRegistry.addListener((ServletRequestAttributeListenerInfo) info, handler);
- }
- }
- catch (final RegistrationFailureException e)
- {
- serviceFailures.put(e.getInfo(), e.getErrorCode());
- SystemLogger.error("Exception while registering whiteboard service " + info.getServiceReference(), e);
- }
- catch (final RuntimeException e)
- {
- serviceFailures.put(info, FAILURE_REASON_UNKNOWN);
- SystemLogger.error("Exception while registering whiteboard service " + info.getServiceReference(), e);
- }
- }
-
- /**
- * Unregister whiteboard service from the http service
- * @param handler Context handler
- * @param info Whiteboard service info
- */
- private void unregisterWhiteboardService(final ContextHandler handler, final WhiteboardServiceInfo<?> info)
- {
- try
- {
- if ( info instanceof ServletInfo )
- {
- this.httpService.unregisterServlet(handler, (ServletInfo)info);
- }
- else if ( info instanceof FilterInfo )
- {
- this.httpService.unregisterFilter(handler, (FilterInfo)info);
- }
- else if ( info instanceof ResourceInfo )
- {
- this.httpService.unregisterResource(handler, (ResourceInfo)info);
- }
-
- else if ( info instanceof ServletContextAttributeListenerInfo )
- {
- this.listenerRegistry.removeListener((ServletContextAttributeListenerInfo) info, handler);
- }
- else if ( info instanceof HttpSessionListenerInfo )
- {
- this.listenerRegistry.removeListener((HttpSessionListenerInfo) info, handler);
- }
- else if ( info instanceof HttpSessionAttributeListenerInfo )
- {
- this.listenerRegistry.removeListener((HttpSessionAttributeListenerInfo) info, handler);
- }
- else if ( info instanceof HttpSessionIdListenerInfo )
- {
- this.listenerRegistry.removeListener((HttpSessionIdListenerInfo) info, handler);
- }
- else if ( info instanceof ServletRequestListenerInfo )
- {
- this.listenerRegistry.removeListener((ServletRequestListenerInfo) info, handler);
- }
- else if ( info instanceof ServletRequestAttributeListenerInfo )
- {
- this.listenerRegistry.removeListener((ServletRequestAttributeListenerInfo) info, handler);
- }
- }
- catch (final RegistrationFailureException e)
- {
- serviceFailures.put(e.getInfo(), e.getErrorCode());
- SystemLogger.error("Exception while removing servlet", e);
- }
- serviceFailures.remove(info);
- }
-
- private void removeFailure(AbstractInfo<?> info, int failureCode)
- {
- Integer registeredFailureCode = this.serviceFailures.get(info);
- if (registeredFailureCode != null && registeredFailureCode == failureCode)
- {
- this.serviceFailures.remove(info);
- }
- }
-
- /**
- * Check whether the service is specifying a target http service runtime
- * and if so if that is matching this runtime
- */
- private boolean isMatchingService(final AbstractInfo<?> info)
- {
- final String target = info.getTarget();
- if ( target != null )
- {
- try
- {
- final Filter f = this.bundleContext.createFilter(target);
- return f.match(this.httpServiceRuntime);
- }
- catch ( final InvalidSyntaxException ise)
- {
- // log and ignore service
- SystemLogger.error("Invalid target filter expression for " + info.getServiceReference() + " : " + target, ise);
- return false;
- }
- }
- return true;
- }
-
- public ContextHandler getContextHandler(final Long contextId)
- {
- synchronized ( this.contextMap )
- {
- for(final List<ContextHandler> handlerList : this.contextMap.values())
- {
- final ContextHandler h = handlerList.get(0);
- if ( h.getContextInfo().getServiceId() == contextId )
- {
- return h;
- }
- }
- }
- return null;
- }
-
- public Collection<ContextHandler> getContextHandlers()
- {
- final List<ContextHandler> handlers = new ArrayList<ContextHandler>();
- synchronized ( this.contextMap )
- {
- for(final List<ContextHandler> handlerList : this.contextMap.values())
- {
- final ContextHandler h = handlerList.get(0);
- handlers.add(h);
- }
- }
- return handlers;
- }
-
- public RegistryRuntime getRuntime(HandlerRegistry registry)
- {
- Collection<ServletContextHelperRuntime> contextRuntimes = new TreeSet<ServletContextHelperRuntime>(ServletContextHelperRuntime.COMPARATOR);
- List<ContextRuntime> handlerRuntimes;
- Map<Long, Collection<ServiceReference<?>>> listenerRuntimes;
- FailureRuntime.Builder failureRuntime = FailureRuntime.builder();
- synchronized ( this.contextMap )
- {
- for (List<ContextHandler> contextHandlerList : this.contextMap.values())
- {
- if ( !contextHandlerList.isEmpty() )
- {
- contextRuntimes.add(contextHandlerList.get(0));
- }
- }
- handlerRuntimes = registry.getRuntime(failureRuntime);
- listenerRuntimes = listenerRegistry.getContextRuntimes();
- failureRuntime.add(serviceFailures);
- }
- return new RegistryRuntime(contextRuntimes, handlerRuntimes, listenerRuntimes, failureRuntime.build());
- }
-}
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
index f750db2..82020a5 100644
--- 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
@@ -16,22 +16,77 @@
*/
package org.apache.felix.http.base.internal.whiteboard;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_UNKNOWN;
+import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_VALIDATION_FAILED;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentSkipListMap;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
+import javax.servlet.ServletContextListener;
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.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.HttpSessionIdListenerInfo;
+import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ResourceInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletInfo;
+import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
+import org.apache.felix.http.base.internal.runtime.ServletRequestListenerInfo;
+import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
+import org.apache.felix.http.base.internal.runtime.dto.ContextRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.FailureRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.RegistryRuntime;
+import org.apache.felix.http.base.internal.runtime.dto.ServletContextHelperRuntime;
import org.apache.felix.http.base.internal.service.HttpServiceFactory;
import org.apache.felix.http.base.internal.service.HttpServiceRuntimeImpl;
+import org.apache.felix.http.base.internal.util.MimeTypes;
+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.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceFactory;
+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.runtime.HttpServiceRuntimeConstants;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
+import org.osgi.util.tracker.ServiceTracker;
public final class WhiteboardManager
{
@@ -41,7 +96,25 @@
private final HttpServiceRuntimeImpl serviceRuntime;
- private final ServletContextHelperManager contextManager;
+ /** A map containing all servlet context registrations. Mapped by context name */
+ private final Map<String, List<ContextHandler>> contextMap = new HashMap<String, List<ContextHandler>>();
+
+ /** A map with all servlet/filter registrations, mapped by abstract info. */
+ private final Map<WhiteboardServiceInfo<?>, List<ContextHandler>> servicesMap = new HashMap<WhiteboardServiceInfo<?>, List<ContextHandler>>();
+
+ private final WhiteboardHttpService httpService;
+
+ private final ListenerRegistry listenerRegistry;
+
+ private final Map<AbstractInfo<?>, Integer> serviceFailures = new ConcurrentSkipListMap<AbstractInfo<?>, Integer>();
+
+ private volatile ServletContext webContext;
+
+ private volatile ServiceReference<HttpServiceRuntime> httpServiceRuntime;
+
+ private volatile ServiceRegistration<ServletContextHelper> defaultContextRegistration;
+
+ private final List<ServiceTracker<?, ?>> trackers = new ArrayList<ServiceTracker<?, ?>>();
private volatile ServiceRegistration<HttpServiceRuntime> runtimeServiceReg;
@@ -57,8 +130,9 @@
{
this.bundleContext = bundleContext;
this.httpServiceFactory = httpServiceFactory;
- this.contextManager = new ServletContextHelperManager(bundleContext, registry);
- this.serviceRuntime = new HttpServiceRuntimeImpl(registry, this.contextManager);
+ this.httpService = new WhiteboardHttpService(this.bundleContext, registry);
+ this.listenerRegistry = new ListenerRegistry(bundleContext.getBundle());
+ this.serviceRuntime = new HttpServiceRuntimeImpl(registry, this);
}
public void start(final ServletContext context)
@@ -70,12 +144,82 @@
serviceRuntime,
this.serviceRuntime.getAttributes());
- this.contextManager.start(context, this.runtimeServiceReg.getReference());
+ this.webContext = webContext;
+ 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>()
+ {
+
+ @Override
+ public ServletContextHelper getService(
+ final Bundle bundle,
+ final ServiceRegistration<ServletContextHelper> registration)
+ {
+ return new ServletContextHelper(bundle)
+ {
+
+ @Override
+ public String getMimeType(final String file)
+ {
+ return MimeTypes.get().getByFile(file);
+ }
+ };
+ }
+
+ @Override
+ public void ungetService(
+ final Bundle bundle,
+ final ServiceRegistration<ServletContextHelper> registration,
+ final ServletContextHelper service)
+ {
+ // nothing to do
+ }
+ }, props);
+ addTracker(new FilterTracker(this.bundleContext, this));
+ addTracker(new ServletTracker(this.bundleContext, this));
+ addTracker(new ResourceTracker(this.bundleContext, this));
+
+ addTracker(new HttpSessionListenerTracker(this.bundleContext, this));
+ addTracker(new HttpSessionAttributeListenerTracker(this.bundleContext, this));
+
+ addTracker(new ServletContextHelperTracker(this.bundleContext, this));
+ addTracker(new ServletContextListenerTracker(this.bundleContext, this));
+ addTracker(new ServletContextAttributeListenerTracker(this.bundleContext, this));
+
+ addTracker(new ServletRequestListenerTracker(this.bundleContext, this));
+ addTracker(new ServletRequestAttributeListenerTracker(this.bundleContext, this));
}
+ private void addTracker(ServiceTracker<?, ?> tracker)
+ {
+ this.trackers.add(tracker);
+ tracker.open();
+ }
+
+ /**
+ * Stop the instance
+ */
public void stop()
{
- this.contextManager.stop();
+ for(final ServiceTracker<?, ?> t : this.trackers)
+ {
+ t.close();
+ }
+ this.trackers.clear();
+
+ // TODO cleanup
+ if (this.defaultContextRegistration != null)
+ {
+ this.defaultContextRegistration.unregister();
+ this.defaultContextRegistration = null;
+ }
if ( this.runtimeServiceReg != null )
{
@@ -101,17 +245,473 @@
{
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.getContextHandler(contextId);
+ if ( handler != 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());
+ }
+ }
+ }
+
+ /**
+ * Activate a servlet context helper.
+ * @param contextInfo A context info
+ */
+ private void activate(final ContextHandler handler)
+ {
+ handler.activate();
+
+ this.httpService.registerContext(handler);
+
+ final Map<ServiceReference<ServletContextListener>, ServletContextListenerInfo> listeners = new TreeMap<ServiceReference<ServletContextListener>, ServletContextListenerInfo>();
+ final List<WhiteboardServiceInfo<?>> services = new ArrayList<WhiteboardServiceInfo<?>>();
+
+ for(final Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>> entry : this.servicesMap.entrySet())
+ {
+ if ( entry.getKey().getContextSelectionFilter().match(handler.getContextInfo().getServiceReference()) )
+ {
+ entry.getValue().add(handler);
+ if ( entry.getKey() instanceof ServletContextListenerInfo )
{
- final ExtServletContext context = handler.getServletContext(this.bundleContext.getBundle());
- new HttpSessionWrapper(contextId, session, context, true).invalidate();
- handler.ungetServletContext(this.bundleContext.getBundle());
+ final ServletContextListenerInfo info = (ServletContextListenerInfo)entry.getKey();
+ listeners.put(info.getServiceReference(), info);
+ }
+ else
+ {
+ services.add(entry.getKey());
+ }
+ removeFailure(entry.getKey(), FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING);
+ }
+ }
+ // context listeners first
+ for(final ServletContextListenerInfo info : listeners.values())
+ {
+ this.listenerRegistry.initialized(info, handler);
+ }
+ // now register services
+ for(final WhiteboardServiceInfo<?> info : services)
+ {
+ this.registerWhiteboardService(handler, info);
+ }
+ }
+
+ /**
+ * Deactivate a servlet context helper.
+ * @param contextInfo A context info
+ */
+ private void deactivate(final ContextHandler handler)
+ {
+ // context listeners last
+ final Map<ServiceReference<ServletContextListener>, ServletContextListenerInfo> listeners = new TreeMap<ServiceReference<ServletContextListener>, ServletContextListenerInfo>();
+ final Iterator<Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>>> i = this.servicesMap.entrySet().iterator();
+ while ( i.hasNext() )
+ {
+ final Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>> entry = i.next();
+ if ( entry.getValue().remove(handler) )
+ {
+ if ( entry.getKey() instanceof ServletContextListenerInfo )
+ {
+ final ServletContextListenerInfo info = (ServletContextListenerInfo)entry.getKey();
+ listeners.put(info.getServiceReference(), info);
+ }
+ else
+ {
+ this.unregisterWhiteboardService(handler, entry.getKey());
}
}
}
+ for(final ServletContextListenerInfo info : listeners.values())
+ {
+ this.listenerRegistry.destroyed(info, handler);
+ }
+ handler.deactivate();
+
+ this.httpService.unregisterContext(handler);
+ }
+
+ /**
+ * Add a servlet context helper.
+ */
+ public void addContextHelper(final ServletContextHelperInfo info)
+ {
+ // no failure DTO and no logging if not matching
+ if ( isMatchingService(info) )
+ {
+ if ( info.isValid() )
+ {
+ 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 )
+ {
+ handlerList = new ArrayList<ContextHandler>();
+ this.contextMap.put(info.getName(), handlerList);
+ }
+ handlerList.add(handler);
+ Collections.sort(handlerList);
+ // check for activate/deactivate
+ if ( handlerList.get(0) == handler )
+ {
+ // check for deactivate
+ if ( handlerList.size() > 1 )
+ {
+ ContextHandler oldHead = handlerList.get(1);
+ this.deactivate(oldHead);
+ this.serviceFailures.put(oldHead.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
+ removeFailure(handler.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ this.activate(handler);
+ }
+ else
+ {
+ this.serviceFailures.put(handler.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
+ }
+ }
+ else
+ {
+ final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
+ SystemLogger.debug("Ignoring " + type + " service " + info.getServiceReference());
+ this.serviceFailures.put(info, FAILURE_REASON_VALIDATION_FAILED);
+ }
+ }
+ }
+
+ /**
+ * Remove a servlet context helper
+ */
+ public void removeContextHelper(final ServletContextHelperInfo info)
+ {
+ // no failure DTO and no logging if not matching
+ if ( isMatchingService(info) )
+ {
+ if ( info.isValid() )
+ {
+ synchronized ( this.contextMap )
+ {
+ final List<ContextHandler> handlerList = this.contextMap.get(info.getName());
+ if ( handlerList != null )
+ {
+ final Iterator<ContextHandler> i = handlerList.iterator();
+ boolean first = true;
+ boolean activateNext = false;
+ while ( i.hasNext() )
+ {
+ final ContextHandler handler = i.next();
+ if ( handler.getContextInfo().compareTo(info) == 0 )
+ {
+ i.remove();
+ // check for deactivate
+ if ( first )
+ {
+ this.deactivate(handler);
+ activateNext = true;
+ }
+ break;
+ }
+ first = false;
+ }
+ if ( handlerList.isEmpty() )
+ {
+ this.contextMap.remove(info.getName());
+ }
+ else if ( activateNext )
+ {
+ ContextHandler newHead = handlerList.get(0);
+ this.activate(newHead);
+ removeFailure(newHead.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
+ }
+ listenerRegistry.removeContext(info);
+ }
+ }
+ }
+ this.serviceFailures.remove(info);
+ }
+ }
+
+ /**
+ * Find the list of matching contexts for the whiteboard service
+ */
+ private List<ContextHandler> getMatchingContexts(final WhiteboardServiceInfo<?> info)
+ {
+ final List<ContextHandler> result = new ArrayList<ContextHandler>();
+ for(final List<ContextHandler> handlerList : this.contextMap.values()) {
+ final ContextHandler h = handlerList.get(0);
+ if ( info.getContextSelectionFilter().match(h.getContextInfo().getServiceReference()) )
+ {
+ result.add(h);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Add new whiteboard service to the registry
+ * @param info Whiteboard service info
+ */
+ public void addWhiteboardService(@Nonnull final WhiteboardServiceInfo<?> info)
+ {
+ // no logging and no DTO if other target service
+ if ( isMatchingService(info) )
+ {
+ if ( info.isValid() )
+ {
+ synchronized ( this.contextMap )
+ {
+ final List<ContextHandler> handlerList = this.getMatchingContexts(info);
+ this.servicesMap.put(info, handlerList);
+ if (handlerList.isEmpty())
+ {
+ this.serviceFailures.put(info, FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING);
+ }
+ else
+ {
+ for(final ContextHandler h : handlerList)
+ {
+ this.registerWhiteboardService(h, info);
+ }
+ }
+ }
+ }
+ else
+ {
+ final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
+ SystemLogger.debug("Ignoring invalid " + type + " service " + info.getServiceReference());
+ this.serviceFailures.put(info, FAILURE_REASON_VALIDATION_FAILED);
+ }
+ }
+ }
+
+ /**
+ * Remove whiteboard service from the registry
+ * @param info Whiteboard service info
+ */
+ public void removeWhiteboardService(@Nonnull final WhiteboardServiceInfo<?> info)
+ {
+ // no logging and no DTO if other target service
+ if ( isMatchingService(info) ) {
+ if ( info.isValid() )
+ {
+ synchronized ( this.contextMap )
+ {
+ final List<ContextHandler> handlerList = this.servicesMap.remove(info);
+ if ( handlerList != null )
+ {
+ for(final ContextHandler h : handlerList)
+ {
+ this.unregisterWhiteboardService(h, info);
+ }
+ }
+ }
+ }
+ this.serviceFailures.remove(info);
+ }
+ }
+
+ /**
+ * Register whiteboard service in the http service
+ * @param handler Context handler
+ * @param info Whiteboard service info
+ */
+ private void registerWhiteboardService(final ContextHandler handler, final WhiteboardServiceInfo<?> info)
+ {
+ try
+ {
+ if ( info instanceof ServletInfo )
+ {
+ this.httpService.registerServlet(handler, (ServletInfo)info);
+ }
+ else if ( info instanceof FilterInfo )
+ {
+ this.httpService.registerFilter(handler, (FilterInfo)info);
+ }
+ else if ( info instanceof ResourceInfo )
+ {
+ this.httpService.registerResource(handler, (ResourceInfo)info);
+ }
+
+ else if ( info instanceof ServletContextAttributeListenerInfo )
+ {
+ this.listenerRegistry.addListener((ServletContextAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionListenerInfo )
+ {
+ this.listenerRegistry.addListener((HttpSessionListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionAttributeListenerInfo )
+ {
+ this.listenerRegistry.addListener((HttpSessionAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionIdListenerInfo )
+ {
+ this.listenerRegistry.addListener((HttpSessionIdListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestListenerInfo )
+ {
+ this.listenerRegistry.addListener((ServletRequestListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestAttributeListenerInfo )
+ {
+ this.listenerRegistry.addListener((ServletRequestAttributeListenerInfo) info, handler);
+ }
+ }
+ catch (final RegistrationFailureException e)
+ {
+ serviceFailures.put(e.getInfo(), e.getErrorCode());
+ SystemLogger.error("Exception while registering whiteboard service " + info.getServiceReference(), e);
+ }
+ catch (final RuntimeException e)
+ {
+ serviceFailures.put(info, FAILURE_REASON_UNKNOWN);
+ SystemLogger.error("Exception while registering whiteboard service " + info.getServiceReference(), e);
+ }
+ }
+
+ /**
+ * Unregister whiteboard service from the http service
+ * @param handler Context handler
+ * @param info Whiteboard service info
+ */
+ private void unregisterWhiteboardService(final ContextHandler handler, final WhiteboardServiceInfo<?> info)
+ {
+ try
+ {
+ if ( info instanceof ServletInfo )
+ {
+ this.httpService.unregisterServlet(handler, (ServletInfo)info);
+ }
+ else if ( info instanceof FilterInfo )
+ {
+ this.httpService.unregisterFilter(handler, (FilterInfo)info);
+ }
+ else if ( info instanceof ResourceInfo )
+ {
+ this.httpService.unregisterResource(handler, (ResourceInfo)info);
+ }
+
+ else if ( info instanceof ServletContextAttributeListenerInfo )
+ {
+ this.listenerRegistry.removeListener((ServletContextAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionListenerInfo )
+ {
+ this.listenerRegistry.removeListener((HttpSessionListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionAttributeListenerInfo )
+ {
+ this.listenerRegistry.removeListener((HttpSessionAttributeListenerInfo) info, handler);
+ }
+ else if ( info instanceof HttpSessionIdListenerInfo )
+ {
+ this.listenerRegistry.removeListener((HttpSessionIdListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestListenerInfo )
+ {
+ this.listenerRegistry.removeListener((ServletRequestListenerInfo) info, handler);
+ }
+ else if ( info instanceof ServletRequestAttributeListenerInfo )
+ {
+ this.listenerRegistry.removeListener((ServletRequestAttributeListenerInfo) info, handler);
+ }
+ }
+ catch (final RegistrationFailureException e)
+ {
+ serviceFailures.put(e.getInfo(), e.getErrorCode());
+ SystemLogger.error("Exception while removing servlet", e);
+ }
+ serviceFailures.remove(info);
+ }
+
+ private void removeFailure(AbstractInfo<?> info, int failureCode)
+ {
+ Integer registeredFailureCode = this.serviceFailures.get(info);
+ if (registeredFailureCode != null && registeredFailureCode == failureCode)
+ {
+ this.serviceFailures.remove(info);
+ }
+ }
+
+ /**
+ * Check whether the service is specifying a target http service runtime
+ * and if so if that is matching this runtime
+ */
+ private boolean isMatchingService(final AbstractInfo<?> info)
+ {
+ final String target = info.getTarget();
+ if ( target != null )
+ {
+ try
+ {
+ final Filter f = this.bundleContext.createFilter(target);
+ return f.match(this.httpServiceRuntime);
+ }
+ catch ( final InvalidSyntaxException ise)
+ {
+ // log and ignore service
+ SystemLogger.error("Invalid target filter expression for " + info.getServiceReference() + " : " + target, ise);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public ContextHandler getContextHandler(final Long contextId)
+ {
+ synchronized ( this.contextMap )
+ {
+ for(final List<ContextHandler> handlerList : this.contextMap.values())
+ {
+ final ContextHandler h = handlerList.get(0);
+ if ( h.getContextInfo().getServiceId() == contextId )
+ {
+ return h;
+ }
+ }
+ }
+ return null;
+ }
+
+ public Collection<ContextHandler> getContextHandlers()
+ {
+ final List<ContextHandler> handlers = new ArrayList<ContextHandler>();
+ synchronized ( this.contextMap )
+ {
+ for(final List<ContextHandler> handlerList : this.contextMap.values())
+ {
+ final ContextHandler h = handlerList.get(0);
+ handlers.add(h);
+ }
+ }
+ return handlers;
+ }
+
+ public RegistryRuntime getRuntime(HandlerRegistry registry)
+ {
+ Collection<ServletContextHelperRuntime> contextRuntimes = new TreeSet<ServletContextHelperRuntime>(ServletContextHelperRuntime.COMPARATOR);
+ List<ContextRuntime> handlerRuntimes;
+ Map<Long, Collection<ServiceReference<?>>> listenerRuntimes;
+ FailureRuntime.Builder failureRuntime = FailureRuntime.builder();
+ synchronized ( this.contextMap )
+ {
+ for (List<ContextHandler> contextHandlerList : this.contextMap.values())
+ {
+ if ( !contextHandlerList.isEmpty() )
+ {
+ contextRuntimes.add(contextHandlerList.get(0));
+ }
+ }
+ handlerRuntimes = registry.getRuntime(failureRuntime);
+ listenerRuntimes = listenerRegistry.getContextRuntimes();
+ failureRuntime.add(serviceFailures);
+ }
+ return new RegistryRuntime(contextRuntimes, handlerRuntimes, listenerRuntimes, failureRuntime.build());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java
index 5f594bb..3a10f33 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/FilterTracker.java
@@ -20,14 +20,14 @@
import org.apache.felix.http.base.internal.runtime.FilterInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
public final class FilterTracker extends WhiteboardServiceTracker<Filter>
{
- public FilterTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public FilterTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, String.format("(&(objectClass=%s)(|(%s=*)(%s=*)(%s=*)))",
Filter.class.getName(),
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionAttributeListenerTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionAttributeListenerTracker.java
index 0971399..64f2003 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionAttributeListenerTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionAttributeListenerTracker.java
@@ -20,13 +20,13 @@
import org.apache.felix.http.base.internal.runtime.HttpSessionAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public final class HttpSessionAttributeListenerTracker extends WhiteboardServiceTracker<HttpSessionAttributeListener>
{
- public HttpSessionAttributeListenerTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public HttpSessionAttributeListenerTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, createListenerFilterExpression(HttpSessionAttributeListener.class));
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionIdListenerTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionIdListenerTracker.java
index 894e2a8..1256862 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionIdListenerTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionIdListenerTracker.java
@@ -20,13 +20,13 @@
import org.apache.felix.http.base.internal.runtime.HttpSessionIdListenerInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public final class HttpSessionIdListenerTracker extends WhiteboardServiceTracker<HttpSessionIdListener>
{
- public HttpSessionIdListenerTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public HttpSessionIdListenerTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, createListenerFilterExpression(HttpSessionIdListener.class));
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionListenerTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionListenerTracker.java
index bf70059..cc351fa 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionListenerTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/HttpSessionListenerTracker.java
@@ -20,13 +20,13 @@
import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public final class HttpSessionListenerTracker extends WhiteboardServiceTracker<HttpSessionListener>
{
- public HttpSessionListenerTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public HttpSessionListenerTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, createListenerFilterExpression(HttpSessionListener.class));
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ResourceTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ResourceTracker.java
index 4c22004..e902d06 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ResourceTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ResourceTracker.java
@@ -18,14 +18,14 @@
import org.apache.felix.http.base.internal.runtime.ResourceInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
public final class ResourceTracker extends WhiteboardServiceTracker<Object>
{
- public ResourceTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public ResourceTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, String.format("(&(%s=*)(%s=*))",
HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN,
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextAttributeListenerTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextAttributeListenerTracker.java
index a64e6d2..f0edbf2 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextAttributeListenerTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextAttributeListenerTracker.java
@@ -20,13 +20,13 @@
import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public final class ServletContextAttributeListenerTracker extends WhiteboardServiceTracker<ServletContextAttributeListener>
{
- public ServletContextAttributeListenerTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public ServletContextAttributeListenerTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, createListenerFilterExpression(ServletContextAttributeListener.class));
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextHelperTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextHelperTracker.java
index 3818437..6b5fe65 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextHelperTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextHelperTracker.java
@@ -19,7 +19,7 @@
import javax.annotation.Nonnull;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
@@ -31,7 +31,7 @@
*/
public final class ServletContextHelperTracker extends ServiceTracker<ServletContextHelper, ServiceReference<ServletContextHelper>>
{
- private final ServletContextHelperManager contextManager;
+ private final WhiteboardManager contextManager;
private static org.osgi.framework.Filter createFilter(final BundleContext btx)
{
@@ -47,7 +47,7 @@
return null; // we never get here - and if we get an NPE which is fine
}
- public ServletContextHelperTracker(@Nonnull final BundleContext context, @Nonnull final ServletContextHelperManager manager)
+ public ServletContextHelperTracker(@Nonnull final BundleContext context, @Nonnull final WhiteboardManager manager)
{
super(context, createFilter(context), null);
this.contextManager = manager;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextListenerTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextListenerTracker.java
index 618902b..bc48043 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextListenerTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletContextListenerTracker.java
@@ -20,13 +20,13 @@
import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public final class ServletContextListenerTracker extends WhiteboardServiceTracker<ServletContextListener>
{
- public ServletContextListenerTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public ServletContextListenerTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, createListenerFilterExpression(ServletContextListener.class));
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestAttributeListenerTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestAttributeListenerTracker.java
index 42cb1c3..1931d3a 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestAttributeListenerTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestAttributeListenerTracker.java
@@ -20,13 +20,13 @@
import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public final class ServletRequestAttributeListenerTracker extends WhiteboardServiceTracker<ServletRequestAttributeListener>
{
- public ServletRequestAttributeListenerTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public ServletRequestAttributeListenerTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, createListenerFilterExpression(ServletRequestAttributeListener.class));
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestListenerTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestListenerTracker.java
index 40343bc..e7c2eca 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestListenerTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletRequestListenerTracker.java
@@ -20,13 +20,13 @@
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.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
public final class ServletRequestListenerTracker extends WhiteboardServiceTracker<ServletRequestListener>
{
- public ServletRequestListenerTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public ServletRequestListenerTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, createListenerFilterExpression(ServletRequestListener.class));
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java
index 4088432..ea7bfe0 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/ServletTracker.java
@@ -20,14 +20,14 @@
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.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
public final class ServletTracker extends WhiteboardServiceTracker<Servlet>
{
- public ServletTracker(final BundleContext context, final ServletContextHelperManager manager)
+ public ServletTracker(final BundleContext context, final WhiteboardManager manager)
{
super(manager, context, String.format("(&(objectClass=%s)(|(%s=*)(%s=*)))",
Servlet.class.getName(),
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/WhiteboardServiceTracker.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/WhiteboardServiceTracker.java
index 8a2c515..ba3c72c 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/WhiteboardServiceTracker.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/tracker/WhiteboardServiceTracker.java
@@ -17,7 +17,7 @@
package org.apache.felix.http.base.internal.whiteboard.tracker;
import org.apache.felix.http.base.internal.runtime.WhiteboardServiceInfo;
-import org.apache.felix.http.base.internal.whiteboard.ServletContextHelperManager;
+import org.apache.felix.http.base.internal.whiteboard.WhiteboardManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
@@ -56,8 +56,8 @@
return null; // we never get here - and if we get an NPE which is fine
}
- /** The context manager is called for each added/removed reference. */
- private final ServletContextHelperManager contextManager;
+ /** The manager is called for each added/removed reference. */
+ private final WhiteboardManager contextManager;
/**
* Create a new tracker
@@ -65,7 +65,7 @@
* @param bundleContext The bundle context.
* @param filterExpr The filter expression for the services to track
*/
- public WhiteboardServiceTracker(final ServletContextHelperManager contextManager,
+ public WhiteboardServiceTracker(final WhiteboardManager contextManager,
final BundleContext bundleContext, final String filterExpr)
{
super(bundleContext, createFilter(bundleContext, filterExpr), null);