Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: caf295a2ac110db508f132cafbb97ae3f404cd59 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/*
 * Copyright (c) OSGi Alliance (2001, 2015). All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.osgi.service.cm;

import java.io.IOException;
import java.util.Dictionary;
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;

/**
 * Service for administering configuration data.
 * 
 * <p>
 * The main purpose of this interface is to store bundle configuration data
 * persistently. This information is represented in {@code Configuration}
 * objects. The actual configuration data is a {@code Dictionary} of properties
 * inside a {@code Configuration} object.
 * 
 * <p>
 * There are two principally different ways to manage configurations. First
 * there is the concept of a Managed Service, where configuration data is
 * uniquely associated with an object registered with the service registry.
 * 
 * <p>
 * Next, there is the concept of a factory where the Configuration Admin service
 * will maintain 0 or more {@code Configuration} objects for a Managed Service
 * Factory that is registered with the Framework.
 * 
 * <p>
 * The first concept is intended for configuration data about "things/services"
 * whose existence is defined externally, e.g. a specific printer. Factories are
 * intended for "things/services" that can be created any number of times, e.g.
 * a configuration for a DHCP server for different networks.
 * 
 * <p>
 * Bundles that require configuration should register a Managed Service or a
 * Managed Service Factory in the service registry. A registration property
 * named {@code service.pid} (persistent identifier or PID) must be used to
 * identify this Managed Service or Managed Service Factory to the Configuration
 * Admin service.
 * 
 * <p>
 * When the ConfigurationAdmin detects the registration of a Managed Service, it
 * checks its persistent storage for a configuration object whose
 * {@code service.pid} property matches the PID service property (
 * {@code service.pid}) of the Managed Service. If found, it calls
 * {@link ManagedService#updated(Dictionary)} method with the new properties.
 * The implementation of a Configuration Admin service must run these call-backs
 * asynchronously to allow proper synchronization.
 * 
 * <p>
 * When the Configuration Admin service detects a Managed Service Factory
 * registration, it checks its storage for configuration objects whose
 * {@code service.factoryPid} property matches the PID service property of the
 * Managed Service Factory. For each such {@code Configuration} objects, it
 * calls the {@code ManagedServiceFactory.updated} method asynchronously with
 * the new properties. The calls to the {@code updated} method of a
 * {@code ManagedServiceFactory} must be executed sequentially and not overlap
 * in time.
 * 
 * <p>
 * In general, bundles having permission to use the Configuration Admin service
 * can only access and modify their own configuration information. Accessing or
 * modifying the configuration of other bundles requires
 * {@code ConfigurationPermission[location,CONFIGURE]}, where location is the
 * configuration location.
 * 
 * <p>
 * {@code Configuration} objects can be <i>bound</i> to a specified bundle
 * location or to a region (configuration location starts with {@code ?}). If a
 * location is not set, it will be learned the first time a target is
 * registered. If the location is learned this way, the Configuration Admin
 * service must detect if the bundle corresponding to the location is
 * uninstalled. If this occurs, the {@code Configuration} object must be
 * unbound, that is its location field is set back to {@code null}.
 * 
 * <p>
 * If target's bundle location matches the configuration location it is always
 * updated.
 * 
 * <p>
 * If the configuration location starts with {@code ?}, that is, the location is
 * a region, then the configuration must be delivered to all targets registered
 * with the given PID. If security is on, the target bundle must have
 * Configuration Permission[location,TARGET], where location matches given the
 * configuration location with wildcards as in the Filter substring match. The
 * security must be verified using the
 * {@link org.osgi.framework.Bundle#hasPermission(Object)} method on the target
 * bundle.
 * 
 * <p>
 * If a target cannot be updated because the location does not match or it has
 * no permission and security is active then the Configuration Admin service
 * must not do the normal callback.
 * 
 * <p>
 * The method descriptions of this class refer to a concept of "the calling
 * bundle". This is a loose way of referring to the bundle which obtained the
 * Configuration Admin service from the service registry. Implementations of
 * {@code ConfigurationAdmin} must use a
 * {@link org.osgi.framework.ServiceFactory} to support this concept.
 * 
 * @author $Id$
 * @ThreadSafe
 */
@ProviderType
public interface ConfigurationAdmin {
	/**
	 * Configuration property naming the Factory PID in the configuration
	 * dictionary. The property's value is of type {@code String}.
	 * 
	 * @since 1.1
	 */
	public final static String	SERVICE_FACTORYPID		= "service.factoryPid";
	/**
	 * Configuration property naming the location of the bundle that is
	 * associated with a {@code Configuration} object. This property can be
	 * searched for but must not appear in the configuration dictionary for
	 * security reason. The property's value is of type {@code String}.
	 * 
	 * @since 1.1
	 */
	public final static String	SERVICE_BUNDLELOCATION	= "service.bundleLocation";

	/**
	 * Create a new factory {@code Configuration} object with a new PID.
	 * 
	 * The properties of the new {@code Configuration} object are {@code null}
	 * until the first time that its {@link Configuration#update(Dictionary)}
	 * method is called.
	 * 
	 * <p>
	 * It is not required that the {@code factoryPid} maps to a registered
	 * Managed Service Factory.
	 * 
	 * <p>
	 * The {@code Configuration} object is bound to the location of the calling
	 * bundle. It is possible that the same factoryPid has associated
	 * configurations that are bound to different bundles. Bundles should only
	 * see the factory configurations that they are bound to or have the proper
	 * permission.
	 * 
	 * @param factoryPid PID of factory (not {@code null}).
	 * @return A new {@code Configuration} object.
	 * @throws IOException if access to persistent storage fails.
	 */
	public Configuration createFactoryConfiguration(String factoryPid) throws IOException;

	/**
	 * Create a new factory {@code Configuration} object with a new PID.
	 * 
	 * The properties of the new {@code Configuration} object are {@code null}
	 * until the first time that its {@link Configuration#update(Dictionary)}
	 * method is called.
	 * 
	 * <p>
	 * It is not required that the {@code factoryPid} maps to a registered
	 * Managed Service Factory.
	 * 
	 * <p>
	 * The {@code Configuration} is bound to the location specified. If this
	 * location is {@code null} it will be bound to the location of the first
	 * bundle that registers a Managed Service Factory with a corresponding PID.
	 * It is possible that the same factoryPid has associated configurations
	 * that are bound to different bundles. Bundles should only see the factory
	 * configurations that they are bound to or have the proper permission.
	 * 
	 * <p>
	 * If the location starts with {@code ?} then the configuration must be
	 * delivered to all targets with the corresponding PID.
	 * 
	 * @param factoryPid PID of factory (not {@code null}).
	 * @param location A bundle location string, or {@code null}.
	 * @return a new {@code Configuration} object.
	 * @throws IOException if access to persistent storage fails.
	 * @throws SecurityException when the require permissions are not available
	 * @security ConfigurationPermission[location,CONFIGURE] if location is not
	 *           {@code null}
	 * @security ConfigurationPermission["*",CONFIGURE] if location is
	 *           {@code null}
	 */
	public Configuration createFactoryConfiguration(String factoryPid, String location) throws IOException;

	/**
	 * Get an existing {@code Configuration} object from the persistent store,
	 * or create a new {@code Configuration} object.
	 * 
	 * <p>
	 * If a {@code Configuration} with this PID already exists in Configuration
	 * Admin service return it. The location parameter is ignored in this case
	 * though it is still used for a security check.
	 * 
	 * <p>
	 * Else, return a new {@code Configuration} object. This new object is bound
	 * to the location and the properties are set to {@code null}. If the
	 * location parameter is {@code null}, it will be set when a Managed Service
	 * with the corresponding PID is registered for the first time. If the
	 * location starts with {@code ?} then the configuration is bound to all
	 * targets that are registered with the corresponding PID.
	 * 
	 * @param pid Persistent identifier.
	 * @param location The bundle location string, or {@code null}.
	 * @return An existing or new {@code Configuration} object.
	 * @throws IOException if access to persistent storage fails.
	 * @throws SecurityException when the require permissions are not available
	 * @security ConfigurationPermission[*,CONFIGURE] if location is
	 *           {@code null} or if the returned configuration {@code c} already
	 *           exists and c.location is {@code null}
	 * @security ConfigurationPermission[location,CONFIGURE] if location is not
	 *           {@code null}
	 * @security ConfigurationPermission[c.location,CONFIGURE] if the returned
	 *           configuration {@code c} already exists and c.location is not
	 *           {@code null}
	 */
	public Configuration getConfiguration(String pid, String location) throws IOException;

	/**
	 * Get an existing or new {@code Configuration} object from the persistent
	 * store.
	 * 
	 * If the {@code Configuration} object for this PID does not exist, create a
	 * new {@code Configuration} object for that PID, where properties are
	 * {@code null}. Bind its location to the calling bundle's location.
	 * 
	 * <p>
	 * Otherwise, if the location of the existing {@code Configuration} object
	 * is {@code null}, set it to the calling bundle's location.
	 * 
	 * @param pid persistent identifier.
	 * @return an existing or new {@code Configuration} matching the PID.
	 * @throws IOException if access to persistent storage fails.
	 * @throws SecurityException when the required permission is not available
	 * @security ConfigurationPermission[c.location,CONFIGURE] If the
	 *           configuration {@code c} already exists and c.location is not
	 *           {@code null}
	 */
	public Configuration getConfiguration(String pid) throws IOException;

	/**
	 * List the current {@code Configuration} objects which match the filter.
	 * 
	 * <p>
	 * Only {@code Configuration} objects with non- {@code null} properties are
	 * considered current. That is, {@code Configuration.getProperties()} is
	 * guaranteed not to return {@code null} for each of the returned
	 * {@code Configuration} objects.
	 * 
	 * <p>
	 * When there is no security on then all configurations can be returned. If
	 * security is on, the caller must have
	 * ConfigurationPermission[location,CONFIGURE].
	 * 
	 * <p>
	 * The syntax of the filter string is as defined in the {@link Filter}
	 * class. The filter can test any configuration properties including the
	 * following:
	 * <ul>
	 * <li>{@code service.pid} - the persistent identity</li>
	 * <li>{@code service.factoryPid} - the factory PID, if applicable</li>
	 * <li>{@code service.bundleLocation} - the bundle location</li>
	 * </ul>
	 * The filter can also be {@code null}, meaning that all
	 * {@code Configuration} objects should be returned.
	 * 
	 * @param filter A filter string, or {@code null} to retrieve all
	 *        {@code Configuration} objects.
	 * @return All matching {@code Configuration} objects, or {@code null} if
	 *         there aren't any.
	 * @throws IOException if access to persistent storage fails
	 * @throws InvalidSyntaxException if the filter string is invalid
	 * @security ConfigurationPermission[c.location,CONFIGURE] Only
	 *           configurations {@code c} are returned for which the caller has
	 *           this permission
	 */
	public Configuration[] listConfigurations(String filter) throws IOException, InvalidSyntaxException;
}

Back to the top