4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
SECDInterfaceThread.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: SECDInterfaceThread.java
5  * Description: Class provides links anotation client with NLP for questions on vocabulary items.
6  */
7 
8 /**
9  * @file SECDInterfaceThread.java
10  *
11  * @brief Class forwards queries from anotation client to the NLP server and and
12  * creates a message for annotation client with the results from the NLP server.
13  */
14 
15 package cz.vutbr.fit.knot.annotations.modules.SECDictionaryInterface;
16 
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Set;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37 import org.json.simple.JSONArray;
38 import org.json.simple.JSONObject;
39 import org.json.simple.JSONValue;
40 
41 /**
42  * @brief Class forwards queries from anotation client to the SEC API server and and
43  * creates a message for annotation client with the results from the SEC API server.
44  *
45  * @author Martin Petr (xpetrm05)
46  */
47 public class SECDInterfaceThread extends Thread{
48  /** Informations about client request */
50  /** Detailed informations about request for entities */
52 
53  /** New prefix of freebase image URI */
54  public static final String PREFIX_NEW = "https://www.googleapis.com/freebase/v1/image/";
55  /** New postfix of freebase image URI */
56  public static final String POSTFIX_NEW = "?maxwidth=500&maxheight=500";
57  /** Old prefix of freebase image URI which must be replaced */
58  public static final String PREFIX = "api.freebase.com/api/trans/raw/";
59 
60  /** Maximum results to return if limit is not specified by client */
61  public static final int MAX_RESULTS = 50;
62 
63  /**
64  * Name of column in KB where name of entity is stored.
65  * Entities in KB have more options where name can be so fallback must be used
66  */
67  public static final ArrayList<String> NAME_ATTRIBUTES = new ArrayList<String>(Arrays.asList(
68  "name",
69  "preferred_term",
70  "display_term",
71  "short_name",
72  "alias"
73  ));
74  /** Name of column in KB where URI of entity is stored. */
75  public static final String URI_ATTRIBUTE = "identifier";
76  /** Name of column in KB where URI of image of entity is stored. */
77  public static final String VIS_REPRESENTATION_ATTRIBUTE = "image";
78  /** Alternative name of column in KB where URI of image of entity is stored. */
79  public static final String ALT_VIS_REPRESENTATION_ATTRIBUTE = "freebase_image";
80  /** Name of column in KB where description of entity is stored. */
81  public static final String DESCRIPTION_ATTRIBUTE = "description";
82 
83  /** Separator of values in multivalue attributes */
84  public static final String MULTIPLE_DATA_SEPARATOR = "\\|";
85 
86  /** Allowed postfix of image file name */
87  private final static ArrayList<String> ALLOWED_POSTFIX = new ArrayList<String>(Arrays.asList(
88  "jpg",
89  "gif",
90  "bmp",
91  "png",
92  "jpeg"
93  ));
94 
95  /** Attributes which should be requested from SEC API */
96  public static final ArrayList<String> REQUESTED_ATTRIBUTES = new ArrayList<String>(Arrays.asList(
97  "name",
98  "preferred_term",
99  "display_term",
100  "short_name",
105  ));
106 
107  /**
108  * Constructor.
109  *
110  * @param requestInfo object with informations about requests from client
111  */
113  super("SECDInterfaceThread");
114  this.requestInfo = requestInfo;
115  request = requestInfo.getEntityRequest();
116  }
117 
118  /**
119  * Method gets entities according to client's request and send the response
120  * to the client by comet channel.
121  */
122  @Override
123  public void run() {
124  String messageForClient = "";
125  ArrayList<EntityAttribute> resultsArray = null;
126 
127  resultsArray = getResultFromSECAPI(request);
128 
129  // workaround for old URIs of Freebase images in KB
130  if(resultsArray != null && !resultsArray.isEmpty() && Constants.VISUAL_REPRESENTATION_URI_CHANGE){
131  Iterator<EntityAttribute> resultIt = resultsArray.iterator();
132  while(resultIt.hasNext()){
133  EntityAttribute currentAttr = resultIt.next();
134  if(((Entity)currentAttr.getValue()).getVisualRepresentation()!= null){
135  String uri = ((Entity)currentAttr.getValue()).getVisualRepresentation();
136  if(!uri.isEmpty()){
137  String[] result = uri.split(PREFIX);
138  if(result.length == 2){
139  String core = result[1];
140  if(!core.isEmpty()){
141  Entity currentValue = (Entity)currentAttr.getValue();
142  currentValue.setVisualRepresentation(PREFIX_NEW + core + POSTFIX_NEW);
143  currentAttr.setValue(currentValue);
144  }
145  }
146  }
147  }
148  }
149  }
150 
151  // make message with results for client
152  if (resultsArray != null && !resultsArray.isEmpty()) {
153  messageForClient = makeMessageFromResult(resultsArray);
154  }
155 
156  if (messageForClient != null && !messageForClient.isEmpty()) {
157  requestInfo.getSession().addMessageTS(messageForClient);
158  requestInfo.getSession().notifyComet();
159  }
160  } // run()
161 
162  /**
163  * Method makes JSON string from EntityRequest object (that represents request
164  * for entity from client).
165  *
166  * @param request request from client that will be parse
167  * @return JSON string for SEC Store API
168  */
170  StringBuilder resultBuilder = new StringBuilder();
171 
172  resultBuilder.append("{ \"getEntities\":\n");
173  resultBuilder.append("{ \"type\":\n");
174  resultBuilder.append("\"");
175  resultBuilder.append(request.getType());
176  resultBuilder.append("\",\n");
177  resultBuilder.append(" \"filter\":\n");
178  resultBuilder.append("\"");
179  resultBuilder.append(request.getFilter());
180  resultBuilder.append("\",\n");
181  resultBuilder.append(" \"user\":\n");
182  resultBuilder.append("\"");
183  resultBuilder.append(requestInfo.getSession().getUser().getLogin());
184  resultBuilder.append("\",\n");
185 
186  resultBuilder.append("\"userGroups\":[\n");
187  Iterator<UserGroup> groupIt = requestInfo.getSession().getUser().getGroups().iterator();
188  while(groupIt.hasNext()){
189  UserGroup actualGroup = groupIt.next();
190  resultBuilder.append("{\"uri\":");
191  resultBuilder.append("\"");
192  resultBuilder.append(EscapeCharsToSend(actualGroup.getUri()));
193  resultBuilder.append("\",\n");
194  resultBuilder.append("\"name\":");
195  resultBuilder.append("\"");
196  resultBuilder.append(actualGroup.getName());
197  if(groupIt.hasNext()){
198  resultBuilder.append("\"},\n");
199  }
200  else{
201  resultBuilder.append("\"}\n");
202  }
203  }
204  resultBuilder.append("],\n");
205  resultBuilder.append(" \"userFrom\":\n");
206  resultBuilder.append("\"");
207  if(requestInfo.getSession().getUser().getComeFrom() != null){
208  resultBuilder.append(requestInfo.getSession().getUser().getComeFrom());
209  }else{
210  resultBuilder.append("");
211  }
212  resultBuilder.append("\"}}\n");
213 
214 
215  return resultBuilder.toString();
216  } // makeRequestString()
217 
218  /**
219  * Method make string from array of EntityAtributes that will be sent to client.
220  *
221  * @param responses array list with objects from SEC Store API
222  * @return XML string for client
223  */
224  private String makeMessageFromResult(ArrayList<EntityAttribute> responses){
225  StringBuilder resultString = new StringBuilder();
226  Iterator<EntityAttribute> resultIt = responses.iterator();
227  int counter = 0;
228  Integer limit = request.getMaxResults();
229 
230  // If user didn't defined maximum results, default value is used
231  if(limit == null || limit == -1){
232  limit = MAX_RESULTS;
233  }
234 
235  if (requestInfo.getSession().getProtocolLOD() < Constants.PROTOCOL_LOD_V2) {
236  // Protocol v1.x is used
237  resultString.append("<entities>");
238  while(resultIt.hasNext()){
239  EntityAttribute currentEntity = resultIt.next();
240  if (currentEntity.getStringValue() == null || currentEntity.getStringValue().isEmpty()) {
241  continue; // client can not handle entity without name
242  }
243  if (currentEntity.getUri() == null || currentEntity.getUri().isEmpty()) {
244  continue; // client can not handle entity without URI
245  }
246  resultString.append(currentEntity.toXmlString());
247  }
248  resultString.append("</entities>");
249  } else { // Protocol v2
250  //Building header of msg
251  resultString.append("<entities name=\"").append(request.getFilter());
252 
253  if(request.getType() != null){
254  resultString.append("\" type=\"").append(request.getType()).append("\">");
255  }
256  else{
257  resultString.append("\">");
258  }
259 
260  //Building list of entitites
261  while(resultIt.hasNext()){
262  EntityAttribute currentEntity = resultIt.next();
263  counter++;
264 
265  if (currentEntity.getStringValue() == null || currentEntity.getStringValue().isEmpty()) {
266  continue; // client can not handle entity without name
267  }
268  if (currentEntity.getUri() == null || currentEntity.getUri().isEmpty()) {
269  continue; // client can not handle entity without URI
270  }
271 
272  // Getting just exact requested number of entities
273  if(counter <= limit){
274  resultString.append(currentEntity.toXMLResponseStringV2());
275  }
276  else{
277  break;
278  }
279  }
280 
281  resultString.append("</entities>");
282  } // Protocol v2
283 
284  return resultString.toString();
285  } // makeMessageFromResult()
286 
287  /**
288  * Method parse response string from the SEC Store API and save entities in it to
289  * array.
290  *
291  * @param JSONString JSON string from SEC Store API
292  * @return list of EntityAtributes parsed from JSON String
293  */
294  private ArrayList<EntityAttribute> makeArrayFromResult(String JSONString){
295  ArrayList<EntityAttribute> returnList = new ArrayList<EntityAttribute>();
296 
297  // create JSON array from received textual data
298  JSONObject jsonResponse = (JSONObject)JSONValue.parse(JSONString);
299  if (jsonResponse == null) {
301  String msg = "Unable to parse received JSON string with vocabulary entities.";
302  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
303  }
304  return returnList;
305  }
306 
307  // get all recived entities
308  JSONArray jsonEntities = (JSONArray)jsonResponse.get("entities");
309  if (jsonEntities == null) {
311  String msg = "Unable to get new suggestions data from received JSON.";
312  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
313  }
314  return returnList;
315  }
316  else if (jsonEntities.isEmpty()) {
317  return returnList;
318  }
319 
320  //go trough all recived entities
321  for(int index = 0; index < jsonEntities.size(); index++){
322  // obtain one entity
323  JSONObject currentEntity = (JSONObject)jsonEntities.get(index);
324 
325  String name;
326  String uri;
327  String visualUri;
328  String description;
329  String type;
330 
331 
332  // parse uri from entity JSON string
333  try {
334  uri = (String)currentEntity.get("uri");
335  }
336  catch (ClassCastException e) {
338  String msg = "Entity uri is not a String type.";
339  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
340  }
341  continue;
342  }
343 
344  // parse type from entity JSON string
345  try {
346  type = (String)currentEntity.get("type");
347  }
348  catch (ClassCastException e) {
350  String msg = "Entity type is not a String type.";
351  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
352  }
353  continue;
354  }
355 
356  // parse name from entity JSON string
357  try {
358  name = (String)currentEntity.get("name");
359  }
360  catch (ClassCastException e) {
362  String msg = "Entity name is not a String type.";
363  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
364  }
365  continue;
366  }
367 
368  // parse uri of visual representation from entity JSON string
369  try {
370  visualUri = (String)currentEntity.get("visual_representation");
371  }
372  catch (ClassCastException e) {
374  String msg = "Entity uri of visual representation is not a String type.";
375  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
376  }
377  continue;
378  }
379 
380  // parse description of entity from entity JSON string
381  try {
382  description = (String)currentEntity.get("description");
383  }
384  catch (ClassCastException e) {
386  String msg = "Entity uri of visual representation is not a String type.";
387  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
388  }
389  continue;
390  }
391 
392  EntityAttribute attr = new EntityAttribute(name,type,uri,visualUri,description);
393  ArrayList<EntityAdditionalAttribute> addAttrs = getAdditionalAttributes(currentEntity, attr);
394  attr.setEntityAdditionalAttributes(addAttrs);
395  returnList.add(attr);
396 
397  }
398 
399  return returnList;
400  } // makeArrayFromResult()
401 
402  /**
403  * Creates escaped version of the provided textual data. It is used when
404  * text to be sent to the SEC Store server contains special characters like
405  * quotes and backslash. Method expects SEC Store server to store strings
406  * enclosed in double quote. That's why double quote character needs to be
407  * escaped and single quote not.
408  */
409  private String EscapeCharsToSend(String source) {
410  String result = source;
411  // string can have null value if suggestions type is not requested
412  if (result != null) {
413  result = result.replace("\\", "\\\\");
414  result = result.replace("\"", "\\\"");
415  result = result.replace("\n", " ");
416  result = result.replace("\t", " ");
417  }
418  return result;
419  } // EscapeCharsToSend()
420 
421  /**
422  * Method searches vocabulary entities by using a SEC API.
423  *
424  * @param request Request from client that will be searched
425  * @return Returns finded vocabulary entities
426  */
427  public ArrayList<EntityAttribute> getResultFromSECAPI(EntityRequest request){
428  ArrayList<EntityAttribute> retList = new ArrayList<EntityAttribute>();
429 
430  String secApiResults = "";
431 
433  secApiResults = makeRemoteSECAPIRequest(request);
434  } else {
435  secApiResults = makeSECAPIRequest(request);
436  }
437 
438 
439  try {
440  JSONObject jsonData = (JSONObject) JSONValue.parse(secApiResults);
441  if (jsonData == null) {
443  String msg = "List with dictionary entities was not returned from SEC API.";
444  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
445  }
446  return retList;
447  }
448 
449  JSONArray jsonEntities = (JSONArray) jsonData.get("data");
450 
451  if (checkException(jsonData)) {
452  return retList;
453  }
454 
455  if (jsonEntities == null) {
457  String msg = "List with dictionary entities was not returned from SEC API.";
458  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
459  }
460  return retList;
461  }
462 
463  int numOfEntities = jsonEntities.size();
464  for (int i = 0; i < numOfEntities; i++) { // for each entity
465  try {
466  JSONObject entity = (JSONObject) jsonEntities.get(i);
467  Set keySet = entity.keySet();
468  Iterator kIt = keySet.iterator();
469  if (kIt.hasNext()) {
470  String type = kIt.next().toString();
471  JSONObject entityAttributes = (JSONObject) entity.get(type);
472  Iterator<String> namesIt = NAME_ATTRIBUTES.iterator();
473  String name = null;
474  while ((name == null || name.isEmpty()) && namesIt.hasNext()) {
475  name = (String) entityAttributes.get(namesIt.next());
476  }
477  String uri = (String) entityAttributes.get(URI_ATTRIBUTE);
478  String visual_representation = (String) entityAttributes.get(VIS_REPRESENTATION_ATTRIBUTE);
479  if (visual_representation == null) {
480  visual_representation = (String) entityAttributes.get(ALT_VIS_REPRESENTATION_ATTRIBUTE);
481  }
482  if (visual_representation == null) {
483  visual_representation = "";
484  } else {
485  ArrayList<String> pictures = getPicturesFromString(visual_representation);
486  if (!pictures.isEmpty()) {
487  visual_representation = pictures.get(0);
488  }
489  }
490  String description = (String) entityAttributes.get(DESCRIPTION_ATTRIBUTE);
491  EntityAttribute ea = new EntityAttribute(name, type, uri, visual_representation, description);
492  ArrayList<EntityAdditionalAttribute> addAttrs = getAdditionalAttributes(entityAttributes, ea);
493  ea.setEntityAdditionalAttributes(addAttrs);
494  retList.add(ea);
495  }
496  } catch (Exception e) {
498  String msg = "Unable to parse received dictionary entity.";
499  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg, e);
500  }
501  }
502  } // for each entity
503 
504  } catch (Exception e) {
506  String msg = "Unable to parse received JSON string with dictionary entities.";
507  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg, e);
508  }
509  return retList;
510  }
511 
512  return retList;
513  } // getResultFromSECAPI()
514 
515  /**
516  * Creates request to SEC API
517  *
518  * @param request Request from client that will be searched
519  * @return Returns request for SEC API
520  */
522  StringBuilder result = new StringBuilder();
523  result.append("{\"get_entities\":{");
524 
525  result.append("\"input_string\": \"");
526  result.append(request.getFilter());
527  result.append("\",");
528 
529  result.append("\"types_and_attributes\": {");
530 
531 
532  // determine which types should be available for entity autocomplete
533  ArrayList<SecApiReqTypeDef> available = null;
534  if (AppBean.getReqTypeDefinitionsEA() != null && !AppBean.getReqTypeDefinitionsEA().isEmpty()) {
535  available = AppBean.getReqTypeDefinitionsEA();
536  } else {
537  available = AppBean.getAvTypeDefinitions();
538  }
539 
540  // select requested types or all
541  ArrayList<SecApiReqTypeDef> requested = new ArrayList<SecApiReqTypeDef>();
542  String requestedType = request.getType();
543  requestedType.replace(AppBean.getBaseTypeUri(), ""); // remove base URI
544  if (requestedType != null && !requestedType.isEmpty()
545  && requestedType.startsWith("*") && requestedType.endsWith("*")) {
546  requestedType = requestedType.substring(1, requestedType.length() - 1);
547  Iterator<SecApiReqTypeDef> avIt = available.iterator();
548  while (avIt.hasNext()) {
549  SecApiReqTypeDef td = avIt.next();
550  if (td.getTypeName().contains(requestedType) && !Constants.FORBIDDEN_ENTITY_TYPES.contains(td.getTypeName())) {
551  requested.add(td);
552  }
553  }
554  } else if (requestedType != null && !requestedType.isEmpty() && requestedType.endsWith("*")) {
555  requestedType = requestedType.substring(0, requestedType.length() - 1);
556  Iterator<SecApiReqTypeDef> avIt = available.iterator();
557  while (avIt.hasNext()) {
558  SecApiReqTypeDef td = avIt.next();
559  if (td.getTypeName().startsWith(requestedType) && !Constants.FORBIDDEN_ENTITY_TYPES.contains(td.getTypeName())) {
560  requested.add(td);
561  }
562  }
563  } else if (requestedType != null && !requestedType.isEmpty() && requestedType.startsWith("*")) {
564  requestedType = requestedType.substring(1, requestedType.length());
565  Iterator<SecApiReqTypeDef> avIt = available.iterator();
566  while (avIt.hasNext()) {
567  SecApiReqTypeDef td = avIt.next();
568  if (td.getTypeName().endsWith(requestedType) && !Constants.FORBIDDEN_ENTITY_TYPES.contains(td.getTypeName())) {
569  requested.add(td);
570  }
571  }
572  } else if (requestedType != null && !requestedType.isEmpty()) {
573  Iterator<SecApiReqTypeDef> avIt = available.iterator();
574  while (avIt.hasNext()) {
575  SecApiReqTypeDef td = avIt.next();
576  if (td.getTypeName().contentEquals(requestedType) && !Constants.FORBIDDEN_ENTITY_TYPES.contains(td.getTypeName())) {
577  requested.add(td);
578  }
579  }
580  } else {
581  Iterator<SecApiReqTypeDef> avIt = available.iterator();
582  while (avIt.hasNext()) {
583  SecApiReqTypeDef td = avIt.next();
584  if (!Constants.FORBIDDEN_ENTITY_TYPES.contains(td.getTypeName())) {
585  requested.add(td);
586  }
587  }
588  }
589 
590  if (requestInfo.getSession().getProtocolLOD() >= Constants.PROTOCOL_LOD_V2
591  && AppBean.getReqTypeDefinitionsEA() != null && !AppBean.getReqTypeDefinitionsEA().isEmpty()) {
592  Iterator<SecApiReqTypeDef> reqIt = requested.iterator();
593  if (reqIt.hasNext()) { // first entry
594  SecApiReqTypeDef r = reqIt.next();
595  result.append(r.getRequestString());
596  }
597  while (reqIt.hasNext()) {
598  result.append(",");
599  SecApiReqTypeDef r = reqIt.next();
600  result.append(r.getRequestString());
601  }
602  } else {
603  Iterator<SecApiReqTypeDef> reqIt = requested.iterator();
604  if (reqIt.hasNext()) { // first entry
605  SecApiReqTypeDef r = reqIt.next();
606  result.append(r.getRequestString(REQUESTED_ATTRIBUTES));
607  }
608  while (reqIt.hasNext()) {
609  result.append(",");
610  SecApiReqTypeDef r = reqIt.next();
611  result.append(r.getRequestString(REQUESTED_ATTRIBUTES));
612  }
613  }
614 
615  result.append("},");
616 
617  Integer maxResults = MAX_RESULTS;
618  Object[] paramsP = {"name", Constants.MAX_ENTITIES_SETTINGS_NAME};
619  @SuppressWarnings("unchecked")
620  List<ServerSetting> settingsList = AppBean.getPersistenceManager().queryDB("ServerSetting.findByName", paramsP);
621  if (settingsList != null && !settingsList.isEmpty()) {
622  if (!settingsList.get(0).getSettingValue().isEmpty()) {
623  try {
624  maxResults = Integer.parseInt(settingsList.get(0).getSettingValue());
625  } catch (Exception e) {
626  maxResults = MAX_RESULTS;
627  }
628  }
629  }
630 
631  // if user has specified maximum number of results
632  // this can be only used in protocol version 2 or higher
633  if(requestInfo.getSession().getProtocolLOD() >= Constants.PROTOCOL_LOD_V2){
634  if(request.getMaxResults() != null && request.getMaxResults() != -1){
635  maxResults = request.getMaxResults();
636 
637  //applying reserve
638  maxResults = (int)Math.round((double)maxResults * (1.0 + Constants.SEC_API_AUTOCOMPLETE_RESULTS_RESERVE / 100.0));
639  }
640  }
641 
642  result.append("\"max_results\": ");
643  result.append(maxResults.toString());
644 
645  result.append("}}");
646  return result.toString();
647  } // createGERequest()
648 
649  /**
650  * Makes SEC API request and return result
651  *
652  * @param request Request from client that will be searched
653  * @return Returns result from SEC API
654  */
656 
657  String secApiRequest = createGERequest(request);
658  String SECAPIResults = "";
659 
660  Boolean processed = false;
661  try {
662  SECAPIInterface sai = AppBean.getSecApiInterface();
663  SECAPIResults = sai.makeRequest(secApiRequest);
664  processed = true;
665  } catch (Exception ex) {
666  String message = "SEC API call error : " + ex.getMessage();
667  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, message);
668  }
669 
670  // Second attempt
671  if (SECAPIResults == null || SECAPIResults.isEmpty()) {
672  try {
673  SECAPIInterface sai = AppBean.getSecApiInterface();
674  // restart SEC API before process
675  sai.close();
676  if (!sai.init()) {
677  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, "Initialisation of SEC API failed!");
678  return SECAPIResults;
679  }
680  // it is possible that we have updated version of SEC API now
681  // (old version was killed and new was started now)
682  SuggestionManager.initReqTypes();
683  if (AppBean.getReqTypeDefinitions().isEmpty()) {
684  return SECAPIResults;
685  }
686  // update request data
687  secApiRequest = createGERequest(request);
688  // process request
689  SECAPIResults = sai.makeRequest(secApiRequest);
690  processed = true;
691  } catch (Exception ex) {
692  String message = "SEC API call error : " + ex.getMessage();
693  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, message);
694  return SECAPIResults;
695  }
696  }
697 
698  return SECAPIResults;
699  } // makeSECAPIRequest();
700 
701  /**
702  * Makes remote SEC API request and return result
703  *
704  * @param request Request from client that will be searched
705  * @return Returns result from SEC API
706  */
708 
709  String secApiRequest = "";
710  String SECAPIResults = "";
711 
712  try {
713  SECAPIConn sac = new SECAPIConn();
714  // it is possible that SEC API was updated after last request
715  // (old version was killed and new was started) so we need to refresh types
716  SuggestionManager.initReqTypesFromRemote(sac, null);
717  if (AppBean.getReqTypeDefinitions().isEmpty()) {
718  return SECAPIResults;
719  }
720  // create request data
721  secApiRequest = createGERequest(request);
722  // process request
723  SECAPIResults = sac.sendReqToSECAPI(secApiRequest, null);
724  } catch (Exception ex) {
725  String message = "Remote SEC API call error : " + ex.getMessage();
726  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, message);
727  }
728 
729  return SECAPIResults;
730  } // makeRemoteSECAPIRequest();
731 
732  /**
733  * Checks if JSON from SEC API contains exception and if yes, logs it
734  *
735  * @param jsonData JSON data from SEC API
736  * @return If exception was presented, returns true, false otherwise
737  */
738  private boolean checkException(JSONObject jsonData) {
739  String exceptionData = null;
740  try { // try to get exception
741  exceptionData = (String) jsonData.get("exception");
742  } catch (Exception e) { // error never mind here
743  }
744  if (exceptionData != null && !exceptionData.isEmpty()) {
746  String msg = "SEC API returned exception: " + exceptionData;
747  Logger.getLogger(SECDInterfaceThread.class.getName()).log(Level.SEVERE, msg);
748  }
749  return true;
750  }
751  return false;
752  }
753 
754  /**
755  * Gets pictures from string
756  *
757  * @param string string with pictures
758  * @return list of strings
759  */
760  private ArrayList<String> getPicturesFromString(String string){
761  ArrayList<String> result = new ArrayList<String>();
762  String[] values = string.split(MULTIPLE_DATA_SEPARATOR,-1);
763 
764  String picture = "";
765  for(int i = 0; i < values.length; i++){
766  String[] tmpVal = (values[i]).split("\\.",-1);
767  picture += values[i];
768  if(tmpVal.length > 1){
769  String tmpStr = tmpVal[tmpVal.length-1];
770  Iterator<String> strIt = ALLOWED_POSTFIX.iterator();
771  while(strIt.hasNext()){
772  if(tmpStr.equals(strIt.next())){
773  result.add(picture);
774  picture = "";
775  }
776  }
777  }
778  }
779  return result;
780  }
781 
782  /**
783  * Parses additional attributes of entity from SEC API
784  *
785  * @param entityAttributes JSON object with entity
786  * @param parentAttr Entity attribute of annotation to which additional attributes belongs
787  * @return Returns array of additional attributes
788  */
789  ArrayList<EntityAdditionalAttribute> getAdditionalAttributes(JSONObject entityAttributes, EntityAttribute parentAttr){
790  ArrayList<EntityAdditionalAttribute> result = new ArrayList<EntityAdditionalAttribute>();
791  SecApiReqTypeDef pattern = new SecApiReqTypeDef(parentAttr.getName());
792  Integer index = null;
793  if (AppBean.getDesTypeDefinitionsEA() != null) {
794  index = AppBean.getDesTypeDefinitionsEA().indexOf(pattern);
795  }
796  SecApiReqTypeDef priorities = null;
797  if (index != null && index >= 0) {
798  priorities = AppBean.getDesTypeDefinitionsEA().get(index);
799  }
800  Set keys = entityAttributes.keySet();
801  Iterator keysIt = keys.iterator();
802  while(keysIt.hasNext()){
803  String actualKey = (String) keysIt.next().toString();
804  if(!actualKey.equals(URI_ATTRIBUTE) && !actualKey.equals(VIS_REPRESENTATION_ATTRIBUTE)
805  && !actualKey.equals(ALT_VIS_REPRESENTATION_ATTRIBUTE) && !actualKey.equals(DESCRIPTION_ATTRIBUTE)
806  && !NAME_ATTRIBUTES.contains(actualKey)){
807 
808  String value = (String)entityAttributes.get(actualKey);
809 
810  EntityAdditionalAttribute newAdditionalAttr = new EntityAdditionalAttribute();
811  newAdditionalAttr.setName(actualKey);
812  if (actualKey.endsWith("_uri") || actualKey.endsWith("_url") || actualKey.endsWith("ulan_id")) {
813  // unreliable hotfix - should be changed in the future
814  newAdditionalAttr.setType("URI");
815  }
816  newAdditionalAttr.setStringValue(value);
817  newAdditionalAttr.setRefEntityAttribute(parentAttr);
818  if (priorities != null) {
819  newAdditionalAttr.setPriority(priorities.getPriority(actualKey));
820  }
821 
822  result.add(newAdditionalAttr);
823  }
824  }
825 
826  return result;
827  } // getAdditionalAttributes()
828 
829 } // public class SECDInterfaceThread
Class representing parameter of server settings.
static final boolean VISUAL_REPRESENTATION_URI_CHANGE
Definition: Constants.java:345
static final ArrayList< String > FORBIDDEN_ENTITY_TYPES
Definition: Constants.java:432
Singleton for storing global variables.
Definition: AppBean.java:47
Class representing vocabulary entity attribute.
Interface for call of SEC API as external program (deamon)
Class representing user group.
Definition: UserGroup.java:47
Holds information about the query to dictionary entries.
static ArrayList< SecApiReqTypeDef > getDesTypeDefinitionsEA()
Definition: AppBean.java:954
Class provides offerining of suggestions with usage of local knowledge repository.
Class forwards queries from anotation client to the SEC API server and and creates a message for anno...
Class for creating of requested type definition for SEC API.
static ArrayList< SecApiReqTypeDef > getReqTypeDefinitions()
Definition: AppBean.java:863
Class implementing functions for communication with remote SEC API.
Definition: SECAPIConn.java:37
static ArrayList< SecApiReqTypeDef > getReqTypeDefinitionsEA()
Definition: AppBean.java:972
Processed informations about client request.
ArrayList< EntityAdditionalAttribute > getAdditionalAttributes(JSONObject entityAttributes, EntityAttribute parentAttr)
static final double SEC_API_AUTOCOMPLETE_RESULTS_RESERVE
Definition: Constants.java:316