blob: 05fede3a62a306b6d0db5833876d21d569d27a97 [file] [log] [blame]
/*
* 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.annotation.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotates an OSGi Component class with its dependencies. Components are the main building
* blocks for OSGi applications. They can publish themselves as a service, and/or they can have
* dependencies. These dependencies will influence their life cycle as component will only be
* activated when all required dependencies are available.
* By default, all directly implemented interfaces are registered into the OSGi registry,
* and the component is instantiated automatically, when the component bundle is started and
* when the component dependencies are available. If you need to take control of when and how
* much component instances must be created, then you can use the <code>factoryName</code>
* annotation attribute.<p>
* If a <code>factoryPid</code> attribute is set, the component is not started automatically
* during bundle startup, and the component can then be instantiated multiple times using
* Configuration Admin "Factory Configurations".
*
* <h3>Usage Examples</h3>
*
* Here is a sample showing a Hello component, which depends on a configuration dependency:
* <blockquote>
*
* <pre>
* &#47;**
* * This component will be activated once the bundle is started and when all required dependencies
* * are available.
* *&#47;
* &#64;Component
* class Hello implements HelloService {
* &#64;ConfigurationDependency(pid="my.pid")
* void configure(Dictionary conf) {
* // Configure or reconfigure our component.
* }
*
* &#64;Start
* void start() {
* // Our component is starting and is about to be registered in the OSGi registry as a HelloService service.
* }
* }
* </pre>
* </blockquote>
*
* Here is a sample showing how a HelloFactory component may dynamically instantiate several Hello component instances,
* using Configuration Admin "Factory Configurations":
* <blockquote>
*
* <pre>
* &#47;**
* * All component instances will be created/updated/removed by the "HelloFactory" component
* *&#47;
* &#64;Component(factoryPid="my.factory.pid")
* class Hello implements HelloService {
* void updated(Dictionary conf) {
* // Configure or reconfigure our component. The conf is provided by the factory,
* }
*
* &#64;Start
* void start() {
* // Our component is starting and is about to be registered in the OSGi registry as a Hello service.
* }
* }
*
* &#47;**
* * This class will instantiate some Hello component instances
* *&#47;
* &#64;Component
* class HelloFactory {
* &#64;ServiceDependency
* void bind(ConfigurationAdmin cm) {
* // instantiate a first instance of Hello component
* Configuration c1 = cm.createFactoryConfiguration("my.factory.pid", "?");
* Hashtable props = new Hashtable();
* newprops.put("key", "value1");
* c1.update(props);
*
* // instantiate another instance of Hello component
* Configuration c2 = cm.createFactoryConfiguration("my.factory.pid", "?");
* props = new Hashtable();
* newprops.put("key", "value2");
* c2.update(props);
*
* // destroy the two instances of X component
* c1.delete();
* c2.delete();
* }
* }
* </pre>
* </blockquote>
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Component
{
/**
* Sets list of provided interfaces. By default, the directly implemented interfaces are provided.
* @return the provided interfaces
*/
Class<?>[] provides() default {};
/**
* Sets the static method used to create the components implementation instance.
* @return the factory method used to instantiate the component
*/
String factoryMethod() default "";
/**
* Returns the factory pid whose configurations will instantiate the annotated service class. Leaving this attribute
* unset means your component is a singleton. If you specify a factory pid, then this component will be instantiated
* each time a corresponding factory configuration is created.
*
* @return the factory pid
*/
String factoryPid() default "";
/**
* The Update method to invoke (defaulting to "updated"), when a factory configuration is created or updated.
* Only used if the factoryPid attribute is set.
* The updated callback supported signatures are the following:<p>
* <ul><li>callback(Dictionary)
* <li>callback(Component, Dictionary)
* <li>callback(Component, Configuration ... configTypes) // type safe configuration interface(s)
* <li>callback(Configuration ... configTypes) // type safe configuration interface(s)
* <li>callback(Dictionary, Configuration ... configTypes) // type safe configuration interfaces(s)
* <li>callback(Component, Dictionary, Configuration ... configTypes) // type safe configuration interfaces(s)
* </ul>
* @return the updated callback
*/
String updated() default "updated";
/**
* Returns true if the factory configuration properties must be published to the service properties.
* Only used if the factoryPid attribute is set.
* @return true if configuration must be published along with the service, false if not.
*/
boolean propagate() default false;
/**
* The service scope for the service of this Component.
*
* <p>
* If not specified, the {@link ServiceScope#SINGLETON singleton} service
* scope is used.
*/
ServiceScope scope() default ServiceScope.SINGLETON;
/**
* Sets list of provided service properties. Since R7 version, Property annotation is repeatable and you can directly
* apply it on top of the component class multiple times, instead of using the Component properties attribute.
* @return the component properties.
* @deprecated you can apply {@link Property} annotation directly on the component class.
*/
Property[] properties() default {};
}