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