3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
11 package eu
.etaxonomy
.taxeditor
.annotatedlineeditor
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Collections
;
15 import java
.util
.Comparator
;
16 import java
.util
.HashSet
;
17 import java
.util
.Iterator
;
18 import java
.util
.List
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.eclipse
.jface
.text
.BadLocationException
;
23 import org
.eclipse
.jface
.text
.IDocument
;
24 import org
.eclipse
.jface
.text
.Position
;
25 import org
.eclipse
.jface
.text
.source
.Annotation
;
26 import org
.eclipse
.jface
.text
.source
.AnnotationModel
;
27 import org
.eclipse
.jface
.text
.source
.AnnotationModelEvent
;
29 import eu
.etaxonomy
.taxeditor
.bulkeditor
.BulkEditorUtil
;
32 * An <code>AnnotationModel</code> which holds <code>LineAnnotation</code>'s.
34 * Major difference with <code>AnnotationModel</code> is that <code>removeAnnotation(Annotation annotation,
35 * boolean fireModelChanged)</code> adds annotations marked for removal to a collection for further
36 * processing, i.e. when the document is saved. This collection is accessed via <code>getDeletedAnnotations()</code>
37 * and <code>clearDeletedAnnotations()</code>.
43 public class LineAnnotationModel
extends AnnotationModel
{
45 private Comparator
<Annotation
> comparator
;
46 private IEntityCreator
<?
> entityCreator
;
47 private Set
<LineAnnotation
> deletedAnnotations
= new HashSet
<LineAnnotation
>();
49 private ILineDisplayStrategy lineDisplayStrategy
;
52 * <p>Constructor for LineAnnotationModel.</p>
54 * @param lineDisplayStrategy a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.ILineDisplayStrategy} object.
56 public LineAnnotationModel(ILineDisplayStrategy lineDisplayStrategy
) {
58 this.lineDisplayStrategy
= lineDisplayStrategy
;
62 * Changes the annotation's type and fires model changed
63 * notification. Resulting redraw will cause any change
64 * in annotation's decoration to be displayed.
66 * @param annotation a {@link org.eclipse.jface.text.source.Annotation} object.
67 * @param type a {@link java.lang.String} object.
69 public void changeAnnotationType(Annotation annotation
, String type
) {
70 annotation
.setType(type
);
71 fireModelChanged(new AnnotationModelEvent(this));
75 * @see org.eclipse.jface.text.source.AnnotationModel#removeAnnotation(org.eclipse.jface.text.source.Annotation, boolean)
78 protected void removeAnnotation(Annotation annotation
,
79 boolean fireModelChanged
) {
80 // Set data model element for deletion
81 annotation
.markDeleted(true);
82 if (annotation
instanceof LineAnnotation
) {
83 deletedAnnotations
.add((LineAnnotation
) annotation
);
85 super.removeAnnotation(annotation
, fireModelChanged
);
89 * <p>removeTypeFromAllAnnotations</p>
91 * @param type a {@link java.lang.String} object.
93 public void removeTypeFromAllAnnotations(String type
) {
94 Iterator
<?
> iterator
= getAnnotationIterator();
95 while (iterator
.hasNext()) {
96 Annotation annotation
= ((Annotation
) iterator
.next());
97 if (annotation
.getType().equals(type
)) {
98 annotation
.setType(Annotation
.TYPE_UNKNOWN
);
104 * <p>getAllAnnotationsOfType</p>
106 * @param type a {@link java.lang.String} object.
107 * @return a {@link java.util.Set} object.
109 public Set
<LineAnnotation
> getAllAnnotationsOfType(String type
) {
110 Set
<LineAnnotation
> candidates
= new HashSet
<LineAnnotation
>();
111 Iterator
<?
> iterator
= getAnnotationIterator();
112 while (iterator
.hasNext()) {
113 LineAnnotation annotation
= ((LineAnnotation
) iterator
.next());
114 if (annotation
.getType().equals(type
)) {
115 candidates
.add(annotation
);
122 * <p>getFirstAnnotationOfType</p>
124 * @param type a {@link java.lang.String} object.
125 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
127 public Annotation
getFirstAnnotationOfType(String type
) {
128 Iterator
<?
> iterator
= getAnnotationIterator();
129 while (iterator
.hasNext()) {
130 Annotation annotation
= ((Annotation
) iterator
.next());
131 if (annotation
.getType().equals(type
)) {
139 * Gets first LineAnnotation in line
142 * @param document a {@link org.eclipse.jface.text.IDocument} object.
143 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
145 public Annotation
getAnnotationAtLine(int line
, IDocument document
) {
146 // Annotation annotation = null;
148 int offset
= document
.getLineOffset(line
);
149 int length
= document
.getLineLength(line
);
151 Iterator
<?
> iterator
= getAnnotationIterator(offset
, length
, true, true);
152 while (iterator
.hasNext()) {
153 Object next
= iterator
.next();
154 if (next
instanceof LineAnnotation
) {
155 return (LineAnnotation
) next
;
157 // annotation = (Annotation) iterator.next();
159 } catch (BadLocationException e
) {
166 * <p>getOrderedAnnotations</p>
168 * @return a {@link java.util.List} object.
170 public List
<Annotation
> getOrderedAnnotations() {
171 List
<Annotation
> list
= new ArrayList
<Annotation
>();
172 Iterator
<?
> iterator
= getAnnotationIterator();
173 while (iterator
.hasNext()) {
174 list
.add((Annotation
) iterator
.next());
176 Collections
.sort(list
, getAnnotationComparator());
181 * <p>printAnnotations</p>
183 public void printAnnotations() {
184 Logger logger
= BulkEditorUtil
.getLog4JLogger(getClass());
185 logger
.debug("------------------------");
186 logger
.debug("Active annotations");
187 logger
.debug("------------------------");
188 List
<Annotation
> list
= getOrderedAnnotations();
190 for (Annotation annotation
: list
) {
192 (annotation
.isMarkedDeleted() ?
"DELETED " : "") +
193 (((LineAnnotation
) annotation
).isMarkedAsMerged() ?
"MERGED " : "") +
194 (((LineAnnotation
) annotation
).isDirty() ?
"DIRTY " : "") +
195 (((LineAnnotation
) annotation
).isMarkedAsNew() ?
"NEW " : "") +
196 annotation
.getText() + ": o " +
197 getPosition(annotation
).getOffset() + ", l " +
198 getPosition(annotation
).getLength());
200 logger
.debug("------------------------");
201 logger
.debug("Deleted annotations");
202 logger
.debug("------------------------");
203 for (LineAnnotation annotation
: deletedAnnotations
) {
205 (annotation
.isMarkedDeleted() ?
"DELETED " : "") +
206 (((LineAnnotation
) annotation
).isMarkedAsMerged() ?
"MERGED " : "") +
207 (((LineAnnotation
) annotation
).isDirty() ?
"DIRTY " : "") +
208 (((LineAnnotation
) annotation
).isMarkedAsNew() ?
"NEW " : "") +
209 annotation
.getText() + ": o ");
214 * <p>getUndeletedAnnotations</p>
216 * @param offset a int.
217 * @param length a int.
218 * @return a {@link java.util.List} object.
220 public List
<LineAnnotation
> getUndeletedAnnotations(int offset
, int length
) {
222 List
<LineAnnotation
> list
= new ArrayList
<LineAnnotation
>();
224 Iterator
<?
> iterator
= getAnnotationIterator(offset
, length
, true, true);
225 while (iterator
.hasNext()) {
226 Object next
= iterator
.next();
227 if (next
instanceof LineAnnotation
&& !((Annotation
) next
).isMarkedDeleted()) {
228 list
.add((LineAnnotation
) next
);
231 Collections
.sort(list
, getAnnotationComparator());
236 * <p>Getter for the field <code>deletedAnnotations</code>.</p>
238 * @return a {@link java.util.Set} object.
240 public Set
<LineAnnotation
> getDeletedAnnotations() {
241 return deletedAnnotations
;
245 * <p>clearDeletedAnnotations</p>
247 public void clearDeletedAnnotations() {
248 deletedAnnotations
.clear();
251 private Comparator
<Annotation
> getAnnotationComparator() {
252 if (comparator
== null) {
253 this.comparator
= new AnnotationComparator();
258 class AnnotationComparator
implements Comparator
<Annotation
> {
261 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
263 public int compare(Annotation annotation1
, Annotation annotation2
) {
264 if (annotation1
.isMarkedDeleted() && !annotation2
.isMarkedDeleted()) {
267 if (!annotation1
.isMarkedDeleted() && annotation2
.isMarkedDeleted()) {
270 int offset1
= LineAnnotationModel
.this.
271 getPosition(annotation1
).getOffset();
272 int offset2
= LineAnnotationModel
.this.
273 getPosition(annotation2
).getOffset();
274 if (offset1
> offset2
) {
276 } else if (offset1
< offset2
) {
285 * The annotation model is assigned responsibility for creating new containers
286 * from blocks of text.
288 * @param entityCreator a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator} object.
290 public void setEntityCreator(IEntityCreator
<?
> entityCreator
) {
291 this.entityCreator
= entityCreator
;
295 * Creates an annotation without adding it to the model.
297 * This object must have its <code>cdmEntityCreator</code> set.
299 * @param text a {@link java.lang.String} object.
300 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
302 public Annotation
createAnnotation(String text
) {
303 LineAnnotation annotation
= null;
304 if (entityCreator
!= null) {
305 annotation
= new LineAnnotation(entityCreator
.createEntity(text
), lineDisplayStrategy
);
306 annotation
.markAsNew(true);
312 * Creates an annotation without adding it to the model.
314 * @param entity a {@link java.lang.Object} object.
315 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
317 public Annotation
createAnnotation(Object entity
) {
318 LineAnnotation annotation
= new LineAnnotation(entity
, lineDisplayStrategy
);
319 annotation
.markAsNew(true);
324 * @see org.eclipse.jface.text.source.AnnotationModel#addAnnotation(org.eclipse.jface.text.source.Annotation, org.eclipse.jface.text.Position)
328 public void addAnnotation(Annotation annotation
, Position position
) {
329 super.addAnnotation(annotation
, position
);
333 * <p>getAnnotation</p>
335 * @param entity a {@link java.lang.Object} object.
336 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
338 public Annotation
getAnnotation(Object entity
) {
339 if (entity
!= null) {
340 Iterator iterator
= getAnnotationIterator();
341 while (iterator
.hasNext()) {
342 LineAnnotation annotation
= (LineAnnotation
) iterator
.next();
343 if (entity
.equals(annotation
.getEntity())) {