blob: 5b16edfd2069d8b3c8dee47edf1bb2ed62a35c20 [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
Marcel Offermans5be5f142011-04-26 10:47:12 +000021import java.lang.ref.WeakReference;
Marcel Offermansa962bc92009-11-21 17:59:33 +000022import java.util.ArrayList;
23import java.util.Collections;
Marcel Offermans5be5f142011-04-26 10:47:12 +000024import java.util.HashSet;
25import java.util.Iterator;
Marcel Offermansa962bc92009-11-21 17:59:33 +000026import java.util.List;
Marcel Offermans5be5f142011-04-26 10:47:12 +000027import java.util.Set;
Marcel Offermansa962bc92009-11-21 17:59:33 +000028
Pierre De Rop34231582010-05-23 20:05:16 +000029import org.apache.felix.dm.impl.AdapterServiceImpl;
Pierre De Rop19476fe2010-05-23 08:13:58 +000030import org.apache.felix.dm.impl.AspectServiceImpl;
Pierre De Rop13dd63d2010-05-23 21:58:28 +000031import org.apache.felix.dm.impl.BundleAdapterServiceImpl;
Marcel Offermansfaaed472010-09-08 10:07:32 +000032import org.apache.felix.dm.impl.ComponentImpl;
Pierre De Rop3e100372010-05-24 12:43:44 +000033import org.apache.felix.dm.impl.FactoryConfigurationAdapterServiceImpl;
Pierre De Ropae4a5db2009-12-04 22:08:05 +000034import org.apache.felix.dm.impl.Logger;
Pierre De Rop445ddec2010-05-23 21:05:27 +000035import org.apache.felix.dm.impl.ResourceAdapterServiceImpl;
Pierre De Ropae4a5db2009-12-04 22:08:05 +000036import org.apache.felix.dm.impl.dependencies.BundleDependencyImpl;
37import org.apache.felix.dm.impl.dependencies.ConfigurationDependencyImpl;
38import org.apache.felix.dm.impl.dependencies.ResourceDependencyImpl;
39import org.apache.felix.dm.impl.dependencies.ServiceDependencyImpl;
40import org.apache.felix.dm.impl.dependencies.TemporalServiceDependencyImpl;
Marcel Offermans90ba4fa2011-04-27 07:57:44 +000041import org.apache.felix.dm.impl.index.AspectFilterIndex;
42import org.apache.felix.dm.impl.index.MultiPropertyExactFilter;
43import org.apache.felix.dm.impl.index.ServiceRegistryCache;
Pierre De Ropa0204f52010-03-06 22:23:57 +000044import org.apache.felix.dm.impl.metatype.PropertyMetaDataImpl;
Marcel Offermansb8405a52009-12-22 19:01:31 +000045import org.osgi.framework.BundleContext;
Marcel Offermans227dd712011-04-19 07:14:22 +000046import org.osgi.framework.FrameworkUtil;
Marcel Offermansa962bc92009-11-21 17:59:33 +000047
48/**
Marcel Offermansfaaed472010-09-08 10:07:32 +000049 * The dependency manager manages all components and their dependencies. Using
50 * this API you can declare all components and their dependencies. Under normal
Marcel Offermans4fd903f2009-12-29 09:18:05 +000051 * circumstances, you get passed an instance of this class through the
52 * <code>DependencyActivatorBase</code> subclass you use as your
53 * <code>BundleActivator</code>, but it is also possible to create your
54 * own instance.
Marcel Offermansa962bc92009-11-21 17:59:33 +000055 *
56 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
57 */
58public class DependencyManager {
Marcel Offermansad760672010-03-03 15:30:01 +000059 public static final String ASPECT = "org.apache.felix.dependencymanager.aspect";
Marcel Offermans227dd712011-04-19 07:14:22 +000060 public static final String SERVICEREGISTRY_CACHE_INDICES = "dm.index"; // TODO rename
Marcel Offermanse0906072011-05-17 11:09:05 +000061 public static final String METHOD_CACHE_SIZE = "org.apache.felix.dependencymanager.methodcache";
Marcel Offermansa962bc92009-11-21 17:59:33 +000062 private final BundleContext m_context;
63 private final Logger m_logger;
Marcel Offermans5be5f142011-04-26 10:47:12 +000064 private List m_components = Collections.synchronizedList(new ArrayList());
Marcel Offermansa962bc92009-11-21 17:59:33 +000065
66 /**
Marcel Offermans4fd903f2009-12-29 09:18:05 +000067 * Creates a new dependency manager. You need to supply the
68 * <code>BundleContext</code> to be used by the dependency
69 * manager to register services and communicate with the
70 * framework.
Marcel Offermansa962bc92009-11-21 17:59:33 +000071 *
72 * @param context the bundle context
Marcel Offermansa962bc92009-11-21 17:59:33 +000073 */
Pierre De Ropae4a5db2009-12-04 22:08:05 +000074 public DependencyManager(BundleContext context) {
75 this(context, new Logger(context));
76 }
77
Marcel Offermans4fd903f2009-12-29 09:18:05 +000078 DependencyManager(BundleContext context, Logger logger) {
Marcel Offermans227dd712011-04-19 07:14:22 +000079 m_context = createContext(context);
Marcel Offermansa962bc92009-11-21 17:59:33 +000080 m_logger = logger;
Marcel Offermans5be5f142011-04-26 10:47:12 +000081 synchronized (m_dependencyManagers) {
82 m_dependencyManagers.add(new WeakReference(this));
83 }
Marcel Offermansa962bc92009-11-21 17:59:33 +000084 }
Pierre De Ropae4a5db2009-12-04 22:08:05 +000085
Marcel Offermans227dd712011-04-19 07:14:22 +000086 // service registry cache
87 private static ServiceRegistryCache m_serviceRegistryCache;
Marcel Offermans5be5f142011-04-26 10:47:12 +000088 private static final Set /* WeakReference<DependencyManager> */ m_dependencyManagers = new HashSet();
Marcel Offermans227dd712011-04-19 07:14:22 +000089 static {
90 String index = System.getProperty(SERVICEREGISTRY_CACHE_INDICES);
Marcel Offermans227dd712011-04-19 07:14:22 +000091 if (index != null) {
Marcel Offermansfd7deb02011-04-20 11:26:09 +000092 m_serviceRegistryCache = new ServiceRegistryCache(FrameworkUtil.getBundle(DependencyManager.class).getBundleContext());
93 m_serviceRegistryCache.open(); // TODO close it somewhere
Marcel Offermans227dd712011-04-19 07:14:22 +000094 String[] props = index.split(";");
95 for (int i = 0; i < props.length; i++) {
Marcel Offermansfd7deb02011-04-20 11:26:09 +000096 if (props[i].equals("*aspect*")) {
97 m_serviceRegistryCache.addFilterIndex(new AspectFilterIndex());
98 }
99 else {
100 String[] propList = props[i].split(",");
101 m_serviceRegistryCache.addFilterIndex(new MultiPropertyExactFilter(propList));
102 }
Marcel Offermans227dd712011-04-19 07:14:22 +0000103 }
104 }
Marcel Offermans5be5f142011-04-26 10:47:12 +0000105 }
106
107 public static List getDependencyManagers() {
108 List /* DependencyManager */ result = new ArrayList();
109 synchronized (m_dependencyManagers) {
110 Iterator iterator = m_dependencyManagers.iterator();
111 while (iterator.hasNext()) {
112 WeakReference reference = (WeakReference) iterator.next();
113 DependencyManager manager = (DependencyManager) reference.get();
114 if (manager != null) {
Marcel Offermansc7fbf782011-05-18 14:34:33 +0000115 try {
116 manager.getBundleContext().getBundle();
117 result.add(manager);
118 continue;
119 }
120 catch (IllegalStateException e) {
121 }
Marcel Offermans5be5f142011-04-26 10:47:12 +0000122 }
Marcel Offermansc7fbf782011-05-18 14:34:33 +0000123 iterator.remove();
Marcel Offermans5be5f142011-04-26 10:47:12 +0000124 }
Marcel Offermans227dd712011-04-19 07:14:22 +0000125 }
Marcel Offermans5be5f142011-04-26 10:47:12 +0000126 return result;
Marcel Offermans227dd712011-04-19 07:14:22 +0000127 }
128
129 private BundleContext createContext(BundleContext context) {
130 if (m_serviceRegistryCache != null) {
131// System.out.println("DM: Enabling bundle context interceptor for bundle #" + context.getBundle().getBundleId());
132 return m_serviceRegistryCache.createBundleContextInterceptor(context);
133 }
134 else {
135 return context;
136 }
137 }
Marcel Offermans5be5f142011-04-26 10:47:12 +0000138
139 public BundleContext getBundleContext() {
140 return m_context;
141 }
Marcel Offermans227dd712011-04-19 07:14:22 +0000142
Marcel Offermansa962bc92009-11-21 17:59:33 +0000143 /**
144 * Adds a new service to the dependency manager. After the service was added
145 * it will be started immediately.
146 *
147 * @param service the service to add
148 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000149 public void add(Component service) {
Marcel Offermans5be5f142011-04-26 10:47:12 +0000150 m_components.add(service);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000151 service.start();
152 }
153
154 /**
155 * Removes a service from the dependency manager. Before the service is removed
156 * it is stopped first.
157 *
158 * @param service the service to remove
159 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000160 public void remove(Component service) {
Marcel Offermansa962bc92009-11-21 17:59:33 +0000161 service.stop();
Marcel Offermans5be5f142011-04-26 10:47:12 +0000162 m_components.remove(service);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000163 }
164
165 /**
166 * Creates a new service.
167 *
168 * @return the new service
169 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000170 public Component createComponent() {
171 return new ComponentImpl(m_context, this, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000172 }
173
174 /**
175 * Creates a new service dependency.
176 *
177 * @return the service dependency
178 */
179 public ServiceDependency createServiceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000180 return new ServiceDependencyImpl(m_context, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000181 }
182
Marcel Offermans74363c32009-11-23 19:56:08 +0000183 /**
184 * Creates a new temporal service dependency.
185 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000186 * @return a new temporal service dependency
Marcel Offermans74363c32009-11-23 19:56:08 +0000187 */
188 public TemporalServiceDependency createTemporalServiceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000189 return new TemporalServiceDependencyImpl(m_context, m_logger);
Marcel Offermans74363c32009-11-23 19:56:08 +0000190 }
Marcel Offermans2925f172009-12-02 13:03:39 +0000191
192 /**
193 * Creates a new configuration dependency.
194 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000195 * @return the configuration dependency
Marcel Offermans2925f172009-12-02 13:03:39 +0000196 */
Marcel Offermansa962bc92009-11-21 17:59:33 +0000197 public ConfigurationDependency createConfigurationDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000198 return new ConfigurationDependencyImpl(m_context, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000199 }
200
Marcel Offermans2925f172009-12-02 13:03:39 +0000201 /**
Marcel Offermansfaaed472010-09-08 10:07:32 +0000202 * Creates a new configuration property metadata.
203 *
204 * @return the configuration property metadata.
Pierre De Ropa0204f52010-03-06 22:23:57 +0000205 */
206 public PropertyMetaData createPropertyMetaData() {
207 return new PropertyMetaDataImpl();
208 }
209
210 /**
Marcel Offermans2925f172009-12-02 13:03:39 +0000211 * Creates a new bundle dependency.
212 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000213 * @return a new BundleDependency instance.
Marcel Offermans2925f172009-12-02 13:03:39 +0000214 */
Marcel Offermansd66c5ce2009-11-26 09:58:44 +0000215 public BundleDependency createBundleDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000216 return new BundleDependencyImpl(m_context, m_logger);
Marcel Offermansd66c5ce2009-11-26 09:58:44 +0000217 }
Marcel Offermans2925f172009-12-02 13:03:39 +0000218
219 /**
220 * Creates a new resource dependency.
221 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000222 * @return the resource dependency
Marcel Offermans2925f172009-12-02 13:03:39 +0000223 */
224 public ResourceDependency createResourceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000225 return new ResourceDependencyImpl(m_context, m_logger);
Marcel Offermans2925f172009-12-02 13:03:39 +0000226 }
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000227
Marcel Offermans2925f172009-12-02 13:03:39 +0000228 /**
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000229 * Creates a new aspect. The aspect will be applied to any service that
230 * matches the specified interface and filter. For each matching service
231 * an aspect will be created based on the aspect implementation class.
232 * The aspect will be registered with the same interface and properties
233 * as the original service, plus any extra properties you supply here.
234 * It will also inherit all dependencies, and if you declare the original
235 * service as a member it will be injected.
Marcel Offermans2925f172009-12-02 13:03:39 +0000236 *
Pierre De Rop19476fe2010-05-23 08:13:58 +0000237 * <h3>Usage Example</h3>
238 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000239 * <blockquote><pre>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000240 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_service")
241 * .setImplementation(ExistingServiceAspect.class)
242 * );
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000243 * </pre></blockquote>
Pierre De Rop19476fe2010-05-23 08:13:58 +0000244 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000245 * @param serviceInterface the service interface to apply the aspect to
246 * @param serviceFilter the filter condition to use with the service interface
Pierre De Rop19476fe2010-05-23 08:13:58 +0000247 * @param ranking the level used to organize the aspect chain ordering
Marcel Offermansa8818d52011-03-09 10:03:35 +0000248 * @param autoConfig the aspect implementation field name where to inject original service.
Marcel Offermansfaaed472010-09-08 10:07:32 +0000249 * If null, any field matching the original service will be injected.
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000250 * @return a service that acts as a factory for generating aspects
Marcel Offermans2925f172009-12-02 13:03:39 +0000251 */
Marcel Offermansa8818d52011-03-09 10:03:35 +0000252 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String autoConfig) {
253 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null);
254 }
255 /**
256 * Creates a new aspect. The aspect will be applied to any service that
257 * matches the specified interface and filter. For each matching service
258 * an aspect will be created based on the aspect implementation class.
259 * The aspect will be registered with the same interface and properties
260 * as the original service, plus any extra properties you supply here.
261 * It will also inherit all dependencies, and if you declare the original
262 * service as a member it will be injected.
263 *
264 * <h3>Usage Example</h3>
265 *
266 * <blockquote><pre>
267 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10)
268 * .setImplementation(ExistingServiceAspect.class)
269 * );
270 * </pre></blockquote>
271 *
272 * @param serviceInterface the service interface to apply the aspect to
273 * @param serviceFilter the filter condition to use with the service interface
274 * @param ranking the level used to organize the aspect chain ordering
275 * @return a service that acts as a factory for generating aspects
276 */
277 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking) {
278 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null);
279 }
280 /**
281 * Creates a new aspect. The aspect will be applied to any service that
282 * matches the specified interface and filter. For each matching service
283 * an aspect will be created based on the aspect implementation class.
284 * The aspect will be registered with the same interface and properties
285 * as the original service, plus any extra properties you supply here.
286 * It will also inherit all dependencies, and if you declare the original
287 * service as a member it will be injected.
288 *
289 * <h3>Usage Example</h3>
290 *
291 * <blockquote><pre>
292 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
293 * .setImplementation(ExistingServiceAspect.class)
294 * );
295 * </pre></blockquote>
296 *
297 * @param serviceInterface the service interface to apply the aspect to
298 * @param serviceFilter the filter condition to use with the service interface
299 * @param ranking the level used to organize the aspect chain ordering
300 * @param add name of the callback method to invoke on add
301 * @param change name of the callback method to invoke on change
302 * @param remove name of the callback method to invoke on remove
303 * @return a service that acts as a factory for generating aspects
304 */
305 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) {
306 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove);
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000307 }
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000308
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000309 /**
310 * Creates a new adapter. The adapter will be applied to any service that
311 * matches the specified interface and filter. For each matching service
312 * an adapter will be created based on the adapter implementation class.
313 * The adapter will be registered with the specified interface and existing properties
314 * from the original service plus any extra properties you supply here.
315 * It will also inherit all dependencies, and if you declare the original
316 * service as a member it will be injected.
317 *
Pierre De Rop34231582010-05-23 20:05:16 +0000318 * <h3>Usage Example</h3>
319 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000320 * <blockquote><pre>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000321 * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
322 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
323 * .setImplementation(AdapterImpl.class);
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000324 * </pre></blockquote>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000325 *
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000326 * @param serviceInterface the service interface to apply the adapter to
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000327 * @param serviceFilter the filter condition to use with the service interface
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000328 * @return a service that acts as a factory for generating adapters
329 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000330 public Component createAdapterService(Class serviceInterface, String serviceFilter) {
Marcel Offermansa8818d52011-03-09 10:03:35 +0000331 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null);
332 }
333 /**
334 * Creates a new adapter. The adapter will be applied to any service that
335 * matches the specified interface and filter. For each matching service
336 * an adapter will be created based on the adapter implementation class.
337 * The adapter will be registered with the specified interface and existing properties
338 * from the original service plus any extra properties you supply here.
339 * It will also inherit all dependencies, and if you declare the original
340 * service as a member it will be injected.
341 *
342 * <h3>Usage Example</h3>
343 *
344 * <blockquote><pre>
345 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "m_service")
346 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
347 * .setImplementation(AdapterImpl.class);
348 * </pre></blockquote>
349 *
350 * @param serviceInterface the service interface to apply the adapter to
351 * @param serviceFilter the filter condition to use with the service interface
352 * @param autoConfig the name of the member to inject the service into
353 * @return a service that acts as a factory for generating adapters
354 */
355 public Component createAdapterService(Class serviceInterface, String serviceFilter, String autoConfig) {
356 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null);
357 }
358 /**
359 * Creates a new adapter. The adapter will be applied to any service that
360 * matches the specified interface and filter. For each matching service
361 * an adapter will be created based on the adapter implementation class.
362 * The adapter will be registered with the specified interface and existing properties
363 * from the original service plus any extra properties you supply here.
364 * It will also inherit all dependencies, and if you declare the original
365 * service as a member it will be injected.
366 *
367 * <h3>Usage Example</h3>
368 *
369 * <blockquote><pre>
370 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove")
371 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
372 * .setImplementation(AdapterImpl.class);
373 * </pre></blockquote>
374 *
375 * @param serviceInterface the service interface to apply the adapter to
376 * @param serviceFilter the filter condition to use with the service interface
377 * @param add name of the callback method to invoke on add
378 * @param change name of the callback method to invoke on change
379 * @param remove name of the callback method to invoke on remove
380 * @return a service that acts as a factory for generating adapters
381 */
382 public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, String remove) {
383 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, add, change, remove);
Marcel Offermans61a81142010-04-02 15:16:50 +0000384 }
Pierre De Rop34231582010-05-23 20:05:16 +0000385
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000386 /**
387 * Creates a new resource adapter. The adapter will be applied to any resource that
388 * matches the specified filter condition. For each matching resource
389 * an adapter will be created based on the adapter implementation class.
390 * The adapter will be registered with the specified interface and existing properties
391 * from the original resource plus any extra properties you supply here.
392 * It will also inherit all dependencies, and if you declare the original
393 * service as a member it will be injected.
394 *
Pierre De Rop445ddec2010-05-23 21:05:27 +0000395 * <h3>Usage Example</h3>
396 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000397 * <blockquote><pre>
Pierre De Rop445ddec2010-05-23 21:05:27 +0000398 * manager.createResourceAdapterService("(&(path=/test)(repository=TestRepository))", true)
399 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000400 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop445ddec2010-05-23 21:05:27 +0000401 * // the implementation of the adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000402 * .setImplementation(AdapterServiceImpl.class);
403 * </pre></blockquote>
Pierre De Rop445ddec2010-05-23 21:05:27 +0000404 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000405 * @param resourceFilter the filter condition to use with the resource
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000406 * @param propagate <code>true</code> if properties from the resource should be propagated to the service
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000407 * @param callbackInstance
408 * @param callbackChanged
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000409 * @return a service that acts as a factory for generating resource adapters
410 * @see Resource
411 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000412 public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance, String callbackChanged) {
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000413 return new ResourceAdapterServiceImpl(this, resourceFilter, propagate, callbackInstance, callbackChanged);
Marcel Offermans61a81142010-04-02 15:16:50 +0000414 }
Pierre De Rop445ddec2010-05-23 21:05:27 +0000415
Marcel Offermansfaaed472010-09-08 10:07:32 +0000416 public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) {
Marcel Offermans26081d32010-07-12 12:43:42 +0000417 return new ResourceAdapterServiceImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, callbackChanged);
418 }
419
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000420 /**
421 * Creates a new bundle adapter. The adapter will be applied to any bundle that
422 * matches the specified bundle state mask and filter condition. For each matching
423 * bundle an adapter will be created based on the adapter implementation class.
424 * The adapter will be registered with the specified interface
425 *
426 * TODO and existing properties from the original resource plus any extra properties you supply here.
427 * It will also inherit all dependencies, and if you declare the original
428 * service as a member it will be injected.
429 *
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000430 * <h3>Usage Example</h3>
431 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000432 * <blockquote><pre>
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000433 * manager.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE,
434 * "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
435 * true)
436 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000437 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000438 * // the implementation of the adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000439 * .setImplementation(AdapterServiceImpl.class);
440 * </pre></blockquote>
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000441 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000442 * @param bundleStateMask the bundle state mask to apply
443 * @param bundleFilter the filter to apply to the bundle manifest
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000444 * @param propagate <code>true</code> if properties from the bundle should be propagated to the service
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000445 * @return a service that acts as a factory for generating bundle adapters
446 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000447 public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000448 return new BundleAdapterServiceImpl(this, bundleStateMask, bundleFilter, propagate);
Marcel Offermans61a81142010-04-02 15:16:50 +0000449 }
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000450
Marcel Offermansa962bc92009-11-21 17:59:33 +0000451 /**
Pierre De Ropef94c882010-04-17 18:23:35 +0000452 * Creates a new Managed Service Factory Configuration Adapter. For each new Config Admin factory configuration matching
453 * the factoryPid, an adapter will be created based on the adapter implementation class.
454 * The adapter will be registered with the specified interface, and with the specified adapter service properties.
455 * Depending on the <code>propagate</code> parameter, every public factory configuration properties
456 * (which don't start with ".") will be propagated along with the adapter service properties.
457 * It will also inherit all dependencies.
458 *
Pierre De Rop3e100372010-05-24 12:43:44 +0000459 * <h3>Usage Example</h3>
460 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000461 * <blockquote><pre>
Pierre De Rop3e100372010-05-24 12:43:44 +0000462 * manager.createFactoryConfigurationAdapterService("MyFactoryPid", "update", true)
463 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000464 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop3e100372010-05-24 12:43:44 +0000465 * // the implementation of the adapter
466 * .setImplementation(AdapterServiceImpl.class);
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000467 * </pre></blockquote>
468 *
Pierre De Ropef94c882010-04-17 18:23:35 +0000469 * @param factoryPid the pid matching the factory configuration
470 * @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 +0000471 * @param propagate true if public factory configuration should be propagated to the adapter service properties
472 * @return a service that acts as a factory for generating the managed service factory configuration adapter
473 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000474 public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) {
Pierre De Rop3e100372010-05-24 12:43:44 +0000475 return new FactoryConfigurationAdapterServiceImpl(this, factoryPid, update, propagate);
Pierre De Ropef94c882010-04-17 18:23:35 +0000476 }
477
478 /**
Pierre De Rop3e100372010-05-24 12:43:44 +0000479 * Creates a new Managed Service Factory Configuration Adapter with meta type support. For each new Config Admin
480 * factory configuration matching the factoryPid, an adapter will be created based on the adapter implementation
481 * class. The adapter will be registered with the specified interface, and with the specified adapter service
482 * properties. Depending on the <code>propagate</code> parameter, every public factory configuration properties
Pierre De Ropef94c882010-04-17 18:23:35 +0000483 * (which don't start with ".") will be propagated along with the adapter service properties.
484 * It will also inherit all dependencies.
485 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000486 * <h3>Usage Example</h3>
487 *
488 * <blockquote><pre>
489 * PropertyMetaData[] propertiesMetaData = new PropertyMetaData[] {
490 * manager.createPropertyMetaData()
491 * .setCardinality(Integer.MAX_VALUE)
492 * .setType(String.class)
493 * .setHeading("English words")
494 * .setDescription("Declare here some valid english words")
495 * .setDefaults(new String[] {"hello", "world"})
496 * .setId("words")
497 * };
498 *
499 * manager.add(createFactoryConfigurationAdapterService("FactoryPid",
500 * "updated",
501 * true, // propagate CM settings
502 * "EnglishDictionary",
503 * "English dictionary configuration properties",
504 * null,
505 * propertiesMetaData)
506 * .setImplementation(Adapter.class));
507 * </pre></blockquote>
508 *
Pierre De Ropef94c882010-04-17 18:23:35 +0000509 * @param factoryPid the pid matching the factory configuration
510 * @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 +0000511 * @param propagate true if public factory configuration should be propagated to the adapter service properties
Pierre De Rop3e100372010-05-24 12:43:44 +0000512 * @param heading The label used to display the tab name (or section) where the properties are displayed.
513 * Example: "Printer Service"
514 * @param desc A human readable description of the factory PID this configuration is associated with.
515 * Example: "Configuration for the PrinterService bundle"
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000516 * @param localization Points to the basename of the Properties file that can localize the Meta Type informations.
517 * The default localization base name for the properties is OSGI-INF/l10n/bundle, but can
Pierre De Rop3e100372010-05-24 12:43:44 +0000518 * be overridden by the manifest Bundle-Localization header (see core specification, in section Localization
519 * on page 68). You can specify a specific localization basename file using this parameter
520 * (e.g. <code>"person"</code> will match person_du_NL.properties in the root bundle directory).
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000521 * @param propertiesMetaData Array of MetaData regarding configuration properties
522 * @return a service that acts as a factory for generating the managed service factory configuration adapter
523 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000524 public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate,
Pierre De Rop3e100372010-05-24 12:43:44 +0000525 String heading, String desc, String localization,
526 PropertyMetaData[] propertiesMetaData)
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000527 {
Pierre De Rop3e100372010-05-24 12:43:44 +0000528 return new FactoryConfigurationAdapterServiceImpl(this, factoryPid, update, propagate, m_context, m_logger,
529 heading, desc, localization, propertiesMetaData);
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000530 }
531
532 /**
Marcel Offermansa962bc92009-11-21 17:59:33 +0000533 * Returns a list of services.
534 *
535 * @return a list of services
536 */
Marcel Offermans5be5f142011-04-26 10:47:12 +0000537 public List getComponents() {
538 return Collections.unmodifiableList(m_components);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000539 }
Marcel Offermansa962bc92009-11-21 17:59:33 +0000540}