1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.annotation

File Annotation.java

 

Coverage histogram

../../../img/srcFileCovDistChart8.png
56% of files have more coverage

Code metrics

18
41
23
1
341
147
34
0.83
1.78
23
1.48

Classes

Class Line # Actions
Annotation 37 41 0% 34 23
0.719512272%
 

Contributing tests

This file is covered by 173 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20   
21    package org.xwiki.annotation;
22   
23    import java.util.Date;
24    import java.util.HashMap;
25    import java.util.Map;
26    import java.util.Set;
27   
28    import org.apache.commons.lang3.StringUtils;
29    import org.xwiki.annotation.maintainer.AnnotationState;
30   
31    /**
32    * This class wraps together the data needed to describe an annotation.
33    *
34    * @version $Id: b56e10436000e339cb7a24b13af3dbcd1d2c9cdd $
35    * @since 2.3M1
36    */
 
37    public class Annotation
38    {
39    /**
40    * The name of the field of this annotation selection. <br>
41    * The text on which this annotation is added.
42    */
43    public static final String SELECTION_FIELD = "selection";
44   
45    /**
46    * The name of the field of this annotation selection context to the left of the annotation. <br>
47    * The context of the selection is used to uniquely localize an annotation on the content where is added. Or, if the
48    * context appears twice, semantically speaking it shouldn't make any difference if the annotation is displayed and
49    * handled in one or other of the occurrences.
50    */
51    public static final String SELECTION_LEFT_CONTEXT_FIELD = "selectionLeftContext";
52   
53    /**
54    * The name of the field of this annotation selection context to the right of the annotation. <br>
55    * The context of the selection is used to uniquely localize an annotation on the content where is added. Or, if the
56    * context appears twice, semantically speaking it shouldn't make any difference if the annotation is displayed and
57    * handled in one or other of the occurrences.
58    */
59    public static final String SELECTION_RIGHT_CONTEXT_FIELD = "selectionRightContext";
60   
61    /**
62    * The name of the field of this annotation state. <br>
63    * TODO: find out if it's the right place to put the state information, as it's a maintainer particular information.
64    */
65    public static final String STATE_FIELD = "state";
66   
67    /**
68    * The name of the field of this annotation original selection.
69    */
70    public static final String ORIGINAL_SELECTION_FIELD = "originalSelection";
71   
72    /**
73    * The name of the field of this annotation author.
74    */
75    public static final String AUTHOR_FIELD = "author";
76   
77    /**
78    * The name of the field of this annotation serialized date.
79    */
80    public static final String DATE_FIELD = "date";
81   
82    /**
83    * The name of the field of this annotation's reference to the target content.
84    */
85    public static final String TARGET_FIELD = "target";
86   
87    /**
88    * The unique identifier of this annotation, which should be unique among all the annotations on the same target.
89    */
90    protected final String id;
91   
92    /**
93    * The values of the fields of this annotation.
94    */
95    protected Map<String, Object> fields = new HashMap<String, Object>();
96   
97    /**
98    * Builds an annotation description for the annotation with the passed id: used for annotation updates where only a
99    * part of the fields my need to be set.
100    *
101    * @param id the id of this annotation
102    */
 
103  306 toggle public Annotation(String id)
104    {
105  306 this.id = id;
106    }
107   
108    /**
109    * Builds an annotation for the passed selection in the context, used to pass an annotation to be added (which does
110    * not have an id yet since it hasn't been stored yet).
111    *
112    * @param initialSelection the selected text of this annotation
113    * @param leftContext the context to the left of the selection, which makes the selection uniquely identifiable in
114    * the content on which this annotation is added. Can be void if selection itself is unique
115    * @param rightContext the context to the right of the selection, which makes the selection uniquely identifiable in
116    * the content on which this annotation is added. Can be void if selection itself is unique
117    */
 
118  4 toggle public Annotation(String initialSelection, String leftContext, String rightContext)
119    {
120  4 this(null);
121  4 setSelection(initialSelection, leftContext, rightContext);
122    // also initialize the state of this annotation to safe
123  4 setState(AnnotationState.SAFE);
124    }
125   
126    /**
127    * @return author of annotation.
128    */
 
129  68 toggle public String getAuthor()
130    {
131  68 return (String) fields.get(AUTHOR_FIELD);
132    }
133   
134    /**
135    * Sets the author of this annotation.
136    *
137    * @param author the author of this annotation.
138    */
 
139  246 toggle public void setAuthor(String author)
140    {
141  246 fields.put(AUTHOR_FIELD, author);
142    }
143   
144    /**
145    * @return date of annotation
146    */
 
147  16 toggle public Date getDate()
148    {
149  16 return (Date) fields.get(DATE_FIELD);
150    }
151   
152    /**
153    * @param date the serialized date to set
154    */
 
155  0 toggle public void setDate(Date date)
156    {
157  0 fields.put(DATE_FIELD, date);
158    }
159   
160    /**
161    * @return state of annotation
162    */
 
163  377 toggle public AnnotationState getState()
164    {
165    // have a little bit of mercy, try to parse this from string if it's a string
166  377 Object stateField = fields.get(STATE_FIELD);
167  377 if (stateField == null) {
168    // null stays null no matter what
169  0 return null;
170    }
171  377 if (AnnotationState.class.isAssignableFrom(stateField.getClass())) {
172  377 return (AnnotationState) stateField;
173  0 } else if (String.class.isAssignableFrom(stateField.getClass())) {
174  0 try {
175  0 return AnnotationState.valueOf((String) stateField);
176    } catch (IllegalArgumentException e) {
177  0 return null;
178    }
179    }
180   
181    // return no state, can't actually make sense of the value in the map. Hopefully this will never happen
182  0 return null;
183    }
184   
185    /**
186    * @param state to set
187    */
 
188  346 toggle public void setState(AnnotationState state)
189    {
190  346 fields.put(STATE_FIELD, state);
191    }
192   
193    /**
194    * @return selected text of this annotation
195    */
 
196  742 toggle public String getSelection()
197    {
198  742 return (String) fields.get(SELECTION_FIELD);
199    }
200   
201    /**
202    * Helper method to get the selection of this annotation in its context, with the context left to the left and
203    * context right to the right. This method ensures that a non-null value will be returned, even if some of the
204    * components of the selection are missing.
205    *
206    * @return the selection of this annotation in its context, with the context left to the left and context right to
207    * the right
208    */
 
209  132 toggle public String getSelectionInContext()
210    {
211  132 return (StringUtils.isEmpty(getSelectionLeftContext()) ? "" : getSelectionLeftContext())
212  132 + (StringUtils.isEmpty(getSelection()) ? "" : getSelection())
213  132 + (StringUtils.isEmpty(getSelectionRightContext()) ? "" : getSelectionRightContext());
214    }
215   
216    /**
217    * Sets the selection of this annotation and the context along with it.
218    *
219    * @param selection the selection of this annotation
220    * @param contextLeft the context to the left of the annotation
221    * @param contextRight the context to the right of the annotation
222    */
 
223  299 toggle public void setSelection(String selection, String contextLeft, String contextRight)
224    {
225  299 fields.put(SELECTION_FIELD, selection);
226  299 fields.put(SELECTION_LEFT_CONTEXT_FIELD, contextLeft);
227  299 fields.put(SELECTION_RIGHT_CONTEXT_FIELD, contextRight);
228    }
229   
230    /**
231    * Sets the selection of this annotation.
232    *
233    * @param selection the selection of the annotation
234    */
 
235  0 toggle public void setSelection(String selection)
236    {
237  0 setSelection(selection, "", "");
238    }
239   
240    /**
241    * @return selection context to the left of annotation
242    */
 
243  448 toggle public String getSelectionLeftContext()
244    {
245  448 return (String) fields.get(SELECTION_LEFT_CONTEXT_FIELD);
246    }
247   
248    /**
249    * @return selection context to the right of annotation
250    */
 
251  446 toggle public String getSelectionRightContext()
252    {
253  446 return (String) fields.get(SELECTION_RIGHT_CONTEXT_FIELD);
254    }
255   
256    /**
257    * @return id of annotation
258    */
 
259  1063 toggle public String getId()
260    {
261  1063 return id;
262    }
263   
 
264  8 toggle @Override
265    public String toString()
266    {
267  8 return "id: " + getId() + " | author: " + getAuthor() + " | selection left context: "
268    + getSelectionLeftContext() + " | selection: " + getSelection() + " | selection right context: "
269    + getSelectionRightContext();
270    }
271   
 
272  215 toggle @Override
273    public boolean equals(Object obj)
274    {
275  215 if (!(obj instanceof Annotation)) {
276  0 return false;
277    }
278  215 Annotation other = (Annotation) obj;
279  215 if (other.getId() != null || getId() != null) {
280    // if they have ids, compare ids
281  215 return ("" + getId()).equals(other.getId());
282    } else {
283    // else compare selection and selection context
284  0 return ("" + getSelection()).equals(other.getSelection())
285    && ("" + getSelectionLeftContext()).equals(other.getSelectionLeftContext())
286    && ("" + getSelectionRightContext()).equals(other.getSelectionRightContext());
287    }
288    }
289   
 
290  0 toggle @Override
291    public int hashCode()
292    {
293  0 return (getId() != null ? getId() : getSelectionLeftContext() + getSelection() + getSelectionRightContext())
294    .hashCode();
295    }
296   
297    /**
298    * @return the originalSelection
299    */
 
300  98 toggle public String getOriginalSelection()
301    {
302  98 return (String) fields.get(ORIGINAL_SELECTION_FIELD);
303    }
304   
305    /**
306    * @param originalSelection the originalSelection to set
307    */
 
308  56 toggle public void setOriginalSelection(String originalSelection)
309    {
310  56 fields.put(ORIGINAL_SELECTION_FIELD, originalSelection);
311    }
312   
313    /**
314    * @param key the key of the field to get
315    * @return the value of the field
316    */
 
317  36 toggle public Object get(String key)
318    {
319  36 return fields.get(key);
320    }
321   
322    /**
323    * Sets / adds a value in the fields of this annotation.
324    *
325    * @param key the key of the field
326    * @param value the value to set for the field
327    * @return the old value of this field, or null if none was set
328    */
 
329  790 toggle public Object set(String key, Object value)
330    {
331  790 return fields.put(key, value);
332    }
333   
334    /**
335    * @return a set of names of the fields set in this annotation object
336    */
 
337  4 toggle public Set<String> getFieldNames()
338    {
339  4 return fields.keySet();
340    }
341    }