4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
P2AnnotBaseProcessor.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: P2AnnotBaseProcessor.java
5  * Description: Abstract class provides a parser for the annotation.
6  */
7 
8 /**
9  * @file P2AnnotBaseProcessor.java
10  *
11  * @brief Abstract class provides a parser for the annotation of protocol version 2.
12  */
13 
14 package cz.vutbr.fit.knot.annotations.comet.protocolV2_0;
15 
22 import cz.vutbr.fit.knot.annotations.comet.protocolV2_0.P2Trix.*;
30 import java.util.*;
31 import java.util.logging.Level;
32 import java.util.logging.Logger;
33 import javax.xml.bind.DatatypeConverter;
34 import org.w3c.dom.Element;
35 import org.w3c.dom.Node;
36 import org.w3c.dom.NodeList;
37 
38 
39 /**
40  * Abstract class provides a parser for the annotation of protocol version 2.
41  *
42  * @brief Abstract class provides a parser for the annotation of protocol version 2.
43  * @author Martin Petr (xpetrm05)
44  */
45 public abstract class P2AnnotBaseProcessor{
46 
47  /**
48  * Method process annotation from given element.
49  *
50  * @param annotationEl element with annotation for process
51  * @param requestInfo informations about client request
52  * @return annotation or null if any error occurs
53  */
54  public Annotation processAnnotation(Element annotationEl,RequestInfo requestInfo){
55  Annotation newAnnotation = new Annotation();
56  newAnnotation.setFragments(new ArrayList<Fragment>());
57  newAnnotation.setContent("");
58 
59  // get rdf:about attribute (same as uri of annotation)
60  String annotUri = annotationEl.getAttribute("rdf:about");
61  if(annotUri == null || annotUri.isEmpty()){
62  // error - annotation without uri
63  int langNum = requestInfo.getSession().getLanguageNum();
64  int lod = requestInfo.getSession().getProtocolLOD();
65  String info = "<annotation uri=\"\" invalidProperty=\"uri\"/>";
66  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
68  String msg = "Annotation is without uri.";
69  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
70  }
71  return null;
72  }
73 
74  String annotUriPrefix = getUriType(annotUri);
75 
76  if (annotUriPrefix.equals("serv")) {
77  Integer id;
78  String idString = annotUri.replace(AppBean.getBaseUri() + "/serv/", "");
79  try {
80  id = Integer.decode(idString);
81  } catch (NumberFormatException ex) {
82  // error can't decode id
83  int langNum = requestInfo.getSession().getLanguageNum();
84  int lod = requestInfo.getSession().getProtocolLOD();
85  String info = "<annotation uri=\"" + annotUri + "\"/>";
86  requestInfo.addError(lod, langNum, Localisation.ERROR_29_CHANGED_ANNOT_NOT_FOUND, info);
88  String msg = "Can't decode annotation id. Id: " + idString;
89  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
90  }
91  return null;
92  }
93 
94  newAnnotation.setId(id);
95  } else if (annotUriPrefix.equals("temp")) {
96  String idString = annotUri.replace(AppBean.getBaseUri() + "/temp/", "");
97  newAnnotation.setTmpId(idString);
98  } else if (annotUriPrefix.equals("sugg")) {
99  String idString = annotUri.replace(AppBean.getBaseUri() + "/sugg/", "");
100  newAnnotation.setTmpId(idString);
101  } else {
102  // bad annotation uri prefix
103  int langNum = requestInfo.getSession().getLanguageNum();
104  int lod = requestInfo.getSession().getProtocolLOD();
105  String info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"uri\"/>";
106  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
108  String msg = "Bad annotation uri prefix. Prefix: " + annotUriPrefix;
109  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
110  }
111  return null;
112  }
113 
114  // get informations about autor
115  NodeList anotatedByMsg = annotationEl.getElementsByTagName("oa:annotatedBy");
116  Element anotatedByEl = (Element) anotatedByMsg.item(0);
117  if(anotatedByEl != null) {
118  // process autor of annotation
119  User author = processAuthor(anotatedByEl, annotUri, requestInfo);
120  if(author == null){
121  // process of parsing author of annotation failed
122  return null;
123  }
124  newAnnotation.setUser(author);
125  }
126 
127  // get informations about date of creation
128  NodeList annotatedAtMsg = annotationEl.getElementsByTagName("oa:annotatedAt");
129  Element annotatedAtEl = (Element) annotatedAtMsg.item(0);
130  if(annotatedAtEl != null) {
131  // informations about time and date of creation
132  Date creationDate = processCreationDate(annotatedAtEl, annotUri, requestInfo, true);
133  if(creationDate == null){
134  // process of parsing time and date of creation failed
135  return null;
136  }
137 
138  newAnnotation.setCreated(creationDate);
139  }
140 
141  /*
142  * Gets informations about serialization
143  *
144  * Note: As server serialize annotation imediatelly after it has been processed, the same date
145  * as date of creation is automatically used for serialization.
146  * This is just confirmation, that client sent correct format of serialization date
147  * If there is an error, client is informed about bad format of date and annotation is malformed
148  */
149  NodeList serializedAtMsg = annotationEl.getElementsByTagName("oa:serializedAt");
150  Element serializedAtEl = (Element) serializedAtMsg.item(0);
151  if(serializedAtEl != null){
152  processCreationDate(serializedAtEl, annotUri, requestInfo, false);
153  }
154 
155  // get bodies of annotation (there are type of annotation, content and attributes)
156  NodeList bodiesOfAnnot = annotationEl.getElementsByTagName("oa:hasBody");
157  if(bodiesOfAnnot != null){
158  if(!processBodies(bodiesOfAnnot,newAnnotation,requestInfo)){
159  // process of parsing bodies of annotation failed
160  return null;
161  }
162  }
163 
164  // get informations about trget (there are fragments and annotated document)
165  NodeList targetMsg = annotationEl.getElementsByTagName("oa:hasTarget");
166  Element targetEl = (Element) targetMsg.item(0);
167  if(targetEl != null) {
168  if(!processTarget(targetEl,newAnnotation, requestInfo)){
169  // process of parsing targets of annotation failed
170  return null;
171  }
172  }
173 
174  return newAnnotation;
175  } // processAnnotation()
176 
177  /**
178  * Method process target element of annotation.
179  *
180  * @param targetEl element with target of annotation for process
181  * @param annot annotation which information from target element will be set
182  * @param requestInfo informations about client request
183  * @return false if any error occurs
184  */
185  private boolean processTarget(Element targetEl, Annotation annot, RequestInfo requestInfo){
186 
187  // find composite
188  NodeList fragCompositeMsg = targetEl.getElementsByTagName("oa:Composite");
189  Element fragCompositeEl = (Element) fragCompositeMsg.item(0);
190  if(fragCompositeEl != null) {
191  // if composite process composite
192  ArrayList<Fragment> fragments = processSRComposite(fragCompositeEl,annot,requestInfo);
193  if(fragments != null && !fragments.isEmpty()){
194  annot.setFragments(fragments);
195 
196  AnnotDocument doc = processHasSource(annot, fragCompositeEl,requestInfo);
197  if(doc == null){
198  return false;
199  }
200  annot.setSourceDocument(doc);
201  return true;
202  }else{
203  return false;
204  }
205  }
206 
207  // find specificResource
208  NodeList specificResourceMsg = targetEl.getElementsByTagName("oa:SpecificResource");
209  Element specificResourceEl = (Element) specificResourceMsg.item(0);
210  if (specificResourceEl != null) {
211  // if fragment then process fragment
212  Fragment frag = processSpecificResource(specificResourceEl, annot, requestInfo);
213  if (frag != null) {
214  ArrayList<Fragment> newFragments = new ArrayList<Fragment>();
215  newFragments.add(frag);
216  annot.setFragments(newFragments);
217 
218  AnnotDocument doc = processHasSource(annot, specificResourceEl,requestInfo);
219  if(doc == null){
220  return false;
221  }
222  annot.setSourceDocument(doc);
223  return true;
224  }else{
225  return false;
226  }
227  }
228 
229  // if whole document make fragment for whole doc
230  NodeList wholeDocMsg = targetEl.getElementsByTagName("dctypes:Text");
231  Element wholeDocEl = (Element) wholeDocMsg.item(0);
232  if(wholeDocEl != null) {
233 
234  // set document
235  String documentUri = wholeDocEl.getAttribute("rdf:about");
236  if(documentUri == null || documentUri.isEmpty()){
237  // error - uri of document not found
238  int langNum = requestInfo.getSession().getLanguageNum();
239  int lod = requestInfo.getSession().getProtocolLOD();
240  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
241  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
243  String msg = "Unable to find document uri (rdf:about).";
244  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
245  }
246  return false;
247  }
248 
249  //check for format element
250  NodeList formatMsg = targetEl.getElementsByTagName("dc:format");
251  if(formatMsg.item(0) == null){
252  // error - can't find trix element
253  int langNum = requestInfo.getSession().getLanguageNum();
254  int lod = requestInfo.getSession().getProtocolLOD();
255  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
256  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
258  String msg = "Element format in target is missing.";
259  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
260  }
261  return false;
262  }
263 
264 
265  AnnotDocument syncDocument = requestInfo.getSession().getSyncDocument();
266  AnnotDocument doc = null;
267  if (syncDocument.getUri() != null && syncDocument.getUri().equals(documentUri)) {
268  doc = syncDocument;
269  } else {
270  doc = getDocumentFromUri(documentUri, annot, requestInfo);
271  }
272  if(doc == null){
273  return false;
274  }
275 
276  annot.setSourceDocument(doc);
277  return true;
278  }
279 
280  return false;
281  } // processTarget()
282 
283  /**
284  * Method process element with multiple annotated fragments of document.
285  *
286  * @param compositeEl element with multiple annotated fragments for process
287  * @param annot annotation which multiple fragments belongs
288  * @param requestInfo informations about client request
289  * @return list of fragments or null if any error occurs
290  */
291  private ArrayList<Fragment> processSRComposite(Element compositeEl, Annotation annot, RequestInfo requestInfo){
292  ArrayList<Fragment> fragments = new ArrayList<Fragment>();
293 
294  NodeList itemsMsg = compositeEl.getElementsByTagName("oa:item");
295  int size = itemsMsg.getLength();
296  if (size > 0) {
297  for (int index = 0; index < size; index++) {
298  Element documentEl = (Element) itemsMsg.item(index);
299 
300  // find specificResource
301  NodeList specificResourceMsg = documentEl.getElementsByTagName("oa:SpecificResource");
302  Element specificResourceEl = (Element) specificResourceMsg.item(0);
303  if (specificResourceEl != null) {
304  // if fragment then process fragment
305  Fragment frag = processSpecificResource(specificResourceEl, annot, requestInfo);
306  if (frag != null) {
307  fragments.add(frag);
308  }
309  }
310  }
311  } else {
312  // can't find any item in composite of fragments
313  int langNum = requestInfo.getSession().getLanguageNum();
314  int lod = requestInfo.getSession().getProtocolLOD();
315  String info = "<annotation uri=\"" + annot.getURIV2() + "\"/>";
316  requestInfo.addError(lod, langNum, Localisation.ERROR_81_EMPTY_COMPOSITE, info);
318  String msg = "Cant find any item in composite of fragments.";
319  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
320  }
321  return null;
322  }
323 
324  return fragments;
325  }
326 
327  /**
328  * Method process source element (element with inforamtions about document) of
329  * annotation.
330  *
331  * @param annot Annotation to which element belongs
332  * @param hasSourceEl Element with source of annotation for process
333  * @param requestInfo Informations about client request
334  * @return Returns annotated docuemnt or null if any error occurs
335  */
336  private AnnotDocument processHasSource(Annotation annot, Element hasSourceEl, RequestInfo requestInfo){
337  NodeList dctypesMsg = hasSourceEl.getElementsByTagName("dctypes:Text");
338  Element dctypesEl = (Element) dctypesMsg.item(0);
339  if (dctypesEl == null) {
340  // can't find dctypes:Text element
341  int langNum = requestInfo.getSession().getLanguageNum();
342  int lod = requestInfo.getSession().getProtocolLOD();
343  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
344  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
346  String msg = "Element dctypes:Text is missing.";
347  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
348  }
349  return null;
350  } else {
351  String documentUri = dctypesEl.getAttribute("rdf:about");
352  if(documentUri == null || documentUri.isEmpty()){
353  // can't find document uri
354  int langNum = requestInfo.getSession().getLanguageNum();
355  int lod = requestInfo.getSession().getProtocolLOD();
356  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
357  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
359  String msg = "Unable to find document uri.";
360  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
361  }
362  return null;
363  }
364 
365  //search for format element
366  NodeList formatMsg = hasSourceEl.getElementsByTagName("dc:format");
367  if(formatMsg.item(0) == null){
368  // error - can't find trix element
369  int langNum = requestInfo.getSession().getLanguageNum();
370  int lod = requestInfo.getSession().getProtocolLOD();
371  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
372  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
374  String msg = "Element format in target - source is missing.";
375  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
376  }
377  return null;
378  }
379 
380  AnnotDocument syncDoc = requestInfo.getSession().getSyncDocument();
381  if (syncDoc.getUri() != null && syncDoc.getUri().equals(documentUri)) {
382  return syncDoc;
383  }
384  return getDocumentFromUri(documentUri, annot, requestInfo);
385  }
386  }
387 
388  /**
389  * Method process specific resources of annotations and save them as fragments.
390  *
391  * @param specificResourceEl element with specific resources of annotation for process
392  * @param annot annotation which specific resources (fragment) belongs
393  * @param requestInfo informations about client request
394  * @return fragment or null if any error occurs
395  */
396  private Fragment processSpecificResource(Element specificResourceEl, Annotation annot, RequestInfo requestInfo){
397  //check for oa:hasSelector element
398  NodeList formatMsg = specificResourceEl.getElementsByTagName("oa:hasSelector");
399  if(formatMsg.item(0) == null){
400  // error - can't find trix element
401  int langNum = requestInfo.getSession().getLanguageNum();
402  int lod = requestInfo.getSession().getProtocolLOD();
403  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
404  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
406  String msg = "Element oa:hasSelector in target is missing.";
407  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
408  }
409  return null;
410  }
411 
412  // get anotated document
413  Fragment newFragment = new Fragment();
414  NodeList documentMsg = specificResourceEl.getElementsByTagName("oa:FragmentSelector");
415  Element documentEl = (Element) documentMsg.item(0);
416  newFragment.setRefAnnotation(annot);
417  newFragment.setIsGood(true);
418  if (documentEl == null) {
419  // can't find dcterms:conformsTo element
420  int langNum = requestInfo.getSession().getLanguageNum();
421  int lod = requestInfo.getSession().getProtocolLOD();
422  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
423  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
425  String msg = "Element dcterms:conformsTo is missing.";
426  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
427  }
428  return null;
429  } else {
430  // get xpointer
431  NodeList xpointerMsg = documentEl.getElementsByTagName("rdf:value");
432  Element xpointerEl = (Element) xpointerMsg.item(0);
433  if(xpointerEl != null) {
434  String xpointer = MessageProcessor.getElementContent(xpointerEl);
435  if(xpointer == null || xpointer.isEmpty()){
436  // can't find xpointer value
437  int langNum = requestInfo.getSession().getLanguageNum();
438  int lod = requestInfo.getSession().getProtocolLOD();
439  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
440  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
442  String msg = "Cannot find xpointer value.";
443  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
444  }
445  return null;
446  }
447 
448  // process xpointer
449  if (!processXpointer(xpointer, newFragment, annot, requestInfo)) {
450  int langNum = requestInfo.getSession().getLanguageNum();
451  int lod = requestInfo.getSession().getProtocolLOD();
452  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
453  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
455  String msg = "Cannot process xpointer.";
456  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
457  }
458  return null;
459  }
460  }
461  }
462 
463  return newFragment;
464  }
465 
466  /**
467  * Method process xpointer from given string and set informations into given
468  * fragment object.
469  *
470  * @param xpointer xpointer string that will be parsed
471  * @param fragment fragment that will be set
472  * @param annot Annotation to which fragment belongs
473  * @param requestInfo informations about client request
474  * @return false if any error occurs
475  */
476  private boolean processXpointer(String xpointer, Fragment fragment, Annotation annot, RequestInfo requestInfo){
477  // parse xpath
478  int xpathEndIndex = xpointer.indexOf(',');
479  String xpath = xpointer.substring(0,xpathEndIndex);
480  xpath = xpath.replace("xpointer(string-range(", "");
481  xpath = UpdatableFragment.improveXPath(xpath);
482 
483  // parse text from xpointer
484  int textStartIndex = xpointer.indexOf('\'');
485  int textEndIndex = xpointer.lastIndexOf('\'');
486  String text = xpointer.substring(textStartIndex+1, textEndIndex);
487 
488  // parse offset and length
489  String partsList[] = xpointer.substring(textEndIndex).split(",");
490 
491  Integer offset;
492  Integer length;
493 
494  try {
495  offset = Integer.decode(partsList[1].trim());
496  length = Integer.decode(partsList[2].replaceAll("\\)", "").trim());
497  } catch (NumberFormatException ex) {
498  // can't decode offset or length value
499  int langNum = requestInfo.getSession().getLanguageNum();
500  int lod = requestInfo.getSession().getProtocolLOD();
501  String info = "<annotation uri=\"" + annot.getURIV2() + "\"/>";
502  requestInfo.addError(lod, langNum, Localisation.ERROR_25_BAD_FRAGMENT, info);
504  String msg = "Unable to decode offset or length value.";
505  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
506  }
507  return false;
508  }
509 
510  fragment.setLength(length);
511  fragment.setOffset(offset);
512  fragment.setAnnotatedText(text);
513  fragment.setPath(xpath);
514 
515  return true;
516  }
517 
518  /**
519  * Method process element with bodies of annotation.
520  *
521  * @param bodiesOfAnnot element with bodies of annotation for process
522  * @param annot annotation which bodies (as fragments) belongs
523  * @param requestInfo informations about client request
524  * @return false if any error occurs
525  */
526  private boolean processBodies(NodeList bodiesOfAnnot, Annotation annot, RequestInfo requestInfo){
527  int bodiesCount = bodiesOfAnnot.getLength();
528 
529  if(bodiesCount == 0){
530  //Annotation must have at least 1 body
531  int langNum = requestInfo.getSession().getLanguageNum();
532  int lod = requestInfo.getSession().getProtocolLOD();
533  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"body\"/>";
534  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
536  String msg = "rdf:about is not presented in body.";
537  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
538  }
539  return false;
540  }
541 
542  // go trough all body elements
543  for(int index = 0; index < bodiesCount; index++){
544  Element bodyEl = (Element) bodiesOfAnnot.item(index);
545  if(bodyEl != null) {
546 
547  // try find type of annotation element
548  NodeList annotTypeMsg = bodyEl.getElementsByTagName("oa:SemanticTag");
549  Element annotTypeEl = (Element) annotTypeMsg.item(0);
550  if(annotTypeEl != null) {
551  // process element with type of annotation
552  if(!processAnnotType(annotTypeEl,annot,requestInfo)){
553  // process of parsing type of annotation failed
554  return false;
555  }
556  }
557 
558  // try find contents of annotation
559  NodeList textContentMsg = bodyEl.getElementsByTagName("cnt:ContentAsText");
560  if(textContentMsg != null && textContentMsg.getLength() > 0){
561  // process contents of annotations
562  if(!processAnnotContents(textContentMsg,annot,requestInfo)){
563  // process of parsing contents of annotation failed
564  return false;
565  }
566  }
567  }
568  }
569 
570  return true;
571  }
572 
573  /**
574  * Method process annotation contents element.
575  *
576  * @param contentsOfAnnot element with contents of annotation for process
577  * @param annot annotation which information from contents will be set
578  * @param requestInfo informations about client request
579  * @return false if any error occurs
580  */
581  private boolean processAnnotContents(NodeList contentsOfAnnot, Annotation annot, RequestInfo requestInfo){
582  int contentsCount = contentsOfAnnot.getLength();
583 
584  for(int index = 0; index < contentsCount; index++){
585  Element contentEl = (Element) contentsOfAnnot.item(index);
586 
587  if(contentEl != null) {
588  // get content uri attribute
589  String typeUriAttr = contentEl.getAttribute("rdf:about");
590  if(typeUriAttr == null || typeUriAttr.isEmpty()){
591  // uri of content is not presented
592  int langNum = requestInfo.getSession().getLanguageNum();
593  int lod = requestInfo.getSession().getProtocolLOD();
594  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"body\"/>";
595  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
597  String msg = "rdf:about is not presented in body.";
598  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
599  }
600  return false;
601  }
602 
603  // if content is body
604  if(isUriOfBody(typeUriAttr)){
605  // process body of annotation
606  if(!processBody(contentEl,annot,requestInfo)){
607  // process of parsing body of annotation failed
608  return false;
609  }
610  }else{
611  // if content is graph of attributes of annotation
612  // process attributes of annotation
613  if(!processAttributesNew(contentEl,annot,requestInfo)){
614  // process attributes of annotation failed
615  return false;
616  }
617  }
618  }
619  }
620 
621  return true;
622  }
623 
624  /**
625  * Method process body element of annotation.
626  *
627  * @param bodyEl element with body of annotation for process
628  * @param annot annotation which information from body will be set
629  * @param requestInfo informations about client request
630  * @return false if any error occurs
631  */
632  private boolean processBody(Element bodyEl, Annotation annot,RequestInfo requestInfo){
633  /** Check if type, format and chars elements are within this body */
634  NodeList formatMsg = bodyEl.getElementsByTagName("dc:format");
635  if(formatMsg.item(0) == null){
636  // error - can't find trix element
637  int langNum = requestInfo.getSession().getLanguageNum();
638  int lod = requestInfo.getSession().getProtocolLOD();
639  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"content\"/>";
640  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
642  String msg = "Element format is missing.";
643  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
644  }
645  return false;
646  }
647 
648  NodeList contentTypeMsg = bodyEl.getElementsByTagName("rdf:type");
649  Element contentTypeEl = (Element) contentTypeMsg.item(0);
650  if (contentTypeEl != null) {
651 
652  NodeList charsMsg = bodyEl.getElementsByTagName("cnt:chars");
653  Element charsEl = (Element) charsMsg.item(0);
654  if (charsEl != null) {
655  String bodyContent = MessageProcessor.getElementContent(charsEl);
656  if (bodyContent == null) {
657  bodyContent = "";
658  }
659  annot.setContent(bodyContent);
660  return true;
661  } else {
662  // can't find chars element
663  int langNum = requestInfo.getSession().getLanguageNum();
664  int lod = requestInfo.getSession().getProtocolLOD();
665  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"content\"/>";
666  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
668  String msg = "Element chars is missing.";
669  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
670  }
671  return false;
672  }
673  } else {
674  // error - can't find content type element
675  int langNum = requestInfo.getSession().getLanguageNum();
676  int lod = requestInfo.getSession().getProtocolLOD();
677  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"content\"/>";
678  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
680  String msg = "Element content type is missing.";
681  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
682  }
683  return false;
684  }
685  }
686 
687  /**
688  * Method process author of annotation.
689  *
690  * @param anotatedByEl element with author of annotation for process
691  * @param annotUri URI of annotation to which element belongs
692  * @param requestInfo informations about client request
693  * @return user or null if any error occurs
694  */
695  private User processAuthor(Element anotatedByEl, String annotUri, RequestInfo requestInfo){
696  // get autor uri attribute
697  NodeList personMsg = anotatedByEl.getElementsByTagName("foaf:Person");
698  Element personEl = (Element) personMsg.item(0);
699  if(personEl != null) {
700 
701  String authorUriAttr = personEl.getAttribute("rdf:about");
702  if(authorUriAttr == null || authorUriAttr.isEmpty()){
703  // uri of autor is not presented
704  int langNum = requestInfo.getSession().getLanguageNum();
705  int lod = requestInfo.getSession().getProtocolLOD();
706  String info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"author\"/>";
707  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
709  String msg = "Uri of author is not presented.";
710  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
711  }
712 
713  return null;
714  }
715 
716  // transform uri to id
717  Integer authorId;
718  try {
719  authorId = Integer.decode(authorUriAttr.replace(AppBean.getBaseUserUriV2(), ""));
720  } catch(NumberFormatException e){
721  // can't decode author id
722  int langNum = requestInfo.getSession().getLanguageNum();
723  int lod = requestInfo.getSession().getProtocolLOD();
724  String info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"author\"/>";
725  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
727  String msg = "Unable to decode author's id.";
728  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
729  }
730  return null;
731  }
732 
733  // try find autor in DB
734  PersistM persistMan = AppBean.getPersistenceManager();
735  Object[] authorParams = new Object[2];
736  authorParams[0] = "id";
737  authorParams[1] = authorId;
738  @SuppressWarnings("unchecked")
739  List<User> usersList = persistMan.queryDB("User.findById", authorParams);
740  if(usersList == null || usersList.isEmpty()){
741  // unknown user
742  int langNum = requestInfo.getSession().getLanguageNum();
743  int lod = requestInfo.getSession().getProtocolLOD();
744  String info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"author\"/>";
745  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
747  String msg = "Unable to find author of annotation: " + authorId;
748  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
749  }
750  return null;
751  }
752 
753  return usersList.get(0);
754  }
755  else{
756  int langNum = requestInfo.getSession().getLanguageNum();
757  int lod = requestInfo.getSession().getProtocolLOD();
758  String info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"author\"/>";
759  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
761  String msg = "Missing foaf:Person element.";
762  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
763  }
764 
765  return null;
766  }
767  } // processAuthor()
768 
769  /**
770  * Method process creation and serialization date of annotation.
771  *
772  * @param annotatedAtEl element with creation date of annotation for process
773  * @param annotUri URI of annotation to which element belongs
774  * @param requestInfo informations about client request
775  * @param created tag if its date of creation element
776  * @return creation date or null if any error occurs
777  */
778  private Date processCreationDate(Element annotatedAtEl, String annotUri, RequestInfo requestInfo, boolean created){
779  String creationDateValue = MessageProcessor.getElementContent(annotatedAtEl);
780  if(creationDateValue == null || creationDateValue.isEmpty()){
781  // creation date and time not found
782  int langNum = requestInfo.getSession().getLanguageNum();
783  int lod = requestInfo.getSession().getProtocolLOD();
784  String info, msg;
785  if(created){
786  info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"annotatedAt\"/>";
787  msg = "Bad date and time format in annotatedAt.";
788  }
789  else{
790  info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"serializedAt\"/>";
791  msg = "Bad date and time format in serializedAt.";
792  }
793  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
795  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
796  }
797  return null;
798  }
799 
800  Date dateOfCreation;
801 
802  // try to convert string to date
803  try{
804  dateOfCreation = DatatypeConverter.parseDateTime(creationDateValue).getTime();
805  }catch(IllegalArgumentException ex){
806  // bad date time format
807  int langNum = requestInfo.getSession().getLanguageNum();
808  int lod = requestInfo.getSession().getProtocolLOD();
809  String info, msg;
810  if(created){
811  info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"annotatedAt\"/>";
812  msg = "Bad date and time format in annotatedAt.";
813  }
814  else{
815  info = "<annotation uri=\"" + annotUri + "\" invalidProperty=\"serializedAt\"/>";
816  msg = "Bad date and time format in serializedAt.";
817  }
818  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
820  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
821  }
822  return null;
823  }
824 
825  return dateOfCreation;
826  }
827 
828  /**
829  * Method process type of annotation and add them into annotation.
830  *
831  * @param annotTypeEl element with type of annotation for process
832  * @param annot annotation which type will be set
833  * @param requestInfo informations about client request
834  * @return false if any error occurs
835  */
836  private boolean processAnnotType(Element annotTypeEl, Annotation annot, RequestInfo requestInfo){
837  // get annotation type uri attribute
838  String typeUriAttr = annotTypeEl.getAttribute("rdf:about");
839  if(typeUriAttr == null || typeUriAttr.isEmpty()){
840  // uri of annotation type is not presented
841  int langNum = requestInfo.getSession().getLanguageNum();
842  int lod = requestInfo.getSession().getProtocolLOD();
843  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"type\"/>";
844  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
846  String msg = "Uri of annotation type is not presented.";
847  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
848  }
849 
850  return false;
851  }
852 
853  // try find type in DB
854  PersistM persistMan = AppBean.getPersistenceManager();
855  Object[] typeParams = new Object[2];
856  typeParams[0] = "uri";
857  typeParams[1] = typeUriAttr;
858  @SuppressWarnings("unchecked")
859  List<AnnotType> usersList = persistMan.queryDB("AnnotType.findByUri", typeParams);
860  if(usersList == null || usersList.isEmpty()){
861  if(requestInfo.getFlier().getAddedTypes() != null && !requestInfo.getFlier().getAddedTypes().isEmpty()){
862  // try find type in just added types
863  Iterator<AnnotType> typesIt = requestInfo.getFlier().getAddedTypes().iterator();
864  while(typesIt.hasNext()){
865  AnnotType currentType = typesIt.next();
866  if(typeUriAttr.equals(currentType.getUri())){
867  annot.setAnnotType(currentType);
868  return true;
869  }
870  }
871  }else{
872  // unknown annotation type
873  int langNum = requestInfo.getSession().getLanguageNum();
874  int lod = requestInfo.getSession().getProtocolLOD();
875  String info = "<annotation uri=\"" + typeUriAttr + "\"/>";
876  requestInfo.addError(lod, langNum, Localisation.ERROR_19_TYPE_UNKNOWN, info);
878  String msg = "Unknown annotation type. Type uri: " + typeUriAttr;
879  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
880  }
881  return false;
882  }
883  }
884 
885  annot.setAnnotType(usersList.get(0));
886  return true;
887  }
888 
889  /**
890  * Method finds document in server database by uri of document.
891  *
892  * @param uri uri of document
893  * @param annot Annotation for which we are searching target
894  * @param requestInfo informations about client request
895  * @return annotated document or null if document is not found
896  */
897  private AnnotDocument getDocumentFromUri(String uri, Annotation annot, RequestInfo requestInfo){
898  Integer documentId;
899  AnnotDocument document;
900 
901  try {
902  documentId = Integer.decode(uri.replace(AppBean.getBaseDocumentUri(), ""));
903  } catch (NumberFormatException ex) {
904  // bad document id
905  int langNum = requestInfo.getSession().getLanguageNum();
906  int lod = requestInfo.getSession().getProtocolLOD();
907  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"target\"/>";
908  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
910  String msg = "Id of document is bad.";
911  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
912  }
913  return null;
914  }
915 
916  // get document from DB
917  PersistM persistMan = AppBean.getPersistenceManager();
918 
919  Object[] params = new Object[2];
920  params[0] = "id";
921  params[1] = documentId;
922  @SuppressWarnings("unchecked")
923  List<AnnotDocument> documentsList = persistMan.queryDB("AnnotDocument.findById", params);
924  if (documentsList != null && !documentsList.isEmpty()) {
925  document = documentsList.get(0);
926  } else {
927  // can't find document
928  int langNum = requestInfo.getSession().getLanguageNum();
929  int lod = requestInfo.getSession().getProtocolLOD();
930  requestInfo.addError(lod, langNum, Localisation.ERROR_53_BAD_DOCUMENT_URI);
932  String msg = "Unable to find document with uri " + uri;
933  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
934  }
935  return null;
936  }
937 
938  return document;
939  }
940 
941  /**
942  * Method determine if given uri is uri of document.
943  *
944  * @param uri uri that will be tested
945  * @return true if uri is uri of document
946  */
947  private static boolean isUriOfBody(String uri){
948  if(uri.contains("#body")){
949  return true;
950  }
951 
952  return false;
953  }
954 
955  /**
956  * Method detects the type of annotation uri. (temp/serv/sugg)
957  *
958  * @param uri uri from which method will determine type of uri
959  * @return string with type of uri
960  */
961  protected static String getUriType(String uri){
962  String parts[] = uri.split("/");
963  if(parts.length > 3){
964  return parts[parts.length-2];
965  }
966  return null;
967  }
968 
969  /**
970  * Method that process each of triple element from user message
971  * @param trixList List of trixes
972  * @param requestInfo Info about clients request
973  * @param annot Ref annotation
974  */
975  private ArrayList<P2BaseTrix> processTrixElements(NodeList trixList, RequestInfo requestInfo, Annotation annot){
976  HashMap<String, P2BaseTrix> trixMap = new HashMap<String, P2BaseTrix>();
977 
978  // Key - attribute name | Value - linked/nested uri
979  HashMap<String, ArrayList<String>> links = new HashMap<String, ArrayList<String>>();
980 
981  // Key - URI of nested annotation | Value - URI of parent annotation
982  HashMap<String, String> nestedAnnots = new HashMap<String, String>();
983 
984  // Key - attribute name | Value - priority
985  HashMap<String, String> priorityMap = new HashMap<String, String>();
986 
987  // Key - attribute name | Value - entity type
988  HashMap<String, String> entityDic = new HashMap<String, String>();
989 
990  HashMap<String, ArrayList<P2EntityAdditionalTrix>> eadtAL = new HashMap<String, ArrayList<P2EntityAdditionalTrix>>();
991 
992 
993 
994  boolean first = false, second = false, third = false;
995  int trixCount = trixList.getLength();
996 
997  String destinationUri = null;
998  String uriInOntology = null;
999  String name = null;
1000  boolean fromOntology = false;
1001 
1002  //Process each of tripple
1003  for(int i = 0; i < trixCount; i++){
1004  Node trixNode = trixList.item(i);
1005 
1006  first = false;
1007  second = false;
1008  third = false;
1009  fromOntology = false;
1010  name = null;
1011  uriInOntology = null;
1012 
1013  for(Node node = trixNode.getFirstChild(); node != null; node = node.getNextSibling()) {
1014  if(!(node instanceof Element)){
1015  continue;
1016  }
1017 
1018  Element element = (Element) node;
1019 
1020  if(!first){
1021  /* Check element tag name */
1022  if(!element.getTagName().equals("trix:uri")){
1023  int langNum = requestInfo.getSession().getLanguageNum();
1024  int lod = requestInfo.getSession().getProtocolLOD();
1025 
1026  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"trix\"";
1027 
1028  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
1030  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.SEVERE, info);
1031  }
1032  return null;
1033  }
1034 
1035  destinationUri = MessageProcessor.getElementContent(element);
1036  first = true;
1037  }
1038  else if(!second){
1039  name = MessageProcessor.getElementContent(element);
1040  if(!element.getTagName().equals("trix:uri") && !element.getTagName().equals("trix:name")){
1041  int langNum = requestInfo.getSession().getLanguageNum();
1042  int lod = requestInfo.getSession().getProtocolLOD();
1043 
1044  String info = "<attribute annotationUri=\"" + destinationUri + "\" name=\"\" invalidProperty=\"designation\"/>";
1045 
1046  requestInfo.addError(lod, langNum, Localisation.ERROR_26_ATTRIBUTE_MALFORMED, info);
1048  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.SEVERE, info);
1049  }
1050  return null;
1051  }
1052 
1053  if(element.getTagName().equals("trix:uri")){
1054  fromOntology = true;
1055  uriInOntology = name;
1056  /* Obtain name from URI */
1057  name = name.substring(name.lastIndexOf("#")+1);
1058  }
1059 
1060  second = true;
1061  }
1062  /* Possible syntaxes of third trix:
1063  * <trix:uri> - uri entity, uri linked/nested annot, uri annot type, flag for linked/nested annot, anyAnnotation
1064  * or anyEntity
1065  * <trix:name> - name of type of entity
1066  * <trix:typedLiteral> - type of attribute
1067  *
1068  */
1069  else if(!third){
1070  if(element.getTagName().equals("trix:uri")){
1071  String thirdValue = MessageProcessor.getElementContent(element);
1072  P2BaseTrix att = null;
1073 
1074  //If it's anyEntity or anyAnnotation
1075  if(thirdValue.endsWith("#anyEntity") || thirdValue.endsWith("#anyAnnotation")){
1076  att = new P2SimpleTrix(destinationUri);
1077 
1078  ((P2SimpleTrix)att).setTypeUri(thirdValue);
1079  att.setName(name);
1080  att.setFromOntology(fromOntology);
1081  att.setUriInOntology(uriInOntology);
1082  }
1083  else if(thirdValue.equals("koae:linkedAnnotation")){
1084  /*
1085  * Search if attribute with this name is not already stored in map
1086  * If it's there, we have not yet determined that this attribute is linked,
1087  * so it's needed to create specific attribute
1088  */
1089  att = trixMap.get(name);
1090  if(att != null){
1091  att = new P2LinkedTrix(att);
1092  }
1093  else{
1094  att = new P2LinkedTrix(destinationUri);
1095  att.setName(name);
1096  att.setFromOntology(fromOntology);
1097  att.setUriInOntology(uriInOntology);
1098  }
1099  }
1100  else if(thirdValue.equals("koae:nestedAnnotation")){
1101  att = trixMap.get(name);
1102  if(att != null){
1103  att = new P2NestedTrix(att);
1104  }
1105  else{
1106  att = new P2NestedTrix(destinationUri);
1107  att.setName(name);
1108  att.setFromOntology(fromOntology);
1109  att.setUriInOntology(uriInOntology);
1110  }
1111  }
1112  //Its uri of annot type
1113  else if(thirdValue.contains(AppBean.getBaseTypeUri())){
1114  att = trixMap.get(name);
1115 
1116  if(att == null){
1117  att = new P2BaseTrix(destinationUri);
1118  att.setName(name);
1119  att.setFromOntology(fromOntology);
1120  att.setUriInOntology(uriInOntology);
1121  }
1122 
1123  att.setAnnotType(thirdValue);
1124  }
1125  else if(thirdValue.contains("serv")
1126  || thirdValue.contains("sugg")
1127  || thirdValue.contains("temp")){
1128  // Check if destinationUri is uri of document, otherwise it's just a nestedIn links
1129  if(isDocumentUri(destinationUri)){
1130  //Search for attribute
1131  att = trixMap.get(name);
1132  if(att != null){
1133  //Check if type of attribute is know at this time
1134  if(att instanceof P2NestedTrix){
1135  ((P2NestedTrix)att).addNestedAnnotUri(thirdValue);
1136  }
1137  else if(att instanceof P2LinkedTrix){
1138  ((P2LinkedTrix)att).addLinkedAnnotUri(thirdValue);
1139  }
1140  //Type of attribute is not know at this time
1141  else{
1142  ArrayList<String> tmpL = links.get(name);
1143  if(tmpL == null){
1144  tmpL = new ArrayList<String>();
1145  }
1146  tmpL.add(thirdValue);
1147  links.put(name, tmpL);
1148 
1149  first = false; second = false;
1150  continue;
1151  }
1152  }
1153  //Attribute may not been created yet so its type is not known at this time
1154  else{
1155  ArrayList<String> tmpL = links.get(name);
1156  if(tmpL == null){
1157  tmpL = new ArrayList<String>();
1158  }
1159  tmpL.add(thirdValue);
1160  links.put(name, tmpL);
1161 
1162  first = false; second = false;
1163  continue;
1164  }
1165  }
1166  else{
1167  /* This is the case, when triple has following format:
1168  * <trix:uri>{URI of nested annotation}</trix:uri>
1169  * <trix:uri>koae:nestedIn</trix:uri>
1170  * <trix:uri>{URI of parent annotation}</trix:uri>
1171  *
1172  * We need to check, whether second trix has "koae:nestedIn", otherwise, its an error
1173  */
1174  if(!name.equals("koae:nestedIn")){
1175  int langNum = requestInfo.getSession().getLanguageNum();
1176  int lod = requestInfo.getSession().getProtocolLOD();
1177 
1178  String info = "<attribute annotationUri=\"" + thirdValue + "\" name=\"\" invalidProperty=\"nestedIn\"/>";
1179 
1180  requestInfo.addError(lod, langNum, Localisation.ERROR_26_ATTRIBUTE_MALFORMED, info);
1182  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.SEVERE, info);
1183  }
1184  return null;
1185  }
1186  nestedAnnots.put(destinationUri, thirdValue);
1187  first = false; second = false;
1188  continue;
1189  }
1190  }
1191  //Its uri of entity or error
1192  else{
1193  /* In this case, third trix may be uri of entity or corrupted nesting element, so due to this fact
1194  * we need to check whether attribute with this target and name has already been parsed;
1195  * If yes, it's an error, otherwise it's uri of entity
1196  */
1197  if(trixMap.get(name) != null){
1198  int langNum = requestInfo.getSession().getLanguageNum();
1199  int lod = requestInfo.getSession().getProtocolLOD();
1200 
1201  String info = "<attribute annotationUri=\"" + destinationUri + "\" name=\"" + name + "\" invalidProperty=\"nesting\"/>";
1202 
1203  requestInfo.addError(lod, langNum, Localisation.ERROR_26_ATTRIBUTE_MALFORMED, info);
1205  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.SEVERE, info);
1206  }
1207  return null;
1208  }
1209  else{
1210  att = new P2EntityTrix(destinationUri);
1211  ((P2EntityTrix)att).setName(name);
1212  ((P2EntityTrix)att).setUriInOntology(uriInOntology);
1213  ((P2EntityTrix)att).setEntityUri(thirdValue);
1214  }
1215  }
1216 
1217  //Save processed triple
1218  trixMap.put(name, att);
1219 
1220  }
1221  //Save entity type into dictionary
1222  else if(element.getTagName().equals("trix:name")){
1223  entityDic.put(destinationUri, MessageProcessor.getElementContent(element));
1224  }
1225  else if(element.getTagName().equals("trix:typedLiteral")){
1226  //If first of triple is not document uri, then this triple is entityadditional attribute
1227  String dataType = element.getAttribute("datatype");
1228 
1229  if(!isDocumentUri(destinationUri)){
1230  /* As type,name,description and imageUri are properties of entity attribute, first of all try to assign
1231  * this values into entity...if image or something else occurs more than once, first of them is set as property of entity
1232  * and all of the rest is parsed as additional attribute
1233  *
1234  * Those properties are stored as additional attributes, so once trix is transforming into attribute, each of this values if taken,
1235  * and removed from additional attributes
1236  */
1238  adt.setEntityUri(destinationUri);
1239  adt.setEntityAttributeName(name);
1240  adt.setTypeUri(dataType);
1241 
1242  if(element.getFirstChild() != null && element.getFirstChild().getNodeValue() != null){
1243  adt.setValue(element.getFirstChild().getNodeValue());
1244  }
1245 
1246  ArrayList<P2EntityAdditionalTrix> al = eadtAL.get(destinationUri);
1247  if(al == null){
1248  al = new ArrayList<P2EntityAdditionalTrix>();
1249  }
1250  al.add(adt);
1251  eadtAL.put(destinationUri, al);
1252  }
1253  else{
1254  if(dataType.endsWith("#attributePriority")){
1255  if(element.getFirstChild() != null && element.getFirstChild().getNodeValue() != null){
1256  priorityMap.put(name, element.getFirstChild().getNodeValue());
1257  }
1258  }
1259  else{
1260  P2SimpleTrix att = (P2SimpleTrix) trixMap.get(name);
1261 
1262  if(att == null){
1263  att = new P2SimpleTrix(destinationUri);
1264  att.setName(name);
1265  att.setUriInOntology(uriInOntology);
1266  att.setTypeUri(dataType);
1267  }
1268 
1269  if(dataType.endsWith("#Point")){
1270  parseGeoPoint(att, element);
1271  trixMap.put(name, att);
1272  }
1273  else{
1274  if(element.getFirstChild() != null && element.getFirstChild().getNodeValue() != null){
1275  att.addValue(element.getFirstChild().getNodeValue());
1276  }
1277  trixMap.put(name, att);
1278  }
1279  }
1280  }
1281  }
1282  else{
1283  int langNum = requestInfo.getSession().getLanguageNum();
1284  int lod = requestInfo.getSession().getProtocolLOD();
1285 
1286  String info = "<attribute annotationUri=\"" + destinationUri + "\" name=\"" + name + "\" invalidProperty=\"designation\"/>";
1287 
1288  requestInfo.addError(lod, langNum, Localisation.ERROR_26_ATTRIBUTE_MALFORMED, info);
1290  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.SEVERE, "Wrong tag name of third element in triple");
1291  }
1292  return null;
1293  }
1294  third = true;
1295  } // third
1296  }// inner for-cycle
1297  }// for-cycle
1298 
1299 
1300  //Iterate through processed trixes and assign remaining values
1301  Iterator it = trixMap.values().iterator();
1302  while(it.hasNext()){
1303  P2BaseTrix t = (P2BaseTrix)it.next();
1304 
1305  //First assign priority
1306  if(priorityMap.get(t.getName()) != null){
1307  t.setPriority(priorityMap.get(t.getName()));
1308  }
1309 
1310  //If attribute is type of linked, check for links
1311  if(t instanceof P2LinkedTrix){
1312  if(links.get(t.getName()) != null){
1313  ((P2LinkedTrix)t).addAllLinkedAnnotUris(links.get(t.getName()));
1314  }
1315  }
1316 
1317  //If attribute is type of entity, check for additional attributes and dictionary
1318  if(t instanceof P2EntityTrix){
1319  if(entityDic.get(((P2EntityTrix)t).getEntityUri()) != null){
1320  ((P2EntityTrix)t).setEntityType(entityDic.get(((P2EntityTrix)t).getEntityUri()));
1321  }
1322  if(eadtAL.get(((P2EntityTrix)t).getEntityUri()) != null){
1323  ((P2EntityTrix)t).setEntityAdditionalTrixAL(eadtAL.get(((P2EntityTrix)t).getEntityUri()));
1324  }
1325  }
1326  //If attribute is type of nested, check for links and references to parent annots
1327  else if(t instanceof P2NestedTrix){
1328  if(links.get(t.getName()) != null){
1329  ((P2NestedTrix)t).addAllNestedAnnotUris(links.get(t.getName()));
1330  }
1331 
1332  //As all nested annot uris got the same ref. annot, it's enough to take just first one and assign
1333  // appropriate value to variable
1334  if(((P2NestedTrix)t).getNestedAnnotUris() != null){
1335  String ref = nestedAnnots.get(((P2NestedTrix)t).getNestedAnnotUris().get(0));
1336  ((P2NestedTrix)t).setRefAnnotUri(ref);
1337  }
1338  }
1339  }
1340 
1341  return new ArrayList<P2BaseTrix>(trixMap.values());
1342  } //processTrixElements
1343 
1344  /**
1345  * Process GeoPoint attribute and assign it's value into appropriate object
1346  *
1347  * @param att Trix attribute object, into which processed value should be assigned
1348  * @param el Element which contains GeoPoint value
1349  */
1350  private void parseGeoPoint(P2SimpleTrix att, Element el){
1351  for(Node node = el.getFirstChild(); node != null; node = node.getNextSibling()) {
1352  if(!(node instanceof Element)){
1353  continue;
1354  }
1355 
1356  Element tmpEl = (Element) node;
1357  if(tmpEl.getTagName().equals("geo:Point")){
1358  for(Node innerNode = tmpEl.getFirstChild(); innerNode != null; innerNode = innerNode.getNextSibling()){
1359  if(!(innerNode instanceof Element)){
1360  continue;
1361  }
1362  if(((Element)innerNode).getTagName().equals("geo:lat")){
1363  att.addLatitude(getGeoPointNodeValue(innerNode.getFirstChild()));
1364  }
1365  else if(((Element)innerNode).getTagName().equals("geo:long")){
1366  att.addLongitude(getGeoPointNodeValue(innerNode.getFirstChild()));
1367  }
1368  else{
1369  continue;
1370  }
1371  }
1372  }
1373  }
1374  }
1375 
1376  /**
1377  * Gets value of passed node
1378  *
1379  * @param node node whose value is going to be returned
1380  * @return Node value in string form
1381  */
1382  private String getGeoPointNodeValue(Node node){
1383 
1384  for(Node n = node; n != null; n = n.getNextSibling()){
1385  if(n.getNodeValue() != null){
1386  return n.getNodeValue();
1387  }
1388  }
1389  return null;
1390  }
1391 
1392 
1393  /**
1394  * Method process attributes of annotation and add them into annotation.
1395  *
1396  * @param attributesEl element with attributes of annotations for process
1397  * @param annot annotation that given attributes belongs
1398  * @param requestInfo informations about client request
1399  * @return false if any error occurs
1400  */
1401  private boolean processAttributesNew(Element attributesEl, Annotation annot, RequestInfo requestInfo){
1402  /**Search for rdf:type and trix:TriX elements as they has to be present within content element */
1403  NodeList contentTypeMsg = attributesEl.getElementsByTagName("rdf:type");
1404  if(contentTypeMsg.item(0) == null){
1405  // error - can't find content type element
1406  int langNum = requestInfo.getSession().getLanguageNum();
1407  int lod = requestInfo.getSession().getProtocolLOD();
1408  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"trix\"/>";
1409  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
1411  String msg = "Element content type is missing.";
1412  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
1413  }
1414  return false;
1415  }
1416 
1417  NodeList trixMsg = attributesEl.getElementsByTagName("trix:TriX");
1418  if(trixMsg.item(0) == null){
1419  // error - can't find trix element
1420  int langNum = requestInfo.getSession().getLanguageNum();
1421  int lod = requestInfo.getSession().getProtocolLOD();
1422  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"trix\"/>";
1423  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
1425  String msg = "Element Trix is missing.";
1426  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
1427  }
1428  return false;
1429  }
1430 
1431  NodeList formatMsg = attributesEl.getElementsByTagName("dc:format");
1432  if(formatMsg.item(0) == null){
1433  // error - can't find trix element
1434  int langNum = requestInfo.getSession().getLanguageNum();
1435  int lod = requestInfo.getSession().getProtocolLOD();
1436  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"trix\"/>";
1437  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
1439  String msg = "Element format is missing.";
1440  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
1441  }
1442  return false;
1443  }
1444 
1445 
1446  NodeList trixGraphMsg = attributesEl.getElementsByTagName("trix:graph");
1447  Element trixGraphEl = (Element) trixGraphMsg.item(0);
1448  if(trixGraphEl != null){
1449 
1450  // go trough all triple elements
1451  NodeList triplesMsg = attributesEl.getElementsByTagName("trix:triple");
1452 
1453  ArrayList<P2BaseTrix> trixesList = processTrixElements(triplesMsg, requestInfo, annot);
1454  ArrayList<BaseAttribute> attributesList = new ArrayList<BaseAttribute>();
1455 
1456  //Error
1457  if(trixesList == null){
1458  return false;
1459  }
1460 
1461  Iterator<P2BaseTrix> trixesIt = trixesList.iterator();
1462  int counter = 0;
1463  while(trixesIt.hasNext()){
1464  ArrayList<BaseAttribute> tmpAttList = trixesIt.next().trixToAnnotAtt(annot, requestInfo, counter);
1465  counter++;
1466  if(tmpAttList == null){
1467  //Error
1468  return false;
1469  }
1470  attributesList.addAll(tmpAttList);
1471  }
1472 
1473 
1474  annot.setAttributes(attributesList);
1475  return true;
1476  }
1477  else{
1478  // error - can't find Graph element
1479  int langNum = requestInfo.getSession().getLanguageNum();
1480  int lod = requestInfo.getSession().getProtocolLOD();
1481  String info = "<annotation uri=\"" + annot.getURIV2() + "\" invalidProperty=\"trix\"/>";
1482  requestInfo.addError(lod, langNum, Localisation.ERROR_38_ANNOT_MALFORMED, info);
1484  String msg = "Element graph is missing.";
1485  Logger.getLogger(P2AnnotBaseProcessor.class.getName()).log(Level.ALL, msg);
1486  }
1487  return false;
1488  }
1489  } // processAttributesNew()
1490 
1491 
1492  /**
1493  * Check if given uri is uri of document.
1494  *
1495  * @param uri uri to check
1496  * @return returns true if given uri is uri of document
1497  */
1498  boolean isDocumentUri(String uri){
1499  if(uri.contains(AppBean.getBaseDocumentUri())){
1500  return true;
1501  }else{
1502  return false;
1503  }
1504  }
1505 
1506 } // public abstract class P2AnnotBaseProcessor
boolean processTarget(Element targetEl, Annotation annot, RequestInfo requestInfo)
Class that represents entity additional attribute trix triple.
Persistence manager (database manipulator)
Definition: PersistM.java:35
Class representing annotated copy of document.
ArrayList< P2BaseTrix > processTrixElements(NodeList trixList, RequestInfo requestInfo, Annotation annot)
Singleton for storing global variables.
Definition: AppBean.java:47
boolean processBody(Element bodyEl, Annotation annot, RequestInfo requestInfo)
boolean processXpointer(String xpointer, Fragment fragment, Annotation annot, RequestInfo requestInfo)
Abstract class provides a parser for the annotation of protocol version 2.
boolean processAnnotType(Element annotTypeEl, Annotation annot, RequestInfo requestInfo)
Static class which parses and process XML with messages.
Annotation processAnnotation(Element annotationEl, RequestInfo requestInfo)
User processAuthor(Element anotatedByEl, String annotUri, RequestInfo requestInfo)
Base class representing attribute of annotation.
Class representing type of annotation.
Definition: AnnotType.java:58
Class representing user.
Definition: User.java:51
AnnotDocument processHasSource(Annotation annot, Element hasSourceEl, RequestInfo requestInfo)
Fragment processSpecificResource(Element specificResourceEl, Annotation annot, RequestInfo requestInfo)
Date processCreationDate(Element annotatedAtEl, String annotUri, RequestInfo requestInfo, boolean created)
boolean processBodies(NodeList bodiesOfAnnot, Annotation annot, RequestInfo requestInfo)
Processed informations about client request.
boolean processAnnotContents(NodeList contentsOfAnnot, Annotation annot, RequestInfo requestInfo)
boolean processAttributesNew(Element attributesEl, Annotation annot, RequestInfo requestInfo)
Class responsible for localised strings.
ArrayList< Fragment > processSRComposite(Element compositeEl, Annotation annot, RequestInfo requestInfo)
Class representing annotated fragment.
Definition: Fragment.java:48
AnnotDocument getDocumentFromUri(String uri, Annotation annot, RequestInfo requestInfo)