FELIX-4060 : Implement HTTP Whiteboard Service (RFC-189). Move handler registration to own registry class.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1681425 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
index 2fcdae4..888efe1 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
@@ -34,7 +34,7 @@
* The filter handler handles the initialization and destruction of filter
* objects.
*/
-public class FilterHandler implements Comparable<FilterHandler>
+public abstract class FilterHandler implements Comparable<FilterHandler>
{
private final long contextServiceId;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ListenerHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ListenerHandler.java
new file mode 100644
index 0000000..a93a84b
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ListenerHandler.java
@@ -0,0 +1,144 @@
+/*
+ * 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.handler;
+
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.runtime.ListenerInfo;
+import org.osgi.service.http.runtime.dto.DTOConstants;
+
+/**
+ * The listener handler handles the initialization and destruction of listener
+ * objects.
+ */
+public abstract class ListenerHandler<T> implements Comparable<ListenerHandler<T>>
+{
+ private final long contextServiceId;
+
+ private final ListenerInfo<T> listenerInfo;
+
+ private final ExtServletContext context;
+
+ private T listener;
+
+ protected volatile int useCount;
+
+ public ListenerHandler(final long contextServiceId,
+ final ExtServletContext context,
+ final ListenerInfo<T> listenerInfo)
+ {
+ this.contextServiceId = contextServiceId;
+ this.context = context;
+ this.listenerInfo = listenerInfo;
+ }
+
+ @Override
+ public int compareTo(final ListenerHandler<T> other)
+ {
+ return this.listenerInfo.compareTo(other.listenerInfo);
+ }
+
+ public ExtServletContext getContext()
+ {
+ return this.context;
+ }
+
+ public long getContextServiceId()
+ {
+ return this.contextServiceId;
+ }
+
+ public T getListener()
+ {
+ return listener;
+ }
+
+ protected void setListener(final T f)
+ {
+ this.listener = f;
+ }
+
+ public ListenerInfo<T> getListenerInfo()
+ {
+ return this.listenerInfo;
+ }
+
+ /**
+ * Initialize the object
+ * @return {code -1} on success, a failure reason according to {@link DTOConstants} otherwise.
+ */
+ public int init()
+ {
+ if ( this.useCount > 0 )
+ {
+ this.useCount++;
+ return -1;
+ }
+
+ if (this.listener == null)
+ {
+ return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ }
+
+ this.useCount++;
+ return -1;
+ }
+
+ public boolean destroy()
+ {
+ if (this.listener == null)
+ {
+ return false;
+ }
+
+ this.useCount--;
+ if ( this.useCount == 0 )
+ {
+
+ listener = null;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean dispose()
+ {
+ // fully destroy the listener
+ this.useCount = 1;
+ return this.destroy();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return 31 + listenerInfo.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object obj)
+ {
+ if (this == obj)
+ {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass() )
+ {
+ return false;
+ }
+ final ListenerHandler<T> other = (ListenerHandler<T>) obj;
+ return listenerInfo.equals(other.listenerInfo);
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/WhiteboardListenerHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/WhiteboardListenerHandler.java
new file mode 100644
index 0000000..b17210a
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/WhiteboardListenerHandler.java
@@ -0,0 +1,86 @@
+/*
+ * 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.handler;
+
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.runtime.ListenerInfo;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceObjects;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Listener handler for listeners registered through the http whiteboard.
+ */
+public final class WhiteboardListenerHandler<T> extends ListenerHandler<T>
+{
+ private final BundleContext bundleContext;
+
+ public WhiteboardListenerHandler(final long contextServiceId,
+ final ExtServletContext context,
+ final ListenerInfo<T> listenerInfo,
+ final BundleContext bundleContext)
+ {
+ super(contextServiceId, context, listenerInfo);
+ this.bundleContext = bundleContext;
+ }
+
+ @Override
+ public int init()
+ {
+ if ( this.useCount > 0 )
+ {
+ this.useCount++;
+ return -1;
+ }
+
+ final ServiceReference<T> serviceReference = getListenerInfo().getServiceReference();
+ final ServiceObjects<T> so = this.bundleContext.getServiceObjects(serviceReference);
+
+ this.setListener((so == null ? null : so.getService()));
+
+ final int reason = super.init();
+ if ( reason != -1 )
+ {
+ if ( so != null )
+ {
+ so.ungetService(this.getListener());
+ }
+ this.setListener(null);
+ }
+ return reason;
+ }
+
+ @Override
+ public boolean destroy()
+ {
+ final T s = this.getListener();
+ if ( s != null )
+ {
+ if ( super.destroy() )
+ {
+
+ final ServiceObjects<T> so = this.bundleContext.getServiceObjects(getListenerInfo().getServiceReference());
+ if (so != null)
+ {
+ so.ungetService(s);
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java
index dfcf458..cd47a05 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ErrorPageRegistry.java
@@ -253,6 +253,12 @@
}
}
+ public synchronized void cleanup()
+ {
+ this.errorMapping.clear();
+ this.status = Collections.emptyList();
+ }
+
private void addErrorHandling(final ServletHandler handler, final ErrorRegistrationStatus status, final long code, final String exception)
{
final String key = (exception != null ? exception : String.valueOf(code));
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/EventListenerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/EventListenerRegistry.java
index c921a58..392ba71 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/EventListenerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/EventListenerRegistry.java
@@ -16,13 +16,10 @@
*/
package org.apache.felix.http.base.internal.registry;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.ArrayList;
+import java.util.List;
import javax.annotation.Nonnull;
-import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
@@ -37,19 +34,16 @@
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
+import org.apache.felix.http.base.internal.handler.ListenerHandler;
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.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.runtime.dto.ListenerDTOBuilder;
-import org.apache.felix.http.base.internal.util.CollectionUtils;
-import org.apache.felix.http.base.internal.whiteboard.ContextHandler;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.http.runtime.dto.DTOConstants;
+import org.osgi.service.http.runtime.dto.FailedListenerDTO;
import org.osgi.service.http.runtime.dto.ListenerDTO;
import org.osgi.service.http.runtime.dto.ServletContextDTO;
@@ -65,87 +59,65 @@
ServletRequestAttributeListener
{
/** Servlet context listeners. */
- private final Map<ServiceReference<ServletContextListener>, ServletContextListener> contextListeners = new ConcurrentSkipListMap<ServiceReference<ServletContextListener>, ServletContextListener>();
+ private final ListenerMap<ServletContextListener> contextListeners = new ListenerMap<ServletContextListener>();
/** Servlet context attribute listeners. */
- private final Map<ServiceReference<ServletContextAttributeListener>, ServletContextAttributeListener> contextAttributeListeners = new ConcurrentSkipListMap<ServiceReference<ServletContextAttributeListener>, ServletContextAttributeListener>();
+ private final ListenerMap<ServletContextAttributeListener> contextAttributeListeners = new ListenerMap<ServletContextAttributeListener>();
/** Session attribute listeners. */
- private final Map<ServiceReference<HttpSessionAttributeListener>, HttpSessionAttributeListener> sessionAttributeListeners = new ConcurrentSkipListMap<ServiceReference<HttpSessionAttributeListener>, HttpSessionAttributeListener>();
+ private final ListenerMap<HttpSessionAttributeListener> sessionAttributeListeners = new ListenerMap<HttpSessionAttributeListener>();
/** Session listeners. */
- private final Map<ServiceReference<HttpSessionListener>, HttpSessionListener> sessionListeners = new ConcurrentSkipListMap<ServiceReference<HttpSessionListener>, HttpSessionListener>();
+ private final ListenerMap<HttpSessionListener> sessionListeners = new ListenerMap<HttpSessionListener>();
/** Session id listeners. */
- private final Map<ServiceReference<HttpSessionIdListener>, HttpSessionIdListener> sessionIdListeners = new ConcurrentSkipListMap<ServiceReference<HttpSessionIdListener>, HttpSessionIdListener>();
+ private final ListenerMap<HttpSessionIdListener> sessionIdListeners = new ListenerMap<HttpSessionIdListener>();
/** Request listeners. */
- private final Map<ServiceReference<ServletRequestListener>, ServletRequestListener> requestListeners = new ConcurrentSkipListMap<ServiceReference<ServletRequestListener>, ServletRequestListener>();
+ private final ListenerMap<ServletRequestListener> requestListeners = new ListenerMap<ServletRequestListener>();
/** Request attribute listeners. */
- private final Map<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener> requestAttributeListeners = new ConcurrentSkipListMap<ServiceReference<ServletRequestAttributeListener>, ServletRequestAttributeListener>();
+ private final ListenerMap<ServletRequestAttributeListener> requestAttributeListeners = new ListenerMap<ServletRequestAttributeListener>();
- private final Bundle bundle;
-
- public EventListenerRegistry(final Bundle bundle)
+ public synchronized void cleanup()
{
- this.bundle = bundle;
+ this.contextListeners.cleanup();
+ this.contextAttributeListeners.cleanup();
+ this.sessionAttributeListeners.cleanup();
+ this.sessionListeners.cleanup();
+ this.sessionIdListeners.cleanup();
+ this.requestListeners.cleanup();
+ this.requestAttributeListeners.cleanup();
}
- public int initialized(@Nonnull final ServletContextListenerInfo listenerInfo, @Nonnull final ContextHandler contextHandler)
+ /**
+ * Add servlet context listener
+ *
+ * @param handler
+ */
+ public void addServletContextListener(@Nonnull final ListenerHandler<ServletContextListener> handler)
{
- final ServletContextListener listener = listenerInfo.getService(bundle);
- if (listener != null)
- {
- final ServletContext context = contextHandler
- .getServletContext(listenerInfo.getServiceReference()
- .getBundle());
- if ( context != null )
- {
- this.contextListeners.put(listenerInfo.getServiceReference(), listener);
-
- listener.contextInitialized(new ServletContextEvent(context));
- return -1;
- }
- return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
- }
- return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ this.contextListeners.add(handler);
}
- public void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo, @Nonnull final ContextHandler contextHandler)
+ /**
+ * Remove servlet context listener
+ *
+ * @param info
+ */
+ public void removeServletContextListener(@Nonnull final ServletContextListenerInfo info)
{
- final ServiceReference<ServletContextListener> listenerRef = listenerInfo
- .getServiceReference();
- final ServletContextListener listener = this.contextListeners
- .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);
- }
+ this.contextListeners.remove(info);
}
/**
* Add servlet context attribute listener
*
- * @param info
+ * @param handler
*/
- public int addListener(@Nonnull final ServletContextAttributeListenerInfo info)
+ public void addServletContextAttributeListener(@Nonnull final ListenerHandler<ServletContextAttributeListener> handler)
{
- final ServletContextAttributeListener service = info.getService(bundle);
- if (service != null)
- {
- this.contextAttributeListeners.put(info.getServiceReference(),
- service);
- return -1;
- }
- return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ this.contextAttributeListeners.add(handler);
}
/**
@@ -153,31 +125,19 @@
*
* @param info
*/
- public void removeListener(@Nonnull final ServletContextAttributeListenerInfo info)
+ public void removeServletContextAttributeListener(@Nonnull final ServletContextAttributeListenerInfo info)
{
- final ServletContextAttributeListener service = this.contextAttributeListeners
- .remove(info.getServiceReference());
- if (service != null)
- {
- info.ungetService(bundle, service);
- }
+ this.contextAttributeListeners.remove(info);
}
/**
* Add session attribute listener
*
- * @param info
+ * @param handler
*/
- public int addListener(@Nonnull final HttpSessionAttributeListenerInfo info)
+ public void addSessionAttributeListener(@Nonnull final ListenerHandler<HttpSessionAttributeListener> handler)
{
- final HttpSessionAttributeListener service = info.getService(bundle);
- if (service != null)
- {
- this.sessionAttributeListeners.put(info.getServiceReference(),
- service);
- return -1;
- }
- return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ this.sessionAttributeListeners.add(handler);
}
/**
@@ -185,30 +145,19 @@
*
* @param info
*/
- public void removeListener(@Nonnull final HttpSessionAttributeListenerInfo info)
+ public void removeSessionAttributeListener(@Nonnull final HttpSessionAttributeListenerInfo info)
{
- final HttpSessionAttributeListener service = this.sessionAttributeListeners
- .remove(info.getServiceReference());
- if (service != null)
- {
- info.ungetService(bundle, service);
- }
+ this.sessionAttributeListeners.remove(info);
}
/**
* Add session listener
*
- * @param info
+ * @param handler
*/
- public int addListener(@Nonnull final HttpSessionListenerInfo info)
+ public void addSessionListener(@Nonnull final ListenerHandler<HttpSessionListener> handler)
{
- final HttpSessionListener service = info.getService(bundle);
- if (service != null)
- {
- this.sessionListeners.put(info.getServiceReference(), service);
- return -1;
- }
- return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ this.sessionListeners.add(handler);
}
/**
@@ -216,31 +165,19 @@
*
* @param info
*/
- public void removeListener(@Nonnull final HttpSessionListenerInfo info)
+ public void removeSessionListener(@Nonnull final HttpSessionListenerInfo info)
{
- final HttpSessionListener service = this.sessionListeners.remove(info
- .getServiceReference());
- if (service != null)
- {
- info.ungetService(bundle, service);
- }
+ this.sessionListeners.remove(info);
}
/**
* Add session id listener
*
- * @param info
+ * @param handler
*/
- public int addListener(@Nonnull final HttpSessionIdListenerInfo info)
+ public void addSessionIdListener(@Nonnull final ListenerHandler<HttpSessionIdListener> handler)
{
- final HttpSessionIdListener service = info.getService(bundle);
- if (service != null)
- {
- this.sessionIdListeners.put(info.getServiceReference(),
- service);
- return -1;
- }
- return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ this.sessionIdListeners.add(handler);
}
/**
@@ -248,29 +185,19 @@
*
* @param info
*/
- public void removeListener(@Nonnull final HttpSessionIdListenerInfo info)
+ public void removeSessionIdListener(@Nonnull final HttpSessionIdListenerInfo info)
{
- final HttpSessionIdListener service = this.sessionIdListeners.remove(info.getServiceReference());
- if (service != null)
- {
- info.ungetService(bundle, service);
- }
+ this.sessionIdListeners.remove(info);
}
/**
* Add request listener
*
- * @param info
+ * @param handler
*/
- public int addListener(@Nonnull final ServletRequestListenerInfo info)
+ public void addServletRequestListener(@Nonnull final ListenerHandler<ServletRequestListener> handler)
{
- final ServletRequestListener service = info.getService(bundle);
- if (service != null)
- {
- this.requestListeners.put(info.getServiceReference(), service);
- return -1;
- }
- return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ this.requestListeners.add(handler);
}
/**
@@ -278,31 +205,19 @@
*
* @param info
*/
- public void removeListener(@Nonnull final ServletRequestListenerInfo info)
+ public void removeServletRequestListener(@Nonnull final ServletRequestListenerInfo info)
{
- final ServletRequestListener service = this.requestListeners
- .remove(info.getServiceReference());
- if (service != null)
- {
- info.ungetService(bundle, service);
- }
+ this.requestListeners.remove(info);
}
/**
* Add request attribute listener
*
- * @param info
+ * @param handler
*/
- public int addListener(@Nonnull final ServletRequestAttributeListenerInfo info)
+ public void addServletRequestAttributeListener(@Nonnull final ListenerHandler<ServletRequestAttributeListener> handler)
{
- final ServletRequestAttributeListener service = info.getService(bundle);
- if (service != null)
- {
- this.requestAttributeListeners.put(info.getServiceReference(),
- service);
- return -1;
- }
- return DTOConstants.FAILURE_REASON_SERVICE_NOT_GETTABLE;
+ this.requestAttributeListeners.add(handler);
}
/**
@@ -310,21 +225,42 @@
*
* @param info
*/
- public void removeListener(@Nonnull final ServletRequestAttributeListenerInfo info)
+ public void removeServletRequestAttributeListener(@Nonnull final ServletRequestAttributeListenerInfo info)
{
- final ServletRequestAttributeListener service = this.requestAttributeListeners
- .remove(info.getServiceReference());
- if (service != null)
+ this.requestAttributeListeners.remove(info);
+ }
+
+ public ListenerHandler<ServletContextListener> getServletContextListener(@Nonnull final ListenerInfo<ServletContextListener> info)
+ {
+ return this.contextListeners.getListenerHandler(info);
+ }
+
+ public void contextInitialized() {
+ for (final ListenerHandler<ServletContextListener> l : contextListeners.getActiveHandlers())
{
- info.ungetService(bundle, service);
+ final ServletContextListener listener = l.getListener();
+ if ( listener != null )
+ {
+ listener.contextInitialized(new ServletContextEvent(l.getContext()));
+ }
+ }
+ }
+
+ public void contextDestroyed() {
+ for (final ListenerHandler<ServletContextListener> l : contextListeners.getActiveHandlers())
+ {
+ final ServletContextListener listener = l.getListener();
+ if ( listener != null )
+ {
+ listener.contextDestroyed(new ServletContextEvent(l.getContext()));
+ }
}
}
@Override
public void attributeReplaced(final HttpSessionBindingEvent event)
{
- for (final HttpSessionAttributeListener l : sessionAttributeListeners
- .values())
+ for (final HttpSessionAttributeListener l : sessionAttributeListeners.getActiveListeners())
{
l.attributeReplaced(event);
}
@@ -333,8 +269,7 @@
@Override
public void attributeRemoved(final HttpSessionBindingEvent event)
{
- for (final HttpSessionAttributeListener l : sessionAttributeListeners
- .values())
+ for (final HttpSessionAttributeListener l : sessionAttributeListeners.getActiveListeners())
{
l.attributeReplaced(event);
}
@@ -343,8 +278,7 @@
@Override
public void attributeAdded(final HttpSessionBindingEvent event)
{
- for (final HttpSessionAttributeListener l : sessionAttributeListeners
- .values())
+ for (final HttpSessionAttributeListener l : sessionAttributeListeners.getActiveListeners())
{
l.attributeReplaced(event);
}
@@ -353,8 +287,7 @@
@Override
public void attributeReplaced(final ServletContextAttributeEvent event)
{
- for (final ServletContextAttributeListener l : contextAttributeListeners
- .values())
+ for (final ServletContextAttributeListener l : contextAttributeListeners.getActiveListeners())
{
l.attributeReplaced(event);
}
@@ -363,8 +296,7 @@
@Override
public void attributeRemoved(final ServletContextAttributeEvent event)
{
- for (final ServletContextAttributeListener l : contextAttributeListeners
- .values())
+ for (final ServletContextAttributeListener l : contextAttributeListeners.getActiveListeners())
{
l.attributeReplaced(event);
}
@@ -373,8 +305,7 @@
@Override
public void attributeAdded(final ServletContextAttributeEvent event)
{
- for (final ServletContextAttributeListener l : contextAttributeListeners
- .values())
+ for (final ServletContextAttributeListener l : contextAttributeListeners.getActiveListeners())
{
l.attributeReplaced(event);
}
@@ -383,7 +314,7 @@
@Override
public void sessionCreated(final HttpSessionEvent se)
{
- for (final HttpSessionListener l : sessionListeners.values())
+ for (final HttpSessionListener l : sessionListeners.getActiveListeners())
{
l.sessionCreated(se);
}
@@ -392,7 +323,7 @@
@Override
public void sessionDestroyed(final HttpSessionEvent se)
{
- for (final HttpSessionListener l : sessionListeners.values())
+ for (final HttpSessionListener l : sessionListeners.getActiveListeners())
{
l.sessionDestroyed(se);
}
@@ -401,7 +332,7 @@
@Override
public void requestDestroyed(final ServletRequestEvent sre)
{
- for (final ServletRequestListener l : requestListeners.values())
+ for (final ServletRequestListener l : requestListeners.getActiveListeners())
{
l.requestDestroyed(sre);
}
@@ -410,7 +341,7 @@
@Override
public void requestInitialized(final ServletRequestEvent sre)
{
- for (final ServletRequestListener l : requestListeners.values())
+ for (final ServletRequestListener l : requestListeners.getActiveListeners())
{
l.requestInitialized(sre);
}
@@ -419,8 +350,7 @@
@Override
public void attributeAdded(final ServletRequestAttributeEvent srae)
{
- for (final ServletRequestAttributeListener l : requestAttributeListeners
- .values())
+ for (final ServletRequestAttributeListener l : requestAttributeListeners.getActiveListeners())
{
l.attributeAdded(srae);
}
@@ -429,8 +359,7 @@
@Override
public void attributeRemoved(final ServletRequestAttributeEvent srae)
{
- for (final ServletRequestAttributeListener l : requestAttributeListeners
- .values())
+ for (final ServletRequestAttributeListener l : requestAttributeListeners.getActiveListeners())
{
l.attributeRemoved(srae);
}
@@ -439,8 +368,7 @@
@Override
public void attributeReplaced(final ServletRequestAttributeEvent srae)
{
- for (final ServletRequestAttributeListener l : requestAttributeListeners
- .values())
+ for (final ServletRequestAttributeListener l : requestAttributeListeners.getActiveListeners())
{
l.attributeReplaced(srae);
}
@@ -451,29 +379,26 @@
*/
@Override
public void sessionIdChanged(@Nonnull final HttpSessionEvent event, @Nonnull final String oldSessionId) {
- for (final HttpSessionIdListener l : sessionIdListeners.values())
+ for (final HttpSessionIdListener l : sessionIdListeners.getActiveListeners())
{
l.sessionIdChanged(event, oldSessionId);
}
}
- @SuppressWarnings("unchecked")
- public void getRuntime(final ServletContextDTO dto)
+ public void getRuntimeInfo(final ServletContextDTO dto, final List<FailedListenerDTO> failedListenerDTOs)
{
- final Collection<ServiceReference<?>> col = CollectionUtils.<ServiceReference<?>>sortedUnion(
- Collections.<ServiceReference<?>>reverseOrder(),
- contextListeners.keySet(),
- contextAttributeListeners.keySet(),
- sessionAttributeListeners.keySet(),
- sessionIdListeners.keySet(),
- sessionListeners.keySet(),
- requestAttributeListeners.keySet(),
- requestListeners.keySet());
- dto.listenerDTOs = new ListenerDTO[col.size()];
- int index = 0;
- for(final ServiceReference<?> ref : col)
+ final List<ListenerDTO> listenerDTOs = new ArrayList<ListenerDTO>();
+ this.contextListeners.getRuntimeInfo(listenerDTOs, failedListenerDTOs);
+ this.contextAttributeListeners.getRuntimeInfo(listenerDTOs, failedListenerDTOs);
+ this.requestListeners.getRuntimeInfo(listenerDTOs, failedListenerDTOs);
+ this.requestAttributeListeners.getRuntimeInfo(listenerDTOs, failedListenerDTOs);
+ this.sessionListeners.getRuntimeInfo(listenerDTOs, failedListenerDTOs);
+ this.sessionAttributeListeners.getRuntimeInfo(listenerDTOs, failedListenerDTOs);
+ this.sessionIdListeners.getRuntimeInfo(listenerDTOs, failedListenerDTOs);
+
+ if ( listenerDTOs.size() > 0 )
{
- dto.listenerDTOs[index++] = ListenerDTOBuilder.build(ref, dto.serviceId);
+ dto.listenerDTOs = listenerDTOs.toArray(new ListenerDTO[listenerDTOs.size()]);
}
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
index 81acbae6..ad0695e 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/FilterRegistry.java
@@ -159,6 +159,11 @@
}
}
+ public synchronized void cleanup()
+ {
+ this.filters = Collections.emptyList();
+ }
+
/**
* Get all filters handling the request.
* Filters are applied to the url and/or the servlet
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java
index f1c01d5..a3fd974 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/HandlerRegistry.java
@@ -74,18 +74,6 @@
}
/**
- * Add a context registration.
- * @param info The servlet context helper info
- */
- public void add(@Nonnull ServletContextHelperInfo info)
- {
- synchronized ( this )
- {
- this.add(new PerContextHandlerRegistry(info));
- }
- }
-
- /**
* Remove a context registration.
* @param info The servlet context helper info
*/
@@ -112,7 +100,7 @@
/**
* Add a new context registration.
*/
- private void add(@Nonnull PerContextHandlerRegistry registry)
+ public void add(@Nonnull PerContextHandlerRegistry registry)
{
synchronized ( this )
{
@@ -277,7 +265,7 @@
return null;
}
- public boolean getRuntime(final ServletContextDTO dto,
+ public boolean getRuntimeInfo(final ServletContextDTO dto,
final FailedDTOHolder failedDTOHolder)
{
final PerContextHandlerRegistry reg = this.getRegistry(dto.serviceId);
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ListenerMap.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ListenerMap.java
new file mode 100644
index 0000000..fdbc4f0
--- /dev/null
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ListenerMap.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.felix.http.base.internal.registry;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import javax.annotation.Nonnull;
+
+import org.apache.felix.http.base.internal.handler.ListenerHandler;
+import org.apache.felix.http.base.internal.runtime.ListenerInfo;
+import org.apache.felix.http.base.internal.runtime.dto.ListenerDTOBuilder;
+import org.osgi.service.http.runtime.dto.FailedListenerDTO;
+import org.osgi.service.http.runtime.dto.ListenerDTO;
+
+public class ListenerMap<T> {
+
+ private volatile List<ListenerRegistrationStatus<T>> handlers = Collections.emptyList();
+
+ /**
+ * The status object keeps track of the registration status of a listener
+ * The status objects are sorted by result first, followed by ranking. The active
+ * listeners ( result == -1) are first, followed by the inactive ones. This sorting
+ * allows to only traverse over the active ones and also avoids any sorting
+ * as the listeners are processed in the correct order already.
+ */
+ private static final class ListenerRegistrationStatus<T> implements Comparable<ListenerRegistrationStatus<T>>
+ {
+ private final int result;
+ private final ListenerHandler<T> handler;
+
+ public ListenerRegistrationStatus(@Nonnull final ListenerHandler<T> handler, final int result)
+ {
+ this.handler = handler;
+ this.result = result;
+ }
+
+ public int getResult()
+ {
+ return this.result;
+ }
+
+ public @Nonnull ListenerHandler<T> getHandler()
+ {
+ return this.handler;
+ }
+
+ @Override
+ public int compareTo(final ListenerRegistrationStatus<T> o)
+ {
+ int result = this.result - o.result;
+ if ( result == 0 )
+ {
+ result = this.handler.compareTo(o.handler);
+ }
+ return result;
+ }
+ }
+
+ public void cleanup()
+ {
+ this.handlers = Collections.emptyList();
+ }
+
+ public synchronized void add(final ListenerHandler<T> handler)
+ {
+ final int reason = handler.init();
+ final ListenerRegistrationStatus<T> status = new ListenerRegistrationStatus<T>(handler, reason);
+
+ final List<ListenerRegistrationStatus<T>> newList = new ArrayList<ListenerMap.ListenerRegistrationStatus<T>>(this.handlers);
+ newList.add(status);
+ Collections.sort(newList);
+ this.handlers = newList;
+ }
+
+ public synchronized void remove(final ListenerInfo<T> info)
+ {
+ final List<ListenerRegistrationStatus<T>> newList = new ArrayList<ListenerMap.ListenerRegistrationStatus<T>>(this.handlers);
+ final Iterator<ListenerRegistrationStatus<T>> i = newList.iterator();
+ while ( i.hasNext() )
+ {
+ final ListenerRegistrationStatus<T> status = i.next();
+ if ( status.getHandler().getListenerInfo().equals(info) )
+ {
+ if ( status.getResult() == - 1 )
+ {
+ status.getHandler().destroy();
+ }
+ i.remove();
+ this.handlers = newList;
+ break;
+ }
+ }
+ }
+
+ public ListenerHandler<T> getListenerHandler(@Nonnull final ListenerInfo<T> info)
+ {
+ final List<ListenerRegistrationStatus<T>> list = this.handlers;
+ for(final ListenerRegistrationStatus<T> status : list)
+ {
+ if ( status.getHandler().getListenerInfo().equals(info) )
+ {
+ return status.getHandler();
+ }
+ }
+ return null;
+ }
+
+ public Iterable<ListenerHandler<T>> getActiveHandlers()
+ {
+ final List<ListenerRegistrationStatus<T>> list = this.handlers;
+ final Iterator<ListenerRegistrationStatus<T>> iter = list.iterator();
+ final Iterator<ListenerHandler<T>> newIter = new Iterator<ListenerHandler<T>>()
+ {
+
+ private ListenerHandler<T> next;
+
+ {
+ peek();
+ }
+
+ private void peek()
+ {
+ next = null;
+ if ( iter.hasNext() )
+ {
+ final ListenerRegistrationStatus<T> status = iter.next();
+ if ( status.getResult() == -1 )
+ {
+ next = status.getHandler();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return this.next != null;
+ }
+
+ @Override
+ public ListenerHandler<T> next()
+ {
+ if ( this.next == null )
+ {
+ throw new NoSuchElementException();
+ }
+ final ListenerHandler<T> result = this.next;
+ peek();
+ return result;
+ }
+
+ @Override
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ return new Iterable<ListenerHandler<T>>()
+ {
+
+ @Override
+ public Iterator<ListenerHandler<T>> iterator()
+ {
+ return newIter;
+ }
+ };
+ }
+
+ public Iterable<T> getActiveListeners()
+ {
+ final Iterator<ListenerHandler<T>> iter = this.getActiveHandlers().iterator();
+ final Iterator<T> newIter = new Iterator<T>()
+ {
+
+ private T next;
+
+ {
+ peek();
+ }
+
+ private void peek()
+ {
+ next = null;
+ while ( next == null && iter.hasNext() )
+ {
+ final ListenerHandler<T> handler = iter.next();
+ next = handler.getListener();
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return this.next != null;
+ }
+
+ @Override
+ public T next()
+ {
+ if ( this.next == null )
+ {
+ throw new NoSuchElementException();
+ }
+ final T result = this.next;
+ peek();
+ return result;
+ }
+
+ @Override
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ return new Iterable<T>()
+ {
+
+ @Override
+ public Iterator<T> iterator()
+ {
+ return newIter;
+ }
+ };
+ }
+
+ public void getRuntimeInfo(final List<ListenerDTO> listenerDTOs, final List<FailedListenerDTO> failedListenerDTOs)
+ {
+ final int length = listenerDTOs.size();
+ final int failedLength = failedListenerDTOs.size();
+ final List<ListenerRegistrationStatus<T>> list = this.handlers;
+ for (final ListenerRegistrationStatus<T> status : list)
+ {
+ // search for DTO with same service id and failureCode
+ if ( status.getResult() == -1 )
+ {
+ int index = 0;
+ boolean found = false;
+ final Iterator<ListenerDTO> i = listenerDTOs.iterator();
+ while ( !found && index < length )
+ {
+ final ListenerDTO dto = i.next();
+ if ( dto.serviceId == status.getHandler().getListenerInfo().getServiceId() )
+ {
+ found = true;
+ final String[] types = new String[dto.types.length + 1];
+ System.arraycopy(dto.types, 0, types, 0, dto.types.length);
+ types[dto.types.length] = status.getHandler().getListenerInfo().getListenerName();
+ dto.types = types;
+ }
+ index++;
+ }
+ if ( !found )
+ {
+ listenerDTOs.add(ListenerDTOBuilder.build(status.getHandler(), status.getResult()));
+ }
+ }
+ else
+ {
+ int index = 0;
+ boolean found = false;
+ final Iterator<FailedListenerDTO> i = failedListenerDTOs.iterator();
+ while ( !found && index < failedLength )
+ {
+ final FailedListenerDTO dto = i.next();
+ if ( dto.serviceId == status.getHandler().getListenerInfo().getServiceId()
+ && dto.failureReason == status.getResult() )
+ {
+ found = true;
+ final String[] types = new String[dto.types.length + 1];
+ System.arraycopy(dto.types, 0, types, 0, dto.types.length);
+ types[dto.types.length] = status.getHandler().getListenerInfo().getListenerName();
+ dto.types = types;
+ }
+ index++;
+ }
+ if ( !found )
+ {
+ failedListenerDTOs.add((FailedListenerDTO)ListenerDTOBuilder.build(status.getHandler(), status.getResult()));
+ }
+ }
+ }
+ }
+}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java
index 32e4453..51e942e 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PerContextHandlerRegistry.java
@@ -55,6 +55,8 @@
private final ErrorPageRegistry errorPageRegistry = new ErrorPageRegistry();
+ private final EventListenerRegistry eventListenerRegistry = new EventListenerRegistry();
+
/**
* Default http service registry
*/
@@ -92,7 +94,10 @@
public void removeAll()
{
- // TODO - implement
+ this.errorPageRegistry.cleanup();
+ this.eventListenerRegistry.cleanup();
+ this.filterRegistry.cleanup();
+ this.servletRegistry.cleanup();
}
@Override
@@ -181,6 +186,11 @@
return this.errorPageRegistry.get(exception, code);
}
+ public EventListenerRegistry getEventListenerRegistry()
+ {
+ return this.eventListenerRegistry;
+ }
+
/**
* Create all DTOs for servlets, filters, resources and error pages
* @param dto The servlet context DTO
@@ -197,5 +207,8 @@
// collect servlets and resources
this.servletRegistry.getRuntimeInfo(dto, failedDTOHolder.failedServletDTOs, failedDTOHolder.failedResourceDTOs);
+
+ // collect listeners
+ this.eventListenerRegistry.getRuntimeInfo(dto, failedDTOHolder.failedListenerDTOs);
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
index 373a494..ced9b7c 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
@@ -293,6 +293,14 @@
}
}
+ public synchronized void cleanup()
+ {
+ this.activeServletMappings.clear();
+ this.inactiveServletMappings.clear();
+ this.servletsByName.clear();
+ this.statusMapping.clear();
+ }
+
private void addToInactiveList(final String pattern, final ServletHandler handler, final ServletRegistrationStatus status)
{
List<ServletHandler> inactiveList = this.inactiveServletMappings.get(pattern);
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionAttributeListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionAttributeListenerInfo.java
index f751140..da52c22 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionAttributeListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionAttributeListenerInfo.java
@@ -29,6 +29,6 @@
{
public HttpSessionAttributeListenerInfo(final ServiceReference<HttpSessionAttributeListener> ref)
{
- super(ref);
+ super(ref, HttpSessionAttributeListener.class.getName());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionIdListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionIdListenerInfo.java
index b0eedc0..0d8296d 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionIdListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionIdListenerInfo.java
@@ -29,6 +29,6 @@
{
public HttpSessionIdListenerInfo(final ServiceReference<HttpSessionIdListener> ref)
{
- super(ref);
+ super(ref, HttpSessionIdListener.class.getName());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionListenerInfo.java
index aa2f1de..3473993 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/HttpSessionListenerInfo.java
@@ -29,6 +29,6 @@
{
public HttpSessionListenerInfo(final ServiceReference<HttpSessionListener> ref)
{
- super(ref);
+ super(ref, HttpSessionListener.class.getName());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ListenerInfo.java
index 15eda56..b758bd0 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ListenerInfo.java
@@ -18,9 +18,6 @@
*/
package org.apache.felix.http.base.internal.runtime;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceObjects;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
@@ -32,10 +29,13 @@
private final String enabled;
- public ListenerInfo(final ServiceReference<T> ref)
+ private final String listenerName;
+
+ public ListenerInfo(final ServiceReference<T> ref, final String listenerName)
{
super(ref);
this.enabled = this.getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER);
+ this.listenerName = listenerName;
}
@Override
@@ -44,37 +44,8 @@
return super.isValid() && "true".equalsIgnoreCase(this.enabled);
}
-
- public T getService(final Bundle bundle)
+ public String getListenerName()
{
- if (this.getServiceReference() != null)
- {
- final BundleContext bctx = bundle.getBundleContext();
- if ( bctx != null )
- {
- final ServiceObjects<T> so = bctx.getServiceObjects(this.getServiceReference());
- if (so != null)
- {
- return so.getService();
- }
- }
- }
- return null;
- }
-
- public void ungetService(final Bundle bundle, final T service)
- {
- if (this.getServiceReference() != null)
- {
- final BundleContext bctx = bundle.getBundleContext();
- if ( bctx != null )
- {
- final ServiceObjects<T> so = bctx.getServiceObjects(this.getServiceReference());
- if (so != null)
- {
- so.ungetService(service);
- }
- }
- }
+ return this.listenerName;
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextAttributeListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextAttributeListenerInfo.java
index c41901c..3384557 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextAttributeListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextAttributeListenerInfo.java
@@ -30,6 +30,6 @@
public ServletContextAttributeListenerInfo(final ServiceReference<ServletContextAttributeListener> ref)
{
- super(ref);
+ super(ref, ServletContextAttributeListener.class.getName());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextListenerInfo.java
index 1a11329..7300276 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextListenerInfo.java
@@ -29,6 +29,6 @@
{
public ServletContextListenerInfo(final ServiceReference<ServletContextListener> ref)
{
- super(ref);
+ super(ref, ServletContextListener.class.getName());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestAttributeListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestAttributeListenerInfo.java
index 0898b39..7eb86d4 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestAttributeListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestAttributeListenerInfo.java
@@ -29,6 +29,6 @@
{
public ServletRequestAttributeListenerInfo(final ServiceReference<ServletRequestAttributeListener> ref)
{
- super(ref);
+ super(ref, ServletRequestAttributeListener.class.getName());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestListenerInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestListenerInfo.java
index c8eb3ca..f1e41cd 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestListenerInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletRequestListenerInfo.java
@@ -29,6 +29,6 @@
{
public ServletRequestListenerInfo(final ServiceReference<ServletRequestListener> ref)
{
- super(ref);
+ super(ref, ServletRequestListener.class.getName());
}
}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
index 4df84a6..a6972c3 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/dto/ListenerDTOBuilder.java
@@ -29,9 +29,8 @@
import javax.servlet.http.HttpSessionIdListener;
import javax.servlet.http.HttpSessionListener;
+import org.apache.felix.http.base.internal.handler.ListenerHandler;
import org.apache.felix.http.base.internal.runtime.ListenerInfo;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
import org.osgi.service.http.runtime.dto.FailedListenerDTO;
import org.osgi.service.http.runtime.dto.ListenerDTO;
@@ -54,6 +53,7 @@
final ListenerDTO dto = (reason == -1 ? new ListenerDTO() : new FailedListenerDTO());
dto.serviceId = info.getServiceId();
+ dto.types = new String[] {info.getListenerName()};
if ( reason != -1 )
{
@@ -63,22 +63,10 @@
return dto;
}
- public static ListenerDTO build(final ServiceReference<?> listenerRef, final long servletContextId)
+ public static ListenerDTO build(final ListenerHandler<?> handler, final int reason)
{
- final ListenerDTO listenerDTO = new ListenerDTO();
- listenerDTO.serviceId = (Long) listenerRef.getProperty(Constants.SERVICE_ID);
- listenerDTO.servletContextId = servletContextId;
-
- final String[] objectClass = (String[])listenerRef.getProperty(Constants.OBJECTCLASS);
- final Set<String> names = new HashSet<String>();
- for(final String name : objectClass)
- {
- if ( ALLOWED_INTERFACES.contains(name) )
- {
- names.add(name);
- }
- }
- listenerDTO.types = names.toArray(new String[names.size()]);
- return listenerDTO;
+ final ListenerDTO dto = build(handler.getListenerInfo(), reason);
+ dto.servletContextId = handler.getContextServiceId();
+ return dto;
}
}
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 bbfeb05..6a9f76c 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
@@ -49,7 +49,7 @@
@Override
public RuntimeDTO getRuntimeDTO()
{
- final RuntimeDTOBuilder runtimeDTOBuilder = new RuntimeDTOBuilder(contextManager.getRuntime(registry),
+ final RuntimeDTOBuilder runtimeDTOBuilder = new RuntimeDTOBuilder(contextManager.getRuntimeInfo(registry),
this.serviceReference);
return runtimeDTOBuilder.build();
}
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 16cbcc6..9a57ca2 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
@@ -19,11 +19,12 @@
import java.util.HashMap;
import java.util.Map;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
import org.apache.felix.http.base.internal.context.ExtServletContext;
-import org.apache.felix.http.base.internal.registry.EventListenerRegistry;
+import org.apache.felix.http.base.internal.registry.PerContextHandlerRegistry;
import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -35,8 +36,10 @@
/** The info object for the context. */
private final ServletContextHelperInfo info;
+ private final ServletContext webContext;
+
/** The shared part of the servlet context. */
- private final ServletContext sharedContext;
+ private volatile ServletContext sharedContext;
/** The http bundle. */
private final Bundle bundle;
@@ -44,20 +47,15 @@
/** A map of all created servlet contexts. Each bundle gets it's own instance. */
private final Map<Long, ContextHolder> perBundleContextMap = new HashMap<Long, ContextHolder>();
- private final EventListenerRegistry eventListener;
+ private volatile PerContextHandlerRegistry registry;
public ContextHandler(final ServletContextHelperInfo info,
final ServletContext webContext,
final Bundle bundle)
{
+ this.webContext = webContext;
this.info = info;
- this.eventListener = new EventListenerRegistry(bundle);
this.bundle = bundle;
- this.sharedContext = new SharedServletContextImpl(webContext,
- info.getName(),
- info.getPath(),
- info.getInitParameters(),
- eventListener);
}
public ServletContextHelperInfo getContextInfo()
@@ -75,17 +73,37 @@
* Activate this context.
* @return {@code true} if it succeeded.
*/
- public boolean activate()
+ public boolean activate(final WhiteboardHttpService httpService)
{
- return getServletContext(bundle) != null;
+ this.registry = new PerContextHandlerRegistry(this.info);
+ this.sharedContext = new SharedServletContextImpl(webContext,
+ info.getName(),
+ info.getPath(),
+ info.getInitParameters(),
+ this.registry.getEventListenerRegistry());
+ final boolean activate = getServletContext(bundle) != null;
+ if ( !activate )
+ {
+ this.registry = null;
+ this.sharedContext = null;
+ }
+ else
+ {
+ httpService.registerContext(this.registry);
+ }
+ return activate;
}
/**
* Deactivate this context.
*/
- public void deactivate()
+ public void deactivate(final WhiteboardHttpService httpService)
{
+ httpService.unregisterContext(this);
+ this.registry = null;
+ this.sharedContext = null;
this.ungetServletContext(bundle);
+ // TODO we should clear all state
}
public ServletContext getSharedContext()
@@ -93,8 +111,12 @@
return sharedContext;
}
- public ExtServletContext getServletContext(@Nonnull final Bundle bundle)
+ public ExtServletContext getServletContext(@CheckForNull final Bundle bundle)
{
+ if ( bundle == null )
+ {
+ return null;
+ }
final Long key = bundle.getBundleId();
synchronized ( this.perBundleContextMap )
{
@@ -113,7 +135,7 @@
holder.servletContext = new PerBundleServletContextImpl(bundle,
this.sharedContext,
service,
- this.eventListener);
+ this.registry.getEventListenerRegistry());
this.perBundleContextMap.put(key, holder);
}
}
@@ -161,7 +183,8 @@
public ServletContextHelper servletContextHelper;
}
- public EventListenerRegistry getListenerRegistry() {
- return this.eventListener;
+ public PerContextHandlerRegistry getRegistry()
+ {
+ return this.registry;
}
}
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 5ce2948..b6149e8 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
@@ -17,17 +17,34 @@
package org.apache.felix.http.base.internal.whiteboard;
import javax.annotation.Nonnull;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionIdListener;
+import javax.servlet.http.HttpSessionListener;
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.HttpServiceServletHandler;
+import org.apache.felix.http.base.internal.handler.ListenerHandler;
import org.apache.felix.http.base.internal.handler.ServletHandler;
import org.apache.felix.http.base.internal.handler.WhiteboardFilterHandler;
+import org.apache.felix.http.base.internal.handler.WhiteboardListenerHandler;
import org.apache.felix.http.base.internal.handler.WhiteboardServletHandler;
import org.apache.felix.http.base.internal.registry.HandlerRegistry;
+import org.apache.felix.http.base.internal.registry.PerContextHandlerRegistry;
import org.apache.felix.http.base.internal.runtime.FilterInfo;
+import org.apache.felix.http.base.internal.runtime.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.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.service.ResourceServlet;
import org.osgi.framework.BundleContext;
import org.osgi.service.http.runtime.dto.DTOConstants;
@@ -114,6 +131,167 @@
contextHandler.ungetServletContext(filterInfo.getServiceReference().getBundle());
}
+ public int registerListener(@Nonnull final ContextHandler contextHandler,
+ @Nonnull final ServletContextListenerInfo info)
+ {
+ final ExtServletContext context = contextHandler.getServletContext(info.getServiceReference().getBundle());
+ if ( context == null )
+ {
+ return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
+ }
+ final ListenerHandler<ServletContextListener> handler = new WhiteboardListenerHandler<ServletContextListener>(
+ contextHandler.getContextInfo().getServiceId(),
+ context,
+ info,
+ bundleContext);
+ contextHandler.getRegistry().getEventListenerRegistry().addServletContextListener(handler);
+ return -1;
+ }
+
+ public void unregisterListener(@Nonnull final ContextHandler contextHandler, @Nonnull final ServletContextListenerInfo info)
+ {
+ contextHandler.getRegistry().getEventListenerRegistry().removeServletContextListener(info);
+ contextHandler.ungetServletContext(info.getServiceReference().getBundle());
+ }
+
+ public int registerListener(@Nonnull final ContextHandler contextHandler,
+ @Nonnull final ServletContextAttributeListenerInfo info)
+ {
+ final ExtServletContext context = contextHandler.getServletContext(info.getServiceReference().getBundle());
+ if ( context == null )
+ {
+ return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
+ }
+ final ListenerHandler<ServletContextAttributeListener> handler = new WhiteboardListenerHandler<ServletContextAttributeListener>(
+ contextHandler.getContextInfo().getServiceId(),
+ context,
+ info,
+ bundleContext);
+ contextHandler.getRegistry().getEventListenerRegistry().addServletContextAttributeListener(handler);
+ return -1;
+ }
+
+ public void unregisterListener(@Nonnull final ContextHandler contextHandler, @Nonnull final ServletContextAttributeListenerInfo info)
+ {
+ contextHandler.getRegistry().getEventListenerRegistry().removeServletContextAttributeListener(info);
+ contextHandler.ungetServletContext(info.getServiceReference().getBundle());
+ }
+
+ public int registerListener(@Nonnull final ContextHandler contextHandler,
+ @Nonnull final HttpSessionListenerInfo info)
+ {
+ final ExtServletContext context = contextHandler.getServletContext(info.getServiceReference().getBundle());
+ if ( context == null )
+ {
+ return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
+ }
+ final ListenerHandler<HttpSessionListener> handler = new WhiteboardListenerHandler<HttpSessionListener>(
+ contextHandler.getContextInfo().getServiceId(),
+ context,
+ info,
+ bundleContext);
+ contextHandler.getRegistry().getEventListenerRegistry().addSessionListener(handler);
+ return -1;
+ }
+
+ public void unregisterListener(@Nonnull final ContextHandler contextHandler, @Nonnull final HttpSessionListenerInfo info)
+ {
+ contextHandler.getRegistry().getEventListenerRegistry().removeSessionListener(info);
+ contextHandler.ungetServletContext(info.getServiceReference().getBundle());
+ }
+
+ public int registerListener(@Nonnull final ContextHandler contextHandler,
+ @Nonnull final HttpSessionIdListenerInfo info)
+ {
+ final ExtServletContext context = contextHandler.getServletContext(info.getServiceReference().getBundle());
+ if ( context == null )
+ {
+ return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
+ }
+ final ListenerHandler<HttpSessionIdListener> handler = new WhiteboardListenerHandler<HttpSessionIdListener>(
+ contextHandler.getContextInfo().getServiceId(),
+ context,
+ info,
+ bundleContext);
+ contextHandler.getRegistry().getEventListenerRegistry().addSessionIdListener(handler);
+ return -1;
+ }
+
+ public void unregisterListener(@Nonnull final ContextHandler contextHandler, @Nonnull final HttpSessionIdListenerInfo info)
+ {
+ contextHandler.getRegistry().getEventListenerRegistry().removeSessionIdListener(info);
+ contextHandler.ungetServletContext(info.getServiceReference().getBundle());
+ }
+
+ public int registerListener(@Nonnull final ContextHandler contextHandler,
+ @Nonnull final HttpSessionAttributeListenerInfo info)
+ {
+ final ExtServletContext context = contextHandler.getServletContext(info.getServiceReference().getBundle());
+ if ( context == null )
+ {
+ return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
+ }
+ final ListenerHandler<HttpSessionAttributeListener> handler = new WhiteboardListenerHandler<HttpSessionAttributeListener>(
+ contextHandler.getContextInfo().getServiceId(),
+ context,
+ info,
+ bundleContext);
+ contextHandler.getRegistry().getEventListenerRegistry().addSessionAttributeListener(handler);
+ return -1;
+ }
+
+ public void unregisterListener(@Nonnull final ContextHandler contextHandler, @Nonnull final HttpSessionAttributeListenerInfo info)
+ {
+ contextHandler.getRegistry().getEventListenerRegistry().removeSessionAttributeListener(info);
+ contextHandler.ungetServletContext(info.getServiceReference().getBundle());
+ }
+
+ public int registerListener(@Nonnull final ContextHandler contextHandler,
+ @Nonnull final ServletRequestListenerInfo info)
+ {
+ final ExtServletContext context = contextHandler.getServletContext(info.getServiceReference().getBundle());
+ if ( context == null )
+ {
+ return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
+ }
+ final ListenerHandler<ServletRequestListener> handler = new WhiteboardListenerHandler<ServletRequestListener>(
+ contextHandler.getContextInfo().getServiceId(),
+ context,
+ info,
+ bundleContext);
+ contextHandler.getRegistry().getEventListenerRegistry().addServletRequestListener(handler);
+ return -1;
+ }
+
+ public void unregisterListener(@Nonnull final ContextHandler contextHandler, @Nonnull final ServletRequestListenerInfo info)
+ {
+ contextHandler.getRegistry().getEventListenerRegistry().removeServletRequestListener(info);
+ contextHandler.ungetServletContext(info.getServiceReference().getBundle());
+ }
+
+ public int registerListener(@Nonnull final ContextHandler contextHandler,
+ @Nonnull final ServletRequestAttributeListenerInfo info)
+ {
+ final ExtServletContext context = contextHandler.getServletContext(info.getServiceReference().getBundle());
+ if ( context == null )
+ {
+ return DTOConstants.FAILURE_REASON_SERVLET_CONTEXT_FAILURE;
+ }
+ final ListenerHandler<ServletRequestAttributeListener> handler = new WhiteboardListenerHandler<ServletRequestAttributeListener>(
+ contextHandler.getContextInfo().getServiceId(),
+ context,
+ info,
+ bundleContext);
+ contextHandler.getRegistry().getEventListenerRegistry().addServletRequestAttributeListener(handler);
+ return -1;
+ }
+
+ public void unregisterListener(@Nonnull final ContextHandler contextHandler, @Nonnull final ServletRequestAttributeListenerInfo info)
+ {
+ contextHandler.getRegistry().getEventListenerRegistry().removeServletRequestAttributeListener(info);
+ contextHandler.ungetServletContext(info.getServiceReference().getBundle());
+ }
+
/**
* Register a resource.
* @param contextInfo The servlet context helper info
@@ -151,9 +329,9 @@
contextHandler.ungetServletContext(servletInfo.getServiceReference().getBundle());
}
- public void registerContext(@Nonnull final ContextHandler contextHandler)
+ public void registerContext(@Nonnull final PerContextHandlerRegistry registry)
{
- this.handlerRegistry.add(contextHandler.getContextInfo());
+ this.handlerRegistry.add(registry);
}
public void unregisterContext(@Nonnull final ContextHandler contextHandler)
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 89b729d..dcf17c7 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
@@ -31,10 +31,10 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
import javax.annotation.Nonnull;
import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
@@ -42,6 +42,7 @@
import org.apache.felix.http.base.internal.console.HttpServicePlugin;
import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.handler.HttpSessionWrapper;
+import org.apache.felix.http.base.internal.handler.ListenerHandler;
import org.apache.felix.http.base.internal.logger.SystemLogger;
import org.apache.felix.http.base.internal.registry.HandlerRegistry;
import org.apache.felix.http.base.internal.runtime.AbstractInfo;
@@ -270,7 +271,7 @@
final ContextHandler handler = this.getContextHandler(contextId);
if ( handler != null )
{
- handler.getListenerRegistry().sessionIdChanged(event, oldSessionId);
+ handler.getRegistry().getEventListenerRegistry().sessionIdChanged(event, oldSessionId);
}
}
}
@@ -283,49 +284,37 @@
*/
private boolean activate(final ContextHandler handler)
{
- if ( !handler.activate() )
+ if ( !handler.activate(this.httpService) )
{
return false;
}
- this.httpService.registerContext(handler);
-
- // use a map to sort the listeners
- 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());
- }
if ( entry.getValue().size() == 1 )
{
this.failureStateHandler.remove(entry.getKey());
}
+ if ( entry.getKey() instanceof ServletContextListenerInfo )
+ {
+ // servlet context listeners will be registered directly
+ this.registerWhiteboardService(handler, entry.getKey());
+ }
+ else
+ {
+ // registration of other services will be delayed
+ services.add(entry.getKey());
+ }
}
}
- // context listeners first
- for(final ServletContextListenerInfo info : listeners.values())
- {
- final int reason = handler.getListenerRegistry().initialized(info, handler);
- if ( reason != -1 )
- {
- final String type = info.getClass().getSimpleName().substring(0,info.getClass().getSimpleName().length() - 4);
- SystemLogger.debug("Ignoring " + type + " service " + info.getServiceReference());
- this.failureStateHandler.add(info, handler.getContextInfo().getServiceId(), reason);
- }
- }
- // now register services
+ // notify context listeners first
+ handler.getRegistry().getEventListenerRegistry().contextInitialized();
+
+ // register services
for(final WhiteboardServiceInfo<?> info : services)
{
this.registerWhiteboardService(handler, info);
@@ -341,8 +330,8 @@
*/
private void deactivate(final ContextHandler handler)
{
- // context listeners last but sorted
- final Map<ServiceReference<ServletContextListener>, ServletContextListenerInfo> listeners = new TreeMap<ServiceReference<ServletContextListener>, ServletContextListenerInfo>();
+ // services except context listeners first
+ final List<WhiteboardServiceInfo<?>> listeners = new ArrayList<WhiteboardServiceInfo<?>>();
final Iterator<Map.Entry<WhiteboardServiceInfo<?>, List<ContextHandler>>> i = this.servicesMap.entrySet().iterator();
while ( i.hasNext() )
{
@@ -353,8 +342,7 @@
{
if ( entry.getKey() instanceof ServletContextListenerInfo )
{
- final ServletContextListenerInfo info = (ServletContextListenerInfo)entry.getKey();
- listeners.put(info.getServiceReference(), info);
+ listeners.add(entry.getKey());
}
else
{
@@ -369,14 +357,14 @@
}
}
}
- for(final ServletContextListenerInfo info : listeners.values())
+ // context listeners last
+ handler.getRegistry().getEventListenerRegistry().contextDestroyed();
+ for(final WhiteboardServiceInfo<?> info : listeners)
{
- handler.getListenerRegistry().destroyed(info, handler);
+ this.unregisterWhiteboardService(handler, info);
}
- this.httpService.unregisterContext(handler);
-
- handler.deactivate();
+ handler.deactivate(this.httpService);
}
/**
@@ -584,20 +572,19 @@
{
for(final ContextHandler h : handlerList)
{
+ this.registerWhiteboardService(h, info);
if ( info instanceof ServletContextListenerInfo )
{
- final int reason = h.getListenerRegistry().initialized((ServletContextListenerInfo)info, h);
- if ( reason != -1 )
+ final ListenerHandler<ServletContextListener> handler = h.getRegistry().getEventListenerRegistry().getServletContextListener((ServletContextListenerInfo)info);
+ if ( handler != null )
{
- final String type = info.getClass().getSimpleName().substring(0,info.getClass().getSimpleName().length() - 4);
- SystemLogger.debug("Ignoring " + type + " service " + info.getServiceReference());
- this.failureStateHandler.add(info, h.getContextInfo().getServiceId(), reason);
+ final ServletContextListener listener = handler.getListener();
+ if ( listener != null )
+ {
+ listener.contextInitialized(new ServletContextEvent(handler.getContext()));
+ }
}
}
- else
- {
- this.registerWhiteboardService(h, info);
- }
}
}
}
@@ -631,14 +618,19 @@
{
if ( !failureStateHandler.remove(info, h.getContextInfo().getServiceId()) )
{
- if ( !(info instanceof ServletContextListenerInfo ) )
+ if ( info instanceof ServletContextListenerInfo )
{
- this.unregisterWhiteboardService(h, info);
+ final ListenerHandler<ServletContextListener> handler = h.getRegistry().getEventListenerRegistry().getServletContextListener((ServletContextListenerInfo)info);
+ if ( handler != null )
+ {
+ final ServletContextListener listener = handler.getListener();
+ if ( listener != null )
+ {
+ listener.contextDestroyed(new ServletContextEvent(handler.getContext()));
+ }
+ }
}
- else
- {
- h.getListenerRegistry().destroyed((ServletContextListenerInfo)info, h);
- }
+ this.unregisterWhiteboardService(h, info);
}
}
}
@@ -670,29 +662,33 @@
failureCode = this.httpService.registerResource(handler, (ResourceInfo)info);
}
+ else if ( info instanceof ServletContextListenerInfo )
+ {
+ failureCode = this.httpService.registerListener(handler, (ServletContextListenerInfo) info);
+ }
else if ( info instanceof ServletContextAttributeListenerInfo )
{
- failureCode = handler.getListenerRegistry().addListener((ServletContextAttributeListenerInfo) info);
+ failureCode = this.httpService.registerListener(handler, (ServletContextAttributeListenerInfo) info);
}
else if ( info instanceof HttpSessionListenerInfo )
{
- failureCode = handler.getListenerRegistry().addListener((HttpSessionListenerInfo) info);
+ failureCode = this.httpService.registerListener(handler, (HttpSessionListenerInfo) info);
}
else if ( info instanceof HttpSessionAttributeListenerInfo )
{
- failureCode = handler.getListenerRegistry().addListener((HttpSessionAttributeListenerInfo) info);
+ failureCode = this.httpService.registerListener(handler, (HttpSessionAttributeListenerInfo) info);
}
else if ( info instanceof HttpSessionIdListenerInfo )
{
- failureCode = handler.getListenerRegistry().addListener((HttpSessionIdListenerInfo) info);
+ failureCode = this.httpService.registerListener(handler, (HttpSessionIdListenerInfo) info);
}
else if ( info instanceof ServletRequestListenerInfo )
{
- failureCode = handler.getListenerRegistry().addListener((ServletRequestListenerInfo) info);
+ failureCode = this.httpService.registerListener(handler, (ServletRequestListenerInfo) info);
}
else if ( info instanceof ServletRequestAttributeListenerInfo )
{
- failureCode = handler.getListenerRegistry().addListener((ServletRequestAttributeListenerInfo) info);
+ failureCode = this.httpService.registerListener(handler, (ServletRequestAttributeListenerInfo) info);
}
else
{
@@ -735,29 +731,33 @@
this.httpService.unregisterResource(handler, (ResourceInfo)info);
}
+ else if ( info instanceof ServletContextListenerInfo )
+ {
+ this.httpService.unregisterListener(handler, (ServletContextListenerInfo) info);
+ }
else if ( info instanceof ServletContextAttributeListenerInfo )
{
- handler.getListenerRegistry().removeListener((ServletContextAttributeListenerInfo) info);
+ this.httpService.unregisterListener(handler, (ServletContextAttributeListenerInfo) info);
}
else if ( info instanceof HttpSessionListenerInfo )
{
- handler.getListenerRegistry().removeListener((HttpSessionListenerInfo) info);
+ this.httpService.unregisterListener(handler, (HttpSessionListenerInfo) info);
}
else if ( info instanceof HttpSessionAttributeListenerInfo )
{
- handler.getListenerRegistry().removeListener((HttpSessionAttributeListenerInfo) info);
+ this.httpService.unregisterListener(handler, (HttpSessionAttributeListenerInfo) info);
}
else if ( info instanceof HttpSessionIdListenerInfo )
{
- handler.getListenerRegistry().removeListener((HttpSessionIdListenerInfo) info);
+ this.httpService.unregisterListener(handler, (HttpSessionIdListenerInfo) info);
}
else if ( info instanceof ServletRequestListenerInfo )
{
- handler.getListenerRegistry().removeListener((ServletRequestListenerInfo) info);
+ this.httpService.unregisterListener(handler, (ServletRequestListenerInfo) info);
}
else if ( info instanceof ServletRequestAttributeListenerInfo )
{
- handler.getListenerRegistry().removeListener((ServletRequestAttributeListenerInfo) info);
+ this.httpService.unregisterListener(handler, (ServletRequestAttributeListenerInfo) info);
}
}
catch (final Exception e)
@@ -807,7 +807,7 @@
return null;
}
- public RegistryRuntime getRuntime(final HandlerRegistry registry)
+ public RegistryRuntime getRuntimeInfo(final HandlerRegistry registry)
{
final FailedDTOHolder failedDTOHolder = new FailedDTOHolder();
@@ -817,7 +817,7 @@
HttpServiceFactory.HTTP_SERVICE_CONTEXT_SERVICE_ID,
HttpServiceFactory.HTTP_SERVICE_CONTEXT_NAME, "/", null);
final ServletContextDTO dto = ServletContextDTOBuilder.build(info, webContext, -1);
- if ( registry.getRuntime(dto, failedDTOHolder) )
+ if ( registry.getRuntimeInfo(dto, failedDTOHolder) )
{
contextDTOs.add(dto);
}
@@ -841,9 +841,8 @@
{
final ServletContextDTO scDTO = ServletContextDTOBuilder.build(handler.getContextInfo(), handler.getSharedContext(), -1);
- if ( registry.getRuntime(scDTO, failedDTOHolder) )
+ if ( registry.getRuntimeInfo(scDTO, failedDTOHolder) )
{
- handler.getListenerRegistry().getRuntime(scDTO);
contextDTOs.add(scDTO);
}
}
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/HandlerRegistryTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/HandlerRegistryTest.java
index a9530ed..08834df 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/registry/HandlerRegistryTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/registry/HandlerRegistryTest.java
@@ -46,14 +46,14 @@
final ServletContextDTO dto = new ServletContextDTO();
dto.serviceId = HttpServiceFactory.HTTP_SERVICE_CONTEXT_SERVICE_ID;
- assertFalse(registry.getRuntime(dto, holder));
+ assertFalse(registry.getRuntimeInfo(dto, holder));
registry.init();
- assertTrue(registry.getRuntime(dto, holder));
+ assertTrue(registry.getRuntimeInfo(dto, holder));
registry.shutdown();
- assertFalse(registry.getRuntime(dto, holder));
+ assertFalse(registry.getRuntimeInfo(dto, holder));
}
@Test
@@ -67,28 +67,28 @@
dto.servletDTOs = new ServletDTO[0];
Servlet servlet = Mockito.mock(Servlet.class);
- final ServletInfo info = new ServletInfo("foo", "/foo", 0, Collections.EMPTY_MAP);
+ final ServletInfo info = new ServletInfo("foo", "/foo", 0, Collections.<String, String> emptyMap());
ServletHandler handler = new HttpServiceServletHandler(null, info, servlet);
- assertTrue(registry.getRuntime(dto, holder));
+ assertTrue(registry.getRuntimeInfo(dto, holder));
assertEquals("Precondition", 0, dto.servletDTOs.length);
registry.addServlet(handler);
Mockito.verify(servlet, Mockito.times(1)).init(Mockito.any(ServletConfig.class));
- assertTrue(registry.getRuntime(dto, holder));
+ assertTrue(registry.getRuntimeInfo(dto, holder));
assertEquals(1, dto.servletDTOs.length);
assertEquals(info.getServiceId(), dto.servletDTOs[0].serviceId);
- final ServletInfo info2 = new ServletInfo("bar", "/bar", 0, Collections.EMPTY_MAP);
+ final ServletInfo info2 = new ServletInfo("bar", "/bar", 0, Collections.<String, String> emptyMap());
ServletHandler handler2 = new HttpServiceServletHandler(null, info2, Mockito.mock(Servlet.class));
registry.addServlet(handler2);
- assertTrue(registry.getRuntime(dto, holder));
+ assertTrue(registry.getRuntimeInfo(dto, holder));
assertEquals(2, dto.servletDTOs.length);
- final ServletInfo info3 = new ServletInfo("zar", "/foo", 0, Collections.EMPTY_MAP);
+ final ServletInfo info3 = new ServletInfo("zar", "/foo", 0, Collections.<String, String> emptyMap());
ServletHandler handler3 = new HttpServiceServletHandler(null,info3, Mockito.mock(Servlet.class));
registry.addServlet(handler3);
- assertTrue(registry.getRuntime(dto, holder));
+ assertTrue(registry.getRuntimeInfo(dto, holder));
assertEquals(2, dto.servletDTOs.length);
assertEquals(1, holder.failedServletDTOs.size());