KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.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.team.core.*;
17 import org.eclipse.team.core.mapping.ISynchronizationScope;
18 import org.eclipse.team.core.subscribers.Subscriber;
19 import org.eclipse.team.core.synchronize.*;
20 import org.eclipse.team.internal.core.Messages;
21 import org.eclipse.team.internal.core.TeamPlugin;
22
23 /**
24  * An event handler that collects {@link SyncInfo} in a {@link SyncInfoTree}.
25  */

26 public class SubscriberSyncInfoEventHandler extends SubscriberEventHandler {
27     
28     // The set that receives notification when the resource synchronization state
29
// has been calculated by the job.
30
private final SyncSetInputFromSubscriber syncSetInput;
31     
32     private class SubscriberSyncInfoEvent extends SubscriberEvent {
33         private final SyncInfo result;
34
35         public SubscriberSyncInfoEvent(IResource resource, int type, int depth, SyncInfo result) {
36             super(resource, type, depth);
37             this.result = result;
38         }
39         public SyncInfo getResult() {
40             return result;
41         }
42     }
43     
44     public static ISynchronizationScope createScope(IResource[] roots, Subscriber subscriber) {
45         if (roots == null)
46             roots = subscriber.roots();
47         return new RootResourceSynchronizationScope(roots);
48     }
49     
50     /**
51      * Create the event handler for the given subscriber and roots
52      * @param subscriber the subscriber
53      * @param roots the roots or <code>null</code> if the roots from the subscriber
54      * should be used.
55      */

56     public SubscriberSyncInfoEventHandler(final Subscriber subscriber, IResource[] roots) {
57         super(subscriber, createScope(roots, subscriber));
58         this.syncSetInput = new SyncSetInputFromSubscriber(subscriber, this);
59     }
60
61     /* (non-Javadoc)
62      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#handleException(org.eclipse.core.runtime.CoreException, org.eclipse.core.resources.IResource, int, java.lang.String)
63      */

64     protected void handleException(CoreException e, IResource resource, int code, String JavaDoc message) {
65         super.handleException(e, resource, code, message);
66         syncSetInput.handleError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, code, message, e, resource));
67     }
68     
69     /* (non-Javadoc)
70      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#handleCancel(org.eclipse.core.runtime.OperationCanceledException)
71      */

72     protected void handleCancel(OperationCanceledException e) {
73         super.handleCancel(e);
74         syncSetInput.handleError(new TeamStatus(IStatus.ERROR, TeamPlugin.ID, ITeamStatus.SYNC_INFO_SET_CANCELLATION, Messages.SubscriberEventHandler_12, e, ResourcesPlugin.getWorkspace().getRoot()));
75     }
76     
77     /**
78      * Return the sync set input that was created by this event handler
79      * @return the sync set input
80      */

81     public SyncSetInputFromSubscriber getSyncSetInput() {
82         return syncSetInput;
83     }
84     
85     /* (non-Javadoc)
86      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#handleChange(org.eclipse.core.resources.IResource)
87      */

88     protected void handleChange(IResource resource) throws TeamException {
89         SyncInfo info = syncSetInput.getSubscriber().getSyncInfo(resource);
90         // resource is no longer under the subscriber control
91
if (info == null) {
92             queueDispatchEvent(
93                 new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_ZERO));
94         } else {
95             queueDispatchEvent(
96                 new SubscriberSyncInfoEvent(resource, SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, info));
97         }
98     }
99     
100     /* (non-Javadoc)
101      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#collectAll(org.eclipse.core.resources.IResource, int, org.eclipse.core.runtime.IProgressMonitor)
102      */

103     protected void collectAll(
104             IResource resource,
105             int depth,
106             IProgressMonitor monitor) {
107             
108         monitor.beginTask(null, IProgressMonitor.UNKNOWN);
109         try {
110             
111             // Create a monitor that will handle preemption and dispatch if required
112
IProgressMonitor collectionMonitor = new SubProgressMonitor(monitor, IProgressMonitor.UNKNOWN) {
113                 boolean dispatching = false;
114                 public void subTask(String JavaDoc name) {
115                     dispatch();
116                     super.subTask(name);
117                 }
118                 private void dispatch() {
119                     if (dispatching) return;
120                     try {
121                         dispatching = true;
122                         handlePreemptiveEvents(this);
123                         handlePendingDispatch(this);
124                     } finally {
125                         dispatching = false;
126                     }
127                 }
128                 public void worked(int work) {
129                     dispatch();
130                     super.worked(work);
131                 }
132             };
133             
134             // Create a sync set that queues up resources and errors for dispatch
135
SyncInfoSet collectionSet = new SyncInfoSet() {
136                 public void add(SyncInfo info) {
137                     super.add(info);
138                     queueDispatchEvent(
139                             new SubscriberSyncInfoEvent(info.getLocal(), SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, info));
140                 }
141                 public void addError(ITeamStatus status) {
142                     if (status instanceof TeamStatus) {
143                         TeamStatus ts = (TeamStatus) status;
144                         IResource resource = ts.getResource();
145                         if (resource != null && !resource.getProject().isAccessible()) {
146                             // The project was closed while we were collecting sync info.
147
// The close delta will cause us to clean up properly
148
return;
149                         }
150                     }
151                     super.addError(status);
152                     TeamPlugin.getPlugin().getLog().log(status);
153                     syncSetInput.handleError(status);
154                 }
155                 public void remove(IResource resource) {
156                     super.remove(resource);
157                     queueDispatchEvent(
158                             new SubscriberEvent(resource, SubscriberEvent.REMOVAL, IResource.DEPTH_ZERO));
159                 }
160             };
161             
162             syncSetInput.getSubscriber().collectOutOfSync(new IResource[] { resource }, depth, collectionSet, collectionMonitor);
163             
164         } finally {
165             monitor.done();
166         }
167     }
168
169     /* (non-Javadoc)
170      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#dispatchEvents(org.eclipse.team.internal.core.subscribers.SubscriberEventHandler.SubscriberEvent[], org.eclipse.core.runtime.IProgressMonitor)
171      */

172     protected void dispatchEvents(SubscriberEvent[] events, IProgressMonitor monitor) {
173         // this will batch the following set changes until endInput is called.
174
SubscriberSyncInfoSet syncSet = syncSetInput.getSyncSet();
175         try {
176             syncSet.beginInput();
177             for (int i = 0; i < events.length; i++) {
178                 SubscriberEvent event = events[i];
179                 switch (event.getType()) {
180                     case SubscriberEvent.CHANGE :
181                         if (event instanceof SubscriberSyncInfoEvent) {
182                             SubscriberSyncInfoEvent se = (SubscriberSyncInfoEvent) event;
183                             syncSetInput.collect(se.getResult(), monitor);
184                         }
185                         break;
186                     case SubscriberEvent.REMOVAL :
187                         syncSet.remove(event.getResource(), event.getDepth());
188                         break;
189                 }
190             }
191         } finally {
192             syncSet.endInput(monitor);
193         }
194     }
195     
196     /**
197      * Initialize all resources for the subscriber associated with the set. This will basically recalculate
198      * all synchronization information for the subscriber.
199      * <p>
200      * This method is synchronized with the queueEvent method to ensure that the two events
201      * queued by this method are back-to-back
202      */

203     public void reset(IResource[] roots) {
204         RootResourceSynchronizationScope scope = (RootResourceSynchronizationScope)getScope();
205         if (roots == null)
206             roots = getSubscriber().roots();
207         scope.setRoots(roots);
208     }
209     
210     /* (non-Javadoc)
211      * @see org.eclipse.team.internal.core.subscribers.SubscriberEventHandler#reset(org.eclipse.core.resources.mapping.ResourceTraversal[], org.eclipse.core.resources.mapping.ResourceTraversal[])
212      */

213     protected synchronized void reset(ResourceTraversal[] oldTraversals, ResourceTraversal[] newTraversals) {
214         // First, reset the sync set input to clear the sync set
215
run(new IWorkspaceRunnable() {
216             public void run(IProgressMonitor monitor) throws CoreException {
217                 syncSetInput.reset(monitor);
218             }
219         }, false /* keep ordering the same */);
220         // Then, prime the set from the subscriber
221
super.reset(oldTraversals, newTraversals);
222     }
223 }
224
Popular Tags