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 2012/12/25 20:56:32 UTC
svn commit: r1425765 [1/2] - in /felix/trunk/webconsole: ./
src/main/java/org/apache/felix/webconsole/internal/compendium/
src/main/java/org/apache/felix/webconsole/internal/configuration/
src/main/java/org/apache/felix/webconsole/internal/servlet/
Author: fmeschbe
Date: Tue Dec 25 19:56:31 2012
New Revision: 1425765
URL: http://svn.apache.org/viewvc?rev=1425765&view=rev
Log:
FELIX-3784 Refactor support for Configuration Admin Service:
- Split ConfigurationSupport in ManagedService and meta type support
and check MetatypeProvider API availability to decide
- Split ConfigManager to dynamically and controllably make use
of the Configuration Admin service to access configurations and
the Metatype Service for configuration descriptors
Added:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java
- copied, changed from r1418242, felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigurationAdminConfigurationPrinter.java
- copied, changed from r1418242, felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeSupport.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetatypePropertyDescriptor.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/PropertyDescriptor.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationMetatypeSupport.java
Removed:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManagerBase.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java
Modified:
felix/trunk/webconsole/pom.xml
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
Modified: felix/trunk/webconsole/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/pom.xml?rev=1425765&r1=1425764&r2=1425765&view=diff
==============================================================================
--- felix/trunk/webconsole/pom.xml (original)
+++ felix/trunk/webconsole/pom.xml Tue Dec 25 19:56:31 2012
@@ -133,7 +133,6 @@
</Export-Package>
<Import-Package>
org.json.*;version=0,
- org.osgi.service.metatype;resolution:=optional,
javax.servlet.*;version=2.4,
org.apache.commons.io; version="[1.4,3)",
*
@@ -154,8 +153,7 @@
</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.osgi.compendium;inline=org/osgi/service/metatype/**
+ org.apache.felix.framework;inline=org/apache/felix/framework/util/VersionRange**
</Embed-Dependency>
<_removeheaders>
Embed-Dependency,Private-Package,Include-Resource
Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java?rev=1425765&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigAdminSupport.java Tue Dec 25 19:56:31 2012
@@ -0,0 +1,729 @@
+/*
+ * 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.configuration;
+
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.Vector;
+import java.util.Map.Entry;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.felix.webconsole.internal.Util;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.json.JSONWriter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+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.metatype.AttributeDefinition;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+
+class ConfigAdminSupport
+{
+
+ private final BundleContext bundleContext;
+ private final ConfigurationAdmin service;
+
+ private final ConfigManager configManager;
+
+
+ /**
+ *
+ * @param bundleContext
+ * @param service
+ *
+ * @throws ClassCastException if {@code service} is not a MetaTypeService instances
+ */
+ ConfigAdminSupport( final ConfigManager configManager, final BundleContext bundleContext, final Object service )
+ {
+ this.configManager = configManager;
+ this.bundleContext = bundleContext;
+ this.service = ( ConfigurationAdmin ) service;
+ }
+
+
+ public BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+
+ private MetaTypeServiceSupport getMetaTypeSupport()
+ {
+ Object metaTypeService = configManager.getService( ConfigManager.META_TYPE_NAME );
+ if ( metaTypeService != null )
+ {
+ return new MetaTypeServiceSupport( this.getBundleContext(), metaTypeService );
+ }
+
+ return null;
+ }
+
+
+ final Configuration getConfiguration( String pid )
+ {
+ if ( pid != null )
+ {
+ try
+ {
+ // we use listConfigurations to not create configuration
+ // objects persistently without the user providing actual
+ // configuration
+ String filter = '(' + Constants.SERVICE_PID + '=' + pid + ')';
+ Configuration[] configs = this.service.listConfigurations( filter );
+ if ( configs != null && configs.length > 0 )
+ {
+ return configs[0];
+ }
+ }
+ catch ( InvalidSyntaxException ise )
+ {
+ // should print message
+ }
+ catch ( IOException ioe )
+ {
+ // should print message
+ }
+ }
+
+ // fallback to no configuration at all
+ return null;
+ }
+
+
+ final Configuration getConfiguration( String pid, String factoryPid ) throws IOException
+ {
+ if ( factoryPid != null && ( pid == null || pid.equals( ConfigManager.PLACEHOLDER_PID ) ) )
+ {
+ return this.service.createFactoryConfiguration( factoryPid, null );
+ }
+
+ return this.service.getConfiguration( pid, null );
+ }
+
+
+ Configuration getPlaceholderConfiguration( final String factoryPid )
+ {
+ return new PlaceholderConfiguration( factoryPid );
+ }
+
+ String getPlaceholderPid() {
+ return ConfigManager.PLACEHOLDER_PID;
+ }
+
+ String applyConfiguration( HttpServletRequest request, String pid )
+ throws IOException
+ {
+ if ( request.getParameter( "delete" ) != null ) //$NON-NLS-1$
+ {
+ // only delete if the PID is not our place holder
+ if ( !ConfigManager.PLACEHOLDER_PID.equals( pid ) )
+ {
+ configManager.log( "applyConfiguration: Deleting configuration " + pid );
+ Configuration config = service.getConfiguration( pid, null );
+ config.delete();
+ }
+ return null; // return request.getHeader( "Referer" );
+ }
+
+ String factoryPid = request.getParameter( ConfigManager.factoryPID );
+ Configuration config = null;
+
+ String propertyList = request.getParameter( "propertylist" ); //$NON-NLS-1$
+ if ( propertyList == null )
+ {
+ // FIXME: this would be a bug !!
+ }
+ else
+ {
+ config = getConfiguration( pid, factoryPid );
+
+ Dictionary props = config.getProperties();
+ if ( props == null )
+ {
+ props = new Hashtable();
+ }
+
+ final MetaTypeServiceSupport mtss = getMetaTypeSupport();
+ final Map adMap = ( mtss != null ) ? mtss.getAttributeDefinitionMap( config, null ) : new HashMap();
+ final StringTokenizer propTokens = new StringTokenizer( propertyList, "," ); //$NON-NLS-1$
+ while ( propTokens.hasMoreTokens() )
+ {
+ String propName = propTokens.nextToken();
+ PropertyDescriptor ad = (PropertyDescriptor) adMap.get( propName );
+
+ // try to derive from current value
+ if (ad == null) {
+ Object currentValue = props.get( propName );
+ ad = MetaTypeSupport.createAttributeDefinition( propName, currentValue );
+ }
+
+ int attributeType = MetaTypeSupport.getAttributeType( ad );
+
+ if ( ad == null
+ || ( ad.getCardinality() == 0 && ( attributeType == AttributeDefinition.STRING || attributeType == MetaTypeServiceSupport.ATTRIBUTE_TYPE_PASSWORD ) ) )
+ {
+ String prop = request.getParameter( propName );
+ if ( prop != null
+ && ( attributeType != MetaTypeSupport.ATTRIBUTE_TYPE_PASSWORD || !MetaTypeSupport.PASSWORD_PLACEHOLDER_VALUE.equals( prop ) ) )
+ {
+ props.put( propName, prop );
+ }
+ }
+ else if ( ad.getCardinality() == 0 )
+ {
+ // scalar of non-string
+ String prop = request.getParameter( propName );
+ if ( prop != null )
+ {
+ try
+ {
+ props.put( propName, MetaTypeSupport.toType( attributeType, prop ) );
+ }
+ catch ( NumberFormatException nfe )
+ {
+ // don't care
+ }
+ }
+ }
+ else
+ {
+ // array or vector of any type
+ Vector vec = new Vector();
+
+ String[] properties = request.getParameterValues( propName );
+ if ( properties != null )
+ {
+ if ( attributeType == MetaTypeSupport.ATTRIBUTE_TYPE_PASSWORD )
+ {
+ MetaTypeSupport.setPasswordProps( vec, properties, props.get( propName ) );
+ }
+ else
+ {
+ for ( int i = 0; i < properties.length; i++ )
+ {
+ try
+ {
+ vec.add( MetaTypeSupport.toType( attributeType, properties[i] ) );
+ }
+ catch ( NumberFormatException nfe )
+ {
+ // don't care
+ }
+ }
+ }
+ }
+
+ // but ensure size (check for positive value since
+ // abs(Integer.MIN_VALUE) is still INTEGER.MIN_VALUE)
+ int maxSize = Math.abs( ad.getCardinality() );
+ if ( vec.size() > maxSize && maxSize > 0 )
+ {
+ vec.setSize( maxSize );
+ }
+
+ if ( ad.getCardinality() < 0 )
+ {
+ // keep the vector, but only add if not empty
+ if ( vec.isEmpty() )
+ {
+ props.remove( propName );
+ }
+ else
+ {
+ props.put( propName, vec );
+ }
+ }
+ else
+ {
+ // convert to an array
+ props.put( propName, MetaTypeSupport.toArray( attributeType, vec ) );
+ }
+ }
+ }
+
+ config.update( props );
+ }
+
+ // redirect to the new configuration (if existing)
+ return (config != null) ? config.getPid() : ""; //$NON-NLS-1$
+ }
+
+
+ void printConfigurationJson( PrintWriter pw, String pid, Configuration config, String pidFilter,
+ String locale )
+ {
+
+ JSONWriter result = new JSONWriter( pw );
+
+ if ( pid != null )
+ {
+ try
+ {
+ result.object();
+ this.configForm( result, pid, config, pidFilter, locale );
+ result.endObject();
+ }
+ catch ( Exception e )
+ {
+ configManager.log( "Error reading configuration PID " + pid, e );
+ }
+ }
+
+ }
+
+
+ void configForm( JSONWriter json, String pid, Configuration config, String pidFilter, String locale )
+ throws JSONException
+ {
+
+ json.key( ConfigManager.PID );
+ json.value( pid );
+
+ if ( pidFilter != null )
+ {
+ json.key( ConfigManager.PID_FILTER );
+ json.value( pidFilter );
+ }
+
+ Dictionary props = null;
+ if ( config != null )
+ {
+ props = config.getProperties(); // unchecked
+ }
+ if ( props == null )
+ {
+ props = new Hashtable();
+ }
+
+ boolean doSimpleMerge = true;
+ final MetaTypeServiceSupport mtss = getMetaTypeSupport();
+ if ( mtss != null )
+ {
+ ObjectClassDefinition ocd = null;
+ if ( config != null )
+ {
+ ocd = mtss.getObjectClassDefinition( config, locale );
+ }
+ if ( ocd == null )
+ {
+ ocd = mtss.getObjectClassDefinition( pid, locale );
+ }
+ if ( ocd != null )
+ {
+ mtss.mergeWithMetaType( props, ocd, json );
+ doSimpleMerge = false;
+ }
+ }
+
+ if (doSimpleMerge)
+ {
+ json.key( "title" ).value( pid ); //$NON-NLS-1$
+ json.key( "description" ).value( //$NON-NLS-1$
+ "This form is automatically generated from existing properties because no property "
+ + "descriptors are available for this configuration. This may be cause by the absence "
+ + "of the OSGi Metatype Service or the absence of a MetaType descriptor for this configuration." );
+
+ json.key( "properties" ).object(); //$NON-NLS-1$
+ for ( Enumeration pe = props.keys(); pe.hasMoreElements(); )
+ {
+ final String id = ( String ) pe.nextElement();
+
+ // ignore well known special properties
+ if ( !id.equals( Constants.SERVICE_PID ) && !id.equals( Constants.SERVICE_DESCRIPTION )
+ && !id.equals( Constants.SERVICE_ID ) && !id.equals( Constants.SERVICE_VENDOR )
+ && !id.equals( ConfigurationAdmin.SERVICE_BUNDLELOCATION )
+ && !id.equals( ConfigurationAdmin.SERVICE_FACTORYPID ) )
+ {
+ final Object value = props.get( id );
+ final PropertyDescriptor ad = MetaTypeServiceSupport.createAttributeDefinition( id, value );
+ json.key( id );
+ MetaTypeServiceSupport.attributeToJson( json, ad, value );
+ }
+ }
+ json.endObject();
+ }
+
+ if ( config != null )
+ {
+ this.addConfigurationInfo( config, json, locale );
+ }
+ }
+
+
+ void addConfigurationInfo( Configuration config, JSONWriter json, String locale ) throws JSONException
+ {
+
+ if ( config.getFactoryPid() != null )
+ {
+ json.key( ConfigManager.factoryPID );
+ json.value( config.getFactoryPid() );
+ }
+
+ String location;
+ if ( config.getBundleLocation() == null )
+ {
+ location = ""; //$NON-NLS-1$
+ }
+ else
+ {
+ // if the configuration is bound to a bundle location which
+ // is not related to an installed bundle, we just print the
+ // raw bundle location binding
+ Bundle bundle = MetaTypeServiceSupport.getBundle( this.getBundleContext(), config.getBundleLocation() );
+ if ( bundle == null )
+ {
+ location = config.getBundleLocation();
+ }
+ else
+ {
+ Dictionary headers = bundle.getHeaders( locale );
+ String name = ( String ) headers.get( Constants.BUNDLE_NAME );
+ if ( name == null )
+ {
+ location = bundle.getSymbolicName();
+ }
+ else
+ {
+ location = name + " (" + bundle.getSymbolicName() + ')'; //$NON-NLS-1$
+ }
+
+ Version v = Version.parseVersion( ( String ) headers.get( Constants.BUNDLE_VERSION ) );
+ location += ", Version " + v.toString();
+ }
+ }
+ json.key( "bundleLocation" ); //$NON-NLS-1$
+ json.value( location );
+ // raw bundle location and service locations
+ final String pid = config.getPid();
+ String serviceLocation = ""; //$NON-NLS-1$
+ try
+ {
+ final ServiceReference[] refs = getBundleContext().getServiceReferences(
+ null,
+ "(&(" + Constants.OBJECTCLASS + '=' + ManagedService.class.getName() //$NON-NLS-1$
+ + ")(" + Constants.SERVICE_PID + '=' + pid + "))"); //$NON-NLS-1$ //$NON-NLS-2$
+ if ( refs != null && refs.length > 0 )
+ {
+ serviceLocation = refs[0].getBundle().getLocation();
+ }
+ }
+ catch (Throwable t)
+ {
+ configManager.log( "Error getting service associated with configuration " + pid, t );
+ }
+ json.key( "bundle_location" ); //$NON-NLS-1$
+ json.value ( config.getBundleLocation() );
+ json.key( "service_location" ); //$NON-NLS-1$
+ json.value ( serviceLocation );
+ }
+
+
+ private final Bundle getBoundBundle(Configuration config)
+ {
+ if (null == config)
+ return null;
+ final String location = config.getBundleLocation();
+ if (null == location)
+ return null;
+
+ final Bundle bundles[] = getBundleContext().getBundles();
+ for (int i = 0; bundles != null && i < bundles.length; i++)
+ {
+ if (bundles[i].getLocation().equals(location))
+ return bundles[i];
+
+ }
+ return null;
+ }
+
+
+ final void listConfigurations( JSONObject json, String pidFilter, String locale, Locale loc )
+ {
+ try
+ {
+ // start with ManagedService instances
+ Map optionsPlain = getServices(ManagedService.class.getName(), pidFilter,
+ locale, true);
+
+ // next are the MetaType informations without ManagedService
+ final MetaTypeServiceSupport mtss = getMetaTypeSupport();
+ if ( mtss != null )
+ {
+ addMetaTypeNames( optionsPlain, mtss.getPidObjectClasses( locale ), pidFilter, Constants.SERVICE_PID );
+ }
+
+ // add in existing configuration (not duplicating ManagedServices)
+ Configuration[] cfgs = this.service.listConfigurations(pidFilter);
+ for (int i = 0; cfgs != null && i < cfgs.length; i++)
+ {
+
+ // ignore configuration object if an entry already exists in the map
+ // or if it is invalid
+ final String pid = cfgs[i].getPid();
+ if (optionsPlain.containsKey(pid) || !ConfigManager.isAllowedPid(pid) )
+ {
+ continue;
+ }
+
+ // insert and entry for the PID
+ if ( mtss != null )
+ {
+ try
+ {
+ ObjectClassDefinition ocd = mtss.getObjectClassDefinition( cfgs[i], locale );
+ if ( ocd != null )
+ {
+ optionsPlain.put( pid, ocd.getName() );
+ continue;
+ }
+ }
+ catch ( IllegalArgumentException t )
+ {
+ // MetaTypeProvider.getObjectClassDefinition might throw illegal
+ // argument exception. So we must catch it here, otherwise the
+ // other configurations will not be shown
+ // See https://issues.apache.org/jira/browse/FELIX-2390
+ }
+ }
+
+ // no object class definition, use plain PID
+ optionsPlain.put( pid, pid );
+ }
+
+ for ( Iterator ii = optionsPlain.keySet().iterator(); ii.hasNext(); )
+ {
+ String id = ( String ) ii.next();
+ Object name = optionsPlain.get( id );
+
+ final Configuration config = this.getConfiguration( id );
+ JSONObject data = new JSONObject() //
+ .put( "id", id ) //$NON-NLS-1$
+ .put( "name", name ); //$NON-NLS-1$
+ if ( null != config )
+ {
+ final String fpid = config.getFactoryPid();
+ if ( null != fpid )
+ {
+ data.put( "fpid", fpid ); //$NON-NLS-1$
+ }
+
+ final Bundle bundle = getBoundBundle( config );
+ if ( null != bundle )
+ {
+ data.put( "bundle", bundle.getBundleId() ); //$NON-NLS-1$
+ data.put( "bundle_name", Util.getName( bundle, loc ) ); //$NON-NLS-1$
+ }
+ }
+
+ json.append( "pids", data ); //$NON-NLS-1$
+ }
+ }
+ catch (Exception e)
+ {
+ configManager.log("listConfigurations: Unexpected problem encountered", e);
+ }
+ }
+
+
+ final void listFactoryConfigurations(JSONObject json, String pidFilter,
+ String locale)
+ {
+ try
+ {
+ final Map optionsFactory = getServices(ManagedServiceFactory.class.getName(),
+ pidFilter, locale, true);
+ final MetaTypeServiceSupport mtss = getMetaTypeSupport();
+ if ( mtss != null )
+ {
+ addMetaTypeNames( optionsFactory, mtss.getFactoryPidObjectClasses( locale ), pidFilter,
+ ConfigurationAdmin.SERVICE_FACTORYPID );
+ }
+ for ( Iterator ii = optionsFactory.keySet().iterator(); ii.hasNext(); )
+ {
+ String id = ( String ) ii.next();
+ Object name = optionsFactory.get( id );
+ json.append( "fpids", new JSONObject() //$NON-NLS-1$
+ .put( "id", id ) //$NON-NLS-1$
+ .put( "name", name ) ); //$NON-NLS-1$
+ }
+ }
+ catch (Exception e)
+ {
+ configManager.log("listFactoryConfigurations: Unexpected problem encountered", e);
+ }
+ }
+
+ SortedMap getServices( String serviceClass, String serviceFilter, String locale,
+ boolean ocdRequired ) throws InvalidSyntaxException
+ {
+ // sorted map of options
+ SortedMap optionsFactory = new TreeMap( String.CASE_INSENSITIVE_ORDER );
+
+ // find all ManagedServiceFactories to get the factoryPIDs
+ ServiceReference[] refs = this.getBundleContext().getServiceReferences( serviceClass, serviceFilter );
+ for ( int i = 0; refs != null && i < refs.length; i++ )
+ {
+ Object pidObject = refs[i].getProperty( Constants.SERVICE_PID );
+ // only include valid PIDs
+ if ( pidObject instanceof String && ConfigManager.isAllowedPid((String)pidObject) )
+ {
+ String pid = ( String ) pidObject;
+ String name = pid;
+ boolean haveOcd = !ocdRequired;
+ final MetaTypeServiceSupport mtss = getMetaTypeSupport();
+ if ( mtss != null )
+ {
+ final ObjectClassDefinition ocd = mtss.getObjectClassDefinition( refs[i].getBundle(), pid, locale );
+ if ( ocd != null )
+ {
+ name = ocd.getName();
+ haveOcd = true;
+ }
+ }
+
+ if ( haveOcd )
+ {
+ optionsFactory.put( pid, name );
+ }
+ }
+ }
+
+ return optionsFactory;
+ }
+
+ private void addMetaTypeNames( final Map pidMap, final Map ocdCollection, final String filterSpec, final String type )
+ {
+ Filter filter = null;
+ if ( filterSpec != null )
+ {
+ try
+ {
+ filter = getBundleContext().createFilter( filterSpec );
+ }
+ catch ( InvalidSyntaxException not_expected )
+ {
+ /* filter is correct */
+ }
+ }
+
+ for ( Iterator ei = ocdCollection.entrySet().iterator(); ei.hasNext(); )
+ {
+ Entry ociEntry = ( Entry ) ei.next();
+ final String pid = ( String ) ociEntry.getKey();
+ final ObjectClassDefinition ocd = ( ObjectClassDefinition ) ociEntry.getValue();
+ if ( filter == null )
+ {
+ pidMap.put( pid, ocd.getName() );
+ }
+ else
+ {
+ final Dictionary props = new Hashtable();
+ props.put( type, pid );
+ if ( filter.match( props ) )
+ {
+ pidMap.put( pid, ocd.getName() );
+ }
+ }
+ }
+ }
+
+ private static class PlaceholderConfiguration implements Configuration
+ {
+
+ private final String factoryPid;
+ private String bundleLocation;
+
+
+ PlaceholderConfiguration( String factoryPid )
+ {
+ this.factoryPid = factoryPid;
+ }
+
+
+ public String getPid()
+ {
+ return ConfigManager.PLACEHOLDER_PID;
+ }
+
+
+ public String getFactoryPid()
+ {
+ return factoryPid;
+ }
+
+
+ public void setBundleLocation( String bundleLocation )
+ {
+ this.bundleLocation = bundleLocation;
+ }
+
+
+ public String getBundleLocation()
+ {
+ return bundleLocation;
+ }
+
+
+ public Dictionary getProperties()
+ {
+ // dummy configuration has no properties
+ return null;
+ }
+
+
+ public void update()
+ {
+ // dummy configuration cannot be updated
+ }
+
+
+ public void update( Dictionary properties )
+ {
+ // dummy configuration cannot be updated
+ }
+
+
+ public void delete()
+ {
+ // dummy configuration cannot be deleted
+ }
+
+ }
+}
Copied: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java (from r1418242, felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java)
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java?p2=felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java&p1=felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java&r1=1418242&r2=1425765&rev=1425765&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigManager.java Tue Dec 25 19:56:31 2012
@@ -14,57 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.felix.webconsole.internal.compendium;
+package org.apache.felix.webconsole.internal.configuration;
import java.io.IOException;
import java.io.PrintWriter;
-import java.lang.reflect.Array;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Hashtable;
import java.util.Iterator;
-import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Map.Entry;
-import java.util.SortedMap;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-import java.util.Vector;
-
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.webconsole.DefaultVariableResolver;
+import org.apache.felix.webconsole.SimpleWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleUtil;
-import org.apache.felix.webconsole.internal.Util;
-import org.json.JSONArray;
+import org.apache.felix.webconsole.internal.OsgiManagerPlugin;
import org.json.JSONException;
import org.json.JSONObject;
-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.metatype.AttributeDefinition;
-import org.osgi.service.metatype.ObjectClassDefinition;
/**
- * The <code>ConfigManager</code>
+ * The <code>ConfigManager</code> class is the Web Console plugin to
+ * manage configurations.
*/
-public class ConfigManager extends ConfigManagerBase
+public class ConfigManager extends SimpleWebConsolePlugin implements OsgiManagerPlugin
{
private static final long serialVersionUID = 5021174538498622428L;
@@ -73,25 +49,15 @@ public class ConfigManager extends Confi
private static final String TITLE = "%configMgr.pluginTitle"; //$NON-NLS-1$
private static final String CSS[] = { "/res/ui/config.css" }; //$NON-NLS-1$
- private static final String PID_FILTER = "pidFilter"; //$NON-NLS-1$
- private static final String PID = "pid"; //$NON-NLS-1$
- private static final String factoryPID = "factoryPid"; //$NON-NLS-1$
+ static final String PID_FILTER = "pidFilter"; //$NON-NLS-1$
+ static final String PID = "pid"; //$NON-NLS-1$
+ static final String factoryPID = "factoryPid"; //$NON-NLS-1$
- private static final String PLACEHOLDER_PID = "[Temporary PID replaced by real PID upon save]";
+ static final String CONFIGURATION_ADMIN_NAME = "org.osgi.service.cm.ConfigurationAdmin";
- /**
- * Attribute type code for PASSWORD attributes as defined in
- * Metatype Service Specification 1.2. Since we cannot yet refer
- * to the 1.2 API package we just replicate the type code here. Once
- * the API is available and can be referred to, we should use it.
- */
- private static final int ATTRIBUTE_TYPE_PASSWORD = 12;
+ static final String META_TYPE_NAME = "org.osgi.service.metatype.MetaTypeService";
- /**
- * Marker value of password fields used as dummy values and
- * indicating unmodified values.
- */
- private static final String PASSWORD_PLACEHOLDER_VALUE = "unmodified"; //$NON-NLS-1$
+ static final String PLACEHOLDER_PID = "[Temporary PID replaced by real PID upon save]";
// templates
private final String TEMPLATE;
@@ -105,7 +71,7 @@ public class ConfigManager extends Confi
TEMPLATE = readTemplateFile( "/templates/config.html" ); //$NON-NLS-1$
}
- private static final boolean isAllowedPid(final String pid)
+ static final boolean isAllowedPid(final String pid)
{
for(int i = 0; i < pid.length(); i++)
{
@@ -118,6 +84,22 @@ public class ConfigManager extends Confi
return true;
}
+
+ private static final Locale getLocale( HttpServletRequest request )
+ {
+ try
+ {
+ return request.getLocale();
+ }
+ catch ( Throwable t )
+ {
+ // expected in standard OSGi Servlet 2.1 environments
+ // fallback to using the default locale
+ return Locale.getDefault();
+ }
+ }
+
+
/**
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@@ -134,10 +116,10 @@ public class ConfigManager extends Confi
// the filter to select part of the configurations
String pidFilter = request.getParameter( PID_FILTER );
- final ConfigurationAdmin ca = this.getConfigurationAdmin();
+ final ConfigAdminSupport cas = getConfigurationAdminSupport();
// ignore this request if the PID and/or configuration admin is missing
- if ( pid == null || pid.length() == 0 || ca == null )
+ if ( pid == null || pid.length() == 0 || cas == null )
{
// should log this here !!
return;
@@ -161,12 +143,12 @@ public class ConfigManager extends Confi
// should actually apply the configuration before redirecting
if ( request.getParameter( "create" ) != null ) //$NON-NLS-1$
{
- config = new PlaceholderConfiguration( pid ); // ca.createFactoryConfiguration( pid, null );
+ config = cas.getPlaceholderConfiguration( pid ); // ca.createFactoryConfiguration( pid, null );
pid = config.getPid();
}
else if ( request.getParameter( "apply" ) != null ) //$NON-NLS-1$
{
- String redirect = applyConfiguration( request, ca, pid );
+ String redirect = cas.applyConfiguration( request, pid );
if ( redirect != null )
{
if (pidFilter != null) {
@@ -186,7 +168,7 @@ public class ConfigManager extends Confi
if ( config == null )
{
- config = getConfiguration( ca, pid );
+ config = cas.getConfiguration( pid );
}
// check for configuration unbinding
@@ -217,7 +199,7 @@ public class ConfigManager extends Confi
response.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
final Locale loc = getLocale( request );
final String locale = ( loc != null ) ? loc.toString() : null;
- printConfigurationJson( response.getWriter(), pid, config, pidFilter, locale );
+ cas.printConfigurationJson( response.getWriter(), pid, config, pidFilter, locale );
}
@@ -271,38 +253,40 @@ public class ConfigManager extends Confi
response.sendError(500);
}
- final ConfigurationAdmin ca = this.getConfigurationAdmin();
final Locale loc = getLocale( request );
final String locale = ( loc != null ) ? loc.toString() : null;
final PrintWriter pw = response.getWriter();
-
- try
+ pw.write( "[" ); //$NON-NLS-1$
+ final ConfigAdminSupport ca = this.getConfigurationAdminSupport();
+ if ( ca != null )
{
- pw.write( "[" ); //$NON-NLS-1$
- final Map services = this.getServices( pid, pidFilter, locale, false );
- boolean printColon = false;
- for ( Iterator spi = services.keySet().iterator(); spi.hasNext(); )
+ try
{
- final String servicePid = ( String ) spi.next();
- final Configuration config = getConfiguration( ca, servicePid );
- if ( config != null )
+ final Map services = ca.getServices( pid, pidFilter, locale, false );
+ boolean printComma = false;
+ for ( Iterator spi = services.keySet().iterator(); spi.hasNext(); )
{
- if ( printColon )
+ final String servicePid = ( String ) spi.next();
+ final Configuration config = ca.getConfiguration( servicePid );
+ if ( config != null )
{
- pw.print( ',' );
+ if ( printComma )
+ {
+ pw.print( ',' );
+ }
+ ca.printConfigurationJson( pw, servicePid, config, pidFilter, locale );
+ printComma = true;
}
- this.printConfigurationJson( pw, servicePid, config, pidFilter, locale );
- printColon = true;
}
}
- pw.write( "]" ); //$NON-NLS-1$
- }
- catch ( InvalidSyntaxException e )
- {
- // this should not happened as we checked the filter before
+ catch ( InvalidSyntaxException e )
+ {
+ // this should not happened as we checked the filter before
+ }
}
+ pw.write( "]" ); //$NON-NLS-1$
// nothing more to do
return;
@@ -361,7 +345,6 @@ public class ConfigManager extends Confi
{
response.sendError(500);
}
- final ConfigurationAdmin ca = this.getConfigurationAdmin();
final Locale loc = getLocale( request );
final String locale = ( loc != null ) ? loc.toString() : null;
@@ -370,11 +353,12 @@ public class ConfigManager extends Confi
JSONObject json = new JSONObject();
try
{
+ final ConfigAdminSupport ca = getConfigurationAdminSupport();
json.put("status", ca != null ? Boolean.TRUE : Boolean.FALSE); //$NON-NLS-1$
if ( ca != null )
{
- listConfigurations( json, ca, pidFilter, locale, loc );
- listFactoryConfigurations( json, pidFilter, locale );
+ ca.listConfigurations( json, pidFilter, locale, loc );
+ ca.listFactoryConfigurations( json, pidFilter, locale );
}
}
catch (JSONException e)
@@ -385,7 +369,7 @@ public class ConfigManager extends Confi
// if a configuration is addressed, display it immediately
if ( request.getParameter( "create" ) != null && pid != null ) //$NON-NLS-1$
{
- pid = new PlaceholderConfiguration( pid ).getPid();
+ pid = PLACEHOLDER_PID; // new PlaceholderConfiguration( pid ).getPid();
}
@@ -397,1015 +381,16 @@ public class ConfigManager extends Confi
response.getWriter().print(TEMPLATE);
}
-
- private static final Configuration getConfiguration( ConfigurationAdmin ca, String pid )
- {
- if ( ca != null && pid != null )
- {
- try
- {
- // we use listConfigurations to not create configuration
- // objects persistently without the user providing actual
- // configuration
- String filter = '(' + Constants.SERVICE_PID + '=' + pid + ')';
- Configuration[] configs = ca.listConfigurations( filter );
- if ( configs != null && configs.length > 0 )
- {
- return configs[0];
- }
- }
- catch ( InvalidSyntaxException ise )
- {
- // should print message
- }
- catch ( IOException ioe )
- {
- // should print message
- }
- }
-
- // fallback to no configuration at all
- return null;
- }
-
-
- private final void listFactoryConfigurations(JSONObject json, String pidFilter,
- String locale)
- {
- try
- {
- Map optionsFactory = getServices(ManagedServiceFactory.class.getName(),
- pidFilter, locale, true);
- addMetaTypeNames(optionsFactory, getFactoryPidObjectClasses(locale),
- pidFilter, ConfigurationAdmin.SERVICE_FACTORYPID);
- for ( Iterator ii = optionsFactory.keySet().iterator(); ii.hasNext(); )
- {
- String id = ( String ) ii.next();
- Object name = optionsFactory.get( id );
- json.append( "fpids", new JSONObject() //$NON-NLS-1$
- .put( "id", id ) //$NON-NLS-1$
- .put( "name", name ) ); //$NON-NLS-1$
- }
- }
- catch (Exception e)
- {
- log("listFactoryConfigurations: Unexpected problem encountered", e);
- }
- }
-
- private final void listConfigurations(JSONObject json, ConfigurationAdmin ca,
- String pidFilter, String locale, Locale loc)
- {
- try
- {
- // start with ManagedService instances
- Map 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);
- for (int i = 0; cfgs != null && i < cfgs.length; i++)
- {
-
- // ignore configuration object if an entry already exists in the map
- // or if it is invalid
- final String pid = cfgs[i].getPid();
- if (optionsPlain.containsKey(pid) || !isAllowedPid(pid) )
- {
- continue;
- }
-
- // insert and entry for the PID
- ObjectClassDefinition ocd = null;
- try
- {
- ocd = this.getObjectClassDefinition(cfgs[i], locale);
- }
- catch (IllegalArgumentException t)
- {
- // MetaTypeProvider.getObjectClassDefinition might throw illegal
- // argument exception. So we must catch it here, otherwise the
- // other configurations will not be shown
- // See https://issues.apache.org/jira/browse/FELIX-2390
- }
-
- if (ocd != null)
- {
- optionsPlain.put(pid, ocd.getName());
- }
- else
- {
- optionsPlain.put(pid, pid);
- }
- }
-
- for ( Iterator ii = optionsPlain.keySet().iterator(); ii.hasNext(); )
- {
- String id = ( String ) ii.next();
- Object name = optionsPlain.get( id );
-
- final Configuration config = getConfiguration( ca, id );
- JSONObject data = new JSONObject() //
- .put( "id", id ) //$NON-NLS-1$
- .put( "name", name ); //$NON-NLS-1$
- if ( null != config )
- {
- final String fpid = config.getFactoryPid();
- if ( null != fpid )
- {
- data.put( "fpid", fpid ); //$NON-NLS-1$
- }
-
- final Bundle bundle = getBoundBundle( config );
- if ( null != bundle )
- {
- data.put( "bundle", bundle.getBundleId() ); //$NON-NLS-1$
- data.put( "bundle_name", Util.getName( bundle, loc ) ); //$NON-NLS-1$
- }
- }
-
- json.append( "pids", data ); //$NON-NLS-1$
- }
- }
- catch (Exception e)
- {
- log("listConfigurations: Unexpected problem encountered", e);
- }
- }
-
- private final Bundle getBoundBundle(Configuration config)
+ private ConfigAdminSupport getConfigurationAdminSupport()
{
- if (null == config)
- return null;
- final String location = config.getBundleLocation();
- if (null == location)
- return null;
-
- final Bundle bundles[] = getBundleContext().getBundles();
- for (int i = 0; bundles != null && i < bundles.length; i++)
+ Object configurationAdmin = getService( CONFIGURATION_ADMIN_NAME );
+ if ( configurationAdmin != null )
{
- if (bundles[i].getLocation().equals(location))
- return bundles[i];
-
+ return new ConfigAdminSupport( this, this.getBundleContext(), configurationAdmin );
}
return null;
}
- private SortedMap getServices( String serviceClass, String serviceFilter, String locale,
- boolean ocdRequired ) throws InvalidSyntaxException
- {
- // sorted map of options
- SortedMap optionsFactory = new TreeMap( String.CASE_INSENSITIVE_ORDER );
-
- // find all ManagedServiceFactories to get the factoryPIDs
- ServiceReference[] refs = this.getBundleContext().getServiceReferences( serviceClass, serviceFilter );
- for ( int i = 0; refs != null && i < refs.length; i++ )
- {
- Object pidObject = refs[i].getProperty( Constants.SERVICE_PID );
- // only include valid PIDs
- if ( pidObject instanceof String && isAllowedPid((String)pidObject) )
- {
- String pid = ( String ) pidObject;
- String name;
- final ObjectClassDefinition ocd = this.getObjectClassDefinition( refs[i].getBundle(), pid, locale );
- if ( ocd != null )
- {
- name = ocd.getName();
- }
- else
- {
- name = pid;
- }
-
- if ( !ocdRequired || ocd != null ) {
- optionsFactory.put( pid, name );
- }
- }
- }
-
- return optionsFactory;
- }
-
-
- private void addMetaTypeNames( final Map pidMap, final Map ocdCollection, final String filterSpec, final String type )
- {
- Filter filter = null;
- if ( filterSpec != null )
- {
- try
- {
- filter = getBundleContext().createFilter( filterSpec );
- }
- catch ( InvalidSyntaxException not_expected )
- {
- /* filter is correct */
- }
- }
-
- for ( Iterator ei = ocdCollection.entrySet().iterator(); ei.hasNext(); )
- {
- Entry ociEntry = ( Entry ) ei.next();
- final String pid = ( String ) ociEntry.getKey();
- final ObjectClassDefinition ocd = ( ObjectClassDefinition ) ociEntry.getValue();
- if ( filter == null )
- {
- pidMap.put( pid, ocd.getName() );
- }
- else
- {
- final Dictionary props = new Hashtable();
- props.put( type, pid );
- if ( filter.match( props ) )
- {
- pidMap.put( pid, ocd.getName() );
- }
- }
- }
- }
-
-
- private void printConfigurationJson( PrintWriter pw, String pid, Configuration config, String pidFilter,
- String locale )
- {
-
- JSONWriter result = new JSONWriter( pw );
-
- if ( pid != null )
- {
- try
- {
- result.object();
- this.configForm( result, pid, config, pidFilter, locale );
- result.endObject();
- }
- catch ( Exception e )
- {
- log( "Error reading configuration PID " + pid, e );
- }
- }
-
- }
-
-
- private void configForm( JSONWriter json, String pid, Configuration config, String pidFilter, String locale )
- throws JSONException
- {
-
- json.key( ConfigManager.PID );
- json.value( pid );
-
- if ( pidFilter != null )
- {
- json.key( PID_FILTER );
- json.value( pidFilter );
- }
-
- Dictionary props = null;
- ObjectClassDefinition ocd = null;
- if ( config != null )
- {
- props = config.getProperties(); // unchecked
- ocd = this.getObjectClassDefinition( config, locale );
- }
- if (ocd == null)
- {
- ocd = this.getObjectClassDefinition( pid, locale );
- }
-
- if ( props == null )
- {
- props = new Hashtable();
- }
-
- if ( ocd != null )
- {
- mergeWithMetaType( props, ocd, json );
- }
- else
- {
- json.key( "title" ).value( pid ); //$NON-NLS-1$
- json.key( "description" ).value( //$NON-NLS-1$
- "This form is automatically generated from existing properties because no property "
- + "descriptors are available for this configuration. This may be cause by the absence "
- + "of the OSGi Metatype Service or the absence of a MetaType descriptor for this configuration." );
-
- json.key( "properties" ).object(); //$NON-NLS-1$
- for ( Enumeration pe = props.keys(); pe.hasMoreElements(); )
- {
- final String id = ( String ) pe.nextElement();
-
- // ignore well known special properties
- if ( !id.equals( Constants.SERVICE_PID ) && !id.equals( Constants.SERVICE_DESCRIPTION )
- && !id.equals( Constants.SERVICE_ID ) && !id.equals( Constants.SERVICE_VENDOR )
- && !id.equals( ConfigurationAdmin.SERVICE_BUNDLELOCATION )
- && !id.equals( ConfigurationAdmin.SERVICE_FACTORYPID ) )
- {
- final Object value = props.get( id );
- final AttributeDefinition ad = getAttributeDefinition( id, value );
- json.key( id );
- attributeToJson( json, ad, value );
- }
- }
- json.endObject();
- }
-
- if ( config != null )
- {
- this.addConfigurationInfo( config, json, locale );
- }
- }
-
-
- private static final void mergeWithMetaType( Dictionary props, ObjectClassDefinition ocd, JSONWriter json ) throws JSONException
- {
- json.key( "title" ).value( ocd.getName() ); //$NON-NLS-1$
-
- if ( ocd.getDescription() != null )
- {
- json.key( "description" ).value( ocd.getDescription() ); //$NON-NLS-1$
- }
-
- AttributeDefinition[] ad = ocd.getAttributeDefinitions( ObjectClassDefinition.ALL );
- if ( ad != null )
- {
- json.key( "properties" ).object(); //$NON-NLS-1$
- for ( int i = 0; i < ad.length; i++ )
- {
- final AttributeDefinition adi = ad[i];
- final String attrId = adi.getID();
- json.key( attrId );
- attributeToJson( json, adi, props.get( attrId ) );
- }
- json.endObject();
- }
- }
-
-
- private void addConfigurationInfo( Configuration config, JSONWriter json, String locale ) throws JSONException
- {
-
- if ( config.getFactoryPid() != null )
- {
- json.key( factoryPID );
- json.value( config.getFactoryPid() );
- }
-
- String location;
- if ( config.getBundleLocation() == null )
- {
- location = ""; //$NON-NLS-1$
- }
- else
- {
- // if the configuration is bound to a bundle location which
- // is not related to an installed bundle, we just print the
- // raw bundle location binding
- Bundle bundle = this.getBundle( config.getBundleLocation() );
- if ( bundle == null )
- {
- location = config.getBundleLocation();
- }
- else
- {
- Dictionary headers = bundle.getHeaders( locale );
- String name = ( String ) headers.get( Constants.BUNDLE_NAME );
- if ( name == null )
- {
- location = bundle.getSymbolicName();
- }
- else
- {
- location = name + " (" + bundle.getSymbolicName() + ')'; //$NON-NLS-1$
- }
-
- Version v = Version.parseVersion( ( String ) headers.get( Constants.BUNDLE_VERSION ) );
- location += ", Version " + v.toString();
- }
- }
- json.key( "bundleLocation" ); //$NON-NLS-1$
- json.value( location );
- // raw bundle location and service locations
- final String pid = config.getPid();
- String serviceLocation = ""; //$NON-NLS-1$
- try
- {
- final ServiceReference[] refs = getBundleContext().getServiceReferences(
- null,
- "(&(" + Constants.OBJECTCLASS + '=' + ManagedService.class.getName() //$NON-NLS-1$
- + ")(" + Constants.SERVICE_PID + '=' + pid + "))"); //$NON-NLS-1$ //$NON-NLS-2$
- if ( refs != null && refs.length > 0 )
- {
- serviceLocation = refs[0].getBundle().getLocation();
- }
- }
- catch (Throwable t)
- {
- log( "Error getting service associated with configuration " + pid, t );
- }
- json.key( "bundle_location" ); //$NON-NLS-1$
- json.value ( config.getBundleLocation() );
- json.key( "service_location" ); //$NON-NLS-1$
- json.value ( serviceLocation );
- }
-
-
- private String applyConfiguration( HttpServletRequest request, ConfigurationAdmin ca, String pid )
- throws IOException
- {
- if ( request.getParameter( "delete" ) != null ) //$NON-NLS-1$
- {
- // only delete if the PID is not our place holder
- if ( !PLACEHOLDER_PID.equals( pid ) )
- {
- log( "applyConfiguration: Deleting configuration " + pid );
- Configuration config = ca.getConfiguration( pid, null );
- config.delete();
- }
- return null; // return request.getHeader( "Referer" );
- }
-
- String factoryPid = request.getParameter( ConfigManager.factoryPID );
- Configuration config = null;
-
- String propertyList = request.getParameter( "propertylist" ); //$NON-NLS-1$
- if ( propertyList == null )
- {
- // FIXME: this would be a bug !!
- }
- else
- {
- config = getConfiguration( ca, pid, factoryPid );
-
- Dictionary props = config.getProperties();
- if ( props == null )
- {
- props = new Hashtable();
- }
-
- Map adMap = this.getAttributeDefinitionMap( config, null );
- StringTokenizer propTokens = new StringTokenizer( propertyList, "," ); //$NON-NLS-1$
- while ( propTokens.hasMoreTokens() )
- {
- String propName = propTokens.nextToken();
- AttributeDefinition ad = (AttributeDefinition) adMap.get( propName );
-
- // try to derive from current value
- if (ad == null) {
- Object currentValue = props.get( propName );
- ad = getAttributeDefinition( propName, currentValue );
- }
-
- int attributeType = getAttributeType( ad );
-
- if ( ad == null
- || ( ad.getCardinality() == 0 && ( attributeType == AttributeDefinition.STRING || attributeType == ATTRIBUTE_TYPE_PASSWORD ) ) )
- {
- String prop = request.getParameter( propName );
- if ( prop != null
- && ( attributeType != ATTRIBUTE_TYPE_PASSWORD || !PASSWORD_PLACEHOLDER_VALUE.equals( prop ) ) )
- {
- props.put( propName, prop );
- }
- }
- else if ( ad.getCardinality() == 0 )
- {
- // scalar of non-string
- String prop = request.getParameter( propName );
- if ( prop != null )
- {
- try
- {
- props.put( propName, toType( attributeType, prop ) );
- }
- catch ( NumberFormatException nfe )
- {
- // don't care
- }
- }
- }
- else
- {
- // array or vector of any type
- Vector vec = new Vector();
-
- String[] properties = request.getParameterValues( propName );
- if ( properties != null )
- {
- if ( attributeType == ATTRIBUTE_TYPE_PASSWORD )
- {
- setPasswordProps( vec, properties, props.get( propName ) );
- }
- else
- {
- for ( int i = 0; i < properties.length; i++ )
- {
- try
- {
- vec.add( toType( attributeType, properties[i] ) );
- }
- catch ( NumberFormatException nfe )
- {
- // don't care
- }
- }
- }
- }
-
- // but ensure size (check for positive value since
- // abs(Integer.MIN_VALUE) is still INTEGER.MIN_VALUE)
- int maxSize = Math.abs( ad.getCardinality() );
- if ( vec.size() > maxSize && maxSize > 0 )
- {
- vec.setSize( maxSize );
- }
-
- if ( ad.getCardinality() < 0 )
- {
- // keep the vector, but only add if not empty
- if ( vec.isEmpty() )
- {
- props.remove( propName );
- }
- else
- {
- props.put( propName, vec );
- }
- }
- else
- {
- // convert to an array
- props.put( propName, toArray( attributeType, vec ) );
- }
- }
- }
-
- config.update( props );
- }
-
- // redirect to the new configuration (if existing)
- return (config != null) ? config.getPid() : ""; //$NON-NLS-1$
- }
-
-
- private static final Configuration getConfiguration( ConfigurationAdmin ca, String pid, String factoryPid ) throws IOException
- {
- if ( factoryPid != null && ( pid == null || pid.equals( PLACEHOLDER_PID ) ) )
- {
- return ca.createFactoryConfiguration( factoryPid, null );
- }
-
- return ca.getConfiguration( pid, null );
- }
-
-
- private static void attributeToJson( final JSONWriter json, final AttributeDefinition ad, final Object propValue )
- throws JSONException
- {
- json.object();
-
- Object value;
- if ( propValue != null )
- {
- value = propValue;
- }
- else if ( ad.getDefaultValue() != null )
- {
- value = ad.getDefaultValue();
- }
- else if ( ad.getCardinality() == 0 )
- {
- value = ""; //$NON-NLS-1$
- }
- else
- {
- value = new String[0];
- }
-
- json.key( "name" ); //$NON-NLS-1$
- json.value( ad.getName() );
-
- // attribute type - overwrite metatype provided type
- // if the property name contains "password" and the
- // type is string
- int propertyType = getAttributeType( ad );
-
- json.key( "type" ); //$NON-NLS-1$
- if ( ad.getOptionLabels() != null && ad.getOptionLabels().length > 0 )
- {
- json.object();
- json.key( "labels" ); //$NON-NLS-1$
- json.value( Arrays.asList( ad.getOptionLabels() ) );
- json.key( "values" ); //$NON-NLS-1$
- json.value( Arrays.asList( ad.getOptionValues() ) );
- json.endObject();
- }
- else
- {
- json.value( propertyType );
- }
-
- // unless the property is of password type, send it
- final boolean isPassword = propertyType == ATTRIBUTE_TYPE_PASSWORD;
- if ( ad.getCardinality() == 0 )
- {
- // scalar
- if ( isPassword )
- {
- value = PASSWORD_PLACEHOLDER_VALUE;
- }
- else if ( value instanceof Vector )
- {
- value = ( ( Vector ) value ).get( 0 );
- }
- else if ( value.getClass().isArray() )
- {
- value = Array.get( value, 0 );
- }
- json.key( "value" ); //$NON-NLS-1$
- json.value( value );
- }
- else
- {
- value = new JSONArray( toList( value ) );
- if ( isPassword )
- {
- JSONArray tmp = ( JSONArray ) value;
- for ( int tmpI = 0; tmpI < tmp.length(); tmpI++ )
- {
- tmp.put( tmpI, PASSWORD_PLACEHOLDER_VALUE );
- }
- }
- json.key( "values" ); //$NON-NLS-1$
- json.value( value );
- }
-
- if ( ad.getDescription() != null )
- {
- json.key( "description" ); //$NON-NLS-1$
- json.value( ad.getDescription() + " (" + ad.getID() + ")" ); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- json.endObject();
- }
-
-
- private static AttributeDefinition getAttributeDefinition( final String id, final Object value )
- {
- int attrType;
- int attrCardinality;
- Class type;
-
- if ( value == null )
- {
- attrCardinality = 0;
- type = String.class;
- }
- else if ( value instanceof Collection )
- {
- attrCardinality = Integer.MIN_VALUE;
- Collection coll = ( Collection ) value;
- if ( coll.isEmpty() )
- {
- type = String.class;
- }
- else
- {
- type = coll.iterator().next().getClass();
- }
- }
- else if ( value.getClass().isArray() )
- {
- attrCardinality = Integer.MAX_VALUE;
- type = value.getClass().getComponentType();
- }
- else
- {
- attrCardinality = 0;
- type = value.getClass();
- }
-
- if ( type == Boolean.class || type == Boolean.TYPE )
- {
- attrType = AttributeDefinition.BOOLEAN;
- }
- else if ( type == Byte.class || type == Byte.TYPE )
- {
- attrType = AttributeDefinition.BYTE;
- }
- else if ( type == Character.class || type == Character.TYPE )
- {
- attrType = AttributeDefinition.CHARACTER;
- }
- else if ( type == Double.class || type == Double.TYPE )
- {
- attrType = AttributeDefinition.DOUBLE;
- }
- else if ( type == Float.class || type == Float.TYPE )
- {
- attrType = AttributeDefinition.FLOAT;
- }
- else if ( type == Long.class || type == Long.TYPE )
- {
- attrType = AttributeDefinition.LONG;
- }
- else if ( type == Integer.class || type == Integer.TYPE )
- {
- attrType = AttributeDefinition.INTEGER;
- }
- else if ( type == Short.class || type == Short.TYPE )
- {
- attrType = AttributeDefinition.SHORT;
- }
- else
- {
- attrType = AttributeDefinition.STRING;
- }
-
- return new PlaceholderAttributeDefinition( id, attrType, attrCardinality );
- }
-
- private static boolean isPasswordProperty(String name)
- {
- return name == null ? false : name.toLowerCase().indexOf("password") != -1; //$NON-NLS-1$
- }
-
- private static int getAttributeType( final AttributeDefinition ad )
- {
- if ( ad.getType() == AttributeDefinition.STRING && isPasswordProperty( ad.getID() ) )
- {
- return ATTRIBUTE_TYPE_PASSWORD;
- }
- return ad.getType();
- }
-
-
- /**
- * @throws NumberFormatException If the value cannot be converted to
- * a number and type indicates a numeric type
- */
- private static final Object toType( int type, String value )
- {
- switch ( type )
- {
- case AttributeDefinition.BOOLEAN:
- return Boolean.valueOf( value );
- case AttributeDefinition.BYTE:
- return Byte.valueOf( value );
- case AttributeDefinition.CHARACTER:
- char c = ( value.length() > 0 ) ? value.charAt( 0 ) : 0;
- return new Character( c );
- case AttributeDefinition.DOUBLE:
- return Double.valueOf( value );
- case AttributeDefinition.FLOAT:
- return Float.valueOf( value );
- case AttributeDefinition.LONG:
- return Long.valueOf( value );
- case AttributeDefinition.INTEGER:
- return Integer.valueOf( value );
- case AttributeDefinition.SHORT:
- return Short.valueOf( value );
- default:
- // includes AttributeDefinition.STRING
- // includes ATTRIBUTE_TYPE_PASSWORD/AttributeDefinition.PASSWORD
- return value;
- }
- }
-
-
- private static List toList( Object value )
- {
- if ( value instanceof Vector )
- {
- return ( Vector ) value;
- }
- else if ( value.getClass().isArray() )
- {
- if ( value.getClass().getComponentType().isPrimitive() )
- {
- final int len = Array.getLength( value );
- final Object[] tmp = new Object[len];
- for ( int j = 0; j < len; j++ )
- {
- tmp[j] = Array.get( value, j );
- }
- value = tmp;
- }
- return Arrays.asList( ( Object[] ) value );
- }
- else
- {
- return Collections.singletonList( value );
- }
- }
-
-
- private static void setPasswordProps( final Vector vec, final String[] properties, Object props )
- {
- List propList = toList( props );
- for ( int i = 0; i < properties.length; i++ )
- {
- if ( PASSWORD_PLACEHOLDER_VALUE.equals( properties[i] ) )
- {
- if ( i < propList.size() && propList.get( i ) != null )
- {
- vec.add( propList.get( i ) );
- }
- }
- else
- {
- vec.add( properties[i] );
- }
- }
- }
-
-
- private static final Object toArray( int type, Vector values )
- {
- int size = values.size();
-
- // short cut for string array
- if ( type == AttributeDefinition.STRING || type == ATTRIBUTE_TYPE_PASSWORD )
- {
- return values.toArray( new String[size] );
- }
-
- Object array;
- switch ( type )
- {
- case AttributeDefinition.BOOLEAN:
- array = new boolean[size];
- break;
- case AttributeDefinition.BYTE:
- array = new byte[size];
- break;
- case AttributeDefinition.CHARACTER:
- array = new char[size];
- break;
- case AttributeDefinition.DOUBLE:
- array = new double[size];
- break;
- case AttributeDefinition.FLOAT:
- array = new float[size];
- break;
- case AttributeDefinition.LONG:
- array = new long[size];
- break;
- case AttributeDefinition.INTEGER:
- array = new int[size];
- break;
- case AttributeDefinition.SHORT:
- array = new short[size];
- break;
- default:
- // unexpected, but assume string
- array = new String[size];
- }
-
- for ( int i = 0; i < size; i++ )
- {
- Array.set( array, i, values.get( i ) );
- }
-
- return array;
- }
-
- private static class PlaceholderConfiguration implements Configuration
- {
-
- private final String factoryPid;
- private String bundleLocation;
-
-
- PlaceholderConfiguration( String factoryPid )
- {
- this.factoryPid = factoryPid;
- }
-
-
- public String getPid()
- {
- return PLACEHOLDER_PID;
- }
-
-
- public String getFactoryPid()
- {
- return factoryPid;
- }
-
-
- public void setBundleLocation( String bundleLocation )
- {
- this.bundleLocation = bundleLocation;
- }
-
-
- public String getBundleLocation()
- {
- return bundleLocation;
- }
-
-
- public Dictionary getProperties()
- {
- // dummy configuration has no properties
- return null;
- }
-
-
- public void update()
- {
- // dummy configuration cannot be updated
- }
-
-
- public void update( Dictionary properties )
- {
- // dummy configuration cannot be updated
- }
-
-
- public void delete()
- {
- // dummy configuration cannot be deleted
- }
-
- }
-
- private static class PlaceholderAttributeDefinition implements AttributeDefinition
- {
-
- final String id;
- final int type;
- final int cardinality;
-
-
- public PlaceholderAttributeDefinition( final String id, int type, int cardinality )
- {
- this.id = id;
- this.type = type;
- this.cardinality = cardinality;
- }
-
-
- public String getName()
- {
- return id;
- }
-
-
- public String getID()
- {
- return id;
- }
-
-
- public String getDescription()
- {
- // no description
- return null;
- }
-
-
- public int getCardinality()
- {
- return cardinality;
- }
-
-
- public int getType()
- {
- return type;
- }
-
-
- public String[] getOptionValues()
- {
- return null;
- }
-
-
- public String[] getOptionLabels()
- {
- return null;
- }
-
-
- public String validate( String value )
- {
- // no validation
- return null;
- }
-
-
- public String[] getDefaultValue()
- {
- return null;
- }
- }
}
+
Copied: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigurationAdminConfigurationPrinter.java (from r1418242, felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java)
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigurationAdminConfigurationPrinter.java?p2=felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigurationAdminConfigurationPrinter.java&p1=felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java&r1=1418242&r2=1425765&rev=1425765&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigurationAdminConfigurationPrinter.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/ConfigurationAdminConfigurationPrinter.java Tue Dec 25 19:56:31 2012
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.felix.webconsole.internal.compendium;
+package org.apache.felix.webconsole.internal.configuration;
import java.io.PrintWriter;
import java.util.Dictionary;
@@ -55,7 +55,7 @@ public class ConfigurationAdminConfigura
*/
public void printConfiguration(PrintWriter pw)
{
- ServiceReference sr = getBundleContext().getServiceReference( ConfigManagerBase.CONFIGURATION_ADMIN_NAME );
+ ServiceReference sr = getBundleContext().getServiceReference( ConfigManager.CONFIGURATION_ADMIN_NAME );
if (sr == null)
{
pw.println("Status: Configuration Admin Service not available");