1 11 package org.eclipse.team.internal.ccvs.ui.subscriber; 12 13 import com.ibm.icu.text.DateFormat; 14 import java.util.Date ; 15 16 import org.eclipse.core.resources.IResource; 17 import org.eclipse.core.resources.IWorkspaceRunnable; 18 import org.eclipse.core.runtime.IProgressMonitor; 19 import org.eclipse.core.runtime.IStatus; 20 import org.eclipse.core.runtime.jobs.Job; 21 import org.eclipse.team.core.TeamException; 22 import org.eclipse.team.core.TeamStatus; 23 import org.eclipse.team.core.subscribers.Subscriber; 24 import org.eclipse.team.core.synchronize.SyncInfo; 25 import org.eclipse.team.core.synchronize.SyncInfoSet; 26 import org.eclipse.team.core.variants.IResourceVariant; 27 import org.eclipse.team.internal.ccvs.core.*; 28 import org.eclipse.team.internal.ccvs.core.resources.RemoteResource; 29 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; 30 import org.eclipse.team.internal.ccvs.core.util.Util; 31 import org.eclipse.team.internal.ccvs.ui.*; 32 import org.eclipse.team.internal.ccvs.ui.Policy; 33 import org.eclipse.team.internal.ccvs.ui.operations.RemoteLogOperation.LogEntryCache; 34 import org.eclipse.team.internal.core.subscribers.*; 35 import org.eclipse.team.internal.ui.synchronize.SyncInfoSetChangeSetCollector; 36 import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; 37 import org.eclipse.team.ui.synchronize.SynchronizePageActionGroup; 38 39 42 public class CVSChangeSetCollector extends SyncInfoSetChangeSetCollector implements LogEntryCacheUpdateHandler.ILogsFetchedListener { 43 44 48 public static final String CVS_CHECKED_IN_COLLECTOR = CVSUIPlugin.ID + ".CVSCheckedInCollector"; 50 54 private static final String LOG_ENTRY_HANDLER = CVSUIPlugin.ID + ".LogEntryHandler"; 56 private static final String DEFAULT_INCOMING_SET_NAME = CVSUIMessages.CVSChangeSetCollector_0; 57 58 boolean disposed = false; 59 60 private LogEntryCache logEntryCache; 61 62 65 public class CVSUpdatableSyncInfo extends CVSSyncInfo { 66 public int kind; 67 public CVSUpdatableSyncInfo(int kind, IResource local, IResourceVariant base, IResourceVariant remote, Subscriber s) { 68 super(local, base, remote, s); 69 this.kind = kind; 70 } 71 72 protected int calculateKind() throws TeamException { 73 return kind; 74 } 75 } 76 77 private class DefaultCheckedInChangeSet extends CheckedInChangeSet { 78 79 private Date date = new Date (); 80 81 public DefaultCheckedInChangeSet(String name) { 82 setName(name); 83 } 84 87 public String getAuthor() { 88 return ""; } 90 91 94 public Date getDate() { 95 return date; 96 } 97 98 101 public String getComment() { 102 return ""; } 104 105 } 106 107 private class CVSCheckedInChangeSet extends CheckedInChangeSet { 108 109 private final ILogEntry entry; 110 111 public CVSCheckedInChangeSet(ILogEntry entry) { 112 this.entry = entry; 113 Date date = entry.getDate(); 114 String comment = Util.flattenText(entry.getComment()); 115 if (date == null) { 116 setName("["+entry.getAuthor()+ "] " + comment); } else { 118 String dateString = DateFormat.getDateTimeInstance().format(date); 119 setName("["+entry.getAuthor()+ "] (" + dateString +") " + comment); } 121 } 122 123 126 public String getAuthor() { 127 return entry.getAuthor(); 128 } 129 130 133 public Date getDate() { 134 return entry.getDate(); 135 } 136 137 140 public String getComment() { 141 return entry.getComment(); 142 } 143 } 144 145 public CVSChangeSetCollector(ISynchronizePageConfiguration configuration) { 146 super(configuration); 147 configuration.setProperty(CVSChangeSetCollector.CVS_CHECKED_IN_COLLECTOR, this); 148 } 149 150 public synchronized LogEntryCacheUpdateHandler getLogEntryHandler() { 151 LogEntryCacheUpdateHandler handler = (LogEntryCacheUpdateHandler)getConfiguration().getProperty(LOG_ENTRY_HANDLER); 152 if (handler == null) { 153 handler = initializeLogEntryHandler(getConfiguration()); 154 } 155 handler.setListener(this); 156 return handler; 157 } 158 159 162 private LogEntryCacheUpdateHandler initializeLogEntryHandler(final ISynchronizePageConfiguration configuration) { 163 final LogEntryCacheUpdateHandler logEntryHandler = new LogEntryCacheUpdateHandler(configuration); 164 configuration.setProperty(LOG_ENTRY_HANDLER, logEntryHandler); 165 configuration.addActionContribution(new SynchronizePageActionGroup() { 167 public void dispose() { 168 super.dispose(); 169 LogEntryCacheUpdateHandler handler = (LogEntryCacheUpdateHandler)configuration.getProperty(LOG_ENTRY_HANDLER); 170 if (handler != null) { 171 handler.shutdown(); 172 configuration.setProperty(LOG_ENTRY_HANDLER, null); 173 } 174 } 175 }); 176 return logEntryHandler; 179 } 180 181 184 protected void add(SyncInfo[] infos) { 185 LogEntryCacheUpdateHandler handler = getLogEntryHandler(); 186 if (handler != null) 187 try { 188 handler.fetch(infos); 189 } catch (CVSException e) { 190 getConfiguration().getSyncInfoSet().addError(new TeamStatus(IStatus.ERROR, CVSUIPlugin.ID, 0, e.getMessage(), e, null)); 191 } 192 } 193 194 197 public void reset(SyncInfoSet seedSet) { 198 LogEntryCacheUpdateHandler handler = getLogEntryHandler(); 200 if (handler != null) { 201 handler.stopFetching(); 202 } 203 super.reset(seedSet); 204 } 205 206 209 public void dispose() { 210 disposed = true; 213 LogEntryCacheUpdateHandler handler = getLogEntryHandler(); 214 if (handler != null) handler.setListener(null); 215 getConfiguration().setProperty(CVSChangeSetCollector.CVS_CHECKED_IN_COLLECTOR, null); 216 logEntryCache = null; 217 super.dispose(); 218 } 219 220 224 private void handleRemoteChanges(final SyncInfo[] infos, final LogEntryCache logEntries, final IProgressMonitor monitor) { 225 performUpdate(new IWorkspaceRunnable() { 226 public void run(IProgressMonitor monitor) { 227 addLogEntries(infos, logEntries, monitor); 228 } 229 }, true , monitor); 230 } 231 232 236 private void addLogEntries(SyncInfo[] commentInfos, LogEntryCache logs, IProgressMonitor monitor) { 237 try { 238 monitor.beginTask(null, commentInfos.length * 10); 239 if (logs != null) { 240 for (int i = 0; i < commentInfos.length; i++) { 241 addSyncInfoToCommentNode(commentInfos[i], logs); 242 monitor.worked(10); 243 } 244 } 245 } finally { 246 monitor.done(); 247 } 248 } 249 250 256 private void addSyncInfoToCommentNode(SyncInfo info, LogEntryCache logs) { 257 LogEntryCacheUpdateHandler handler = getLogEntryHandler(); 258 if (handler != null) { 259 ICVSRemoteResource remoteResource = handler.getRemoteResource(info); 260 if(handler.getSubscriber() instanceof CVSCompareSubscriber && remoteResource != null) { 261 addMultipleRevisions(info, logs, remoteResource); 262 } else { 263 addSingleRevision(info, logs, remoteResource); 264 } 265 } 266 } 267 268 275 private void addSingleRevision(SyncInfo info, LogEntryCache logs, ICVSRemoteResource remoteResource) { 276 ILogEntry logEntry = logs.getLogEntry(remoteResource); 277 if (remoteResource != null && !remoteResource.isFolder()) { 278 try { 281 String remoteRevision = ((ICVSRemoteFile) remoteResource).getRevision(); 282 if (isDeletedRemotely(info)) { 283 ILogEntry[] logEntries = logs.getLogEntries(remoteResource); 284 for (int i = 0; i < logEntries.length; i++) { 285 ILogEntry entry = logEntries[i]; 286 String revision = entry.getRevision(); 287 if (entry.isDeletion() && ResourceSyncInfo.isLaterRevision(revision, remoteRevision)) { 288 logEntry = entry; 289 } 290 } 291 } 292 } catch (TeamException e) { 293 } 295 } 296 addRemoteChange(info, remoteResource, logEntry); 297 } 298 299 306 private void addMultipleRevisions(SyncInfo info, LogEntryCache logs, ICVSRemoteResource remoteResource) { 307 ILogEntry[] logEntries = logs.getLogEntries(remoteResource); 308 if(logEntries == null || logEntries.length == 0) { 309 addRemoteChange(info, null, null); 312 } else { 313 for (int i = 0; i < logEntries.length; i++) { 314 ILogEntry entry = logEntries[i]; 315 addRemoteChange(info, remoteResource, entry); 316 } 317 } 318 } 319 320 private boolean isDeletedRemotely(SyncInfo info) { 321 int kind = info.getKind(); 322 if(kind == (SyncInfo.INCOMING | SyncInfo.DELETION)) return true; 323 if(SyncInfo.getDirection(kind) == SyncInfo.CONFLICTING && info.getRemote() == null) return true; 324 return false; 325 } 326 327 330 private void addRemoteChange(SyncInfo info, ICVSRemoteResource remoteResource, ILogEntry logEntry) { 331 if (disposed) return; 332 LogEntryCacheUpdateHandler handler = getLogEntryHandler(); 333 if(handler != null && remoteResource != null && logEntry != null && handler.isRemoteChange(info)) { 334 if(requiresCustomSyncInfo(info, remoteResource, logEntry)) { 335 info = new CVSUpdatableSyncInfo(info.getKind(), info.getLocal(), info.getBase(), (RemoteResource)logEntry.getRemoteFile(), ((CVSSyncInfo)info).getSubscriber()); 336 try { 337 info.init(); 338 } catch (TeamException e) { 339 } 341 } 342 IResourceVariant base = info.getBase(); 344 IResourceVariant remote = info.getRemote(); 345 if ((base == null && remote != null) || (remote == null && base != null) || (remote != null && base != null && !base.equals(remote))) { 346 synchronized(this) { 347 CheckedInChangeSet set = getChangeSetFor(logEntry); 348 if (set == null) { 349 set = createChangeSetFor(logEntry); 350 add(set); 351 } 352 set.add(info); 353 } 354 } 355 } else { 356 addToDefaultSet(DEFAULT_INCOMING_SET_NAME, info); 359 } 360 } 361 362 private void addToDefaultSet(String name, SyncInfo info) { 363 CheckedInChangeSet set; 364 synchronized(this) { 365 set = getChangeSetFor(name); 366 if (set == null) { 367 set = createDefaultChangeSet(name); 368 add(set); 369 } 370 set.add(info); 371 } 372 } 373 374 private CheckedInChangeSet createDefaultChangeSet(String name) { 375 return new DefaultCheckedInChangeSet(name); 376 } 377 378 private CheckedInChangeSet createChangeSetFor(ILogEntry logEntry) { 379 return new CVSCheckedInChangeSet(logEntry); 380 } 381 382 private CheckedInChangeSet getChangeSetFor(ILogEntry logEntry) { 383 ChangeSet[] sets = getSets(); 384 for (int i = 0; i < sets.length; i++) { 385 ChangeSet set = sets[i]; 386 if (set instanceof CheckedInChangeSet && 387 set.getComment().equals(logEntry.getComment()) && 388 ((CheckedInChangeSet)set).getAuthor().equals(logEntry.getAuthor())) { 389 return (CheckedInChangeSet)set; 390 } 391 } 392 return null; 393 } 394 395 private CheckedInChangeSet getChangeSetFor(String name) { 396 ChangeSet[] sets = getSets(); 397 for (int i = 0; i < sets.length; i++) { 398 ChangeSet set = sets[i]; 399 if (set.getName().equals(name)) { 400 return (CheckedInChangeSet)set; 401 } 402 } 403 return null; 404 } 405 406 private boolean requiresCustomSyncInfo(SyncInfo info, ICVSRemoteResource remoteResource, ILogEntry logEntry) { 407 if (logEntry.isDeletion() || !(info instanceof CVSSyncInfo)) return false; 409 IResourceVariant remote = info.getRemote(); 412 if (remote == null) return true; 413 return !remote.equals(remoteResource); 414 } 415 416 419 public void waitUntilDone(IProgressMonitor monitor) { 420 super.waitUntilDone(monitor); 421 monitor.worked(1); 422 LogEntryCacheUpdateHandler handler = getLogEntryHandler(); 424 if (handler != null) { 425 while(handler.getEventHandlerJob().getState() != Job.NONE) { 426 monitor.worked(1); 427 try { 428 Thread.sleep(10); 429 } catch (InterruptedException e) { 430 } 431 Policy.checkCanceled(monitor); 432 } 433 } 434 monitor.worked(1); 435 } 436 437 440 public void logEntriesFetched(SyncInfoSet set, LogEntryCache logEntryCache, IProgressMonitor monitor) { 441 if (disposed) return; 442 this.logEntryCache = logEntryCache; 444 handleRemoteChanges(set.getSyncInfos(), logEntryCache, monitor); 445 } 446 447 public ICVSRemoteFile getImmediatePredecessor(ICVSRemoteFile file) throws TeamException { 448 if (logEntryCache != null) 449 return logEntryCache.getImmediatePredecessor(file); 450 return null; 451 } 452 453 protected void initializeSets() { 454 } 456 } 457 | Popular Tags |