source: trunk/gli/src/org/greenstone/gatherer/cdm/Argument.java@ 10250

Last change on this file since 10250 was 9126, checked in by kjdon, 19 years ago

moved the argument details xml parsing code to Argument.parseXML - the same code was duplicated in BuildOptions, PluginManager, ClassifierManager

  • Property svn:keywords set to Author Date Id Revision
File size: 21.2 KB
RevLine 
[4838]1/**
2 *#########################################################################
3 *
[6389]4 * A component of the Greenstone Librarian Interface (GLI) application,
5 * part of the Greenstone digital library software suite from the New
6 * Zealand Digital Library Project at the University of Waikato,
7 * New Zealand.
[4838]8 *
[6389]9 * Author: John Thompson
10 * Greenstone Project, New Zealand Digital Library
11 * University of Waikato
12 * http://www.nzdl.org
[4838]13 *
[6389]14 * Copyright (C) 2004 New Zealand Digital Library, University of Waikato
[4838]15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *########################################################################
30 */
[6389]31
[4932]32package org.greenstone.gatherer.cdm;
[4838]33
[4932]34import java.io.*;
35import java.util.*;
[6389]36import org.greenstone.gatherer.Configuration;
[8236]37import org.greenstone.gatherer.DebugStream;
[4932]38import org.greenstone.gatherer.Gatherer;
39import org.greenstone.gatherer.collection.Collection;
40import org.greenstone.gatherer.collection.CollectionManager;
[8313]41import org.greenstone.gatherer.metadata.MetadataElement;
42import org.greenstone.gatherer.metadata.MetadataTools;
[4932]43import org.greenstone.gatherer.util.StaticStrings;
[4838]44import org.greenstone.gatherer.util.Utility;
[8015]45import org.greenstone.gatherer.util.XMLTools;
[4932]46import org.w3c.dom.*;
47
[4838]48/** 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.
[6389]49 * @author John Thompson, Greenstone Project, New Zealand Digital Library, University of Waikato
50 * @version 2.41 final
[4838]51 */
52public class Argument
53 implements Comparable, Serializable {
[6389]54 /** An element of the argument type enumeration specifying a combobox control. */
[4838]55 static final public byte ENUM = 0;
[6389]56 /** An element of the argument type enumeration specifying a checkbox control. */
[4838]57 static final public byte FLAG = 1;
[6389]58 /** An element of the argument type enumeration specifying a tree control. */
[4838]59 static final public byte HIERARCHY = 2;
[6389]60 /** An element of the argument type enumeration specifying a spinner control. */
[4838]61 static final public byte INTEGER = 3;
[6389]62 /** An element of the argument type enumeration specifying a language combobox control. */
[4838]63 static final public byte LANGUAGE = 4;
[6389]64 /** An element of the argument type enumeration specifying a list control. */
[4838]65 static final public byte METADATA = 5;
[6389]66 /** An element of the argument type enumeration specifying a metadata combobox control. */
[4838]67 static final public byte METADATUM = 6;
[6389]68 /** An element of the argument type enumeration specifying a text field. */
[4838]69 static final public byte STRING = 7;
[6389]70 /** An element of the argument type enumeration specifying a regular expression text field. */
71 static final public byte REGEXP = 8;
72 /** true if this argument should actually be hidden within the GLI. This is iportant for arguments such as import dir or other location critical arguments. */
73 private boolean hidden_gli = false;
[4932]74 /** <i>true</i> if this argument is required for the applicable script to work properly, <i>false</i> otherwise. */
75 private boolean required = false;
[6389]76 /** The type of this argument. Used to be an int, but bytes are cheaper. */
[4932]77 private byte type = STRING;
[6087]78 /** The maximum value an integer based control can have. */
79 private int maximum = Integer.MAX_VALUE;
80 /** The minimum value an integer based control can have. */
81 private int minimum = Integer.MIN_VALUE;
[6389]82 /** Every argument has a detail mode level at which it becomes available to the user to edit.
83 * @see org.greenstone.gatherer.Configuration
84 */
85 private int mode_level = Configuration.LIBRARIAN_MODE;
86 /** The DOM element this argument is built around, if any. */
[4932]87 private Element element;
88 /** If the argument is of type ENUM then this map holds all the various options. Each entry is an &lt;option value&gt; -&gt; &lt;description&gt; mapping. */
89 private HashMap list = null;
90 /** A default value for parameter-type arguments. May be a Perl pattern. */
91 private String default_value = null;
92 /** The text description of this argument parsed from the pluginfo output. */
93 private String description = null;
94 /** The argument flag as it appears in the command. Also used as the unique identifier of an argument. */
95 private String name = null;
96 /** The plugin that owns this argument, for the purposes of visualising inheritance. */
97 private String owner = null;
98
[4838]99 /** Default Constructor. */
100 public Argument() {
101 }
[4932]102
[6389]103 /** Another constructor but this one is a little more interesting as it takes a DOM element.
104 * @param element the Element this argument is based around
105 */
[4932]106 public Argument(Element element) {
107 this.element = element;
[4838]108 }
[4932]109
[4838]110 /** Method to add an element to the option list.
[6389]111 * @param name the name value of the option as a String
112 * @param desc the description of this options as a String
[4932]113 */
[4838]114 public void addOption(String name, String desc) {
115 if(type == ENUM && name != null) {
116 if(desc == null) {
117 desc = "";
118 }
[4932]119 if(list == null) {
120 list = new HashMap();
[4838]121 }
[4932]122 list.put(name, desc);
[4838]123 }
124 }
[4932]125
[4838]126 /** Method to compare two arguments for ordering.
[6389]127 * @param object the argument we are comparing to, as an Object
128 * @return an int specifying the argument order, using values as set out in String
[4932]129 * @see org.greenstone.gatherer.cdm.Argument
130 */
[4838]131 public int compareTo(Object object) {
[4932]132 if(object instanceof Argument) {
133 return getName().compareTo(((Argument)object).getName());
134 }
135 else {
136 return toString().compareTo(object.toString());
137 }
[4838]138 }
[4932]139
[6389]140 /** Create a copy of this argument.
141 * @return a newly created Argument with the same details as this one
142 */
[4838]143 public Argument copy() {
[4932]144 Argument copy = new Argument();
145 copy.setDefaultValue(default_value);
146 copy.setDescription(description);
147 copy.setOptions(list);
148 copy.setOwner(owner);
149 copy.setName(name);
[4838]150 copy.setRequired(required);
[4932]151 copy.setType(type);
[7108]152 copy.setMinimum(minimum);
153 copy.setMaximum(maximum);
154 copy.setModeLevel(mode_level);
[4838]155 return copy;
156 }
[4932]157
[4838]158 /** Method to determine if two arguments are equal.
[6389]159 * @param object the argument to test against, as an Object
160 * @return true if the arguments names match, false otherwise
[4932]161 */
[4838]162 public boolean equals(Object object) {
163 return (compareTo(object) == 0);
164 }
[4932]165
[4838]166 /** Method to retrieve the value of default_value.
[6389]167 * @return a String containing the default value
[4932]168 */
[4838]169 public String getDefaultValue() {
170 return default_value;
171 }
[4932]172
[4838]173 /** Method to retrieve this arguments description.
[6389]174 * @return a String containing the description
[4932]175 */
176 public String getDescription() {
177 return description;
[4838]178 }
[4932]179
[4838]180 /** Method to retrieve the description of a certain list option value.
[6389]181 * @param key the String whose description we are searching for
182 * @return the description of the desired key as a String which may be empty if no such key exists
[4932]183 */
184 public String getDescription(String key) {
[4838]185 if(list.containsKey(key)) {
186 return (String)list.get(key);
187 }
188 return "";
189 }
[4932]190
[6389]191 /** Retrieve the upper bound of a range based argument.
192 * @return the maximum as an int
193 */
[6087]194 public int getMaximum() {
195 return maximum;
196 }
197
[6389]198 /** Retrieve the lower bound of a range based argument.
199 * @return the minimum as an int
200 */
[6087]201 public int getMinimum() {
202 return minimum;
203 }
204
[6389]205 /** Retrieves the mode level at which this argument should become available. Any higher levels should also see this argument.
206 * @return the mode level as an int
[4932]207 */
[6389]208 public int getModeLevel() {
209 return mode_level;
[4838]210 }
[4932]211
[4838]212 /** Method to retrieve the value of name.
[6389]213 * @return a String containing the argument name
214 * @see org.greenstone.gatherer.util.StaticStrings#NAME_ATTRIBUTE
[4932]215 */
[4838]216 public String getName() {
[4932]217 if(name == null && element != null) {
218 name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
219 }
[4838]220 return name;
221 }
[4932]222
[6389]223 /** Method to retrieve the option list for this argument.
224 * @return a HashMap containing &lt;option value&gt; -&gt; &lt;description&gt; entries
225 */
226 public HashMap getOptions() {
227 return list;
228 }
229
[4838]230 /** Retrieve the name of the owner of this argument.
[6389]231 * @return the owners name as a String
[4932]232 */
[4838]233 public String getOwner() {
234 return owner;
235 }
[4932]236
[4838]237 /** Method to determine the type of this argument.
[6389]238 * @return a byte specifying the type
[4932]239 */
[4838]240 public byte getType() {
241 return type;
242 }
[4932]243
[4838]244 /** Method to retrieve the value of value.
[6389]245 * @return the value of value as a String
246 * @see org.greenstone.gatherer.Gatherer#c_man
247 * @see org.greenstone.gatherer.collection.CollectionManager#getCollection
[4932]248 */
[8313]249 public String getValue()
250 {
251 // Only assigned arguments have values.
252 if (element == null) {
253 return null;
[4838]254 }
[4932]255
[8313]256 return XMLTools.getValue(element);
[4838]257 }
[4932]258
[8313]259
[4838]260 /** Method to determine if this argument has been assigned.
[6389]261 * @return true if it has, false otherwise
262 * @see org.greenstone.gatherer.util.StaticStrings#ASSIGNED_ATTRIBUTE
263 * @see org.greenstone.gatherer.util.StaticStrings#TRUE_STR
[4932]264 */
[4838]265 public boolean isAssigned() {
[4932]266 return (element != null && element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.TRUE_STR));
[4838]267 }
[4932]268
[6389]269 /** 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.
270 * @return true if this argument is a custom, false otherwise
271 * @see org.greenstone.gatherer.util.StaticStrings#CUSTOM_ATTRIBUTE
272 * @see org.greenstone.gatherer.util.StaticStrings#TRUE_STR
273 */
[4932]274 public boolean isCustomArgument() {
275 return (element != null && element.getAttribute(StaticStrings.CUSTOM_ATTRIBUTE).equals(StaticStrings.TRUE_STR));
276 }
277
[6389]278 /** Determine if this argument is hidden in GLI
279 * @return true if the argument is hidden, false otherwise
280 */
281 public boolean isHiddenGLI() {
282 return hidden_gli;
283 }
284
[4838]285 /** Method to determine of this argument is required for the associated script to work.
[6389]286 * @return true if this argument is required, false otherwise
[4932]287 */
[4838]288 public boolean isRequired() {
289 return required;
290 }
[4932]291
[4838]292 /** Method to allow for the activation of arguments that might never have their setValue() method called.
[4932]293 * @param assigned the desired state as a boolean
[6389]294 * @see org.greenstone.gatherer.util.StaticStrings#ASSIGNED_ATTRIBUTE
295 * @see org.greenstone.gatherer.util.StaticStrings#FALSE_STR
296 * @see org.greenstone.gatherer.util.StaticStrings#TRUE_STR
[4932]297 */
298 public void setAssigned(boolean assigned) {
299 if(element != null) {
300 element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, (assigned ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR));
[4838]301 }
[4932]302 }
303
[6389]304 /** Set the custom argument flag.
305 * @param custom true to make this argument custom, false otherwise
306 * @see org.greenstone.gatherer.util.StaticStrings#CUSTOM_ATTRIBUTE
307 * @see org.greenstone.gatherer.util.StaticStrings#FALSE_STR
308 * @see org.greenstone.gatherer.util.StaticStrings#TRUE_STR
309 */
[4932]310 public void setCustomArgument(boolean custom) {
311 if(element != null) {
312 element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, (custom ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR));
[4838]313 }
314 }
[4932]315
[4838]316 /** Sets the value of default_value.
[4932]317 * @param default_value The new value for default_value as a <strong>String</strong>.
318 */
319 public void setDefaultValue(String default_value) {
320 this.default_value = default_value;
[4838]321 }
[4932]322
[4838]323 /** Set the value of desc.
[6389]324 * @param description the new value of desc as a String
[4932]325 */
326 public void setDescription(String description) {
327 this.description = description;
[4838]328 }
329
[6389]330 /** Set the element this argument should be based upon.
331 * @param element the Element
332 */
[4932]333 public void setElement(Element element) {
[4838]334 this.element = element;
335 }
336
[6389]337 /** Mark this argument as being hidden in GLI. */
338 public void setHiddenGLI() {
339 hidden_gli = true;
340 }
341
342 /** Set the upper bound for a range type argument.
343 * @param maximum the maximum as an int
344 */
[6087]345 public void setMaximum(int maximum) {
346 this.maximum = maximum;
347 }
348
[6389]349 /** Set the lower bound for a range type argument.
350 * @param minimum the minimum as an int
351 */
[6087]352 public void setMinimum(int minimum) {
353 this.minimum = minimum;
354 }
355
[6389]356 /** Set the detail mode level where this argument will become available.
357 * @param mode_level the mode level as an int
358 */
359 public void setModeLevel(int mode_level) {
360 this.mode_level = mode_level;
361 }
362
[4838]363 /** Set the value of name.
[6389]364 * @param name the new value of name as a String
[4932]365 */
366 public void setName(String name) {
367 this.name = name;
[4838]368 }
[4932]369
[4838]370 /** Sets the value of the options list.
[6389]371 * @param list the new options list as a HashMap
[4932]372 */
373 public void setOptions(HashMap list) {
374 this.list = list;
[4838]375 }
[4932]376
[4838]377 /** Set the owner of this argument.
[6389]378 * @param owner the name of the owner of this argument as a String
[4932]379 */
[4838]380 public void setOwner(String owner) {
381 this.owner = owner;
382 }
[4932]383
[4838]384 /** Set the value of required.
[6389]385 * @param required the new value of required as a boolean
[4932]386 */
387 public void setRequired(boolean required) {
388 this.required = required;
[4838]389 }
[4932]390
[4838]391 /** Set the value of type.
[6389]392 * @param type the new value of type as an byte
[4932]393 */
394 public void setType(byte type) {
395 this.type = type;
[4838]396 }
[4932]397
[4838]398 /** Set the value of type, by matching a type to the given string.
[6389]399 * @param new_type a String which contains the name of a certain argument type
400 * @see org.greenstone.gatherer.util.StaticStrings#ENUM_STR
401 * @see org.greenstone.gatherer.util.StaticStrings#FLAG_STR
402 * @see org.greenstone.gatherer.util.StaticStrings#HIERARCHY_STR
403 * @see org.greenstone.gatherer.util.StaticStrings#INT_STR
404 * @see org.greenstone.gatherer.util.StaticStrings#LANGUAGE_STR
405 * @see org.greenstone.gatherer.util.StaticStrings#METADATA_TYPE_STR
406 * @see org.greenstone.gatherer.util.StaticStrings#METADATUM_TYPE_STR
407 * @see org.greenstone.gatherer.util.StaticStrings#REGEXP_STR
[4932]408 */
[4838]409 public void setType(String new_type) {
[4932]410 if(new_type.equalsIgnoreCase(StaticStrings.ENUM_STR)) {
[4838]411 this.type = ENUM;
412 list = new HashMap();
413 }
[4932]414 else if(new_type.equalsIgnoreCase(StaticStrings.FLAG_STR)) {
[4838]415 this.type = FLAG;
416 }
[4932]417 else if(new_type.equalsIgnoreCase(StaticStrings.HIERARCHY_STR)) {
[4838]418 this.type = HIERARCHY;
419 }
[4932]420 else if(new_type.equalsIgnoreCase(StaticStrings.INT_STR)) {
[4838]421 this.type = INTEGER;
422 }
[4932]423 else if(new_type.equalsIgnoreCase(StaticStrings.LANGUAGE_STR)) {
[4838]424 this.type = LANGUAGE;
425 }
[4932]426 else if(new_type.equalsIgnoreCase(StaticStrings.METADATA_TYPE_STR)) {
[4838]427 this.type = METADATA;
428 }
[4932]429 else if(new_type.equalsIgnoreCase(StaticStrings.METADATUM_TYPE_STR)) {
[4838]430 this.type = METADATUM;
431 }
[6389]432 else if(new_type.equalsIgnoreCase(StaticStrings.REGEXP_STR)) {
433 this.type = REGEXP;
434 }
[4932]435 else {
[4838]436 this.type = STRING;
437 }
438 }
[6389]439
[4932]440 /** Method to set the value of this argument.
[6389]441 * @param value the new value for the argument
442 * @see org.greenstone.gatherer.Gatherer#println
[4932]443 */
444 public void setValue(String value) {
445 if(element != null) {
[8015]446 XMLTools.setValue(element, value);
[4932]447 }
448 else {
[8236]449 DebugStream.println("Argument.setValue(" + value + ") called on a base Argument.");
[4932]450 }
451 }
[4838]452
453 /** 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.
[4932]454 * @param values an ArrayList of values
[6389]455 * @see org.greenstone.gatherer.Gatherer#println
[4932]456 */
457 public void setValues(ArrayList values) {
458 if(element != null) {
459 StringBuffer value = new StringBuffer();
460 int value_length = values.size();
461 for(int i = 0; i < value_length; i++) {
462 value.append(values.get(i));
463 value.append(StaticStrings.COMMA_CHARACTER);
[4838]464 }
[4932]465 value.deleteCharAt(value.length() - 1); // Remove last ','
[8015]466 XMLTools.setValue(element, value.toString());
[4838]467 }
[4932]468 else {
[8236]469 DebugStream.println("Argument.setValues([" + values.size() + " items]) called on a base Argument.");
[4932]470 }
[4838]471 }
472
[4932]473 /** Method for translating the data of this class into a string.
474 * @return a String containing a fragment of the total arguments string
[6389]475 * @see org.greenstone.gatherer.Gatherer#c_man
476 * @see org.greenstone.gatherer.collection.CollectionManager#getCollection
477 * @see org.greenstone.gatherer.util.StaticStrings#COMMA_CHARACTER
478 * @see org.greenstone.gatherer.util.StaticStrings#NAME_ATTRIBUTE
479 * @see org.greenstone.gatherer.util.StaticStrings#SPACE_CHARACTER
480 * @see org.greenstone.gatherer.util.StaticStrings#SPEECH_CHARACTER
[4932]481 */
[8313]482 public String toString()
483 {
[4932]484 StringBuffer text = new StringBuffer("-");
[8313]485
486 if (element == null) {
487 return text.toString();
[4838]488 }
[8313]489
490 if (name == null) {
491 name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
492 }
493 text.append(name);
494
495 String value = XMLTools.getValue(element);
496 if (value.length() == 0) {
497 return text.toString();
498 }
499
500 text.append(StaticStrings.SPACE_CHARACTER);
501
502// // Handle metadata elements specially
503// if (type == METADATA || type == METADATUM) {
504// // Tokenize the string
505// StringTokenizer tokenizer = new StringTokenizer(value, ",");
506// while (tokenizer.hasMoreTokens()) {
507// String token = tokenizer.nextToken();
508
509// MetadataElement metadata_element = MetadataTools.getMetadataElementWithDisplayName(token);
510// if (metadata_element != null) {
511// text.append(metadata_element.getFullName());
512// }
513// else {
514// text.append(token);
515// }
516
517// if (tokenizer.hasMoreTokens()) {
518// text.append(StaticStrings.COMMA_CHARACTER);
519// }
520// }
521// return text.toString();
522// }
523
524 // If the value contains a space, add speech marks
525 // (Except for metadata elements, which won't have spaces when written out to collect.cfg)
526 if (value.indexOf(StaticStrings.SPACE_CHARACTER) != -1 && !(type == METADATUM || type == METADATA)) {
527 value = StaticStrings.SPEECH_CHARACTER + value + StaticStrings.SPEECH_CHARACTER;
528 }
529
530 text.append(value);
[4932]531 return text.toString();
[9126]532 }
533
534 /** parse the <Option> XML from eg import.pl -xml or pluginfo.pl -xml */
535 public void parseXML(Element option) {
536
537 for(Node node = option.getFirstChild(); node != null; node = node.getNextSibling()) {
538 String node_name = node.getNodeName();
539 if(node_name.equals("Name")) {
540 setName(XMLTools.getValue(node));
541 }
542 else if(node_name.equals("Desc")) {
543 setDescription(XMLTools.getValue(node));
544 }
545 else if(node_name.equals("Type")) {
546 setType(XMLTools.getValue(node));
547 }
548 else if(node_name.equals("Default")) {
549 setDefaultValue(XMLTools.getValue(node));
550 }
551 else if(node_name.equals("Required")) {
552 String v = XMLTools.getValue(node);
553 if(v != null && v.equals("yes")) {
554 setRequired(true);
555 }
556 }
557 else if(node_name.equals("List")) {
558 // Two final loops are required to parse lists.
559 for(Node value = node.getFirstChild(); value != null; value = value.getNextSibling()) {
560 if(value.getNodeName().equals("Value")) {
561 String key = null;
562 String desc = "";
563 for(Node subvalue = value.getFirstChild(); subvalue != null; subvalue = subvalue.getNextSibling()) {
564 node_name = subvalue.getNodeName();
565 if(node_name.equals("Name")) {
566 key = XMLTools.getValue(subvalue);
567 }
568 else if(node_name.equals("Desc")) {
569 desc = XMLTools.getValue(subvalue);
570 }
571 }
572 if(key != null) {
573 addOption(key, desc);
574 }
575 }
576 }
577 }
578 else if(node_name.equals("Range")) {
579 String range_raw = XMLTools.getValue(node);
580 int index = -1;
581 if((index = range_raw.indexOf(StaticStrings.COMMA_CHARACTER)) != -1) {
582 if(index > 0) {
583 try {
584 String first_number = range_raw.substring(0, index);
585 setMinimum(Integer.parseInt(first_number));
586 first_number = null;
587 }
588 catch(Exception exception) {
589 }
590 }
591
592 if(index + 1 < range_raw.length()) {
593 try {
594 String second_number = range_raw.substring(index + 1);
595 setMaximum(Integer.parseInt(second_number));
596 second_number = null;
597 }
598 catch(Exception exception) {
599 }
600 }
601 }
602 // Else it wasn't a valid range anyway, so ignore it
603 }
604 else if(node_name.equals("HiddenGLI")) {
605 setHiddenGLI();
606 }
607 else if(node_name.equals("ModeGLI")) {
608 String mode_level_str = XMLTools.getValue(node);
609 try {
610 int mode_level = Integer.parseInt(mode_level_str);
611 setModeLevel(mode_level);
612 }
613 catch(Exception exception) {
614 DebugStream.println("Exception in Argument.parseXML() - Unexpected but non-fatal");
615 DebugStream.printStackTrace(exception);
616 }
617 }
618
619 } // for each option
620
621 } // parseXML
[4838]622}
Note: See TracBrowser for help on using the repository browser.