You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2011/12/19 13:54:03 UTC
svn commit: r1220723 - in /felix/trunk/webconsole: ./
src/main/java/org/apache/felix/webconsole/internal/servlet/
src/main/resources/res/ui/
Author: fmeschbe
Date: Mon Dec 19 12:54:03 2011
New Revision: 1220723
URL: http://svn.apache.org/viewvc?rev=1220723&view=rev
Log:
FELIX-2117 Reduce the static dependencies
- Import most Compendium services dynamically
(still require Http, Startlevel, and PackageAdmin)
- Embed Metatype service package and import optionally
(allows to synthesize descriptors but still use imported
package if available)
- Make sure existing factory configurations are displayed even
in the absence of a Metatype service
Added:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java
- copied, changed from r1215540, felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationListener.java
Removed:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationListener.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationListener2.java
Modified:
felix/trunk/webconsole/pom.xml
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
felix/trunk/webconsole/src/main/resources/res/ui/config.js
Modified: felix/trunk/webconsole/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/pom.xml?rev=1220723&r1=1220722&r2=1220723&view=diff
==============================================================================
--- felix/trunk/webconsole/pom.xml (original)
+++ felix/trunk/webconsole/pom.xml Mon Dec 19 12:54:03 2011
@@ -130,22 +130,28 @@
org.apache.felix.webconsole.internal.OsgiManagerActivator
</Bundle-Activator>
<Import-Package>
- org.osgi.service.http,
- org.apache.felix.shell;
- org.osgi.service.*;resolution:=optional,
+ org.osgi.service.metatype;resolution:=optional,
javax.servlet.*;version=2.4,
*
</Import-Package>
<DynamicImport-Package>
- org.apache.felix.bundlerepository,
- org.osgi.service.obr
+ org.apache.felix.bundlerepository;version="[2.0,3)",
+ org.osgi.service.obr;version="[1.0,2)",
+ org.osgi.service.cm;version="[1.2,2)",
+ org.osgi.service.condpermadmin;version="[1.0,2)",
+ org.osgi.service.log;version="[1.3,2)",
+ org.osgi.service.metatype;version="[1.1,2)",
+ org.osgi.service.permissionadmin;version="[1.2,2)",
+ org.osgi.service.prefs;version="[1.1,2)",
+ org.osgi.service.wireadmin;version="[1.0,2)"
</DynamicImport-Package>
<Include-Resource>
{maven-resources},META-INF=src/main/bare-resources
</Include-Resource>
<Embed-Dependency>
org.apache.felix.utils;inline=org/apache/felix/utils/manifest/**,
- org.apache.felix.framework;inline=org/apache/felix/framework/util/VersionRange**
+ org.apache.felix.framework;inline=org/apache/felix/framework/util/VersionRange**,
+ org.osgi.compendium;inline=org/osgi/service/metatype/**
</Embed-Dependency>
<_removeheaders>
Embed-Dependency,Private-Package,Include-Resource
@@ -199,7 +205,6 @@
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
<scope>provided</scope>
- <optional>true</optional>
</dependency>
<dependency>
@@ -207,7 +212,6 @@
<artifactId>commons-io</artifactId>
<version>1.4</version>
<scope>provided</scope>
- <optional>true</optional>
</dependency>
<dependency>
Copied: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java (from r1215540, felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationListener.java)
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java?p2=felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java&p1=felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationListener.java&r1=1215540&r2=1220723&rev=1220723&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationListener.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java Mon Dec 19 12:54:03 2011
@@ -19,52 +19,276 @@
package org.apache.felix.webconsole.internal.servlet;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Dictionary;
-import java.util.Hashtable;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.TreeMap;
+
+import org.apache.felix.webconsole.internal.Util;
import org.osgi.service.cm.ManagedService;
+import org.osgi.service.metatype.AttributeDefinition;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.ObjectClassDefinition;
-class ConfigurationListener implements ManagedService
+class ConfigurationSupport implements ManagedService, MetaTypeProvider
{
+ private static final String[] CONF_PROPS = new String[] {
+ OsgiManager.PROP_MANAGER_ROOT, OsgiManager.DEFAULT_MANAGER_ROOT, //
+ OsgiManager.PROP_HTTP_SERVICE_SELECTOR, OsgiManager.DEFAULT_HTTP_SERVICE_SELECTOR, //
+ OsgiManager.PROP_DEFAULT_RENDER, OsgiManager.DEFAULT_PAGE, //
+ OsgiManager.PROP_REALM, OsgiManager.DEFAULT_REALM, //
+ OsgiManager.PROP_USER_NAME, OsgiManager.DEFAULT_USER_NAME, //
+ OsgiManager.PROP_PASSWORD, OsgiManager.DEFAULT_PASSWORD, //
+ OsgiManager.PROP_LOCALE, "" , //$NON-NLS-1$
+ };
+
+ // used by an inner class, to prevent synthetic methods
+ final OsgiManager osgiManager;
+
+ private final Object ocdLock = new Object();
+ private String ocdLocale;
+ private ObjectClassDefinition ocd;
- private final OsgiManager osgiManager;
-
-
- static ServiceRegistration create( OsgiManager osgiManager )
+ ConfigurationSupport( OsgiManager osgiManager )
{
- ConfigurationListener cl = new ConfigurationListener( osgiManager );
- return registerService( cl, new String[]
- { ManagedService.class.getName() } );
+ this.osgiManager = osgiManager;
}
- static ServiceRegistration registerService( ConfigurationListener listener, final String[] serviceNames )
+ //---------- ManagedService
+
+ @SuppressWarnings("unchecked")
+ public void updated( @SuppressWarnings("rawtypes") Dictionary config )
{
- final OsgiManager osgiManager = listener.osgiManager;
+ osgiManager.updateConfiguration( config );
+ }
- Dictionary<String, String> props = new Hashtable<String, String>();
- props.put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" );
- props.put( Constants.SERVICE_DESCRIPTION, "OSGi Management Console Configuration Receiver" );
- props.put( Constants.SERVICE_PID, osgiManager.getConfigurationPid() );
+ //---------- MetaTypeProvider
- return osgiManager.getBundleContext().registerService( serviceNames, listener, props );
+ public String[] getLocales()
+ {
+ // there is no locale support here
+ return null;
}
-
- protected ConfigurationListener( OsgiManager osgiManager )
+ static final String getString(ResourceBundle rb, String key, String def)
{
- this.osgiManager = osgiManager;
+ try
+ {
+ return rb.getString(key);
+ }
+ catch (Throwable t)
+ {
+ return def;
+ }
}
+ public ObjectClassDefinition getObjectClassDefinition( String id, String locale )
+ {
+ if ( !osgiManager.getConfigurationPid().equals( id ) )
+ {
+ return null;
+ }
+
+ if (locale == null) locale = Locale.ENGLISH.getLanguage();
+
+ // check if OCD is already initialized and it's locale is the same as the requested one
+ synchronized (ocdLock)
+ {
+ if ( ocd != null && ocdLocale != null && ocdLocale.equals(locale) )
+ {
+ return ocd;
+ }
+ }
+
+ ObjectClassDefinition xocd = null;
+ final Locale localeObj = Util.parseLocaleString(locale);
+ final ResourceBundle rb = osgiManager.resourceBundleManager.getResourceBundle(osgiManager.getBundleContext().getBundle(), localeObj);
+ final Map<String, ?> defaultConfig = osgiManager.getDefaultConfiguration();
+
+ // simple configuration properties
+ final ArrayList<AttributeDefinition> adList = new ArrayList<AttributeDefinition>();
+ for (int i = 0; i < CONF_PROPS.length; i++)
+ {
+ final String key = CONF_PROPS[i++];
+ final String defaultValue = ConfigurationUtil.getProperty( defaultConfig, key, CONF_PROPS[i] );
+ final String name = getString(rb, "metadata." + key + ".name", key); //$NON-NLS-1$ //$NON-NLS-2$
+ final String descr = getString(rb, "metadata." + key + ".description", key); //$NON-NLS-1$ //$NON-NLS-2$
+ adList.add( new AttributeDefinitionImpl(key, name, descr, defaultValue) );
+ }
+
+ // log level is select - so no simple default value; requires localized option labels
+ adList.add( new AttributeDefinitionImpl( OsgiManager.PROP_LOG_LEVEL,
+ getString(rb, "metadata.loglevel.name", OsgiManager.PROP_LOG_LEVEL), //$NON-NLS-1$
+ getString(rb, "metadata.loglevel.description", OsgiManager.PROP_LOG_LEVEL), //$NON-NLS-1$
+ AttributeDefinition.INTEGER, // type
+ new String[]
+ { String.valueOf( ConfigurationUtil.getProperty( defaultConfig, OsgiManager.PROP_LOG_LEVEL,
+ OsgiManager.DEFAULT_LOG_LEVEL ) ) }, // default values
+ 0, // cardinality
+ new String[] { // option labels
+ getString(rb, "log.level.debug", "Debug"), //$NON-NLS-1$ //$NON-NLS-2$
+ getString(rb, "log.level.info", "Information"), //$NON-NLS-1$ //$NON-NLS-2$
+ getString(rb, "log.level.warn", "Warn"), //$NON-NLS-1$ //$NON-NLS-2$
+ getString(rb, "log.level.error", "Error"), //$NON-NLS-1$ //$NON-NLS-2$
+ },
+ new String[] { "4", "3", "2", "1" } ) ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ // list plugins - requires localized plugin titles
+ final TreeMap<String, String> namesByClassName = new TreeMap<String, String>();
+ final String[] defaultPluginsClasses = OsgiManager.PLUGIN_MAP;
+ for ( int i = 0; i < defaultPluginsClasses.length; i++ )
+ {
+ final String clazz = defaultPluginsClasses[i++];
+ final String label = defaultPluginsClasses[i];
+ final String name = getString(rb, label + ".pluginTitle", label); //$NON-NLS-1$
+ namesByClassName.put(clazz, name);
+ }
+ final String[] classes = namesByClassName.keySet().toArray(
+ new String[namesByClassName.size()] );
+ final String[] names = namesByClassName.values().toArray( new String[namesByClassName.size()] );
+
+ adList.add( new AttributeDefinitionImpl( OsgiManager.PROP_ENABLED_PLUGINS,
+ getString(rb, "metadata.plugins.name", OsgiManager.PROP_ENABLED_PLUGINS), //$NON-NLS-1$
+ getString(rb, "metadata.plugins.description", OsgiManager.PROP_ENABLED_PLUGINS), //$NON-NLS-1$
+ AttributeDefinition.STRING, classes, Integer.MIN_VALUE, names, classes ) );
+
+ xocd = new ObjectClassDefinition()
+ {
+
+ private final AttributeDefinition[] attrs = adList
+ .toArray( new AttributeDefinition[adList.size()] );
+
+
+ public String getName()
+ {
+ return getString(rb, "metadata.name", "Apache Felix OSGi Management Console"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+
+ public InputStream getIcon( int arg0 )
+ {
+ return null;
+ }
+
+
+ public String getID()
+ {
+ return osgiManager.getConfigurationPid();
+ }
+
+
+ public String getDescription()
+ {
+ return getString(rb, "metadata.description", "Configuration of the Apache Felix OSGi Management Console."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+
+ public AttributeDefinition[] getAttributeDefinitions( int filter )
+ {
+ return ( filter == OPTIONAL ) ? null : attrs;
+ }
+ };
+
+ synchronized(ocdLock) {
+ this.ocd = xocd;
+ this.ocdLocale = locale;
+ }
- //---------- ManagedService
+ return ocd;
+ }
- @SuppressWarnings("unchecked")
- public void updated( @SuppressWarnings("rawtypes") Dictionary config )
+ private static class AttributeDefinitionImpl implements AttributeDefinition
{
- osgiManager.updateConfiguration( config );
+
+ private final String id;
+ private final String name;
+ private final String description;
+ private final int type;
+ private final String[] defaultValues;
+ private final int cardinality;
+ private final String[] optionLabels;
+ private final String[] optionValues;
+
+
+ AttributeDefinitionImpl( final String id, final String name, final String description, final String defaultValue )
+ {
+ this( id, name, description, STRING, new String[]
+ { defaultValue }, 0, null, null );
+ }
+
+
+ AttributeDefinitionImpl( final String id, final String name, final String description, final int type,
+ final String[] defaultValues, final int cardinality, final String[] optionLabels,
+ final String[] optionValues )
+ {
+ this.id = id;
+ this.name = name;
+ this.description = description;
+ this.type = type;
+ this.defaultValues = defaultValues;
+ this.cardinality = cardinality;
+ this.optionLabels = optionLabels;
+ this.optionValues = optionValues;
+ }
+
+
+ public int getCardinality()
+ {
+ return cardinality;
+ }
+
+
+ public String[] getDefaultValue()
+ {
+ return defaultValues;
+ }
+
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+
+ public String getID()
+ {
+ return id;
+ }
+
+
+ public String getName()
+ {
+ return name;
+ }
+
+
+ public String[] getOptionLabels()
+ {
+ return optionLabels;
+ }
+
+
+ public String[] getOptionValues()
+ {
+ return optionValues;
+ }
+
+
+ public int getType()
+ {
+ return type;
+ }
+
+
+ public String validate( String arg0 )
+ {
+ return null;
+ }
}
}
\ No newline at end of file
Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java?rev=1220723&r1=1220722&r2=1220723&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java Mon Dec 19 12:54:03 2011
@@ -35,6 +35,8 @@ import java.util.ResourceBundle;
import java.util.Set;
import javax.servlet.GenericServlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -59,6 +61,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.http.HttpContext;
@@ -218,6 +221,7 @@ public class OsgiManager extends Generic
private int logLevel = DEFAULT_LOG_LEVEL;
+ @SuppressWarnings("serial")
public OsgiManager(BundleContext bundleContext)
{
this.bundleContext = bundleContext;
@@ -314,23 +318,28 @@ public class OsgiManager extends Generic
// configure and start listening for configuration
updateConfiguration(null);
- try
- {
- this.configurationListener = ConfigurationListener2.create(this);
- }
- catch (Throwable t2)
- {
- // might be caused by Metatype API not available
- // try without MetaTypeProvider
- try
+ // register managed service as a service factory
+ this.configurationListener = bundleContext.registerService( "org.osgi.service.cm.ManagedService", //$NON-NLS-1$
+ new ServiceFactory()
{
- this.configurationListener = ConfigurationListener.create(this);
- }
- catch (Throwable t)
+ public Object getService( Bundle bundle, ServiceRegistration registration )
+ {
+ return new ConfigurationSupport( OsgiManager.this );
+ }
+
+
+ public void ungetService( Bundle bundle, ServiceRegistration registration, Object service )
+ {
+ // do nothing
+ }
+ }, new Hashtable<String, String>()
{
- // might be caused by CM API not available
- }
- }
+ {
+ put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" ); //$NON-NLS-1$
+ put( Constants.SERVICE_DESCRIPTION, "OSGi Management Console Configuration Receiver" ); //$NON-NLS-1$
+ put( Constants.SERVICE_PID, getConfigurationPid() );
+ }
+ } );
}
public void dispose()
@@ -551,14 +560,18 @@ public class OsgiManager extends Generic
return getClass().getName();
}
+
/**
- * Calls the <code>GenericServlet.log(String)</code> method if the
+ * Calls the <code>ServletContext.log(String)</code> method if the
* configured log level is less than or equal to the given <code>level</code>.
* <p>
* Note, that the <code>level</code> parameter is only used to decide whether
* the <code>GenericServlet.log(String)</code> method is called or not. The
* actual implementation of the <code>GenericServlet.log</code> method is
* outside of the control of this method.
+ * <p>
+ * If the servlet has not been initialized yet or has already been destroyed
+ * the message is printed to stderr.
*
* @param level The log level at which to log the message
* @param message The message to log
@@ -567,12 +580,23 @@ public class OsgiManager extends Generic
{
if (logLevel >= level)
{
- log(message);
+ ServletConfig config = getServletConfig();
+ if ( config != null )
+ {
+ ServletContext context = config.getServletContext();
+ if ( context != null )
+ {
+ context.log( message );
+ return;
+ }
+ }
+
+ System.err.println( message );
}
}
/**
- * Calls the <code>GenericServlet.log(String, Throwable)</code> method if
+ * Calls the <code>ServletContext.log(String, Throwable)</code> method if
* the configured log level is less than or equal to the given
* <code>level</code>.
* <p>
@@ -580,6 +604,9 @@ public class OsgiManager extends Generic
* the <code>GenericServlet.log(String, Throwable)</code> method is called
* or not. The actual implementation of the <code>GenericServlet.log</code>
* method is outside of the control of this method.
+ * <p>
+ * If the servlet has not been initialized yet or has already been destroyed
+ * the message is printed to stderr.
*
* @param level The log level at which to log the message
* @param message The message to log
@@ -589,7 +616,22 @@ public class OsgiManager extends Generic
{
if (logLevel >= level)
{
- log(message, t);
+ ServletConfig config = getServletConfig();
+ if ( config != null )
+ {
+ ServletContext context = config.getServletContext();
+ if ( context != null )
+ {
+ context.log( message, t );
+ return;
+ }
+ }
+
+ System.err.println( message );
+ if ( t != null )
+ {
+ t.printStackTrace( System.err );
+ }
}
}
Modified: felix/trunk/webconsole/src/main/resources/res/ui/config.js
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/config.js?rev=1220723&r1=1220722&r2=1220723&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/config.js (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/config.js Mon Dec 19 12:54:03 2011
@@ -541,11 +541,22 @@ $(document).ready(function() {
for(var i in configData.fpids) {
addFactoryConfig(configData.fpids[i]);
- var confs = factories[ configData.fpids[i].id ];
- if (confs) for (var j in confs) {
- addConfig(confs[j]);
+ var fpid = configData.fpids[i].id;
+ var confs = factories[ fpid ];
+ if (confs) {
+ for (var j in confs) {
+ addConfig(confs[j]);
+ }
+ delete factories[ fpid ];
}
}
+ for(var fpid in factories) {
+ var flist = factories[fpid];
+ for(var i in flist) {
+ delete flist[i].fpid; // render as regular config
+ addConfig(flist[i]);
+ }
+ }
initStaticWidgets(configTable);
// init tablesorte