blob: f2afb90d5804eb2d4b1a59f8ef80e166f02e8f8b [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
28import org.apache.felix.dm.DependencyManager;
Pierre De Rop19476fe2010-05-23 08:13:58 +000029import org.apache.felix.dm.dependencies.Dependency;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000030import org.apache.felix.dm.service.Service;
Pierre De Rop19476fe2010-05-23 08:13:58 +000031import org.apache.felix.dm.service.ServiceStateListener;
Marcel Offermansd665eaf2010-02-16 15:56:35 +000032import org.osgi.framework.Bundle;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000033import org.osgi.framework.ServiceReference;
Pierre De Ropef94c882010-04-17 18:23:35 +000034import org.osgi.service.cm.ConfigurationException;
Marcel Offermans3e1998c2009-12-16 20:47:25 +000035
Pierre De Ropef94c882010-04-17 18:23:35 +000036public abstract class AbstractDecorator {
Marcel Offermans3e1998c2009-12-16 20:47:25 +000037 protected volatile DependencyManager m_manager;
38 private final Map m_services = new HashMap();
39
40 public abstract Service createService(Object[] properties);
Pierre De Ropef94c882010-04-17 18:23:35 +000041
42 /**
43 * Extra method, which may be used by sub-classes, when adaptee has changed.
44 * For now, it's only used by the FactoryConfigurationAdapterImpl class,
45 * but it might also make sense to use this for Resource Adapters ...
46 */
47 public void updateService(Object[] properties) {
48 throw new NoSuchMethodError("Method updateService not implemented");
49 }
50
Pierre De Rop19476fe2010-05-23 08:13:58 +000051 /**
52 * Set some service properties to all already instantiated services.
53 */
54 public void setServiceProperties(Dictionary serviceProperties) {
55 Map services = new HashMap();
56 synchronized (this) {
57 services.putAll(m_services);
58 }
59 Iterator i = services.values().iterator();
60 while (i.hasNext()) {
61 ((Service) i.next()).setServiceProperties(serviceProperties);
62 }
63 }
64
65 /**
66 * Remove a StateListener from all already instantiated services.
67 */
68 public void addStateListener(ServiceStateListener listener) {
69 Map services = new HashMap();
70 synchronized (this) {
71 services.putAll(m_services);
72 }
73 Iterator i = services.values().iterator();
74 while (i.hasNext()) {
75 ((Service) i.next()).addStateListener(listener);
76 }
77 }
78
79 /**
80 * Remove a StateListener from all already instantiated services.
81 */
82 public void removeStateListener(ServiceStateListener listener) {
83 Map services = new HashMap();
84 synchronized (this) {
85 services.putAll(m_services);
86 }
87 Iterator i = services.values().iterator();
88 while (i.hasNext()) {
89 ((Service) i.next()).removeStateListener(listener);
90 }
91 }
92
93 /**
94 * Add a Dependency to all already instantiated services.
95 */
96 public void addDependency(Dependency d) {
97 Map services = new HashMap();
98 synchronized (this) {
99 services.putAll(m_services);
100 }
101 Iterator i = services.values().iterator();
102 while (i.hasNext()) {
103 ((Service) i.next()).add(d);
104 }
105 }
106
107 /**
108 * Add a Dependency to all already instantiated services.
109 */
110 public void addDependencies(List dependencies) {
111 Map services = new HashMap();
112 synchronized (this) {
113 services.putAll(m_services);
114 }
115 Iterator i = services.values().iterator();
116 while (i.hasNext()) {
117 ((Service) i.next()).add(dependencies);
118 }
119 }
120
121 /**
122 * Remove a Dependency from all instantiated services.
123 */
124 public void removeDependency(Dependency d) {
125 Map services = new HashMap();
126 synchronized (this) {
127 services.putAll(m_services);
128 }
129 Iterator i = services.values().iterator();
130 while (i.hasNext()) {
131 ((Service) i.next()).remove(d);
132 }
133 }
134
Pierre De Ropef94c882010-04-17 18:23:35 +0000135 // callbacks for FactoryConfigurationAdapterImpl
136 public void updated(String pid, Dictionary properties) throws ConfigurationException {
137 try {
Pierre De Rop21f95dd2010-04-24 10:31:41 +0000138 Service service;
139 synchronized (this) {
140 service = (Service) m_services.get(pid);
141 }
Pierre De Ropef94c882010-04-17 18:23:35 +0000142 if (service == null) {
143 service = createService(new Object[] { properties });
144 synchronized (this) {
145 m_services.put(pid, service);
146 }
147 m_manager.add(service);
148 } else {
149 updateService(new Object[] { properties, service });
150 }
151 }
152
153 catch (Throwable t) {
154 if (t instanceof ConfigurationException) {
155 throw (ConfigurationException) t;
156 } else if (t.getCause() instanceof ConfigurationException) {
157 throw (ConfigurationException) t.getCause();
158 } else {
159 throw new ConfigurationException(null, "Could not create service for ManagedServiceFactory Pid " + pid, t);
160 }
161 }
162 }
163
Pierre De Rop19476fe2010-05-23 08:13:58 +0000164 public void deleted(String pid) {
Pierre De Ropef94c882010-04-17 18:23:35 +0000165 Service service = null;
166 synchronized (this) {
167 service = (Service) m_services.remove(pid);
168 }
169 if (service != null)
170 {
171 m_manager.remove(service);
172 }
173 }
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000174
175 // callbacks for resources
Marcel Offermansa8c213f2010-07-02 17:27:20 +0000176 public void added(URL resource) {
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000177 Service newService = createService(new Object[] { resource });
178 m_services.put(resource, newService);
179 m_manager.add(newService);
180 }
181
Marcel Offermansa8c213f2010-07-02 17:27:20 +0000182 public void removed(URL resource) {
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000183 Service newService = (Service) m_services.remove(resource);
184 if (newService == null) {
185 System.out.println("Service should not be null here, dumping stack.");
186 Thread.dumpStack();
187 }
188 else {
189 m_manager.remove(newService);
190 }
191 }
192
193 // callbacks for services
194 public void added(ServiceReference ref, Object service) {
195 Service newService = createService(new Object[] { ref, service });
196 m_services.put(ref, newService);
197 m_manager.add(newService);
198 }
199
200 public void removed(ServiceReference ref, Object service) {
201 Service newService = (Service) m_services.remove(ref);
202 if (newService == null) {
203 System.out.println("Service should not be null here, dumping stack.");
204 Thread.dumpStack();
205 }
206 else {
207 m_manager.remove(newService);
208 }
209 }
210
Marcel Offermansd665eaf2010-02-16 15:56:35 +0000211 // callbacks for bundles
212 public void added(Bundle bundle) {
213 Service newService = createService(new Object[] { bundle });
214 m_services.put(bundle, newService);
215 m_manager.add(newService);
216 }
217
218 public void removed(Bundle bundle) {
219 Service newService = (Service) m_services.remove(bundle);
220 if (newService == null) {
221 System.out.println("Service should not be null here, dumping stack.");
222 Thread.dumpStack();
223 }
224 else {
225 m_manager.remove(newService);
226 }
227 }
228
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000229 public void stop() {
230 Iterator i = m_services.values().iterator();
231 while (i.hasNext()) {
232 m_manager.remove((Service) i.next());
233 }
234 m_services.clear();
Pierre De Ropef94c882010-04-17 18:23:35 +0000235 }
Marcel Offermans3e1998c2009-12-16 20:47:25 +0000236}