blob: 6ef1f6078cbd15851ef6bde2f226dffafaed3daf [file] [log] [blame]
Pierre De Rop3a00a212015-03-01 09:27:46 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.felix.dm.annotation.api;
20
21import java.lang.annotation.ElementType;
22import java.lang.annotation.Retention;
23import java.lang.annotation.RetentionPolicy;
24import java.lang.annotation.Target;
25
26
27/**
28 * Annotates a method for injecting a Configuration Dependency. A configuration dependency
29 * is always required, and allows you to depend on the availability of a valid configuration
30 * for your component. This dependency requires the OSGi Configuration Admin Service.
31 *
32 * <h3>Usage Examples</h3>
33 *
34 * <p> In the following example, the "Printer" component depends on a configuration
35 * whose PID name is "sample.PrinterConfiguration". This service will initialize
36 * its ip/port number from the provided configuration.
37 * <p> First, we define the configuration metadata, using standard bndtools metatatype annotations
38 * (see http://www.aqute.biz/Bnd/MetaType):
39 *
40 * <blockquote>
41 * <pre>
42 * package sample;
43 * import aQute.bnd.annotation.metatype.Meta.AD;
44 * import aQute.bnd.annotation.metatype.Meta.OCD;
45 *
46 * &#64;OCD(description = "Declare here the Printer Configuration.")
47 * public interface PrinterConfiguration {
48 * &#64;AD(description = "Enter the printer ip address")
49 * String ipAddress();
50 *
51 * &#64;AD(description = "Enter the printer address port number.")
52 * int portNumber();
53 * }
54 * </pre>
55 * </blockquote>
56 *
57 * Next, we define our Printer service which depends on the PrinterConfiguration:
58 *
59 * <blockquote>
60 * <pre>
61 * package sample;
62 * import aQute.bnd.annotation.metatype.*;
63 *
64 * &#64;Component
65 * public class Printer {
66 * &#64;ConfigurationDependency(pidClass = PrinterConfiguration.class) // Will use pid "sample.PrinterConfiguration"
67 * void updated(Dictionary props) {
68 * // load configuration from the provided dictionary, or throw an exception of any configuration error.
69 * PrinterConfig cnf = Configurable.createConfigurable(PrinterConfig.class, props);
70 * String ip = cnf.ipAddress();
71 * int port = cnf.portNumber();
72 * ...
73 * }
74 * }
75 * </pre>
76 * </blockquote>
77 *
78 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
79 */
80@Retention(RetentionPolicy.CLASS)
81@Target(ElementType.METHOD)
82public @interface ConfigurationDependency
83{
84 /**
85 * Returns the pid for a given service (by default, the pid is the service class name).
86 * @return the pid for a given service (default = Service class name)
87 */
88 String pid() default "";
89
90 /**
91 * Returns the pid from a class name. The full class name will be used as the configuration PID.
Pierre De Rop40ecace2016-02-09 21:44:38 +000092 * You can use this method when you use an interface annotated with standard bndtols metatype annotations.
Pierre De Rop3a00a212015-03-01 09:27:46 +000093 * (see http://www.aqute.biz/Bnd/MetaType).
Pierre De Rop1c0431f2016-02-06 23:28:44 +000094 * @return the pid class
Pierre De Rop3a00a212015-03-01 09:27:46 +000095 */
96 Class<?> pidClass() default Object.class;
97
98 /**
99 * Returns true if the configuration properties must be published along with the service.
100 * Any additional service properties specified directly are merged with these.
101 * @return true if configuration must be published along with the service, false if not.
102 */
103 boolean propagate() default false;
104
105 /**
106 * The name for this configuration dependency. When you give a name a dependency, it won't be evaluated
107 * immediately, but after the component's init method has been called, and from the init method, you can then return
108 * a map in order to dynamically configure the configuration dependency (the map has to contain a "pid" and/or "propagate"
109 * flag, prefixed with the dependency name). Then the dependency will be evaluated after the component init method, and will
110 * be injected before the start method.
111 *
112 * <p> Usage example of a Configuration dependency whose pid and propagate flag is configured dynamically from init method:
113 *
114 * <blockquote><pre>
115 * &#47;**
116 * * A Service that dynamically defines an extra dynamic configuration dependency from its init method.
117 * *&#47;
118 * &#64;Component
119 * class X {
120 * private Dictionary m_config;
121 *
122 * // Inject initial Configuration (injected before any other required dependencies)
123 * &#64;ConfigurationDependency
124 * void componentConfiguration(Dictionary config) {
125 * // you must throw an exception if the configuration is not valid
126 * m_config = config;
127 * }
128 *
129 * &#47;**
130 * * All unnamed dependencies are injected: we can now configure our dynamic configuration whose dependency name is "global".
131 * *&#47;
132 * &#64;Init
133 * Map init() {
134 * return new HashMap() {{
135 * put("global.pid", m_config.get("globalConfig.pid"));
136 * put("global.propagate", m_config.get("globalConfig.propagate"));
137 * }};
138 * }
139 *
140 * // Injected after init, and dynamically configured by the init method.
141 * &#64;ConfigurationDependency(name="global")
142 * void globalConfiguration(Dictionary globalConfig) {
143 * // you must throw an exception if the configuration is not valid
144 * }
145 *
146 * &#47;**
147 * * All dependencies are injected and our service is now ready to be published.
148 * *&#47;
149 * &#64;Start
150 * void start() {
151 * }
152 * }
153 * </pre></blockquote>
Pierre De Rop1c0431f2016-02-06 23:28:44 +0000154 * @return the dependency name used to configure the dependency dynamically from init callback
Pierre De Rop3a00a212015-03-01 09:27:46 +0000155 */
156 String name() default "";
157
158 /**
159 * The label used to display the tab name (or section) where the properties are displayed. Example: "Printer Service".
160 * @return The label used to display the tab name where the properties are displayed.
161 * @deprecated use standard bndtools metatype annotations instead (see http://www.aqute.biz/Bnd/MetaType)
162 */
163 String heading() default "";
164
165 /**
166 * A human readable description of the PID this annotation is associated with. Example: "Configuration for the PrinterService bundle".
167 * @return A human readable description of the PID this annotation is associated with.
168 * @deprecated use standard bndtools metatype annotations instead (see http://www.aqute.biz/Bnd/MetaType)
169 */
170 String description() default "";
171
172 /**
173 * The list of properties types used to expose properties in web console.
174 * @return The list of properties types used to expose properties in web console.
175 * @deprecated use standard bndtools metatype annotations instead (see http://www.aqute.biz/Bnd/MetaType)
176 */
177 PropertyMetaData[] metadata() default {};
178}