4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
P2SuggestionProcessor.java
Go to the documentation of this file.
1 /*
2  * Project: Server for annotations sharing
3  * Author: Jaroslav Dytrych, Martin Petr
4  * File: P2SuggestionProcessor.java
5  * Description: Class which process XML elements with messages related
6  * to suggestions in 4A protocol v 2.0
7  */
8 
9 /**
10  * @file P2SuggestionProcessor.java
11  *
12  * @brief Class which process messages related to suggestions in protocol v 2.0
13  */
14 package cz.vutbr.fit.knot.annotations.comet.protocolV2_0;
15 
24 import static cz.vutbr.fit.knot.annotations.comet.protocolV2_0.P2AnnotBaseProcessor.getUriType;
43 import java.util.*;
44 import java.util.logging.Level;
45 import java.util.logging.Logger;
46 import org.w3c.dom.Element;
47 import org.w3c.dom.NodeList;
48 
49 /**
50  * Class which process XML elements with messages related to suggestions
51  * in 4A protocol v 2.0
52  *
53  * @brief Class which process messages related to suggestions in protocol v 2.0
54  * @author Martin Petr, Jaroslav Dytrych
55  */
57 
58  /**
59  * Method for processing of message with query for suggestions
60  *
61  * @param suggQueryEl Element with message
62  * @param requestInfo Informations about client request
63  */
64  public void processSuggestionQuery(Element suggQueryEl, RequestInfo requestInfo) {
65  // get minimal confidence attribute
66  String minConfidenceStr = suggQueryEl.getAttribute("minConfidence");
67  if(minConfidenceStr == null || minConfidenceStr.isEmpty()){
68  // error - minimal confidence attribute is required
69  int langNum = requestInfo.getSession().getLanguageNum();
70  int lod = requestInfo.getSession().getProtocolLOD();
71  requestInfo.addError(lod, langNum, Localisation.ERROR_95_MISSING_CONFIDENCE);
73  String msg = "Can't found minimal confidence attribute in request.";
74  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
75  }
76  }
77 
78  // convert to string with value to intege
79  Integer minConfidence;
80  try{
81  minConfidence = Integer.parseInt(minConfidenceStr);
82  } catch(NumberFormatException ex){
83  // error - bad format of minimal confidence
84  int langNum = requestInfo.getSession().getLanguageNum();
85  int lod = requestInfo.getSession().getProtocolLOD();
86  requestInfo.addError(lod, langNum, Localisation.ERROR_95_MISSING_CONFIDENCE);
88  String msg = "Can't decode minConfidence value. Value is: " + minConfidenceStr;
89  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
90  }
91  return;
92  }
93 
94  Integer autoConfirm = null;
95  // get autoconfirm attribute
96  String autoConfirmStr = suggQueryEl.getAttribute("autoConfirm");
97  if (autoConfirmStr != null && !autoConfirmStr.isEmpty()) {
98  try {
99  autoConfirm = Integer.parseInt(autoConfirmStr);
100  } catch (NumberFormatException ex) {
101  // error - bad format of autoConfirm
102  int langNum = requestInfo.getSession().getLanguageNum();
103  int lod = requestInfo.getSession().getProtocolLOD();
104  requestInfo.addError(lod, langNum, Localisation.ERROR_107_BAD_AUTOCONFIRM);
106  String msg = "Can't decode autoConfirm value. Value is: " + autoConfirmStr;
107  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
108  }
109  return;
110  }
111  }
112 
113  ArrayList<Fragment> fragments = new ArrayList<Fragment>();
114  NodeList fragmentsElems = suggQueryEl.getElementsByTagName("fragments");
115  Element fragmentsEl = (Element) fragmentsElems.item(0);
116  if(fragmentsEl != null) {
117  // fragments are presented
118  fragments = processSuggFragments(fragmentsEl,requestInfo);
119  if(fragments == null || fragments.isEmpty()){
120  // error occured (error message is printed by processSuggFragments())
121  return;
122  }
123  } else { // fragments element is not presented, create special fragment for whole document
124  fragments.add(new Fragment("", null, null));
125  }
126 
127  ArrayList<String> typesUris = null;
128  NodeList suggTypesElems = suggQueryEl.getElementsByTagName("types");
129  Element suggTypesEl = (Element) suggTypesElems.item(0);
130  if(suggTypesEl != null) {
131  typesUris = processSuggTypes(suggTypesEl,requestInfo);
132  if(typesUris == null || typesUris.isEmpty()){
133  // error occured (error message is printed by processSuggTypes())
134  return;
135  }
136  }
137 
138  if(autoConfirm == null){
139  requestInfo.setAutoconfirmRequested(false);
140  }else{
141  requestInfo.setAutoconfirmRequested(true);
142  }
143 
144  requestInfo.getSession().setAutoConfirm(autoConfirm);
145  requestInfo.getSession().setMinConfidence(minConfidence);
146  requestInfo.getSession().setSuggestionsFr(fragments);
147  requestInfo.getSession().setSuggestionsTypes(typesUris);
148  requestInfo.setSuggFragmentChanged(true);
149  if (requestInfo.getSession() != null) {
150  requestInfo.getSession().setSugRequestFlag(Boolean.TRUE);
151  }
152 
153  if (autoConfirm != null && autoConfirm > 0 && autoConfirm <= 100) { // reasonable is 1 - 100%
154  processSuggestionAutoConfirm(autoConfirm, requestInfo);
155  }
156  } // processSuggestionQuery()
157 
158  /**
159  * Method for processing of message with confirmation of suggestions
160  *
161  * @param suggConfirmEl Element with message
162  * @param requestInfo Informations about client request
163  */
164  public void processSuggestionConfirm(Element suggConfirmEl, RequestInfo requestInfo) {
165  ArrayList<Suggestion> allSuggest;
166  if (requestInfo.getSession().getDefaultGroup() == null) {
167  int lod = requestInfo.getSession().getProtocolLOD();
168  requestInfo.addError(lod, requestInfo.getSession().getLanguageNum(), Localisation.ERROR_97_NOT_IN_GROUP);
170  String msg = "User is not in any group.";
171  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.SEVERE, msg);
172  }
173  return;
174  } else { // if user is in any group
175  allSuggest = SuggestionManager.getSuggestionsFromDB(requestInfo.getSession().getSyncDocument().getId());
176  ArrayList<Suggestion> updatedSuggs = new ArrayList<Suggestion>();
177  ArrayList<Suggestion> removedSug = getSuggestionWithoutFeedback(requestInfo, allSuggest, updatedSuggs);
178  ArrayList<Suggestion> rSug = SuggestionManager.getNestedSuggFromToDelete(allSuggest, removedSug);
179  updatedSuggs.addAll(cutRefusedSuggLinks(allSuggest, rSug));
180 
181  // now we should have same list of Suggestions as in SuggestionManager
182  // so we know, what client see
183 
184  } // if user is in any group
185 
186 
187  // get all confirmed suggestion
188  NodeList confirmedElems = suggConfirmEl.getElementsByTagName("suggestion");
189  HashMap<String,Annotation> confirmedSuggestions = new HashMap<String,Annotation>();
190  ArrayList<Annotation> annotList = new ArrayList<Annotation>();
191 
192  for(int index = 0; index < confirmedElems.getLength(); index ++){
193  Element suggEl = (Element) confirmedElems.item(index);
194  if(suggEl != null){
195 
196  String suggModified = suggEl.getAttribute("modified");
197  if (suggModified == null && suggModified.isEmpty()) {
198  //error - can't find information about modification in suggestion
199  int langNum = requestInfo.getSession().getLanguageNum();
200  int lod = requestInfo.getSession().getProtocolLOD();
201  String suggUri = suggEl.getAttribute("uri");
202  if (suggUri == null) {
203  NodeList annotsElems = suggEl.getElementsByTagName("oa:Annotation");
204  Element annotEl = (Element) annotsElems.item(0);
205  if (annotEl != null) {
206  suggUri = annotEl.getAttribute("rdf:about");
207  }
208  }
209  if (suggUri == null) {
210  suggUri = "";
211  }
212  String info = "<suggestion uri=\"" + suggUri + "\"/>";
213  requestInfo.addError(lod, langNum, Localisation.ERROR_28_BAD_CONFIRM, info);
215  String msg = "Can't find information about modification in suggestion. Suggestion is not comfirmed. Index: " + Integer.toString(index);
216  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
217  }
218  continue;
219  }
220 
221  boolean modified = Boolean.valueOf(suggModified);
222 
223  SuggestionLogEntry logEntry;
224 
225  if (modified) {
226  NodeList annotsElems = suggEl.getElementsByTagName("oa:Annotation");
227  Element annotEl = (Element) annotsElems.item(0);
228  if (annotEl != null) {
229  Annotation newAnnotation = processAnnotation(annotEl, requestInfo);
230  if (newAnnotation != null) {
231  // here I have annotation
232  String idString = newAnnotation.getTmpId();
233 
234  logEntry = new SuggestionLogEntry(idString);
235  logEntry.setConfirmedVersion(newAnnotation);
236  requestInfo.getFlier().AddAddedAnnotation(newAnnotation);
237  logEntry.setConfirmMethod(Constants.CONFIRMED_MANUALLY_EDITED);
238 
239  confirmedSuggestions.put(newAnnotation.getTmpId(),newAnnotation);
240  annotList.add(newAnnotation);
241 
242  } else {
243  // can't parse annotation
244  return;
245  }
246  } else {
247  // error - there MUST be an annotation
248  int langNum = requestInfo.getSession().getLanguageNum();
249  int lod = requestInfo.getSession().getProtocolLOD();
250  String suggUri = suggEl.getAttribute("uri");
251  if (suggUri == null) {
252  suggUri = "";
253  }
254  String info = "<suggestion uri=\"" + suggUri + "\"/>";
255  requestInfo.addError(lod, langNum, Localisation.ERROR_103_MISSING_MODIFIED_SUG, info);
257  String msg = "There isn't oa:Annotation element in suggestion element of suggestion confirmation.";
258  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
259  }
260  return;
261  }
262  } else {
263  String suggUri = suggEl.getAttribute("uri");
264  if(suggUri == null && suggUri.isEmpty()){
265  //error - can't find uri of confirmed suggestion
266  int langNum = requestInfo.getSession().getLanguageNum();
267  int lod = requestInfo.getSession().getProtocolLOD();
268  String info = "<suggestion uri=\"\"/>";
269  requestInfo.addError(lod, langNum, Localisation.ERROR_28_BAD_CONFIRM, info);
271  String msg = "Can't find URI of confirmed suggestion. URI of confirmed suggestion is required.";
272  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
273  }
274  return;
275  }
276 
277  String idString = suggUri.replace(AppBean.getBaseUri() + "/sugg/","");
278  logEntry = new SuggestionLogEntry(idString);
279  logEntry.setConfirmMethod(Constants.CONFIRMED_MANUALLY);
280  }
281 
282  // find suggestion
283 
284  if (requestInfo.getSession().getSendedSuggestions() != null && !requestInfo.getSession().getSendedSuggestions().isEmpty()) {
285  Integer id = null;
286  try {
287  id = Integer.parseInt(logEntry.getTmpId());
288  } catch (NumberFormatException nfe) {
290  String msg = "The ID of the confirmed suggestion is not a number: " + logEntry.getTmpId();
291  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
292  }
293  }
294  // ID was parsed successfuly and the ID is contained within sended suggestions
295  if (id != null && requestInfo.getSession().isSuggInSendedSuggestions(id)) {
296 
297  Suggestion sended = SuggestionManager.getSuggestionFromList(id, allSuggest);
298  if (sended == null) {
300  String msg = "Unable to confirm suggestion with id = " + id + ". Suggestion with this id is not found in sended suggestions list.";
301  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
302  }
303  continue; // not found - imposssible to confirm
304  }
305 
306  Annotation sendedSug = new Annotation();
307  sendedSug.setTmpId(logEntry.getTmpId());
308  sendedSug.updateWithSuggestion(sended);
309  sendedSug.setUser(requestInfo.getSession().getUser());
310  sendedSug.setAuthorIdStr(requestInfo.getSession().getUser().getURIV2());
311  sendedSug.setAuthorAddress(requestInfo.getSession().getUser().getEmail());
312  sendedSug.setAuthorName(requestInfo.getSession().getUser().getName());
313  sendedSug.setCreated(new Date());
314  // set informations about confirmation
315  confirmedSuggestions.put(sended.getURIV2(), sendedSug);
316  annotList.add(sendedSug);
317  if (logEntry.getConfirmedVersion() == null) {
318  logEntry.setConfirmedVersion(sendedSug);
319  requestInfo.getFlier().AddAddedAnnotation(sendedSug);
320  }
321  if (!modified && requestInfo.getSession().getKBRefMode()) {
322  BaseAttribute uAAt = new BooleanAttribute(Constants.UPDATABLE_AN_AT_NAME, true, sendedSug);
323  sendedSug.getAttributes().add(uAAt);
324  }
325  logEntry.setSuggestion(sendedSug);
326  // add to list of confirmed suggestions
327  if (!requestInfo.getConfirmedSuggestions().contains(logEntry)) {
328  requestInfo.addConfirmedSuggestion(logEntry);
329  }
330  } else { // the suggestion's not been found
332  String msg = "Suggestion with the following ID not found: " + logEntry.getTmpId();
333  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
334  }
335  }
336  }
337  }
338  }
339  connectAnnotations(annotList,confirmedSuggestions,requestInfo);
340 
341  if (requestInfo.getSession().getEnableUpdatePositiveFeedback()) {
342  updatePositiveFeedback(requestInfo);
343  }
344  } // processSuggestionConfirm()
345 
346  /**
347  * Method for updating positive feedback
348  * Automatically cnfirms other similar (same annotated text and URI of entity)
349  * suggestions in the same part of document.
350  *
351  * @param requestInfo Informations about client request
352  * @return Automatically onfirmed suggestions
353  */
354  private ArrayList<SuggestionLogEntry> updatePositiveFeedback(RequestInfo requestInfo) {
355  ArrayList<SuggestionLogEntry> suggLog = requestInfo.getConfirmedSuggestions();
356  Integer groupId = requestInfo.getSession().getDefaultGroup().getId();
357 
358  ArrayList<SuggestionLogEntry> addToLog = new ArrayList<SuggestionLogEntry>();
359 
360  ArrayList<Suggestion> allSugg = requestInfo.getSession().getWholeSendedSuggestions();
361  if (allSugg != null && !allSugg.isEmpty()) { // if there are some sended suggestions
362  HashMap<Integer, ArrayList<SuggestionFragment>> sugToLinFragments = new HashMap<Integer, ArrayList<SuggestionFragment>>();
363  SECAPISuggestionTranslator.linearizeSuggestions(sugToLinFragments, requestInfo.getSession().getParsedSyncDocument(), allSugg);
364  ArrayList<Integer> separators = findSeparators(requestInfo.getSession().getParsedLinDocument());
365  int docLength = requestInfo.getSession().getParsedLinDocument().length();
366 
367  Iterator<SuggestionLogEntry> confSugIt = suggLog.iterator();
368  while (confSugIt.hasNext()) { // for each confirmed suggestion
369  SuggestionLogEntry confSugLogEntry = confSugIt.next();
370 
371  // get confirmed suggestion's annotated text
372  Integer confirmedSuggestionId = Integer.parseInt(confSugLogEntry.getTmpId());
373  Suggestion confirmedSuggestion = getSuggestionFromDB(confirmedSuggestionId);
374  ArrayList<SuggestionFragment> suggFragList = confirmedSuggestion.getFragmentsAL();
375  AnnotType confirmedSuggType = confirmedSuggestion.getAnnotType();
376 
377  // get confirmedURI
378  String confirmedURI = confirmedSuggestion.getSAEntityIdentifier();
379  if (confirmedURI != null && !confirmedURI.isEmpty()) { // if there is URI of Entity
380  if (suggFragList != null && !suggFragList.isEmpty()) { // if suggestion have at least one fragment
381  if (suggFragList.size() >= 2) {
382  Collections.sort(suggFragList, new SuggestionFragmentComp());
383  }
384 
385  // find separators for current suggestion
386  int leftSep = 0;
387  int rightSep = docLength;
388  Integer curOffset = null;
389  ArrayList<SuggestionFragment> frags = sugToLinFragments.get(confirmedSuggestionId);
390  SuggestionFragment frag;
391  if (frags != null && !frags.isEmpty()) {
392  frag = frags.get(0);
393  } else {
394  frag = null; // no fragments - maybe it is for whole document
395  }
396  if (frag != null) {
397  curOffset = frag.getOffset();
398  Iterator<Integer> sepIt = separators.iterator();
399  while (sepIt.hasNext()) {
400  Integer s = sepIt.next();
401  if (s < curOffset && leftSep < s) {
402  leftSep = s;
403  }
404  if (s > curOffset && s < rightSep) {
405  rightSep = s;
406  }
407  }
408  }
409 
410  Iterator<Suggestion> allSuggIt = allSugg.iterator();
411  while (allSuggIt.hasNext()) { // for each sended suggestion
412  Suggestion actualSugg = allSuggIt.next();
413 
414  // Find offset for comparison with separators
415  frags = sugToLinFragments.get(actualSugg.getId());
416  if (frags != null && !frags.isEmpty()) {
417  frag = frags.get(0);
418  } else {
419  frag = null;
420  }
421  if (frag != null) {
422  curOffset = frag.getOffset();
423  } else {
424  curOffset = null;
425  }
426 
427  // condition to ensure that sugg. are the same type and sugg. with the same id will be skipped
428  Integer actualSuggId = actualSugg.getId();
429  AnnotType actualSuggType = actualSugg.getAnnotType();
430  String actualURI = actualSugg.getSAEntityIdentifier();
431  if (actualSuggId != null && confirmedSuggestionId != null && !actualSuggId.equals(confirmedSuggestionId)
432  && actualSuggType != null && confirmedSuggType != null && actualSuggType.equals(confirmedSuggType)
433  && actualURI != null && confirmedURI.equals(actualURI)) {
434  // if it is not same suggestion but have same type and SEC API Entity URI
435  ArrayList<SuggestionFragment> tmpFragList = actualSugg.getFragmentsAL();
436  if (tmpFragList.size() >= 2) {
437  Collections.sort(tmpFragList, new SuggestionFragmentComp());
438  }
439  // check whether both suggestion fragment lists have the same amount of fragments
440  if (tmpFragList.size() == suggFragList.size()) {
441  Iterator<SuggestionFragment> tmpFragListIt = tmpFragList.iterator();
442  Iterator<SuggestionFragment> suggFragListIt = suggFragList.iterator();
443  Boolean errFlag = false;
444  // condition to check if !tmpFragList.isEmpty() is not needed
445  while (tmpFragListIt.hasNext()) {
446  // same annotated text
447  SuggestionFragment tmpFrag1 = tmpFragListIt.next();
448  SuggestionFragment tmpFrag2 = suggFragListIt.next();
449  if (!(tmpFrag1.getAnnotatedText()).equals(tmpFrag2.getAnnotatedText())) {
450  errFlag = true;
451  break;
452  }
453  // different path and offset
454  String path1 = tmpFrag1.getPath();
455  String path2 = tmpFrag2.getPath();
456  if (path1 != null && path2 != null && path1.equals(path2)) {
457  Integer offset1 = tmpFrag1.getOffset();
458  Integer offset2 = tmpFrag2.getOffset();
459  if (offset1 != null && offset2 != null && offset1.equals(offset2)) {
460  errFlag = true;
461  break;
462  }
463  }
464  }
465  if (curOffset != null) {
466  if (curOffset < leftSep || curOffset > rightSep) {
467  errFlag = true; // out of borders given by separators
468  }
469  }
470  if (haveNestedOrLinked(actualSugg)) {
471  errFlag = true; // this feature is not allowed if there are nested or linked attributes
472  }
473  if (!errFlag) {
474  SuggestionLogEntry tmpLogEntry = new SuggestionLogEntry((actualSugg.getId()).toString());
475  Annotation sendedSug = new Annotation();
476  sendedSug.setTmpId(tmpLogEntry.getTmpId());
477  sendedSug.updateWithSuggestion(actualSugg);
478  sendedSug.setUser(requestInfo.getSession().getUser());
479  sendedSug.setAuthorIdStr(requestInfo.getSession().getUser().getURIV2());
480  sendedSug.setAuthorAddress(requestInfo.getSession().getUser().getEmail());
481  sendedSug.setAuthorName(requestInfo.getSession().getUser().getName());
482  sendedSug.setCreated(new Date());
483  tmpLogEntry.setConfirmedVersion(sendedSug);
484  tmpLogEntry.setConfirmMethod(Constants.CONFIRMED_AUTOMATICALLY);
485  addToLog.add(tmpLogEntry);
486  requestInfo.getFlier().AddAddedAnnotation(sendedSug);
487  requestInfo.addAutoconfirmedSuggestion(tmpLogEntry);
488  }
489  }
490  } // if it is not same suggestion but have same type and SEC API Entity URI
491  } // for each sended suggestion
492  } // if suggestion have at least one fragment
493  } // if there is URI of Entity
494  } // for each confirmed suggestion
495  } // if there are some sended suggestions
496 
497  suggLog.addAll(addToLog); // add additional suggestions found
498 
499  return addToLog;
500  } // updatePositiveFeedback()
501 
502  /**
503  * Method loads suggestion specified by id from the database.
504  *
505  * @param id id that specify suggestions
506  * @return querried suggestion or null if suggestion isn't found
507  */
508  public static Suggestion getSuggestionFromDB(Integer id){
509  Object[] params = {"id",id};
510  @SuppressWarnings("unchecked")
511  List<Suggestion> suggestionList = AppBean.getPersistenceManager().queryDB("Suggestion.findById",params);
512  if(suggestionList != null && !suggestionList.isEmpty()){
513  return suggestionList.get(0);
514  }
515 
516  return null;
517  }
518 
519  /**
520  * Class which implements Comparator to sort arrayList of SuggestionFragment alphabetically
521  *
522  * @brief Class which implements Comparator to sort arrayList of SuggestionFragment alphabetically
523  */
524  class SuggestionFragmentComp implements java.util.Comparator<SuggestionFragment>{
525 
526  /**
527  * Compares two fragments according to offset and length
528  *
529  * @param frag1 First fragment
530  * @param frag2 Second fragment
531  * @return Returns a negative integer, zero, or a positive integer as first
532  * fragment is less than, equal to, or greater than the second fragment.
533  */
534  @Override
536  return (frag1.getAnnotatedText()).compareTo(frag2.getAnnotatedText());
537  }
538  }
539 
540  /**
541  * Finds offsets of all ocurrences of refuse border separator in linearized
542  * document (separators are defined in Constants)
543  *
544  * @param doc Linearized document
545  * @return Returns offsets of separators
546  */
547  private static ArrayList<Integer> findSeparators(String doc) {
548  ArrayList<Integer> result = new ArrayList<Integer>();
549  Iterator<String> sepIt = Constants.REFUSE_BORDER_SEPARATOR.iterator();
550  while (sepIt.hasNext()) {
551  String sep = sepIt.next();
552  int offset = doc.indexOf(sep);
553  while (offset >= 0) {
554  result.add(offset);
555  offset = doc.indexOf(sep, offset + 1);
556  }
557  }
558  Collections.sort(result);
559  return result;
560  } // findSeparators()
561 
562  /**
563  * Checks whether suggestion have some linked or nested attributes
564  *
565  * @param sug Suggestion to check
566  * @return Returns whether suggestion have some linked or nested attributes
567  */
568  private boolean haveNestedOrLinked(Suggestion sug) {
569  if (sug.getAttributes() == null) {
570  return false;
571  }
572  Iterator<SugBaseAttribute> sAttIt = sug.getAttributes().iterator();
573  while (sAttIt.hasNext()) {
574  SugBaseAttribute at = sAttIt.next();
575  if (at instanceof SugLinkedAttribute || at instanceof SugNestedAttribute) {
576  return true;
577  }
578  if (at.getSimpleType() != null && (at.getSimpleType().equalsIgnoreCase("linkedSuggestion")
579  || at.getSimpleType().equalsIgnoreCase("nestedSuggestion")
580  || at.getSimpleType().equalsIgnoreCase("linkedAnnotation")
581  || at.getSimpleType().equalsIgnoreCase("nestedAnnotation"))) {
582  // it is possible that instance is not good so it is better to do second check
583  return true;
584  }
585  }
586 
587  return false;
588  } // haveNestedOrLinked()
589 
590  /**
591  * Process request to automatically confirm the suggestions (part of request
592  * for suggestions)
593  *
594  * Dependencies with lower confidence are also confirmed!
595  *
596  * @param minConfidence Minimal confidence to automatically confirm suggestion
597  * @param requestInfo Informations about client request
598  */
599  public void processSuggestionAutoConfirm(Integer minConfidence,RequestInfo requestInfo){
600  if (requestInfo.getSession().getDefaultGroup() == null) {
601  int lod = requestInfo.getSession().getProtocolLOD();
602  requestInfo.addError(lod, requestInfo.getSession().getLanguageNum(), Localisation.ERROR_97_NOT_IN_GROUP);
604  String msg = "User is not in any group.";
605  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.SEVERE, msg);
606  }
607  return;
608  }
609 
610  EditorSession session = requestInfo.getSession();
611 
612  ArrayList<Suggestion> allSuggest = SuggestionManager.getSuggestionsFromDB(requestInfo.getSession().getSyncDocument().getId());
613  if (allSuggest == null || allSuggest.isEmpty()) {
614  // Error - suggestions are not ready (it is necessary to try it later)
615  int langNum = requestInfo.getSession().getLanguageNum();
616  int lod = requestInfo.getSession().getProtocolLOD();
617  requestInfo.addError(lod, langNum, Localisation.ERROR_101_SUGGESTIONR_NOT_READY);
619  String msg = "Suggestions are not ready (it is necessary to try it later).";
620  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
621  }
622  return;
623  }
624  ArrayList<Suggestion> filteredSuggest = new ArrayList<Suggestion>(allSuggest);
625  SuggestionManager.filtrateSuggestions(requestInfo, session, filteredSuggest);
626  ArrayList<Suggestion> shouldHave = SuggestionManager.addAllDependencies(filteredSuggest, allSuggest);
627  ArrayList<Suggestion> updatedSuggs = new ArrayList<Suggestion>();
628  ArrayList<Suggestion> removedSug = getSuggestionWithoutFeedback(requestInfo, shouldHave, updatedSuggs);
629  ArrayList<Suggestion> rSug = SuggestionManager.getNestedSuggFromToDelete(shouldHave, removedSug);
630  updatedSuggs.addAll(cutRefusedSuggLinks(shouldHave, rSug));
631  ArrayList<AnnotType> newTypes = new ArrayList<AnnotType>();
632  SuggestionManager.checkTypes(session, shouldHave, newTypes, true);
633  SuggestionManager.persistTypes(newTypes);
634  // message with types
635  String msgTypes = SuggestionManager.printTypes(requestInfo, session, newTypes);
636  // send types to others
637  SuggestionManager.sendToOthers(requestInfo, msgTypes);
638 
639  // Here we should have list of suugestions which client can get according to
640  // just received request
641 
642  // get IDs of all confirmed suggestions
643  ArrayList<Suggestion> allConfSugs = new ArrayList<Suggestion>();
644 
645  Iterator<Suggestion> shouldHaveIt = shouldHave.iterator();
646  while (shouldHaveIt.hasNext()) {
647  Suggestion sug = shouldHaveIt.next();
648  if (sug == null) {
649  continue;
650  }
651  if (sug.getConfidence() < minConfidence) {
652  continue;
653  }
654  allConfSugs.add(sug);
655  }
656 
657  // Add dependencies with lower confidence
658  allConfSugs = SuggestionManager.addAllDependencies(allConfSugs, shouldHave);
659 
660  HashMap<String,Annotation> confirmedSuggestions = new HashMap<String,Annotation>();
661  ArrayList<Annotation> annotList = new ArrayList<Annotation>();
662 
663  Iterator<Suggestion> confSugIt = allConfSugs.iterator();
664  while (confSugIt.hasNext()) {
665  Suggestion sended = confSugIt.next();
666  Integer id = sended.getId();
667  String idString = id.toString();
668 
669  SuggestionLogEntry logEntry = new SuggestionLogEntry(idString);
670  logEntry.setConfirmMethod(Constants.CONFIRMED_AUTOMATICALLY);
671 
672  Annotation sendedSug = new Annotation();
673  sendedSug.setTmpId(logEntry.getTmpId());
674  sendedSug.updateWithSuggestion(sended);
675  sendedSug.setUser(requestInfo.getSession().getUser());
676  sendedSug.setAuthorIdStr(requestInfo.getSession().getUser().getURIV2());
677  sendedSug.setAuthorAddress(requestInfo.getSession().getUser().getEmail());
678  sendedSug.setAuthorName(requestInfo.getSession().getUser().getName());
679  sendedSug.setCreated(new Date());
680  // set informations about confirmation
681  confirmedSuggestions.put(sended.getURIV2(), sendedSug);
682  annotList.add(sendedSug);
683  if (logEntry.getConfirmedVersion() == null) {
684  logEntry.setConfirmedVersion(sendedSug);
685  requestInfo.getFlier().AddAddedAnnotation(sendedSug);
686  }
687  if (requestInfo.getSession().getKBRefMode()) {
688  BaseAttribute uAAt = new BooleanAttribute(Constants.UPDATABLE_AN_AT_NAME, true, sendedSug);
689  sendedSug.getAttributes().add(uAAt);
690  }
691  logEntry.setSuggestion(sendedSug);
692  // add to list of confirmed suggestions
693  if (!requestInfo.getConfirmedSuggestions().contains(logEntry)) {
694  requestInfo.addConfirmedSuggestion(logEntry);
695  requestInfo.addAutoconfirmedSuggestion(logEntry);
696  }
697  }
698  connectAnnotations(annotList, confirmedSuggestions,requestInfo);
699 
700  } // processSuggestionAutoConfirm()
701 
702  /**
703  * Method which reconstruct links between annotation objects (references
704  * to appropriate objects) using URIs in attributes. For example if there
705  * is link to another annotation but only URI of annotation is set
706  * in the attribute, it will set also reference to linked annotation.
707  * It also reconstruct both sides of nesting relation.
708  *
709  * @param annotsToConnect List of annotation in which links should be reconstructed.
710  * @param tmpIdMap Map with mapping of URIs to objects
711  * @param requestInfo Informations about client request
712  */
713  private void connectAnnotations(ArrayList<Annotation> annotsToConnect, HashMap<String, Annotation> tmpIdMap, RequestInfo requestInfo) {
714  Iterator<Annotation> connectIt = annotsToConnect.iterator();
715  while (connectIt.hasNext()) { // for each annotation in the list
716 
717  // go trough all added annotations
718  Annotation actualAnnot = connectIt.next();
719  if (actualAnnot.getAttributes() != null) { // if annotation have some attributes
720 
721  // go tough all attributes
722  Iterator<BaseAttribute> attributesIt = actualAnnot.getAttributes().iterator();
723  while (attributesIt.hasNext()) { // for each attribute
724 
725  // try find nested or linked attribute
726  BaseAttribute actualAttribute = attributesIt.next();
727  if ((actualAttribute instanceof LinkedAnnotationAttribute)) { // if it is link to annotation
728  if (actualAttribute.getUri() != null && !actualAttribute.getUri().isEmpty()) {
729  // try find annotation uri in just added annotations
730 
731  String annotUri = actualAttribute.getUri();
732  String uriType = getUriType(annotUri);
733 
734  if (uriType.equals("sugg")) {
735  Annotation findedAnnot = tmpIdMap.get(actualAttribute.getUri());
736  if (findedAnnot != null) {
737  ((LinkedAnnotationAttribute) actualAttribute).setValue(findedAnnot);
738  }
739  } else if (uriType.equals("serv")) {
740  Integer id = null;
741  String idString = annotUri.replace(AppBean.getBaseUri() + "/serv/", "");
742  try {
743  id = Integer.decode(idString);
744  } catch (NumberFormatException ex) {
745  // error - cant decode id
746  int langNum = requestInfo.getSession().getLanguageNum();
747  int lod = requestInfo.getSession().getProtocolLOD();
748  String info = "<attribute annotationUri=\"" + actualAnnot.getURIV2()
749  + "\" uri=\"" + actualAttribute.getUriInOntology()
750  + "\" name=\"" + actualAttribute.getName()
751  + "\" valueType=\"" + actualAttribute.getValueType()
752  + "\" type=\"" + actualAttribute.getTypeUriV2() + "\"/>";
753  requestInfo.addError(lod, langNum, Localisation.ERROR_7_ATTRIBUTE_VALUE, info);
755  String msg = "Can't decode suggestion id. Id value: " + idString;
756  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
757  }
758  continue;
759  }
760 
761  PersistM persistMan = AppBean.getPersistenceManager();
762 
763  Object[] annotParams = new Object[2];
764  annotParams[0] = "id";
765  annotParams[1] = id;
766 
767  @SuppressWarnings("unchecked")
768  List<Annotation> annotList = persistMan.queryDB("Annotation.findById", annotParams);
769  if (annotList == null || annotList.isEmpty()) {
770  //error - cant find linked annot in DB
771  int langNum = requestInfo.getSession().getLanguageNum();
772  int lod = requestInfo.getSession().getProtocolLOD();
773  String info = "<attribute annotationUri=\"" + actualAnnot.getURIV2()
774  + "\" uri=\"" + actualAttribute.getUriInOntology()
775  + "\" name=\"" + actualAttribute.getName()
776  + "\" valueType=\"" + actualAttribute.getValueType()
777  + "\" type=\"" + actualAttribute.getTypeUriV2() + "\"/>";
778  requestInfo.addError(lod, langNum, Localisation.ERROR_7_ATTRIBUTE_VALUE, info);
780  String msg = "Can't find linked annot in DB. Id value: " + idString;
781  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
782  }
783  continue;
784  }
785 
786  LinkedAnnotationAttribute actualLinked = (LinkedAnnotationAttribute) actualAttribute;
787  actualLinked.setValue(annotList.get(0));
788  actualLinked.setAttributeType(annotList.get(0).getAnnotType());
789  }
790  }
791  } // if it is link to annotation
792 
793 
794  if ((actualAttribute instanceof NestedAnnotationAttribute)) {
795  NestedAnnotationAttribute nestedAttr = (NestedAnnotationAttribute) actualAttribute;
796  if (actualAttribute.getUri() != null && !actualAttribute.getUri().isEmpty()) {
797  // try find annotation uri in just added annotations
798  Annotation findedAnnot = tmpIdMap.get(actualAttribute.getUri());
799  nestedAttr.setValue(findedAnnot);
800  findedAnnot.setNestedInAnnot(nestedAttr.getRefAnnotation());
801  }
802  }
803  } // for each attribute
804  } // if annotation have some attributes
805  } // for each annotation in the list
806  } // connectAnnotations()
807 
808  /**
809  * Method for processing of message with refusing of suggestions
810  *
811  * @param suggRefuseEl Element with message
812  * @param requestInfo Informations about client request
813  */
814  public void processSuggestionRefuse(Element suggRefuseEl, RequestInfo requestInfo) {
815  // get all refused suggestion
816  NodeList refusedElems = suggRefuseEl.getElementsByTagName("suggestion");
817 
818  for(int index = 0; index < refusedElems.getLength(); index ++){ // for each refused
819  Element suggEl = (Element) refusedElems.item(index);
820  if(suggEl != null){
821  String suggUri = suggEl.getAttribute("uri");
822  if(suggUri == null && suggUri.isEmpty()){
823  //error - can't find uri of refused suggestion
824  int langNum = requestInfo.getSession().getLanguageNum();
825  int lod = requestInfo.getSession().getProtocolLOD();
826  String info = "<suggestion uri=\"\"/>";
827  requestInfo.addError(lod, langNum, Localisation.ERROR_28_BAD_CONFIRM, info);
829  String msg = "Can't find uri of refused annotation suggestion.";
830  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
831  }
832  continue;
833  }
834 
835  String idString = suggUri.replace(AppBean.getBaseUri() + "/sugg/","");
836  SuggestionLogEntry logEntry = new SuggestionLogEntry(idString);
837  logEntry.setRefuseMethod(Constants.REFUSED_MANUALLY);
838 
839  // find suggested annotation in list of suggestions
840  if (requestInfo.getSession().getSendedSuggestions() != null && !requestInfo.getSession().getSendedSuggestions().isEmpty()) {
841  Integer id = null;
842  try {
843  id = Integer.parseInt(idString);
844  } catch (NumberFormatException nfe) {
846  String msg = "The ID of the refused suggestion is not a number: " + idString;
847  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
848  }
849  }
850  // ID was parsed successfuly and the ID is contained within sended suggestions
851  if (id != null && requestInfo.getSession().isSuggInSendedSuggestions(id)) {
852  Annotation refused = new Annotation();
853  refused.updateWithSuggestion(requestInfo.getSession().getWholeSendedSuggestion(id));
854  logEntry.setSuggestion(refused);
855  }
856  } else { // the suggestion's not been found
858  String msg = "Suggestion with the following ID not found: " + idString;
859  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
860  }
861  continue;
862  }
863 
864  requestInfo.addRefusedSuggestion(logEntry);
865  }
866  } // for each refused
867 
868  requestInfo.getOrigRefusedSuggestions().addAll(requestInfo.getRefusedSuggestions());
869  } // processSuggestionRefuse()
870 
871  /**
872  * Method for processing of message with request for alternatives
873  *
874  * @param getAltEl Element with message
875  * @param requestInfo Informations about client request
876  */
877  public void processGetAlternatives(Element getAltEl, RequestInfo requestInfo) {
878  // get all suggestions
879  NodeList getAltElems = getAltEl.getElementsByTagName("suggestion");
880 
881  for(int index = 0; index < getAltElems.getLength(); index ++){ // for each suggestion
882  Element suggEl = (Element) getAltElems.item(index);
883  if(suggEl != null){
884  String suggUri = suggEl.getAttribute("uri");
885  if(suggUri == null && suggUri.isEmpty()){
886  //error - can't find uri of suggestion
887  int langNum = requestInfo.getSession().getLanguageNum();
888  int lod = requestInfo.getSession().getProtocolLOD();
889  // There can be some message for client in the future but now it is not needed
890  // requestInfo.addError(lod, langNum, Localisation., info);
892  String msg = "Can't find uri of suggestion.";
893  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
894  }
895  continue;
896  }
897 
898  String idString = suggUri.replace(AppBean.getBaseUri() + "/sugg/","");
899 
900  // find suggested annotation in list of suggestions
901  if (requestInfo.getSession().getSendedSuggestions() != null && !requestInfo.getSession().getSendedSuggestions().isEmpty()) {
902  Integer id = null;
903  try {
904  id = Integer.parseInt(idString);
905  } catch (NumberFormatException nfe) {
907  String msg = "The ID of the suggestion is not a number: " + idString;
908  Logger.getLogger(P2SuggestionProcessor.class.getName()).log(Level.ALL, msg);
909  }
910  }
911  // ID was parsed successfuly and the ID is contained within sended suggestions
912  if (id != null && requestInfo.getSession().isSuggInSendedSuggestions(id)) {
913  requestInfo.addSugToAlternativesRequestedFor(requestInfo.getSession().getWholeSendedSuggestion(id));
914  }
915  } else { // the suggestion's not been found
917  String msg = "Suggestion with the following ID was not found: " + idString;
918  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
919  }
920  continue;
921  }
922  }
923  } // for each suggestion
924  } // processGetAlternatives()
925 
926  /**
927  * Processes elements with fragments for which annotations should be suggested
928  *
929  * @param fragmentsEl Elements with fragments
930  * @param requestInfo Informations about client request
931  * @return Returns list of processed fragments
932  */
933  private ArrayList<Fragment> processSuggFragments(Element fragmentsEl, RequestInfo requestInfo){
934  // get all fragment nodes
935  NodeList fragmentElems = fragmentsEl.getElementsByTagName("fragment");
936  ArrayList<Fragment> resultsFragments = new ArrayList<Fragment>(fragmentElems.getLength());
937 
938  // go trough all fragment elements
939  for(int index = 0; index < fragmentElems.getLength(); index++){
940  Element currentFragmentsEl = (Element) fragmentElems.item(0);
941  if(currentFragmentsEl != null){
942  Fragment newFragment = new Fragment();
943 
944  // get XPath attribute (required)
945  String xPathString = currentFragmentsEl.getAttribute("path");
946  if(xPathString == null || xPathString.isEmpty()){
947  // error - XPath attribute is required in attribute element
948  int langNum = requestInfo.getSession().getLanguageNum();
949  int lod = requestInfo.getSession().getProtocolLOD();
950  requestInfo.addError(lod, langNum, Localisation.ERROR_8_SUG_FRAGMENT);
952  String msg = "XPath attribute is required in suggestion request fragment element.";
953  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
954  }
955  }
956 
957  // get offset attribute
958  Integer offset;
959  String attributeString = currentFragmentsEl.getAttribute("offset");
960  if (attributeString == null || attributeString.isEmpty()) {
961  offset = null;
962  } else {
963  try {
964  offset = Integer.parseInt(attributeString);
965  } catch (NumberFormatException ex) {
966  // error - bad format of fragment offset
967  int langNum = requestInfo.getSession().getLanguageNum();
968  int lod = requestInfo.getSession().getProtocolLOD();
969  requestInfo.addError(lod, langNum, Localisation.ERROR_8_SUG_FRAGMENT);
971  String msg = "Can't decode fragment offset. Value of offset: " + attributeString;
972  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
973  }
974  return null;
975  }
976  }
977 
978  Integer length;
979  String lengthString = currentFragmentsEl.getAttribute("length");
980  if(lengthString == null || lengthString.isEmpty()){
981  length = null;
982  }else{
983  try {
984  length = Integer.parseInt(lengthString);
985  } catch (NumberFormatException ex) {
986  // error - bad format of length offset
987  int langNum = requestInfo.getSession().getLanguageNum();
988  int lod = requestInfo.getSession().getProtocolLOD();
989  requestInfo.addError(lod, langNum, Localisation.ERROR_8_SUG_FRAGMENT);
991  String msg = "Can't decode fragment length. Value of length: " + lengthString;
992  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
993  }
994  return null;
995  }
996  }
997 
998  // improve XPath to be usable
999  String sPath = UpdatableFragment.improveXPath(xPathString);
1000  // create object with fragment
1001  newFragment = new Fragment(sPath, offset, length);
1002  // add new fragment
1003  resultsFragments.add(newFragment);
1004  }
1005  }
1006  return resultsFragments;
1007  } // processSuggFragments()
1008 
1009  /**
1010  * Processes elements with types of annotations which should be suggested
1011  *
1012  * @param typesEl Elements with types
1013  * @param requestInfo Informations about client request
1014  * @return Returns list of URIs of types
1015  */
1016  private ArrayList<String> processSuggTypes(Element typesEl, RequestInfo requestInfo) {
1017  // get all annotation types
1018  NodeList annotTypeElems = typesEl.getElementsByTagName("type");
1019  ArrayList<String> resultsAnnotType = new ArrayList<String>(annotTypeElems.getLength());
1020 
1021  // go trough all annotation types elements
1022  for (int index = 0; index < annotTypeElems.getLength(); index++) {
1023  Element currentAnnotTypesEl = (Element) annotTypeElems.item(0);
1024  if (currentAnnotTypesEl != null) {
1025  // get uri of annotation type uri (required)
1026  String typeUriString = currentAnnotTypesEl.getAttribute("uri");
1027  if (typeUriString == null || typeUriString.isEmpty()) {
1028  // error - annotation type uri is required
1029  int langNum = requestInfo.getSession().getLanguageNum();
1030  int lod = requestInfo.getSession().getProtocolLOD();
1031  String info = "<type uri=\"\"/>";
1032  requestInfo.addError(lod, langNum, Localisation.ERROR_40_BAD_SUGG_TYPE, info);
1034  String msg = "Annotation type uri is required.";
1035  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
1036  }
1037  return null;
1038  }
1039 
1040  // find annotation type in DB
1041  PersistM persistMan = AppBean.getPersistenceManager();
1042 
1043  Object[] params = new Object[2];
1044  params[0] = "uri";
1045  params[1] = typeUriString;
1046 
1047  @SuppressWarnings("unchecked")
1048  List<AnnotType> annotTypeList = persistMan.queryDB("AnnotType.findByUri", params);
1049  if(annotTypeList != null && !annotTypeList.isEmpty()){
1050  resultsAnnotType.add(typeUriString);
1051  }else{
1052  // error - can't find annotation type of suggestion request
1053  int langNum = requestInfo.getSession().getLanguageNum();
1054  int lod = requestInfo.getSession().getProtocolLOD();
1055  String info = "<type uri=\"" + typeUriString + "\"/>";
1056  requestInfo.addError(lod, langNum, Localisation.ERROR_40_BAD_SUGG_TYPE, info);
1058  String msg = "Can't find annotation type of suggestion request. Type uri: " + typeUriString;
1059  Logger.getLogger(MessageProcessor.class.getName()).log(Level.ALL, msg);
1060  }
1061  return null;
1062  }
1063  }
1064  }
1065 
1066  return resultsAnnotType;
1067  } // processSuggTypes()
1068 
1069 
1070  /**
1071  * Removes suggestions with feedback from the list and replaces all references
1072  * to them by annotations from feedback (for negative feedback by null).
1073  *
1074  * @param requestInfo Informations about client request
1075  * @param list List of suggestions
1076  * @param modified List to which modified suggestions will be added
1077  * @return Removed suggestions from list.
1078  */
1079  private ArrayList<Suggestion> getSuggestionWithoutFeedback(RequestInfo requestInfo, ArrayList<Suggestion> list, ArrayList<Suggestion> modified) {
1080  ArrayList<Suggestion> removedSuggestions = new ArrayList<Suggestion>();
1081  UserGroup defGroup = requestInfo.getSession().getDefaultGroup();
1082  int defaultUserGroupID = defGroup.getId();
1083 
1084  List<SuggestionFeedback> feedList = SuggestionManager.getFeedbackFromDB(requestInfo.getSession().getSyncDocument().getId(), defaultUserGroupID);
1085  ArrayList<SuggestionFeedback> feedListOtherGroups = new ArrayList<SuggestionFeedback>();
1086 
1087  if (requestInfo.getSession().getUser() != null) {
1088  Iterator<UserGroup> allUserGroups = requestInfo.getSession().getUser().getGroupsAL().iterator();
1089  while(allUserGroups.hasNext()){
1090  UserGroup group = allUserGroups.next();
1091  if(group.getId() != defaultUserGroupID){
1092  List<SuggestionFeedback> feed = SuggestionManager.getFeedbackFromDB(requestInfo.getSession().getSyncDocument().getId(), group.getId());
1093  feedListOtherGroups.addAll(feed);
1094  }
1095  }
1096  }
1097 
1098  // delete suggestions with positiveFeedback in default group
1099  for (Iterator<SuggestionFeedback> it = feedList.iterator(); it.hasNext();) {
1100  SuggestionFeedback fb = it.next();
1101  if (fb.getSuggestion() == null) {
1102  continue;
1103  }
1104  Suggestion sgFromList = SuggestionManager.getSuggestionFromList(fb.getSuggestion().getId(), list);
1105  if (sgFromList != null) { // suggestion was found
1106  feedbackChangeRef(list, sgFromList, modified, fb, removedSuggestions);
1107  }
1108  }
1109 
1110  // delete suggestions with positiveFeedback in other group
1111  for (Iterator<SuggestionFeedback> it = feedListOtherGroups.iterator(); it.hasNext();) {
1112  SuggestionFeedback fb = it.next();
1113  if (fb.getSuggestion() == null) {
1114  continue;
1115  }
1116  Suggestion sgFromList = SuggestionManager.getSuggestionFromList(fb.getSuggestion().getId(), list);
1117  if (sgFromList != null) { // suggestion was found
1118  feedbackChangeRef(list, sgFromList, modified, fb, removedSuggestions);
1119  }
1120  }
1121 
1122  return removedSuggestions;
1123  } // getSuggestionWithoutFeedback()
1124 
1125  /**
1126  * Adds links in suggestion to modified suggs
1127  *
1128  * @param list List of suggestions
1129  * @param sgFromList Suggestion to check for links
1130  * @param modified List to which modified suggestions will be added
1131  * @param fb feedback for this suggestion
1132  * @param removedSuggestions Removed suggestions from list.
1133  */
1134  private void feedbackChangeRef(ArrayList<Suggestion> list,
1135  Suggestion sgFromList, ArrayList<Suggestion> modified, SuggestionFeedback fb,
1136  ArrayList<Suggestion> removedSuggestions)
1137  {
1138  for (Iterator<Suggestion> itList = list.iterator(); itList.hasNext(); ) {
1139  Suggestion sg = itList.next();
1140  List atrs = sg.getAttributes();
1141  // iterate in all atributes
1142  for (Iterator it2 = atrs.iterator(); it2.hasNext();) {
1143  Object obj = (Object) it2.next();
1144  Object value = null;
1145  if (obj instanceof SugLinkedAttribute) {
1146  value = ((SugLinkedAttribute) obj).getValue();
1147  }
1148  if (obj instanceof SugNestedAttribute) {
1149  value = ((SugNestedAttribute) obj).getValue();
1150  }
1151  if (value instanceof Suggestion) {
1152  if (((Suggestion) value).equals(sgFromList)) {
1153  if (obj instanceof SugLinkedAttribute) {
1154  ((SugLinkedAttribute) obj).setValue(fb.getAnnot());
1155  if (fb.getAnnot() != null) {
1156  ((SugLinkedAttribute) obj).setUri(fb.getAnnot().getURIV2());
1157  } else {
1158  ((SugLinkedAttribute) obj).setUri(null);
1159  }
1160  if (modified != null && !modified.contains(sg)) {
1161  modified.add(sg);
1162  }
1163  }
1164  if (obj instanceof SugNestedAttribute) {
1165  ((SugNestedAttribute) obj).setValue(fb.getAnnot());
1166  if (fb.getAnnot() != null) {
1167  ((SugNestedAttribute) obj).setUri(fb.getAnnot().getURIV2());
1168  } else {
1169  ((SugNestedAttribute) obj).setUri(null);
1170  }
1171  if (modified != null && !modified.contains(sg)) {
1172  modified.add(sg);
1173  }
1174  }
1175  }
1176  }
1177  }
1178  }
1179  list.remove(sgFromList);
1180  removedSuggestions.add(sgFromList);
1181  }
1182 
1183  /**
1184  * Method sets the rejected references to null and return changed suggestions.
1185  *
1186  * @param userSuggestions list of filtered suggestions
1187  * @param refusedSuggestions list of refused suggestions by users
1188  * @return changed suggestions
1189  */
1190  private ArrayList<Suggestion> cutRefusedSuggLinks(ArrayList<Suggestion> userSuggestions, ArrayList<Suggestion> refusedSuggestions){
1191  ArrayList<Suggestion> changedSuggestions = new ArrayList<Suggestion>();
1192  if(userSuggestions != null && !userSuggestions.isEmpty() && refusedSuggestions != null && !refusedSuggestions.isEmpty()){
1193  Iterator<Suggestion> userSuggIt = userSuggestions.iterator();
1194  while(userSuggIt.hasNext()){
1195  Suggestion actualSugg = userSuggIt.next();
1196  List attrList = actualSugg.getAttributes();
1197  Iterator attrListIt = attrList.iterator();
1198  // Go trough all attributes of suggestion
1199  while(attrListIt.hasNext()){
1200  Object actualObject = (Object) attrListIt.next();
1201  // Search for suggestion link
1202  if(actualObject instanceof SugLinkedAttribute){
1203  SugLinkedAttribute actualLink = (SugLinkedAttribute)actualObject;
1204  if(actualLink.getValue() != null && actualLink.getValue() instanceof Suggestion){
1205  Iterator<Suggestion> refSugIterator = refusedSuggestions.iterator();
1206  while(refSugIterator.hasNext()){
1207  // Check if linked suggestion parameter points to refused suggestion
1208  if(((Suggestion)actualLink.getValue()).getId().equals(refSugIterator.next().getId())){
1209  // Then set link to null (cut off refused suggestion)
1210  actualLink.setValue(null);
1211  actualLink.setUri(null);
1212  if(!changedSuggestions.contains(actualSugg)){
1213  changedSuggestions.add(actualSugg);
1214  }
1215  }
1216  } // while(refSugIterator.hasNext())
1217  } // ... instanceof Suggestion){
1218  } // if(actualObject instanceof SugLinkedAttribute
1219  else if(actualObject instanceof SugNestedAttribute){
1220  SugNestedAttribute actualLink = (SugNestedAttribute)actualObject;
1221  if(actualLink.getValue() != null && actualLink.getValue() instanceof Suggestion){
1222  Iterator<Suggestion> refSugIterator = refusedSuggestions.iterator();
1223  while(refSugIterator.hasNext()){
1224  // Check if nested suggestion parameter points to refused suggestion
1225  if(((Suggestion)actualLink.getValue()).getId().equals(refSugIterator.next().getId())){
1226  // Then set link to null (cut off refused suggestion)
1227  actualLink.setValue(null);
1228  actualLink.setUri(null);
1229  if(!changedSuggestions.contains(actualSugg)){
1230  changedSuggestions.add(actualSugg);
1231  }
1232  }
1233  } // while(refSugIterator.hasNext())
1234  } // ... instanceof Suggestion){
1235  } // if(actualObject instanceof SugNestedAttribute
1236  } // while(attrListIt.hasNext())
1237  } // while(userSuggIt.hasNext())
1238  } // if(userSuggestions != null && ...
1239  return changedSuggestions;
1240  } // cutRefusedSuggLinks()
1241 
1242 } // public class P2SuggestionProcessor
ArrayList< Fragment > processSuggFragments(Element fragmentsEl, RequestInfo requestInfo)
Attribute manager provides a way how to create new attributes for prupose of suggestion.
Persistence manager (database manipulator)
Definition: PersistM.java:35
Class representing attribute of type NestedAnnotation for peupose of suggestion.
void feedbackChangeRef(ArrayList< Suggestion > list, Suggestion sgFromList, ArrayList< Suggestion > modified, SuggestionFeedback fb, ArrayList< Suggestion > removedSuggestions)
Class which implements Comparator to sort arrayList of SuggestionFragment alphabetically.
Singleton for storing global variables.
Definition: AppBean.java:47
ArrayList< Suggestion > getSuggestionWithoutFeedback(RequestInfo requestInfo, ArrayList< Suggestion > list, ArrayList< Suggestion > modified)
ArrayList< SuggestionLogEntry > updatePositiveFeedback(RequestInfo requestInfo)
void processSuggestionRefuse(Element suggRefuseEl, RequestInfo requestInfo)
Abstract class provides a parser for the annotation of protocol version 2.
Suggested annotation with informations about suggestion.
Static class which parses and process XML with messages.
Class representing user group.
Definition: UserGroup.java:47
Annotation processAnnotation(Element annotationEl, RequestInfo requestInfo)
Methods for translating output from SEC API to the Suggestion objects.
void connectAnnotations(ArrayList< Annotation > annotsToConnect, HashMap< String, Annotation > tmpIdMap, RequestInfo requestInfo)
void processSuggestionAutoConfirm(Integer minConfidence, RequestInfo requestInfo)
Class provides offerining of suggestions with usage of local knowledge repository.
Class which process messages related to suggestions in protocol v 2.0.
void processGetAlternatives(Element getAltEl, RequestInfo requestInfo)
Base class representing attribute of annotation.
Class representing type of annotation.
Definition: AnnotType.java:58
Class representing attribute of type Boolean.
Class representing attribute of type AnnotationLink for prupose of suggestion.
void processSuggestionQuery(Element suggQueryEl, RequestInfo requestInfo)
ArrayList< SuggestionLogEntry > getConfirmedSuggestions()
Processed informations about client request.
Class representing suggestion of annotation.
Definition: Suggestion.java:87
Class responsible for localised strings.
Informations about client session.
Represents database entitiy with suggestion feedback. feedback.
ArrayList< String > processSuggTypes(Element typesEl, RequestInfo requestInfo)
ArrayList< SuggestionLogEntry > getRefusedSuggestions()
ArrayList< Suggestion > cutRefusedSuggLinks(ArrayList< Suggestion > userSuggestions, ArrayList< Suggestion > refusedSuggestions)
Class representing annotated fragment.
Definition: Fragment.java:48
void processSuggestionConfirm(Element suggConfirmEl, RequestInfo requestInfo)