package org.greenstone.gatherer.collection; import java.io.*; import java.util.*; import org.greenstone.gatherer.Configuration; import org.greenstone.gatherer.DebugStream; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.cdm.Argument; import org.greenstone.gatherer.greenstone.LocalGreenstone; import org.greenstone.gatherer.remote.RemoteGreenstoneServer; import org.greenstone.gatherer.util.ArrayTools; import org.greenstone.gatherer.util.Codec; import org.greenstone.gatherer.util.SafeProcess; import org.greenstone.gatherer.util.Utility; import org.greenstone.gatherer.util.XMLTools; import org.w3c.dom.*; /** This class parses options from Perl scripts: import.pl, buildcol.pl and explode_metadata_database.pl in particular. */ public class ScriptOptions { /** The root element of the argument tree. */ private Element arguments_element; /** The root element of the values tree. */ private Element values_element; /** The name of an argument element. */ static final private String ARGUMENT = "Argument"; /** The name of the enabled attribute. */ static final private String ENABLED = "enabled"; /** The name of the 'false' value. */ static final private String FALSE = "false"; /** The name of a name attribute. */ static final private String NAME = "name"; /** The name of an option element. */ static final private String OPTION = "Option"; /** The name of the 'true' value. */ static final private String TRUE = "true"; /** Parse the arguments from running "script_name -xml" */ public ScriptOptions(Element values_element, String script_name) { this.values_element = values_element; this.arguments_element = loadArguments(script_name, Configuration.getLanguage()); } /** Retrieve the indexth argument */ public Argument getArgument(int index) { Argument argument = null; NodeList option_list = arguments_element.getElementsByTagName(OPTION); if (index >= 0 && index < option_list.getLength()) { argument = new Argument(); argument.parseXML((Element) option_list.item(index)); } return argument; } /** Retrieve the number of arguments. */ public int getArgumentCount() { // Determining the total count is easy. NodeList argument_elements = arguments_element.getElementsByTagName(OPTION); return argument_elements.getLength(); } /** Retrieve the value of a certain argument. */ public String getValue(String name) { return getValue(name, false); } /** Determine if the named argument value is enabled or disabled. */ public boolean getValueEnabled(String name) { boolean result = false; String value = getValue(name, true); if(value != null && value.length() > 0) { result = (value.equalsIgnoreCase(TRUE)); } return result; } /** Retrieve all of the values as a String array ready to added to the script call. */ public String[] getValues() { ArrayList values = new ArrayList(); try { NodeList arguments = values_element.getElementsByTagName(ARGUMENT); for(int i = 0; i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); // Determine if this argument is enabled. if(argument_element.getAttribute(ENABLED).equalsIgnoreCase(TRUE)) { // First store the name of the argument prefixed with a '-' values.add("-" + argument_element.getAttribute(NAME)); // Now retrieve the value. String argument_value = Codec.transform(XMLTools.getValue(argument_element), Codec.DOM_TO_TEXT); // If there is a value, tokenize it by commas only. if(argument_value != null && argument_value.length() > 0) { values.add(argument_value); } argument_value = null; } argument_element = null; } arguments = null; } catch (Exception error) { DebugStream.printStackTrace(error); } return ArrayTools.arrayListToStringArray(values); } /** Remove the named value from the arguments */ public void removeValue(String name) { try { NodeList arguments = values_element.getElementsByTagName(ARGUMENT); boolean found = false; for(int i = 0; !found && i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); // Is this the argument we want. if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) { values_element.removeChild(argument_element); found = true; } argument_element = null; } arguments = null; } catch (Exception error) { DebugStream.printStackTrace(error); } } /** 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. */ public void setValue(String name, boolean enable, String value) { ///ystem.err.println("Set value: " + (arguments_element == build_values_element ? "Build" : "Import") + ", " + name + ", " + enable + ", " + value); try { Document document = values_element.getOwnerDocument(); NodeList arguments = values_element.getElementsByTagName(ARGUMENT); boolean found = false; for(int i = 0; i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); // If this the argument named. if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) { found = true; // Set whether this argument is enabled argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE)); // Now we set the value, depending or what it is. if(value == null) { // Nothing to do. } else { // Remove existing text nodes. while(argument_element.hasChildNodes()) { argument_element.removeChild(argument_element.getFirstChild()); } argument_element.appendChild(document.createTextNode((String)value)); } } argument_element = null; } // If we haven't found an instance of this argument, but should have, then add it. if(!found && (enable || value != null)) { Element argument_element = document.createElement(ARGUMENT); argument_element.setAttribute(NAME, name); argument_element.setAttribute(ENABLED, (enable ? TRUE : FALSE)); // Now we set the value, depending or what it is. if(value == null) { // Nothing to do. } else { argument_element.appendChild(document.createTextNode((String)value)); } values_element.appendChild(argument_element); } arguments = null; document = null; // Make sure the collection knows to save. Gatherer.c_man.getCollection().setSaved(false); } catch (Exception error) { DebugStream.printStackTrace(error); } } private String getValue(String name, boolean is_enabled) { String result = null; try { NodeList arguments = values_element.getElementsByTagName(ARGUMENT); for(int i = 0; result == null && i < arguments.getLength(); i++) { Element argument_element = (Element) arguments.item(i); // Is this the argument we want. if(argument_element.getAttribute(NAME).equalsIgnoreCase(name)) { // Are we simply determining if this argument is enabled if(is_enabled) { result = argument_element.getAttribute(ENABLED); } else { String argument_value = XMLTools.getValue(argument_element); if(argument_value != null) { result = argument_value; } argument_value = null; } } argument_element = null; } arguments = null; } catch (Exception error) { DebugStream.printStackTrace(error); } return result; } private Element loadArguments(String filename, String lang) { // Run the required program. try { Document document; if (Gatherer.isGsdlRemote) { String script_output = Gatherer.remoteGreenstoneServer.getScriptOptions(filename, ""); document = XMLTools.parseXML(new StringReader(script_output)); } else { String args[]; args = new String[6]; args[0] = Configuration.perl_path; args[1] = "-S"; args[2] = LocalGreenstone.getBinScriptDirectoryPath() + filename; args[3] = "-xml"; args[4] = "-language"; args[5] = lang; // Create the process. SafeProcess process = new SafeProcess(args); //for (int i=0; i