1 | package org.greenstone.gatherer.collection;
|
---|
2 |
|
---|
3 | import java.io.*;
|
---|
4 | import java.lang.ref.*;
|
---|
5 | import java.net.*;
|
---|
6 | import java.util.*;
|
---|
7 | import org.apache.xerces.parsers.DOMParser;
|
---|
8 | import org.greenstone.gatherer.Configuration;
|
---|
9 | import org.greenstone.gatherer.DebugStream;
|
---|
10 | import org.greenstone.gatherer.Gatherer;
|
---|
11 | import org.greenstone.gatherer.cdm.Argument;
|
---|
12 | import org.greenstone.gatherer.util.ArrayTools;
|
---|
13 | import org.greenstone.gatherer.util.Codec;
|
---|
14 | import org.greenstone.gatherer.util.StaticStrings;
|
---|
15 | import org.greenstone.gatherer.util.Utility;
|
---|
16 | import org.greenstone.gatherer.util.XMLTools;
|
---|
17 | import org.w3c.dom.*;
|
---|
18 | import 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. */
|
---|
21 | public 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 | NodeList option_list = arguments_element.getElementsByTagName(OPTION);
|
---|
223 | if(0 <= index && index < option_list.getLength()) {
|
---|
224 | Argument argument = new Argument();
|
---|
225 | argument.parseXML((Element) option_list.item(index));
|
---|
226 | return argument;
|
---|
227 | }
|
---|
228 | return null; // no arg at this position
|
---|
229 | }
|
---|
230 |
|
---|
231 | private String getValue(Element arguments_element, String name, boolean is_enabled) {
|
---|
232 | String result = null;
|
---|
233 | try {
|
---|
234 | NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
|
---|
235 | for(int i = 0; result == null && i < arguments.getLength(); i++) {
|
---|
236 | Element argument_element = (Element) arguments.item(i);
|
---|
237 | // Is this the argument we want.
|
---|
238 | if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
|
---|
239 | // Are we simply determining if this argument is enabled
|
---|
240 | if(is_enabled) {
|
---|
241 | result = argument_element.getAttribute(ENABLED);
|
---|
242 | }
|
---|
243 | else {
|
---|
244 | String argument_value = XMLTools.getValue(argument_element);
|
---|
245 | if(argument_value != null) {
|
---|
246 | result = argument_value;
|
---|
247 | }
|
---|
248 | argument_value = null;
|
---|
249 | }
|
---|
250 | }
|
---|
251 | argument_element = null;
|
---|
252 | }
|
---|
253 | arguments = null;
|
---|
254 | }
|
---|
255 | catch (Exception error) {
|
---|
256 | DebugStream.printStackTrace(error);
|
---|
257 | }
|
---|
258 | return result;
|
---|
259 | }
|
---|
260 |
|
---|
261 | private String[] getValues(Element arguments_element) {
|
---|
262 | ArrayList values = new ArrayList();
|
---|
263 | try {
|
---|
264 | NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
|
---|
265 | for(int i = 0; i < arguments.getLength(); i++) {
|
---|
266 | Element argument_element = (Element) arguments.item(i);
|
---|
267 | // Determine if this argument is enabled.
|
---|
268 | if(argument_element.getAttribute(ENABLED).equalsIgnoreCase(TRUE)) {
|
---|
269 | // First store the name of the argument prefixed with a '-'
|
---|
270 | values.add("-" + argument_element.getAttribute(NAME));
|
---|
271 | // Now retrieve the value.
|
---|
272 | String argument_value = Codec.transform(XMLTools.getValue(argument_element), Codec.DOM_TO_TEXT);
|
---|
273 | // If there is a value, tokenize it by commas only.
|
---|
274 | if(argument_value != null && argument_value.length() > 0) {
|
---|
275 | values.add(argument_value);
|
---|
276 | }
|
---|
277 | argument_value = null;
|
---|
278 | }
|
---|
279 | argument_element = null;
|
---|
280 | }
|
---|
281 | arguments = null;
|
---|
282 | }
|
---|
283 | catch (Exception error) {
|
---|
284 | DebugStream.printStackTrace(error);
|
---|
285 | }
|
---|
286 | return ArrayTools.arrayListToStringArray(values);
|
---|
287 | }
|
---|
288 |
|
---|
289 | private Element loadArguments(String filename, String lang) {
|
---|
290 | Element arguments_element = null;
|
---|
291 | InputStream input_stream = null;
|
---|
292 |
|
---|
293 | // Run the required program.
|
---|
294 | try {
|
---|
295 | String args[];
|
---|
296 | if (Gatherer.isGsdlRemote) {
|
---|
297 | String launch = Gatherer.cgiBase + "launch";
|
---|
298 | launch += "?cmd=" + filename;
|
---|
299 | launch += "&xml=&language="+lang;
|
---|
300 |
|
---|
301 | System.err.println("*** launch = " + launch);
|
---|
302 |
|
---|
303 | URL launch_url = new URL(launch);
|
---|
304 | URLConnection launch_connection = launch_url.openConnection();
|
---|
305 | input_stream = launch_connection.getInputStream();
|
---|
306 | }
|
---|
307 | else {
|
---|
308 | if(Utility.isWindows()) {
|
---|
309 | args = new String[6];
|
---|
310 | args[0] = Configuration.perl_path;
|
---|
311 | args[1] = "-S";
|
---|
312 | args[2] = Configuration.getScriptPath() + filename;
|
---|
313 | args[3] = "-xml";
|
---|
314 | args[4] = "-language";
|
---|
315 | args[5] = lang;
|
---|
316 | }
|
---|
317 | else {
|
---|
318 | args = new String[4];
|
---|
319 | args[0] = Configuration.getScriptPath() + filename;
|
---|
320 | args[1] = "-xml";
|
---|
321 | args[2] = "-language";
|
---|
322 | args[3] = lang;
|
---|
323 | }
|
---|
324 |
|
---|
325 | // Create the process.
|
---|
326 | Runtime runtime = Runtime.getRuntime();
|
---|
327 | Process process = runtime.exec(args);
|
---|
328 |
|
---|
329 | input_stream = process.getErrorStream();
|
---|
330 | }
|
---|
331 |
|
---|
332 | Document document = XMLTools.parseXML(input_stream);
|
---|
333 | arguments_element = document.getDocumentElement();
|
---|
334 | }
|
---|
335 | catch (Exception error) {
|
---|
336 | DebugStream.println("Error in BuildOptions.loadArguments(): " + error);
|
---|
337 | DebugStream.printStackTrace(error);
|
---|
338 | }
|
---|
339 | return arguments_element;
|
---|
340 | }
|
---|
341 |
|
---|
342 | /** 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. */
|
---|
343 | public void setValue(Element arguments_element, String name, boolean enable, String value) {
|
---|
344 | ///ystem.err.println("Set value: " + (arguments_element == build_values_element ? "Build" : "Import") + ", " + name + ", " + enable + ", " + value);
|
---|
345 | try {
|
---|
346 | Document document = arguments_element.getOwnerDocument();
|
---|
347 | NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
|
---|
348 | boolean found = false;
|
---|
349 | for(int i = 0; i < arguments.getLength(); i++) {
|
---|
350 | Element argument_element = (Element) arguments.item(i);
|
---|
351 | // If this the argument named.
|
---|
352 | if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
|
---|
353 | found = true;
|
---|
354 | // Set whether this argument is enabled
|
---|
355 | argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE));
|
---|
356 | // Now we set the value, depending or what it is.
|
---|
357 | if(value == null) {
|
---|
358 | // Nothing to do.
|
---|
359 | }
|
---|
360 | else {
|
---|
361 | // Remove existing text nodes.
|
---|
362 | while(argument_element.hasChildNodes()) {
|
---|
363 | argument_element.removeChild(argument_element.getFirstChild());
|
---|
364 | }
|
---|
365 | argument_element.appendChild(document.createTextNode((String)value));
|
---|
366 | }
|
---|
367 | }
|
---|
368 | argument_element = null;
|
---|
369 | }
|
---|
370 | // If we haven't found an instance of this argument, but should have, then add it.
|
---|
371 | if(!found && (enable || value != null)) {
|
---|
372 | Element argument_element = document.createElement(ARGUMENT);
|
---|
373 | argument_element.setAttribute(NAME, name);
|
---|
374 | argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE));
|
---|
375 | // Now we set the value, depending or what it is.
|
---|
376 | if(value == null) {
|
---|
377 | // Nothing to do.
|
---|
378 | }
|
---|
379 | else {
|
---|
380 | argument_element.appendChild(document.createTextNode((String)value));
|
---|
381 | }
|
---|
382 | arguments_element.appendChild(argument_element);
|
---|
383 | }
|
---|
384 | arguments = null;
|
---|
385 | document = null;
|
---|
386 | // Make sure the collection knows to save.
|
---|
387 | Gatherer.c_man.getCollection().setSaved(false);
|
---|
388 | }
|
---|
389 | catch (Exception error) {
|
---|
390 | DebugStream.printStackTrace(error);
|
---|
391 | }
|
---|
392 | }
|
---|
393 |
|
---|
394 | /** Remove the named value from the given arguments element. */
|
---|
395 | private void removeValue(Element arguments_element, String name) {
|
---|
396 | try {
|
---|
397 | NodeList arguments = arguments_element.getElementsByTagName(ARGUMENT);
|
---|
398 | boolean found = false;
|
---|
399 | for(int i = 0; !found && i < arguments.getLength(); i++) {
|
---|
400 | Element argument_element = (Element) arguments.item(i);
|
---|
401 | // Is this the argument we want.
|
---|
402 | if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
|
---|
403 | arguments_element.removeChild(argument_element);
|
---|
404 | found = true;
|
---|
405 | }
|
---|
406 | argument_element = null;
|
---|
407 | }
|
---|
408 | arguments = null;
|
---|
409 | }
|
---|
410 | catch (Exception error) {
|
---|
411 | DebugStream.printStackTrace(error);
|
---|
412 | }
|
---|
413 | }
|
---|
414 | }
|
---|