blob: 9f3d9043ac8305ecf7904d6b04a2d98cd4bc581c [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.impl;
20
21import java.util.Enumeration;
22import java.util.Hashtable;
23import java.util.List;
24
25import org.apache.felix.dm.Component;
26import org.apache.felix.dm.ComponentStateListener;
27import org.apache.felix.dm.Dependency;
28import org.apache.felix.dm.DependencyManager;
29import org.apache.felix.dm.context.DependencyContext;
30import org.osgi.framework.Bundle;
31
32/**
33 * Bundle Adapter Service implementation. This class extends the FilterService in order to catch
34 * some Service methods for configuring actual adapter service implementation.
35 *
36 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
37 */
38public class BundleAdapterImpl extends FilterComponent
39{
Pierre De Ropc40d93f2015-05-04 20:25:57 +000040 /**
Pierre De Rop3a00a212015-03-01 09:27:46 +000041 * Creates a new Bundle Adapter Service implementation.
42 */
43 public BundleAdapterImpl(DependencyManager dm, int bundleStateMask, String bundleFilter, boolean propagate)
44 {
Pierre De Ropc40d93f2015-05-04 20:25:57 +000045 this(dm, bundleStateMask, bundleFilter, propagate, null, null, null, null);
Pierre De Rop3a00a212015-03-01 09:27:46 +000046 }
47
Pierre De Ropc40d93f2015-05-04 20:25:57 +000048 public BundleAdapterImpl(DependencyManager dm, int stateMask, String filter, boolean propagate, Object cbInstance, String add, String change, String remove) {
49 super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
50 m_component
51 .setImplementation(new BundleAdapterDecorator(stateMask, propagate, cbInstance, add, change, remove))
52 .add(dm.createBundleDependency()
53 .setFilter(filter)
54 .setStateMask(stateMask)
55 .setCallbacks("added", "removed"))
56 .setCallbacks("init", null, "stop", null);
57 }
58
59 public class BundleAdapterDecorator extends AbstractDecorator {
Pierre De Rop3a00a212015-03-01 09:27:46 +000060 private final boolean m_propagate;
61 private final int m_bundleStateMask;
Pierre De Ropc40d93f2015-05-04 20:25:57 +000062 public final Object m_cbInstance;
63 public final String m_add;
64 public final String m_change;
65 public final String m_remove;
Pierre De Rop3a00a212015-03-01 09:27:46 +000066
67 public BundleAdapterDecorator(int bundleStateMask, boolean propagate) {
Pierre De Ropc40d93f2015-05-04 20:25:57 +000068 this(bundleStateMask, propagate, null, null, null, null);
Pierre De Rop3a00a212015-03-01 09:27:46 +000069 }
70
Pierre De Ropc40d93f2015-05-04 20:25:57 +000071 public BundleAdapterDecorator(int bundleStateMask, boolean propagate, Object callbackInstance, String add, String change, String remove) {
72 m_bundleStateMask = bundleStateMask;
73 m_propagate = propagate;
74 m_cbInstance = callbackInstance;
75 m_add = add;
76 m_change = change;
77 m_remove = remove;
78 }
79
80 public Component createService(Object[] properties) {
Pierre De Rop3a00a212015-03-01 09:27:46 +000081 Bundle bundle = (Bundle) properties[0];
82 Hashtable<String, Object> props = new Hashtable<>();
83 if (m_serviceProperties != null) {
84 Enumeration<String> e = m_serviceProperties.keys();
85 while (e.hasMoreElements()) {
86 String key = e.nextElement();
87 props.put(key, m_serviceProperties.get(key));
88 }
89 }
90 List<DependencyContext> dependencies = m_component.getDependencies();
91 // the first dependency is always the dependency on the bundle, which
92 // will be replaced with a more specific dependency below
93 dependencies.remove(0);
94 Component service = m_manager.createComponent()
95 .setInterface(m_serviceInterfaces, props)
96 .setImplementation(m_serviceImpl)
97 .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
98 .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
99 .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
100 .add(m_manager.createBundleDependency()
101 .setBundle(bundle)
102 .setStateMask(m_bundleStateMask)
103 .setPropagate(m_propagate)
Pierre De Ropc40d93f2015-05-04 20:25:57 +0000104 .setCallbacks(m_cbInstance, m_add, m_change, m_remove)
Pierre De Rop3a00a212015-03-01 09:27:46 +0000105 .setAutoConfig(true)
106 .setRequired(true));
107
108 for (DependencyContext dc : dependencies) {
109 service.add((Dependency) dc.createCopy());
110 }
111
112 for (ComponentStateListener stateListener : m_stateListeners) {
113 service.add(stateListener);
114 }
115 configureAutoConfigState(service, m_component);
116 return service;
117 }
118 }
119}