@@ -451,18 +451,17 @@ protected void replaceAnnotations(Annotation[] annotationsToRemove, Map<? extend
451451 */
452452 protected void addAnnotation (Annotation annotation , Position position , boolean fireModelChanged ) throws BadLocationException {
453453 IAnnotationMap annotations = getAnnotationMap ();
454- if (!annotations .containsKey (annotation )) {
455-
456- addPosition (fDocument , position );
457- annotations .put (annotation , position );
458- fPositions .put (position , annotation );
459- synchronized (getLockObject ()) {
460- getAnnotationModelEvent ().annotationAdded (annotation );
461- }
462-
463- if (fireModelChanged ) {
464- fireModelChanged ();
454+ synchronized (getLockObject ()) {
455+ if (annotations .containsKey (annotation )) {
456+ return ;
465457 }
458+ fPositions .put (position , annotation );
459+ annotations .put (annotation , position );
460+ getAnnotationModelEvent ().annotationAdded (annotation );
461+ }
462+ addPosition (fDocument , position );
463+ if (fireModelChanged ) {
464+ fireModelChanged ();
466465 }
467466 }
468467
@@ -679,9 +678,8 @@ private void cleanup(boolean fireModelChanged, boolean forkNotification) {
679678
680679 ArrayList <Annotation > deleted = new ArrayList <>();
681680 IAnnotationMap annotations = getAnnotationMap ();
682- Object mapLock = annotations .getLockObject ();
683681
684- synchronized (mapLock ) {
682+ synchronized (getLockObject () ) {
685683 annotations .forEach ((a , p ) -> {
686684 if (p == null || p .isDeleted ()) {
687685 deleted .add (a );
@@ -693,10 +691,12 @@ private void cleanup(boolean fireModelChanged, boolean forkNotification) {
693691 removeAnnotations (deleted , false , false );
694692 synchronized (getLockObject ()) {
695693 if (fModelEvent != null ) {
694+ final AnnotationModelEvent event = fModelEvent ;
695+ fModelEvent = null ;
696696 new Thread () {
697697 @ Override
698698 public void run () {
699- fireModelChanged ();
699+ fireModelChanged (event );
700700 }
701701 }.start ();
702702 }
@@ -760,7 +760,11 @@ private Iterator<Annotation> getRegionAnnotationIterator(int offset, int length,
760760
761761 try {
762762 Position [] positions = document .getPositions (IDocument .DEFAULT_CATEGORY , offset , length , canStartBefore , canEndAfter );
763- return new AnnotationsInterator (positions , fPositions );
763+ IdentityHashMap <Position , Annotation > positionsMap ;
764+ synchronized (getLockObject ()) {
765+ positionsMap = new IdentityHashMap <>(fPositions );
766+ }
767+ return new AnnotationsInterator (positions , positionsMap );
764768 } catch (BadPositionCategoryException e ) {
765769 // can happen if e.g. the document doesn't contain such a category, or when removed in a different thread
766770 return Collections .<Annotation >emptyList ().iterator ();
@@ -784,11 +788,14 @@ private Iterator<Annotation> getAnnotationIterator(boolean cleanup, boolean recu
784788 return iter ;
785789 }
786790
787- List <Iterator <Annotation >> iterators = new ArrayList <>(fAttachments .size () + 1 );
788- iterators .add (iter );
789- Iterator <Object > it = fAttachments .keySet ().iterator ();
790- while (it .hasNext ()) {
791- iterators .add (fAttachments .get (it .next ()).getAnnotationIterator ());
791+ List <Iterator <Annotation >> iterators ;
792+ synchronized (getLockObject ()) {
793+ iterators = new ArrayList <>(fAttachments .size () + 1 );
794+ iterators .add (iter );
795+ Iterator <Object > it = fAttachments .keySet ().iterator ();
796+ while (it .hasNext ()) {
797+ iterators .add (fAttachments .get (it .next ()).getAnnotationIterator ());
798+ }
792799 }
793800
794801 return new MetaIterator <>(iterators .iterator ());
@@ -837,22 +844,21 @@ public void removeAllAnnotations() {
837844 */
838845 protected void removeAllAnnotations (boolean fireModelChanged ) {
839846 IAnnotationMap annotations = getAnnotationMap ();
840- if (fDocument != null ) {
847+ List <Position > positionsToRemove = new ArrayList <>();
848+ synchronized (getLockObject ()) {
841849 Iterator <Annotation > e = getAnnotationMap ().keySetIterator ();
842850 while (e .hasNext ()) {
843851 Annotation a = e .next ();
844852 Position p = annotations .get (a );
845- removePosition (fDocument , p );
846- // p.delete();
847- synchronized (getLockObject ()) {
848- getAnnotationModelEvent ().annotationRemoved (a , p );
849- }
853+ positionsToRemove .add (p );
854+ getAnnotationModelEvent ().annotationRemoved (a , p );
850855 }
856+ annotations .clear ();
857+ fPositions .clear ();
858+ }
859+ for (Position position : positionsToRemove ) {
860+ removePosition (fDocument , position );
851861 }
852-
853- annotations .clear ();
854- fPositions .clear ();
855-
856862 if (fireModelChanged ) {
857863 fireModelChanged ();
858864 }
@@ -872,24 +878,22 @@ public void removeAnnotation(Annotation annotation) {
872878 */
873879 protected void removeAnnotation (Annotation annotation , boolean fireModelChanged ) {
874880 IAnnotationMap annotations = getAnnotationMap ();
875- if (annotations .containsKey (annotation )) {
876-
877- Position p = null ;
881+ Position p ;
882+ synchronized (getLockObject ()) {
878883 p = annotations .get (annotation );
879- if (fDocument != null ) {
880- removePosition (fDocument , p );
881- // p.delete();
884+ if (p == null ) {
885+ return ;
882886 }
883-
884887 annotations .remove (annotation );
885888 fPositions .remove (p );
886- synchronized (getLockObject ()) {
887- getAnnotationModelEvent ().annotationRemoved (annotation , p );
888- }
889+ getAnnotationModelEvent ().annotationRemoved (annotation , p );
890+ }
891+ if (fDocument != null ) {
892+ removePosition (fDocument , p );
893+ }
889894
890- if (fireModelChanged ) {
891- fireModelChanged ();
892- }
895+ if (fireModelChanged ) {
896+ fireModelChanged ();
893897 }
894898 }
895899
@@ -982,13 +986,20 @@ public void removeAnnotationModelListener(IAnnotationModelListener listener) {
982986 @ Override
983987 public void addAnnotationModel (Object key , IAnnotationModel attachment ) {
984988 Assert .isNotNull (attachment );
985- if (!fAttachments .containsValue (attachment )) {
989+ Assert .isNotNull (key );
990+ synchronized (getLockObject ()) {
991+ if (fAttachments .containsValue (attachment )) {
992+ return ;
993+ }
986994 fAttachments .put (key , attachment );
995+ }
996+ IDocument document = fDocument ;
997+ if (document != null ) {
987998 for (int i = 0 ; i < fOpenConnections ; i ++) {
988- attachment .connect (fDocument );
999+ attachment .connect (document );
9891000 }
990- attachment .addAnnotationModelListener (fModelListener );
9911001 }
1002+ attachment .addAnnotationModelListener (fModelListener );
9921003 }
9931004
9941005 /*
@@ -1006,13 +1017,21 @@ public IAnnotationModel getAnnotationModel(Object key) {
10061017 */
10071018 @ Override
10081019 public IAnnotationModel removeAnnotationModel (Object key ) {
1009- IAnnotationModel ret = fAttachments .remove (key );
1010- if (ret != null ) {
1020+ Assert .isNotNull (key );
1021+ IAnnotationModel ret ;
1022+ synchronized (getLockObject ()) {
1023+ ret = fAttachments .remove (key );
1024+ if (ret == null ) {
1025+ return null ;
1026+ }
1027+ }
1028+ IDocument document = fDocument ;
1029+ if (document != null ) {
10111030 for (int i = 0 ; i < fOpenConnections ; i ++) {
1012- ret .disconnect (fDocument );
1031+ ret .disconnect (document );
10131032 }
1014- ret .removeAnnotationModelListener (fModelListener );
10151033 }
1034+ ret .removeAnnotationModelListener (fModelListener );
10161035 return ret ;
10171036 }
10181037
0 commit comments