1 11 package org.eclipse.team.internal.ccvs.ui; 12 13 14 import com.ibm.icu.text.SimpleDateFormat; 15 import java.util.ArrayList ; 16 import java.util.Date ; 17 import java.util.HashSet ; 18 import java.util.List ; 19 import java.util.Locale ; 20 import java.util.Set ; 21 22 import org.eclipse.core.resources.*; 23 import org.eclipse.core.resources.mapping.*; 24 import org.eclipse.core.runtime.*; 25 import org.eclipse.jface.preference.IPreferenceStore; 26 import org.eclipse.jface.util.IPropertyChangeListener; 27 import org.eclipse.jface.util.PropertyChangeEvent; 28 import org.eclipse.jface.viewers.*; 29 import org.eclipse.swt.widgets.Display; 30 import org.eclipse.team.core.RepositoryProvider; 31 import org.eclipse.team.core.diff.IDiff; 32 import org.eclipse.team.core.diff.IThreeWayDiff; 33 import org.eclipse.team.internal.ccvs.core.*; 34 import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; 35 import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; 36 import org.eclipse.team.internal.ccvs.core.syncinfo.FolderSyncInfo; 37 import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo; 38 import org.eclipse.team.internal.ccvs.core.util.KnownRepositories; 39 import org.eclipse.team.internal.ccvs.core.util.ResourceStateChangeListeners; 40 import org.eclipse.team.internal.core.ExceptionCollector; 41 import org.eclipse.team.internal.ui.Utils; 42 import org.eclipse.team.ui.TeamUI; 43 import org.eclipse.team.ui.mapping.SynchronizationStateTester; 44 import org.eclipse.ui.PlatformUI; 45 import org.eclipse.ui.themes.ITheme; 46 import org.osgi.framework.Bundle; 47 48 public class CVSLightweightDecorator extends LabelProvider implements ILightweightLabelDecorator, IResourceStateChangeListener, IPropertyChangeListener { 49 50 public final static String ID = "org.eclipse.team.cvs.ui.decorator"; 53 private static ExceptionCollector exceptions = new ExceptionCollector(CVSUIMessages.CVSDecorator_exceptionMessage, CVSUIPlugin.ID, IStatus.ERROR, CVSUIPlugin.getPlugin().getLog()); 55 private static String DECORATOR_FORMAT = "yyyy/MM/dd HH:mm:ss"; private static SimpleDateFormat decorateFormatter = new SimpleDateFormat(DECORATOR_FORMAT, Locale.getDefault()); 57 58 private static String [] fonts = new String [] { 59 CVSDecoratorConfiguration.IGNORED_FONT, 60 CVSDecoratorConfiguration.OUTGOING_CHANGE_FONT}; 61 62 private static String [] colors = new String [] { 63 CVSDecoratorConfiguration.OUTGOING_CHANGE_BACKGROUND_COLOR, 64 CVSDecoratorConfiguration.OUTGOING_CHANGE_FOREGROUND_COLOR, 65 CVSDecoratorConfiguration.IGNORED_BACKGROUND_COLOR, 66 CVSDecoratorConfiguration.IGNORED_FOREGROUND_COLOR}; 67 68 private static final SynchronizationStateTester DEFAULT_TESTER = new SynchronizationStateTester(); 69 70 public CVSLightweightDecorator() { 71 ResourceStateChangeListeners.getListener().addResourceStateChangeListener(this); 72 TeamUI.addPropertyChangeListener(this); 73 CVSUIPlugin.addPropertyChangeListener(this); 74 75 ensureFontAndColorsCreated(fonts, colors); 78 79 PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().addPropertyChangeListener(this); 80 CVSProviderPlugin.broadcastDecoratorEnablementChanged(true ); 81 } 82 83 91 private void ensureFontAndColorsCreated(final String [] fonts, final String [] colors) { 92 CVSUIPlugin.getStandardDisplay().syncExec(new Runnable () { 93 public void run() { 94 ITheme theme = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme(); 95 for (int i = 0; i < colors.length; i++) { 96 theme.getColorRegistry().get(colors[i]); 97 98 } 99 for (int i = 0; i < fonts.length; i++) { 100 theme.getFontRegistry().get(fonts[i]); 101 } 102 } 103 }); 104 } 105 106 public static boolean isDirty(final ICVSResource resource) throws CVSException { 107 return getSubscriber().isDirty(resource, null); 108 } 109 110 public static boolean isDirty(IResource resource) { 111 try { 112 return getSubscriber().isDirty(resource, null); 113 } catch (CVSException e) { 114 handleException(resource, e); 115 return true; 116 } 117 } 118 119 123 private static CVSTeamProvider getCVSProviderFor(IResource resource) { 124 if (resource == null) return null; 125 RepositoryProvider p = 126 RepositoryProvider.getProvider( 127 resource.getProject(), 128 CVSProviderPlugin.getTypeId()); 129 if (p == null) { 130 return null; 131 } 132 return (CVSTeamProvider) p; 133 } 134 135 140 public void decorate(Object element, IDecoration decoration) { 141 142 IResource resource = getResource(element); 144 if (resource != null && resource.getType() == IResource.ROOT) 145 return; 146 147 ResourceMapping mapping = Utils.getResourceMapping(element); 149 if (mapping == null) 150 return; 151 if (!isMappedToCVS(mapping)) 152 return; 153 154 IDecorationContext context = decoration.getDecorationContext(); 156 SynchronizationStateTester tester = DEFAULT_TESTER; 157 Object property = context.getProperty(SynchronizationStateTester.PROP_TESTER); 158 if (property instanceof SynchronizationStateTester) { 159 tester = (SynchronizationStateTester) property; 160 } 161 162 try { 164 if (tester.isDecorationEnabled(element)) { 165 CVSDecoration cvsDecoration = decorate(element, tester); 166 cvsDecoration.apply(decoration); 167 } 168 } catch(CoreException e) { 169 handleException(element, e); 170 } catch (IllegalStateException e) { 171 if (Platform.getBundle(CVSUIPlugin.ID).getState() == Bundle.ACTIVE) { 175 throw e; 176 } 177 } 178 } 179 180 private static IResource getResource(Object element) { 181 if (element instanceof ResourceMapping) { 182 element = ((ResourceMapping) element).getModelObject(); 183 } 184 return Utils.getResource(element); 185 } 186 187 190 private boolean isMappedToCVS(ResourceMapping mapping) { 191 IProject[] projects = mapping.getProjects(); 192 boolean foundOne = false; 193 for (int i = 0; i < projects.length; i++) { 194 IProject project = projects[i]; 195 if (project != null) { 196 RepositoryProvider provider = RepositoryProvider.getProvider(project); 197 if (provider instanceof CVSTeamProvider) { 198 foundOne = true; 199 } else if (provider != null) { 200 return false; 201 } 202 } 203 } 204 return foundOne; 205 } 206 207 public static CVSDecoration decorate(Object element, SynchronizationStateTester tester) throws CoreException { 208 IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 209 CVSDecoration result = new CVSDecoration(); 210 211 int state = IDiff.NO_CHANGE; 213 if (isSupervised(element)) { 214 result.setHasRemote(true); 216 state = tester.getState(element, 217 store.getBoolean(ICVSUIConstants.PREF_CALCULATE_DIRTY) 218 ? IDiff.ADD | IDiff.REMOVE | IDiff.CHANGE | IThreeWayDiff.OUTGOING 219 : 0, 220 new NullProgressMonitor()); 221 result.setStateFlags(state); 222 } else { 223 result.setIgnored(true); 224 } 225 if (!result.isIgnored()) { 227 CVSTag tag = getTagToShow(element); 228 if (tag != null) { 229 String name = tag.getName(); 230 if (tag.getType() == CVSTag.DATE) { 231 Date date = tag.asDate(); 232 if (date != null) { 233 name = decorateFormatter.format(date); 234 } 235 } 236 result.setTag(name); 237 } 238 } 239 240 IResource resource = getResource(element); 242 if (resource == null) { 243 result.setResourceType(CVSDecoration.MODEL); 244 } else { 245 decorate(resource, result); 246 } 247 tester.elementDecorated(element, result.asTeamStateDescription(null)); 248 return result; 249 } 250 251 private static boolean isSupervised(Object element) throws CoreException { 252 IResource[] resources = getTraversalRoots(element); 253 for (int i = 0; i < resources.length; i++) { 254 IResource resource = resources[i]; 255 if (getSubscriber().isSupervised(resource)) 256 return true; 257 } 258 return false; 259 } 260 261 private static IResource[] getTraversalRoots(Object element) throws CoreException { 262 Set result = new HashSet (); 263 ResourceMapping mapping = Utils.getResourceMapping(element); 264 if (mapping != null) { 265 ResourceTraversal[] traversals = mapping.getTraversals(ResourceMappingContext.LOCAL_CONTEXT, null); 266 for (int i = 0; i < traversals.length; i++) { 267 ResourceTraversal traversal = traversals[i]; 268 IResource[] resources = traversal.getResources(); 269 for (int j = 0; j < resources.length; j++) { 270 IResource resource = resources[j]; 271 result.add(resource); 272 } 273 } 274 } 275 return (IResource[]) result.toArray(new IResource[result.size()]); 276 } 277 278 private static void decorate(IResource resource, CVSDecoration cvsDecoration) throws CVSException { 279 IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 280 ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); 281 cvsDecoration.setResourceType(resource.getType()); 282 283 cvsDecoration.setHasRemote(hasRemote(cvsResource)); 284 if (cvsResource.isIgnored()) { 285 cvsDecoration.setIgnored(true); 286 } 287 if (!cvsDecoration.isIgnored()) { 288 boolean decorateModel = store.getBoolean(ICVSUIConstants.PREF_CALCULATE_DIRTY); 290 if (!decorateModel) { 291 try { 293 IDiff node = getSubscriber().getDiff(resource); 294 if (node != null) { 295 if (node instanceof IThreeWayDiff) { 296 IThreeWayDiff twd = (IThreeWayDiff) node; 297 cvsDecoration.setDirty(twd.getDirection() == IThreeWayDiff.OUTGOING 298 || twd.getDirection() == IThreeWayDiff.CONFLICTING); 299 } 300 } 301 } catch (CoreException e) { 302 handleException(resource, e); 303 } 304 } 307 if (store.getBoolean(ICVSUIConstants.PREF_SHOW_NEWRESOURCE_DECORATION)) { 309 if (cvsResource.exists()) { 310 if (cvsResource.isFolder()) { 311 if (!((ICVSFolder) cvsResource).isCVSFolder()) { 312 cvsDecoration.setNewResource(true); 313 } 314 } else if (!cvsResource.isManaged()) { 315 cvsDecoration.setNewResource(true); 316 } 317 } 318 } 319 if (resource.getType() == IResource.FILE) { 321 extractFileProperties((IFile) resource, cvsDecoration); 322 } else { 323 extractContainerProperties((IContainer) resource, cvsDecoration); 324 } 325 } 326 } 327 328 private static boolean hasRemote(ICVSResource cvsResource) { 329 try { 330 return (cvsResource.isManaged() || cvsResource.isFolder() && ((ICVSFolder)cvsResource).isCVSFolder()); 331 } catch (CVSException e) { 332 return false; 333 } 334 } 335 336 public static CVSDecoration decorate(IResource resource, boolean includeDirtyCheck) throws CVSException { 337 IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 338 ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); 339 CVSDecoration cvsDecoration = new CVSDecoration(); 340 cvsDecoration.setResourceType(resource.getType()); 341 342 if (cvsResource.isIgnored()) { 343 cvsDecoration.setIgnored(true); 344 } 345 if (!cvsDecoration.isIgnored()) { 346 if (includeDirtyCheck) { 348 boolean computeDeepDirtyCheck = store.getBoolean(ICVSUIConstants.PREF_CALCULATE_DIRTY); 349 int type = resource.getType(); 350 if (type == IResource.FILE || computeDeepDirtyCheck) { 351 cvsDecoration.setDirty(CVSLightweightDecorator.isDirty(resource)); 352 } 353 } 354 } 355 decorate(resource, cvsDecoration); 356 return cvsDecoration; 357 } 358 359 private static void extractContainerProperties(IContainer resource, CVSDecoration cvsDecoration) throws CVSException { 360 ICVSFolder folder = CVSWorkspaceRoot.getCVSFolderFor(resource); 361 FolderSyncInfo folderInfo = folder.getFolderSyncInfo(); 362 if (folderInfo != null) { 363 cvsDecoration.setLocation(KnownRepositories.getInstance().getRepository(folderInfo.getRoot())); 364 cvsDecoration.setRepository(folderInfo.getRepository()); 365 cvsDecoration.setVirtualFolder(folderInfo.isVirtualDirectory()); 366 } 367 } 368 369 private static void extractFileProperties(IFile resource, CVSDecoration cvsDecoration) throws CVSException { 370 ICVSFile file = CVSWorkspaceRoot.getCVSFileFor(resource); 371 ResourceSyncInfo fileInfo = file.getSyncInfo(); 372 KSubstOption option = KSubstOption.fromFile(resource); 373 if (fileInfo != null) { 374 cvsDecoration.setAdded(fileInfo.isAdded()); 375 cvsDecoration.setRevision(fileInfo.getRevision()); 376 cvsDecoration.setReadOnly(file.isReadOnly()); 377 cvsDecoration.setNeedsMerge(fileInfo.isNeedsMerge(file.getTimeStamp())); 378 option = fileInfo.getKeywordMode(); 379 } 380 cvsDecoration.setKeywordSubstitution(option.getShortDisplayText()); 381 CVSTeamProvider provider = getCVSProviderFor(resource); 382 if (provider != null) 383 cvsDecoration.setWatchEditEnabled(provider.isWatchEditEnabled()); 384 } 385 386 protected static CVSTag getTagToShow(Object element) throws CoreException { 387 IResource r = getResource(element); 388 if (r != null) 389 return getTagToShow(r); 390 IResource[] resources = getTraversalRoots(element); 391 boolean first = true; 392 CVSTag tag = null; 393 for (int i = 0; i < resources.length; i++) { 394 IResource resource = resources[i]; 395 if (getSubscriber().isSupervised(resource)) { 396 CVSTag nextTag = getTagToShow(resource); 397 if (first) { 398 tag = nextTag; 399 first = false; 400 } else if (!equals(tag, nextTag)) { 401 return null; 402 } 403 404 } 405 } 406 return tag; 407 } 408 409 private static boolean equals(CVSTag tag, CVSTag nextTag) { 410 if (tag == nextTag) 411 return true; 412 if (tag == null || nextTag == null) 413 return false; 414 return tag.getName().equals(nextTag.getName()); 415 } 416 417 421 protected static CVSTag getTagToShow(IResource resource) throws CVSException { 422 ICVSResource cvsResource = CVSWorkspaceRoot.getCVSResourceFor(resource); 423 CVSTag tag = null; 424 425 boolean managed = false; 429 430 if(cvsResource.isFolder()) { 431 FolderSyncInfo folderInfo = ((ICVSFolder)cvsResource).getFolderSyncInfo(); 432 if(folderInfo != null) { 433 tag = folderInfo.getTag(); 434 managed = true; 435 } 436 } else { 437 ResourceSyncInfo info = ((ICVSFile)cvsResource).getSyncInfo(); 438 if(info != null) { 439 tag = info.getTag(); 440 managed = true; 441 } 442 } 443 444 ICVSFolder parent = cvsResource.getParent(); 445 if(parent != null && managed) { 446 FolderSyncInfo parentInfo = parent.getFolderSyncInfo(); 447 if(parentInfo != null) { 448 CVSTag parentTag = parentInfo.getTag(); 449 parentTag = (parentTag == null ? CVSTag.DEFAULT : parentTag); 450 tag = (tag == null ? CVSTag.DEFAULT : tag); 451 if( parentTag.getName().equals(tag.getName())) { 454 tag = null; 455 } 456 } 457 } 458 return tag; 459 } 460 461 464 465 private void addWithParents(IResource resource, Set resources) { 466 IResource current = resource; 467 468 while (current.getType() != IResource.ROOT) { 469 resources.add(current); 470 current = current.getParent(); 471 } 472 } 473 474 477 public static void refresh() { 478 CVSUIPlugin.getPlugin().getWorkbench().getDecoratorManager().update(CVSUIPlugin.DECORATOR_ID); 479 } 480 481 484 485 public void refresh(IProject project) { 486 final List resources = new ArrayList (); 487 try { 488 project.accept(new IResourceVisitor() { 489 public boolean visit(IResource resource) { 490 resources.add(resource); 491 return true; 492 } 493 }); 494 postLabelEvent(new LabelProviderChangedEvent(this, resources.toArray())); 495 } catch (CoreException e) { 496 handleException(project, e); 497 } 498 } 499 500 503 public void resourceSyncInfoChanged(IResource[] changedResources) { 504 resourceStateChanged(changedResources); 505 } 506 507 510 public void externalSyncInfoChange(IResource[] changedResources) { 511 resourceStateChanged(changedResources); 512 } 513 514 517 public void resourceModified(IResource[] changedResources) { 518 resourceStateChanged(changedResources); 519 } 520 521 524 public void resourceStateChanged(IResource[] changedResources) { 525 Set resourcesToUpdate = new HashSet (); 528 529 IPreferenceStore store = CVSUIPlugin.getPlugin().getPreferenceStore(); 530 boolean showingDeepDirtyIndicators = store.getBoolean(ICVSUIConstants.PREF_CALCULATE_DIRTY); 531 532 for (int i = 0; i < changedResources.length; i++) { 533 IResource resource = changedResources[i]; 534 535 if(showingDeepDirtyIndicators) { 536 addWithParents(resource, resourcesToUpdate); 537 } else { 538 resourcesToUpdate.add(resource); 539 } 540 } 541 542 postLabelEvent(new LabelProviderChangedEvent(this, resourcesToUpdate.toArray())); 543 } 544 545 548 public void projectConfigured(IProject project) { 549 refresh(project); 550 } 551 554 public void projectDeconfigured(IProject project) { 555 refresh(project); 556 } 557 558 563 private void postLabelEvent(final LabelProviderChangedEvent event) { 564 Display.getDefault().asyncExec(new Runnable () { 565 public void run() { 566 fireLabelProviderChanged(event); 567 } 568 }); 569 } 570 571 574 public void dispose() { 575 super.dispose(); 576 PlatformUI.getWorkbench().getThemeManager().getCurrentTheme().removePropertyChangeListener(this); 577 CVSProviderPlugin.broadcastDecoratorEnablementChanged(false ); 578 TeamUI.removePropertyChangeListener(this); 579 CVSUIPlugin.removePropertyChangeListener(this); 580 } 581 582 587 private static void handleException(IResource resource, CoreException e) { 588 if (resource == null || resource.isAccessible()) 589 exceptions.handleException(e); 590 } 591 592 597 private void handleException(Object element, CoreException e) { 598 IResource resource = Utils.getResource(element); 599 if (resource != null) { 600 handleException(resource, e); 601 } 602 ResourceMapping mapping = Utils.getResourceMapping(element); 603 IProject[] projects = mapping.getProjects(); 604 for (int i = 0; i < projects.length; i++) { 605 IProject project = projects[i]; 606 if (!project.isAccessible()) { 607 return; 608 } 609 } 610 exceptions.handleException(e); 611 } 612 613 616 public void propertyChange(PropertyChangeEvent event) { 617 if (isEventOfInterest(event)) { 618 ensureFontAndColorsCreated(fonts, colors); 619 refresh(); 620 } 621 } 622 623 private boolean isEventOfInterest(PropertyChangeEvent event) { 624 String prop = event.getProperty(); 625 return prop.equals(TeamUI.GLOBAL_IGNORES_CHANGED) 626 || prop.equals(TeamUI.GLOBAL_FILE_TYPES_CHANGED) 627 || prop.equals(CVSUIPlugin.P_DECORATORS_CHANGED) 628 || prop.equals(CVSDecoratorConfiguration.OUTGOING_CHANGE_BACKGROUND_COLOR) 629 || prop.equals(CVSDecoratorConfiguration.OUTGOING_CHANGE_FOREGROUND_COLOR) 630 || prop.equals(CVSDecoratorConfiguration.OUTGOING_CHANGE_FONT) 631 || prop.equals(CVSDecoratorConfiguration.IGNORED_FOREGROUND_COLOR) 632 || prop.equals(CVSDecoratorConfiguration.IGNORED_BACKGROUND_COLOR) 633 || prop.equals(CVSDecoratorConfiguration.IGNORED_FONT); 634 } 635 636 private static CVSWorkspaceSubscriber getSubscriber() { 637 return CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber(); 638 } 639 } 640 | Popular Tags |