Project

General

Profile

Download (10.6 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
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.
9
*/
10

    
11
package eu.etaxonomy.taxeditor.annotatedlineeditor;
12

    
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;
19
import java.util.Set;
20

    
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;
28

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

    
31
/**
32
 * An <code>AnnotationModel</code> which holds <code>LineAnnotation</code>'s.
33
 * <p>
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>.
38
 *
39
 * @author p.ciardelli
40
 * @created 25.06.2009
41
 * @version 1.0
42
 */
43
public class LineAnnotationModel extends AnnotationModel {
44
	
45
	private Comparator<Annotation> comparator;
46
	private IEntityCreator<?> entityCreator;
47
	private Set<LineAnnotation> deletedAnnotations = new HashSet<LineAnnotation>();
48

    
49
	private ILineDisplayStrategy lineDisplayStrategy;
50
	
51
	/**
52
	 * <p>Constructor for LineAnnotationModel.</p>
53
	 *
54
	 * @param lineDisplayStrategy a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.ILineDisplayStrategy} object.
55
	 */
56
	public LineAnnotationModel(ILineDisplayStrategy lineDisplayStrategy) {
57
		super();
58
		this.lineDisplayStrategy = lineDisplayStrategy;
59
	}
60
	
61
	/**
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.
65
	 *
66
	 * @param annotation a {@link org.eclipse.jface.text.source.Annotation} object.
67
	 * @param type a {@link java.lang.String} object.
68
	 */
69
	public void changeAnnotationType(Annotation annotation, String type) {
70
		annotation.setType(type);
71
		fireModelChanged(new AnnotationModelEvent(this));
72
	}
73
	
74
	/* (non-Javadoc)
75
	 * @see org.eclipse.jface.text.source.AnnotationModel#removeAnnotation(org.eclipse.jface.text.source.Annotation, boolean)
76
	 */
77
	/** {@inheritDoc} */
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);
84
		}
85
		super.removeAnnotation(annotation, fireModelChanged);
86
	}
87
		
88
	/**
89
	 * <p>removeTypeFromAllAnnotations</p>
90
	 *
91
	 * @param type a {@link java.lang.String} object.
92
	 */
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);
99
			}
100
		}
101
	}
102
	
103
	/**
104
	 * <p>getAllAnnotationsOfType</p>
105
	 *
106
	 * @param type a {@link java.lang.String} object.
107
	 * @return a {@link java.util.Set} object.
108
	 */
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);
116
			}
117
		}	
118
		return candidates;	
119
	}	
120
	
121
	/**
122
	 * <p>getFirstAnnotationOfType</p>
123
	 *
124
	 * @param type a {@link java.lang.String} object.
125
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
126
	 */
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)) {
132
				return annotation;
133
			}
134
		}		
135
		return null;
136
	}
137
	
138
	/**
139
	 * Gets first LineAnnotation in line
140
	 *
141
	 * @param line a int.
142
	 * @param document a {@link org.eclipse.jface.text.IDocument} object.
143
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
144
	 */
145
	public Annotation getAnnotationAtLine(int line, IDocument document) {
146
//		Annotation annotation = null;
147
		try {
148
			int offset = document.getLineOffset(line);
149
			int length = document.getLineLength(line);
150
						
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;
156
				}
157
//				annotation = (Annotation) iterator.next();
158
			}
159
		} catch (BadLocationException e) {
160
			// do nothing
161
		}
162
		return null;
163
	}
164
		
165
	/**
166
	 * <p>getOrderedAnnotations</p>
167
	 *
168
	 * @return a {@link java.util.List} object.
169
	 */
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());
175
		}
176
		Collections.sort(list, getAnnotationComparator());
177
		return list;
178
	}
179
		
180
	/**
181
	 * <p>printAnnotations</p>
182
	 */
183
	public void printAnnotations() {
184
		Logger logger = MessagingUtils.getLog4JLogger(getClass());
185
		logger.debug("------------------------");
186
		logger.debug("Active annotations");
187
		logger.debug("------------------------");
188
		List<Annotation> list = getOrderedAnnotations();
189
		
190
		for (Annotation annotation : list) {
191
			logger.debug(
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());
199
		}
200
		logger.debug("------------------------");
201
		logger.debug("Deleted annotations");
202
		logger.debug("------------------------");
203
		for (LineAnnotation annotation : deletedAnnotations) {
204
			logger.debug(
205
					(annotation.isMarkedDeleted() ?  "DELETED " : "") +
206
					(((LineAnnotation) annotation).isMarkedAsMerged() ?  "MERGED " : "") +
207
					(((LineAnnotation) annotation).isDirty() ?  "DIRTY " : "") +
208
					(((LineAnnotation) annotation).isMarkedAsNew() ?  "NEW " : "") +
209
					annotation.getText() + ": o ");			
210
		}
211
	}
212
	
213
	/**
214
	 * <p>getUndeletedAnnotations</p>
215
	 *
216
	 * @param offset a int.
217
	 * @param length a int.
218
	 * @return a {@link java.util.List} object.
219
	 */
220
	public List<LineAnnotation> getUndeletedAnnotations(int offset, int length) {
221
		
222
		List<LineAnnotation> list = new ArrayList<LineAnnotation>();
223
		
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); 
229
			}
230
		}
231
		Collections.sort(list, getAnnotationComparator());
232
		return list;
233
	}
234
	
235
	/**
236
	 * <p>Getter for the field <code>deletedAnnotations</code>.</p>
237
	 *
238
	 * @return a {@link java.util.Set} object.
239
	 */
240
	public Set<LineAnnotation> getDeletedAnnotations() {
241
		return deletedAnnotations;
242
	}
243
	
244
	/**
245
	 * <p>clearDeletedAnnotations</p>
246
	 */
247
	public void clearDeletedAnnotations() {
248
		deletedAnnotations.clear();
249
	}
250
	
251
	private Comparator<Annotation> getAnnotationComparator() {
252
		if (comparator == null) {
253
			this.comparator = new AnnotationComparator();
254
		}
255
		return comparator;
256
	}
257
	
258
	class AnnotationComparator implements Comparator<Annotation> {
259

    
260
		/* (non-Javadoc)
261
		 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
262
		 */
263
		public int compare(Annotation annotation1, Annotation annotation2) {
264
			if (annotation1.isMarkedDeleted() && !annotation2.isMarkedDeleted()) {
265
				return 1;
266
			}
267
			if (!annotation1.isMarkedDeleted() && annotation2.isMarkedDeleted()) {
268
				return -1;
269
			}
270
			int offset1 = LineAnnotationModel.this.
271
								getPosition(annotation1).getOffset();
272
			int offset2 = LineAnnotationModel.this.
273
								getPosition(annotation2).getOffset();
274
			if (offset1 > offset2) {
275
				return 1;
276
			} else if (offset1 < offset2) {
277
				return -1;
278
			} else {
279
				return 0;
280
			}
281
		}	
282
	}
283
	
284
	/**
285
	 * The annotation model is assigned responsibility for creating new containers
286
	 * from blocks of text.
287
	 *
288
	 * @param entityCreator a {@link eu.etaxonomy.taxeditor.annotatedlineeditor.IEntityCreator} object.
289
	 */
290
	public void setEntityCreator(IEntityCreator<?> entityCreator) {
291
		this.entityCreator = entityCreator;
292
	}
293
	
294
	/**
295
	 * Creates an annotation without adding it to the model.
296
	 *
297
	 * This object must have its <code>cdmEntityCreator</code> set.
298
	 *
299
	 * @param text a {@link java.lang.String} object.
300
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
301
	 */
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);
307
		}
308
		return annotation;
309
	}
310

    
311
	/**
312
	 * Creates an annotation without adding it to the model.
313
	 *
314
	 * @param entity a {@link java.lang.Object} object.
315
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
316
	 */
317
	public Annotation createAnnotation(Object entity) {
318
		LineAnnotation annotation = new LineAnnotation(entity, lineDisplayStrategy);
319
		annotation.markAsNew(true);
320
		return annotation;
321
	}
322
	
323
	/* (non-Javadoc)
324
	 * @see org.eclipse.jface.text.source.AnnotationModel#addAnnotation(org.eclipse.jface.text.source.Annotation, org.eclipse.jface.text.Position)
325
	 */
326
	/** {@inheritDoc} */
327
	@Override
328
	public void addAnnotation(Annotation annotation, Position position) {
329
		super.addAnnotation(annotation, position);
330
	}
331
	
332
	/**
333
	 * <p>getAnnotation</p>
334
	 *
335
	 * @param entity a {@link java.lang.Object} object.
336
	 * @return a {@link org.eclipse.jface.text.source.Annotation} object.
337
	 */
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())) {
344
					return annotation;
345
				}
346
			}
347
		}
348
		return null;
349
	}
350
}
(13-13/16)