Return-Path: X-Original-To: apmail-felix-commits-archive@www.apache.org Delivered-To: apmail-felix-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3CD2BC0FF for ; Thu, 5 Jun 2014 12:02:00 +0000 (UTC) Received: (qmail 47495 invoked by uid 500); 5 Jun 2014 12:02:00 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 47447 invoked by uid 500); 5 Jun 2014 12:02:00 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 47440 invoked by uid 99); 5 Jun 2014 12:02:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Jun 2014 12:02:00 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Jun 2014 12:01:55 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 64B3923888E4; Thu, 5 Jun 2014 12:01:35 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1600620 [1/2] - in /felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm: src/org/apache/felix/dm/ src/org/apache/felix/dm/context/ src/org/apache/felix/dm/impl/ src/org/apache/felix/dm/tracker/ test/org/apache/felix/dm/tra... Date: Thu, 05 Jun 2014 12:01:32 -0000 To: commits@felix.apache.org From: pderop@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140605120135.64B3923888E4@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: pderop Date: Thu Jun 5 12:01:30 2014 New Revision: 1600620 URL: http://svn.apache.org/r1600620 Log: Javadoc. Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/BundleDependency.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Component.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentState.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentStateListener.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ConfigurationDependency.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Dependency.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceDependency.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceHandler.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ServiceDependency.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/ComponentContext.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/DependencyContext.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/Event.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleAdapterImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleDependencyImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleEventImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ComponentImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ConfigurationDependencyImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/DependencyImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/EventImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/FactoryConfigurationAdapterImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ResourceAdapterImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ResourceDependencyImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ResourceEventImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/SerialExecutor.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ServiceDependencyImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/ServiceEventImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/TemporalServiceDependencyImpl.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/tracker/AbstractCustomizerActionSet.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/org/apache/felix/dm/tracker/TrackedTest.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/test/ComponentTest.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/test/ConcurrencyTest.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/test/ConfigurationTest.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/test/Ensure.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/test/SerialExecutorTest.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/test/ServiceRaceTest.java felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/test/test/TestBase.java Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/BundleDependency.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/BundleDependency.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/BundleDependency.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/BundleDependency.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm; import org.osgi.framework.Bundle; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Component.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Component.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Component.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Component.java Thu Jun 5 12:01:30 2014 @@ -1,36 +1,282 @@ +/* + * 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.dm; import java.util.Dictionary; -import java.util.concurrent.Executor; import org.osgi.framework.ServiceRegistration; /** - * A component. Has dependencies. + * Component interface. Components are the main building blocks for OSGi applications. + * They can publish themselves as a service, and they can have dependencies. These + * dependencies will influence their life cycle as component will only be activated + * when all required dependencies are available. + * + * @author Felix Project Team */ public interface Component { + /** + * Sets the implementation for this component. You can actually specify + * an instance you have instantiated manually, or a Class + * 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 life cycle management options: + *
    + *
  1. init() is invoked after the instance has been + * created and dependencies have been resolved, and can be used to + * initialize the internal state of the instance or even to add more + * dependencies based on runtime state
  2. + *
  3. start() is invoked right before the service is + * registered
  4. + *
  5. stop() is invoked right after the service is + * unregistered
  6. + *
  7. destroy() is invoked after all dependencies are + * removed
  8. + *
+ * 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 component + * @see ComponentStateListener + */ public Component setImplementation(Object implementation); + + /** + * Adds dependency(ies) to this component, atomically. If the component is already active or if you add + * dependencies from the init method, then you should add all the dependencies in one single add method call + * (using the varargs argument). + * + * @param dependency the dependency(ies) to add + * @return this component + */ public Component add(Dependency ... dependencies); + + /** + * Removes a dependency from the component. + * @param d the dependency to remove + * @return this component + */ public Component remove(Dependency d); + + /** + * Adds a component state listener to this component. + * + * @param listener the state listener + */ public Component add(ComponentStateListener l); + + /** + * Removes a component state listener from this component. + * + * @param listener the state listener + */ public Component remove(ComponentStateListener l); - public Component setInterface(String serviceName, Dictionary properties); - public Component setInterface(String[] serviceNames, Dictionary properties); - public Component setAutoConfig(Class clazz, boolean autoConfig); - public Component setAutoConfig(Class clazz, String instanceName); - public ServiceRegistration getServiceRegistration(); - public Object[] getInstances(); - public Dictionary getServiceProperties(); - public Component setServiceProperties(Dictionary serviceProperties); - public Component setCallbacks(String init, String start, String stop, String destroy); - public Component setCallbacks(Object instance, String init, String start, String stop, String destroy); - public Component setFactory(Object factory, String createMethod); + + /** + * Sets the public interface under which this component 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 component + */ + public Component setInterface(String serviceName, Dictionary properties); + + /** + * Sets the public interfaces under which this component should be registered + * in the OSGi service registry. + * + * @param serviceNames the names of the service interface + * @param properties the properties for these services + * @return this component + */ + public Component setInterface(String[] serviceNames, Dictionary properties); + + /** + * Configures auto configuration of injected classes in the component instance. + * The following injections are currently performed, unless you explicitly + * turn them off: + *
+ *
BundleContext
the bundle context of the bundle
+ *
ServiceRegistration
the service registration used to register your service
+ *
DependencyManager
the dependency manager instance
+ *
Component
the component instance of the dependency manager
+ *
+ * + * @param clazz the class (from the list above) + * @param autoConfig false to turn off auto configuration + */ + public Component setAutoConfig(Class clazz, boolean autoConfig); + + /** + * Configures auto configuration of injected classes in the component instance. + * + * @param clazz the class (from the list above) + * @param instanceName the name of the instance to inject the class into + * @see setAutoConfig(Class, boolean) + */ + public Component setAutoConfig(Class clazz, String instanceName); + + /** + * Returns the service registration for this component. The method + * will return null if no service registration is + * available, for example if this component is not registered as a + * service at all. + * + * @return the service registration + */ + public ServiceRegistration getServiceRegistration(); + + /** + * Returns the composition instances that make up this component, or just the + * component instance if it does not have a composition, or an empty array if + * the component has not even been instantiated. + * + * @return the component instances + */ + public Object[] getInstances(); + + /** + * Returns the service properties associated with the component. + * + * @return the properties or null if there are none + */ + public Dictionary getServiceProperties(); + + /** + * Sets the service properties associated with the component. If the service + * was already registered, it will be updated. + * + * @param serviceProperties the properties + */ + public Component 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 component implementation. The + * dependency manager will look for a method of this name with the following signatures, + * in this order: + *
    + *
  1. method(Component component)
  2. + *
  3. method()
  4. + *
+ * + * @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 component + */ + public Component setCallbacks(String init, String start, String stop, String destroy); + + /** + * Sets the names of the methods used as callbacks. These methods, when found, are + * invoked on the specified instance as part of the life cycle management of the component + * implementation. + *

+ * See setCallbacks(String init, String start, String stop, String destroy) for more + * information on the signatures. Specifying an instance means you can create a manager + * that will be invoked whenever the life cycle of a component changes and this manager + * can then decide how to expose this life cycle to the actual component, offering an + * important indirection when developing your own component models. + * + * @return this component + */ + public Component setCallbacks(Object instance, String init, String start, String stop, String destroy); + + /** + * 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 setComposition to create a + * composition of instances that work together to implement a component. The + * factory itself can also be instantiated lazily by not specifying an + * instance, but a Class. + * + * @param factory the factory instance or class + * @param createMethod the name of the create method + * @return this component + */ + public Component 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 + * setComposition to create a composition of instances that + * work together to implement a component. + *

+ * Note that currently, there is no default for the factory, so please use + * setFactory(factory, createMethod) instead. + * + * @param createMethod the name of the create method + * @return this component + */ public Component 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 Object[]. + * + * @param instance the instance that has the method + * @param getMethod the method to invoke + * @return this component + */ public Component 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 Object[]. + * + * @param getMethod the method to invoke + * @return this component + */ public Component setComposition(String getMethod); + + /** + * Returns the dependency manager associated with this component. + * @return the dependency manager associated with this component. + */ public DependencyManager getDependencyManager(); + + /** + * Returns the component description (dependencies, service provided, etc ...). + * @return the component description (dependencies, service provided, etc ...). + */ public ComponentDeclaration getComponentDeclaration(); + /** + * Activate debug for this component. Informations related to dependency processing will be displayed + * using osgi log service, our to standard output if no log service is currently available. + * @param label + */ public void setDebug(String label); } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentState.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentState.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentState.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentState.java Thu Jun 5 12:01:30 2014 @@ -1,8 +1,48 @@ +/* + * 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.dm; +/** + * Component states. Any state listeners registered using @link {@link Component#add(ComponentStateListener)} method + * are notified with the following stated whenever the component state changes. + * + * @author Felix Project Team + */ public enum ComponentState { + /** + * The component is not currently started, and is inactive. + */ INACTIVE, + + /** + * The component is waiting for some required dependencies. + */ WAITING_FOR_REQUIRED, + + /** + * The component has all its initial required dependencies available, but is now waiting for some extra required + * dependencies which have been added after the component have been started (like from the component init method for example). + */ INSTANTIATED_AND_WAITING_FOR_REQUIRED, + + /** + * The component is active, and is now tracking available optional dependencies. + */ TRACKING_OPTIONAL } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentStateListener.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentStateListener.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentStateListener.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ComponentStateListener.java Thu Jun 5 12:01:30 2014 @@ -1,6 +1,31 @@ +/* + * 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.dm; - +/** + * This interface can be used to register a component state listener. Component + * state listeners are called whenever a component state changes. You get notified + * when the component is starting, started, stopping and stopped. Each callback + * includes a reference to the component in question. + * + * @author Felix Project Team + */ public interface ComponentStateListener { public void changed(Component c, ComponentState state); } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ConfigurationDependency.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ConfigurationDependency.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ConfigurationDependency.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ConfigurationDependency.java Thu Jun 5 12:01:30 2014 @@ -1,12 +1,96 @@ +/* + * 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.dm; - +/** + * 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 component as a ManagedService(Factory) 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 updated(Dictionary) method: + *

    + *
  • Make sure it throws a ConfigurationException 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.
  • + *
  • This method will be called before all required dependencies are available. Make sure you + * do not depend on these to parse your settings.
  • + *
+ * + * @author Felix Project Team + */ public interface ConfigurationDependency extends Dependency, ComponentDependencyDeclaration { + /** + * Sets the name of the callback method that should be invoked when a configuration + * is available. The contract for this method is identical to that of + * ManagedService.updated(Dictionary) throws ConfigurationException. + * + * @param callback the name of the callback method + */ ConfigurationDependency setCallback(String callback); + + /** + * Sets the service.pid of the configuration you are depending + * on. + */ ConfigurationDependency setPid(String pid); + + /** + * Sets propagation of the configuration properties to the service + * properties. Any additional service properties specified directly are + * merged with these. + */ ConfigurationDependency setPropagate(boolean propagate); + + /** + * The label used to display the tab name (or section) where the properties + * are displayed. Example: "Printer Service". + * + * @return The label used to display the tab name where the properties are + * displayed (may be localized) + */ ConfigurationDependency setHeading(String heading); + + /** + * A human readable description of the PID this configuration is associated + * with. Example: "Configuration for the PrinterService bundle". + * + * @return A human readable description of the PID this configuration is + * associated with (may be localized) + */ ConfigurationDependency setDescription(String description); + + /** + * Points to the basename of the Properties file that can localize the Meta + * Type informations. The default localization base name for the properties + * is OSGI-INF/l10n/bundle, but can be overridden by the manifest + * Bundle-Localization header (see core specification, in section + * Localization on page 68). You can specify a specific localization + * basename file using this method (e.g. + * setLocalization("person") will match person_du_NL.properties + * in the root bundle directory. + */ ConfigurationDependency setLocalization(String path); + + /** + * Adds a MetaData regarding a given configuration property. + */ ConfigurationDependency add(PropertyMetaData properties); } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Dependency.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Dependency.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Dependency.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/Dependency.java Thu Jun 5 12:01:30 2014 @@ -1,15 +1,82 @@ +/* + * 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.dm; import java.util.Dictionary; /** - * A dependency. Can be added to a single component. Can be available, or not. + * Generic dependency for a component. + * Can be added to a single component. Can be available, or not.. + * + * @author Felix Project Team */ public interface Dependency { + /** + * Returns true if this a required dependency. Required dependencies + * are dependencies that must be available before the component can be activated. + * + * @return true if the dependency is required + */ public boolean isRequired(); + + /** + * Returns true if the dependency is available. + * + * @return true if the dependency is available + */ public boolean isAvailable(); + + /** + * Returns true>code> if auto configuration is enabled for this dependency. + * Auto configuration means that a dependency is injected in the component instance + * when it's available, and if it's unavailable, a "null object" will be inserted + * instead. + * + * @return true if auto configuration is enabled for this dependency + */ public boolean isAutoConfig(); + + /** + * Returns the name of the member in the class of the component instance + * to inject into. If you specify this, not all members of the right + * type will be injected, only the member whose name matches. + * + * @return + */ public String getAutoConfigName(); + + /** + * Determines if the properties associated with this dependency should be propagated to + * the properties of the service registered by the component they belong to. + * + * @see Dependency#getProperties() + * + * @return true if the properties should be propagated + */ public boolean isPropagated(); + + /** + * Returns the properties associated with this dependency. + * + * @see Dependency#isPropagated() + * + * @return the properties + */ public Dictionary getProperties(); } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/DependencyManager.java Thu Jun 5 12:01:30 2014 @@ -69,7 +69,7 @@ public class DependencyManager { // service registry cache private static ServiceRegistryCache m_serviceRegistryCache; - private static final Set /* WeakReference */ m_dependencyManagers = new HashSet(); + private static final Set /* WeakReference */m_dependencyManagers = new HashSet(); static { String index = System.getProperty(SERVICEREGISTRY_CACHE_INDICES); if (index != null) { @@ -79,7 +79,7 @@ public class DependencyManager { bundle.start(); } BundleContext bundleContext = bundle.getBundleContext(); - + m_serviceRegistryCache = new ServiceRegistryCache(bundleContext); m_serviceRegistryCache.open(); // TODO close it somewhere String[] props = index.split(";"); @@ -101,11 +101,19 @@ public class DependencyManager { } } } - + + /** + * Creates a new dependency manager. You need to supply the + * BundleContext to be used by the dependency + * manager to register services and communicate with the + * framework. + * + * @param context the bundle context + */ public DependencyManager(BundleContext context) { this(context, new Logger(context)); } - + DependencyManager(BundleContext context, Logger logger) { m_context = createContext(context); m_logger = logger; @@ -113,9 +121,13 @@ public class DependencyManager { m_dependencyManagers.add(new WeakReference(this)); } } - + + /** + * Returns the list of currently created dependency managers. + * @return the list of currently created dependency managers + */ public static List getDependencyManagers() { - List /* DependencyManager */ result = new ArrayList(); + List /* DependencyManager */result = new ArrayList(); synchronized (m_dependencyManagers) { Iterator iterator = m_dependencyManagers.iterator(); while (iterator.hasNext()) { @@ -135,120 +147,517 @@ public class DependencyManager { } return result; } - + + /** + * Returns the bundle context associated with this dependency manager. + * @return the bundle context associated with this dependency manager. + */ public BundleContext getBundleContext() { return m_context; } + /** + * Adds a new component to the dependency manager. After the service is added + * it will be started immediately. + * + * @param service the service to add + */ public void add(Component service) { m_components.add(service); ((ComponentContext) 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(Component service) { ((ComponentContext) service).stop(); m_components.remove(service); } + /** + * Creates a new component. + * + * @return the new component + */ public Component createComponent() { return new ComponentImpl(m_context, this, m_logger); } - + + /** + * Creates a new service dependency. + * + * @return the service dependency + */ public ServiceDependency createServiceDependency() { return new ServiceDependencyImpl(m_context, m_logger); } - + + /** + * Creates a new configuration dependency. + * + * @return the configuration dependency + */ public ConfigurationDependency createConfigurationDependency() { return new ConfigurationDependencyImpl(m_context, m_logger); } - + + /** + * Creates a new bundle dependency. + * + * @return a new BundleDependency instance. + */ public BundleDependency createBundleDependency() { return new BundleDependencyImpl(m_context, m_logger); } + /** + * Creates a new resource dependency. + * + * @return the resource dependency + */ public ResourceDependency createResourceDependency() { return new ResourceDependencyImpl(m_context, m_logger); } + /** + * Creates a new timed required service dependency. A timed dependency blocks the invoker thread is the required dependency + * is currently unavailable, until it comes up again. + * + * @return a new timed service dependency + */ public ServiceDependency createTemporalServiceDependency(long timeout) { return new TemporalServiceDependencyImpl(m_context, m_logger, timeout); } + /** + * Creates a new adapter. The adapter will be applied to any service that + * matches the specified interface and filter. For each matching service + * an adapter will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface and existing properties + * from the original service plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "m_service")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * 
+ * + * @param serviceInterface the service interface to apply the adapter to + * @param serviceFilter the filter condition to use with the service interface + * @param autoConfig the name of the member to inject the service into + * @return a service that acts as a factory for generating adapters + */ public Component createAdapterService(Class serviceInterface, String serviceFilter, String autoConfig) { return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null); } + /** + * Creates a new adapter. The adapter will be applied to any service that + * matches the specified interface and filter. For each matching service + * an adapter will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface and existing properties + * from the original service plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * 
+ * + * @param serviceInterface the service interface to apply the adapter to + * @param serviceFilter the filter condition to use with the service interface + * @return a service that acts as a factory for generating adapters + */ public Component createAdapterService(Class serviceInterface, String serviceFilter) { return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null); } - - public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, String remove, String swap) { + + /** + * Creates a new adapter. The adapter will be applied to any service that + * matches the specified interface and filter. For each matching service + * an adapter will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface and existing properties + * from the original service plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove", "swap")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * 
+ * + * @param serviceInterface the service interface to apply the adapter to + * @param serviceFilter the filter condition to use with the service interface + * @param add name of the callback method to invoke on add + * @param change name of the callback method to invoke on change + * @param remove name of the callback method to invoke on remove + * @param swap name of the callback method to invoke on swap + * @return a service that acts as a factory for generating adapters + */ + public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, + String remove, String swap) + { return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, add, change, remove, swap); } - public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, String remove) { + /** + * Creates a new adapter. The adapter will be applied to any service that + * matches the specified interface and filter. For each matching service + * an adapter will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface and existing properties + * from the original service plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove")
+     *     .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+     *     .setImplementation(AdapterImpl.class);
+     * 
+ * + * @param serviceInterface the service interface to apply the adapter to + * @param serviceFilter the filter condition to use with the service interface + * @param add name of the callback method to invoke on add + * @param change name of the callback method to invoke on change + * @param remove name of the callback method to invoke on remove + * @param swap name of the callback method to invoke on swap + * @return a service that acts as a factory for generating adapters + */ + public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, + String remove) + { return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, add, change, remove); } + /** + * Creates a new Managed Service Factory Configuration Adapter. For each new Config Admin factory configuration matching + * the factoryPid, an adapter will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface, and with the specified adapter service properties. + * Depending on the propagate parameter, every public factory configuration properties + * (which don't start with ".") will be propagated along with the adapter service properties. + * It will also inherit all dependencies. + * + *

Usage Example

+ * + *
+     *  manager.createFactoryConfigurationAdapterService("MyFactoryPid",  "update", true)
+     *         // The interface to use when registering adapter
+     *         .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
+     *         // the implementation of the adapter
+     *         .setImplementation(AdapterServiceImpl.class);
+     * 
+ * + * @param factoryPid the pid matching the factory configuration + * @param update the adapter method name that will be notified when the factory configuration is created/updated. + * @param propagate true if public factory configuration should be propagated to the adapter service properties + * @return a service that acts as a factory for generating the managed service factory configuration adapter + */ public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) { return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate); } - public Component createAdapterFactoryConfigurationService(String factoryPid, String update, boolean propagate, String heading, String desc, String localization, PropertyMetaData[] propertiesMetaData) { - return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, m_context, m_logger, heading, desc, localization, propertiesMetaData); - } - + /** + * Creates a new Managed Service Factory Configuration Adapter with meta type support. For each new Config Admin + * factory configuration matching the factoryPid, an adapter will be created based on the adapter implementation + * class. The adapter will be registered with the specified interface, and with the specified adapter service + * properties. Depending on the propagate parameter, every public factory configuration properties + * (which don't start with ".") will be propagated along with the adapter service properties. + * It will also inherit all dependencies. + * + *

Usage Example

+ * + *
+     *       PropertyMetaData[] propertiesMetaData = new PropertyMetaData[] {
+     *            manager.createPropertyMetaData()
+     *               .setCardinality(Integer.MAX_VALUE)
+     *               .setType(String.class)
+     *               .setHeading("English words")
+     *               .setDescription("Declare here some valid english words")
+     *               .setDefaults(new String[] {"hello", "world"})
+     *               .setId("words")
+     *       };
+     * 
+     *       manager.add(createFactoryConfigurationAdapterService("FactoryPid", 
+     *                                                            "updated",
+     *                                                            true, // propagate CM settings
+     *                                                            "EnglishDictionary",
+     *                                                            "English dictionary configuration properties",
+     *                                                            null,
+     *                                                            propertiesMetaData)
+     *               .setImplementation(Adapter.class));
+     * 
+ * + * @param factoryPid the pid matching the factory configuration + * @param update the adapter method name that will be notified when the factory configuration is created/updated. + * @param propagate true if public factory configuration should be propagated to the adapter service properties + * @param heading The label used to display the tab name (or section) where the properties are displayed. + * Example: "Printer Service" + * @param desc A human readable description of the factory PID this configuration is associated with. + * Example: "Configuration for the PrinterService bundle" + * @param localization Points to the basename of the Properties file that can localize the Meta Type informations. + * The default localization base name for the properties is OSGI-INF/l10n/bundle, but can + * be overridden by the manifest Bundle-Localization header (see core specification, in section Localization + * on page 68). You can specify a specific localization basename file using this parameter + * (e.g. "person" will match person_du_NL.properties in the root bundle directory). + * @param propertiesMetaData Array of MetaData regarding configuration properties + * @return a service that acts as a factory for generating the managed service factory configuration adapter + */ + public Component createAdapterFactoryConfigurationService(String factoryPid, String update, boolean propagate, + String heading, String desc, String localization, PropertyMetaData[] propertiesMetaData) + { + return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, m_context, m_logger, heading, + desc, localization, propertiesMetaData); + } + + /** + * Creates a new bundle adapter. The adapter will be applied to any bundle that + * matches the specified bundle state mask and filter condition. For each matching + * bundle an adapter will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface + * + * TODO and existing properties from the original resource plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     *  manager.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE, 
+     *                                     "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
+     *                                     true)
+     *         // The interface to use when registering adapter
+     *         .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
+     *         // the implementation of the adapter
+     *         .setImplementation(AdapterServiceImpl.class);
+     * 
+ * + * @param bundleStateMask the bundle state mask to apply + * @param bundleFilter the filter to apply to the bundle manifest + * @param propagate true if properties from the bundle should be propagated to the service + * @return a service that acts as a factory for generating bundle adapters + */ public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) { return new BundleAdapterImpl(this, bundleStateMask, bundleFilter, propagate); } - public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance, String callbackChanged) { + /** + * Creates a new resource adapter. The adapter will be applied to any resource that + * matches the specified filter condition. For each matching resource + * an adapter will be created based on the adapter implementation class. + * The adapter will be registered with the specified interface and existing properties + * from the original resource plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     *  manager.createResourceAdapterService("(&(path=/test)(repository=TestRepository))", true)
+     *         // The interface to use when registering adapter
+     *         .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
+     *         // the implementation of the adapter
+     *         .setImplementation(AdapterServiceImpl.class);
+     * 
+ * + * @param resourceFilter the filter condition to use with the resource + * @param resourcePropertiesFilter the filter condition on the resource properties to use with the resource + * @param propagate true if properties from the resource should be propagated to the service + * @param callbackInstance instance to invoke the callback on + * @param callbackChanged the name of the callback method + * @return a service that acts as a factory for generating resource adapters + * @see Resource + */ + public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance, + String callbackChanged) + { return new ResourceAdapterImpl(this, resourceFilter, propagate, callbackInstance, null, callbackChanged); } - - public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance, String callbackSet, String callbackChanged) { + + /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */ + public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance, + String callbackSet, String callbackChanged) + { return new ResourceAdapterImpl(this, resourceFilter, propagate, callbackInstance, callbackSet, callbackChanged); } - - public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) { - return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, null, callbackChanged); - } - - public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackSet, String callbackChanged) { - return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, callbackSet, callbackChanged); - } - + + /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */ + public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, + String propagateCallbackMethod, Object callbackInstance, String callbackChanged) + { + return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, + callbackInstance, null, callbackChanged); + } + + /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */ + public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, + String propagateCallbackMethod, Object callbackInstance, String callbackSet, String callbackChanged) + { + return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, + callbackInstance, callbackSet, callbackChanged); + } + + /** + * Returns a list of components. + * + * @return a list of components + */ public List getComponents() { return m_components; } + /** + * Creates a new aspect. The aspect will be applied to any service that + * matches the specified interface and filter. For each matching service + * an aspect will be created based on the aspect implementation class. + * The aspect will be registered with the same interface and properties + * as the original service, plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_service")
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * 
+ * + * @param serviceInterface the service interface to apply the aspect to + * @param serviceFilter the filter condition to use with the service interface + * @param ranking the level used to organize the aspect chain ordering + * @param autoConfig the aspect implementation field name where to inject original service. + * If null, any field matching the original service will be injected. + * @return a service that acts as a factory for generating aspects + */ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String autoConfig) { return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null, null); } - + + /** + * Creates a new aspect. The aspect will be applied to any service that + * matches the specified interface and filter. For each matching service + * an aspect will be created based on the aspect implementation class. + * The aspect will be registered with the same interface and properties + * as the original service, plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10)
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * 
+ * + * @param serviceInterface the service interface to apply the aspect to + * @param serviceFilter the filter condition to use with the service interface + * @param ranking the level used to organize the aspect chain ordering + * @return a service that acts as a factory for generating aspects + */ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking) { return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null, null); } - - public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) { + + /** + * Creates a new aspect. The aspect will be applied to any service that + * matches the specified interface and filter. For each matching service + * an aspect will be created based on the aspect implementation class. + * The aspect will be registered with the same interface and properties + * as the original service, plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * 
+ * + * @param serviceInterface the service interface to apply the aspect to + * @param serviceFilter the filter condition to use with the service interface + * @param ranking the level used to organize the aspect chain ordering + * @param add name of the callback method to invoke on add + * @param change name of the callback method to invoke on change + * @param remove name of the callback method to invoke on remove + * @return a service that acts as a factory for generating aspects + */ + public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, + String change, String remove) + { return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, null); } - - public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove, String swap) { - return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, swap); - } + /** + * Creates a new aspect. The aspect will be applied to any service that + * matches the specified interface and filter. For each matching service + * an aspect will be created based on the aspect implementation class. + * The aspect will be registered with the same interface and properties + * as the original service, plus any extra properties you supply here. + * It will also inherit all dependencies, and if you declare the original + * service as a member it will be injected. + * + *

Usage Example

+ * + *
+     * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
+     *     .setImplementation(ExistingServiceAspect.class)
+     * );
+     * 
+ * + * @param serviceInterface the service interface to apply the aspect to + * @param serviceFilter the filter condition to use with the service interface + * @param ranking the level used to organize the aspect chain ordering + * @param add name of the callback method to invoke on add + * @param change name of the callback method to invoke on change + * @param remove name of the callback method to invoke on remove + * @param swap name of the callback method to invoke on swap + * @return a service that acts as a factory for generating aspects + */ + public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, + String change, String remove, String swap) + { + return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, swap); + } + + /** + * Removes all components and their dependencies. + */ public void clear() { for (Component component : m_components) { remove(component); } m_components.clear(); } - + + /** + * Creates a new configuration property metadata. + * + * @return the configuration property metadata. + */ public PropertyMetaData createPropertyMetaData() { return new PropertyMetaDataImpl(); } - + private BundleContext createContext(BundleContext context) { if (m_serviceRegistryCache != null) { return m_serviceRegistryCache.createBundleContextInterceptor(context); Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceDependency.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceDependency.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceDependency.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceDependency.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm; import java.net.URL; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceHandler.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceHandler.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceHandler.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ResourceHandler.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm; import java.net.URL; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ServiceDependency.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ServiceDependency.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ServiceDependency.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/ServiceDependency.java Thu Jun 5 12:01:30 2014 @@ -1,26 +1,218 @@ +/* + * 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.dm; import org.osgi.framework.ServiceReference; +/** + * Service dependency that can track an OSGi service. + * + * @author Felix Project Team + */ public interface ServiceDependency extends Dependency, ComponentDependencyDeclaration { + /** + * 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 ServiceDependency setCallbacks(String add, String remove); + + /** + * 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 ServiceDependency setCallbacks(String add, String change, String remove); - public ServiceDependency setCallbacks(String added, String changed, String removed, String swapped); + + /** + * 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 + * @param swapped the method to call when the service was swapped due to addition or + * removal of an aspect + * @return this service dependency + */ + public ServiceDependency setCallbacks(String added, String changed, String removed, String swapped); + + /** + * 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 ServiceDependency setCallbacks(Object instance, String add, String remove); + + /** + * 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 ServiceDependency setCallbacks(Object instance, String add, String change, String remove); - public ServiceDependency setCallbacks(Object instance, String added, String changed, String removed, String swapped); + + /** + * 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 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 + * @param swapped the method to call when the service was swapped due to addition or + * removal of an aspect + * @return this service dependency + */ + public ServiceDependency setCallbacks(Object instance, String added, String changed, String removed, String swapped); + + /** + * Sets the required flag which determines if this service is required or not. + * A ServiceDependency is false by default. + * + * @param required the required flag + * @return this service dependency + */ public ServiceDependency setRequired(boolean required); + + /** + * 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 ServiceDependency setAutoConfig(boolean autoConfig); - public ServiceDependency setAutoConfig(String instanceName); + /** + * 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 ServiceDependency setAutoConfig(String instanceName); + + /** + * Sets the name of the service that should be tracked. + * + * @param serviceName the name of the service + * @return this service dependency + */ public ServiceDependency setService(Class serviceName); + + /** + * 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 ServiceDependency setService(Class serviceName, String serviceFilter); + + /** + * Sets the filter for the services that should be tracked. Any service object + * matching the filter will be returned, without any additional filter on the + * class. + * + * @param serviceFilter the filter condition + * @return this service dependency + */ public ServiceDependency setService(String serviceFilter); + + /** + * 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 ServiceDependency setService(Class serviceName, ServiceReference serviceReference); + + /** + * 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 ServiceDependency setDefaultImplementation(Object implementation); + + /** + * Sets propagation of the service dependency properties to the provided service properties. Any additional + * service properties specified directly are merged with these. + */ public ServiceDependency setPropagate(boolean propagate); + + /** + * Sets an Object instance and a callback method used to propagate some properties to the provided service properties. + * The method will be invoked on the specified object instance and must have one of the following signatures:

+ *

  • Dictionary callback(ServiceReference, Object service) + *
  • Dictionary callback(ServiceReference) + *
+ * @param instance the Object instance which is used to retrieve propagated service properties + * @param method the method to invoke for retrieving the properties to be propagated to the service properties. + * @return this service dependency. + */ public ServiceDependency setPropagate(Object instance, String method); - // TODO ASPECTS: Added debug option. Decide whether we might just leave it in. + /** + * Enabled debug logging for this dependency instance. The logging is prefixed with the given identifier. + * @param identifier + * @return this service dependency. + */ public void setDebug(String debugKey); } Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/ComponentContext.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/ComponentContext.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/ComponentContext.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/ComponentContext.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm.context; import java.util.List; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/DependencyContext.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/DependencyContext.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/DependencyContext.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/DependencyContext.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm.context; import java.util.Dictionary; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/Event.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/Event.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/Event.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/context/Event.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm.context; import org.osgi.framework.BundleContext; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleAdapterImpl.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleAdapterImpl.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleAdapterImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleAdapterImpl.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm.impl; import java.util.Enumeration; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleDependencyImpl.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleDependencyImpl.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleDependencyImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleDependencyImpl.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm.impl; import java.lang.reflect.InvocationTargetException; Modified: felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleEventImpl.java URL: http://svn.apache.org/viewvc/felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleEventImpl.java?rev=1600620&r1=1600619&r2=1600620&view=diff ============================================================================== --- felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleEventImpl.java (original) +++ felix/sandbox/pderop/dependencymanager-prototype/org.apache.felix.dm/src/org/apache/felix/dm/impl/BundleEventImpl.java Thu Jun 5 12:01:30 2014 @@ -1,3 +1,21 @@ +/* + * 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.dm.impl; import org.osgi.framework.Bundle;