1 11 package org.eclipse.team.internal.core.subscribers; 12 13 import java.util.*; 14 15 import org.eclipse.core.resources.IResource; 16 import org.eclipse.core.runtime.*; 17 import org.eclipse.core.runtime.jobs.Job; 18 import org.eclipse.core.runtime.preferences.InstanceScope; 19 import org.eclipse.osgi.util.NLS; 20 import org.eclipse.team.core.TeamException; 21 import org.eclipse.team.core.diff.IDiff; 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 import org.osgi.service.prefs.Preferences; 26 27 30 public class SubscriberChangeSetManager extends ActiveChangeSetManager { 31 32 private static final String PREF_CHANGE_SETS = "changeSets"; 34 private static final int RESOURCE_REMOVAL = 1; 35 private static final int RESOURCE_CHANGE = 2; 36 37 private EventHandler handler; 38 private ResourceCollector collector; 39 40 43 private class EventHandler extends BackgroundEventHandler { 44 45 private List dispatchEvents = new ArrayList(); 46 47 protected EventHandler(String jobName, String errorTitle) { 48 super(jobName, errorTitle); 49 } 50 51 54 protected void processEvent(Event event, IProgressMonitor monitor) throws CoreException { 55 if (isShutdown()) 57 throw new OperationCanceledException(); 58 dispatchEvents.add(event); 59 } 60 61 64 protected boolean doDispatchEvents(IProgressMonitor monitor) throws TeamException { 65 if (dispatchEvents.isEmpty()) { 66 return false; 67 } 68 if (isShutdown()) 69 throw new OperationCanceledException(); 70 ResourceDiffTree[] locked = null; 71 try { 72 locked = beginDispath(); 73 for (Iterator iter = dispatchEvents.iterator(); iter.hasNext();) { 74 Event event = (Event) iter.next(); 75 switch (event.getType()) { 76 case RESOURCE_REMOVAL: 77 handleRemove(event.getResource()); 78 break; 79 case RESOURCE_CHANGE: 80 handleChange(event.getResource(), ((ResourceEvent)event).getDepth()); 81 break; 82 default: 83 break; 84 } 85 if (isShutdown()) 86 throw new OperationCanceledException(); 87 } 88 } catch (CoreException e) { 89 throw TeamException.asTeamException(e); 90 } finally { 91 try { 92 endDispatch(locked, monitor); 93 } finally { 94 dispatchEvents.clear(); 95 } 96 } 97 return true; 98 } 99 100 105 private ResourceDiffTree[] beginDispath() { 106 ChangeSet[] sets = getSets(); 107 List lockedSets = new ArrayList(); 108 try { 109 for (int i = 0; i < sets.length; i++) { 110 ActiveChangeSet set = (ActiveChangeSet)sets[i]; 111 ResourceDiffTree tree = set.internalGetDiffTree(); 112 lockedSets.add(tree); 113 tree.beginInput(); 114 } 115 return (ResourceDiffTree[]) lockedSets.toArray(new ResourceDiffTree[lockedSets.size()]); 116 } catch (RuntimeException e) { 117 try { 118 for (Iterator iter = lockedSets.iterator(); iter.hasNext();) { 119 ResourceDiffTree tree = (ResourceDiffTree) iter.next(); 120 try { 121 tree.endInput(null); 122 } catch (Throwable e1) { 123 } 125 } 126 } catch (Throwable e1) { 127 } 129 throw e; 130 } 131 } 132 133 private void endDispatch(ResourceDiffTree[] locked, IProgressMonitor monitor) { 134 if (locked == null) { 135 return; 137 } 138 monitor.beginTask(null, 100 * locked.length); 139 for (int i = 0; i < locked.length; i++) { 140 ResourceDiffTree tree = locked[i]; 141 try { 142 tree.endInput(Policy.subMonitorFor(monitor, 100)); 143 } catch (RuntimeException e) { 144 TeamPlugin.log(IStatus.ERROR, Messages.SubscriberChangeSetCollector_0, e); 147 throw e; 148 } 149 } 150 monitor.done(); 151 } 152 153 156 protected synchronized void queueEvent(Event event, boolean front) { 157 super.queueEvent(event, front); 159 } 160 161 164 private void handleRemove(IResource resource) { 165 ChangeSet[] sets = getSets(); 166 for (int i = 0; i < sets.length; i++) { 167 ChangeSet set = sets[i]; 168 if (!set.isEmpty()) { 171 set.rootRemoved(resource, IResource.DEPTH_INFINITE); 172 if (set.isEmpty()) { 173 remove(set); 174 } 175 } 176 } 177 } 178 179 182 private void handleChange(IResource resource, int depth) throws CoreException { 183 IDiff diff = getDiff(resource); 184 if (isModified(diff)) { 185 ActiveChangeSet[] containingSets = getContainingSets(resource); 186 if (containingSets.length == 0) { 187 if (getDefaultSet() != null) { 190 getDefaultSet().add(diff); 191 } 192 } else { 193 for (int i = 0; i < containingSets.length; i++) { 194 ActiveChangeSet set = containingSets[i]; 195 set.add(diff); 197 } 198 } 199 } else { 200 removeFromAllSets(resource); 201 } 202 if (depth != IResource.DEPTH_ZERO) { 203 IResource[] members = getSubscriber().members(resource); 204 for (int i = 0; i < members.length; i++) { 205 IResource member = members[i]; 206 handleChange(member, depth == IResource.DEPTH_ONE ? IResource.DEPTH_ZERO : IResource.DEPTH_INFINITE); 207 } 208 } 209 } 210 211 private void removeFromAllSets(IResource resource) { 212 List toRemove = new ArrayList(); 213 ChangeSet[] sets = getSets(); 214 for (int i = 0; i < sets.length; i++) { 215 ChangeSet set = sets[i]; 216 if (set.contains(resource)) { 217 set.remove(resource); 218 if (set.isEmpty()) { 219 toRemove.add(set); 220 } 221 } 222 } 223 for (Iterator iter = toRemove.iterator(); iter.hasNext();) { 224 ActiveChangeSet set = (ActiveChangeSet) iter.next(); 225 remove(set); 226 } 227 } 228 229 private ActiveChangeSet[] getContainingSets(IResource resource) { 230 Set result = new HashSet(); 231 ChangeSet[] sets = getSets(); 232 for (int i = 0; i < sets.length; i++) { 233 ChangeSet set = sets[i]; 234 if (set.contains(resource)) { 235 result.add(set); 236 } 237 } 238 return (ActiveChangeSet[]) result.toArray(new ActiveChangeSet[result.size()]); 239 } 240 } 241 242 private class ResourceCollector extends SubscriberResourceCollector { 243 244 public ResourceCollector(Subscriber subscriber) { 245 super(subscriber); 246 } 247 248 251 protected void remove(IResource resource) { 252 if (handler != null) 253 handler.queueEvent(new BackgroundEventHandler.ResourceEvent(resource, RESOURCE_REMOVAL, IResource.DEPTH_INFINITE), false); 254 } 255 256 259 protected void change(IResource resource, int depth) { 260 if (handler != null) 261 handler.queueEvent(new BackgroundEventHandler.ResourceEvent(resource, RESOURCE_CHANGE, depth), false); 262 } 263 264 protected boolean hasMembers(IResource resource) { 265 return SubscriberChangeSetManager.this.hasMembers(resource); 266 } 267 } 268 269 public SubscriberChangeSetManager(Subscriber subscriber) { 270 collector = new ResourceCollector(subscriber); 271 handler = new EventHandler(NLS.bind(Messages.SubscriberChangeSetCollector_1, new String [] { subscriber.getName() }), NLS.bind(Messages.SubscriberChangeSetCollector_2, new String [] { subscriber.getName() })); } 273 274 277 protected void initializeSets() { 278 load(getPreferences()); 279 } 280 281 public boolean hasMembers(IResource resource) { 282 ChangeSet[] sets = getSets(); 283 for (int i = 0; i < sets.length; i++) { 284 ActiveChangeSet set = (ActiveChangeSet)sets[i]; 285 if (set.getDiffTree().getChildren(resource.getFullPath()).length > 0) 286 return true; 287 } 288 if (getDefaultSet() != null) 289 return (getDefaultSet().getDiffTree().getChildren(resource.getFullPath()).length > 0); 290 return false; 291 } 292 293 300 public IDiff getDiff(IResource resource) throws CoreException { 301 Subscriber subscriber = getSubscriber(); 302 return subscriber.getDiff(resource); 303 } 304 305 309 public Subscriber getSubscriber() { 310 return collector.getSubscriber(); 311 } 312 313 316 public void dispose() { 317 handler.shutdown(); 318 collector.dispose(); 319 super.dispose(); 320 save(getPreferences()); 321 } 322 323 private Preferences getPreferences() { 324 return getParentPreferences().node(getSubscriberIdentifier()); 325 } 326 327 private static Preferences getParentPreferences() { 328 return getTeamPreferences().node(PREF_CHANGE_SETS); 329 } 330 331 private static Preferences getTeamPreferences() { 332 return new InstanceScope().getNode(TeamPlugin.getPlugin().getBundle().getSymbolicName()); 333 } 334 335 340 protected String getSubscriberIdentifier() { 341 return getSubscriber().getName(); 342 } 343 344 349 public void waitUntilDone(IProgressMonitor monitor) { 350 monitor.worked(1); 351 while(handler.getEventHandlerJob().getState() != Job.NONE) { 353 monitor.worked(1); 354 try { 355 Thread.sleep(10); 356 } catch (InterruptedException e) { 357 } 358 Policy.checkCanceled(monitor); 359 } 360 monitor.worked(1); 361 } 362 363 366 protected String getName() { 367 return getSubscriber().getName(); 368 } 369 } 370 | Popular Tags |