KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > core > subscribers > SubscriberDiffTreeEventHandler


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.team.internal.core.subscribers;
12
13 import org.eclipse.core.resources.*;
14 import org.eclipse.core.resources.mapping.ResourceTraversal;
15 import org.eclipse.core.runtime.*;
16 import org.eclipse.osgi.util.NLS;
17 import org.eclipse.team.core.ITeamStatus;
18 import org.eclipse.team.core.TeamStatus;
19 import org.eclipse.team.core.diff.*;
20 import org.eclipse.team.core.mapping.IResourceDiffTree;
21 import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
22 import org.eclipse.team.core.mapping.provider.ResourceDiffTree;
23 import org.eclipse.team.core.subscribers.Subscriber;
24 import org.eclipse.team.internal.core.*;
25
26 /**
27  * A subscriber event handler whose output is a diff tree
28  */

29 public class SubscriberDiffTreeEventHandler extends SubscriberEventHandler {
30
31     // State constants for the event handler
32
private static final int STATE_NEW = 0;
33     public static final int STATE_STARTED = 1;
34     private static final int STATE_OK_TO_INITIALIZE = 3;
35     private static final int STATE_COLLECTING_CHANGES = 5;
36     private static final int STATE_SHUTDOWN = 8;
37     
38     // state constants for exceptions
39
private static final int EXCEPTION_NONE = 0;
40     private static final int EXCEPTION_CANCELED = 1;
41     private static final int EXCEPTION_ERROR = 2;
42     
43     private ResourceDiffTree tree;
44     private SubscriberDiffCollector collector;
45     private ISynchronizationScopeManager manager;
46     private Object JavaDoc family;
47     private DiffFilter filter;
48     private int state = STATE_NEW;
49     private int exceptionState = EXCEPTION_NONE;
50
51     /*
52      * An event used to represent a change in a diff
53      */

54     private class SubscriberDiffChangedEvent extends SubscriberEvent {
55         private final IDiff node;
56
57         public SubscriberDiffChangedEvent(IResource resource, int type, int depth, IDiff node) {
58             super(resource, type, depth);
59             this.node = node;
60         }
61         public IDiff getChangedNode() {
62             return node;
63         }
64     }
65     
66     /*
67      * Collects resource and subscriber changes
68      */

69     private class SubscriberDiffCollector extends SubscriberResourceCollector {
70
71         public SubscriberDiffCollector(Subscriber subscriber) {
72             super(subscriber);
73         }
74
75         /* (non-Javadoc)
76          * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#hasMembers(org.eclipse.core.resources.IResource)
77          */

78         protected boolean hasMembers(IResource resource) {
79             return tree.members(resource).length > 0;
80         }
81
82         /* (non-Javadoc)
83          * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#remove(org.eclipse.core.resources.IResource)
84          */

85         protected void remove(IResource resource) {
86             SubscriberDiffTreeEventHandler.this.remove(resource);
87         }
88
89         /* (non-Javadoc)
90          * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#change(org.eclipse.core.resources.IResource, int)
91          */

92         protected void change(IResource resource, int depth) {
93             SubscriberDiffTreeEventHandler.this.change(resource, depth);
94         }
95     }
96     
97     /**
98      * Create the handler
99      * @param subscriber the subscriber for the handler
100      * @param manager the scope of the handler
101      * @param tree the tree to be populated by this handler
102      * @param filter a filter
103      */

104     public SubscriberDiffTreeEventHandler(Subscriber subscriber, ISynchronizationScopeManager manager, ResourceDiffTree tree, DiffFilter filter) {
105         super(subscriber, manager.getScope());
106         this.manager = manager;
107         this.tree = tree;
108         this.collector = new SubscriberDiffCollector(subscriber);
109         this.filter = filter;
110     }
111
112     protected void reset(ResourceTraversal[] traversals, int type) {
113         // Reset the exception state since we are reseting
114
exceptionState = EXCEPTION_NONE;
115         if (!manager.isInitialized() && state == STATE_OK_TO_INITIALIZE) {
116             // This means the scope has not been initialized
117
queueEvent(new RunnableEvent(new IWorkspaceRunnable() {
118                 public void run(IProgressMonitor monitor) throws CoreException {
119                     // Only initialize the scope if we are in the STARTED state
120
if (state == STATE_OK_TO_INITIALIZE) {
121                         try {
122                             prepareScope(monitor);
123                             state = STATE_COLLECTING_CHANGES;
124                         } finally {
125                             // If the initialization didn't complete,
126
// return to the STARTED state.
127
if (state != STATE_COLLECTING_CHANGES) {
128                                 state = STATE_STARTED;
129                                 if (exceptionState == EXCEPTION_NONE)
130                                     exceptionState = EXCEPTION_CANCELED;
131                             }
132                         }
133                     }
134                 }
135             }, true), true);
136         } else if (manager.isInitialized()) {
137             state = STATE_COLLECTING_CHANGES;
138             super.reset(traversals, type);
139         }
140     }
141     
142     public void reset(){
143         reset(getScope().getTraversals(),
144                 SubscriberEventHandler.SubscriberEvent.INITIALIZE);
145     }
146     
147     protected void prepareScope(IProgressMonitor monitor) {
148         try {
149             manager.initialize(monitor);
150         } catch (CoreException e) {
151             handleException(e);
152         }
153         ResourceTraversal[] traversals = manager.getScope().getTraversals();
154         if (traversals.length > 0)
155             reset(traversals, SubscriberEvent.INITIALIZE);
156     }
157
158     /* (non-Javadoc)
159      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#handleChange(org.eclipse.core.resources.IResource)
160      */

161     protected void handleChange(IResource resource) throws CoreException {
162         IDiff node = getSubscriber().getDiff(resource);
163         if (node == null) {
164             queueDispatchEvent(
165                 new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_ZERO));
166         } else {
167             if (isInScope(resource))
168                 queueDispatchEvent(
169                     new SubscriberDiffChangedEvent(resource, SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, node));
170         }
171     }
172
173     private boolean isInScope(IResource resource) {
174         return manager.getScope().contains(resource);
175     }
176
177     /* (non-Javadoc)
178      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#collectAll(org.eclipse.core.resources.IResource, int, org.eclipse.core.runtime.IProgressMonitor)
179      */

180     protected void collectAll(IResource resource, int depth,
181             final IProgressMonitor monitor) {
182         Policy.checkCanceled(monitor);
183         monitor.beginTask(null, IProgressMonitor.UNKNOWN);
184         ResourceTraversal[] traversals = new ResourceTraversal[] { new ResourceTraversal(new IResource[] { resource }, depth, IResource.NONE) };
185         try {
186             getSubscriber().accept(traversals, new IDiffVisitor() {
187                 public boolean visit(IDiff diff) {
188                     Policy.checkCanceled(monitor);
189                     monitor.subTask(NLS.bind(Messages.SubscriberDiffTreeEventHandler_0, tree.getResource(diff).getFullPath().toString()));
190                     // Queue up any found diffs for inclusion into the output tree
191
queueDispatchEvent(
192                             new SubscriberDiffChangedEvent(tree.getResource(diff), SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, diff));
193                     // Handle any pending dispatches
194
handlePreemptiveEvents(monitor);
195                     handlePendingDispatch(monitor);
196                     return true;
197                 }
198             });
199         } catch (CoreException e) {
200             if (resource.getProject().isAccessible())
201                 handleException(e, resource, ITeamStatus.SYNC_INFO_SET_ERROR, e.getMessage());
202         } finally {
203             monitor.done();
204         }
205     }
206
207     /* (non-Javadoc)
208      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#dispatchEvents(org.eclipse.team.internal.core.subscribers.SubscriberEventHandler.SubscriberEvent[], org.eclipse.core.runtime.IProgressMonitor)
209      */

210     protected void dispatchEvents(SubscriberEvent[] events,
211             IProgressMonitor monitor) {
212         try {
213             tree.beginInput();
214             for (int i = 0; i < events.length; i++) {
215                 SubscriberEvent event = events[i];
216                 switch (event.getType()) {
217                     case SubscriberEvent.CHANGE :
218                         if (event instanceof SubscriberDiffChangedEvent) {
219                             SubscriberDiffChangedEvent se = (SubscriberDiffChangedEvent) event;
220                             IDiff changedNode = se.getChangedNode();
221                             if (changedNode.getKind() == IDiff.NO_CHANGE) {
222                                 tree.remove(changedNode.getPath());
223                             } else {
224                                 addDiff(changedNode, monitor);
225                             }
226                         }
227                         break;
228                     case SubscriberEvent.REMOVAL :
229                         IDiff[] nodesToRemove = tree.getDiffs(new ResourceTraversal[] { event.asTraversal() });
230                         for (int j = 0; j < nodesToRemove.length; j++) {
231                             IDiff node = nodesToRemove[j];
232                             tree.remove(node.getPath());
233                         }
234                         break;
235                 }
236             }
237         } finally {
238             tree.endInput(monitor);
239         }
240     }
241
242     private void addDiff(IDiff diff, IProgressMonitor monitor) {
243         if (filter == null || filter.select(diff, monitor)) {
244             tree.add(diff);
245         } else {
246             tree.remove(diff.getPath());
247         }
248     }
249
250     /**
251      * Return the resource diff tree that contains the out-of-sync diffs for the
252      * subscriber.
253      * @return the resource diff tree
254      */

255     public IResourceDiffTree getTree() {
256         return tree;
257     }
258     
259     /* (non-Javadoc)
260      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#getSubscriber()
261      */

262     public Subscriber getSubscriber() {
263         return super.getSubscriber();
264     }
265     
266     /* (non-Javadoc)
267      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#shutdown()
268      */

269     public void shutdown() {
270         state = STATE_SHUTDOWN;
271         collector.dispose();
272         super.shutdown();
273     }
274
275     /* (non-Javadoc)
276      * @see org.eclipse.team.internal.core.BackgroundEventHandler#getJobFamiliy()
277      */

278     protected Object JavaDoc getJobFamiliy() {
279         return family;
280     }
281     
282     /**
283      * Set the family of this handler to the given object
284      * @param family the family of the handler's job
285      */

286     public void setJobFamily(Object JavaDoc family) {
287         this.family = family;
288     }
289     
290     /* (non-Javadoc)
291      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#handleException(org.eclipse.core.runtime.CoreException, org.eclipse.core.resources.IResource, int, java.lang.String)
292      */

293     protected void handleException(CoreException e, IResource resource, int code, String JavaDoc message) {
294         super.handleException(e, resource, code, message);
295         tree.reportError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, code, message, e, resource));
296         exceptionState = EXCEPTION_ERROR;
297     }
298     
299     /* (non-Javadoc)
300      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#handleCancel(org.eclipse.core.runtime.OperationCanceledException)
301      */

302     protected void handleCancel(OperationCanceledException e) {
303         super.handleCancel(e);
304         tree.reportError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, ITeamStatus.SYNC_INFO_SET_CANCELLATION, Messages.SubscriberEventHandler_12, e, ResourcesPlugin.getWorkspace().getRoot()));
305         if (exceptionState == EXCEPTION_NONE)
306             exceptionState = EXCEPTION_CANCELED;
307     }
308
309     public DiffFilter getFilter() {
310         return filter;
311     }
312
313     public void setFilter(DiffFilter filter) {
314         this.filter = filter;
315     }
316
317     /**
318      * If the handler is not initialized or not in the process
319      * of initializing, start the initialization process.
320      */

321     public synchronized void initializeIfNeeded() {
322         if (state == STATE_STARTED) {
323             state = STATE_OK_TO_INITIALIZE;
324             reset(getScope().getTraversals(), SubscriberEvent.INITIALIZE);
325         } else if (exceptionState != EXCEPTION_NONE) {
326             reset(getScope().getTraversals(), SubscriberEvent.INITIALIZE);
327         }
328     }
329
330     public synchronized void start() {
331         super.start();
332         if (state == STATE_NEW)
333             state = STATE_STARTED;
334     }
335
336     public int getState() {
337         return state;
338     }
339     
340     protected boolean isSystemJob() {
341         if (manager != null && !manager.isInitialized())
342             return false;
343         return super.isSystemJob();
344     }
345     
346     public synchronized void remove(IResource resource) {
347         // Don't queue changes if we haven't been initialized
348
if (state == STATE_STARTED)
349             return;
350         super.remove(resource);
351     }
352     
353     public void change(IResource resource, int depth) {
354         // Don't queue changes if we haven't been initialized
355
if (state == STATE_STARTED)
356             return;
357         super.change(resource, depth);
358     }
359 }
360
Popular Tags