Project

General

Profile

Download (10.4 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

    
10
package eu.etaxonomy.taxeditor.annotatedlineeditor;
11

    
12
import java.util.ArrayList;
13
import java.util.Collections;
14
import java.util.Comparator;
15
import java.util.HashSet;
16
import java.util.Iterator;
17
import java.util.List;
18
import java.util.Set;
19

    
20
import org.apache.log4j.Logger;
21
import org.eclipse.jface.text.BadLocationException;
22
import org.eclipse.jface.text.IDocument;
23
import org.eclipse.jface.text.Position;
24
import org.eclipse.jface.text.source.Annotation;
25
import org.eclipse.jface.text.source.AnnotationModel;
26
import org.eclipse.jface.text.source.AnnotationModelEvent;
27

    
28
import eu.etaxonomy.taxeditor.model.MessagingUtils;
29

    
30
/**
31
 * An <code>AnnotationModel</code> which holds <code>LineAnnotation</code>'s.
32
 * <p>
33
 * Major difference with <code>AnnotationModel</code> is that <code>removeAnnotation(Annotation annotation,
34
 * boolean fireModelChanged)</code> adds annotations marked for removal to a collection for further
35
 * processing, i.e. when the document is saved. This collection is accessed via <code>getDeletedAnnotations()</code>
36
 * and <code>clearDeletedAnnotations()</code>.
37
 *
38
 * @author p.ciardelli
39
 * @created 25.06.2009
40
 * @version 1.0
41
 */
42
public class LineAnnotationModel extends AnnotationModel {
43

    
44
	private Comparator<Annotation> comparator;
45
	private IEntityCreator<?> entityCreator;
46
	private Set<LineAnnotation> deletedAnnotations = new HashSet<LineAnnotation>();
47

    
48
	private ILineDisplayStrategy lineDisplayStrategy;
49

    
50
	/**
51
	 * <p>Constructor for LineAnnotationModel.</p>
52
	 *
53
	 * @param lineDisplayStrategy a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.ILineDisplayStrategy} object.
54
	 */
55
	public LineAnnotationModel(ILineDisplayStrategy lineDisplayStrategy) {
56
		super();
57
		this.lineDisplayStrategy = lineDisplayStrategy;
58
	}
59

    
60
	/**
61
	 * Changes the annotation's type and fires model changed
62
	 * notification. Resulting redraw will cause any change
63
	 * in annotation's decoration to be displayed.
64
	 *
65
	 * @param annotation a {@link org.eclipse.jface.text.source.Annotation} object.
66
	 * @param type a {@link java.lang.String} object.
67
	 */
68
	public void changeAnnotationType(Annotation annotation, String type) {
69
		annotation.setType(type);
70
		fireModelChanged(new AnnotationModelEvent(this));
71
	}
72

    
73
	/* (non-Javadoc)
74
	 * @see org.eclipse.jface.text.source.AnnotationModel#removeAnnotation(org.eclipse.jface.text.source.Annotation, boolean)
75
	 */
76
	/** {@inheritDoc} */
77
	@Override
78
    protected void removeAnnotation(Annotation annotation,
79
			boolean fireModelChanged) {
80
		if (annotation instanceof LineAnnotation) {
81
			deletedAnnotations.add((LineAnnotation) annotation);
82
		}
83
		super.removeAnnotation(annotation, fireModelChanged);
84
	}
85

    
86
	/**
87
	 * <p>removeTypeFromAllAnnotations</p>
88
	 *
89
	 * @param type a {@link java.lang.String} object.
90
	 */
91
	public void removeTypeFromAllAnnotations(String type) {
92
		Iterator<?> iterator = getAnnotationIterator();
93
		while (iterator.hasNext()) {
94
			Annotation annotation = ((Annotation) iterator.next());
95
			if (annotation.getType().equals(type)) {
96
				annotation.setType(Annotation.TYPE_UNKNOWN);
97
			}
98
		}
99
	}
100

    
101
	/**
102
	 * <p>getAllAnnotationsOfType</p>
103
	 *
104
	 * @param type a {@link java.lang.String} object.
105
	 * @return a {@link java.util.Set} object.
106
	 */
107
	public Set<LineAnnotation> getAllAnnotationsOfType(String type) {
108
		Set<LineAnnotation> candidates = new HashSet<LineAnnotation>();
109
		Iterator<?> iterator = getAnnotationIterator();
110
		while (iterator.hasNext()) {
111
			LineAnnotation annotation = ((LineAnnotation) iterator.next());
112
			if (annotation.getType().equals(type)) {
113
				candidates.add(annotation);
114
			}
115
		}
116
		return candidates;
117
	}
118

    
119
	/**
120
	 * <p>getFirstAnnotationOfType</p>
121
	 *
122
	 * @param type a {@link java.lang.String} object.
123
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
124
	 */
125
	public Annotation getFirstAnnotationOfType(String type) {
126
		Iterator<?> iterator = getAnnotationIterator();
127
		while (iterator.hasNext()) {
128
			Annotation annotation = ((Annotation) iterator.next());
129
			if (annotation.getType().equals(type)) {
130
				return annotation;
131
			}
132
		}
133
		return null;
134
	}
135

    
136
	/**
137
	 * Gets first LineAnnotation in line
138
	 *
139
	 * @param line a int.
140
	 * @param document a {@link org.eclipse.jface.text.IDocument} object.
141
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
142
	 */
143
	public Annotation getAnnotationAtLine(int line, IDocument document) {
144
//		Annotation annotation = null;
145
		try {
146
			int offset = document.getLineOffset(line);
147
			int length = document.getLineLength(line);
148

    
149
			Iterator<?> iterator = getAnnotationIterator(offset, length, true, true);
150
			while (iterator.hasNext()) {
151
				Object next = iterator.next();
152
				if (next instanceof LineAnnotation) {
153
					return (LineAnnotation) next;
154
				}
155
//				annotation = (Annotation) iterator.next();
156
			}
157
		} catch (BadLocationException e) {
158
			// do nothing
159
		}
160
		return null;
161
	}
162

    
163
	/**
164
	 * <p>getOrderedAnnotations</p>
165
	 *
166
	 * @return a {@link java.util.List} object.
167
	 */
168
	public List<Annotation> getOrderedAnnotations() {
169
		List<Annotation> list = new ArrayList<Annotation>();
170
		Iterator<?> iterator = getAnnotationIterator();
171
		while (iterator.hasNext()) {
172
			list.add((Annotation) iterator.next());
173
		}
174
		Collections.sort(list, getAnnotationComparator());
175
		return list;
176
	}
177

    
178
	/**
179
	 * <p>printAnnotations</p>
180
	 */
181
	public void printAnnotations() {
182
		Logger logger = MessagingUtils.getLog4JLogger(getClass());
183
		logger.debug("------------------------");
184
		logger.debug("Active annotations");
185
		logger.debug("------------------------");
186
		List<Annotation> list = getOrderedAnnotations();
187

    
188
		for (Annotation annotation : list) {
189
			logger.debug(
190
					(annotation.isMarkedDeleted() ?  "DELETED " : "") +
191
					(((LineAnnotation) annotation).isMarkedAsMerged() ?  "MERGED " : "") +
192
					(((LineAnnotation) annotation).isDirty() ?  "DIRTY " : "") +
193
					(((LineAnnotation) annotation).isMarkedAsNew() ?  "NEW " : "") +
194
					annotation.getText() + ": o " +
195
					getPosition(annotation).getOffset() + ", l " +
196
					getPosition(annotation).getLength());
197
		}
198
		logger.debug("------------------------");
199
		logger.debug("Deleted annotations");
200
		logger.debug("------------------------");
201
		for (LineAnnotation annotation : deletedAnnotations) {
202
			logger.debug(
203
					(annotation.isMarkedDeleted() ?  "DELETED " : "") +
204
					(annotation.isMarkedAsMerged() ?  "MERGED " : "") +
205
					(annotation.isDirty() ?  "DIRTY " : "") +
206
					(annotation.isMarkedAsNew() ?  "NEW " : "") +
207
					annotation.getText() + ": o ");
208
		}
209
	}
210

    
211
	/**
212
	 * <p>getUndeletedAnnotations</p>
213
	 *
214
	 * @param offset a int.
215
	 * @param length a int.
216
	 * @return a {@link java.util.List} object.
217
	 */
218
	public List<LineAnnotation> getUndeletedAnnotations(int offset, int length) {
219

    
220
		List<LineAnnotation> list = new ArrayList<LineAnnotation>();
221

    
222
		Iterator<?> iterator = getAnnotationIterator(offset, length, true, true);
223
		while (iterator.hasNext()) {
224
			Object next = iterator.next();
225
			if (next instanceof LineAnnotation && !((Annotation) next).isMarkedDeleted()) {
226
				list.add((LineAnnotation) next);
227
			}
228
		}
229
		Collections.sort(list, getAnnotationComparator());
230
		return list;
231
	}
232

    
233
	/**
234
	 * <p>Getter for the field <code>deletedAnnotations</code>.</p>
235
	 *
236
	 * @return a {@link java.util.Set} object.
237
	 */
238
	public Set<LineAnnotation> getDeletedAnnotations() {
239
		return deletedAnnotations;
240
	}
241

    
242
	/**
243
	 * <p>clearDeletedAnnotations</p>
244
	 */
245
	public void clearDeletedAnnotations() {
246
		deletedAnnotations.clear();
247
	}
248

    
249
	private Comparator<Annotation> getAnnotationComparator() {
250
		if (comparator == null) {
251
			this.comparator = new AnnotationComparator();
252
		}
253
		return comparator;
254
	}
255

    
256
	class AnnotationComparator implements Comparator<Annotation> {
257

    
258
		/* (non-Javadoc)
259
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
260
		 */
261
		@Override
262
        public int compare(Annotation annotation1, Annotation annotation2) {
263
			if (annotation1.isMarkedDeleted() && !annotation2.isMarkedDeleted()) {
264
				return 1;
265
			}
266
			if (!annotation1.isMarkedDeleted() && annotation2.isMarkedDeleted()) {
267
				return -1;
268
			}
269
			int offset1 = LineAnnotationModel.this.
270
								getPosition(annotation1).getOffset();
271
			int offset2 = LineAnnotationModel.this.
272
								getPosition(annotation2).getOffset();
273
			if (offset1 > offset2) {
274
				return 1;
275
			} else if (offset1 < offset2) {
276
				return -1;
277
			} else {
278
				return 0;
279
			}
280
		}
281
	}
282

    
283
	/**
284
	 * The annotation model is assigned responsibility for creating new containers
285
	 * from blocks of text.
286
	 *
287
	 * @param entityCreator a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator} object.
288
	 */
289
	public void setEntityCreator(IEntityCreator<?> entityCreator) {
290
		this.entityCreator = entityCreator;
291
	}
292

    
293
	/**
294
	 * Creates an annotation without adding it to the model.
295
	 *
296
	 * This object must have its <code>cdmEntityCreator</code> set.
297
	 *
298
	 * @param text a {@link java.lang.String} object.
299
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
300
	 */
301
	public Annotation createAnnotation(String text) {
302
		LineAnnotation annotation = null;
303
		if (entityCreator != null) {
304
			annotation = new LineAnnotation(entityCreator.createEntity(text), lineDisplayStrategy);
305
			annotation.markAsNew(true);
306
		}
307
		return annotation;
308
	}
309

    
310
	/**
311
	 * Creates an annotation without adding it to the model.
312
	 *
313
	 * @param entity a {@link java.lang.Object} object.
314
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
315
	 */
316
	public Annotation createAnnotation(Object entity) {
317
		LineAnnotation annotation = new LineAnnotation(entity, lineDisplayStrategy);
318
		annotation.markAsNew(true);
319
		return annotation;
320
	}
321

    
322
	/* (non-Javadoc)
323
	 * @see org.eclipse.jface.text.source.AnnotationModel#addAnnotation(org.eclipse.jface.text.source.Annotation, org.eclipse.jface.text.Position)
324
	 */
325
	/** {@inheritDoc} */
326
	@Override
327
	public void addAnnotation(Annotation annotation, Position position) {
328
		super.addAnnotation(annotation, position);
329
	}
330

    
331
	/**
332
	 * <p>getAnnotation</p>
333
	 *
334
	 * @param entity a {@link java.lang.Object} object.
335
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
336
	 */
337
	public Annotation getAnnotation(Object entity) {
338
		if (entity != null) {
339
			Iterator iterator = getAnnotationIterator();
340
			while (iterator.hasNext()) {
341
				LineAnnotation annotation = (LineAnnotation) iterator.next();
342
				if (entity.equals(annotation.getEntity())) {
343
					return annotation;
344
				}
345
			}
346
		}
347
		return null;
348
	}
349
}
(13-13/16)