1 11 package org.eclipse.ui.texteditor; 12 13 import java.util.ArrayList ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 17 import org.osgi.framework.Bundle; 18 19 import org.eclipse.core.resources.IMarker; 20 import org.eclipse.core.resources.IResourceStatus; 21 22 import org.eclipse.core.runtime.Assert; 23 import org.eclipse.core.runtime.CoreException; 24 import org.eclipse.core.runtime.IConfigurationElement; 25 import org.eclipse.core.runtime.IExtensionPoint; 26 import org.eclipse.core.runtime.ILog; 27 import org.eclipse.core.runtime.IStatus; 28 import org.eclipse.core.runtime.Platform; 29 import org.eclipse.core.runtime.Status; 30 31 import org.eclipse.core.filebuffers.IPersistableAnnotationModel; 32 33 import org.eclipse.jface.text.BadLocationException; 34 import org.eclipse.jface.text.IDocument; 35 import org.eclipse.jface.text.Position; 36 import org.eclipse.jface.text.source.Annotation; 37 import org.eclipse.jface.text.source.AnnotationModel; 38 import org.eclipse.jface.text.source.IAnnotationMap; 39 40 import org.eclipse.ui.editors.text.EditorsUI; 41 42 import org.eclipse.ui.PlatformUI; 43 44 45 66 public abstract class AbstractMarkerAnnotationModel extends AnnotationModel implements IPersistableAnnotationModel { 67 68 69 private List fDeletedAnnotations= new ArrayList (2); 70 71 private List fInstantiatedMarkerUpdaters= null; 72 73 private List fMarkerUpdaterSpecifications= null; 74 75 76 84 protected abstract IMarker[] retrieveMarkers() throws CoreException; 85 86 94 protected abstract void deleteMarkers(IMarker[] markers) throws CoreException; 95 96 104 protected abstract void listenToMarkerChanges(boolean listen); 105 106 116 protected abstract boolean isAcceptable(IMarker marker); 117 118 122 protected AbstractMarkerAnnotationModel() { 123 } 124 125 132 protected void addMarkerUpdater(IMarkerUpdater markerUpdater) { 133 if (!fInstantiatedMarkerUpdaters.contains(markerUpdater)) 134 fInstantiatedMarkerUpdaters.add(markerUpdater); 135 } 136 137 142 protected void removeMarkerUpdater(IMarkerUpdater markerUpdater) { 143 fInstantiatedMarkerUpdaters.remove(markerUpdater); 144 } 145 146 154 protected MarkerAnnotation createMarkerAnnotation(IMarker marker) { 155 return new MarkerAnnotation(marker); 156 } 157 158 165 protected void handleCoreException(CoreException exception, String message) { 166 167 Bundle bundle = Platform.getBundle(PlatformUI.PLUGIN_ID); 168 ILog log= Platform.getLog(bundle); 169 if (message != null) 170 log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, message, exception)); 171 else 172 log.log(exception.getStatus()); 173 } 174 175 184 protected Position createPositionFromMarker(IMarker marker) { 185 186 int start= MarkerUtilities.getCharStart(marker); 187 int end= MarkerUtilities.getCharEnd(marker); 188 189 if (start > end) { 190 end= start + end; 191 start= end - start; 192 end= end - start; 193 } 194 195 if (start == -1 && end == -1) { 196 int line= MarkerUtilities.getLineNumber(marker); 198 if (line > 0 && fDocument != null) { 199 try { 200 start= fDocument.getLineOffset(line - 1); 201 end= start; 202 } catch (BadLocationException x) { 203 } 204 } 205 } 206 207 if (start > -1 && end > -1) 208 return new Position(start, end - start); 209 210 return null; 211 } 212 213 220 protected final void addMarkerAnnotation(IMarker marker) { 221 222 if (isAcceptable(marker)) { 223 Position p= createPositionFromMarker(marker); 224 if (p != null) 225 try { 226 MarkerAnnotation annotation= createMarkerAnnotation(marker); 227 if (annotation != null) 228 addAnnotation(annotation, p, false); 229 } catch (BadLocationException e) { 230 } 232 } 233 } 234 235 239 protected void connected() { 240 241 listenToMarkerChanges(true); 242 243 try { 244 catchupWithMarkers(); 245 } catch (CoreException x) { 246 if (x.getStatus().getCode() != IResourceStatus.RESOURCE_NOT_FOUND) 247 handleCoreException(x, TextEditorMessages.AbstractMarkerAnnotationModel_connected); 248 } 249 250 fireModelChanged(); 251 } 252 253 256 private void installMarkerUpdaters() { 257 258 fMarkerUpdaterSpecifications= new ArrayList (2); 260 fInstantiatedMarkerUpdaters= new ArrayList (2); 261 262 IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(EditorsUI.PLUGIN_ID, "markerUpdaters"); if (extensionPoint != null) { 265 IConfigurationElement[] elements= extensionPoint.getConfigurationElements(); 266 for (int i= 0; i < elements.length; i++) 267 fMarkerUpdaterSpecifications.add(elements[i]); 268 } 269 } 270 271 274 private void uninstallMarkerUpdaters() { 275 if (fInstantiatedMarkerUpdaters != null) { 276 fInstantiatedMarkerUpdaters.clear(); 277 fInstantiatedMarkerUpdaters= null; 278 } 279 280 if (fMarkerUpdaterSpecifications != null) { 281 fMarkerUpdaterSpecifications.clear(); 282 fMarkerUpdaterSpecifications= null; 283 } 284 } 285 286 290 protected void disconnected() { 291 listenToMarkerChanges(false); 292 uninstallMarkerUpdaters(); 293 } 294 295 301 public Position getMarkerPosition(IMarker marker) { 302 MarkerAnnotation a= getMarkerAnnotation(marker); 303 if (a != null) { 304 return (Position) getAnnotationMap().get(a); 305 } 306 return null; 307 } 308 309 317 protected void modifyMarkerAnnotation(IMarker marker) { 318 MarkerAnnotation a= getMarkerAnnotation(marker); 319 if (a != null) { 320 Position p= createPositionFromMarker(marker); 321 if (p != null) { 322 a.update(); 323 modifyAnnotationPosition(a, p, false); 324 } 325 } else 326 addMarkerAnnotation(marker); 327 } 328 329 332 protected void removeAnnotations(List annotations, boolean fireModelChanged, boolean modelInitiated) { 333 if (annotations != null && annotations.size() > 0) { 334 335 List markerAnnotations= new ArrayList (); 336 for (Iterator e= annotations.iterator(); e.hasNext();) { 337 Annotation a= (Annotation) e.next(); 338 if (a instanceof MarkerAnnotation) 339 markerAnnotations.add(a); 340 341 removeAnnotation(a, false); 343 } 344 345 if (markerAnnotations.size() > 0) { 346 347 if (modelInitiated) { 348 350 listenToMarkerChanges(false); 351 try { 352 353 IMarker[] m= new IMarker[markerAnnotations.size()]; 354 for (int i= 0; i < m.length; i++) { 355 MarkerAnnotation ma = (MarkerAnnotation) markerAnnotations.get(i); 356 m[i]= ma.getMarker(); 357 } 358 deleteMarkers(m); 359 360 } catch (CoreException x) { 361 handleCoreException(x, TextEditorMessages.AbstractMarkerAnnotationModel_removeAnnotations); 362 } 363 listenToMarkerChanges(true); 364 365 } else { 366 fDeletedAnnotations.addAll(markerAnnotations); 368 } 369 } 370 371 if (fireModelChanged) 372 fireModelChanged(); 373 } 374 } 375 376 382 protected final void removeMarkerAnnotation(IMarker marker) { 383 MarkerAnnotation a= getMarkerAnnotation(marker); 384 if (a != null) { 385 removeAnnotation(a, false); 386 } 387 } 388 389 395 private void catchupWithMarkers() throws CoreException { 396 397 for (Iterator e=getAnnotationIterator(false); e.hasNext();) { 398 Annotation a= (Annotation) e.next(); 399 if (a instanceof MarkerAnnotation) 400 removeAnnotation(a, false); 401 } 402 403 IMarker[] markers= retrieveMarkers(); 404 if (markers != null) { 405 for (int i= 0; i < markers.length; i++) 406 addMarkerAnnotation(markers[i]); 407 } 408 } 409 410 416 public final MarkerAnnotation getMarkerAnnotation(IMarker marker) { 417 Iterator e= getAnnotationIterator(false); 418 while (e.hasNext()) { 419 Object o= e.next(); 420 if (o instanceof MarkerAnnotation) { 421 MarkerAnnotation a= (MarkerAnnotation) o; 422 if (marker.equals(a.getMarker())) { 423 return a; 424 } 425 } 426 } 427 return null; 428 } 429 430 436 private IMarkerUpdater createMarkerUpdater(IConfigurationElement element) { 437 try { 438 return (IMarkerUpdater) element.createExecutableExtension("class"); } catch (CoreException x) { 440 handleCoreException(x, TextEditorMessages.AbstractMarkerAnnotationModel_createMarkerUpdater); 441 } 442 443 return null; 444 } 445 446 454 private void checkMarkerUpdaters(IMarker marker) { 455 List toBeDeleted= new ArrayList (); 456 for (int i= 0; i < fMarkerUpdaterSpecifications.size(); i++) { 457 IConfigurationElement spec= (IConfigurationElement) fMarkerUpdaterSpecifications.get(i); 458 String markerType= spec.getAttribute("markerType"); if (markerType == null || MarkerUtilities.isMarkerType(marker, markerType)) { 460 toBeDeleted.add(spec); 461 IMarkerUpdater updater= createMarkerUpdater(spec); 462 if (updater != null) 463 addMarkerUpdater(updater); 464 } 465 } 466 467 for (int i= 0; i < toBeDeleted.size(); i++) 468 fMarkerUpdaterSpecifications.remove(toBeDeleted.get(i)); 469 } 470 471 491 public boolean updateMarker(IMarker marker, IDocument document, Position position) throws CoreException { 492 493 if (fMarkerUpdaterSpecifications == null) 494 installMarkerUpdaters(); 495 496 if (!fMarkerUpdaterSpecifications.isEmpty()) 497 checkMarkerUpdaters(marker); 498 499 boolean isOK= true; 500 501 for (int i= 0; i < fInstantiatedMarkerUpdaters.size(); i++) { 502 IMarkerUpdater updater= (IMarkerUpdater) fInstantiatedMarkerUpdaters.get(i); 503 String markerType= updater.getMarkerType(); 504 if (markerType == null || MarkerUtilities.isMarkerType(marker, markerType)) { 505 506 if (position == null) { 507 508 position= createPositionFromMarker(marker); 509 } 510 511 isOK= (isOK && updater.updateMarker(marker, document, position)); 512 } 513 } 514 515 return isOK; 516 } 517 518 532 public boolean updateMarker(IDocument document, IMarker marker, Position position) throws CoreException { 533 listenToMarkerChanges(false); 534 try { 535 return updateMarker(marker, document, position); 536 } finally { 537 listenToMarkerChanges(true); 538 } 539 } 540 541 548 public void updateMarkers(IDocument document) throws CoreException { 549 550 Assert.isTrue(fDocument == document); 551 552 IAnnotationMap annotationMap= getAnnotationMap(); 553 554 if (annotationMap.size() == 0 && fDeletedAnnotations.size() == 0) 555 return; 556 557 if (fMarkerUpdaterSpecifications == null) 558 installMarkerUpdaters(); 559 560 listenToMarkerChanges(false); 561 562 try { 563 564 for (Iterator e= getAnnotationIterator(false); e.hasNext();) { 566 Object o= e.next(); 567 if (o instanceof MarkerAnnotation) { 568 MarkerAnnotation a= (MarkerAnnotation) o; 569 IMarker marker= a.getMarker(); 570 Position position= (Position) annotationMap.get(a); 571 if ( !updateMarker(marker, document, position)) { 572 if ( !fDeletedAnnotations.contains(a)) 573 fDeletedAnnotations.add(a); 574 } 575 } 576 } 577 578 if (!fDeletedAnnotations.isEmpty()) { 579 removeAnnotations(fDeletedAnnotations, true, true); 580 fDeletedAnnotations.clear(); 581 } 582 583 } finally { 584 585 listenToMarkerChanges(true); 586 587 } 588 } 589 590 593 public void resetMarkers() { 594 595 for (Iterator e= getAnnotationIterator(false); e.hasNext();) { 597 Object o= e.next(); 598 if (o instanceof MarkerAnnotation) { 599 MarkerAnnotation a= (MarkerAnnotation) o; 600 Position p= createPositionFromMarker(a.getMarker()); 601 if (p != null) { 602 removeAnnotation(a, false); 603 try { 604 addAnnotation(a, p, false); 605 } catch (BadLocationException e1) { 606 } 608 } 609 } 610 } 611 612 for (Iterator e= fDeletedAnnotations.iterator(); e.hasNext();) { 614 Object o= e.next(); 615 if (o instanceof MarkerAnnotation) { 616 MarkerAnnotation a= (MarkerAnnotation) o; 617 Position p= createPositionFromMarker(a.getMarker()); 618 if (p != null) 619 try { 620 addAnnotation(a, p, false); 621 } catch (BadLocationException e1) { 622 } 624 } 625 } 626 fDeletedAnnotations.clear(); 627 628 fireModelChanged(); 630 } 631 632 635 public void commit(IDocument document) throws CoreException { 636 updateMarkers(document); 637 } 638 639 642 public void revert(IDocument document) { 643 resetMarkers(); 644 } 645 646 649 public void reinitialize(IDocument document) { 650 resetMarkers(); 651 } 652 } 653 | Popular Tags |