View Javadoc

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              // if this is not a new target return
76              if (proxies.containsKey(target)) {
77                  return;
78              }
79  
80              // create and add the proxy
81              if (AbstractGBeanReference.NO_PROXY) {
82                  try {
83                      proxy = kernel.getGBean(target);
84                  } catch (GBeanNotFoundException e) {
85                      // gbean disappeard on us
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              // make a snapshot of the listeners
95              listenerCopy = new ArrayList(listeners);
96          }
97  
98          // fire the member added event
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             // remove the proxy
114             proxy = proxies.remove(target);
115 
116             // if this was not a target return
117             if (proxy == null) {
118                 return;
119             }
120 
121             // make a snapshot of the listeners
122             listenerCopy = new ArrayList(listeners);
123         }
124 
125         // fire the member removed event
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         // destroy the proxy
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             // copy the proxies, so the client can iterate without concurrent modification
197             // this is necssary since the client has nothing to synchronize on
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 }