KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > viewers > AsynchronousTreeModel


1 /*******************************************************************************
2  * Copyright (c) 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.debug.internal.ui.viewers;
12
13 import org.eclipse.debug.internal.ui.DebugUIPlugin;
14 import org.eclipse.debug.internal.ui.viewers.provisional.IAsynchronousContentAdapter;
15 import org.eclipse.debug.internal.ui.viewers.provisional.IContainerRequestMonitor;
16 import org.eclipse.jface.viewers.TreePath;
17
18
19 /**
20  * Model for an asynchronous tree
21  *
22  * @since 3.2
23  */

24 public class AsynchronousTreeModel extends AsynchronousModel {
25
26     /**
27      * Constructs a new empty tree model
28      *
29      * @param viewer associated viewer
30      */

31     public AsynchronousTreeModel(AsynchronousViewer viewer) {
32         super(viewer);
33     }
34     
35     /**
36      * Adds the given path to this model
37      *
38      * @param treePath
39      */

40     public synchronized void add(TreePath treePath) {
41         if (treePath.getSegmentCount() > 1) {
42             int parentIndex = treePath.getSegmentCount() - 2;
43             Object JavaDoc parent = treePath.getSegment(parentIndex);
44
45             // find the paths to the parent, if it's present
46
ModelNode[] nodes = getNodes(parent);
47             if (nodes != null) {
48                 // find the right node
49
for (int i = 0; i < nodes.length; i++) {
50                     ModelNode node = nodes[i];
51                     if (treePath.startsWith(node.getTreePath(), null)) {
52                         AddRequestMonitor addRequest = new AddRequestMonitor(node, treePath, this);
53                         requestScheduled(addRequest);
54                         addRequest.done();
55                         return;
56                     }
57                 }
58             }
59             // refresh the leaf parent, if any
60
for (int i = parentIndex - 1; i >= 0; i--) {
61                 parent = treePath.getSegment(i);
62                 nodes = getNodes(parent);
63                 if (nodes != null) {
64                     for (int j = 0; j < nodes.length; j++) {
65                         final ModelNode node = nodes[j];
66                         if (treePath.startsWith(node.getTreePath(), null)) {
67                             Runnable JavaDoc runnable = new Runnable JavaDoc() {
68                                 public void run() {
69                                     getViewer().nodeChanged(node);
70                                 }
71                             };
72                             getViewer().getControl().getDisplay().asyncExec(runnable);
73                             return;
74                         }
75                     }
76                 }
77             }
78         }
79     }
80     
81     /**
82      * Removes the item specified in the given tree path from this model.
83      *
84      * @param treePath
85      */

86     public synchronized void remove(TreePath treePath) {
87         if (treePath.getSegmentCount() > 1) {
88             // find the paths to the element, if it's present
89
Object JavaDoc element = treePath.getLastSegment();
90             ModelNode[] nodes = getNodes(element);
91             if (nodes != null) {
92                 // find the right node
93
for (int i = 0; i < nodes.length; i++) {
94                     ModelNode node = nodes[i];
95                     if (node.correspondsTo(treePath)) {
96                         RemoveRequestMonitor request = new RemoveRequestMonitor(node, treePath, this);
97                         requestScheduled(request);
98                         request.done();
99                         return;
100                     }
101                 }
102             }
103             // find the first parent present, and update its children
104
// to avoid a pending add in the subtree adding something
105
// that has been removed
106
int index = treePath.getSegmentCount() - 2;
107             while (index > 0) {
108                 element = treePath.getSegment(index);
109                 nodes = getNodes(element);
110                 if (nodes != null) {
111                     // find the right node
112
for (int i = 0; i < nodes.length; i++) {
113                         ModelNode node = nodes[i];
114                         if (treePath.startsWith(node.getTreePath(), null)) {
115                             updateChildren(node);
116                             return;
117                         }
118                     }
119                 }
120                 index--;
121             }
122         }
123     }
124     
125     /**
126      * Callback from async request to remove a node.
127      *
128      * @param node
129      */

130     protected void remove(final ModelNode node) {
131         final ModelNode parentNode = node.getParentNode();
132         if (parentNode == null) {
133             return;
134         }
135         int index = -1;
136         synchronized (this) {
137             index = parentNode.getChildIndex(node);
138             parentNode.removeChild(node);
139             unmapNode(node);
140             node.dispose();
141             if (DEBUG_MODEL) {
142                 DebugUIPlugin.debug("REMOVE: " + node); //$NON-NLS-1$
143
DebugUIPlugin.debug(toString());
144             }
145         }
146         final int unmapFrom = index;
147         final AsynchronousTreeViewer viewer = getTreeViewer();
148         preservingSelection(new Runnable JavaDoc() {
149             public void run() {
150                 // unmap the removed node and all children that were shifted
151
viewer.unmapNode(node);
152                 if (unmapFrom > -1) {
153                     ModelNode[] childrenNodes = parentNode.getChildrenNodes();
154                     for (int i = unmapFrom; i < childrenNodes.length; i++) {
155                         viewer.unmapNode(childrenNodes[i]);
156                     }
157                 }
158                 viewer.nodeChildRemoved(parentNode, unmapFrom);
159             }
160         });
161     }
162     
163     /**
164      * Asynchronous update for add request.
165      *
166      * @param parent
167      * @param element
168      */

169     protected void add(final ModelNode parent, Object JavaDoc element) {
170         Object JavaDoc[] children = filter(parent.getElement(), new Object JavaDoc[] { element });
171         if (children.length == 0) {
172             return; // added element was filtered out.
173
}
174         synchronized (this) {
175             ModelNode[] childrenNodes = parent.getChildrenNodes();
176             if (childrenNodes != null) {
177                 for (int i = 0; i < childrenNodes.length; i++) {
178                     if (element.equals(childrenNodes[i].getElement()))
179                         return; //already added to the tree (probably via a refresh)
180
}
181             }
182             ModelNode node = new ModelNode(parent, element);
183             parent.addChild(node);
184             mapElement(element, node);
185             if (DEBUG_MODEL) {
186                 DebugUIPlugin.debug("ADD: (parent) " + parent + " (child) " + element); //$NON-NLS-1$//$NON-NLS-2$
187
DebugUIPlugin.debug(toString());
188             }
189         }
190         //TODO sort???
191
// notify the viewer to update
192

193         preservingSelection(new Runnable JavaDoc() {
194             public void run() {
195                 getTreeViewer().nodeChildrenAdded(parent);
196             }
197         });
198                 
199     }
200     
201     /**
202      * Returns all paths to the given element or <code>null</code> if none.
203      *
204      * @param element model element
205      * @return paths to the given element or <code>null</code>
206      */

207     public synchronized TreePath[] getTreePaths(Object JavaDoc element) {
208         ModelNode[] nodes = getNodes(element);
209         if (nodes == null) {
210             return null;
211         }
212         TreePath[] paths = new TreePath[nodes.length];
213         for (int i = 0; i < nodes.length; i++) {
214             paths[i] = nodes[i].getTreePath();
215         }
216         return paths;
217     }
218     
219     protected AsynchronousTreeViewer getTreeViewer() {
220         return (AsynchronousTreeViewer) getViewer();
221     }
222     
223     /**
224      * Updates whether the given node has children.
225      *
226      * @param node
227      * node to update
228      */

229     protected void updateHasChildren(ModelNode node) {
230         Object JavaDoc element = node.getElement();
231         IAsynchronousContentAdapter adapter = getContentAdapter(element);
232         if (adapter == null) {
233             adapter = fEmptyContentAdapter;
234         }
235         if (adapter != null) {
236             IContainerRequestMonitor update = new ContainerRequestMonitor(node, this);
237             requestScheduled(update);
238             adapter.isContainer(element, getPresentationContext(), update);
239         }
240     }
241
242     /* (non-Javadoc)
243      *
244      * Also unmaps chidren
245      *
246      * @see org.eclipse.debug.internal.ui.viewers.AsynchronousModel#unmapNode(org.eclipse.debug.internal.ui.viewers.ModelNode)
247      */

248     protected synchronized void unmapNode(ModelNode node) {
249         ModelNode[] childrenNodes = node.getChildrenNodes();
250         if (childrenNodes != null) {
251             for (int i = 0; i < childrenNodes.length; i++) {
252                 unmapNode(childrenNodes[i]);
253             }
254         }
255         super.unmapNode(node);
256     }
257     
258     /**
259      * Called by <code>ContainerRequestMonitor</code> after it is determined
260      * if the node contains children.
261      *
262      * @param node
263      * @param containsChildren
264      */

265      void setIsContainer(final ModelNode node, boolean containsChildren) {
266         ModelNode[] unmapChildren = null;
267         synchronized (this) {
268             ModelNode[] prevChildren = node.getChildrenNodes();
269             node.setIsContainer(containsChildren);
270             if (!containsChildren && prevChildren != null) {
271                 unmapChildren = prevChildren;
272                 for (int i = 0; i < prevChildren.length; i++) {
273                     ModelNode child = prevChildren[i];
274                     unmapNode(child);
275                     child.dispose();
276                 }
277                 node.setChildren(null);
278             }
279             if (DEBUG_MODEL) {
280                 DebugUIPlugin.debug("SET CONTAINER: " + node); //$NON-NLS-1$
281
DebugUIPlugin.debug(toString());
282             }
283         }
284 // update tree outside lock
285
final ModelNode[] finalUnmap = unmapChildren;
286         preservingSelection(new Runnable JavaDoc() {
287             public void run() {
288                 if (finalUnmap != null) {
289                     for (int i = 0; i < finalUnmap.length; i++) {
290                         getViewer().unmapNode(finalUnmap[i]);
291                     }
292                 }
293                 getTreeViewer().nodeContainerChanged(node);
294                 getViewer().nodeChildrenChanged(node);
295             }
296         });
297         
298     }
299 }
300
Popular Tags