1 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 29 public class SubscriberDiffTreeEventHandler extends SubscriberEventHandler { 30 31 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 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 family; 47 private DiffFilter filter; 48 private int state = STATE_NEW; 49 private int exceptionState = EXCEPTION_NONE; 50 51 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 69 private class SubscriberDiffCollector extends SubscriberResourceCollector { 70 71 public SubscriberDiffCollector(Subscriber subscriber) { 72 super(subscriber); 73 } 74 75 78 protected boolean hasMembers(IResource resource) { 79 return tree.members(resource).length > 0; 80 } 81 82 85 protected void remove(IResource resource) { 86 SubscriberDiffTreeEventHandler.this.remove(resource); 87 } 88 89 92 protected void change(IResource resource, int depth) { 93 SubscriberDiffTreeEventHandler.this.change(resource, depth); 94 } 95 } 96 97 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 exceptionState = EXCEPTION_NONE; 115 if (!manager.isInitialized() && state == STATE_OK_TO_INITIALIZE) { 116 queueEvent(new RunnableEvent(new IWorkspaceRunnable() { 118 public void run(IProgressMonitor monitor) throws CoreException { 119 if (state == STATE_OK_TO_INITIALIZE) { 121 try { 122 prepareScope(monitor); 123 state = STATE_COLLECTING_CHANGES; 124 } finally { 125 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 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 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 queueDispatchEvent( 192 new SubscriberDiffChangedEvent(tree.getResource(diff), SubscriberEvent.CHANGE, IResource.DEPTH_ZERO, diff)); 193 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 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 255 public IResourceDiffTree getTree() { 256 return tree; 257 } 258 259 262 public Subscriber getSubscriber() { 263 return super.getSubscriber(); 264 } 265 266 269 public void shutdown() { 270 state = STATE_SHUTDOWN; 271 collector.dispose(); 272 super.shutdown(); 273 } 274 275 278 protected Object getJobFamiliy() { 279 return family; 280 } 281 282 286 public void setJobFamily(Object family) { 287 this.family = family; 288 } 289 290 293 protected void handleException(CoreException e, IResource resource, int code, String 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 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 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 if (state == STATE_STARTED) 349 return; 350 super.remove(resource); 351 } 352 353 public void change(IResource resource, int depth) { 354 if (state == STATE_STARTED) 356 return; 357 super.change(resource, depth); 358 } 359 } 360 | Popular Tags |