001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.gbean.runtime;
017:
018: import org.apache.commons.logging.Log;
019: import org.apache.commons.logging.LogFactory;
020: import org.apache.geronimo.gbean.AbstractName;
021: import org.apache.geronimo.gbean.ReferenceCollection;
022: import org.apache.geronimo.gbean.ReferenceCollectionEvent;
023: import org.apache.geronimo.gbean.ReferenceCollectionListener;
024: import org.apache.geronimo.kernel.Kernel;
025: import org.apache.geronimo.kernel.GBeanNotFoundException;
026:
027: import javax.management.ObjectName;
028: import java.util.ArrayList;
029: import java.util.Collection;
030: import java.util.HashMap;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.Map;
034: import java.util.NoSuchElementException;
035: import java.util.Set;
036:
037: /**
038: * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
039: */
040: class ProxyCollection implements ReferenceCollection {
041: private static final Log log = LogFactory
042: .getLog(ProxyCollection.class);
043: private final String name;
044: private final Kernel kernel;
045: private final Map proxies = new HashMap();
046: private final Set listeners = new HashSet();
047: private boolean stopped = false;
048: private final Class type;
049:
050: public ProxyCollection(String name, Class type, Set targets,
051: Kernel kernel) {
052: this .name = name;
053: this .kernel = kernel;
054: this .type = type;
055:
056: for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
057: addTarget((AbstractName) iterator.next());
058: }
059: }
060:
061: synchronized void destroy() {
062: stopped = true;
063: if (!AbstractGBeanReference.NO_PROXY) {
064: for (Iterator iterator = proxies.values().iterator(); iterator
065: .hasNext();) {
066: kernel.getProxyManager().destroyProxy(iterator.next());
067: }
068: }
069: proxies.clear();
070: listeners.clear();
071: }
072:
073: void addTarget(AbstractName target) {
074: Object proxy;
075: ArrayList listenerCopy;
076: synchronized (this ) {
077: // if this is not a new target return
078: if (proxies.containsKey(target)) {
079: return;
080: }
081:
082: // create and add the proxy
083: if (AbstractGBeanReference.NO_PROXY) {
084: try {
085: proxy = kernel.getGBean(target);
086: } catch (GBeanNotFoundException e) {
087: // gbean disappeard on us
088: log
089: .debug("GBean was unloaded before it could be added to reference collections: "
090: + target);
091: return;
092: }
093: } else {
094: proxy = kernel.getProxyManager().createProxy(target,
095: type);
096: }
097: proxies.put(target, proxy);
098:
099: // make a snapshot of the listeners
100: listenerCopy = new ArrayList(listeners);
101: }
102:
103: // fire the member added event
104: for (Iterator iterator = listenerCopy.iterator(); iterator
105: .hasNext();) {
106: ReferenceCollectionListener listener = (ReferenceCollectionListener) iterator
107: .next();
108: try {
109: listener.memberAdded(new ReferenceCollectionEvent(name,
110: proxy));
111: } catch (Throwable t) {
112: log.error("Listener threw exception", t);
113: }
114: }
115: }
116:
117: void removeTarget(AbstractName target) {
118: Object proxy;
119: ArrayList listenerCopy;
120: synchronized (this ) {
121: // remove the proxy
122: proxy = proxies.remove(target);
123:
124: // if this was not a target return
125: if (proxy == null) {
126: return;
127: }
128:
129: // make a snapshot of the listeners
130: listenerCopy = new ArrayList(listeners);
131: }
132:
133: // fire the member removed event
134: for (Iterator iterator = listenerCopy.iterator(); iterator
135: .hasNext();) {
136: ReferenceCollectionListener listener = (ReferenceCollectionListener) iterator
137: .next();
138: try {
139: listener.memberRemoved(new ReferenceCollectionEvent(
140: name, proxy));
141: } catch (Throwable t) {
142: log.error("Listener threw exception", t);
143: }
144: }
145:
146: // destroy the proxy
147: if (!AbstractGBeanReference.NO_PROXY) {
148: kernel.getProxyManager().destroyProxy(proxy);
149: }
150: }
151:
152: public synchronized ObjectName[] getMemberObjectNames() {
153: return (ObjectName[]) proxies.keySet().toArray(
154: new ObjectName[0]);
155: }
156:
157: public synchronized boolean isStopped() {
158: return stopped;
159: }
160:
161: public synchronized void addReferenceCollectionListener(
162: ReferenceCollectionListener listener) {
163: listeners.add(listener);
164: }
165:
166: public synchronized void removeReferenceCollectionListener(
167: ReferenceCollectionListener listener) {
168: listeners.remove(listener);
169: }
170:
171: public synchronized int size() {
172: if (stopped) {
173: return 0;
174: }
175: return proxies.size();
176: }
177:
178: public synchronized boolean isEmpty() {
179: if (stopped) {
180: return true;
181: }
182: return proxies.isEmpty();
183: }
184:
185: public synchronized boolean contains(Object o) {
186: if (stopped) {
187: return false;
188: }
189: return proxies.containsValue(o);
190: }
191:
192: public synchronized Iterator iterator() {
193: if (stopped) {
194: return new Iterator() {
195: public boolean hasNext() {
196: return false;
197: }
198:
199: public Object next() {
200: throw new NoSuchElementException();
201: }
202:
203: public void remove() {
204: throw new UnsupportedOperationException();
205: }
206: };
207: }
208:
209: return new Iterator() {
210: // copy the proxies, so the client can iterate without concurrent modification
211: // this is necssary since the client has nothing to synchronize on
212: private final Iterator iterator = new ArrayList(proxies
213: .values()).iterator();
214:
215: public boolean hasNext() {
216: return iterator.hasNext();
217: }
218:
219: public Object next() {
220: return iterator.next();
221: }
222:
223: public void remove() {
224: throw new UnsupportedOperationException();
225: }
226: };
227: }
228:
229: public synchronized Object[] toArray() {
230: if (stopped) {
231: return new Object[0];
232: }
233: return proxies.values().toArray();
234: }
235:
236: public synchronized Object[] toArray(Object a[]) {
237: if (stopped) {
238: if (a.length > 0) {
239: a[0] = null;
240: }
241: return a;
242: }
243: return proxies.values().toArray(a);
244: }
245:
246: public synchronized boolean containsAll(Collection c) {
247: if (stopped) {
248: return c.isEmpty();
249: }
250: return proxies.values().containsAll(c);
251: }
252:
253: public boolean add(Object o) {
254: throw new UnsupportedOperationException();
255: }
256:
257: public boolean remove(Object o) {
258: throw new UnsupportedOperationException();
259: }
260:
261: public boolean addAll(Collection c) {
262: throw new UnsupportedOperationException();
263: }
264:
265: public boolean removeAll(Collection c) {
266: throw new UnsupportedOperationException();
267: }
268:
269: public boolean retainAll(Collection c) {
270: throw new UnsupportedOperationException();
271: }
272:
273: public void clear() {
274: throw new UnsupportedOperationException();
275: }
276: }
|