blob: c889744edd418e5d6e16f1427b3e4cac1f5dec8a [file] [log] [blame]
Marcel Offermans3e1998c2009-12-16 20:47:25 +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
Marcel Offermansa8c213f2010-07-02 17:27:20 +000021import java.net.URL;
Pierre De Ropef94c882010-04-17 18:23:35 +000022import java.util.Dictionary;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000023import java.util.HashMap;
24import java.util.Iterator;
Pierre De Rop19476fe2010-05-23 08:13:58 +000025import java.util.List;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000026import java.util.Map;
27
Marcel Offermans8b93efa2010-07-02 18:27:21 +000028import org.apache.felix.dm.Dependency;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000029import org.apache.felix.dm.DependencyManager;
Marcel Offermans8b93efa2010-07-02 18:27:21 +000030import org.apache.felix.dm.Service;
31import org.apache.felix.dm.ServiceStateListener;
Marcel Offermansd665eaf2010-02-16 15:56:35 +000032import org.osgi.framework.Bundle;
Marcel Offermans3d921212010-08-09 13:37:02 +000033import org.osgi.framework.BundleContext;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000034import org.osgi.framework.ServiceReference;
Marcel Offermans3d921212010-08-09 13:37:02 +000035import org.osgi.framework.ServiceRegistration;
Pierre De Ropef94c882010-04-17 18:23:35 +000036import org.osgi.service.cm.ConfigurationException;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000037
Pierre De Ropef94c882010-04-17 18:23:35 +000038public abstract class AbstractDecorator {
Marcel Offermans3e1998c2009-12-16 20:47:25 +000039 protected volatile DependencyManager m_manager;
40 private final Map m_services = new HashMap();
41
42 public abstract Service createService(Object[] properties);
Pierre De Ropef94c882010-04-17 18:23:35 +000043
44 /**
45 * Extra method, which may be used by sub-classes, when adaptee has changed.
46 * For now, it's only used by the FactoryConfigurationAdapterImpl class,
47 * but it might also make sense to use this for Resource Adapters ...
48 */
49 public void updateService(Object[] properties) {
50 throw new NoSuchMethodError("Method updateService not implemented");
51 }
52
Pierre De Rop19476fe2010-05-23 08:13:58 +000053 /**
54 * Set some service properties to all already instantiated services.
55 */
56 public void setServiceProperties(Dictionary serviceProperties) {
57 Map services = new HashMap();
58 synchronized (this) {
59 services.putAll(m_services);
60 }
61 Iterator i = services.values().iterator();
62 while (i.hasNext()) {
63 ((Service) i.next()).setServiceProperties(serviceProperties);
64 }
65 }
66
67 /**
68 * Remove a StateListener from all already instantiated services.
69 */
70 public void addStateListener(ServiceStateListener listener) {
71 Map services = new HashMap();
72 synchronized (this) {
73 services.putAll(m_services);
74 }
75 Iterator i = services.values().iterator();
76 while (i.hasNext()) {
77 ((Service) i.next()).addStateListener(listener);
78 }
79 }
80
81 /**
82 * Remove a StateListener from all already instantiated services.
83 */
84 public void removeStateListener(ServiceStateListener listener) {
85 Map services = new HashMap();
86 synchronized (this) {
87 services.putAll(m_services);
88 }
89 Iterator i = services.values().iterator();
90 while (i.hasNext()) {
91 ((Service) i.next()).removeStateListener(listener);
92 }
93 }
94
95 /**
96 * Add a Dependency to all already instantiated services.
97 */
98 public void addDependency(Dependency d) {
99 Map services = new HashMap();
100 synchronized (this) {
101 services.putAll(m_services);
102 }
103 Iterator i = services.values().iterator();
104 while (i.hasNext()) {
105 ((Service) i.next()).add(d);
106 }
107 }
108
109 /**
110 * Add a Dependency to all already instantiated services.
111 */
112 public void addDependencies(List dependencies) {
113 Map services = new HashMap();
114 synchronized (this) {
115 services.putAll(m_services);
116 }
117 Iterator i = services.values().iterator();
118 while (i.hasNext()) {
119 ((Service) i.next()).add(dependencies);
120 }
121 }
122
123 /**
124 * Remove a Dependency from all instantiated services.
125 */
126 public void removeDependency(Dependency d) {
127 Map services = new HashMap();
128 synchronized (this) {
129 services.putAll(m_services);
130 }
131 Iterator i = services.values().iterator();
132 while (i.hasNext()) {
133 ((Service) i.next()).remove(d);
134 }
135 }
136
Pierre De Ropef94c882010-04-17 18:23:35 +0000137 // callbacks for FactoryConfigurationAdapterImpl
138 public void updated(String pid, Dictionary properties) throws ConfigurationException {
139 try {
Pierre De Rop21f95dd2010-04-24 10:31:41 +0000140 Service service;
141 synchronized (this) {
142 service = (Service) m_services.get(pid);
143 }
Pierre De Ropef94c882010-04-17 18:23:35 +0000144 if (service == null) {
145 service = createService(new Object[] { properties });
146 synchronized (this) {
147 m_services.put(pid, service);
148 }
149 m_manager.add(service);
150 } else {
151 updateService(new Object[] { properties, service });
152 }
153 }
154
155 catch (Throwable t) {
156 if (t instanceof ConfigurationException) {
157 throw (ConfigurationException) t;
158 } else if (t.getCause() instanceof ConfigurationException) {
159 throw (ConfigurationException) t.getCause();
160 } else {
161 throw new ConfigurationException(null, "Could not create service for ManagedServiceFactory Pid " + pid, t);
162 }
163 }
164 }
165
Pierre De Rop19476fe2010-05-23 08:13:58 +0000166 public void deleted(String pid) {
Pierre De Ropef94c882010-04-17 18:23:35 +0000167 Service service = null;
168 synchronized (this) {
169 service = (Service) m_services.remove(pid);
170 }
171 if (service != null)
172 {
173 m_manager.remove(service);
174 }
175 }
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000176
177 // callbacks for resources
Marcel Offermansa8c213f2010-07-02 17:27:20 +0000178 public void added(URL resource) {
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000179 Service newService = createService(new Object[] { resource });
180 m_services.put(resource, newService);
181 m_manager.add(newService);
182 }
183
Marcel Offermansa8c213f2010-07-02 17:27:20 +0000184 public void removed(URL resource) {
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000185 Service newService = (Service) m_services.remove(resource);
186 if (newService == null) {
187 System.out.println("Service should not be null here, dumping stack.");
188 Thread.dumpStack();
189 }
190 else {
191 m_manager.remove(newService);
192 }
193 }
194
195 // callbacks for services
196 public void added(ServiceReference ref, Object service) {
197 Service newService = createService(new Object[] { ref, service });
198 m_services.put(ref, newService);
199 m_manager.add(newService);
200 }
201
202 public void removed(ServiceReference ref, Object service) {
203 Service newService = (Service) m_services.remove(ref);
204 if (newService == null) {
205 System.out.println("Service should not be null here, dumping stack.");
206 Thread.dumpStack();
207 }
208 else {
209 m_manager.remove(newService);
210 }
211 }
212
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000213 // callbacks for bundles
214 public void added(Bundle bundle) {
215 Service newService = createService(new Object[] { bundle });
216 m_services.put(bundle, newService);
217 m_manager.add(newService);
218 }
219
220 public void removed(Bundle bundle) {
221 Service newService = (Service) m_services.remove(bundle);
222 if (newService == null) {
223 System.out.println("Service should not be null here, dumping stack.");
224 Thread.dumpStack();
225 }
226 else {
227 m_manager.remove(newService);
228 }
229 }
230
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000231 public void stop() {
232 Iterator i = m_services.values().iterator();
233 while (i.hasNext()) {
234 m_manager.remove((Service) i.next());
235 }
236 m_services.clear();
Pierre De Ropef94c882010-04-17 18:23:35 +0000237 }
Marcel Offermans3d921212010-08-09 13:37:02 +0000238
239 public void configureAutoConfigState(Service target, Service source) {
240 configureAutoConfigState(target, source, BundleContext.class);
241 configureAutoConfigState(target, source, ServiceRegistration.class);
242 configureAutoConfigState(target, source, DependencyManager.class);
243 configureAutoConfigState(target, source, Service.class);
244 }
245
246 private void configureAutoConfigState(Service target, Service source, Class clazz) {
247 String name = source.getAutoConfigInstance(clazz);
248 if (name != null) {
249 target.setAutoConfig(clazz, name);
250 }
251 else {
252 target.setAutoConfig(clazz, source.getAutoConfig(clazz));
253 }
254 }
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000255}