You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by zo...@apache.org on 2011/02/27 22:21:22 UTC

svn commit: r1075149 [8/23] - in /aries/tags/blueprint-0.3.1: ./ blueprint-annotation-api/ blueprint-annotation-api/src/ blueprint-annotation-api/src/main/ blueprint-annotation-api/src/main/java/ blueprint-annotation-api/src/main/java/org/ blueprint-an...

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,351 @@
+/**
+ * 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.aries.blueprint.compendium.cm;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.aries.blueprint.BeanProcessor;
+import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.ServiceProcessor;
+import org.apache.aries.blueprint.container.ServiceListener;
+import org.apache.aries.blueprint.utils.JavaUtils;
+import org.apache.aries.blueprint.utils.ReflectionUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.blueprint.reflect.ServiceMetadata;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO: if we need to make those exported services tied to their references as for other <service/> elements
+ * TODO: it becomes a problem as currently we would have to create a specific recipe or something like that
+ *
+ * @version $Rev: 896324 $, $Date: 2010-01-06 06:05:04 +0000 (Wed, 06 Jan 2010) $
+ */
+public class CmManagedServiceFactory {
+
+    static final int CONFIGURATION_ADMIN_OBJECT_DELETED = 1;
+
+    static final int BUNDLE_STOPPING = 2;
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CmManagedServiceFactory.class);
+    
+    private ExtendedBlueprintContainer blueprintContainer;
+    private ConfigurationAdmin configAdmin;
+    private String id;
+    private String factoryPid;
+    private List<String> interfaces;
+    private int autoExport;
+    private int ranking;
+    private Map serviceProperties;
+    private String managedComponentName;
+    private String componentDestroyMethod;
+    private List<ServiceListener> listeners;
+    private final Object lock = new Object();
+
+    private ServiceRegistration registration;
+    private Map<String, ServiceRegistration> pids = new ConcurrentHashMap<String, ServiceRegistration>();
+    private Map<ServiceRegistration, Object> services = new ConcurrentHashMap<ServiceRegistration, Object>();
+
+    public void init() throws Exception {
+        LOGGER.debug("Initializing CmManagedServiceFactory for factoryPid={}", factoryPid);
+        Properties props = new Properties();
+        props.put(Constants.SERVICE_PID, factoryPid);
+        Bundle bundle = blueprintContainer.getBundleContext().getBundle();
+        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
+        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
+        
+        synchronized(lock) {
+            registration = blueprintContainer.getBundleContext().registerService(ManagedServiceFactory.class.getName(), new ConfigurationWatcher(), props);
+        
+            String filter = '(' + ConfigurationAdmin.SERVICE_FACTORYPID + '=' + this.factoryPid + ')';
+            Configuration[] configs = configAdmin.listConfigurations(filter);
+            if (configs != null) {
+                for (Configuration config : configs) {
+                    updated(config.getPid(), config.getProperties());
+                }
+            }
+        }
+    }
+
+    public void destroy() {
+        if (registration != null) {
+            registration.unregister();
+        }
+        for (Map.Entry<ServiceRegistration, Object> entry : services.entrySet()) {
+            destroy(entry.getValue(), entry.getKey(), BUNDLE_STOPPING);
+        }
+        services.clear();
+        pids.clear();
+    }
+
+    private void destroy(Object component, ServiceRegistration registration, int code) {
+        if (listeners != null) {
+            ServiceReference ref = registration.getReference();
+            for (ServiceListener listener : listeners) {
+                Hashtable props = JavaUtils.getProperties(ref);
+                listener.unregister(component, props);
+            }
+        }
+        destroyComponent(component, code);
+        registration.unregister();
+    }
+    
+    public Map<ServiceRegistration, Object> getServiceMap() {
+        return Collections.unmodifiableMap(services);
+    }
+
+    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
+        this.blueprintContainer = blueprintContainer;
+    }
+
+    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
+        this.configAdmin = configAdmin;
+    }
+
+    public void setListeners(List<ServiceListener> listeners) {
+        this.listeners = listeners;
+    }
+    
+    public void setId(String id) {
+        this.id = id;
+    }
+    
+    public void setFactoryPid(String factoryPid) {
+        this.factoryPid = factoryPid;
+    }
+
+    public void setInterfaces(List<String> interfaces) {
+        this.interfaces = interfaces;
+    }
+
+    public void setAutoExport(int autoExport) {
+        this.autoExport = autoExport;
+    }
+
+    public void setRanking(int ranking) {
+        this.ranking = ranking;
+    }
+
+    public void setServiceProperties(Map serviceProperties) {
+        this.serviceProperties = serviceProperties;
+    }
+    
+    public void setManagedComponentName(String managedComponentName) {
+        this.managedComponentName = managedComponentName;
+    }
+
+    public void setComponentDestroyMethod(String componentDestroyMethod) {
+        this.componentDestroyMethod = componentDestroyMethod;
+    }
+    
+    protected void updated(String pid, Dictionary props) {
+        LOGGER.debug("Updated configuration {} with props {}", pid, props);
+        ServiceRegistration reg = pids.get(pid);
+        if (reg == null) {      
+            updateComponentProperties(props);
+
+            Object component = blueprintContainer.getComponentInstance(managedComponentName);
+            
+            //  TODO: call listeners, etc...
+                    
+            Hashtable regProps = getRegistrationProperties(pid);            
+            CmProperties cm = findServiceProcessor();
+            if (cm != null) {
+                if ("".equals(cm.getPersistentId())) {
+                    JavaUtils.copy(regProps, props);
+                }
+                cm.updateProperties(new PropertiesUpdater(pid), regProps);
+            }
+            
+            Set<String> classes = getClasses(component);
+            String[] classArray = classes.toArray(new String[classes.size()]);
+            reg = blueprintContainer.getBundleContext().registerService(classArray, component, regProps);
+
+            LOGGER.debug("Service {} registered with interfaces {} and properties {}", new Object [] { component, classes, regProps });
+            
+            services.put(reg, component);
+            pids.put(pid, reg);
+            
+            if (listeners != null) {
+                for (ServiceListener listener : listeners) {
+                    listener.register(component, regProps);
+                }
+            }
+        } else {
+            updateComponentProperties(props);
+            
+            CmProperties cm = findServiceProcessor();
+            if (cm != null && "".equals(cm.getPersistentId())) {
+                Dictionary regProps = getRegistrationProperties(pid);    
+                JavaUtils.copy(regProps, props);
+                cm.updated(regProps);
+            }
+        }
+    }
+
+    private Hashtable getRegistrationProperties(String pid) {
+        Hashtable regProps = new Hashtable();
+        if (serviceProperties != null) {
+            regProps.putAll(serviceProperties);
+        }
+        regProps.put(Constants.SERVICE_PID, pid);
+        regProps.put(Constants.SERVICE_RANKING, ranking);
+        return regProps;
+    }
+    
+    private void updateComponentProperties(Dictionary props) {
+        CmManagedProperties cm = findBeanProcessor();
+        if (cm != null) {
+            cm.updated(props);
+        }
+    }
+    
+    private CmManagedProperties findBeanProcessor() {
+        for (BeanProcessor beanProcessor : blueprintContainer.getProcessors(BeanProcessor.class)) {
+            if (beanProcessor instanceof CmManagedProperties) {
+                CmManagedProperties cm = (CmManagedProperties) beanProcessor;
+                if (managedComponentName.equals(cm.getBeanName()) && "".equals(cm.getPersistentId())) {
+                    return cm;
+                }
+            }
+        }
+        return null;
+    }
+        
+    private CmProperties findServiceProcessor() {
+        for (ServiceProcessor processor : blueprintContainer.getProcessors(ServiceProcessor.class)) {
+            if (processor instanceof CmProperties) {
+                CmProperties cm = (CmProperties) processor;
+                if (id.equals(cm.getServiceId())) {
+                    return cm;
+                }
+            }
+        }
+        return null;
+    }
+        
+    private void destroyComponent(Object instance, int reason) {
+        Method method = findDestroyMethod(instance.getClass());
+        if (method != null) {
+            try {
+                method.invoke(instance, new Object [] { reason });
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    private Method findDestroyMethod(Class clazz) {
+        Method method = null;        
+        if (componentDestroyMethod != null && componentDestroyMethod.length() > 0) {
+            List<Method> methods = ReflectionUtils.findCompatibleMethods(clazz, componentDestroyMethod, new Class [] { int.class });
+            if (methods != null && !methods.isEmpty()) {
+                method = methods.get(0);
+            }
+        }
+        return method;
+    }
+    
+    protected void deleted(String pid) {
+        LOGGER.debug("Deleted configuration {}", pid);
+        ServiceRegistration reg = pids.remove(pid);
+        if (reg != null) {
+            Object component = services.remove(reg);
+            destroy(component, reg, CONFIGURATION_ADMIN_OBJECT_DELETED);
+        }
+    }
+
+    private Set<String> getClasses(Object service) {
+        Class serviceClass = service.getClass();
+        Set<String> classes;
+        switch (autoExport) {
+            case ServiceMetadata.AUTO_EXPORT_INTERFACES:
+                classes = ReflectionUtils.getImplementedInterfaces(new HashSet<String>(), serviceClass);
+                break;
+            case ServiceMetadata.AUTO_EXPORT_CLASS_HIERARCHY:
+                classes = ReflectionUtils.getSuperClasses(new HashSet<String>(), serviceClass);
+                break;
+            case ServiceMetadata.AUTO_EXPORT_ALL_CLASSES:
+                classes = ReflectionUtils.getSuperClasses(new HashSet<String>(), serviceClass);
+                classes = ReflectionUtils.getImplementedInterfaces(classes, serviceClass);
+                break;
+            default:
+                classes = new HashSet<String>(interfaces);
+                break;
+        }
+        return classes;
+    }
+    
+    private class ConfigurationWatcher implements ManagedServiceFactory {
+
+        public String getName() {
+            return null;
+        }
+
+        public void updated(String pid, Dictionary props) throws ConfigurationException {
+            CmManagedServiceFactory.this.updated(pid, props);
+        }
+
+        public void deleted(String pid) {
+            CmManagedServiceFactory.this.deleted(pid);
+        }
+    }
+
+    private class PropertiesUpdater implements ServiceProcessor.ServicePropertiesUpdater {
+
+        private String pid;
+        
+        public PropertiesUpdater(String pid) {
+            this.pid = pid;
+        }
+        
+        public String getId() {
+            return id;
+        }
+
+        public void updateProperties(Dictionary properties) {
+            ServiceRegistration reg = pids.get(pid);
+            if (reg != null) {
+                ServiceReference ref = reg.getReference();
+                if (ref != null) {
+                    Hashtable table = JavaUtils.getProperties(ref);
+                    JavaUtils.copy(table, properties);
+                    reg.setProperties(table);
+                }
+            }
+        }
+    }
+   
+}

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,569 @@
+/**
+ * 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.aries.blueprint.compendium.cm;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.container.Parser;
+import org.apache.aries.blueprint.container.ParserContextImpl;
+import org.apache.aries.blueprint.container.ServiceListener;
+import org.apache.aries.blueprint.ext.ExtNamespaceHandler;
+import org.apache.aries.blueprint.ext.PlaceholdersUtils;
+import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
+import org.apache.aries.blueprint.mutable.MutableCollectionMetadata;
+import org.apache.aries.blueprint.mutable.MutableComponentMetadata;
+import org.apache.aries.blueprint.mutable.MutableIdRefMetadata;
+import org.apache.aries.blueprint.mutable.MutableMapMetadata;
+import org.apache.aries.blueprint.mutable.MutableRefMetadata;
+import org.apache.aries.blueprint.mutable.MutableValueMetadata;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.BeanProperty;
+import org.osgi.service.blueprint.reflect.CollectionMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.IdRefMetadata;
+import org.osgi.service.blueprint.reflect.MapMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.RefMetadata;
+import org.osgi.service.blueprint.reflect.RegistrationListener;
+import org.osgi.service.blueprint.reflect.ServiceMetadata;
+import org.osgi.service.blueprint.reflect.ValueMetadata;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Namespace handler for the Config Admin service.
+ * This handler will parse the various elements defined and populate / modify the registry
+ * accordingly.
+ *
+ * @see CmManagedProperties
+ * @see CmManagedServiceFactory
+ * @see CmProperties
+ * @see CmPropertyPlaceholder
+ *
+ * @version $Rev: 1002327 $, $Date: 2010-09-28 20:06:56 +0100 (Tue, 28 Sep 2010) $
+ */
+public class CmNamespaceHandler implements NamespaceHandler {
+
+    public static final String BLUEPRINT_NAMESPACE = "http://www.osgi.org/xmlns/blueprint/v1.0.0";
+    public static final String BLUEPRINT_CM_NAMESPACE_1_0 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0";
+    public static final String BLUEPRINT_CM_NAMESPACE_1_1 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0";
+
+    public static final String PROPERTY_PLACEHOLDER_ELEMENT = "property-placeholder";
+    public static final String MANAGED_PROPERTIES_ELEMENT = "managed-properties";
+    public static final String MANAGED_SERVICE_FACTORY_ELEMENT = "managed-service-factory";
+    public static final String CM_PROPERTIES_ELEMENT = "cm-properties";
+    public static final String DEFAULT_PROPERTIES_ELEMENT = "default-properties";
+    public static final String PROPERTY_ELEMENT = "property";
+    public static final String INTERFACES_ELEMENT = "interfaces";
+    public static final String VALUE_ELEMENT = "value";
+    public static final String MANAGED_COMPONENT_ELEMENT = "managed-component";
+
+    public static final String ID_ATTRIBUTE = "id";
+    public static final String PERSISTENT_ID_ATTRIBUTE = "persistent-id";
+    public static final String PLACEHOLDER_PREFIX_ATTRIBUTE = "placeholder-prefix";
+    public static final String PLACEHOLDER_SUFFIX_ATTRIBUTE = "placeholder-suffix";
+    public static final String DEFAULTS_REF_ATTRIBUTE = "defaults-ref";
+    public static final String UPDATE_STRATEGY_ATTRIBUTE = "update-strategy";
+    public static final String UPDATE_METHOD_ATTRIBUTE = "update-method";
+    public static final String FACTORY_PID_ATTRIBUTE = "factory-pid";
+    public static final String AUTO_EXPORT_ATTRIBUTE = "auto-export";
+    public static final String RANKING_ATTRIBUTE = "ranking";
+    public static final String INTERFACE_ATTRIBUTE = "interface";
+    public static final String UPDATE_ATTRIBUTE = "update";
+
+    public static final String AUTO_EXPORT_DISABLED = "disabled";
+    public static final String AUTO_EXPORT_INTERFACES = "interfaces";
+    public static final String AUTO_EXPORT_CLASS_HIERARCHY = "class-hierarchy";
+    public static final String AUTO_EXPORT_ALL = "all-classes";
+    public static final String AUTO_EXPORT_DEFAULT = AUTO_EXPORT_DISABLED;
+    public static final String RANKING_DEFAULT = "0";
+
+    private static final String MANAGED_OBJECT_MANAGER_NAME = "org.apache.aries.managedObjectManager";
+    
+    private static final Logger LOGGER = LoggerFactory.getLogger(CmNamespaceHandler.class);
+
+    // This property is static but it should be ok since there will be only a single instance
+    // of this class for the bundle
+    private static ConfigurationAdmin configAdmin;
+
+    private int idCounter;
+
+    public int getIdCounter() {
+        return idCounter;
+    }
+
+    public void setIdCounter(int idCounter) {
+        this.idCounter = idCounter;
+    }
+
+    public static ConfigurationAdmin getConfigAdmin() {
+        return configAdmin;
+    }
+
+    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
+        this.configAdmin = configAdmin;
+    }
+
+    public URL getSchemaLocation(String namespace) {
+        if (BLUEPRINT_CM_NAMESPACE_1_1.equals(namespace)) {
+            return getClass().getResource("blueprint-cm-1.1.0.xsd");
+        } else if (BLUEPRINT_CM_NAMESPACE_1_0.equals(namespace)) {
+            return getClass().getResource("blueprint-cm-1.0.0.xsd");
+        } else {
+            return null;
+        }
+    }
+
+    public Set<Class> getManagedClasses() {
+        return new HashSet<Class>(Arrays.asList(
+                CmPropertyPlaceholder.class,
+                CmManagedServiceFactory.class,
+                CmManagedProperties.class,
+                CmProperties.class
+        ));
+    }
+
+    public Metadata parse(Element element, ParserContext context) {
+        LOGGER.debug("Parsing element {{}}{}", element.getNamespaceURI(), element.getLocalName());
+        ComponentDefinitionRegistry registry = context.getComponentDefinitionRegistry();
+        registerManagedObjectManager(context, registry);
+        if (nodeNameEquals(element, PROPERTY_PLACEHOLDER_ELEMENT)) {
+            return parsePropertyPlaceholder(context, element);
+        } else if (nodeNameEquals(element, MANAGED_SERVICE_FACTORY_ELEMENT)) {
+            return parseManagedServiceFactory(context, element);
+        } else {
+            throw new ComponentDefinitionException("Unsupported element: " + element.getNodeName());
+        }
+    }
+
+    public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
+        LOGGER.debug("Decorating node {{}}{}", node.getNamespaceURI(), node.getLocalName());
+        ComponentDefinitionRegistry registry = context.getComponentDefinitionRegistry();
+        registerManagedObjectManager(context, registry);
+        if (node instanceof Element) {
+            if (nodeNameEquals(node, MANAGED_PROPERTIES_ELEMENT)) {
+                return decorateManagedProperties(context, (Element) node, component);
+            } else if (nodeNameEquals(node, CM_PROPERTIES_ELEMENT)) {
+                return decorateCmProperties(context, (Element) node, component);
+            } else {
+                throw new ComponentDefinitionException("Unsupported element: " + node.getNodeName());
+            }
+        } else {
+            throw new ComponentDefinitionException("Illegal use of blueprint cm namespace");
+        }
+    }
+
+    private ComponentMetadata parsePropertyPlaceholder(ParserContext context, Element element) {
+        MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
+        metadata.setProcessor(true);
+        metadata.setId(getId(context, element));
+        metadata.setScope(BeanMetadata.SCOPE_SINGLETON);
+        metadata.setRuntimeClass(CmPropertyPlaceholder.class);
+        metadata.setInitMethod("init");
+        metadata.setDestroyMethod("destroy");
+        metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+        metadata.addProperty("configAdmin", createConfigAdminProxy(context));
+        metadata.addProperty("persistentId", createValue(context, element.getAttribute(PERSISTENT_ID_ATTRIBUTE)));
+        String prefix = element.hasAttribute(PLACEHOLDER_PREFIX_ATTRIBUTE)
+                                    ? element.getAttribute(PLACEHOLDER_PREFIX_ATTRIBUTE)
+                                    : "${";
+        metadata.addProperty("placeholderPrefix", createValue(context, prefix));
+        String suffix = element.hasAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
+                                    ? element.getAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
+                                    : "}";
+        metadata.addProperty("placeholderSuffix", createValue(context, suffix));
+        String defaultsRef = element.hasAttribute(DEFAULTS_REF_ATTRIBUTE) ? element.getAttribute(DEFAULTS_REF_ATTRIBUTE) : null;
+        if (defaultsRef != null) {
+            metadata.addProperty("defaultProperties", createRef(context, defaultsRef));
+        }
+        String ignoreMissingLocations = element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE)
+                ? element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.IGNORE_MISSING_LOCATIONS_ATTRIBUTE) : null;
+        if (ignoreMissingLocations != null) {
+            metadata.addProperty("ignoreMissingLocations", createValue(context, ignoreMissingLocations));
+        }
+        String systemProperties = element.hasAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE)
+                ? element.getAttributeNS(ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE, ExtNamespaceHandler.SYSTEM_PROPERTIES_ATTRIBUTE) : null;
+        if (systemProperties == null) {
+            systemProperties = ExtNamespaceHandler.SYSTEM_PROPERTIES_NEVER;
+        }
+        metadata.addProperty("systemProperties", createValue(context, systemProperties));
+        String updateStrategy = element.getAttribute(UPDATE_STRATEGY_ATTRIBUTE);
+        if (updateStrategy != null) {
+            metadata.addProperty("updateStrategy", createValue(context, updateStrategy));
+        }
+        metadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
+        // Parse elements
+        List<String> locations = new ArrayList<String>();
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element e = (Element) node;
+                if (BLUEPRINT_CM_NAMESPACE_1_0.equals(e.getNamespaceURI())
+                        || BLUEPRINT_CM_NAMESPACE_1_1.equals(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, DEFAULT_PROPERTIES_ELEMENT)) {
+                        if (defaultsRef != null) {
+                            throw new ComponentDefinitionException("Only one of " + DEFAULTS_REF_ATTRIBUTE + " attribute or " + DEFAULT_PROPERTIES_ELEMENT + " element is allowed");
+                        }
+                        Metadata props = parseDefaultProperties(context, metadata, e);
+                        metadata.addProperty("defaultProperties", props);
+                    }
+                } else if (ExtNamespaceHandler.BLUEPRINT_EXT_NAMESPACE.equals(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, ExtNamespaceHandler.LOCATION_ELEMENT)) {
+                        locations.add(getTextValue(e));
+                    }
+                }
+            }
+        }
+        if (!locations.isEmpty()) {
+            metadata.addProperty("locations", createList(context, locations));
+        }
+
+        PlaceholdersUtils.validatePlaceholder(metadata, context.getComponentDefinitionRegistry());
+        
+        return metadata;
+    }
+
+    private Metadata parseDefaultProperties(ParserContext context, MutableBeanMetadata enclosingComponent, Element element) {
+        MutableMapMetadata props = context.createMetadata(MutableMapMetadata.class);
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element e = (Element) node;
+                if (BLUEPRINT_CM_NAMESPACE_1_0.equals(e.getNamespaceURI())
+                        || BLUEPRINT_CM_NAMESPACE_1_1.equals(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, PROPERTY_ELEMENT)) {
+                        BeanProperty prop = context.parseElement(BeanProperty.class, enclosingComponent, e);
+                        props.addEntry(createValue(context, prop.getName(), String.class.getName()), prop.getValue());
+                    }
+                }
+            }
+        }
+        return props;
+    }
+
+    private ComponentMetadata parseManagedServiceFactory(ParserContext context, Element element) {
+        String id = getId(context, element);
+
+        MutableBeanMetadata factoryMetadata = context.createMetadata(MutableBeanMetadata.class);
+        generateIdIfNeeded(context, factoryMetadata);
+        factoryMetadata.addProperty("id", createValue(context, factoryMetadata.getId()));
+        factoryMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
+        factoryMetadata.setRuntimeClass(CmManagedServiceFactory.class);
+        factoryMetadata.setInitMethod("init");
+        factoryMetadata.setDestroyMethod("destroy");
+        factoryMetadata.addProperty("configAdmin", createConfigAdminProxy(context));
+        factoryMetadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+        factoryMetadata.addProperty("factoryPid", createValue(context, element.getAttribute(FACTORY_PID_ATTRIBUTE)));
+        String autoExport = element.hasAttribute(AUTO_EXPORT_ATTRIBUTE) ? element.getAttribute(AUTO_EXPORT_ATTRIBUTE) : AUTO_EXPORT_DEFAULT;
+        if (AUTO_EXPORT_DISABLED.equals(autoExport)) {
+            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_DISABLED);
+        } else if (AUTO_EXPORT_INTERFACES.equals(autoExport)) {
+            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_INTERFACES);
+        } else if (AUTO_EXPORT_CLASS_HIERARCHY.equals(autoExport)) {
+            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_CLASS_HIERARCHY);
+        } else if (AUTO_EXPORT_ALL.equals(autoExport)) {
+            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_ALL_CLASSES);
+        } else {
+            throw new ComponentDefinitionException("Illegal value (" + autoExport + ") for " + AUTO_EXPORT_ATTRIBUTE + " attribute");
+        }
+        factoryMetadata.addProperty("autoExport", createValue(context, autoExport));
+        String ranking = element.hasAttribute(RANKING_ATTRIBUTE) ? element.getAttribute(RANKING_ATTRIBUTE) : RANKING_DEFAULT;
+        factoryMetadata.addProperty("ranking", createValue(context, ranking));
+
+        List<String> interfaces = null;
+        if (element.hasAttribute(INTERFACE_ATTRIBUTE)) {
+            interfaces = Collections.singletonList(element.getAttribute(INTERFACE_ATTRIBUTE));
+            factoryMetadata.addProperty("interfaces", createList(context, interfaces));
+        }
+
+        Parser parser = getParser(context);
+        
+        // Parse elements
+        List<RegistrationListener> listeners = new ArrayList<RegistrationListener>();
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element e = (Element) node;
+                if (isBlueprintNamespace(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, INTERFACES_ELEMENT)) {
+                        if (interfaces != null) {
+                            throw new ComponentDefinitionException("Only one of " + Parser.INTERFACE_ATTRIBUTE + " attribute or " + INTERFACES_ELEMENT + " element must be used");
+                        }
+                        interfaces = parseInterfaceNames(e);
+                        factoryMetadata.addProperty("interfaces", createList(context, interfaces));                    
+                    } else if (nodeNameEquals(e, Parser.SERVICE_PROPERTIES_ELEMENT)) { 
+                        MapMetadata map = parser.parseServiceProperties(e, factoryMetadata);
+                        factoryMetadata.addProperty("serviceProperties", map);
+                    } else if (nodeNameEquals(e, Parser.REGISTRATION_LISTENER_ELEMENT)) {
+                        listeners.add(parser.parseRegistrationListener(e, factoryMetadata));
+                    }
+                } else if (BLUEPRINT_CM_NAMESPACE_1_0.equals(e.getNamespaceURI())
+                        || BLUEPRINT_CM_NAMESPACE_1_1.equals(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, MANAGED_COMPONENT_ELEMENT)) {
+                        MutableBeanMetadata managedComponent = context.parseElement(MutableBeanMetadata.class, null, e);
+                        generateIdIfNeeded(context, managedComponent);
+                        managedComponent.setScope(BeanMetadata.SCOPE_PROTOTYPE);
+                        // destroy-method on managed-component has different signature than on regular beans
+                        // so we'll handle it differently
+                        String destroyMethod = managedComponent.getDestroyMethod();
+                        if (destroyMethod != null) {
+                            factoryMetadata.addProperty("componentDestroyMethod", createValue(context, destroyMethod));
+                            managedComponent.setDestroyMethod(null);
+                        }
+                        context.getComponentDefinitionRegistry().registerComponentDefinition(managedComponent);
+                        factoryMetadata.addProperty("managedComponentName", createIdRef(context, managedComponent.getId()));
+                    }
+                }
+            }
+        }
+
+        MutableCollectionMetadata listenerCollection = context.createMetadata(MutableCollectionMetadata.class);
+        listenerCollection.setCollectionClass(List.class);
+        for (RegistrationListener listener : listeners) {
+            MutableBeanMetadata bean = context.createMetadata(MutableBeanMetadata.class);
+            bean.setRuntimeClass(ServiceListener.class);
+            bean.addProperty("listener", listener.getListenerComponent());
+            bean.addProperty("registerMethod", createValue(context, listener.getRegistrationMethod()));
+            bean.addProperty("unregisterMethod", createValue(context, listener.getUnregistrationMethod()));
+            listenerCollection.addValue(bean);
+        }
+        factoryMetadata.addProperty("listeners", listenerCollection);
+        
+        context.getComponentDefinitionRegistry().registerComponentDefinition(factoryMetadata);
+        
+        MutableBeanMetadata mapMetadata = context.createMetadata(MutableBeanMetadata.class);
+        mapMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
+        mapMetadata.setId(id);
+        mapMetadata.setFactoryComponent(createRef(context, factoryMetadata.getId()));
+        mapMetadata.setFactoryMethod("getServiceMap");
+        return mapMetadata;
+    }
+
+    private ComponentMetadata decorateCmProperties(ParserContext context, Element element, ComponentMetadata component) {
+        generateIdIfNeeded(context, ((MutableComponentMetadata) component));
+        MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
+        metadata.setProcessor(true);
+        metadata.setId(getId(context, element));
+        metadata.setRuntimeClass(CmProperties.class);
+        String persistentId = element.getAttribute(PERSISTENT_ID_ATTRIBUTE);
+        // if persistentId is "" the cm-properties element in nested in managed-service-factory
+        // and the configuration object will come from the factory. So we only really need to register
+        // ManagedService if the persistentId is not an empty string.
+        if (persistentId.length() > 0) {
+            metadata.setInitMethod("init");
+            metadata.setDestroyMethod("destroy");
+        }
+        metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+        metadata.addProperty("configAdmin", createConfigAdminProxy(context));
+        metadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
+        metadata.addProperty("persistentId", createValue(context, persistentId));
+        if (element.hasAttribute(UPDATE_ATTRIBUTE)) {
+            metadata.addProperty("update", createValue(context, element.getAttribute(UPDATE_ATTRIBUTE)));
+        }
+        metadata.addProperty("serviceId", createIdRef(context, component.getId()));
+        context.getComponentDefinitionRegistry().registerComponentDefinition(metadata);
+        return component;
+    }
+
+    private ComponentMetadata decorateManagedProperties(ParserContext context, Element element, ComponentMetadata component) {
+        if (!(component instanceof MutableBeanMetadata)) {
+            throw new ComponentDefinitionException("Element " + MANAGED_PROPERTIES_ELEMENT + " must be used inside a <bp:bean> element");
+        }
+        generateIdIfNeeded(context, ((MutableBeanMetadata) component));
+        MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
+        metadata.setProcessor(true);
+        metadata.setId(getId(context, element));
+        metadata.setRuntimeClass(CmManagedProperties.class);
+        String persistentId = element.getAttribute(PERSISTENT_ID_ATTRIBUTE);
+        // if persistentId is "" the managed properties element in nested in managed-service-factory
+        // and the configuration object will come from the factory. So we only really need to register
+        // ManagedService if the persistentId is not an empty string.
+        if (persistentId.length() > 0) {
+            metadata.setInitMethod("init");
+            metadata.setDestroyMethod("destroy");
+        }
+        metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+        metadata.addProperty("configAdmin", createConfigAdminProxy(context));
+        metadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
+        metadata.addProperty("persistentId", createValue(context, persistentId));
+        String updateStrategy = element.getAttribute(UPDATE_STRATEGY_ATTRIBUTE);
+        if (updateStrategy != null) {
+            metadata.addProperty("updateStrategy", createValue(context, updateStrategy));
+        }
+        if (element.hasAttribute(UPDATE_METHOD_ATTRIBUTE)) {
+            metadata.addProperty("updateMethod", createValue(context, element.getAttribute(UPDATE_METHOD_ATTRIBUTE)));
+        } else if ("component-managed".equals(updateStrategy)) {
+            throw new ComponentDefinitionException(UPDATE_METHOD_ATTRIBUTE + " attribute must be set when " + UPDATE_STRATEGY_ATTRIBUTE + " is set to 'component-managed'");
+        }
+        metadata.addProperty("beanName", createIdRef(context, component.getId()));
+        context.getComponentDefinitionRegistry().registerComponentDefinition(metadata);
+        return component;
+    }
+
+    /**
+     * Create a reference to the ConfigurationAdmin service if not already done
+     * and add it to the registry.
+     *
+     * @param context the parser context
+     * @return a metadata pointing to the config admin
+     */
+    private Metadata createConfigAdminProxy(ParserContext context) {
+        MutableBeanMetadata bean = context.createMetadata(MutableBeanMetadata.class);
+        bean.setRuntimeClass(CmNamespaceHandler.class);
+        bean.setFactoryMethod("getConfigAdmin");
+        bean.setActivation(MutableBeanMetadata.ACTIVATION_LAZY);
+        bean.setScope(MutableBeanMetadata.SCOPE_PROTOTYPE);
+        return bean;
+    }
+
+    private void registerManagedObjectManager(ParserContext context, ComponentDefinitionRegistry registry) {
+        if (registry.getComponentDefinition(MANAGED_OBJECT_MANAGER_NAME) == null) {
+            MutableBeanMetadata beanMetadata = context.createMetadata(MutableBeanMetadata.class);
+            beanMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
+            beanMetadata.setId(MANAGED_OBJECT_MANAGER_NAME);
+            beanMetadata.setRuntimeClass(ManagedObjectManager.class);            
+            registry.registerComponentDefinition(beanMetadata);
+        }
+    }
+    
+    private static ValueMetadata createValue(ParserContext context, String value) {
+        return createValue(context, value, null);
+    }
+
+    private static ValueMetadata createValue(ParserContext context, String value, String type) {
+        MutableValueMetadata m = context.createMetadata(MutableValueMetadata.class);
+        m.setStringValue(value);
+        m.setType(type);
+        return m;
+    }
+
+    private static RefMetadata createRef(ParserContext context, String value) {
+        MutableRefMetadata m = context.createMetadata(MutableRefMetadata.class);
+        m.setComponentId(value);
+        return m;
+    }
+
+    private static IdRefMetadata createIdRef(ParserContext context, String value) {
+        MutableIdRefMetadata m = context.createMetadata(MutableIdRefMetadata.class);
+        m.setComponentId(value);
+        return m;
+    }
+
+    private static CollectionMetadata createList(ParserContext context, List<String> list) {
+        MutableCollectionMetadata m = context.createMetadata(MutableCollectionMetadata.class);
+        m.setCollectionClass(List.class);
+        m.setValueType(String.class.getName());
+        for (String v : list) {
+            m.addValue(createValue(context, v, String.class.getName()));
+        }
+        return m;
+    }
+
+    private static String getTextValue(Element element) {
+        StringBuffer value = new StringBuffer();
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node item = nl.item(i);
+            if ((item instanceof CharacterData && !(item instanceof Comment)) || item instanceof EntityReference) {
+                value.append(item.getNodeValue());
+            }
+        }
+        return value.toString();
+    }
+
+    private static boolean nodeNameEquals(Node node, String name) {
+        return (name.equals(node.getNodeName()) || name.equals(node.getLocalName()));
+    }
+
+    public static boolean isBlueprintNamespace(String ns) {
+        return BLUEPRINT_NAMESPACE.equals(ns);
+    }
+
+    public String getId(ParserContext context, Element element) {
+        if (element.hasAttribute(ID_ATTRIBUTE)) {
+            return element.getAttribute(ID_ATTRIBUTE);
+        } else {
+            return generateId(context);
+        }
+    }
+
+    public void generateIdIfNeeded(ParserContext context, MutableComponentMetadata metadata) {
+        if (metadata.getId() == null) {
+            metadata.setId(generateId(context));
+        }
+    }
+
+    private String generateId(ParserContext context) {
+        String id;
+        do {
+            id = ".cm-" + ++idCounter;
+        } while (context.getComponentDefinitionRegistry().containsComponentDefinition(id));
+        return id;
+    }
+    
+    private Parser getParser(ParserContext ctx) {
+        if (ctx instanceof ParserContextImpl) {
+            return ((ParserContextImpl) ctx).getParser();
+        }
+        throw new RuntimeException("Unable to get parser");
+    }
+
+    public List<String> parseInterfaceNames(Element element) {
+        List<String> interfaceNames = new ArrayList<String>();
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element e = (Element) node;
+                if (nodeNameEquals(e, VALUE_ELEMENT)) {
+                    String v = getTextValue(e).trim();
+                    if (interfaceNames.contains(v)) {
+                        throw new ComponentDefinitionException("The element " + INTERFACES_ELEMENT + " should not contain the same interface twice");
+                    }
+                    interfaceNames.add(getTextValue(e));
+                } else {
+                    throw new ComponentDefinitionException("Unsupported element " + e.getNodeName() + " inside an " + INTERFACES_ELEMENT + " element");
+                }
+            }
+        }
+        return interfaceNames;
+    }
+
+}

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,156 @@
+/**
+ * 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.aries.blueprint.compendium.cm;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.ServiceProcessor;
+import org.apache.aries.blueprint.utils.JavaUtils;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version $Rev: 820286 $, $Date: 2009-09-30 15:45:55 +0100 (Wed, 30 Sep 2009) $
+ */
+public class CmProperties implements ManagedObject, ServiceProcessor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CmProperties.class);
+
+    private ExtendedBlueprintContainer blueprintContainer;
+    private ConfigurationAdmin configAdmin;
+    private ManagedObjectManager managedObjectManager;
+    private String persistentId;
+    private boolean update;
+    private String serviceId;
+
+    private final Object lock = new Object();
+    private final Set<ServicePropertiesUpdater> services = new HashSet<ServicePropertiesUpdater>();
+    private Dictionary<String,Object> properties;
+
+    public ExtendedBlueprintContainer getBlueprintContainer() {
+        return blueprintContainer;
+    }
+
+    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
+        this.blueprintContainer = blueprintContainer;
+    }
+
+    public ConfigurationAdmin getConfigAdmin() {
+        return configAdmin;
+    }
+
+    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
+        this.configAdmin = configAdmin;
+    }
+
+    public void setManagedObjectManager(ManagedObjectManager managedObjectManager) {
+        this.managedObjectManager = managedObjectManager;
+    }
+    
+    public ManagedObjectManager getManagedObjectManager() {
+        return managedObjectManager;
+    }
+    
+    public Bundle getBundle() {
+        return blueprintContainer.getBundleContext().getBundle();
+    }
+    
+    public String getPersistentId() {
+        return persistentId;
+    }
+
+    public void setPersistentId(String persistentId) {
+        this.persistentId = persistentId;
+    }
+
+    public boolean getUpdate() {
+        return update;
+    }
+
+    public void setUpdate(boolean update) {
+        this.update = update;
+    }
+
+    public String getServiceId() {
+        return serviceId;
+    }
+
+    public void setServiceId(String serviceId) {
+        this.serviceId = serviceId;
+    }
+    
+    public void init() throws Exception {
+        LOGGER.debug("Initializing CmProperties for service={} / pid={}", serviceId, persistentId);
+        
+        Properties props = new Properties();
+        props.put(Constants.SERVICE_PID, persistentId);
+        Bundle bundle = blueprintContainer.getBundleContext().getBundle();
+        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
+        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
+                
+        synchronized (lock) {
+            managedObjectManager.register(this, props);
+            Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
+            if (config != null) {
+                properties = config.getProperties();
+            }
+        }
+    }
+
+    public void destroy() {
+        managedObjectManager.unregister(this);
+    }
+
+    public void updated(Dictionary props) {
+        LOGGER.debug("Service properties updated for service={} / pid={}, {}", new Object[] {serviceId, persistentId, props});
+        
+        synchronized (lock) {
+            this.properties = props;
+            if (update) {
+                for (ServicePropertiesUpdater service : services) {
+                    service.updateProperties(props);
+                }
+            }
+        }
+    }
+
+    public void updateProperties(ServicePropertiesUpdater service, Dictionary props) {
+        if (!this.serviceId.equals(service.getId())) {
+            return;
+        }
+                
+        LOGGER.debug("Service properties initialized for service={} / pid={}, {}", new Object[] {serviceId, persistentId, props});
+        
+        synchronized (lock) {
+            services.add(service);
+            if (properties != null) {
+                JavaUtils.copy(props, properties);
+            }
+        }
+    }
+
+}

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,168 @@
+/**
+ * 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.aries.blueprint.compendium.cm;
+
+import java.io.IOException;
+import java.util.*;
+
+import org.apache.aries.blueprint.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.ext.AbstractPropertyPlaceholder;
+import org.apache.aries.blueprint.ext.PropertyPlaceholder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO: javadoc
+ *
+ * @version $Rev: 1002318 $, $Date: 2010-09-28 19:47:49 +0100 (Tue, 28 Sep 2010) $
+ */
+public class CmPropertyPlaceholder extends PropertyPlaceholder implements ManagedObject {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CmPropertyPlaceholder.class);
+
+    private ExtendedBlueprintContainer blueprintContainer;
+    private ConfigurationAdmin configAdmin; 
+    private String persistentId;
+    private String updateStrategy;
+    private ManagedObjectManager managedObjectManager;
+    private Dictionary<String,Object> properties;
+
+    public ExtendedBlueprintContainer getBlueprintContainer() {
+        return blueprintContainer;
+    }
+
+    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
+        this.blueprintContainer = blueprintContainer;
+    }
+
+    public ConfigurationAdmin getConfigAdmin() {
+        return configAdmin;
+    }
+
+    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
+        this.configAdmin = configAdmin;
+    }
+
+    public String getPersistentId() {
+        return persistentId;
+    }
+
+    public void setPersistentId(String persistentId) {
+        this.persistentId = persistentId;
+    }
+
+    public String getUpdateStrategy() {
+        return updateStrategy;
+    }
+
+    public void setUpdateStrategy(String updateStrategy) {
+        this.updateStrategy = updateStrategy;
+    }
+
+    public ManagedObjectManager getManagedObjectManager() {
+        return managedObjectManager;
+    }
+
+    public void setManagedObjectManager(ManagedObjectManager managedObjectManager) {
+        this.managedObjectManager = managedObjectManager;
+    }
+
+    public void init() throws Exception {
+        LOGGER.debug("Initializing CmPropertyPlaceholder");
+        Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
+        if (config != null) {
+            properties = config.getProperties();
+        }
+        Properties props = new Properties();
+        props.put(Constants.SERVICE_PID, persistentId);
+        Bundle bundle = blueprintContainer.getBundleContext().getBundle();
+        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
+        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
+        managedObjectManager.register(this, props);
+    }
+
+    public void destroy() {
+        LOGGER.debug("Destroying CmPropertyPlaceholder");
+        managedObjectManager.unregister(this);
+    }
+
+    protected String getProperty(String val) {
+        LOGGER.debug("Retrieving property value {} from configuration with pid {}", val, persistentId);
+        Object v = null;
+        if (properties != null) {
+            v = properties.get(val);
+            if (v != null) {
+                LOGGER.debug("Found property value {}", v);
+            } else {
+                LOGGER.debug("Property not found in configuration");
+            }
+        }
+        if (v == null) {
+            v = super.getProperty(val);
+        }
+        return v != null ? v.toString() : null;
+    }
+
+    public Bundle getBundle() {
+        return blueprintContainer.getBundleContext().getBundle();
+    }
+
+    public void updated(Dictionary props) {
+        if ("reload".equalsIgnoreCase(updateStrategy) && !equals(properties, props)) {
+            LOGGER.debug("Configuration updated for pid={}", persistentId);
+            // Run in a separate thread to avoid re-entrance
+            new Thread() {
+                public void run() {
+                    blueprintContainer.reload();
+                }
+            }.start();
+        }
+    }
+
+    private <T,U> boolean equals(Dictionary<T,U> d1, Dictionary<T,U> d2) {
+        if (d1 == null || d1.isEmpty()) {
+            return d2 == null || d2.isEmpty();
+        } else if (d2 == null || d1.size() != d2.size()) {
+            return false;
+        } else {
+            for (Enumeration<T> e = d1.keys(); e.hasMoreElements();) {
+                T k = e.nextElement();
+                U v1 = d1.get(k);
+                U v2 = d2.get(k);
+                if (v1 == null) {
+                    if (v2 != null) {
+                        return false;
+                    }
+                } else {
+                    if (!v1.equals(v2)) {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+    }
+
+}

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,51 @@
+/**
+ * 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.aries.blueprint.compendium.cm;
+
+import java.io.IOException;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+public class CmUtils  {
+
+    private CmUtils() {        
+    }
+    
+    public static Configuration getConfiguration(ConfigurationAdmin configAdmin, String persistentId) throws IOException {
+        String filter = '(' + Constants.SERVICE_PID + '=' + persistentId + ')';
+        Configuration[] configs;
+        try {
+            configs = configAdmin.listConfigurations(filter);
+        } catch (InvalidSyntaxException e) {
+            // this should not happen
+            throw new RuntimeException("Invalid filter: " + filter);
+        }
+        if (configs != null && configs.length > 0) {
+            return configs[0];
+        } else {
+            // TODO: what should we do?
+            // throw new RuntimeException("No configuration object for pid=" + persistentId);
+            return null;
+        }
+    }
+  
+}

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObject.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObject.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObject.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObject.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,32 @@
+/**
+ * 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.aries.blueprint.compendium.cm;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+
+public interface ManagedObject {
+
+    Bundle getBundle();
+    String getPersistentId();
+    
+    void updated(Dictionary props);
+          
+}

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java Sun Feb 27 21:21:05 2011
@@ -0,0 +1,105 @@
+/**
+ * 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.aries.blueprint.compendium.cm;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
+
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Since persistence id can only be associated with one ManagedService in a bundle
+ * this class ensures only one ManagedService is registered per persistence id.
+ */
+public class ManagedObjectManager {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ManagedObjectManager.class);
+
+    private HashMap<String, ConfigurationWatcher> map = new HashMap<String, ConfigurationWatcher>();
+               
+    public synchronized void register(ManagedObject cm, Properties props) {
+        String key = cm.getPersistentId();
+        ConfigurationWatcher reg = map.get(key);
+        if (reg == null) {
+            reg = new ConfigurationWatcher(); 
+            ServiceRegistration registration = cm.getBundle().getBundleContext().registerService(ManagedService.class.getName(), reg, props);
+            reg.setRegistration(registration);            
+            map.put(key, reg);
+        }
+        reg.add(cm);
+    }
+
+    public synchronized void unregister(ManagedObject cm) {
+        String key = cm.getPersistentId();
+        ConfigurationWatcher reg = map.get(key);
+        if (reg != null) {
+            reg.remove(cm);
+            if (reg.isEmpty()) {
+                map.remove(key);
+                reg.getRegistration().unregister();
+            }
+        }
+    }
+            
+    private static class ConfigurationWatcher implements ManagedService {
+
+        private ServiceRegistration registration;
+        private List<ManagedObject> list = Collections.synchronizedList(new ArrayList<ManagedObject>());
+        
+        public ConfigurationWatcher() {
+        }
+        
+        public void updated(Dictionary props) throws ConfigurationException {
+            synchronized (list) {
+                for (ManagedObject cm : list) {
+                    cm.updated(props);
+                }
+            }
+        }
+        
+        private void setRegistration(ServiceRegistration registration) {
+            this.registration = registration;
+        }
+        
+        private ServiceRegistration getRegistration() {
+            return registration;
+        }
+        
+        private void add(ManagedObject cm) {
+            list.add(cm);
+        }
+        
+        private void remove(ManagedObject cm) {
+            list.remove(cm);
+        }
+        
+        private boolean isEmpty() {
+            return list.isEmpty();
+        }
+    }
+        
+}

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml Sun Feb 27 21:21:05 2011
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+    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.
+
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">
+
+    <service interface="org.apache.aries.blueprint.NamespaceHandler">
+        <service-properties>
+            <entry key="osgi.service.blueprint.namespace">
+                <array>
+                    <value>http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0</value>
+                    <value>http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0</value>
+                </array>
+            </entry>
+        </service-properties>
+        <bean class="org.apache.aries.blueprint.compendium.cm.CmNamespaceHandler">
+            <property name="configAdmin">
+                <reference interface="org.osgi.service.cm.ConfigurationAdmin"/>
+            </property>
+        </bean>
+    </service>
+
+</blueprint>

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.0.0.xsd
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.0.0.xsd?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.0.0.xsd (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.0.0.xsd Sun Feb 27 21:21:05 2011
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    /*
+    * $Revision: 1002327 $
+    *
+    * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+    *
+    * Licensed 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.
+    */
+    -->
+<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
+            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+            xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
+            elementFormDefault="qualified"
+            attributeFormDefault="unqualified"
+            version="1.0.0">
+
+    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0" />
+
+    <!-- property placeholder -->
+
+    <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
+
+    <xsd:complexType name="TpropertyPlaceholder">
+        <xsd:complexContent>
+            <xsd:extension base="bp:Tcomponent">
+                <xsd:sequence>
+                    <!-- nested properties declaration -->
+                    <xsd:element name="default-properties" type="TdefaultProperties" minOccurs="0" maxOccurs="1"/>
+                </xsd:sequence>
+
+                <!-- #### What should be the type for a persistent id?  I think we need to define one like class and method -->
+                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+                <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
+                <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
+                <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <!-- #### is this the correct type here?  This is defining placeholder properties,
+         so should this be a restricted set of value types or should this be expanded to
+         all of the elements you can inject into a bean property? -->
+    <xsd:complexType name="TdefaultProperties">
+        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+            <xsd:element name="property" type="bp:Tproperty"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
+
+    <!--  managed-properties  -->
+
+    <xsd:element name="managed-properties" type="TmanagedProperties"/>
+
+    <xsd:complexType name="TmanagedProperties">
+        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+        <xsd:attribute name="update-strategy" type="TupdateStrategyType" use="optional"/>
+        <xsd:attribute name="update-method" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+
+    <xsd:simpleType name="TupdateStrategyType">
+        <xsd:restriction base="xsd:NMTOKEN">
+            <xsd:enumeration value="none"/>
+            <xsd:enumeration value="component-managed"/>
+            <xsd:enumeration value="container-managed"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <!--  managed-service-factory -->
+
+    <xsd:element name="managed-service-factory" type="TmanagedServiceFactory"/>
+
+    <xsd:complexType name="TmanagedServiceFactory">
+        <xsd:complexContent>
+            <xsd:extension base="bp:Tcomponent">
+                <xsd:sequence>
+                    <xsd:group ref="bp:GbaseServiceElements"/>
+                    <xsd:element name="managed-component" type="TmanagedComponent" minOccurs="1" maxOccurs="1"/>
+                </xsd:sequence>
+                <xsd:attribute name="interface" type="bp:Tclass" use="optional" />
+                <xsd:attribute name="ref" type="bp:Tidref" use="optional" />
+                <xsd:attribute name="auto-export" type="bp:TautoExportModes" default="disabled" />
+                <xsd:attribute name="ranking" type="xsd:int" default="0"/>
+                <xsd:attribute name="factory-pid" type="xsd:string" use="required"/>
+                <xsd:anyAttribute namespace="##other" processContents="strict"/>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="TmanagedComponent">
+        <xsd:group ref="bp:GbeanElements"/>
+        <xsd:attribute name="class" type="bp:Tclass"/>
+        <xsd:attribute name="init-method" type="bp:Tmethod"/>
+        <xsd:attribute name="destroy-method" type="bp:Tmethod"/>
+        <xsd:attribute name="factory-method" type="bp:Tmethod"/>
+        <xsd:attribute name="factory-component" type="bp:Tidref"/>
+        <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+
+
+    <!-- cm-properties -->
+
+    <xsd:element name="cm-properties" type="TcmProperties"/>
+
+    <xsd:complexType name="TcmProperties">
+        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+        <xsd:attribute name="update" type="xsd:boolean" use="optional" default="false"/>
+    </xsd:complexType>
+
+</xsd:schema>

Added: aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd (added)
+++ aries/tags/blueprint-0.3.1/blueprint-cm/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd Sun Feb 27 21:21:05 2011
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    /*
+    * $Revision: 1002327 $
+    *
+    * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+    *
+    * Licensed 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.
+    */
+    -->
+<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
+            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+            xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+            targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
+            elementFormDefault="qualified"
+            attributeFormDefault="unqualified"
+            version="1.0.0">
+
+    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0" />
+
+    <!-- property placeholder -->
+
+    <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
+
+    <xsd:complexType name="TpropertyPlaceholder">
+        <xsd:complexContent>
+            <xsd:extension base="bp:Tcomponent">
+                <xsd:sequence>
+                    <!-- nested properties declaration -->
+                    <xsd:element name="default-properties" type="TdefaultProperties" minOccurs="0" maxOccurs="1"/>
+                </xsd:sequence>
+
+                <!-- #### What should be the type for a persistent id?  I think we need to define one like class and method -->
+                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+                <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
+                <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
+                <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
+                <xsd:attribute name="update-strategy" type="TplaceholderUpdateStrategyType" use="optional" default="none"/>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:simpleType name="TplaceholderUpdateStrategyType">
+        <xsd:restriction base="xsd:NMTOKEN">
+            <xsd:enumeration value="none"/>
+            <xsd:enumeration value="reload"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <!-- #### is this the correct type here?  This is defining placeholder properties,
+         so should this be a restricted set of value types or should this be expanded to
+         all of the elements you can inject into a bean property? -->
+    <xsd:complexType name="TdefaultProperties">
+        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+            <xsd:element name="property" type="bp:Tproperty"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
+
+    <!--  managed-properties  -->
+
+    <xsd:element name="managed-properties" type="TmanagedProperties"/>
+
+    <xsd:complexType name="TmanagedProperties">
+        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+        <xsd:attribute name="update-strategy" type="TupdateStrategyType" use="optional"/>
+        <xsd:attribute name="update-method" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+
+    <xsd:simpleType name="TupdateStrategyType">
+        <xsd:restriction base="xsd:NMTOKEN">
+            <xsd:enumeration value="none"/>
+            <xsd:enumeration value="component-managed"/>
+            <xsd:enumeration value="container-managed"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+
+    <!--  managed-service-factory -->
+
+    <xsd:element name="managed-service-factory" type="TmanagedServiceFactory"/>
+
+    <xsd:complexType name="TmanagedServiceFactory">
+        <xsd:complexContent>
+            <xsd:extension base="bp:Tcomponent">
+                <xsd:sequence>
+                    <xsd:group ref="bp:GbaseServiceElements"/>
+                    <xsd:element name="managed-component" type="TmanagedComponent" minOccurs="1" maxOccurs="1"/>
+                </xsd:sequence>
+                <xsd:attribute name="interface" type="bp:Tclass" use="optional" />
+                <xsd:attribute name="ref" type="bp:Tidref" use="optional" />
+                <xsd:attribute name="auto-export" type="bp:TautoExportModes" default="disabled" />
+                <xsd:attribute name="ranking" type="xsd:int" default="0"/>
+                <xsd:attribute name="factory-pid" type="xsd:string" use="required"/>
+                <xsd:anyAttribute namespace="##other" processContents="strict"/>
+            </xsd:extension>
+        </xsd:complexContent>
+    </xsd:complexType>
+
+    <xsd:complexType name="TmanagedComponent">
+        <xsd:group ref="bp:GbeanElements"/>
+        <xsd:attribute name="class" type="bp:Tclass"/>
+        <xsd:attribute name="init-method" type="bp:Tmethod"/>
+        <xsd:attribute name="destroy-method" type="bp:Tmethod"/>
+        <xsd:attribute name="factory-method" type="bp:Tmethod"/>
+        <xsd:attribute name="factory-component" type="bp:Tidref"/>
+        <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+
+
+    <!-- cm-properties -->
+
+    <xsd:element name="cm-properties" type="TcmProperties"/>
+
+    <xsd:complexType name="TcmProperties">
+        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
+        <xsd:attribute name="update" type="xsd:boolean" use="optional" default="false"/>
+    </xsd:complexType>
+
+</xsd:schema>

Added: aries/tags/blueprint-0.3.1/blueprint-core/pom.xml
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/pom.xml?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/pom.xml (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/pom.xml Sun Feb 27 21:21:05 2011
@@ -0,0 +1,131 @@
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.aries.blueprint</groupId>
+    <artifactId>blueprint</artifactId>
+    <version>0.3.1</version>
+  </parent>
+
+  <artifactId>org.apache.aries.blueprint.core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Apache Aries Blueprint Core</name>
+  <description>
+      This bundle contains the core implementation of Blueprint 
+      along with the "ext" namespace handler.
+  </description>
+
+  <properties>
+      <aries.osgi.activator>
+          org.apache.aries.blueprint.container.BlueprintExtender
+      </aries.osgi.activator>
+      <aries.osgi.export.pkg>
+          !org.apache.aries.blueprint.annotation*,
+          org.apache.aries.blueprint*
+      </aries.osgi.export.pkg>
+      <aries.osgi.import>
+          !org.apache.aries.blueprint*,
+        org.apache.aries.util.tracker;resolution:=optional,
+        org.osgi.service.event*;resolution:=optional,
+        org.osgi.service.framework;resolution:=optional,
+        org.apache.aries.blueprint.annotation.service;resolution:=optional,
+        org.apache.aries.quiesce.manager;version="[0.2,1.0)";resolution:=optional,
+        org.apache.aries.quiesce.participant;version="[0.2,1.0)";resolution:=optional,
+        *
+      </aries.osgi.import>
+      <aries.osgi.export.service>
+          org.apache.aries.blueprint.ParserService
+      </aries.osgi.export.service>
+  </properties>
+  
+  <dependencies>
+      <dependency>
+          <groupId>org.apache.aries.blueprint</groupId>
+          <artifactId>org.apache.aries.blueprint.api</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.apache.aries.blueprint</groupId>
+          <artifactId>org.apache.aries.blueprint.annotation.api</artifactId>
+          <optional>true</optional>
+      </dependency>
+      <dependency>
+          <groupId>org.apache.aries</groupId>
+          <artifactId>org.apache.aries.util</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.osgi</groupId>
+          <artifactId>org.osgi.core</artifactId>
+          <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>org.osgi</groupId>
+          <artifactId>org.osgi.compendium</artifactId>
+          <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>org.eclipse</groupId>
+          <artifactId>osgi</artifactId>
+          <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-api</artifactId>
+      </dependency>
+      <dependency>
+          <groupId>org.slf4j</groupId>
+          <artifactId>slf4j-simple</artifactId>
+          <scope>test</scope>
+      </dependency>
+      <dependency>
+          <groupId>asm</groupId>
+          <artifactId>asm-all</artifactId>
+          <optional>true</optional>
+      </dependency>
+      <dependency>
+      	<groupId>org.apache.aries.quiesce</groupId>
+      	<artifactId>org.apache.aries.quiesce.api</artifactId>
+      	<scope>provided</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.aries.testsupport</groupId>
+        <artifactId>org.apache.aries.testsupport.unit</artifactId>
+      </dependency>            
+      <dependency>
+      	<groupId>org.apache.aries.proxy</groupId>
+      	<artifactId>org.apache.aries.proxy.api</artifactId>
+      </dependency>
+  </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>../blueprint-api/src/main/resources/org/osgi/service/blueprint</directory>
+                <targetPath>org/apache/aries/blueprint</targetPath>
+                <includes>
+                    <include>blueprint.xsd</include>
+                </includes>
+            </resource>
+        </resources>
+    </build>
+  
+</project>

Added: aries/tags/blueprint-0.3.1/blueprint-core/src/main/appended-resources/META-INF/NOTICE.vm
URL: http://svn.apache.org/viewvc/aries/tags/blueprint-0.3.1/blueprint-core/src/main/appended-resources/META-INF/NOTICE.vm?rev=1075149&view=auto
==============================================================================
--- aries/tags/blueprint-0.3.1/blueprint-core/src/main/appended-resources/META-INF/NOTICE.vm (added)
+++ aries/tags/blueprint-0.3.1/blueprint-core/src/main/appended-resources/META-INF/NOTICE.vm Sun Feb 27 21:21:05 2011
@@ -0,0 +1,2 @@
+This product includes software developed at
+the OSGi Alliance (http://www.osgi.org/).
\ No newline at end of file