FELIX-857 Statically register EventAdminServlet in the OSGi Manager
and register servlet as EventHandler during activation without the
need for Declarative Services

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@728649 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java
index 2a3a975..fff014f 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java
@@ -19,7 +19,14 @@
 
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Date;
+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 javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -30,21 +37,18 @@
 import org.apache.felix.webconsole.internal.servlet.OsgiManager;
 import org.json.JSONException;
 import org.json.JSONWriter;
-import org.osgi.framework.*;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.event.*;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
 
 
-/**
- * @scr.component metatype="false"
- * @scr.service interface="javax.servlet.Servlet"
- * @scr.service interface="org.osgi.service.event.EventHandler"
- * @scr.property name="event.topics" value="*"
- * @scr.property name="felix.webconsole.label" valueRef="LABEL"
- */
-public class EventAdminServlet
-extends BaseWebConsolePlugin
-implements EventHandler
+public class EventAdminServlet extends BaseWebConsolePlugin implements EventHandler
 {
 
     public static final String LABEL = "events";
@@ -59,69 +63,89 @@
     /** Custom event renderers hashed by topic. */
     private final Map eventRenderers = new HashMap();
 
+    // the service registration of this plugin
+    private ServiceRegistration eventReceiver;
+
+
     public EventAdminServlet()
     {
-        eventRenderers.put(ServiceEvent.class.getName().replace('.', '/') + "/", new ServiceEventInfoProvider());
-        eventRenderers.put(BundleEvent.class.getName().replace('.', '/') + "/", new BundleEventInfoProvider());
+        eventRenderers.put( ServiceEvent.class.getName().replace( '.', '/' ) + "/", new ServiceEventInfoProvider() );
+        eventRenderers.put( BundleEvent.class.getName().replace( '.', '/' ) + "/", new BundleEventInfoProvider() );
     }
 
+
     public String getLabel()
     {
         return LABEL;
     }
 
 
-    /**
-     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#getTitle()
-     */
     public String getTitle()
     {
         return TITLE;
     }
 
+
     /**
      * Activate this component.
      */
-    protected void activate(ComponentContext context)
+    public void activate( BundleContext context )
     {
-        this.activate(context.getBundleContext());
+        super.activate( context );
+
         this.events.clear();
+
+        // register as EventHandler service to receive events
+        Dictionary props = new Hashtable();
+        props.put( Constants.SERVICE_DESCRIPTION, "EventAdmin plugin for the Felix Web Console" );
+        props.put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" );
+        props.put( "event.topics", "*" );
+        eventReceiver = context.registerService( EventHandler.class.getName(), this, props );
     }
 
+
     /**
      * Deactivate this component.
      */
-    protected void deactivate(ComponentContext context)
+    public void deactivate()
     {
-        this.deactivate();
+        if ( eventReceiver != null )
+        {
+            eventReceiver.unregister();
+            eventReceiver = null;
+        }
+
         this.events.clear();
+
+        super.deactivate();
     }
 
+
     /**
      * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
      */
-    public void handleEvent(Event event)
+    public void handleEvent( Event event )
     {
         // we add everything which is not a log event
-        if ( !event.getTopic().startsWith("org/osgi/service/log") )
+        if ( !event.getTopic().startsWith( "org/osgi/service/log" ) )
         {
             synchronized ( this.events )
             {
-                this.events.add(new EventInfo(event));
+                this.events.add( new EventInfo( event ) );
                 if ( events.size() > this.maxSize )
                 {
-                    events.remove(0);
+                    events.remove( 0 );
                 }
             }
         }
     }
 
-    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
-    throws ServletException, IOException
+
+    protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
     {
-        final String action = getParameter(req, "action");
+        final String action = getParameter( req, "action" );
         // for now we only have the clear action
-        if ( "clear".equals(action) )
+        if ( "clear".equals( action ) )
         {
             synchronized ( this.events )
             {
@@ -129,38 +153,42 @@
             }
         }
         // we always send back the json data
-        resp.setContentType("application/json");
-        resp.setCharacterEncoding("utf-8");
+        resp.setContentType( "application/json" );
+        resp.setCharacterEncoding( "utf-8" );
 
-        renderJSON(resp.getWriter());
+        renderJSON( resp.getWriter() );
     }
 
-    private void renderJSON(final PrintWriter pw)
-    throws IOException
+
+    private void renderJSON( final PrintWriter pw ) throws IOException
     {
         List copiedEvents;
         synchronized ( this.events )
         {
-            copiedEvents = new ArrayList(this.events);
+            copiedEvents = new ArrayList( this.events );
         }
         // create status line
-        final EventAdmin admin = (EventAdmin) this.getService(EventAdmin.class.getName());
+        final EventAdmin admin = ( EventAdmin ) this.getService( EventAdmin.class.getName() );
         StringBuffer statusLine = new StringBuffer();
-        if ( admin == null ) {
-            statusLine.append("Event Admin is not installed/running.");
-        } else {
-            statusLine.append("Event Admin is running.");
+        if ( admin == null )
+        {
+            statusLine.append( "Event Admin is not installed/running." );
         }
-        statusLine.append(" ");
-        statusLine.append(copiedEvents.size());
-        statusLine.append(" Events received");
-        if ( !copiedEvents.isEmpty() ) {
-            statusLine.append(" since ");
+        else
+        {
+            statusLine.append( "Event Admin is running." );
+        }
+        statusLine.append( " " );
+        statusLine.append( copiedEvents.size() );
+        statusLine.append( " Events received" );
+        if ( !copiedEvents.isEmpty() )
+        {
+            statusLine.append( " since " );
             Date d = new Date();
-            d.setTime(((EventInfo)copiedEvents.get(0)).received);
-            statusLine.append(d);
+            d.setTime( ( ( EventInfo ) copiedEvents.get( 0 ) ).received );
+            statusLine.append( d );
         }
-        statusLine.append(".");
+        statusLine.append( "." );
 
         JSONWriter jw = new JSONWriter( pw );
         try
@@ -168,16 +196,16 @@
             jw.object();
 
             jw.key( "status" );
-            jw.value ( statusLine );
+            jw.value( statusLine );
 
             jw.key( "data" );
 
             jw.array();
 
             // display list in reverse order
-            for(int index = copiedEvents.size() -1; index >= 0; index--)
+            for ( int index = copiedEvents.size() - 1; index >= 0; index-- )
             {
-                eventJson( jw, (EventInfo)copiedEvents.get(index), index );
+                eventJson( jw, ( EventInfo ) copiedEvents.get( index ), index );
             }
 
             jw.endArray();
@@ -192,8 +220,9 @@
 
     }
 
-    protected void doGet( HttpServletRequest request, HttpServletResponse response )
-    throws ServletException, IOException
+
+    protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+        IOException
     {
 
         final String info = request.getPathInfo();
@@ -203,7 +232,7 @@
             response.setCharacterEncoding( "UTF-8" );
 
             PrintWriter pw = response.getWriter();
-            this.renderJSON(pw);
+            this.renderJSON( pw );
 
             // nothing more to do
             return;
@@ -212,14 +241,16 @@
         super.doGet( request, response );
     }
 
-    protected void renderContent( HttpServletRequest request, HttpServletResponse response )
-    throws ServletException, IOException
+
+    protected void renderContent( HttpServletRequest request, HttpServletResponse response ) throws ServletException,
+        IOException
     {
         final PrintWriter pw = response.getWriter();
 
         String appRoot = ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT );
         pw.println( "<script src='" + appRoot + "/res/ui/jquery-1.2.6.min.js' language='JavaScript'></script>" );
-        pw.println( "<script src='" + appRoot + "/res/ui/jquery.tablesorter-2.0.3.min.js' language='JavaScript'></script>" );
+        pw.println( "<script src='" + appRoot
+            + "/res/ui/jquery.tablesorter-2.0.3.min.js' language='JavaScript'></script>" );
         pw.println( "<script src='" + appRoot + "/res/ui/events.js' language='JavaScript'></script>" );
 
         Util.startScript( pw );
@@ -227,8 +258,8 @@
         Util.endScript( pw );
     }
 
-    private void eventJson( JSONWriter jw, EventInfo info, int index)
-    throws JSONException
+
+    private void eventJson( JSONWriter jw, EventInfo info, int index ) throws JSONException
     {
         final Event e = info.event;
 
@@ -237,20 +268,20 @@
         String infoText = null;
         while ( infoText == null && iter.hasNext() )
         {
-            final Map.Entry entry = (Map.Entry) iter.next();
-            if ( e.getTopic().startsWith(entry.getKey().toString()) )
+            final Map.Entry entry = ( Map.Entry ) iter.next();
+            if ( e.getTopic().startsWith( entry.getKey().toString() ) )
             {
-                infoText = ((EventInfoProvider)entry.getValue()).getInfo(e);
+                infoText = ( ( EventInfoProvider ) entry.getValue() ).getInfo( e );
             }
         }
 
         jw.object();
         jw.key( "id" );
-        jw.value( String.valueOf(index) );
-        jw.key( "received");
+        jw.value( String.valueOf( index ) );
+        jw.key( "received" );
         jw.value( info.received );
         jw.key( "topic" );
-        jw.value( e.getTopic());
+        jw.value( e.getTopic() );
         if ( infoText != null )
         {
             jw.key( "info" );
@@ -261,10 +292,10 @@
         final String[] names = e.getPropertyNames();
         if ( names != null && names.length > 0 )
         {
-            for(int i=0;i<names.length;i++)
+            for ( int i = 0; i < names.length; i++ )
             {
-                jw.key(names[i]);
-                jw.value(e.getProperty(names[i]).toString());
+                jw.key( names[i] );
+                jw.value( e.getProperty( names[i] ).toString() );
             }
         }
         jw.endObject();
@@ -276,9 +307,10 @@
     {
 
         public final Event event;
-        public final long  received;
+        public final long received;
 
-        public EventInfo(final Event e)
+
+        public EventInfo( final Event e )
         {
             this.event = e;
             this.received = System.currentTimeMillis();
@@ -287,7 +319,7 @@
 
     private static interface EventInfoProvider
     {
-        String getInfo(Event event);
+        String getInfo( Event event );
     }
 
     private static final class ServiceEventInfoProvider implements EventInfoProvider
@@ -296,26 +328,26 @@
         /**
          * @see org.apache.felix.webconsole.internal.misc.EventAdminServlet.EventInfoProvider#getInfo(org.osgi.service.event.Event)
          */
-        public String getInfo(Event event)
+        public String getInfo( Event event )
         {
-            final ServiceEvent serviceEvent = (ServiceEvent) event.getProperty(EventConstants.EVENT);
+            final ServiceEvent serviceEvent = ( ServiceEvent ) event.getProperty( EventConstants.EVENT );
             if ( serviceEvent == null )
             {
                 return null;
             }
-            final StringBuffer buffer = new StringBuffer("Service ");
-            buffer.append(serviceEvent.getServiceReference().getProperty(Constants.SERVICE_ID));
-            buffer.append(' ');
-            switch (serviceEvent.getType())
+            final StringBuffer buffer = new StringBuffer( "Service " );
+            buffer.append( serviceEvent.getServiceReference().getProperty( Constants.SERVICE_ID ) );
+            buffer.append( ' ' );
+            switch ( serviceEvent.getType() )
             {
                 case ServiceEvent.REGISTERED:
-                    buffer.append("registered");
+                    buffer.append( "registered" );
                     break;
                 case ServiceEvent.MODIFIED:
-                    buffer.append("modified");
+                    buffer.append( "modified" );
                     break;
                 case ServiceEvent.UNREGISTERING:
-                    buffer.append("unregistering");
+                    buffer.append( "unregistering" );
                     break;
                 default:
                     return null; // IGNOREE
@@ -331,44 +363,44 @@
         /**
          * @see org.apache.felix.webconsole.internal.misc.EventAdminServlet.EventInfoProvider#getInfo(org.osgi.service.event.Event)
          */
-        public String getInfo(Event event)
+        public String getInfo( Event event )
         {
-            final BundleEvent bundleEvent = (BundleEvent) event.getProperty(EventConstants.EVENT);
+            final BundleEvent bundleEvent = ( BundleEvent ) event.getProperty( EventConstants.EVENT );
             if ( bundleEvent == null )
             {
                 return null;
             }
-            final StringBuffer buffer = new StringBuffer("Bundle ");
-            buffer.append(bundleEvent.getBundle().getSymbolicName());
-            buffer.append(' ');
-            switch (bundleEvent.getType())
+            final StringBuffer buffer = new StringBuffer( "Bundle " );
+            buffer.append( bundleEvent.getBundle().getSymbolicName() );
+            buffer.append( ' ' );
+            switch ( bundleEvent.getType() )
             {
                 case BundleEvent.INSTALLED:
-                    buffer.append("installed");
+                    buffer.append( "installed" );
                     break;
                 case BundleEvent.RESOLVED:
-                    buffer.append("resolved");
+                    buffer.append( "resolved" );
                     break;
                 case BundleEvent.STARTED:
-                    buffer.append("started");
+                    buffer.append( "started" );
                     break;
                 case BundleEvent.STARTING:
-                    buffer.append("starting");
+                    buffer.append( "starting" );
                     break;
                 case BundleEvent.STOPPED:
-                    buffer.append("stopped");
+                    buffer.append( "stopped" );
                     break;
                 case BundleEvent.STOPPING:
-                    buffer.append("stopping");
+                    buffer.append( "stopping" );
                     break;
                 case BundleEvent.UNINSTALLED:
-                    buffer.append("uninstalled");
+                    buffer.append( "uninstalled" );
                     break;
                 case BundleEvent.UNRESOLVED:
-                    buffer.append("unresolved");
+                    buffer.append( "unresolved" );
                     break;
                 case BundleEvent.UPDATED:
-                    buffer.append("updated");
+                    buffer.append( "updated" );
                     break;
                 default:
                     return null; // IGNOREE
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index 4330ba5..1289c79 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -119,6 +119,7 @@
             "org.apache.felix.webconsole.internal.core.BundlesServlet",
             "org.apache.felix.webconsole.internal.core.InstallAction",
             "org.apache.felix.webconsole.internal.core.SetStartLevelAction",
+            "org.apache.felix.webconsole.internal.misc.EventAdminServlet",
             "org.apache.felix.webconsole.internal.misc.LicenseServlet",
             "org.apache.felix.webconsole.internal.misc.ConfigurationRender",
             "org.apache.felix.webconsole.internal.misc.ShellServlet",