You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2006/06/14 17:22:08 UTC

svn commit: r414287 [5/6] - in /incubator/felix/trunk: org.apache.felix.ipojo.arch/ org.apache.felix.ipojo.arch/src/ org.apache.felix.ipojo.arch/src/main/ org.apache.felix.ipojo.arch/src/main/java/ org.apache.felix.ipojo.arch/src/main/java/org/ org.apa...

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,281 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+import java.util.Properties;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Activator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+
+/**
+ * Provided Service represent a provided service by the component.
+ * Date : 3 déc. 2005
+ * @author clément
+ *
+ */
+public class ProvidedService implements ServiceFactory {
+
+    /**
+     * Service State : REGISTRED.
+     */
+    public static final int REGISTERED = 1;
+
+    /**
+     * Service State : UNREGISTRED.
+     */
+    public static final int UNREGISTERED = 0;
+
+    /**
+     * Factory Policy : SINGLETON_FACTORY.
+     */
+    public static final int SINGLETON_FACTORY = 0;
+
+    /**
+     * Factory policy : SERVICE_FACTORY.
+     */
+    public static final int SERVICE_FACTORY = 1;
+
+    /**
+     * Factory policy : COMPONENT_FACTORY.
+     * TODO : Component_factory behavior
+     */
+    public static final int COMPONENT_FACTORY = 2;
+
+    /**
+     * The service registration.
+     * is null when the service is not registred.
+     * m_serviceRegistration : ServiceRegistration
+     */
+    private ServiceRegistration m_serviceRegistration;
+
+    /**
+     * Link to the component manager.
+     * m_handler : ComponentManager
+     */
+    private ProvidedServiceHandler m_handler;
+
+    /**
+     * Provided service metadata.
+     */
+    private ProvidedServiceMetadata m_metadata;
+
+    /**
+     * State of the provided service.
+     */
+    private int m_state;
+
+    /**
+     * Properties Array.
+     */
+    private Property[] m_properties = new Property[0];
+
+
+    /**
+     * Construct a provided service object.
+     * @param handler : the provided service handler.
+     * @param psm : the provided service metadata.
+     */
+    public ProvidedService(ProvidedServiceHandler handler, ProvidedServiceMetadata psm) {
+        m_handler = handler;
+        m_metadata = psm;
+        for (int i = 0; i < psm.getProperties().length; i++) {
+        	Property prop = new Property(this, ((PropertyMetadata)psm.getProperties()[i]));
+        	addProperty(prop);
+        }
+    }
+
+    /**
+     * Add the given property to the property list.
+     * @param p : the element to add
+     */
+    private void addProperty(Property p) {
+        for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
+            if (m_properties[i] == p) { return; }
+        }
+
+        if (m_properties.length > 0) {
+            Property[] newProp = new Property[m_properties.length + 1];
+            System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
+            newProp[m_properties.length] = p;
+            m_properties = newProp;
+        }
+        else { m_properties = new Property[] {p}; }
+    }
+
+    /**
+     * @return the service reference of the provided service (null if the service is not published).
+     */
+    public ServiceReference getServiceReference() {
+    	if (m_serviceRegistration != null) { return m_serviceRegistration.getReference(); }
+    	else { return null; }
+    }
+
+    /**
+     * Return a service object for the dependency.
+     * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+     * @param bundle : the bundle
+     * @param registration : the service registration of the registred service
+     * @return : a new service object or a already created service object (in the case of singleton)
+     */
+    public Object getService(Bundle bundle, ServiceRegistration registration) {
+
+    	switch(m_metadata.getFactoryPolicy()) {
+
+    	case SINGLETON_FACTORY :
+            return m_handler.getComponentManager().getInstance();
+
+    	case SERVICE_FACTORY :
+    		return m_handler.getComponentManager().createInstance();
+
+    	case COMPONENT_FACTORY :
+    		//TODO Component Factory Behavior
+    		return null;
+
+    	default :
+    		Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Unknown factory policy for " + m_metadata.getServiceSpecification() + " : " + m_metadata.getFactoryPolicy());
+    		return null;
+    	}
+
+    }
+
+    /**
+     * The unget method.
+     * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+     * @param bundle : bundle
+     * @param registration : service registration
+     * @param service : service object
+     */
+    public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+        //Nothing to do
+    }
+
+//    /**
+//     * Validate the service dependencies of the current provided service.
+//     * @return true if the service dependencies are valid
+//     */
+//    public boolean validate() {
+//        boolean valide = true;
+//        for (int i = 0; i < m_dependencies.length; i++) {
+//            Dependency dep = m_dependencies[i];
+//            valide = valide & dep.isSatisfied();
+//            if (!valide) {
+//                ComponentManager.getLogger().log(Level.INFO, "Service Dependency  for " + m_interface + " not valid : " + dep.getInterface());
+//                return false;
+//            }
+//        }
+//        ComponentManager.getLogger().log(Level.INFO, "Service dependencies for " + m_interface + " are valid");
+//        return valide;
+//    }
+
+    /**
+     * Register the service.
+     * The service object must be able to serve this service.
+     * To avoid cycle in Check Context, the registred service is set to registred before the real registration.
+     */
+    protected void registerService() {
+    	if (m_state != REGISTERED) {
+            String spec = "";
+            for (int i = 0; i < m_metadata.getServiceSpecification().length; i++) {
+                spec = spec + m_metadata.getServiceSpecification()[i] + ", ";
+            }
+    			Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Register the service : " + spec);
+    			// Contruct the service properties list
+    			Properties serviceProperties = getServiceProperties();
+
+    			m_state = REGISTERED;
+    			m_serviceRegistration = m_handler.getComponentManager().getContext().registerService(m_metadata.getServiceSpecification(), this, serviceProperties);
+    	}
+    }
+
+    /**
+     * Unregister the service.
+     */
+    protected void unregisterService() {
+    	if (m_state == REGISTERED) {
+    		try {
+    			m_serviceRegistration.unregister();
+    			m_serviceRegistration = null;
+    		} catch (Exception e) { return; }
+			m_state = UNREGISTERED;
+    	}
+    }
+
+    /**
+     * @return The state of the provided service.
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * @return the component manager.
+     */
+    protected ComponentManager getComponentManager() {
+    	return m_handler.getComponentManager();
+    }
+
+    /**
+     * Return the list of properties attached to this service.
+     * This list contains only property where a value are assigned.
+     * @return the properties attached to the provided service.
+     */
+    private Properties getServiceProperties() {
+        // Contruct the service properties list
+        Properties serviceProperties = new Properties();
+        for (int i = 0; i < m_properties.length; i++) {
+            if (m_properties[i].get() != null) {
+                serviceProperties.put(m_properties[i].getMetadata().getName(), m_properties[i].get().toString());
+            }
+        }
+        return serviceProperties;
+    }
+
+    /**
+     * @return the properties attached to the provided service.
+     */
+    public Property[] getProperties() {
+        return m_properties;
+    }
+
+    /**
+     * Update refresh the service properties.
+     * The new list of properties is sended to the service registry.
+     */
+    protected void update() {
+        // Update the service properties
+
+        // Contruct the service properties list
+        Properties serviceProperties = getServiceProperties();
+
+        // Update the service registration
+        if (m_state == REGISTERED) { m_serviceRegistration.setProperties(serviceProperties); }
+    }
+
+	/**
+	 * @return the propvided service metadata.
+	 */
+	public ProvidedServiceMetadata getMetadata() {
+		return m_metadata;
+	}
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,306 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * @author Clement Escoffier
+ *
+ */
+public class ProvidedServiceHandler implements Handler {
+
+
+	/**
+	 * The list of the provided service.
+	 */
+	private ProvidedService[] m_providedServices = new ProvidedService[0];
+
+	/**
+	 * The component manager.
+	 */
+	private ComponentManager m_componentManager;
+
+	private void addProvidedService(ProvidedService ps) {
+	        //  Verify that the provided service is not already in the array.
+	        for (int i = 0; (m_providedServices != null) && (i < m_providedServices.length); i++) {
+	            if (m_providedServices[i] == ps) { return; }
+	        }
+
+	        if (m_providedServices.length > 0) {
+	            ProvidedService[] newPS = new ProvidedService[m_providedServices.length + 1];
+	            System.arraycopy(m_providedServices, 0, newPS, 0, m_providedServices.length);
+	            newPS[m_providedServices.length] = ps;
+	            m_providedServices = newPS;
+	        }
+	        else { m_providedServices = new ProvidedService[] {ps}; }
+	}
+
+	/**
+	 * @return the component manager.
+	 */
+	public ComponentManager getComponentManager() { return m_componentManager; }
+
+	/**
+	 * @return the list of the provided service.
+	 */
+	public ProvidedService[] getProvidedService() { return m_providedServices; }
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element componentMetadata) {
+		// Fix the component managert & clean the provided service list
+		m_componentManager = cm;
+		m_providedServices = new ProvidedService[0];
+		// Create the dependency according to the component metadata
+		Element[] providedServices = componentMetadata.getElements("Provides");
+		for (int i = 0; i < providedServices.length; i++) {
+			// Create a ProvidedServiceMetadata object
+
+            // First : create the serviceSpecification array
+            String[] serviceSpecification = new String[0];
+            if (providedServices[i].containsAttribute("interface")) {
+                String serviceSpecificationStr = providedServices[i].getAttribute("interface");
+                //Get serviceSpecification if exist in the metadata
+                String[] spec = serviceSpecificationStr.split(",");
+                serviceSpecification = new String[spec.length];
+                for (int j = 0; j < spec.length; j++) { serviceSpecification[j] = spec[j].trim(); }
+            } else {
+            	Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+            	serviceSpecification = new String[manipulation.getElements("Interface").length];
+            	for (int j = 0; j < manipulation.getElements("Interface").length; j++) {
+            		serviceSpecification[j] = manipulation.getElements("Interface")[j].getAttribute("name");
+            	}
+            }
+
+            // Get the factory policy
+			int factory = ProvidedServiceMetadata.SINGLETON_FACTORY;
+			if (providedServices[i].containsAttribute("factory") && providedServices[i].getAttribute("factory").equals("service")) { factory = ProvidedService.SERVICE_FACTORY; }
+
+			// Then create the provided service metadata
+			ProvidedServiceMetadata psm = new ProvidedServiceMetadata(serviceSpecification, factory);
+
+			// Create properties
+			Element[] dynamicProps = providedServices[i].getElements("DynamicProperty");
+			Element[] staticProps = providedServices[i].getElements("StaticProperty");
+			Element[] props = providedServices[i].getElements("Property");
+			for (int j = 0; j < dynamicProps.length; j++) {
+				Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Please use property instead of dynamic property");
+				String name = null;
+				if (dynamicProps[j].containsAttribute("name")) { name = dynamicProps[j].getAttribute("name"); }
+				String field = dynamicProps[j].getAttribute("field");
+				String value = null;
+				if (dynamicProps[j].containsAttribute("value")) { value = dynamicProps[j].getAttribute("value"); }
+				String type = null;
+				if (dynamicProps[j].containsAttribute("type")) { type = dynamicProps[j].getAttribute("type"); }
+				PropertyMetadata pm = new PropertyMetadata(name, field, type, value);
+				psm.addProperty(pm);
+			}
+			for (int j = 0; j < staticProps.length; j++) {
+				Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Please use property instead of static property");
+				String name = staticProps[j].getAttribute("name");
+				String value = staticProps[j].getAttribute("value");
+				String type = staticProps[j].getAttribute("type");
+				PropertyMetadata pm = new PropertyMetadata(name, null, type, value);
+				psm.addProperty(pm);
+			}
+			for (int j = 0; j < props.length; j++) {
+				String name = null;
+				if (props[j].containsAttribute("name")) { name = props[j].getAttribute("name"); }
+				String value = null;
+				if (props[j].containsAttribute("value")) { value = props[j].getAttribute("value"); }
+				String type = null;
+				if (props[j].containsAttribute("type")) { type = props[j].getAttribute("type"); }
+				String field = null;
+				if (props[j].containsAttribute("field")) { field = props[j].getAttribute("field"); }
+				PropertyMetadata pm = new PropertyMetadata(name, field, type, value);
+				psm.addProperty(pm);
+			}
+
+			// Create the provided service object
+			ProvidedService ps = new ProvidedService(this, psm);
+			if (checkProvidedService(ps)) { addProvidedService(ps); }
+			else {
+                String itfs = "";
+                for (int j = 0; j < serviceSpecification.length; j++) {
+                    itfs = itfs + " " + serviceSpecification[j];
+                }
+				Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The provided service" + itfs + " is not valid, it will be removed");
+				ps = null;
+			}
+		}
+
+		if (providedServices.length > 0) { m_componentManager.register(this); }
+	}
+
+	private boolean containsInterface(String s) {
+		Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+		for (int i = 0; i < manipulation.getElements("Interface").length; i++) {
+			if (manipulation.getElements("Interface")[i].getAttribute("name").equals(s)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	private boolean checkProvidedService(ProvidedService ps) {
+
+        for (int i = 0; i < ps.getMetadata().getServiceSpecification().length; i++) {
+            if (!containsInterface(ps.getMetadata().getServiceSpecification()[i])) {
+                Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The service specification " + ps.getMetadata().getServiceSpecification()[i] + " is not implemented by the component class");
+                return false;
+            }
+        }
+
+		// Fix internal property type
+		for (int i = 0; i < ps.getProperties().length; i++) {
+			Property prop = ps.getProperties()[i];
+			String field = prop.getMetadata().getField();
+
+			if (field == null) {
+				// Static dependency -> Nothing to check
+				return true;
+			} else {
+				Element manipulation = getComponentManager().getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+	        	String type = null;
+	        	for (int j = 0; j < manipulation.getElements("Field").length; j++) {
+	        		if (field.equals(manipulation.getElements("Field")[j].getAttribute("name"))) {
+	        			type = manipulation.getElements("Field")[j].getAttribute("type");
+	        			break;
+	        		}
+	        	}
+				if (type == null) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] A declared property was not found in the class : " + prop.getMetadata().getField());
+					return false;
+				}
+
+				if (type != null) {
+					if (type.endsWith("[]")) {
+						// TODO array property
+						Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] An array property was found in the class [Not implemented yet] : " + prop.getMetadata().getField());
+						return false;
+					}
+
+					if (prop.getMetadata().getType() == null) { prop.getMetadata().setType(type); }
+
+					if (!prop.getMetadata().getType().equals(type)) {
+						Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The field type [" + type + "] and the declared type [" + prop.getMetadata().getType() + "] are not the same for " + prop.getMetadata().getField());
+						prop.getMetadata().setType(type);
+					}
+				}
+				else {
+					Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The declared property " + prop.getMetadata().getField() + "  does not exist in the code");
+				}
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * Stop the provided service handler : unregister all provided services.
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+		for (int i = 0; i < m_providedServices.length; i++) {
+			m_providedServices[i].unregisterService();
+		}
+	}
+
+	/**
+	 * Start the provided service handler : register the service if the component is resolved.
+	 * Else do nothing and whait for a component state change event
+	 * @see org.apache.felix.ipojo.Handler#start()
+	 */
+	public void start() {
+		Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Start the provided service handler");
+			for (int i = 0; (m_componentManager.getState() == ComponentManager.VALID) && i < m_providedServices.length; i++) {
+				m_providedServices[i].registerService();
+			}
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) {
+		// Verify that the field name coreespond to a dependency
+		for (int i = 0; i < m_providedServices.length; i++) {
+			ProvidedService ps = m_providedServices[i];
+			for (int j = 0; j < ps.getProperties().length; j++) {
+				Property prop = ps.getProperties()[j];
+				if (fieldName.equals(prop.getMetadata().getField())) {
+					// it is the associated property
+					prop.set(value);
+				}
+			}
+		}
+		//Else do nothing
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) {
+		for (int i = 0; i < m_providedServices.length; i++) {
+			ProvidedService ps = m_providedServices[i];
+			for (int j = 0; j < ps.getProperties().length; j++) {
+				Property prop = ps.getProperties()[j];
+				if (fieldName.equals(prop.getMetadata().getField())) {
+					// it is the associated property
+					return prop.get();
+				}
+			}
+		}
+		// Else it is not a property
+		return value;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() {
+		// The provided service handler does not need to manipulate the field
+		// Return always true
+		return true;
+	}
+
+	/**
+	 * Register the services if the new state is VALID.
+	 * Unregister the services if the new state is UNRESOLVED.
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		// If the new state is UNRESOLVED => unregister all the services
+		if (state == ComponentManager.INVALID) {
+			stop();
+			return;
+		}
+
+		// If the new state is VALID => regiter all the services
+		if (state == ComponentManager.VALID) {
+			start();
+			return;
+		}
+
+	}
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,108 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+
+/**
+ * Provided Service Metadata.
+ * @author Clément Escoffier
+ */
+public class ProvidedServiceMetadata {
+
+	 /**
+     * Factory Policy : SINGLETON_FACTORY.
+     */
+    public static final int SINGLETON_FACTORY = 0;
+
+    /**
+     * Factory policy : SERVICE_FACTORY.
+     */
+    public static final int SERVICE_FACTORY = 1;
+
+    /**
+     * Factory policy : COMPONENT_FACTORY.
+     * TODO : Component_factory behavior
+     */
+    public static final int COMPONENT_FACTORY = 2;
+
+	/**
+	 * At this time, it is only the java interface full name.
+	 */
+	private String[] m_serviceSpecification = new String[0];
+
+	/**
+	 * List of proeprty metadata.
+	 */
+	private PropertyMetadata[] m_properties = new PropertyMetadata[0];
+
+	/**
+	 * Foactory policy.
+	 */
+	private int m_factoryPolicy = SINGLETON_FACTORY;
+
+	//CONSTRUCTOR :
+
+	/**
+     * Constructor.
+	 * @param specification : service specification (i.e. the interface)
+	 * @param factoryPolicy : the facotry policy.
+	 */
+	public ProvidedServiceMetadata(String[] specification, int factoryPolicy) {
+		m_serviceSpecification = specification;
+		m_factoryPolicy = factoryPolicy;
+	}
+
+	// GETTERS :
+
+
+	/**
+	 * @return the service specification (i.e. the interface)
+	 */
+	public String[] getServiceSpecification() { return m_serviceSpecification; }
+
+	/**
+	 * @return the property metadata list.
+	 */
+	public PropertyMetadata[] getProperties() { return m_properties; }
+
+	/**
+	 * @return the factory policy.
+	 */
+	public int getFactoryPolicy() { return m_factoryPolicy; }
+
+	// SETTERS  :
+
+	/**
+     * Add the given property metadata to the property metadata list.
+	 * @param p : property metdata to add
+	 */
+	protected void addProperty(PropertyMetadata p) {
+        for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
+            if (m_properties[i] == p) { return; }
+        }
+
+        if (m_properties.length > 0) {
+            PropertyMetadata[] newProp = new PropertyMetadata[m_properties.length + 1];
+            System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
+            newProp[m_properties.length] = p;
+            m_properties = newProp;
+        }
+        else {
+        	m_properties = new PropertyMetadata[] {p};
+        }
+	}
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/ProvidedServiceMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,180 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.
+ *
+ */
+package org.apache.felix.ipojo.parser;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Manifest Metadata parser.
+ * Read a manifest file and construct metadata
+ * @author Clement Escoffier
+ */
+public class ManifestMetadataParser {
+
+	/**
+	 * Manifest Headers.
+	 */
+	private Dictionary m_headers;
+
+	/**
+	 * Element list.
+	 */
+	private Element[] m_elements = new Element[0];
+
+    /**
+     * @return the component metadata.
+     * @throws ParseException when a parsing error occurs
+     */
+    public Element[] getComponentsMetadata() throws ParseException {
+    	return m_elements[0].getElements("Component");
+    }
+
+    private void addElement(Element elem) {
+    	for (int i = 0; (m_elements != null) && (i < m_elements.length); i++) {
+            if (m_elements[i] == elem) { return; }
+        }
+
+        if (m_elements != null) {
+            Element[] newElementsList = new Element[m_elements.length + 1];
+            System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
+            newElementsList[m_elements.length] = elem;
+            m_elements = newElementsList;
+        }
+        else { m_elements = new Element[] {elem}; }
+	}
+
+    private Element removeLastElement() {
+		int idx = -1;
+		idx = m_elements.length - 1;
+		Element last = m_elements[idx];
+        if (idx >= 0) {
+            if ((m_elements.length - 1) == 0) {
+            	// It is the last element of the list;
+            	m_elements = new Element[0];
+            	}
+            else {
+            	// Remove the last element of the list :
+                Element[] newElementsList = new Element[m_elements.length - 1];
+                System.arraycopy(m_elements, 0, newElementsList, 0, idx);
+                m_elements = newElementsList;
+            }
+        }
+        return last;
+	}
+
+	/**
+	 * Parse the given dictionnary and create the components manager.
+	 * @param dict : the given headers of the manifest file
+	 * @throws ParseException : if any error occurs
+	 */
+	public void parse(Dictionary dict) throws ParseException {
+		m_headers = dict;
+		String componentClassesStr = (String)m_headers.get("iPOJO-Components");
+		//Add the ipojo element inside the element list
+		addElement(new Element("iPOJO", ""));
+		parseElements(componentClassesStr.trim());
+
+	}
+
+	/**
+	 * Parse the metadata from the string given in argument.
+	 * @param metadata : the metadata to parse
+	 * @return Element : the root element resulting of the parsing
+	 * @throws ParseException : if any error occurs
+	 */
+	public static Element parse(String metadata) throws ParseException  {
+		ManifestMetadataParser parser = new ManifestMetadataParser();
+		parser.parseElements(metadata);
+		if (parser.m_elements.length != 1) { throw new ParseException("Error in parsing, root element not found : " + metadata); }
+		return parser.m_elements[0];
+	}
+
+	private void parseElements(String s) {
+		char[] string = s.toCharArray();
+
+		for (int i = 0; i < string.length; i++) {
+			char c = string[i];
+
+			switch(c) {
+
+			case '$' :
+				String attName = "";
+				String attValue = "";
+				String attNs = "";
+				i++;
+				c = string[i];
+				while (c != '=') {
+					if (c == ':') {
+						attNs = attName;
+						attName = "";
+					} else { attName = attName + c; }
+					i = i + 1;
+					c = string[i];
+				}
+				i++; // skip =
+				c = string[i];
+				while (c != ' ') {
+					attValue = attValue + c;
+					i++;
+					c = string[i];
+				}
+				Attribute att = new Attribute(attName, attNs , attValue);
+				m_elements[m_elements.length - 1].addAttribute(att);
+				break;
+
+			case '}' :
+				Element lastElement = removeLastElement();
+				if (m_elements.length != 0) {
+					Element newQueue = m_elements[m_elements.length - 1];
+					newQueue.addElement(lastElement);
+				}
+				else {
+					addElement(lastElement);
+				}
+				break;
+			case ' ' : break; // do nothing;
+			default :
+					String name = "";
+					String ns = "";
+					c = string[i];
+					while (c != ' ') {
+						if (c == ':') {
+							ns = name;
+							name = "";
+							i++;
+							c = string[i];
+						}
+						else {
+							name = name + c;
+							i++;
+							c = string[i];
+						}
+					}
+					// Skip spaces
+					while (string[i] == ' ') { i = i + 1; }
+					i = i + 1; // skip {
+				    Element elem = new Element(name, ns);
+					addElement(elem);
+				break;
+			}
+			}
+		}
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,38 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   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.
+ *
+ */
+package org.apache.felix.ipojo.parser;
+
+/**
+ * Exceptions thrown by parsers.
+ * @author Clement Escoffier
+ */
+public class ParseException extends Exception {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Parsing error.
+     * @param msg : the error emssage.
+     */
+    public ParseException(String msg) {
+        super(msg);
+    }
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,227 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/Configuration.java,v 1.16 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). 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.
+ */
+package org.osgi.service.cm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+/**
+ * The configuration information for a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code> object.
+ * 
+ * The Configuration Admin service uses this interface to represent the
+ * configuration information for a <code>ManagedService</code> or for a
+ * service instance of a <code>ManagedServiceFactory</code>.
+ * 
+ * <p>
+ * A <code>Configuration</code> object contains a configuration dictionary and
+ * allows the properties to be updated via this object. Bundles wishing to
+ * receive configuration dictionaries do not need to use this class - they
+ * register a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code>. Only administrative bundles, and
+ * bundles wishing to update their own configurations need to use this class.
+ * 
+ * <p>
+ * The properties handled in this configuration have case insensitive
+ * <code>String</code> objects as keys. However, case is preserved from the
+ * last set key/value.
+ * <p>
+ * A configuration can be <i>bound </i> to a bundle location (
+ * <code>Bundle.getLocation()</code>). The purpose of binding a
+ * <code>Configuration</code> object to a location is to make it impossible
+ * for another bundle to forge a PID that would match this configuration. When a
+ * configuration is bound to a specific location, and a bundle with a different
+ * location registers a corresponding <code>ManagedService</code> object or
+ * <code>ManagedServiceFactory</code> object, then the configuration is not
+ * passed to the updated method of that object.
+ * 
+ * <p>
+ * If a configuration's location is <code>null</code>, it is not yet bound to
+ * a location. It will become bound to the location of the first bundle that
+ * registers a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code> object with the corresponding PID.
+ * <p>
+ * The same <code>Configuration</code> object is used for configuring both a
+ * Managed Service Factory and a Managed Service. When it is important to
+ * differentiate between these two the term "factory configuration" is used.
+ * 
+ * @version $Revision: 1.16 $
+ */
+public interface Configuration {
+	/**
+	 * Get the PID for this <code>Configuration</code> object.
+	 * 
+	 * @return the PID for this <code>Configuration</code> object.
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public String getPid();
+
+	/**
+	 * Return the properties of this <code>Configuration</code> object.
+	 * 
+	 * The <code>Dictionary</code> object returned is a private copy for the
+	 * caller and may be changed without influencing the stored configuration.
+	 * The keys in the returned dictionary are case insensitive and are always
+	 * of type <code>String</code>.
+	 * 
+	 * <p>
+	 * If called just after the configuration is created and before update has
+	 * been called, this method returns <code>null</code>.
+	 * 
+	 * @return A private copy of the properties for the caller or
+	 *         <code>null</code>. These properties must not contain the
+	 *         "service.bundleLocation" property. The value of this property may
+	 *         be obtained from the <code>getBundleLocation</code> method.
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public Dictionary getProperties();
+
+	/**
+	 * Update the properties of this <code>Configuration</code> object.
+	 * 
+	 * Stores the properties in persistent storage after adding or overwriting
+	 * the following properties:
+	 * <ul>
+	 * <li>"service.pid" : is set to be the PID of this configuration.</li>
+	 * <li>"service.factoryPid" : if this is a factory configuration it is set
+	 * to the factory PID else it is not set.</li>
+	 * </ul>
+	 * These system properties are all of type <code>String</code>.
+	 * 
+	 * <p>
+	 * If the corresponding Managed Service/Managed Service Factory is
+	 * registered, its updated method must be called asynchronously. Else, this
+	 * callback is delayed until aforementioned registration occurs.
+	 * 
+	 * <p>
+	 * Also intiates an asynchronous call to all
+	 * <code>ConfigurationListener</code>s with a
+	 * <code>ConfigurationEvent.CM_UPDATED</code> event.
+	 * 
+	 * @param properties the new set of properties for this configuration
+	 * @throws IOException if update cannot be made persistent
+	 * @throws IllegalArgumentException if the <code>Dictionary</code> object
+	 *         contains invalid configuration types or contains case variants of
+	 *         the same key name.
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public void update(Dictionary properties) throws IOException;
+
+	/**
+	 * Delete this <code>Configuration</code> object.
+	 * 
+	 * Removes this configuration object from the persistent store. Notify
+	 * asynchronously the corresponding Managed Service or Managed Service
+	 * Factory. A <code>ManagedService</code> object is notified by a call to
+	 * its <code>updated</code> method with a <code>null</code> properties
+	 * argument. A <code>ManagedServiceFactory</code> object is notified by a
+	 * call to its <code>deleted</code> method.
+	 * 
+	 * <p>
+	 * Also intiates an asynchronous call to all
+	 * <code>ConfigurationListener</code>s with a
+	 * <code>ConfigurationEvent.CM_DELETED</code> event.
+	 * 
+	 * @throws IOException If delete fails
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public void delete() throws IOException;
+
+	/**
+	 * For a factory configuration return the PID of the corresponding Managed
+	 * Service Factory, else return <code>null</code>.
+	 * 
+	 * @return factory PID or <code>null</code>
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public String getFactoryPid();
+
+	/**
+	 * Update the <code>Configuration</code> object with the current
+	 * properties.
+	 * 
+	 * Initiate the <code>updated</code> callback to the Managed Service or
+	 * Managed Service Factory with the current properties asynchronously.
+	 * 
+	 * <p>
+	 * This is the only way for a bundle that uses a Configuration Plugin
+	 * service to initate a callback. For example, when that bundle detects a
+	 * change that requires an update of the Managed Service or Managed Service
+	 * Factory via its <code>ConfigurationPlugin</code> object.
+	 * 
+	 * @see ConfigurationPlugin
+	 * @throws IOException if update cannot access the properties in persistent
+	 *         storage
+	 * @throws IllegalStateException if this configuration has been deleted
+	 */
+	public void update() throws IOException;
+
+	/**
+	 * Bind this <code>Configuration</code> object to the specified bundle
+	 * location.
+	 * 
+	 * If the bundleLocation parameter is <code>null</code> then the
+	 * <code>Configuration</code> object will not be bound to a location. It
+	 * will be set to the bundle's location before the first time a Managed
+	 * Service/Managed Service Factory receives this <code>Configuration</code>
+	 * object via the updated method and before any plugins are called. The
+	 * bundle location will be set persistently.
+	 * 
+	 * @param bundleLocation a bundle location or <code>null</code>
+	 * @throws IllegalStateException If this configuration has been deleted.
+	 * @throws SecurityException If the caller does not have
+	 *         <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public void setBundleLocation(String bundleLocation);
+
+	/**
+	 * Get the bundle location.
+	 * 
+	 * Returns the bundle location to which this configuration is bound, or
+	 * <code>null</code> if it is not yet bound to a bundle location.
+	 * 
+	 * @return location to which this configuration is bound, or
+	 *         <code>null</code>.
+	 * @throws IllegalStateException If this <code>Configuration</code> object
+	 *         has been deleted.
+	 * @throws SecurityException If the caller does not have
+	 *         <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public String getBundleLocation();
+
+	/**
+	 * Equality is defined to have equal PIDs
+	 * 
+	 * Two Configuration objects are equal when their PIDs are equal.
+	 * 
+	 * @param other <code>Configuration</code> object to compare against
+	 * @return <code>true</code> if equal, <code>false</code> if not a
+	 *         <code>Configuration</code> object or one with a different PID.
+	 */
+	public boolean equals(Object other);
+
+	/**
+	 * Hash code is based on PID.
+	 * 
+	 * The hashcode for two Configuration objects must be the same when the
+	 * Configuration PID's are the same.
+	 * 
+	 * @return hash code for this Configuration object
+	 */
+	public int hashCode();
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/Configuration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,256 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationAdmin.java,v 1.14 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). 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.
+ */
+package org.osgi.service.cm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Service for administering configuration data.
+ * 
+ * <p>
+ * The main purpose of this interface is to store bundle configuration data
+ * persistently. This information is represented in <code>Configuration</code>
+ * objects. The actual configuration data is a <code>Dictionary</code> of
+ * properties inside a <code>Configuration</code> object.
+ * 
+ * <p>
+ * There are two principally different ways to manage configurations. First
+ * there is the concept of a Managed Service, where configuration data is
+ * uniquely associated with an object registered with the service registry.
+ * 
+ * <p>
+ * Next, there is the concept of a factory where the Configuration Admin service
+ * will maintain 0 or more <code>Configuration</code> objects for a Managed
+ * Service Factory that is registered with the Framework.
+ * 
+ * <p>
+ * The first concept is intended for configuration data about "things/services"
+ * whose existence is defined externally, e.g. a specific printer. Factories are
+ * intended for "things/services" that can be created any number of times, e.g.
+ * a configuration for a DHCP server for different networks.
+ * 
+ * <p>
+ * Bundles that require configuration should register a Managed Service or a
+ * Managed Service Factory in the service registry. A registration property
+ * named <code>service.pid</code> (persistent identifier or PID) must be used
+ * to identify this Managed Service or Managed Service Factory to the
+ * Configuration Admin service.
+ * 
+ * <p>
+ * When the ConfigurationAdmin detects the registration of a Managed Service, it
+ * checks its persistent storage for a configuration object whose PID matches
+ * the PID registration property (<code>service.pid</code>) of the Managed
+ * Service. If found, it calls {@link ManagedService#updated}method with the
+ * new properties. The implementation of a Configuration Admin service must run
+ * these call-backs asynchronously to allow proper synchronization.
+ * 
+ * <p>
+ * When the Configuration Admin service detects a Managed Service Factory
+ * registration, it checks its storage for configuration objects whose
+ * <code>factoryPid</code> matches the PID of the Managed Service Factory. For
+ * each such <code>Configuration</code> objects, it calls the
+ * <code>ManagedServiceFactory.updated</code> method asynchronously with the
+ * new properties. The calls to the <code>updated</code> method of a
+ * <code>ManagedServiceFactory</code> must be executed sequentially and not
+ * overlap in time.
+ * 
+ * <p>
+ * In general, bundles having permission to use the Configuration Admin service
+ * can only access and modify their own configuration information. Accessing or
+ * modifying the configuration of another bundle requires
+ * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ * 
+ * <p>
+ * <code>Configuration</code> objects can be <i>bound </i> to a specified
+ * bundle location. In this case, if a matching Managed Service or Managed
+ * Service Factory is registered by a bundle with a different location, then the
+ * Configuration Admin service must not do the normal callback, and it should
+ * log an error. In the case where a <code>Configuration</code> object is not
+ * bound, its location field is <code>null</code>, the Configuration Admin
+ * service will bind it to the location of the bundle that registers the first
+ * Managed Service or Managed Service Factory that has a corresponding PID
+ * property. When a <code>Configuration</code> object is bound to a bundle
+ * location in this manner, the Confguration Admin service must detect if the
+ * bundle corresponding to the location is uninstalled. If this occurs, the
+ * <code>Configuration</code> object is unbound, that is its location field is
+ * set back to <code>null</code>.
+ * 
+ * <p>
+ * The method descriptions of this class refer to a concept of "the calling
+ * bundle". This is a loose way of referring to the bundle which obtained the
+ * Configuration Admin service from the service registry. Implementations of
+ * <code>ConfigurationAdmin</code> must use a
+ * {@link org.osgi.framework.ServiceFactory}to support this concept.
+ * 
+ * @version $Revision: 1.14 $
+ */
+public interface ConfigurationAdmin {
+	/**
+	 * Service property naming the Factory PID in the configuration dictionary.
+	 * The property's value is of type <code>String</code>.
+	 * 
+	 * @since 1.1
+	 */
+	public final static String	SERVICE_FACTORYPID		= "service.factoryPid";
+	/**
+	 * Service property naming the location of the bundle that is associated
+	 * with a a <code>Configuration</code> object. This property can be
+	 * searched for but must not appear in the configuration dictionary for
+	 * security reason. The property's value is of type <code>String</code>.
+	 * 
+	 * @since 1.1
+	 */
+	public final static String	SERVICE_BUNDLELOCATION	= "service.bundleLocation";
+
+	/**
+	 * Create a new factory <code>Configuration</code> object with a new PID.
+	 * 
+	 * The properties of the new <code>Configuration</code> object are
+	 * <code>null</code> until the first time that its
+	 * {@link Configuration#update(Dictionary)}method is called.
+	 * 
+	 * <p>
+	 * It is not required that the <code>factoryPid</code> maps to a
+	 * registered Managed Service Factory.
+	 * <p>
+	 * The <code>Configuration</code> object is bound to the location of the
+	 * calling bundle.
+	 * 
+	 * @param factoryPid PID of factory (not <code>null</code>).
+	 * @return A new <code>Configuration</code> object.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code> and <code>factoryPid</code> is bound to another bundle.
+	 */
+	public Configuration createFactoryConfiguration(String factoryPid)
+			throws IOException;
+
+	/**
+	 * Create a new factory <code>Configuration</code> object with a new PID.
+	 * 
+	 * The properties of the new <code>Configuration</code> object are
+	 * <code>null</code> until the first time that its
+	 * {@link Configuration#update(Dictionary)}method is called.
+	 * 
+	 * <p>
+	 * It is not required that the <code>factoryPid</code> maps to a
+	 * registered Managed Service Factory.
+	 * 
+	 * <p>
+	 * The <code>Configuration</code> is bound to the location specified. If
+	 * this location is <code>null</code> it will be bound to the location of
+	 * the first bundle that registers a Managed Service Factory with a
+	 * corresponding PID.
+	 * 
+	 * @param factoryPid PID of factory (not <code>null</code>).
+	 * @param location A bundle location string, or <code>null</code>.
+	 * @return a new <code>Configuration</code> object.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public Configuration createFactoryConfiguration(String factoryPid, String location)
+			throws IOException;
+
+	/**
+	 * Get an existing <code>Configuration</code> object from the persistent
+	 * store, or create a new <code>Configuration</code> object.
+	 * 
+	 * <p>
+	 * If a <code>Configuration</code> with this PID already exists in
+	 * Configuration Admin service return it. The location parameter is ignored
+	 * in this case.
+	 * 
+	 * <p>
+	 * Else, return a new <code>Configuration</code> object. This new object
+	 * is bound to the location and the properties are set to <code>null</code>.
+	 * If the location parameter is <code>null</code>, it will be set when a
+	 * Managed Service with the corresponding PID is registered for the first
+	 * time.
+	 * 
+	 * @param pid Persistent identifier.
+	 * @param location The bundle location string, or <code>null</code>.
+	 * @return An existing or new <code>Configuration</code> object.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if the caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public Configuration getConfiguration(String pid, String location)
+			throws IOException;
+
+	/**
+	 * Get an existing or new <code>Configuration</code> object from the
+	 * persistent store.
+	 * 
+	 * If the <code>Configuration</code> object for this PID does not exist,
+	 * create a new <code>Configuration</code> object for that PID, where
+	 * properties are <code>null</code>. Bind its location to the calling
+	 * bundle's location.
+	 * 
+	 * <p>
+	 * Otherwise, if the location of the existing <code>Configuration</code> object
+	 * is <code>null</code>, set it to the calling bundle's location.
+	 * 
+	 * @param pid persistent identifier.
+	 * @return an existing or new <code>Configuration</code> matching the PID.
+	 * @throws IOException if access to persistent storage fails.
+	 * @throws SecurityException if the <code>Configuration</code> object is bound to a location different from that of the calling bundle and it has no <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 */
+	public Configuration getConfiguration(String pid) throws IOException;
+
+	/**
+	 * List the current <code>Configuration</code> objects which match the
+	 * filter.
+	 * 
+	 * <p>
+	 * Only <code>Configuration</code> objects with non- <code>null</code>
+	 * properties are considered current. That is,
+	 * <code>Configuration.getProperties()</code> is guaranteed not to return
+	 * <code>null</code> for each of the returned <code>Configuration</code>
+	 * objects.
+	 * 
+	 * <p>
+	 * Normally only <code>Configuration</code> objects that are bound to the
+	 * location of the calling bundle are returned, or all if the caller has 
+	 * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+	 * 
+	 * <p>
+	 * The syntax of the filter string is as defined in the <code>Filter</code>
+	 * class. The filter can test any configuration parameters including the
+	 * following system properties:
+	 * <ul>
+	 * <li><code>service.pid</code>-<code>String</code>- the PID under
+	 * which this is registered</li>
+	 * <li><code>service.factoryPid</code>-<code>String</code>- the
+	 * factory if applicable</li>
+	 * <li><code>service.bundleLocation</code>-<code>String</code>- the
+	 * bundle location</li>
+	 * </ul>
+	 * The filter can also be <code>null</code>, meaning that all
+	 * <code>Configuration</code> objects should be returned.
+	 * 
+	 * @param filter a <code>Filter</code> object, or <code>null</code> to
+	 *        retrieve all <code>Configuration</code> objects.
+	 * @return all matching <code>Configuration</code> objects, or
+	 *         <code>null</code> if there aren't any
+	 * @throws IOException if access to persistent storage fails
+	 * @throws InvalidSyntaxException if the filter string is invalid
+	 */
+	public Configuration[] listConfigurations(String filter) throws IOException,
+			InvalidSyntaxException;
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,167 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationEvent.java,v 1.8 2006/03/14 01:21:09 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2004, 2005). 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.
+ */
+package org.osgi.service.cm;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A Configuration Event.
+ * 
+ * <p>
+ * <code>ConfigurationEvent</code> objects are delivered to all registered
+ * <code>ConfigurationListener</code> service objects. ConfigurationEvents
+ * must be asynchronously delivered in chronological order with respect to each
+ * listener.
+ * 
+ * <p>
+ * A type code is used to identify the type of event. The following event types
+ * are defined:
+ * <ul>
+ * <li>{@link #CM_UPDATED}
+ * <li>{@link #CM_DELETED}
+ * </ul>
+ * Additional event types may be defined in the future.
+ * 
+ * <p>
+ * Security Considerations. <code>ConfigurationEvent</code> objects do not
+ * provide <code>Configuration</code> objects, so no sensitive configuration
+ * information is available from the event. If the listener wants to locate the
+ * <code>Configuration</code> object for the specified pid, it must use
+ * <code>ConfigurationAdmin</code>.
+ * 
+ * @see ConfigurationListener
+ * 
+ * @version $Revision: 1.8 $
+ * @since 1.2
+ */
+public class ConfigurationEvent {
+	/**
+	 * A <code>Configuration</code> has been updated.
+	 * 
+	 * <p>
+	 * This <code>ConfigurationEvent</code> type that indicates that a
+	 * <code>Configuration</code> object has been updated with new properties.
+	 * 
+	 * An event is fired when a call to <code>Configuration.update</code>
+	 * successfully changes a configuration.
+	 * 
+	 * <p>
+	 * The value of <code>CM_UPDATED</code> is 1.
+	 */
+	public static final int			CM_UPDATED	= 1;
+	/**
+	 * A <code>Configuration</code> has been deleted.
+	 * 
+	 * <p>
+	 * This <code>ConfigurationEvent</code> type that indicates that a
+	 * <code>Configuration</code> object has been deleted.
+	 * 
+	 * An event is fired when a call to <code>Configuration.delete</code>
+	 * successfully deletes a configuration.
+	 * 
+	 * <p>
+	 * The value of <code>CM_DELETED</code> is 2.
+	 */
+	public static final int			CM_DELETED	= 2;
+	/**
+	 * Type of this event.
+	 * 
+	 * @see #getType
+	 */
+	private final int				type;
+	/**
+	 * The factory pid associated with this event.
+	 */
+	private final String			factoryPid;
+	/**
+	 * The pid associated with this event.
+	 */
+	private final String			pid;
+	/**
+	 * The ConfigurationAdmin service which created this event.
+	 */
+	private final ServiceReference	reference;
+
+	/**
+	 * Constructs a <code>ConfigurationEvent</code> object from the given
+	 * <code>ServiceReference</code> object, event type, and pids.
+	 * 
+	 * @param reference The <code>ServiceReference</code> object of the
+	 *        Configuration Admin service that created this event.
+	 * @param type The event type. See {@link #getType}.
+	 * @param factoryPid The factory pid of the associated configuration if the
+	 *        target of the configuration is a ManagedServiceFactory. Otherwise
+	 *        <code>null</code> if the target of the configuration is a
+	 *        ManagedService.
+	 * @param pid The pid of the associated configuration.
+	 */
+	public ConfigurationEvent(ServiceReference reference, int type,
+			String factoryPid, String pid) {
+		this.reference = reference;
+		this.type = type;
+		this.factoryPid = factoryPid;
+		this.pid = pid;
+	}
+
+	/**
+	 * Returns the factory pid of the associated configuration.
+	 * 
+	 * @return Returns the factory pid of the associated configuration if the
+	 *         target of the configuration is a ManagedServiceFactory. Otherwise
+	 *         <code>null</code> if the target of the configuration is a
+	 *         ManagedService.
+	 */
+	public String getFactoryPid() {
+		return factoryPid;
+	}
+
+	/**
+	 * Returns the pid of the associated configuration.
+	 * 
+	 * @return Returns the pid of the associated configuration.
+	 */
+	public String getPid() {
+		return pid;
+	}
+
+	/**
+	 * Return the type of this event.
+	 * <p>
+	 * The type values are:
+	 * <ul>
+	 * <li>{@link #CM_UPDATED}
+	 * <li>{@link #CM_DELETED}
+	 * </ul>
+	 * 
+	 * @return The type of this event.
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * Return the <code>ServiceReference</code> object of the Configuration
+	 * Admin service that created this event.
+	 * 
+	 * @return The <code>ServiceReference</code> object for the Configuration
+	 *         Admin service that created this event.
+	 */
+	public ServiceReference getReference() {
+		return reference;
+	}
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,112 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationException.java,v 1.11 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). 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.
+ */
+package org.osgi.service.cm;
+
+/**
+ * An <code>Exception</code> class to inform the Configuration Admin service
+ * of problems with configuration data.
+ * 
+ * @version $Revision: 1.11 $
+ */
+public class ConfigurationException extends Exception {
+	static final long	serialVersionUID	= -1690090413441769377L;
+
+	private String		property;
+	private String		reason;
+
+	/**
+	 * Nested exception.
+	 */
+	private Throwable	cause;
+
+	/**
+	 * Create a <code>ConfigurationException</code> object.
+	 * 
+	 * @param property name of the property that caused the problem,
+	 *        <code>null</code> if no specific property was the cause
+	 * @param reason reason for failure
+	 */
+	public ConfigurationException(String property, String reason) {
+		super(property + " : " + reason);
+		this.property = property;
+		this.reason = reason;
+		this.cause = null;
+	}
+
+	/**
+	 * Create a <code>ConfigurationException</code> object.
+	 * 
+	 * @param property name of the property that caused the problem,
+	 *        <code>null</code> if no specific property was the cause
+	 * @param reason reason for failure
+	 * @param cause The cause of this exception.
+	 * @since 1.2
+	 */
+	public ConfigurationException(String property, String reason,
+			Throwable cause) {
+		super(property + " : " + reason);
+		this.property = property;
+		this.reason = reason;
+		this.cause = cause;
+	}
+
+	/**
+	 * Return the property name that caused the failure or null.
+	 * 
+	 * @return name of property or null if no specific property caused the
+	 *         problem
+	 */
+	public String getProperty() {
+		return property;
+	}
+
+	/**
+	 * Return the reason for this exception.
+	 * 
+	 * @return reason of the failure
+	 */
+	public String getReason() {
+		return reason;
+	}
+
+	/**
+	 * Returns the cause of this exception or <code>null</code> if no cause
+	 * was specified when this exception was created.
+	 * 
+	 * @return The cause of this exception or <code>null</code> if no cause
+	 *         was specified.
+	 * @since 1.2
+	 */
+	public Throwable getCause() {
+		return cause;
+	}
+
+	/**
+	 * The cause of this exception can only be set when constructed.
+	 * 
+	 * @param cause Cause of the exception.
+	 * @return This object.
+	 * @throws java.lang.IllegalStateException This method will always throw an
+	 *         <code>IllegalStateException</code> since the cause of this
+	 *         exception can only be set when constructed.
+	 * @since 1.2
+	 */
+	public Throwable initCause(Throwable cause) {
+		throw new IllegalStateException();
+	}
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,50 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationListener.java,v 1.9 2006/03/14 01:21:09 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2004, 2005). 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.
+ */
+package org.osgi.service.cm;
+
+/**
+ * Listener for Configuration Events. When a <code>ConfigurationEvent</code>
+ * is fired, it is asynchronously delivered to a
+ * <code>ConfigurationListener</code>.
+ * 
+ * <p>
+ * <code>ConfigurationListener</code> objects are registered with the
+ * Framework service registry and are notified with a
+ * <code>ConfigurationEvent</code> object when an event is fired.
+ * <p>
+ * <code>ConfigurationListener</code> objects can inspect the received
+ * <code>ConfigurationEvent</code> object to determine its type, the pid of
+ * the <code>Configuration</code> object with which it is associated, and the
+ * Configuration Admin service that fired the event.
+ * 
+ * <p>
+ * Security Considerations. Bundles wishing to monitor configuration events will
+ * require <code>ServicePermission[ConfigurationListener,REGISTER]</code> to
+ * register a <code>ConfigurationListener</code> service.
+ * 
+ * @version $Revision: 1.9 $
+ * @since 1.2
+ */
+public interface ConfigurationListener {
+	/**
+	 * Receives notification of a Configuration that has changed.
+	 * 
+	 * @param event The <code>ConfigurationEvent</code>.
+	 */
+	public void configurationEvent(ConfigurationEvent event);
+}
\ No newline at end of file

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,217 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPermission.java,v 1.20 2006/03/14 01:21:09 hargrave Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2004, 2005). 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.
+ */
+
+package org.osgi.service.cm;
+
+import java.security.*;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * Indicates a bundle's authority to configure bundles.
+ * 
+ * This permission has only a single action: CONFIGURE.
+ * 
+ * @version $Revision: 1.20 $
+ * @since 1.2
+ */
+
+public final class ConfigurationPermission extends BasicPermission {
+	static final long			serialVersionUID	= 5716868734811965383L;
+	/**
+	 * The action string <code>configure</code>.
+	 */
+	public final static String	CONFIGURE			= "configure";
+
+	/**
+	 * Create a new ConfigurationPermission.
+	 * 
+	 * @param name Name must be &quot;*&quot;.
+	 * @param actions <code>configure</code> (canonical order).
+	 */
+
+	public ConfigurationPermission(String name, String actions) {
+		super(name);
+		if (!name.equals("*")) {
+			throw new IllegalArgumentException("name must be *");
+		}
+		actions = actions.trim();
+		if (actions.equalsIgnoreCase(CONFIGURE)||actions.equals("*"))
+			return;
+		
+		throw new IllegalArgumentException("actions must be " + CONFIGURE);
+	}
+
+	/**
+	 * Determines if a <code>ConfigurationPermission</code> object "implies"
+	 * the specified permission.
+	 * 
+	 * @param p The target permission to check.
+	 * @return <code>true</code> if the specified permission is implied by
+	 *         this object; <code>false</code> otherwise.
+	 */
+
+	public boolean implies(Permission p) {
+		return p instanceof ConfigurationPermission;
+	}
+
+	/**
+	 * Determines the equality of two <code>ConfigurationPermission</code>
+	 * objects.
+	 * <p>
+	 * Two <code>ConfigurationPermission</code> objects are equal.
+	 * 
+	 * @param obj The object being compared for equality with this object.
+	 * @return <code>true</code> if <code>obj</code> is equivalent to this
+	 *         <code>ConfigurationPermission</code>; <code>false</code>
+	 *         otherwise.
+	 */
+	public boolean equals(Object obj) {
+		return obj instanceof ConfigurationPermission;
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return Hash code value for this object.
+	 */
+
+	public int hashCode() {
+		return getName().hashCode() ^ getActions().hashCode();
+	}
+
+	/**
+	 * Returns the canonical string representation of the
+	 * <code>ConfigurationPermission</code> actions.
+	 * 
+	 * <p>
+	 * Always returns present <code>ConfigurationPermission</code> actions in
+	 * the following order: <code>CONFIGURE</code>
+	 * 
+	 * @return Canonical string representation of the
+	 *         <code>ConfigurationPermission</code> actions.
+	 */
+	public String getActions() {
+		return CONFIGURE;
+	}
+
+	/**
+	 * Returns a new <code>PermissionCollection</code> object suitable for
+	 * storing <code>ConfigurationPermission</code>s.
+	 * 
+	 * @return A new <code>PermissionCollection</code> object.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new ConfigurationPermissionCollection();
+	}
+}
+
+/**
+ * Stores a set of <code>ConfigurationPermission</code> permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class ConfigurationPermissionCollection extends PermissionCollection {
+	static final long	serialVersionUID	= -6917638867081695839L;
+	/**
+	 * True if collection is non-empty.
+	 * 
+	 * @serial
+	 */
+	private boolean		hasElement;
+
+	/**
+	 * Creates an empty <tt>ConfigurationPermissionCollection</tt> object.
+	 * 
+	 */
+	public ConfigurationPermissionCollection() {
+		hasElement = false;
+	}
+
+	/**
+	 * Adds the specified permission to the
+	 * <tt>ConfigurationPermissionCollection</tt>. The key for the hash is
+	 * the interface name of the service.
+	 * 
+	 * @param permission The <tt>Permission</tt> object to add.
+	 * 
+	 * @exception IllegalArgumentException If the permission is not an
+	 *            <tt>ConfigurationPermission</tt>.
+	 * 
+	 * @exception SecurityException If this ConfigurationPermissionCollection
+	 *            object has been marked read-only.
+	 */
+
+	public void add(Permission permission) {
+		if (!(permission instanceof ConfigurationPermission)) {
+			throw new IllegalArgumentException("invalid permission: "
+					+ permission);
+		}
+
+		if (isReadOnly())
+			throw new SecurityException("attempt to add a Permission to a "
+					+ "readonly PermissionCollection");
+
+		hasElement = true;
+	}
+
+	/**
+	 * Determines if the specified set of permissions implies the permissions
+	 * expressed in the parameter <tt>permission</tt>.
+	 * 
+	 * @param p The Permission object to compare.
+	 * 
+	 * @return true if permission is a proper subset of a permission in the set;
+	 *         false otherwise.
+	 */
+
+	public boolean implies(Permission p) {
+		return hasElement && (p instanceof ConfigurationPermission);
+	}
+
+	/**
+	 * Returns an enumeration of an <tt>ConfigurationPermission</tt> object.
+	 * 
+	 * @return Enumeration of an <tt>ConfigurationPermission</tt> object.
+	 */
+
+	public Enumeration elements() {
+		return new Enumeration() {
+			private boolean	more	= hasElement;
+
+			public boolean hasMoreElements() {
+				return more;
+			}
+
+			public Object nextElement() {
+				if (more) {
+					more = false;
+
+					return new ConfigurationPermission("*",
+							ConfigurationPermission.CONFIGURE);
+				}
+				else {
+					throw new NoSuchElementException();
+				}
+			}
+		};
+	}
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,131 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPlugin.java,v 1.10 2006/03/14 01:21:09 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2001, 2005). 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.
+ */
+package org.osgi.service.cm;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A service interface for processing configuration dictionary before the
+ * update.
+ * 
+ * <p>
+ * A bundle registers a <code>ConfigurationPlugin</code> object in order to
+ * process configuration updates before they reach the Managed Service or
+ * Managed Service Factory. The Configuration Admin service will detect
+ * registrations of Configuration Plugin services and must call these services
+ * every time before it calls the <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code>
+ * <code>updated</code> method. The
+ * Configuration Plugin service thus has the opportunity to view and modify the
+ * properties before they are passed to the ManagedS ervice or Managed Service
+ * Factory.
+ * 
+ * <p>
+ * Configuration Plugin (plugin) services have full read/write access to all
+ * configuration information. Therefore, bundles using this facility should be
+ * trusted. Access to this facility should be limited with
+ * <code>ServicePermission[ConfigurationPlugin,REGISTER]</code>.
+ * Implementations of a Configuration Plugin service should assure that they
+ * only act on appropriate configurations.
+ * 
+ * <p>
+ * The <code>Integer</code> <code>service.cmRanking</code> registration
+ * property may be specified. Not specifying this registration property, or
+ * setting it to something other than an <code>Integer</code>, is the same as
+ * setting it to the <code>Integer</code> zero. The
+ * <code>service.cmRanking</code> property determines the order in which
+ * plugins are invoked. Lower ranked plugins are called before higher ranked
+ * ones. In the event of more than one plugin having the same value of
+ * <code>service.cmRanking</code>, then the Configuration Admin service
+ * arbitrarily chooses the order in which they are called.
+ * 
+ * <p>
+ * By convention, plugins with <code>service.cmRanking&lt; 0</code> or
+ * <code>service.cmRanking &gt; 1000</code> should not make modifications to
+ * the properties.
+ * 
+ * <p>
+ * The Configuration Admin service has the right to hide properties from
+ * plugins, or to ignore some or all the changes that they make. This might be
+ * done for security reasons. Any such behavior is entirely implementation
+ * defined.
+ * 
+ * <p>
+ * A plugin may optionally specify a <code>cm.target</code> registration
+ * property whose value is the PID of the Managed Service or Managed Service
+ * Factory whose configuration updates the plugin is intended to intercept. The
+ * plugin will then only be called with configuration updates that are targetted
+ * at the Managed Service or Managed Service Factory with the specified PID.
+ * Omitting the <code>cm.target</code> registration property means that the
+ * plugin is called for all configuration updates.
+ * 
+ * @version $Revision: 1.10 $
+ */
+public interface ConfigurationPlugin {
+	/**
+	 * A service property to limit the Managed Service or Managed Service
+	 * Factory configuration dictionaries a Configuration Plugin service
+	 * receives.
+	 * 
+	 * This property contains a <code>String[]</code> of PIDs. A Configuration
+	 * Admin service must call a Configuration Plugin service only when this
+	 * property is not set, or the target service's PID is listed in this
+	 * property.
+	 */
+	public static final String	CM_TARGET	= "cm.target";
+	/**
+	 * A service property to specify the order in which plugins are invoked.
+	 * 
+	 * This property contains an <code>Integer</code> ranking of the plugin.
+	 * Not specifying this registration property, or setting it to something
+	 * other than an <code>Integer</code>, is the same as setting it to the
+	 * <code>Integer</code> zero. This property determines the order in which
+	 * plugins are invoked. Lower ranked plugins are called before higher ranked
+	 * ones.
+	 * 
+	 * @since 1.2
+	 */
+	public static final String	CM_RANKING	= "service.cmRanking";
+
+	/**
+	 * View and possibly modify the a set of configuration properties before
+	 * they are sent to the Managed Service or the Managed Service Factory. The
+	 * Configuration Plugin services are called in increasing order of their
+	 * <code>service.cmRanking</code> property. If this property is undefined
+	 * or is a non- <code>Integer</code> type, 0 is used.
+	 * 
+	 * <p>
+	 * This method should not modify the properties unless the
+	 * <code>service.cmRanking</code> of this plugin is in the range
+	 * <code>0 &lt;= service.cmRanking &lt;= 1000</code>.
+	 * <p>
+	 * If this method throws any <code>Exception</code>, the Configuration
+	 * Admin service must catch it and should log it.
+	 * 
+	 * @param reference reference to the Managed Service or Managed Service
+	 *        Factory
+	 * @param properties The configuration properties. This argument must not
+	 *        contain the "service.bundleLocation" property. The value of this
+	 *        property may be obtained from the
+	 *        <code>Configuration.getBundleLocation</code> method.
+	 */
+	public void modifyConfiguration(ServiceReference reference,
+			Dictionary properties);
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
------------------------------------------------------------------------------
    svn:eol-style = native