source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/build/GS2PerlConstructor.java@ 27715

Last change on this file since 27715 was 27715, checked in by sjm84, 11 years ago

Fixed some potential perl path errors

  • Property svn:keywords set to Author Date Id Revision
File size: 12.8 KB
Line 
1package org.greenstone.gsdl3.build;
2
3// greenstome classes
4import org.greenstone.gsdl3.util.*;
5import org.greenstone.util.GlobalProperties;
6
7// xml classes
8import org.w3c.dom.Element;
9import org.w3c.dom.NodeList;
10
11//general java classes
12import java.io.BufferedReader;
13import java.io.BufferedWriter;
14import java.io.FileWriter;
15import java.io.InputStreamReader;
16import java.io.File;
17import java.util.ArrayList;
18import java.util.Vector;
19
20import org.apache.log4j.*;
21
22/**
23 * CollectionConstructor class for greenstone 2 compatible building it uses the
24 * perl scripts to do the building stuff
25 */
26public class GS2PerlConstructor extends CollectionConstructor
27{
28 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.build.GS2PerlConstructor.class.getName());
29
30 public static final int NEW = 0;
31 public static final int IMPORT = 1;
32 public static final int BUILD = 2;
33 public static final int ACTIVATE = 3;
34
35 /**
36 * gsdlhome for greenstone 2 - we use the perl modules and building scripts
37 * from there
38 */
39 protected String gsdl2home = null;
40 /** gsdlhome for gsdl3 - shouldn't need this eventually ?? */
41 protected String gsdl3home = null;
42 /** gsdlos for greenstone 2 */
43 protected String gsdlos = null;
44 /** the path environment variable */
45 protected String path = null;
46
47 public GS2PerlConstructor(String name)
48 {
49 super(name);
50 }
51
52 /** retrieves the necessary environment variables */
53 public boolean configure()
54 {
55 // try to get the environment variables
56 this.gsdl3home = GlobalProperties.getGSDL3Home();
57 this.gsdl2home = this.gsdl3home + File.separator + ".." + File.separator + "gs2build";
58 this.gsdlos = System.getProperty("os.name").startsWith("Windows") ? "Windows" : "Linux";
59 this.path = System.getenv("PATH");
60
61 if (this.gsdl2home == null)
62 {
63 System.err.println("You must have gs2build installed, and GSDLHOME set for GS2Perl building to work!!");
64 return false;
65 }
66 if (this.gsdl3home == null || this.gsdlos == null)
67 {
68 System.err.println("You must have GSDL3HOME and GSDLOS set for GS2Perl building to work!!");
69 return false;
70 }
71 if (this.path == null)
72 {
73 System.err.println("You must have the PATH set for GS2Perl building to work!!");
74 return false;
75 }
76 return true;
77 }
78
79 public void run()
80 {
81 String msg;
82 ConstructionEvent evt;
83 if (this.process_type == -1)
84 {
85 msg = "Error: you must set the action type";
86 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
87 sendMessage(evt);
88 return;
89 }
90 if (this.site_home == null)
91 {
92 msg = "Error: you must set site_home";
93 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
94 sendMessage(evt);
95 return;
96 }
97 if (this.process_type != NEW && this.collection_name == null)
98 {
99 msg = "Error: you must set collection_name";
100 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
101 sendMessage(evt);
102 return;
103 }
104
105 switch (this.process_type)
106 {
107 case NEW:
108 newCollection();
109 break;
110 case IMPORT:
111 importCollection();
112 break;
113 case BUILD:
114 buildCollection();
115 break;
116 case ACTIVATE:
117 activateCollection();
118 break;
119 default:
120 msg = "wrong type of action specified!";
121 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
122 sendMessage(evt);
123 break;
124 }
125 }
126
127 protected void newCollection()
128 {
129 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: new collection."));
130 Vector<String> command = new Vector<String>();
131 command.add("gs2_mkcol.pl");
132 command.add("-site");
133 command.add(this.site_home);
134 command.add("-collectdir");
135 command.add(GSFile.collectDir(this.site_home));
136 command.addAll(extractParameters(this.process_params));
137 command.add(this.collection_name);
138 String[] command_str = {};
139 command_str = command.toArray(command_str);
140 if (runPerlCommand(command_str))
141 {
142 // success!! - need to send the final completed message
143 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
144 } // else an error message has already been sent, do nothing
145
146 }
147
148 protected void importCollection()
149 {
150 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: import collection."));
151 Vector<String> command = new Vector<String>();
152
153 String perlPath = GlobalProperties.getProperty("perl.path", "perl");
154 if (perlPath.charAt(perlPath.length() - 1) != File.separatorChar)
155 {
156 perlPath = perlPath + File.separator;
157 }
158
159 command.add(perlPath + "perl");
160 command.add("-S");
161 command.add(GlobalProperties.getGS2Build() + File.separator + "bin" + File.separator + "script" + File.separator + "import.pl");
162 if (this.manifest_file != null)
163 {
164 command.add("-keepold");
165 command.add("-manifest");
166 command.add(this.manifest_file);
167 }
168 command.add("-site");
169 command.add(this.site_name);
170 command.add("-collectdir");
171 command.add(GSFile.collectDir(this.site_home));
172 command.addAll(extractParameters(this.process_params));
173 command.add(this.collection_name);
174 String[] command_str = {};
175 command_str = command.toArray(command_str);
176
177 if (runPerlCommand(command_str))
178 {
179 // success!! - need to send the final completed message
180 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
181 } // else an error message has already been sent, do nothing
182 }
183
184 protected void buildCollection()
185 {
186 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: build collection."));
187 Vector<String> command = new Vector<String>();
188
189 String perlPath = GlobalProperties.getProperty("perl.path", "perl");
190 if (perlPath.charAt(perlPath.length() - 1) != File.separatorChar)
191 {
192 perlPath = perlPath + File.separator;
193 }
194
195 command.add(perlPath + "perl");
196 command.add("-S");
197 command.add(GlobalProperties.getGS2Build() + File.separator + "bin" + File.separator + "script" + File.separator + "buildcol.pl");
198 command.add("-site");
199 command.add(this.site_name);
200 command.add("-collectdir");
201 command.add(GSFile.collectDir(this.site_home));
202 command.addAll(extractParameters(this.process_params));
203 command.add(this.collection_name);
204
205 String[] command_str = {};
206 command_str = command.toArray(command_str);
207
208 if (runPerlCommand(command_str))
209 {
210 // success!! - need to send the final completed message
211 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
212 }// else an error message has already been sent, do nothing
213 }
214
215 protected void activateCollection()
216 {
217 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: activate collection."));
218
219 // first check that we have a building directory
220 // (don't want to bother running activate.pl otherwise)
221 File build_dir = new File(GSFile.collectionBuildDir(this.site_home, this.collection_name));
222 if (!build_dir.exists())
223 {
224 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "build dir doesn't exist!"));
225 return;
226 }
227
228 /*
229
230 // move building to index
231 File index_dir = new File(GSFile.collectionIndexDir(this.site_home, this.collection_name));
232 if (index_dir.exists())
233 {
234 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "deleting index directory"));
235 GSFile.deleteFile(index_dir);
236 if (index_dir.exists())
237 {
238 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "index directory still exists!"));
239 return;
240 }
241 }
242
243 GSFile.moveDirectory(build_dir, index_dir);
244 if (!index_dir.exists())
245 {
246 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "index dir wasn't created!"));
247 }
248
249 // success!! - need to send the final completed message
250 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
251 */
252
253 // Running activate.pl instead of making java move building to index as above
254 // circumvents the issue of the jdbm .lg log file (managed by TransactionManager)
255 // in index dir not getting deleted at times. The perl code is able to delete this
256 // sucessfully consistently during testing, whereas java at times is unable to delete it.
257 Vector<String> command = new Vector<String>();
258
259 String perlPath = GlobalProperties.getProperty("perl.path", "perl");
260 if (perlPath.charAt(perlPath.length() - 1) != File.separatorChar)
261 {
262 perlPath = perlPath + File.separator;
263 }
264
265 command.add(perlPath + "perl");
266 command.add("-S");
267 command.add(GlobalProperties.getGS2Build() + File.separator + "bin" + File.separator + "script" + File.separator + "activate.pl");
268 command.add("-site");
269 command.add(this.site_name);
270 command.add("-collectdir");
271 command.add(GSFile.collectDir(this.site_home));
272 command.addAll(extractParameters(this.process_params));
273 command.add(this.collection_name);
274
275 String[] command_str = {};
276 command_str = command.toArray(command_str);
277
278 if (runPerlCommand(command_str))
279 {
280 // success!! - need to send the final completed message
281 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
282 }// else an error message has already been sent, do nothing
283
284 }
285
286 /** extracts all the args from the xml and returns them in a Vector */
287 protected Vector<String> extractParameters(Element param_list)
288 {
289
290 Vector<String> args = new Vector<String>();
291 if (param_list == null)
292 {
293 return args; // return an empty vector
294 }
295 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
296
297 for (int i = 0; i < params.getLength(); i++)
298 {
299 Element p = (Element) params.item(i);
300 String name = p.getAttribute(GSXML.NAME_ATT);
301 String value = p.getAttribute(GSXML.VALUE_ATT);
302 if (!name.equals(""))
303 {
304 args.add("-" + name);
305 if (!value.equals(""))
306 {
307 args.add(value);
308 }
309 }
310 }
311
312 return args;
313 }
314
315 /** returns true if completed correctly, false otherwise */
316 protected boolean runPerlCommand(String[] command)
317 {
318 int sepIndex = this.gsdl3home.lastIndexOf(File.separator);
319 String srcHome = this.gsdl3home.substring(0, sepIndex);
320
321 ArrayList<String> args = new ArrayList<String>();
322 args.add("GSDLHOME=" + this.gsdl2home);
323 args.add("GSDL3HOME=" + this.gsdl3home);
324 args.add("GSDL3SRCHOME=" + srcHome);
325 args.add("GSDLOS=" + this.gsdlos);
326 args.add("GSDL-RUN-SETUP=true");
327
328 for (String a : System.getenv().keySet())
329 {
330 args.add(a + "=" + System.getenv(a));
331 }
332
333 String command_str = "";
334 for (int i = 0; i < command.length; i++)
335 {
336 command_str = command_str + command[i] + " ";
337 }
338
339 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "command = " + command_str));
340 try
341 {
342 Runtime rt = Runtime.getRuntime();
343 sendProcessBegun(new ConstructionEvent(this, GSStatus.ACCEPTED, "starting"));
344 Process prcs = rt.exec(command, args.toArray(new String[args.size()]));
345
346 InputStreamReader eisr = new InputStreamReader(prcs.getErrorStream());
347 InputStreamReader stdinisr = new InputStreamReader(prcs.getInputStream());
348 BufferedReader ebr = new BufferedReader(eisr);
349 BufferedReader stdinbr = new BufferedReader(stdinisr);
350 // Captures the std err of a program and pipes it into
351 // std in of java
352
353 File logDir = new File(GSFile.collectDir(this.site_home) + File.separator + this.collection_name + File.separator + "log");
354 if (!logDir.exists())
355 {
356 logDir.mkdir();
357 }
358
359 BufferedWriter bw = new BufferedWriter(new FileWriter(GSFile.collectDir(this.site_home) + File.separator + this.collection_name + File.separator + "log" + File.separator + "build_log." + (System.currentTimeMillis()) + ".txt"));
360 bw.write("Document Editor Build \n");
361
362 String eline = null;
363 String stdinline = null;
364 while (((eline = ebr.readLine()) != null || (stdinline = stdinbr.readLine()) != null) && !this.cancel)
365 {
366 if (eline != null)
367 {
368 //System.err.println("ERROR: " + eline);
369 bw.write(eline + "\n");
370 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, eline));
371 }
372 if (stdinline != null)
373 {
374 //System.err.println("OUT: " + stdinline);
375 bw.write(stdinline + "\n");
376 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, stdinline));
377 }
378 }
379 bw.close();
380
381 if (!this.cancel)
382 {
383 // Now display final message based on exit value
384 prcs.waitFor();
385
386 if (prcs.exitValue() == 0)
387 {
388 //status = OK;
389 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, "Success"));
390
391 }
392 else
393 {
394 //status = ERROR;
395 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Failure"));
396
397 return false;
398
399 }
400 }
401 else
402 {
403 // I need to somehow kill the child process. Unfortunately Thread.stop() and Process.destroy() both fail to do this. But now, thankx to the magic of Michaels 'close the stream suggestion', it works fine.
404 sendProcessStatus(new ConstructionEvent(this, GSStatus.HALTED, "killing the process"));
405 prcs.getOutputStream().close();
406 prcs.destroy();
407 //status = ERROR;
408 return false;
409 }
410 }
411 catch (Exception e)
412 {
413 e.printStackTrace();
414 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Exception occurred " + e.toString()));
415 }
416
417 // we're done, but we dont send a process complete message here cos there ight be stuff to do after this has finished.
418 return true;
419
420 }
421
422}
Note: See TracBrowser for help on using the repository browser.