1 11 package org.eclipse.team.internal.ui.history; 12 13 import java.util.*; 14 15 import org.eclipse.compare.ITypedElement; 16 import org.eclipse.compare.internal.CompareUIPlugin; 17 import org.eclipse.compare.internal.StructureCreatorDescriptor; 18 import org.eclipse.compare.structuremergeviewer.*; 19 import org.eclipse.core.resources.IFile; 20 import org.eclipse.core.resources.IResource; 21 import org.eclipse.core.runtime.*; 22 import org.eclipse.osgi.util.NLS; 23 import org.eclipse.swt.graphics.Image; 24 import org.eclipse.team.core.TeamException; 25 import org.eclipse.team.core.history.IFileRevision; 26 import org.eclipse.team.internal.core.history.LocalFileHistory; 27 import org.eclipse.team.internal.ui.*; 28 import org.eclipse.team.internal.ui.actions.CompareRevisionAction; 29 import org.eclipse.team.internal.ui.synchronize.LocalResourceTypedElement; 30 import org.eclipse.team.ui.history.IHistoryPage; 31 import org.eclipse.team.ui.history.IHistoryPageSite; 32 import org.eclipse.ui.IWorkbenchPage; 33 34 42 public class EditionHistoryPage extends LocalHistoryPage { 43 44 private final IFile file; 45 private final Object element; 46 private final LocalResourceTypedElement localFileElement; 47 private IStructureCreator structureCreator; 48 private Map editions = new HashMap(); 49 private ITypedElement localEdition; 50 private String name; 51 52 class CompareEditionAction extends CompareRevisionAction { 53 54 protected ITypedElement getElementFor(IResource resource) { 55 if (resource.equals(file)) 56 return localFileElement; 57 return super.getElementFor(resource); 58 } 59 60 protected CompareFileRevisionEditorInput createCompareEditorInput(ITypedElement left, ITypedElement right, IWorkbenchPage page) { 61 ITypedElement leftEdition = getEdition(left); 62 boolean leftIsLocal = false; 63 if (leftEdition == null && left instanceof LocalResourceTypedElement) { 64 leftEdition = createLocalEdition(structureCreator, localFileElement, element); 65 leftIsLocal = true; 66 } 67 ITypedElement rightEdition = getEdition(right); 68 return new CompareEditionsEditorInput(structureCreator, left, right, leftEdition, rightEdition, leftIsLocal, page); 69 } 70 71 private ITypedElement getEdition(ITypedElement input) { 72 if (input instanceof FileRevisionTypedElement) { 73 FileRevisionTypedElement te = (FileRevisionTypedElement) input; 74 return getEditionFor(te.getRevision()); 75 } 76 return null; 77 } 78 } 79 80 static class CompareEditionsEditorInput extends CompareFileRevisionEditorInput { 81 82 private final ITypedElement leftRevision; 83 private final ITypedElement rightRevision; 84 private final boolean leftIsLocal; 85 private IStructureCreator structureCreator; 86 87 public CompareEditionsEditorInput(IStructureCreator structureCreator, ITypedElement left, 88 ITypedElement right, ITypedElement leftEdition, 89 ITypedElement rightEdition, boolean leftIsLocal, IWorkbenchPage page) { 90 super(leftEdition, rightEdition, page); 91 this.structureCreator = structureCreator; 92 leftRevision = left; 93 rightRevision = right; 94 this.leftIsLocal = leftIsLocal; 95 } 96 97 public LocalResourceTypedElement getLocalElement() { 98 if (leftRevision instanceof LocalResourceTypedElement) { 99 return (LocalResourceTypedElement) leftRevision; 100 } 101 return super.getLocalElement(); 102 } 103 104 protected FileRevisionTypedElement getRightRevision() { 105 if (rightRevision instanceof FileRevisionTypedElement) { 106 return (FileRevisionTypedElement) rightRevision; 107 } 108 return null; 109 } 110 111 protected FileRevisionTypedElement getLeftRevision() { 112 if (leftRevision instanceof FileRevisionTypedElement) { 113 return (FileRevisionTypedElement) leftRevision; 114 } 115 return null; 116 } 117 public Object getAdapter(Class adapter) { 118 if (adapter == IFile.class) 119 return null; 120 return super.getAdapter(adapter); 121 } 122 123 protected void handleDispose() { 124 if (leftIsLocal && structureCreator != null) 125 internalDestroy(structureCreator, getLeft()); 126 structureCreator = null; 127 super.handleDispose(); 128 } 129 } 130 131 public static ITypedElement getPreviousState(IFile file, Object element) throws TeamException { 132 LocalResourceTypedElement localFileElement= new LocalResourceTypedElement(file); 133 IStructureCreator structureCreator = getStructureCreator(localFileElement); 134 if (structureCreator == null) 135 return null; 136 LocalFileHistory history = new LocalFileHistory(file, false); 137 history.refresh(new NullProgressMonitor()); 138 IFileRevision[] revisions = history.getFileRevisions(); 139 if (revisions.length == 0) 140 return null; 141 sortDescending(revisions); 142 ITypedElement localEdition = null; 143 try { 144 localEdition = createLocalEdition(structureCreator, localFileElement, element); 145 for (int i = 0; i < revisions.length; i++) { 146 IFileRevision revision = revisions[i]; 147 ITypedElement edition = createEdition(structureCreator, element, new FileRevisionTypedElement(revision)); 148 if (edition != null && !contentsEqual(structureCreator, localEdition, edition)) { 149 return edition; 150 } 151 } 152 } finally { 153 if (localEdition != null) 154 destroyLocalEdition(structureCreator, localFileElement, localEdition); 155 } 156 return null; 157 } 158 159 private static IStructureCreator getStructureCreator(ITypedElement element) { 160 StructureCreatorDescriptor scd= CompareUIPlugin.getDefault().getStructureCreator(element.getType()); 161 if (scd != null) { 162 return scd.createStructureCreator(); 163 } 164 return null; 165 } 166 167 public EditionHistoryPage(IFile file, Object element) { 168 super(ON | ALWAYS); 169 Assert.isNotNull(file); 170 Assert.isNotNull(element); 171 this.file = file; 172 this.element = element; 173 this.localFileElement= new LocalResourceTypedElement(getFile()); 174 structureCreator = getStructureCreator(localFileElement); 175 } 176 177 public void setSite(IHistoryPageSite site) { 178 super.setSite(site); 179 if (site.isModal()) { 181 localEdition = createLocalEdition(structureCreator, localFileElement, element); 182 } 183 } 184 185 188 protected IFile getFile() { 189 return file; 190 } 191 192 195 protected void update(IFileRevision[] revisions, IProgressMonitor monitor) { 196 monitor.beginTask(null, 100); 197 ITypedElement te = null; 198 try { 199 if (localEdition == null) { 200 te = createLocalEdition(structureCreator, localFileElement, element); 201 } else { 202 te = localEdition; 203 } 204 if (te != null) { 205 String oldValue = getName(); 206 String oldDesc = getDescription(); 207 name = te.getName(); 208 IFileRevision[] filtered = filterRevisions(te, revisions, Policy.subMonitorFor(monitor, 75)); 209 super.update(filtered, Policy.subMonitorFor(monitor, 25)); 210 firePropertyChange(this, IHistoryPage.P_NAME, oldValue, getName()); 211 firePropertyChange(this, IHistoryPage.P_DESCRIPTION, oldDesc, getDescription()); 212 } 213 } finally { 214 if (localEdition == null && te != null) 215 internalDestroy(structureCreator, te); 216 monitor.done(); 217 } 218 } 219 220 private IFileRevision[] filterRevisions(ITypedElement localEdition, IFileRevision[] revisions, 221 IProgressMonitor monitor) { 222 ITypedElement previousEdition = localEdition; 223 List result = new ArrayList(); 224 sortDescending(revisions); 225 editions.clear(); 226 for (int i = 0; i < revisions.length; i++) { 227 IFileRevision revision = revisions[i]; 228 ITypedElement edition = createEdition(new FileRevisionTypedElement(revision)); 229 if (edition != null && !contentsEqual(structureCreator, previousEdition, edition)) { 230 editions.put(revision, edition); 231 previousEdition = edition; 232 result.add(revision); 233 } 234 } 235 return (IFileRevision[]) result.toArray(new IFileRevision[result.size()]); 236 } 237 238 private static void sortDescending(IFileRevision[] revisions) { 239 Arrays.sort(revisions, new Comparator() { 240 public int compare(Object o1, Object o2) { 241 IFileRevision d1= (IFileRevision) o1; 242 IFileRevision d2= (IFileRevision) o2; 243 long d= d2.getTimestamp() - d1.getTimestamp(); 244 if (d < 0) 245 return -1; 246 if (d > 0) 247 return 1; 248 return 0; 249 } 250 }); 251 } 252 253 private static boolean contentsEqual(IStructureCreator creator, ITypedElement previousEdition, 254 ITypedElement edition) { 255 if (previousEdition == null || creator == null || edition == null) 256 return false; 257 String contents1 = creator.getContents(previousEdition, false ); 258 String contents2 = creator.getContents(edition, false ); 259 return (contents1 != null && contents2 != null && contents1.equals(contents2)); 260 } 261 262 265 public ICompareInput getCompareInput(Object object) { 266 ITypedElement edition = getEditionFor(object); 267 if (edition != null && localEdition != null) 268 return new DiffNode(localEdition, edition); 269 return null; 270 } 271 272 public ITypedElement getEditionFor(Object object) { 273 return (ITypedElement)editions.get(object); 274 } 275 276 private static ITypedElement createLocalEdition(IStructureCreator creator, ITypedElement input, Object element) { 277 if (creator == null) 278 return null; 279 ITypedElement result = null; 280 if (creator instanceof IStructureCreator2) { 281 IStructureCreator2 sc2 = (IStructureCreator2) creator; 282 try { 283 result = sc2.createElement(element, input, null); 284 } catch (CoreException e) { 285 TeamUIPlugin.log(e); 286 } 287 } 288 if (result == null) { 289 result = createEdition(creator, element, input); 290 } 291 return result; 292 } 293 294 private ITypedElement createEdition(ITypedElement input) { 295 return createEdition(structureCreator, element, input); 296 } 297 298 private static ITypedElement createEdition(IStructureCreator creator, Object element, ITypedElement input) { 299 if (creator == null) 300 return null; 301 IStructureComparator edition = creator.locate(element, input); 302 if (edition instanceof ITypedElement) 303 return (ITypedElement) edition; 304 return null; 305 } 306 307 310 public boolean isValidInput(Object object) { 311 return object.equals(element); 313 } 314 315 318 public void dispose() { 319 try { 320 disconnect(); 321 } finally { 322 super.dispose(); 323 } 324 } 325 326 private void disconnect() { 327 if (localFileElement != null) 328 localFileElement.discardBuffer(); 329 internalDestroy(structureCreator, localEdition); 330 localEdition = null; 331 structureCreator = null; 332 } 333 334 private static void internalDestroy(IStructureCreator creator, ITypedElement te) { 335 if (te != null && creator instanceof IStructureCreator2) { 336 IStructureCreator2 sc2 = (IStructureCreator2) creator; 337 sc2.destroy(te); 338 } 339 } 340 341 private static void destroyLocalEdition( 342 IStructureCreator structureCreator, LocalResourceTypedElement localFileElement, ITypedElement localEdition) { 343 if (localFileElement != null) 344 localFileElement.discardBuffer(); 345 if (localEdition != null && structureCreator instanceof IStructureCreator2) { 346 IStructureCreator2 sc2 = (IStructureCreator2) structureCreator; 347 sc2.destroy(localEdition); 348 } 349 } 350 351 354 protected String getNoChangesMessage() { 355 if (name != null) 356 return NLS.bind(TeamUIMessages.EditionHistoryPage_0, name); 357 return TeamUIMessages.EditionHistoryPage_1; 358 } 359 360 protected Image getImage(Object object) { 361 if (object == localEdition) 362 return localEdition.getImage(); 363 Object revision = getRevisionFor(object); 364 if (revision != null) 365 return super.getImage(revision); 366 return super.getImage(object); 367 } 368 369 protected String getLabel(Object object) { 370 Object revision = getRevisionFor(object); 371 if (revision != null) 372 return super.getLabel(revision); 373 return super.getLabel(object); 374 } 375 376 private Object getRevisionFor(Object object) { 377 if (object == localEdition) 378 return localFileElement; 379 for (Iterator iterator = editions.keySet().iterator(); iterator.hasNext();) { 380 IFileRevision revision = (IFileRevision) iterator.next(); 381 if (editions.get(revision) == object) { 382 return revision; 383 } 384 } 385 return null; 386 } 387 388 391 public String getName() { 392 if (name != null) 393 return name; 394 return super.getName(); 395 } 396 397 400 public String getDescription() { 401 if (name != null) 402 return NLS.bind(TeamUIMessages.EditionHistoryPage_2, name); 403 return super.getDescription(); 404 } 405 406 409 protected CompareRevisionAction createCompareAction() { 410 return new CompareEditionAction(); 411 } 412 413 } 414 | Popular Tags |