1 /**
2 *
3 * Copyright 2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.geronimo.gbean.runtime;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.geronimo.gbean.AbstractName;
22 import org.apache.geronimo.gbean.ReferenceCollection;
23 import org.apache.geronimo.gbean.ReferenceCollectionEvent;
24 import org.apache.geronimo.gbean.ReferenceCollectionListener;
25 import org.apache.geronimo.kernel.Kernel;
26 import org.apache.geronimo.kernel.GBeanNotFoundException;
27
28 import javax.management.ObjectName;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.Map;
35 import java.util.NoSuchElementException;
36 import java.util.Set;
37
38 /**
39 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
40 */
41 class ProxyCollection implements ReferenceCollection {
42 private static final Log log = LogFactory.getLog(ProxyCollection.class);
43 private final String name;
44 private final Kernel kernel;
45 private final Map proxies = new HashMap();
46 private final Set listeners = new HashSet();
47 private boolean stopped = false;
48 private final Class type;
49
50 public ProxyCollection(String name, Class type, Set targets, Kernel kernel) {
51 this.name = name;
52 this.kernel = kernel;
53 this.type = type;
54
55 for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
56 addTarget((AbstractName) iterator.next());
57 }
58 }
59
60 synchronized void destroy() {
61 stopped = true;
62 if (!AbstractGBeanReference.NO_PROXY) {
63 for (Iterator iterator = proxies.values().iterator(); iterator.hasNext();) {
64 kernel.getProxyManager().destroyProxy(iterator.next());
65 }
66 }
67 proxies.clear();
68 listeners.clear();
69 }
70
71 void addTarget(AbstractName target) {
72 Object proxy;
73 ArrayList listenerCopy;
74 synchronized (this) {
75
76 if (proxies.containsKey(target)) {
77 return;
78 }
79
80
81 if (AbstractGBeanReference.NO_PROXY) {
82 try {
83 proxy = kernel.getGBean(target);
84 } catch (GBeanNotFoundException e) {
85
86 log.debug("GBean was unloaded before it could be added to reference collections: " + target);
87 return;
88 }
89 } else {
90 proxy = kernel.getProxyManager().createProxy(target, type);
91 }
92 proxies.put(target, proxy);
93
94
95 listenerCopy = new ArrayList(listeners);
96 }
97
98
99 for (Iterator iterator = listenerCopy.iterator(); iterator.hasNext();) {
100 ReferenceCollectionListener listener = (ReferenceCollectionListener) iterator.next();
101 try {
102 listener.memberAdded(new ReferenceCollectionEvent(name, proxy));
103 } catch (Throwable t) {
104 log.error("Listener threw exception", t);
105 }
106 }
107 }
108
109 void removeTarget(AbstractName target) {
110 Object proxy;
111 ArrayList listenerCopy;
112 synchronized (this) {
113
114 proxy = proxies.remove(target);
115
116
117 if (proxy == null) {
118 return;
119 }
120
121
122 listenerCopy = new ArrayList(listeners);
123 }
124
125
126 for (Iterator iterator = listenerCopy.iterator(); iterator.hasNext();) {
127 ReferenceCollectionListener listener = (ReferenceCollectionListener) iterator.next();
128 try {
129 listener.memberRemoved(new ReferenceCollectionEvent(name, proxy));
130 } catch (Throwable t) {
131 log.error("Listener threw exception", t);
132 }
133 }
134
135
136 if (!AbstractGBeanReference.NO_PROXY) {
137 kernel.getProxyManager().destroyProxy(proxy);
138 }
139 }
140
141 public synchronized ObjectName[] getMemberObjectNames() {
142 return (ObjectName[])proxies.keySet().toArray(new ObjectName[0]);
143 }
144
145 public synchronized boolean isStopped() {
146 return stopped;
147 }
148
149 public synchronized void addReferenceCollectionListener(ReferenceCollectionListener listener) {
150 listeners.add(listener);
151 }
152
153 public synchronized void removeReferenceCollectionListener(ReferenceCollectionListener listener) {
154 listeners.remove(listener);
155 }
156
157 public synchronized int size() {
158 if (stopped) {
159 return 0;
160 }
161 return proxies.size();
162 }
163
164 public synchronized boolean isEmpty() {
165 if (stopped) {
166 return true;
167 }
168 return proxies.isEmpty();
169 }
170
171 public synchronized boolean contains(Object o) {
172 if (stopped) {
173 return false;
174 }
175 return proxies.containsValue(o);
176 }
177
178 public synchronized Iterator iterator() {
179 if (stopped) {
180 return new Iterator() {
181 public boolean hasNext() {
182 return false;
183 }
184
185 public Object next() {
186 throw new NoSuchElementException();
187 }
188
189 public void remove() {
190 throw new UnsupportedOperationException();
191 }
192 };
193 }
194
195 return new Iterator() {
196
197
198 private final Iterator iterator = new ArrayList(proxies.values()).iterator();
199
200 public boolean hasNext() {
201 return iterator.hasNext();
202 }
203
204 public Object next() {
205 return iterator.next();
206 }
207
208 public void remove() {
209 throw new UnsupportedOperationException();
210 }
211 };
212 }
213
214 public synchronized Object[] toArray() {
215 if (stopped) {
216 return new Object[0];
217 }
218 return proxies.values().toArray();
219 }
220
221 public synchronized Object[] toArray(Object a[]) {
222 if (stopped) {
223 if (a.length > 0) {
224 a[0] = null;
225 }
226 return a;
227 }
228 return proxies.values().toArray(a);
229 }
230
231 public synchronized boolean containsAll(Collection c) {
232 if (stopped) {
233 return c.isEmpty();
234 }
235 return proxies.values().containsAll(c);
236 }
237
238 public boolean add(Object o) {
239 throw new UnsupportedOperationException();
240 }
241
242 public boolean remove(Object o) {
243 throw new UnsupportedOperationException();
244 }
245
246 public boolean addAll(Collection c) {
247 throw new UnsupportedOperationException();
248 }
249
250 public boolean removeAll(Collection c) {
251 throw new UnsupportedOperationException();
252 }
253
254 public boolean retainAll(Collection c) {
255 throw new UnsupportedOperationException();
256 }
257
258 public void clear() {
259 throw new UnsupportedOperationException();
260 }
261 }