KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > timers > InstanceWatcher


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.timers;
20
21 import java.lang.ref.Reference JavaDoc;
22 import java.lang.ref.ReferenceQueue JavaDoc;
23 import java.lang.ref.WeakReference JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.LinkedList JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.concurrent.ExecutorService JavaDoc;
30 import java.util.concurrent.Executors JavaDoc;
31 import javax.swing.event.ChangeEvent JavaDoc;
32 import javax.swing.event.ChangeListener JavaDoc;
33
34 /** A class for watching instances.
35  *
36  * @author Petr Hrebejk
37  */

38 public class InstanceWatcher {
39
40     private List JavaDoc<Reference JavaDoc<Object JavaDoc>> references;
41     private ReferenceQueue JavaDoc<Object JavaDoc> queue;
42     private static ExecutorService JavaDoc executor = Executors.newSingleThreadExecutor();
43     
44     private transient List JavaDoc<WeakReference JavaDoc<ChangeListener JavaDoc>> changeListenerList;
45
46     
47     /** Creates a new instance of InstanceWatcher */
48     public InstanceWatcher() {
49         references = new ArrayList JavaDoc<Reference JavaDoc<Object JavaDoc>>();
50         queue = new ReferenceQueue JavaDoc<Object JavaDoc>();
51         new FinalizingToken();
52     }
53            
54     public synchronized void add( Object JavaDoc instance ) {
55         if ( ! contains( instance ) ) {
56             references.add( new WeakReference JavaDoc<Object JavaDoc>( instance, queue ) );
57         }
58     }
59     
60     private synchronized boolean contains( Object JavaDoc o ) {
61         for( Reference JavaDoc r : references ) {
62             if ( r.get() == o ) {
63                 return true;
64             }
65         }
66         return false;
67     }
68     
69     public synchronized int size() {
70         removeNulls();
71         return references.size();
72     }
73     
74     public Collection JavaDoc<?> getInstances() {
75         List JavaDoc<Object JavaDoc> l = new ArrayList JavaDoc<Object JavaDoc>(references.size());
76         for (Reference JavaDoc wr : references) {
77             Object JavaDoc inst = wr.get();
78             if (inst != null) l.add(inst);
79         }
80         return l;
81     }
82     
83     /*
84     public Iterator iterator() {
85         
86     }
87     */

88     
89     /**
90      * Registers ChangeListener to receive events. Notice that the listeners are
91      * held weakly. Make sure that you create hard reference to yopur listener.
92      * @param listener The listener to register.
93      */

94     public synchronized void addChangeListener(javax.swing.event.ChangeListener JavaDoc listener) {
95         if (changeListenerList == null ) {
96             changeListenerList = new ArrayList JavaDoc<WeakReference JavaDoc<ChangeListener JavaDoc>>();
97         }
98         changeListenerList.add(new WeakReference JavaDoc<ChangeListener JavaDoc>( listener ) );
99     }
100
101     /**
102      * Removes ChangeListener from the list of listeners.
103      * @param listener The listener to remove.
104      */

105     public synchronized void removeChangeListener(ChangeListener JavaDoc listener) {
106         
107         if ( listener == null ) {
108             return;
109         }
110         
111         if (changeListenerList != null ) {
112             for( WeakReference JavaDoc<ChangeListener JavaDoc> r : changeListenerList ) {
113                 if ( listener.equals( r.get() ) ) {
114                     changeListenerList.remove( r );
115                 }
116             }
117         }
118         
119     }
120     
121     // Private methods ---------------------------------------------------------
122

123     private static <T> void cleanAndCopy( List JavaDoc<? extends Reference JavaDoc<T>> src, List JavaDoc<? super T> dest ) {
124         for( int i = src.size() - 1; i >= 0; i-- ) {
125             T o = src.get(i).get();
126             if( o == null ) {
127                 src.remove(i);
128             }
129             else if ( dest != null ) {
130                 dest.add( 0, o );
131             }
132         }
133     }
134     
135     
136     private synchronized void removeNulls() {
137         cleanAndCopy( references, null );
138     }
139     
140     private boolean cleanQueue() {
141         boolean retValue = false;
142         
143         while( queue.poll() != null ) {
144             retValue = true;
145         }
146         
147         return retValue;
148     }
149     
150     private void refresh() {
151         if ( cleanQueue() ) {
152             removeNulls();
153             fireChangeListenerStateChanged();
154         }
155         
156         new FinalizingToken();
157     }
158     
159     private void fireChangeListenerStateChanged() {
160         List JavaDoc<ChangeListener JavaDoc> list = new LinkedList JavaDoc<ChangeListener JavaDoc>();
161         synchronized (this) {
162             if (changeListenerList == null) {
163                 return;
164             }
165             cleanAndCopy( changeListenerList, list );
166         }
167         
168         ChangeEvent JavaDoc e = new ChangeEvent JavaDoc( this );
169         for (ChangeListener JavaDoc ch : list ) {
170             ch.stateChanged (e);
171         }
172     }
173     
174     // Private innerclasses ----------------------------------------------------
175

176     private class FinalizingToken implements Runnable JavaDoc {
177                 
178         public void finalize() {
179             executor.submit( this );
180         }
181         
182         public void run() {
183             refresh();
184         }
185         
186     }
187                
188 }
189
Popular Tags