FELIX-1230 - Use MetaTypeService to get all object class definitions for
singleton and factory configurations to be made available on the
configuration page.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@784089 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
index 9d7b1b8..f519ceb 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
@@ -17,9 +17,25 @@
package org.apache.felix.webconsole.internal.compendium;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.lang.reflect.Array;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Vector;
import java.util.Map.Entry;
import javax.servlet.ServletException;
@@ -28,9 +44,20 @@
import org.apache.felix.webconsole.internal.Util;
import org.apache.felix.webconsole.internal.servlet.OsgiManager;
-import org.json.*;
-import org.osgi.framework.*;
-import org.osgi.service.cm.*;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONWriter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.log.LogService;
import org.osgi.service.metatype.AttributeDefinition;
import org.osgi.service.metatype.ObjectClassDefinition;
@@ -346,6 +373,9 @@
{
// start with ManagedService instances
SortedMap optionsPlain = getServices( ManagedService.class.getName(), pidFilter, locale, true );
+
+ // next are the MetaType informations without ManagedService
+ addMetaTypeNames( optionsPlain, getPidObjectClasses( locale ), pidFilter, Constants.SERVICE_PID );
// add in existing configuration (not duplicating ManagedServices)
Configuration[] cfgs = ca.listConfigurations( pidFilter );
@@ -383,7 +413,7 @@
}
catch ( Exception e )
{
- // write a message or ignore
+ getLog().log( LogService.LOG_ERROR, "listConfigurations: Unexpected problem encountered", e );
}
}
@@ -394,11 +424,13 @@
try
{
SortedMap optionsFactory = getServices( ManagedServiceFactory.class.getName(), pidFilter, locale, true );
+ addMetaTypeNames( optionsFactory, getFactoryPidObjectClasses( locale ), pidFilter,
+ ConfigurationAdmin.SERVICE_FACTORYPID );
printOptionsForm( pw, optionsFactory, "configSelection_factory", "create", "Create" );
}
catch ( Exception e )
{
- // write a message or ignore
+ getLog().log( LogService.LOG_ERROR, "listFactoryConfigurations: Unexpected problem encountered", e );
}
}
@@ -439,6 +471,36 @@
}
+ private void addMetaTypeNames( final Map pidMap, final Collection ocdCollection, final String filterSpec, final String type )
+ {
+ Filter filter = null;
+ if ( filterSpec != null )
+ {
+ try
+ {
+ filter = getBundleContext().createFilter( filterSpec );
+ }
+ catch ( InvalidSyntaxException not_expected )
+ {
+ }
+ }
+
+ for ( Iterator oci = ocdCollection.iterator(); oci.hasNext(); )
+ {
+ final ObjectClassDefinition ocd = ( ObjectClassDefinition ) oci.next();
+ final String pid = ocd.getID();
+ final Dictionary props = new Hashtable();
+ props.put( type, pid );
+ if ( filter == null || filter.match( props ) )
+ {
+ final String name = ocd.getName() + " (" + pid + ")";
+ pidMap.put( pid, name );
+ }
+ }
+
+ }
+
+
private void printOptionsForm( PrintWriter pw, SortedMap options, String formId, String submitMethod,
String submitLabel )
{
@@ -725,7 +787,7 @@
// only delete if the PID is not our place holder
if ( !PLACEHOLDER_PID.equals( pid ) )
{
- // TODO: should log this here !!
+ getLog().log( LogService.LOG_INFO, "applyConfiguration: Deleting configuration " + pid );
Configuration config = ca.getConfiguration( pid, null );
config.delete();
}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java
index 0aae6f4..b8e2548 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java
@@ -17,6 +17,8 @@
package org.apache.felix.webconsole.internal.compendium;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -34,11 +36,16 @@
/**
- * The <code>ConfigManagerBase</code> TODO
- *
+ * The <code>ConfigManagerBase</code> is the base class for the
+ * ConfigurationAdmin support in the web console. It provides various helper
+ * methods mostly with respect to using the MetaTypeService to access
+ * configuration descriptiorns.
*/
abstract class ConfigManagerBase extends BaseWebConsolePlugin
{
+
+ private static final long serialVersionUID = -6691093960031418130L;
+
private static final String CONFIGURATION_ADMIN_NAME = ConfigurationAdmin.class.getName();
private static final String META_TYPE_NAME = MetaTypeService.class.getName();
@@ -52,32 +59,69 @@
protected MetaTypeService getMetaTypeService()
{
- //TODO:
return ( MetaTypeService ) getService( META_TYPE_NAME );
}
- protected Map getMetadataPids()
+ /**
+ * Returns a map of PIDs and providing bundles of MetaType information. The
+ * map is indexed by PID and the value of each entry is the bundle providing
+ * the MetaType information for that PID.
+ */
+ protected Collection getPidObjectClasses( final String locale )
{
- Map pids = new HashMap();
- MetaTypeService mts = this.getMetaTypeService();
+ return getObjectClasses( PID_GETTER, locale );
+ }
+
+
+ /**
+ * Returns a map of factory PIDs and providing bundles of MetaType
+ * information. The map is indexed by factory PID and the value of each
+ * entry is the bundle providing the MetaType information for that factory
+ * PID.
+ */
+ protected Collection getFactoryPidObjectClasses( final String locale )
+ {
+ return getObjectClasses( FACTORY_PID_GETTER, locale );
+ }
+
+
+ /**
+ * Returns the <code>ObjectClassDefinition</code> objects for the ids
+ * returned by the <code>idGetter</code>. Depending on the
+ * <code>idGetter</code> implementation this will be for factory PIDs or
+ * plain PIDs.
+ *
+ * @param idGetter The {@link IdGetter} used to get the list of factory PIDs
+ * or PIDs from <code>MetaTypeInformation</code> objetcs.
+ * @param locale The name of the locale to get the object class definitions
+ * for.
+ */
+ private Collection getObjectClasses( final IdGetter idGetter, final String locale )
+ {
+ final Collection objectClasses = new ArrayList();
+ final MetaTypeService mts = this.getMetaTypeService();
if ( mts != null )
{
- Bundle[] bundles = this.getBundleContext().getBundles();
+ final Bundle[] bundles = this.getBundleContext().getBundles();
for ( int i = 0; i < bundles.length; i++ )
{
- MetaTypeInformation mti = mts.getMetaTypeInformation( bundles[i] );
+ final MetaTypeInformation mti = mts.getMetaTypeInformation( bundles[i] );
if ( mti != null )
{
- String[] pidList = mti.getPids();
- for ( int j = 0; pidList != null && j < pidList.length; j++ )
+ final String[] idList = idGetter.getIds( mti );
+ for ( int j = 0; idList != null && j < idList.length; j++ )
{
- pids.put( pidList[j], bundles[i] );
+ ObjectClassDefinition ocd = mti.getObjectClassDefinition( idList[j], locale );
+ if ( ocd != null )
+ {
+ objectClasses.add( ocd );
+ }
}
}
}
}
- return pids;
+ return objectClasses;
}
@@ -221,4 +265,45 @@
}
}
+ /**
+ * The <code>IdGetter</code> interface is an internal helper to abstract
+ * retrieving object class definitions from all bundles for either
+ * pids or factory pids.
+ *
+ * @see #PID_GETTER
+ * @see #FACTORY_PID_GETTER
+ */
+ private static interface IdGetter
+ {
+ String[] getIds( MetaTypeInformation metaTypeInformation );
+ }
+
+ /**
+ * The implementation of the {@link IdGetter} interface returning the PIDs
+ * listed in the meta type information.
+ *
+ * @see #getPidObjectClasses(String)
+ */
+ private static final IdGetter PID_GETTER = new IdGetter()
+ {
+ public String[] getIds( MetaTypeInformation metaTypeInformation )
+ {
+ return metaTypeInformation.getPids();
+ }
+ };
+
+ /**
+ * The implementation of the {@link IdGetter} interface returning the
+ * factory PIDs listed in the meta type information.
+ *
+ * @see #getFactoryPidObjectClasses(String)
+ */
+ private static final IdGetter FACTORY_PID_GETTER = new IdGetter()
+ {
+ public String[] getIds( MetaTypeInformation metaTypeInformation )
+ {
+ return metaTypeInformation.getFactoryPids();
+ }
+ };
+
}