4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
Fragment.java
Go to the documentation of this file.
1 /*
2  * Project: Server for annotations sharing
3  * Author: Ing. Jaroslav Dytrych idytrych@fit.vutbr.cz
4  * File: Fragment.java
5  * Description: Class representing annotated fragment
6  */
7 
8 /**
9  * @file Fragment.java
10  *
11  * @brief Class representing annotated fragment
12  */
13 
14 package cz.vutbr.fit.knot.annotations.entity;
15 
18 import java.io.Serializable;
19 import javax.persistence.Basic;
20 import javax.persistence.Column;
21 import javax.persistence.Entity;
22 import javax.persistence.GeneratedValue;
23 import javax.persistence.GenerationType;
24 import javax.persistence.Id;
25 import javax.persistence.JoinColumn;
26 import javax.persistence.Lob;
27 import javax.persistence.ManyToOne;
28 import javax.persistence.NamedQueries;
29 import javax.persistence.NamedQuery;
30 import javax.persistence.Table;
31 import javax.xml.xpath.XPathExpressionException;
32 
33 /**
34  * Class representing annotated fragment
35  *
36  * @brief Class representing annotated fragment
37  *
38  * @author idytrych
39  */
40 @Entity
41 @Table(name = "fragment")
42 @NamedQueries({
43  @NamedQuery(name = "Fragment.findAll", query = "SELECT f FROM Fragment f"),
44  @NamedQuery(name = "Fragment.findById", query = "SELECT f FROM Fragment f WHERE f.id = :id"),
45  @NamedQuery(name = "Fragment.findByAnnotation", query = "SELECT f FROM Fragment f WHERE f.annotation = :annotation"),
46  @NamedQuery(name = "Fragment.findByOffset", query = "SELECT f FROM Fragment f WHERE f.offset = :offset"),
47  @NamedQuery(name = "Fragment.findByLength", query = "SELECT f FROM Fragment f WHERE f.length = :length")})
48 public class Fragment implements Serializable, Comparable<Object> {
49 
50  private static final long serialVersionUID = 1L;
51  /**
52  * Id of fragment
53  */
54  @Id
55  @GeneratedValue(strategy = GenerationType.IDENTITY)
56  @Basic(optional = false)
57  @Column(name = "id")
58  private Integer id;
59  /**
60  * Id of annotation to which this fragment belongs
61  */
62  @Basic(optional = false)
63  @Column(name = "annotation", nullable = false, insertable = false, updatable = false)
64  private int annotation;
65  /**
66  * XPath of element with annotated fragment
67  */
68  @Lob
69  @Column(name = "frPath")
70  private String path;
71  /**
72  * Offset of annotated fragment in given element
73  */
74  @Column(name = "frOffset")
75  private Integer offset;
76  /**
77  * Length of annotated fragment
78  */
79  @Column(name = "frLength")
80  private Integer length;
81  /**
82  * Textual content of annotated fragment
83  */
84  @Basic(optional = false)
85  @Lob
86  @Column(name = "annotatedText")
87  private String annotatedText;
88  /**
89  * Indicator, whether fragment is good (not orphaned)
90  */
91  @Basic(optional = false)
92  @Column(name = "isGood")
93  private boolean isGood;
94  /**
95  * Annotation to which this fragment belongs
96  */
97  @ManyToOne(optional = false)
98  @JoinColumn(name = "annotation", referencedColumnName = "id")
99  private Annotation refAnnotation;
100 
101  /**
102  * Constructor
103  */
104  public Fragment() {
105  }
106 
107  /**
108  * Constructor
109  *
110  * @param id sets id of the object
111  */
112  public Fragment(Integer id) {
113  this.id = id;
114  }
115 
116 
117  /**
118  * Constructor
119  *
120  * @param path XPath of element with annotated fragment
121  * @param offset Offset of annotated fragment in given element
122  * @param length Length of annotated fragment
123  * @param annotatedText Textual content of annotated fragment
124  * @param refAnnotation Annotation to which this fragment belongs
125  */
126  public Fragment(String path, Integer offset, Integer length, String annotatedText, Annotation refAnnotation) {
127  this.path = path;
128  this.offset = offset;
129  this.length = length;
130  this.annotatedText = annotatedText;
131  this.refAnnotation = refAnnotation;
132  this.isGood = true;
133  }
134 
135  /**
136  * Constructor
137  *
138  * @param path XPath of element with annotated fragment
139  * @param offset Offset of annotated fragment in given element
140  * @param length Length of annotated fragment
141  * @param annotatedText Textual content of annotated fragment
142  * @param refAnnotation Annotation to which this fragment belongs
143  * @param isGood Indicator, whether fragment is good (not orphaned)
144  */
145  public Fragment(String path, Integer offset, Integer length, String annotatedText, Annotation refAnnotation, Boolean isGood) {
146  this.path = path;
147  this.offset = offset;
148  this.length = length;
149  this.annotatedText = annotatedText;
150  this.refAnnotation = refAnnotation;
151  this.isGood = isGood;
152  }
153 
154  /**
155  * Constructor
156  *
157  * @param path XPath of element with annotated fragment
158  * @param offset Offset of annotated fragment in given element
159  * @param length Length of annotated fragment
160  */
161  public Fragment(String path, Integer offset, Integer length) {
162  this.path = path;
163  this.offset = offset;
164  this.length = length;
165  this.isGood = true;
166  }
167 
168  /**
169  * Gets id of fragment
170  *
171  * @return Returns id of fragment
172  */
173  public Integer getId() {
174  return id;
175  }
176 
177  /**
178  * Sets id of fragment
179  *
180  * @param id Id of fragment
181  */
182  public void setId(Integer id) {
183  this.id = id;
184  }
185 
186  /**
187  * Gets annotation to which this fragment belongs
188  *
189  * @return Returns annotation to which this fragment belongs
190  */
191  public int getAnnotation() {
192  return annotation;
193  }
194 
195  /**
196  * Sets annotation to which this fragment belongs
197  *
198  * @param annotation Annotation to which this fragment belongs
199  */
200  public void setAnnotation(int annotation) {
201  this.annotation = annotation;
202  }
203 
204  /**
205  * Gets XPath of element with this annotated fragment
206  *
207  * @return Returns XPath of element with this annotated fragment
208  */
209  public String getPath() {
210  return path;
211  }
212 
213  /**
214  * Sets XPath of element with this annotated fragment
215  *
216  * @param path XPath of element with this annotated fragment
217  */
218  public void setPath(String path) {
219  this.path = path;
220  }
221 
222  /**
223  * Gets offset of annotated fragment in given element
224  *
225  * @return Returns offset of annotated fragment in given element
226  */
227  public Integer getOffset() {
228  return offset;
229  }
230 
231  /**
232  * Sets offset of annotated fragment in given element
233  *
234  * @param offset Offset of annotated fragment in given element
235  */
236  public void setOffset(Integer offset) {
237  this.offset = offset;
238  }
239 
240  /**
241  * Gets length of annotated fragment
242  *
243  * @return Returns length of annotated fragment
244  */
245  public Integer getLength() {
246  return length;
247  }
248 
249  /**
250  * Sets length of annotated fragment
251  *
252  * @param length Length of annotated fragment
253  */
254  public void setLength(Integer length) {
255  this.length = length;
256  }
257 
258  /**
259  * Gets textual content of annotated fragment
260  *
261  * @return Returns textual content of annotated fragment
262  */
263  public String getAnnotatedText() {
264  return annotatedText;
265  }
266 
267  /**
268  * Sets textual content of annotated fragment
269  *
270  * @param annotatedText Textual content of annotated fragment
271  */
272  public void setAnnotatedText(String annotatedText) {
273  this.annotatedText = annotatedText;
274  }
275 
276  /**
277  * Gets annotation to which this fragment belongs
278  *
279  * @return Returns annotation to which this fragment belongs
280  */
282  return refAnnotation;
283  }
284 
285  /**
286  * Sets annotation to which this fragment belongs
287  *
288  * @param refAnnotation Annotation to which this fragment belongs
289  */
290  public void setRefAnnotation(Annotation refAnnotation) {
291  this.refAnnotation = refAnnotation;
292  }
293 
294  /**
295  * Get information about fragment status (whether fragment is good or
296  * orphaned))
297  *
298  * @return If fragment is good, returns true, if it's orphaned, returns false
299  */
300  public boolean getIsGood() {
301  return isGood;
302  }
303 
304  /**
305  * Sets fragment status
306  *
307  * @param isGood If fragment is good then true, if it's orphaned then false
308  */
309  public void setIsGood(boolean isGood) {
310  this.isGood = isGood;
311  }
312 
313  @Override
314  public int hashCode() {
315  int hash = 0;
316  hash += (id != null ? id.hashCode() : 0);
317  hash += (offset != null ? offset.hashCode() : 0);
318  hash += (length != null ? length.hashCode() : 0);
319  hash += (annotatedText != null ? annotatedText.hashCode() : 0);
320  return hash;
321  }
322 
323  /**
324  * Compares this with other object and returns, whether objects are same type
325  * and have same content (id is irrelevant).
326  *
327  * @param object Object to compare with
328  * @return If object is same type and have same id, returns true, false
329  * otherwise
330  */
331  @Override
332  public boolean equals(Object object) {
333  if (!(object instanceof Fragment)) {
334  return false;
335  }
336  Fragment other = (Fragment) object;
337 
338  if (this.path != other.path && (this.path == null || !this.path.equals(other.path))) {
339  return false;
340  }
341  if (this.offset != other.offset && (this.offset == null || !this.offset.equals(other.offset))) {
342  return false;
343  }
344  if (this.length != other.length && (this.length == null || !this.length.equals(other.length))) {
345  return false;
346  }
347  if ((this.annotatedText == null) ? (other.annotatedText != null) : !this.annotatedText.equals(other.annotatedText)) {
348  return false;
349  }
350 
351  return true;
352  }
353 
354  /**
355  * Compares this with other object and returns, whether objects are same type
356  * and have same content (id is irrelevant).
357  *
358  * @param obj Object to compare with
359  * @return If object is same type and have same content, returns true, false
360  * otherwise
361  */
362  public boolean contentEquals(Object obj) {
363  if (obj == null) {
364  return false;
365  }
366  if (getClass() != obj.getClass()) {
367  return false;
368  }
369  final Fragment other = (Fragment) obj;
370  if ((this.path == null) ? (other.path != null) : !this.path.equals(other.path)) {
371  if ((this.path == null) ? (other.path != null) : !this.path.equals(other.path.concat("/text()"))) {
372  return false;
373  }
374  }
375  if (this.offset != other.offset && (this.offset == null || !this.offset.equals(other.offset))) {
376  return false;
377  }
378  if (this.length != other.length && (this.length == null || !this.length.equals(other.length))) {
379  return false;
380  }
381  if ((this.annotatedText == null) ? (other.annotatedText != null) : !this.annotatedText.equals(other.annotatedText)) {
382  return false;
383  }
384  return true;
385  } // contentEquals()
386 
387  /**
388  * Compares this with instance of UpdatableFragment and returns, whether
389  * fragments have same location (XPath, offset and length) and textual
390  * content.
391  *
392  * @param uf Instance of UpdatableFragment to compare with
393  * @return If fragments have same location and textual content, returns true,
394  * false otherwise
395  */
397  if (uf == null) {
398  return false;
399  }
400  if ((this.path == null) ? (uf.getXPathString() != null) : !this.path.equals(uf.getXPathString())) {
401  return false;
402  }
403  if (this.offset != uf.getOffset() && (this.offset == null || !this.offset.equals(uf.getOffset()))) {
404  return false;
405  }
406  if (this.length != uf.getLength() && (this.length == null || !this.length.equals(uf.getLength()))) {
407  return false;
408  }
409  if ((this.annotatedText == null) ? (uf.getText() != null) : !this.annotatedText.equals(uf.getText())) {
410  return false;
411  }
412  return true;
413  } // fragmentEqualsWUF()
414 
415  /**
416  * Creates UpdatableFragment from this fragment and returns it
417  *
418  * @return UpdatableFragment created from this fragment
419  */
420  public UpdatableFragment toUpdatableFragment() throws XPathExpressionException {
421  UpdatableFragment retUF = new UpdatableFragment(path, offset, length, annotatedText);
422  return retUF;
423  }
424 
425  /**
426  * Updates data in this fragment with data from UpdatableFragment
427  *
428  * @param uf UpdatableFragment with new (updated) data
429  */
431  if (uf.getXPathString().contains("/text()")) {
432  this.path = uf.getXPathString();
433  } else {
434  this.path = uf.getXPathString() + "/text()";
435  }
436  this.offset = uf.getOffset();
437  this.length = uf.getLength();
438  this.annotatedText = uf.getText();
439  }
440 
441  @Override
442  public String toString() {
443  return "cz.vutbr.fit.knot.annotations.entity.Fragment[id=" + id + "]";
444  }
445 
446  /**
447  * Returns serialized informations about annotated fragment in XML
448  *
449  * @return Returns serialized informations about annotated fragment in XML
450  */
451  public String toXMLString() {
452  String invalid = "";
453  if (!isGood) {
454  invalid = " valid=\"false\"";
455  }
456  return "<a:fragment" + invalid + ">"
457  + "<a:path>" + path + "</a:path>"
458  + "<a:offset>" + offset + "</a:offset>"
459  + "<a:length>" + length + "</a:length>"
460  + "<a:annotatedText>" + Util.toHTMLString(annotatedText) + "</a:annotatedText>"
461  + "</a:fragment>";
462  }
463 
464  /**
465  * Returns serialized informations about annotated fragment in XML for protocol version 2
466  *
467  * @return Returns serialized informations about annotated fragment in XML for protocol version 2
468  */
469  public String toXMLStringV2(){
470  String annotUri = this.getRefAnnotation().getSource();
471  String fragXpointer = this.getXpointerV2();
472 
473  return "<oa:SpecificResource rdf:about=\"" + annotUri + "#" + fragXpointer + "\">"
474  + "<oa:hasSelector>"
475  + "<oa:FragmentSelector rdf:about=\"" + annotUri + "#" + fragXpointer + "#selector\">"
476  + "<dcterms:conformsTo rdf:resource=\"http://tools.ietf.org/rfc/rfc3023\" />"
477  + "<rdf:value>" + fragXpointer + "</rdf:value></oa:FragmentSelector></oa:hasSelector>"
478  + "<oa:hasSource><dctypes:Text rdf:about=\"" + annotUri + "\"><dc:format>text/xml</dc:format>"
479  + "</dctypes:Text></oa:hasSource></oa:SpecificResource>";
480  }
481 
482  /**
483  * Returns Xpointer of annotated fragment
484  *
485  * @return Returns Xpointer of annotated fragment
486  */
487  public String getXpointer(){
488  return "xpointer(string-range(" + path + ",\"" + annotatedText + "\", " + offset + ", " + length + "))";
489  }
490 
491  /**
492  * Returns Xpointer of annotated fragment for protocol version 2
493  *
494  * @return Returns Xpointer of annotated fragment
495  */
496  public String getXpointerV2(){
497  String xpointer = "xpointer(string-range(" + path + ",'" + annotatedText + "', " + offset + ", " + length + "))";
498  return Util.toHTMLString(xpointer);
499  }
500 
501  /**
502  * Compares this fragment with another fragment according to offset and length
503  *
504  * @param object Fragment to compare
505  * @return Returns a negative integer, zero, or a positive integer as this
506  * object is less than, equal to, or greater than the specified object.
507  */
508  @Override
509  public int compareTo(Object object) {
510  if (!(object instanceof Fragment)) {
511  throw new UnsupportedOperationException("Not supported yet.");
512  }
513  Fragment other = (Fragment) object;
514  int compareResult = offset.compareTo(other.getOffset());
515  if (compareResult == 0) {
516  compareResult = length.compareTo(other.getLength());
517  }
518 
519  return compareResult;
520  }
521 } // class Fragment
Fragment(String path, Integer offset, Integer length)
Definition: Fragment.java:161
boolean fragmentEqualsWUF(UpdatableFragment uf)
Definition: Fragment.java:396
Fragment(String path, Integer offset, Integer length, String annotatedText, Annotation refAnnotation, Boolean isGood)
Definition: Fragment.java:145
Fragment(String path, Integer offset, Integer length, String annotatedText, Annotation refAnnotation)
Definition: Fragment.java:126
void setAnnotatedText(String annotatedText)
Definition: Fragment.java:272
void setRefAnnotation(Annotation refAnnotation)
Definition: Fragment.java:290
Utility class (manipulates RFC 3339 dates)
Definition: Util.java:29
Class representing annotated fragment.
Definition: Fragment.java:48
void updateWithUpdatableFragment(UpdatableFragment uf)
Definition: Fragment.java:430