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

Last change on this file since 6224 was 6087, checked in by jmt12, 21 years ago

Extended arguments so they could be given a minimum and maximum range. Then if they are INTEGER type controls, the spinner control generated will honour any range information. Range information is supplied via the perl -xml type mechanism, using the tag form <Range>0,3</Range>

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