KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > tasklist > docscan > FilteredTasksList


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
20 package org.netbeans.modules.tasklist.docscan;
21
22 import org.netbeans.modules.tasklist.core.ObservableList;
23 import org.netbeans.modules.tasklist.core.TaskListener;
24 import org.netbeans.modules.tasklist.core.Task;
25 import org.netbeans.modules.tasklist.core.TaskList;
26
27 import java.util.*;
28
29 /**
30  * Delegate actions to original task list while
31  * narrowing them to source tasks.
32  *
33  * @author Petr Kuzel
34  */

35 final class FilteredTasksList implements ObservableList {
36
37     /*
38      * There is one realy strict implementation assumption
39      * that source tasks never nest. It simplifies
40      * implementation a lot because it degrades to list.
41      *
42      * It also assumes that visible view must have attached
43      * TaskListener
44      */

45
46     private final TaskList peer;
47     private List listeners = new ArrayList(1);
48     private List tasks = new LinkedList();
49     private EventHandler handler;
50     private boolean silent = false;
51
52     public FilteredTasksList(TaskList peer) {
53         this.peer = peer;
54     }
55
56     public List getTasks() {
57         return tasks;
58     }
59
60     public synchronized void addTaskListener(TaskListener l) {
61         // we do not add directly to peer
62
// because we filter fired events
63
assert l != null;
64         assert listeners.contains(l) == false; // missing removeListener ?
65
ArrayList clisteners = new ArrayList(listeners);
66         clisteners.add(l);
67         if (clisteners.size() == 1) {
68             handler = new EventHandler();
69             peer.addTaskListener(handler);
70         }
71         listeners = clisteners;
72     }
73
74     public synchronized void removeTaskListener(TaskListener l) {
75         ArrayList clisteners = new ArrayList(listeners);
76         clisteners.remove(l);
77         if (clisteners.size() == 0) {
78             peer.removeTaskListener(handler); // nobody is interested in changes
79
handler = null;
80         }
81         listeners = clisteners;
82     }
83
84     /**
85      * Notify that it's not needed anymore.
86      */

87     synchronized void byebye() {
88         if (listeners.size() > 0) {
89 // System.err.println("Leaked listeners: " + listeners);
90
}
91         listeners.clear();
92         peer.removeTaskListener(handler); // nobody is interested in changes
93
handler = null;
94     }
95
96     private void fireStructureChanged(Task task) {
97 // if (silent) return; // the event comes from root.updatedStructure
98

99         Iterator it = listeners.iterator();
100         while (it.hasNext()) {
101             TaskListener listener = (TaskListener) it.next();
102             listener.structureChanged(task);
103         }
104     }
105
106     /** Client must fire structure changed event */
107     private void refreshSnapshot() {
108         tasks.clear();
109         loadSourceTasks(peer.getTasks());
110     }
111
112     private void loadSourceTasks(List tasks) {
113         if (tasks.size() == 0) return;
114         Iterator it = tasks.iterator();
115         while (it.hasNext()) {
116             Task task = (Task) it.next();
117             if (task.getSeed() instanceof SourceTaskProvider) {
118                 tasks.add(task);
119             } else {
120                 // There are those nesting category tasks
121
// if grouping treshold is matched.
122
// Eliminate them to sustain list assumption.
123
if (task.hasSubtasks()) {
124                     loadSourceTasks(task.getSubtasks()); // recursion
125
}
126             }
127         }
128     }
129
130     /**
131      * Forward filtered events
132      */

133     private class EventHandler implements TaskListener {
134         public void selectedTask(Task t) {
135             if (getTasks().contains(t)) {
136                 Iterator it = listeners.iterator();
137                 while (it.hasNext()) {
138                     TaskListener listener = (TaskListener) it.next();
139                     listener.selectedTask(t);
140                 }
141             }
142         }
143
144         public void warpedTask(Task t) {
145             assert false : "Not implemented";
146         }
147
148         public void addedTask(Task t) {
149             if (t.getSeed() instanceof SourceTaskProvider) {
150                 try {
151                     silent = true;
152                     tasks.add(t);
153                 } finally {
154                     silent = false;
155                 }
156
157                 // fire event
158

159                 Iterator it = listeners.iterator();
160                 while (it.hasNext()) {
161                     TaskListener listener = (TaskListener) it.next();
162                     listener.addedTask(t);
163                 }
164             } else if (t.hasSubtasks()) {
165                 // category nodes
166
Iterator it = t.subtasksIterator();
167                 while (it.hasNext()) {
168                     Task task = (Task) it.next();
169                     addedTask(task); // recursion
170
}
171             }
172         }
173
174         public void removedTask(Task pt, Task t, int index) {
175             if (t.getSeed() instanceof SourceTaskProvider) {
176                 boolean removed = false;
177                 try {
178                     silent = true;
179                     removed = tasks.remove(t);
180                 } finally {
181                     silent = false;
182                 }
183
184                 // fire event
185

186                 if (removed) {
187                     Iterator it = listeners.iterator();
188                     while (it.hasNext()) {
189                         TaskListener listener = (TaskListener) it.next();
190                         listener.removedTask(null, t, index);
191                     }
192                 }
193             } else if (t.hasSubtasks()) {
194                 // category nodes
195
Iterator it = t.subtasksIterator();
196                 int ind = 0;
197                 while (it.hasNext()) {
198                     Task task = (Task) it.next();
199                     // TODO: always use 0 here instead of ind++?
200
removedTask(null, task, ind++); // recursion
201
}
202             }
203         }
204
205         public void structureChanged(Task t) {
206             // need to build it again
207
try {
208                 silent = true;
209                 refreshSnapshot();
210             } finally {
211                 silent = false;
212             }
213             fireStructureChanged(t);
214         }
215     }
216
217 }
218
Popular Tags