4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
SECAPISuggestionTranslator.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: SECAPISuggestionTranslator.java
5  * Description: Class provides methods for translating of suggestions from
6  * SEC API to the objects of class Suggestion.
7  */
8 
9 /**
10  * @file SuggestionManager.java
11  *
12  * @brief Methods for translating output from SEC API to the Suggestion objects
13  */
14 
15 package cz.vutbr.fit.knot.annotations.modules.suggestionManager;
16 
26 import cz.vutbr.fit.knot.annotations.modules.suggestionManager.alternative.*;
27 import cz.vutbr.fit.knot.annotations.modules.suggestionManager.attributes.*;
28 import java.io.IOException;
29 import java.io.StringReader;
30 import java.math.BigDecimal;
31 import java.text.SimpleDateFormat;
32 import java.util.*;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
35 import javax.xml.parsers.DocumentBuilder;
36 import javax.xml.parsers.DocumentBuilderFactory;
37 import javax.xml.parsers.ParserConfigurationException;
38 import org.w3c.dom.Document;
39 import org.w3c.dom.Node;
40 import org.w3c.dom.Element;
41 import org.w3c.dom.NodeList;
42 import org.xml.sax.InputSource;
43 import org.xml.sax.SAXException;
44 
45 /**
46  * Class provides methods for translating of suggestions from SEC API
47  * to the objects of class Suggestion.
48  *
49  * @brief Methods for translating output from SEC API to the Suggestion objects
50  *
51  * @author idytrych
52  */
54 
55  /** Separator of String values if they should be concatenated into one String attribute */
56  public static final String STRING_ATT_VALUES_SEPARATOR = ", ";
57  /** Separator of Text values if they should be concatenated into one Text attribute */
58  public static final String TEXT_ATT_VALUES_SEPARATOR = " \n";
59  /** Name of this module */
60  public static final String MODULE_NAME = "SECAPISuggestionTranslator";
61 
62  /** Default name of attribute with latitude from SEC API */
63  public static final String LATITUDE_NAME = "latitude";
64  /** Default name of attribute with longitude from SEC API */
65  public static final String LONGITUDE_NAME = "longitude";
66 
67  /* Default suggestion confidence (used if it was not set by SEC API) */
68  public static final int DEFAULT_SUGGESTION_CONFIDENCE = 50;
69 
70  /** Default user group. */
72 
73  /** Default user group. */
75  /** Base URI for type of annotation. */
76  String baseTypeUri;
77 
78  /** Cache for types of annotations */
79  HashMap<String,AnnotType> typesBuffer;
80 
81  /**
82  * Set default userGroup.
83  *
84  * @param userGroup User group.
85  */
87  this.userGroup = userGroup;
88  baseTypeUri = AppBean.getBaseTypeUri();
89  }
90 
91  /**
92  * Gets alternatives from SEC API and translates them to the Suugestion objects.
93  *
94  * @param requestInfo Informations about client request
95  * @param SECAPIResults Results from SEC API in String
96  * @param newTypes Array for adding new types of annotations
97  * @param validSuggestions Alternatives is assign to one of theese suggestions
98  * @return Resutns alternatives for the document
99  */
100  public ArrayList<Alternative> translateAlternativeFromSecApi(RequestInfo requestInfo, String SECAPIResults, ArrayList<AnnotType> newTypes, ArrayList<Suggestion> validSuggestions) {
101  HashMap<Integer, ArrayList<SuggestionFragment>> sugToLinFragments = new HashMap<Integer, ArrayList<SuggestionFragment>>();
102  typesBuffer = new HashMap<String, AnnotType>();
103 
104  // linearize given suggestions
105  linearizeSuggestions(sugToLinFragments,requestInfo.getSession().getParsedSyncDocument(),validSuggestions);
106 
107  SECAPIResults = SECAPIResults.replace("<suggestion>",
108  "<suggestion xmlns:geo=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">");
109 
110  // parse XML message
111  Document doc = parseXml(SECAPIResults);
112  if (doc == null) {
114  String msg = "Bad XML from SEC API: " + SECAPIResults;
115  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
116  }
117  return null; // bad request
118  }
119 
120  Element docEl = doc.getDocumentElement();
121  HashMap<Integer,TranslateAlternativeHolder> alternatives = new HashMap<Integer,TranslateAlternativeHolder>();
122 
123  // process message from SEC API
124  NodeList fragmentElements = docEl.getChildNodes();
125  int fCount = fragmentElements.getLength();
126  for (int i= 0; i < fCount; i++) { // for each fragment from SEC API
127 
128  if(!(fragmentElements.item(i) instanceof Element)){
129  continue;
130  }
131  if(!((Element) fragmentElements.item(i)).getTagName().equalsIgnoreCase("text")){
132  continue;
133  }
134 
135  Element fragmentEl = (Element) fragmentElements.item(i);
136 
138 
139  // process alternative fragment from SEC API
140  AlternativeFragment altFragment = processAlternativeFragment(fragmentEl);
141  if(altFragment == null){
142  continue; // can't process fragment
143  }
144 
145  // proces alternative suggestions
146  ArrayList<Alternative> alternativesFromSecApi = processAlternatives(requestInfo,fragmentEl,newTypes,altFragment);
147 
148  newAlternative.setUnconvertedAlternatives(alternativesFromSecApi);
149 
150  Alternative dummyAlternative = new Alternative();
151  dummyAlternative.setId(i);
152  dummyAlternative.addFragment(altFragment);
153  altFragment.setRefAlternative(dummyAlternative);
154  newAlternative.setDummyAlternative(dummyAlternative);
155  alternatives.put(i,newAlternative);
156  }
157 
158  // find alternatives
159  findAlternativeSuggestions(alternatives,validSuggestions,sugToLinFragments);
160 
161  // get only new alternative suggestions
162  return makeNewAlternative(requestInfo, sugToLinFragments, alternatives);
163  }
164 
165  /**
166  * Method that process nested alternatives
167  *
168  * Note: It's called recursively
169  *
170  * @param atEl Attribute element
171  * @param requestInfo RequestInfo
172  * @param newTypes New Annotations types
173  *
174  * @return Nested alternative
175  */
176  private Alternative processNestedAlternative(Element atEl, RequestInfo requestInfo, ArrayList<AnnotType> newTypes) {
177  // process message from SEC API
178  Alternative nestedAlt = null;
179  NodeList fragmentElements = atEl.getChildNodes();
180  int fCount = fragmentElements.getLength();
181  for (int i = 0; i < fCount; i++) { // for each fragment from SEC API
182 
183  if (!(fragmentElements.item(i) instanceof Element)) {
184  continue;
185  }
186  if (!((Element) fragmentElements.item(i)).getTagName().equalsIgnoreCase("text")) {
187  continue;
188  }
189 
190  Element fragmentEl = (Element) fragmentElements.item(i);
191 
192  // process alternative fragment from SEC API
193  AlternativeFragment altFragment = processAlternativeFragment(fragmentEl);
194  if (altFragment == null) {
195  continue; // can't process fragment
196  }
197 
198  NodeList annotationElements = fragmentEl.getChildNodes();
199  int aCount = annotationElements.getLength();
200  int alternativeCreated = 0;
201 
202  /*
203  * In case of nested, there should be always just one Annotation tag
204  */
205  for (int j = 0; j < aCount; j++) { // for each annotation from SEC API
206  if (alternativeCreated >= Constants.MAX_COUNT_OF_ALTERNATIVES_TO_ONE_SUGGESTION) {
207  break;
208  }
209  if (!(annotationElements.item(j) instanceof Element)) {
210  continue;
211  }
212  if (!((Element) annotationElements.item(j)).getTagName().equalsIgnoreCase("annotation")) {
213  continue;
214  }
215 
216  Element annotationEl = (Element) annotationElements.item(j);
217 
218  nestedAlt = (Alternative) createSugFromElement(requestInfo, annotationEl, newTypes, true);
219 
220  if (nestedAlt != null) {
221  nestedAlt.setSourceDocument(requestInfo.getSession().getSyncDocument());
222  nestedAlt.setSource(requestInfo.getSession().getSyncDocument().getUriForAnnot());
223  nestedAlt.setSourceDocumentId(requestInfo.getSession().getSyncDocument().getId());
224  AlternativeFragment fr = new AlternativeFragment("", altFragment.getOffset(), altFragment.getLength(), altFragment.getAnnotatedText(), null);
225  fr.setRefAlternative(nestedAlt);
226  nestedAlt.addFragment(fr);
227  }
228  }
229  }
230  return nestedAlt;
231  } // processNestedAlternative()
232 
233  /**
234  * Method converts the raw format of alternatives from SEC Api to array of
235  * objects.
236  *
237  * @param requestInfo Informations about client request
238  * @param alternatvesEl Element with alternatives from SEC Api in raw format
239  * @param newTypes Array for adding new types of annotations
240  * @param altFragment Fragment that is assigned to all created alternatives
241  * @return array of alternatives from SEC Api
242  */
243  private ArrayList<Alternative> processAlternatives(RequestInfo requestInfo,Element alternatvesEl, ArrayList<AnnotType> newTypes,AlternativeFragment altFragment){
244  ArrayList<Alternative> result = new ArrayList<Alternative>();
245  NodeList annotationElements = alternatvesEl.getChildNodes();
246  int aCount = annotationElements.getLength();
247  int alternativeCreated = 0;
248 
249  for (int j = 0; j < aCount; j++) { // for each annotation from SEC API
250  if (alternativeCreated >= Constants.MAX_COUNT_OF_ALTERNATIVES_TO_ONE_SUGGESTION) {
251  break;
252  }
253  if(!(annotationElements.item(j) instanceof Element)){
254  continue;
255  }
256  if(!((Element) annotationElements.item(j)).getTagName().equalsIgnoreCase("annotation")){
257  continue;
258  }
259 
260  Element annotationEl = (Element) annotationElements.item(j);
261 
262  Alternative alt = (Alternative) createSugFromElement(requestInfo, annotationEl, newTypes, true);
263  if (alt != null) {
264  alt.setSourceDocument(requestInfo.getSession().getSyncDocument());
265  alt.setSource(requestInfo.getSession().getSyncDocument().getUriForAnnot());
266  alt.setSourceDocumentId(requestInfo.getSession().getSyncDocument().getId());
267  AlternativeFragment fr = new AlternativeFragment("", altFragment.getOffset(), altFragment.getLength(), altFragment.getAnnotatedText(), null);
268  fr.setRefAlternative(alt);
269  alt.addFragment(fr);
270  result.add(alt);
271  }
272  }
273 
274  return result;
275  }
276 
277  /**
278  * Method converts the raw format of alternatives fragments from SEC Api to array of
279  * objects.
280  *
281  * @param fragmentEl Element with alternatives fragments from SEC Api in raw format
282  * @return array of alternatives fragments from SEC Api
283  */
284  private static AlternativeFragment processAlternativeFragment(Element fragmentEl){
285  String startOffsetStr = fragmentEl.getAttribute("s_offset");
286  String endOffsetStr = fragmentEl.getAttribute("e_offset");
287  String fragmentText = fragmentEl.getAttribute("string");
288 
289  Integer startOf;
290  Integer endOf;
291  try {
292  startOf = Integer.parseInt(startOffsetStr);
293  endOf = Integer.parseInt(endOffsetStr);
294  } catch (Exception e) {
295  String msg = "Bad fragment in SEC API output: " + startOffsetStr + "," + endOffsetStr + " " + fragmentText;
296  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
297  return null;
298  }
299  if (startOf == null || endOf == null || startOf >= endOf) {
300  String msg = "Bad fragment in SEC API output: " + startOffsetStr + "," + endOffsetStr + " " + fragmentText;
301  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
302  return null;
303  }
304 
305  return new AlternativeFragment("", startOf, endOf - startOf, fragmentText, null);
306  }
307 
308  /**
309  * Method creates new alternatives from SEC API message for given suggestions.
310  *
311  * @param requestInfo Informations about client request
312  * @param sugToLinFragments Linearized fragments of given suggestions
313  * @param alternativesHolders new alternatives and alternatives from DB
314  * @return array of new alternatives
315  */
316  private ArrayList<Alternative> makeNewAlternative(RequestInfo requestInfo,
317  HashMap<Integer, ArrayList<SuggestionFragment>> sugToLinFragments,
318  HashMap<Integer,TranslateAlternativeHolder> alternativesHolders){
319 
320  ArrayList<AlternativeFragment> allLinFragments = new ArrayList<AlternativeFragment>();
321  ArrayList<Alternative> result = new ArrayList<Alternative>();
322 
323  /* HashMap of all alternatives which contains tmpId */
324  HashMap<String, Alternative> alternativeMap = new HashMap<String, Alternative>();
325  ArrayList<AlternativeAttribute> nestedLinkedList = new ArrayList<AlternativeAttribute>();
326 
327  Iterator<TranslateAlternativeHolder> secAPIAlternativesIt = alternativesHolders.values().iterator();
328  while (secAPIAlternativesIt.hasNext()) {
329  TranslateAlternativeHolder currentAlternativeHolder = secAPIAlternativesIt.next();
330  ArrayList<Alternative> alternatives = currentAlternativeHolder.getUnconvertedAlternatives();
331  ArrayList<Suggestion> suggestionsFromDB = currentAlternativeHolder.getConvertedAlternatives();
332 
333  if (currentAlternativeHolder.getDummyAlternative().getAlternativeOfSuggestion() == null) {
334  Iterator<Alternative> altIt = alternatives.iterator();
335  while (altIt.hasNext()) {
336  Alternative tmpAlt = altIt.next();
337  if(tmpAlt.getTmpId() != null && !tmpAlt.getTmpId().isEmpty()){
338  alternativeMap.put(tmpAlt.getTmpId(), tmpAlt);
339  }
340  }
341  continue;
342  }
343 
344  int altCount = 0;
345  if (currentAlternativeHolder.getConvertedAlternatives() != null) {
346  altCount = currentAlternativeHolder.getConvertedAlternatives().size();
347  }
348  currentAlternativeHolder.sortUncoveredByCofidence();
349 
350  Iterator<Alternative> alternativesIt = alternatives.iterator();
351  while (alternativesIt.hasNext()) {
352  Alternative currentAlternative = alternativesIt.next();
353  AlternativeFragment currentAltFrag = currentAlternative.getFragmentsAL().get(0);
354 
355  Suggestion alternativeOf = currentAlternative.getAlternativeOfSuggestion();
356 
358  break;
359  }
360 
361  if (!currentAlternative.contentEqualsForSec(alternativeOf, sugToLinFragments.get(alternativeOf.getId()), false)) {
362  // alternative is not alternativeOf suggestion
363  if (!isAlternativeInSuggestionList(suggestionsFromDB, currentAlternative, sugToLinFragments)) {
364  // alternative has not been transform to suggestion yet
365  allLinFragments.add(currentAltFrag);
366  result.add(currentAlternative);
367  altCount++;
368 
369  /*
370  * Iterate through all alternative attributes and if attribute
371  * contains some uri (either to linked or nested attribute)
372  * we need to store this attribute, and once all attributes are processed,
373  * search for this attribute, and assign and link to proper variable
374  *
375  */
376 
377  Iterator<AlternativeAttribute> attIt = currentAlternative.getAttributes().iterator();
378  while(attIt.hasNext()){
379  AlternativeAttribute currentTmpAtt = attIt.next();
380  // If its pointing to another alternative, store this attribute
381  if(currentTmpAtt.getUri() != null && !currentTmpAtt.getUri().isEmpty()){
382  nestedLinkedList.add(currentTmpAtt);
383  }
384  }
385  }
386  }
387  }
388  }
389 
390  /*
391  * Iterate through all processed alternatives and try to find value in hashmap
392  * whose key is tmpId of current alternative
393  */
394  ArrayList<AlternativeAttribute>openNestedLinkedList = nestedLinkedList;
395 
396  while(!openNestedLinkedList.isEmpty()){
397  AlternativeAttribute tmpAtt = openNestedLinkedList.get(0);
398 
399  if(alternativeMap.get(tmpAtt.getUri()) != null){
400  Alternative alt = alternativeMap.get(tmpAtt.getUri());
401  // If it is an attribute of nestedAnnotation type, assign refAlternative to founded alternative
402  // nestedInAlternative variable, and add this alternative to result list if it's not already there
403  // If type of attribute is LinkedAnnotation, just make sure that this founded alternative
404  // is in result list
405  if(tmpAtt.getSimpleType().equalsIgnoreCase("NestedSuggestion")){
406  tmpAtt.setNestedAlternative(alt);
407  alt.setNestedInAlternative(tmpAtt.getRefAlternative());
408  }
409  else if (tmpAtt.getSimpleType().equalsIgnoreCase("SuggestionLink")){
410  tmpAtt.setLinkedAlternative(alt);
411  }
412 
413  if(!result.contains(alt)){
414  result.add(alt);
415  allLinFragments.add(alt.getFragmentsAL().get(0));
416 
417  //Add all nested/linked attributes to list
418  Iterator<AlternativeAttribute> tmpIt = alt.getAttributes().iterator();
419  while(tmpIt.hasNext()){
420  AlternativeAttribute at = tmpIt.next();
421  if(tmpAtt.getSimpleType().equalsIgnoreCase("NestedSuggestion") || tmpAtt.getSimpleType().equalsIgnoreCase("SuggestionLink")){
422  openNestedLinkedList.add(at);
423  }
424  }
425  }
426  }
427  else{
428  if (!(tmpAtt.getSimpleType().equalsIgnoreCase("URI") || tmpAtt.getSimpleType().equalsIgnoreCase("Image"))) {
429  tmpAtt.setUri(null);
430  }
431  }
432 
433  openNestedLinkedList.remove(tmpAtt);
434  }
435 
436  @SuppressWarnings("unchecked")
437  ArrayList<Alternative> retList = convertLinFragments(requestInfo, result, allLinFragments, true);
438  return retList;
439 
440  } // makeNewAlternative()
441 
442  /**
443  * Finds suggestions for which were alternatives sent and adds alternatives
444  * from DB.
445  *
446  * @param alternatives Alternatives from SEC API
447  * @param validSuggestions Alternatives is assign to one of these suggestions
448  * @param sugToLinFragments Linearized fragments of given valid suggestions
449  */
450  private void findAlternativeSuggestions(HashMap<Integer,TranslateAlternativeHolder> alternatives, ArrayList<Suggestion> validSuggestions,HashMap<Integer, ArrayList<SuggestionFragment>> sugToLinFragments){
451 
452  Iterator<TranslateAlternativeHolder> alternativesFromSECIt = alternatives.values().iterator();
453  while(alternativesFromSECIt.hasNext()){
454  TranslateAlternativeHolder currentAlternative = alternativesFromSECIt.next();
455 
456  Iterator<AlternativeFragment> currentFragmentsIt = currentAlternative.getDummyAlternative().getFragmentsAL().iterator();
457  while(currentFragmentsIt.hasNext()){
458  AlternativeFragment currentFrag = currentFragmentsIt.next();
459 
460  // attempt to find suggestion with same part of fragment
461  Suggestion alternativeOf = null;
462  for (Iterator<Suggestion> sgIt = validSuggestions.iterator(); sgIt.hasNext();) {
463  Suggestion sg = sgIt.next();
464  if (!sugToLinFragments.containsKey(sg.getId())) {
465  continue;
466  }
467  if (AlternativeManager.overlappingFragment(sugToLinFragments.get(sg.getId()), currentFrag.getOffset(), currentFrag.getOffset() + currentFrag.getLength())) {
468  alternativeOf = sg;
469  break;
470  }
471  }
472  // main suggestion with same part of fragment was not found
473  if (alternativeOf == null) {
474  continue;
475  }
476 
477  currentFrag.getRefAlternative().setAlternativeOfSuggestion(alternativeOf);
478  // set alternative for all unconverted alternatives
479  currentAlternative.setAlternativeOf(alternativeOf);
480 
481  ArrayList<Suggestion> findedSugg = new ArrayList<Suggestion>();
482  // find all alternative suggestions of "alternativeOf suggestion"
483  List<Suggestion> alternativeSuggestions = AlternativeManager.getOtherSuggestions(alternativeOf.getId());
484  for (Iterator<Suggestion> sugIt = alternativeSuggestions.iterator(); sugIt.hasNext();) {
485  Suggestion sugg = sugIt.next();
486  Integer sgId = sugg.getId();
487  if(!findedSugg.contains(sugg)){
488  findedSugg.add(sugg);
489  }
490  }
491  currentAlternative.setConvertedAlternatives(findedSugg);
492  }
493  } // while(alternativesFromSECIt.
494  } // findAlternativeSuggestions()
495 
496 
497  /**
498  * Linearize fragments of given suggestions and return fragments as hash map where
499  * key is id of suggestion.
500  *
501  * @param linFragmentsMap hash map where the result will be stored
502  * @param doc annotated document
503  * @param suggestions suggestion which fragments will be linearize
504  */
505  public static void linearizeSuggestions(HashMap<Integer, ArrayList<SuggestionFragment>> linFragmentsMap, Document doc, ArrayList<Suggestion> suggestions){
506  ArrayList<ArrayList<SuggestionFragment>> notConverted = new ArrayList<ArrayList<SuggestionFragment>>();
507  ArrayList<SuggestionFragment> linearizedFragments;
508  ArrayList<ArrayList<SuggestionFragment>> normalFragments = new ArrayList<ArrayList<SuggestionFragment>>();
509 
510  Iterator<Suggestion> suggestionsIt = suggestions.iterator();
511  while(suggestionsIt.hasNext()){
512  Suggestion currentSuggestion = suggestionsIt.next();
513  normalFragments.add(currentSuggestion.getFragmentsAL());
514  }
515 
516  // convert fragments to linearized fragments
517  linearizedFragments = Linearizer.fragmentsToLinSugFragments(normalFragments,doc, notConverted, true);
518 
519  if(!linearizedFragments.isEmpty()){
520  Iterator<SuggestionFragment> linearizedFragsIt = linearizedFragments.iterator();
521  while(linearizedFragsIt.hasNext()){
522  SuggestionFragment currentLinFragment = linearizedFragsIt.next();
523  // suggestions for the whole document don't possess any fragment, avoid NPException
524  // process regular suggestions fragments only
525  if (currentLinFragment != null) {
526  if(linFragmentsMap.containsKey(currentLinFragment.getRefSuggestion().getId())){
527  ArrayList<SuggestionFragment> resutFragments = linFragmentsMap.get(currentLinFragment.getSuggestion());
528  resutFragments.add(currentLinFragment);
529  }else{
530  ArrayList<SuggestionFragment> currentLinFrag = new ArrayList<SuggestionFragment>();
531  currentLinFrag.add(currentLinFragment);
532  linFragmentsMap.put(currentLinFragment.getRefSuggestion().getId(), currentLinFrag);
533  }
534  }
535  }
536  }
537  } // linearizeSuggestions()
538 
539  /**
540  * Check, if alternative is in suggestion list.
541  *
542  * @param suggestions Suggestion list.
543  * @param alt Alternative.
544  * @param sugToLinFragments HashMap with linearized fragments
545  * @return Check, if alternative is in suggestion list.
546  */
547  private boolean isAlternativeInSuggestionList(List<Suggestion> suggestions, Alternative alt,
548  HashMap<Integer, ArrayList<SuggestionFragment>> sugToLinFragments) {
549  for (Iterator<Suggestion> it = suggestions.iterator(); it.hasNext(); ) {
550  Suggestion sg = it.next();
551  if (alt.contentEqualsForSec(sg, sugToLinFragments.get(sg.getId()), false)) {
552  return true;
553  }
554  }
555  return false;
556  }
557 
558  /**
559  * Converts linearized fragment to normal fragment
560  *
561  * @param requestInfo Informations about client request
562  * @param frg Linearized fragment to convert
563  * @return Returns converted fragment
564  */
566  Document doc = requestInfo.getSession().getParsedSyncDocument();
567 
568  // linearized fragment from SEC API to normal fragment
569  ArrayList<AlternativeFragment> input = new ArrayList<AlternativeFragment>();
570  input.add(frg);
571  ArrayList<ArrayList<AlternativeFragment>> badFragments = new ArrayList<ArrayList<AlternativeFragment>>();
572  ArrayList<ArrayList<AlternativeFragment>> convertedFragments = Linearizer.linAltFragmentsToFragments(input, doc, badFragments);
573 
574  String info = "<module name=\"" + SECAPISuggestionTranslator.MODULE_NAME + "\"/>";
575  int langNum = requestInfo.getSession().getLanguageNum();
576 
577  // check consistency
578  if (convertedFragments == null || convertedFragments.size() != 1) {
579  return null;
580  }
581  ArrayList<AlternativeFragment> output = convertedFragments.get(0);
582  if (output.size() < 1) {
583  return null;
584  }
585  frg = output.get(0);
586 
587  // normal fragment to correctly linearized fragment
588  ArrayList<ArrayList<AlternativeFragment>> notConverted = new ArrayList<ArrayList<AlternativeFragment>>();
589  ArrayList<ArrayList<AlternativeFragment>> comFragments = new ArrayList<ArrayList<AlternativeFragment>>();
590 
591  ArrayList<AlternativeFragment> input2 = new ArrayList<AlternativeFragment>();
592  input2.add(frg);
593  comFragments.add(input2);
594 
595  ArrayList<AlternativeFragment> linearizedList;
596  linearizedList = Linearizer.fragmentsToLinAltFragments(comFragments,doc, notConverted, true);
597 
598  if (linearizedList.isEmpty()) {
599  return null;
600  }
601 
602  return linearizedList.get(0);
603  } // fixAlternativeFragment()
604 
605  /**
606  * Gets suggestions from SEC API and translates them to the Suugestion objects.
607  *
608  * @param requestInfo Informations about client request
609  * @param SECAPIResults Results from SEC API in String
610  * @param newTypes Array for adding new types of annotations
611  * @return Resutns suggestions for the document
612  */
613  public ArrayList<Suggestion> translateSugFromSecApi(RequestInfo requestInfo, String SECAPIResults, ArrayList<AnnotType> newTypes) {
614  ArrayList<Suggestion> result = new ArrayList<Suggestion>();
615  ArrayList<SuggestionFragment> allLinFragments = new ArrayList<SuggestionFragment>();
616  typesBuffer = new HashMap<String, AnnotType>();
617 
618  //Add geoNamespace if necessary
619  SECAPIResults = SECAPIResults.replace("<suggestion>",
620  "<suggestion xmlns:geo=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">");
621 
622  // parse XML
623  Document doc = parseXml(SECAPIResults);
624  if (doc == null) {
626  String msg = "Bad XML from SEC API: " + SECAPIResults;
627  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
628  }
629  return null; // bad request
630  }
631  Element docEl = doc.getDocumentElement();
632  HashMap<String, SugNestedAttribute> nestedInMap = new HashMap<String, SugNestedAttribute>();
633  HashMap<String, ArrayList<SugLinkedAttribute>> linkedInMap = new HashMap<String, ArrayList<SugLinkedAttribute>>();
634 
635  NodeList fragmentElements = docEl.getChildNodes();
636  int fCount = fragmentElements.getLength();
637  for (int i= 0; i < fCount; i++) { // for each fragment from SEC API
638 
639  if(!(fragmentElements.item(i) instanceof Element)){
640  continue;
641  }
642  if(!((Element) fragmentElements.item(i)).getTagName().equalsIgnoreCase("text")){
643  continue;
644  }
645 
646  Element fragmentEl = (Element) fragmentElements.item(i);
647  String startOffsetStr = fragmentEl.getAttribute("s_offset");
648  String endOffsetStr = fragmentEl.getAttribute("e_offset");
649  String fragmentText = fragmentEl.getAttribute("string");
650 
651  Integer startOf;
652  Integer endOf;
653  try {
654  startOf = Integer.parseInt(startOffsetStr);
655  endOf = Integer.parseInt(endOffsetStr);
656  } catch (Exception e) {
657  String msg = "Bad fragment in SEC API output: " + startOffsetStr + "," + endOffsetStr + " " + fragmentText;
658  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
659  continue;
660  }
661  if (startOf == null || endOf == null || startOf >= endOf) {
662  String msg = "Bad fragment in SEC API output: " + startOffsetStr + "," + endOffsetStr + " " + fragmentText;
663  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
664  continue;
665  }
666 
667  NodeList annotationElements = fragmentEl.getChildNodes();
668  int aCount = annotationElements.getLength();
669  for (int j = 0; j < aCount; j++) { // for each annotation from SEC API
670 
671  if(!(annotationElements.item(j) instanceof Element)){
672  continue;
673  }
674  if(!((Element) annotationElements.item(j)).getTagName().equalsIgnoreCase("annotation")){
675  continue;
676  }
677 
678  Element annotationEl = (Element) annotationElements.item(j);
679 
680  Suggestion sug = (Suggestion) createSugFromElement(requestInfo, annotationEl, newTypes, false);
681  if (sug != null) {
682  sug.setSourceDocument(requestInfo.getSession().getSyncDocument());
683  sug.setSource(requestInfo.getSession().getSyncDocument().getUriForAnnot());
684  sug.setSourceDocumentId(requestInfo.getSession().getSyncDocument().getId());
685  sug.setIsFromSECAPI(true);
686  if (requestInfo.getSession() != null && requestInfo.getSession().getSugRequestFlag()) {
687  sug.setDisplayConfidence(true);
688  }
689  SuggestionFragment fr = new SuggestionFragment("", startOf, endOf - startOf, fragmentText, null);
690  fr.setRefSuggestion(sug);
691  sug.addFragment(fr);
692  allLinFragments.add(fr);
693  result.add(sug);
694 
695  /*
696  * Iterate through all suggestion attributes and if attribute's type is nested,
697  * and contains uri to suggestion, we need to store it's suggestion,
698  * and once all suggestions are processed, search
699  * for this suggestion, and assign to 'nestedInSuggestion' suggestion,
700  * which this attribute contains
701  *
702  * Similiar process is used for linked suggestions
703  */
704  Iterator<SugBaseAttribute> attrIt = sug.getAttributes().iterator();
705  while(attrIt.hasNext()){
706  SugBaseAttribute tmpAttr = attrIt.next();
707  if(tmpAttr.getSimpleType().equalsIgnoreCase("NestedSuggestion")){
708  if(tmpAttr.getUri() != null && !tmpAttr.getUri().isEmpty()){
709  nestedInMap.put(tmpAttr.getUri(), (SugNestedAttribute)tmpAttr);
710  }
711  }
712  else if(tmpAttr.getSimpleType().equalsIgnoreCase("SuggestionLink")){
713  if(tmpAttr.getUri() != null && !tmpAttr.getUri().isEmpty()){
714  ArrayList<SugLinkedAttribute> list = linkedInMap.get(tmpAttr.getUri());
715  if(list == null){
716  list = new ArrayList<SugLinkedAttribute>();
717  }
718  list.add((SugLinkedAttribute)tmpAttr);
719  linkedInMap.put(tmpAttr.getUri(), list);
720  }
721  }
722  } //iterator
723  } // if sug != null
724 
725  } // for each annotation from SEC API
726 
727  } // for each fragment from SEC API
728 
729 
730  /*
731  * Iterate through all processed suggestion and try to find value in hashmap
732  * whose key is tmpId of current suggestion
733  */
734  Iterator<Suggestion> sugIt = result.iterator();
735  while(sugIt.hasNext()){
736  Suggestion s = sugIt.next();
737  if(nestedInMap.get(s.getTmpId()) != null){
738  s.setNestedInSuggestion(nestedInMap.get(s.getTmpId()).getRefSuggestion());
739  nestedInMap.get(s.getTmpId()).setNestedSuggestion(s);
740  nestedInMap.remove(s.getTmpId());
741  }
742  else if(linkedInMap.get(s.getTmpId()) != null){
743  Iterator<SugLinkedAttribute> attIt = linkedInMap.get(s.getTmpId()).iterator();
744  while(attIt.hasNext()){
745  attIt.next().setLinkedSuggestion(s);
746  }
747  linkedInMap.remove(s.getTmpId());
748  }
749  }
750 
751  /* For all attributes which left in hash map, remove theirs uri-s */
752  Iterator<SugNestedAttribute> nestedAttIt = nestedInMap.values().iterator();
753  while(nestedAttIt.hasNext()){
754  nestedAttIt.next().setUri(null);
755  }
756 
757  Iterator<ArrayList<SugLinkedAttribute>> linkedALIt = linkedInMap.values().iterator();
758  while(linkedALIt.hasNext()){
759  Iterator<SugLinkedAttribute> linkedAttIt = linkedALIt.next().iterator();
760  while(linkedAttIt.hasNext()){
761  linkedAttIt.next().setUri(null);
762  }
763  }
764 
765  @SuppressWarnings("unchecked")
766  ArrayList<Suggestion> retList = convertLinFragments(requestInfo, result, allLinFragments, false);
767  return retList;
768  } // translateSugFromSecApi()
769 
770 
771  /**
772  * Method that process nested suggestions
773  *
774  * Note: It's called recursively
775  *
776  * @param attEl Attribute element
777  * @param requestInfo RequestInfo
778  * @param newTypes New Annotations types
779  *
780  * @return Nested suggestion
781  */
782  private Suggestion processNestedSugg(Element attEl, RequestInfo requestInfo, ArrayList<AnnotType> newTypes){
783  Suggestion sug = null;
784  NodeList fragmentElements = attEl.getChildNodes();
785  int fCount = fragmentElements.getLength();
786  for (int i = 0; i < fCount; i++) { // for each fragment from SEC API
787 
788  if (!(fragmentElements.item(i) instanceof Element)) {
789  continue;
790  }
791  if (!((Element) fragmentElements.item(i)).getTagName().equalsIgnoreCase("text")) {
792  continue;
793  }
794  Element fragmentEl = (Element) fragmentElements.item(i);
795  String startOffsetStr = fragmentEl.getAttribute("s_offset");
796  String endOffsetStr = fragmentEl.getAttribute("e_offset");
797  String fragmentText = fragmentEl.getAttribute("string");
798 
799  Integer startOf;
800  Integer endOf;
801  try {
802  startOf = Integer.parseInt(startOffsetStr);
803  endOf = Integer.parseInt(endOffsetStr);
804  } catch (Exception e) {
805  String msg = "Bad fragment in SEC API output: " + startOffsetStr + "," + endOffsetStr + " " + fragmentText;
806  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
807  continue;
808  }
809  if (startOf == null || endOf == null || startOf >= endOf) {
810  String msg = "Bad fragment in SEC API output: " + startOffsetStr + "," + endOffsetStr + " " + fragmentText;
811  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
812  continue;
813  }
814 
815  NodeList annotationElements = fragmentEl.getChildNodes();
816  int aCount = annotationElements.getLength();
817  for (int j = 0; j < aCount; j++) { // for each annotation from SEC API
818 
819  if (!(annotationElements.item(j) instanceof Element)) {
820  continue;
821  }
822  if (!((Element) annotationElements.item(j)).getTagName().equalsIgnoreCase("annotation")) {
823  continue;
824  }
825 
826  Element annotationEl = (Element) annotationElements.item(j);
827 
828  sug = (Suggestion) createSugFromElement(requestInfo, annotationEl, newTypes, false);
829  if (sug != null) {
830  sug.setSourceDocument(requestInfo.getSession().getSyncDocument());
831  sug.setSource(requestInfo.getSession().getSyncDocument().getUriForAnnot());
832  sug.setSourceDocumentId(requestInfo.getSession().getSyncDocument().getId());
833  sug.setIsFromSECAPI(true);
834  SuggestionFragment fr = new SuggestionFragment("", startOf, endOf - startOf, fragmentText, null);
835  fr.setRefSuggestion(sug);
836  sug.addFragment(fr);
837  }
838 
839  } // for each annotation from SEC API
840  } // for each fragment from SEC API
841  return sug;
842  } // processNestedSugg()
843 
844  /**
845  * Converts linearized fragments to common fragments
846  *
847  * @param requestInfo Informations about client request
848  * @param result List with suggestions or alternatives to which fragments belongs
849  * @param allLinFragments List of all linearized fragments to convert
850  * @param useAlternatives True for work with alternatives, false otherwise
851  * @return Returns list with suggestions or alternatives to which fragments
852  * belongs with converted fragments
853  */
854  @SuppressWarnings("unchecked")
855  private ArrayList convertLinFragments(RequestInfo requestInfo, ArrayList result, ArrayList allLinFragments, boolean useAlternatives) {
856 
857  // is important to sort fragments by offset and length
858  try {
859  Collections.sort(allLinFragments);
860  } catch (Exception e) {
862  String msg = "Some fragments from SEC API was not sorted successfully.";
863  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
864  }
865  return (useAlternatives ? new ArrayList<Alternative>() : new ArrayList<Suggestion>());
866  }
867 
868  // build new list of sorted suggestions from fragment list
869  ArrayList sortedSug = (useAlternatives ? new ArrayList<Alternative>() : new ArrayList<Suggestion>());
870  Iterator allInIterator = allLinFragments.iterator();
871  while(allInIterator.hasNext()){
872  SecFragment frag = (SecFragment) allInIterator.next();
873  sortedSug.add(frag.getRefSecSuggestion());
874  }
875 
876  // delete all suggestions with fragment from original suggestions list
877  Iterator unsortedSugIt = result.iterator();
878  while(unsortedSugIt.hasNext()){
879  SecSuggestion actualSug = (SecSuggestion) unsortedSugIt.next();
880  if(actualSug.getFragments() != null || !actualSug.getFragments().isEmpty()){
881  unsortedSugIt.remove();
882  }
883  }
884 
885  // insert sorted suggestions before suggestions without fragment
886  result.addAll(0, sortedSug);
887 
888  // list for storing of bad fragments
889  ArrayList badFragments = (useAlternatives ?
890  new ArrayList<ArrayList<AlternativeFragment>>()
891  : new ArrayList<ArrayList<SuggestionFragment>>());
892 
893  ArrayList convertedFragments = (useAlternatives ?
894  Linearizer.linAltFragmentsToFragments(allLinFragments, requestInfo.getSession().getParsedSyncDocument(), badFragments)
895  : Linearizer.linSugFragmentsToFragments(allLinFragments, requestInfo.getSession().getParsedSyncDocument(), badFragments));
896 
897  String info = "<module name=\"" + SECAPISuggestionTranslator.MODULE_NAME + "\"/>";
898  int langNum = requestInfo.getSession().getLanguageNum();
899 
900  // check consistency
901  if (convertedFragments == null || convertedFragments.size() != allLinFragments.size()) {
902  int lod = requestInfo.getSession().getProtocolLOD();
903  requestInfo.getSession().addMessageTS(RequestInfo.createErrorMsg(lod, langNum, Localisation.ERROR_33_MODULE_ERROR,info));
905  String msg = "Some fragments from SEC API was not converted successfully.";
906  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
907  }
908  return (useAlternatives ? new ArrayList<Alternative>() : new ArrayList<Suggestion>());
909  }
910 
911  if (badFragments != null) {
912  Iterator badFrIt = badFragments.iterator();
913  while (badFrIt.hasNext()) {
914  ArrayList badFrListForSug = (useAlternatives ?
915  (ArrayList<AlternativeFragment>) badFrIt.next()
916  : (ArrayList<SuggestionFragment>) badFrIt.next());
917  Iterator badFrItForSug = badFrListForSug.iterator();
918  while (badFrItForSug.hasNext()) {
919  SecFragment fragment = (SecFragment) badFrItForSug.next();
920  String msg = "This fragment from SEC API was not converted successfully: ";
921  msg = msg + " offset: " + fragment.getOffset()
922  + " length: " + fragment.getLength() + " text: " + fragment.getAnnotatedText();
923  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
924  }
925  }
926  }
927 
928  // replace fragments with converted
929  Iterator linFrIt = allLinFragments.iterator();
930  Iterator/*<ArrayList<SuggestionFragment>>*/ newFrIt = convertedFragments.iterator();
931  for (Iterator sIt = result.iterator(); sIt.hasNext();) {
932  SecSuggestion sug = (SecSuggestion) sIt.next();
933  // this is suggestion for the whole document, it doesn't have fragments
934  if (sug.getFragments() != null && sug.getFragments().isEmpty()) {
935  continue;
936  }
937  if (useAlternatives) {
938  ((Alternative) sug).setFragments(new ArrayList<AlternativeFragment>()); // remove linearized fragments
939  } else {
940  ((Suggestion) sug).setFragments(new ArrayList<SuggestionFragment>()); // remove linearized fragments
941  }
942  SecFragment linFr = (SecFragment) linFrIt.next();
943  ArrayList fragments = (ArrayList) newFrIt.next();
944  for (Iterator nFrIt = fragments.iterator(); nFrIt.hasNext();) {
945  SecFragment newFr = (SecFragment) nFrIt.next();
946  newFr.setRefSecSuggestion(linFr.getRefSecSuggestion());
947  sug.addSecFragment(newFr); // add converted fragment
948  }
949  }
950  return result;
951  } // convertLinFragments()
952 
953  /**
954  * Creates suggestion object from XML element with suggestion
955  *
956  * @param requestInfo Informations about client request
957  * @param el XML element with suggestion
958  * @param newTypes Array for adding new types of annotations
959  * @param useAlternatives True for work with alternatives, false otherwise
960  * @return Object with suggestion
961  */
962  @SuppressWarnings("unchecked")
963  private SecSuggestion createSugFromElement(RequestInfo requestInfo, Element el, ArrayList<AnnotType> newTypes, boolean useAlternatives) {
964  int lNum = requestInfo.getSession().getLanguageNum();
965 
966  String typeStr = el.getAttribute("type");
967  String tmpIdStr = el.getAttribute("id");
968 
969  if (typeStr == null || typeStr.isEmpty()) {
971  String msg = "Suggestion from SEC API without type.";
972  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
973  return null;
974  }
975  }
976 
977  String typePath = typeStr;
978  Integer typeIndex = Localisation.TYPE_PATH_NUMBERS.get(typeStr);
979  if (typeIndex != null) {
980  typePath = Localisation.getKBStr(lNum, typeIndex);
981  }
982 
983  NodeList attributeElements = el.getChildNodes();
984  int atCount = attributeElements.getLength();
985 
986  boolean isCorefefence = false;
987  for (int i = 0; i < atCount; i++) { // search for coreference
988  if(!(attributeElements.item(i) instanceof Element)){
989  continue;
990  }
991  if(!((Element) attributeElements.item(i)).getTagName().equalsIgnoreCase("attribute")){
992  continue;
993  }
994 
995  Element attrEl = (Element) attributeElements.item(i);
996  String nameStr = attrEl.getAttribute("name");
997  if (nameStr != null && nameStr.equalsIgnoreCase("coreference")) {
998  String valueStr = MessageProcessor.getElementContent(attrEl);
999  if (valueStr != null) {
1000  Integer v = null;
1001  try {
1002  v = Integer.parseInt(valueStr);
1003  } catch (Exception e) {
1004  }
1005  if ((v != null && v > 0) || valueStr.equalsIgnoreCase("true")) {
1006  isCorefefence = true;
1007  }
1008  break;
1009  }
1010  }
1011  } // search for coreference
1012 
1013  if (isCorefefence) {
1014  typePath = typePath + "/" + Localisation.getKBStr(lNum, Localisation.KB_COREFERENCE_TO) + typePath;
1015  }
1016 
1017  boolean typeCreated = false;
1018  ArrayList<AnnotTypeAttr> atList = new ArrayList<AnnotTypeAttr>();
1019  // try to find a type in the DB or newTypes array or create new one
1020  AnnotType annotType = findType(requestInfo, newTypes, typePath);
1021  if (annotType == null) {
1023  String msg = "Unable to obtain suggestion type";
1024  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1025  }
1026  return null;
1027  }
1028  // a type not found, new one was created
1029  else if (annotType.getId() == null && annotType.getAttributes().isEmpty()) {
1030  newTypes.addAll(SuggestionManager.breakdownType(annotType, requestInfo, newTypes));
1031  newTypes.add(annotType);
1032  typeCreated = true;
1033  }
1034 
1035  SecSuggestion sug = (useAlternatives ? new Alternative(annotType, "", null) : new Suggestion(annotType, "", null));
1036  ArrayList sugAList = (useAlternatives ? new ArrayList<AlternativeAttribute>() : new ArrayList<SugBaseAttribute>());
1037 
1038  HashMap<String, Integer> atPriorities = getPriorities(typeStr);
1039  HashMap<String, Integer> usedPriorities = new HashMap<String, Integer>();
1040 
1041  int pGen = 100; // counter for generating of missing priorities
1042  for (int i = 0; i < atCount; i++) { // for each attribute
1043  if(!(attributeElements.item(i) instanceof Element)){
1044  continue;
1045  }
1046  if(!((Element) attributeElements.item(i)).getTagName().equalsIgnoreCase("attribute")){
1047  continue;
1048  }
1049 
1050 
1051  Element attrEl = (Element) attributeElements.item(i);
1052 
1053  String nameStr = attrEl.getAttribute("name");
1054  if (nameStr != null && nameStr.equalsIgnoreCase("coreference")) {
1055  continue; // coreference was already processed
1056  }
1057 
1058  if(nameStr != null && nameStr.equalsIgnoreCase("confidence")){
1059  // confidence is special attribute
1060  String confidenceRawVal = MessageProcessor.getElementContent(attrEl);
1061  Integer confidenceValue;
1062  try {
1063  confidenceValue = Integer.parseInt(confidenceRawVal);
1064  } catch (Exception e) {
1065  // error can't decode confidence
1067  String msg = "Can't decode confidence attribute from sec api. Attribute:" + confidenceRawVal;
1068  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1069  }
1070  continue;
1071  }
1072 
1073  // set confidence
1074  if(useAlternatives){
1075  Alternative tmpAlt = (Alternative) sug;
1076  tmpAlt.setConfidence(confidenceValue);
1077  }else{
1078  Suggestion tmpSug = (Suggestion) sug;
1079  tmpSug.setConfidence(confidenceValue);
1080  }
1081  continue;
1082  }
1083 
1084  SecAttribute attr = processAttributeEl(requestInfo, attrEl, sugAList, atPriorities, usedPriorities, pGen, atList, useAlternatives, sug, newTypes);
1085 
1086  if (attr != null) {
1087  attr.setRefSecSuggestion(sug);
1088  sugAList.add(attr);
1089  pGen++;
1090  }
1091 
1092  } // for each attribute
1093 
1094  // Check confidence and set if it is missing
1095  if (useAlternatives) {
1096  Alternative tmpAlt = (Alternative) sug;
1097  if (tmpAlt.getConfidence() == null) {
1098  tmpAlt.setConfidence(DEFAULT_SUGGESTION_CONFIDENCE);
1099  }
1100  } else {
1101  Suggestion tmpSug = (Suggestion) sug;
1102  if (tmpSug.getConfidence() == null) {
1103  tmpSug.setConfidence(DEFAULT_SUGGESTION_CONFIDENCE);
1104  }
1105  }
1106 
1107  // Latitude and longitude should be combined to GeoPoint (visualised on the map)
1108  Iterator<SecAttribute> sait = sugAList.iterator();
1109  SecAttribute latitude = null;
1110  SecAttribute longitude = null;
1111  Integer pri = null;
1112  while (sait.hasNext()) {
1113  SecAttribute sba = sait.next();
1114  if (sba.getName().equals(LATITUDE_NAME)
1115  || sba.getName().equals(Localisation.getKBStr(lNum, Localisation.KB_LATITUDE))) {
1116  latitude = sba;
1117  pri = sba.getPriority();
1118  sait.remove();
1119  } else if (sba.getName().equals(LONGITUDE_NAME)
1120  || sba.getName().equals(Localisation.getKBStr(lNum, Localisation.KB_LONGITUDE))) {
1121  longitude = sba;
1122  if (pri == null) {
1123  pri = sba.getPriority();
1124  }
1125  sait.remove();
1126  }
1127  }
1128  SecAttribute geoAt = null;
1129  if (latitude != null && longitude != null) {
1130  try {
1131  BigDecimal lat = null;
1132  BigDecimal lon = null;
1133  String latStr = latitude.getStringValue();
1134  if (latStr != null && latStr.startsWith("\"") && latStr.endsWith("\"")) {
1135  latStr = latStr.substring(1,latStr.length() - 1);
1136  }
1137  String longStr = longitude.getStringValue();
1138  if (longStr != null && longStr.startsWith("\"") && longStr.endsWith("\"")) {
1139  longStr = longStr.substring(1,longStr.length() - 1);
1140  }
1141  if (latitude.getStringValue() != null && !latitude.getStringValue().equals("")) {
1142  lat = new BigDecimal(latStr);
1143  }
1144  if (longitude.getStringValue() != null && !longitude.getStringValue().equals("")) {
1145  lon = new BigDecimal(longStr);
1146  }
1147  if (latitude.getDecValue() != null) {
1148  lat = latitude.getDecValue();
1149  }
1150  if (longitude.getDecValue() != null) {
1151  lon = longitude.getDecValue();
1152  }
1153  SugBaseAttribute newSBA = new SugGeoPointAttribute(Localisation.getKBStr(lNum, Localisation.KB_GEO_LOCATION), lat, lon, null, pri);
1154  geoAt = (useAlternatives ? new AlternativeAttribute(newSBA) : newSBA);
1155  geoAt.setRefSecSuggestion(sug);
1156  sugAList.add(geoAt);
1157  } catch (NumberFormatException e) {
1158  if (latitude.getStringValue() != null && longitude.getStringValue() != null) {
1159  String stringVal = Localisation.getKBStr(lNum, Localisation.KB_LATITUDE) + ": " + latitude.getStringValue()
1160  + " " + Localisation.getKBStr(lNum, Localisation.KB_LONGITUDE) + ": " + longitude.getStringValue();
1162  geoAt = (useAlternatives ? new AlternativeAttribute(newSBA) : newSBA);
1163  geoAt.setRefSecSuggestion(sug);
1164  sugAList.add(geoAt);
1165  }
1166  }
1167  } else if (latitude != null) {
1168  sugAList.add(latitude);
1169  } else if (longitude != null) {
1170  sugAList.add(longitude);
1171  }
1172 
1173  if (useAlternatives) {
1174  ((Alternative) sug).setAttributes(sugAList);
1175  ((Alternative) sug).setTmpId(tmpIdStr);
1176  } else {
1177  ((Suggestion) sug).setAttributes(sugAList);
1178  ((Suggestion) sug).setTmpId(tmpIdStr);
1179  }
1180 
1181  if (typeCreated) {
1182  // if new type was created, attributes should be added
1183  Iterator<AnnotTypeAttr> atIt = atList.iterator();
1184  while (atIt.hasNext()) {
1185  AnnotTypeAttr ata = atIt.next();
1186  ata.setAnnotationType(annotType);
1187  }
1188  annotType.setAttributes(atList);
1189  }
1190 
1191  return sug;
1192  } // createSugFromElement()
1193 
1194  /**
1195  * Gets map with priorities of attributes of given type
1196  *
1197  * @param name Name of type
1198  * @return Returns map with priorities of attributes of given type
1199  */
1200  private static HashMap<String, Integer> getPriorities(String name) {
1201  ArrayList<SecApiReqTypeDef> des = AppBean.getDesTypeDefinitions();
1202  Iterator<SecApiReqTypeDef> dIt = des.iterator();
1203  while (dIt.hasNext()) {
1204  SecApiReqTypeDef rtd = dIt.next();
1205  if (rtd.getTypeName().contentEquals(name)) { // type found
1206  if (rtd.getPriorities() != null) {
1207  return rtd.getPriorities();
1208  }
1209  break; // priorities are not available, abort search
1210  }
1211  }
1212  return new HashMap<String, Integer>();
1213  } // getPriorities()
1214 
1215  /**
1216  * Creates suggestion object from XML element with attribute
1217  *
1218  * @param requestInfo Informations about client request
1219  * @param sugAList List of already processed attributes (for searching of duplicities)
1220  * @param atEl XML element with attribute
1221  * @param atPriorities Array with priorities of attributes
1222  * @param usedPriorities Array with priorities which was already used
1223  * @param pGen Counter for generating of missing priorities
1224  * @param atList List of attributes for creation of type of annotation
1225  * @param useAlternatives True for work with alternatives, false otherwise
1226  * @param sug Suggestion to which this attribute will be added
1227  * @param newTypes New annotation types
1228  * @return Object with attribute
1229  */
1230  private SecAttribute processAttributeEl(RequestInfo requestInfo, Element atEl,
1231  ArrayList sugAList,
1232  HashMap<String, Integer>atPriorities,
1233  HashMap<String, Integer>usedPriorities,
1234  int pGen, ArrayList<AnnotTypeAttr> atList,
1235  boolean useAlternatives,
1236  SecSuggestion sug,
1237  ArrayList<AnnotType> newTypes) {
1238  int lNum = requestInfo.getSession().getLanguageNum();
1239 
1240  String nameStr = atEl.getAttribute("name");
1241  String typeStr = atEl.getAttribute("type");
1242  String valueStr = null;
1243 
1244  /*
1245  * As entite has another attributes inside, this would cause an nullpointer exception
1246  */
1247  if(!typeStr.equalsIgnoreCase("entity")){
1248  valueStr = MessageProcessor.getElementContent(atEl);
1249  }
1250 
1251 
1252  if (nameStr == null || nameStr.isEmpty()) {
1254  String msg = "Attribute of suggestion from SEC API without name.";
1255  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1256  }
1257  return null;
1258  }
1259  if (typeStr == null || typeStr.isEmpty()) {
1261  String msg = "Attribute of suggestion from SEC API without type.";
1262  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1263  }
1264  return null;
1265  }
1266 
1267  if (typeStr.equals("url") || typeStr.equals("Url") || typeStr.equals("uri") || typeStr.equals("Uri")) {
1268  typeStr = "URI"; // fix case sensitivity and URL
1269  }
1270 
1271  String origName = nameStr;
1272 
1273  Integer nameIndex = Localisation.KB_STRINGS_INTERNAL.indexOf(nameStr);
1274  if (Constants.IDENTIFIER_TO_ENTITY_URI && (nameStr.equalsIgnoreCase("identifier") || nameStr.equalsIgnoreCase("URI_of_entity"))) {
1275  nameStr = Localisation.getKBStr(lNum, Localisation.KB_ENTITY_URI);
1276  if (typeStr.equals("URI") && valueStr != null && !valueStr.isEmpty()) {
1277  sug.setSAEntityIdentifier(valueStr);
1278  }
1279  } else if (Constants.DISPLAY_TERM_TO_NAME && nameStr.equalsIgnoreCase("display_term")) {
1280  nameStr = Localisation.getKBStr(lNum, Localisation.KB_PERSON_NAME);
1281  } else if (nameIndex > 0) { // if it is possible, localise attribute name
1282  nameStr = Localisation.getKBStr(lNum, nameIndex);
1283  }
1284 
1285  String ucType = Character.toUpperCase(typeStr.charAt(0)) + typeStr.substring(1);
1286 
1287  if (Constants.COMPLETE_IMAGE_URI && ucType.equals("Image") && valueStr != null
1288  && !valueStr.startsWith("http")) {
1289  valueStr = AppBean.getKBImagePrefix() + valueStr;
1290  }
1291 
1292  SecAttribute result = null;
1293 
1294  if (Constants.SIMPLE_TYPES.contains(ucType)) {
1295  if (ucType.equals("Date")) { // date must be handled separately (ISO format)
1296  if (valueStr == null || valueStr.isEmpty()) {
1297  result = (useAlternatives ?
1298  new AlternativeAttribute(new SugDateAttribute(nameStr, null, null))
1299  : new SugDateAttribute(nameStr, null, null));
1300  } else {
1301  Date dateVal = parseDate(valueStr);
1302  if (dateVal == null) { // date as "1995" must be handled as String
1303  result = (useAlternatives ?
1304  new AlternativeAttribute(new SugStringAttribute(nameStr, valueStr, null))
1305  : new SugStringAttribute(nameStr, valueStr, null));
1306  } else {
1307  result = (useAlternatives ?
1308  new AlternativeAttribute(new SugDateAttribute(nameStr, dateVal, null))
1309  : new SugDateAttribute(nameStr, dateVal, null));
1310  if (useAlternatives) {
1311  AlternativeAttribute tmpAt = (AlternativeAttribute) result;
1312  tmpAt.setBoolVAlue(true);
1313  } else {
1314  SugBaseAttribute tmpAt = (SugBaseAttribute) result;
1315  tmpAt.setBoolVAlue(true);
1316  }
1317  }
1318  }
1319  }
1320  /*
1321  * GeoPoint attribute
1322  */
1323  else if(ucType.equalsIgnoreCase("GeoPoint")){
1324  try {
1325  // Create proper type of attribute
1326  result = (useAlternatives ?
1327  new AlternativeAttribute(SugAttributeManager.createAttribute(nameStr, ucType, null))
1328  : SugAttributeManager.createAttribute(nameStr, ucType, null));
1329 
1330  //Assign value to GeoPointAttribute
1331  String latitude = processGeoPoint(atEl, true);
1332  String longitude = processGeoPoint(atEl, false);
1333  if (useAlternatives) {
1334  ((AlternativeAttribute) result).setGeoPointStringValue(latitude, longitude);
1335  } else {
1336  ((SugGeoPointAttribute) result).setStringValue(latitude, longitude);
1337  }
1338  } catch (ClassNotFoundException ex) {
1340  String msg = "Unknown type of attribute of suggestion from SEC API: " + typeStr;
1341  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1342  }
1343  return null;
1344  }catch (IllegalArgumentException ex) {
1346  String msg = "Bad value of attribute of suggestion from SEC API: " + valueStr + " (type " + typeStr + ")";
1347  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
1348  }
1349  result = (useAlternatives ?
1350  new AlternativeAttribute(new SugStringAttribute(nameStr, valueStr, null))
1351  : new SugStringAttribute(nameStr, valueStr, null));
1352  }
1353 
1354  }
1355  /*
1356  * Entity Attribute
1357  */
1358  else if(ucType.equalsIgnoreCase("Entity")){
1359  try {
1360  // Create proper type of attribute
1361  result = (useAlternatives ?
1362  new AlternativeAttribute(SugAttributeManager.createAttribute(nameStr, ucType, null))
1363  : SugAttributeManager.createAttribute(nameStr, ucType, null));
1364 
1365  //Get all additional attributes
1366  if (useAlternatives) {
1367  ArrayList<AltEntityAdditionalAttribute> altAddAttList;
1368  altAddAttList = processAltEntityAddAttributes(atEl, (AlternativeAttribute) result);
1369  ((AlternativeAttribute) result).setEntityAdditionalAttributes(altAddAttList);
1370  } else {
1371  ArrayList<SugEntityAdditionalAttribute> sugAddAttList;
1372  sugAddAttList = processSugEntityAddAttributes(atEl, (SugEntityAttribute) result);
1373  ((SugEntityAttribute) result).setEntityAdditionalAttributes(sugAddAttList);
1374  }
1375 
1376  } catch (ClassNotFoundException ex) {
1378  String msg = "Unknown type of attribute of suggestion from SEC API: " + typeStr;
1379  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1380  }
1381  return null;
1382  }
1383  }
1384  else { // Other simple types
1385  try {
1386  result = (useAlternatives ?
1387  new AlternativeAttribute(SugAttributeManager.createAttribute(nameStr, ucType, null))
1388  : SugAttributeManager.createAttribute(nameStr, ucType, null));
1389  if (useAlternatives) {
1390  ((AlternativeAttribute) result).setRawValue(valueStr);
1391  } else {
1392  ((SugBaseAttribute) result).setRawValue(valueStr);
1393  }
1394  } catch (ClassNotFoundException ex) {
1396  String msg = "Unknown type of attribute of suggestion from SEC API: " + typeStr;
1397  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1398  }
1399  return null;
1400  } catch (IllegalArgumentException ex) {
1402  String msg = "Bad value of attribute of suggestion from SEC API: " + valueStr + " (type " + typeStr + ")";
1403  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.WARNING, msg);
1404  }
1405  result = (useAlternatives ?
1406  new AlternativeAttribute(new SugStringAttribute(nameStr, valueStr, null))
1407  : new SugStringAttribute(nameStr, valueStr, null));
1408  }
1409  }
1410  } else { // it is not simple
1411  /*
1412  * Linked Attribute
1413  */
1414  if (ucType.equalsIgnoreCase("LinkedAnnotation") || ucType.equalsIgnoreCase("AnnotationLink")) {
1415  try {
1416  // Create proper type of attribute
1417  result = (useAlternatives
1418  ? new AlternativeAttribute(SugAttributeManager.createAttribute(nameStr, ucType, null))
1419  : SugAttributeManager.createAttribute(nameStr, ucType, null));
1420 
1421  String typeName = atEl.getAttribute("annotType");
1422  AnnotType type = null;
1423 
1424  if (typeName != null) {
1425  Integer typeIndex = Localisation.TYPE_PATH_NUMBERS.get(typeStr);
1426  if (typeIndex != null) {
1427  typeName = Localisation.getKBStr(lNum, typeIndex);
1428  }
1429  type = findType(requestInfo, newTypes, typeName);
1430 
1431  if (type == null) {
1433  String msg = "Unable to obtain suggestion type";
1434  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1435  }
1436  return null;
1437  }
1438  // a type not found, new one was created
1439  else if (type.getId() == null && type.getAttributes().isEmpty()) {
1440  newTypes.addAll(SuggestionManager.breakdownType(type, requestInfo, newTypes));
1441  newTypes.add(type);
1442  }
1443  }
1444 
1445  if (useAlternatives) {
1446  ((AlternativeAttribute) result).setAttributeType(type);
1447  } else {
1448  ((SugLinkedAttribute) result).setAttributeType(type);
1449  }
1450 
1451  if (valueStr != null && !valueStr.isEmpty()) {
1452  if (useAlternatives) {
1453  ((AlternativeAttribute) result).setUri(valueStr);
1454  } else {
1455  ((SugLinkedAttribute) result).setUri(valueStr);
1456  }
1457  }
1458  } catch (ClassNotFoundException ex) {
1460  String msg = "Unknown type of attribute of suggestion from SEC API: " + typeStr;
1461  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1462  }
1463  return null;
1464  }
1465  }
1466  /*
1467  * Nested Attribute
1468  */
1469  else if (ucType.equalsIgnoreCase("NestedAnnotation")) {
1470  try {
1471  // Create proper type of attribute
1472  result = (useAlternatives ?
1473  new AlternativeAttribute(SugAttributeManager.createAttribute(nameStr, ucType, null))
1474  : SugAttributeManager.createAttribute(nameStr, ucType, null));
1475 
1476  String typeName = atEl.getAttribute("annotType");
1477  AnnotType type = null;
1478 
1479  if (typeName != null) {
1480  Integer typeIndex = Localisation.TYPE_PATH_NUMBERS.get(typeStr);
1481  if (typeIndex != null) {
1482  typeName = Localisation.getKBStr(lNum, typeIndex);
1483  }
1484  type = findType(requestInfo, newTypes, typeName);
1485 
1486  if (type == null) {
1488  String msg = "Unable to obtain suggestion type";
1489  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1490  }
1491  return null;
1492  }
1493  // a type not found, new one was created
1494  else if (type.getId() == null && type.getAttributes().isEmpty()) {
1495  newTypes.addAll(SuggestionManager.breakdownType(type, requestInfo, newTypes));
1496  newTypes.add(type);
1497  }
1498  }
1499 
1500  if (useAlternatives) {
1501  ((AlternativeAttribute) result).setAttributeType(type);
1502  } else {
1503  ((SugNestedAttribute) result).setAttributeType(type);
1504  }
1505 
1506  String tmpUri = valueStr;
1507  if (valueStr.startsWith("<text")) { // directly nested
1508  tmpUri = null;
1509  } else if (valueStr.replaceAll("[\\s\\u00A0]+$", "").contentEquals("")) { // empty
1510  tmpUri = null;
1511  }
1512  if (tmpUri != null && !tmpUri.isEmpty()) {
1513  if (useAlternatives) {
1514  ((AlternativeAttribute) result).setUri(tmpUri);
1515  } else {
1516  ((SugNestedAttribute) result).setUri(tmpUri);
1517  }
1518  } else {
1519  //Search for a nested annotation within this attribute
1520  if (useAlternatives) {
1521  ((AlternativeAttribute) result).setNestedAlternative(processNestedAlternative(atEl, requestInfo, newTypes));
1522  //Assign to processed nested alternative value of 'nestedInAlternative' variable which is owner of this attribute
1523  ((AlternativeAttribute) result).getNestedAlternative().setNestedInAlternative((Alternative)sug);
1524  } else {
1525  ((SugNestedAttribute) result).setNestedSuggestion(processNestedSugg(atEl, requestInfo, newTypes));
1526  //Assign to processed nested suggestion value of 'nestedInSug' variable which is owner of this attribute
1527  ((SugNestedAttribute) result).getNestedSuggestion().setNestedInSuggestion((Suggestion)sug);
1528  }
1529  }
1530 
1531  } catch (ClassNotFoundException ex) {
1533  String msg = "Unknown type of attribute of suggestion from SEC API: " + typeStr;
1534  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1535  }
1536  return null;
1537  }
1538  }
1539  } // it is not simple
1540 
1541  Integer p = usedPriorities.get(origName);
1542  if (p == null) {
1543  p = atPriorities.get(origName); // find default priority for attribute
1544  if (p == null) {
1545  p = pGen; // use counter as backup solution
1546  }
1547  } else { // if priority was already used
1548  while (usedPriorities.containsValue(p)) {
1549  p++; // increment it to do not use same priority twice
1550  }
1551  }
1552  if (result != null) {
1553  result.setPriority(p);
1554  usedPriorities.put(origName, p);
1555 
1556  AnnotTypeAttr ata = new AnnotTypeAttr(null, result.getName(), ucType, false, p);
1557 
1558  if (useAlternatives) {
1559  if(((AlternativeAttribute) result).getAttributeType() != null){
1560  ata.setAttributeType(((AlternativeAttribute) result).getAttributeType());
1561  }
1562  } else {
1563  if(((SugBaseAttribute)result).getAttributeType() != null){
1564  ata.setAttributeType(((SugBaseAttribute)result).getAttributeType());
1565  }
1566  }
1567 
1568 
1569  atList.add(ata);
1570  }
1571 
1572  return result;
1573  } // processAttributeEl()
1574 
1575  /**
1576  * Processes element with entity additional attributes in entity in attribute of suggestion
1577  *
1578  * @param el Element with entity additional attributes
1579  * @param refEntity Attribute of suggestion of type entity to which attributes belongs
1580  * @return List of entity additional attributes
1581  */
1582  private static ArrayList<SugEntityAdditionalAttribute> processSugEntityAddAttributes(Element el,
1583  SugEntityAttribute refEntity) {
1584 
1585  ArrayList<SugEntityAdditionalAttribute> result = new ArrayList<SugEntityAdditionalAttribute>();
1586  for (Node node = el.getFirstChild(); node != null; node = node.getNextSibling()) {
1587  if (!(node instanceof Element)) {
1588  continue;
1589  }
1590  if (!((Element) node).getTagName().equalsIgnoreCase("entityAttribute")) {
1591  continue;
1592  }
1593 
1594  String nameStr = ((Element) node).getAttribute("name");
1595  String typeStr = ((Element) node).getAttribute("type");
1596  String valueStr = MessageProcessor.getElementContent(((Element) node));
1597 
1598  result.add(new SugEntityAdditionalAttribute(nameStr, typeStr, valueStr, refEntity));
1599  }
1600 
1601 
1602  return result;
1603  }
1604 
1605  /**
1606  * Processes element with entity additional attributes in entity in attribute of alternative
1607  *
1608  * @param el Element with entity additional attributes
1609  * @param refAltAtt Attribute of alternative of type entity to which attributes belongs
1610  * @return List of entity additional attributes
1611  */
1612  private static ArrayList<AltEntityAdditionalAttribute> processAltEntityAddAttributes(Element el,
1613  AlternativeAttribute refAltAtt) {
1614 
1615  ArrayList<AltEntityAdditionalAttribute> result = new ArrayList<AltEntityAdditionalAttribute>();
1616  for (Node node = el.getFirstChild(); node != null; node = node.getNextSibling()) {
1617  if (!(node instanceof Element)) {
1618  continue;
1619  }
1620  if (!((Element) node).getTagName().equalsIgnoreCase("entityAttribute")) {
1621  continue;
1622  }
1623 
1624  String nameStr = ((Element) node).getAttribute("name");
1625  String typeStr = ((Element) node).getAttribute("type");
1626  String valueStr = MessageProcessor.getElementContent(((Element) node));
1627 
1628  result.add(new AltEntityAdditionalAttribute(nameStr, typeStr, valueStr, refAltAtt));
1629  }
1630 
1631  return result;
1632  }
1633 
1634  /**
1635  * Gets GeoPoint value from element
1636  *
1637  * @param el GeoPoint element
1638  * @param latitude Flag for getting either latitude or longitude
1639  * @return If flag parameter is set to true, returns latitude value, longitude otherwise
1640  */
1641  private static String processGeoPoint(Element el, boolean latitude) {
1642 
1643  for (Node node = el.getFirstChild(); node != null; node = node.getNextSibling()) {
1644  if (!(node instanceof Element)) {
1645  continue;
1646  }
1647 
1648  Element tmpEl = (Element) node;
1649  if (tmpEl.getTagName().equals("geo:Point")) {
1650  for (Node innerNode = tmpEl.getFirstChild(); innerNode != null; innerNode = innerNode.getNextSibling()) {
1651  if (!(innerNode instanceof Element)) {
1652  continue;
1653  }
1654  if (((Element) innerNode).getTagName().equals("geo:lat")) {
1655  if (latitude) {
1656  return getGeoPointNodeValue(innerNode.getFirstChild());
1657  }
1658  } else if (((Element) innerNode).getTagName().equals("geo:long")) {
1659  if (!latitude) {
1660  return getGeoPointNodeValue(innerNode.getFirstChild());
1661  }
1662  } else {
1663  continue;
1664  }
1665  }
1666  }
1667  }
1668 
1669  return "";
1670  }
1671 
1672  /**
1673  * Returns node value of node with GeoPoint
1674  *
1675  * @return Returns node value
1676  */
1677  private static String getGeoPointNodeValue(Node node) {
1678 
1679  for (Node n = node; n != null; n = n.getNextSibling()) {
1680  if (n.getNodeValue() != null) {
1681  return n.getNodeValue();
1682  }
1683  }
1684  return null;
1685  }
1686 
1687  /**
1688  * Parses XML from the SEC API
1689  *
1690  * @param XMLString String with XML with messages from client
1691  * @return Parsed XML in w3c.dom.Document
1692  */
1693  private static Document parseXml(String XMLString) {
1694  Document dom;
1695  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1696  dbf.setNamespaceAware(true);
1697 
1698  try {
1699  DocumentBuilder db = dbf.newDocumentBuilder();
1700  InputSource is = new InputSource();
1701  is.setCharacterStream(new StringReader(XMLString));
1702  dom = db.parse(is);
1703  } catch (ParserConfigurationException pce) {
1705  String msg = "ParserConfigurationException while parsing XML from the SEC API.";
1706  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg, pce);
1707  }
1708  return null; // bad request
1709  } catch (SAXException se) {
1711  String msg = "SAXException while parsing XML from the SEC API.";
1712  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.ALL, msg, se);
1713  }
1714  return null;
1715  } catch (IOException ioe) {
1717  String msg = "IOException while parsing XML from the SEC API.";
1718  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg, ioe);
1719  }
1720  return null;
1721  }
1722 
1723  return dom;
1724  } // parseXml()
1725 
1726  /**
1727  * Parses date from ISO format from dates.py (which is part of SEC API NER)
1728  *
1729  * @param sDate String with date
1730  * @return Returns parsed date
1731  */
1732  private static Date parseDate(String sDate) {
1733  if (sDate == null || sDate.isEmpty()) {
1734  return null;
1735  }
1736  if (sDate.length() == 4 || sDate.length() == 7) { // probably "yyyy" or "yyyy-MM"
1737  return null; // partial date unsupported
1738  }
1739  if (sDate.length() < 10) { // "yyyy-MM-dd" must have 10 characters
1741  String msg = "Wrong date format from SEC API: " + sDate;
1742  Logger.getLogger(SECAPISuggestionTranslator.class.getName()).log(Level.SEVERE, msg);
1743  }
1744  return null;
1745  }
1746  int index1 = sDate.indexOf("-");
1747  int index2 = sDate.lastIndexOf("-");
1748  if (index1 == -1 || index2 == -1 || index1 == index2) {
1749  return null;
1750  }
1751  if (sDate.substring(index1 + 1, index2).equals("00")) {
1752  return null;
1753  }
1754  if (sDate.length() - index2 == 3) {
1755  if (sDate.substring(index2 + 1).equals("00")) {
1756  return null;
1757  }
1758  }
1759  Date date;
1760  try {
1761  date = new SimpleDateFormat("yyyy-MM-dd").parse(sDate);
1762  } catch (Exception e) {
1763  return null;
1764  }
1765  return date;
1766  } // parseDate()
1767 
1768  /**
1769  * Searches for a type specified by the typePath and returns the type if found
1770  *
1771  * @param requestInfo Information about a client request
1772  * @param newTypes A list containing newly created types
1773  * @param typePath A path for the type identification
1774  * @return Type data if found, empty data object otherwise
1775  */
1776  public AnnotType findType(RequestInfo requestInfo, ArrayList<AnnotType> newTypes, String typePath) {
1777  UserGroup group;
1778 
1779  if(defaultUserGroup == null){
1780  defaultUserGroup = requestInfo.getSession().getDefaultGroup();
1781  if (defaultUserGroup == null) {
1782  defaultUserGroup = this.userGroup;
1783  }
1784  }
1785 
1786  group = defaultUserGroup;
1787 
1788  String typeUri = baseTypeUri + "g" + group.getId() + "/" + typePath;
1789 
1790  if(typesBuffer.containsKey(typeUri)){
1791  return typesBuffer.get(typeUri);
1792  }
1793 
1794  if (newTypes != null && !newTypes.isEmpty()) { // look into the new type list
1795  Iterator<AnnotType> annotTypeIt = newTypes.iterator();
1796  while (annotTypeIt.hasNext()) {
1797  AnnotType aT = annotTypeIt.next();
1798  if (aT.getUri() != null && aT.getUri().equals(typeUri)) {
1799  return aT;
1800  }
1801  }
1802  }
1803 
1804  Object[] params = new Object[2];
1805  params[0] = "uri";
1806  params[1] = typeUri;
1807 
1808  List tList = AppBean.getPersistenceManager().queryDB("AnnotType.findByUri", params);
1809 
1810  if (tList != null && !tList.isEmpty()) { // if type is already in the DB
1811  typesBuffer.put(typeUri, (AnnotType) tList.get(0));
1812  return (AnnotType) tList.get(0);
1813  }
1814 
1815 
1816  return new AnnotType(typeUri, typePath, null, group); // an empty type
1817  } // findType()
1818 
1819 
1820  /**
1821  * @brief The object that hold informations ipmortant for translate of alternative
1822  * from SEC Api.
1823  */
1825  /** Dummy alternative for converting of fragment */
1827  /** Array of unconverted alternatives from SEC API */
1828  private ArrayList<Alternative> unconvertedAlternatives;
1829  /** Array of converted alternative suggestions from DB */
1830  private ArrayList<Suggestion> convertedAlternatives;
1831 
1832  /**
1833  * Gets dummy alternative for converting of fragment.
1834  *
1835  * @return dummy alternative for converting of fragment
1836  */
1838  return dummyAlternative;
1839  }
1840 
1841  /**
1842  * Sets dummy alternative for converting of fragment.
1843  *
1844  * @param dummyAlternative dummy alternative for converting of fragment.
1845  */
1847  this.dummyAlternative = dummyAlternative;
1848  }
1849 
1850  /**
1851  * Gets array of unconverted alternatives from SEC API.
1852  *
1853  * @return array of unconverted alternatives from SEC API
1854  */
1855  public ArrayList<Alternative> getUnconvertedAlternatives() {
1856  return unconvertedAlternatives;
1857  }
1858 
1859  /**
1860  * Sets array of unconverted alternatives from SEC API.
1861  *
1862  * @param unconvertedAlternatives array of unconverted alternatives from SEC API
1863  */
1864  public void setUnconvertedAlternatives(ArrayList<Alternative> unconvertedAlternatives) {
1865  this.unconvertedAlternatives = unconvertedAlternatives;
1866  }
1867 
1868  /**
1869  * Gets array of converted alternative suggestions from DB.
1870  *
1871  * @return array of converted alternative suggestions from DB
1872  */
1873  public ArrayList<Suggestion> getConvertedAlternatives() {
1874  return convertedAlternatives;
1875  }
1876 
1877  /**
1878  * Sets array of converted alternative suggestions from DB.
1879  *
1880  * @param convertedAlternatives array of converted alternative suggestions from DB
1881  */
1882  public void setConvertedAlternatives(ArrayList<Suggestion> convertedAlternatives) {
1883  this.convertedAlternatives = convertedAlternatives;
1884  }
1885 
1886  /**
1887  * Sets alternative of paramether for each unconverted alternative.
1888  *
1889  * @param alternativeOf suggestion that will be set as main suggestion
1890  */
1891  public void setAlternativeOf(Suggestion alternativeOf){
1892  if(unconvertedAlternatives != null && !unconvertedAlternatives.isEmpty()){
1893  Iterator<Alternative> unconvertedIt = unconvertedAlternatives.iterator();
1894  while(unconvertedIt.hasNext()){
1895  unconvertedIt.next().setAlternativeOfSuggestion(alternativeOf);
1896  }
1897  }
1898  }
1899 
1900  /**
1901  * Method sorts array of uncovered alternatives.
1902  */
1904  Collections.sort(unconvertedAlternatives, new ConfidenceComparator());
1905  }
1906 
1907  /**
1908  * @brief The object implements comparator of Alternative objects that are
1909  * compared by confidence (from highest to lowest confidence).
1910  */
1911  public class ConfidenceComparator implements Comparator<Alternative> {
1912 
1913  @Override
1914  public int compare(Alternative o1, Alternative o2) {
1915  int result = o1.getConfidence().compareTo(o2.getConfidence());
1916  if (result == 0) {
1917  return result;
1918  } else {
1919  return (result * (-1));
1920  }
1921  }
1922  } // public class ConfidenceComparator
1923 
1924  } // private class TranslateAlternativeHolder
1925 
1926 } // public class SECAPISuggestionTranslator
Alternative processNestedAlternative(Element atEl, RequestInfo requestInfo, ArrayList< AnnotType > newTypes)
Class representing attribute of type Date for prupose of suggestion.
static ArrayList< AltEntityAdditionalAttribute > processAltEntityAddAttributes(Element el, AlternativeAttribute refAltAtt)
Utility functions for document linearization.
Definition: Linearizer.java:40
Attribute manager provides a way how to create new attributes for prupose of suggestion.
Class representing attribute of type of annotation.
static void linearizeSuggestions(HashMap< Integer, ArrayList< SuggestionFragment >> linFragmentsMap, Document doc, ArrayList< Suggestion > suggestions)
SecAttribute processAttributeEl(RequestInfo requestInfo, Element atEl, ArrayList sugAList, HashMap< String, Integer >atPriorities, HashMap< String, Integer >usedPriorities, int pGen, ArrayList< AnnotTypeAttr > atList, boolean useAlternatives, SecSuggestion sug, ArrayList< AnnotType > newTypes)
Class representing attribute of type NestedAnnotation for peupose of suggestion.
Singleton for storing global variables.
Definition: AppBean.java:47
boolean isAlternativeInSuggestionList(List< Suggestion > suggestions, Alternative alt, HashMap< Integer, ArrayList< SuggestionFragment >> sugToLinFragments)
Class representing vocabulary entity attribute for prupose of suggestion.
ArrayList< Alternative > processAlternatives(RequestInfo requestInfo, Element alternatvesEl, ArrayList< AnnotType > newTypes, AlternativeFragment altFragment)
static final ArrayList< String > SIMPLE_TYPES
Definition: Constants.java:153
Static class which parses and process XML with messages.
Class representing user group.
Definition: UserGroup.java:47
Interface for SugBaseAttribute and AlternativeAttribuge.
void findAlternativeSuggestions(HashMap< Integer, TranslateAlternativeHolder > alternatives, ArrayList< Suggestion > validSuggestions, HashMap< Integer, ArrayList< SuggestionFragment >> sugToLinFragments)
ArrayList convertLinFragments(RequestInfo requestInfo, ArrayList result, ArrayList allLinFragments, boolean useAlternatives)
Methods for translating output from SEC API to the Suggestion objects.
Class representing attribute of type String for prupose of suggestion.
ArrayList< Alternative > translateAlternativeFromSecApi(RequestInfo requestInfo, String SECAPIResults, ArrayList< AnnotType > newTypes, ArrayList< Suggestion > validSuggestions)
Class for creating of requested type definition for SEC API.
static final int MAX_COUNT_OF_ALTERNATIVES_TO_ONE_SUGGESTION
Definition: Constants.java:351
AlternativeFragment fixAlternativeFragment(RequestInfo requestInfo, AlternativeFragment frg)
Class representing type of annotation.
Definition: AnnotType.java:58
SecSuggestion createSugFromElement(RequestInfo requestInfo, Element el, ArrayList< AnnotType > newTypes, boolean useAlternatives)
ArrayList< Alternative > makeNewAlternative(RequestInfo requestInfo, HashMap< Integer, ArrayList< SuggestionFragment >> sugToLinFragments, HashMap< Integer, TranslateAlternativeHolder > alternativesHolders)
Class representing additional attribute of entity in alternative attribute.
static boolean overlappingFragment(ArrayList< SuggestionFragment > sugFragments, int newFragStart, int newFragEnd)
Class representing attribute of type AnnotationLink for prupose of suggestion.
static String createErrorMsg(int version, int lNum, int error)
static ArrayList< ArrayList< SuggestionFragment > > linSugFragmentsToFragments(ArrayList< SuggestionFragment > linFragments, Document doc, ArrayList< ArrayList< SuggestionFragment >> badFragments)
Class consisting of traversing method and compare method.
Definition: Comparator.java:37
Suggestion processNestedSugg(Element attEl, RequestInfo requestInfo, ArrayList< AnnotType > newTypes)
AnnotType findType(RequestInfo requestInfo, ArrayList< AnnotType > newTypes, String typePath)
Processed informations about client request.
Class representing suggestion of annotation.
Definition: Suggestion.java:87
The object that hold informations ipmortant for translate of alternative from SEC Api...
The object implements comparator of Alternative objects that are compared by confidence (from highest...
Class responsible for localised strings.
boolean contentEqualsForSec(Suggestion other, ArrayList< SuggestionFragment > linearizedFragments, boolean testFragments)
static String getKBStr(int langNum, int stringNum)
static ArrayList< SugEntityAdditionalAttribute > processSugEntityAddAttributes(Element el, SugEntityAttribute refEntity)
Interface for SuggestionFragment and AlternativeFragment.
ArrayList< Suggestion > translateSugFromSecApi(RequestInfo requestInfo, String SECAPIResults, ArrayList< AnnotType > newTypes)