4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
P2AnnotTypeProcessor.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: P2AnnotTypeProcessor.java
5  * Description: Class which parses and process XML with messages with types for
6  * protocol version 2.
7  */
8 
9 /**
10  * @file P2AnnotTypeProcessor.java
11  *
12  * @brief Class which parses and process XML with messages with types for protocol
13  * version 2.
14  */
15 package cz.vutbr.fit.knot.annotations.comet.protocolV2_0;
16 
25 import cz.vutbr.fit.knot.annotations.document.Pair;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.NodeList;
37 
38 /**
39  * Class which parses and process XML with messages with types for protocol
40  * version 2.
41  *
42  * @brief Class which parses and process XML with messages with types for protocol
43  * version 2
44  * @author Martin Petr (xpetrm05)
45  */
46 public class P2AnnotTypeProcessor {
47  /** Informations about client request */
49  /** List of new annotations without founded ancestors */
50  private ArrayList<Pair<String,AnnotType>> ancestorPair;
51  /** List of new annotations without founded direct ancestors */
52  private ArrayList<Pair<String,AnnotType>> direcAncestorPair;
53 
54  /**
55  * Constructor
56  */
58  ancestorPair = new ArrayList<Pair<String,AnnotType>>();
59  direcAncestorPair = new ArrayList<Pair<String,AnnotType>>();
60  }
61 
62  /**
63  * Entry method for processing types for add.
64  *
65  * @param typesElement element with types for add
66  * @param requestInfo informations about client request
67  */
68  public void procesTypesAdd(Element typesElement,RequestInfo requestInfo){
69  this.requestInfo = requestInfo;
70  procesAnnotTypes(typesElement,requestInfo,false);
71  }
72 
73  /**
74  * Entry method for processing types for remove.
75  *
76  * @param typesElement element with types for remove
77  * @param requestInfo informations about client request
78  */
79  public void procesTypesRemove(Element typesElement,RequestInfo requestInfo){
80  this.requestInfo = requestInfo;
81  procesDeleteTypes(typesElement,requestInfo);
82  }
83 
84  /**
85  * Entry method for processing types for change.
86  *
87  * @param typesElement element with types for change
88  * @param requestInfo informations about client request
89  */
90  public void procesTypesChange(Element typesElement,RequestInfo requestInfo){
91  this.requestInfo = requestInfo;
92  procesAnnotTypes(typesElement,requestInfo,true);
93  }
94 
95  /**
96  * Entry method for processing types guery.
97  *
98  * @param typesQueryElement element with types guery
99  * @param requestInfo informations about client request
100  */
101  public void procesTypeQuery(Element typesQueryElement,RequestInfo requestInfo){
102  String uriAttr = typesQueryElement.getAttribute("uri");
103  if(uriAttr == null || uriAttr.isEmpty()){
104  uriAttr = "*";
105  }
106 
107  EditorSession session = requestInfo.getSession();
108  requestInfo.addQueryTypes(uriAttr);
109  // Remember queries for later sending the types changes
110  if (session.getQueriedTypes() != null && !session.getQueriedTypes().contains(uriAttr)) {
111  session.addQueriedTypes(uriAttr);
112  }
113  }
114 
115  /**
116  * Method process element with types for add or update.
117  *
118  * @param typesElement element with types for add or update
119  * @param requestInfo informations about client request
120  * @param update if true proces types for update if is false process types for add
121  */
122  private void procesAnnotTypes(Element typesElement,RequestInfo requestInfo, boolean update){
123  NodeList typesMsg = typesElement.getElementsByTagName("type");
124  int typesCount = typesMsg.getLength();
125 
126  for(int index = 0; index < typesCount; index++){
127  Element modifyTypesEl = (Element) typesMsg.item(index);
128  if(modifyTypesEl != null) {
129  procesAnnotType(modifyTypesEl,requestInfo,update);
130  }
131  }
132 
133  if(update){
134  setMissingAncestors(requestInfo.getFlier().getEditedTypes(),requestInfo);
135  setMissingDirectAncestors(requestInfo.getFlier().getEditedTypes(),requestInfo);
136  checkAncestors(requestInfo.getFlier().getEditedTypes(),requestInfo);
137  }else{
138  setMissingAncestors(requestInfo.getFlier().getAddedTypes(),requestInfo);
139  setMissingDirectAncestors(requestInfo.getFlier().getAddedTypes(),requestInfo);
140  checkAncestors(requestInfo.getFlier().getAddedTypes(),requestInfo);
141  }
142 
143 
144  this.direcAncestorPair.clear();
145  this.ancestorPair.clear();
146  }
147 
148  /**
149  * Method process element with type for add or update.
150  *
151  * @param typeElement element with type for add or update
152  * @param requestInfo informations about client request
153  * @param update if true proces type for update if is false process types for add
154  */
155  private void procesAnnotType(Element typeElement,RequestInfo requestInfo, boolean update){
156  AnnotType type = new AnnotType();
157  AnnotType typeForChange = null;
158  PersistM persistMan = AppBean.getPersistenceManager();
159 
160  // get name attribute
161  String nameAttr = typeElement.getAttribute("name");
162  if(nameAttr == null){
163  nameAttr = "";
164  }
165 
166  // get uri attribute
167  String uriAttr = typeElement.getAttribute("uri");
168  if(uriAttr == null){
169  uriAttr = "";
170  }
171 
172  // get groupUri attribute
173  String groupUriAttr = typeElement.getAttribute("groupUri");
174  if(groupUriAttr == null){
175  groupUriAttr = "";
176  }
177 
178  // get uri in ontology attribute
179  String ontologyUriAttr = typeElement.getAttribute("ontologyUri");
180  if(ontologyUriAttr == null){
181  ontologyUriAttr = "";
182  }
183 
184  // get restrictedAttributes attribute
185  String restrictedAttributesAttr = typeElement.getAttribute("restrictedAttributes");
186  if(restrictedAttributesAttr == null){
187  restrictedAttributesAttr = "";
188  }
189 
190  // test if all required informations are presented
191  if (nameAttr.isEmpty()) {
192  int langNum = requestInfo.getSession().getLanguageNum();
193  int lod = requestInfo.getSession().getProtocolLOD();
194  String info = "<type name=\"" + nameAttr + "\" "
195  + "uri=\"" + uriAttr + "\" "
196  + "invalidAttribute=\"name\"/>";
197  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
199  String msg = "Empty required attribute of add type of annotation.";
200  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
201  }
202  return;
203  }
204  if (uriAttr.isEmpty()) {
205  int langNum = requestInfo.getSession().getLanguageNum();
206  int lod = requestInfo.getSession().getProtocolLOD();
207  String info = "<type name=\"" + nameAttr + "\" "
208  + "uri=\"" + uriAttr + "\" "
209  + "invalidAttribute=\"uri\"/>";
210  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
212  String msg = "Empty required attribute of add type of annotation.";
213  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
214  }
215  return;
216  }
217 
218  // Check ancestor in URI
219  String foundAncUri = "";
220  // get string with name of type and names of his ancestors from URI
221  String namesStr = uriAttr.replace(AppBean.getBaseTypeUri(), "");
222  String[] namesArr = namesStr.split("/");
223  ArrayList<String> names = new ArrayList<String>(Arrays.asList(namesArr));
224  int nSize = names.size(); // compute number of names
225  if (nSize > 2) { // if there is more then name of type and id of group
226  // get URI of ancestor type
227  // prevUri = uri of type without "/" and name
228  foundAncUri = uriAttr.substring(0, uriAttr.lastIndexOf("/"));
229  } // if there is more then name of type and id of group
230 
231 
232  if (groupUriAttr.isEmpty()) {
233  int langNum = requestInfo.getSession().getLanguageNum();
234  int lod = requestInfo.getSession().getProtocolLOD();
235  String info = "<type name=\"" + nameAttr + "\" "
236  + "uri=\"" + uriAttr + "\" "
237  + "invalidAttribute=\"groupUri\"/>";
238  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
240  String msg = "Empty required attribute of add type of annotation.";
241  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
242  }
243  return;
244  }
245  if (restrictedAttributesAttr.isEmpty()) {
246  int langNum = requestInfo.getSession().getLanguageNum();
247  int lod = requestInfo.getSession().getProtocolLOD();
248  String info = "<type name=\"" + nameAttr + "\" "
249  + "uri=\"" + uriAttr + "\" "
250  + "invalidAttribute=\"restrictedAttributes\"/>";
251  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
253  String msg = "Empty required attribute of add type of annotation.";
254  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
255  }
256  return;
257  }
258 
259  // test if group exist
260  Integer groupId = null;
261  try{
262  groupId = Integer.decode(groupUriAttr.replace(AppBean.getBaseGroupUri(), ""));
263  } catch(NumberFormatException e){
264  int langNum = requestInfo.getSession().getLanguageNum();
265  int lod = requestInfo.getSession().getProtocolLOD();
266  String info = "<type name=\"" + nameAttr + "\" "
267  + "uri=\"" + uriAttr + "\" "
268  + "invalidAttribute=\"groupUri\"/>";
269  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
271  String msg = "Can't decode group id.";
272  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
273  }
274  return;
275  }
276 
277  Object[] groupParams = new Object[2];
278  groupParams[0] = "id";
279  groupParams[1] = groupId;
280  @SuppressWarnings("unchecked")
281  List<UserGroup> groupsList = persistMan.queryDB("UserGroup.findById", groupParams);
282  if(groupsList == null || groupsList.isEmpty()){
283  // if grup was not found - error
284  int langNum = requestInfo.getSession().getLanguageNum();
285  int lod = requestInfo.getSession().getProtocolLOD();
286  String info = "<type name=\"" + nameAttr + "\" "
287  + "uri=\"" + uriAttr + "\" "
288  + "invalidAttribute=\"groupUri\"/>";
289  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
291  String msg = "Can't find group with id:" + groupId.toString();
292  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
293  }
294  return;
295  }
296 
297  // test if type is already in DB
298  Object[] typeParams = new Object[4];
299  typeParams[0] = "uri";
300  typeParams[1] = uriAttr;
301  typeParams[2] = "groupId";
302  typeParams[3] = groupId;
303  @SuppressWarnings("unchecked")
304  List<AnnotType> typesList = persistMan.queryDB("AnnotType.findByUriAndGroup", typeParams);
305 
306  if (typesList != null && !typesList.isEmpty() && !update) {
307  // if annotation type was found and it is not update - error
308  int langNum = requestInfo.getSession().getLanguageNum();
309  int lod = requestInfo.getSession().getProtocolLOD();
310  String info = "<type name=\"" + nameAttr + "\" uri=\"" + uriAttr + "\"/>";
311  requestInfo.addError(lod, langNum, Localisation.ERROR_49_DUPLICIT_TYPE, info);
313  String msg = "Attempt to create of duplicit type of annotation; uri: " + uriAttr;
314  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
315  }
316  return;
317  } else if ((typesList == null || typesList.isEmpty()) && update) {
318  // if it is update request and annotation type was not found - error
319  int langNum = requestInfo.getSession().getLanguageNum();
320  int lod = requestInfo.getSession().getProtocolLOD();
321  String info = "<type name=\"" + nameAttr + "\" uri=\"" + uriAttr + "\"/>";
322  requestInfo.addError(lod, langNum, Localisation.ERROR_19_TYPE_UNKNOWN, info);
324  String msg = "Unknown type of annotation for update: uri: " + uriAttr;
325  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
326  }
327  return;
328  }
329 
330  if(update){
331  typeForChange = typesList.get(0);
332  }
333 
334  // get ancestors
335  ArrayList<AnnotType> ancestors = new ArrayList<AnnotType>();
336  AnnotType primaryAncestor = null;
337  NodeList ancestorsMsg = typeElement.getElementsByTagName("directAncestors");
338  Element ancestorsEl = (Element) ancestorsMsg.item(0);
339 
340  if (ancestorsEl != null) {
341  String primaryAncestorUri = ancestorsEl.getAttribute("primary");
342  if (primaryAncestorUri != null && !primaryAncestorUri.isEmpty()) {
343  primaryAncestor = getAncestor(nameAttr, uriAttr, primaryAncestorUri);
344  if (primaryAncestor == null) {
345  this.direcAncestorPair.add(new Pair<String, AnnotType>(primaryAncestorUri, type));
346  }
347  if (!primaryAncestorUri.equals(foundAncUri)) {
348  // We must handle it as wrong URI as primary ancestor is different here
349  int langNum = requestInfo.getSession().getLanguageNum();
350  int lod = requestInfo.getSession().getProtocolLOD();
351  String info = "<type name=\"" + nameAttr + "\" "
352  + "uri=\"" + uriAttr + "\" "
353  + "invalidAttribute=\"uri\"/>";
354  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
356  String msg = "URI of added type of annotation contains wrong ancestor.";
357  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
358  }
359  return;
360  }
361  } else if (!foundAncUri.isEmpty()) { // if ancestor is missing but was found in URI
362  // We must handle it as wrong URI as ancestor was not declared
363  int langNum = requestInfo.getSession().getLanguageNum();
364  int lod = requestInfo.getSession().getProtocolLOD();
365  String info = "<type name=\"" + nameAttr + "\" "
366  + "uri=\"" + uriAttr + "\" "
367  + "invalidAttribute=\"uri\"/>";
368  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
370  String msg = "URI of added type of annotation contains missing ancestor.";
371  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
372  }
373  return;
374  }
375 
376  NodeList ancestorMsg = ancestorsEl.getElementsByTagName("ancestor");
377  int ancestorsCount = ancestorMsg.getLength();
378  for(int index = 0; index < ancestorsCount; index++){
379  Element ancestorEl = (Element) ancestorMsg.item(index);
380  String currentAncestorUri = processAncestors(nameAttr, uriAttr, ancestorEl);
381  AnnotType currentAncestor = getAncestor(nameAttr, uriAttr, currentAncestorUri);
382  if (currentAncestor != null) {
383  ancestors.add(currentAncestor);
384  } else {
385  this.ancestorPair.add(new Pair<String, AnnotType>(currentAncestorUri, type));
386  }
387  }
388  } else if (!foundAncUri.isEmpty()) { // if ancestor is missing but was found in URI
389  // We must handle it as wrong URI as ancestor was not declared
390  int langNum = requestInfo.getSession().getLanguageNum();
391  int lod = requestInfo.getSession().getProtocolLOD();
392  String info = "<type name=\"" + nameAttr + "\" "
393  + "uri=\"" + uriAttr + "\" "
394  + "invalidAttribute=\"uri\"/>";
395  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED, info);
397  String msg = "URI of added type of annotation contains missing ancestor.";
398  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
399  }
400  return;
401  }
402 
403  // process comment
404  String comment = null;
405  NodeList commentNL = typeElement.getElementsByTagName("comment");
406  if (commentNL.getLength() != 0) {
407  for(int index = 0; index < commentNL.getLength(); index ++){
408  Element commentEl = (Element) commentNL.item(index);
409  if(commentEl.getParentNode().getNodeName().equals(typeElement.getNodeName())){
410  comment = MessageProcessor.getElementContent(commentEl);
411  }
412  }
413  }
414 
415  if(update){
416  // test for forbidden changes
417  if(!typeForChange.getName().equals(nameAttr)){
418  // forbidden operation change name - error
419  int langNum = requestInfo.getSession().getLanguageNum();
420  int lod = requestInfo.getSession().getProtocolLOD();
421  String info = "<type name=\"" + typeForChange.getName()
422  + "\" uri=\"" + typeForChange.getUri()
423  + "\" invalidAttribute=\"name\"/>";
424  String msg = "Attempt to change name of the type of annotation: "
425  + typeForChange.getName() + " - " + nameAttr;
426  requestInfo.addError(lod, langNum, Localisation.ERROR_20_TYPE_NAME_MODIFY, info);
428  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
429  }
430  return;
431  }
432 
433  if(!typeForChange.getGroup().getUri().equals(groupUriAttr)){
434  // forbidden operation change group - error
435  int langNum = requestInfo.getSession().getLanguageNum();
436  int lod = requestInfo.getSession().getProtocolLOD();
437  String info = "<type name=\"" + typeForChange.getName()
438  + "\" uri=\"" + typeForChange.getUri()
439  + "\" invalidAttribute=\"groupUri\"/>";
440  String msg = "Attempt to change group of the type of annotation.";
441  requestInfo.addError(lod, langNum, Localisation.ERROR_20_TYPE_NAME_MODIFY, info);
443  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
444  }
445  return;
446  }
447 
448  if(((typeForChange.getAncestorType() == null && primaryAncestor != null) ||
449  (typeForChange.getAncestorType() != null && primaryAncestor != null)) &&
450  !(typeForChange.getAncestorType().equals(primaryAncestor))){
451  // forbidden operation change ancestor - error
452  int langNum = requestInfo.getSession().getLanguageNum();
453  int lod = requestInfo.getSession().getProtocolLOD();
454  String info = "<type name=\"" + typeForChange.getName()
455  + "\" uri=\"" + typeForChange.getUri()
456  + "\" invalidAttribute=\"ancestor\"/>";
457  String msg = "Attempt to change ancestor type of annotation.";
458  requestInfo.addError(lod, langNum, Localisation.ERROR_20_TYPE_NAME_MODIFY, info);
460  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
461  }
462  return;
463  }
464 
465  type.setId(typeForChange.getId());
466  }
467  // set group that type belongs
468  type.setGroup(groupsList.get(0));
469  // set restricted attributes
470  if(restrictedAttributesAttr.equalsIgnoreCase("true")){
471  type.setRestrictedAtt(true);
472  }else{
473  type.setRestrictedAtt(false);
474  }
475  // set name of type
476  type.setName(nameAttr);
477  // set uri of type
478  type.setUri(uriAttr);
479  // set uri in ontology
480  type.setUriInOntology(ontologyUriAttr);
481 
482  // set ancestors
483  type.setAncestorType(primaryAncestor);
484  type.setAncestorTypes(ancestors);
485 
486  // set commentary
487  type.setComment(comment);
488 
489  // get atrributes
490  ArrayList<AnnotTypeAttr> attributes = new ArrayList<AnnotTypeAttr>();
491  NodeList attributesMsg = typeElement.getElementsByTagName("attributes");
492  Element attributesEl = (Element) attributesMsg.item(0);
493  if(attributesEl != null){
494  NodeList attributeMsg = attributesEl.getElementsByTagName("attribute");
495  int attributesCount = attributeMsg.getLength();
496  for(int index = 0; index < attributesCount; index++){
497  Element attributeEl = (Element) attributeMsg.item(index);
498  AnnotTypeAttr currentAttr = processTypeAttribute(attributeEl,type);
499  if (currentAttr != null) {
500  attributes.add(currentAttr);
501  } else {
502  // type don't have any attributes
503  return;
504  }
505  }
506  }
507 
508  // set attributes
509  type.setAttributes(attributes);
510 
511  if (update) {
512  requestInfo.getFlier().AddEditedType(type);
513  } else {
514  requestInfo.getFlier().AddAddedType(type);
515  }
516  } // procesAnnotType()
517 
518  /**
519  * Method gets ancestor of annotation type from DB.
520  *
521  * @param name name of type for which we are searching ancestor
522  * @param typeUri uri of type for which we are searching ancestor
523  * @param uri uri of ancestor of annotation type
524  * @return annotation type object from DB or null if not found
525  */
526  private AnnotType getAncestor(String name, String typeUri, String uri){
527  AnnotType ancestor = null;
528 
529  // query database for ancestor
530  Object[] params = new Object[2];
531  params[0] = "uri";
532  params[1] = uri;
533 
534  PersistM persistMan = AppBean.getPersistenceManager();
535  @SuppressWarnings("unchecked")
536  List <AnnotType>aList = persistMan.queryDB("AnnotType.findByUri", params);
537  if (aList != null && !aList.isEmpty()) {
538  // if ancestor was found
539  ancestor = aList.get(0);
540  } else { // if ancestor was not found
541  // it possibly can be new type
542  Iterator<AnnotType> atIter = (Iterator<AnnotType>) requestInfo.getFlier().getAddedTypes().iterator();
543  while(atIter.hasNext() && ancestor == null) { // look over just added types
544  AnnotType addedT = atIter.next();
545  if (addedT.getUri().equals(uri)) { // if type was found
546  ancestor = addedT;
547  }
548  }
549 
550  if(ancestor == null) { // if ancestor is not new type
551  // unknown ancestor
552  int langNum = requestInfo.getSession().getLanguageNum();
553  int lod = requestInfo.getSession().getProtocolLOD();
554  String info = "<type name=\"" + name
555  + "\" uri=\"" + typeUri + "\" ancestor=\"" + uri + "\"/>";
556  requestInfo.addError(lod, langNum, Localisation.ERROR_19_TYPE_UNKNOWN, info);
558  String msg = "Unknown annotation type ancestor with uri:" + uri + "";
559  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
560  }
561  return null;
562  }
563  }
564 
565  return ancestor;
566  }
567 
568  /**
569  * Method process element with ancestor of annotation type.
570  *
571  * @param name Name of type of annotation to which ancestors should be assigned
572  * @param uri URI of type of annotation to which ancestors should be assigned
573  * @param ancestorEl element with type for add or update
574  * @return uri of ancestor of annotation type
575  */
576  private String processAncestors(String name, String uri, Element ancestorEl){
577  String uriAttr = ancestorEl.getAttribute("uri");
578  if(uriAttr == null || uriAttr.isEmpty()){
579  int langNum = requestInfo.getSession().getLanguageNum();
580  int lod = requestInfo.getSession().getProtocolLOD();
581  String info = "<type name=\"" + name
582  + "\" uri=\"" + uri + "\"/>";
583  requestInfo.addError(lod, langNum, Localisation.ERROR_55_TYPE_ANCESTORS_MALFORMED, info);
585  String msg = "Bad ancestor type in new type of annotation.";
586  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
587  }
588  return null;
589  }
590 
591  return uriAttr;
592  }
593 
594  /**
595  * Method process element with attribute of annotation type.
596  *
597  * @param attributeEl element with attribute of annotation type
598  * @param annotType Type of annotation to which this attribute belongs
599  * @return attribute of annotation type
600  */
601  private AnnotTypeAttr processTypeAttribute(Element attributeEl, AnnotType annotType){
602  AnnotTypeAttr newAttr = null;
603  Boolean isRequired = false;
604 
605  // get type attribute
606  String typeAttr = attributeEl.getAttribute("type");
607  if(typeAttr == null){
608  typeAttr = "";
609  }
610 
611  // get name attribute
612  String nameAttr = attributeEl.getAttribute("name");
613  if(nameAttr == null){
614  nameAttr = "";
615  }
616 
617  // get type attribute
618  String typeUriAttr = attributeEl.getAttribute("typeUri");
619  if(typeUriAttr == null){
620  typeUriAttr = "";
621  }
622 
623  // get uri in ontology attribute
624  String ontologyUriAttr = attributeEl.getAttribute("ontologyUri");
625  if(ontologyUriAttr == null){
626  ontologyUriAttr = "";
627  }
628 
629  // get required attribute
630  String requiredAttr = attributeEl.getAttribute("required");
631  if(requiredAttr == null){
632  requiredAttr = "";
633  }
634  if(requiredAttr.equalsIgnoreCase("true")){
635  isRequired = true;
636  }
637 
638  // test if all required attributes are presented
639  if(nameAttr.isEmpty()){
640  // missing name, uri of attribute type or information if attribute is required
641  int langNum = requestInfo.getSession().getLanguageNum();
642  int lod = requestInfo.getSession().getProtocolLOD();
643  String info = "<attribute typeName=\"" + annotType.getName() + "\" "
644  + "typeUri=\"" + annotType.getUri() + "\" "
645  + "name=\"" + nameAttr + "\" "
646  + "ontologyUri=\"" + ontologyUriAttr + "\" "
647  + "invalidAttribute=\"name\"/>";
648  requestInfo.addError(lod, langNum, Localisation.ERROR_17_TYPE_ATTRIBUTES_MALFORMED, info);
650  String msg = "Missing name, type uri or required attribute.";
651  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
652  }
653  return null;
654  }
655  if(typeUriAttr.isEmpty()){
656  // missing name, uri of attribute type or information if attribute is required
657  int langNum = requestInfo.getSession().getLanguageNum();
658  int lod = requestInfo.getSession().getProtocolLOD();
659  String info = "<attribute typeName=\"" + annotType.getName() + "\" "
660  + "typeUri=\"" + annotType.getUri() + "\" "
661  + "name=\"" + nameAttr + "\" "
662  + "ontologyUri=\"" + ontologyUriAttr + "\" "
663  + "invalidAttribute=\"type\"/>";
664  requestInfo.addError(lod, langNum, Localisation.ERROR_17_TYPE_ATTRIBUTES_MALFORMED, info);
666  String msg = "Missing name, type uri or required attribute.";
667  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
668  }
669  return null;
670  }
671  if (requiredAttr.isEmpty()) {
672  // missing name, uri of attribute type or information if attribute is required
673  int langNum = requestInfo.getSession().getLanguageNum();
674  int lod = requestInfo.getSession().getProtocolLOD();
675  String info = "<attribute typeName=\"" + annotType.getName() + "\" "
676  + "typeUri=\"" + annotType.getUri() + "\" "
677  + "name=\"" + nameAttr + "\" "
678  + "ontologyUri=\"" + ontologyUriAttr + "\" "
679  + "invalidAttribute=\"required\"/>";
680  requestInfo.addError(lod, langNum, Localisation.ERROR_17_TYPE_ATTRIBUTES_MALFORMED, info);
682  String msg = "Missing name, type uri or required attribute.";
683  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
684  }
685  return null;
686  }
687 
688  // get comment
689  String comment = null;
690  NodeList commentMsg = attributeEl.getElementsByTagName("comment");
691  Element commentEl = (Element) commentMsg.item(0);
692  if(commentEl != null){
693  comment = MessageProcessor.getElementContent(commentEl);
694  }
695 
696  // find type
697  if (Constants.SIMPLE_TYPES_URI_V2.contains(typeUriAttr)) { // if it's simple type
698  // create object with attribute of type of annotation
699  String typeName = Constants.SIMPLE_TYPES_NAMES_V2.get(Constants.SIMPLE_TYPES_URI_V2.indexOf(typeUriAttr));
700  newAttr = new AnnotTypeAttr(annotType, nameAttr, typeName, isRequired);
701  // set comment
702  newAttr.setComment(comment);
703  // set uri in ontology
704  newAttr.setUriInOntology(ontologyUriAttr);
705 
706  if (containsAttrName(annotType, nameAttr)) { // if it is duplicit attribute
707  // duplicit attribute
708  int langNum = requestInfo.getSession().getLanguageNum();
709  int lod = requestInfo.getSession().getProtocolLOD();
710  String info = "<attribute typeName=\"" + annotType.getName()
711  + "\" typeUri=\"" + annotType.getUri()
712  + "\" name=\"" + nameAttr
713  + "\" ontologyUri=\"" + ontologyUriAttr + "\"/>";
714  requestInfo.addError(lod, langNum, Localisation.ERROR_92_DUPLICIT_ATTRIBUTE_OF_TYPE, info);
716  String msg = "Duplicit attribute of the type of annotation.";
717  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
718  }
719 
720  return null;
721  }
722  } else { // if it is structured type
723  // if it's structured type query database for type of attribute (type of annotation)
724  Object[] typeParams = new Object[2];
725  typeParams[0] = "uri";
726  typeParams[1] = typeUriAttr;
727  PersistM persistMan = AppBean.getPersistenceManager();
728  List tList = persistMan.queryDB("AnnotType.findByUri", typeParams);
729  if (tList != null && !tList.isEmpty()) {
730  // if type was found
731  AnnotType attrStructType = (AnnotType) tList.get(0);
732  // create object with attribute of type of annotation
733  newAttr = new AnnotTypeAttr(annotType, nameAttr, attrStructType, isRequired);
734  // set comment
735  newAttr.setComment(comment);
736  // set uri in ontology
737  newAttr.setUriInOntology(ontologyUriAttr);
738 
739  // set information about type
740  if(typeAttr.equals("linked")){
741  newAttr.setSimpleType("annotationLink");
742  }else if(typeAttr.equals("nested")){
743  newAttr.setSimpleType("nestedAnnotation");
744  }
745 
746  if (containsAttrName(annotType,nameAttr)) {
747  // duplicit attribute
748  int langNum = requestInfo.getSession().getLanguageNum();
749  int lod = requestInfo.getSession().getProtocolLOD();
750  String info = "<attribute typeName=\"" + annotType.getName()
751  + "\" typeUri=\"" + annotType.getUri()
752  + "\" name=\"" + nameAttr
753  + "\" ontologyUri=\"" + ontologyUriAttr + "\"/>";
754  requestInfo.addError(lod, langNum, Localisation.ERROR_92_DUPLICIT_ATTRIBUTE_OF_TYPE, info);
756  String msg = "Duplicit attribute of the type of annotation.";
757  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
758  }
759  return null;
760  }
761  } else {
762  // try find annotation type in added types
763  ArrayList<AnnotType> addedTypes = requestInfo.getFlier().getAddedTypes();
764  if(addedTypes != null && !addedTypes.isEmpty()){
765  Iterator<AnnotType> addedTypesIt = addedTypes.iterator();
766  while(addedTypesIt.hasNext()){
767  AnnotType actualType = addedTypesIt.next();
768  if(actualType.getUri().equals(typeUriAttr)){
769  // create object with attribute of type of annotation
770  newAttr = new AnnotTypeAttr(annotType, nameAttr, actualType, isRequired);
771  // set comment
772  newAttr.setComment(comment);
773 
774  // set information about type
775  if(typeAttr.equals("linked")){
776  newAttr.setSimpleType("annotationLink");
777  }else if(typeAttr.equals("nested")){
778  newAttr.setSimpleType("nestedAnnotation");
779  }
780 
781  if (containsAttrName(annotType,nameAttr)) {
782  // duplicit attribute
783  int langNum = requestInfo.getSession().getLanguageNum();
784  int lod = requestInfo.getSession().getProtocolLOD();
785  String info = "<attribute typeName=\"" + annotType.getName()
786  + "\" typeUri=\"" + annotType.getUri()
787  + "\" name=\"" + nameAttr
788  + "\" ontologyUri=\"" + ontologyUriAttr + "\"/>";
789  requestInfo.addError(lod, langNum, Localisation.ERROR_92_DUPLICIT_ATTRIBUTE_OF_TYPE, info);
791  String msg = "Duplicit attribute of the type of annotation.";
792  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
793  }
794  return null;
795  }
796  }
797  }
798  } else {
799  int langNum = requestInfo.getSession().getLanguageNum();
800  int lod = requestInfo.getSession().getProtocolLOD();
801  // if type was not found - error
802  String info = "<attribute typeName=\"" + annotType.getName() + "\" "
803  + "typeUri=\"" + annotType.getUri() + "\" "
804  + "name=\"" + nameAttr + "\" "
805  + "ontologyUri=\"" + ontologyUriAttr + "\" "
806  + "invalidAttribute=\"typeUri\"/>";
807  requestInfo.addError(lod, langNum, Localisation.ERROR_17_TYPE_ATTRIBUTES_MALFORMED, info);
809  String msg = "Unknown structured type of attribute of the type of annotation: " + typeUriAttr;
810  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
811  }
812  return null;
813  }
814  }
815  } // if it is structured type
816 
817  return newAttr;
818  } // processTypeAttribute()
819 
820  /**
821  * Method process element with annotation types to delete.
822  *
823  * @param typeElement element with annotation types to delete
824  * @param requestInfo informations about client request
825  */
826  private void procesDeleteTypes(Element typeElement,RequestInfo requestInfo){
827  NodeList typesMsgs = typeElement.getElementsByTagName("type");
828  int typesListSize = typesMsgs.getLength();
829  for(int index = 0; index < typesListSize; index ++){
830  Element currentTypeEl = (Element) typesMsgs.item(index);
831  procesDeleteAnnotType(currentTypeEl,requestInfo);
832  }
833  }
834 
835  /**
836  * Method process element with annotation type to delete.
837  *
838  * @param typeElement element with annotation type to delete
839  * @param requestInfo informations about client request
840  */
841  private void procesDeleteAnnotType(Element typeElement,RequestInfo requestInfo){
842  // search for annotation type uri
843  String typeUri = typeElement.getAttribute("uri");
844  if(typeUri == null || typeUri.isEmpty()){
845  // nothing to delete
846  int langNum = requestInfo.getSession().getLanguageNum();
847  int lod = requestInfo.getSession().getProtocolLOD();
848  String info = "<type uri=\"" + typeUri + "\"/>";
849  requestInfo.addError(lod, langNum, Localisation.ERROR_19_TYPE_UNKNOWN, info);
851  String msg = "Attempt to remove type of annotation without uri.";
852  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
853  }
854 
855  return;
856  }
857 
858  // try to find annotation type by its uri
859  Object[] params = new Object[2];
860  params[0] = "uri";
861  params[1] = typeUri;
862  @SuppressWarnings("unchecked")
863  List<AnnotType> typesList = AppBean.getPersistenceManager().queryDB("AnnotType.findByUri", params);
864  if(typesList == null || typesList.isEmpty()){
865  int langNum = requestInfo.getSession().getLanguageNum();
866  int lod = requestInfo.getSession().getProtocolLOD();
867  String info = "<type uri=\"" + typeUri + "\"/>";
868  requestInfo.addError(lod, langNum, Localisation.ERROR_19_TYPE_UNKNOWN, info);
870  String msg = "Attempt to remove unknown type of annotation: " + typeUri;
871  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
872  }
873  return;
874  }
875 
876  // query database for annotations of this type
877  AnnotType dType = (AnnotType) typesList.get(0);
878  params[0] = "type";
879  params[1] = dType.getId();
880  List aList = AppBean.getPersistenceManager().queryDB("Annotation.findByType", params);
881  if(aList != null && !aList.isEmpty()) {
882  // ifannotations was found then it is forbidden operation beaciuse is used by some annotation
883  int langNum = requestInfo.getSession().getLanguageNum();
884  int lod = requestInfo.getSession().getProtocolLOD();
885  String info = "<type name=\"" + dType.getName() + "\" uri=\"" + dType.getUri() + "\"/>";
886  requestInfo.addError(lod, langNum, Localisation.ERROR_47_USED_TYPE_DEL, info);
888  String msg = "Attempt to delete used type of annotation: " + typeUri;
889  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
890  }
891  } else {
892  // ifannotations of this type was not found query database for subtypes of this type of annotation
893  params[0] = "ancestor";
894  params[1] = dType.getId();
895  List aTList = AppBean.getPersistenceManager().queryDB("AnnotType.findByAncestor", params);
896  if(aTList != null && !aTList.isEmpty()) {
897  // ifsubtypes was found then it is forbidden operation
898  int langNum = requestInfo.getSession().getLanguageNum();
899  int lod = requestInfo.getSession().getProtocolLOD();
900  String info = "<type name=\"" + dType.getName() + "\" uri=\"" + dType.getUri() + "\"/>";
901  requestInfo.addError(lod, langNum, Localisation.ERROR_51_TYPE_W_SUBTYPE_DEL, info);
903  String msg = "Attempt to delete type of annotation with subtypes: " + typeUri;
904  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
905  }
906  } else {
907  // ifsubtypes was not found add type to list of removed types in flier
908  requestInfo.getFlier().AddRemovedType(dType);
909  }
910  } // ifannotations of this type was not found
911  } // procesDeleteAnnotType()
912 
913  /**
914  * Method check if annotation type have attribute with specific name.
915  *
916  * @param annotType type in which method will seek
917  * @param name name of attribute which method will seek
918  * @return true if corresponding attribute is found
919  */
920  private boolean containsAttrName(AnnotType annotType, String name){
921  if(annotType.getAttributes() != null){
922  Iterator<AnnotTypeAttr> attrsIt = annotType.getAttributes().iterator();
923  while(attrsIt.hasNext()){
924  if(attrsIt.next().getName().equals(name)){
925  return true;
926  }
927  }
928  }
929 
930  return false;
931  }
932 
933  /**
934  * The method finds the ancestors of a new types which don't have the
935  * ancestors yet (they are in the same request probably). This covers
936  * only the types which had the ancestors filled out in the serialized form.
937  *
938  * @param types all new types
939  * @param requestInfo informations about client request
940  */
941  private void setMissingAncestors(ArrayList<AnnotType> types, RequestInfo requestInfo){
942  if(types != null){
943  Iterator<Pair<String,AnnotType>> ancestIt = this.ancestorPair.iterator();
944  while(ancestIt.hasNext()){
945  Pair<String,AnnotType> actualPair = ancestIt.next();
946  AnnotType findedAncestor = findTypeByUri(types,actualPair.left);
947  if(findedAncestor == null){
948  // cant find ancestor
949  int langNum = requestInfo.getSession().getLanguageNum();
950  int lod = requestInfo.getSession().getProtocolLOD();
951  String info = "<type name=\"" + actualPair.right.getName()
952  + "\" uri=\"" + actualPair.right.getUri() + "\" ancestor=\"" + actualPair.left + "\"/>";
953  requestInfo.addError(lod, langNum, Localisation.ERROR_19_TYPE_UNKNOWN, info);
955  String msg = "Bad ancestor type in new type of annotation: " + actualPair.left;
956  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
957  }
958 
959  deleteTypeByUri(types,actualPair.right.getUri());
960  ancestIt.remove();
961  continue;
962  }
963 
964  AnnotType actualType = actualPair.right;
965  actualType.addAncestorType(findedAncestor);
966  ancestIt.remove();
967  }
968  }
969  }
970 
971  /**
972  * The method finds the direct ancestor of a new types which don't have the
973  * direct ancestors yet (they are in the same request probably). This covers
974  * only the types which had the ancestors filled out in the serialized form.
975  *
976  * @param types all new types
977  * @param requestInfo informations about client request
978  */
979  private void setMissingDirectAncestors(ArrayList<AnnotType> types, RequestInfo requestInfo){
980  if(types != null){
981  // go trough all types without ancestor
982  Iterator<Pair<String,AnnotType>> ancestIt = this.direcAncestorPair.iterator();
983  while(ancestIt.hasNext()){
984  Pair<String,AnnotType> actualPair = ancestIt.next();
985  AnnotType findedAncestor = findTypeByUri(types,actualPair.left);
986  if(findedAncestor == null){
987  // cant find ancestor
988  int langNum = requestInfo.getSession().getLanguageNum();
989  int lod = requestInfo.getSession().getProtocolLOD();
990  String info = "<type name=\"" + actualPair.right.getName()
991  + "\" uri=\"" + actualPair.right.getUri() + "\" ancestor=\"" + actualPair.left + "\"/>";
992  requestInfo.addError(lod, langNum, Localisation.ERROR_19_TYPE_UNKNOWN, info);
994  String msg = "Bad ancestor type in new type of annotation: " + actualPair.left;
995  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
996  }
997 
998  deleteTypeByUri(types,actualPair.right.getUri());
999  ancestIt.remove();
1000  continue;
1001  }
1002 
1003  AnnotType actualType = actualPair.right;
1004  actualType.setAncestorType(findedAncestor);
1005  ancestIt.remove();
1006  }
1007  }
1008  }
1009 
1010  /**
1011  * Find type of annotation in the list
1012  *
1013  * @param types List of types of annotation
1014  * @param uri Uri of type of annotation which should be found
1015  * @return If it was found returns given type, null otherwise
1016  */
1017  AnnotType findTypeByUri(ArrayList<AnnotType> types, String uri){
1018  Iterator<AnnotType> typesIt = types.iterator();
1019  while(typesIt.hasNext()){
1020  AnnotType actualType = typesIt.next();
1021  if(actualType.getUri().equals(uri)){
1022  return actualType;
1023  }
1024  }
1025  return null;
1026  }
1027 
1028  /**
1029  * Removes type with given URI from list
1030  *
1031  * @param types List of types
1032  * @param uri URI of type which should be removed from the list
1033  */
1034  void deleteTypeByUri(ArrayList<AnnotType> types, String uri){
1035  Iterator<AnnotType> typesIt = types.iterator();
1036  while(typesIt.hasNext()){
1037  AnnotType actualType = typesIt.next();
1038  if(actualType.getUri().equals(uri)){
1039  typesIt.remove();
1040  return;
1041  }
1042  }
1043  }
1044 
1045  /**
1046  * Consistency check for primary ancestor and list of ancestors
1047  *
1048  * @param types List with types to check
1049  * @param requestInfo Informations about client request
1050  */
1051  private void checkAncestors(ArrayList<AnnotType> types, RequestInfo requestInfo){
1052  if(types != null){
1053  Iterator<AnnotType> typesIt = types.iterator();
1054  while(typesIt.hasNext()){
1055  AnnotType actualType = typesIt.next();
1056  if (actualType.getAncestorType() == null && (actualType.getAncestorTypesAL() != null && !actualType.getAncestorTypesAL().isEmpty())) {
1057  // error - primary ancestor is not choosed but there are some ancestors
1058  int langNum = requestInfo.getSession().getLanguageNum();
1059  int lod = requestInfo.getSession().getProtocolLOD();
1060  String context = "<type name=\"" + actualType.getName() + "\" uri=\"" + actualType.getUri() + "\" invalidAttribute=\"directAncestors\"/>";
1061  requestInfo.addError(lod, langNum, Localisation.ERROR_16_TYPE_MALFORMED,context);
1063  String msg = "Primary ancestor not choosed.";
1064  Logger.getLogger(P2AnnotTypeProcessor.class.getName()).log(Level.ALL, msg);
1065  }
1066 
1067  typesIt.remove();
1068  } else if (actualType.getAncestorType() != null && (actualType.getAncestorTypesAL() == null || actualType.getAncestorTypesAL().isEmpty())) {
1069  // there is primary ancestor but list of ancestors is empty
1070  if (actualType.getAncestorTypesAL() == null) {
1071  actualType.setAncestorTypes(new ArrayList<AnnotType>());
1072  }
1073  actualType.addAncestorType(actualType.getAncestorType());
1074  } else if (actualType.getAncestorType() != null) {
1075  if (!actualType.getAncestorTypesAL().contains(actualType.getAncestorType())) {
1076  actualType.addAncestorType(actualType.getAncestorType());
1077  }
1078  }
1079  }
1080  }
1081  } // checkAncestors()
1082 
1083  /**
1084  * Search for type in DB and currently added types which are stored in flier
1085  * @param uri Uri of annotation type
1086  * @param typesFromFlier ArrayList of annotation types, which have been recently added
1087  * @return
1088  */
1089  public static AnnotType searchAnnotType(String uri, ArrayList<AnnotType> typesFromFlier){
1090  if(typesFromFlier != null){
1091  Iterator<AnnotType> annotTypeIt = typesFromFlier.iterator();
1092  while(annotTypeIt.hasNext()){
1093  AnnotType tmpType = annotTypeIt.next();
1094  if(tmpType.getUri() != null && tmpType.getUri().equals(uri)){
1095  return tmpType;
1096  }
1097  }
1098  }
1099 
1100 
1101  PersistM persistMan = AppBean.getPersistenceManager();
1102  Object[] typeParams = new Object[2];
1103 
1104  typeParams[0] = "uri";
1105  typeParams[1] = uri;
1106 
1107  @SuppressWarnings("unchecked")
1108  List<AnnotType> attrsList = persistMan.queryDB("AnnotType.findByUri", typeParams);
1109  if(attrsList == null || attrsList.isEmpty()){
1110  return null;
1111  }
1112 
1113  return attrsList.get(0);
1114  }
1115 
1116 } // public class P2AnnotTypeProcessor
AnnotTypeAttr processTypeAttribute(Element attributeEl, AnnotType annotType)
void setMissingDirectAncestors(ArrayList< AnnotType > types, RequestInfo requestInfo)
void checkAncestors(ArrayList< AnnotType > types, RequestInfo requestInfo)
Persistence manager (database manipulator)
Definition: PersistM.java:35
Class representing attribute of type of annotation.
void procesAnnotType(Element typeElement, RequestInfo requestInfo, boolean update)
void procesTypesAdd(Element typesElement, RequestInfo requestInfo)
void procesTypesRemove(Element typesElement, RequestInfo requestInfo)
Singleton for storing global variables.
Definition: AppBean.java:47
void procesDeleteTypes(Element typeElement, RequestInfo requestInfo)
void procesDeleteAnnotType(Element typeElement, RequestInfo requestInfo)
void procesAnnotTypes(Element typesElement, RequestInfo requestInfo, boolean update)
Static class which parses and process XML with messages.
Class representing user group.
Definition: UserGroup.java:47
AnnotType findTypeByUri(ArrayList< AnnotType > types, String uri)
Class which parses and process XML with messages with types for protocol version 2.
static final ArrayList< String > SIMPLE_TYPES_URI_V2
Definition: Constants.java:175
void setMissingAncestors(ArrayList< AnnotType > types, RequestInfo requestInfo)
Class representing type of annotation.
Definition: AnnotType.java:58
Flier with informations for comet handlers.
Definition: Flier.java:31
static AnnotType searchAnnotType(String uri, ArrayList< AnnotType > typesFromFlier)
Processed informations about client request.
String processAncestors(String name, String uri, Element ancestorEl)
Class responsible for localised strings.
void procesTypeQuery(Element typesQueryElement, RequestInfo requestInfo)
Informations about client session.
void procesTypesChange(Element typesElement, RequestInfo requestInfo)
AnnotType getAncestor(String name, String typeUri, String uri)