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

Last change on this file since 7115 was 7022, checked in by kjdon, 20 years ago

now reads in build options in the right language, and doesn't use the ones saved in config.xml unless the language is the same

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