blob: 7c3d160c5c20faa20b7fce2391411bb2156563e3 [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.webconsole.internal.core;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;
import org.apache.felix.webconsole.internal.AbstractConfigurationPrinter;
import org.apache.felix.webconsole.internal.Util;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
/**
* ServicesConfigurationPrinter provides a configuration printer for inspecting the
* registered services.
*/
public class ServicesConfigurationPrinter extends AbstractConfigurationPrinter implements Constants
{
private static final String TITLE = "Services";
private static final MessageFormat INFO = new MessageFormat(
"Service {0} - {1} (pid: {2})");
private static final MessageFormat FROM = new MessageFormat(
" from Bundle {0} - {1} ({2}), version {3}");
private static final MessageFormat USING = new MessageFormat(
" Using Bundle {0} - {1} ({2}), version {3}");
// don't create empty reference array all the time, create it only once - it is immutable
private static final ServiceReference[] NO_REFS = new ServiceReference[0];
/**
* @see org.apache.felix.webconsole.ConfigurationPrinter#getTitle()
*/
public final String getTitle()
{
return TITLE;
}
/**
* @see org.apache.felix.webconsole.ConfigurationPrinter#printConfiguration(java.io.PrintWriter)
*/
public final void printConfiguration(PrintWriter pw)
{
final Object[] data = new Object[4]; // used as message formatter parameters
final ServiceReference refs[] = getServices();
pw.print("Status: ");
pw.println(ServicesServlet.getStatusLine(refs));
for (int i = 0; refs != null && i < refs.length; i++)
{
try
{
final Bundle bundle = refs[i].getBundle();
final Bundle[] usingBundles = refs[i].getUsingBundles();
pw.println();
pw.println(INFO.format(params(refs[i], data)));
pw.println(FROM.format(params(bundle, data)));
// print registration properties
String[] keys = refs[i].getPropertyKeys();
for (int j = 0; keys != null && j < keys.length; j++)
{
final String key = keys[j];
// skip common keys - already added above
if (SERVICE_ID.equals(key) || OBJECTCLASS.equals(key)
|| SERVICE_PID.equals(key))
continue;
pw.print(" ");
pw.print(key);
pw.print(": ");
pw.println(ServicesServlet.propertyAsString(refs[i], key));
}
// using bundles
for (int j = 0; usingBundles != null && j < usingBundles.length; j++)
{
pw.println(USING.format(params(usingBundles[j], data)));
}
}
catch (Throwable t)
{
// a problem handling a service - ignore and continue with the next
}
}
}
private static final Object[] params(Bundle bundle, Object[] data)
{
data[0] = String.valueOf(bundle.getBundleId());
data[1] = Util.getName(bundle, Locale.ENGLISH);
data[2] = bundle.getSymbolicName();
data[3] = Util.getHeaderValue(bundle, Constants.BUNDLE_VERSION);
return data;
}
private static final Object[] params(ServiceReference ref, Object[] data)
{
data[0] = ServicesServlet.propertyAsString(ref, SERVICE_ID);
data[1] = ServicesServlet.propertyAsString(ref, OBJECTCLASS);
data[2] = ServicesServlet.propertyAsString(ref, SERVICE_PID);
data[3] = "";
return data;
}
private final ServiceReference[] getServices()
{
ServiceReference[] refs = null;
try
{
refs = BundleContextUtil.getWorkingBundleContext(getBundleContext()).getAllServiceReferences(null, null);
}
catch (InvalidSyntaxException e)
{
// ignore
}
// no services or invalid filter syntax (unlikely)
if (refs != null)
{
Arrays.sort(refs, new ServiceReferenceComparator());
}
else
{
refs = NO_REFS;
}
return refs;
}
}
class ServiceReferenceComparator implements Comparator
{
private static final Long ZERO = new Long(0);
public int compare(ServiceReference p1, ServiceReference p2)
{
Long id1 = null;
if (p1 != null)
{
id1 = (Long) p1.getProperty(Constants.SERVICE_ID);
}
if (id1 == null)
{
id1 = ZERO;
}
Long id2 = null;
if (p2 != null)
{
id2 = (Long) p2.getProperty(Constants.SERVICE_ID);
}
if (id2 == null)
{
id2 = ZERO;
}
return id1.compareTo(id2);
}
public int compare(Object o1, Object o2)
{
return compare((ServiceReference) o1, (ServiceReference) o2);
}
}