Preparing move...
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@882951 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/LICENSE b/dependencymanager/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/dependencymanager/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed 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.
diff --git a/dependencymanager/NOTICE b/dependencymanager/NOTICE
deleted file mode 100644
index cfc3633..0000000
--- a/dependencymanager/NOTICE
+++ /dev/null
@@ -1,26 +0,0 @@
-Apache Felix Dependency Manager
-Copyright 2009 The Apache Software Foundation
-
-
-I. Included Software
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-Licensed under the Apache License 2.0.
-
-This product includes software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2007).
-Licensed under the Apache License 2.0.
-
-
-II. Used Software
-
-This product uses software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2007).
-Licensed under the Apache License 2.0.
-
-
-III. License Summary
-- Apache License 2.0
diff --git a/dependencymanager/pom.xml b/dependencymanager/pom.xml
deleted file mode 100644
index 9012544..0000000
--- a/dependencymanager/pom.xml
+++ /dev/null
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
- <!--
- 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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <parent>
- <groupId>org.apache.felix</groupId>
- <artifactId>felix</artifactId>
- <version>1.0.4</version>
- <relativePath>../pom/pom.xml</relativePath>
- </parent>
- <modelVersion>4.0.0</modelVersion>
- <packaging>bundle</packaging>
- <name>Apache Felix Dependency Manager</name>
- <version>3.0.0-SNAPSHOT</version>
- <artifactId>org.apache.felix.dependencymanager</artifactId>
- <dependencies>
- <dependency>
- <groupId>${pom.groupId}</groupId>
- <artifactId>org.osgi.core</artifactId>
- <version>1.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>${pom.groupId}</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- <version>1.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam</artifactId>
- <version>1.2.0</version>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-default</artifactId>
- <version>1.2.0</version>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit</artifactId>
- <version>1.2.0</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.7</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>1.4.0</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-SymbolicName>org.apache.felix.dependencymanager</Bundle-SymbolicName>
- <Bundle-Name>Apache Felix Dependency Manager</Bundle-Name>
- <Bundle-Description>A bundle that provides a run-time
- service dependency manager.</Bundle-Description>
- <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
- <Export-Package>org.apache.felix.dependencymanager</Export-Package>
- <Import-Package>!org.apache.felix.dependencymanager,*</Import-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <executions>
- <execution>
- <id>default-testCompile</id>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>maven-paxexam-plugin</artifactId>
- <version>1.2.0</version>
- <executions>
- <execution>
- <id>generate-config</id>
- <goals>
- <goal>generate-depends-file</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
- <scm>
- <connection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.dependencymanager-3.0.0</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.dependencymanager-3.0.0</developerConnection>
- <url>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.dependencymanager-3.0.0</url>
- </scm>
-</project>
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
deleted file mode 100644
index f7ac01b..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ConfigurationDependency.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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.dependencymanager;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Dictionary;
-import java.util.Properties;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
-
-/**
- * Configuration dependency that can track the availability of a (valid) configuration.
- * To use it, specify a PID for the configuration. The dependency is always required,
- * because if it is not, it does not make sense to use the dependency manager. In that
- * scenario, simply register your service as a <code>ManagedService(Factory)</code> and
- * handle everything yourself. Also, only managed services are supported, not factories.
- * There are a couple of things you need to be aware of when implementing the
- * <code>updated(Dictionary)</code> method:
- * <ul>
- * <li>Make sure it throws a <code>ConfigurationException</code> when you get a
- * configuration that is invalid. In this case, the dependency will not change:
- * if it was not available, it will still not be. If it was available, it will
- * remain available and implicitly assume you keep working with your old
- * configuration.</li>
- * <li>This method will be called before all required dependencies are available.
- * Make sure you do not depend on these to parse your settings.</li>
- * </ul>
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ConfigurationDependency implements Dependency, ManagedService, ServiceComponentDependency {
- private BundleContext m_context;
- private String m_pid;
- private ServiceRegistration m_registration;
- private volatile Service m_service;
- private Dictionary m_settings;
- private boolean m_propagate;
- private final Logger m_logger;
- private String m_callback;
-
- public ConfigurationDependency(BundleContext context, Logger logger) {
- m_context = context;
- m_logger = logger;
- }
-
- public synchronized boolean isAvailable() {
- return m_settings != null;
- }
-
- /**
- * Will always return <code>true</code> as optional configuration dependencies
- * do not make sense. You might as well just implement <code>ManagedService</code>
- * yourself in those cases.
- */
- public boolean isRequired() {
- return true;
- }
-
- /**
- * Returns <code>true</code> when configuration properties should be propagated
- * as service properties.
- */
- public boolean isPropagated() {
- return m_propagate;
- }
-
- public Dictionary getConfiguration() {
- return m_settings;
- }
-
- public void start(Service service) {
- m_service = service;
- Properties props = new Properties();
- props.put(Constants.SERVICE_PID, m_pid);
- m_registration = m_context.registerService(ManagedService.class.getName(), this, props);
- }
-
- public void stop(Service service) {
- m_registration.unregister();
- m_service = null;
- }
-
- public Dependency setCallback(String callback) {
- m_callback = callback;
- return this;
- }
-
- public void updated(Dictionary settings) throws ConfigurationException {
- // if non-null settings come in, we have to instantiate the service and
- // apply these settings
- ((ServiceImpl) m_service).initService();
- Object service = m_service.getService();
-
- Dictionary oldSettings = null;
- synchronized (this) {
- oldSettings = m_settings;
- }
-
- if (oldSettings == null && settings == null) {
- // CM has started but our configuration is not still present in the CM database: ignore
- return;
- }
-
- if (service != null) {
- String callback = (m_callback == null) ? "updated" : m_callback;
- Method m;
- try {
- m = service.getClass().getDeclaredMethod(callback, new Class[] { Dictionary.class });
- m.setAccessible(true);
- // if exception is thrown here, what does that mean for the
- // state of this dependency? how smart do we want to be??
- // it's okay like this, if the new settings contain errors, we
- // remain in the state we were, assuming that any error causes
- // the "old" configuration to stay in effect.
- // CM will log any thrown exceptions.
- m.invoke(service, new Object[] { settings });
- }
- catch (InvocationTargetException e) {
- // The component has thrown an exception during it's callback invocation.
- if (e.getTargetException() instanceof ConfigurationException) {
- // the callback threw an OSGi ConfigurationException: just re-throw it.
- throw (ConfigurationException) e.getTargetException();
- }
- else {
- // wrap the callback exception into a ConfigurationException.
- throw new ConfigurationException(null, "Service " + m_service + " with " + this.toString() + " could not be updated", e.getTargetException());
- }
- }
- catch (Throwable t) {
- // wrap any other exception as a ConfigurationException.
- throw new ConfigurationException(null, "Service " + m_service + " with " + this.toString() + " could not be updated", t);
- }
- }
- else {
- m_logger.log(Logger.LOG_ERROR, "Service " + m_service + " with configuration dependency " + this + " could not be instantiated.");
- return;
- }
-
- // If these settings did not cause a configuration exception, we determine if they have
- // caused the dependency state to change
- synchronized (this) {
- m_settings = settings;
- }
-
- if ((oldSettings == null) && (settings != null)) {
- m_service.dependencyAvailable(this);
- }
- if ((oldSettings != null) && (settings == null)) {
- m_service.dependencyUnavailable(this);
- }
- if ((oldSettings != null) && (settings != null)) {
- m_service.dependencyChanged(this);
- }
- }
-
- /**
- * Sets the <code>service.pid</code> of the configuration you
- * are depending on.
- */
- public ConfigurationDependency setPid(String pid) {
- ensureNotActive();
- m_pid = pid;
- return this;
- }
-
- /**
- * Sets propagation of the configuration properties to the service
- * properties. Any additional service properties specified directly
- * are merged with these.
- */
- public ConfigurationDependency setPropagate(boolean propagate) {
- ensureNotActive();
- m_propagate = propagate;
- return this;
- }
-
- private void ensureNotActive() {
- if (m_service != null) {
- throw new IllegalStateException("Cannot modify state while active.");
- }
- }
-
- public String toString() {
- return "ConfigurationDependency[" + m_pid + "]";
- }
-
- public String getName() {
- return m_pid;
- }
-
- public int getState() {
- return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
- }
-
- public String getType() {
- return "configuration";
- }
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java
deleted file mode 100644
index 79bb240..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DefaultNullObject.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-
-
-/**
- * Default null object implementation. Uses a dynamic proxy. Null objects are used
- * as placeholders for services that are not available.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public final class DefaultNullObject implements InvocationHandler {
- private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
- private static final Byte DEFAULT_BYTE = new Byte((byte) 0);
- private static final Short DEFAULT_SHORT = new Short((short) 0);
- private static final Integer DEFAULT_INT = new Integer(0);
- private static final Long DEFAULT_LONG = new Long(0);
- private static final Float DEFAULT_FLOAT = new Float(0.0f);
- private static final Double DEFAULT_DOUBLE = new Double(0.0);
-
- /**
- * Invokes a method on this null object. The method will return a default
- * value without doing anything.
- */
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Class returnType = method.getReturnType();
- if (returnType.equals(Boolean.class) || returnType.equals(Boolean.TYPE)) {
- return DEFAULT_BOOLEAN;
- }
- else if (returnType.equals(Byte.class) || returnType.equals(Byte.TYPE)) {
- return DEFAULT_BYTE;
- }
- else if (returnType.equals(Short.class) || returnType.equals(Short.TYPE)) {
- return DEFAULT_SHORT;
- }
- else if (returnType.equals(Integer.class) || returnType.equals(Integer.TYPE)) {
- return DEFAULT_INT;
- }
- else if (returnType.equals(Long.class) || returnType.equals(Long.TYPE)) {
- return DEFAULT_LONG;
- }
- else if (returnType.equals(Float.class) || returnType.equals(Float.TYPE)) {
- return DEFAULT_FLOAT;
- }
- else if (returnType.equals(Double.class) || returnType.equals(Double.TYPE)) {
- return DEFAULT_DOUBLE;
- }
- else {
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Dependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Dependency.java
deleted file mode 100644
index 64d241a..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Dependency.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.dependencymanager;
-
-/**
- * Generic dependency for a service. A dependency can be required or not.
- * A dependency will be activated by the service it belongs to. The service
- * will call the <code>start(Service service)</code> and
- * <code>stop(Service service)</code> methods.
- *
- * After it has been started, a dependency must callback
- * the associated service's <code>dependencyAvailable()</code> and
- * <code>dependencyUnavailable()</code>
- * methods. State changes of the dependency itself may only be made as long as
- * the dependency is not 'active', meaning it is associated with a running service.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface Dependency {
- /**
- * Returns <code>true</code> if this a required dependency. Required dependencies
- * are dependencies that must be available before the service can be activated.
- *
- * @return <code>true</code> if the dependency is required
- */
- public boolean isRequired();
-
- /**
- * Returns <code>true</code> if the dependency is available.
- *
- * @return <code>true</code> if the dependency is available
- */
- public boolean isAvailable();
-
- /**
- * Starts tracking the dependency. This activates some implementation
- * specific mechanism to do the actual tracking. If the tracking discovers
- * that the dependency becomes available, it should call
- * <code>dependencyAvailable()</code> on the service.
- *
- * @param service the service that is associated with this dependency
- */
- public void start(Service service);
-
- /**
- * Stops tracking the dependency. This deactivates the tracking. If the
- * dependency was available, the tracker should call
- * <code>dependencyUnavaible()</code> before stopping itself to ensure
- * that dependencies that aren't "active" are unavailable.
- */
- public void stop(Service service);
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
deleted file mode 100644
index 2fa8b13..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyActivatorBase.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.util.List;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-/**
- * Base bundle activator class. Subclass this activator if you want to use dependency
- * management in your bundle. There are two methods you should implement:
- * <code>init()</code> and <code>destroy()</code>. Both methods take two arguments,
- * the bundle context and the dependency manager. The dependency manager can be used
- * to define all the dependencies.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public abstract class DependencyActivatorBase implements BundleActivator {
- private BundleContext m_context;
- private DependencyManager m_manager;
- private Logger m_logger;
-
- /**
- * Initialize the dependency manager. Here you can add all services and their dependencies.
- * If something goes wrong and you do not want your bundle to be started, you can throw an
- * exception. This exception will be passed on to the <code>start()</code> method of the
- * bundle activator, causing the bundle not to start.
- *
- * @param context the bundle context
- * @param manager the dependency manager
- * @throws Exception if the initialization fails
- */
- public abstract void init(BundleContext context, DependencyManager manager) throws Exception;
-
- /**
- * Destroy the dependency manager. Here you can remove all services and their dependencies.
- * Actually, the base class will clean up your dependencies anyway, so most of the time you
- * don't need to do anything here.
- * If something goes wrong and you do not want your bundle to be stopped, you can throw an
- * exception. This exception will be passed on to the <code>stop()</code> method of the
- * bundle activator, causing the bundle not to stop.
- *
- * @param context the bundle context
- * @param manager the dependency manager
- * @throws Exception if the destruction fails
- */
- public abstract void destroy(BundleContext context, DependencyManager manager) throws Exception;
-
- /**
- * Start method of the bundle activator. Initializes the dependency manager
- * and calls <code>init()</code>.
- *
- * @param context the bundle context
- */
- public void start(BundleContext context) throws Exception {
- m_context = context;
- m_logger = new Logger(context);
- m_manager = new DependencyManager(context, m_logger);
- init(m_context, m_manager);
- }
-
- /**
- * Stop method of the bundle activator. Calls the <code>destroy()</code> method
- * and cleans up all left over dependencies.
- *
- * @param context the bundle context
- */
- public void stop(BundleContext context) throws Exception {
- destroy(m_context, m_manager);
- cleanup(m_manager);
- m_manager = null;
- m_context = null;
- }
-
- /**
- * Creates a new service.
- *
- * @return the new service
- */
- public Service createService() {
- return new ServiceImpl(m_context, m_manager, m_logger);
- }
-
- /**
- * Creates a new service dependency.
- *
- * @return the service dependency
- */
- public ServiceDependency createServiceDependency() {
- return new ServiceDependency(m_context, m_logger);
- }
-
- /**
- * Creates a new configuration dependency.
- *
- * @return the configuration dependency
- */
- public ConfigurationDependency createConfigurationDependency() {
- return new ConfigurationDependency(m_context, m_logger);
- }
-
- /**
- * Cleans up all services and their dependencies.
- *
- * @param manager the dependency manager
- */
- private void cleanup(DependencyManager manager) {
- List services = manager.getServices();
- for (int i = services.size() - 1; i >= 0; i--) {
- Service service = (Service) services.get(i);
- manager.remove(service);
- // remove any state listeners that are still registered
- if (service instanceof ServiceImpl) {
- ServiceImpl si = (ServiceImpl) service;
- si.removeStateListeners();
- }
- }
- }
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
deleted file mode 100644
index 5c99c7b..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/DependencyManager.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.osgi.framework.BundleContext;
-
-/**
- * The dependency manager. Manages all services and their dependencies.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class DependencyManager {
- private final BundleContext m_context;
- private final Logger m_logger;
- private List m_services = Collections.synchronizedList(new ArrayList());
-
- /**
- * Creates a new dependency manager.
- *
- * @param context the bundle context
- * @param logger
- */
- public DependencyManager(BundleContext context, Logger logger) {
- m_context = context;
- m_logger = logger;
- }
-
- /**
- * Adds a new service to the dependency manager. After the service was added
- * it will be started immediately.
- *
- * @param service the service to add
- */
- public void add(Service service) {
- m_services.add(service);
- service.start();
- }
-
- /**
- * Removes a service from the dependency manager. Before the service is removed
- * it is stopped first.
- *
- * @param service the service to remove
- */
- public void remove(Service service) {
- service.stop();
- m_services.remove(service);
- }
-
- /**
- * Creates a new service.
- *
- * @return the new service
- */
- public Service createService() {
- return new ServiceImpl(m_context, this, m_logger);
- }
-
- /**
- * Creates a new service dependency.
- *
- * @return the service dependency
- */
- public ServiceDependency createServiceDependency() {
- return new ServiceDependency(m_context, m_logger);
- }
-
- public ConfigurationDependency createConfigurationDependency() {
- return new ConfigurationDependency(m_context, m_logger);
- }
-
- /**
- * Returns a list of services.
- *
- * @return a list of services
- */
- public List getServices() {
- return Collections.unmodifiableList(m_services);
- }
-
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.java
deleted file mode 100644
index ab85366..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Logger.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-
-/**
- * This class mimics the standard OSGi <tt>LogService</tt> interface. An
- * instance of this class is used by the dependency manager for all logging.
- * By default this class logs messages to standard out. The log level can be set to
- * control the amount of logging performed, where a higher number results in
- * more logging. A log level of zero turns off logging completely.
- *
- * The log levels match those specified in the OSGi Log Service.
- * This class also tracks log services and will use the highest ranking
- * log service, if present, as a back end instead of printing to standard
- * out. The class uses reflection to invoking the log service's method to
- * avoid a dependency on the log interface. This class is in many ways similar
- * to the one used in the system bundle for that same purpose.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class Logger implements ServiceListener {
- public static final int LOG_ERROR = 1;
- public static final int LOG_WARNING = 2;
- public static final int LOG_INFO = 3;
- public static final int LOG_DEBUG = 4;
-
- private final BundleContext m_context;
-
- private final static int LOGGER_OBJECT_IDX = 0;
- private final static int LOGGER_METHOD_IDX = 1;
- private ServiceReference m_logRef = null;
- private Object[] m_logger = null;
-
- public Logger(BundleContext context) {
- m_context = context;
- startListeningForLogService();
- }
-
- public final void log(int level, String msg) {
- _log(null, level, msg, null);
- }
-
- public final void log(int level, String msg, Throwable throwable) {
- _log(null, level, msg, throwable);
- }
-
- public final void log(ServiceReference sr, int level, String msg) {
- _log(sr, level, msg, null);
- }
-
- public final void log(ServiceReference sr, int level, String msg, Throwable throwable) {
- _log(sr, level, msg, throwable);
- }
-
- protected void doLog(ServiceReference sr, int level, String msg, Throwable throwable) {
- String s = (sr == null) ? null : "SvcRef " + sr;
- s = (s == null) ? msg : s + " " + msg;
- s = (throwable == null) ? s : s + " (" + throwable + ")";
- switch (level) {
- case LOG_DEBUG:
- System.out.println("DEBUG: " + s);
- break;
- case LOG_ERROR:
- System.out.println("ERROR: " + s);
- if (throwable != null) {
- if ((throwable instanceof BundleException) && (((BundleException) throwable).getNestedException() != null)) {
- throwable = ((BundleException) throwable).getNestedException();
- }
- throwable.printStackTrace();
- }
- break;
- case LOG_INFO:
- System.out.println("INFO: " + s);
- break;
- case LOG_WARNING:
- System.out.println("WARNING: " + s);
- break;
- default:
- System.out.println("UNKNOWN[" + level + "]: " + s);
- }
- }
-
- private void _log(ServiceReference sr, int level, String msg, Throwable throwable) {
- // Save our own copy just in case it changes. We could try to do
- // more conservative locking here, but let's be optimistic.
- Object[] logger = m_logger;
- // Use the log service if available.
- if (logger != null) {
- _logReflectively(logger, sr, level, msg, throwable);
- }
- // Otherwise, default logging action.
- else {
- doLog(sr, level, msg, throwable);
- }
- }
-
- private void _logReflectively(Object[] logger, ServiceReference sr, int level, String msg, Throwable throwable) {
- if (logger != null) {
- Object[] params = { sr, new Integer(level), msg, throwable };
- try {
- ((Method) logger[LOGGER_METHOD_IDX]).invoke(logger[LOGGER_OBJECT_IDX], params);
- }
- catch (InvocationTargetException ex) {
- System.err.println("Logger: " + ex);
- }
- catch (IllegalAccessException ex) {
- System.err.println("Logger: " + ex);
- }
- }
- }
-
- /**
- * This method is called when the bundle context is set;
- * it simply adds a service listener so that the bundle can track
- * log services to be used as the back end of the logging mechanism. It also
- * attempts to get an existing log service, if present, but in general
- * there will never be a log service present since the system bundle is
- * started before every other bundle.
- */
- private synchronized void startListeningForLogService() {
- // Add a service listener for log services.
- try {
- m_context.addServiceListener(this, "(objectClass=org.osgi.service.log.LogService)");
- }
- catch (InvalidSyntaxException ex) {
- // This will never happen since the filter is hard coded.
- }
- // Try to get an existing log service.
- m_logRef = m_context.getServiceReference("org.osgi.service.log.LogService");
- // Get the service object if available and set it in the logger.
- if (m_logRef != null) {
- setLogger(m_context.getService(m_logRef));
- }
- }
-
- /**
- * This method implements the callback for the ServiceListener interface.
- * It is public as a byproduct of implementing the interface and should
- * not be called directly. This method tracks run-time changes to log
- * service availability. If the log service being used by the framework's
- * logging mechanism goes away, then this will try to find an alternative.
- * If a higher ranking log service is registered, then this will switch
- * to the higher ranking log service.
- */
- public final synchronized void serviceChanged(ServiceEvent event) {
- // If no logger is in use, then grab this one.
- if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef == null)) {
- m_logRef = event.getServiceReference();
- // Get the service object and set it in the logger.
- setLogger(m_context.getService(m_logRef));
- }
- // If a logger is in use, but this one has a higher ranking, then swap
- // it for the existing logger.
- else if ((event.getType() == ServiceEvent.REGISTERED) && (m_logRef != null)) {
- ServiceReference ref = m_context.getServiceReference("org.osgi.service.log.LogService");
- if (!ref.equals(m_logRef)) {
- m_context.ungetService(m_logRef);
- m_logRef = ref;
- setLogger(m_context.getService(m_logRef));
- }
- }
- // If the current logger is going away, release it and try to
- // find another one.
- else if ((event.getType() == ServiceEvent.UNREGISTERING) && m_logRef.equals(event.getServiceReference())) {
- // Unget the service object.
- m_context.ungetService(m_logRef);
- // Try to get an existing log service.
- m_logRef = m_context.getServiceReference("org.osgi.service.log.LogService");
- // Get the service object if available and set it in the logger.
- if (m_logRef != null) {
- setLogger(m_context.getService(m_logRef));
- }
- else {
- setLogger(null);
- }
- }
- }
-
- /**
- * This method sets the new log service object. It also caches the method to
- * invoke. The service object and method are stored in array to optimistically
- * eliminate the need to locking when logging.
- */
- private void setLogger(Object logObj) {
- if (logObj == null) {
- m_logger = null;
- }
- else {
- Class[] formalParams = { ServiceReference.class, Integer.TYPE, String.class, Throwable.class };
- try {
- Method logMethod = logObj.getClass().getMethod("log", formalParams);
- logMethod.setAccessible(true);
- m_logger = new Object[] { logObj, logMethod };
- }
- catch (NoSuchMethodException ex) {
- System.err.println("Logger: " + ex);
- m_logger = null;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/SerialExecutor.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/SerialExecutor.java
deleted file mode 100644
index 72063c3..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/SerialExecutor.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.util.LinkedList;
-import java.util.NoSuchElementException;
-
-/**
- * Allows you to enqueue tasks from multiple threads and then execute
- * them on one thread sequentially. It assumes more than one thread will
- * try to execute the tasks and it will make an effort to pick the first
- * task that comes along whilst making sure subsequent tasks return
- * without waiting.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public final class SerialExecutor {
- private final LinkedList m_workQueue = new LinkedList();
- private Runnable m_active;
-
- /**
- * Enqueue a new task for later execution. This method is
- * thread-safe, so multiple threads can contribute tasks.
- *
- * @param runnable the runnable containing the actual task
- */
- public synchronized void enqueue(final Runnable runnable) {
- m_workQueue.addLast(new Runnable() {
- public void run() {
- try {
- runnable.run();
- }
- finally {
- scheduleNext();
- }
- }
- });
- }
-
- /**
- * Execute any pending tasks. This method is thread safe,
- * so multiple threads can try to execute the pending
- * tasks, but only the first will be used to actually do
- * so. Other threads will return immediately.
- */
- public void execute() {
- Runnable active;
- synchronized (this) {
- active = m_active;
- }
- if (active == null) {
- scheduleNext();
- }
- }
-
- private void scheduleNext() {
- Runnable active;
- synchronized (this) {
- try {
- m_active = (Runnable) m_workQueue.removeFirst();
- }
- catch (NoSuchElementException e) {
- m_active = null;
- }
- active = m_active;
- }
- if (active != null) {
- active.run();
- }
- }
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java
deleted file mode 100644
index dddc800..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/Service.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.util.Dictionary;
-import java.util.List;
-
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Service interface.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface Service {
- /**
- * Adds a new dependency to this service.
- *
- * @param dependency the dependency to add
- * @return this service
- */
- public Service add(Dependency dependency);
-
- /**
- * Removes a dependency from this service.
- *
- * @param dependency the dependency to remove
- * @return this service
- */
- public Service remove(Dependency dependency);
-
- /**
- * Sets the public interface under which this service should be registered
- * in the OSGi service registry.
- *
- * @param serviceName the name of the service interface
- * @param properties the properties for this service
- * @return this service
- */
- public Service setInterface(String serviceName, Dictionary properties);
-
- /**
- * Sets the public interfaces under which this service should be registered
- * in the OSGi service registry.
- *
- * @param serviceNames the names of the service interface
- * @param properties the properties for this service
- * @return this service
- */
- public Service setInterface(String[] serviceNames, Dictionary properties);
-
- /**
- * Sets the implementation for this service. You can actually specify
- * an instance you have instantiated manually, or a <code>Class</code>
- * that will be instantiated using its default constructor when the
- * required dependencies are resolved (effectively giving you a lazy
- * instantiation mechanism).
- *
- * There are four special methods that are called when found through
- * reflection to give you some life-cycle management options:
- * <ol>
- * <li><code>init()</code> is invoked right after the instance has been
- * created, and before any dependencies are resolved, and can be used to
- * initialize the internal state of the instance</li>
- * <li><code>start()</code> is invoked after the required dependencies
- * are resolved and injected, and before the service is registered</li>
- * <li><code>stop()</code> is invoked right after the service is
- * unregistered</li>
- * <li><code>destroy()</code> is invoked after all dependencies are
- * removed</li>
- * </ol>
- * In short, this allows you to initialize your instance before it is
- * registered, perform some post-initialization and pre-destruction code
- * as well as final cleanup. If a method is not defined, it simply is not
- * called, so you can decide which one(s) you need. If you need even more
- * fine-grained control, you can register as a service state listener too.
- *
- * @param implementation the implementation
- * @return this service
- * @see ServiceStateListener
- */
- public Service setImplementation(Object implementation);
-
- /**
- * Returns a list of dependencies.
- *
- * @return a list of dependencies
- */
- public List getDependencies();
-
- /**
- * Returns the service registration for this service. The method
- * will return <code>null</code> if no service registration is
- * available.
- *
- * @return the service registration
- */
- public ServiceRegistration getServiceRegistration();
-
- /**
- * Returns the service instance for this service. The method will
- * return <code>null</code> if no service instance is available.
- *
- * @return the service instance
- */
- public Object getService();
-
- /**
- * Returns the service properties associated with the service.
- *
- * @return the properties or <code>null</code> if there are none
- */
- public Dictionary getServiceProperties();
-
- /**
- * Sets the service properties associated with the service. If the service
- * was already registered, it will be updated.
- *
- * @param serviceProperties the properties
- */
- public void setServiceProperties(Dictionary serviceProperties);
-
- /**
- * Sets the names of the methods used as callbacks. These methods, when found, are
- * invoked as part of the life-cycle management of the service implementation. The
- * methods should not have any parameters.
- *
- * @param init the name of the init method
- * @param start the name of the start method
- * @param stop the name of the stop method
- * @param destroy the name of the destroy method
- * @return the service instance
- */
- public Service setCallbacks(String init, String start, String stop, String destroy);
-
- // listener
- /**
- * Adds a service state listener to this service.
- *
- * @param listener the state listener
- */
- public void addStateListener(ServiceStateListener listener);
-
- /**
- * Removes a service state listener from this service.
- *
- * @param listener the state listener
- */
- public void removeStateListener(ServiceStateListener listener);
-
- // events, must be fired when the dependency is started/active
-
- /**
- * Will be called when the dependency becomes available.
- *
- * @param dependency the dependency
- */
- public void dependencyAvailable(Dependency dependency);
-
- /**
- * Will be called when the dependency changes.
- *
- * @param dependency the dependency
- */
- public void dependencyUnavailable(Dependency dependency);
-
- /**
- * Will be called when the dependency becomes unavailable.
- *
- * @param dependency the dependency
- */
- public void dependencyChanged(Dependency dependency);
-
- /**
- * Starts the service. This activates the dependency tracking mechanism
- * for this service.
- */
- public void start();
-
- /**
- * Stops the service. This deactivates the dependency tracking mechanism
- * for this service.
- */
- public void stop();
-
- /**
- * Sets the factory to use to create the implementation. You can specify
- * both the factory class and method to invoke. The method should return
- * the implementation, and can use any method to create it. Actually, this
- * can be used together with <code>setComposition</code> to create a
- * composition of instances that work together to implement a service. The
- * factory itself can also be instantiated lazily by not specifying an
- * instance, but a <code>Class</code>.
- *
- * @param factory the factory instance or class
- * @param createMethod the name of the create method
- */
- public Service setFactory(Object factory, String createMethod);
-
- /**
- * Sets the factory to use to create the implementation. You specify the
- * method to invoke. The method should return the implementation, and can
- * use any method to create it. Actually, this can be used together with
- * <code>setComposition</code> to create a composition of instances that
- * work together to implement a service.
- * <p>
- * Note that currently, there is no default for the factory, so please use
- * <code>setFactory(factory, createMethod)</code> instead.
- *
- * @param createMethod the name of the create method
- */
- public Service setFactory(String createMethod);
-
- /**
- * Sets the instance and method to invoke to get back all instances that
- * are part of a composition and need dependencies injected. All of them
- * will be searched for any of the dependencies. The method that is
- * invoked must return an <code>Object[]</code>.
- *
- * @param instance the instance that has the method
- * @param getMethod the method to invoke
- */
- public Service setComposition(Object instance, String getMethod);
-
- /**
- * Sets the method to invoke on the service implementation to get back all
- * instances that are part of a composition and need dependencies injected.
- * All of them will be searched for any of the dependencies. The method that
- * is invoked must return an <code>Object[]</code>.
- *
- * @param getMethod the method to invoke
- */
- public Service setComposition(String getMethod);
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
deleted file mode 100644
index 2d70ea7..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponent.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.dependencymanager;
-
-/**
- * Describes a service component. Service components form descriptions of services
- * that are managed by the dependency manager. They can be used to query their state
- * for monitoring tools. The dependency manager shell command is an example of
- * such a tool.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface ServiceComponent {
- /** Names for the states of this component. */
- public static final String[] STATE_NAMES = { "unregistered", "registered" };
- /** State constant for an unregistered component. */
- public static final int STATE_UNREGISTERED = 0;
- /** State constant for a registered component. */
- public static final int STATE_REGISTERED = 1;
- /** Returns a list of dependencies associated with this service component. */
- public ServiceComponentDependency[] getComponentDependencies();
- /** Returns the name of this service component. */
- public String getName();
- /** Returns the state of this service component. */
- public int getState();
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
deleted file mode 100644
index 53c13ac..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceComponentDependency.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.dependencymanager;
-
-/**
- * Describes a service component dependency. They form descriptions of dependencies
- * that are managed by the dependency manager. They can be used to query their state
- * for monitoring tools. The dependency manager shell command is an example of
- * such a tool.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface ServiceComponentDependency {
- /** Names for the states of this dependency. */
- public static final String[] STATE_NAMES = {
- "optional unavailable",
- "optional available",
- "required unavailable",
- "required available"
- };
- /** State constant for an unavailable, optional dependency. */
- public static final int STATE_UNAVAILABLE_OPTIONAL = 0;
- /** State constant for an available, optional dependency. */
- public static final int STATE_AVAILABLE_OPTIONAL = 1;
- /** State constant for an unavailable, required dependency. */
- public static final int STATE_UNAVAILABLE_REQUIRED = 2;
- /** State constant for an available, required dependency. */
- public static final int STATE_AVAILABLE_REQUIRED = 3;
- /** Returns the name of this dependency. */
- public String getName();
- /** Returns the name of the type of this dependency. */
- public String getType();
- /** Returns the state of this dependency. */
- public int getState();
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
deleted file mode 100644
index 195fa12..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceDependency.java
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Proxy;
-import java.util.AbstractMap;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Service dependency that can track an OSGi service.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceDependency implements Dependency, ServiceTrackerCustomizer, ServiceComponentDependency {
- private boolean m_isRequired;
- private Service m_service;
- private volatile ServiceTracker m_tracker;
- private BundleContext m_context;
- private boolean m_isAvailable;
- private volatile Class m_trackedServiceName;
- private Object m_nullObject;
- private volatile String m_trackedServiceFilter;
- private volatile String m_trackedServiceFilterUnmodified;
- private volatile ServiceReference m_trackedServiceReference;
- private volatile boolean m_isStarted;
- private Object m_callbackInstance;
- private String m_callbackAdded;
- private String m_callbackChanged;
- private String m_callbackRemoved;
- private boolean m_autoConfig;
- private ServiceReference m_reference;
- private Object m_serviceInstance;
- private final Logger m_logger;
- private String m_autoConfigInstance;
- private boolean m_autoConfigInvoked;
- private Object m_defaultImplementation;
- private Object m_defaultImplementationInstance;
-
- private static final Comparator COMPARATOR = new Comparator() {
- public int getRank(ServiceReference ref) {
- Object ranking = ref.getProperty(Constants.SERVICE_RANKING);
- if (ranking != null && (ranking instanceof Integer)) {
- return ((Integer) ranking).intValue();
- }
- return 0;
- }
-
- public int compare(Object a, Object b) {
- ServiceReference ra = (ServiceReference) a, rb = (ServiceReference) b;
- int ranka = getRank(ra);
- int rankb = getRank(rb);
- if (ranka < rankb) {
- return -1;
- }
- else if (ranka > rankb) {
- return 1;
- }
- return 0;
- }
- };
-
- /**
- * Entry to wrap service properties behind a Map.
- */
- private final static class ServicePropertiesMapEntry implements Map.Entry {
- private final String m_key;
- private Object m_value;
-
- public ServicePropertiesMapEntry(String key, Object value) {
- m_key = key;
- m_value = value;
- }
-
- public Object getKey() {
- return m_key;
- }
-
- public Object getValue() {
- return m_value;
- }
-
- public String toString() {
- return m_key + "=" + m_value;
- }
-
- public Object setValue(Object value) {
- Object oldValue = m_value;
- m_value = value;
- return oldValue;
- }
-
- public boolean equals(Object o) {
- if (!(o instanceof Map.Entry)) {
- return false;
- }
- Map.Entry e = (Map.Entry) o;
- return eq(m_key, e.getKey()) && eq(m_value, e.getValue());
- }
-
- public int hashCode() {
- return ((m_key == null) ? 0 : m_key.hashCode()) ^ ((m_value == null) ? 0 : m_value.hashCode());
- }
-
- private static final boolean eq(Object o1, Object o2) {
- return (o1 == null ? o2 == null : o1.equals(o2));
- }
- }
-
- /**
- * Wraps service properties behind a Map.
- */
- private final static class ServicePropertiesMap extends AbstractMap {
- private final ServiceReference m_ref;
-
- public ServicePropertiesMap(ServiceReference ref) {
- m_ref = ref;
- }
-
- public Object get(Object key) {
- return m_ref.getProperty(key.toString());
- }
-
- public int size() {
- return m_ref.getPropertyKeys().length;
- }
-
- public Set entrySet() {
- Set set = new HashSet();
- String[] keys = m_ref.getPropertyKeys();
- for (int i = 0; i < keys.length; i++) {
- set.add(new ServicePropertiesMapEntry(keys[i], m_ref.getProperty(keys[i])));
- }
- return set;
- }
- }
-
- /**
- * Creates a new service dependency.
- *
- * @param context the bundle context
- * @param logger the logger
- */
- public ServiceDependency(BundleContext context, Logger logger) {
- m_context = context;
- m_logger = logger;
- m_autoConfig = true;
- }
-
- public synchronized boolean isRequired() {
- return m_isRequired;
- }
-
- public synchronized boolean isAvailable() {
- return m_isAvailable;
- }
-
- public synchronized boolean isAutoConfig() {
- return m_autoConfig;
- }
-
- public synchronized Object getService() {
- Object service = null;
- if (m_isStarted) {
- service = m_tracker.getService();
- }
- if (service == null) {
- service = getDefaultImplementation();
- if (service == null) {
- service = getNullObject();
- }
- }
- return service;
- }
-
- public Object lookupService() {
- Object service = null;
- if (m_isStarted) {
- service = m_tracker.getService();
- }
- else {
- ServiceReference[] refs = null;
- ServiceReference ref = null;
- if (m_trackedServiceName != null) {
- if (m_trackedServiceFilter != null) {
- try {
- refs = m_context.getServiceReferences(m_trackedServiceName.getName(), m_trackedServiceFilter);
- if (refs != null) {
- Arrays.sort(refs, COMPARATOR);
- ref = refs[0];
- }
- }
- catch (InvalidSyntaxException e) {
- throw new IllegalStateException("Invalid filter definition for dependency.");
- }
- }
- else if (m_trackedServiceReference != null) {
- ref = m_trackedServiceReference;
- }
- else {
- ref = m_context.getServiceReference(m_trackedServiceName.getName());
- }
- if (ref != null) {
- service = m_context.getService(ref);
- }
- }
- else {
- throw new IllegalStateException("Could not lookup dependency, no service name specified.");
- }
- }
- if (service == null) {
- service = getDefaultImplementation();
- if (service == null) {
- service = getNullObject();
- }
- }
- return service;
- }
-
- private Object getNullObject() {
- if (m_nullObject == null) {
- Class trackedServiceName;
- synchronized (this) {
- trackedServiceName = m_trackedServiceName;
- }
- try {
- m_nullObject = Proxy.newProxyInstance(trackedServiceName.getClassLoader(), new Class[] {trackedServiceName}, new DefaultNullObject());
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Could not create null object for " + trackedServiceName + ".", e);
- }
- }
- return m_nullObject;
- }
-
- private Object getDefaultImplementation() {
- if (m_defaultImplementation != null) {
- if (m_defaultImplementation instanceof Class) {
- try {
- m_defaultImplementationInstance = ((Class) m_defaultImplementation).newInstance();
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Could not create default implementation instance of class " + m_defaultImplementation + ".", e);
- }
- }
- else {
- m_defaultImplementationInstance = m_defaultImplementation;
- }
- }
- return m_defaultImplementationInstance;
- }
-
- public synchronized Class getInterface() {
- return m_trackedServiceName;
- }
-
- public void start(Service service) {
- synchronized (this) {
- if (m_isStarted) {
- throw new IllegalStateException("Service dependency was already started." + m_trackedServiceName);
- }
- m_service = service;
- if (m_trackedServiceName != null) {
- if (m_trackedServiceFilter != null) {
- try {
- m_tracker = new ServiceTracker(m_context, m_context.createFilter(m_trackedServiceFilter), this);
- }
- catch (InvalidSyntaxException e) {
- throw new IllegalStateException("Invalid filter definition for dependency.");
- }
- }
- else if (m_trackedServiceReference != null) {
- m_tracker = new ServiceTracker(m_context, m_trackedServiceReference, this);
- }
- else {
- m_tracker = new ServiceTracker(m_context, m_trackedServiceName.getName(), this);
- }
- }
- else {
- throw new IllegalStateException("Could not create tracker for dependency, no service name specified.");
- }
- m_isStarted = true;
- }
- m_tracker.open();
- }
-
- public void stop(Service service) {
- synchronized (this) {
- if (!m_isStarted) {
- throw new IllegalStateException("Service dependency was not started.");
- }
- m_isStarted = false;
- }
- m_tracker.close();
- m_tracker = null;
- }
-
- public Object addingService(ServiceReference ref) {
- Object service = m_context.getService(ref);
- // first check to make sure the service is actually an instance of our service
- if (!m_trackedServiceName.isInstance(service)) {
- return null;
- }
-
- // we remember these for future reference, needed for required service callbacks
- m_reference = ref;
- m_serviceInstance = service;
- return service;
- }
-
- public void addedService(ServiceReference ref, Object service) {
- if (makeAvailable()) {
- m_service.dependencyAvailable(this);
- // try to invoke callback, if specified, but only for optional dependencies
- // because callbacks for required dependencies are handled differently
- if (!isRequired()) {
- invokeAdded(ref, service);
- }
- }
- else {
- m_service.dependencyChanged(this);
- invokeAdded(ref, service);
- }
- }
-
- public void invokeAdded() {
- invokeAdded(m_reference, m_serviceInstance);
- }
-
- public void invokeAdded(ServiceReference reference, Object serviceInstance) {
- Object[] callbackInstances = getCallbackInstances();
- if ((callbackInstances != null) && (m_callbackAdded != null)) {
- invokeCallbackMethod(callbackInstances, m_callbackAdded, reference, serviceInstance);
- }
- }
-
- public void modifiedService(ServiceReference ref, Object service) {
- m_reference = ref;
- m_serviceInstance = service;
- m_service.dependencyChanged(this);
- // only invoke the changed callback if the service itself is "active"
- if (((ServiceImpl) m_service).isRegistered()) {
- invokeChanged(ref, service);
- }
- }
-
- public void invokeChanged(ServiceReference reference, Object serviceInstance) {
- Object[] callbackInstances = getCallbackInstances();
- if ((callbackInstances != null) && (m_callbackChanged != null)) {
- invokeCallbackMethod(callbackInstances, m_callbackChanged, reference, serviceInstance);
- }
- }
-
- public void removedService(ServiceReference ref, Object service) {
- if (makeUnavailable()) {
- m_service.dependencyUnavailable(this);
- // try to invoke callback, if specified, but only for optional dependencies
- // because callbacks for required dependencies are handled differently
- if (!isRequired()) {
- invokeRemoved(ref, service);
- }
- }
- else {
- m_service.dependencyChanged(this);
- invokeRemoved(ref, service);
- }
-
- // unget what we got in addingService (see ServiceTracker 701.4.1)
- m_context.ungetService(ref);
- }
-
- public void invokeRemoved() {
- invokeRemoved(m_reference, m_serviceInstance);
- }
-
- public void invokeRemoved(ServiceReference reference, Object serviceInstance) {
- Object[] callbackInstances = getCallbackInstances();
- if ((callbackInstances != null) && (m_callbackRemoved != null)) {
- invokeCallbackMethod(callbackInstances, m_callbackRemoved, reference, serviceInstance);
- }
- }
-
- private synchronized boolean makeAvailable() {
- if (!m_isAvailable) {
- m_isAvailable = true;
- return true;
- }
- return false;
- }
-
- private synchronized boolean makeUnavailable() {
- if ((m_isAvailable) && (m_tracker.getServiceReference() == null)) {
- m_isAvailable = false;
- return true;
- }
- return false;
- }
-
- private synchronized Object[] getCallbackInstances() {
- return m_callbackInstance != null ? new Object[] { m_callbackInstance } : ((ServiceImpl) m_service).getCompositionInstances();
- }
-
- private void invokeCallbackMethod(Object[] instances, String methodName, ServiceReference reference, Object service) {
- for (int i = 0; i < instances.length; i++) {
- try {
- invokeCallbackMethod(instances[i], methodName, reference, service);
- }
- catch (NoSuchMethodException e) {
- m_logger.log(Logger.LOG_DEBUG, "Method '" + methodName + "' does not exist on " + instances[i] + ". Callback skipped.");
- }
- }
- }
-
- private void invokeCallbackMethod(Object instance, String methodName, ServiceReference reference, Object service) throws NoSuchMethodException {
- Class currentClazz = instance.getClass();
- boolean done = false;
- while (!done && currentClazz != null) {
- Class trackedServiceName;
- synchronized (this) {
- trackedServiceName = m_trackedServiceName;
- }
- done = invokeMethod(instance, currentClazz, methodName,
- new Class[][] {{ServiceReference.class, trackedServiceName}, {ServiceReference.class, Object.class}, {ServiceReference.class}, {trackedServiceName}, {Object.class}, {}, {Map.class, trackedServiceName}},
- new Object[][] {{reference, service}, {reference, service}, {reference}, {service}, {service}, {}, {new ServicePropertiesMap(reference), service}},
- false);
- if (!done) {
- currentClazz = currentClazz.getSuperclass();
- }
- }
- if (!done && currentClazz == null) {
- throw new NoSuchMethodException(methodName);
- }
- }
-
- private boolean invokeMethod(Object object, Class clazz, String name, Class[][] signatures, Object[][] parameters, boolean isSuper) {
- Method m = null;
- for (int i = 0; i < signatures.length; i++) {
- Class[] signature = signatures[i];
- try {
- m = clazz.getDeclaredMethod(name, signature);
- if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) {
- m.setAccessible(true);
- try {
- m.invoke(object, parameters[i]);
- }
- catch (InvocationTargetException e) {
- m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + m + ".", e);
- }
- // we did find and invoke the method, so we return true
- return true;
- }
- }
- catch (NoSuchMethodException e) {
- // ignore this and keep looking
- }
- catch (Exception e) {
- // could not even try to invoke the method
- m_logger.log(Logger.LOG_ERROR, "Exception while trying to invoke method " + m + ".", e);
- }
- }
- return false;
- }
-
- // ----- CREATION
-
- /**
- * Sets the name of the service that should be tracked.
- *
- * @param serviceName the name of the service
- * @return this service dependency
- */
- public synchronized ServiceDependency setService(Class serviceName) {
- ensureNotActive();
- if (serviceName == null) {
- throw new IllegalArgumentException("Service name cannot be null.");
- }
- m_trackedServiceName = serviceName;
- m_trackedServiceReference = null;
- m_trackedServiceFilter = null;
- return this;
- }
-
- /**
- * Sets the name of the service that should be tracked. You can either specify
- * only the name, or the name and a filter. In the latter case, the filter is used
- * to track the service and should only return services of the type that was specified
- * in the name. To make sure of this, the filter is actually extended internally to
- * filter on the correct name.
- *
- * @param serviceName the name of the service
- * @param serviceFilter the filter condition
- * @return this service dependency
- */
- public synchronized ServiceDependency setService(Class serviceName, String serviceFilter) {
- ensureNotActive();
- if (serviceName == null) {
- throw new IllegalArgumentException("Service name cannot be null.");
- }
- m_trackedServiceName = serviceName;
- if (serviceFilter != null) {
- m_trackedServiceFilterUnmodified = serviceFilter;
- m_trackedServiceFilter ="(&(" + Constants.OBJECTCLASS + "=" + serviceName.getName() + ")" + serviceFilter + ")";
- }
- else {
- m_trackedServiceFilterUnmodified = null;
- m_trackedServiceFilter = null;
- }
- m_trackedServiceReference = null;
- return this;
- }
-
- /**
- * Sets the name of the service that should be tracked. You can either specify
- * only the name, or the name and a reference. In the latter case, the service reference
- * is used to track the service and should only return services of the type that was
- * specified in the name.
- *
- * @param serviceName the name of the service
- * @param serviceReference the service reference to track
- * @return this service dependency
- */
- public synchronized ServiceDependency setService(Class serviceName, ServiceReference serviceReference) {
- ensureNotActive();
- if (serviceName == null) {
- throw new IllegalArgumentException("Service name cannot be null.");
- }
- m_trackedServiceName = serviceName;
- m_trackedServiceReference = serviceReference;
- m_trackedServiceFilterUnmodified = null;
- m_trackedServiceFilter = null;
- return this;
- }
-
- /**
- * Sets the default implementation for this service dependency. You can use this to supply
- * your own implementation that will be used instead of a Null Object when the dependency is
- * not available. This is also convenient if the service dependency is not an interface
- * (which would cause the Null Object creation to fail) but a class.
- *
- * @param implementation the instance to use or the class to instantiate if you want to lazily
- * instantiate this implementation
- * @return this service dependency
- */
- public synchronized ServiceDependency setDefaultImplementation(Object implementation) {
- ensureNotActive();
- m_defaultImplementation = implementation;
- return this;
- }
-
- /**
- * Sets the required flag which determines if this service is required or not.
- *
- * @param required the required flag
- * @return this service dependency
- */
- public synchronized ServiceDependency setRequired(boolean required) {
- ensureNotActive();
- m_isRequired = required;
- return this;
- }
-
- /**
- * Sets auto configuration for this service. Auto configuration allows the
- * dependency to fill in any attributes in the service implementation that
- * are of the same type as this dependency. Default is on.
- *
- * @param autoConfig the value of auto config
- * @return this service dependency
- */
- public synchronized ServiceDependency setAutoConfig(boolean autoConfig) {
- ensureNotActive();
- m_autoConfig = autoConfig;
- m_autoConfigInvoked = true;
- return this;
- }
-
- /**
- * Sets auto configuration for this service. Auto configuration allows the
- * dependency to fill in the attribute in the service implementation that
- * has the same type and instance name.
- *
- * @param instanceName the name of attribute to auto config
- * @return this service dependency
- */
- public synchronized ServiceDependency setAutoConfig(String instanceName) {
- ensureNotActive();
- m_autoConfig = (instanceName != null);
- m_autoConfigInstance = instanceName;
- m_autoConfigInvoked = true;
- return this;
- }
-
- /**
- * Sets the callbacks for this service. These callbacks can be used as hooks whenever a
- * dependency is added or removed. When you specify callbacks, the auto configuration
- * feature is automatically turned off, because we're assuming you don't need it in this
- * case.
- *
- * @param added the method to call when a service was added
- * @param removed the method to call when a service was removed
- * @return this service dependency
- */
- public synchronized ServiceDependency setCallbacks(String added, String removed) {
- return setCallbacks(null, added, null, removed);
- }
-
- /**
- * Sets the callbacks for this service. These callbacks can be used as hooks whenever a
- * dependency is added, changed or removed. When you specify callbacks, the auto
- * configuration feature is automatically turned off, because we're assuming you don't
- * need it in this case.
- *
- * @param added the method to call when a service was added
- * @param changed the method to call when a service was changed
- * @param removed the method to call when a service was removed
- * @return this service dependency
- */
- public synchronized ServiceDependency setCallbacks(String added, String changed, String removed) {
- return setCallbacks(null, added, changed, removed);
- }
-
- /**
- * Sets the callbacks for this service. These callbacks can be used as hooks whenever a
- * dependency is added or removed. They are called on the instance you provide. When you
- * specify callbacks, the auto configuration feature is automatically turned off, because
- * we're assuming you don't need it in this case.
- *
- * @param instance the instance to call the callbacks on
- * @param added the method to call when a service was added
- * @param removed the method to call when a service was removed
- * @return this service dependency
- */
- public synchronized ServiceDependency setCallbacks(Object instance, String added, String removed) {
- return setCallbacks(instance, added, null, removed);
- }
-
- /**
- * Sets the callbacks for this service. These callbacks can be used as hooks whenever a
- * dependency is added, changed or removed. They are called on the instance you provide. When you
- * specify callbacks, the auto configuration feature is automatically turned off, because
- * we're assuming you don't need it in this case.
- *
- * @param instance the instance to call the callbacks on
- * @param added the method to call when a service was added
- * @param changed the method to call when a service was changed
- * @param removed the method to call when a service was removed
- * @return this service dependency
- */
- public synchronized ServiceDependency setCallbacks(Object instance, String added, String changed, String removed) {
- ensureNotActive();
- // if at least one valid callback is specified, we turn off auto configuration, unless
- // someone already explicitly invoked autoConfig
- if ((added != null || removed != null || changed != null) && ! m_autoConfigInvoked) {
- setAutoConfig(false);
- }
- m_callbackInstance = instance;
- m_callbackAdded = added;
- m_callbackChanged = changed;
- m_callbackRemoved = removed;
- return this;
- }
-
- private void ensureNotActive() {
- if (m_tracker != null) {
- throw new IllegalStateException("Cannot modify state while active.");
- }
- }
-
- public synchronized String toString() {
- return "ServiceDependency[" + m_trackedServiceName + " " + m_trackedServiceFilterUnmodified + "]";
- }
-
- public String getAutoConfigName() {
- return m_autoConfigInstance;
- }
-
- public String getName() {
- StringBuilder sb = new StringBuilder();
- sb.append(m_trackedServiceName.getName());
- if (m_trackedServiceFilterUnmodified != null) {
- sb.append(m_trackedServiceFilterUnmodified);
- }
- return sb.toString();
- }
-
- public int getState() {
- return (isAvailable() ? 1 : 0) + (isRequired() ? 2 : 0);
- }
-
- public String getType() {
- return "service";
- }
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
deleted file mode 100644
index f5f4c90..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceImpl.java
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * Service implementation.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceImpl implements Service, ServiceComponent {
- private static final Class[] VOID = new Class[] {};
- private static final ServiceRegistration NULL_REGISTRATION;
- private static final ServiceStateListener[] SERVICE_STATE_LISTENER_TYPE = new ServiceStateListener[] {};
-
- private final BundleContext m_context;
- private final DependencyManager m_manager;
-
- // configuration (static)
- private String m_callbackInit;
- private String m_callbackStart;
- private String m_callbackStop;
- private String m_callbackDestroy;
- private Object m_serviceName;
- private Object m_implementation;
-
- // configuration (dynamic, but does not affect state)
- private Dictionary m_serviceProperties;
-
- // configuration (dynamic, and affects state)
- private ArrayList m_dependencies = new ArrayList();
-
- // runtime state (calculated from dependencies)
- private State m_state;
-
- // runtime state (changes because of state changes)
- private Object m_serviceInstance;
- private ServiceRegistration m_registration;
-
- // service state listeners
- private final List m_stateListeners = new ArrayList();
-
- // work queue
- private final SerialExecutor m_executor = new SerialExecutor();
-
- // instance factory
- private Object m_instanceFactory;
- private String m_instanceFactoryCreateMethod;
-
- // composition manager
- private Object m_compositionManager;
- private String m_compositionManagerGetMethod;
- private Object m_compositionManagerInstance;
-
- // internal logging
- private final Logger m_logger;
- private ServiceRegistration m_serviceRegistration;
- private Map m_autoConfig = new HashMap();
- private Map m_autoConfigInstance = new HashMap();
-
- public ServiceImpl(BundleContext context, DependencyManager manager, Logger logger) {
- m_logger = logger;
- m_state = new State((List) m_dependencies.clone(), false);
- m_context = context;
- m_manager = manager;
- m_callbackInit = "init";
- m_callbackStart = "start";
- m_callbackStop = "stop";
- m_callbackDestroy = "destroy";
- m_implementation = null;
- m_autoConfig.put(BundleContext.class, Boolean.TRUE);
- m_autoConfig.put(ServiceRegistration.class, Boolean.TRUE);
- m_autoConfig.put(DependencyManager.class, Boolean.TRUE);
- }
-
- private void calculateStateChanges(final State oldState, final State newState) {
- if (oldState.isWaitingForRequired() && newState.isTrackingOptional()) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- activateService(newState);
- }});
- }
- if (oldState.isTrackingOptional() && newState.isWaitingForRequired()) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- deactivateService(oldState);
- }});
- }
- if (oldState.isInactive() && (newState.isTrackingOptional())) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- activateService(newState);
- }});
- }
- if (oldState.isInactive() && (newState.isWaitingForRequired())) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- startTrackingRequired(newState);
- }});
- }
- if ((oldState.isWaitingForRequired()) && newState.isInactive()) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- stopTrackingRequired(oldState);
- }});
- }
- if ((oldState.isTrackingOptional()) && newState.isInactive()) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- deactivateService(oldState);
- stopTrackingRequired(oldState);
- }});
- }
- m_executor.execute();
- }
-
- public Service add(final Dependency dependency) {
- State oldState, newState;
- synchronized (m_dependencies) {
- oldState = m_state;
- m_dependencies.add(dependency);
- }
- if (oldState.isTrackingOptional() || (oldState.isWaitingForRequired() && dependency.isRequired())) {
- dependency.start(this);
- }
- synchronized (m_dependencies) {
- newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
- m_state = newState;
- calculateStateChanges(oldState, newState);
- }
- return this;
- }
-
- public Service remove(Dependency dependency) {
- State oldState, newState;
- synchronized (m_dependencies) {
- oldState = m_state;
- m_dependencies.remove(dependency);
- }
- if (oldState.isTrackingOptional() || (oldState.isWaitingForRequired() && dependency.isRequired())) {
- dependency.stop(this);
- }
- synchronized (m_dependencies) {
- newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
- m_state = newState;
- }
- calculateStateChanges(oldState, newState);
- return this;
- }
-
- public List getDependencies() {
- synchronized (m_dependencies) {
- return (List) m_dependencies.clone();
- }
- }
-
- public ServiceRegistration getServiceRegistration() {
- return m_registration;
- }
-
- public Object getService() {
- return m_serviceInstance;
- }
-
- public void dependencyAvailable(final Dependency dependency) {
- State oldState, newState;
- synchronized (m_dependencies) {
- oldState = m_state;
- newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
- m_state = newState;
- }
- calculateStateChanges(oldState, newState);
- if (newState.isTrackingOptional()) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- updateInstance(dependency);
- }
- });
- m_executor.execute();
- }
- }
-
- public void dependencyChanged(final Dependency dependency) {
- State state;
- synchronized (m_dependencies) {
- state = m_state;
- }
- if (state.isTrackingOptional()) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- updateInstance(dependency);
- }
- });
- m_executor.execute();
- }
- }
-
- public void dependencyUnavailable(final Dependency dependency) {
- State oldState, newState;
- synchronized (m_dependencies) {
- oldState = m_state;
- newState = new State((List) m_dependencies.clone(), !oldState.isInactive());
- m_state = newState;
- }
- calculateStateChanges(oldState, newState);
- if (newState.isTrackingOptional()) {
- m_executor.enqueue(new Runnable() {
- public void run() {
- updateInstance(dependency);
- }
- });
- m_executor.execute();
- }
- }
-
- public synchronized void start() {
- m_serviceRegistration = m_context.registerService(ServiceComponent.class.getName(), this, null);
- State oldState, newState;
- synchronized (m_dependencies) {
- oldState = m_state;
- newState = new State((List) m_dependencies.clone(), true);
- m_state = newState;
- }
- calculateStateChanges(oldState, newState);
- }
-
- public synchronized void stop() {
- State oldState, newState;
- synchronized (m_dependencies) {
- oldState = m_state;
- newState = new State((List) m_dependencies.clone(), false);
- m_state = newState;
- }
- calculateStateChanges(oldState, newState);
- m_serviceRegistration.unregister();
- }
-
- public synchronized Service setInterface(String serviceName, Dictionary properties) {
- ensureNotActive();
- m_serviceName = serviceName;
- m_serviceProperties = properties;
- return this;
- }
-
- public synchronized Service setInterface(String[] serviceName, Dictionary properties) {
- ensureNotActive();
- m_serviceName = serviceName;
- m_serviceProperties = properties;
- return this;
- }
-
- public synchronized Service setCallbacks(String init, String start, String stop, String destroy) {
- ensureNotActive();
- m_callbackInit = init;
- m_callbackStart = start;
- m_callbackStop = stop;
- m_callbackDestroy = destroy;
- return this;
- }
-
- public synchronized Service setImplementation(Object implementation) {
- ensureNotActive();
- m_implementation = implementation;
- return this;
- }
-
- public synchronized Service setFactory(Object factory, String createMethod) {
- ensureNotActive();
- m_instanceFactory = factory;
- m_instanceFactoryCreateMethod = createMethod;
- return this;
- }
-
- public synchronized Service setFactory(String createMethod) {
- return setFactory(null, createMethod);
- }
-
- public synchronized Service setComposition(Object instance, String getMethod) {
- ensureNotActive();
- m_compositionManager = instance;
- m_compositionManagerGetMethod = getMethod;
- return this;
- }
-
- public synchronized Service setComposition(String getMethod) {
- return setComposition(null, getMethod);
- }
-
- public String toString() {
- return "ServiceImpl[" + m_serviceName + " " + m_implementation + "]";
- }
-
- public synchronized Dictionary getServiceProperties() {
- if (m_serviceProperties != null) {
- return (Dictionary) ((Hashtable) m_serviceProperties).clone();
- }
- return null;
- }
-
- public synchronized void setServiceProperties(Dictionary serviceProperties) {
- m_serviceProperties = serviceProperties;
- if (isRegistered() && (m_serviceName != null)) {
- m_registration.setProperties(calculateServiceProperties());
- }
- }
-
- // service state listener methods
- public void addStateListener(ServiceStateListener listener) {
- synchronized (m_stateListeners) {
- m_stateListeners.add(listener);
- }
- // when we register as a listener and the service is already started
- // make sure we invoke the right callbacks so the listener knows
- State state;
- synchronized (m_dependencies) {
- state = m_state;
- }
- if (state.isTrackingOptional()) {
- listener.starting(this);
- listener.started(this);
- }
- }
-
- public void removeStateListener(ServiceStateListener listener) {
- synchronized (m_stateListeners) {
- m_stateListeners.remove(listener);
- }
- }
-
- void removeStateListeners() {
- synchronized (m_stateListeners) {
- m_stateListeners.clear();
- }
- }
-
- private void stateListenersStarting() {
- ServiceStateListener[] list = getListeners();
- for (int i = 0; i < list.length; i++) {
- try {
- list[i].starting(this);
- }
- catch (Throwable t) {
- m_logger.log(Logger.LOG_ERROR, "Error invoking listener starting method.", t);
- }
- }
- }
-
- private void stateListenersStarted() {
- ServiceStateListener[] list = getListeners();
- for (int i = 0; i < list.length; i++) {
- try {
- list[i].started(this);
- }
- catch (Throwable t) {
- m_logger.log(Logger.LOG_ERROR, "Error invoking listener started method.", t);
- }
- }
- }
-
- private void stateListenersStopping() {
- ServiceStateListener[] list = getListeners();
- for (int i = 0; i < list.length; i++) {
- try {
- list[i].stopping(this);
- }
- catch (Throwable t) {
- m_logger.log(Logger.LOG_ERROR, "Error invoking listener stopping method.", t);
- }
- }
- }
-
- private void stateListenersStopped() {
- ServiceStateListener[] list = getListeners();
- for (int i = 0; i < list.length; i++) {
- try {
- list[i].stopped(this);
- }
- catch (Throwable t) {
- m_logger.log(Logger.LOG_ERROR, "Error invoking listener stopped method.", t);
- }
- }
- }
-
- private ServiceStateListener[] getListeners() {
- synchronized (m_stateListeners) {
- return (ServiceStateListener[]) m_stateListeners.toArray(SERVICE_STATE_LISTENER_TYPE);
- }
- }
-
- private void activateService(State state) {
- String init, start;
- synchronized (this) {
- init = m_callbackInit;
- start = m_callbackStart;
- }
- // service activation logic, first we initialize the service instance itself
- // meaning it is created if necessary and the bundle context is set
- initService();
- // then we invoke the init callback so the service can further initialize
- // itself
- invoke(init);
- // now is the time to configure the service, meaning all required
- // dependencies will be set and any callbacks called
- configureService(state);
- // inform the state listeners we're starting
- stateListenersStarting();
- // invoke the start callback, since we're now ready to be used
- invoke(start);
- // start tracking optional services
- startTrackingOptional(state);
- // register the service in the framework's service registry
- registerService();
- // inform the state listeners we've started
- stateListenersStarted();
- }
-
- private void deactivateService(State state) {
- String stop, destroy;
- synchronized (this) {
- stop = m_callbackStop;
- destroy = m_callbackDestroy;
- }
- // service deactivation logic, first inform the state listeners
- // we're stopping
- stateListenersStopping();
- // then, unregister the service from the framework
- unregisterService();
- // stop tracking optional services
- stopTrackingOptional(state);
- // invoke the stop callback
- invoke(stop);
- // inform the state listeners we've stopped
- stateListenersStopped();
- // invoke the destroy callback
- invoke(destroy);
- // destroy the service instance
- destroyService(state);
- }
-
- private void invoke(String name) {
- if (name != null) {
- // invoke method if it exists
- try {
- Class clazz = m_serviceInstance.getClass();
- while (clazz != null) {
- try {
- Method method = clazz.getDeclaredMethod(name, null);
- if (method != null) {
- method.setAccessible(true);
- try {
- method.invoke(m_serviceInstance, null);
- }
- catch (InvocationTargetException e) {
- m_logger.log(Logger.LOG_ERROR, "Exception while invoking method " + method + ".", e);
- }
- return;
- }
- }
- catch (NoSuchMethodException e) {
- // ignore this, we keep searching if the method does not exist
- }
- clazz = clazz.getSuperclass();
- }
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Error trying to invoke method named " + name + ".", e);
- }
- }
- }
-
- private void startTrackingOptional(State state) {
- Iterator i = state.getDependencies().iterator();
- while (i.hasNext()) {
- Dependency dependency = (Dependency) i.next();
- if (!dependency.isRequired()) {
- dependency.start(this);
- }
- }
- }
-
- private void stopTrackingOptional(State state) {
- Iterator i = state.getDependencies().iterator();
- while (i.hasNext()) {
- Dependency dependency = (Dependency) i.next();
- if (!dependency.isRequired()) {
- dependency.stop(this);
- }
- }
- }
-
- private void startTrackingRequired(State state) {
- Iterator i = state.getDependencies().iterator();
- while (i.hasNext()) {
- Dependency dependency = (Dependency) i.next();
- if (dependency.isRequired()) {
- dependency.start(this);
- }
- }
- }
-
- private void stopTrackingRequired(State state) {
- Iterator i = state.getDependencies().iterator();
- while (i.hasNext()) {
- Dependency dependency = (Dependency) i.next();
- if (dependency.isRequired()) {
- dependency.stop(this);
- }
- }
- }
-
- private Object createInstance(Class clazz) throws SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException {
- Constructor constructor = clazz.getConstructor(VOID);
- constructor.setAccessible(true);
- return clazz.newInstance();
- }
-
- void initService() {
- if (m_serviceInstance == null) {
- if (m_implementation instanceof Class) {
- // instantiate
- try {
- m_serviceInstance = createInstance((Class) m_implementation);
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Could not create service instance of class " + m_implementation + ".", e);
- }
- }
- else {
- if (m_instanceFactoryCreateMethod != null) {
- Object factory = null;
- if (m_instanceFactory != null) {
- if (m_instanceFactory instanceof Class) {
- try {
- factory = createInstance((Class) m_instanceFactory);
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Could not create factory instance of class " + m_instanceFactory + ".", e);
- }
- }
- else {
- factory = m_instanceFactory;
- }
- }
- else {
- // TODO review if we want to try to default to something if not specified
- // for now the JavaDoc of setFactory(method) reflects the fact that we need
- // to review it
- }
- if (factory == null) {
- m_logger.log(Logger.LOG_ERROR, "Factory cannot be null.");
- }
- else {
- try {
- Method m = factory.getClass().getDeclaredMethod(m_instanceFactoryCreateMethod, null);
- m_serviceInstance = m.invoke(factory, null);
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Could not create service instance using factory " + factory + " method " + m_instanceFactoryCreateMethod + ".", e);
- }
- }
- }
- if (m_implementation == null) {
- m_logger.log(Logger.LOG_ERROR, "Implementation cannot be null.");
- }
- if (m_serviceInstance == null) {
- m_serviceInstance = m_implementation;
- }
- }
- // configure the bundle context
- if (((Boolean) m_autoConfig.get(BundleContext.class)).booleanValue()) {
- configureImplementation(BundleContext.class, m_context, (String) m_autoConfigInstance.get(BundleContext.class));
- }
- if (((Boolean) m_autoConfig.get(ServiceRegistration.class)).booleanValue()) {
- configureImplementation(ServiceRegistration.class, NULL_REGISTRATION, (String) m_autoConfigInstance.get(ServiceRegistration.class));
- }
- if (((Boolean) m_autoConfig.get(DependencyManager.class)).booleanValue()) {
- configureImplementation(DependencyManager.class, m_manager, (String) m_autoConfigInstance.get(DependencyManager.class));
- }
- }
- }
-
- public void setAutoConfig(Class clazz, boolean autoConfig) {
- m_autoConfig.put(clazz, Boolean.valueOf(autoConfig));
- }
-
- public void setAutoConfig(Class clazz, String instanceName) {
- m_autoConfig.put(clazz, Boolean.valueOf(instanceName != null));
- m_autoConfigInstance.put(clazz, instanceName);
- }
-
- private void configureService(State state) {
- // configure all services (the optional dependencies might be configured
- // as null objects but that's what we want at this point)
- configureServices(state);
- }
-
- private void destroyService(State state) {
- unconfigureServices(state);
- m_serviceInstance = null;
- }
-
- private void registerService() {
- if (m_serviceName != null) {
- ServiceRegistrationImpl wrapper = new ServiceRegistrationImpl();
- m_registration = wrapper;
- if (((Boolean) m_autoConfig.get(ServiceRegistration.class)).booleanValue()) {
- configureImplementation(ServiceRegistration.class, m_registration, (String) m_autoConfigInstance.get(ServiceRegistration.class));
- }
-
- // service name can either be a string or an array of strings
- ServiceRegistration registration;
-
- // determine service properties
- Dictionary properties = calculateServiceProperties();
-
- // register the service
- try {
- if (m_serviceName instanceof String) {
- registration = m_context.registerService((String) m_serviceName, m_serviceInstance, properties);
- }
- else {
- registration = m_context.registerService((String[]) m_serviceName, m_serviceInstance, properties);
- }
- wrapper.setServiceRegistration(registration);
- }
- catch (IllegalArgumentException iae) {
- m_logger.log(Logger.LOG_ERROR, "Could not register service " + m_serviceInstance, iae);
- // set the registration to an illegal state object, which will make all invocations on this
- // wrapper fail with an ISE (which also occurs when the SR becomes invalid)
- wrapper.setIllegalState();
- }
- }
- }
-
- private Dictionary calculateServiceProperties() {
- Dictionary properties = new Properties();
- addTo(properties, m_serviceProperties);
- for (int i = 0; i < m_dependencies.size(); i++) {
- Dependency d = (Dependency) m_dependencies.get(i);
- if (d instanceof ConfigurationDependency) {
- ConfigurationDependency cd = (ConfigurationDependency) d;
- if (cd.isPropagated()) {
- Dictionary dict = cd.getConfiguration();
- addTo(properties, dict);
- }
- }
- }
- if (properties.size() == 0) {
- properties = null;
- }
- return properties;
- }
-
- private void addTo(Dictionary properties, Dictionary additional) {
- if (properties == null) {
- throw new IllegalArgumentException("Dictionary to add to cannot be null.");
- }
- if (additional != null) {
- Enumeration e = additional.keys();
- while (e.hasMoreElements()) {
- Object key = e.nextElement();
- properties.put(key, additional.get(key));
- }
- }
- }
-
- private void unregisterService() {
- if (m_serviceName != null) {
- m_registration.unregister();
- configureImplementation(ServiceRegistration.class, NULL_REGISTRATION);
- }
- }
-
- private void updateInstance(Dependency dependency) {
- if (dependency instanceof ServiceDependency) {
- ServiceDependency sd = (ServiceDependency) dependency;
- // update the dependency in the service instance (it will use
- // a null object if necessary)
- if (sd.isAutoConfig()) {
- configureImplementation(sd.getInterface(), sd.getService(), sd.getAutoConfigName());
- }
- }
- else if (dependency instanceof ConfigurationDependency) {
- ConfigurationDependency cd = (ConfigurationDependency) dependency;
- if (cd.isPropagated()) {
- // change service properties accordingly
- Dictionary props = calculateServiceProperties();
- m_registration.setProperties(props);
- }
- }
- }
-
- /**
- * Configure a field in the service implementation. The service implementation
- * is searched for fields that have the same type as the class that was specified
- * and for each of these fields, the specified instance is filled in.
- *
- * @param clazz the class to search for
- * @param instance the instance to fill in
- * @param instanceName the name of the instance to fill in, or <code>null</code> if not used
- */
- private void configureImplementation(Class clazz, Object instance, String instanceName) {
- Object[] instances = getCompositionInstances();
- if (instances != null) {
- for (int i = 0; i < instances.length; i++) {
- Object serviceInstance = instances[i];
- Class serviceClazz = serviceInstance.getClass();
- while (serviceClazz != null) {
- Field[] fields = serviceClazz.getDeclaredFields();
- for (int j = 0; j < fields.length; j++) {
- if (fields[j].getType().equals(clazz) && (instanceName == null || fields[j].getName().equals(instanceName))) {
- try {
- fields[j].setAccessible(true);
- // synchronized makes sure the field is actually written to immediately
- synchronized (new Object()) {
- fields[j].set(serviceInstance, instance);
- }
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Could not set field " + fields[j], e);
- return;
- }
- }
- }
- serviceClazz = serviceClazz.getSuperclass();
- }
- }
- }
- }
-
- public Object[] getCompositionInstances() {
- Object[] instances = null;
- if (m_compositionManagerGetMethod != null) {
- if (m_compositionManager != null) {
- m_compositionManagerInstance = m_compositionManager;
- }
- else {
- m_compositionManagerInstance = m_serviceInstance;
- }
- if (m_compositionManagerInstance != null) {
- try {
- Method m = m_compositionManagerInstance.getClass().getDeclaredMethod(m_compositionManagerGetMethod, null);
- m.setAccessible(true);
- instances = (Object[]) m.invoke(m_compositionManagerInstance, null);
- }
- catch (Exception e) {
- m_logger.log(Logger.LOG_ERROR, "Could not obtain instances from the composition manager.", e);
- instances = new Object[] { m_serviceInstance };
- }
- }
- }
- else {
- instances = new Object[] { m_serviceInstance };
- }
- return instances;
- }
-
- private void configureImplementation(Class clazz, Object instance) {
- configureImplementation(clazz, instance, null);
- }
-
- private void configureServices(State state) {
- Iterator i = state.getDependencies().iterator();
- while (i.hasNext()) {
- Dependency dependency = (Dependency) i.next();
- if (dependency instanceof ServiceDependency) {
- ServiceDependency sd = (ServiceDependency) dependency;
- if (sd.isAutoConfig()) {
- if (sd.isRequired()) {
- configureImplementation(sd.getInterface(), sd.getService(), sd.getAutoConfigName());
- }
- else {
- // for optional services, we do an "ad-hoc" lookup to inject the service if it is
- // already available even though the tracker has not yet been started
- configureImplementation(sd.getInterface(), sd.lookupService(), sd.getAutoConfigName());
- }
- }
- // for required dependencies, we invoke any callbacks here
- if (sd.isRequired()) {
- sd.invokeAdded();
- }
- }
- }
- }
-
- private void unconfigureServices(State state) {
- Iterator i = state.getDependencies().iterator();
- while (i.hasNext()) {
- Dependency dependency = (Dependency) i.next();
- if (dependency instanceof ServiceDependency) {
- ServiceDependency sd = (ServiceDependency) dependency;
- // for required dependencies, we invoke any callbacks here
- if (sd.isRequired()) {
- sd.invokeRemoved();
- }
- }
- }
- }
-
- private void ensureNotActive() {
- State state;
- synchronized (m_dependencies) {
- state = m_state;
- }
- if (!state.isInactive()) {
- throw new IllegalStateException("Cannot modify state while active.");
- }
- }
- boolean isRegistered() {
- State state;
- synchronized (m_dependencies) {
- state = m_state;
- }
- return (state.isTrackingOptional());
- }
-
- // ServiceComponent interface
-
- static class SCDImpl implements ServiceComponentDependency {
- private final String m_name;
- private final int m_state;
- private final String m_type;
-
- public SCDImpl(String name, int state, String type) {
- m_name = name;
- m_state = state;
- m_type = type;
- }
-
- public String getName() {
- return m_name;
- }
-
- public int getState() {
- return m_state;
- }
-
- public String getType() {
- return m_type;
- }
- }
-
- public ServiceComponentDependency[] getComponentDependencies() {
- List deps = getDependencies();
- if (deps != null) {
- ServiceComponentDependency[] result = new ServiceComponentDependency[deps.size()];
- for (int i = 0; i < result.length; i++) {
- Dependency dep = (Dependency) deps.get(i);
- if (dep instanceof ServiceComponentDependency) {
- result[i] = (ServiceComponentDependency) dep;
- }
- else {
- result[i] = new SCDImpl(dep.toString(), (dep.isAvailable() ? 1 : 0) + (dep.isRequired() ? 2 : 0), dep.getClass().getName());
- }
- }
- return result;
- }
- return null;
- }
-
- public String getName() {
- if (m_serviceName instanceof String[]) {
- StringBuffer sb = new StringBuffer();
- String[] names = (String[]) m_serviceName;
- for (int i = 0; i < names.length; i++) {
- if (i > 0) {
- sb.append(", ");
- }
- sb.append(names[i]);
- }
- return sb.toString();
- }
- else if (m_serviceName instanceof String) {
- return m_serviceName.toString();
- }
- else {
- return m_implementation.toString();
- }
- }
-
- public int getState() {
- return (isRegistered() ? 1 : 0);
- }
-
- static {
- NULL_REGISTRATION = (ServiceRegistration) Proxy.newProxyInstance(ServiceImpl.class.getClassLoader(), new Class[] {ServiceRegistration.class}, new DefaultNullObject());
- }
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java
deleted file mode 100644
index 0ff8473..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceRegistrationImpl.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.util.Dictionary;
-
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/**
- * A wrapper around a service registration that blocks until the
- * service registration is available.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public final class ServiceRegistrationImpl implements ServiceRegistration {
- public static final ServiceRegistrationImpl ILLEGAL_STATE = new ServiceRegistrationImpl();
- private volatile ServiceRegistration m_registration;
-
- public ServiceRegistrationImpl() {
- m_registration = null;
- }
-
- public ServiceReference getReference() {
- return ensureRegistration().getReference();
- }
-
- public void setProperties(Dictionary dictionary) {
- ensureRegistration().setProperties(dictionary);
- }
-
- public void unregister() {
- ensureRegistration().unregister();
- }
-
- public boolean equals(Object obj) {
- return ensureRegistration().equals(obj);
- }
-
- public int hashCode() {
- return ensureRegistration().hashCode();
- }
-
- public String toString() {
- return ensureRegistration().toString();
- }
-
- private synchronized ServiceRegistration ensureRegistration() {
- while (m_registration == null) {
- try {
- wait();
- }
- catch (InterruptedException ie) {
- // we were interrupted so hopefully we will now have a
- // service registration ready; if not we wait again
- }
- }
- // check if we're in an illegal state and throw an exception
- if (ILLEGAL_STATE == m_registration) {
- throw new IllegalStateException("Service is not registered.");
- }
- return m_registration;
- }
-
- /**
- * Sets the service registration and notifies all waiting parties.
- */
- void setServiceRegistration(ServiceRegistration registration) {
- synchronized (this) {
- m_registration = registration;
- notifyAll();
- }
- }
-
- /**
- * Sets this wrapper to an illegal state, which will cause all threads
- * that are waiting for this service registration to fail.
- */
- void setIllegalState() {
- setServiceRegistration(ServiceRegistrationImpl.ILLEGAL_STATE);
- }
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java
deleted file mode 100644
index a655633..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceStateListener.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.dependencymanager;
-
-/**
- * This interface can be used to register a service state listener. Service
- * state listeners are called whenever a service state changes. You get notified
- * when the service is starting, started, stopping and stopped. Each callback
- * includes a reference to the service in question.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface ServiceStateListener {
- /**
- * Called when the service is starting. At this point, the required
- * dependencies have been injected, but the service has not been registered
- * yet.
- *
- * @param service the service
- */
- public void starting(Service service);
-
- /**
- * Called when the service is started. At this point, the service has been
- * registered.
- *
- * @param service the service
- */
- public void started(Service service);
-
- /**
- * Called when the service is stopping. At this point, the service is still
- * registered.
- *
- * @param service the service
- */
- public void stopping(Service service);
-
- /**
- * Called when the service is stopped. At this point, the service has been
- * unregistered.
- *
- * @param service the service
- */
- public void stopped(Service service);
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
deleted file mode 100644
index 83c4b4b..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTracker.java
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.LinkedList;
-
-import org.osgi.framework.AllServiceListener;
-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;
-
-/**
- * A modified <code>ServiceTracker</code> class simplifies using services
- * from the Framework's service registry. This class is used internally
- * by the dependency manager. It is based on the OSGi R4.1 sources, which
- * are made available under the same ASF 2.0 license.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public class ServiceTracker implements ServiceTrackerCustomizer {
- /* set this to true to compile in debug messages */
- static final boolean DEBUG = false;
- /**
- * Bundle context against which this <code>ServiceTracker</code> object is
- * tracking.
- */
- protected final BundleContext context;
- /**
- * Filter specifying search criteria for the services to track.
- *
- * @since 1.1
- */
- protected final Filter filter;
- /**
- * <code>ServiceTrackerCustomizer</code> object for this tracker.
- */
- final ServiceTrackerCustomizer customizer;
- /**
- * Filter string for use when adding the ServiceListener. If this field is
- * set, then certain optimizations can be taken since we don't have a user
- * supplied filter.
- */
- final String listenerFilter;
- /**
- * Class name to be tracked. If this field is set, then we are tracking by
- * class name.
- */
- private final String trackClass;
- /**
- * Reference to be tracked. If this field is set, then we are tracking a
- * single ServiceReference.
- */
- private final ServiceReference trackReference;
- /**
- * Tracked services: <code>ServiceReference</code> object -> customized
- * Object and <code>ServiceListener</code> object
- */
- private volatile Tracked tracked;
- /**
- * Modification count. This field is initialized to zero by open, set to -1
- * by close and incremented by modified.
- *
- * This field is volatile since it is accessed by multiple threads.
- */
- private volatile int trackingCount = -1;
- /**
- * Cached ServiceReference for getServiceReference.
- *
- * This field is volatile since it is accessed by multiple threads.
- */
- private volatile ServiceReference cachedReference;
- /**
- * Cached service object for getService.
- *
- * This field is volatile since it is accessed by multiple threads.
- */
- private volatile Object cachedService;
-
- /**
- * Create a <code>ServiceTracker</code> object on the specified
- * <code>ServiceReference</code> object.
- *
- * <p>
- * The service referenced by the specified <code>ServiceReference</code>
- * object will be tracked by this <code>ServiceTracker</code> object.
- *
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param reference <code>ServiceReference</code> object for the service
- * to be tracked.
- * @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> object will be used as the
- * <code>ServiceTrackerCustomizer</code> object and the
- * <code>ServiceTracker</code> object will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
- */
- public ServiceTracker(BundleContext context, ServiceReference reference,
- ServiceTrackerCustomizer customizer) {
- this.context = context;
- this.trackReference = reference;
- this.trackClass = null;
- this.customizer = (customizer == null) ? this : customizer;
- this.listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- try {
- this.filter = context.createFilter(listenerFilter);
- }
- catch (InvalidSyntaxException e) { // we could only get this exception
- // if the ServiceReference was
- // invalid
- throw new IllegalArgumentException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
- }
- }
-
- /**
- * Create a <code>ServiceTracker</code> object on the specified class
- * name.
- *
- * <p>
- * Services registered under the specified class name will be tracked by
- * this <code>ServiceTracker</code> object.
- *
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param clazz Class name of the services to be tracked.
- * @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is <code>null</code>, then this
- * <code>ServiceTracker</code> object will be used as the
- * <code>ServiceTrackerCustomizer</code> object and the
- * <code>ServiceTracker</code> object will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
- */
- public ServiceTracker(BundleContext context, String clazz,
- ServiceTrackerCustomizer customizer) {
- this.context = context;
- this.trackReference = null;
- this.trackClass = clazz;
- this.customizer = (customizer == null) ? this : customizer;
- this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
- try {
- this.filter = context.createFilter(listenerFilter);
- }
- catch (InvalidSyntaxException e) { // we could only get this exception
- // if the clazz argument was
- // malformed
- throw new IllegalArgumentException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
- }
- }
-
- /**
- * Create a <code>ServiceTracker</code> object on the specified
- * <code>Filter</code> object.
- *
- * <p>
- * Services which match the specified <code>Filter</code> object will be
- * tracked by this <code>ServiceTracker</code> object.
- *
- * @param context <code>BundleContext</code> object against which the
- * tracking is done.
- * @param filter <code>Filter</code> object to select the services to be
- * tracked.
- * @param customizer The customizer object to call when services are added,
- * modified, or removed in this <code>ServiceTracker</code> object.
- * If customizer is null, then this <code>ServiceTracker</code>
- * object will be used as the <code>ServiceTrackerCustomizer</code>
- * object and the <code>ServiceTracker</code> object will call the
- * <code>ServiceTrackerCustomizer</code> methods on itself.
- * @since 1.1
- */
- public ServiceTracker(BundleContext context, Filter filter,
- ServiceTrackerCustomizer customizer) {
- this.context = context;
- this.trackReference = null;
- this.trackClass = null;
- this.listenerFilter = null;
- this.filter = filter;
- this.customizer = (customizer == null) ? this : customizer;
- if ((context == null) || (filter == null)) { // we throw a NPE here
- // to
- // be consistent with the
- // other constructors
- throw new NullPointerException();
- }
- }
-
- /**
- * Open this <code>ServiceTracker</code> object and begin tracking
- * services.
- *
- * <p>
- * This method calls <code>open(false)</code>.
- *
- * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
- * object with which this <code>ServiceTracker</code> object was
- * created is no longer valid.
- * @see #open(boolean)
- */
- public void open() {
- open(false);
- }
-
- /**
- * Open this <code>ServiceTracker</code> object and begin tracking
- * services.
- *
- * <p>
- * Services which match the search criteria specified when this
- * <code>ServiceTracker</code> object was created are now tracked by this
- * <code>ServiceTracker</code> object.
- *
- * @param trackAllServices If <code>true</code>, then this
- * <code>ServiceTracker</code> will track all matching services
- * regardless of class loader accessibility. If <code>false</code>,
- * then this <code>ServiceTracker</code> will only track matching
- * services which are class loader accessibile to the bundle whose
- * <code>BundleContext</code> is used by this
- * <code>ServiceTracker</code>.
- * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
- * object with which this <code>ServiceTracker</code> object was
- * created is no longer valid.
- * @since 1.3
- */
- public synchronized void open(boolean trackAllServices) {
- if (tracked != null) {
- return;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
- }
- tracked = trackAllServices ? new AllTracked() : new Tracked();
- trackingCount = 0;
- synchronized (tracked) {
- try {
- context.addServiceListener(tracked, listenerFilter);
- ServiceReference[] references;
- if (listenerFilter == null) { // user supplied filter
- references = getInitialReferences(trackAllServices, null,
- filter.toString());
- }
- else { // constructor supplied filter
- if (trackClass == null) {
- references = new ServiceReference[] {trackReference};
- }
- else {
- references = getInitialReferences(trackAllServices,
- trackClass, null);
- }
- }
-
- tracked.setInitialServices(references); // set tracked with
- // the initial
- // references
- }
- catch (InvalidSyntaxException e) {
- throw new RuntimeException(
- "unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
- }
- }
- /* Call tracked outside of synchronized region */
- tracked.trackInitialServices(); // process the initial references
- }
-
- /**
- * Returns the list of initial <code>ServiceReference</code> objects that
- * will be tracked by this <code>ServiceTracker</code> object.
- *
- * @param trackAllServices If true, use getAllServiceReferences.
- * @param trackClass the class name with which the service was registered,
- * or null for all services.
- * @param filterString the filter criteria or null for all services.
- * @return the list of initial <code>ServiceReference</code> objects.
- * @throws InvalidSyntaxException if the filter uses an invalid syntax.
- */
- private ServiceReference[] getInitialReferences(boolean trackAllServices,
- String trackClass, String filterString)
- throws InvalidSyntaxException {
- if (trackAllServices) {
- return context.getAllServiceReferences(trackClass, filterString);
- }
- else {
- return context.getServiceReferences(trackClass, filterString);
- }
- }
-
- /**
- * Close this <code>ServiceTracker</code> object.
- *
- * <p>
- * This method should be called when this <code>ServiceTracker</code>
- * object should end the tracking of services.
- */
- public synchronized void close() {
- if (tracked == null) {
- return;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
- }
- tracked.close();
- ServiceReference[] references = getServiceReferences();
- Tracked outgoing = tracked;
- tracked = null;
- try {
- context.removeServiceListener(outgoing);
- }
- catch (IllegalStateException e) {
- /* In case the context was stopped. */
- }
- if (references != null) {
- for (int i = 0; i < references.length; i++) {
- outgoing.untrack(references[i]);
- }
- }
- trackingCount = -1;
- if (DEBUG) {
- if ((cachedReference == null) && (cachedService == null)) {
- System.out
- .println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
- }
- }
- }
-
- /**
- * Default implementation of the
- * <code>ServiceTrackerCustomizer.addingService</code> method.
- *
- * <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
- *
- * The default implementation returns the result of calling
- * <code>getService</code>, on the <code>BundleContext</code> object
- * with which this <code>ServiceTracker</code> object was created, passing
- * the specified <code>ServiceReference</code> object.
- * <p>
- * This method can be overridden in a subclass to customize the service
- * object to be tracked for the service being added. In that case, take care
- * not to rely on the default implementation of removedService that will
- * unget the service.
- *
- * @param reference Reference to service being added to this
- * <code>ServiceTracker</code> object.
- * @return The service object to be tracked for the service added to this
- * <code>ServiceTracker</code> object.
- * @see ServiceTrackerCustomizer
- */
- public Object addingService(ServiceReference reference) {
- return context.getService(reference);
- }
-
- /**
- * Default implementation of the
- * <code>ServiceTrackerCustomizer.modifiedService</code> method.
- *
- * <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
- *
- * The default implementation does nothing.
- *
- * @param reference Reference to modified service.
- * @param service The service object for the modified service.
- * @see ServiceTrackerCustomizer
- */
- public void modifiedService(ServiceReference reference, Object service) {
- }
-
- /**
- * Default implementation of the
- * <code>ServiceTrackerCustomizer.removedService</code> method.
- *
- * <p>
- * This method is only called when this <code>ServiceTracker</code> object
- * has been constructed with a <code>null ServiceTrackerCustomizer</code>
- * argument.
- *
- * The default implementation calls <code>ungetService</code>, on the
- * <code>BundleContext</code> object with which this
- * <code>ServiceTracker</code> object was created, passing the specified
- * <code>ServiceReference</code> object.
- * <p>
- * This method can be overridden in a subclass. If the default
- * implementation of <code>addingService</code> method was used, this
- * method must unget the service.
- *
- * @param reference Reference to removed service.
- * @param service The service object for the removed service.
- * @see ServiceTrackerCustomizer
- */
- public void removedService(ServiceReference reference, Object service) {
- context.ungetService(reference);
- }
-
- /**
- * Wait for at least one service to be tracked by this
- * <code>ServiceTracker</code> object.
- * <p>
- * It is strongly recommended that <code>waitForService</code> is not used
- * during the calling of the <code>BundleActivator</code> methods.
- * <code>BundleActivator</code> methods are expected to complete in a
- * short period of time.
- *
- * @param timeout time interval in milliseconds to wait. If zero, the method
- * will wait indefinately.
- * @return Returns the result of <code>getService()</code>.
- * @throws InterruptedException If another thread has interrupted the
- * current thread.
- * @throws IllegalArgumentException If the value of timeout is negative.
- */
- public Object waitForService(long timeout) throws InterruptedException {
- if (timeout < 0) {
- throw new IllegalArgumentException("timeout value is negative"); //$NON-NLS-1$
- }
- Object object = getService();
- while (object == null) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
- return null;
- }
- synchronized (tracked) {
- if (tracked.size() == 0) {
- tracked.wait(timeout);
- }
- }
- object = getService();
- if (timeout > 0) {
- return object;
- }
- }
- return object;
- }
-
- /**
- * Return an array of <code>ServiceReference</code> objects for all
- * services being tracked by this <code>ServiceTracker</code> object.
- *
- * @return Array of <code>ServiceReference</code> objects or
- * <code>null</code> if no service are being tracked.
- */
- public ServiceReference[] getServiceReferences() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
- return null;
- }
- synchronized (tracked) {
- int length = tracked.size();
- if (length == 0) {
- return null;
- }
- ServiceReference[] references = new ServiceReference[length];
- Enumeration keys = tracked.keys();
- for (int i = 0; i < length; i++) {
- references[i] = (ServiceReference) keys.nextElement();
- }
- return references;
- }
- }
-
- /**
- * Returns a <code>ServiceReference</code> object for one of the services
- * being tracked by this <code>ServiceTracker</code> object.
- *
- * <p>
- * If multiple services are being tracked, the service with the highest
- * ranking (as specified in its <code>service.ranking</code> property) is
- * returned.
- *
- * <p>
- * If there is a tie in ranking, the service with the lowest service ID (as
- * specified in its <code>service.id</code> property); that is, the
- * service that was registered first is returned.
- * <p>
- * This is the same algorithm used by
- * <code>BundleContext.getServiceReference</code>.
- *
- * @return <code>ServiceReference</code> object or <code>null</code> if
- * no service is being tracked.
- * @since 1.1
- */
- public ServiceReference getServiceReference() {
- ServiceReference reference = cachedReference;
- if (reference != null) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
- }
- return reference;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
- }
- ServiceReference[] references = getServiceReferences();
- int length = (references == null) ? 0 : references.length;
- if (length == 0) /* if no service is being tracked */
- {
- return null;
- }
- int index = 0;
- if (length > 1) /* if more than one service, select highest ranking */
- {
- int rankings[] = new int[length];
- int count = 0;
- int maxRanking = Integer.MIN_VALUE;
- for (int i = 0; i < length; i++) {
- Object property = references[i]
- .getProperty(Constants.SERVICE_RANKING);
- int ranking = (property instanceof Integer) ? ((Integer) property)
- .intValue()
- : 0;
- rankings[i] = ranking;
- if (ranking > maxRanking) {
- index = i;
- maxRanking = ranking;
- count = 1;
- }
- else {
- if (ranking == maxRanking) {
- count++;
- }
- }
- }
- if (count > 1) /* if still more than one service, select lowest id */
- {
- long minId = Long.MAX_VALUE;
- for (int i = 0; i < length; i++) {
- if (rankings[i] == maxRanking) {
- long id = ((Long) (references[i]
- .getProperty(Constants.SERVICE_ID)))
- .longValue();
- if (id < minId) {
- index = i;
- minId = id;
- }
- }
- }
- }
- }
- return cachedReference = references[index];
- }
-
- /**
- * Returns the service object for the specified
- * <code>ServiceReference</code> object if the referenced service is being
- * tracked by this <code>ServiceTracker</code> object.
- *
- * @param reference Reference to the desired service.
- * @return Service object or <code>null</code> if the service referenced
- * by the specified <code>ServiceReference</code> object is not
- * being tracked.
- */
- public Object getService(ServiceReference reference) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
- return null;
- }
- synchronized (tracked) {
- return tracked.get(reference);
- }
- }
-
- /**
- * Return an array of service objects for all services being tracked by this
- * <code>ServiceTracker</code> object.
- *
- * @return Array of service objects or <code>null</code> if no service are
- * being tracked.
- */
- public Object[] getServices() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
- return null;
- }
- synchronized (tracked) {
- ServiceReference[] references = getServiceReferences();
- int length = (references == null) ? 0 : references.length;
- if (length == 0) {
- return null;
- }
- Object[] objects = new Object[length];
- for (int i = 0; i < length; i++) {
- objects[i] = getService(references[i]);
- }
- return objects;
- }
- }
-
- /**
- * Returns a service object for one of the services being tracked by this
- * <code>ServiceTracker</code> object.
- *
- * <p>
- * If any services are being tracked, this method returns the result of
- * calling <code>getService(getServiceReference())</code>.
- *
- * @return Service object or <code>null</code> if no service is being
- * tracked.
- */
- public Object getService() {
- Object service = cachedService;
- if (service != null) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
- }
- return service;
- }
- if (DEBUG) {
- System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
- }
- ServiceReference reference = getServiceReference();
- if (reference == null) {
- return null;
- }
- return cachedService = getService(reference);
- }
-
- /**
- * Remove a service from this <code>ServiceTracker</code> object.
- *
- * The specified service will be removed from this
- * <code>ServiceTracker</code> object. If the specified service was being
- * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
- * method will be called for that service.
- *
- * @param reference Reference to the service to be removed.
- */
- public void remove(ServiceReference reference) {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
- return;
- }
- tracked.untrack(reference);
- }
-
- /**
- * Return the number of services being tracked by this
- * <code>ServiceTracker</code> object.
- *
- * @return Number of services being tracked.
- */
- public int size() {
- Tracked tracked = this.tracked; /*
- * use local var since we are not
- * synchronized
- */
- if (tracked == null) { /* if ServiceTracker is not open */
- return 0;
- }
- return tracked.size();
- }
-
- /**
- * Returns the tracking count for this <code>ServiceTracker</code> object.
- *
- * The tracking count is initialized to 0 when this
- * <code>ServiceTracker</code> object is opened. Every time a service is
- * added, modified or removed from this <code>ServiceTracker</code> object
- * the tracking count is incremented.
- *
- * <p>
- * The tracking count can be used to determine if this
- * <code>ServiceTracker</code> object has added, modified or removed a
- * service by comparing a tracking count value previously collected with the
- * current tracking count value. If the value has not changed, then no
- * service has been added, modified or removed from this
- * <code>ServiceTracker</code> object since the previous tracking count
- * was collected.
- *
- * @since 1.2
- * @return The tracking count for this <code>ServiceTracker</code> object
- * or -1 if this <code>ServiceTracker</code> object is not open.
- */
- public int getTrackingCount() {
- return trackingCount;
- }
-
- /**
- * Called by the Tracked object whenever the set of tracked services is
- * modified. Increments the tracking count and clears the cache.
- *
- * @GuardedBy tracked
- */
- /*
- * This method must not be synchronized since it is called by Tracked while
- * Tracked is synchronized. We don't want synchronization interactions
- * between the ServiceListener thread and the user thread.
- */
- void modified() {
- trackingCount++; /* increment modification count */
- cachedReference = null; /* clear cached value */
- cachedService = null; /* clear cached value */
- if (DEBUG) {
- System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
- }
- }
-
- /**
- * Inner class to track services. If a <code>ServiceTracker</code> object
- * is reused (closed then reopened), then a new Tracked object is used. This
- * class is a hashtable mapping <code>ServiceReference</code> object ->
- * customized Object. This class is the <code>ServiceListener</code>
- * object for the tracker. This class is used to synchronize access to the
- * tracked services. This is not a public class. It is only for use by the
- * implementation of the <code>ServiceTracker</code> class.
- *
- * @ThreadSafe
- */
- class Tracked extends Hashtable implements ServiceListener {
- static final long serialVersionUID = -7420065199791006079L;
- /**
- * List of ServiceReferences in the process of being added. This is used
- * to deal with nesting of ServiceEvents. Since ServiceEvents are
- * synchronously delivered, ServiceEvents can be nested. For example,
- * when processing the adding of a service and the customizer causes the
- * service to be unregistered, notification to the nested call to
- * untrack that the service was unregistered can be made to the track
- * method.
- *
- * Since the ArrayList implementation is not synchronized, all access to
- * this list must be protected by the same synchronized object for
- * thread-safety.
- *
- * @GuardedBy this
- */
- private final ArrayList adding;
-
- /**
- * true if the tracked object is closed.
- *
- * This field is volatile because it is set by one thread and read by
- * another.
- */
- private volatile boolean closed;
-
- /**
- * Initial list of ServiceReferences for the tracker. This is used to
- * correctly process the initial services which could become
- * unregistered before they are tracked. This is necessary since the
- * initial set of tracked services are not "announced" by ServiceEvents
- * and therefore the ServiceEvent for unregistration could be delivered
- * before we track the service.
- *
- * A service must not be in both the initial and adding lists at the
- * same time. A service must be moved from the initial list to the
- * adding list "atomically" before we begin tracking it.
- *
- * Since the LinkedList implementation is not synchronized, all access
- * to this list must be protected by the same synchronized object for
- * thread-safety.
- *
- * @GuardedBy this
- */
- private final LinkedList initial;
-
- /**
- * Tracked constructor.
- */
- protected Tracked() {
- super();
- closed = false;
- adding = new ArrayList(6);
- initial = new LinkedList();
- }
-
- /**
- * Set initial list of services into tracker before ServiceEvents begin
- * to be received.
- *
- * This method must be called from ServiceTracker.open while
- * synchronized on this object in the same synchronized block as the
- * addServiceListener call.
- *
- * @param references The initial list of services to be tracked.
- * @GuardedBy this
- */
- protected void setInitialServices(ServiceReference[] references) {
- if (references == null) {
- return;
- }
- int size = references.length;
- for (int i = 0; i < size; i++) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$
- }
- initial.add(references[i]);
- }
- }
-
- /**
- * Track the initial list of services. This is called after
- * ServiceEvents can begin to be received.
- *
- * This method must be called from ServiceTracker.open while not
- * synchronized on this object after the addServiceListener call.
- *
- */
- protected void trackInitialServices() {
- while (true) {
- ServiceReference reference;
- synchronized (this) {
- if (initial.size() == 0) {
- /*
- * if there are no more inital services
- */
- return; /* we are done */
- }
- /*
- * move the first service from the initial list to the
- * adding list within this synchronized block.
- */
- reference = (ServiceReference) initial.removeFirst();
- if (this.get(reference) != null) {
- /* if we are already tracking this service */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$
- }
- continue; /* skip this service */
- }
- if (adding.contains(reference)) {
- /*
- * if this service is already in the process of being
- * added.
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$
- }
- continue; /* skip this service */
- }
- adding.add(reference);
- }
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$
- }
- trackAdding(reference); /*
- * Begin tracking it. We call
- * trackAdding since we have already put
- * the reference in the adding list.
- */
- }
- }
-
- /**
- * Called by the owning <code>ServiceTracker</code> object when it is
- * closed.
- */
- protected void close() {
- closed = true;
- }
-
- /**
- * <code>ServiceListener</code> method for the
- * <code>ServiceTracker</code> class. This method must NOT be
- * synchronized to avoid deadlock potential.
- *
- * @param event <code>ServiceEvent</code> object from the framework.
- */
- public void serviceChanged(ServiceEvent event) {
- /*
- * Check if we had a delayed call (which could happen when we
- * close).
- */
- if (closed) {
- return;
- }
- ServiceReference reference = event.getServiceReference();
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- switch (event.getType()) {
- case ServiceEvent.REGISTERED :
- case ServiceEvent.MODIFIED :
- if (listenerFilter != null) { // constructor supplied
- // filter
- track(reference);
- /*
- * If the customizer throws an unchecked exception, it
- * is safe to let it propagate
- */
- }
- else { // user supplied filter
- if (filter.match(reference)) {
- track(reference);
- /*
- * If the customizer throws an unchecked exception,
- * it is safe to let it propagate
- */
- }
- else {
- untrack(reference);
- /*
- * If the customizer throws an unchecked exception,
- * it is safe to let it propagate
- */
- }
- }
- break;
- case ServiceEvent.UNREGISTERING :
- untrack(reference);
- /*
- * If the customizer throws an unchecked exception, it is
- * safe to let it propagate
- */
- break;
- }
- }
-
- /**
- * Begin to track the referenced service.
- *
- * @param reference Reference to a service to be tracked.
- */
- private void track(ServiceReference reference) {
- Object object;
- synchronized (this) {
- object = this.get(reference);
- }
- if (object != null) /* we are already tracking the service */
- {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
- }
- synchronized (this) {
- modified(); /* increment modification count */
- }
- /* Call customizer outside of synchronized region */
- customizer.modifiedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe
- * to let it propagate
- */
- return;
- }
- synchronized (this) {
- if (adding.contains(reference)) { /*
- * if this service is
- * already in the process of
- * being added.
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
- }
- return;
- }
- adding.add(reference); /* mark this service is being added */
- }
-
- trackAdding(reference); /*
- * call trackAdding now that we have put the
- * reference in the adding list
- */
- }
-
- /**
- * Common logic to add a service to the tracker used by track and
- * trackInitialServices. The specified reference must have been placed
- * in the adding list before calling this method.
- *
- * @param reference Reference to a service to be tracked.
- */
- private void trackAdding(ServiceReference reference) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$
- }
- Object object = null;
- boolean becameUntracked = false;
- /* Call customizer outside of synchronized region */
- try {
- object = customizer.addingService(reference);
- /*
- * If the customizer throws an unchecked exception, it will
- * propagate after the finally
- */
- }
- finally {
- boolean needToCallback = false;
- synchronized (this) {
- if (adding.remove(reference)) { /*
- * if the service was not
- * untracked during the
- * customizer callback
- */
- if (object != null) {
- this.put(reference, object);
- modified(); /* increment modification count */
- notifyAll(); /*
- * notify any waiters in
- * waitForService
- */
- // marrs: extra callback added, will be invoked after
- // the synchronized block
- needToCallback = true;
- }
- }
- else {
- becameUntracked = true;
- }
- }
- if (needToCallback) {
- customizer.addedService(reference, object);
- }
- }
- /*
- * The service became untracked during the customizer callback.
- */
- if (becameUntracked) {
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$
- }
- /* Call customizer outside of synchronized region */
- customizer.removedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe
- * to let it propagate
- */
- }
- }
-
- /**
- * Discontinue tracking the referenced service.
- *
- * @param reference Reference to the tracked service.
- */
- protected void untrack(ServiceReference reference) {
- Object object;
- synchronized (this) {
- if (initial.remove(reference)) { /*
- * if this service is
- * already in the list of
- * initial references to
- * process
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$
- }
- return; /*
- * we have removed it from the list and it will not
- * be processed
- */
- }
-
- if (adding.remove(reference)) { /*
- * if the service is in the
- * process of being added
- */
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
- }
- return; /*
- * in case the service is untracked while in the
- * process of adding
- */
- }
- object = this.remove(reference); /*
- * must remove from tracker
- * before calling customizer
- * callback
- */
- if (object == null) { /* are we actually tracking the service */
- return;
- }
- modified(); /* increment modification count */
- }
- if (DEBUG) {
- System.out
- .println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
- }
- /* Call customizer outside of synchronized region */
- customizer.removedService(reference, object);
- /*
- * If the customizer throws an unchecked exception, it is safe to
- * let it propagate
- */
- }
- }
-
- /**
- * Subclass of Tracked which implements the AllServiceListener interface.
- * This class is used by the ServiceTracker if open is called with true.
- *
- * @since 1.3
- * @ThreadSafe
- */
- class AllTracked extends Tracked implements AllServiceListener {
- static final long serialVersionUID = 4050764875305137716L;
-
- /**
- * AllTracked constructor.
- */
- protected AllTracked() {
- super();
- }
- }
-
- public void addedService(ServiceReference ref, Object service) {
- // do nothing
- }
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java
deleted file mode 100644
index 44f7590..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/ServiceTrackerCustomizer.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import org.osgi.framework.ServiceReference;
-
-/**
- * A modified version of a normal service tracker customizer. This one has an
- * extra callback "addedservice" that is invoked after the service has been added
- * to the tracker (and therefore is accessible through the tracker API).
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public interface ServiceTrackerCustomizer {
- public Object addingService(ServiceReference ref);
- public void addedService(ServiceReference ref, Object service);
- public void modifiedService(ServiceReference ref, Object service);
- public void removedService(ServiceReference ref, Object service);
-}
diff --git a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/State.java b/dependencymanager/src/main/java/org/apache/felix/dependencymanager/State.java
deleted file mode 100644
index bd960b6..0000000
--- a/dependencymanager/src/main/java/org/apache/felix/dependencymanager/State.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * 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.dependencymanager;
-
-import java.util.List;
-
-/**
- * Encapsulates the current state of the dependencies of a service. A state is
- * basically an immutable value object.
- *
- * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
- */
-public final class State {
- private static final String[] STATES = { "?", "inactive", "waiting for required", "tracking optional" };
- private static final int INACTIVE = 1;
- private static final int WAITING_FOR_REQUIRED = 2;
- private static final int TRACKING_OPTIONAL = 3;
- private final List m_deps;
- private final int m_state;
- private String m_stringValue;
-
- /**
- * Creates a new state instance.
- *
- * @param deps the dependencies that determine the state
- * @param isActive <code>true</code> if the service is active (started)
- */
- public State(List deps, boolean isActive) {
- m_deps = deps;
- // only bother calculating dependencies if we're active
- if (isActive) {
- boolean allRequiredAvailable = true;
- for (int i = 0; i < deps.size(); i++) {
- Dependency dep = (Dependency) deps.get(i);
- if (dep.isRequired()) {
- if (!dep.isAvailable()) {
- allRequiredAvailable = false;
- }
- }
- }
- if (allRequiredAvailable) {
- m_state = TRACKING_OPTIONAL;
- }
- else {
- m_state = WAITING_FOR_REQUIRED;
- }
- }
- else {
- m_state = INACTIVE;
- }
- }
-
- public boolean isInactive() {
- return m_state == INACTIVE;
- }
-
- public boolean isWaitingForRequired() {
- return m_state == WAITING_FOR_REQUIRED;
- }
-
- public boolean isTrackingOptional() {
- return m_state == TRACKING_OPTIONAL;
- }
-
- public List getDependencies() {
- return m_deps;
- }
-
- public synchronized String toString() {
- if (m_stringValue == null) {
- // we only need to determine this once, but we do it lazily
- StringBuffer buf = new StringBuffer();
- buf.append("State[" + STATES[m_state] + "|");
- List deps = m_deps;
- for (int i = 0; i < deps.size(); i++) {
- Dependency dep = (Dependency) deps.get(i);
- buf.append("(" + dep + (dep.isRequired() ? " R" : " O") + (dep.isAvailable() ? " +" : " -") + ")");
- }
- m_stringValue = buf.toString();
- }
- return m_stringValue;
- }
-}
diff --git a/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/ComponentLifeCycleTest.java b/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/ComponentLifeCycleTest.java
deleted file mode 100644
index 0a57d73..0000000
--- a/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/ComponentLifeCycleTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.apache.felix.dependencymanager.test;
-
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.provision;
-
-import org.apache.felix.dependencymanager.DependencyManager;
-import org.apache.felix.dependencymanager.Logger;
-import org.apache.felix.dependencymanager.Service;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.Configuration;
-import org.ops4j.pax.exam.junit.JUnit4TestRunner;
-import org.osgi.framework.BundleContext;
-
-@RunWith( JUnit4TestRunner.class )
-public class ComponentLifeCycleTest {
- @Configuration
- public static Option[] configuration() {
- return options(
- provision(
- mavenBundle().groupId("org.apache.felix").artifactId("org.osgi.compendium").versionAsInProject(),
- mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject()
- )
- );
- }
-
- @Test
- public void testComponentLifeCycleCallbacks(BundleContext context) {
- DependencyManager m = new DependencyManager(context, new Logger(context));
- // helper class that ensures certain steps get executed in sequence
- Ensure e = new Ensure();
- // create a simple service component
- Service s = m.createService().setImplementation(new ComponentInstance(e));
- // add it, and since it has no dependencies, it should be activated immediately
- m.add(s);
- // remove it so it gets destroyed
- m.remove(s);
- // ensure we executed all steps inside the component instance
- e.step(6);
-
- // helper class that ensures certain steps get executed in sequence
- e = new Ensure();
- // create a simple service component
- s = m.createService().setImplementation(new CustomComponentInstance(e)).setCallbacks("a", "b", "c", "d");
- // add it, and since it has no dependencies, it should be activated immediately
- m.add(s);
- // remove it so it gets destroyed
- m.remove(s);
- // ensure we executed all steps inside the component instance
- e.step(6);
- }
-
-}
-
-class ComponentInstance {
- private final Ensure m_ensure;
- public ComponentInstance(Ensure e) {
- m_ensure = e;
- m_ensure.step(1);
- }
- public void init() {
- m_ensure.step(2);
- }
- public void start() {
- m_ensure.step(3);
- }
- public void stop() {
- m_ensure.step(4);
- }
- public void destroy() {
- m_ensure.step(5);
- }
-}
-
-class CustomComponentInstance {
- private final Ensure m_ensure;
- public CustomComponentInstance(Ensure e) {
- m_ensure = e;
- m_ensure.step(1);
- }
- public void a() {
- m_ensure.step(2);
- }
- public void b() {
- m_ensure.step(3);
- }
- public void c() {
- m_ensure.step(4);
- }
- public void d() {
- m_ensure.step(5);
- }
-}
diff --git a/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/Ensure.java b/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/Ensure.java
deleted file mode 100644
index c27e246..0000000
--- a/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/Ensure.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.apache.felix.dependencymanager.test;
-
-import junit.framework.Assert;
-
-public class Ensure {
- int step = 1;
- public synchronized void step(int nr) {
- Assert.assertEquals(nr, step);
- step++;
- }
-}
diff --git a/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/ServiceDependencyTest.java b/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/ServiceDependencyTest.java
deleted file mode 100644
index ddd5af6..0000000
--- a/dependencymanager/src/test/java/org/apache/felix/dependencymanager/test/ServiceDependencyTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.apache.felix.dependencymanager.test;
-
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.provision;
-
-import org.apache.felix.dependencymanager.DependencyManager;
-import org.apache.felix.dependencymanager.Logger;
-import org.apache.felix.dependencymanager.Service;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.Configuration;
-import org.ops4j.pax.exam.junit.JUnit4TestRunner;
-import org.osgi.framework.BundleContext;
-
-@RunWith( JUnit4TestRunner.class )
-public class ServiceDependencyTest {
- @Configuration
- public static Option[] configuration() {
- return options(
- provision(
- mavenBundle().groupId("org.apache.felix").artifactId("org.osgi.compendium").versionAsInProject(),
- mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject()
- )
- );
- }
-
- @Test
- public void testServiceRegistrationAndConsumption(BundleContext context) {
- DependencyManager m = new DependencyManager(context, new Logger(context));
- // helper class that ensures certain steps get executed in sequence
- Ensure e = new Ensure();
- // create a service provider and consumer
- Service sp = m.createService().setImplementation(new ServiceProvider(e)).setInterface(ServiceInterface.class.getName(), null);
- Service sc = m.createService().setImplementation(new ServiceConsumer(e)).add(m.createServiceDependency().setService(ServiceInterface.class).setRequired(true));
- m.add(sp);
- m.add(sc);
- m.remove(sp);
- m.remove(sc);
- // ensure we executed all steps inside the component instance
- e.step(4);
- }
-}
-
-interface ServiceInterface {
- public void invoke();
-}
-
-class ServiceProvider implements ServiceInterface {
- private final Ensure m_ensure;
- public ServiceProvider(Ensure e) {
- m_ensure = e;
- }
- public void invoke() {
- m_ensure.step(2);
- }
-}
-
-class ServiceConsumer {
- private volatile ServiceInterface m_service;
- private final Ensure m_ensure;
-
- public ServiceConsumer(Ensure e) {
- m_ensure = e;
- }
-
- public void start() {
- m_ensure.step(1);
- m_service.invoke();
- }
-
- public void stop() {
- m_ensure.step(3);
- }
-}