@@ -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