FELIX-2649 : Support for configuration printers without requiring them to implement the interface
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1021352 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
index a8590e0..e08f4d0 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleConstants.java
@@ -19,6 +19,7 @@
package org.apache.felix.webconsole;
import java.util.Locale;
+import java.util.Map;
/**
* WebConsoleConstants provides some common constants that are used by plugin
@@ -63,6 +64,20 @@
public static final String PLUGIN_TITLE = "felix.webconsole.title";
/**
+ * The property marking a service as a configuration printer.
+ * This can be any service having either a printConfiguration(PrintWriter)
+ * or printConfiguration(PrintWriter, String) method - this is according
+ * to the ConfigurationPrinter and ModeAwareConfigurationPrinter
+ * interfaces.
+ *
+ * If a service has a {@link #PLUGIN_LABEL}, {@link #PLUGIN_TITLE} and
+ * this property, it is treated as a configuration printer servce.
+ *
+ * @since 3.1.4
+ */
+ public static final String CONFIG_PRINTER_MODES = "felix.webconsole.configprinter.modes";
+
+ /**
* The name of the service registration properties providing references
* to addition CSS files that should be loaded when rendering the header
* for a registered plugin.
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java
new file mode 100644
index 0000000..7be7e32
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationPrinterAdapter.java
@@ -0,0 +1,77 @@
+/*
+ * 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.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.felix.webconsole.ConfigurationPrinter;
+
+
+/**
+ * Adapter for a service acting as configuration printer.
+ */
+public class ConfigurationPrinterAdapter implements ConfigurationPrinter
+{
+
+ private final Object service;
+
+ private final String title;
+
+ private final Method printMethod;
+
+ public ConfigurationPrinterAdapter(final Object service,
+ final String title,
+ final Method printMethod)
+ {
+ this.title = title;
+ this.service = service;
+ this.printMethod = printMethod;
+ }
+
+ public String getTitle()
+ {
+ return this.title;
+ }
+
+ protected void invoke(final Object[] args)
+ {
+ try
+ {
+ printMethod.invoke(service, args);
+ }
+ catch (IllegalArgumentException e)
+ {
+ // ignore
+ }
+ catch (IllegalAccessException e)
+ {
+ // ignore
+ }
+ catch (InvocationTargetException e)
+ {
+ // ignore
+ }
+ }
+
+ public void printConfiguration(final PrintWriter printWriter)
+ {
+ invoke(new Object[] {printWriter});
+ }
+}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
index e8611dd..2a1a316 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ConfigurationRender.java
@@ -18,6 +18,7 @@
import java.io.*;
+import java.lang.reflect.Method;
import java.net.URL;
import java.text.*;
import java.util.*;
@@ -31,8 +32,7 @@
import org.apache.felix.webconsole.*;
import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.apache.felix.webconsole.internal.i18n.ResourceBundleManager;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.*;
import org.osgi.util.tracker.ServiceTracker;
@@ -280,11 +280,23 @@
}
- private final ArrayList getConfigurationPrinters()
+ private final synchronized List getConfigurationPrinters()
{
if ( cfgPrinterTracker == null )
{
- cfgPrinterTracker = new ServiceTracker( getBundleContext(), ConfigurationPrinter.SERVICE, null );
+ try
+ {
+ cfgPrinterTracker = new ServiceTracker( getBundleContext(),
+ getBundleContext().createFilter("(|(" + Constants.OBJECTCLASS + "=" + ConfigurationPrinter.class.getName() + ")" +
+ "(&(" + WebConsoleConstants.PLUGIN_LABEL + "=*)(&("
+ + WebConsoleConstants.PLUGIN_TITLE + "=*)("
+ + WebConsoleConstants.CONFIG_PRINTER_MODES + "=*))))"),
+ null );
+ }
+ catch (InvalidSyntaxException e)
+ {
+ // ignore
+ }
cfgPrinterTracker.open();
cfgPrinterTrackerCount = -1;
}
@@ -297,10 +309,56 @@
{
for ( int i = 0; i < refs.length; i++ )
{
- ConfigurationPrinter cfgPrinter = ( ConfigurationPrinter ) cfgPrinterTracker.getService( refs[i] );
- addConfigurationPrinter( cp, cfgPrinter, refs[i].getBundle(), refs[i]
- .getProperty( WebConsoleConstants.PLUGIN_LABEL ), refs[i]
- .getProperty( ConfigurationPrinter.PROPERTY_MODES ) );
+ final ServiceReference ref = refs[i];
+ final Object service = cfgPrinterTracker.getService( ref );
+ if ( service != null )
+ {
+ if ( service instanceof ConfigurationPrinter )
+ {
+ final ConfigurationPrinter cfgPrinter = (ConfigurationPrinter) service;
+ addConfigurationPrinter( cp, cfgPrinter, refs[i].getBundle(),
+ ref.getProperty( WebConsoleConstants.PLUGIN_LABEL ),
+ ref.getProperty( ConfigurationPrinter.PROPERTY_MODES ) );
+ }
+ else
+ {
+ ConfigurationPrinter cfgPrinter = null;
+ // first: printConfiguration(PrintWriter, String)
+ try
+ {
+ final Method method = service.getClass().getDeclaredMethod("printConfiguration",
+ new Class[] {PrintWriter.class, String.class});
+ cfgPrinter = new ModeAwareConfigurationPrinterAdapter(service,
+ (String)ref.getProperty( WebConsoleConstants.PLUGIN_TITLE ), method);
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // ignore
+ }
+ if ( cfgPrinter == null )
+ {
+ // second: printConfiguration(PrintWriter)
+ try
+ {
+ final Method method = service.getClass().getDeclaredMethod("printConfiguration",
+ new Class[] {PrintWriter.class});
+ cfgPrinter = new ConfigurationPrinterAdapter(service,
+ (String)ref.getProperty( WebConsoleConstants.PLUGIN_TITLE ), method);
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // ignore
+ }
+ }
+
+ if ( cfgPrinter != null )
+ {
+ addConfigurationPrinter( cp, cfgPrinter, ref.getBundle(),
+ ref.getProperty( WebConsoleConstants.PLUGIN_LABEL ),
+ ref.getProperty( WebConsoleConstants.CONFIG_PRINTER_MODES ) );
+ }
+ }
+ }
}
}
configurationPrinters = new ArrayList(cp.values());
@@ -311,28 +369,28 @@
}
- private final void addConfigurationPrinter( final SortedMap printers, final ConfigurationPrinter cfgPrinter,
- final Bundle provider, final Object labelProperty, final Object mode )
+ private final void addConfigurationPrinter( final SortedMap printers,
+ final ConfigurationPrinter cfgPrinter,
+ final Bundle provider,
+ final Object labelProperty,
+ final Object mode )
{
- if ( cfgPrinter != null )
+ final String title = getTitle( cfgPrinter.getTitle(), provider );
+ String sortKey = title;
+ if ( printers.containsKey( sortKey ) )
{
- final String title = getTitle( cfgPrinter.getTitle(), provider );
- String sortKey = title;
- if ( printers.containsKey( sortKey ) )
+ int idx = -1;
+ String idxTitle;
+ do
{
- int idx = -1;
- String idxTitle;
- do
- {
- idx++;
- idxTitle = sortKey + idx;
- }
- while ( printers.containsKey( idxTitle ) );
- sortKey = idxTitle;
+ idx++;
+ idxTitle = sortKey + idx;
}
- String label = ( labelProperty instanceof String ) ? ( String ) labelProperty : sortKey;
- printers.put( sortKey, new PrinterDesc( cfgPrinter, title, label, mode ) );
+ while ( printers.containsKey( idxTitle ) );
+ sortKey = idxTitle;
}
+ String label = ( labelProperty instanceof String ) ? ( String ) labelProperty : sortKey;
+ printers.put( sortKey, new PrinterDesc( cfgPrinter, title, label, mode ) );
}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ModeAwareConfigurationPrinterAdapter.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ModeAwareConfigurationPrinterAdapter.java
new file mode 100644
index 0000000..21eba00
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/ModeAwareConfigurationPrinterAdapter.java
@@ -0,0 +1,50 @@
+/*
+ * 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.PrintWriter;
+import java.lang.reflect.Method;
+
+import org.apache.felix.webconsole.ConfigurationPrinter;
+import org.apache.felix.webconsole.ModeAwareConfigurationPrinter;
+
+
+/**
+ * Adapter for a service acting as mode aware configuration printer.
+ */
+public class ModeAwareConfigurationPrinterAdapter
+ extends ConfigurationPrinterAdapter
+ implements ModeAwareConfigurationPrinter
+{
+ public ModeAwareConfigurationPrinterAdapter(final Object service,
+ final String title,
+ final Method printMethod)
+ {
+ super(service, title, printMethod);
+ }
+
+ public void printConfiguration(final PrintWriter printWriter)
+ {
+ printConfiguration(printWriter, ConfigurationPrinter.MODE_ALWAYS);
+ }
+
+ public void printConfiguration(final PrintWriter printWriter, final String mode)
+ {
+ invoke(new Object[] {printWriter, mode});
+ }
+}