blob: 5c275643caefa7f8c48696ad696d1a6ca62b084e [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.Dictionary;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
25import java.util.concurrent.CopyOnWriteArrayList;
26import java.util.concurrent.Executor;
27
28import org.apache.felix.dm.Component;
29import org.apache.felix.dm.ComponentDeclaration;
30import org.apache.felix.dm.ComponentDependencyDeclaration;
31import org.apache.felix.dm.ComponentStateListener;
32import org.apache.felix.dm.Dependency;
33import org.apache.felix.dm.DependencyManager;
34import org.apache.felix.dm.Logger;
35import org.apache.felix.dm.context.ComponentContext;
36import org.apache.felix.dm.context.DependencyContext;
37import org.apache.felix.dm.context.Event;
38import org.apache.felix.dm.context.EventType;
39import org.osgi.framework.Bundle;
40import org.osgi.framework.BundleContext;
41import org.osgi.framework.ServiceRegistration;
42
43/**
44 * This class allows to filter a Component interface. All Aspect/Adapters extend this class
45 * in order to add functionality to the default Component implementation.
46 *
47 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
48 */
49public class FilterComponent implements Component, ComponentContext, ComponentDeclaration {
50 protected volatile ComponentImpl m_component;
51 protected volatile List<ComponentStateListener> m_stateListeners = new CopyOnWriteArrayList<>();
52 protected volatile String m_init = "init";
53 protected volatile String m_start = "start";
54 protected volatile String m_stop = "stop";
55 protected volatile String m_destroy = "destroy";
56 protected volatile Object m_callbackObject;
57 protected volatile Object m_compositionInstance;
58 protected volatile String m_compositionMethod;
59 protected volatile String[] m_serviceInterfaces;
60 protected volatile Object m_serviceImpl;
61 protected volatile Object m_factory;
62 protected volatile String m_factoryCreateMethod;
63 protected volatile Dictionary<String, Object> m_serviceProperties;
64
65 public FilterComponent(Component service) {
66 m_component = (ComponentImpl) service;
67 }
68
69 @Override
Pierre De Rop9e5cdba2016-02-17 20:35:16 +000070 public <T> T createConfigurationProxy(Class<T> type, Dictionary<?, ?> config) {
71 return m_component.createConfigurationProxy(type, config);
72 }
73
74 @Override
Pierre De Ropc723eb32015-11-22 21:49:00 +000075 public Executor getExecutor() {
76 return m_component.getExecutor();
77 }
78
79 @Override
Pierre De Rop3a00a212015-03-01 09:27:46 +000080 public String toString() {
81 return m_component.toString();
82 }
83
84 public Component add(Dependency ... dependencies) {
Pierre De Ropbecfed42016-01-31 22:00:44 +000085 m_component.add(dependencies);
86 // Add the dependencies to all already instantiated services.
87 // If one dependency from the list is required, we have nothing to do, since our internal
88 // service will be stopped/restarted.
Pierre De Rop3a00a212015-03-01 09:27:46 +000089 for (Dependency dependency : dependencies) {
Pierre De Ropbecfed42016-01-31 22:00:44 +000090 if (((DependencyContext) dependency).isRequired()) {
91 return this;
Pierre De Rop3a00a212015-03-01 09:27:46 +000092 }
93 }
Pierre De Ropbecfed42016-01-31 22:00:44 +000094 // Ok, the list contains no required dependencies: add optionals dependencies in already instantiated services.
95 Object[] instances = m_component.getInstances();
96 if (instances.length > 0) {
97 AbstractDecorator ad = (AbstractDecorator) instances[0];
98 if (ad != null) {
99 ad.addDependency(dependencies);
Pierre De Rop3a00a212015-03-01 09:27:46 +0000100 }
101 }
102 return this;
103 }
104
105 public Component add(ComponentStateListener listener) {
106 m_stateListeners.add(listener);
107 // Add the listener to all already instantiated services.
108 Object[] instances = m_component.getInstances();
109 if (instances.length > 0) {
110 AbstractDecorator ad = (AbstractDecorator) instances[0];
111 if (ad != null) {
112 ad.addStateListener(listener);
113 }
114 }
115 return this;
116 }
117
118 public List<DependencyContext> getDependencies() {
119 return m_component.getDependencies();
120 }
121
122 public String getClassName() {
123 return m_component.getClassName();
124 }
125
126 @SuppressWarnings("unchecked")
127 public Dictionary<String, Object> getServiceProperties() {
128 return m_serviceProperties;
129 }
130
131 public ServiceRegistration getServiceRegistration() {
132 return m_component.getServiceRegistration();
133 }
134
135 public Component remove(Dependency dependency) {
136 m_component.remove(dependency);
137 // Remove the dependency (if optional) from all already instantiated services.
138 // If the dependency is required, our internal service will be stopped, so in this case
139 // we have nothing to do.
140 if (!((DependencyContext) dependency).isRequired())
141 {
142 Object[] instances = m_component.getInstances();
143 if (instances.length > 0) {
144 AbstractDecorator ad = (AbstractDecorator) instances[0];
145 if (ad != null) {
146 ad.removeDependency(dependency);
147 }
148 }
149 }
150 return this;
151 }
152
153 public Component remove(ComponentStateListener listener) {
154 m_stateListeners.remove(listener);
155 // Remove the listener from all already instantiated services.
156 Object[] instances = m_component.getInstances();
157 if (instances.length > 0) {
158 AbstractDecorator ad = (AbstractDecorator) instances[0];
159 if (ad != null) {
160 ad.removeStateListener(listener);
161 }
162 }
163 return this;
164 }
165
166 public Component setCallbacks(Object instance, String init, String start, String stop, String destroy) {
167 m_component.ensureNotActive();
168 m_callbackObject = instance;
169 m_init = init;
170 m_start = start;
171 m_stop = stop;
172 m_destroy = destroy;
173 return this;
174 }
175
176 public Component setCallbacks(String init, String start, String stop, String destroy) {
177 setCallbacks(null, init, start, stop, destroy);
178 return this;
179 }
180
181 public Component setComposition(Object instance, String getMethod) {
182 m_component.ensureNotActive();
183 m_compositionInstance = instance;
184 m_compositionMethod = getMethod;
185 return this;
186 }
187
188 public Component setComposition(String getMethod) {
189 m_component.ensureNotActive();
190 m_compositionMethod = getMethod;
191 return this;
192 }
193
194 public Component setFactory(Object factory, String createMethod) {
195 m_component.ensureNotActive();
196 m_factory = factory;
197 m_factoryCreateMethod = createMethod;
198 return this;
199 }
200
201 public Component setFactory(String createMethod) {
202 return setFactory(null, createMethod);
203 }
204
205 public Component setImplementation(Object implementation) {
206 m_component.ensureNotActive();
207 m_serviceImpl = implementation;
208 return this;
209 }
210
211 public Component setInterface(String serviceName, Dictionary<?, ?> properties) {
212 return setInterface(new String[] { serviceName }, properties);
213 }
214
215 @SuppressWarnings("unchecked")
216 public Component setInterface(String[] serviceInterfaces, Dictionary<?, ?> properties) {
217 m_component.ensureNotActive();
218 if (serviceInterfaces != null) {
219 m_serviceInterfaces = new String[serviceInterfaces.length];
220 System.arraycopy(serviceInterfaces, 0, m_serviceInterfaces, 0, serviceInterfaces.length);
221 m_serviceProperties = (Dictionary<String, Object>) properties;
222 }
223 return this;
224 }
225
226 @SuppressWarnings("unchecked")
227 public Component setServiceProperties(Dictionary<?, ?> serviceProperties) {
228 m_serviceProperties = (Dictionary<String, Object>) serviceProperties;
229 // Set the properties to all already instantiated services.
230 if (serviceProperties != null) {
231 Object[] instances = m_component.getInstances();
232 if (instances.length > 0) {
233 AbstractDecorator ad = (AbstractDecorator) instances[0];
234 if (ad != null) {
235 ad.setServiceProperties(serviceProperties);
236 }
237 }
238 }
239 return this;
240 }
241
242 public void start() {
243 m_component.start();
244 }
245
246 public void stop() {
247 m_component.stop();
248 }
249
250 public void invokeCallbackMethod(Object[] instances, String methodName, Class<?>[][] signatures, Object[][] parameters) {
251 m_component.invokeCallbackMethod(instances, methodName, signatures, parameters);
252 }
253
254 public DependencyManager getDependencyManager() {
255 return m_component.getDependencyManager();
256 }
257
258 public Component setAutoConfig(Class<?> clazz, boolean autoConfig) {
259 m_component.setAutoConfig(clazz, autoConfig);
260 return this;
261 }
262
263 public Component setAutoConfig(Class<?> clazz, String instanceName) {
264 m_component.setAutoConfig(clazz, instanceName);
265 return this;
266 }
267
268 public boolean getAutoConfig(Class<?> clazz) {
269 return m_component.getAutoConfig(clazz);
270 }
271
272 public String getAutoConfigInstance(Class<?> clazz) {
273 return m_component.getAutoConfigInstance(clazz);
274 }
275
276 public ComponentDependencyDeclaration[] getComponentDependencies() {
277 return m_component.getComponentDependencies();
278 }
279
280 public String getName() {
281 return m_component.getName();
282 }
283
284 public int getState() {
285 return m_component.getState();
286 }
287
288 public long getId() {
289 return m_component.getId();
290 }
291
292 public String[] getServices() {
293 return m_component.getServices();
294 }
295
296 public BundleContext getBundleContext() {
297 return m_component.getBundleContext();
298 }
299
300 @Override
301 public boolean isActive() {
302 return m_component.isActive();
303 }
304
305 @Override
306 public boolean isAvailable() {
307 return m_component.isAvailable();
308 }
309
310 @Override
311 public void handleEvent(DependencyContext dc, EventType type, Event ... e) {
312 m_component.handleEvent(dc, type, e);
313 }
314
315 @Override
316 public <T> T getInstance() {
317 return m_component.getInstance();
318 }
319
320 @Override
321 public Object[] getInstances() {
322 return m_component.getInstances();
323 }
324
325 @Override
326 public Event getDependencyEvent(DependencyContext dc) {
327 return m_component.getDependencyEvent(dc);
328 }
329
330 @Override
331 public Set<Event> getDependencyEvents(DependencyContext dc) {
332 return m_component.getDependencyEvents(dc);
333 }
334
335 public ComponentDeclaration getComponentDeclaration() {
336 return this;
337 }
338
339 @Override
340 public Component setDebug(String label) {
341 m_component.setDebug(label);
342 return this;
343 }
344
345 @Override
346 public void setThreadPool(Executor threadPool) {
347 m_component.setThreadPool(threadPool);
348 }
349
350 @Override
351 public Map<String, Long> getCallbacksTime() {
352 return m_component.getCallbacksTime();
353 }
354
355 @Override
356 public Bundle getBundle() {
357 return m_component.getBundle();
358 }
359
360 @Override
361 public Logger getLogger() {
362 return m_component.getLogger();
363 }
Pierre De Rop2c3aeab2016-01-04 11:23:04 +0000364
365 protected void copyDependencies(List<DependencyContext> dependencies, Component component) {
366 for (DependencyContext dc : dependencies) {
367 DependencyContext copy = dc.createCopy();
Pierre De Ropbecfed42016-01-31 22:00:44 +0000368
Pierre De Rop2c3aeab2016-01-04 11:23:04 +0000369 component.add(copy);
370 }
371 }
Pierre De Rop3a00a212015-03-01 09:27:46 +0000372}