KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > navigator > resources > workbench > ResourceExtensionContentProvider


1 /*******************************************************************************
2  * Copyright (c) 2003, 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.ui.internal.navigator.resources.workbench;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.Iterator JavaDoc;
16
17 import org.eclipse.core.resources.IContainer;
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.resources.IResourceDelta;
20 import org.eclipse.jface.viewers.AbstractTreeViewer;
21 import org.eclipse.jface.viewers.StructuredViewer;
22 import org.eclipse.jface.viewers.Viewer;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.ui.model.WorkbenchContentProvider;
25
26 /**
27  * <p>
28  * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
29  * part of a work in progress. There is a guarantee neither that this API will
30  * work nor that it will remain the same. Please do not use this API without
31  * consulting with the Platform/UI team.
32  * </p>
33  * @since 3.2
34  */

35 public class ResourceExtensionContentProvider extends WorkbenchContentProvider {
36  
37     private static final Object JavaDoc[] NO_CHILDREN = new Object JavaDoc[0];
38     private Viewer viewer;
39     
40     /**
41      *
42      */

43     public ResourceExtensionContentProvider() {
44         super();
45     }
46
47     /*
48      * (non-Javadoc)
49      *
50      * @see org.eclipse.ui.model.BaseWorkbenchContentProvider#getElements(java.lang.Object)
51      */

52     public Object JavaDoc[] getElements(Object JavaDoc element) {
53         return super.getChildren(element);
54     }
55
56     /*
57      * (non-Javadoc)
58      *
59      * @see org.eclipse.ui.model.BaseWorkbenchContentProvider#getChildren(java.lang.Object)
60      */

61     public Object JavaDoc[] getChildren(Object JavaDoc element) {
62         if(element instanceof IResource)
63             return super.getChildren(element);
64         return NO_CHILDREN;
65     }
66     
67     /* (non-Javadoc)
68      * @see org.eclipse.ui.model.BaseWorkbenchContentProvider#hasChildren(java.lang.Object)
69      */

70     public boolean hasChildren(Object JavaDoc element) {
71         return element instanceof IContainer && super.hasChildren(element);
72     }
73     
74     /* (non-Javadoc)
75      * @see org.eclipse.ui.model.WorkbenchContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
76      */

77     public void inputChanged(Viewer viewer, Object JavaDoc oldInput, Object JavaDoc newInput) {
78         super.inputChanged(viewer, oldInput, newInput);
79         this.viewer = viewer;
80     }
81
82
83     /**
84      * Process the resource delta.
85      *
86      * @param delta
87      */

88     protected void processDelta(IResourceDelta delta) {
89
90         Control ctrl = viewer.getControl();
91         if (ctrl == null || ctrl.isDisposed()) {
92             return;
93         }
94         
95         
96         final Collection JavaDoc runnables = new ArrayList JavaDoc();
97         processDelta(delta, runnables);
98
99         if (runnables.isEmpty()) {
100             return;
101         }
102
103         //Are we in the UIThread? If so spin it until we are done
104
if (ctrl.getDisplay().getThread() == Thread.currentThread()) {
105             runUpdates(runnables);
106         } else {
107             ctrl.getDisplay().asyncExec(new Runnable JavaDoc(){
108                 /* (non-Javadoc)
109                  * @see java.lang.Runnable#run()
110                  */

111                 public void run() {
112                     //Abort if this happens after disposes
113
Control ctrl = viewer.getControl();
114                     if (ctrl == null || ctrl.isDisposed()) {
115                         return;
116                     }
117                     
118                     runUpdates(runnables);
119                 }
120             });
121         }
122
123     }
124     
125     /**
126      * Process a resource delta. Add any runnables
127      */

128     private void processDelta(IResourceDelta delta, Collection JavaDoc runnables) {
129         //he widget may have been destroyed
130
// by the time this is run. Check for this and do nothing if so.
131
Control ctrl = viewer.getControl();
132         if (ctrl == null || ctrl.isDisposed()) {
133             return;
134         }
135
136         // Get the affected resource
137
final IResource resource = delta.getResource();
138     
139         // If any children have changed type, just do a full refresh of this
140
// parent,
141
// since a simple update on such children won't work,
142
// and trying to map the change to a remove and add is too dicey.
143
// The case is: folder A renamed to existing file B, answering yes to
144
// overwrite B.
145
IResourceDelta[] affectedChildren = delta
146                 .getAffectedChildren(IResourceDelta.CHANGED);
147         for (int i = 0; i < affectedChildren.length; i++) {
148             if ((affectedChildren[i].getFlags() & IResourceDelta.TYPE) != 0) {
149                 runnables.add(getRefreshRunnable(resource));
150                 return;
151             }
152         }
153
154         // Check the flags for changes the Navigator cares about.
155
// See ResourceLabelProvider for the aspects it cares about.
156
// Notice we don't care about F_CONTENT or F_MARKERS currently.
157
int changeFlags = delta.getFlags();
158         if ((changeFlags & (IResourceDelta.OPEN | IResourceDelta.SYNC
159                 | IResourceDelta.TYPE | IResourceDelta.DESCRIPTION)) != 0) {
160 // Runnable updateRunnable = new Runnable(){
161
// public void run() {
162
// ((StructuredViewer) viewer).update(resource, null);
163
// }
164
// };
165
// runnables.add(updateRunnable);
166

167             /* support the Closed Projects filter;
168              * when a project is closed, it may need to be removed from the view.
169              */

170             runnables.add(getRefreshRunnable(resource.getParent()));
171         }
172         // Replacing a resource may affect its label and its children
173
if ((changeFlags & IResourceDelta.REPLACED) != 0) {
174             runnables.add(getRefreshRunnable(resource));
175             return;
176         }
177
178
179         // Handle changed children .
180
for (int i = 0; i < affectedChildren.length; i++) {
181             processDelta(affectedChildren[i], runnables);
182         }
183
184         // @issue several problems here:
185
// - should process removals before additions, to avoid multiple equal
186
// elements in viewer
187
// - Kim: processing removals before additions was the indirect cause of
188
// 44081 and its varients
189
// - Nick: no delta should have an add and a remove on the same element,
190
// so processing adds first is probably OK
191
// - using setRedraw will cause extra flashiness
192
// - setRedraw is used even for simple changes
193
// - to avoid seeing a rename in two stages, should turn redraw on/off
194
// around combined removal and addition
195
// - Kim: done, and only in the case of a rename (both remove and add
196
// changes in one delta).
197

198         IResourceDelta[] addedChildren = delta
199                 .getAffectedChildren(IResourceDelta.ADDED);
200         IResourceDelta[] removedChildren = delta
201                 .getAffectedChildren(IResourceDelta.REMOVED);
202
203         if (addedChildren.length == 0 && removedChildren.length == 0) {
204             return;
205         }
206
207         final Object JavaDoc[] addedObjects;
208         final Object JavaDoc[] removedObjects;
209
210         // Process additions before removals as to not cause selection
211
// preservation prior to new objects being added
212
// Handle added children. Issue one update for all insertions.
213
int numMovedFrom = 0;
214         int numMovedTo = 0;
215         if (addedChildren.length > 0) {
216             addedObjects = new Object JavaDoc[addedChildren.length];
217             for (int i = 0; i < addedChildren.length; i++) {
218                 addedObjects[i] = addedChildren[i].getResource();
219                 if ((addedChildren[i].getFlags() & IResourceDelta.MOVED_FROM) != 0) {
220                     ++numMovedFrom;
221                 }
222             }
223         } else {
224             addedObjects = new Object JavaDoc[0];
225         }
226
227         // Handle removed children. Issue one update for all removals.
228
if (removedChildren.length > 0) {
229             removedObjects = new Object JavaDoc[removedChildren.length];
230             for (int i = 0; i < removedChildren.length; i++) {
231                 removedObjects[i] = removedChildren[i].getResource();
232                 if ((removedChildren[i].getFlags() & IResourceDelta.MOVED_TO) != 0) {
233                     ++numMovedTo;
234                 }
235             }
236         } else {
237             removedObjects = new Object JavaDoc[0];
238         }
239         // heuristic test for items moving within same folder (i.e. renames)
240
final boolean hasRename = numMovedFrom > 0 && numMovedTo > 0;
241         
242         Runnable JavaDoc addAndRemove = new Runnable JavaDoc(){
243             public void run() {
244                 if (viewer instanceof AbstractTreeViewer) {
245                     AbstractTreeViewer treeViewer = (AbstractTreeViewer) viewer;
246                     // Disable redraw until the operation is finished so we don't
247
// get a flash of both the new and old item (in the case of
248
// rename)
249
// Only do this if we're both adding and removing files (the
250
// rename case)
251
if (hasRename) {
252                         treeViewer.getControl().setRedraw(false);
253                     }
254                     try {
255                         if (addedObjects.length > 0) {
256                             treeViewer.add(resource, addedObjects);
257                         }
258                         if (removedObjects.length > 0) {
259                             treeViewer.remove(removedObjects);
260                         }
261                     }
262                     finally {
263                         if (hasRename) {
264                             treeViewer.getControl().setRedraw(true);
265                         }
266                     }
267                 } else {
268                     ((StructuredViewer) viewer).refresh(resource);
269                 }
270             }
271         };
272         runnables.add(addAndRemove);
273     }
274     
275     /**
276      * Return a runnable for refreshing a resource.
277      * @param resource
278      * @return Runnable
279      */

280     private Runnable JavaDoc getRefreshRunnable(final IResource resource) {
281         return new Runnable JavaDoc(){
282             public void run() {
283                 ((StructuredViewer) viewer).refresh(resource);
284             }
285         };
286     }
287     
288     /**
289      * Run all of the runnables that are the widget updates
290      * @param runnables
291      */

292     private void runUpdates(Collection JavaDoc runnables) {
293         Iterator JavaDoc runnableIterator = runnables.iterator();
294         while(runnableIterator.hasNext()){
295             ((Runnable JavaDoc)runnableIterator.next()).run();
296         }
297         
298     }
299     
300 }
301
Popular Tags