blob: 6826b6f9a70a8b698a9fbeca089484248fb712eb [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;
Pierre De Ropa0204f52010-03-06 22:23:57 +000041import org.apache.felix.dm.impl.metatype.PropertyMetaDataImpl;
Marcel Offermansfd7deb02011-04-20 11:26:09 +000042import org.apache.felix.dm.index.AspectFilterIndex;
Marcel Offermans227dd712011-04-19 07:14:22 +000043import org.apache.felix.dm.index.MultiPropertyExactFilter;
44import org.apache.felix.dm.index.ServiceRegistryCache;
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 Offermansa962bc92009-11-21 17:59:33 +000061 private final BundleContext m_context;
62 private final Logger m_logger;
Marcel Offermans5be5f142011-04-26 10:47:12 +000063 private List m_components = Collections.synchronizedList(new ArrayList());
Marcel Offermansa962bc92009-11-21 17:59:33 +000064
65 /**
Marcel Offermans4fd903f2009-12-29 09:18:05 +000066 * Creates a new dependency manager. You need to supply the
67 * <code>BundleContext</code> to be used by the dependency
68 * manager to register services and communicate with the
69 * framework.
Marcel Offermansa962bc92009-11-21 17:59:33 +000070 *
71 * @param context the bundle context
Marcel Offermansa962bc92009-11-21 17:59:33 +000072 */
Pierre De Ropae4a5db2009-12-04 22:08:05 +000073 public DependencyManager(BundleContext context) {
74 this(context, new Logger(context));
75 }
76
Marcel Offermans4fd903f2009-12-29 09:18:05 +000077 DependencyManager(BundleContext context, Logger logger) {
Marcel Offermans227dd712011-04-19 07:14:22 +000078 m_context = createContext(context);
Marcel Offermansa962bc92009-11-21 17:59:33 +000079 m_logger = logger;
Marcel Offermans5be5f142011-04-26 10:47:12 +000080 synchronized (m_dependencyManagers) {
81 m_dependencyManagers.add(new WeakReference(this));
82 }
Marcel Offermansa962bc92009-11-21 17:59:33 +000083 }
Pierre De Ropae4a5db2009-12-04 22:08:05 +000084
Marcel Offermans227dd712011-04-19 07:14:22 +000085 // service registry cache
86 private static ServiceRegistryCache m_serviceRegistryCache;
Marcel Offermans5be5f142011-04-26 10:47:12 +000087 private static final Set /* WeakReference<DependencyManager> */ m_dependencyManagers = new HashSet();
Marcel Offermans227dd712011-04-19 07:14:22 +000088 static {
89 String index = System.getProperty(SERVICEREGISTRY_CACHE_INDICES);
Marcel Offermans227dd712011-04-19 07:14:22 +000090 if (index != null) {
Marcel Offermansfd7deb02011-04-20 11:26:09 +000091 m_serviceRegistryCache = new ServiceRegistryCache(FrameworkUtil.getBundle(DependencyManager.class).getBundleContext());
92 m_serviceRegistryCache.open(); // TODO close it somewhere
Marcel Offermans227dd712011-04-19 07:14:22 +000093 String[] props = index.split(";");
94 for (int i = 0; i < props.length; i++) {
Marcel Offermansfd7deb02011-04-20 11:26:09 +000095 if (props[i].equals("*aspect*")) {
96 m_serviceRegistryCache.addFilterIndex(new AspectFilterIndex());
97 }
98 else {
99 String[] propList = props[i].split(",");
100 m_serviceRegistryCache.addFilterIndex(new MultiPropertyExactFilter(propList));
101 }
Marcel Offermans227dd712011-04-19 07:14:22 +0000102 }
103 }
Marcel Offermans5be5f142011-04-26 10:47:12 +0000104 }
105
106 public static List getDependencyManagers() {
107 List /* DependencyManager */ result = new ArrayList();
108 synchronized (m_dependencyManagers) {
109 Iterator iterator = m_dependencyManagers.iterator();
110 while (iterator.hasNext()) {
111 WeakReference reference = (WeakReference) iterator.next();
112 DependencyManager manager = (DependencyManager) reference.get();
113 if (manager != null) {
114 result.add(manager);
115 }
116 else {
117 iterator.remove();
118 }
119 }
Marcel Offermans227dd712011-04-19 07:14:22 +0000120 }
Marcel Offermans5be5f142011-04-26 10:47:12 +0000121 return result;
Marcel Offermans227dd712011-04-19 07:14:22 +0000122 }
123
124 private BundleContext createContext(BundleContext context) {
125 if (m_serviceRegistryCache != null) {
126// System.out.println("DM: Enabling bundle context interceptor for bundle #" + context.getBundle().getBundleId());
127 return m_serviceRegistryCache.createBundleContextInterceptor(context);
128 }
129 else {
130 return context;
131 }
132 }
Marcel Offermans5be5f142011-04-26 10:47:12 +0000133
134 public BundleContext getBundleContext() {
135 return m_context;
136 }
Marcel Offermans227dd712011-04-19 07:14:22 +0000137
Marcel Offermansa962bc92009-11-21 17:59:33 +0000138 /**
139 * Adds a new service to the dependency manager. After the service was added
140 * it will be started immediately.
141 *
142 * @param service the service to add
143 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000144 public void add(Component service) {
Marcel Offermans5be5f142011-04-26 10:47:12 +0000145 m_components.add(service);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000146 service.start();
147 }
148
149 /**
150 * Removes a service from the dependency manager. Before the service is removed
151 * it is stopped first.
152 *
153 * @param service the service to remove
154 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000155 public void remove(Component service) {
Marcel Offermansa962bc92009-11-21 17:59:33 +0000156 service.stop();
Marcel Offermans5be5f142011-04-26 10:47:12 +0000157 m_components.remove(service);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000158 }
159
160 /**
161 * Creates a new service.
162 *
163 * @return the new service
164 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000165 public Component createComponent() {
166 return new ComponentImpl(m_context, this, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000167 }
168
169 /**
170 * Creates a new service dependency.
171 *
172 * @return the service dependency
173 */
174 public ServiceDependency createServiceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000175 return new ServiceDependencyImpl(m_context, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000176 }
177
Marcel Offermans74363c32009-11-23 19:56:08 +0000178 /**
179 * Creates a new temporal service dependency.
180 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000181 * @return a new temporal service dependency
Marcel Offermans74363c32009-11-23 19:56:08 +0000182 */
183 public TemporalServiceDependency createTemporalServiceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000184 return new TemporalServiceDependencyImpl(m_context, m_logger);
Marcel Offermans74363c32009-11-23 19:56:08 +0000185 }
Marcel Offermans2925f172009-12-02 13:03:39 +0000186
187 /**
188 * Creates a new configuration dependency.
189 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000190 * @return the configuration dependency
Marcel Offermans2925f172009-12-02 13:03:39 +0000191 */
Marcel Offermansa962bc92009-11-21 17:59:33 +0000192 public ConfigurationDependency createConfigurationDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000193 return new ConfigurationDependencyImpl(m_context, m_logger);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000194 }
195
Marcel Offermans2925f172009-12-02 13:03:39 +0000196 /**
Marcel Offermansfaaed472010-09-08 10:07:32 +0000197 * Creates a new configuration property metadata.
198 *
199 * @return the configuration property metadata.
Pierre De Ropa0204f52010-03-06 22:23:57 +0000200 */
201 public PropertyMetaData createPropertyMetaData() {
202 return new PropertyMetaDataImpl();
203 }
204
205 /**
Marcel Offermans2925f172009-12-02 13:03:39 +0000206 * Creates a new bundle dependency.
207 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000208 * @return a new BundleDependency instance.
Marcel Offermans2925f172009-12-02 13:03:39 +0000209 */
Marcel Offermansd66c5ce2009-11-26 09:58:44 +0000210 public BundleDependency createBundleDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000211 return new BundleDependencyImpl(m_context, m_logger);
Marcel Offermansd66c5ce2009-11-26 09:58:44 +0000212 }
Marcel Offermans2925f172009-12-02 13:03:39 +0000213
214 /**
215 * Creates a new resource dependency.
216 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000217 * @return the resource dependency
Marcel Offermans2925f172009-12-02 13:03:39 +0000218 */
219 public ResourceDependency createResourceDependency() {
Pierre De Ropae4a5db2009-12-04 22:08:05 +0000220 return new ResourceDependencyImpl(m_context, m_logger);
Marcel Offermans2925f172009-12-02 13:03:39 +0000221 }
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000222
Marcel Offermans2925f172009-12-02 13:03:39 +0000223 /**
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000224 * Creates a new aspect. The aspect will be applied to any service that
225 * matches the specified interface and filter. For each matching service
226 * an aspect will be created based on the aspect implementation class.
227 * The aspect will be registered with the same interface and properties
228 * as the original service, plus any extra properties you supply here.
229 * It will also inherit all dependencies, and if you declare the original
230 * service as a member it will be injected.
Marcel Offermans2925f172009-12-02 13:03:39 +0000231 *
Pierre De Rop19476fe2010-05-23 08:13:58 +0000232 * <h3>Usage Example</h3>
233 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000234 * <blockquote><pre>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000235 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_service")
236 * .setImplementation(ExistingServiceAspect.class)
237 * );
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000238 * </pre></blockquote>
Pierre De Rop19476fe2010-05-23 08:13:58 +0000239 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000240 * @param serviceInterface the service interface to apply the aspect to
241 * @param serviceFilter the filter condition to use with the service interface
Pierre De Rop19476fe2010-05-23 08:13:58 +0000242 * @param ranking the level used to organize the aspect chain ordering
Marcel Offermansa8818d52011-03-09 10:03:35 +0000243 * @param autoConfig the aspect implementation field name where to inject original service.
Marcel Offermansfaaed472010-09-08 10:07:32 +0000244 * If null, any field matching the original service will be injected.
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000245 * @return a service that acts as a factory for generating aspects
Marcel Offermans2925f172009-12-02 13:03:39 +0000246 */
Marcel Offermansa8818d52011-03-09 10:03:35 +0000247 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String autoConfig) {
248 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null);
249 }
250 /**
251 * Creates a new aspect. The aspect will be applied to any service that
252 * matches the specified interface and filter. For each matching service
253 * an aspect will be created based on the aspect implementation class.
254 * The aspect will be registered with the same interface and properties
255 * as the original service, plus any extra properties you supply here.
256 * It will also inherit all dependencies, and if you declare the original
257 * service as a member it will be injected.
258 *
259 * <h3>Usage Example</h3>
260 *
261 * <blockquote><pre>
262 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10)
263 * .setImplementation(ExistingServiceAspect.class)
264 * );
265 * </pre></blockquote>
266 *
267 * @param serviceInterface the service interface to apply the aspect to
268 * @param serviceFilter the filter condition to use with the service interface
269 * @param ranking the level used to organize the aspect chain ordering
270 * @return a service that acts as a factory for generating aspects
271 */
272 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking) {
273 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null);
274 }
275 /**
276 * Creates a new aspect. The aspect will be applied to any service that
277 * matches the specified interface and filter. For each matching service
278 * an aspect will be created based on the aspect implementation class.
279 * The aspect will be registered with the same interface and properties
280 * as the original service, plus any extra properties you supply here.
281 * It will also inherit all dependencies, and if you declare the original
282 * service as a member it will be injected.
283 *
284 * <h3>Usage Example</h3>
285 *
286 * <blockquote><pre>
287 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
288 * .setImplementation(ExistingServiceAspect.class)
289 * );
290 * </pre></blockquote>
291 *
292 * @param serviceInterface the service interface to apply the aspect to
293 * @param serviceFilter the filter condition to use with the service interface
294 * @param ranking the level used to organize the aspect chain ordering
295 * @param add name of the callback method to invoke on add
296 * @param change name of the callback method to invoke on change
297 * @param remove name of the callback method to invoke on remove
298 * @return a service that acts as a factory for generating aspects
299 */
300 public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) {
301 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove);
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000302 }
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000303
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000304 /**
305 * Creates a new adapter. The adapter will be applied to any service that
306 * matches the specified interface and filter. For each matching service
307 * an adapter will be created based on the adapter implementation class.
308 * The adapter will be registered with the specified interface and existing properties
309 * from the original service plus any extra properties you supply here.
310 * It will also inherit all dependencies, and if you declare the original
311 * service as a member it will be injected.
312 *
Pierre De Rop34231582010-05-23 20:05:16 +0000313 * <h3>Usage Example</h3>
314 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000315 * <blockquote><pre>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000316 * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
317 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
318 * .setImplementation(AdapterImpl.class);
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000319 * </pre></blockquote>
Marcel Offermansa8818d52011-03-09 10:03:35 +0000320 *
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000321 * @param serviceInterface the service interface to apply the adapter to
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000322 * @param serviceFilter the filter condition to use with the service interface
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000323 * @return a service that acts as a factory for generating adapters
324 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000325 public Component createAdapterService(Class serviceInterface, String serviceFilter) {
Marcel Offermansa8818d52011-03-09 10:03:35 +0000326 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null);
327 }
328 /**
329 * Creates a new adapter. The adapter will be applied to any service that
330 * matches the specified interface and filter. For each matching service
331 * an adapter will be created based on the adapter implementation class.
332 * The adapter will be registered with the specified interface and existing properties
333 * from the original service plus any extra properties you supply here.
334 * It will also inherit all dependencies, and if you declare the original
335 * service as a member it will be injected.
336 *
337 * <h3>Usage Example</h3>
338 *
339 * <blockquote><pre>
340 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "m_service")
341 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
342 * .setImplementation(AdapterImpl.class);
343 * </pre></blockquote>
344 *
345 * @param serviceInterface the service interface to apply the adapter to
346 * @param serviceFilter the filter condition to use with the service interface
347 * @param autoConfig the name of the member to inject the service into
348 * @return a service that acts as a factory for generating adapters
349 */
350 public Component createAdapterService(Class serviceInterface, String serviceFilter, String autoConfig) {
351 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null);
352 }
353 /**
354 * Creates a new adapter. The adapter will be applied to any service that
355 * matches the specified interface and filter. For each matching service
356 * an adapter will be created based on the adapter implementation class.
357 * The adapter will be registered with the specified interface and existing properties
358 * from the original service plus any extra properties you supply here.
359 * It will also inherit all dependencies, and if you declare the original
360 * service as a member it will be injected.
361 *
362 * <h3>Usage Example</h3>
363 *
364 * <blockquote><pre>
365 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove")
366 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
367 * .setImplementation(AdapterImpl.class);
368 * </pre></blockquote>
369 *
370 * @param serviceInterface the service interface to apply the adapter to
371 * @param serviceFilter the filter condition to use with the service interface
372 * @param add name of the callback method to invoke on add
373 * @param change name of the callback method to invoke on change
374 * @param remove name of the callback method to invoke on remove
375 * @return a service that acts as a factory for generating adapters
376 */
377 public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, String remove) {
378 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, add, change, remove);
Marcel Offermans61a81142010-04-02 15:16:50 +0000379 }
Pierre De Rop34231582010-05-23 20:05:16 +0000380
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000381 /**
382 * Creates a new resource adapter. The adapter will be applied to any resource that
383 * matches the specified filter condition. For each matching resource
384 * an adapter will be created based on the adapter implementation class.
385 * The adapter will be registered with the specified interface and existing properties
386 * from the original resource plus any extra properties you supply here.
387 * It will also inherit all dependencies, and if you declare the original
388 * service as a member it will be injected.
389 *
Pierre De Rop445ddec2010-05-23 21:05:27 +0000390 * <h3>Usage Example</h3>
391 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000392 * <blockquote><pre>
Pierre De Rop445ddec2010-05-23 21:05:27 +0000393 * manager.createResourceAdapterService("(&(path=/test)(repository=TestRepository))", true)
394 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000395 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop445ddec2010-05-23 21:05:27 +0000396 * // the implementation of the adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000397 * .setImplementation(AdapterServiceImpl.class);
398 * </pre></blockquote>
Pierre De Rop445ddec2010-05-23 21:05:27 +0000399 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000400 * @param resourceFilter the filter condition to use with the resource
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000401 * @param propagate <code>true</code> if properties from the resource should be propagated to the service
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000402 * @param callbackInstance
403 * @param callbackChanged
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000404 * @return a service that acts as a factory for generating resource adapters
405 * @see Resource
406 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000407 public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance, String callbackChanged) {
Marcel Offermanse9c13d92010-07-01 14:01:02 +0000408 return new ResourceAdapterServiceImpl(this, resourceFilter, propagate, callbackInstance, callbackChanged);
Marcel Offermans61a81142010-04-02 15:16:50 +0000409 }
Pierre De Rop445ddec2010-05-23 21:05:27 +0000410
Marcel Offermansfaaed472010-09-08 10:07:32 +0000411 public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance, String propagateCallbackMethod, Object callbackInstance, String callbackChanged) {
Marcel Offermans26081d32010-07-12 12:43:42 +0000412 return new ResourceAdapterServiceImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod, callbackInstance, callbackChanged);
413 }
414
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000415 /**
416 * Creates a new bundle adapter. The adapter will be applied to any bundle that
417 * matches the specified bundle state mask and filter condition. For each matching
418 * bundle an adapter will be created based on the adapter implementation class.
419 * The adapter will be registered with the specified interface
420 *
421 * TODO and existing properties from the original resource plus any extra properties you supply here.
422 * It will also inherit all dependencies, and if you declare the original
423 * service as a member it will be injected.
424 *
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000425 * <h3>Usage Example</h3>
426 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000427 * <blockquote><pre>
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000428 * manager.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE,
429 * "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
430 * true)
431 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000432 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000433 * // the implementation of the adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000434 * .setImplementation(AdapterServiceImpl.class);
435 * </pre></blockquote>
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000436 *
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000437 * @param bundleStateMask the bundle state mask to apply
438 * @param bundleFilter the filter to apply to the bundle manifest
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000439 * @param propagate <code>true</code> if properties from the bundle should be propagated to the service
Marcel Offermans4fd903f2009-12-29 09:18:05 +0000440 * @return a service that acts as a factory for generating bundle adapters
441 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000442 public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
Pierre De Rop13dd63d2010-05-23 21:58:28 +0000443 return new BundleAdapterServiceImpl(this, bundleStateMask, bundleFilter, propagate);
Marcel Offermans61a81142010-04-02 15:16:50 +0000444 }
Marcel Offermans80eeafe2009-12-01 22:12:26 +0000445
Marcel Offermansa962bc92009-11-21 17:59:33 +0000446 /**
Pierre De Ropef94c882010-04-17 18:23:35 +0000447 * Creates a new Managed Service Factory Configuration Adapter. For each new Config Admin factory configuration matching
448 * the factoryPid, an adapter will be created based on the adapter implementation class.
449 * The adapter will be registered with the specified interface, and with the specified adapter service properties.
450 * Depending on the <code>propagate</code> parameter, every public factory configuration properties
451 * (which don't start with ".") will be propagated along with the adapter service properties.
452 * It will also inherit all dependencies.
453 *
Pierre De Rop3e100372010-05-24 12:43:44 +0000454 * <h3>Usage Example</h3>
455 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000456 * <blockquote><pre>
Pierre De Rop3e100372010-05-24 12:43:44 +0000457 * manager.createFactoryConfigurationAdapterService("MyFactoryPid", "update", true)
458 * // The interface to use when registering adapter
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000459 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
Pierre De Rop3e100372010-05-24 12:43:44 +0000460 * // the implementation of the adapter
461 * .setImplementation(AdapterServiceImpl.class);
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000462 * </pre></blockquote>
463 *
Pierre De Ropef94c882010-04-17 18:23:35 +0000464 * @param factoryPid the pid matching the factory configuration
465 * @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 +0000466 * @param propagate true if public factory configuration should be propagated to the adapter service properties
467 * @return a service that acts as a factory for generating the managed service factory configuration adapter
468 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000469 public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) {
Pierre De Rop3e100372010-05-24 12:43:44 +0000470 return new FactoryConfigurationAdapterServiceImpl(this, factoryPid, update, propagate);
Pierre De Ropef94c882010-04-17 18:23:35 +0000471 }
472
473 /**
Pierre De Rop3e100372010-05-24 12:43:44 +0000474 * Creates a new Managed Service Factory Configuration Adapter with meta type support. For each new Config Admin
475 * factory configuration matching the factoryPid, an adapter will be created based on the adapter implementation
476 * class. The adapter will be registered with the specified interface, and with the specified adapter service
477 * properties. Depending on the <code>propagate</code> parameter, every public factory configuration properties
Pierre De Ropef94c882010-04-17 18:23:35 +0000478 * (which don't start with ".") will be propagated along with the adapter service properties.
479 * It will also inherit all dependencies.
480 *
Pierre De Ropc3dfbb72010-05-24 13:16:35 +0000481 * <h3>Usage Example</h3>
482 *
483 * <blockquote><pre>
484 * PropertyMetaData[] propertiesMetaData = new PropertyMetaData[] {
485 * manager.createPropertyMetaData()
486 * .setCardinality(Integer.MAX_VALUE)
487 * .setType(String.class)
488 * .setHeading("English words")
489 * .setDescription("Declare here some valid english words")
490 * .setDefaults(new String[] {"hello", "world"})
491 * .setId("words")
492 * };
493 *
494 * manager.add(createFactoryConfigurationAdapterService("FactoryPid",
495 * "updated",
496 * true, // propagate CM settings
497 * "EnglishDictionary",
498 * "English dictionary configuration properties",
499 * null,
500 * propertiesMetaData)
501 * .setImplementation(Adapter.class));
502 * </pre></blockquote>
503 *
Pierre De Ropef94c882010-04-17 18:23:35 +0000504 * @param factoryPid the pid matching the factory configuration
505 * @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 +0000506 * @param propagate true if public factory configuration should be propagated to the adapter service properties
Pierre De Rop3e100372010-05-24 12:43:44 +0000507 * @param heading The label used to display the tab name (or section) where the properties are displayed.
508 * Example: "Printer Service"
509 * @param desc A human readable description of the factory PID this configuration is associated with.
510 * Example: "Configuration for the PrinterService bundle"
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000511 * @param localization Points to the basename of the Properties file that can localize the Meta Type informations.
512 * The default localization base name for the properties is OSGI-INF/l10n/bundle, but can
Pierre De Rop3e100372010-05-24 12:43:44 +0000513 * be overridden by the manifest Bundle-Localization header (see core specification, in section Localization
514 * on page 68). You can specify a specific localization basename file using this parameter
515 * (e.g. <code>"person"</code> will match person_du_NL.properties in the root bundle directory).
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000516 * @param propertiesMetaData Array of MetaData regarding configuration properties
517 * @return a service that acts as a factory for generating the managed service factory configuration adapter
518 */
Marcel Offermansfaaed472010-09-08 10:07:32 +0000519 public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate,
Pierre De Rop3e100372010-05-24 12:43:44 +0000520 String heading, String desc, String localization,
521 PropertyMetaData[] propertiesMetaData)
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000522 {
Pierre De Rop3e100372010-05-24 12:43:44 +0000523 return new FactoryConfigurationAdapterServiceImpl(this, factoryPid, update, propagate, m_context, m_logger,
524 heading, desc, localization, propertiesMetaData);
Pierre De Rop9a8ebfd2010-04-25 22:25:34 +0000525 }
526
527 /**
Marcel Offermansa962bc92009-11-21 17:59:33 +0000528 * Returns a list of services.
529 *
530 * @return a list of services
531 */
Marcel Offermans5be5f142011-04-26 10:47:12 +0000532 public List getComponents() {
533 return Collections.unmodifiableList(m_components);
Marcel Offermansa962bc92009-11-21 17:59:33 +0000534 }
Marcel Offermansa962bc92009-11-21 17:59:33 +0000535}