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

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

Replaced all "Gatherer.config" with "Configuration".

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