blob: 1c35a4a64dc6338eb3d593c4094c8151d1484983 [file] [log] [blame]
/*
* 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.inventory.impl.webconsole;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
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 java.util.ResourceBundle;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.felix.inventory.InventoryPrinter;
import org.apache.felix.inventory.Format;
import org.apache.felix.inventory.ZipAttachmentProvider;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* The web console adapter registers web console status printers
* as inventory printers.
*/
public class WebConsoleAdapter implements ServiceTrackerCustomizer
{
private final BundleContext bundleContext;
private final ServiceTracker cfgPrinterTracker;
private final Map registrations = new HashMap();
private final ResourceBundleManager rbManager;
public WebConsoleAdapter(final BundleContext btx) throws InvalidSyntaxException
{
this.bundleContext = btx;
this.rbManager = new ResourceBundleManager(btx);
this.cfgPrinterTracker = new ServiceTracker(this.bundleContext, this.bundleContext.createFilter("(|("
+ Constants.OBJECTCLASS + "=" + ConsoleConstants.INTERFACE_CONFIGURATION_PRINTER + ")" + "(&("
+ ConsoleConstants.PLUGIN_LABEL + "=*)(&(" + ConsoleConstants.PLUGIN_TITLE + "=*)("
+ ConsoleConstants.CONFIG_PRINTER_MODES + "=*))))"), this);
this.cfgPrinterTracker.open();
}
/**
* Dispose this service
*/
public void dispose()
{
this.cfgPrinterTracker.close();
final List regs = new ArrayList();
synchronized (this.registrations)
{
regs.addAll(this.registrations.values());
this.registrations.clear();
}
final Iterator i = regs.iterator();
while (i.hasNext())
{
final ServiceRegistration reg = (ServiceRegistration) i.next();
reg.unregister();
}
this.rbManager.dispose();
}
private void add(final ServiceReference reference, final Object service)
{
final ConfigurationPrinterAdapter cpa = ConfigurationPrinterAdapter.createAdapter(service, reference);
if (cpa != null && cpa.title != null)
{
if (cpa.title.startsWith("%"))
{
String title = cpa.title.substring(1);
final ResourceBundle rb = this.rbManager.getResourceBundle(reference.getBundle());
if (rb != null)
{
try
{
title = rb.getString(title);
}
catch (Exception e)
{
// ClassCastException, MissingResourceException
// ignore
}
}
cpa.title = title;
}
if (cpa.label == null)
{
cpa.label = cpa.title;
}
final Dictionary props = new Hashtable();
props.put(InventoryPrinter.NAME, cpa.label);
props.put(InventoryPrinter.TITLE, cpa.title);
props.put(InventoryPrinter.FORMAT, cpa.getPrinterModes());
final ServiceRegistration reg = this.bundleContext.registerService(InventoryPrinter.class.getName(),
new WebConsolePrinter(cpa), props);
synchronized (this.registrations)
{
this.registrations.put(reference, reg);
}
}
}
private final void remove(final ServiceReference reference)
{
final ServiceRegistration reg;
synchronized (this.registrations)
{
reg = (ServiceRegistration) this.registrations.remove(reference);
}
if (reg != null)
{
reg.unregister();
}
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
*/
public Object addingService(final ServiceReference reference)
{
final Object service = this.bundleContext.getService(reference);
if (service != null)
{
this.add(reference, service);
}
return service;
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference,
* java.lang.Object)
*/
public void modifiedService(final ServiceReference reference, final Object service)
{
this.remove(reference);
this.add(reference, service);
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference,
* java.lang.Object)
*/
public void removedService(final ServiceReference reference, final Object service)
{
this.remove(reference);
this.bundleContext.ungetService(reference);
}
private static class WebConsolePrinter implements InventoryPrinter, ZipAttachmentProvider
{
final ConfigurationPrinterAdapter cpa;
public WebConsolePrinter(final ConfigurationPrinterAdapter cpa)
{
this.cpa = cpa;
}
/**
* @see org.apache.felix.inventory.InventoryPrinter#print(org.apache.felix.inventory.Format,
* java.io.PrintWriter)
*/
public void print(final PrintWriter printWriter, final Format format, final boolean isZip)
{
final String m;
if (!isZip && format == Format.HTML)
{
m = ConsoleConstants.MODE_WEB;
}
else if (!isZip && format == Format.TEXT)
{
m = ConsoleConstants.MODE_TXT;
}
else if (isZip && (format == Format.TEXT || format == Format.HTML))
{
m = ConsoleConstants.MODE_ZIP;
}
else
{
m = null;
}
if (m != null)
{
cpa.printConfiguration(printWriter, m);
}
}
/**
* @see org.apache.felix.inventory.ZipAttachmentProvider#addAttachments(java.util.zip.ZipOutputStream,
* java.lang.String)
*/
public void addAttachments(final ZipOutputStream zos, final String namePrefix) throws IOException
{
final URL[] attachments = cpa.getAttachments();
if (attachments != null)
{
for (int i = 0; i < attachments.length; i++)
{
final URL current = attachments[i];
final String path = current.getPath();
final String name;
if (path == null || path.length() == 0)
{
// sanity code, we should have a path, but if not let's
// just create some random name
name = "file" + Double.doubleToLongBits(Math.random());
}
else
{
final int pos = path.lastIndexOf('/');
name = (pos == -1 ? path : path.substring(pos + 1));
}
final ZipEntry entry = new ZipEntry(namePrefix + name);
zos.putNextEntry(entry);
final InputStream is = current.openStream();
try
{
byte[] buffer = new byte[4096];
int n = 0;
while (-1 != (n = is.read(buffer)))
{
zos.write(buffer, 0, n);
}
}
finally
{
if (is != null)
{
try
{
is.close();
}
catch (final IOException ignore)
{
}
}
}
zos.closeEntry();
}
}
}
}
}