org.apache.felix.webconsole.internal.misc.EventAdminServlet.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.felix.webconsole.internal.misc.EventAdminServlet.java

Source

/*
 * 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.webconsole.internal.misc;

import java.io.IOException;
import java.io.PrintWriter;
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;
import javax.servlet.http.HttpServletResponse;

import org.apache.felix.webconsole.internal.BaseWebConsolePluginServlet;
import org.apache.felix.webconsole.internal.Util;
import org.apache.felix.webconsole.internal.servlet.OsgiManager;
import org.json.JSONException;
import org.json.JSONWriter;
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;

public class EventAdminServlet extends BaseWebConsolePluginServlet implements EventHandler {

    private static final class BundleEventInfoProvider implements EventInfoProvider {

        /**
         * @see org.apache.felix.webconsole.internal.misc.EventAdminServlet.EventInfoProvider#getInfo(org.osgi.service.event.Event)
         */
        public String getInfo(Event event) {
            final BundleEvent currBundleEvent = (BundleEvent) event.getProperty(EventConstants.EVENT);
            if (currBundleEvent == null) {
                return null;
            }
            final StringBuffer tmpBuffer = new StringBuffer("Bundle ");
            tmpBuffer.append(currBundleEvent.getBundle().getSymbolicName());
            tmpBuffer.append(' ');
            switch (currBundleEvent.getType()) {
            case BundleEvent.RESOLVED:
                tmpBuffer.append("resolved");
                break;
            case BundleEvent.STARTED:
                tmpBuffer.append("started");
                break;
            case BundleEvent.STARTING:
                tmpBuffer.append("starting");
                break;
            case BundleEvent.STOPPED:
                tmpBuffer.append("stopped");
                break;
            case BundleEvent.STOPPING:
                tmpBuffer.append("stopping");
                break;
            case BundleEvent.INSTALLED:
                tmpBuffer.append("installed");
                break;
            case BundleEvent.UNRESOLVED:
                tmpBuffer.append("unresolved");
                break;
            case BundleEvent.UPDATED:
                tmpBuffer.append("updated");
                break;
            case BundleEvent.UNINSTALLED:
                tmpBuffer.append("uninstalled");
                break;

            default:
                return null; // IGNOREE
            }

            return tmpBuffer.toString();
        }
    }

    private static final class EventInfo {

        public final Event myEvent;
        public final long myReceivedTime;

        public EventInfo(final Event event) {
            this.myReceivedTime = System.currentTimeMillis();
            this.myEvent = event;
        }
    }

    private static interface EventInfoProvider {
        String getInfo(Event event);
    }

    private static final class ServiceEventInfoProvider implements EventInfoProvider {

        /**
         * @see org.apache.felix.webconsole.internal.misc.EventAdminServlet.EventInfoProvider#getInfo(org.osgi.service.event.Event)
         */
        public String getInfo(Event event) {
            final ServiceEvent currServiceEvent = (ServiceEvent) event.getProperty(EventConstants.EVENT);
            if (currServiceEvent == null) {
                return null;
            }
            final StringBuffer tmpBuffer = new StringBuffer("Service ");
            tmpBuffer.append(currServiceEvent.getServiceReference().getProperty(Constants.SERVICE_ID));
            tmpBuffer.append(' ');
            switch (currServiceEvent.getType()) {
            case ServiceEvent.REGISTERED:
                tmpBuffer.append("registered");
                break;
            case ServiceEvent.MODIFIED:
                tmpBuffer.append("modified");
                break;
            case ServiceEvent.UNREGISTERING:
                tmpBuffer.append("unregistering");
                break;
            default:
                return null; // IGNOREE
            }

            return tmpBuffer.toString();
        }
    }

    public static final String CLASS_SERV_INFO = "events";

    public static final String CLASS_SERV_ADMIN = "Event Admin";

    /** Number of events to be displayed. */
    private int maxSize = 50;

    private final List events = new ArrayList();

    /** 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());
    }

    /**
     * Activate this component.
     */
    public void activateBundle(BundleContext context) {
        super.activateBundle(context);

        this.events.clear();

        // register as EventHandler service to receive events
        Dictionary propsBook = new Hashtable();
        propsBook.put(Constants.SERVICE_DESCRIPTION, "Felix Web Console EventAdmin plugin");
        propsBook.put(Constants.SERVICE_VENDOR, "The Apache Software Foundation");
        propsBook.put("event.topics", "*");
        eventReceiver = context.registerService(EventHandler.class.getName(), this, propsBook);
    }

    /**
     * Deactivate this component.
     */
    public void deActivate() {
        if (eventReceiver != null) {
            eventReceiver.unregister();
            eventReceiver = null;
        }

        this.events.clear();

        super.deActivate();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        final String info = request.getPathInfo();
        if (info.endsWith(".json")) {
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");

            PrintWriter printWriter = response.getWriter();
            this.renderJSON(printWriter);

            // nothing more to do
            return;
        }

        super.doGet(request, response);
    }

    protected void doPost(HttpServletRequest comingRequest, HttpServletResponse response)
            throws ServletException, IOException {
        final String currAction = getRequestParameter(comingRequest, "action");
        // for now we only have the clear action
        if ("clear".equals(currAction)) {
            synchronized (this.events) {
                this.events.clear();
            }
        }
        // we always send back the json data
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");

        renderJSON(response.getWriter());
    }

    private void eventJson(JSONWriter jsonWriter, EventInfo info, int index) throws JSONException {
        final Event event = info.myEvent;

        // check if we have an info provider
        final Iterator iter = this.eventRenderers.entrySet().iterator();
        String infoText = null;
        while (infoText == null && iter.hasNext()) {
            final Map.Entry entry = (Map.Entry) iter.next();
            if (event.getTopic().startsWith(entry.getKey().toString())) {
                infoText = ((EventInfoProvider) entry.getValue()).getInfo(event);
            }
        }

        jsonWriter.object();
        jsonWriter.key("id");
        jsonWriter.value(String.valueOf(index));
        jsonWriter.key("received");
        jsonWriter.value(info.myReceivedTime);
        jsonWriter.key("topic");
        jsonWriter.value(event.getTopic());
        if (infoText != null) {
            jsonWriter.key("info");
            jsonWriter.value(infoText);
        }
        jsonWriter.key("properties");
        jsonWriter.object();
        final String[] names = event.getPropertyNames();
        if (names != null && names.length > 0) {
            for (int i = 0; i < names.length; i++) {
                jsonWriter.key(names[i]);
                jsonWriter.value(event.getProperty(names[i]).toString());
            }
        }
        jsonWriter.endObject();

        jsonWriter.endObject();
    }

    public String getServletCapital() {
        return CLASS_SERV_ADMIN;
    }

    public String getServletLabel() {
        return CLASS_SERV_INFO;
    }

    public void handleEvent(Event event) {
        // we add everything which is not a log event
        String addr = "org/osgi/service/log";
        if (!event.getTopic().startsWith(addr)) {
            synchronized (this.events) {
                this.events.add(new EventInfo(event));
                if (events.size() > this.maxSize) {
                    events.remove(0);
                }
            }
        }
    }

    private void renderJSON(final PrintWriter printWriter) throws IOException {
        List tmpCopiedEvents = null;
        synchronized (this.events) {
            tmpCopiedEvents = new ArrayList(this.events);
        }
        // create status line
        final EventAdmin admin = (EventAdmin) this.getService(EventAdmin.class.getName());
        StringBuffer statusLine = new StringBuffer();
        if (admin == null) {
            statusLine.append("The Event Admin is not installed or running.");
        } else {
            statusLine.append("Cong! The Event Admin is running.");
        }
        statusLine.append(" ");
        statusLine.append(tmpCopiedEvents.size());
        statusLine.append(" Events received");
        if (!tmpCopiedEvents.isEmpty()) {
            statusLine.append(" since ");
            Date d = new Date();
            d.setTime(((EventInfo) tmpCopiedEvents.get(0)).myReceivedTime);
            statusLine.append(d);
        }
        statusLine.append(".");

        JSONWriter jsonWriter = new JSONWriter(printWriter);
        try {
            jsonWriter.object();
            jsonWriter.key("status");

            jsonWriter.value(statusLine);

            jsonWriter.key("data");

            jsonWriter.array();

            // display list in reverse order
            for (int index = tmpCopiedEvents.size() - 1; index >= 0; index--) {
                eventJson(jsonWriter, (EventInfo) tmpCopiedEvents.get(index), index);
            }

            jsonWriter.endArray();

            jsonWriter.endObject();

        } catch (JSONException jsonEx) {
            throw new IOException(jsonEx.toString());
        }

    }

    protected void renderServletRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        final PrintWriter printWriter = response.getWriter();

        final String appRoot = (String) request.getAttribute(OsgiManager.OSGI_APP_ROOT);
        Util.printScriptBody(printWriter, appRoot, "events.js");

        printWriter.println("<div id='plugin_content'/>");

        Util.startScript(printWriter);
        printWriter.println("renderEvents( );");
        Util.endScript(printWriter);
    }
}