You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2009/04/14 15:42:56 UTC

svn commit: r764777 - in /felix/trunk/ipojo/api: ./ src/main/java/org/apache/felix/ipojo/api/ src/main/java/org/apache/felix/ipojo/api/composite/ src/test/ src/test/java/ src/test/java/org/ src/test/java/org/apache/ src/test/java/org/apache/felix/ src/...

Author: clement
Date: Tue Apr 14 13:42:55 2009
New Revision: 764777

URL: http://svn.apache.org/viewvc?rev=764777&view=rev
Log:
Add the composite API (initial version)
Add the SingletonComponentType

Added:
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/SingletonComponentType.java   (with props)
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/CompositeComponentType.java   (with props)
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ExportedService.java   (with props)
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ImportedService.java   (with props)
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/Instance.java   (with props)
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/InstantiatedService.java   (with props)
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ProvidedService.java   (with props)
    felix/trunk/ipojo/api/src/test/
    felix/trunk/ipojo/api/src/test/java/
    felix/trunk/ipojo/api/src/test/java/org/
    felix/trunk/ipojo/api/src/test/java/org/apache/
    felix/trunk/ipojo/api/src/test/java/org/apache/felix/
    felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/
    felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/
    felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/composite/
    felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/composite/InstanceTest.java   (with props)
Modified:
    felix/trunk/ipojo/api/pom.xml
    felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java

Modified: felix/trunk/ipojo/api/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/pom.xml?rev=764777&r1=764776&r2=764777&view=diff
==============================================================================
--- felix/trunk/ipojo/api/pom.xml (original)
+++ felix/trunk/ipojo/api/pom.xml Tue Apr 14 13:42:55 2009
@@ -39,15 +39,22 @@
 					<instructions>
 						<Bundle-SymbolicName>${pom.artifactId}
 						</Bundle-SymbolicName>
-						<Import-Package>!org.objectweb.asm.tree, *</Import-Package>
-						<Export-Package>org.apache.felix.ipojo.api
-						</Export-Package>
-						<Private-Package>org.apache.felix.ipojo.manipulation,
+						<Import-Package>
+							!org.objectweb.asm.tree, 
+							org.apache.felix.ipojo.composite;resolution:=optional,
+							*
+						</Import-Package>
+						<Export-Package>
+							org.apache.felix.ipojo.api,
+							org.apache.felix.ipojo.api.composite,
+							org.apache.felix.ipojo.manipulation,
 							org.apache.felix.ipojo.manipulation.annotations,
-							org.objectweb.asm.commons, org.objectweb.asm</Private-Package>
+							org.objectweb.asm.commons, org.objectweb.asm
+						</Export-Package>
 						<Include-Resource> META-INF/LICENCE=LICENSE,
 							META-INF/NOTICE=NOTICE, META-INF/LICENSE.asm=LICENSE.asm
 						</Include-Resource>
+						
 					</instructions>
 				</configuration>
 			</plugin>
@@ -87,6 +94,11 @@
 		</dependency>
 		<dependency>
 			<groupId>org.apache.felix</groupId>
+			<artifactId>org.apache.felix.ipojo.composite</artifactId>
+			<version>1.3.0-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.felix</groupId>
 			<artifactId>org.apache.felix.ipojo.manipulator</artifactId>
 			<version>1.3.0-SNAPSHOT</version>
 		</dependency>

Modified: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java?rev=764777&r1=764776&r2=764777&view=diff
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java (original)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java Tue Apr 14 13:42:55 2009
@@ -122,7 +122,7 @@
     /**
      * The temporal dependencies.
      */
-    private ArrayList m_temporals = new ArrayList();;
+    private ArrayList m_temporals = new ArrayList();
     
     /**
      * Checks that the component type is not already

Added: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/SingletonComponentType.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/SingletonComponentType.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/SingletonComponentType.java (added)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/SingletonComponentType.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,130 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+
+/**
+ * Allows defining a primitive component type that create an unique
+ * instance when created. The factory is set to private by default.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SingletonComponentType extends PrimitiveComponentType {
+    
+    private Object m_pojo;
+    
+    /**
+     * Creates a SingletonComponentType.
+     * This type is set to private by default.
+     */
+    public SingletonComponentType() {
+        setPublic(false);
+    }
+    
+    /**
+     * Set the pojo object used by the instance.
+     * The object must be compatible with the 
+     * implementation class. 
+     * @param obj the object.
+     */
+    public SingletonComponentType setObject(Object obj) {
+        m_pojo = obj;
+        return this;
+    }
+    
+    /**
+     * Starts the component type and creates the singleton
+     * instance. This method has to be called in place of the
+     * {@link PrimitiveComponentType#start()} and the
+     * {@link PrimitiveComponentType#createInstance()}  methods.
+     * @throws ConfigurationException occurs if the type description is
+     * incorrect
+     * @throws MissingHandlerException occurs if a handler is not available 
+     * @throws UnacceptableConfiguration  occurs if the configuration is not 
+     * acceptable by the instance  
+     * @see org.apache.felix.ipojo.api.ComponentType#start()
+     * @see PrimitiveComponentType#createInstance()
+     */
+    public ComponentInstance create() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        start();
+        if (m_pojo != null) {
+            Dictionary dict = new Properties();
+            dict.put("instance.object", m_pojo);
+            return createInstance(dict);
+        } else {
+            return createInstance();
+        }
+    }
+    
+    /**
+     * Starts the component type and creates the singleton
+     * instance. This method has to be called in place of the
+     * {@link PrimitiveComponentType#start()} and the
+     * {@link PrimitiveComponentType#createInstance()}  methods.
+     * @param conf the instance configuration
+     * @throws ConfigurationException occurs if the type description is
+     * incorrect
+     * @throws MissingHandlerException occurs if a handler is not available 
+     * @throws UnacceptableConfiguration  occurs if the configuration is not 
+     * acceptable by the instance  
+     * @see org.apache.felix.ipojo.api.ComponentType#start()
+     * @see PrimitiveComponentType#createInstance()
+     */
+    public ComponentInstance create(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        start();
+        if (m_pojo != null) {
+            conf.put("instance.object", m_pojo);
+        }
+        return createInstance(conf);
+    }
+    
+    /**
+     * Starts the component type and creates the singleton
+     * instance. This method has to be called in place of the
+     * {@link PrimitiveComponentType#start()} and the
+     * {@link PrimitiveComponentType#createInstance()}  methods.
+     * @throws ConfigurationException occurs if the type description is
+     * incorrect
+     * @throws MissingHandlerException occurs if a handler is not available 
+     * @throws UnacceptableConfiguration  occurs if the configuration is not 
+     * acceptable by the instance  
+     * @see org.apache.felix.ipojo.api.ComponentType#start()
+     * @see PrimitiveComponentType#createInstance()
+     */
+    public ComponentInstance create(String name) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        start();
+        if (m_pojo != null) {
+            Dictionary dict = new Properties();
+            dict.put("instance.name", name);
+            dict.put("instance.object", m_pojo);
+            return createInstance(dict);
+        } else {
+            return createInstance(name);
+        }
+    }
+    
+   
+
+}

Propchange: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/SingletonComponentType.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/CompositeComponentType.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/CompositeComponentType.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/CompositeComponentType.java (added)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/CompositeComponentType.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,247 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.api.ComponentType;
+import org.apache.felix.ipojo.composite.CompositeFactory;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Allows defining composite types.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositeComponentType extends ComponentType {
+    
+    /**
+     * The bundle context.
+     */
+    private BundleContext m_context;
+    
+    /**
+     * Component factory attached to the component
+     * type. 
+     */
+    private ComponentFactory m_factory;
+    
+    /**
+     * Component type metadata. 
+     */
+    private Element m_metadata;
+    
+    /**
+     * List of provided services. 
+     */
+    private List m_provided = new ArrayList(1);
+    
+    /**
+     * List of exported services. 
+     */
+    private List m_exported = new ArrayList(1);
+    
+    /**
+     * List of imported services. 
+     */
+    private List m_imported = new ArrayList(1);
+    
+    /**
+     * List of instantiated services. 
+     */
+    private List m_instantiated = new ArrayList();
+    
+    /**
+     * List of contained instance:
+     */
+    private List m_contained = new ArrayList(); 
+    
+    /**
+     * Is the factory public? 
+     */
+    private boolean m_public = true;
+
+    private String m_name;
+
+    /**
+     * Checks that the component type is not already
+     * started.
+     */
+    private void ensureNotInitialized() {
+        if (m_factory != null) {
+            throw new IllegalStateException("The component type was already initialized, cannot modify metadata");
+        }
+    }
+    
+    /**
+     * Checks that the component type description is valid.
+     */
+    private void ensureValidity() {
+        if (m_context == null) {
+            throw new IllegalStateException("The primitive component type has no bundle context");
+        }
+    }
+
+    /**
+     * Gets the component factory.
+     * @return the factory attached to this component type.
+     * @see org.apache.felix.ipojo.api.ComponentType#getFactory()
+     */
+    public Factory getFactory() {
+        initializeFactory();
+        return m_factory;
+    }
+
+    /**
+     * Starts the component type.
+     * @see org.apache.felix.ipojo.api.ComponentType#start()
+     */
+    public void start() {
+        initializeFactory();
+        m_factory.start();
+    }
+
+    /**
+     * Stops the component type.
+     * @see org.apache.felix.ipojo.api.ComponentType#stop()
+     */
+    public void stop() {
+        initializeFactory();
+        m_factory.stop();
+    }
+    
+    /**
+     * Initializes the factory.
+     */
+    private void initializeFactory() {
+        if (m_factory == null) {
+            createFactory();
+        }
+    }
+    
+    /**
+     * Sets the bundle context.
+     * @param bc the bundle context
+     * @return the current component type
+     */
+    public CompositeComponentType setBundleContext(BundleContext bc) {
+        ensureNotInitialized();
+        m_context = bc;
+        return this;
+    }
+    
+    /**
+     * Sets the factory public aspect.
+     * @param visible <code>false</code> to create a private factory. 
+     * @return the current component type
+     */
+    public CompositeComponentType setPublic(boolean visible) {
+        ensureNotInitialized();
+        m_public = visible;
+        return this;
+    }
+    
+    /**
+     * Sets the component type name.
+     * @param name the factory name
+     * @return the current component type
+     */
+    public CompositeComponentType setComponentTypeName(String name) {
+        ensureNotInitialized();
+        m_name = name;
+        return this;
+    }
+    
+    public CompositeComponentType addInstance(Instance inst) {
+        m_contained.add(inst);
+        return this;
+    }
+    
+    public CompositeComponentType addSubService(ImportedService is) {
+        m_imported.add(is);
+        return this;
+    }
+    
+    public CompositeComponentType addSubService(InstantiatedService is) {
+        m_instantiated.add(is);
+        return this;
+    }
+    
+    public CompositeComponentType addService(ExportedService es) {
+        m_exported.add(es);
+        return this;
+    }
+    
+    public CompositeComponentType addService(ProvidedService es) {
+        m_provided.add(es);
+        return this;
+    }
+    
+    /**
+     * Generates the component description.
+     * @return the component type description of 
+     * the current component type
+     */
+    private Element generateComponentMetadata() {
+        Element element = new Element("composite", "");
+        if (m_name != null) {
+            element.addAttribute(new Attribute("name", m_name));
+        }
+        if (! m_public) {
+            element.addAttribute(new Attribute("public", "false"));
+        }
+        for (int i = 0; i < m_contained.size(); i++) {
+            Instance inst = (Instance) m_contained.get(i);
+            element.addElement(inst.getElement());
+        }
+        for (int i = 0; i < m_imported.size(); i++) {
+            ImportedService inst = (ImportedService) m_imported.get(i);
+            element.addElement(inst.getElement());
+        }
+        for (int i = 0; i < m_instantiated.size(); i++) {
+            InstantiatedService inst = (InstantiatedService) m_instantiated.get(i);
+            element.addElement(inst.getElement());
+        }
+        return element;
+    }
+    
+    /**
+     * Creates the component factory.
+     */
+    private void createFactory() {
+        ensureValidity();
+        m_metadata = generateComponentMetadata();
+        try {
+           m_factory = new CompositeFactory(m_context, m_metadata);
+            m_factory.start();
+        } catch (ConfigurationException e) {
+            throw new IllegalStateException("An exception occurs during factory initialization : " + e.getMessage());
+        }
+       
+    }
+    
+
+    
+
+}

Propchange: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/CompositeComponentType.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ExportedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ExportedService.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ExportedService.java (added)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ExportedService.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,180 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api.composite;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.DependencyModel;
+
+public class ExportedService {
+    
+    /**
+     * The required specification.
+     */
+    private String m_specification;
+    
+    /**
+     * The LDAP filter of the dependency. 
+     */
+    private String m_filter;
+    
+    /**
+     * Is the dependency optional? 
+     */
+    private boolean m_optional;
+    
+    /**
+     * Is the dependency aggregate? 
+     */
+    private boolean m_aggregate;
+  
+    /**
+     * The dependency binding policy. 
+     * Default: Dynamic policy.
+     */
+    private int m_policy = DependencyModel.DYNAMIC_BINDING_POLICY;
+    
+    /**
+     * The dependency comparator.
+     * (used to compare service providers) 
+     */
+    private String m_comparator;
+
+    
+   
+    /**
+     * Gets the dependency metadata.
+     * @return the 'requires' element describing
+     * the current dependency.
+     */
+    public Element getElement() {
+        ensureValidity();
+        
+        Element dep = new Element("provides", "");
+        dep.addAttribute(new Attribute("action", "export"));
+       
+        dep.addAttribute(new Attribute("specification", m_specification));
+
+        
+        if (m_filter != null) {
+            dep.addAttribute(new Attribute("filter", m_filter));
+        }
+        if (m_comparator != null) {
+            dep.addAttribute(new Attribute("comparator", m_comparator));
+        }
+       
+        if (m_optional) {
+            dep.addAttribute(new Attribute("optional", "true"));
+        }
+        if (m_aggregate) {
+            dep.addAttribute(new Attribute("aggregate", "true"));
+        }
+
+        if (m_policy == DependencyModel.DYNAMIC_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "dynamic"));
+        } else if (m_policy == DependencyModel.STATIC_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "static"));
+        } else if (m_policy == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "dynamic-priority"));
+        }
+        
+        return dep;
+    }
+    
+    /**
+     * Sets the required service specification.
+     * @param spec the specification
+     * @return the current exported service.
+     */
+    public ExportedService setSpecification(String spec) {
+        m_specification = spec;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency filter.
+     * @param filter the LDAP filter
+     * @return the current exported service
+     */
+    public ExportedService setFilter(String filter) {
+        m_filter = filter;
+        return this;
+    }
+    
+    
+    /**
+     * Sets the dependency optionality.
+     * @param opt <code>true</code> to set the 
+     * dependency to optional.
+     * @return the current exported service.
+     */
+    public ExportedService setOptional(boolean opt) {
+        m_optional = opt;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency cardinality.
+     * @param agg <code>true</code> to set the 
+     * dependency to aggregate.
+     * @return the current exported service.
+     */
+    public ExportedService setAggregate(boolean agg) {
+        m_aggregate = agg;
+        return this;
+    }
+    
+    
+    /**
+     * Sets the dependency binding policy.
+     * @param policy the binding policy
+     * @return the current exported service
+     */
+    public ExportedService setBindingPolicy(int policy) {
+        m_policy = policy;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency comparator.
+     * @param cmp the comparator class name
+     * @return the current exported service
+     */
+    public ExportedService setComparator(String cmp) {
+        m_comparator = cmp;
+        return this;
+    }
+    
+    
+    /**
+     * Checks dependency configuration validity.
+     */
+    private void ensureValidity() {
+        // Check specification
+        if (m_specification == null) {
+            throw new IllegalStateException("The specification of the exported service must be set");
+        }
+
+        // Check binding policy.
+        if (!(m_policy == DependencyModel.DYNAMIC_BINDING_POLICY || m_policy == DependencyModel.STATIC_BINDING_POLICY || m_policy == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY)) {
+            throw new IllegalStateException("Unknown binding policy : " + m_policy);
+        }
+    }
+
+}

Propchange: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ExportedService.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ImportedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ImportedService.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ImportedService.java (added)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ImportedService.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,221 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api.composite;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.DependencyModel;
+
+public class ImportedService {
+    
+    public static final String COMPOSITE_SCOPE = "composite";
+    
+    public static final String GLOBAL_SCOPE = "global";
+    
+    public static final String COMPOSITE_AND_GLOBAL_SCOPE = "composite+global";
+    
+    
+    /**
+     * The required specification.
+     */
+    private String m_specification;
+    
+    /**
+     * The LDAP filter of the dependency. 
+     */
+    private String m_filter;
+    
+    /**
+     * Is the dependency optional? 
+     */
+    private boolean m_optional;
+    
+    /**
+     * Is the dependency aggregate? 
+     */
+    private boolean m_aggregate;
+  
+    /**
+     * The dependency binding policy. 
+     * Default: Dynamic policy.
+     */
+    private int m_policy = DependencyModel.DYNAMIC_BINDING_POLICY;
+    
+    /**
+     * The dependency comparator.
+     * (used to compare service providers) 
+     */
+    private String m_comparator;
+      
+     /**
+     * The dependency id. 
+     */
+    private String m_id;
+    
+    /**
+     * Dependency scope
+     */
+    private String m_scope = COMPOSITE_SCOPE;
+   
+    /**
+     * Gets the dependency metadata.
+     * @return the 'requires' element describing
+     * the current dependency.
+     */
+    public Element getElement() {
+        ensureValidity();
+        
+        Element dep = new Element("subservice", "");
+        dep.addAttribute(new Attribute("action", "import"));
+       
+        dep.addAttribute(new Attribute("specification", m_specification));
+        dep.addAttribute(new Attribute("scope", m_scope));
+
+        
+        if (m_filter != null) {
+            dep.addAttribute(new Attribute("filter", m_filter));
+        }
+        if (m_comparator != null) {
+            dep.addAttribute(new Attribute("comparator", m_comparator));
+        }
+  
+        if (m_id != null) {
+            dep.addAttribute(new Attribute("id", m_id));
+        }
+       
+        if (m_optional) {
+            dep.addAttribute(new Attribute("optional", "true"));
+        }
+        if (m_aggregate) {
+            dep.addAttribute(new Attribute("aggregate", "true"));
+        }
+
+        if (m_policy == DependencyModel.DYNAMIC_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "dynamic"));
+        } else if (m_policy == DependencyModel.STATIC_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "static"));
+        } else if (m_policy == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "dynamic-priority"));
+        }
+        
+        return dep;
+    }
+    
+    /**
+     * Sets the required service specification.
+     * @param spec the specification
+     * @return the current imported sub-service.
+     */
+    public ImportedService setSpecification(String spec) {
+        m_specification = spec;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency filter.
+     * @param filter the LDAP filter
+     * @return the current imported sub-service
+     */
+    public ImportedService setFilter(String filter) {
+        m_filter = filter;
+        return this;
+    }
+    
+    
+    /**
+     * Sets the dependency optionality.
+     * @param opt <code>true</code> to set the 
+     * dependency to optional.
+     * @return the current imported sub-service.
+     */
+    public ImportedService setOptional(boolean opt) {
+        m_optional = opt;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency cardinality.
+     * @param agg <code>true</code> to set the 
+     * dependency to aggregate.
+     * @return the current imported sub-service.
+     */
+    public ImportedService setAggregate(boolean agg) {
+        m_aggregate = agg;
+        return this;
+    }
+    
+    
+    /**
+     * Sets the dependency binding policy.
+     * @param policy the binding policy
+     * @return the current imported sub-service
+     */
+    public ImportedService setBindingPolicy(int policy) {
+        m_policy = policy;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency comparator.
+     * @param cmp the comparator class name
+     * @return the current imported sub-service
+     */
+    public ImportedService setComparator(String cmp) {
+        m_comparator = cmp;
+        return this;
+    }
+    
+    
+    /**
+     * Sets the dependency id.
+     * @param id the dependency id.
+     * @return the current imported sub-service.
+     */
+    public ImportedService setId(String id) {
+        m_id = id;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency scope.
+     * @param scope the dependency scope (global, composite or
+     * composite+global).
+     * @return the current imported sub-service.
+     */
+    public ImportedService setScope(String scope) {
+        m_scope = scope;
+        return this;
+    }
+    
+    /**
+     * Checks dependency configuration validity.
+     */
+    private void ensureValidity() {
+        // Check specification
+        if (m_specification == null) {
+            throw new IllegalStateException("The specification of the imported service must be set");
+        }
+
+        // Check binding policy.
+        if (!(m_policy == DependencyModel.DYNAMIC_BINDING_POLICY || m_policy == DependencyModel.STATIC_BINDING_POLICY || m_policy == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY)) {
+            throw new IllegalStateException("Unknown binding policy : " + m_policy);
+        }
+    }
+
+}

Propchange: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ImportedService.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/Instance.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/Instance.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/Instance.java (added)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/Instance.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,179 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api.composite;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import java.util.Map.Entry;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+public class Instance {
+    private String m_type;
+    private List m_conf = new ArrayList();
+    
+    public Instance(String type) {
+        m_type = type;
+    }
+    
+    public Instance addProperty(String name, String value) {
+        Element elem = new Element("property", "");
+        m_conf.add(elem);
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("value", value));
+        return this;
+    }
+    
+    public Instance addProperty(String name, List values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "list"));
+
+        m_conf.add(elem);
+        
+        for (int i = 0; i < values.size(); i++) {
+            Object obj = values.get(i);
+            Element e = new Element("property", "");
+            elem.addElement(e);
+            if (obj instanceof String) {
+                e.addAttribute(new Attribute("value", obj.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+    
+    public Instance addProperty(String name, String[] values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "array"));
+
+        m_conf.add(elem);
+        
+        for (int i = 0; i < values.length; i++) {
+            Object obj = values[i];
+            Element e = new Element("property", "");
+            elem.addElement(e);
+            e.addAttribute(new Attribute("value", obj.toString()));
+        }
+        
+        return this;
+   }
+    
+    public Instance addProperty(String name, Vector values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "vector"));
+
+        m_conf.add(elem);
+
+        for (int i = 0; i < values.size(); i++) {
+            Object obj = values.get(i);
+            Element e = new Element("property", "");
+            elem.addElement(e);
+            if (obj instanceof String) {
+                e.addAttribute(new Attribute("value", obj.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+    
+    public Instance addProperty(String name, Map values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "map"));
+
+        m_conf.add(elem);
+        Set entries = values.entrySet();
+        Iterator it = entries.iterator();
+        while(it.hasNext()) {
+            Map.Entry entry = (Entry) it.next();
+            Element e = new Element("property", "");
+            elem.addElement(e);
+
+            String n = (String) entry.getKey();
+            Object v = entry.getValue();
+            if (v instanceof String) {
+                e.addAttribute(new Attribute("name", n));
+                e.addAttribute(new Attribute("value", v.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+    
+    public Instance addProperty(String name, Dictionary values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "dictionary"));
+
+        m_conf.add(elem);
+        Enumeration e = values.keys();
+        while(e.hasMoreElements()) {
+            Element el = new Element("property", "");
+            elem.addElement(el);
+
+            String n = (String) e.nextElement();
+            Object v = values.get(n);
+            if (v instanceof String) {
+                el.addAttribute(new Attribute("name", n));
+                el.addAttribute(new Attribute("value", v.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+
+    private void ensureValidity() {
+        if(m_type == null) {
+            throw new IllegalStateException("Invalid containted instance configuration : the component type is not set");
+        }
+    }
+    
+    public Element getElement() {
+        ensureValidity();
+        Element instance = new Element("instance", "");
+        instance.addAttribute(new Attribute("component", m_type));
+        for (int i = 0; i < m_conf.size(); i++) {
+            Element elem = (Element) m_conf.get(i);
+            instance.addElement(elem);
+        }
+        return instance;
+    }
+}
\ No newline at end of file

Propchange: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/Instance.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/InstantiatedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/InstantiatedService.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/InstantiatedService.java (added)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/InstantiatedService.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,319 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api.composite;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+import java.util.Map.Entry;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.DependencyModel;
+
+public class InstantiatedService {
+    
+    /**
+     * The required specification.
+     */
+    private String m_specification;
+    
+    /**
+     * The LDAP filter of the dependency. 
+     */
+    private String m_filter;
+    
+    /**
+     * Is the dependency optional? 
+     */
+    private boolean m_optional;
+    
+    /**
+     * Is the dependency aggregate? 
+     */
+    private boolean m_aggregate;
+  
+    /**
+     * The dependency binding policy. 
+     * Default: Dynamic policy.
+     */
+    private int m_policy = DependencyModel.DYNAMIC_BINDING_POLICY;
+    
+    /**
+     * The dependency comparator.
+     * (used to compare service providers) 
+     */
+    private String m_comparator;
+    
+    /**
+     * Instance configuration
+     * List of Element (Property)
+     */
+    private List m_conf = new ArrayList();
+    
+    /**
+     * Gets the dependency metadata.
+     * @return the 'requires' element describing
+     * the current dependency.
+     */
+    public Element getElement() {
+        ensureValidity();
+        
+        Element dep = new Element("subservice", "");
+        dep.addAttribute(new Attribute("action", "instantiate"));
+       
+        dep.addAttribute(new Attribute("specification", m_specification));
+
+        
+        if (m_filter != null) {
+            dep.addAttribute(new Attribute("filter", m_filter));
+        }
+        if (m_comparator != null) {
+            dep.addAttribute(new Attribute("comparator", m_comparator));
+        }
+  
+        if (m_optional) {
+            dep.addAttribute(new Attribute("optional", "true"));
+        }
+        if (m_aggregate) {
+            dep.addAttribute(new Attribute("aggregate", "true"));
+        }
+
+        if (m_policy == DependencyModel.DYNAMIC_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "dynamic"));
+        } else if (m_policy == DependencyModel.STATIC_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "static"));
+        } else if (m_policy == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY) {
+            dep.addAttribute(new Attribute("policy", "dynamic-priority"));
+        }
+        
+        for (int i = 0; i < m_conf.size(); i++) {
+            Element elem = (Element) m_conf.get(i);
+            dep.addElement(elem);
+        }
+        
+        return dep;
+    }
+    
+    public InstantiatedService addProperty(String name, String value) {
+        Element elem = new Element("property", "");
+        m_conf.add(elem);
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("value", value));
+        return this;
+    }
+    
+    public InstantiatedService addProperty(String name, List values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "list"));
+
+        m_conf.add(elem);
+        
+        for (int i = 0; i < values.size(); i++) {
+            Object obj = values.get(i);
+            Element e = new Element("property", "");
+            elem.addElement(e);
+            if (obj instanceof String) {
+                e.addAttribute(new Attribute("value", obj.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+    
+    public InstantiatedService addProperty(String name, String[] values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "array"));
+
+        m_conf.add(elem);
+        
+        for (int i = 0; i < values.length; i++) {
+            Object obj = values[i];
+            Element e = new Element("property", "");
+            elem.addElement(e);
+            e.addAttribute(new Attribute("value", obj.toString()));
+        }
+        
+        return this;
+   }
+    
+    public InstantiatedService addProperty(String name, Vector values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "vector"));
+
+        m_conf.add(elem);
+
+        for (int i = 0; i < values.size(); i++) {
+            Object obj = values.get(i);
+            Element e = new Element("property", "");
+            elem.addElement(e);
+            if (obj instanceof String) {
+                e.addAttribute(new Attribute("value", obj.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+    
+    public InstantiatedService addProperty(String name, Map values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "map"));
+
+        m_conf.add(elem);
+        Set entries = values.entrySet();
+        Iterator it = entries.iterator();
+        while(it.hasNext()) {
+            Map.Entry entry = (Entry) it.next();
+            Element e = new Element("property", "");
+            elem.addElement(e);
+
+            String n = (String) entry.getKey();
+            Object v = entry.getValue();
+            if (v instanceof String) {
+                e.addAttribute(new Attribute("name", n));
+                e.addAttribute(new Attribute("value", v.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+    
+    public InstantiatedService addProperty(String name, Dictionary values) {
+        Element elem = new Element("property", "");
+        elem.addAttribute(new Attribute("name", name));
+        elem.addAttribute(new Attribute("type", "dictionary"));
+
+        m_conf.add(elem);
+        Enumeration e = values.keys();
+        while(e.hasMoreElements()) {
+            Element el = new Element("property", "");
+            elem.addElement(el);
+
+            String n = (String) e.nextElement();
+            Object v = values.get(n);
+            if (v instanceof String) {
+                el.addAttribute(new Attribute("name", n));
+                el.addAttribute(new Attribute("value", v.toString()));
+            } else {
+                // TODO 
+               throw new UnsupportedOperationException("Complex properties are not supported yet");
+            }
+        }
+        
+        return this;
+   }
+    
+    /**
+     * Sets the required service specification.
+     * @param spec the specification
+     * @return the current imported sub-service.
+     */
+    public InstantiatedService setSpecification(String spec) {
+        m_specification = spec;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency filter.
+     * @param filter the LDAP filter
+     * @return the current imported sub-service
+     */
+    public InstantiatedService setFilter(String filter) {
+        m_filter = filter;
+        return this;
+    }
+    
+    
+    /**
+     * Sets the dependency optionality.
+     * @param opt <code>true</code> to set the 
+     * dependency to optional.
+     * @return the current imported sub-service.
+     */
+    public InstantiatedService setOptional(boolean opt) {
+        m_optional = opt;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency cardinality.
+     * @param agg <code>true</code> to set the 
+     * dependency to aggregate.
+     * @return the current imported sub-service.
+     */
+    public InstantiatedService setAggregate(boolean agg) {
+        m_aggregate = agg;
+        return this;
+    }
+    
+    
+    /**
+     * Sets the dependency binding policy.
+     * @param policy the binding policy
+     * @return the current imported sub-service
+     */
+    public InstantiatedService setBindingPolicy(int policy) {
+        m_policy = policy;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency comparator.
+     * @param cmp the comparator class name
+     * @return the current imported sub-service
+     */
+    public InstantiatedService setComparator(String cmp) {
+        m_comparator = cmp;
+        return this;
+    }
+    
+    /**
+     * Checks dependency configuration validity.
+     */
+    private void ensureValidity() {
+        // Check specification
+        if (m_specification == null) {
+            throw new IllegalStateException("The specification of the instantiated service must be set");
+        }
+
+        // Check binding policy.
+        if (!(m_policy == DependencyModel.DYNAMIC_BINDING_POLICY || m_policy == DependencyModel.STATIC_BINDING_POLICY || m_policy == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY)) {
+            throw new IllegalStateException("Unknown binding policy : " + m_policy);
+        }
+    }
+
+}

Propchange: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/InstantiatedService.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ProvidedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ProvidedService.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ProvidedService.java (added)
+++ felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ProvidedService.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,100 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api.composite;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+public class ProvidedService {
+    public static final String ALL_POLICY = "all";
+    public static final String ONE_POLICY = "one";
+    
+    
+    /**
+     * The required specification.
+     */
+    private String m_specification;
+    
+    /**
+     * List of delegation.
+     * List of Element ({delegation $method $policy}) 
+     */
+    private List m_delegation = new ArrayList();
+
+    
+   
+    /**
+     * Gets the dependency metadata.
+     * @return the 'requires' element describing
+     * the current dependency.
+     */
+    public Element getElement() {
+        ensureValidity();
+        
+        Element dep = new Element("provides", "");
+        dep.addAttribute(new Attribute("action", "implement"));
+       
+        dep.addAttribute(new Attribute("specification", m_specification));
+
+        for (int i = 0; i < m_delegation.size(); i++) {
+            dep.addElement((Element) m_delegation.get(i));
+        }
+        
+        return dep;
+    }
+    
+    /**
+     * Sets the required service specification.
+     * @param spec the specification
+     * @return the current exported service.
+     */
+    public ProvidedService setSpecification(String spec) {
+        m_specification = spec;
+        return this;
+    }
+    
+    /**
+     * Sets the delegation policy of the given method
+     * @param method  the method name
+     * @param policy the delegation policy
+     * @return the current exported service.
+     */
+    public ProvidedService setDelegation(String method, String policy) {
+        Element element = new Element("delegation", "");
+        element.addAttribute(new Attribute("method", method));
+        element.addAttribute(new Attribute("policy", policy));
+        m_delegation.add(element);
+        return this;
+    }
+
+    
+    /**
+     * Checks dependency configuration validity.
+     */
+    private void ensureValidity() {
+        // Check specification
+        if (m_specification == null) {
+            throw new IllegalStateException("The specification of the implemented service must be set");
+        }
+    }
+
+}

Propchange: felix/trunk/ipojo/api/src/main/java/org/apache/felix/ipojo/api/composite/ProvidedService.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/composite/InstanceTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/composite/InstanceTest.java?rev=764777&view=auto
==============================================================================
--- felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/composite/InstanceTest.java (added)
+++ felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/composite/InstanceTest.java Tue Apr 14 13:42:55 2009
@@ -0,0 +1,246 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api.composite;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Vector;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+public class InstanceTest extends TestCase {
+    
+    public void testJustComponent() {
+        Instance inst = new Instance("mycmp");
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        assertEquals("Check component attribute", "mycmp", cmp);
+    }
+    
+    public void testStringProp() {
+        Instance inst = new Instance("mycmp");
+        inst.addProperty("p1", "v1");
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        Element[] elems = elem.getElements();
+        assertEquals("Check component attribute", "mycmp", cmp);
+        assertNotNull("Check properties", elems);
+        assertEquals("Check properties count", 1, elems.length);
+        String n = elems[0].getAttribute("name");
+        String v = elems[0].getAttribute("value");
+        String t = elems[0].getAttribute("type");
+
+
+        assertEquals("Check property 0 - name", "p1", n);
+        assertEquals("Check property 0 - value", "v1", v);
+        assertNull("Check property 0 - type", t);
+
+    }
+    
+    public void testStringProps() {
+        Instance inst = new Instance("mycmp");
+        inst.addProperty("p1", "v1");
+        inst.addProperty("p2", "v2");
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        Element[] elems = elem.getElements();
+        assertEquals("Check component attribute", "mycmp", cmp);
+        assertNotNull("Check properties", elems);
+        assertEquals("Check properties count", 2, elems.length);
+        String n = elems[0].getAttribute("name");
+        String v = elems[0].getAttribute("value");
+        assertEquals("Check property 0 - name", "p1", n);
+        assertEquals("Check property 0 - value", "v1", v);
+        n = elems[1].getAttribute("name");
+        v = elems[1].getAttribute("value");
+        assertEquals("Check property 1 - name", "p2", n);
+        assertEquals("Check property 1 - value", "v2", v);
+    }
+    
+    public void testListProp() {
+        Instance inst = new Instance("mycmp");
+        List list = new ArrayList();
+        list.add("a");
+        list.add("a");
+        list.add("a");
+        
+        inst.addProperty("p1", list);
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        Element[] elems = elem.getElements();
+        assertEquals("Check component attribute", "mycmp", cmp);
+        assertNotNull("Check properties", elems);
+        assertEquals("Check properties count", 1, elems.length);
+        String n = elems[0].getAttribute("name");
+        String v = elems[0].getAttribute("value");
+        String t = elems[0].getAttribute("type");
+
+        assertEquals("Check property 0 - name", "p1", n);
+        assertNull("Check property 0 - value", v);
+        assertEquals("Check property 0 - type", "list", t);
+
+        
+        Element[] subs = elems[0].getElements();
+        assertEquals("Check the number of sub-elements", 3, subs.length);
+        for (int i = 0; i < subs.length; i++) {
+            Element a = subs[i];
+            assertEquals("Check the value of " + i, "a", a.getAttribute("value"));
+            assertNull("Check the name of " + i, a.getAttribute("name"));
+
+        }
+    }
+    
+    public void testArrayProp() {
+        Instance inst = new Instance("mycmp");
+        String[] list = new String[] {"a", "a", "a"};
+        
+        inst.addProperty("p1", list);
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        Element[] elems = elem.getElements();
+        assertEquals("Check component attribute", "mycmp", cmp);
+        assertNotNull("Check properties", elems);
+        assertEquals("Check properties count", 1, elems.length);
+        String n = elems[0].getAttribute("name");
+        String v = elems[0].getAttribute("value");
+        String t = elems[0].getAttribute("type");
+
+        assertEquals("Check property 0 - name", "p1", n);
+        assertNull("Check property 0 - value", v);
+        assertEquals("Check property 0 - type", "array", t);
+
+        
+        Element[] subs = elems[0].getElements();
+        assertEquals("Check the number of sub-elements", 3, subs.length);
+        for (int i = 0; i < subs.length; i++) {
+            Element a = subs[i];
+            assertEquals("Check the value of " + i, "a", a.getAttribute("value"));
+            assertNull("Check the name of " + i, a.getAttribute("name"));
+
+        }
+    }
+    
+    public void testVectorProp() {
+        Instance inst = new Instance("mycmp");
+        Vector list = new Vector();
+        list.add("a");
+        list.add("a");
+        list.add("a");
+        
+        inst.addProperty("p1", list);
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        Element[] elems = elem.getElements();
+        assertEquals("Check component attribute", "mycmp", cmp);
+        assertNotNull("Check properties", elems);
+        assertEquals("Check properties count", 1, elems.length);
+        String n = elems[0].getAttribute("name");
+        String v = elems[0].getAttribute("value");
+        String t = elems[0].getAttribute("type");
+        
+        
+        assertEquals("Check property 0 - name", "p1", n);
+        assertNull("Check property 0 - value", v);
+        assertEquals("Check property 0 - type", "vector", t);
+
+        
+        Element[] subs = elems[0].getElements();
+        assertEquals("Check the number of sub-elements", 3, subs.length);
+        for (int i = 0; i < subs.length; i++) {
+            Element a = subs[i];
+            assertEquals("Check the value of " + i, "a", a.getAttribute("value"));
+            assertNull("Check the name of " + i, a.getAttribute("name"));
+
+        }
+    }
+    
+    public void testMapProp() {
+        Instance inst = new Instance("mycmp");
+        Map map = new HashMap();
+        map.put("p1", "b");
+        map.put("p2", "b");
+        map.put("p3", "b");
+        
+        inst.addProperty("p1", map);
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        Element[] elems = elem.getElements();
+        assertEquals("Check component attribute", "mycmp", cmp);
+        assertNotNull("Check properties", elems);
+        assertEquals("Check properties count", 1, elems.length);
+        String n = elems[0].getAttribute("name");
+        String v = elems[0].getAttribute("value");
+        String t = elems[0].getAttribute("type");
+
+        
+        assertEquals("Check property 0 - name", "p1", n);
+        assertNull("Check property 0 - value", v);
+        assertEquals("Check property 0 - type", "map", t);
+
+        Element[] subs = elems[0].getElements();
+        assertEquals("Check the number of sub-elements", 3, subs.length);
+        for (int i = 0; i < subs.length; i++) {
+            Element a = subs[i];
+            assertEquals("Check the value of " + i, "b", a.getAttribute("value"));
+            assertNotNull("Check the name of " + i, a.getAttribute("name"));
+
+        }
+    }
+    
+    public void testDictProp() {
+        Instance inst = new Instance("mycmp");
+        Dictionary map = new Properties();
+        map.put("p1", "b");
+        map.put("p2", "b");
+        map.put("p3", "b");
+        
+        inst.addProperty("p1", map);
+        Element elem = inst.getElement();
+        String cmp = elem.getAttribute("component");
+        Element[] elems = elem.getElements();
+        assertEquals("Check component attribute", "mycmp", cmp);
+        assertNotNull("Check properties", elems);
+        assertEquals("Check properties count", 1, elems.length);
+        String n = elems[0].getAttribute("name");
+        String v = elems[0].getAttribute("value");
+        String t = elems[0].getAttribute("type");
+
+        
+        assertEquals("Check property 0 - name", "p1", n);
+        assertNull("Check property 0 - value", v);
+        assertEquals("Check property 0 - type", "dictionary", t);
+
+        
+        Element[] subs = elems[0].getElements();
+        assertEquals("Check the number of sub-elements", 3, subs.length);
+        for (int i = 0; i < subs.length; i++) {
+            Element a = subs[i];
+            assertEquals("Check the value of " + i, "b", a.getAttribute("value"));
+            assertNotNull("Check the name of " + i, a.getAttribute("name"));
+
+        }
+    }
+
+}

Propchange: felix/trunk/ipojo/api/src/test/java/org/apache/felix/ipojo/api/composite/InstanceTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain