blob: 07ec03a088370cd15f5c5c22eeacc8d7bd239c07 [file] [log] [blame]
Marcel Offermansa962bc92009-11-21 17:59:33 +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 */
Pierre De Ropae4a5db2009-12-04 22:08:05 +000019package org.apache.felix.dm;
Marcel Offermansa962bc92009-11-21 17:59:33 +000020
21import java.util.ArrayList;
22import java.util.Collections;
23import java.util.List;
24
Pierre De Rop34231582010-05-23 20:05:16 +000025import org.apache.felix.dm.impl.AdapterServiceImpl;
Pierre De Rop19476fe2010-05-23 08:13:58 +000026import org.apache.felix.dm.impl.AspectServiceImpl;
Pierre De Rop13dd63d2010-05-23 21:58:28 +000027import org.apache.felix.dm.impl.BundleAdapterServiceImpl;
Marcel Offermansfaaed472010-09-08 10:07:32 +000028import org.apache.felix.dm.impl.ComponentImpl;
Pierre De Rop3e100372010-05-24 12:43:44 +000029import org.apache.felix.dm.impl.FactoryConfigurationAdapterServiceImpl;
Pierre De Ropae4a5db2009-12-04 22:08:05 +000030import org.apache.felix.dm.impl.Logger;
Pierre De Rop445ddec2010-05-23 21:05:27 +000031import org.apache.felix.dm.impl.ResourceAdapterServiceImpl;
Pierre De Ropae4a5db2009-12-04 22:08:05 +000032import org.apache.felix.dm.impl.dependencies.BundleDependencyImpl;
33import org.apache.felix.dm.impl.dependencies.ConfigurationDependencyImpl;
34import org.apache.felix.dm.impl.dependencies.ResourceDependencyImpl;
35import org.apache.felix.dm.impl.dependencies.ServiceDependencyImpl;
36import org.apache.felix.dm.impl.dependencies.TemporalServiceDependencyImpl;
Pierre De Ropa0204f52010-03-06 22:23:57 +000037import org.apache.felix.dm.impl.metatype.PropertyMetaDataImpl;
Marcel Offermansfd7deb02011-04-20 11:26:09 +000038import org.apache.felix.dm.index.AspectFilterIndex;
Marcel Offermans227dd712011-04-19 07:14:22 +000039import org.apache.felix.dm.index.MultiPropertyExactFilter;
40import org.apache.felix.dm.index.ServiceRegistryCache;
Marcel Offermansb8405a52009-12-22 19:01:31 +000041import org.osgi.framework.BundleContext;
Marcel Offermans227dd712011-04-19 07:14:22 +000042import org.osgi.framework.FrameworkUtil;
Marcel Offermansa962bc92009-11-21 17:59:33 +000043
44/**
Marcel Offermansfaaed472010-09-08 10:07:32 +000045 * The dependency manager manages all components and their dependencies. Using
46 * this API you can declare all components and their dependencies. Under normal
Marcel Offermans4fd903f2009-12-29 09:18:05 +000047 * circumstances, you get passed an instance of this class through the
48 * <code>DependencyActivatorBase</code> subclass you use as your
49 * <code>BundleActivator</code>, but it is also possible to create your
50 * own instance.
Marcel Offermansa962bc92009-11-21 17:59:33 +000051 *
52 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
53 */
54public class DependencyManager {
Marcel Offermansad760672010-03-03 15:30:01 +000055 public static final String ASPECT = "org.apache.felix.dependencymanager.aspect";
Marcel Offermans227dd712011-04-19 07:14:22 +000056 public static final String SERVICEREGISTRY_CACHE_INDICES = "dm.index"; // TODO rename
Marcel Offermansa962bc92009-11-21 17:59:33 +000057 private final BundleContext m_context;
58 private final Logger m_logger;
59 private List m_services = Collections.synchronizedList(new ArrayList());
60
61 /**
Marcel Offermans4fd903f2009-12-29 09:18:05 +000062 * Creates a new dependency manager. You need to supply the
63 * <code>BundleContext</code> to be used by the dependency
64 * manager to register services and communicate with the
65 * framework.
Marcel Offermansa962bc92009-11-21 17:59:33 +000066 *
67 * @param context the bundle context
Marcel Offermansa962bc92009-11-21 17:59:33 +000068 */
Pierre De Ropae4a5db2009-12-04 22:08:05 +000069 public DependencyManager(BundleContext context) {
70 this(context, new Logger(context));
71 }
72
Marcel Offermans4fd903f2009-12-29 09:18:05 +000073 DependencyManager(BundleContext context, Logger logger) {
Marcel Offermans227dd712011-04-19 07:14:22 +000074 m_context = createContext(context);
Marcel Offermansa962bc92009-11-21 17:59:33 +000075 m_logger = logger;
76 }
Pierre De Ropae4a5db2009-12-04 22:08:05 +000077
Marcel Offermans227dd712011-04-19 07:14:22 +000078 // service registry cache
79 private static ServiceRegistryCache m_serviceRegistryCache;
80 static {
81 String index = System.getProperty(SERVICEREGISTRY_CACHE_INDICES);
Marcel Offermans227dd712011-04-19 07:14:22 +000082 if (index != null) {
Marcel Offermansfd7deb02011-04-20 11:26:09 +000083 m_serviceRegistryCache = new ServiceRegistryCache(FrameworkUtil.getBundle(DependencyManager.class).getBundleContext());
84 m_serviceRegistryCache.open(); // TODO close it somewhere
Marcel Offermans227dd712011-04-19 07:14:22 +000085 String[] props = index.split(";");
86 for (int i = 0; i < props.length; i++) {
Marcel Offermansfd7deb02011-04-20 11:26:09 +000087 if (props[i].equals("*aspect*")) {
88 m_serviceRegistryCache.addFilterIndex(new AspectFilterIndex());
89 }
90 else {
91 String[] propList = props[i].split(",");
92 m_serviceRegistryCache.addFilterIndex(new MultiPropertyExactFilter(propList));
93 }
Marcel Offermans227dd712011-04-19 07:14:22 +000094// System.out.println("DM: Creating index on " + props[i]);
95 }
96 }
97 else {
98// System.out.println("DM: Property 'dm.index' not found, not setting indices.");
99 }
100
101 }
102
103 private BundleContext createContext(BundleContext context) {
104 if (m_serviceRegistryCache != null) {
105// System.out.println("DM: Enabling bundle context interceptor for bundle #" + context.getBundle().getBundleId());
106 return m_serviceRegistryCache.createBundleContextInterceptor(context);
107 }
108 else {
109 return context;
110 }
111 }
112
113// private BundleContext createContextX(BundleContext context) {
114// System.out.println("DM: Enabling bundle context interceptor for bundle #" + context.getBundle().getBundleId());
115// BundleContextInterceptor result = new BundleContextInterceptor(context);
116// if (BundleContextInterceptor.indices() == 0) {
117// String index = System.getProperty("dm.index");
118// if (index != null) {
119// String[] props = index.split(";");
120// for (int i = 0; i < props.length; i++) {
121// String[] propList = props[i].split(",");
122// MultiPropertyExactFilter filter;
123// try {
124// filter = new MultiPropertyExactFilter(result, propList);
125// m_filterIndices.add(filter);
126// System.out.println("DM: Creating index on " + props[i]);
127// }
128// catch (InvalidSyntaxException e) {
129// // TODO Auto-generated catch block
130// e.printStackTrace();
131// }
132// }
133// }
134// else {
135// System.out.println("DM: Property 'dm.index' not found, not setting indices.");
136// }
137// }
138// System.out.println("DM: Indices created, setting them on the interceptor.");
139// Iterator iterator = m_filterIndices.iterator();
140// while (iterator.hasNext()) {
141// FilterIndex filter = (FilterIndex) iterator.next();
142// result.addFilterIndex(filter);
143// }
144// return result;
145// }
146
Marcel Offermansa962bc92009-11-21 17:59:33 +0000147 /**
148 * Adds a new service to the dependency manager. After the service was added
149 * it will be started immediately.
150 *
151 * @param service the service to add
152 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000153 public void add(Component service) {
Marcel Offermansa962bc92009-11-21 17:59:33 +0000154 m_services.add(service);
155 service.start();
156 }
157
158 /**
159 * Removes a service from the dependency manager. Before the service is removed
160 * it is stopped first.
161 *
162 * @param service the service to remove
163 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000164 public void remove(Component service) {
Marcel Offermansa962bc92009-11-21 17:59:33 +0000165 service.stop();
166 m_services.remove(service);
167 }
168
169 /**
170 * Creates a new service.
171 *
172 * @return the new service
173 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000174 public Component createComponent() {
175 return new ComponentImpl(m_context, this, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000176 }
177
178 /**
179 * Creates a new service dependency.
180 *
181 * @return the service dependency
182 */
183 public ServiceDependency createServiceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000184 return new ServiceDependencyImpl(m_context, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000185 }
186
Marcel Offermans74363c32009-11-23 19:56:08 +0000187 /**
188 * Creates a new temporal service dependency.
189 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000190 * @return a new temporal service dependency
Marcel Offermans74363c32009-11-23 19:56:08 +0000191 */
192 public TemporalServiceDependency createTemporalServiceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000193 return new TemporalServiceDependencyImpl(m_context, m_logger);
Marcel Offermans74363c32009-11-23 19:56:08 +0000194 }
Marcel Offermans2925f172009-12-02 13:03:39 +0000195
196 /**
197 * Creates a new configuration dependency.
198 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000199 * @return the configuration dependency
Marcel Offermans2925f172009-12-02 13:03:39 +0000200 */
Marcel Offermansa962bc92009-11-21 17:59:33 +0000201 public ConfigurationDependency createConfigurationDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000202 return new ConfigurationDependencyImpl(m_context, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000203 }
204
Marcel Offermans2925f172009-12-02 13:03:39 +0000205 /**
Marcel Offermansfaaed472010-09-08 10:07:32 +0000206 * Creates a new configuration property metadata.
207 *
208 * @return the configuration property metadata.
Pierre De Ropa0204f52010-03-06 22:23:57 +0000209 */
210 public PropertyMetaData createPropertyMetaData() {
211 return new PropertyMetaDataImpl();
212 }
213
214 /**
Marcel Offermans2925f172009-12-02 13:03:39 +0000215 * Creates a new bundle dependency.
216 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000217 * @return a new BundleDependency instance.
Marcel Offermans2925f172009-12-02 13:03:39 +0000218 */
Marcel Offermansd66c5ce2009-11-26 09:58:44 +0000219 public BundleDependency createBundleDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000220 return new BundleDependencyImpl(m_context, m_logger);
Marcel Offermansd66c5ce2009-11-26 09:58:44 +0000221 }
Marcel Offermans2925f172009-12-02 13:03:39 +0000222
223 /**
224 * Creates a new resource dependency.
225 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000226 * @return the resource dependency
Marcel Offermans2925f172009-12-02 13:03:39 +0000227 */
228 public ResourceDependency createResourceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000229 return new ResourceDependencyImpl(m_context, m_logger);
Marcel Offermans2925f172009-12-02 13:03:39 +0000230 }
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000231
Marcel Offermans2925f172009-12-02 13:03:39 +0000232 /**
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000233 * Creates a new aspect. The aspect will be applied to any service that
234 * matches the specified interface and filter. For each matching service
235 * an aspect will be created based on the aspect implementation class.
236 * The aspect will be registered with the same interface and properties
237 * as the original service, plus any extra properties you supply here.
238 * It will also inherit all dependencies, and if you declare the original
239 * service as a member it will be injected.
Marcel Offermans2925f172009-12-02 13:03:39 +0000240 *
Pierre De Rop19476fe2010-05-23 08:13:58 +0000241 * <h3>Usage Example</h3>
242 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000243 * <blockquote><pre>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000244 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_service")
245 * .setImplementation(ExistingServiceAspect.class)
246 * );
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000247 * </pre></blockquote>
Pierre De Rop19476fe2010-05-23 08:13:58 +0000248 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000249 * @param serviceInterface the service interface to apply the aspect to
250 * @param serviceFilter the filter condition to use with the service interface
Pierre De Rop19476fe2010-05-23 08:13:58 +0000251 * @param ranking the level used to organize the aspect chain ordering
Marcel Offermansa8818d52011-03-09 10:03:35 +0000252 * @param autoConfig the aspect implementation field name where to inject original service.
Marcel Offermansfaaed472010-09-08 10:07:32 +0000253 * If null, any field matching the original service will be injected.
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000254 * @return a service that acts as a factory for generating aspects
Marcel Offermans2925f172009-12-02 13:03:39 +0000255 */
Marcel Offermansa8818d52011-03-09 10:03:35 +0000256 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String autoConfig) {
257 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null);
258 }
259 /**
260 * Creates a new aspect. The aspect will be applied to any service that
261 * matches the specified interface and filter. For each matching service
262 * an aspect will be created based on the aspect implementation class.
263 * The aspect will be registered with the same interface and properties
264 * as the original service, plus any extra properties you supply here.
265 * It will also inherit all dependencies, and if you declare the original
266 * service as a member it will be injected.
267 *
268 * <h3>Usage Example</h3>
269 *
270 * <blockquote><pre>
271 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10)
272 * .setImplementation(ExistingServiceAspect.class)
273 * );
274 * </pre></blockquote>
275 *
276 * @param serviceInterface the service interface to apply the aspect to
277 * @param serviceFilter the filter condition to use with the service interface
278 * @param ranking the level used to organize the aspect chain ordering
279 * @return a service that acts as a factory for generating aspects
280 */
281 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking) {
282 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null);
283 }
284 /**
285 * Creates a new aspect. The aspect will be applied to any service that
286 * matches the specified interface and filter. For each matching service
287 * an aspect will be created based on the aspect implementation class.
288 * The aspect will be registered with the same interface and properties
289 * as the original service, plus any extra properties you supply here.
290 * It will also inherit all dependencies, and if you declare the original
291 * service as a member it will be injected.
292 *
293 * <h3>Usage Example</h3>
294 *
295 * <blockquote><pre>
296 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
297 * .setImplementation(ExistingServiceAspect.class)
298 * );
299 * </pre></blockquote>
300 *
301 * @param serviceInterface the service interface to apply the aspect to
302 * @param serviceFilter the filter condition to use with the service interface
303 * @param ranking the level used to organize the aspect chain ordering
304 * @param add name of the callback method to invoke on add
305 * @param change name of the callback method to invoke on change
306 * @param remove name of the callback method to invoke on remove
307 * @return a service that acts as a factory for generating aspects
308 */
309 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) {
310 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove);
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000311 }
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000312
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000313 /**
314 * Creates a new adapter. The adapter will be applied to any service that
315 * matches the specified interface and filter. For each matching service
316 * an adapter will be created based on the adapter implementation class.
317 * The adapter will be registered with the specified interface and existing properties
318 * from the original service plus any extra properties you supply here.
319 * It will also inherit all dependencies, and if you declare the original
320 * service as a member it will be injected.
321 *
Pierre De Rop34231582010-05-23 20:05:16 +0000322 * <h3>Usage Example</h3>
323 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000324 * <blockquote><pre>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000325 * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
326 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
327 * .setImplementation(AdapterImpl.class);
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000328 * </pre></blockquote>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000329 *
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000330 * @param serviceInterface the service interface to apply the adapter to
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000331 * @param serviceFilter the filter condition to use with the service interface
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000332 * @return a service that acts as a factory for generating adapters
333 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000334 public Component createAdapterService(Class serviceInterface, String serviceFilter) {
Marcel Offermansa8818d52011-03-09 10:03:35 +0000335 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null);
336 }
337 /**
338 * Creates a new adapter. The adapter will be applied to any service that
339 * matches the specified interface and filter. For each matching service
340 * an adapter will be created based on the adapter implementation class.
341 * The adapter will be registered with the specified interface and existing properties
342 * from the original service plus any extra properties you supply here.
343 * It will also inherit all dependencies, and if you declare the original
344 * service as a member it will be injected.
345 *
346 * <h3>Usage Example</h3>
347 *
348 * <blockquote><pre>
349 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "m_service")
350 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
351 * .setImplementation(AdapterImpl.class);
352 * </pre></blockquote>
353 *
354 * @param serviceInterface the service interface to apply the adapter to
355 * @param serviceFilter the filter condition to use with the service interface
356 * @param autoConfig the name of the member to inject the service into
357 * @return a service that acts as a factory for generating adapters
358 */
359 public Component createAdapterService(Class serviceInterface, String serviceFilter, String autoConfig) {
360 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null);
361 }
362 /**
363 * Creates a new adapter. The adapter will be applied to any service that
364 * matches the specified interface and filter. For each matching service
365 * an adapter will be created based on the adapter implementation class.
366 * The adapter will be registered with the specified interface and existing properties
367 * from the original service plus any extra properties you supply here.
368 * It will also inherit all dependencies, and if you declare the original
369 * service as a member it will be injected.
370 *
371 * <h3>Usage Example</h3>
372 *
373 * <blockquote><pre>
374 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove")
375 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
376 * .setImplementation(AdapterImpl.class);
377 * </pre></blockquote>
378 *
379 * @param serviceInterface the service interface to apply the adapter to
380 * @param serviceFilter the filter condition to use with the service interface
381 * @param add name of the callback method to invoke on add
382 * @param change name of the callback method to invoke on change
383 * @param remove name of the callback method to invoke on remove
384 * @return a service that acts as a factory for generating adapters
385 */
386 public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, String remove) {
387 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, add, change, remove);
Marcel Offermans61a81142010-04-02 15:16:50 +0000388 }
Pierre De Rop34231582010-05-23 20:05:16 +0000389
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000390 /**
391 * Creates a new resource adapter. The adapter will be applied to any resource that
392 * matches the specified filter condition. For each matching resource
393 * an adapter will be created based on the adapter implementation class.
394 * The adapter will be registered with the specified interface and existing properties
395 * from the original resource plus any extra properties you supply here.
396 * It will also inherit all dependencies, and if you declare the original
397 * service as a member it will be injected.
398 *
Pierre De Rop445ddec2010-05-23 21:05:27 +0000399 * <h3>Usage Example</h3>
400 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000401 * <blockquote><pre>
Pierre De Rop445ddec2010-05-23 21:05:27 +0000402 * manager.createResourceAdapterService("(&(path=/test)(repository=TestRepository))", true)
403 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000404 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop445ddec2010-05-23 21:05:27 +0000405 * // the implementation of the adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000406 * .setImplementation(AdapterServiceImpl.class);
407 * </pre></blockquote>
Pierre De Rop445ddec2010-05-23 21:05:27 +0000408 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000409 * @param resourceFilter the filter condition to use with the resource
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000410 * @param propagate <code>true</code> if properties from the resource should be propagated to the service
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000411 * @param callbackInstance
412 * @param callbackChanged
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000413 * @return a service that acts as a factory for generating resource adapters
414 * @see Resource
415 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000416 public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance, String callbackChanged) {
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000417 return new ResourceAdapterServiceImpl(this, resourceFilter, propagate, callbackInstance, callbackChanged);
Marcel Offermans61a81142010-04-02 15:16:50 +0000418 }
Pierre De Rop445ddec2010-05-23 21:05:27 +0000419
Marcel Offermansfaaed472010-09-08 10:07:32 +0000420 public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) {
Marcel Offermans26081d32010-07-12 12:43:42 +0000421 return new ResourceAdapterServiceImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, callbackChanged);
422 }
423
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000424 /**
425 * Creates a new bundle adapter. The adapter will be applied to any bundle that
426 * matches the specified bundle state mask and filter condition. For each matching
427 * bundle an adapter will be created based on the adapter implementation class.
428 * The adapter will be registered with the specified interface
429 *
430 * TODO and existing properties from the original resource plus any extra properties you supply here.
431 * It will also inherit all dependencies, and if you declare the original
432 * service as a member it will be injected.
433 *
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000434 * <h3>Usage Example</h3>
435 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000436 * <blockquote><pre>
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000437 * manager.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE,
438 * "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
439 * true)
440 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000441 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000442 * // the implementation of the adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000443 * .setImplementation(AdapterServiceImpl.class);
444 * </pre></blockquote>
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000445 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000446 * @param bundleStateMask the bundle state mask to apply
447 * @param bundleFilter the filter to apply to the bundle manifest
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000448 * @param propagate <code>true</code> if properties from the bundle should be propagated to the service
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000449 * @return a service that acts as a factory for generating bundle adapters
450 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000451 public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000452 return new BundleAdapterServiceImpl(this, bundleStateMask, bundleFilter, propagate);
Marcel Offermans61a81142010-04-02 15:16:50 +0000453 }
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000454
Marcel Offermansa962bc92009-11-21 17:59:33 +0000455 /**
Pierre De Ropef94c882010-04-17 18:23:35 +0000456 * Creates a new Managed Service Factory Configuration Adapter. For each new Config Admin factory configuration matching
457 * the factoryPid, an adapter will be created based on the adapter implementation class.
458 * The adapter will be registered with the specified interface, and with the specified adapter service properties.
459 * Depending on the <code>propagate</code> parameter, every public factory configuration properties
460 * (which don't start with ".") will be propagated along with the adapter service properties.
461 * It will also inherit all dependencies.
462 *
Pierre De Rop3e100372010-05-24 12:43:44 +0000463 * <h3>Usage Example</h3>
464 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000465 * <blockquote><pre>
Pierre De Rop3e100372010-05-24 12:43:44 +0000466 * manager.createFactoryConfigurationAdapterService("MyFactoryPid", "update", true)
467 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000468 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop3e100372010-05-24 12:43:44 +0000469 * // the implementation of the adapter
470 * .setImplementation(AdapterServiceImpl.class);
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000471 * </pre></blockquote>
472 *
Pierre De Ropef94c882010-04-17 18:23:35 +0000473 * @param factoryPid the pid matching the factory configuration
474 * @param update the adapter method name that will be notified when the factory configuration is created/updated.
Pierre De Ropef94c882010-04-17 18:23:35 +0000475 * @param propagate true if public factory configuration should be propagated to the adapter service properties
476 * @return a service that acts as a factory for generating the managed service factory configuration adapter
477 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000478 public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) {
Pierre De Rop3e100372010-05-24 12:43:44 +0000479 return new FactoryConfigurationAdapterServiceImpl(this, factoryPid, update, propagate);
Pierre De Ropef94c882010-04-17 18:23:35 +0000480 }
481
482 /**
Pierre De Rop3e100372010-05-24 12:43:44 +0000483 * Creates a new Managed Service Factory Configuration Adapter with meta type support. For each new Config Admin
484 * factory configuration matching the factoryPid, an adapter will be created based on the adapter implementation
485 * class. The adapter will be registered with the specified interface, and with the specified adapter service
486 * properties. Depending on the <code>propagate</code> parameter, every public factory configuration properties
Pierre De Ropef94c882010-04-17 18:23:35 +0000487 * (which don't start with ".") will be propagated along with the adapter service properties.
488 * It will also inherit all dependencies.
489 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000490 * <h3>Usage Example</h3>
491 *
492 * <blockquote><pre>
493 * PropertyMetaData[] propertiesMetaData = new PropertyMetaData[] {
494 * manager.createPropertyMetaData()
495 * .setCardinality(Integer.MAX_VALUE)
496 * .setType(String.class)
497 * .setHeading("English words")
498 * .setDescription("Declare here some valid english words")
499 * .setDefaults(new String[] {"hello", "world"})
500 * .setId("words")
501 * };
502 *
503 * manager.add(createFactoryConfigurationAdapterService("FactoryPid",
504 * "updated",
505 * true, // propagate CM settings
506 * "EnglishDictionary",
507 * "English dictionary configuration properties",
508 * null,
509 * propertiesMetaData)
510 * .setImplementation(Adapter.class));
511 * </pre></blockquote>
512 *
Pierre De Ropef94c882010-04-17 18:23:35 +0000513 * @param factoryPid the pid matching the factory configuration
514 * @param update the adapter method name that will be notified when the factory configuration is created/updated.
Pierre De Ropef94c882010-04-17 18:23:35 +0000515 * @param propagate true if public factory configuration should be propagated to the adapter service properties
Pierre De Rop3e100372010-05-24 12:43:44 +0000516 * @param heading The label used to display the tab name (or section) where the properties are displayed.
517 * Example: "Printer Service"
518 * @param desc A human readable description of the factory PID this configuration is associated with.
519 * Example: "Configuration for the PrinterService bundle"
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000520 * @param localization Points to the basename of the Properties file that can localize the Meta Type informations.
521 * The default localization base name for the properties is OSGI-INF/l10n/bundle, but can
Pierre De Rop3e100372010-05-24 12:43:44 +0000522 * be overridden by the manifest Bundle-Localization header (see core specification, in section Localization
523 * on page 68). You can specify a specific localization basename file using this parameter
524 * (e.g. <code>"person"</code> will match person_du_NL.properties in the root bundle directory).
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000525 * @param propertiesMetaData Array of MetaData regarding configuration properties
526 * @return a service that acts as a factory for generating the managed service factory configuration adapter
527 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000528 public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate,
Pierre De Rop3e100372010-05-24 12:43:44 +0000529 String heading, String desc, String localization,
530 PropertyMetaData[] propertiesMetaData)
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000531 {
Pierre De Rop3e100372010-05-24 12:43:44 +0000532 return new FactoryConfigurationAdapterServiceImpl(this, factoryPid, update, propagate, m_context, m_logger,
533 heading, desc, localization, propertiesMetaData);
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000534 }
535
536 /**
Marcel Offermansa962bc92009-11-21 17:59:33 +0000537 * Returns a list of services.
538 *
539 * @return a list of services
540 */
541 public List getServices() {
542 return Collections.unmodifiableList(m_services);
543 }
Marcel Offermansa962bc92009-11-21 17:59:33 +0000544}