You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2007/04/10 17:16:58 UTC

svn commit: r527156 [2/2] - in /incubator/felix/trunk: ipojo.metadata/src/main/java/org/apache/felix/ipojo/metadata/ ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ ipojo.plugin/src/main/java/org/apache/felix/ipojo/parser/ ipojo.plugin/...

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/StringMap.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/StringMap.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/StringMap.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/StringMap.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,131 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.composite;
+
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Simple utility class that creates a map for string-based keys by
+ * extending <tt>TreeMap</tt>. This map can be set to use case-sensitive
+ * or case-insensitive comparison when searching for the key.
+ * Any keys put into this map will be converted to
+ * a <tt>String</tt> using the <tt>toString()</tt> method,
+ * since it is only intended to compare strings.
+**/
+public class StringMap extends TreeMap {
+    
+	/**
+	 * serialVersionUID.
+	 */
+	private static final long serialVersionUID = 6948801857034259744L;
+
+	/**
+     * Constructor.
+     */
+    public StringMap() {
+        this(true);
+    }
+    
+    /**
+     * Constructor.
+     * @param caseSensitive : fix if the map if case sensitive or not.
+     */
+    public StringMap(boolean caseSensitive) {
+        super(new StringComparator(caseSensitive));
+    }
+    
+    /**
+     * Constructor.
+     * @param map : initial properties.
+     * @param caseSensitive : fix if the map if case sensitive or not.
+     */
+    public StringMap(Map map, boolean caseSensitive) {
+        this(caseSensitive);
+        putAll(map);
+    }
+    
+    /**
+     * @see java.util.TreeMap#put(K, V)
+     */
+    public Object put(Object key, Object value) {
+        return super.put(key.toString(), value);
+    }
+    
+    /**
+     * @return true if the map is case sensitive.
+     */
+    public boolean isCaseSensitive() {
+        return ((StringComparator) comparator()).isCaseSensitive();
+    }
+
+    /**
+     * Set the case sensitivity.
+     * @param b : the new case sensitivity.
+     */
+    public void setCaseSensitive(boolean b) {
+        ((StringComparator) comparator()).setCaseSensitive(b);
+    }
+
+    private static class StringComparator implements Comparator {
+        private boolean m_isCaseSensitive = true;
+
+        /**
+         * Constructor.
+         * @param b : true to enable the case sensitivity.
+         */
+        public StringComparator(boolean b) {
+            m_isCaseSensitive = b;
+        }
+
+        /**
+         * @see java.util.Comparator#compare(T, T)
+         */
+        public int compare(Object o1, Object o2) {
+            if (m_isCaseSensitive) {
+                return o1.toString().compareTo(o2.toString());
+            } else {
+                return o1.toString().compareToIgnoreCase(o2.toString());
+            }
+        }
+
+        /**
+         * @return true if the map is case sensitive.
+         */
+        public boolean isCaseSensitive() {
+            return m_isCaseSensitive;
+        }
+
+        /**
+         * Set the case sensitivity.
+         * @param b : true to enable the case sensitivity
+         */
+        public void setCaseSensitive(boolean b) {
+            m_isCaseSensitive = b;
+        }
+        
+        /**
+         * @see java.lang.Object#clone()
+         */
+        public Object clone() {
+        	return this;
+        }
+    }
+}

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

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java Tue Apr 10 08:16:56 2007
@@ -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.composite.architecture;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Composite Architecture Handler.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ArchitectureHandler extends CompositeHandler implements Architecture {
+
+	/**
+     * Composite Manager.
+     */
+    private CompositeManager m_manager;
+
+    /**
+     * Service Registration of the Architecture service provided by this handler.
+     */
+    private ServiceRegistration m_sr;
+
+    /**
+     * Name of the component.
+     */
+    private String m_name;
+
+    /**
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
+        if (metadata.containsAttribute("architecture")) {
+            String isArchitectureEnabled = (metadata.getAttribute("architecture")).toLowerCase();
+            if (isArchitectureEnabled.equalsIgnoreCase("true")) { im.register(this); }
+        }
+
+        m_name = (String) configuration.get("name");
+
+        m_manager = im;
+    }
+
+    /**
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        try {
+            if (m_sr != null) { m_sr.unregister(); m_sr = null; }
+        } catch (Exception e) { return; }
+    }
+
+    /**
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+        // Unregister the service if already registred
+        if (m_sr != null) { m_sr.unregister(); }
+
+        // Register the ManagedService
+        BundleContext bc = m_manager.getContext();
+        Dictionary properties = new Properties();
+        properties.put("Component.Type", m_manager.getComponentDescription().getName());
+        properties.put(Constants.SERVICE_PID, m_name);
+
+        m_sr = bc.registerService(Architecture.class.getName(), this, properties);
+    }
+
+    /**
+     * @see org.apache.felix.ipojo.architecture.Architecture#getComponentDescription()
+     */
+    public InstanceDescription getInstanceDescription() {
+        return m_manager.getInstanceDescription();
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,77 @@
+/* 
+ * 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;
+
+/**
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ImportExportDescription extends HandlerDescription {
+	
+	private List m_imports;
+	private List m_exports;
+
+	/**
+	 * Constructor.
+	 * @param name
+	 * @param isValid
+	 * @param importers
+	 * @param exporters
+	 */
+	public ImportExportDescription(String name, boolean isValid, List importers, List exporters) {
+		super(name, isValid);
+		m_imports = importers;
+		m_exports = exporters;
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+	 */
+	public String getHandlerInfo() {
+		String s = "";
+		for (int i = 0; i < m_imports.size(); i++) {
+			ServiceImporter imp = (ServiceImporter) m_imports.get(i);
+			if (imp.isSatisfied()) {
+				s += "\t Specification " + imp.getSpecification() + " provided by \n \t";
+				for (int j = 0; j < imp.getProviders().size(); j++) {
+					String prov = (String) imp.getProviders().get(j);
+					s += prov + " ";
+				}	
+			} else {
+				s += "\t Specification " + imp.getSpecification() + " is not statisfied \n";
+			}
+		}
+		for (int i = 0; i < m_exports.size(); i++) {
+			ServiceExporter exp = (ServiceExporter) m_exports.get(i);
+			if (exp.isSatisfied()) {
+				s += "\t Specification " + exp.getSpecification() + " is exported or optional";
+			} else {
+				s += "\t Specification " + exp.getSpecification() + " is not exported";
+			}
+		}
+		return s;
+		
+	}
+	
+	
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportDescription.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,241 @@
+/* 
+ * 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.CompositeHandler;
+import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This handler manages the importation and the exportation of services from / to the parent context.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ImportExportHandler extends CompositeHandler {
+	
+	/**
+	 * Composite Manager.
+	 */
+	private CompositeManager m_manager;
+	
+	/**
+	 * Service Scope. 
+	 */
+	private ServiceContext m_scope;
+	
+	/**
+	 * Parent context. 
+	 */
+	private BundleContext m_context;
+	
+	/**
+	 * List of importers. 
+	 */
+	private List m_importers = new ArrayList();
+	
+	/**
+	 * List of exporters.
+	 */
+	private List m_exporters = new ArrayList(); 
+	
+	/**
+	 * Is the handler valid ?
+	 */
+	private boolean m_valid;
+
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+	 */
+	public void configure(CompositeManager im, Element metadata, Dictionary conf) {
+		m_manager = im;
+		m_context = im.getContext();
+		m_scope = m_manager.getServiceContext();
+		
+		Element[] imp = metadata.getElements("import");
+		Element[] exp = metadata.getElements("export");
+		
+		for (int i = 0; i < imp.length; i++) {
+			boolean optional = false;
+			boolean aggregate = false;
+			String specification = null;
+			
+			if (!imp[i].containsAttribute("specification")) { // Malformed import
+				im.getFactory().getLogger().log(Logger.ERROR, "Malformed import : the specification attribute is mandatory");
+			} else {
+				specification = imp[i].getAttribute("specification");
+				String filter = "(&(objectClass=" + specification + ")(!(service.pid=" + m_manager.getInstanceName() + ")))"; // Cannot import yourself
+				if (imp[i].containsAttribute("optional") && imp[i].getAttribute("optional").equalsIgnoreCase("true")) { optional = true; }
+				if (imp[i].containsAttribute("aggregate") && imp[i].getAttribute("aggregate").equalsIgnoreCase("true")) { aggregate = true; }
+				if (imp[i].containsAttribute("filter")) { 
+					String classnamefilter = "(objectClass=" + specification + ")";
+			        filter = "";
+			        if (!imp[i].getAttribute("filter").equals("")) {
+			            filter = "(&" + classnamefilter + imp[i].getAttribute("filter") + ")";
+			        } else {
+			            filter = classnamefilter;
+			        }
+				}
+				ServiceImporter si = new ServiceImporter(specification, filter, aggregate, optional, this);
+				m_importers.add(si);
+			}
+		}
+		
+		for (int i = 0; i < exp.length; i++) {
+			boolean optional = false;
+			boolean aggregate = false;
+			String specification = null;
+			
+			if (!exp[i].containsAttribute("specification")) { // Malformed exports
+				im.getFactory().getLogger().log(Logger.ERROR, "Malformed exports : the specification attribute is mandatory");
+			} else {
+				specification = exp[i].getAttribute("specification");
+				String filter = "(objectClass=" + specification + ")";
+				if (exp[i].containsAttribute("optional") && exp[i].getAttribute("optional").equalsIgnoreCase("true")) { optional = true; }
+				if (exp[i].containsAttribute("aggregate") && exp[i].getAttribute("aggregate").equalsIgnoreCase("true")) { aggregate = true; }
+				if (exp[i].containsAttribute("filter")) { 
+					String classnamefilter = "(objectClass=" + specification + ")";
+			        filter = "";
+			        if (!imp[i].getAttribute("filter").equals("")) {
+			            filter = "(&" + classnamefilter + exp[i].getAttribute("filter") + ")";
+			        } else {
+			            filter = classnamefilter;
+			        }
+			    }
+				ServiceExporter si = new ServiceExporter(specification, filter, aggregate, optional, this);
+				// Update the componenet type description
+				
+				m_manager.getComponentDescription().addProvidedServiceSpecification(specification);
+				m_exporters.add(si);
+			}
+		}
+		
+		if (m_importers.size() > 0 || m_exporters.size() > 0) {
+			im.register(this);
+		}
+	}
+
+	/**
+	 * @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.configure(m_context, m_scope);
+			si.start();
+		}
+		
+		for (int i = 0; i < m_exporters.size(); i++) {
+			ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+			se.configure(m_scope, m_context);
+			se.start();
+		}
+		
+	}
+
+	/**
+	 * @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();
+		}
+		
+		for (int i = 0; i < m_exporters.size(); i++) {
+			ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+			se.stop();
+		}
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+	 */
+	public boolean isValid() {
+		for (int i = 0; i < m_importers.size(); i++) {
+			ServiceImporter si = (ServiceImporter) m_importers.get(i);
+			if (!si.isSatisfied()) { m_valid = false; return false; }
+		}
+		
+		for (int i = 0; i < m_exporters.size(); i++) {
+			ServiceExporter se = (ServiceExporter) m_exporters.get(i);
+			if (!se.isSatisfied()) { m_valid = false; return false; }
+		}
+	
+		m_valid = true;
+		return 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 (m_valid) { m_manager.checkInstanceState(); }
+		
+	}
+
+	/**
+	 * Notify the handler that an importer becomes valid.
+	 * @param importer : the implicated importer.
+	 */
+	protected void validating(ServiceImporter importer) {
+		// An import becomes valid
+		if (!m_valid && isValid()) { m_manager.checkInstanceState(); }
+		
+	}
+
+	/**
+	 * Notify the handler that an exporter becomes invalid.
+	 * @param exporter : the impcated exporter.
+	 */
+	protected void invalidating(ServiceExporter exporter) {
+		// An import is no more valid
+		if (m_valid) { m_manager.checkInstanceState(); }
+		
+	}
+
+	/**
+	 * Notify the handler that an exporter becomes valid.
+	 * @param exporter : the impcated exporter.
+	 */
+	protected void validating(ServiceExporter exporter) {
+		// An import becomes valid
+		if (!m_valid && isValid()) { m_manager.checkInstanceState(); }
+		
+	}
+	
+	/**
+	 * @return the attached composite manager.
+	 */
+	protected CompositeManager getManager() { return m_manager; }
+	
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+	 */
+	public HandlerDescription getDescription() { return new ImportExportDescription(this.getClass().getName(), isValid(), m_importers, m_exporters); }
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ImportExportHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,301 @@
+/* 
+ * 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.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Export an service from the scope to the parent context.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceExporter implements ServiceListener {
+	
+	private BundleContext m_destination;
+	private ServiceContext m_origin;
+	
+	private String m_specification;
+	private Filter m_filter;
+	private String m_filterStr;
+	
+	private boolean m_aggregate = false;
+	private boolean m_optional = false;
+	
+	private ImportExportHandler m_handler;
+	
+	private boolean m_isValid;
+	
+	private class Record {
+		private ServiceReference m_ref;
+		private ServiceRegistration m_reg;
+		private Object m_svcObject;
+	}
+	
+	private List/*<Record>*/ m_records = new ArrayList()/*<Record>*/;
+	
+	/**
+	 * Constructor.
+	 * @param specification
+	 * @param filter
+	 * @param multiple
+	 * @param optional
+	 * @param from
+	 * @param to
+	 * @param exp
+	 */
+	public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to, ImportExportHandler 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;
+	}
+	
+	/**
+	 * @param specification
+	 * @param filter
+	 * @param multiple
+	 * @param optional
+	 * @param exp
+	 */
+	public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ImportExportHandler exp) {
+		this.m_handler = exp;
+		this.m_filterStr = filter;
+		this.m_aggregate = multiple;
+		this.m_specification = specification;
+		this.m_optional = optional;
+	}
+	
+	/**
+	 * @param from
+	 * @param to
+	 */
+	public void configure(ServiceContext from, BundleContext to) {
+		this.m_destination = to;
+		this.m_origin = from;
+		try {
+			this.m_filter = to.createFilter(m_filterStr);
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); return; }
+	}
+	
+	/**
+	 * 
+	 */
+	public void start() {
+		try {
+			ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
+			if (refs != null) {
+				for (int i = 0; i < refs.length; i++) {
+					if (m_filter.match(refs[i])) {
+						Record rec = new Record();
+						rec.m_ref = refs[i];
+						m_records.add(rec);
+					}
+				}
+			}
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		
+		// Publish available services 
+		if (m_records.size() > 0) {
+			if (m_aggregate) {
+				for (int i = 0; i < m_records.size(); i++) {
+					Record rec = (Record) m_records.get(i);
+					rec.m_svcObject = m_origin.getService(rec.m_ref);
+					rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+				}
+			} else {
+				Record rec = (Record) m_records.get(0);
+				rec.m_svcObject = m_origin.getService(rec.m_ref);
+				rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+			}
+		}
+		
+		// Register service listener
+		try {
+			m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		
+		m_isValid = isSatisfied();
+	}
+	
+	/**
+	 * @param ref
+	 * @return
+	 */
+	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(Constants.SERVICE_PID, m_handler.getManager().getInstanceName());
+		prop.put("factory.pid", m_handler.getManager().getFactory().getFactoryName());
+
+		return prop;
+	}
+	
+	/**
+	 * 
+	 */
+	public void stop() {
+		m_origin.removeServiceListener(this);
+		
+		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_origin.ungetService(rec.m_ref);
+				rec.m_ref = null;
+			}
+		}
+		
+		m_records.clear();
+		
+	}
+	
+	/**
+	 * @return
+	 */
+	public boolean isSatisfied() {
+		return m_optional || m_records.size() > 0;
+	}
+	
+	/**
+	 * @param ref
+	 * @return
+	 */
+	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;
+	}
+	
+	/**
+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+	 */
+	public void serviceChanged(ServiceEvent ev) {
+		if (ev.getType() == ServiceEvent.REGISTERED) { arrivalManagement(ev.getServiceReference()); }
+		if (ev.getType() == ServiceEvent.UNREGISTERING) { departureManagement(ev.getServiceReference()); }
+		
+		if (ev.getType() == ServiceEvent.MODIFIED) {
+			if (m_filter.match(ev.getServiceReference())) {
+				// Test if the ref is always matching with the filter
+				List l = getRecordsByRef(ev.getServiceReference());
+				if (l.size() > 0) { // The ref is already contained => update the properties
+					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)); }
+					}
+				} else  { // it is a new mathcing service => add it
+					arrivalManagement(ev.getServiceReference());
+				}
+			} else {
+				List l = getRecordsByRef(ev.getServiceReference());
+				if (l.size() > 0) { // The ref is already contained => the service does no more match
+					departureManagement(ev.getServiceReference());
+				}
+			}
+		}
+	}
+	
+	/**
+	 * @param ref
+	 */
+	private void arrivalManagement(ServiceReference ref) {
+		// Check if the new service match
+		if (m_filter.match(ref)) {
+			// Add it to the record list
+			Record rec = new Record();
+			rec.m_ref = ref;
+			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_origin.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);
+			}
+		}
+	}
+	
+	/**
+	 * @param ref
+	 */
+	private void departureManagement(ServiceReference ref) {
+		List l = getRecordsByRef(ref);
+		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_origin.ungetService(rec.m_ref);
+			}
+		}
+		m_records.removeAll(l);
+		
+		// Check the validity & if we need to reimport 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 who disappears - create the next one
+					rec.m_svcObject = m_origin.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);
+			}
+		}
+	}
+	
+	/**
+	 * @return the exported specification.
+	 */
+	protected String getSpecification() {
+		return m_specification;
+	}
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceExporter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,316 @@
+/* 
+ * 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.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+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:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceImporter implements ServiceListener {
+	
+	private ServiceContext m_destination;
+	private BundleContext m_origine;
+	
+	private String m_specification;
+	private Filter m_filter;
+	private String m_filterStr;
+	
+	private boolean m_aggregate = false;
+	private boolean m_optional = false;
+	
+	private boolean m_isValid;
+	
+	private ImportExportHandler m_handler;
+	
+	private class Record {
+		private ServiceReference m_ref;
+		private ServiceRegistration m_reg;
+		private Object m_svcObject;
+	}
+	
+	private List/*<Record>*/ m_records = new ArrayList()/*<Record>*/;
+	
+	/**
+	 * Constructor.
+	 * @param specification : targetted 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 in : handler
+	 */
+	public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, BundleContext from, ServiceContext to, ImportExportHandler in) {
+		this.m_destination = to;
+		this.m_origine = from;
+		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;
+	}
+	
+	/**
+	 * Constructor.
+	 * @param specification : targetted specification
+	 * @param filter : LDAP filter
+	 * @param multiple : should the importer imports several services ?
+	 * @param optional : is the import optional ?
+	 * @param in : handler
+	 */
+	public ServiceImporter(String specification, String filter, boolean multiple, boolean optional, ImportExportHandler in) {
+		this.m_filterStr = filter;
+		this.m_aggregate = multiple;
+		this.m_filterStr = filter;
+		this.m_specification = specification;
+		this.m_optional = optional;
+		this.m_handler = in;
+	}
+	
+	/**
+	 * Configure the origin and the destination of the import.
+	 * @param from : origine (parent)
+	 * @param to : destination (internal scope)
+	 */
+	public void configure(BundleContext from, ServiceContext to) {
+		this.m_destination = to;
+		this.m_origine = from;
+		try {
+			this.m_filter = from.createFilter(m_filterStr);
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); return; }
+	}
+	
+	/**
+	 * Start method to begin the import.
+	 */
+	public void start() {
+		try {
+			ServiceReference[] refs = m_origine.getServiceReferences(m_specification, null);
+			if (refs != null) {
+				for (int i = 0; i < refs.length; i++) {
+					if (m_filter.match(refs[i])) {
+						Record rec = new Record();
+						rec.m_ref = refs[i];
+						m_records.add(rec);
+					}
+				}
+			}
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		
+		// Publish available services 
+		if (m_records.size() > 0) {
+			if (m_aggregate) {
+				for (int i = 0; i < m_records.size(); i++) {
+					Record rec = (Record) m_records.get(i);
+					rec.m_svcObject = m_origine.getService(rec.m_ref);
+					rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+				}
+			} else {
+				Record rec = (Record) m_records.get(0);
+				rec.m_svcObject = m_origine.getService(rec.m_ref);
+				rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+			}
+		}
+		
+		// Register service listener
+		try {
+			m_origine.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+		
+		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_origine.removeServiceListener(this);
+		
+		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_origine.ungetService(rec.m_ref);
+				rec.m_ref = null;
+			}
+		}
+		
+		m_records.clear();
+		
+	}
+	
+	/**
+	 * @return true if the import is satisfied.
+	 */
+	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;
+	}
+	
+	/**
+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+	 */
+	public void serviceChanged(ServiceEvent ev) {
+		if (ev.getType() == ServiceEvent.REGISTERED) { arrivalManagement(ev.getServiceReference()); }
+		if (ev.getType() == ServiceEvent.UNREGISTERING) { departureManagement(ev.getServiceReference()); }
+		
+		if (ev.getType() == ServiceEvent.MODIFIED) {
+			if (m_filter.match(ev.getServiceReference())) {
+				// Test if the ref is always matching with the filter
+				List l = getRecordsByRef(ev.getServiceReference());
+				if (l.size() > 0) { // The ref is already contained => update the properties
+					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)); }
+					}
+				} else  { // it is a new mathcing service => add it
+					arrivalManagement(ev.getServiceReference());
+				}
+			} else {
+				List l = getRecordsByRef(ev.getServiceReference());
+				if (l.size() > 0) { // The ref is already contained => the service does no more match
+					departureManagement(ev.getServiceReference());
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Manage the arrival of a consitent service.
+	 * @param ref : the arrival service reference
+	 */
+	private void arrivalManagement(ServiceReference ref) {
+		//	Check if the new service match
+		if (m_filter.match(ref)) {
+			// Add it to the record list
+			Record rec = new Record();
+			rec.m_ref = ref;
+			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_origine.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);
+			}
+		}
+	}
+	
+	/**
+	 * Manage the departure of a used reference.
+	 * @param ref : the leaving reference
+	 */
+	private void departureManagement(ServiceReference ref) {
+		List l = getRecordsByRef(ref);
+		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_origine.ungetService(rec.m_ref);
+			}
+		}
+		m_records.removeAll(l);
+		
+		// Check the validity & if we need to reimport 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 who disappears - create the next one
+					rec.m_svcObject = m_origine.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);
+			}
+		}
+	}
+	
+	/**
+	 * @return the targetted specification.
+	 */
+	public String getSpecification() { return m_specification; }
+		
+	/**
+	 * @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(Constants.SERVICE_PID));
+		}
+		return l;
+		
+	}
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/importer/ServiceImporter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,73 @@
+/* 
+ * 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.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Description of the Service Instantiator Handler.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceInstantiatorDescription extends HandlerDescription {
+	
+	/**
+	 * List of managed service instances.
+	 */
+	private List m_instances;
+
+	/**
+	 * Constructor.
+	 * @param arg0 : name of the handler
+	 * @param arg1 : validity of the handler
+	 * @param insts : list of service instance
+	 */
+	public ServiceInstantiatorDescription(String arg0, boolean arg1, List insts) {
+		super(arg0, arg1);
+		m_instances = insts;
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+	 */
+	public String getHandlerInfo() {
+		String r = "";
+		for (int i = 0; i < m_instances.size(); i++) {
+			SvcInstance inst = (SvcInstance) m_instances.get(i);
+			HashMap 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  && o instanceof ComponentInstance) {
+					r += "\t Specification " + inst.getSpecification() + " instantiated from " + ((ComponentInstance) o).getComponentDescription().getName() + " \n";
+				}
+			}
+		}
+		return r;
+	}
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,158 @@
+/* 
+ * 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.CompositeHandler;
+import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Service Instantiator Class.
+ * This handler allows to instantiate service instance inside the composition.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceInstantiatorHandler extends CompositeHandler {
+	
+	/**
+	 * Composite Manager. 
+	 */
+	private CompositeManager m_manager;
+	
+	/**
+	 * Is the handler valid ?
+	 */
+	private boolean m_isValid = false;
+	
+	/**
+	 * List of instances to manage.
+	 */
+	private List/*<SvcInstance>*/ m_instances = new ArrayList();
+
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+	 */
+	public void configure(CompositeManager im, Element metadata, Dictionary conf) {
+		m_manager = im;
+		Element[] services = metadata.getElements("service");
+		for (int i = 0; i < services.length; i++) {
+			String spec = services[i].getAttribute("specification");
+			String filter = "(objectClass=" + Factory.class.getName() + ")";
+			if (services[i].containsAttribute("filter")) { 
+				String classnamefilter = "(&(objectClass=" + Factory.class.getName() + ")(!(service.pid=" + m_manager.getInstanceName() + ")))";  // Cannot instantaite yourself
+		        filter = "";
+		        if (!services[i].getAttribute("filter").equals("")) {
+		            filter = "(&" + classnamefilter + services[i].getAttribute("filter") + ")";
+		        } else {
+		            filter = classnamefilter;
+		        }
+			}
+			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);
+			}
+			boolean agg = false;
+			if (services[i].containsAttribute("aggregate") && services[i].getAttribute("aggregate").equalsIgnoreCase("true")) { agg = true; }
+			boolean opt = false;
+			if (services[i].containsAttribute("optional") && services[i].getAttribute("optional").equalsIgnoreCase("true")) { opt = true; }
+			SvcInstance inst = new SvcInstance(this, spec, prop, agg, opt, filter);
+			m_instances.add(inst);
+		}
+		if (m_instances.size() > 0) {
+			m_manager.register(this);
+		}
+	}
+
+	/**
+	 * @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();
+		}
+		
+		m_isValid = isValid();
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+	 */
+	public boolean isValid() {
+		for (int i = 0; i < m_instances.size(); i++) {
+			SvcInstance inst = (SvcInstance) m_instances.get(i);
+			if (!inst.isSatisfied()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	/**
+	 * @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 (!m_isValid) {
+			if (isValid()) { m_manager.checkInstanceState(); }
+			m_isValid = true;
+		}
+	}
+	
+	/**
+	 * A service instance becomes invalid.
+	 */
+	public void invalidate() {
+		if (m_isValid) {
+			if (!isValid()) { m_manager.checkInstanceState(); }
+			m_isValid = false;
+		}
+	}
+	
+	/**
+	 * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+	 */
+	public HandlerDescription getDescription() {
+		return new ServiceInstantiatorDescription(this.getClass().getName(), isValid(), m_instances);
+	}
+	
+	/**
+	 * @return the composite manager.
+	 */
+	protected CompositeManager getManager() { return m_manager; }
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java?view=auto&rev=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java Tue Apr 10 08:16:56 2007
@@ -0,0 +1,347 @@
+/* 
+ * 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.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Manage a service instantiation.
+ * This service create componenet instance providing the required service specification.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class SvcInstance implements ServiceListener {
+	
+	/**
+	 * 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 HashMap /*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;
+	
+	/**
+	 * Parent context.
+	 */
+	//private BundleContext m_parent;
+	
+	/**
+	 * True if the service instantiation is valid.
+	 */
+	private boolean m_isValid = false;
+	
+	/**
+	 * String form of the factory filter.
+	 */
+	private String m_filterStr;
+	
+	/**
+	 * Name of the last create instance.
+	 */
+	private long m_index = 0;
+	
+	/**
+	 * Constructor.
+	 * @param h : the handler.
+	 * @param spec : required specification.
+	 * @param conf : instance configuration.
+	 * @param isAgg : is the svc instance an aggregate service ?
+	 * @param isOpt : is the svc instance optional ?
+	 */
+	public SvcInstance(ServiceInstantiatorHandler h, String spec, Dictionary conf, boolean isAgg, boolean isOpt, String filt) {
+		m_handler = h;
+		m_context = h.getManager().getServiceContext();
+		//m_parent = h.getManager().getContext();
+		m_specification = spec;
+		m_configuration = conf;
+		m_isAggregate = isAgg;
+		m_isOptional = isOpt;
+		m_filterStr = filt;
+	}
+	
+	/**
+	 * Start the service instance.
+	 * @param sc
+	 */
+	public void start() {
+		initFactoryList();
+		// Register factory listener
+		try {
+			m_context.addServiceListener(this, m_filterStr);
+		} catch (InvalidSyntaxException e) { 
+			e.printStackTrace(); // Should not happens
+		}
+
+		// Init the instances 
+		if (m_usedRef.size() > 0) {
+			Set keys = m_usedRef.keySet();
+			Iterator it = keys.iterator();
+			if (m_isAggregate) {
+				while (it.hasNext()) {
+					ServiceReference ref = (ServiceReference) it.next();
+					createInstance(ref);
+				}
+			} else {
+				ServiceReference ref = (ServiceReference) it.next();
+				createInstance(ref);
+			}
+		}
+		m_isValid = isSatisfied();
+	}
+	
+	/**
+	 * Stop the service instance.
+	 */
+	public void stop() {
+		m_context.removeServiceListener(this);
+		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).stop();
+			}
+		}
+		m_usedRef.clear();
+		m_isValid = false;
+	}
+	
+	/**
+	 * @return true if at least one instance is created.
+	 */
+	private boolean isAnInstanceCreated() {
+		Set keys = m_usedRef.keySet();
+		Iterator it = keys.iterator();
+		ServiceReference ref = (ServiceReference) it.next();
+		Object o = m_usedRef.get(ref);
+		return o != null;
+	}
+	
+	/**
+	 * Create an instance for the given reference.
+	 */
+	private void createInstance(ServiceReference ref) {
+		try {
+			Factory factory = (Factory) m_context.getService(ref);
+			ComponentInstance instance = factory.createComponentInstance(m_configuration);
+			m_usedRef.put(ref, instance);
+			m_context.ungetService(ref);
+		} catch (UnacceptableConfiguration e) {
+			System.err.println("A matching factory (" + ref.getProperty("service.pid") + ") seems to refuse the given configuration : " + e.getMessage());
+		}
+	}
+	
+	/**
+	 * 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);
+			ComponentInstance instance = factory.createComponentInstance(m_configuration);
+			m_usedRef.put(ref, instance);
+			m_context.ungetService(ref);
+		} catch (UnacceptableConfiguration e) {
+			System.err.println("A matching factory seems to refuse the given configuration : " + e.getMessage());
+		}
+	}
+	
+	/**
+	 * Kill an instance (if exist).
+	 */
+	private void stopInstance(ServiceReference ref) {
+		Object o = m_usedRef.get(ref);
+		if (o != null) {
+			((ComponentInstance) o).stop();
+		}
+	}
+
+
+	/**
+	 * Init the list of available factory.
+	 */
+	public void initFactoryList() {
+		// Init factory list
+		try {
+			ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), m_filterStr);
+			if (refs == null) { return; }
+			for (int i = 0; i < refs.length; i++) {
+				ServiceReference ref = refs[i];
+				Factory fact = (Factory) m_context.getService(ref);
+				// Check provided spec & conf
+				if (match(fact)) {
+					m_usedRef.put(ref, null);
+				}
+				fact = null;
+				m_context.ungetService(ref);
+			}
+		} catch (InvalidSyntaxException e) {
+			e.printStackTrace(); // Should not happen
+		}
+	}
+	
+	/**
+	 * @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) {
+		// Check if the factory can provide the spec
+		for (int i = 0; i < fact.getComponentDescription().getprovidedServiceSpecification().length; i++) {
+			if (fact.getComponentDescription().getprovidedServiceSpecification()[i].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.
+				if (m_configuration.get("name") == null) {
+					m_configuration.put("name", this.toString() + "-" + m_index);
+					m_index++;
+				}
+				
+				// Check the acceptability.
+				return (fact.isAcceptable(m_configuration));
+			}
+		}
+		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) {
+		PropertyDescription[] props = factory.getComponentDescription().getProperties();
+		for (int i = 0; i < props.length; i++) {
+			if (props[i].getName().equalsIgnoreCase(name)) { return true; }
+		}
+		if (name.equalsIgnoreCase("name")) { return true; } // Skip the name property
+		return false;
+	}
+
+	/**
+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+	 */
+	public void serviceChanged(ServiceEvent ev) {
+		if (ev.getType() == ServiceEvent.REGISTERED) {
+			// Check the matching
+			Factory fact = (Factory) m_context.getService(ev.getServiceReference());
+			if (match(fact)) {
+				m_usedRef.put(ev.getServiceReference(), null);
+				if (m_isAggregate) { // Create an instance for the new factory
+					createInstance(ev.getServiceReference());
+					if (!m_isValid) { m_isValid = true; m_handler.validate(); }
+				} else { 
+					if (!isAnInstanceCreated()) { createInstance(ev.getServiceReference()); }
+					if (!m_isValid) { m_isValid = true; m_handler.validate(); }
+				}
+			}
+			fact = null;
+			m_context.ungetService(ev.getServiceReference());
+			return;
+		}
+		if (ev.getType() == ServiceEvent.UNREGISTERING) {
+			// Remove the ref is contained
+			Object o = m_usedRef.remove(ev.getServiceReference());
+			if (o != null) { 
+				stopInstance(ev.getServiceReference());
+				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(); }
+				}
+			}
+		}
+	}
+
+	/**
+	 * @return the required specification.
+	 */
+	public String getSpecification() {
+		return m_specification;
+	}
+	
+	/**
+	 * @return the map of used references.
+	 */
+	protected HashMap getUsedReferences() { 
+		return m_usedRef;
+	}
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?view=diff&rev=527156&r1=527155&r2=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Tue Apr 10 08:16:56 2007
@@ -296,7 +296,6 @@
 
             // If a service goes way.
             if (event.getType() == ServiceEvent.UNREGISTERING) {
-                m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] A service is gone -> " + event.getServiceReference().getBundle());
                 if (containsSR(event.getServiceReference())) { departureManagement(event.getServiceReference()); }
                 return;
             }
@@ -311,12 +310,10 @@
             // If a service is modified
             if (event.getType() == ServiceEvent.MODIFIED) {
                 if (m_filter.match(event.getServiceReference())) {
-                    m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] A service with a filter matching is arrived -> " + event.getServiceReference().getBundle());
                     if (!containsSR(event.getServiceReference())) { 
                     	arrivalManagement(event.getServiceReference()); 
                     }
                 } else {
-                    m_handler.getInstanceManager().getFactory().getLogger().log(Logger.INFO, "[" + m_handler.getInstanceManager().getClassName() + "] A service with a filter matching has gone -> " + event.getServiceReference().getBundle());
                     if (containsSR(event.getServiceReference())) { 
                     	departureManagement(event.getServiceReference()); 
                     }

Modified: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java?view=diff&rev=527156&r1=527155&r2=527156
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java (original)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java Tue Apr 10 08:16:56 2007
@@ -42,11 +42,23 @@
     private Element[] m_elements = new Element[0];
 
     /**
-     * @return the component metadata.
+     * @return the component metadata (composite & component).
      * @throws ParseException when a parsing error occurs
      */
     public Element[] getComponentsMetadata() throws ParseException {
-        return m_elements[0].getElements("Component");
+        Element[] components = m_elements[0].getElements("Component");
+        Element[] composites = m_elements[0].getElements("Composite");
+        Element[] all = new Element[components.length + composites.length];
+        int l = 0;
+        for (int i = 0; i < components.length; i++) {
+        	all[l] = components[i];
+        	l++;
+        }
+        for (int i = 0; i < composites.length; i++) {
+        	all[l] = composites[i];
+        	l++;
+        }
+        return all;
     }
 
     /**
@@ -152,7 +164,6 @@
         //Add the ipojo element inside the element list
         addElement(new Element("iPOJO", ""));
         parseElements(componentClassesStr.trim());
-
     }
 
     /**