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 2007/12/21 20:28:13 UTC

svn commit: r606280 [2/6] - in /felix/sandbox/clement/ipojo: composite/ composite/src/ composite/src/main/ composite/src/main/java/ composite/src/main/java/org/ composite/src/main/java/org/apache/ composite/src/main/java/org/apache/felix/ composite/src...

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,90 @@
+/* 
+ * 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.composite.instance;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler.ManagedConfiguration;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Description of the Instance Handler.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class InstanceHandlerDescription extends HandlerDescription {
+
+    /**
+     * List of managed instances.
+     */
+    private List m_instances;
+
+    /**
+     * Constructor.
+     * 
+     * @param h : handler
+     * @param insts : list of component instances
+     */
+    public InstanceHandlerDescription(CompositeHandler h, List insts) {
+        super(h);
+        m_instances = insts;
+    }
+
+    /**
+     * Build handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element instances = super.getHandlerInfo();
+        for (int i = 0; i < m_instances.size(); i++) {
+            ManagedConfiguration inst = (ManagedConfiguration) m_instances.get(i);
+            Element instance = new Element("Instance", "");
+            if (inst.getInstance() != null) {
+                instance.addAttribute(new Attribute("Factory", inst.getFactory()));
+                instance.addAttribute(new Attribute("Name", inst.getInstance().getInstanceName()));
+                String state = null;
+                switch(inst.getInstance().getState()) {
+                    case ComponentInstance.DISPOSED : 
+                        state = "disposed"; break;
+                    case ComponentInstance.STOPPED : 
+                        state = "stopped"; break;
+                    case ComponentInstance.VALID : 
+                        state = "valid"; break;
+                    case ComponentInstance.INVALID : 
+                        state = "invalid"; break;
+                    default :
+                        break;
+                }
+                instance.addAttribute(new Attribute("State", state));
+                instance.addElement(inst.getInstance().getInstanceDescription().getDescription());
+            } else {
+                instance.addAttribute(new Attribute("Factory", inst.getConfiguration().get("component").toString()));
+                instance.addAttribute(new Attribute("State", "Not Available"));
+            }
+            instances.addElement(instance);
+        }
+        return instances;
+    }
+
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportDescription.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,72 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Description of the Import Export Handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ExportDescription extends HandlerDescription {
+
+    /**
+     * List of exports.
+     */
+    private List m_exports;
+
+    /**
+     * Constructor.
+     * 
+     * @param h : composite handler
+     * @param exporters : list of managed exports
+     */
+    public ExportDescription(CompositeHandler h, List exporters) {
+        super(h);
+        m_exports = exporters;
+    }
+
+    /**
+     * Build the ImportExport handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element handler = super.getHandlerInfo();
+        for (int i = 0; i < m_exports.size(); i++) {
+            ServiceExporter exp = (ServiceExporter) m_exports.get(i);
+            Element expo = new Element("Exports", "");
+            expo.addAttribute(new Attribute("Specification", exp.getSpecification()));
+            expo.addAttribute(new Attribute("Filter", exp.getFilter()));
+            if (exp.isSatisfied()) {
+                expo.addAttribute(new Attribute("State", "resolved"));
+            } else {
+                expo.addAttribute(new Attribute("State", "unresolved"));
+            }
+            handler.addElement(expo);
+        }
+        return handler;
+
+    }
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ExportHandler.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,188 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This handler manages the import and the export of services from /
+ * to the parent context.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ExportHandler extends CompositeHandler {
+
+    /**
+     * Service Scope.
+     */
+    private ServiceContext m_scope;
+
+    /**
+     * Parent context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * List of exporters.
+     */
+    private List m_exporters = new ArrayList();
+
+    /**
+     * Initialize the component type.
+     * @param cd : component type description to populate.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : occurs when the 'specification' attribute is missing
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentTypeDescription cd, Element metadata) throws ConfigurationException {
+        // Update the component type description
+        Element[] exp = metadata.getElements("exports");
+        for (int i = 0; i < exp.length; i++) {
+            String spec = exp[i].getAttribute("specification");
+            if (spec != null) { 
+                cd.addProvidedServiceSpecification(spec);
+            } else {
+                // Malformed exports
+                throw new ConfigurationException("Malformed exports - Missing the specification attribute");
+            }
+        }
+    }
+
+    /**
+     * Configure the handler.
+     * @param metadata : the metadata of the component
+     * @param conf : the instance configuration
+     * @throws ConfigurationException : if the specification attribute is missing in the metadata.
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
+        m_context = getCompositeManager().getContext();
+        m_scope = getCompositeManager().getServiceContext();
+
+        Element[] exp = metadata.getElements("exports");
+
+        for (int i = 0; i < exp.length; i++) {
+            boolean optional = false;
+            boolean aggregate = false;
+            String specification = exp[i].getAttribute("specification");
+            String filter = "(objectClass=" + specification + ")";
+                
+            String opt = exp[i].getAttribute("optional");
+            optional =  opt != null && opt.equalsIgnoreCase("true");
+                
+            String agg = exp[i].getAttribute("aggregate");
+            aggregate = agg != null && agg.equalsIgnoreCase("true");
+
+            String f = exp[i].getAttribute("filter");
+            if (f != null) {
+                filter = "(&" + filter + f + ")";
+            }
+            ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, m_scope, m_context, this);
+            m_exporters.add(si);
+        }
+    }
+
+    /**
+     * Start the handler.
+     * Start importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+            se.start();
+        }
+
+        isHandlerValid();
+
+    }
+
+    /**
+     * Stop the handler.
+     * Stop all importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+            se.stop();
+        }
+    }
+
+    /**
+     * Check the handler validity.
+     * @return true if all importers and exporters are valid
+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+     */
+    private void isHandlerValid() {
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+            if (!se.isSatisfied()) {
+                setValidity(false);
+                return;
+            }
+        }
+        setValidity(true);
+    }
+
+    /**
+     * Notify the handler that an exporter becomes invalid.
+     * 
+     * @param exporter : the implicated exporter.
+     */
+    protected void invalidating(ServiceExporter exporter) {
+        // An export is no more valid
+        if (getValidity()) {
+            setValidity(false);
+        }
+
+    }
+
+    /**
+     * Notify the handler that an exporter becomes valid.
+     * 
+     * @param exporter : the implicated exporter.
+     */
+    protected void validating(ServiceExporter exporter) {
+        // An import becomes valid
+        if (!getValidity()) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * Get the import / export handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return new ExportDescription(this, m_exporters);
+    }
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportDescription.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,79 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Description of the Import Export Handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ImportDescription extends HandlerDescription {
+
+    /**
+     * List of exports.
+     */
+    private List m_imports;
+
+    /**
+     * Constructor.
+     * 
+     * @param h : composite handler
+     * @param importers : list of managed imports
+     */
+    public ImportDescription(CompositeHandler h, List importers) {
+        super(h);
+        m_imports = importers;
+    }
+
+    /**
+     * Build the ImportExport handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element handler = super.getHandlerInfo();
+        for (int i = 0; i < m_imports.size(); i++) {
+            ServiceImporter imp = (ServiceImporter) m_imports.get(i);
+            Element impo = new Element("Requires", "");
+            impo.addAttribute(new Attribute("Specification", imp.getSpecification()));
+            if (imp.getFilter() != null) {
+                impo.addAttribute(new Attribute("Filter", imp.getFilter()));
+            }
+            if (imp.isSatisfied()) {
+                impo.addAttribute(new Attribute("State", "resolved"));
+                for (int j = 0; j < imp.getProviders().size(); j++) {
+                    Element pr = new Element("Provider", "");
+                    pr.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));
+                    impo.addElement(pr);
+                }
+            } else {
+                impo.addAttribute(new Attribute("State", "unresolved"));
+            }
+            handler.addElement(impo);
+        }
+        return handler;
+    }
+
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportHandler.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,205 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This handler manages the import and the export of services from /
+ * to the parent context.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ImportHandler extends CompositeHandler {
+
+    /**
+     * Service Scope.
+     */
+    private ServiceContext m_scope;
+
+    /**
+     * Parent context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * List of importers.
+     */
+    private List m_importers = new ArrayList();
+
+//    /**
+//     * Is the handler valid ?
+//     * (Lifecycle controller)
+//     */
+//    private boolean m_valid;
+    
+
+    /**
+     * Configure the handler.
+     * 
+     * @param metadata : the metadata of the component
+     * @param conf : the instance configuration
+     * @throws ConfigurationException : the specification attribute is missing. 
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
+        m_context = getCompositeManager().getContext();
+        m_scope = getCompositeManager().getServiceContext();
+        Element[] imp = metadata.getElements("requires");
+        
+        // Get instance filters
+        Dictionary filtersConfiguration = null;
+        if (conf.get("requires.filters") != null) {
+            filtersConfiguration = (Dictionary) conf.get("requires.filters");
+        }
+
+        for (int i = 0; i < imp.length; i++) {
+            boolean optional = false;
+            boolean aggregate = false;
+            String specification = imp[i].getAttribute("specification");
+
+            if (specification != null) {                
+                String opt = imp[i].getAttribute("optional");
+                optional = opt != null && opt.equalsIgnoreCase("true");
+
+                String agg = imp[i].getAttribute("aggregate");
+                aggregate = agg != null && agg.equalsIgnoreCase("true");
+
+                String filter = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
+                String f = imp[i].getAttribute("filter");
+                if (f != null) {
+                    filter = "(&" + filter + f + ")";
+                }
+                
+                String id = imp[i].getAttribute("id");
+                
+                int scopePolicy = -1;
+                String scope = imp[i].getAttribute("scope");
+                if (scope != null) {
+                    if (scope.equalsIgnoreCase("global")) {
+                        scopePolicy = PolicyServiceContext.GLOBAL;
+                    } else if (scope.equalsIgnoreCase("composite")) {
+                        scopePolicy = PolicyServiceContext.LOCAL;
+                    } else if (scope.equalsIgnoreCase("composite+global")) {
+                        scopePolicy = PolicyServiceContext.LOCAL_AND_GLOBAL;
+                    }                
+                }
+                
+                // Configure instance filter if available
+                if (filtersConfiguration != null && id != null && filtersConfiguration.get(id) != null) {
+                    filter = (String) filtersConfiguration.get(id);
+                }
+                
+                ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, m_context, m_scope, scopePolicy, id, this);
+                m_importers.add(si);
+            } else { // Malformed import
+                error( "Malformed imports : the specification attribute is mandatory");
+                throw new ConfigurationException("Malformed imports : the specification attribute is mandatory");
+            }
+        }
+    }
+
+    /**
+     * Start the handler.
+     * Start importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            si.start();
+        }
+        isHandlerValid();
+    }
+
+    /**
+     * Stop the handler.
+     * Stop all importers and exporters.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            si.stop();
+        }
+    }
+
+    /**
+     * Check the handler validity.
+     * @return true if all importers and exporters are valid
+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+     */
+    public void isHandlerValid() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter si = (ServiceImporter) m_importers.get(i);
+            if (!si.isSatisfied()) {
+                setValidity(false);
+                return;
+            }
+        }
+        setValidity(true);
+    }
+
+    /**
+     * Notify the handler that an importer is no more valid.
+     * 
+     * @param importer : the implicated importer.
+     */
+    protected void invalidating(ServiceImporter importer) {
+        // An import is no more valid
+        if (getValidity()) {
+            setValidity(false);
+        }
+    }
+
+    /**
+     * Notify the handler that an importer becomes valid. 
+     * @param importer : the implicated importer.
+     */
+    protected void validating(ServiceImporter importer) {
+        // An import becomes valid
+        if (!getValidity()) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * Get the import / export handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return new ImportDescription(this, m_importers);
+    }
+    
+    public List getRequirements() {
+        return m_importers;
+    }
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,313 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Export an service from the scope to the parent context.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceExporter implements TrackerCustomizer {
+
+    /**
+     * Destination context.
+     */
+    private BundleContext m_destination;
+
+    /**
+     * Origin context.
+     */
+    private ServiceContext m_origin;
+
+    /**
+     * Exported specification.
+     */
+    private String m_specification;
+
+    /**
+     * LDAP filter filtering internal provider.
+     */
+    private Filter m_filter;
+
+    /**
+     * String form of the LDAP filter.
+     */
+    private String m_filterStr;
+
+    /**
+     * Should be exported several providers.
+     */
+    private boolean m_aggregate = false;
+
+    /**
+     * Is this exports optional?
+     */
+    private boolean m_optional = false;
+
+    /**
+     * Reference of the handler.
+     */
+    private ExportHandler m_handler;
+
+    /**
+     * Is the exporter valid?
+     */
+    private boolean m_isValid;
+    
+    /**
+     * Tracker tracking internal service (to export).
+     */
+    private Tracker m_tracker;
+
+    /**
+     * Structure Reference, Registration, Service Object.
+     */
+    private class Record {
+        /**
+         * Internal Reference.
+         */
+        private ServiceReference m_ref;
+        /**
+         * External Registration.
+         */
+        private ServiceRegistration m_reg;
+        /**
+         * Exposed object.
+         */
+        private Object m_svcObject;
+    }
+
+    /**
+     * List of managed records.
+     */
+    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
+
+    /**
+     * Constructor.
+     * 
+     * @param specification : exported service specification.
+     * @param filter : LDAP filter
+     * @param multiple : is the export an aggregate export?
+     * @param optional : is the export optional?
+     * @param from : internal service context
+     * @param to : external bundle context
+     * @param exp : handler
+     */
+    public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to,
+            ExportHandler exp) {
+        this.m_destination = to;
+        this.m_origin = from;
+        this.m_handler = exp;
+        try {
+            this.m_filter = to.createFilter(filter);
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+            return;
+        }
+        this.m_aggregate = multiple;
+        this.m_specification = specification;
+        this.m_optional = optional;
+    }
+
+    /**
+     * Start method.
+     * Start the provider tracking and the publication.
+     */
+    public void start() {
+        m_tracker = new Tracker(m_origin, m_filter, this);
+        m_tracker.open();
+
+        m_isValid = isSatisfied();
+    }
+
+    /**
+     * Transform service reference property in a dictionary.
+     * instance.name and factory.name are injected too.
+     * @param ref : the service reference.
+     * @return the dictionary containing all property of the given service reference.
+     */
+    private Dictionary getProps(ServiceReference ref) {
+        Properties prop = new Properties();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            prop.put(keys[i], ref.getProperty(keys[i]));
+        }
+
+        prop.put("instance.name", m_handler.getCompositeManager().getInstanceName());
+        prop.put("factory.name", m_handler.getCompositeManager().getFactory().getName());
+
+        return prop;
+    }
+
+    /**
+     * Stop an exporter.
+     * Remove the service listener
+     * Unregister all exported services.
+     */
+    public void stop() {
+        m_tracker.close();
+
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            rec.m_svcObject = null;
+            if (rec.m_reg != null) {
+                rec.m_reg.unregister();
+                rec.m_reg = null;
+                m_tracker.ungetService(rec.m_ref);
+                rec.m_ref = null;
+            }
+        }
+
+        m_tracker = null;
+        m_records.clear();
+
+    }
+
+    /**
+     * Check the exporter validity.
+     * @return true if optional or 'valid'
+     */
+    public boolean isSatisfied() {
+        return m_optional || m_records.size() > 0;
+    }
+
+    /**
+     * Get the list of records using the given reference.
+     * @param ref : the service reference
+     * @return the list of records using the given reference, empty if no record used this reference
+     */
+    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
+        List l = new ArrayList();
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            if (rec.m_ref == ref) {
+                l.add(rec);
+            }
+        }
+        return l;
+    }
+    
+    protected String getSpecification() {
+        return m_specification;
+    }
+    
+    public String getFilter() {
+        return m_filterStr;
+    }
+
+    /**
+     * An exported service appears.
+     * @param reference : service reference
+     * @return true as the filter guaranty the export.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        return true;
+    }
+    
+    /**
+     * A service has been added in the tracker. Can now thest the validity of the exporter.
+     * @param reference : the new reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference reference) {
+        Record rec = new Record();
+        rec.m_ref = reference;
+        m_records.add(rec);
+        // Publishing ?
+        if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
+            rec.m_svcObject = m_tracker.getService(rec.m_ref);
+            rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+        }
+        // Compute the new state
+        if (!m_isValid && isSatisfied()) {
+            m_isValid = true;
+            m_handler.validating(this);
+        }
+    }
+
+    /**
+     * An exported service was modified.
+     * @param reference : modified reference
+     * @param service : service object
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) { 
+        // A published service has been modified
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Update the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_reg.setProperties(getProps(reference));
+            }
+        }
+    }
+    
+    /**
+     * An exported service disappears.
+     * @param reference : service reference
+     * @param service : service object
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Stop the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_svcObject = null;
+                rec.m_reg.unregister();
+                rec.m_reg = null;
+                m_tracker.ungetService(rec.m_ref);
+            }
+        }
+        m_records.removeAll(l);
+
+        // Check the validity & if we need to re-import the service
+        if (m_records.size() > 0) {
+            // There is other available services
+            if (!m_aggregate) { // Import the next one
+                Record rec = (Record) m_records.get(0);
+                if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
+                    rec.m_svcObject = m_tracker.getService(rec.m_ref);
+                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+                }
+            }
+        } else {
+            if (!m_optional) {
+                m_isValid = false;
+                m_handler.invalidating(this);
+            }
+        }
+        
+    }
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,392 @@
+/* 
+ * 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.composite.service.importer;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Import a service form the parent to the internal service registry.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceImporter implements TrackerCustomizer {
+
+    /**
+     * Destination context.
+     */
+    private ServiceContext m_destination;
+
+    /**
+     * Context where service need to be found. 
+     */
+    private ServiceContext m_origin;
+
+    /**
+     * Imported Specification.
+     */
+    private String m_specification;
+
+    /**
+     * LDAP filter filtering external providers.
+     */
+    private Filter m_filter;
+
+    /**
+     * String form of the LDAP filter.
+     */
+    private String m_filterStr;
+
+    /**
+     * Should we importer several providers?
+     */
+    private boolean m_aggregate = false;
+
+    /**
+     * Is the import optional?
+     */
+    private boolean m_optional = false;
+
+    /**
+     * Is the importer valid?
+     */
+    private boolean m_isValid;
+    
+    /**
+     * Resolving policy.
+     */
+    private int m_policy;
+    
+    /**
+     * TRacker tracking imported service.
+     */
+    private Tracker m_tracker;
+
+    /**
+     * Reference on the handler.
+     */
+    private ImportHandler m_handler;
+
+    private class Record {
+        /**
+         * External Reference.
+         */
+        private ServiceReference m_ref;
+        /**
+         * Internal Registration.
+         */
+        private ServiceRegistration m_reg;
+        /**
+         * Exposed Object.
+         */
+        private Object m_svcObject;
+        
+        /**
+         * Test object equality.
+         * @param o : object to confront against the current object.
+         * @return true if the two objects are equals (same service reference).
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        public boolean equals(Object o) {
+            if (o instanceof Record) {
+                Record rec = (Record) o;
+                return rec.m_ref == m_ref;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * List of managed records.
+     */
+    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
+
+    /**
+     * Requirement Id.
+     */
+    private String m_id;
+
+    /**
+     * Is this requirement attached to a service-level requirement.
+     */
+    private boolean m_isServiceLevelRequirement;
+
+    /**
+     * Constructor.
+     * 
+     * @param specification : targeted specification
+     * @param filter : LDAP filter
+     * @param multiple : should the importer imports several services ?
+     * @param optional : is the import optional ?
+     * @param from : parent context
+     * @param to : internal context
+     * @param policy : resolving policy
+     * @param id : requirement id (may be null)
+     * @param in : handler
+     */
+    public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, int policy, String id,
+            ImportHandler in) {
+        this.m_destination = to;
+        try {
+            this.m_filter = from.createFilter(filter);
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+            return;
+        }
+        this.m_aggregate = multiple;
+        this.m_specification = specification;
+        this.m_optional = optional;
+        this.m_handler = in;
+        
+        if (m_id == null) {
+            m_id = m_specification;
+        } else {
+            m_id = id;
+        }
+        
+        if (policy == -1) {
+            m_policy = PolicyServiceContext.LOCAL_AND_GLOBAL;  
+        } else {
+            m_policy = policy;
+        }
+    }
+
+    /**
+     * Start method to begin the import.
+     */
+    public void start() {
+        m_origin = new PolicyServiceContext(m_handler.getCompositeManager().getGlobalContext(), m_handler.getCompositeManager().getParentServiceContext(), m_policy);
+        m_tracker = new Tracker(m_origin, m_filter, this);
+        m_tracker.open();
+        m_isValid = isSatisfied();
+    }
+
+    /**
+     * Get the properties for the exposed service from the given reference.
+     * 
+     * @param ref : the reference.
+     * @return the property dictionary
+     */
+    private Dictionary getProps(ServiceReference ref) {
+        Properties prop = new Properties();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            prop.put(keys[i], ref.getProperty(keys[i]));
+        }
+        return prop;
+    }
+
+    /**
+     * Stop the management of the import.
+     */
+    public void stop() {
+
+        m_tracker.close();
+
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            rec.m_svcObject = null;
+            if (rec.m_reg != null) {
+                rec.m_reg.unregister();
+                m_tracker.ungetService(rec.m_ref);
+                rec.m_ref = null;
+            }
+        }
+        
+        m_tracker = null;
+        m_records.clear();
+
+    }
+
+    /**
+     * Check if the import is satisfied.
+     * @return true if the import is optional or at least one provider is imported
+     */
+    public boolean isSatisfied() {
+        return m_optional || m_records.size() > 0;
+    }
+
+    /**
+     * Get the record list using the given reference.
+     * 
+     * @param ref : the reference
+     * @return the list containing all record using the given reference
+     */
+    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
+        List l = new ArrayList();
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            if (rec.m_ref == ref) {
+                l.add(rec);
+            }
+        }
+        return l;
+    }
+
+    public String getSpecification() {
+        return m_specification;
+    }
+
+    /**
+     * Build the list of imported service provider.
+     * @return the list of all imported services.
+     */
+    protected List getProviders() {
+        List l = new ArrayList();
+        for (int i = 0; i < m_records.size(); i++) {
+            l.add((((Record) m_records.get(i)).m_ref).getProperty("instance.name"));
+        }
+        return l;
+
+    }
+
+    public String getFilter() {
+        return m_filterStr;
+    }
+    
+    /**
+     * Set that this dependency is a service level dependency.
+     * This forces the scoping policy to be STRICT. 
+     * @param b
+     */
+    public void setServiceLevelDependency() {
+        m_isServiceLevelRequirement = true;
+        m_policy = PolicyServiceContext.LOCAL;
+    }
+
+    public String getId() {
+        return m_id;
+    }
+    
+    public boolean isServiceLevelRequirement() {
+        return m_isServiceLevelRequirement;
+    }
+    
+    public boolean isAggregate() {
+        return m_aggregate;
+    }
+    
+    public boolean isOptional() {
+        return m_optional;
+    }
+
+    /**
+     * A new service is detected.
+     * @param reference : service reference
+     * @return true if not already imported.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            if (rec.m_ref == reference) {
+                return false; // Already contained
+            }
+        }
+        return true;
+    }
+    
+    /**
+     * The given service reference was added inside the tracker list.
+     * Register the internal service.
+     * @param reference : added reference
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference reference) {
+        Record rec = new Record();
+        rec.m_ref = reference;
+        m_records.add(rec);
+        // Publishing ?
+        if (m_records.size() == 1 || m_aggregate) { // If the service is the first one, or if it is a multiple imports
+            rec.m_svcObject = m_tracker.getService(rec.m_ref);
+            rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+        }
+        // Compute the new state
+        if (!m_isValid && isSatisfied()) {
+            m_isValid = true;
+            m_handler.validating(this);
+        }
+    }
+
+    /**
+     * An imported service was modified.
+     * @param reference : service reference
+     * @param service : service object (if already get)
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Stop the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_reg.setProperties(getProps(rec.m_ref));
+            }
+        }
+    }
+
+    /**
+     * An imported service disappears.
+     *@param reference : service reference
+     * @param service : service object (if already get)
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        List l = getRecordsByRef(reference);
+        for (int i = 0; i < l.size(); i++) { // Stop the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_svcObject = null;
+                rec.m_reg.unregister();
+                rec.m_reg = null;
+                m_tracker.ungetService(rec.m_ref);
+            }
+        }
+        m_records.removeAll(l);
+
+        // Check the validity & if we need to re-import the service
+        if (m_records.size() > 0) {
+            // There is other available services
+            if (!m_aggregate) { // Import the next one
+                Record rec = (Record) m_records.get(0);
+                if (rec.m_svcObject == null) { // It is the first service which disappears - create the next one
+                    rec.m_svcObject = m_tracker.getService(rec.m_ref);
+                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+                }
+            }
+        } else {
+            if (!m_optional) {
+                m_isValid = false;
+                m_handler.invalidating(this);
+            }
+        }
+    }
+
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,89 @@
+/* 
+ * 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.composite.service.instantiator;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Description of the Service Creator Handler.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceInstantiatorDescription extends HandlerDescription {
+
+    /**
+     * List of managed service instances.
+     */
+    private List m_instances;
+
+    /**
+     * Constructor.
+     * 
+     * @param h : composite handler
+     * @param insts : list of service instance
+     */
+    public ServiceInstantiatorDescription(CompositeHandler h, List insts) {
+        super(h);
+        m_instances = insts;
+    }
+
+    /**
+     * Build service instantiator handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element services = super.getHandlerInfo();
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            Element service = new Element("Service", "");
+            service.addAttribute(new Attribute("Specification", inst.getSpecification()));
+            String state = "unresolved";
+            if (inst.isSatisfied()) {
+                state = "resolved";
+            }
+            service.addAttribute(new Attribute("State", state));
+            Map map = inst.getUsedReferences();
+            Set keys = map.keySet();
+            Iterator it = keys.iterator();
+            while (it.hasNext()) {
+                ServiceReference ref = (ServiceReference) it.next();
+                Object o = map.get(ref);
+                if (o != null) {
+                    Element fact = new Element("Factory", "");
+                    fact.addAttribute(new Attribute("Name", ((ComponentInstance) o).getFactory().getName()));
+                    service.addElement(fact);
+                }
+            }
+            services.addElement(service);
+        }
+        return services;
+    }
+
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,156 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.composite.service.instantiator;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Service Instantiator Class. This handler allows to instantiate service
+ * instance inside the composition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceInstantiatorHandler extends CompositeHandler {
+
+    /**
+     * List of instances to manage.
+     */
+    private List/* <SvcInstance> */m_instances = new ArrayList();
+
+    /**
+     * Configure the handler.
+     * 
+     * @param metadata : the metadata of the component
+     * @param conf : the instance configuration
+     * @throws ConfigurationException : the specification attribute is missing
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
+        Element[] services = metadata.getElements("service");
+        for (int i = 0; i < services.length; i++) {
+            String spec = services[i].getAttribute("specification");
+            if (spec == null) {
+                throw new ConfigurationException("Malformed service : the specification attribute is mandatory");
+            }
+            String filter = "(&(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
+            String f = services[i].getAttribute("filter");
+            if (f != null) {
+                filter = "(&" + filter + f + ")";
+            }
+            Properties prop = new Properties();
+            for (int k = 0; k < services[i].getElements("property").length; k++) {
+                String key = services[i].getElements("property")[k].getAttribute("name");
+                String value = services[i].getElements("property")[k].getAttribute("value");
+                prop.put(key, value);
+            }
+            String ag = services[i].getAttribute("aggregate");
+            boolean agg = ag != null && ag.equalsIgnoreCase("true");
+            
+            String op = services[i].getAttribute("optional");
+            boolean opt = op != null && op.equalsIgnoreCase("true");
+            
+            SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, filter);
+            m_instances.add(inst);
+        }
+    }
+
+    /**
+     * Start the service instantiator handler.
+     * Start all created service instance.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        // Init
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            inst.start();
+        }
+
+        isHandlerValid();
+    }
+
+    /**
+     * Check the handler validity.
+     * @return true if all created service instances are valid
+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+     */
+    private void isHandlerValid() {
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            if (!inst.isSatisfied()) {
+                setValidity(false);
+                return;
+            }
+        }
+        setValidity(true);
+    }
+
+    /**
+     * Handler stop method.
+     * Stop all created service instance.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            inst.stop();
+        }
+        m_instances.clear();
+    }
+
+    /**
+     * An service instance becomes valid.
+     */
+    public void validate() {
+        if (!getValidity()) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * A service instance becomes invalid.
+     */
+    public void invalidate() {
+        if (getValidity()) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * Get the service instantiator handler description.
+     * @return the description
+     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return new ServiceInstantiatorDescription(this, m_instances);
+    }
+    
+    public List getInstances() {
+        return m_instances;
+    }
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,386 @@
+/* 
+ * 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.composite.service.instantiator;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Manage a service instantiation. This service create component instance
+ * providing the required service specification.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SvcInstance implements TrackerCustomizer {
+
+    /**
+     * Required specification.
+     */
+    private String m_specification;
+
+    /**
+     * Configuration to push to the instance.
+     */
+    private Dictionary m_configuration;
+
+    /**
+     * Map of factory references => instance or NO_INSTANCE.
+     */
+    private Map /* ServiceReference */m_usedRef = new HashMap();
+
+    /**
+     * Does we instantiate several provider ?
+     */
+    private boolean m_isAggregate = false;
+
+    /**
+     * Is the service optional ?
+     */
+    private boolean m_isOptional = false;
+
+    /**
+     * Handler creating the service instance.
+     */
+    private ServiceInstantiatorHandler m_handler;
+
+    /**
+     * Service Context (internal scope).
+     */
+    private ServiceContext m_context;
+
+    /**
+     * True if the service instantiation is valid.
+     */
+    private boolean m_isValid = false;
+
+    /**
+     * Tracker used to track required factory.
+     */
+    private Tracker m_tracker;
+
+    /**
+     * Constructor.
+     * @param h : the handler.
+     * @param spec : required specification.
+     * @param conf : instance configuration.
+     * @param isAgg : is the service instance an aggregate service ?
+     * @param isOpt : is the service instance optional ?
+     * @param filt : LDAP filter
+     */
+    public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, String filt) {
+        m_handler = h;
+        m_context = h.getCompositeManager().getServiceContext();
+        m_specification = spec;
+        m_configuration = conf;
+        m_isAggregate = isAgg;
+        m_isOptional = isOpt;
+        try {
+            m_tracker  = new Tracker(m_context, h.getCompositeManager().getContext().createFilter(filt), this);
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Start the service instance.
+     * @param sc
+     */
+    public void start() {
+        m_tracker.open();
+        m_isValid = isSatisfied();
+    }
+
+    /**
+     * Stop the service instance.
+     */
+    public void stop() {
+        m_tracker.close();
+        
+        Set keys = m_usedRef.keySet();
+        Iterator it = keys.iterator();
+        while (it.hasNext()) {
+            ServiceReference ref = (ServiceReference) it.next();
+            Object o = m_usedRef.get(ref);
+            if (o != null) {
+                ((ComponentInstance) o).dispose();
+            }
+        }
+        m_usedRef.clear();
+        m_tracker = null;
+        m_isValid = false;
+    }
+
+    /**
+     * Check if an instance is already created.
+     * @return true if at least one instance is created.
+     */
+    private boolean isAnInstanceCreated() {
+        Set keys = m_usedRef.keySet();
+        Iterator it = keys.iterator();
+        while (it.hasNext()) {
+            if (m_usedRef.get(it.next()) != null)  {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Create an instance for the given reference.
+     * The instance is not added inside the map.
+     * @param factory : the factory from which we need to create the instance.
+     * @return the created component instance.
+     */
+    private ComponentInstance createInstance(Factory factory) {
+        // Add an unique name if not specified.
+        Properties p = new Properties();
+        Enumeration kk = m_configuration.keys();
+        while (kk.hasMoreElements()) {
+            String k = (String) kk.nextElement();
+            p.put(k, m_configuration.get(k));
+        }
+        ComponentInstance instance = null;
+        try {
+            instance = factory.createComponentInstance(p);
+        } catch (UnacceptableConfiguration e) {
+            e.printStackTrace();
+        } catch (MissingHandlerException e) {
+            e.printStackTrace();
+        } catch (ConfigurationException e) {
+            e.printStackTrace();
+        }
+        return instance;
+    }
+
+    /**
+     * Create an instance for the next available factory.
+     */
+    private void createNextInstance() {
+        Set keys = m_usedRef.keySet();
+        Iterator it = keys.iterator();
+        ServiceReference ref = (ServiceReference) it.next();
+        try {
+            Factory factory = (Factory) m_context.getService(ref);
+
+            // Add an unique name if not specified.
+            Properties p = new Properties();
+            Enumeration kk = m_configuration.keys();
+            while (kk.hasMoreElements()) {
+                String k = (String) kk.nextElement();
+                p.put(k, m_configuration.get(k));
+            }
+            
+            ComponentInstance instance = factory.createComponentInstance(p);
+            m_usedRef.put(ref, instance);
+            m_context.ungetService(ref);
+        } catch (UnacceptableConfiguration e) {
+            m_handler.error( "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
+        } catch (MissingHandlerException e) {
+            m_handler.error( "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
+        } catch (ConfigurationException e) {
+            m_handler.error( "A matching factory (" + ref.getProperty("instance.name") + ") seems to refuse the given configuration : " + e.getMessage());
+        }
+    }
+
+
+
+    /**
+     * Check if the service instance is satisfied.
+     * @return true if the service instance if satisfied.
+     */
+    public boolean isSatisfied() {
+        return m_isOptional || m_usedRef.size() > 0;
+    }
+
+    /**
+     * Does the service instance match with the given factory ?
+     * @param fact : the factory to test.
+     * @return true if the factory match, false otherwise.
+     */
+    private boolean match(Factory fact) {
+        //TODO : use the service reference instead of the factory object to avoid to get the factory.
+        // Check if the factory can provide the specification
+        Element[] provides = fact.getDescription().getElements("provides");
+        for (int i = 0; i < provides.length; i++) {
+            if (provides[i].getAttribute("specification").equals(m_specification)) {
+
+                // Check that the factory needs every properties contained in
+                // the configuration
+                Enumeration e = m_configuration.keys();
+                while (e.hasMoreElements()) {
+                    String k = (String) e.nextElement();
+                    if (!containsProperty(k, fact)) {
+                        return false;
+                    }
+                }
+
+                // Add an unique name if not specified.
+                Properties p = new Properties();
+                Enumeration keys = m_configuration.keys();
+                while (keys.hasMoreElements()) {
+                    String k = (String) keys.nextElement();
+                    p.put(k, m_configuration.get(k));
+                }
+
+                // Check the acceptability.
+                return fact.isAcceptable(p);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Does the factory support the given property ?
+     * 
+     * @param name : name of the property
+     * @param factory : factory to test
+     * @return true if the factory support this property
+     */
+    private boolean containsProperty(String name, Factory factory) {
+        Element[] props = factory.getDescription().getElements("property");
+        for (int i = 0; i < props.length; i++) {
+            if (props[i].getAttribute("name").equalsIgnoreCase(name)) {
+                return true;
+            }
+        }
+        if (name.equalsIgnoreCase("name")) {
+            return true;
+        } // Skip the name property
+        return false;
+    }
+
+    /**
+     * Get the required specification.
+     * @return the required specification.
+     */
+    public String getSpecification() {
+        return m_specification;
+    }
+    
+    public boolean isAggregate() {
+        return m_isAggregate;
+    }
+    
+    public boolean isOptional() {
+        return m_isOptional;
+    }
+
+    /**
+     * Get the map of used references [reference, component instance].
+     * @return the map of used references.
+     */
+    protected Map getUsedReferences() {
+        return m_usedRef;
+    }
+
+    /**
+     * A factory potentially matching with the managed instance appears.
+     * @param reference : service reference
+     * @return : true if the factory match
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        Factory fact = (Factory) m_tracker.getService(reference);
+        if (match(fact)) {
+            m_tracker.ungetService(reference);
+            return true;
+        } else {
+            m_tracker.ungetService(reference);
+            return false;
+        }
+        
+    }
+    
+    /**
+     * A matching service reference has been added in the tracker. 
+     * @param reference : added reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference reference) {
+        Factory fact = (Factory) m_tracker.getService(reference);
+        if (m_isAggregate) { // Create an instance for the new factory
+            m_usedRef.put(reference, createInstance(fact));
+            if (!m_isValid) {
+                m_isValid = true;
+                m_handler.validate();
+            }
+        } else {
+            if (!isAnInstanceCreated()) {
+                m_usedRef.put(reference, createInstance(fact));
+            } else {
+                m_usedRef.put(reference, null); // Store the reference
+            }
+            if (!m_isValid) {
+                m_isValid = true;
+                m_handler.validate();
+            }
+        }
+        m_tracker.ungetService(reference);
+    }
+
+    /**
+     * A used factory was modified.
+     * @param reference : service reference
+     * @param service : object if already get
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) { } 
+        
+    /**
+     * A used factory disappears.
+     * @param reference : service reference
+     * @param service : object if already get
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+     // Remove the reference is contained
+        Object o = m_usedRef.remove(reference);
+        if (o != null) {
+            ((ComponentInstance) o).dispose();
+            if (m_usedRef.size() > 0) {
+                if (!m_isAggregate) {
+                    createNextInstance(); // Create an instance with another factory
+                }
+            } else { // No more candidate
+                if (!m_isOptional) {
+                    m_isValid = false;
+                    m_handler.invalidate();
+                }
+            }
+        }
+    }
+
+}

Added: felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
URL: http://svn.apache.org/viewvc/felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java?rev=606280&view=auto
==============================================================================
--- felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java (added)
+++ felix/sandbox/clement/ipojo/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java Fri Dec 21 11:28:07 2007
@@ -0,0 +1,55 @@
+/* 
+ * 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.composite.service.provides;
+
+/**
+ * Exception occurs when a composition error occurs.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositionException extends Exception {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = -3063353267573738105L;
+
+    /**
+     * Message.
+     */
+    private String m_message;
+
+    /**
+     * Constructor.
+     * @param message : a message.
+     */
+    public CompositionException(String message) {
+        m_message = message;
+    }
+
+    /**
+     * Get the exception message.
+     * @return the message.
+     * @see java.lang.Throwable#getMessage()
+     */
+    public String getMessage() {
+        return m_message;
+    }
+
+}