/** *######################################################################### * * A component of the Greenstone Librarian Interface (GLI) application, * part of the Greenstone digital library software suite from the New * Zealand Digital Library Project at the University of Waikato, * New Zealand. * * Author: John Thompson * Greenstone Project, New Zealand Digital Library * University of Waikato * http://www.nzdl.org * * Copyright (C) 2004 New Zealand Digital Library, University of Waikato * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer.cdm; 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.collection.Collection; import org.greenstone.gatherer.collection.CollectionManager; import org.greenstone.gatherer.metadata.MetadataElement; import org.greenstone.gatherer.metadata.MetadataTools; import org.greenstone.gatherer.util.StaticStrings; import org.greenstone.gatherer.util.Utility; import org.greenstone.gatherer.util.XMLTools; import org.w3c.dom.*; /** This class contains all the details about a single argument that can be passed to this plugin, including option lists if the parameters are restricted. * @author John Thompson, Greenstone Project, New Zealand Digital Library, University of Waikato * @version 2.41 final */ public class Argument implements Comparable, Serializable { /** An element of the argument type enumeration specifying a combobox control. */ static final public byte ENUM = 0; /** An element of the argument type enumeration specifying a checkbox control. */ static final public byte FLAG = 1; /** An element of the argument type enumeration specifying a tree control. */ static final public byte HIERARCHY = 2; /** An element of the argument type enumeration specifying a spinner control. */ static final public byte INTEGER = 3; /** An element of the argument type enumeration specifying a language combobox control. */ static final public byte LANGUAGE = 4; /** An element of the argument type enumeration specifying a metadata combobox control. */ static final public byte METADATA = 5; /** An element of the argument type enumeration specifying a text field. */ static final public byte STRING = 6; /** An element of the argument type enumeration specifying a regular expression text field. */ static final public byte REGEXP = 7; /** An element of the argument type enumeration specifying a metadata set combobox control. */ static final public byte METADATA_SET_NAMESPACE = 8; /** An element of the argument type enumeration specifying a text field. */ static final public byte URL = 9; /** An editable combo box */ static final public byte ENUM_STRING = 10; ///////////////////////////////////////////////////////////////// /** true if this argument should actually be hidden within the GLI. This is important for arguments such as import dir or other location critical arguments. */ private boolean hidden_gli = false; /** true if this argument is required for the applicable script to work properly, false otherwise. */ private boolean required = false; /** The type of this argument. Used to be an int, but bytes are cheaper. */ private byte type = STRING; /** The maximum value an integer based control can have. */ private int maximum = Integer.MAX_VALUE; /** The minimum value an integer based control can have. */ private int minimum = Integer.MIN_VALUE; /** Every argument has a detail mode level at which it becomes available to the user to edit. * @see org.greenstone.gatherer.Configuration */ private int mode_level = Configuration.LIBRARIAN_MODE; /** The DOM element this argument is built around, if any. */ private Element element; /** If the argument is of type ENUM or ENUM_STRING then this map holds all the various options. Each entry is an <option value> -> <description> mapping. */ private ArrayList option_list = null; /** A default value for parameter-type arguments. May be a Perl pattern. */ private String default_value = null; /** The text description of this argument parsed from the pluginfo output. */ private String description = null; /** The argument flag as it appears in the command. Also used as the unique identifier of an argument. */ private String name = null; /** The value of the arg, stored for metadata type options */ private String stored_value = null; /** The plugin that owns this argument, for the purposes of visualising inheritance. */ private String owner = null; private String display_name = null; /** Default Constructor. */ public Argument() { } /** Another constructor but this one is a little more interesting as it takes a DOM element. * @param element the Element this argument is based around */ public Argument(Element element) { this.element = element; } /** Method to add an element to the option_list. * @param name the name value of the option as a String * @param desc the description of this options as a String */ public void addOption(String name, String desc) { if((type == ENUM || type == ENUM_STRING) && name != null) { if(desc == null) { desc = ""; } if(option_list == null) { option_list = new ArrayList(); } option_list.add(new ArgumentOption(name, desc)); } } /** Method to compare two arguments for ordering. * @param object the argument we are comparing to, as an Object * @return an int specifying the argument order, using values as set out in String * @see org.greenstone.gatherer.cdm.Argument */ public int compareTo(Object object) { if(object instanceof Argument) { return getName().compareTo(((Argument)object).getName()); } else { return toString().compareTo(object.toString()); } } /** Create a copy of this argument. * @return a newly created Argument with the same details as this one */ public Argument copy() { Argument copy = new Argument(); copy.setDefaultValue(default_value); copy.setDescription(description); copy.setOptions(option_list); copy.setOwner(owner); copy.setName(name); copy.setDisplayName(display_name); copy.setRequired(required); copy.setType(type); copy.setMinimum(minimum); copy.setMaximum(maximum); copy.setModeLevel(mode_level); copy.setHiddenGLI(hidden_gli); return copy; } /** Method to determine if two arguments are equal. * @param object the argument to test against, as an Object * @return true if the arguments names match, false otherwise */ public boolean equals(Object object) { return (compareTo(object) == 0); } /** Method to retrieve the value of default_value. * @return a String containing the default value */ public String getDefaultValue() { return default_value; } /** Method to retrieve this arguments description. * @return a String containing the description */ public String getDescription() { return description; } public Element getElement() { return element; } /** Retrieve the upper bound of a range based argument. * @return the maximum as an int */ public int getMaximum() { return maximum; } /** Retrieve the lower bound of a range based argument. * @return the minimum as an int */ public int getMinimum() { return minimum; } /** Retrieves the mode level at which this argument should become available. Any higher levels should also see this argument. * @return the mode level as an int */ public int getModeLevel() { return mode_level; } /** Method to retrieve the value of name. * @return a String containing the argument name * @see org.greenstone.gatherer.util.StaticStrings#NAME_ATTRIBUTE */ public String getName() { if(name == null && element != null) { name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE); } return name; } public String getDisplayName() { if(display_name==null) return ""; return display_name; } /** Method to retrieve the option list for this argument. * @return a HashMap containing <option value> -> <description> entries */ public ArrayList getOptions() { return option_list; } /** Retrieve the name of the owner of this argument. * @return the owners name as a String */ public String getOwner() { return owner; } /** Method to determine the type of this argument. * @return a byte specifying the type */ public byte getType() { return type; } /** Method to retrieve the value of value. * @return the value of value as a String * @see org.greenstone.gatherer.Gatherer#c_man * @see org.greenstone.gatherer.collection.CollectionManager#getCollection */ public String getValue() { // Only assigned arguments have values. if (element == null) { return null; } if (stored_value != null) { return stored_value; } String value = XMLTools.getValue(element); if (type == METADATA) { // We display using metadata display name, but store in the XML using // full name (canonical name) stored_value = MetadataTools.convertMetadataElementListNames(value, MetadataTools.TO_DISPLAY_NAMES); return stored_value; } return value; } /** Method to determine if this argument has been assigned. * @return true if it has, false otherwise * @see org.greenstone.gatherer.util.StaticStrings#ASSIGNED_ATTRIBUTE * @see org.greenstone.gatherer.util.StaticStrings#TRUE_STR */ public boolean isAssigned() { return (element != null && element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.TRUE_STR)); } /** Determine if this is a custom argument ie one that has been parsed from the config file but doesn't have a matching entry in the argument library. * @return true if this argument is a custom, false otherwise * @see org.greenstone.gatherer.util.StaticStrings#CUSTOM_ATTRIBUTE * @see org.greenstone.gatherer.util.StaticStrings#TRUE_STR */ public boolean isCustomArgument() { return (element != null && element.getAttribute(StaticStrings.CUSTOM_ATTRIBUTE).equals(StaticStrings.TRUE_STR)); } /** Determine if this argument is hidden in GLI * @return true if the argument is hidden, false otherwise */ public boolean isHiddenGLI() { return hidden_gli; } /** Method to determine of this argument is required for the associated script to work. * @return true if this argument is required, false otherwise */ public boolean isRequired() { return required; } /** Method to allow for the activation of arguments that might never have their setValue() method called. * @param assigned the desired state as a boolean * @see org.greenstone.gatherer.util.StaticStrings#ASSIGNED_ATTRIBUTE * @see org.greenstone.gatherer.util.StaticStrings#FALSE_STR * @see org.greenstone.gatherer.util.StaticStrings#TRUE_STR */ public void setAssigned(boolean assigned) { if(element != null) { element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, (assigned ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR)); } } /** Sets the value of default_value. * @param default_value The new value for default_value as a String. */ public void setDefaultValue(String default_value) { this.default_value = default_value; } /** Set the value of desc. * @param description the new value of desc as a String */ public void setDescription(String description) { this.description = description; } /** Set the element this argument should be based upon. * @param element the Element */ public void setElement(Element element) { this.element = element; } /** Mark this argument as being hidden in GLI. */ public void setHiddenGLI(boolean hidden) { this.hidden_gli = hidden; } /** Set the upper bound for a range type argument. * @param maximum the maximum as an int */ public void setMaximum(int maximum) { this.maximum = maximum; } /** Set the lower bound for a range type argument. * @param minimum the minimum as an int */ public void setMinimum(int minimum) { this.minimum = minimum; } /** Set the detail mode level where this argument will become available. * @param mode_level the mode level as an int */ public void setModeLevel(int mode_level) { this.mode_level = mode_level; } /** Set the value of name. * @param name the new value of name as a String */ public void setName(String name) { this.name = name; } public void setDisplayName(String name) { this.display_name = name; } /** Sets the value of the options list. * @param list the new options list as a HashMap */ public void setOptions(ArrayList list) { this.option_list = list; } /** Set the owner of this argument. * @param owner the name of the owner of this argument as a String */ public void setOwner(String owner) { this.owner = owner; } /** Set the value of required. * @param required the new value of required as a boolean */ public void setRequired(boolean required) { this.required = required; } /** Set the value of type. * @param type the new value of type as an byte */ public void setType(byte type) { this.type = type; } /** Set the value of type, by matching a type to the given string. * @param new_type a String which contains the name of a certain argument type * @see org.greenstone.gatherer.util.StaticStrings#ENUM_STR * @see org.greenstone.gatherer.util.StaticStrings#FLAG_STR * @see org.greenstone.gatherer.util.StaticStrings#HIERARCHY_STR * @see org.greenstone.gatherer.util.StaticStrings#INT_STR * @see org.greenstone.gatherer.util.StaticStrings#LANGUAGE_STR * @see org.greenstone.gatherer.util.StaticStrings#METADATA_TYPE_STR * @see org.greenstone.gatherer.util.StaticStrings#REGEXP_STR */ public void setType(String new_type) { if(new_type.equalsIgnoreCase(StaticStrings.ENUM_STR)) { this.type = ENUM; option_list = new ArrayList(); } else if(new_type.equalsIgnoreCase(StaticStrings.ENUM_STRING_STR)) { this.type = ENUM_STRING; option_list = new ArrayList(); } else if(new_type.equalsIgnoreCase(StaticStrings.FLAG_STR)) { this.type = FLAG; } else if(new_type.equalsIgnoreCase(StaticStrings.HIERARCHY_STR)) { this.type = HIERARCHY; } else if(new_type.equalsIgnoreCase(StaticStrings.INT_STR)) { this.type = INTEGER; } else if(new_type.equalsIgnoreCase(StaticStrings.LANGUAGE_STR)) { this.type = LANGUAGE; } else if(new_type.equalsIgnoreCase(StaticStrings.METADATA_TYPE_STR)) { this.type = METADATA; } else if(new_type.equalsIgnoreCase(StaticStrings.REGEXP_STR)) { this.type = REGEXP; } else { this.type = STRING; } } /** Method to set the value of this argument. * @param value the new value for the argument * @see org.greenstone.gatherer.Gatherer#println */ public void setValue(String value) { if(element != null) { if (type == METADATA) { value = MetadataTools.convertMetadataElementListNames(value, MetadataTools.FROM_DISPLAY_NAMES); stored_value = value; } XMLTools.setValue(element, value); } else { DebugStream.println("Argument.setValue(" + value + ") called on a base Argument."); } } /** Set the values vector to the given values. Currently I just assign the new values, whereas I may later want to implement a deep clone. * @param values an ArrayList of values * @see org.greenstone.gatherer.Gatherer#println */ public void setValues(ArrayList values) { if(element != null) { StringBuffer value = new StringBuffer(); int value_length = values.size(); for(int i = 0; i < value_length; i++) { value.append(values.get(i)); value.append(StaticStrings.COMMA_CHARACTER); } value.deleteCharAt(value.length() - 1); // Remove last ',' XMLTools.setValue(element, value.toString()); } else { DebugStream.println("Argument.setValues([" + values.size() + " items]) called on a base Argument."); } } /** Method for translating the data of this class into a string. * @return a String containing a fragment of the total arguments string * @see org.greenstone.gatherer.Gatherer#c_man * @see org.greenstone.gatherer.collection.CollectionManager#getCollection * @see org.greenstone.gatherer.util.StaticStrings#COMMA_CHARACTER * @see org.greenstone.gatherer.util.StaticStrings#NAME_ATTRIBUTE * @see org.greenstone.gatherer.util.StaticStrings#SPACE_CHARACTER * @see org.greenstone.gatherer.util.StaticStrings#SPEECH_CHARACTER */ public String toString() { StringBuffer text = new StringBuffer("-"); if (element == null) { return text.toString(); } if (name == null) { name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE); } text.append(name); // getValue returns display name for metadata args String value = getValue(); if (value.length() == 0) { return text.toString(); } text.append(StaticStrings.SPACE_CHARACTER); // If the value contains a space, add speech marks // (Except for metadata elements, which won't have spaces when written out to collect.cfg) if (value.indexOf(StaticStrings.SPACE_CHARACTER) != -1 && type != METADATA) { value = StaticStrings.SPEECH_CHARACTER + value + StaticStrings.SPEECH_CHARACTER; } text.append(value); return text.toString(); } /** parse the