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.LocalGreenstone;
|
---|
12 | import org.greenstone.gatherer.cdm.Argument;
|
---|
13 | import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
|
---|
14 | import org.greenstone.gatherer.util.ArrayTools;
|
---|
15 | import org.greenstone.gatherer.util.Codec;
|
---|
16 | import org.greenstone.gatherer.util.StaticStrings;
|
---|
17 | import org.greenstone.gatherer.util.Utility;
|
---|
18 | import org.greenstone.gatherer.util.XMLTools;
|
---|
19 | import org.w3c.dom.*;
|
---|
20 | import org.xml.sax.InputSource;
|
---|
21 |
|
---|
22 | /** 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. */
|
---|
23 | public class ScriptOptions {
|
---|
24 | /** The root element of the argument tree. */
|
---|
25 | private Element arguments_element;
|
---|
26 | /** The root element of the values tree. */
|
---|
27 | private Element values_element;
|
---|
28 | /** A cache of previously created arguments. */
|
---|
29 | private Hashtable arguments_cache = new Hashtable();
|
---|
30 | /** whether the values should be saved or not */
|
---|
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 ScriptOptions object we first try to retrieve the valid arguments from config.xml - if saved is true. If that fails we then try to parse the arguments noticed when calling script_name -xml. If that also fails, we try to load the default arguments from the xml template library. */
|
---|
44 | public ScriptOptions(Element values_element, String script_name, boolean saved) {
|
---|
45 | // first check the saved arguments language
|
---|
46 | String interface_lang = Configuration.getLanguage();
|
---|
47 | String args_lang = Configuration.getArgumentsLanguage();
|
---|
48 | if (saved && interface_lang.equals(args_lang)) {
|
---|
49 | // Try to retrieve the arguments for import and build.
|
---|
50 | arguments_element = Configuration.getArguments(script_name);
|
---|
51 | }
|
---|
52 | // If that fails try to reconstruct the arguments
|
---|
53 | if(arguments_element == null) {
|
---|
54 | boolean used_defaults = false;
|
---|
55 | arguments_element = loadArguments(script_name, interface_lang);
|
---|
56 |
|
---|
57 | // And if that too fails, load the default argument templates
|
---|
58 | if(arguments_element == null) {
|
---|
59 | // replace .pl with .xml to get the template name
|
---|
60 | String template_name = script_name.replaceAll("\\.pl$", "\\.xml");
|
---|
61 | Document document = XMLTools.parseXMLFile("xml/" + template_name, true);
|
---|
62 | if (document != null) {
|
---|
63 | arguments_element = document.getDocumentElement();
|
---|
64 | document = null;
|
---|
65 | used_defaults = true;
|
---|
66 |
|
---|
67 | } else {
|
---|
68 | return;
|
---|
69 | }
|
---|
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 (saved) {
|
---|
77 | if (used_defaults) {
|
---|
78 | Configuration.setArgumentsLanguage("en");
|
---|
79 | } else {
|
---|
80 | Configuration.setArgumentsLanguage(interface_lang);
|
---|
81 | }
|
---|
82 | Configuration.setArguments(arguments_element);
|
---|
83 | }
|
---|
84 | }
|
---|
85 | else {
|
---|
86 | DebugStream.println("Loaded BO arguments from config.xml");
|
---|
87 | }
|
---|
88 | // Now take a note of the values too.
|
---|
89 | this.values_element = values_element;
|
---|
90 | }
|
---|
91 |
|
---|
92 | /** Retrieve the indexth argument */
|
---|
93 | public Argument getArgument(int index) {
|
---|
94 | Argument argument = null;
|
---|
95 | // Try to find the argument in the cache.
|
---|
96 | SoftReference reference = (SoftReference) arguments_cache.get(new Integer(index));
|
---|
97 | if(reference != null) {
|
---|
98 | argument = (Argument) reference.get();
|
---|
99 | }
|
---|
100 | // Otherwise generate a new argument.
|
---|
101 | if(argument == null) {
|
---|
102 | NodeList option_list = arguments_element.getElementsByTagName(OPTION);
|
---|
103 | if(0 <= index && index < option_list.getLength()) {
|
---|
104 | argument = new Argument();
|
---|
105 | argument.parseXML((Element) option_list.item(index));
|
---|
106 | }
|
---|
107 | }
|
---|
108 | return argument;
|
---|
109 | }
|
---|
110 |
|
---|
111 |
|
---|
112 | /** Retrieve the number of arguments.
|
---|
113 | */
|
---|
114 | public int getArgumentCount() {
|
---|
115 | // Determining the total count is easy.
|
---|
116 | NodeList argument_elements = arguments_element.getElementsByTagName(OPTION);
|
---|
117 | return argument_elements.getLength();
|
---|
118 | }
|
---|
119 |
|
---|
120 | /** Retrieve all the argument names and values */
|
---|
121 | public String[] getArguments() {
|
---|
122 | String arguments[] = null;
|
---|
123 | NodeList argument_list = null;
|
---|
124 | argument_list = values_element.getElementsByTagName(ARGUMENT);
|
---|
125 | for(int i = 0; i < argument_list.getLength(); i++) {
|
---|
126 | Element argument = (Element) argument_list.item(i);
|
---|
127 | ArrayTools.add(arguments, argument.getAttribute(NAME));
|
---|
128 | String value = XMLTools.getValue(argument);
|
---|
129 | if(value != null && value.length() > 0) {
|
---|
130 | ArrayTools.add(arguments, value);
|
---|
131 | }
|
---|
132 | }
|
---|
133 | return arguments;
|
---|
134 | }
|
---|
135 |
|
---|
136 | /** Retrieve the value of a certain argument. */
|
---|
137 | public String getValue(String name) {
|
---|
138 | return getValue(name, false);
|
---|
139 | }
|
---|
140 |
|
---|
141 | /** Determine if the named argument value is enabled or disabled. */
|
---|
142 | public boolean getValueEnabled(String name) {
|
---|
143 | boolean result = false;
|
---|
144 | String value = getValue(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 values as a String array ready to added to the script call. */
|
---|
152 | public String[] getValues() {
|
---|
153 | ArrayList values = new ArrayList();
|
---|
154 | try {
|
---|
155 | NodeList arguments = values_element.getElementsByTagName(ARGUMENT);
|
---|
156 | for(int i = 0; i < arguments.getLength(); i++) {
|
---|
157 | Element argument_element = (Element) arguments.item(i);
|
---|
158 | // Determine if this argument is enabled.
|
---|
159 | if(argument_element.getAttribute(ENABLED).equalsIgnoreCase(TRUE)) {
|
---|
160 | // First store the name of the argument prefixed with a '-'
|
---|
161 | values.add("-" + argument_element.getAttribute(NAME));
|
---|
162 | // Now retrieve the value.
|
---|
163 | String argument_value = Codec.transform(XMLTools.getValue(argument_element), Codec.DOM_TO_TEXT);
|
---|
164 | // If there is a value, tokenize it by commas only.
|
---|
165 | if(argument_value != null && argument_value.length() > 0) {
|
---|
166 | values.add(argument_value);
|
---|
167 | }
|
---|
168 | argument_value = null;
|
---|
169 | }
|
---|
170 | argument_element = null;
|
---|
171 | }
|
---|
172 | arguments = null;
|
---|
173 | }
|
---|
174 | catch (Exception error) {
|
---|
175 | DebugStream.printStackTrace(error);
|
---|
176 | }
|
---|
177 | return ArrayTools.arrayListToStringArray(values);
|
---|
178 | }
|
---|
179 |
|
---|
180 | /** Remove the named value from the arguments */
|
---|
181 | public void removeValue(String name) {
|
---|
182 | try {
|
---|
183 | NodeList arguments = values_element.getElementsByTagName(ARGUMENT);
|
---|
184 | boolean found = false;
|
---|
185 | for(int i = 0; !found && i < arguments.getLength(); i++) {
|
---|
186 | Element argument_element = (Element) arguments.item(i);
|
---|
187 | // Is this the argument we want.
|
---|
188 | if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
|
---|
189 | values_element.removeChild(argument_element);
|
---|
190 | found = true;
|
---|
191 | }
|
---|
192 | argument_element = null;
|
---|
193 | }
|
---|
194 | arguments = null;
|
---|
195 | }
|
---|
196 | catch (Exception error) {
|
---|
197 | DebugStream.printStackTrace(error);
|
---|
198 | }
|
---|
199 | }
|
---|
200 |
|
---|
201 | /** Set the state of some argument. Note that value may be either a single String, an ArrayList of Strings or null. If enable is false then any existing argument for the named argument is disabled. */
|
---|
202 | public void setValue(String name, boolean enable, String value) {
|
---|
203 | ///ystem.err.println("Set value: " + (arguments_element == build_values_element ? "Build" : "Import") + ", " + name + ", " + enable + ", " + value);
|
---|
204 | try {
|
---|
205 | Document document = values_element.getOwnerDocument();
|
---|
206 | NodeList arguments = values_element.getElementsByTagName(ARGUMENT);
|
---|
207 | boolean found = false;
|
---|
208 | for(int i = 0; i < arguments.getLength(); i++) {
|
---|
209 | Element argument_element = (Element) arguments.item(i);
|
---|
210 | // If this the argument named.
|
---|
211 | if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
|
---|
212 | found = true;
|
---|
213 | // Set whether this argument is enabled
|
---|
214 | argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE));
|
---|
215 | // Now we set the value, depending or what it is.
|
---|
216 | if(value == null) {
|
---|
217 | // Nothing to do.
|
---|
218 | }
|
---|
219 | else {
|
---|
220 | // Remove existing text nodes.
|
---|
221 | while(argument_element.hasChildNodes()) {
|
---|
222 | argument_element.removeChild(argument_element.getFirstChild());
|
---|
223 | }
|
---|
224 | argument_element.appendChild(document.createTextNode((String)value));
|
---|
225 | }
|
---|
226 | }
|
---|
227 | argument_element = null;
|
---|
228 | }
|
---|
229 | // If we haven't found an instance of this argument, but should have, then add it.
|
---|
230 | if(!found && (enable || value != null)) {
|
---|
231 | Element argument_element = document.createElement(ARGUMENT);
|
---|
232 | argument_element.setAttribute(NAME, name);
|
---|
233 | argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE));
|
---|
234 | // Now we set the value, depending or what it is.
|
---|
235 | if(value == null) {
|
---|
236 | // Nothing to do.
|
---|
237 | }
|
---|
238 | else {
|
---|
239 | argument_element.appendChild(document.createTextNode((String)value));
|
---|
240 | }
|
---|
241 | values_element.appendChild(argument_element);
|
---|
242 | }
|
---|
243 | arguments = null;
|
---|
244 | document = null;
|
---|
245 | // Make sure the collection knows to save.
|
---|
246 | Gatherer.c_man.getCollection().setSaved(false);
|
---|
247 | }
|
---|
248 | catch (Exception error) {
|
---|
249 | DebugStream.printStackTrace(error);
|
---|
250 | }
|
---|
251 | }
|
---|
252 |
|
---|
253 |
|
---|
254 | private String getValue(String name, boolean is_enabled) {
|
---|
255 | String result = null;
|
---|
256 | try {
|
---|
257 | NodeList arguments = values_element.getElementsByTagName(ARGUMENT);
|
---|
258 | for(int i = 0; result == null && i < arguments.getLength(); i++) {
|
---|
259 | Element argument_element = (Element) arguments.item(i);
|
---|
260 | // Is this the argument we want.
|
---|
261 | if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) {
|
---|
262 | // Are we simply determining if this argument is enabled
|
---|
263 | if(is_enabled) {
|
---|
264 | result = argument_element.getAttribute(ENABLED);
|
---|
265 | }
|
---|
266 | else {
|
---|
267 | String argument_value = XMLTools.getValue(argument_element);
|
---|
268 | if(argument_value != null) {
|
---|
269 | result = argument_value;
|
---|
270 | }
|
---|
271 | argument_value = null;
|
---|
272 | }
|
---|
273 | }
|
---|
274 | argument_element = null;
|
---|
275 | }
|
---|
276 | arguments = null;
|
---|
277 | }
|
---|
278 | catch (Exception error) {
|
---|
279 | DebugStream.printStackTrace(error);
|
---|
280 | }
|
---|
281 | return result;
|
---|
282 | }
|
---|
283 |
|
---|
284 |
|
---|
285 | private Element loadArguments(String filename, String lang) {
|
---|
286 | Element arguments_element = null;
|
---|
287 | InputStream input_stream = null;
|
---|
288 |
|
---|
289 | // Run the required program.
|
---|
290 | try {
|
---|
291 | Document document;
|
---|
292 | if (Gatherer.isGsdlRemote) {
|
---|
293 | String script_output = RemoteGreenstoneServer.getScriptOptions(filename, "");
|
---|
294 | document = XMLTools.parseXML(new StringReader(script_output));
|
---|
295 | }
|
---|
296 | else {
|
---|
297 | String args[];
|
---|
298 | if(Utility.isWindows()) {
|
---|
299 | args = new String[6];
|
---|
300 | args[0] = Configuration.perl_path;
|
---|
301 | args[1] = "-S";
|
---|
302 | args[2] = LocalGreenstone.getBinScriptDirectoryPath() + filename;
|
---|
303 | args[3] = "-xml";
|
---|
304 | args[4] = "-language";
|
---|
305 | args[5] = lang;
|
---|
306 | }
|
---|
307 | else {
|
---|
308 | args = new String[4];
|
---|
309 | args[0] = LocalGreenstone.getBinScriptDirectoryPath() + filename;
|
---|
310 | args[1] = "-xml";
|
---|
311 | args[2] = "-language";
|
---|
312 | args[3] = lang;
|
---|
313 | }
|
---|
314 |
|
---|
315 | // Create the process.
|
---|
316 | Runtime runtime = Runtime.getRuntime();
|
---|
317 | Process process = runtime.exec(args);
|
---|
318 |
|
---|
319 | input_stream = process.getErrorStream();
|
---|
320 | document = XMLTools.parseXML(input_stream);
|
---|
321 | }
|
---|
322 |
|
---|
323 | arguments_element = document.getDocumentElement();
|
---|
324 | }
|
---|
325 | catch (Exception error) {
|
---|
326 | DebugStream.println("Error in ScriptOptions.loadArguments(): " + error);
|
---|
327 | DebugStream.printStackTrace(error);
|
---|
328 | }
|
---|
329 | return arguments_element;
|
---|
330 | }
|
---|
331 |
|
---|
332 | }
|
---|