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 [2/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/

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java?rev=1425765&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeServiceSupport.java Tue Dec 25 19:56:31 2012
@@ -0,0 +1,328 @@
+/*
+ * 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.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import org.json.JSONException;
+import org.json.JSONWriter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.metatype.AttributeDefinition;
+import org.osgi.service.metatype.MetaTypeInformation;
+import org.osgi.service.metatype.MetaTypeService;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+
+/**
+ * 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 descriptions.
+ */
+class MetaTypeServiceSupport extends MetaTypeSupport
+{
+
+    private final BundleContext bundleContext;
+
+    private final MetaTypeService service;
+
+    /**
+     *
+     * @param bundleContext
+     * @param service
+     *
+     * @throws ClassCastException if {@code service} is not a MetaTypeService instances
+     */
+    MetaTypeServiceSupport( final BundleContext bundleContext, final Object service )
+    {
+        super();
+        this.bundleContext = bundleContext;
+        this.service = ( MetaTypeService ) service;
+    }
+
+    public BundleContext getBundleContext()
+    {
+        return bundleContext;
+    }
+
+    public MetaTypeService getMetaTypeService()
+    {
+        return service;
+    }
+
+
+    /**
+     * 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.
+     *
+     * @param locale The name of the locale to get the meta data for.
+     * @return see the method description
+     */
+    Map getPidObjectClasses( final String locale )
+    {
+        return getObjectClassDefinitions( 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.
+     *
+     * @param locale The name of the locale to get the meta data for.
+     * @return see the method description
+     */
+    Map getFactoryPidObjectClasses( final String locale )
+    {
+        return getObjectClassDefinitions( 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> objects.
+     * @param locale The name of the locale to get the object class definitions
+     *          for.
+     * @return Map of <code>ObjectClassDefinition</code> objects indexed by the
+     *      PID (or factory PID) to which they pertain
+     */
+    private Map getObjectClassDefinitions( final IdGetter idGetter, final String locale )
+    {
+        final Map objectClassesDefinitions = new HashMap();
+        final MetaTypeService mts = this.getMetaTypeService();
+        if ( mts != null )
+        {
+            final Bundle[] bundles = this.getBundleContext().getBundles();
+            for ( int i = 0; i < bundles.length; i++ )
+            {
+                final MetaTypeInformation mti = mts.getMetaTypeInformation( bundles[i] );
+                if ( mti != null )
+                {
+                    final String[] idList = idGetter.getIds( mti );
+                    for ( int j = 0; idList != null && j < idList.length; j++ )
+                    {
+                        // After getting the list of PIDs, a configuration  might be
+                        // removed. So the getObjectClassDefinition will throw
+                        // an exception, and this will prevent ALL configuration from
+                        // being displayed. By catching it, the configurations will be
+                        // visible
+                        ObjectClassDefinition ocd = null;
+                        try
+                        {
+                            ocd = mti.getObjectClassDefinition( idList[j], locale );
+                        }
+                        catch ( IllegalArgumentException ignore )
+                        {
+                            // ignore - just don't show this configuration
+                        }
+                        if ( ocd != null )
+                        {
+                            objectClassesDefinitions.put( idList[j], ocd );
+                        }
+                    }
+                }
+            }
+        }
+        return objectClassesDefinitions;
+    }
+
+
+    ObjectClassDefinition getObjectClassDefinition( Configuration config, String locale )
+    {
+        // if the configuration is bound, try to get the object class
+        // definition from the bundle installed from the given location
+        if ( config.getBundleLocation() != null )
+        {
+            Bundle bundle = getBundle( this.getBundleContext(), config.getBundleLocation() );
+            if ( bundle != null )
+            {
+                String id = config.getFactoryPid();
+                if ( null == id )
+                {
+                    id = config.getPid();
+                }
+                return getObjectClassDefinition( bundle, id, locale );
+            }
+        }
+
+        // get here if the configuration is not bound or if no
+        // bundle with the bound location is installed. We search
+        // all bundles for a matching [factory] PID
+        // if the configuration is a factory one, use the factory PID
+        if ( config.getFactoryPid() != null )
+        {
+            return this.getObjectClassDefinition( config.getFactoryPid(), locale );
+        }
+
+        // otherwise use the configuration PID
+        return this.getObjectClassDefinition( config.getPid(), locale );
+    }
+
+
+    ObjectClassDefinition getObjectClassDefinition( Bundle bundle, String pid, String locale )
+    {
+        if ( bundle != null )
+        {
+            MetaTypeService mts = this.getMetaTypeService();
+            if ( mts != null )
+            {
+                MetaTypeInformation mti = mts.getMetaTypeInformation( bundle );
+                if ( mti != null )
+                {
+                    // see #getObjectClasses( final IdGetter idGetter, final String locale )
+                    try
+                    {
+                        return mti.getObjectClassDefinition( pid, locale );
+                    }
+                    catch ( IllegalArgumentException e )
+                    {
+                        // 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
+                        // https://issues.apache.org/jira/browse/FELIX-3694
+                    }
+                }
+            }
+        }
+
+        // fallback to nothing found
+        return null;
+    }
+
+
+    ObjectClassDefinition getObjectClassDefinition( String pid, String locale )
+    {
+        Bundle[] bundles = this.getBundleContext().getBundles();
+        for ( int i = 0; i < bundles.length; i++ )
+        {
+            try
+            {
+                ObjectClassDefinition ocd = this.getObjectClassDefinition( bundles[i], pid, locale );
+                if ( ocd != null )
+                {
+                    return ocd;
+                }
+            }
+            catch ( IllegalArgumentException iae )
+            {
+                // don't care
+            }
+        }
+        return null;
+    }
+
+
+    Map getAttributeDefinitionMap( Configuration config, String locale )
+    {
+        Map adMap = new HashMap();
+        ObjectClassDefinition ocd = this.getObjectClassDefinition( config, locale );
+        if ( ocd != null )
+        {
+            AttributeDefinition[] ad = ocd.getAttributeDefinitions( ObjectClassDefinition.ALL );
+            if ( ad != null )
+            {
+                for ( int i = 0; i < ad.length; i++ )
+                {
+                    adMap.put( ad[i].getID(), new MetatypePropertyDescriptor( ad[i] ) );
+                }
+            }
+        }
+        return adMap;
+    }
+
+
+    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, new MetatypePropertyDescriptor( adi ), props.get( attrId ) );
+            }
+            json.endObject();
+        }
+    }
+
+
+
+
+    /**
+     * 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();
+        }
+    };
+
+}

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeSupport.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeSupport.java?rev=1425765&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeSupport.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetaTypeSupport.java Tue Dec 25 19:56:31 2012
@@ -0,0 +1,393 @@
+/*
+ * 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.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Vector;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONWriter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.metatype.AttributeDefinition;
+
+
+/**
+ * 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 descriptions.
+ */
+class MetaTypeSupport
+{
+
+    /**
+     * 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.
+     */
+    static final int ATTRIBUTE_TYPE_PASSWORD = 12;
+
+    /**
+     * Marker value of password fields used as dummy values and
+     * indicating unmodified values.
+     */
+    static final String PASSWORD_PLACEHOLDER_VALUE = "unmodified"; //$NON-NLS-1$
+
+
+    static Bundle getBundle( final BundleContext bundleContext, final String bundleLocation )
+    {
+        if ( bundleLocation == null )
+        {
+            return null;
+        }
+
+        Bundle[] bundles = bundleContext.getBundles();
+        for ( int i = 0; i < bundles.length; i++ )
+        {
+            if ( bundleLocation.equals( bundles[i].getLocation() ) )
+            {
+                return bundles[i];
+            }
+        }
+
+        return null;
+    }
+
+
+    static void attributeToJson( final JSONWriter json, final PropertyDescriptor 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 boolean isPasswordProperty( String name )
+    {
+        return name == null ? false : name.toLowerCase().indexOf( "password" ) != -1; //$NON-NLS-1$
+    }
+
+
+    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 );
+        }
+    }
+
+
+    static PropertyDescriptor createAttributeDefinition( 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 PropertyDescriptor( id, attrType, attrCardinality );
+    }
+
+
+    static int getAttributeType( final PropertyDescriptor 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
+     */
+    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;
+        }
+    }
+
+
+    static void setPasswordProps( final Vector vec, final String[] properties, Object props )
+    {
+        List propList = ( props == null ) ? new ArrayList() : 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] );
+            }
+        }
+    }
+
+
+    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;
+    }
+
+}

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetatypePropertyDescriptor.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetatypePropertyDescriptor.java?rev=1425765&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetatypePropertyDescriptor.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/MetatypePropertyDescriptor.java Tue Dec 25 19:56:31 2012
@@ -0,0 +1,82 @@
+/*
+ * 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 org.osgi.service.metatype.AttributeDefinition;
+
+
+/**
+ * The <code>MetatypePropertyDescriptor</code> extends the
+ * {@link PropertyDescriptor} describing a property based on a real
+ * Metatype Service Attribute Definition.
+ */
+public class MetatypePropertyDescriptor extends PropertyDescriptor
+{
+    private final AttributeDefinition ad;
+
+
+    public MetatypePropertyDescriptor( AttributeDefinition ad )
+    {
+        super( ad.getID(), ad.getType(), ad.getCardinality() );
+        this.ad = ad;
+    }
+
+
+    public String getName()
+    {
+        return ad.getName();
+    }
+
+
+    public String getDescription()
+    {
+        return ad.getDescription();
+    }
+
+
+    public int getType()
+    {
+        return ad.getType();
+    }
+
+
+    public String[] getOptionValues()
+    {
+        return ad.getOptionValues();
+    }
+
+
+    public String[] getOptionLabels()
+    {
+        return ad.getOptionLabels();
+    }
+
+
+    public String validate( String value )
+    {
+        return ad.validate( value );
+    }
+
+
+    public String[] getDefaultValue()
+    {
+        return ad.getDefaultValue();
+    }
+}

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/PropertyDescriptor.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/PropertyDescriptor.java?rev=1425765&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/PropertyDescriptor.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/configuration/PropertyDescriptor.java Tue Dec 25 19:56:31 2012
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+/**
+ * The <code>PropertyDescriptor</code> class describes a property to
+ * generate the Configuration Management UI. It is built after the
+ * AttributeDescriptor but to prevent a hard dependency on the Metatype
+ * Service API, this does not implement it.
+ */
+class PropertyDescriptor
+{
+
+    final String id;
+    final int type;
+    final int cardinality;
+
+
+    public PropertyDescriptor( 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;
+    }
+}
\ No newline at end of file

Added: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationMetatypeSupport.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationMetatypeSupport.java?rev=1425765&view=auto
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationMetatypeSupport.java (added)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationMetatypeSupport.java Tue Dec 25 19:56:31 2012
@@ -0,0 +1,288 @@
+/*
+ * 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.servlet;
+
+
+import java.io.InputStream;
+import java.util.ArrayList;
+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.metatype.AttributeDefinition;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+
+class ConfigurationMetatypeSupport extends ConfigurationSupport implements 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$
+        };
+
+    private final Object ocdLock = new Object();
+    private String ocdLocale;
+    private ObjectClassDefinition ocd;
+
+
+    ConfigurationMetatypeSupport( OsgiManager osgiManager )
+    {
+        super( osgiManager );
+    }
+
+
+    //---------- MetaTypeProvider
+
+    public String[] getLocales()
+    {
+        // there is no locale support here
+        return null;
+    }
+
+
+    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 defaultConfig = osgiManager.getDefaultConfiguration();
+
+        // simple configuration properties
+        final ArrayList adList = new ArrayList();
+        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 namesByClassName = new TreeMap();
+        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 = ( String[] ) namesByClassName.keySet().toArray( new String[namesByClassName.size()] );
+        final String[] names = ( String[] ) 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 = ( AttributeDefinition[] ) 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;
+        }
+
+        return ocd;
+    }
+
+
+    private static final String getString( ResourceBundle rb, String key, String def )
+    {
+        try
+        {
+            return rb.getString( key );
+        }
+        catch ( Throwable t )
+        {
+            return def;
+        }
+    }
+
+    private static class AttributeDefinitionImpl implements AttributeDefinition
+    {
+
+        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/ConfigurationSupport.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java?rev=1425765&r1=1425764&r2=1425765&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/ConfigurationSupport.java Tue Dec 25 19:56:31 2012
@@ -19,41 +19,17 @@
 package org.apache.felix.webconsole.internal.servlet;
 
 
-import java.io.InputStream;
-import java.util.ArrayList;
 import java.util.Dictionary;
-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 ConfigurationSupport implements ManagedService, MetaTypeProvider
+class ConfigurationSupport implements ManagedService
 {
-    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;
+    protected final OsgiManager osgiManager;
 
-    private final Object ocdLock = new Object();
-    private String ocdLocale;
-    private ObjectClassDefinition ocd;
 
-    ConfigurationSupport( OsgiManager osgiManager )
+    ConfigurationSupport( final OsgiManager osgiManager )
     {
         this.osgiManager = osgiManager;
     }
@@ -65,228 +41,4 @@ class ConfigurationSupport implements Ma
     {
         osgiManager.updateConfiguration( config );
     }
-
-    //---------- MetaTypeProvider
-
-    public String[] getLocales()
-    {
-        // there is no locale support here
-        return null;
-    }
-
-    static final String getString(ResourceBundle rb, String key, String def)
-    {
-        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 defaultConfig = osgiManager.getDefaultConfiguration();
-
-        // simple configuration properties
-        final ArrayList adList = new ArrayList();
-        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 namesByClassName = new TreeMap();
-        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 = ( String[] ) namesByClassName.keySet().toArray( new String[namesByClassName.size()] );
-        final String[] names = ( String[] ) 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 = ( AttributeDefinition[] ) 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;
-        }
-
-        return ocd;
-    }
-
-    private static class AttributeDefinitionImpl implements AttributeDefinition
-    {
-
-        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=1425765&r1=1425764&r2=1425765&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 Tue Dec 25 19:56:31 2012
@@ -162,7 +162,7 @@ public class OsgiManager extends Generic
     static final String DEFAULT_MANAGER_ROOT = "/system/console"; //$NON-NLS-1$
 
     static final String[] PLUGIN_CLASSES = {
-            "org.apache.felix.webconsole.internal.compendium.ConfigurationAdminConfigurationPrinter", //$NON-NLS-1$
+            "org.apache.felix.webconsole.internal.configuration.ConfigurationAdminConfigurationPrinter", //$NON-NLS-1$
             "org.apache.felix.webconsole.internal.compendium.PreferencesConfigurationPrinter", //$NON-NLS-1$
             "org.apache.felix.webconsole.internal.compendium.WireAdminConfigurationPrinter", //$NON-NLS-1$
             "org.apache.felix.webconsole.internal.core.BundlesConfigurationPrinter", //$NON-NLS-1$
@@ -172,7 +172,7 @@ public class OsgiManager extends Generic
             "org.apache.felix.webconsole.internal.misc.ThreadPrinter", }; //$NON-NLS-1$
 
     static final String[] PLUGIN_MAP = {
-            "org.apache.felix.webconsole.internal.compendium.ConfigManager", "configMgr", //$NON-NLS-1$ //$NON-NLS-2$
+            "org.apache.felix.webconsole.internal.configuration.ConfigManager", "configMgr", //$NON-NLS-1$ //$NON-NLS-2$
             "org.apache.felix.webconsole.internal.compendium.LogServlet", "logs", //$NON-NLS-1$ //$NON-NLS-2$
             "org.apache.felix.webconsole.internal.core.BundlesServlet", "bundles", //$NON-NLS-1$ //$NON-NLS-2$
             "org.apache.felix.webconsole.internal.core.ServicesServlet", "services", //$NON-NLS-1$ //$NON-NLS-2$
@@ -323,6 +323,23 @@ public class OsgiManager extends Generic
             {
                 public Object getService( Bundle bundle, ServiceRegistration registration )
                 {
+                    /*
+                     * Explicitly load the class through the class loader to dynamically
+                     * wire the API if not wired yet. Implicit loading by creating a
+                     * class instance does not seem to properly work wiring the API
+                     * in time.
+                     */
+                    try
+                    {
+                        OsgiManager.this.getClass().getClassLoader()
+                            .loadClass( "org.osgi.service.metatype.MetaTypeProvider" );
+                        return new ConfigurationMetatypeSupport( OsgiManager.this );
+                    }
+                    catch ( ClassNotFoundException cnfe )
+                    {
+                        // ignore
+                    }
+
                     return new ConfigurationSupport( OsgiManager.this );
                 }
 
@@ -421,7 +438,7 @@ public class OsgiManager extends Generic
         // (we are authorative for our URL space and no other servlet should interfere)
         res.flushBuffer();
     }
-    
+
     private void ensureLocaleCookieSet(HttpServletRequest request, HttpServletResponse response, Locale locale) {
         Cookie[] cookies = request.getCookies();
         boolean hasCookie = false;