4A Server -  2.0
 All Classes Namespaces Files Functions Variables Enumerator
NERInterface.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: NERInterface.java
5  * Description: Interface for call of external program (deamon)
6  */
7 
8 /**
9  * @file NERInterface.java
10  *
11  * @brief Interface for call of external program (deamon) with NER
12  */
13 
14 package cz.vutbr.fit.knot.annotations.modules.suggestionManager;
15 
18 import java.io.BufferedReader;
19 import java.io.BufferedWriter;
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.InputStreamReader;
24 import java.io.OutputStream;
25 import java.io.OutputStreamWriter;
26 import java.util.List;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29 
30 /**
31  * Interface for call of external program (deamon) with NER
32  *
33  * @brief Interface for call of external program (deamon)
34  * @author Marek Kopecky
35  */
36 public class NERInterface {
37 
38  /**
39  * Default command for external program
40  */
41  public static final String NER_COMMAND = "/var/sec/NER/ner.py";
42 
43  /**
44  * Default path for external program
45  */
46  public static final String NER_PATH = "/var/sec/NER/";
47 
48  /**
49  * Default KB path for external program
50  */
51  public static final String NER_KB_PATH = "/var/sec/NER/KBstatsMetrics.all";
52 
53  /**
54  * Name of setting of command for external program
55  */
56  public static final String NER_SETTING_NAME = "nerCommand";
57 
58  /**
59  * Name of setting of command for external program
60  */
61  public static final String NER_PATH_SETTING_NAME = "nerPath";
62 
63  /**
64  * Name of setting of KB for external program
65  */
66  public static final String NER_KB_SETTING_NAME = "nerKB";
67 
68  /**
69  * Input / output separator
70  */
71  public static final String IO_SEPARATOR = "\nNER_NEW_FILE\n";
72  /**
73  * Input / output separator
74  */
75  public static final String IO_SEPARATOR_EMPTY = "NER_NEW_FILE\n";
76  /**
77  * Clean input / output separator
78  */
79  public static final String CLEANED_IO_SEPARATOR = "NER_NEW_FILE";
80  /**
81  * Command for closing of NER
82  */
83  public static final String ENDING_COMMAND = "\nNER_END\n";
84 
85  /**
86  * Standard input of external program
87  */
88  OutputStream stdin = null;
89 
90  /**
91  * Standard error output of external program
92  */
93  InputStream stderr = null;
94 
95  /**
96  * Standard output of external program
97  */
98  InputStream stdout = null;
99 
100  /**
101  * Process builder information
102  */
103  ProcessBuilder processBuilder;
104 
105  /**
106  * Process information
107  */
108  Process processVar;
109 
110  /**
111  * Buffered writer for stdin
112  */
113  BufferedWriter brStdIn;
114 
115  /**
116  * Buffered reader for stdout
117  */
118  BufferedReader brStdOut;
119 
120  /**
121  * Buffered reader for stderr
122  */
123  BufferedReader brStdErrOut;
124 
125  /**
126  * true - proces was initialized, false proces was not initialized
127  */
128  boolean wasInitialized = false;
129 
130  /**
131  * Initialize process
132  *
133  * @return true - process was created, false - process was not created
134  */
135  public synchronized boolean init() {
136  if (wasInitialized) {
137  return false;
138  }
139 
140  String nerCommand = NER_COMMAND;
141  String nerPath = NER_PATH;
142  String nerKBPath = NER_KB_PATH;
143 
144  // Load command from DB
145  Object[] params = {"name",NER_SETTING_NAME};
146  @SuppressWarnings("unchecked")
147  List<ServerSetting> settingsList = AppBean.getPersistenceManager().queryDB("ServerSetting.findByName",params);
148  if(settingsList != null && !settingsList.isEmpty()){
149  nerCommand = settingsList.get(0).getSettingValue();
150  }
151  // Load path from DB
152  Object[] paramsP = {"name",NER_PATH_SETTING_NAME};
153  @SuppressWarnings("unchecked")
154  List<ServerSetting> settingsListP = AppBean.getPersistenceManager().queryDB("ServerSetting.findByName",paramsP);
155  if(settingsListP != null && !settingsListP.isEmpty()){
156  nerPath = settingsListP.get(0).getSettingValue();
157  }
158  // Load KB path from DB
159  Object[] paramsK = {"name",NER_KB_SETTING_NAME};
160  @SuppressWarnings("unchecked")
161  List<ServerSetting> settingsListK = AppBean.getPersistenceManager().queryDB("ServerSetting.findByName",paramsK);
162  if(settingsListK != null && !settingsListK.isEmpty()){
163  nerKBPath = settingsListK.get(0).getSettingValue();
164  }
165 
166  // create process
167  try {
168  processBuilder = new ProcessBuilder (nerCommand,"-d","-k",nerKBPath);
169  processBuilder.directory(new File(nerPath));
170  processBuilder.redirectErrorStream(true);
171  processVar = processBuilder.start();
172  } catch (IOException e) {
173  return false;
174  }
175 
176  stdin = processVar.getOutputStream ();
177  stderr = processVar.getErrorStream ();
178  stdout = processVar.getInputStream ();
179  brStdIn = new BufferedWriter(new OutputStreamWriter(stdin));
180  brStdOut = new BufferedReader(new InputStreamReader(stdout));
181  brStdErrOut = new BufferedReader(new InputStreamReader(stdout));
182 
183  wasInitialized = true;
184  return true;
185  }
186 
187  /**
188  * Send message to process and return response.
189  *
190  * @param s Message
191  * @return Response
192  * @throws Exception, when proces was terminated
193  */
194  public synchronized String process(String s) throws Exception {
195  StringBuilder output = new StringBuilder();
196  try {
197  brStdIn.write(s + IO_SEPARATOR);
198  brStdIn.flush();
199 
200  int counter = 0;
201  boolean processEnd = false;
202  int possibleSeparatorLength = 1000;
203  do {
204  output.append((char) brStdOut.read());
205  if (counter > possibleSeparatorLength) {
206  try {
207  processVar.exitValue();
208  // exitValue return a value
209  processEnd = true;
210  } catch (Exception e) { // process hasn't finished yet
211  }
212  if (processEnd) {
213  throw new Exception("Process was terminated");
214  }
215  counter = 0;
216  }
217  counter++;
218  possibleSeparatorLength = output.length() - IO_SEPARATOR_EMPTY.length();
219  } while ((possibleSeparatorLength >= 0) ? (!output.substring(possibleSeparatorLength).equals(IO_SEPARATOR) &&
220  !output.substring(possibleSeparatorLength).equals(IO_SEPARATOR_EMPTY)) : true);
221  } catch (IOException e) {
222  try {
223  StringBuilder erStr = new StringBuilder("");
224  String row = brStdErrOut.readLine();
225  while (row != null) {
226  erStr.append(row);
227  row = brStdErrOut.readLine();
228  }
229  Logger.getLogger(NERInterface.class.getName()).log(Level.SEVERE, "NER terminated! Error stream: " + erStr.toString());
230  } catch (Exception exc) {
231  }
232  throw new Exception("Process was terminated");
233  }
234  return output.toString();
235  }
236 
237  /**
238  * Destroy process and close streams
239  */
240  public void close() {
241  try {
242  wasInitialized = false;
243  try {
244  stdin.write((ENDING_COMMAND).getBytes());
245  stdin.flush();
246  } catch (Exception exception) {
247  }
248  stdin.close();
249  brStdOut.close();
250  // clean up if any output in stderr
251  BufferedReader brCleanUp = new BufferedReader(new InputStreamReader(stderr));
252  while (brCleanUp.readLine() != null) {
253  }
254  brCleanUp.close();
255  stdout.close();
256  stderr.close();
257  processVar.destroy();
258  } catch (IOException e) {}
259  }
260 } // public class NERInterface
Class representing parameter of server settings.
Singleton for storing global variables.
Definition: AppBean.java:47
Interface for call of external program (deamon)