@@ -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
@@ -680,7 +679,7 @@ private void cleanup(boolean fireModelChanged, boolean forkNotification) {
680679			ArrayList <Annotation > deleted = new  ArrayList <>();
681680			IAnnotationMap  annotations = getAnnotationMap ();
682681			Object  mapLock  = annotations .getLockObject ();
683- 
682+ 			 Assert . isNotNull ( mapLock ); 
684683			synchronized  (mapLock ) {
685684				annotations .forEach ((a , p ) -> {
686685					if  (p  == null  || p .isDeleted ()) {
@@ -693,10 +692,12 @@ private void cleanup(boolean fireModelChanged, boolean forkNotification) {
693692				removeAnnotations (deleted , false , false );
694693				synchronized  (getLockObject ()) {
695694					if  (fModelEvent  != null ) {
695+ 						final  AnnotationModelEvent  event  = fModelEvent ;
696+ 						fModelEvent  = null ;
696697						new  Thread () {
697698							@ Override 
698699							public  void  run () {
699- 								fireModelChanged ();
700+ 								fireModelChanged (event );
700701							}
701702						}.start ();
702703					}
@@ -760,7 +761,11 @@ private Iterator<Annotation> getRegionAnnotationIterator(int offset, int length,
760761
761762		try  {
762763			Position [] positions = document .getPositions (IDocument .DEFAULT_CATEGORY , offset , length , canStartBefore , canEndAfter );
763- 			return  new  AnnotationsInterator (positions , fPositions );
764+ 			IdentityHashMap <Position , Annotation > positionsMap ;
765+ 			synchronized  (getLockObject ()) {
766+ 				positionsMap = new  IdentityHashMap <>(fPositions );
767+ 			}
768+ 			return  new  AnnotationsInterator (positions , positionsMap );
764769		} catch  (BadPositionCategoryException  e ) {
765770			// can happen if e.g. the document doesn't contain such a category, or when removed in a different thread 
766771			return  Collections .<Annotation >emptyList ().iterator ();
@@ -784,11 +789,14 @@ private Iterator<Annotation> getAnnotationIterator(boolean cleanup, boolean recu
784789			return  iter ;
785790		}
786791
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 ());
792+ 		List <Iterator <Annotation >> iterators ;
793+ 		synchronized  (getLockObject ()) {
794+ 			iterators = new  ArrayList <>(fAttachments .size () + 1 );
795+ 			iterators .add (iter );
796+ 			Iterator <Object > it = fAttachments .keySet ().iterator ();
797+ 			while  (it .hasNext ()) {
798+ 				iterators .add (fAttachments .get (it .next ()).getAnnotationIterator ());
799+ 			}
792800		}
793801
794802		return  new  MetaIterator <>(iterators .iterator ());
@@ -837,22 +845,21 @@ public void removeAllAnnotations() {
837845	 */ 
838846	protected  void  removeAllAnnotations (boolean  fireModelChanged ) {
839847		IAnnotationMap  annotations = getAnnotationMap ();
840- 		if  (fDocument  != null ) {
848+ 		List <Position > positionsToRemove  = new  ArrayList <>();
849+ 		synchronized  (getLockObject ()) {
841850			Iterator <Annotation > e = getAnnotationMap ().keySetIterator ();
842851			while  (e .hasNext ()) {
843852				Annotation  a = e .next ();
844853				Position  p = annotations .get (a );
845- 				removePosition (fDocument , p );
846- //				p.delete(); 
847- 				synchronized  (getLockObject ()) {
848- 					getAnnotationModelEvent ().annotationRemoved (a , p );
849- 				}
854+ 				positionsToRemove .add (p );
855+ 				getAnnotationModelEvent ().annotationRemoved (a , p );
850856			}
857+ 			annotations .clear ();
858+ 			fPositions .clear ();
859+ 		}
860+ 		for  (Position  position  : positionsToRemove ) {
861+ 			removePosition (fDocument , position );
851862		}
852- 
853- 		annotations .clear ();
854- 		fPositions .clear ();
855- 
856863		if  (fireModelChanged ) {
857864			fireModelChanged ();
858865		}
@@ -872,24 +879,22 @@ public void removeAnnotation(Annotation annotation) {
872879	 */ 
873880	protected  void  removeAnnotation (Annotation  annotation , boolean  fireModelChanged ) {
874881		IAnnotationMap  annotations = getAnnotationMap ();
875- 		if  (annotations .containsKey (annotation )) {
876- 
877- 			Position  p = null ;
882+ 		Position  p ;
883+ 		synchronized  (getLockObject ()) {
878884			p = annotations .get (annotation );
879- 			if  (fDocument  != null ) {
880- 				removePosition (fDocument , p );
881- //				p.delete(); 
885+ 			if  (p  == null ) {
886+ 				return ;
882887			}
883- 
884888			annotations .remove (annotation );
885889			fPositions .remove (p );
886- 			synchronized  (getLockObject ()) {
887- 				getAnnotationModelEvent ().annotationRemoved (annotation , p );
888- 			}
890+ 			getAnnotationModelEvent ().annotationRemoved (annotation , p );
891+ 		}
892+ 		if  (fDocument  != null ) {
893+ 			removePosition (fDocument , p );
894+ 		}
889895
890- 			if  (fireModelChanged ) {
891- 				fireModelChanged ();
892- 			}
896+ 		if  (fireModelChanged ) {
897+ 			fireModelChanged ();
893898		}
894899	}
895900
@@ -982,13 +987,20 @@ public void removeAnnotationModelListener(IAnnotationModelListener listener) {
982987	@ Override 
983988	public  void  addAnnotationModel (Object  key , IAnnotationModel  attachment ) {
984989		Assert .isNotNull (attachment );
985- 		if  (!fAttachments .containsValue (attachment )) {
990+ 		Assert .isNotNull (key );
991+ 		synchronized  (getLockObject ()) {
992+ 			if  (fAttachments .containsValue (attachment )) {
993+ 				return ;
994+ 			}
986995			fAttachments .put (key , attachment );
996+ 		}
997+ 		IDocument  document = fDocument ;
998+ 		if  (document  != null ) {
987999			for  (int  i = 0 ; i  < fOpenConnections ; i ++) {
988- 				attachment .connect (fDocument );
1000+ 				attachment .connect (document );
9891001			}
990- 			attachment .addAnnotationModelListener (fModelListener );
9911002		}
1003+ 		attachment .addAnnotationModelListener (fModelListener );
9921004	}
9931005
9941006	/* 
@@ -1006,13 +1018,21 @@ public IAnnotationModel getAnnotationModel(Object key) {
10061018	 */ 
10071019	@ Override 
10081020	public  IAnnotationModel  removeAnnotationModel (Object  key ) {
1009- 		IAnnotationModel  ret = fAttachments .remove (key );
1010- 		if  (ret  != null ) {
1021+ 		Assert .isNotNull (key );
1022+ 		IAnnotationModel  ret ;
1023+ 		synchronized  (getLockObject ()) {
1024+ 			ret = fAttachments .remove (key );
1025+ 			if  (ret  == null ) {
1026+ 				return  null ;
1027+ 			}
1028+ 		}
1029+ 		IDocument  document = fDocument ;
1030+ 		if  (document  != null ) {
10111031			for  (int  i = 0 ; i  < fOpenConnections ; i ++) {
10121032				ret .disconnect (fDocument );
10131033			}
1014- 			ret .removeAnnotationModelListener (fModelListener );
10151034		}
1035+ 		ret .removeAnnotationModelListener (fModelListener );
10161036		return  ret ;
10171037	}
10181038
0 commit comments