FELIX-4060 : Implement HTTP Service Update (RFC-189)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1656701 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 748db74..c286cf0 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
@@ -24,7 +24,6 @@
import org.apache.felix.http.base.internal.dispatch.Dispatcher;
import org.apache.felix.http.base.internal.handler.HandlerRegistry;
import org.apache.felix.http.base.internal.handler.HttpServicePlugin;
-import org.apache.felix.http.base.internal.handler.PerContextHandlerRegistry;
import org.apache.felix.http.base.internal.listener.HttpSessionAttributeListenerManager;
import org.apache.felix.http.base.internal.listener.HttpSessionListenerManager;
import org.apache.felix.http.base.internal.listener.ServletContextAttributeListenerManager;
@@ -79,7 +78,6 @@
{
this.bundleContext = bundleContext;
this.registry = new HandlerRegistry();
- this.registry.add(new PerContextHandlerRegistry());
this.dispatcher = new Dispatcher(this.registry);
this.serviceProps = new Hashtable<String, Object>();
this.contextAttributeListener = new ServletContextAttributeListenerManager(bundleContext);
@@ -177,7 +175,7 @@
try
{
this.serviceReg.unregister();
- this.registry.removeAll();
+ this.registry.shutdown();
}
finally
{
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 b3570d0..aaa07ca 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
@@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import javax.annotation.Nonnull;
@@ -25,11 +26,79 @@
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
+/**
+ * Registry for all services.
+ *
+ * The registry is organized per servlet context and is dispatching to one
+ * of the {@link PerContextHandlerRegistry} registries.
+ */
public final class HandlerRegistry
{
+ /** Current list of context registrations. */
private volatile List<PerContextHandlerRegistry> registrations = Collections.emptyList();
- public void add(@Nonnull PerContextHandlerRegistry registry)
+ public HandlerRegistry()
+ {
+ this.add(new PerContextHandlerRegistry());
+ }
+
+ /**
+ * Shutdown
+ */
+ public void shutdown()
+ {
+ final List<PerContextHandlerRegistry> list;
+
+ synchronized ( this )
+ {
+ list = new ArrayList<PerContextHandlerRegistry>(this.registrations);
+ this.registrations = Collections.emptyList();
+
+ }
+
+ for(final PerContextHandlerRegistry r : list)
+ {
+ r.removeAll();
+ }
+ }
+
+ /**
+ * Add a context registration.
+ * @param info The servlet context helper info
+ */
+ public void add(@Nonnull ServletContextHelperInfo info)
+ {
+ this.add(new PerContextHandlerRegistry(info));
+ }
+
+ /**
+ * Remove a context registration.
+ * @param info The servlet context helper info
+ */
+ public void remove(@Nonnull ServletContextHelperInfo info)
+ {
+ synchronized ( this )
+ {
+ final List<PerContextHandlerRegistry> updatedList = new ArrayList<PerContextHandlerRegistry>(this.registrations);
+ final Iterator<PerContextHandlerRegistry> i = updatedList.iterator();
+ while ( i.hasNext() )
+ {
+ final PerContextHandlerRegistry reg = i.next();
+ if ( reg.getContextServiceId() == info.getServiceId() )
+ {
+ i.remove();
+ this.registrations = updatedList;
+ break;
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Add a new context registration.
+ */
+ private void add(@Nonnull PerContextHandlerRegistry registry)
{
synchronized ( this )
{
@@ -41,17 +110,11 @@
}
}
- public void remove(@Nonnull PerContextHandlerRegistry registry)
- {
- synchronized ( this )
- {
- final List<PerContextHandlerRegistry> updatedList = new ArrayList<PerContextHandlerRegistry>(this.registrations);
- updatedList.remove(registry);
-
- this.registrations = updatedList;
- }
- }
-
+ /**
+ * Get the per context registry.
+ * @param info The servlet context helper info or {@code null} for the Http Service context.
+ * @return A per context registry or {@code null}
+ */
public PerContextHandlerRegistry getRegistry(final ServletContextHelperInfo info)
{
final long key = (info == null ? 0 : info.getServiceId());
@@ -65,11 +128,9 @@
return r;
}
}
- final PerContextHandlerRegistry reg = new PerContextHandlerRegistry(info);
- this.add(reg);
-
- return reg;
}
+
+ return null;
}
public ErrorsMapping getErrorsMapping(final String requestURI, final Long serviceId)
@@ -140,21 +201,4 @@
}
return null;
}
-
- public synchronized void removeAll()
- {
- final List<PerContextHandlerRegistry> list;
-
- synchronized ( this )
- {
- list = new ArrayList<PerContextHandlerRegistry>(this.registrations);
- this.registrations = Collections.emptyList();
-
- }
-
- for(final PerContextHandlerRegistry r : list)
- {
- r.removeAll();
- }
- }
}
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 2b77de2..ef35c0f 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
@@ -120,6 +120,9 @@
private void activate(final ContextHandler handler)
{
handler.activate();
+
+ this.httpService.registerContext(handler);
+
// context listeners first
final List<WhiteboardServiceInfo<?>> services = new ArrayList<WhiteboardServiceInfo<?>>();
for(final Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>> entry : this.servicesMap.entrySet())
@@ -150,6 +153,8 @@
*/
private void deactivate(final ContextHandler handler)
{
+ this.httpService.unregisterContext(handler);
+
// context listeners last
final List<ServletContextListenerInfo> listeners = new ArrayList<ServletContextListenerInfo>();
final Iterator<Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>>> i = this.servicesMap.entrySet().iterator();
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 d6f9c5d..2dfbbe7 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
@@ -201,4 +201,14 @@
final ServletInfo servletInfo = new ServletInfo(resourceInfo);
this.unregisterServlet(contextHandler, servletInfo);
}
+
+ public void registerContext(@Nonnull final ContextHandler contextHandler)
+ {
+ this.handlerRegistry.add(contextHandler.getContextInfo());
+ }
+
+ public void unregisterContext(@Nonnull final ContextHandler contextHandler)
+ {
+ this.handlerRegistry.remove(contextHandler.getContextInfo());
+ }
}