- Timestamp:
- 2003-07-15T13:55:22+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/cdm/Classifier.java
r4838 r4932 6 6 * University of Waikato, New Zealand. 7 7 * 8 * <BR><BR>9 *10 8 * Author: John Thompson, Greenstone Digital Library, University of Waikato 11 9 * 12 * <BR><BR>13 *14 10 * Copyright (C) 1999 New Zealand Digital Library Project 15 *16 * <BR><BR>17 11 * 18 12 * This program is free software; you can redistribute it and/or modify … … 21 15 * (at your option) any later version. 22 16 * 23 * <BR><BR>24 *25 17 * This program is distributed in the hope that it will be useful, 26 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 20 * GNU General Public License for more details. 29 *30 * <BR><BR>31 21 * 32 22 * You should have received a copy of the GNU General Public License … … 35 25 *######################################################################## 36 26 */ 37 38 39 40 41 42 43 /* GPL_HEADER */44 27 package org.greenstone.gatherer.cdm; 45 28 /************************************************************************************** 46 * Title: Gatherer47 * Description: The Gatherer: a tool for gathering and enriching a digital collection.48 * Company: The University of Waikato49 29 * Written: 01/05/02 50 30 * Revised: 16/08/02 Optimized and Commented. 31 * 11/07/03 DOM support 51 32 **************************************************************************************/ 52 import java.io. Serializable;53 import java.util. ArrayList;33 import java.io.*; 34 import java.util.*; 54 35 import org.greenstone.gatherer.cdm.Argument; 55 36 import org.greenstone.gatherer.cdm.ArgumentContainer; 56 import org.greenstone.gatherer.cdm.CustomClassifier; 57 import org.greenstone.gatherer.cdm.Format; 37 import org.greenstone.gatherer.cdm.CollectionConfiguration; 38 import org.greenstone.gatherer.cdm.CollectionDesignManager; 39 import org.greenstone.gatherer.cdm.DOMProxyListEntry; 40 import org.greenstone.gatherer.util.StaticStrings; 41 import org.greenstone.gatherer.util.Utility; 42 import org.w3c.dom.*; 58 43 /** This class is responsible for storing information from a parsed classinfo.pl call in such a way that it allows easy access to parsed details for the purposes of user design and specification of classifiers. 59 44 * @author John Thompson, Greenstone Digital Library, University of Waikato 60 45 * @version 2.3 61 46 */ 62 // ####################################################################################63 // Optimization Saving64 // ####################################################################################65 // Vector -> ArrayList (x8) + Processor66 // ####################################################################################67 47 public class Classifier 68 48 extends ArrayList 69 implements ArgumentContainer, Comparable, Serializable { 49 implements ArgumentContainer, Comparable, DOMProxyListEntry, Serializable { 50 51 static final public String CLASSIFIER_PREFIX = "CL"; 52 70 53 /** A reference to the classifier that this one inherits from. */ 71 54 private Classifier super_classifier = null; 72 /** A reference to the manager of this classifier. Only available once the classifiers been assigned, always <i>null</i> for classifiers in reserve. */ 73 private ClassifierManager manager = null; 74 /** Custom arguments (ie those unparsable from classinfo.pl) provided to this class. */ 75 private String custom = null; 55 /** The element this classifier is based upon. */ 56 private Element element; 76 57 /** A description of this classifier. */ 77 private String desc = null;58 private String description = null; 78 59 /** The name of the classifier as it would appear in the collect.cfg file. */ 79 60 private String name = null; 80 /** A list of format commands that are dependant on this classifier. */ 81 private ArrayList dependant_formats = null; 82 /** Default Constructor. 61 /** This string is filled out the first time this classifier is created, and remains unchanged there-after. It is used to match up with Format commands that may not yet have been instantiated (and thus only have offline references along the lines of 'CL1' to figure out what Classifier they want.) */ 62 private String old_position_string = null; 63 64 /** Constructor used only in DOMProxyListModel initializations. 83 65 */ 84 66 public Classifier() { 67 } 68 69 public Classifier(Element element, Classifier base_classifier) { 85 70 super(); 86 dependant_formats = new ArrayList(); 87 } 71 this.element = element; 72 this.name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 73 ///atherer.println("Establishing Classifier: " + name); 74 // Parse in any argument options for this classifier, keeping a list of the ones found 75 HashMap known_arguments = new HashMap(); 76 NodeList option_elements = element.getElementsByTagName(StaticStrings.OPTION_ELEMENT); 77 int option_elements_length = option_elements.getLength(); 78 for(int i = 0; i < option_elements_length; i++) { 79 Element option_element = (Element) option_elements.item(i); 80 Argument argument = new Argument(option_element); 81 ///atherer.println("Rebuilding existing argument: " + argument.getName()); 82 argument.setOwner(name); 83 add(argument); 84 known_arguments.put(argument.getName(), argument); 85 } 86 // If a base classifier was given 87 if(base_classifier != null) { 88 // Copy the details, and add a reference to whatever base_classifiers super classifier is. 89 description = base_classifier.getDescription(); 90 // Now search through the 'dummy' arguments belonging to the base classifier. For each found, if it is already assigned, fill out further details such as type. If any are found that are not already assigned for this classifier, copy them and add them, but without a value. 91 ArrayList all_arguments = base_classifier.getArguments(true, true); 92 int argument_count = all_arguments.size(); 93 for(int j = 0; j < argument_count; j++) { 94 Argument base_argument = (Argument) all_arguments.get(j); 95 String base_argument_name = base_argument.getName(); 96 ///atherer.println("Library indicates this classifier should have an argument: " + base_argument_name); 97 Argument existing_argument = (Argument) known_arguments.get(base_argument_name); 98 // Found an existing argument. Complete its details 99 if(existing_argument != null) { 100 ///atherer.println("Found existing argument. Filling out details."); 101 existing_argument.setCustomArgument(false); 102 existing_argument.setDefaultValue(base_argument.getDefaultValue()); 103 existing_argument.setDescription(base_argument.getDescription()); 104 existing_argument.setOptions(base_argument.getOptions()); 105 existing_argument.setRequired(base_argument.isRequired()); 106 existing_argument.setType(base_argument.getType()); 107 } 108 // No existing argument. Copy base_argument and add it, but do not set its assigned flag. That should be set the first time its changed by the user. 109 else { 110 ///atherer.println("No such argument. Adding new, unassigned, argument."); 111 // The trick thing is that we have to create a new element in the DOM as well. 112 Argument new_argument = base_argument.copy(); 113 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT); 114 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, base_argument_name); 115 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 116 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.FALSE_STR); 117 new_argument.setElement(argument_element); 118 // All done. Add it. 119 element.appendChild(argument_element); 120 add(new_argument); 121 } 122 } 123 } 124 old_position_string = getPositionString(); 125 } 126 88 127 /** Constructor. 89 128 * @param name The name of this classifier as a <strong>String</strong>. … … 91 130 * @param super_classifier The super class of this classifier, as a <strong>Classifier</strong>. 92 131 */ 93 public Classifier(String name, String desc , Classifier super_classifier) {94 this();95 this.desc = desc;132 public Classifier(String name, String description, Classifier super_classifier) { 133 super(); 134 this.description = description; 96 135 this.name = name; 97 136 this.super_classifier = super_classifier; 98 137 } 138 99 139 /** Method to add an argument to this classifier. Only adds the argument if it isn't already present. 100 140 * @param argument The <strong>Argument</strong> to add. 101 141 */ 102 142 public void addArgument(Argument argument) { 103 if( !contains(argument)) {143 if(element == null && !contains(argument)) { 104 144 add(argument); 105 145 argument.setOwner(name); 106 146 } 107 147 } 108 /** Method to register a dependant format with this classifier. If the classifier changes, this format also needs to be updated. 109 * @param format A <strong>Format</strong> which is dependant on this classifier. 110 */ 111 public void addDependantFormat(Format format) { 112 dependant_formats.add(format); 113 } 148 114 149 /** Method to compare two classifiers for ordering. 115 150 * @param object The classifier we are comparing to, as an <strong>Object</strong>. … … 118 153 */ 119 154 public int compareTo(Object object) { 120 if(object instanceof Classifier) { 121 Classifier classifier = (Classifier) object; 122 return name.compareTo(classifier.getName()); 123 } 124 return name.compareTo(object.toString()); 125 } 126 /** This method produces a deep copy of this classifier. Note that this also creates a new copy of each of the super classes of classifiers as well. This is the way it should be, as each assigned classifier may have different values for the higher classifiers (such as BasPlug). 127 * @return A newly created <strong>Classifier</strong> with the same details and Arguments as this one. 128 * @see org.greenstone.gatherer.cdm.Argument 129 */ 130 public Classifier copy() { 131 Classifier copy = null; 132 if(super_classifier == null) { 133 copy = new Classifier(name, desc, null); 134 } 135 else { 136 copy = new Classifier(name, desc, super_classifier.copy()); 137 } 138 for(int i = 0; i < size(); i++) { 139 copy.addArgument(((Argument)get(i)).copy()); 140 } 141 return copy; 142 } 155 if(object == null) { 156 return -1; 157 } 158 return toString().compareTo(object.toString()); 159 } 160 161 /** The assigned classifier constructor. 162 * @param element the DOM Element this classifier is based upon 163 * @param base_classifier the Classifier from the stored library showing details about this classifier, may be null 164 */ 165 public DOMProxyListEntry create(Element element) { 166 String classifier_name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 167 // Determine the base classifier from the classifier name 168 Classifier base_classifier = CollectionDesignManager.classifier_manager.getBaseClassifier(classifier_name); 169 Classifier classifier = new Classifier(element, base_classifier); 170 base_classifier = null; 171 classifier_name = null; 172 return classifier; 173 } 174 143 175 /** Method to determine if two classifiers are equal. 144 145 146 147 176 * @param object The classifier to test against, as an <strong>Object</strong>. 177 * @return <i>true</i> if the classifier names match, <i>false</i> otherwise. 178 * @see org.greenstone.gatherer.cdm.CustomClassifier 179 */ 148 180 public boolean equals(Object object) { 149 if(object instanceof CustomClassifier) { 150 CustomClassifier classifier = (CustomClassifier) object; 151 return (toString().equalsIgnoreCase(classifier.getCommand())); 152 } 153 else { 154 return(toString().equalsIgnoreCase(object.toString())); 155 } 156 } 181 return (compareTo(object) == 0); 182 } 183 157 184 /** Method to retrieve an argument by its name. 158 159 160 185 * @param name The name of the argument as a <strong>String</strong>. 186 * @return The <strong>Argument</strong> requested, or <i>null</i> if no such argument. 187 */ 161 188 public Argument getArgument(String name) { 162 189 // The name given may still include the '-' … … 164 191 name = name.substring(1); 165 192 } 166 ArrayList arguments = getArguments( );193 ArrayList arguments = getArguments(true, true); 167 194 for(int i = 0; i < arguments.size(); i++) { 168 195 Argument argument = (Argument)arguments.get(i); … … 173 200 return null; 174 201 } 175 /** Method to retrieve all of the arguments available to a classifier, including both specific and general ones. 176 * @return A <strong>Hashtable</strong> of arguments, with <name> -> <argument> entries. 177 */ 178 public ArrayList getArguments() { 179 ArrayList all_arguments = new ArrayList(this); 202 203 /** Retrieve all of the arguments available to this base classifier, including its super classifiers arguments. Some complexity is added by allowing the caller to choose whether they want normal arguments, custom arguments, or both. 204 * @return an ArrayList of all of the arguments, starting with those for this classifier and ending with the arguments for basplug or similiar root classifier 205 */ 206 public ArrayList getArguments(boolean include_normal, boolean include_custom) { 207 ArrayList arguments = new ArrayList(); 208 if(include_normal && include_custom) { 209 arguments.addAll(this); 210 } 211 else { 212 int size = size(); 213 for(int i = 0; i < size; i++) { 214 Argument argument = (Argument) get(i); 215 if(argument.isCustomArgument()) { 216 if(include_custom && !arguments.contains(argument)) { 217 arguments.add(argument); 218 } 219 } 220 else { 221 if(include_normal && !arguments.contains(argument)) { 222 arguments.add(argument); 223 } 224 } 225 argument = null; 226 } 227 } 180 228 if(super_classifier != null) { 181 ArrayList super_arguments = super_classifier.getArguments(); 182 for(int i = 0; i < super_arguments.size(); i++) { 183 Object argument = super_arguments.get(i); 184 if(!all_arguments.contains(argument)) { 185 all_arguments.add(argument); 186 } 187 } 188 } 189 return all_arguments; 190 } 191 /** Method to retrieve a classifiers custom argument information. 192 * @return The custom arguments as a <strong>String</strong>. 193 */ 229 ArrayList remainder = super_classifier.getArguments(include_normal, include_custom); 230 remainder.removeAll(arguments); 231 arguments.addAll(remainder); 232 } 233 return arguments; 234 } 235 236 /** Method to retrieve a classifiers custom argument information. Custom arguments are defined to be those that have not got matching arguments in the base reference classifier from the library. Of course if there is no base classifier then all arguments are considered to be custom. 237 * @return the custom arguments as a String 238 */ 194 239 public String getCustom() { 195 return custom; 196 } 240 StringBuffer custom_text = new StringBuffer(); 241 // Retrieve all of the arguments, and append any that are custom into one long string 242 ArrayList arguments = getArguments(false, true); 243 int arguments_size = arguments.size(); 244 boolean first = true; 245 for(int i = 0; i < arguments_size; i++) { 246 Argument argument = (Argument) arguments.get(i); 247 if(argument.isAssigned()) { 248 if(!first) { 249 custom_text.append(" "); 250 } 251 custom_text.append(argument.toString()); 252 first = false; 253 } 254 } 255 return custom_text.toString(); 256 } 257 258 public String getDescription() { 259 return description; 260 } 261 262 public Element getElement() { 263 return element; 264 } 265 197 266 /** Method to retrieve a classifiers name. 198 199 267 * @return A <strong>String</strong> containing the classifiers name. 268 */ 200 269 public String getName() { 270 if(name == null && element != null) { 271 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 272 } 201 273 return name; 202 274 } 203 /** Method to retrieve the position of this classifier as a special keyword or the form "CL#" where # is the classifiers order in the set of classifiers. Note that if this is called for a Classifier that has never been assigned a position of 'Search' is returned, as this is the only case where we will try to write a Classifier that does not have a manager. 204 * @return A <strong>String</strong> containing the special position keyword. 205 * @see org.greenstone.gatherer.cdm.ClassifierManager 206 */ 275 276 public String getOldPositionString() { 277 return old_position_string; 278 } 279 280 /** Generate the string showing this classifiers position. */ 207 281 public String getPositionString() { 208 if(manager == null) { 209 return "Search"; 210 } 211 return "CL" + (manager.indexOf(this) + 1); 212 } 213 /** Method to set the value of custom. 214 * @param custom The new value of custom as a <strong>String</strong>. 215 */ 216 public void setCustom(String custom) { 217 this.custom = custom; 218 } 219 /** Method to set the value of desc. 220 * @param desc The new value of desc as a <strong>String</strong>. 221 */ 222 public void setDesc(String desc) { 223 this.desc = desc; 224 } 225 /** Method to set the value of manager. 226 * @param manager The new manager as a <strong>ClassifierManager</strong>. 227 */ 228 public void setManager(ClassifierManager manager) { 229 this.manager = manager; 230 } 231 /** Method to set the value of name. 232 * @param name The new value of name as a <strong>String</strong>. 233 */ 282 String position_string = CLASSIFIER_PREFIX; 283 if(element != null) { 284 // Determine our place in the collect.cfg file 285 int position_int = CollectionDesignManager.classifier_manager.indexOf(this) + 1; 286 if(position_int != -1) { 287 position_string = position_string + position_int; 288 } 289 } 290 return position_string; 291 } 292 293 public boolean isAssigned() { 294 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR)); 295 } 296 297 public void setAssigned(boolean assigned) { 298 if(element != null) { 299 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 300 } 301 } 302 303 /** Set the custom arguments. This turns out to be quite tricky. We must parse in the string, searching for arguments (for that we use a handy method in CollectionConfiguration). Next, for each argument, we check if we already know about it. If so we update its value, otherwise we create a new argument and assign it (must assign!). 304 * @param custom_str the custom arguments all splodged together in one String 305 */ 306 public void setCustom(String custom_str) { 307 HashMap raw_arguments = CollectionConfiguration.parseArguments(new CommandTokenizer(custom_str)); 308 ArrayList custom_arguments = getArguments(false, true); 309 int size = custom_arguments.size(); 310 for(int i = 0; i < size; i++) { 311 Argument argument = (Argument) custom_arguments.get(i); 312 String original_argument_name = StaticStrings.MINUS_CHARACTER + argument.getName(); 313 if(raw_arguments.containsKey(original_argument_name)) { 314 // Set as assigned 315 argument.setAssigned(true); 316 String argument_value = (String)raw_arguments.remove(original_argument_name); 317 if(argument_value != null) { 318 argument.setValue(argument_value); 319 argument_value = null; 320 } 321 } 322 // We've removed it from our custom statement, so unassign 323 else { 324 argument.setAssigned(false); 325 } 326 argument = null; 327 } 328 // Any left over, add to the classifier 329 Iterator argument_names = raw_arguments.keySet().iterator(); 330 while(argument_names.hasNext()) { 331 String argument_name = (String) argument_names.next(); 332 String argument_value = (String) raw_arguments.get(argument_name); 333 // The tricky thing is that we have to create a new element in the DOM as well. 334 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT); 335 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, argument_name.substring(1)); 336 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 337 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.TRUE_STR); 338 Argument argument = new Argument(argument_element); 339 argument_name = null; 340 if(argument_value != null) { 341 argument.setValue(argument_value); 342 argument_value = null; 343 } 344 // All done. Add it. 345 element.appendChild(argument_element); 346 add(argument); 347 argument_element = null; 348 } 349 raw_arguments = null; 350 } 351 352 /** Method to set the value of desc. 353 * @param desc The new value of desc as a <strong>String</strong>. 354 */ 355 public void setDescription(String desc) { 356 this.description = description; 357 } 358 359 public void setElement(Element element) { 360 this.element = element; 361 } 362 363 /** Method to set the value of name. 364 * @param name The new value of name as a <strong>String</strong>. 365 */ 234 366 public void setName(String name) { 235 367 this.name = name; 236 368 } 369 237 370 /** Method to set the value of the super_classifier. 238 * @param super_classifier The new value of super_classifier as a <strong>Classifier</strong>, or <i>null</i> if this class has no inheritance. 239 371 * @param super_classifier The new value of super_classifier as a <strong>Classifier</strong>, or <i>null</i> if this class has no inheritance. 372 */ 240 373 public void setSuper(Classifier super_classifier) { 241 374 this.super_classifier = super_classifier; 242 375 } 376 243 377 /** Method to print out this classifier as it would appear to the user in the interface 244 378 * @return A <strong>String</strong> containing a single classifier command. 245 379 */ 246 380 public String toString() { 247 StringBuffer text = new StringBuffer("classify "); 248 text.append(name); 249 text.append(" "); 250 ArrayList arguments = getArguments(); 251 for(int i = 0; i < arguments.size(); i++) { 252 Argument argument = (Argument)arguments.get(i); 253 if(argument.isAssigned()) { 254 text.append(argument.toString()); 255 text.append(" "); 256 } 257 } 258 if(custom != null) { 259 text.append(custom); 260 } 261 return text.toString(); 262 } 263 /** Method to print out this classifier as it would appear as a command within the collection configuration file. 264 * @return A <strong>String</strong> containing a single classifier command. 265 */ 266 public String toStringConfig() { 267 StringBuffer text = new StringBuffer("classify "); 268 text.append(name); 269 text.append(" "); 270 ArrayList arguments = getArguments(); 271 for(int i = 0; i < arguments.size(); i++) { 272 Argument argument = (Argument)arguments.get(i); 273 if(argument.isAssigned()) { 274 text.append(argument.toStringConfig()); 275 text.append(" "); 276 } 277 } 278 if(custom != null) { 279 text.append(custom); 280 } 281 return text.toString(); 381 if(element != null) { 382 if(name == null) { 383 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 384 } 385 StringBuffer text = new StringBuffer(StaticStrings.CLASSIFY_STR); 386 text.append(" "); 387 text.append(name); 388 text.append(" "); 389 ArrayList arguments = getArguments(true, true); 390 int arguments_size = arguments.size(); 391 for(int i = 0; i < arguments_size; i++) { 392 Argument argument = (Argument)arguments.get(i); 393 if(argument.isAssigned()) { 394 text.append(argument.toString()); 395 text.append(" "); 396 } 397 } 398 return text.substring(0, text.length() - 1); 399 } 400 else { 401 return name; 402 } 282 403 } 283 404 } 284 285
Note:
See TracChangeset
for help on using the changeset viewer.