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

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

Added the missing GSDL3SRCHOME enviroment variable into the Perl environment

  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 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 command.add(GlobalProperties.getProperty("perl.path", "perl") + "perl");
153 command.add("-S");
154 command.add(GlobalProperties.getGS2Build() + File.separator + "bin" + File.separator + "script" + File.separator + "import.pl");
155 if (this.manifest_file != null)
156 {
157 command.add("-keepold");
158 command.add("-manifest");
159 command.add(this.manifest_file);
160 }
161 command.add("-site");
162 command.add(this.site_name);
163 command.add("-collectdir");
164 command.add(GSFile.collectDir(this.site_home));
165 command.addAll(extractParameters(this.process_params));
166 command.add(this.collection_name);
167 String[] command_str = {};
168 command_str = command.toArray(command_str);
169
170 if (runPerlCommand(command_str))
171 {
172 // success!! - need to send the final completed message
173 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
174 } // else an error message has already been sent, do nothing
175 }
176
177 protected void buildCollection()
178 {
179 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: build collection."));
180 Vector<String> command = new Vector<String>();
181 command.add(GlobalProperties.getProperty("perl.path", "perl") + "perl");
182 command.add("-S");
183 command.add(GlobalProperties.getGS2Build() + File.separator + "bin" + File.separator + "script" + File.separator + "buildcol.pl");
184 command.add("-site");
185 command.add(this.site_name);
186 command.add("-collectdir");
187 command.add(GSFile.collectDir(this.site_home));
188 command.addAll(extractParameters(this.process_params));
189 command.add(this.collection_name);
190
191 String[] command_str = {};
192 command_str = command.toArray(command_str);
193
194 if (runPerlCommand(command_str))
195 {
196 // success!! - need to send the final completed message
197 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
198 }// else an error message has already been sent, do nothing
199 }
200
201 protected void activateCollection()
202 {
203 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: activate collection."));
204
205 // first check that we have a building directory
206 // (don't want to bother running activate.pl otherwise)
207 File build_dir = new File(GSFile.collectionBuildDir(this.site_home, this.collection_name));
208 if (!build_dir.exists())
209 {
210 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "build dir doesn't exist!"));
211 return;
212 }
213
214 /*
215
216 // move building to index
217 File index_dir = new File(GSFile.collectionIndexDir(this.site_home, this.collection_name));
218 if (index_dir.exists())
219 {
220 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "deleting index directory"));
221 GSFile.deleteFile(index_dir);
222 if (index_dir.exists())
223 {
224 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "index directory still exists!"));
225 return;
226 }
227 }
228
229 GSFile.moveDirectory(build_dir, index_dir);
230 if (!index_dir.exists())
231 {
232 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "index dir wasn't created!"));
233 }
234
235 // success!! - need to send the final completed message
236 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
237 */
238
239 // Running activate.pl instead of making java move building to index as above
240 // circumvents the issue of the jdbm .lg log file (managed by TransactionManager)
241 // in index dir not getting deleted at times. The perl code is able to delete this
242 // sucessfully consistently during testing, whereas java at times is unable to delete it.
243 Vector<String> command = new Vector<String>();
244 command.add(GlobalProperties.getProperty("perl.path", "perl") + "perl");
245 command.add("-S");
246 command.add(GlobalProperties.getGS2Build() + File.separator + "bin" + File.separator + "script" + File.separator + "activate.pl");
247 command.add("-site");
248 command.add(this.site_name);
249 command.add("-collectdir");
250 command.add(GSFile.collectDir(this.site_home));
251 command.addAll(extractParameters(this.process_params));
252 command.add(this.collection_name);
253
254 String[] command_str = {};
255 command_str = command.toArray(command_str);
256
257 if (runPerlCommand(command_str))
258 {
259 // success!! - need to send the final completed message
260 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
261 }// else an error message has already been sent, do nothing
262
263 }
264
265 /** extracts all the args from the xml and returns them in a Vector */
266 protected Vector<String> extractParameters(Element param_list)
267 {
268
269 Vector<String> args = new Vector<String>();
270 if (param_list == null)
271 {
272 return args; // return an empty vector
273 }
274 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
275
276 for (int i = 0; i < params.getLength(); i++)
277 {
278 Element p = (Element) params.item(i);
279 String name = p.getAttribute(GSXML.NAME_ATT);
280 String value = p.getAttribute(GSXML.VALUE_ATT);
281 if (!name.equals(""))
282 {
283 args.add("-" + name);
284 if (!value.equals(""))
285 {
286 args.add(value);
287 }
288 }
289 }
290
291 return args;
292 }
293
294 /** returns true if completed correctly, false otherwise */
295 protected boolean runPerlCommand(String[] command)
296 {
297 int sepIndex = this.gsdl3home.lastIndexOf(File.separator);
298 String srcHome = this.gsdl3home.substring(0, sepIndex);
299
300 ArrayList<String> args = new ArrayList<String>();
301 args.add("GSDLHOME=" + this.gsdl2home);
302 args.add("GSDL3HOME=" + this.gsdl3home);
303 args.add("GSDL3SRCHOME=" + srcHome);
304 args.add("GSDLOS=" + this.gsdlos);
305 args.add("GSDL-RUN-SETUP=true");
306
307 for (String a : System.getenv().keySet())
308 {
309 args.add(a + "=" + System.getenv(a));
310 }
311
312 String command_str = "";
313 for (int i = 0; i < command.length; i++)
314 {
315 command_str = command_str + command[i] + " ";
316 }
317
318 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "command = " + command_str));
319 try
320 {
321 Runtime rt = Runtime.getRuntime();
322 sendProcessBegun(new ConstructionEvent(this, GSStatus.ACCEPTED, "starting"));
323 Process prcs = rt.exec(command, args.toArray(new String[args.size()]));
324
325 InputStreamReader eisr = new InputStreamReader(prcs.getErrorStream());
326 InputStreamReader stdinisr = new InputStreamReader(prcs.getInputStream());
327 BufferedReader ebr = new BufferedReader(eisr);
328 BufferedReader stdinbr = new BufferedReader(stdinisr);
329 // Captures the std err of a program and pipes it into
330 // std in of java
331
332 File logDir = new File(GSFile.collectDir(this.site_home) + File.separator + this.collection_name + File.separator + "log");
333 if (!logDir.exists())
334 {
335 logDir.mkdir();
336 }
337
338 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"));
339 bw.write("Document Editor Build \n");
340
341 String eline = null;
342 String stdinline = null;
343 while (((eline = ebr.readLine()) != null || (stdinline = stdinbr.readLine()) != null) && !this.cancel)
344 {
345 if (eline != null)
346 {
347 //System.err.println("ERROR: " + eline);
348 bw.write(eline + "\n");
349 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, eline));
350 }
351 if (stdinline != null)
352 {
353 //System.err.println("OUT: " + stdinline);
354 bw.write(stdinline + "\n");
355 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, stdinline));
356 }
357 }
358 bw.close();
359
360 if (!this.cancel)
361 {
362 // Now display final message based on exit value
363 prcs.waitFor();
364
365 if (prcs.exitValue() == 0)
366 {
367 //status = OK;
368 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, "Success"));
369
370 }
371 else
372 {
373 //status = ERROR;
374 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Failure"));
375
376 return false;
377
378 }
379 }
380 else
381 {
382 // 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.
383 sendProcessStatus(new ConstructionEvent(this, GSStatus.HALTED, "killing the process"));
384 prcs.getOutputStream().close();
385 prcs.destroy();
386 //status = ERROR;
387 return false;
388 }
389 }
390 catch (Exception e)
391 {
392 e.printStackTrace();
393 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Exception occurred " + e.toString()));
394 }
395
396 // we're done, but we dont send a process complete message here cos there ight be stuff to do after this has finished.
397 return true;
398
399 }
400
401}
Note: See TracBrowser for help on using the repository browser.