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());
-
}
/**