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

Last change on this file since 24883 was 24883, checked in by sjm84, 12 years ago

Some updates for running Perl from Greenstone 3

  • Property svn:keywords set to Author Date Id Revision
File size: 10.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
20/**
21 * CollectionConstructor class for greenstone 2 compatible building it uses the
22 * perl scripts to do the building stuff
23 */
24public class GS2PerlConstructor extends CollectionConstructor
25{
26
27 public static final int NEW = 0;
28 public static final int IMPORT = 1;
29 public static final int BUILD = 2;
30 public static final int ACTIVATE = 3;
31
32 /**
33 * gsdlhome for greenstone 2 - we use the perl modules and building scripts
34 * from there
35 */
36 protected String gsdl2home = null;
37 /** gsdlhome for gsdl3 - shouldn't need this eventually ?? */
38 protected String gsdl3home = null;
39 /** gsdlos for greenstone 2 */
40 protected String gsdlos = null;
41 /** the path environment variable */
42 protected String path = null;
43
44 public GS2PerlConstructor(String name)
45 {
46 super(name);
47 }
48
49 /** retrieves the necessary environment variables */
50 public boolean configure()
51 {
52 // try to get the environment variables
53 this.gsdl3home = GlobalProperties.getGSDL3Home();
54 this.gsdl2home = this.gsdl3home + File.separator + ".." + File.separator + "gs2build";
55 this.gsdlos = System.getProperty("os.name").startsWith("Windows") ? "Windows" : "Linux";
56 this.path = System.getenv("PATH");
57
58 if (this.gsdl2home == null)
59 {
60 System.err.println("You must have gs2build installed, and GSDLHOME set for GS2Perl building to work!!");
61 return false;
62 }
63 if (this.gsdl3home == null || this.gsdlos == null)
64 {
65 System.err.println("You must have GSDL3HOME and GSDLOS set for GS2Perl building to work!!");
66 return false;
67 }
68 if (this.path == null)
69 {
70 System.err.println("You must have the PATH set for GS2Perl building to work!!");
71 return false;
72 }
73 return true;
74 }
75
76 public void run()
77 {
78 String msg;
79 ConstructionEvent evt;
80 if (this.process_type == -1)
81 {
82 msg = "Error: you must set the action type";
83 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
84 sendMessage(evt);
85 return;
86 }
87 if (this.site_home == null)
88 {
89 msg = "Error: you must set site_home";
90 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
91 sendMessage(evt);
92 return;
93 }
94 if (this.process_type != NEW && this.collection_name == null)
95 {
96 msg = "Error: you must set collection_name";
97 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
98 sendMessage(evt);
99 return;
100 }
101
102 switch (this.process_type)
103 {
104 case NEW:
105 newCollection();
106 break;
107 case IMPORT:
108 importCollection();
109 break;
110 case BUILD:
111 buildCollection();
112 break;
113 case ACTIVATE:
114 activateCollection();
115 break;
116 default:
117 msg = "wrong type of action specified!";
118 evt = new ConstructionEvent(this, GSStatus.ERROR, msg);
119 sendMessage(evt);
120 break;
121 }
122
123 }
124
125 protected void newCollection()
126 {
127 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: new collection."));
128 Vector command = new Vector();
129 command.add("gs2_mkcol.pl");
130 command.add("-site");
131 command.add(this.site_home);
132 command.add("-collectdir");
133 command.add(GSFile.collectDir(this.site_home));
134 command.addAll(extractParameters(this.process_params));
135 command.add(this.collection_name);
136 String[] command_str = {};
137 command_str = (String[]) command.toArray(command_str);
138 if (runPerlCommand(command_str))
139 {
140 // success!! - need to send the final completed message
141 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
142 } // else an error message has already been sent, do nothing
143
144 }
145
146 protected void importCollection()
147 {
148 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: import collection."));
149 Vector command = new Vector();
150 command.add("import.pl");
151 command.add("-collectdir");
152 command.add(GSFile.collectDir(this.site_home));
153 command.addAll(extractParameters(this.process_params));
154 command.add(this.collection_name);
155 String[] command_str = {};
156 command_str = (String[]) command.toArray(command_str);
157
158 if (runPerlCommand(command_str))
159 {
160 // success!! - need to send the final completed message
161 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
162 } // else an error message has already been sent, do nothing
163 }
164
165 protected void buildCollection()
166 {
167 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: build collection."));
168 Vector command = new Vector();
169 command.add(GlobalProperties.getProperty("perl.path", "perl"));
170 command.add("-S");
171 command.add(GlobalProperties.getGS2Build() + File.separator + "bin" + File.separator + "script" + File.separator + "buildcol.pl");
172 command.add("-site");
173 command.add(this.site_name);
174 command.add("-collectdir");
175 command.add(GSFile.collectDir(this.site_home));
176 command.addAll(extractParameters(this.process_params));
177 command.add(this.collection_name);
178
179 String[] command_str = {};
180 command_str = (String[]) command.toArray(command_str);
181
182 if (runPerlCommand(command_str))
183 {
184 // success!! - need to send the final completed message
185 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
186 }// else an error message has already been sent, do nothing
187 }
188
189 protected void activateCollection()
190 {
191 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "Collection construction: activate collection."));
192
193 // first check that we have a building directory
194 File build_dir = new File(GSFile.collectionBuildDir(this.site_home, this.collection_name));
195 if (!build_dir.exists())
196 {
197 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "build dir doesn't exist!"));
198 return;
199 }
200
201 // move building to index
202 File index_dir = new File(GSFile.collectionIndexDir(this.site_home, this.collection_name));
203 if (index_dir.exists())
204 {
205 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "deleting index directory"));
206 GSFile.deleteFile(index_dir);
207 if (index_dir.exists())
208 {
209 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "index directory still exists!"));
210 return;
211 }
212 }
213
214 GSFile.moveDirectory(build_dir, index_dir);
215 if (!index_dir.exists())
216 {
217 sendMessage(new ConstructionEvent(this, GSStatus.ERROR, "index dir wasn't created!"));
218 }
219
220 // success!! - need to send the final completed message
221 sendProcessComplete(new ConstructionEvent(this, GSStatus.COMPLETED, ""));
222 }
223
224 /** extracts all the args from the xml and returns them in a Vector */
225 protected Vector extractParameters(Element param_list)
226 {
227
228 Vector args = new Vector();
229 if (param_list == null)
230 {
231 return args; // return an empty vector
232 }
233 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
234
235 for (int i = 0; i < params.getLength(); i++)
236 {
237 Element p = (Element) params.item(i);
238 String name = p.getAttribute(GSXML.NAME_ATT);
239 String value = p.getAttribute(GSXML.VALUE_ATT);
240 if (!name.equals(""))
241 {
242 args.add("-" + name);
243 if (!value.equals(""))
244 {
245 args.add(value);
246 }
247 }
248 }
249
250 return args;
251 }
252
253 /** returns true if completed correctly, false otherwise */
254 protected boolean runPerlCommand(String[] command)
255 {
256 String msg;
257 ConstructionEvent evt;
258
259 ArrayList<String> args = new ArrayList<String>();
260 args.add("GSDLHOME=" + this.gsdl2home);
261 args.add("GSDL3HOME=" + this.gsdl3home);
262 args.add("GSDLOS=" + this.gsdlos);
263 args.add("GSDL-RUN-SETUP=true");
264
265 for (String a : System.getenv().keySet())
266 {
267 args.add(a + "=" + System.getenv(a));
268 }
269
270 String command_str = "";
271 for (int i = 0; i < command.length; i++)
272 {
273 command_str = command_str + command[i] + " ";
274 }
275
276 sendMessage(new ConstructionEvent(this, GSStatus.INFO, "command = " + command_str));
277 try
278 {
279 Runtime rt = Runtime.getRuntime();
280 sendProcessBegun(new ConstructionEvent(this, GSStatus.ACCEPTED, "starting"));
281 Process prcs = rt.exec(command, args.toArray(new String[args.size()]));
282
283 InputStreamReader eisr = new InputStreamReader(prcs.getErrorStream());
284 InputStreamReader stdinisr = new InputStreamReader(prcs.getInputStream());
285 BufferedReader ebr = new BufferedReader(eisr);
286 BufferedReader stdinbr = new BufferedReader(stdinisr);
287 // Captures the std err of a program and pipes it into
288 // std in of java
289
290 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"));
291 bw.write("Document Editor Build\n");
292
293 String eline = null;
294 String stdinline = null;
295 while (((eline = ebr.readLine()) != null || (stdinline = stdinbr.readLine()) != null) && !this.cancel)
296 {
297 if (eline != null)
298 {
299 //System.err.println("ERROR: " + eline);
300 bw.write(eline + "\n");
301 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, eline));
302 }
303 if (stdinline != null)
304 {
305 //System.err.println("OUT: " + stdinline);
306 bw.write(stdinline + "\n");
307 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, stdinline));
308 }
309 }
310 bw.close();
311
312 if (!this.cancel)
313 {
314 // Now display final message based on exit value
315 prcs.waitFor();
316
317 if (prcs.exitValue() == 0)
318 {
319 //status = OK;
320 sendProcessStatus(new ConstructionEvent(this, GSStatus.CONTINUING, "Success"));
321
322 }
323 else
324 {
325 //status = ERROR;
326 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Failure"));
327
328 return false;
329
330 }
331 }
332 else
333 {
334 // 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.
335 sendProcessStatus(new ConstructionEvent(this, GSStatus.HALTED, "killing the process"));
336 prcs.getOutputStream().close();
337 prcs.destroy();
338 //status = ERROR;
339 return false;
340 }
341
342 }
343 catch (Exception e)
344 {
345 sendProcessStatus(new ConstructionEvent(this, GSStatus.ERROR, "Exception occurred " + e.toString()));
346 }
347
348 // we're done, but we dont send a process complete message here cos there ight be stuff to do after this has finished.
349 return true;
350
351 }
352
353}
Note: See TracBrowser for help on using the repository browser.