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

Last change on this file since 27107 was 27107, checked in by ak19, 11 years ago

GS2PerlConstructor.activateCollection() now calls perl method activate.pl, since that has no issues with deleting the jdbm colname.lg file in the index folder when moving building to index, whereas the java code that used to move building to index was at times unable to delete this file, so that saving changes in the online GS3 document editor would fail on such occasions.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.2 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"));
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 String msg;
298 ConstructionEvent evt;
299
300 ArrayList<String> args = new ArrayList<String>();
301 args.add("GSDLHOME=" + this.gsdl2home);
302 args.add("GSDL3HOME=" + this.gsdl3home);
303 args.add("GSDLOS=" + this.gsdlos);
304 args.add("GSDL-RUN-SETUP=true");
305
306 for (String a : System.getenv().keySet())
307 {
308 args.add(a + "=" + System.getenv(a));
309 }
310
311 String command_str = "";
312 for (int i = 0; i < command.length; i++)
313 {
314 command_str = command_str + command[i] + " ";
315 }
316
317 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "command = " + command_str));
318 try
319 {
320 Runtime rt = Runtime.getRuntime();
321 sendProcessBegun(new ConstructionEvent(this, GSStatus.ACCEPTED, "starting"));
322 Process prcs = rt.exec(command, args.toArray(new String[args.size()]));
323
324 InputStreamReader eisr = new InputStreamReader(prcs.getErrorStream());
325 InputStreamReader stdinisr = new InputStreamReader(prcs.getInputStream());
326 BufferedReader ebr = new BufferedReader(eisr);
327 BufferedReader stdinbr = new BufferedReader(stdinisr);
328 // Captures the std err of a program and pipes it into
329 // std in of java
330
331 File logDir = new File(GSFile.collectDir(this.site_home) + File.separator + this.collection_name + File.separator + "log");
332 if(!logDir.exists())
333 {
334 logDir.mkdir();
335 }
336
337 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"));
338 bw.write("Document Editor Build\n");
339
340 String eline = null;
341 String stdinline = null;
342 while (((eline = ebr.readLine()) != null || (stdinline = stdinbr.readLine()) != null) && !this.cancel)
343 {
344 if (eline != null)
345 {
346 //System.err.println("ERROR: " + eline);
347 bw.write(eline + "\n");
348 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, eline));
349 }
350 if (stdinline != null)
351 {
352 //System.err.println("OUT: " + stdinline);
353 bw.write(stdinline + "\n");
354 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, stdinline));
355 }
356 }
357 bw.close();
358
359 if (!this.cancel)
360 {
361 // Now display final message based on exit value
362 prcs.waitFor();
363
364 if (prcs.exitValue() == 0)
365 {
366 //status = OK;
367 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, "Success"));
368
369 }
370 else
371 {
372 //status = ERROR;
373 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Failure"));
374
375 return false;
376
377 }
378 }
379 else
380 {
381 // 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.
382 sendProcessStatus(new ConstructionEvent(this, GSStatus.HALTED, "killing the process"));
383 prcs.getOutputStream().close();
384 prcs.destroy();
385 //status = ERROR;
386 return false;
387 }
388
389 }
390 catch (Exception e)
391 {
392 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Exception occurred " + e.toString()));
393 }
394
395 // we're done, but we dont send a process complete message here cos there ight be stuff to do after this has finished.
396 return true;
397
398 }
399
400}
Note: See TracBrowser for help on using the repository browser.