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.core; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Date; import java.util.Dictionary; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; import java.util.TreeMap; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.felix.bundlerepository.R4Attribute; import org.apache.felix.bundlerepository.R4Export; import org.apache.felix.bundlerepository.R4Import; import org.apache.felix.bundlerepository.R4Package; 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.JSONArray; import org.json.JSONException; import org.json.JSONWriter; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; import org.osgi.framework.ServiceReference; import org.osgi.framework.Version; import org.osgi.service.cm.ConfigurationAdmin; import org.osgi.service.component.ComponentConstants; import org.osgi.service.packageadmin.ExportedPackage; import org.osgi.service.packageadmin.PackageAdmin; import org.osgi.service.startlevel.StartLevel; public class BundlesServlet extends BaseWebConsolePluginServlet { private final class ServletRequestInfo { public final String extension; public final Bundle bundle; public final boolean bundleRequested; protected ServletRequestInfo(final HttpServletRequest request) { String info = request.getPathInfo(); // remove label and starting slash info = info.substring(getServletLabel().length() + 1); int extensionLength = 5; // get extension if (info.endsWith(".json")) { extension = "json"; info = info.substring(0, info.length() - extensionLength); } else { extension = "html"; } // we only accept direct requests to a bundle if they have a slash // after the label String bundleInfo = null; if (info.startsWith("/")) { bundleInfo = info.substring(1); } if (bundleInfo == null) { bundle = null; bundleRequested = false; } else { bundle = getBundle(bundleInfo); bundleRequested = true; } request.setAttribute(BundlesServlet.class.getName(), this); } } public static ServletRequestInfo getRequestInfo(final HttpServletRequest request) { return (ServletRequestInfo) request.getAttribute(BundlesServlet.class.getName()); } private final Log logger = LogFactory.getLog(getClass()); public static final String SERV_NAME = "bundles"; public static final String SERV_LABEL = "Bundles"; public static final String BUNDLE_ID = "bundleId"; private static final int STRING_BACKWARD = 1; private static final int STRING_FORWARD = 1; private static final int NOT_FOUND_ERROR = 404; private static final int SLEEP_TIME = 800; // bootdelegation property entries. wildcards are converted to package // name prefixes. whether an entry is a wildcard or not is set as a flag // in the bootPkgWildcards array. // see #activate and #isBootDelegated private String[] bootPkgs; // a flag for each entry in bootPkgs indicating whether the respective // entry was declared as a wildcard or not // see #activate and #isBootDelegated private boolean[] bootPkgWildcards; public void activateBundle(BundleContext bundleContext) { super.activateBundle(bundleContext); // bootdelegation property parsing from Apache Felix R4SearchPolicyCore String bootDelegation = bundleContext.getProperty(Constants.FRAMEWORK_BOOTDELEGATION); bootDelegation = (bootDelegation == null) ? "java.*" : bootDelegation + ",java.*"; StringTokenizer strToken = new StringTokenizer(bootDelegation, " ,"); bootPkgs = new String[strToken.countTokens()]; bootPkgWildcards = new boolean[bootPkgs.length]; for (int i = 0; i < bootPkgs.length; i++) { bootDelegation = strToken.nextToken(); if (bootDelegation.endsWith("*")) { bootPkgWildcards[i] = true; bootDelegation = bootDelegation.substring(0, bootDelegation.length() - STRING_BACKWARD); } bootPkgs[i] = bootDelegation; } } private void appendBundleMsg(final StringBuffer strBuf, String msg, int count) { strBuf.append(count); if (count != 1) strBuf.append(" bundles "); else strBuf.append(" bundle "); strBuf.append(msg); } private void appendProperty(JSONArray array, ServiceReference servRef, String name, String label) { StringBuffer finalString = new StringBuffer(); Object value = servRef.getProperty(name); if (value instanceof Object[]) { Object[] values = (Object[]) value; finalString.append(label).append(": "); for (int j = 0; j < values.length; j++) { if (j > 0) finalString.append(", "); finalString.append(values[j]); } array.put(finalString.toString()); } else if (value != null) { finalString.append(label).append(": ").append(value); array.put(finalString.toString()); } } private void bundleInfo(JSONWriter jsonWriter, Bundle bundle, boolean details) throws JSONException { jsonWriter.object(); jsonWriter.key("id"); jsonWriter.value(bundle.getBundleId()); jsonWriter.key("name"); jsonWriter.value(Util.getBundleName(bundle)); jsonWriter.key("state"); jsonWriter.value(getStateString(bundle)); jsonWriter.key("version"); jsonWriter.value(Util.getHeaderValue(bundle, Constants.BUNDLE_VERSION)); jsonWriter.key("symbolicName"); jsonWriter.value(Util.getHeaderValue(bundle, Constants.BUNDLE_SYMBOLICNAME)); jsonWriter.key("actions"); jsonWriter.array(); if (bundle.getBundleId() != 0) { if (hasStarted(bundle)) { printAction(jsonWriter, hasStarted(bundle), "start", "Start", "start"); } else { printAction(jsonWriter, isStopped(bundle), "stop", "Stop", "stop"); } printAction(jsonWriter, true, "refresh", "Refresh Package Imports", "refresh"); printAction(jsonWriter, isUninstalled(bundle), "uninstall", "Uninstall", "delete"); } jsonWriter.endArray(); if (details) { printBundleDetails(jsonWriter, bundle); } jsonWriter.endObject(); } private void collectImport(JSONArray array, String name, Version version, boolean optional, ExportedPackage export) { StringBuffer importBuff = new StringBuffer(); boolean bootDel = isBootDelegated(name); String marker = null; importBuff.append(name); importBuff.append(",version=").append(version); importBuff.append(" from "); if (export != null) { importBuff.append(getBundleDescriptor(export.getExportingBundle())); if (bootDel) { importBuff.append(" -- It will be overwritten by Boot Delegation"); marker = "INFO"; } } else { importBuff.append(" -- It is unable to be resolved"); marker = "ERROR"; if (optional) { importBuff.append(" that is not required"); } if (bootDel) { importBuff.append(" and overwritten by Boot Delegation"); } } if (marker != null) { importBuff.insert(0, ": "); importBuff.insert(0, marker); } array.put(importBuff); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { final ServletRequestInfo reqInfo = new ServletRequestInfo(request); if (reqInfo.bundle == null && reqInfo.bundleRequested) { response.sendError(NOT_FOUND_ERROR); return; } if (reqInfo.extension.equals("json")) { this.renderResponseJSON(response, reqInfo.bundle); // nothing more to do return; } super.doGet(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { final ServletRequestInfo reqInfo = new ServletRequestInfo(request); if (reqInfo.bundleRequested && reqInfo.bundle == null) { response.sendError(NOT_FOUND_ERROR); return; } boolean successful = false; final String reqAction = request.getParameter("action"); Bundle bundle = getBundle(request.getPathInfo()); if (bundle != null) { if (reqAction == null) { successful = true; } else if ("start".equals(reqAction)) { // start bundle successful = true; try { bundle.start(); } catch (BundleException bundleEx) { logger.error("Bundle can not start. " + bundleEx); } } else if ("stop".equals(reqAction)) { // stop bundle successful = true; try { bundle.stop(); } catch (BundleException bundleEx) { logger.error("It stopped! " + bundleEx); } } else if ("refresh".equals(reqAction)) { // refresh bundle wiring refreshPkg(bundle); successful = true; } else if ("uninstall".equals(reqAction)) { // uninstall bundle successful = true; try { bundle.uninstall(); bundle = null; // bundle has gone ! } catch (BundleException bundleEx) { logger.error("Unable to uninstall bundle! " + bundleEx); } } } if ("refreshPackages".equals(reqAction)) { getPackageAdmin().refreshPackages(null); successful = true; } if (successful) { // let's wait a little bit to give the framework time // to process our request try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException ex) { // we ignore this } this.renderResponseJSON(response, null); } else { super.doPost(request, response); } } private Bundle getBundle(String pathInfo) { // only use last part of the pathInfo pathInfo = pathInfo.substring(pathInfo.lastIndexOf('/') + STRING_FORWARD); // assume bundle Id try { final long bundleId = Long.parseLong(pathInfo); if (bundleId >= 0) { return getBundleContext().getBundle(bundleId); } } catch (NumberFormatException numberEx) { // check if this follows the pattern {symbolic-name}[:{version}] final int position = pathInfo.indexOf(':'); final String symbolicName; final String bundleVersion; if (position == -1) { symbolicName = pathInfo; bundleVersion = null; } else { symbolicName = pathInfo.substring(0, position); bundleVersion = pathInfo.substring(position + STRING_FORWARD); } // search final Bundle[] bundles = getBundleContext().getBundles(); for (int i = 0; i < bundles.length; i++) { final Bundle bundle = bundles[i]; // check symbolic name first if (symbolicName.equals(bundle.getSymbolicName())) { if (bundleVersion == null || bundleVersion.equals(bundle.getHeaders().get(Constants.BUNDLE_VERSION))) { return bundle; } } } } return null; } private String getBundleDescriptor(Bundle bundle) { StringBuffer infoBuf = new StringBuffer(); if (bundle.getLocation() != null) { // otherwise try the location infoBuf.append(bundle.getLocation()); infoBuf.append(" (").append(bundle.getBundleId()); infoBuf.append(")"); } else if (bundle.getSymbolicName() != null) { // list the bundle name if not null infoBuf.append(bundle.getSymbolicName()); infoBuf.append(" (").append(bundle.getBundleId()); infoBuf.append(")"); } else { infoBuf.append(bundle.getBundleId()); } return infoBuf.toString(); } protected Bundle[] getBundles() { return getBundleContext().getBundles(); } private String getBundleStatusLine(final Bundle[] bundles) { int active = 0, installed = 0, resolved = 0, fragments = 0; for (int i = 0; i < bundles.length; i++) { switch (bundles[i].getState()) { case Bundle.ACTIVE: active++; break; case Bundle.INSTALLED: installed++; break; case Bundle.RESOLVED: if (bundles[i].getHeaders().get(Constants.FRAGMENT_HOST) != null) { fragments++; } else { resolved++; } break; } } final StringBuffer strBuffer = new StringBuffer(); strBuffer.append("Bundle information: "); appendBundleMsg(strBuffer, "in total", bundles.length); if (active == bundles.length || active + fragments == bundles.length) { strBuffer.append(" - all "); appendBundleMsg(strBuffer, "active.", bundles.length); } else { if (active != 0) { strBuffer.append(", "); appendBundleMsg(strBuffer, "active", active); } if (fragments != 0) { strBuffer.append(", "); appendBundleMsg(strBuffer, "active fragments", fragments); } if (resolved != 0) { strBuffer.append(", "); appendBundleMsg(strBuffer, "resolved", resolved); } if (installed != 0) { strBuffer.append(", "); appendBundleMsg(strBuffer, "installed", installed); } strBuffer.append('.'); } return strBuffer.toString(); } private void getDelegationInfo(JSONArray array, String name, Version version) { StringBuffer bufVal = new StringBuffer(); boolean bootDel = isBootDelegated(name); if (bootDel) { bufVal.append("!! "); } bufVal.append(name); bufVal.append(",version="); bufVal.append(version); if (bootDel) { bufVal.append(" -- Overwritten by Boot Delegation"); } array.put(bufVal.toString()); } public String getServletCapital() { return SERV_LABEL; } public String getServletLabel() { return SERV_NAME; } private Integer getStartLevel(Bundle bundle) { StartLevel bundleLv = getStartLevel(); return (bundleLv != null) ? new Integer(bundleLv.getBundleStartLevel(bundle)) : null; } private String getStateString(final Bundle bundle) { switch (bundle.getState()) { case Bundle.STARTING: return "Starting"; case Bundle.ACTIVE: return "Active"; case Bundle.STOPPING: return "Stopping"; case Bundle.UNINSTALLED: return "Uninstalled"; case Bundle.INSTALLED: return "Installed"; case Bundle.RESOLVED: if (isFragmentBundle(bundle)) { return "Fragment"; } return "Resolved"; default: return "Unknown: " + bundle.getState(); } } private boolean hasStarted(Bundle bundle) { if (isFragmentBundle(bundle)) { return false; } return bundle.getState() == Bundle.INSTALLED || bundle.getState() == Bundle.RESOLVED; } // returns true if the package is listed in the bootdelegation property private boolean isBootDelegated(String pkgName) { // bootdelegation analysis from Apache Felix R4SearchPolicyCore // Only consider delegation if we have a package name, since // we don't want to promote the default package. The spec does // not take a stand on this issue. if (pkgName.length() > 0) { // Delegate any packages listed in the boot delegation // property to the parent class loader. for (int i = 0; i < bootPkgs.length; i++) { // A wildcarded boot delegation package will be in the form of // "foo.", so if the package is wildcarded do a startsWith() or // a regionMatches() to ignore the trailing "." to determine if // the request should be delegated to the parent class loader. // If the package is not wildcarded, then simply do an equals() // test to see if the request should be delegated to the parent // class loader. if ((bootPkgWildcards[i] && (pkgName.startsWith(bootPkgs[i]) || bootPkgs[i].regionMatches(0, pkgName, 0, pkgName.length()))) || (!bootPkgWildcards[i] && bootPkgs[i].equals(pkgName))) { return true; } } } return false; } private boolean isFragmentBundle(Bundle bundle) { return bundle.getHeaders().get(Constants.FRAGMENT_HOST) != null; } private boolean isStopped(Bundle bundle) { if (isFragmentBundle(bundle)) { return false; } return bundle.getState() == Bundle.ACTIVE; } private boolean isUninstalled(Bundle bundle) { return bundle.getState() == Bundle.INSTALLED || bundle.getState() == Bundle.RESOLVED || bundle.getState() == Bundle.ACTIVE; } private void jsonKeyVal(JSONWriter jsonWriter, String key, Object value) throws JSONException { if (key != null && value != null) { jsonWriter.object(); jsonWriter.key("key"); jsonWriter.value(key); jsonWriter.key("value"); jsonWriter.value(value); jsonWriter.endObject(); } } private void listHeaders(JSONWriter jsonWriter, Bundle bundle) throws JSONException { JSONArray val = new JSONArray(); Dictionary headers = bundle.getHeaders(); Enumeration headerKey = headers.keys(); while (headerKey.hasMoreElements()) { Object header = headerKey.nextElement(); String value = String.valueOf(headers.get(header)); // Package headers may be long, support line breaking by // ensuring blanks after comma and semicolon. value = value.replaceAll("([;,])", "$1 "); val.put(header + ": " + value); } jsonKeyVal(jsonWriter, "Manifest Headers", val); } @SuppressWarnings("deprecation") private void listImportExport(JSONWriter jsonWriter, Bundle bundle) throws JSONException { PackageAdmin packageAdmin = getPackageAdmin(); if (packageAdmin == null) { return; } Map usingBundles = new TreeMap(); ExportedPackage[] exports = packageAdmin.getExportedPackages(bundle); if (exports != null && exports.length > 0) { // do alphabetical sort Arrays.sort(exports, new Comparator() { public int compare(ExportedPackage p1, ExportedPackage p2) { return p1.getName().compareTo(p2.getName()); } public int compare(Object o1, Object o2) { return compare((ExportedPackage) o1, (ExportedPackage) o2); } }); JSONArray val = new JSONArray(); for (int j = 0; j < exports.length; j++) { ExportedPackage export = exports[j]; getDelegationInfo(val, export.getName(), export.getVersion()); Bundle[] ubList = export.getImportingBundles(); if (ubList != null) { for (int i = 0; i < ubList.length; i++) { Bundle ub = ubList[i]; usingBundles.put(ub.getSymbolicName(), ub); } } } jsonKeyVal(jsonWriter, "Exported Packages", val); } else { jsonKeyVal(jsonWriter, "Exported Packages", "None"); } exports = packageAdmin.getExportedPackages((Bundle) null); if (exports != null && exports.length > 0) { // collect import packages first final List imports = new ArrayList(); for (int i = 0; i < exports.length; i++) { final ExportedPackage ep = exports[i]; final Bundle[] importers = ep.getImportingBundles(); for (int j = 0; importers != null && j < importers.length; j++) { if (importers[j].getBundleId() == bundle.getBundleId()) { imports.add(ep); break; } } } // now sort JSONArray val = new JSONArray(); if (imports.size() > 0) { final ExportedPackage[] packages = (ExportedPackage[]) imports .toArray(new ExportedPackage[imports.size()]); Arrays.sort(packages, new Comparator() { public int compare(ExportedPackage p1, ExportedPackage p2) { return p1.getName().compareTo(p2.getName()); } public int compare(Object o1, Object o2) { return compare((ExportedPackage) o1, (ExportedPackage) o2); } }); // and finally print out for (int i = 0; i < packages.length; i++) { ExportedPackage exportPkg = packages[i]; collectImport(val, exportPkg.getName(), exportPkg.getVersion(), false, exportPkg); } } else { // add description if there are no imports val.put("None"); } jsonKeyVal(jsonWriter, "Imported Packages", val); } if (!usingBundles.isEmpty()) { JSONArray val = new JSONArray(); for (Iterator bundleIter = usingBundles.values().iterator(); bundleIter.hasNext();) { Bundle usingBundle = (Bundle) bundleIter.next(); val.put(getBundleDescriptor(usingBundle)); } jsonKeyVal(jsonWriter, "Importing Bundles", val); } } private void listImportExportsUnresolved(JSONWriter jsonWriter, Bundle bundle) throws JSONException { Dictionary dictHeader = bundle.getHeaders(); String exportPkg = (String) dictHeader.get(Constants.EXPORT_PACKAGE); if (exportPkg != null) { R4Package[] pkgs = R4Package.parseImportOrExportHeader(exportPkg); if (pkgs != null && pkgs.length > 0) { // do alphabetical sort Arrays.sort(pkgs, new Comparator() { public int compare(Object o1, Object o2) { return compare((R4Package) o1, (R4Package) o2); } public int compare(R4Package p1, R4Package p2) { return p1.getName().compareTo(p2.getName()); } }); JSONArray val = new JSONArray(); for (int i = 0; i < pkgs.length; i++) { R4Export export = new R4Export(pkgs[i]); getDelegationInfo(val, export.getName(), export.getVersion()); } jsonKeyVal(jsonWriter, "Exported Packages", val); } else { jsonKeyVal(jsonWriter, "Exported Packages", "None"); } } exportPkg = (String) dictHeader.get(Constants.IMPORT_PACKAGE); if (exportPkg != null) { R4Package[] pkgs = R4Package.parseImportOrExportHeader(exportPkg); if (pkgs != null && pkgs.length > 0) { Map imports = new TreeMap(); for (int i = 0; i < pkgs.length; i++) { R4Package pkg = pkgs[i]; imports.put(pkg.getName(), new R4Import(pkg)); } // collect import packages first final Map candidates = new HashMap(); PackageAdmin packageAdmin = getPackageAdmin(); if (packageAdmin != null) { ExportedPackage[] exports = packageAdmin.getExportedPackages((Bundle) null); if (exports != null && exports.length > 0) { for (int i = 0; i < exports.length; i++) { final ExportedPackage ep = exports[i]; R4Import imp = (R4Import) imports.get(ep.getName()); if (imp != null && imp.isSatisfied(toR4Export(ep))) { candidates.put(ep.getName(), ep); } } } } // now sort JSONArray importArray = new JSONArray(); if (imports.size() > 0) { for (Iterator importsIter = imports.values().iterator(); importsIter.hasNext();) { R4Import r4Import = (R4Import) importsIter.next(); ExportedPackage ep = (ExportedPackage) candidates.get(r4Import.getName()); // if there is no matching export, check whether this // bundle has the package, ignore the entry in this case if (ep == null) { String path = r4Import.getName().replace('.', '/'); if (bundle.getResource(path) != null) { continue; } } collectImport(importArray, r4Import.getName(), r4Import.getVersion(), r4Import.isOptional(), ep); } } else { // add description if there are no imports importArray.put("None"); } jsonKeyVal(jsonWriter, "Imported Packages", importArray); } } } private void listServices(JSONWriter jsonWriter, Bundle bundle) throws JSONException { ServiceReference[] refs = bundle.getRegisteredServices(); if (refs == null || refs.length == 0) { return; } for (int i = 0; i < refs.length; i++) { String key = "Service ID " + refs[i].getProperty(Constants.SERVICE_ID); JSONArray propArray = new JSONArray(); appendProperty(propArray, refs[i], Constants.OBJECTCLASS, "Types"); appendProperty(propArray, refs[i], Constants.SERVICE_PID, "PID"); appendProperty(propArray, refs[i], ConfigurationAdmin.SERVICE_FACTORYPID, "Factory PID"); appendProperty(propArray, refs[i], ComponentConstants.COMPONENT_NAME, "Component Name"); appendProperty(propArray, refs[i], ComponentConstants.COMPONENT_ID, "Component ID"); appendProperty(propArray, refs[i], ComponentConstants.COMPONENT_FACTORY, "Component Factory"); appendProperty(propArray, refs[i], Constants.SERVICE_DESCRIPTION, "Description"); appendProperty(propArray, refs[i], Constants.SERVICE_VENDOR, "Vendor"); jsonKeyVal(jsonWriter, key, propArray); } } private void printAction(JSONWriter jsonWriter, boolean enabled, String op, String opLabel, String image) throws JSONException { jsonWriter.object(); jsonWriter.key("enabled").value(enabled); jsonWriter.key("name").value(opLabel); jsonWriter.key("link").value(op); jsonWriter.key("image").value(image); jsonWriter.endObject(); } private void printBundleDetails(JSONWriter jsonWriter, Bundle bundle) throws JSONException { Dictionary headers = bundle.getHeaders(); jsonWriter.key("props"); jsonWriter.array(); jsonKeyVal(jsonWriter, "Symbolic Name", bundle.getSymbolicName()); jsonKeyVal(jsonWriter, "Version", headers.get(Constants.BUNDLE_VERSION)); jsonKeyVal(jsonWriter, "Location", bundle.getLocation()); jsonKeyVal(jsonWriter, "Last Modification", new Date(bundle.getLastModified())); String docUrl = (String) headers.get(Constants.BUNDLE_DOCURL); if (docUrl != null) { jsonKeyVal(jsonWriter, "Bundle Documentation", docUrl); } jsonKeyVal(jsonWriter, "Vendor", headers.get(Constants.BUNDLE_VENDOR)); jsonKeyVal(jsonWriter, "Copyright", headers.get(Constants.BUNDLE_COPYRIGHT)); jsonKeyVal(jsonWriter, "Description", headers.get(Constants.BUNDLE_DESCRIPTION)); jsonKeyVal(jsonWriter, "Start Level", getStartLevel(bundle)); jsonKeyVal(jsonWriter, "Bundle Classpath", headers.get(Constants.BUNDLE_CLASSPATH)); if (bundle.getState() == Bundle.INSTALLED) { listImportExportsUnresolved(jsonWriter, bundle); } else { listImportExport(jsonWriter, bundle); } listServices(jsonWriter, bundle); listHeaders(jsonWriter, bundle); jsonWriter.endArray(); } private void refreshPkg(final Bundle bundle) { getPackageAdmin().refreshPackages(new Bundle[] { bundle }); } private void renderResponseJSON(final HttpServletResponse response, final Bundle bundle) throws IOException { response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); final PrintWriter printWriter = response.getWriter(); writeJSON(printWriter, bundle); } protected void renderServletRequest(HttpServletRequest request, HttpServletResponse response) throws IOException { // get request info from request attribute final ServletRequestInfo reqInfo = getRequestInfo(request); final PrintWriter printWriter = response.getWriter(); final String attrAppRoot = (String) request.getAttribute(OsgiManager.OSGI_APP_ROOT); Util.printScriptBody(printWriter, attrAppRoot, "bundles.js"); Util.startScript(printWriter); printWriter.println("var imgRoot=\"" + attrAppRoot + "/res/imgs\" ;"); printWriter.println("var startLevel = " + getStartLevel().getInitialBundleStartLevel() + ";"); printWriter.println("var drawDetails = " + reqInfo.bundleRequested + ";"); Util.endScript(printWriter); Util.printScriptBody(printWriter, attrAppRoot, "bundles.js"); printWriter.println("<div id='plugin_content'/>"); Util.startScript(printWriter); printWriter.print("renderBundles("); writeJSON(printWriter, reqInfo.bundle); printWriter.println(");"); Util.endScript(printWriter); } private R4Export toR4Export(ExportedPackage export) { R4Attribute version = new R4Attribute(Constants.VERSION_ATTRIBUTE, export.getVersion().toString(), false); return new R4Export(export.getName(), null, new R4Attribute[] { version }); } private void writeJSON(final PrintWriter printWriter, final Bundle bundle) throws IOException { final Bundle[] allBundles = this.getBundles(); final String statusLine = this.getBundleStatusLine(allBundles); final Bundle[] bundles = (bundle != null) ? new Bundle[] { bundle } : allBundles; Util.sortBundleList(bundles); final JSONWriter jsonWriter = new JSONWriter(printWriter); try { jsonWriter.object(); jsonWriter.key("status"); jsonWriter.value(statusLine); jsonWriter.key("data"); jsonWriter.array(); for (int i = 0; i < bundles.length; i++) { bundleInfo(jsonWriter, bundles[i], bundle != null); } jsonWriter.endArray(); jsonWriter.endObject(); } catch (JSONException jsonEx) { throw new IOException(jsonEx.toString()); } } }