source: trunk/gli/src/org/greenstone/gatherer/collection/BuildOptions.java@ 8236

Last change on this file since 8236 was 8236, checked in by mdewsnip, 20 years ago

Replaced all Gatherer.print* with DebugStream.print*.

  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1package org.greenstone.gatherer.collection;
2
3import java.io.*;
4import java.lang.ref.*;
5import java.net.*;
6import java.util.*;
7import org.apache.xerces.parsers.DOMParser;
8import org.greenstone.gatherer.Configuration;
9import org.greenstone.gatherer.DebugStream;
10import org.greenstone.gatherer.Gatherer;
11import org.greenstone.gatherer.cdm.Argument;
12import org.greenstone.gatherer.util.ArrayTools;
13import org.greenstone.gatherer.util.Codec;
14import org.greenstone.gatherer.util.StaticStrings;
15import org.greenstone.gatherer.util.Utility;
16import org.greenstone.gatherer.util.XMLTools;
17import org.w3c.dom.*;
18import org.xml.sax.InputSource;
19
20/** Build options uses the argument list found in config.xml and the current settings from the loaded collection configuration to represent the options the user wants to use during import and build. If there are no arguments stored in config.xml, or if the user indicates the argument are out of date, this class tries to parse new ones. */
21public class BuildOptions {
22 /** The root element of the build argument tree. */
23 private Element build_arguments_element;
24 /** The root element of the build values tree. */
25 private Element build_values_element;
26 /** The root element of the import argument tree. */
27 private Element import_arguments_element;
28 /** The root element of the import values tree. */
29 private Element import_values_element;
30 /** A cache of previously created build arguments. */
31 private Hashtable build_arguments_cache = new Hashtable();
32 /** A cache of previously created import arguments. */
33 private Hashtable import_arguments_cache = new Hashtable();
34 /** The name of an argument element. */
35 static final private String ARGUMENT = "Argument";
36 /** The name of the enabled attribute. */
37 static final private String ENABLED = "enabled";
38 /** The name of the 'false' value. */
39 static final private String FALSE = "false";
40 /** The name of a name attribute. */
41 static final private String NAME = "name";
42 /** The name of an option element. */
43 static final private String OPTION = "Option";
44 /** The name of the 'true' value. */
45 static final private String TRUE = "true";
46 /** When constructing a BuildOptions object we first try to retrieve the valid arguments from config.xml. If that fails we then try to parse the arguments noticed when calling import.pl -xml and buildcol.pl -xml. If that also fails, we load the default arguments from the xml template library. */
47 public BuildOptions(Element build_values_element, Element import_values_element) {
48 // first check the saved arguments language
49 String interface_lang = Configuration.getLanguage();
50 String args_lang = Configuration.getArgumentsLanguage();
51 if (interface_lang.equals(args_lang)) {
52 // Try to retrieve the arguments for import and build.
53 build_arguments_element = Configuration.getArguments("buildcol.pl");
54 import_arguments_element = Configuration.getArguments("import.pl");
55 }
56 // If that fails try to reconstruct the arguments
57 if(build_arguments_element == null || import_arguments_element == null) {
58 boolean used_defaults = false;
59 build_arguments_element = loadArguments("buildcol.pl", interface_lang);
60 import_arguments_element = loadArguments("import.pl", interface_lang);
61 // And if that too fails, load the default argument templates
62 if(build_arguments_element == null || import_arguments_element == null) {
63 Document build_document = Utility.parse("xml/buildcol.xml", true);
64 build_arguments_element = build_document.getDocumentElement();
65 build_document = null;
66 Document import_document = Utility.parse("xml/import.xml", true);
67 import_arguments_element = import_document.getDocumentElement();
68 import_document = null;
69 used_defaults = true;
70 ///atherer.println("Loaded default BO arguments from templates.");
71 }
72 else {
73 ///atherer.println("Loaded BO arguments from scripts.");
74 }
75 // By now we should definately have the arguments. However the reason we are here is because they are not stored in the config.xml file, to make sure they are stored now.
76 if (used_defaults) {
77 Configuration.setArgumentsLanguage("en");
78 } else {
79 Configuration.setArgumentsLanguage(interface_lang);
80 }
81 Configuration.setArguments(build_arguments_element);
82 Configuration.setArguments(import_arguments_element);
83 }
84 else {
85 DebugStream.println("Loaded BO arguments from config.xml");
86 }
87 // Now take a note of the values too.
88 this.build_values_element = build_values_element;
89 this.import_values_element = import_values_element;
90 }
91
92 /** Retrieve the arguments associated with a certain type of action, ie import or build. */
93 public String[] getArguments(boolean build) {
94 String arguments[] = null;
95 NodeList argument_list = null;
96 if(build) {
97 argument_list = build_values_element.getElementsByTagName(ARGUMENT);
98 }
99 else {
100 argument_list = import_values_element.getElementsByTagName(ARGUMENT);
101 }
102 for(int i = 0; i < argument_list.getLength(); i++) {
103 String[] temp = new String[2];
104 Element argument = (Element) argument_list.item(i);
105 ArrayTools.add(arguments, argument.getAttribute(NAME));
106 String value = XMLTools.getValue(argument);
107 if(value != null && value.length() > 0) {
108 ArrayTools.add(arguments, value);
109 }
110 }
111 return arguments;
112 }
113
114 /** Retrieve the indexth argument belonging to build. */
115 public Argument getBuildArgument(int index) {
116 Argument argument = null;
117 // Try to find the argument in the cache.
118 SoftReference reference = (SoftReference) build_arguments_cache.get(new Integer(index));
119 if(reference != null) {
120 argument = (Argument) reference.get();
121 }
122 // Otherwise generate a new argument.
123 if(argument == null) {
124 argument = getArgument(build_arguments_element, index);
125 }
126 return argument;
127 }
128
129 /** Retrieve the number of arguments involved in building.
130 */
131 public int getBuildArgumentCount() {
132 // Determining the total count is easy.
133 NodeList argument_elements = build_arguments_element.getElementsByTagName(OPTION);
134 return argument_elements.getLength();
135 }
136
137 /** Retrieve the value of a certain build argument. */
138 public String getBuildValue(String name) {
139 return getValue(build_values_element, name, false);
140 }
141
142 /** Determine if the named argument value is enabled or disabled. */
143 public boolean getBuildValueEnabled(String name) {
144 boolean result = false;
145 String value = getValue(build_values_element, name, true);
146 if(value != null && value.length() > 0) {
147 result = (value.equalsIgnoreCase(TRUE));
148 }
149 return result;
150 }
151
152 /** Retrieve all of the build values as a String array ready to added to the buildcol.pl call. */
153 public String[] getBuildValues() {
154 return getValues(build_values_element);
155 }
156
157 /** Retrieve the indexth argument belonging to import. */
158 public Argument getImportArgument(int index) {
159 Argument argument = null;
160 // Try to find the argument in the cache.
161 SoftReference reference = (SoftReference) import_arguments_cache.get(new Integer(index));
162 if(reference != null) {
163 argument = (Argument) reference.get();
164 }
165 // Otherwise generate a new argument.
166 if(argument == null) {
167 argument = getArgument(import_arguments_element, index);
168 }
169 return argument;
170 }
171
172 /** Retrieve the number of arguments involved in importing.
173 */
174 public int getImportArgumentCount() {
175 // Determining the total count is easy.
176 NodeList argument_elements = import_arguments_element.getElementsByTagName(OPTION);
177 return argument_elements.getLength();
178 }
179
180 /** Retrieve the value of a certain build argument. */
181 public String getImportValue(String name) {
182 return getValue(import_values_element, name, false);
183 }
184
185 /** Determine if the named argument value is enabled or disabled. */
186 public boolean getImportValueEnabled(String name) {
187 boolean result = false;
188 String value = getValue(import_values_element, name, true);
189 if(value != null && value.length() > 0) {
190 result = (value.equalsIgnoreCase(TRUE));
191 }
192 return result;
193 }
194
195 /** Retrieve all of the import arguments in a form ready to be sent out to a shell process. */
196 public String[] getImportValues() {
197 return getValues(import_values_element);
198 }
199
200 /** Set the value of a build argument. */
201 public void setBuildValue(String name, boolean enable, String value) {
202 setValue(build_values_element, name, enable, value);
203 }
204
205 /** Set the value of a build argument. */
206 public void setImportValue(String name, boolean enable, String value) {
207 setValue(import_values_element, name, enable, value);
208 }
209
210 /** Remove the given build value. */
211 public void removeBuildValue(String name) {
212 removeValue(build_values_element, name);
213 }
214
215 /** Remove the given import value. */
216 public void removeImportValue(String name) {
217 removeValue(import_values_element, name);
218 }
219
220 /** Retrieve the indexth element from the given set of arguments. */
221 private Argument getArgument(Element arguments_element, int index) {
222 Argument argument = null;
223 try {
224 NodeList option_list = arguments_element.getElementsByTagName(OPTION);
225 if(0 <= index && index < option_list.getLength()) {
226 // Retrieve the appropriate argument
227 Element option = (Element) option_list.item(index);
228 // Iterate through this option elements children, making note of any details we find.
229 argument = new Argument();
230 for(Node node = option.getFirstChild(); node != null; node = node.getNextSibling()) {
231 String node_name = node.getNodeName();
232 if(node_name.equals("Name")) {
233 argument.setName(XMLTools.getValue(node));
234 }
235 else if(node_name.equals("Desc")) {
236 argument.setDescription(XMLTools.getValue(node));
237 }
238 else if(node_name.equals("Type")) {
239 argument.setType(XMLTools.getValue(node));
240 }
241 else if(node_name.equals("Default")) {
242 argument.setDefaultValue(XMLTools.getValue(node));
243 }
244 else if(node_name.equals("List")) {
245 // Two final loops are required to parse lists.
246 for(Node value = node.getFirstChild(); value != null; value = value.getNextSibling()) {
247 if(value.getNodeName().equals("Value")) {
248 String key = null;
249 String desc = "";
250 for(Node subvalue = value.getFirstChild(); subvalue != null; subvalue = subvalue.getNextSibling()) {
251 node_name = subvalue.getNodeName();
252 if(node_name.equals("Name")) {
253 key = XMLTools.getValue(subvalue);
254 }
255 else if(node_name.equals("Desc")) {
256 desc = XMLTools.getValue(subvalue);
257 }
258 }
259 if(key != null) {
260 argument.addOption(key, desc);
261 }
262 }
263 }
264 }
265 else if(node_name.equals("Required")) {
266 String v = XMLTools.getValue(node);
267 if(v != null && v.equals("yes")) {
268 argument.setRequired(true);
269 }
270 }
271 else if(node_name.equals(StaticStrings.RANGE_ELEMENT)) {
272 String range_raw = XMLTools.getValue(node);
273 int comma_index = -1;
274 if((comma_index = range_raw.indexOf(StaticStrings.COMMA_CHARACTER)) != -1) {
275 if(comma_index > 0) {
276 try {
277 String first_number = range_raw.substring(0, comma_index);
278 argument.setMinimum(Integer.parseInt(first_number));
279 first_number = null;
280 }
281 catch(Exception exception) {
282 }
283 }
284
285 if(comma_index + 1 < range_raw.length()) {
286 try {
287 String second_number = range_raw.substring(comma_index + 1);
288 argument.setMaximum(Integer.parseInt(second_number));
289 second_number = null;
290 }
291 catch(Exception exception) {
292 }
293 }
294 }
295 // Else it wasn't a valid range anyway, so ignore it
296 range_raw = null;
297 }
298 else if(node_name.equals(StaticStrings.HIDDENGLI_ELEMENT)) {
299 argument.setHiddenGLI();
300 }
301 else if(node_name.equals(StaticStrings.MODEGLI_ELEMENT)) {
302 String mode_level_str = XMLTools.getValue(node);
303 try {
304 int mode_level = Integer.parseInt(mode_level_str);
305 argument.setModeLevel(mode_level);
306 }
307 catch(Exception exception) {
308 DebugStream.println("Exception in BuildOptions.getArgument() - Unexpected but non-fatal");
309 DebugStream.printStackTrace(exception);
310 }
311 }
312 }
313 }
314 }
315 catch (Exception error) {
316 DebugStream.println("Error in BuildOptions.getArgument(): " + error);
317 DebugStream.printStackTrace(error);
318 }
319 return argument;
320 }
321
322 private String getValue(Element arguments_element, String name, boolean is_enabled) {
323 String result = null;
324 try {
325 NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
326 for(int i = 0; result == null && i < arguments.getLength(); i++) {
327 Element argument_element = (Element) arguments.item(i);
328 // Is this the argument we want.
329 if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
330 // Are we simply determining if this argument is enabled
331 if(is_enabled) {
332 result = argument_element.getAttribute(ENABLED);
333 }
334 else {
335 String argument_value = XMLTools.getValue(argument_element);
336 if(argument_value != null) {
337 result = argument_value;
338 }
339 argument_value = null;
340 }
341 }
342 argument_element = null;
343 }
344 arguments = null;
345 }
346 catch (Exception error) {
347 DebugStream.printStackTrace(error);
348 }
349 return result;
350 }
351
352 private String[] getValues(Element arguments_element) {
353 ArrayList values = new ArrayList();
354 try {
355 NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
356 for(int i = 0; i < arguments.getLength(); i++) {
357 Element argument_element = (Element) arguments.item(i);
358 // Determine if this argument is enabled.
359 if(argument_element.getAttribute(ENABLED).equalsIgnoreCase(TRUE)) {
360 // First store the name of the argument prefixed with a '-'
361 values.add("-" + argument_element.getAttribute(NAME));
362 // Now retrieve the value.
363 String argument_value = Codec.transform(XMLTools.getValue(argument_element), Codec.DOM_TO_TEXT);
364 // If there is a value, tokenize it by commas only.
365 if(argument_value != null && argument_value.length() > 0) {
366 values.add(argument_value);
367 }
368 argument_value = null;
369 }
370 argument_element = null;
371 }
372 arguments = null;
373 }
374 catch (Exception error) {
375 DebugStream.printStackTrace(error);
376 }
377 return ArrayTools.arrayListToStringArray(values);
378 }
379
380 private Element loadArguments(String filename, String lang) {
381 Element arguments_element = null;
382 InputStream input_stream = null;
383
384 // Run the required program.
385 try {
386 String args[];
387 if (Gatherer.isGsdlRemote) {
388 String launch = Gatherer.cgiBase + "launch";
389 launch += "?cmd=" + filename;
390 launch += "&xml=&language="+lang;
391
392 System.err.println("*** launch = " + launch);
393
394 URL launch_url = new URL(launch);
395 URLConnection launch_connection = launch_url.openConnection();
396 input_stream = launch_connection.getInputStream();
397 }
398 else {
399 if(Utility.isWindows()) {
400 args = new String[6];
401 args[0] = Configuration.perl_path;
402 args[1] = "-S";
403 args[2] = Configuration.getScriptPath() + filename;
404 args[3] = "-xml";
405 args[4] = "-language";
406 args[5] = lang;
407 }
408 else {
409 args = new String[4];
410 args[0] = Configuration.getScriptPath() + filename;
411 args[1] = "-xml";
412 args[2] = "-language";
413 args[3] = lang;
414 }
415
416 // Create the process.
417 Runtime runtime = Runtime.getRuntime();
418 Process process = runtime.exec(args);
419
420 input_stream = process.getErrorStream();
421 }
422
423 Document document = Utility.parse(input_stream,false);
424
425 //DOMParser parser = new DOMParser();
426 //parser.parse(source);
427 //Document document = parser.getDocument();
428 arguments_element = document.getDocumentElement();
429 }
430 catch (Exception error) {
431 DebugStream.println("Error in BuildOptions.loadArguments(): " + error);
432 DebugStream.printStackTrace(error);
433 }
434 return arguments_element;
435 }
436
437 /** Set the state of some build or import argument. Note that value may be either a single String, and ArrayList of Strings or null. If enable is false then any existing argument for the named argument is disabled. */
438 public void setValue(Element arguments_element, String name, boolean enable, String value) {
439 ///ystem.err.println("Set value: " + (arguments_element == build_values_element ? "Build" : "Import") + ", " + name + ", " + enable + ", " + value);
440 try {
441 Document document = arguments_element.getOwnerDocument();
442 NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
443 boolean found = false;
444 for(int i = 0; i < arguments.getLength(); i++) {
445 Element argument_element = (Element) arguments.item(i);
446 // If this the argument named.
447 if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
448 found = true;
449 // Set whether this argument is enabled
450 argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE));
451 // Now we set the value, depending or what it is.
452 if(value == null) {
453 // Nothing to do.
454 }
455 else {
456 // Remove existing text nodes.
457 while(argument_element.hasChildNodes()) {
458 argument_element.removeChild(argument_element.getFirstChild());
459 }
460 argument_element.appendChild(document.createTextNode((String)value));
461 }
462 }
463 argument_element = null;
464 }
465 // If we haven't found an instance of this argument, but should have, then add it.
466 if(!found && (enable || value != null)) {
467 Element argument_element = document.createElement(ARGUMENT);
468 argument_element.setAttribute(NAME, name);
469 argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE));
470 // Now we set the value, depending or what it is.
471 if(value == null) {
472 // Nothing to do.
473 }
474 else {
475 argument_element.appendChild(document.createTextNode((String)value));
476 }
477 arguments_element.appendChild(argument_element);
478 }
479 arguments = null;
480 document = null;
481 // Make sure the collection knows to save.
482 Gatherer.c_man.getCollection().setSaved(false);
483 }
484 catch (Exception error) {
485 DebugStream.printStackTrace(error);
486 }
487 }
488
489 /** Remove the named value from the given arguments element. */
490 private void removeValue(Element arguments_element, String name) {
491 try {
492 NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
493 boolean found = false;
494 for(int i = 0; !found && i < arguments.getLength(); i++) {
495 Element argument_element = (Element) arguments.item(i);
496 // Is this the argument we want.
497 if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
498 arguments_element.removeChild(argument_element);
499 found = true;
500 }
501 argument_element = null;
502 }
503 arguments = null;
504 }
505 catch (Exception error) {
506 DebugStream.printStackTrace(error);
507 }
508 }
509}
Note: See TracBrowser for help on using the repository browser.