You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2014/03/02 23:38:20 UTC

svn commit: r1573380 - in /felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype: ./ AttributeDefinitionImpl.java MetaTypeProviderImpl.java ObjectClassDefinitionImpl.java PropertyMetaDataImpl.java Resource.java

Author: pderop
Date: Sun Mar  2 22:38:19 2014
New Revision: 1573380

URL: http://svn.apache.org/r1573380
Log:
added ConfigurationDependency and meta type

Added:
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/AttributeDefinitionImpl.java
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/MetaTypeProviderImpl.java
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/ObjectClassDefinitionImpl.java
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/PropertyMetaDataImpl.java
    felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/Resource.java

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/AttributeDefinitionImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/AttributeDefinitionImpl.java?rev=1573380&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/AttributeDefinitionImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/AttributeDefinitionImpl.java Sun Mar  2 22:38:19 2014
@@ -0,0 +1,76 @@
+/*
+ * 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 dm.impl.metatype;
+
+import org.osgi.service.metatype.AttributeDefinition;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class AttributeDefinitionImpl implements AttributeDefinition {
+    private PropertyMetaDataImpl m_propertyMetaData;
+    private Resource m_resource;
+
+    public AttributeDefinitionImpl(PropertyMetaDataImpl propertyMetaData, Resource resource) {
+        m_propertyMetaData = propertyMetaData;
+        m_resource = resource;
+    }
+
+    public int getCardinality() {
+        return m_propertyMetaData.getCardinality();
+    }
+
+    public String[] getDefaultValue() {
+        return m_propertyMetaData.getDefaults();
+    }
+
+    public String getDescription() {
+        return m_resource.localize(m_propertyMetaData.getDescription());
+    }
+
+    public String getID() {
+        return m_propertyMetaData.getId();
+    }
+
+    public String getName() {
+        return m_resource.localize(m_propertyMetaData.getHeading());
+    }
+
+    public String[] getOptionLabels() {
+        String[] labels = m_propertyMetaData.getOptionLabels();
+        if (labels != null) {
+            for (int i = 0; i < labels.length; i++) {
+                labels[i] = m_resource.localize(labels[i]);
+            }
+        }
+        return labels;
+    }
+
+    public String[] getOptionValues() {
+        return m_propertyMetaData.getOptionValues();
+    }
+
+    public int getType() {
+        return m_propertyMetaData.getType();
+    }
+
+    public String validate(String value) {
+        return null;
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/MetaTypeProviderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/MetaTypeProviderImpl.java?rev=1573380&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/MetaTypeProviderImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/MetaTypeProviderImpl.java Sun Mar  2 22:38:19 2014
@@ -0,0 +1,258 @@
+/*
+ * 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 dm.impl.metatype;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import dm.PropertyMetaData;
+import dm.impl.Logger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+/**
+ * When a ConfigurationDepdendency is configured with properties metadata, we provide
+ * a specific ManagedService which also implements the MetaTypeProvider interface. This interface
+ * allows the MetaTypeService to retrieve our properties metadata, which will then be handled by webconsole.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MetaTypeProviderImpl implements MetaTypeProvider, ManagedService, ManagedServiceFactory {
+    private ManagedService m_managedServiceDelegate;
+    private ManagedServiceFactory m_managedServiceFactoryDelegate;
+    private List m_propertiesMetaData = new ArrayList();
+    private String m_description;
+    private String m_heading;
+    private String m_localization;
+    private Map m_localesProperties = new HashMap();
+    private Logger m_logger;
+    private BundleContext m_bctx;
+    private String m_pid;
+
+    public MetaTypeProviderImpl(String pid, BundleContext ctx, Logger logger, ManagedService msDelegate, ManagedServiceFactory msfDelegate) {
+        m_pid = pid;
+        m_bctx = ctx;
+        m_logger = logger;
+        m_managedServiceDelegate = msDelegate;
+        m_managedServiceFactoryDelegate = msfDelegate;
+        // Set the default localization file base name (see core specification, in section Localization on page 68).
+        // By default, this file can be stored in OSGI-INF/l10n/bundle.properties (and corresponding localized version
+        // in OSGI-INF/l10n/bundle_en_GB_welsh.properties,  OSGI-INF/l10n/bundle_en_GB.properties, etc ...
+        // This default localization property file name can be overriden using the PropertyMetaData.setLocalization method.
+        m_localization = (String) m_bctx.getBundle().getHeaders().get(Constants.BUNDLE_LOCALIZATION);
+        if (m_localization == null) {
+            m_localization = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+        }
+    }
+
+    /**
+     * Registers the metatype information of a given configuration property
+     * @param property
+     */
+    public void add(PropertyMetaData property) {
+        m_propertiesMetaData.add(property);
+    }
+
+    /**
+     * A human readable description of the PID this annotation is associated with. Example: "Configuration for the PrinterService bundle".
+     * @return A human readable description of the PID this annotation is associated with (may be localized)
+     */
+    public void setDescription(String description) {
+        m_description = description;
+    }
+
+    /**
+     * The label used to display the tab name (or section) where the properties are displayed. Example: "Printer Service".
+     * @return The label used to display the tab name where the properties are displayed (may be localized)
+     */
+    public void setName(String heading) {
+        m_heading = heading;
+    }
+
+    /**
+     * Points to the basename of the Properties file that can localize the Meta Type informations.
+     * By default, (e.g. <code>setLocalization("person")</code> would match person_du_NL.properties in the root bundle directory.
+     * The default localization base name for the properties is OSGI-INF/l10n/bundle, but can
+     * be overridden by the manifest Bundle-Localization header (see core specification, in section Localization on page 68).
+     */
+    public void setLocalization(String path) {
+        if (path.endsWith(".properties")) {
+            throw new IllegalArgumentException(
+                "path must point to the base name of the propertie file, "
+                + "excluding local suffixes. For example: "
+                + "foo/bar/person is valid and matches the property file \"foo/bar/person_bundle_en_GB_welsh.properties\"");
+        }
+        m_localization = path.startsWith("/") ? path.substring(1) : path;
+    }
+
+    // --------------- MetaTypeProvider interface -------------------------------------------------
+
+    /**
+     * Returns all the Locales our bundle is containing. For instance, if our bundle contains the following localization files:
+     * OSGI-INF/l10n/bundle_en_GB_welsh.properties and OSGI-INF/l10n/bundle_en_GB.properties, then this method will return
+     * "en_GB", "en_GB_welsh" ...
+     * @return the list of Locale supported by our bundle.
+     */
+    public String[] getLocales() {
+        int lastSlash = m_localization.lastIndexOf("/");
+        String path = (lastSlash == -1) ? "/" : ("/" + m_localization.substring(0, lastSlash - 1));
+        String base = (lastSlash == -1) ? m_localization : m_localization.substring(lastSlash + 1);
+        Enumeration e = m_bctx.getBundle().findEntries(path,
+            base + "*.properties", false);
+        if (e == null) {
+            return null;
+        }
+        
+        TreeSet set = new TreeSet();
+        while (e.hasMoreElements()) {
+            // We have found a locale property file in the form of "path/file[_language[_ country[_variation]].properties"
+            // And now, we have to get the "language[_country[_variation]]" part ...
+            URL url = (URL) e.nextElement();
+            String name = url.getPath();
+            name = name.substring(name.lastIndexOf("/") + 1);
+            int underscore = name.indexOf("_");
+            if (underscore != -1) {
+                name = name.substring(underscore + 1, name.length() - ".properties".length());
+            }
+            if (name.length() > 0) {
+                set.add(name);
+            }
+        }
+
+        String[] locales = (String[]) set.toArray(new String[set.size()]);
+        return locales.length == 0 ? null : locales;
+    }
+
+    /**
+     * Returns the ObjectClassDefinition for a given Pid/Locale.
+     */
+    public ObjectClassDefinition getObjectClassDefinition(String id, String locale) {
+        try {
+            // Check if the id matches our PID
+            if (!id.equals(m_pid)) {
+                m_logger.log(LogService.LOG_ERROR, "id " + id + " does not match pid " + m_pid);
+                return null;
+            }
+
+            Properties localeProperties = getLocaleProperties(locale);
+            return new ObjectClassDefinitionImpl(m_pid, m_heading,
+                m_description, m_propertiesMetaData, new Resource(localeProperties));
+        }
+
+        catch (Throwable t) {
+            m_logger.log(
+                Logger.LOG_ERROR,
+                "Unexpected exception while geting ObjectClassDefinition for " + id + " (locale="
+                    + locale + ")", t);
+            return null;
+        }
+    }
+
+    /**
+     * We also implements the ManagedService and we just delegates the configuration handling to
+     * our associated ConfigurationDependency.
+     */
+    public void updated(Dictionary properties) throws ConfigurationException {
+        m_managedServiceDelegate.updated(properties);
+    }
+
+    /**
+     * Gets the properties for a given Locale.
+     * @param locale
+     * @return
+     * @throws IOException
+     */
+    private synchronized Properties getLocaleProperties(String locale) throws IOException {
+        locale = locale == null ? Locale.getDefault().toString() : locale;
+        Properties properties = (Properties) m_localesProperties.get(locale);
+        if (properties == null) {
+            properties = new Properties();
+            URL url = m_bctx.getBundle().getEntry(m_localization + ".properties");
+            if (url != null) {
+                loadLocale(properties, url);
+            }
+
+            String path = m_localization;
+            StringTokenizer tok = new StringTokenizer(locale, "_");
+            while (tok.hasMoreTokens()) {
+                path += "_" + tok.nextToken();
+                url = m_bctx.getBundle().getEntry(path + ".properties");
+                if (url != null) {
+                    properties = new Properties(properties);
+                    loadLocale(properties, url);
+                }
+            }
+            m_localesProperties.put(locale, properties);
+        }
+        return properties;
+    }
+
+    /**
+     * Loads a Locale Properties file.
+     * @param properties
+     * @param url
+     * @throws IOException
+     */
+    private void loadLocale(Properties properties, URL url) throws IOException {
+        InputStream in = null;
+        try {
+            in = url.openStream();
+            properties.load(in);
+        }
+        finally {
+            if (in != null) {
+                try {
+                    in.close();
+                }
+                catch (IOException ignored) {
+                }
+            }
+        }
+    }
+
+    // ManagedServiceFactory implementation
+    public void deleted(String pid) {
+        m_managedServiceFactoryDelegate.deleted(pid);
+    }
+
+    public String getName() {
+        return m_pid;
+    }
+
+    public void updated(String pid, Dictionary properties) throws ConfigurationException {
+        m_managedServiceFactoryDelegate.updated(pid, properties);
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/ObjectClassDefinitionImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/ObjectClassDefinitionImpl.java?rev=1573380&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/ObjectClassDefinitionImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/ObjectClassDefinitionImpl.java Sun Mar  2 22:38:19 2014
@@ -0,0 +1,101 @@
+/*
+ * 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 dm.impl.metatype;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.service.metatype.AttributeDefinition;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+/**
+ * ObjectClassDefinition implementation.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ObjectClassDefinitionImpl implements ObjectClassDefinition {
+    // Our OCD name (may be localized)
+    private String m_name;
+    
+    // Our OCD description (may be localized)
+    private String m_description;
+    
+    // Our OCD id
+    private String m_id;
+    
+    // The list of Properties MetaData objects (from DependencyManager API)
+    private List m_propertiesMetaData;
+    
+    // The localized resource that can be used when localizing some parameters
+    private Resource m_resource;
+
+    public ObjectClassDefinitionImpl(String id, String name, String description, List propertiesMetaData, Resource resource) {
+        m_id = id;
+        m_name = name;
+        m_description = description;
+        m_propertiesMetaData = propertiesMetaData;
+        m_resource = resource;
+    }
+
+    // --------------------- ObjectClassDefinition ----------------------------------------
+
+    public AttributeDefinition[] getAttributeDefinitions(int filter) {
+        List attrs = new ArrayList();
+        for (int i = 0; i < m_propertiesMetaData.size(); i++) {
+            PropertyMetaDataImpl metaData = (PropertyMetaDataImpl) m_propertiesMetaData.get(i);
+            switch (filter) {
+                case ObjectClassDefinition.ALL:
+                    attrs.add(new AttributeDefinitionImpl(metaData, m_resource));
+                    break;
+                case ObjectClassDefinition.OPTIONAL:
+                    if (!metaData.isRequired()) {
+                        attrs.add(new AttributeDefinitionImpl(metaData, m_resource));
+                    }
+                    break;
+                case ObjectClassDefinition.REQUIRED:
+                    if (metaData.isRequired()) {
+                        attrs.add(new AttributeDefinitionImpl(metaData, m_resource));
+                    }
+                    break;
+            }
+        }
+
+        AttributeDefinition[] array = new AttributeDefinitionImpl[attrs.size()];
+        return (AttributeDefinition[]) attrs.toArray(array);
+    }
+
+    public String getDescription() {
+        return m_resource.localize(m_description);
+    }
+
+    public String getID() {
+        return m_id;
+    }
+
+    public InputStream getIcon(int size) throws IOException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public String getName() {
+        return m_resource.localize(m_name);
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/PropertyMetaDataImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/PropertyMetaDataImpl.java?rev=1573380&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/PropertyMetaDataImpl.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/PropertyMetaDataImpl.java Sun Mar  2 22:38:19 2014
@@ -0,0 +1,204 @@
+/*
+ * 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 dm.impl.metatype;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import dm.PropertyMetaData;
+import org.osgi.service.metatype.AttributeDefinition;
+
+/**
+ * DependencyManager PropertyMetaData Implementation. This class describes meta informations regarding
+ * one given configuration property.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PropertyMetaDataImpl implements PropertyMetaData {
+    /**
+     * List of option labels (may be localized)
+     */
+    List m_optionsLabels = new ArrayList();
+    
+    /**
+     * List of option values
+     */
+    List m_optionsValues = new ArrayList();
+    
+    /**
+     * Property cardinality.
+     * @see {@link AttributeDefinition#getCardinality()}
+     */
+    private int m_cardinality;
+    
+    /**
+     * Valid default property values
+     */
+    private String[] m_defaults;
+    
+    /**
+     * Property description.
+     */
+    private String m_description;
+    
+    /**
+     * Property title.
+     */
+    private String m_heading;
+    
+    /**
+     * Property unique Id
+     */
+    private String m_id;
+    
+    /**
+     * Required flag.
+     */
+    private boolean m_required;
+    
+    /**
+     * Property Type.
+     * @see {@link AttributeDefinition#getType()}
+     */
+    private int m_type = AttributeDefinition.STRING;
+    
+    /**
+     * Mapping between java types and valid MetaType types.
+     * @see {@link AttributeDefinition#getType()}
+     */
+    private final static Map m_typeMapping = new HashMap() {{
+        put(Boolean.class, new Integer(AttributeDefinition.BOOLEAN));
+        put(Byte.class, new Integer(AttributeDefinition.BYTE));
+        put(Character.class, new Integer(AttributeDefinition.CHARACTER));
+        put(Double.class, new Integer(AttributeDefinition.FLOAT));
+        put(Integer.class, new Integer(AttributeDefinition.INTEGER));
+        put(Long.class, new Integer(AttributeDefinition.LONG));
+        put(Short.class, new Integer(AttributeDefinition.SHORT));
+        put(String.class, new Integer(AttributeDefinition.STRING));
+    }};
+
+    public PropertyMetaData addOption(String optionLabel, String optionValue) {
+        m_optionsLabels.add(optionLabel);
+        m_optionsValues.add(optionValue);
+        return this;
+    }
+
+    public PropertyMetaData setCardinality(int cardinality) {
+        m_cardinality = cardinality;
+        return this;
+    }
+
+    public PropertyMetaData setDefaults(String[] defaults) {
+        m_defaults = defaults;
+        return this;
+    }
+
+    public PropertyMetaData setDescription(String description) {
+        m_description = description;
+        return this;
+    }
+
+    public PropertyMetaData setHeading(String heading) {
+        m_heading = heading;
+        return this;
+    }
+
+    public PropertyMetaData setId(String id) {
+        m_id = id;
+        return this;
+    }
+
+    public PropertyMetaData setRequired(boolean required) {
+        m_required = required;
+        return this;
+    }
+
+    public PropertyMetaData setType(Class classType) {
+        Integer type = (Integer) m_typeMapping.get(classType);
+        if (type == null) {
+            throw new IllegalArgumentException("Invalid type: " + classType + ". Valid types are "
+                + m_typeMapping.keySet());
+        }
+        m_type = type.intValue();
+        return this;
+    }
+
+    public String[] getOptionLabels() {
+        String[] optionLabels = new String[m_optionsLabels.size()];
+        return (String[]) m_optionsLabels.toArray(optionLabels);
+    }
+
+    public String[] getOptionValues() {
+        String[] optionValues = new String[m_optionsValues.size()];
+        return (String[]) m_optionsValues.toArray(optionValues);
+    }
+
+    public int getCardinality() {
+        return m_cardinality;
+    }
+
+    public String[] getDefaults() {
+        return m_defaults;
+    }
+
+    public String getDescription() {
+        return m_description;
+    }
+
+    public String getHeading() {
+        return m_heading;
+    }
+
+    public String getId() {
+        return m_id;
+    }
+
+    public boolean isRequired() {
+        return m_required;
+    }
+
+    public int getType() {
+        return m_type;
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("cardinality=").append(m_cardinality);
+        sb.append("; defaults="); 
+        for (int i = 0; i < m_defaults.length; i ++) {
+            sb.append(m_defaults[i]).append(" ");
+        }
+        sb.append("; description=").append(m_description);
+        sb.append("; heading=").append(m_heading);
+        sb.append("; id=").append(m_id);
+        sb.append("; required=").append(m_required);
+        sb.append("; type=").append(getType());
+        sb.append("; optionLabels=");
+        for (int i = 0; i < m_optionsLabels.size(); i ++) {
+            sb.append(m_optionsLabels.get(i)).append(" ");
+        }
+        sb.append("; optionValues=");
+        for (int i = 0; i < m_optionsValues.size(); i ++) {
+            sb.append(m_optionsValues.get(i)).append(" ");
+        }
+        return sb.toString();
+    }
+}

Added: felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/Resource.java
URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/Resource.java?rev=1573380&view=auto
==============================================================================
--- felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/Resource.java (added)
+++ felix/sandbox/pderop/dependencymanager-prototype/dm/src/dm/impl/metatype/Resource.java Sun Mar  2 22:38:19 2014
@@ -0,0 +1,42 @@
+/*
+ * 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 dm.impl.metatype;
+
+import java.util.Properties;
+
+/**
+ * Helper class used to localize a given Property Meta Data.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Resource {
+    private Properties m_properties;
+
+    public Resource(Properties properties) {
+        m_properties = properties;
+    }
+    
+    public String localize(String param) {
+        if (m_properties != null && param != null && param.startsWith("%")) {
+            param = param.substring(1);
+            return m_properties.getProperty(param);
+        }
+        return param;
+    }
+}