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