blob: 336f8aefac29a501142dc58981c8aab6a436b88c [file] [log] [blame]
Pierre De Rop3a00a212015-03-01 09:27:46 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.apache.felix.dm;
20
21import java.lang.ref.WeakReference;
22import java.util.ArrayList;
23import java.util.Collections;
24import java.util.HashSet;
25import java.util.Iterator;
26import java.util.List;
27import java.util.Set;
28import java.util.concurrent.ConcurrentHashMap;
29
30import org.apache.felix.dm.impl.AdapterServiceImpl;
31import org.apache.felix.dm.impl.AspectServiceImpl;
32import org.apache.felix.dm.impl.BundleAdapterImpl;
33import org.apache.felix.dm.impl.BundleDependencyImpl;
34import org.apache.felix.dm.impl.ComponentImpl;
35import org.apache.felix.dm.impl.ComponentScheduler;
36import org.apache.felix.dm.impl.ConfigurationDependencyImpl;
37import org.apache.felix.dm.impl.FactoryConfigurationAdapterImpl;
38import org.apache.felix.dm.impl.ResourceAdapterImpl;
39import org.apache.felix.dm.impl.ResourceDependencyImpl;
40import org.apache.felix.dm.impl.ServiceDependencyImpl;
41import org.apache.felix.dm.impl.TemporalServiceDependencyImpl;
42import org.apache.felix.dm.impl.index.AdapterFilterIndex;
43import org.apache.felix.dm.impl.index.AspectFilterIndex;
44import org.apache.felix.dm.impl.index.ServiceRegistryCache;
45import org.apache.felix.dm.impl.index.multiproperty.MultiPropertyFilterIndex;
46import org.apache.felix.dm.impl.metatype.PropertyMetaDataImpl;
47import org.osgi.framework.Bundle;
48import org.osgi.framework.BundleContext;
49import org.osgi.framework.BundleException;
50import org.osgi.framework.FrameworkUtil;
51
52/**
53 * The dependency manager manages all components and their dependencies. Using
54 * this API you can declare all components and their dependencies. Under normal
55 * circumstances, you get passed an instance of this class through the
56 * <code>DependencyActivatorBase</code> subclass you use as your
57 * <code>BundleActivator</code>, but it is also possible to create your
58 * own instance.
59 *
60 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
61 */
62public class DependencyManager {
63 /**
64 * The DependencyManager Activator will wait for a threadpool before creating any DM components if the following
65 * OSGi system property is set to true.
66 */
67 public final static String PARALLEL = "org.apache.felix.dependencymanager.parallel";
68
69 public static final String ASPECT = "org.apache.felix.dependencymanager.aspect";
70 public static final String SERVICEREGISTRY_CACHE_INDICES = "org.apache.felix.dependencymanager.filterindex";
71 public static final String METHOD_CACHE_SIZE = "org.apache.felix.dependencymanager.methodcache";
72
73 private final BundleContext m_context;
74 private final Logger m_logger;
75 private final ConcurrentHashMap<Component, Component> m_components = new ConcurrentHashMap<>();
76
77 // service registry cache
78 private static ServiceRegistryCache m_serviceRegistryCache;
79 private static final Set<WeakReference<DependencyManager>> m_dependencyManagers = new HashSet<>();
80 static {
81 try {
82 Bundle bundle = FrameworkUtil.getBundle(DependencyManager.class);
83 if (bundle != null && bundle.getState() != Bundle.ACTIVE) {
84 bundle.start();
85 BundleContext bundleContext = bundle.getBundleContext();
86 String index = bundleContext.getProperty(SERVICEREGISTRY_CACHE_INDICES);
87 if (index != null) {
88 m_serviceRegistryCache = new ServiceRegistryCache(bundleContext);
89 m_serviceRegistryCache.open(); // TODO close it somewhere
90 String[] props = index.split(";");
91 for (int i = 0; i < props.length; i++) {
92 if (props[i].equals("*aspect*")) {
93 m_serviceRegistryCache.addFilterIndex(new AspectFilterIndex());
94 }
95 else if (props[i].equals("*adapter*")) {
96 m_serviceRegistryCache.addFilterIndex(new AdapterFilterIndex());
97 }
98 else {
99 m_serviceRegistryCache.addFilterIndex(new MultiPropertyFilterIndex(props[i]));
100 }
101 }
102 }
103 }
104 }
105 catch (BundleException e) {
106 // if we cannot start ourselves, we cannot use the indices
107 e.printStackTrace();
108 }
109 }
110
111 /**
112 * Creates a new dependency manager. You need to supply the
113 * <code>BundleContext</code> to be used by the dependency
114 * manager to register services and communicate with the
115 * framework.
116 *
117 * @param context the bundle context
118 */
119 public DependencyManager(BundleContext context) {
120 this(context, new Logger(context));
121 }
122
123 DependencyManager(BundleContext context, Logger logger) {
124 m_context = createContext(context);
125 m_logger = logger;
126 synchronized (m_dependencyManagers) {
127 m_dependencyManagers.add(new WeakReference<DependencyManager>(this));
128 }
129 }
130
131 /**
132 * Returns the list of currently created dependency managers.
133 * @return the list of currently created dependency managers
134 */
135 public static List<DependencyManager> getDependencyManagers() {
136 List<DependencyManager> result = new ArrayList<>();
137 synchronized (m_dependencyManagers) {
138 Iterator<WeakReference<DependencyManager>> iterator = m_dependencyManagers.iterator();
139 while (iterator.hasNext()) {
140 WeakReference<DependencyManager> reference = iterator.next();
141 DependencyManager manager = reference.get();
142 if (manager != null) {
143 try {
144 manager.getBundleContext().getBundle();
145 result.add(manager);
146 continue;
147 }
148 catch (IllegalStateException e) {
149 }
150 }
151 iterator.remove();
152 }
153 }
154 return result;
155 }
156
157 /**
158 * Returns the bundle context associated with this dependency manager.
159 * @return the bundle context associated with this dependency manager.
160 */
161 public BundleContext getBundleContext() {
162 return m_context;
163 }
164
165 /**
166 * Adds a new component to the dependency manager. After the service is added
167 * it will be started immediately.
168 *
169 * @param c the service to add
170 */
171 public void add(Component c) {
172 m_components.put(c, c);
173 ComponentScheduler.instance().add(c);
174 }
175
176 /**
177 * Removes a service from the dependency manager. Before the service is removed
178 * it is stopped first.
179 *
180 * @param c the component to remove
181 */
182 public void remove(Component c) {
183 ComponentScheduler.instance().remove(c);
184 m_components.remove(c);
185 }
186
187 /**
188 * Creates a new component.
189 *
190 * @return the new component
191 */
192 public Component createComponent() {
193 return new ComponentImpl(m_context, this, m_logger);
194 }
195
196 /**
197 * Creates a new service dependency.
198 *
199 * @return the service dependency
200 */
201 public ServiceDependency createServiceDependency() {
202 return new ServiceDependencyImpl();
203 }
204
205 /**
206 * Creates a new configuration dependency.
207 *
208 * @return the configuration dependency
209 */
210 public ConfigurationDependency createConfigurationDependency() {
211 return new ConfigurationDependencyImpl(m_context, m_logger);
212 }
213
214 /**
215 * Creates a new bundle dependency.
216 *
217 * @return a new BundleDependency instance.
218 */
219 public BundleDependency createBundleDependency() {
220 return new BundleDependencyImpl();
221 }
222
223 /**
224 * Creates a new resource dependency.
225 *
226 * @return the resource dependency
227 */
228 public ResourceDependency createResourceDependency() {
229 return new ResourceDependencyImpl();
230 }
231
232 /**
233 * Creates a new timed required service dependency. A timed dependency blocks the invoker thread is the required dependency
234 * is currently unavailable, until it comes up again.
235 *
236 * @return a new timed service dependency
237 */
238 public ServiceDependency createTemporalServiceDependency(long timeout) {
239 return new TemporalServiceDependencyImpl(m_context, timeout);
240 }
241
242 /**
243 * Creates a new adapter. The adapter will be applied to any service that
244 * matches the specified interface and filter. For each matching service
245 * an adapter will be created based on the adapter implementation class.
246 * The adapter will be registered with the specified interface and existing properties
247 * from the original service plus any extra properties you supply here.
248 * It will also inherit all dependencies, and if you declare the original
249 * service as a member it will be injected.
250 *
251 * <h3>Usage Example</h3>
252 *
253 * <blockquote><pre>
254 * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
255 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
256 * .setImplementation(AdapterImpl.class);
257 * </pre></blockquote>
258 *
259 * @param serviceInterface the service interface to apply the adapter to
260 * @param serviceFilter the filter condition to use with the service interface
261 * @return a service that acts as a factory for generating adapters
262 */
263 public Component createAdapterService(Class<?> serviceInterface, String serviceFilter) {
264 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null, null, null, true);
265 }
266
267 /**
268 * Creates a new adapter. The adapter will be applied to any service that
269 * matches the specified interface and filter. For each matching service
270 * an adapter will be created based on the adapter implementation class.
271 * The adapter will be registered with the specified interface and existing properties
272 * from the original service plus any extra properties you supply here.
273 * It will also inherit all dependencies, and if you declare the original
274 * service as a member it will be injected.
275 *
276 * <h3>Usage Example</h3>
277 *
278 * <blockquote><pre>
279 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "m_service")
280 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
281 * .setImplementation(AdapterImpl.class);
282 * </pre></blockquote>
283 *
284 * @param serviceInterface the service interface to apply the adapter to
285 * @param serviceFilter the filter condition to use with the service interface
286 * @param autoConfig the name of the member to inject the service into
287 * @return a service that acts as a factory for generating adapters
288 */
289 public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String autoConfig) {
290 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null, null, null, true);
291 }
292
293 /**
294 * Creates a new adapter. The adapter will be applied to any service that
295 * matches the specified interface and filter. For each matching service
296 * an adapter will be created based on the adapter implementation class.
297 * The adapter will be registered with the specified interface and existing properties
298 * from the original service plus any extra properties you supply here.
299 * It will also inherit all dependencies, and if you declare the original
300 * service as a member it will be injected.
301 *
302 * <h3>Usage Example</h3>
303 *
304 * <blockquote><pre>
305 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove")
306 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
307 * .setImplementation(AdapterImpl.class);
308 * </pre></blockquote>
309 *
310 * @param serviceInterface the service interface to apply the adapter to
311 * @param serviceFilter the filter condition to use with the service interface
312 * @param add name of the callback method to invoke on add
313 * @param change name of the callback method to invoke on change
314 * @param remove name of the callback method to invoke on remove
315 * @return a service that acts as a factory for generating adapters
316 */
317 public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change,
318 String remove)
319 {
320 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, null, true);
321 }
322
323 /**
324 * Creates a new adapter. The adapter will be applied to any service that
325 * matches the specified interface and filter. For each matching service
326 * an adapter will be created based on the adapter implementation class.
327 * The adapter will be registered with the specified interface and existing properties
328 * from the original service plus any extra properties you supply here.
329 * It will also inherit all dependencies, and if you declare the original
330 * service as a member it will be injected.
331 *
332 * <h3>Usage Example</h3>
333 *
334 * <blockquote><pre>
335 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove", "swap")
336 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
337 * .setImplementation(AdapterImpl.class);
338 * </pre></blockquote>
339 *
340 * @param serviceInterface the service interface to apply the adapter to
341 * @param serviceFilter the filter condition to use with the service interface
342 * @param add name of the callback method to invoke on add
343 * @param change name of the callback method to invoke on change
344 * @param remove name of the callback method to invoke on remove
345 * @param swap name of the callback method to invoke on swap
346 * @return a service that acts as a factory for generating adapters
347 */
348 public Component createAdapterService(Class<?> serviceInterface, String serviceFilter, String add, String change,
349 String remove, String swap)
350 {
351 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, add, change, remove, swap, true);
352 }
353
354 /**
355 * Creates a new adapter. The adapter will be applied to any service that
356 * matches the specified interface and filter. For each matching service
357 * an adapter will be created based on the adapter implementation class.
358 * The adapter will be registered with the specified interface (and existing properties
359 * from the original service if you set the propagate flag) plus any extra properties you supply here.
360 * It will also inherit all dependencies, and if you declare the original
361 * service as a member it will be injected.
362 *
363 * <h3>Usage Example</h3>
364 *
365 * <blockquote><pre>
366 * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove", "swap")
367 * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
368 * .setImplementation(AdapterImpl.class);
369 * </pre></blockquote>
370 *
371 * @param serviceInterface the service interface to apply the adapter to
372 * @param serviceFilter the filter condition to use with the service interface
373 * @param autoConfig the name of the member to inject the service into, or null.
374 * @param callbackInstance the instance to invoke the callbacks on, or null if the callbacks have to be invoked on the adapter itself
375 * @param add name of the callback method to invoke on add
376 * @param change name of the callback method to invoke on change
377 * @param remove name of the callback method to invoke on remove
378 * @param swap name of the callback method to invoke on swap
379 * @param propagate true if the adaptee service properties should be propagated to the adapter service consumers
380 * @return a service that acts as a factory for generating adapters
381 */
382 public Component createAdapterService(Class<?> serviceInterface, String serviceFilter,
383 String autoConfig, Object callbackInstance, String add, String change, String remove,
384 String swap, boolean propagate)
385 {
386 return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, callbackInstance, add, change, remove, swap, propagate);
387 }
388
389 /**
390 * Creates a new Managed Service Factory Configuration Adapter. For each new Config Admin factory configuration matching
391 * the factoryPid, an adapter will be created based on the adapter implementation class.
392 * The adapter will be registered with the specified interface, and with the specified adapter service properties.
393 * Depending on the <code>propagate</code> parameter, every public factory configuration properties
394 * (which don't start with ".") will be propagated along with the adapter service properties.
395 * It will also inherit all dependencies.
396 *
397 * <h3>Usage Example</h3>
398 *
399 * <blockquote><pre>
400 * manager.createFactoryConfigurationAdapterService("MyFactoryPid", "update", true)
401 * // The interface to use when registering adapter
402 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
403 * // the implementation of the adapter
404 * .setImplementation(AdapterServiceImpl.class);
405 * </pre></blockquote>
406 *
407 * @param factoryPid the pid matching the factory configuration
408 * @param update the adapter method name that will be notified when the factory configuration is created/updated.
409 * @param propagate true if public factory configuration should be propagated to the adapter service properties
410 * @return a service that acts as a factory for generating the managed service factory configuration adapter
411 */
412 public Component createFactoryConfigurationAdapterService(String factoryPid, String update, boolean propagate) {
413 return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate);
414 }
415
416 /**
417 * Creates a new Managed Service Factory Configuration Adapter with meta type support. For each new Config Admin
418 * factory configuration matching the factoryPid, an adapter will be created based on the adapter implementation
419 * class. The adapter will be registered with the specified interface, and with the specified adapter service
420 * properties. Depending on the <code>propagate</code> parameter, every public factory configuration properties
421 * (which don't start with ".") will be propagated along with the adapter service properties.
422 * It will also inherit all dependencies.
423 *
424 * <h3>Usage Example</h3>
425 *
426 * <blockquote><pre>
427 * PropertyMetaData[] propertiesMetaData = new PropertyMetaData[] {
428 * manager.createPropertyMetaData()
429 * .setCardinality(Integer.MAX_VALUE)
430 * .setType(String.class)
431 * .setHeading("English words")
432 * .setDescription("Declare here some valid english words")
433 * .setDefaults(new String[] {"hello", "world"})
434 * .setId("words")
435 * };
436 *
437 * manager.add(createFactoryConfigurationAdapterService("FactoryPid",
438 * "updated",
439 * true, // propagate CM settings
440 * "EnglishDictionary",
441 * "English dictionary configuration properties",
442 * null,
443 * propertiesMetaData)
444 * .setImplementation(Adapter.class));
445 * </pre></blockquote>
446 *
447 * @param factoryPid the pid matching the factory configuration
448 * @param update the adapter method name that will be notified when the factory configuration is created/updated.
449 * @param propagate true if public factory configuration should be propagated to the adapter service properties
450 * @param heading The label used to display the tab name (or section) where the properties are displayed.
451 * Example: "Printer Service"
452 * @param desc A human readable description of the factory PID this configuration is associated with.
453 * Example: "Configuration for the PrinterService bundle"
454 * @param localization Points to the basename of the Properties file that can localize the Meta Type informations.
455 * The default localization base name for the properties is OSGI-INF/l10n/bundle, but can
456 * be overridden by the manifest Bundle-Localization header (see core specification, in section Localization
457 * on page 68). You can specify a specific localization basename file using this parameter
458 * (e.g. <code>"person"</code> will match person_du_NL.properties in the root bundle directory).
459 * @param propertiesMetaData Array of MetaData regarding configuration properties
460 * @return a service that acts as a factory for generating the managed service factory configuration adapter
461 */
462 public Component createAdapterFactoryConfigurationService(String factoryPid, String update, boolean propagate,
463 String heading, String desc, String localization, PropertyMetaData[] propertiesMetaData)
464 {
465 return new FactoryConfigurationAdapterImpl(this, factoryPid, update, propagate, m_context, m_logger, heading,
466 desc, localization, propertiesMetaData);
467 }
468
469 /**
470 * Creates a new bundle adapter. The adapter will be applied to any bundle that
471 * matches the specified bundle state mask and filter condition. For each matching
472 * bundle an adapter will be created based on the adapter implementation class.
473 * The adapter will be registered with the specified interface
474 *
475 * TODO and existing properties from the original resource plus any extra properties you supply here.
476 * It will also inherit all dependencies, and if you declare the original
477 * service as a member it will be injected.
478 *
479 * <h3>Usage Example</h3>
480 *
481 * <blockquote><pre>
482 * manager.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE,
483 * "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
484 * true)
485 * // The interface to use when registering adapter
486 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
487 * // the implementation of the adapter
488 * .setImplementation(AdapterServiceImpl.class);
489 * </pre></blockquote>
490 *
491 * @param bundleStateMask the bundle state mask to apply
492 * @param bundleFilter the filter to apply to the bundle manifest
493 * @param propagate <code>true</code> if properties from the bundle should be propagated to the service
494 * @return a service that acts as a factory for generating bundle adapters
495 */
496 public Component createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
497 return new BundleAdapterImpl(this, bundleStateMask, bundleFilter, propagate);
498 }
499
500 /**
501 * Creates a new resource adapter. The adapter will be applied to any resource that
502 * matches the specified filter condition. For each matching resource
503 * an adapter will be created based on the adapter implementation class.
504 * The adapter will be registered with the specified interface and existing properties
505 * from the original resource plus any extra properties you supply here.
506 * It will also inherit all dependencies, and if you declare the original
507 * service as a member it will be injected.
508 *
509 * <h3>Usage Example</h3>
510 *
511 * <blockquote><pre>
512 * manager.createResourceAdapterService("(&(path=/test)(repository=TestRepository))", true)
513 * // The interface to use when registering adapter
514 * .setInterface(AdapterService.class.getName(), new Hashtable() {{ put("foo", "bar"); }})
515 * // the implementation of the adapter
516 * .setImplementation(AdapterServiceImpl.class);
517 * </pre></blockquote>
518 *
519 * @param resourceFilter the filter condition to use with the resource
520 * @param propagate <code>true</code> if properties from the resource should be propagated to the service
521 * @param callbackInstance instance to invoke the callback on
522 * @param callbackChanged the name of the callback method
523 * @return a service that acts as a factory for generating resource adapters
524 */
525 public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance,
526 String callbackChanged)
527 {
528 return new ResourceAdapterImpl(this, resourceFilter, propagate, callbackInstance, null, callbackChanged);
529 }
530
531 /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */
532 public Component createResourceAdapterService(String resourceFilter, boolean propagate, Object callbackInstance,
533 String callbackSet, String callbackChanged)
534 {
535 return new ResourceAdapterImpl(this, resourceFilter, propagate, callbackInstance, callbackSet, callbackChanged);
536 }
537
538 /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */
539 public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance,
540 String propagateCallbackMethod, Object callbackInstance, String callbackChanged)
541 {
542 return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod,
543 callbackInstance, null, callbackChanged);
544 }
545
546 /** @see DependencyManager#createResourceAdapterService(String, boolean, Object, String) */
547 public Component createResourceAdapterService(String resourceFilter, Object propagateCallbackInstance,
548 String propagateCallbackMethod, Object callbackInstance, String callbackSet, String callbackChanged)
549 {
550 return new ResourceAdapterImpl(this, resourceFilter, propagateCallbackInstance, propagateCallbackMethod,
551 callbackInstance, callbackSet, callbackChanged);
552 }
553
554 /**
555 * Returns a list of components.
556 *
557 * @return a list of components
558 */
559 public List<Component> getComponents() {
560 return Collections.list(m_components.elements());
561 }
562
563 /**
564 * Creates a new aspect. The aspect will be applied to any service that
565 * matches the specified interface and filter. For each matching service
566 * an aspect will be created based on the aspect implementation class.
567 * The aspect will be registered with the same interface and properties
568 * as the original service, plus any extra properties you supply here.
569 * It will also inherit all dependencies, and if you declare the original
570 * service as a member it will be injected.
571 *
572 * <h3>Usage Example</h3>
573 *
574 * <blockquote><pre>
575 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_service")
576 * .setImplementation(ExistingServiceAspect.class)
577 * );
578 * </pre></blockquote>
579 *
580 * @param serviceInterface the service interface to apply the aspect to
581 * @param serviceFilter the filter condition to use with the service interface
582 * @param ranking the level used to organize the aspect chain ordering
583 * @param autoConfig the aspect implementation field name where to inject original service.
584 * If null, any field matching the original service will be injected.
585 * @return a service that acts as a factory for generating aspects
586 */
587 public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String autoConfig) {
588 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null, null);
589 }
590
591 /**
592 * Creates a new aspect. The aspect will be applied to any service that
593 * matches the specified interface and filter. For each matching service
594 * an aspect will be created based on the aspect implementation class.
595 * The aspect will be registered with the same interface and properties
596 * as the original service, plus any extra properties you supply here.
597 * It will also inherit all dependencies, and if you declare the original
598 * service as a member it will be injected.
599 *
600 * <h3>Usage Example</h3>
601 *
602 * <blockquote><pre>
603 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10)
604 * .setImplementation(ExistingServiceAspect.class)
605 * );
606 * </pre></blockquote>
607 *
608 * @param serviceInterface the service interface to apply the aspect to
609 * @param serviceFilter the filter condition to use with the service interface
610 * @param ranking the level used to organize the aspect chain ordering
611 * @return a service that acts as a factory for generating aspects
612 */
613 public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking) {
614 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null, null);
615 }
616
617 /**
618 * Creates a new aspect. The aspect will be applied to any service that
619 * matches the specified interface and filter. For each matching service
620 * an aspect will be created based on the aspect implementation class.
621 * The aspect will be registered with the same interface and properties
622 * as the original service, plus any extra properties you supply here.
623 * It will also inherit all dependencies, and if you declare the original
624 * service as a member it will be injected.
625 *
626 * <h3>Usage Example</h3>
627 *
628 * <blockquote><pre>
629 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
630 * .setImplementation(ExistingServiceAspect.class)
631 * );
632 * </pre></blockquote>
633 *
634 * @param serviceInterface the service interface to apply the aspect to
635 * @param serviceFilter the filter condition to use with the service interface
636 * @param ranking the level used to organize the aspect chain ordering
637 * @param add name of the callback method to invoke on add
638 * @param change name of the callback method to invoke on change
639 * @param remove name of the callback method to invoke on remove
640 * @return a service that acts as a factory for generating aspects
641 */
642 public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String add,
643 String change, String remove)
644 {
645 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, null);
646 }
647
648 /**
649 * Creates a new aspect. The aspect will be applied to any service that
650 * matches the specified interface and filter. For each matching service
651 * an aspect will be created based on the aspect implementation class.
652 * The aspect will be registered with the same interface and properties
653 * as the original service, plus any extra properties you supply here.
654 * It will also inherit all dependencies, and if you declare the original
655 * service as a member it will be injected.
656 *
657 * <h3>Usage Example</h3>
658 *
659 * <blockquote><pre>
660 * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
661 * .setImplementation(ExistingServiceAspect.class)
662 * );
663 * </pre></blockquote>
664 *
665 * @param serviceInterface the service interface to apply the aspect to
666 * @param serviceFilter the filter condition to use with the service interface
667 * @param ranking the level used to organize the aspect chain ordering
668 * @param add name of the callback method to invoke on add
669 * @param change name of the callback method to invoke on change
670 * @param remove name of the callback method to invoke on remove
671 * @param swap name of the callback method to invoke on swap
672 * @return a service that acts as a factory for generating aspects
673 */
674 public Component createAspectService(Class<?> serviceInterface, String serviceFilter, int ranking, String add,
675 String change, String remove, String swap)
676 {
677 return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove, swap);
678 }
679
680 /**
681 * Removes all components and their dependencies.
682 */
683 public void clear() {
684 for (Component component : m_components.keySet()) {
685 remove(component);
686 }
687 m_components.clear();
688 }
689
690 /**
691 * Creates a new configuration property metadata.
692 *
693 * @return the configuration property metadata.
694 */
695 public PropertyMetaData createPropertyMetaData() {
696 return new PropertyMetaDataImpl();
697 }
698
699 private BundleContext createContext(BundleContext context) {
700 if (m_serviceRegistryCache != null) {
701 return m_serviceRegistryCache.createBundleContextInterceptor(context);
702 }
703 else {
704 return context;
705 }
706 }
707}