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;
+ }
+
+}