Changeset 4932
- Timestamp:
- 2003-07-15T13:55:22+12:00 (21 years ago)
- Location:
- trunk/gli/src/org/greenstone/gatherer
- Files:
-
- 11 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/cdm/Argument.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 /************************************************************************************** 46 * Title: Gatherer 47 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 48 * Company: The University of Waikato 49 * Written: 01/05/02 50 * Revised: 16/08/02 Optimized and Commented. 51 **************************************************************************************/ 52 import java.io.Serializable; 53 import java.util.ArrayList; 54 import java.util.Iterator; 55 import java.util.HashMap; 28 29 import java.io.*; 30 import java.util.*; 31 import org.greenstone.gatherer.Gatherer; 32 import org.greenstone.gatherer.cdm.CollectionConfiguration; 33 import org.greenstone.gatherer.collection.Collection; 34 import org.greenstone.gatherer.collection.CollectionManager; 56 35 import org.greenstone.gatherer.msm.ElementWrapper; 36 import org.greenstone.gatherer.msm.MetadataSetManager; 57 37 import org.greenstone.gatherer.msm.MSMUtils; 38 import org.greenstone.gatherer.util.StaticStrings; 58 39 import org.greenstone.gatherer.util.Utility; 40 import org.w3c.dom.*; 41 59 42 /** 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. 60 43 * @author John Thompson, Greenstone Digital Library, University of Waikato 61 44 * @version 2.3 62 45 */ 63 64 // ####################################################################################65 // Optimization Saving66 // ####################################################################################67 // Vector -> ArrayList + Memory, + Processor (pos. - Processor)68 // Hashtable -> HashMap + Processor69 // int -> byte (x7) + Memory (168b)70 // External method calls + Memory, Processor71 // ####################################################################################72 73 46 public class Argument 74 47 implements Comparable, Serializable { 75 /** If this argument has multiple values, then they are stored here. This was originally a Hashtable, but since the synchronization overhead is unwarrented it was changed to a HashMap. */ 76 private ArrayList values = null; 48 /** An element of the argument type enumeration. */ 49 static final public byte ENUM = 0; 50 /** An element of the argument type enumeration. */ 51 static final public byte FLAG = 1; 52 /** An element of the argument type enumeration. */ 53 static final public byte HIERARCHY = 2; 54 /** An element of the argument type enumeration. */ 55 static final public byte INTEGER = 3; 56 /** An element of the argument type enumeration. */ 57 static final public byte LANGUAGE = 4; 58 /** An element of the argument type enumeration. */ 59 static final public byte METADATA = 5; 60 /** An element of the argument type enumeration. */ 61 static final public byte METADATUM = 6; 62 /** An element of the argument type enumeration. */ 63 static final public byte STRING = 7; 77 64 /** <i>true</i> if this argument is required for the applicable script to work properly, <i>false</i> otherwise. */ 78 65 private boolean required = false; 79 66 /** The type of this argument. Initially an int, but bytes are cheaper. */ 80 private byte type = FLAG; 81 82 private ElementWrapper element = null; 67 private byte type = STRING; 68 private Element element; 83 69 /** If the argument is of type ENUM then this map holds all the various options. Each entry is an <option value> -> <description> mapping. */ 84 70 private HashMap list = null; … … 86 72 private String default_value = null; 87 73 /** The text description of this argument parsed from the pluginfo output. */ 88 private String desc = null;74 private String description = null; 89 75 /** The argument flag as it appears in the command. Also used as the unique identifier of an argument. */ 90 76 private String name = null; 91 77 /** The plugin that owns this argument, for the purposes of visualising inheritance. */ 92 78 private String owner = null; 93 /** If this argument has been assigned, what is its value. Must be non-null for the argument to be printed. */ 94 private String value = null; 95 /** An element of the argument type enumeration. */ 96 static final public byte ENUM = 0; 97 /** An element of the argument type enumeration. */ 98 static final public byte FLAG = 1; 99 /** An element of the argument type enumeration. */ 100 static final public byte HIERARCHY = 2; 101 /** An element of the argument type enumeration. */ 102 static final public byte INTEGER = 3; 103 /** An element of the argument type enumeration. */ 104 static final public byte LANGUAGE = 4; 105 /** An element of the argument type enumeration. */ 106 static final public byte METADATA = 5; 107 /** An element of the argument type enumeration. */ 108 static final public byte METADATUM = 6; 109 /** An element of the argument type enumeration. */ 110 static final public byte STRING = 7; 79 111 80 /** Default Constructor. */ 112 81 public Argument() { 113 82 } 114 /** Normal Constructor, based on data parsed from an information script. 115 * @param name The argument flag as it appears in the command, as a <strong>String</strong>. Also used as the unique identifier of an argument. 116 * @param desc The text description of this argument parsed from the output as a <strong>String</strong>. 117 * @param type The type of this argument as a <i>byte</i>. 118 * @param default_value The default value for a parameter type argument, which may include a Perl type regular expression, as a <strong>String</strong>. 119 */ 120 public Argument(String name, String desc, byte type, String default_value) { 121 this.default_value = default_value; 122 this.desc = desc; 123 this.name = name; 124 this.type = type; 125 if(type == ENUM) { 126 this.list = new HashMap(); 127 } 128 if(type == METADATUM) { 129 values = new ArrayList(); 130 } 131 } 83 84 public Argument(Element element) { 85 this.element = element; 86 } 87 132 88 /** Method to add an element to the option list. 133 134 135 89 * @param name The name value of the option as a <strong>String</strong>. 90 * @param desc The description of this options as a <strong>String</strong>. 91 */ 136 92 public void addOption(String name, String desc) { 137 93 if(type == ENUM && name != null) { … … 139 95 desc = ""; 140 96 } 141 if(!list.containsKey(name)) { 142 list.put(name, desc); 143 } 144 } 145 } 97 if(list == null) { 98 list = new HashMap(); 99 } 100 list.put(name, desc); 101 } 102 } 103 146 104 /** Method to compare two arguments for ordering. 147 148 149 150 151 105 * @param object The argument we are comparing to, as an <strong>Object</strong>. 106 * @return An <i>int</i> specifying the argument order, using values as set out in String. 107 * @see java.lang.String#compareTo 108 * @see org.greenstone.gatherer.cdm.Argument 109 */ 152 110 public int compareTo(Object object) { 153 Argument argument = (Argument)object; 154 return getName().compareTo(argument.getName()); 155 } 156 /** Method to deep copy this argument. 157 * @return A newly created <strong>Argument</strong> which has the same details as this one. 158 */ 111 if(object instanceof Argument) { 112 return getName().compareTo(((Argument)object).getName()); 113 } 114 else { 115 return toString().compareTo(object.toString()); 116 } 117 } 118 159 119 public Argument copy() { 160 Argument copy = new Argument(name, desc, type, default_value); 120 Argument copy = new Argument(); 121 copy.setDefaultValue(default_value); 122 copy.setDescription(description); 123 copy.setOptions(list); 124 copy.setOwner(owner); 125 copy.setName(name); 161 126 copy.setRequired(required); 162 if(values != null) { 163 copy.setValues(values); 164 } 165 if(list != null) { 166 HashMap list_deep_copy = new HashMap(); 167 Iterator it = list.keySet().iterator(); 168 while(it.hasNext()) { 169 String key = (String) it.next(); 170 String desc = (String) list.get(key); 171 list_deep_copy.put(new String(key), new String(desc)); 172 } 173 copy.setOptions(list_deep_copy); 174 } 127 copy.setType(type); 175 128 return copy; 176 129 } 130 177 131 /** Method to determine if two arguments are equal. 178 179 180 132 * @param object The argument to test against, as an <strong>Object</strong>. 133 * @return <i>true</i> if the arguments names match, <i>false</i> otherwise. 134 */ 181 135 public boolean equals(Object object) { 182 136 return (compareTo(object) == 0); 183 137 } 138 184 139 /** Method to retrieve the value of default_value. 185 186 140 * @return A <strong>String</strong> containing the default value. 141 */ 187 142 public String getDefaultValue() { 188 143 return default_value; 189 144 } 145 190 146 /** Method to retrieve this arguments description. 191 * @return A <strong>String</strong> containing the description. 192 */ 193 public String getDesc() { 194 return desc; 195 } 147 * @return A <strong>String</strong> containing the description. 148 */ 149 public String getDescription() { 150 return description; 151 } 152 196 153 /** Method to retrieve the description of a certain list option value. 197 198 199 200 public String getDesc (String key) {154 * @param key The <strong>String</strong> whose description we are searching for. 155 * @return The description of the desired key as a <strong>String</strong> which may be empty if no such key exists. 156 */ 157 public String getDescription(String key) { 201 158 if(list.containsKey(key)) { 202 159 return (String)list.get(key); … … 204 161 return ""; 205 162 } 163 206 164 /** Method to retrieve the option list for this argument. 207 208 209 public HashMap get List() {165 * @return A <strong>HashMap</strong> containing <option value> -> <description> entries. 166 */ 167 public HashMap getOptions() { 210 168 return list; 211 169 } 170 212 171 /** Method to retrieve the value of name. 213 214 172 * @return A <strong>String</strong> containing the argument name. 173 */ 215 174 public String getName() { 175 if(name == null && element != null) { 176 name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 177 } 216 178 return name; 217 179 } 180 218 181 /** Retrieve the name of the owner of this argument. 219 220 182 * @return The owners name as a <strong>String</strong>. 183 */ 221 184 public String getOwner() { 222 185 return owner; 223 186 } 187 224 188 /** Method to determine the type of this argument. 225 226 189 * @return An <i>byte</i> specifying the type. 190 */ 227 191 public byte getType() { 228 192 return type; 229 193 } 194 230 195 /** Method to retrieve the value of value. 231 232 196 * @return The value of value as a <strong>String</strong>. 197 */ 233 198 public String getValue() { 234 if(element != null) { 235 return element.toString(); 199 String value = null; 200 // Only assigned arguments have values. 201 if(element != null) { 202 value = MSMUtils.getValue(element); 203 // We may have to retrieve the language dependant string for a MSM Element 204 if(type == METADATUM) { 205 ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(value); 206 if(element_wrapper != null) { 207 value = element_wrapper.toString(); 208 } 209 } 236 210 } 237 211 return value; 238 212 } 213 239 214 /** Retrieve the vector of values. 240 241 215 * @return An <strong>ArrayList</strong> of values. 216 */ 242 217 public ArrayList getValues() { 218 ArrayList values = new ArrayList(); 219 // Only assigned arguments have values. 220 if(element != null) { 221 String value = MSMUtils.getValue(element); 222 StringTokenizer tokenizer = new StringTokenizer(value, ","); 223 while(tokenizer.hasMoreTokens()) { 224 String token = tokenizer.nextToken(); 225 if(type == METADATA) { 226 ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(token); 227 if(element_wrapper != null) { 228 token = element_wrapper.toString(); 229 } 230 } 231 values.add(token); 232 } 233 } 243 234 return values; 244 235 } 236 245 237 /** Method to determine if this argument has been assigned. 246 247 238 * @return <i>true</i> if it has, <i>false</i> otherwise. 239 */ 248 240 public boolean isAssigned() { 249 return (required || value != null || (values != null && values.size() > 0)); 250 } 241 return (element != null && element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.TRUE_STR)); 242 } 243 244 public boolean isCustomArgument() { 245 return (element != null && element.getAttribute(StaticStrings.CUSTOM_ATTRIBUTE).equals(StaticStrings.TRUE_STR)); 246 } 247 251 248 /** Method to determine of this argument is required for the associated script to work. 252 253 249 * @return <i>true</i> if this argument is required, <i>false</i> otherwise. 250 */ 254 251 public boolean isRequired() { 255 252 return required; 256 253 } 254 257 255 /** Method to allow for the activation of arguments that might never have their setValue() method called. 258 * @param new_state The required state as a <i>boolean</i>. 259 */ 260 public void setAssigned(boolean new_state) { 261 if(new_state && (value == null || values == null)) { 262 value = ""; 263 } 264 else { 265 value = null; 266 } 267 } 256 * @param assigned the desired state as a boolean 257 */ 258 public void setAssigned(boolean assigned) { 259 if(element != null) { 260 element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, (assigned ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR)); 261 } 262 } 263 264 public void setCustomArgument(boolean custom) { 265 if(element != null) { 266 element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, (custom ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR)); 267 } 268 } 269 268 270 /** Sets the value of default_value. 269 * @param new_default_value The new value for default_value as a <strong>String</strong>. 270 */ 271 public void setDefault(String new_default_value) { 272 default_value = new_default_value; 273 } 271 * @param default_value The new value for default_value as a <strong>String</strong>. 272 */ 273 public void setDefaultValue(String default_value) { 274 this.default_value = default_value; 275 } 276 274 277 /** Set the value of desc. 275 * @param new_descThe new value of desc as a <strong>String</strong>.276 277 public void setDesc (String new_desc) {278 desc = new_desc;279 } 280 281 public void setElement Value(ElementWrapperelement) {278 * @param description The new value of desc as a <strong>String</strong>. 279 */ 280 public void setDescription(String description) { 281 this.description = description; 282 } 283 284 public void setElement(Element element) { 282 285 this.element = element; 283 286 } 284 287 285 288 /** Set the value of name. 286 * @param new_name The new value of name as a <strong>String</strong>. 287 */ 288 public void setName(String new_name) { 289 name = new_name; 290 } 289 * @param name The new value of name as a <strong>String</strong>. 290 */ 291 public void setName(String name) { 292 this.name = name; 293 } 294 291 295 /** Sets the value of the options list. 292 * @param new_list The new options list as a <strong>HashMap</strong>. 293 */ 294 public void setOptions(HashMap new_list) { 295 list = new_list; 296 } 296 * @param list The new options list as a <strong>HashMap</strong>. 297 */ 298 public void setOptions(HashMap list) { 299 this.list = list; 300 } 301 297 302 /** Set the owner of this argument. 298 299 303 * @param owner The name of the owner of this argument as a <strong>String</strong>. 304 */ 300 305 public void setOwner(String owner) { 301 306 this.owner = owner; 302 307 } 308 303 309 /** Set the value of required. 304 * @param new_required The new value of required as a <i>boolean</i>. 305 */ 306 public void setRequired(boolean new_required) { 307 required = new_required; 308 } 310 * @param required The new value of required as a <i>boolean</i>. 311 */ 312 public void setRequired(boolean required) { 313 this.required = required; 314 } 315 309 316 /** Set the value of type. 310 * @param new_type The new value of type as an <i>byte</i>. 311 */ 312 public void setType(byte new_type) { 313 type = new_type; 314 if(type == ENUM) { 315 list = new HashMap(); 316 } 317 if(type == METADATUM && values == null) { 318 values = new ArrayList(); 319 } 320 } 317 * @param type The new value of type as an <i>byte</i>. 318 */ 319 public void setType(byte type) { 320 this.type = type; 321 } 322 321 323 /** Set the value of type, by matching a type to the given string. 322 323 324 * @param new_type A <strong>String</strong> which contains the name of a certain argument type. 325 */ 324 326 public void setType(String new_type) { 325 if(new_type.equalsIgnoreCase( "enum")) {327 if(new_type.equalsIgnoreCase(StaticStrings.ENUM_STR)) { 326 328 this.type = ENUM; 327 329 list = new HashMap(); 328 330 } 329 else if(new_type.equalsIgnoreCase( "flag")) {331 else if(new_type.equalsIgnoreCase(StaticStrings.FLAG_STR)) { 330 332 this.type = FLAG; 331 333 } 332 else if(new_type.equalsIgnoreCase( "hierarchy")) {334 else if(new_type.equalsIgnoreCase(StaticStrings.HIERARCHY_STR)) { 333 335 this.type = HIERARCHY; 334 336 } 335 else if(new_type.equalsIgnoreCase( "int")) {337 else if(new_type.equalsIgnoreCase(StaticStrings.INT_STR)) { 336 338 this.type = INTEGER; 337 339 } 338 else if(new_type.equalsIgnoreCase( "language")) {340 else if(new_type.equalsIgnoreCase(StaticStrings.LANGUAGE_STR)) { 339 341 this.type = LANGUAGE; 340 342 } 341 else if(new_type.equalsIgnoreCase( "metadata")) {343 else if(new_type.equalsIgnoreCase(StaticStrings.METADATA_TYPE_STR)) { 342 344 this.type = METADATA; 343 345 } 344 else if(new_type.equalsIgnoreCase( "metadatum")) {346 else if(new_type.equalsIgnoreCase(StaticStrings.METADATUM_TYPE_STR)) { 345 347 this.type = METADATUM; 346 if(values == null) { 347 values = new ArrayList(); 348 } 349 } 350 else if(new_type.equalsIgnoreCase("string")) { 348 } 349 else { 351 350 this.type = STRING; 352 351 } 353 } 354 355 /** Method to set the value of value. 356 * @param new_value The new value of value as a <strong>String</strong>. 357 */ 358 public void setValue(String new_value) { 359 this.value = new_value; 360 } 352 353 } 354 /** Method to set the value of this argument. 355 * @param value 356 * @see org.greenstone.gatherer.Gatherer 357 * @see org.greenstone.gatherer.msm.MSMUtils 358 */ 359 public void setValue(String value) { 360 if(element != null) { 361 MSMUtils.setValue(element, value); 362 } 363 else { 364 Gatherer.println("Argument.setValue(" + value + ") called on a base Argument."); 365 } 366 } 367 361 368 /** 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. 362 * @param new_values An <strong>ArrayList</strong> of values. 363 */ 364 public void setValues(ArrayList new_values) { 365 values = new_values; 366 } 369 * @param values an ArrayList of values 370 * @see org.greenstone.gatherer.Gatherer 371 * @see org.greenstone.gatherer.msm.MSMUtils 372 */ 373 public void setValues(ArrayList values) { 374 if(element != null) { 375 StringBuffer value = new StringBuffer(); 376 int value_length = values.size(); 377 for(int i = 0; i < value_length; i++) { 378 value.append(values.get(i)); 379 value.append(StaticStrings.COMMA_CHARACTER); 380 } 381 value.deleteCharAt(value.length() - 1); // Remove last ',' 382 MSMUtils.setValue(element, value.toString()); 383 } 384 else { 385 Gatherer.println("Argument.setValues([" + values.size() + " items]) called on a base Argument."); 386 } 387 } 388 367 389 /** Method for translating the data of this class into a string. 368 * @return A <strong>String</strong> containing a fragment of the total arguments string. 369 */ 390 * @return a String containing a fragment of the total arguments string 391 * @see org.greenstone.gatherer.Gatherer 392 * @see org.greenstone.gatherer.collection.Collection 393 * @see org.greenstone.gatherer.collection.CollectionManager 394 * @see org.greenstone.gatherer.msm.MetadataSetManager 395 * @see org.greenstone.gatherer.msm.MSMUtils 396 * @see org.greenstone.gatherer.util.StaticStrings 397 */ 370 398 public String toString() { 371 switch(type) { 372 case FLAG: 373 return "-" + name; 374 case METADATA: 375 StringBuffer metadata_text = new StringBuffer("-"); 376 metadata_text.append(name); 377 metadata_text.append(" "); 378 if(element != null) { 379 String element_name = element.toString(); 380 if(element_name.indexOf(" ") != -1) { 381 metadata_text.append("\""); 382 metadata_text.append(element_name); 383 metadata_text.append("\""); 399 StringBuffer text = new StringBuffer("-"); 400 if(element != null) { 401 if(name == null) { 402 name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 403 } 404 text.append(name); 405 String value = MSMUtils.getValue(element); 406 if(value.length() > 0) { 407 text.append(StaticStrings.SPACE_CHARACTER); 408 // Tokenize the string 409 StringTokenizer tokenizer = new StringTokenizer(value, ","); 410 while(tokenizer.hasMoreTokens()) { 411 String token = tokenizer.nextToken(); 412 if(type == METADATA || type == METADATUM) { 413 ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(token); 414 if(element_wrapper != null) { 415 text.append(element_wrapper.toString()); 416 element_wrapper = null; 417 } 418 else { 419 text.append(token); 420 } 421 } 422 else { 423 text.append(token); 424 } 425 token = null; 426 text.append(StaticStrings.COMMA_CHARACTER); 384 427 } 385 else { 386 metadata_text.append(element_name); 387 } 388 element_name = null; 389 } 390 else { 391 metadata_text.append(value); 392 } 393 return metadata_text.toString(); 394 case METADATUM: 395 StringBuffer metadatum_text = new StringBuffer("-"); 396 metadatum_text.append(name); 397 metadatum_text.append(" "); 398 for(int i = 0; i < values.size(); i++) { 399 metadatum_text.append(values.get(i).toString()); 400 if(i < values.size() - 1) { 401 metadatum_text.append(","); 402 } 403 } 404 return metadatum_text.toString(); 405 case STRING: 406 // we need to put quotes if they are not there 407 if (value != null && value.indexOf(' ') != -1 && value.indexOf('"')==-1) { 408 // if there is a space and we haven't got any quotes 409 return "-" + name + " \"" + value + "\""; 410 } // otherwise it will stuff up but I cant be bothered doing this properly 411 default: 412 return "-" + name + " " + value; 413 } 414 } 415 416 public String toStringConfig() { 417 switch(type) { 418 case METADATA: 419 StringBuffer metadata_text = new StringBuffer("-"); 420 metadata_text.append(name); 421 if(element != null) { 422 metadata_text.append(" "); 423 String element_name = element.getName(); 424 if (element_name.startsWith(Utility.EXTRACTED_METADATA_NAMESPACE+MSMUtils.NS_SEP)) { 425 426 element_name = element_name.substring(element_name.indexOf(MSMUtils.NS_SEP)+1); 427 } 428 metadata_text.append(element_name); 429 element_name = null; 430 } 431 else if(value != null) { 432 metadata_text.append(" "); 433 metadata_text.append(value); 434 } 435 return metadata_text.toString(); 436 case METADATUM: 437 StringBuffer metadatum_text = new StringBuffer("-"); 438 metadatum_text.append(name); 439 metadatum_text.append(" "); 440 for(int i = 0; i < values.size(); i++) { 441 String temp_value = values.get(i).toString(); 442 if (temp_value.startsWith(Utility.EXTRACTED_METADATA_NAMESPACE+MSMUtils.NS_SEP)) { 443 444 temp_value = temp_value.substring(temp_value.indexOf(MSMUtils.NS_SEP)+1); 445 } 446 metadatum_text.append(temp_value); 447 if(i < values.size() - 1) { 448 metadatum_text.append(","); 449 } 450 } 451 return metadatum_text.toString(); 452 default: 453 return toString(); 454 } 455 } 456 428 tokenizer = null; 429 text.deleteCharAt(text.length() - 1); 430 } 431 value = null; 432 } 433 return text.toString(); 434 } 457 435 } 458 459 -
trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentConfiguration.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 /************************************************************************************** 46 * Title: Gatherer 47 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 48 * Company: The University of Waikato 49 * Written: 01/05/02 50 * Revised: 16/08/02 Optimized and Commented. Added destructor. 51 **************************************************************************************/ 52 import java.awt.BorderLayout; 53 import java.awt.Color; 54 import java.awt.Component; 55 import java.awt.Dimension; 56 import java.awt.GridLayout; 57 import java.awt.Toolkit; 58 import java.awt.event.ActionEvent; 59 import java.awt.event.ActionListener; 60 import java.awt.event.ItemEvent; 61 import java.awt.event.ItemListener; 62 import java.awt.event.KeyEvent; 63 import java.util.ArrayList; 64 import java.util.Collections; 65 import java.util.HashMap; 66 import java.util.Iterator; 67 import javax.swing.BorderFactory; 68 import javax.swing.BoxLayout; 69 import javax.swing.DefaultListModel; 70 import javax.swing.JButton; 71 import javax.swing.JCheckBox; 72 import javax.swing.JComboBox; 73 import javax.swing.JComponent; 74 import javax.swing.JDialog; 75 import javax.swing.JLabel; 76 import javax.swing.JList; 77 import javax.swing.JOptionPane; 78 import javax.swing.JPanel; 79 import javax.swing.JScrollPane; 80 import javax.swing.JTextField; 28 29 import java.awt.*; 30 import java.awt.event.*; 31 import java.util.*; 32 import javax.swing.*; 81 33 import org.greenstone.gatherer.Gatherer; 82 34 import org.greenstone.gatherer.cdm.Argument; … … 97 49 * @see org.greenstone.gatherer.cdm.PlugIn 98 50 */ 99 // ####################################################################################100 // Optimization Saving101 // ####################################################################################102 // Vector -> ArrayList + Processor103 // Hashtable -> HashMap + Processor104 // Remove several global references + Memory (1Kb+)105 // ####################################################################################106 107 51 public class ArgumentConfiguration 108 52 extends ModalDialog … … 114 58 /** Whether we have successfully edited the arguments associated with the ArgumentContainer or if we have failed to enter required arguments and have instead cancelled (which would cause argument additions to roll back). */ 115 59 private boolean success = false; 116 /** A reference to the main CollectionDesignManager class for access to other managers. */117 private CollectionDesignManager manager = null;118 /** A reference to the Gatherer. */119 private Gatherer gatherer = null;120 60 /** A button to cancel this dialog. */ 121 61 private JButton cancel = null; … … 137 77 static final private Dimension SIZE = new Dimension(800, 425); 138 78 /** Constructor. 139 * @param gatherer A reference to the <strong>Gatherer</strong>.140 * @param manager The <strong>CollectionDesignManager</strong> for access to other configuration managers.141 79 * @param data The plugin or classifier whose arguments we are configuring, in the form of its supported <strong>ArgumentContainer</strong> interface. 142 80 * @see org.greenstone.gatherer.Configuration 143 81 */ 144 public ArgumentConfiguration( Gatherer gatherer, CollectionDesignManager manager,ArgumentContainer data) {145 super( gatherer.g_man);82 public ArgumentConfiguration(ArgumentContainer data) { 83 super(Gatherer.g_man); 146 84 this.data = data; 147 this.gatherer = gatherer;148 this.manager = manager;149 85 this.self = this; 150 86 String custom_str = data.getCustom(); … … 210 146 211 147 // Display on screen. 212 Dimension screen_size = gatherer.config.screen_size;148 Dimension screen_size = Gatherer.config.screen_size; 213 149 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); 214 150 screen_size = null; … … 223 159 if(event.getSource() == ok) { 224 160 // Update the details stored in the data objects arguments. 225 if(custom.getText().length() > 0) { 226 data.setCustom(custom.getText()); 227 } 161 data.setCustom(custom.getText()); 228 162 // Loop through each of the controls in the central pane, updating the matching argument as necessary. 229 163 for(int i = 0; i < central_pane.getComponentCount(); i++) { … … 248 182 custom = null; 249 183 data = null; 250 gatherer = null;251 manager = null;252 184 ok = null; 253 185 self = null; … … 285 217 */ 286 218 private void generateControls() { 287 ArrayList arguments = data.getArguments( );219 ArrayList arguments = data.getArguments(true, false); 288 220 int total_height = 250; 289 221 int size = arguments.size(); … … 317 249 key = "CDM.ArgumentConfiguration." + key; 318 250 } 319 return gatherer.dictionary.get(key, args);251 return Gatherer.dictionary.get(key, args); 320 252 } 321 253 /** This class encapsulates all the technical difficulty of creating a specific control based on an Argument. */ … … 324 256 /** The Argument this control will be based on. */ 325 257 private Argument argument = null; 258 259 private Color colour_one = Gatherer.config.getColor("coloring.collection_heading_background", false); 260 private Color colour_two = Gatherer.config.getColor("coloring.collection_tree_background", false); 326 261 /** One of a possible two buttons available for adding to this control. */ 327 262 private JButton one = null; … … 345 280 public ArgumentControl(Argument argument) { 346 281 this.argument = argument; 347 String tip = "<html>" + argument.getDesc () + "</html>";282 String tip = "<html>" + argument.getDescription() + "</html>"; 348 283 tip = Utility.formatHTMLWidth(tip, 60); 349 284 // If this is the first control, there is no history. 350 285 if(previous_owner == null) { 351 286 previous_owner = argument.getOwner(); 352 addHeader(previous_owner, Color.white);287 addHeader(previous_owner, colour_one); 353 288 } 354 289 // Otherwise if the owner of the control has changed since the last argument, toggle the colouring of the control. … … 356 291 coloured = !coloured; 357 292 previous_owner = argument.getOwner(); 358 addHeader(previous_owner, (coloured ? Gatherer.config.getColor("coloring.collection_tree_background", false) : Color.white));293 addHeader(previous_owner, (coloured ? colour_two : colour_one)); 359 294 } 360 295 // Create 361 296 if(coloured) { 362 setBackground( Gatherer.config.getColor("coloring.collection_tree_background", false));297 setBackground(colour_one); 363 298 } 364 299 else { 365 setBackground( Color.white);300 setBackground(colour_two); 366 301 } 367 302 JLabel owner_label = new JLabel(argument.getOwner()); … … 382 317 case Argument.ENUM: 383 318 // Build an option model, wrapping each entry of the list table. 384 HashMap arg_list = argument.get List();319 HashMap arg_list = argument.getOptions(); 385 320 ArrayList options_model = new ArrayList(); 386 321 Iterator it = arg_list.keySet().iterator(); … … 405 340 break; 406 341 case Argument.HIERARCHY: 407 value = new JComboBox( gatherer.c_man.msm.getAssignedElements(true));342 value = new JComboBox(Gatherer.c_man.getCollection().msm.getAssignedElements(true)); 408 343 /** @TODO - figure out a smarter way of allowing Greenstone extracted metadata to be selected. */ 409 344 ((JComboBox)value).setEditable(true); … … 450 385 break; 451 386 case Argument.LANGUAGE: 452 value = new JComboBox( manager.languages.getLanguageCodes().toArray());387 value = new JComboBox(CollectionDesignManager.language_manager.getLanguageCodes().toArray()); 453 388 // Now ensure we have the existing value or default value selected if either exist. 454 389 Language selected = null; 455 390 if(existing_value != null) { 456 selected = manager.languages.getLanguage(existing_value, false);391 selected = CollectionDesignManager.language_manager.getLanguage(existing_value); 457 392 } 458 393 else if(default_value != null) { 459 selected = manager.languages.getLanguage(default_value, false);394 selected = CollectionDesignManager.language_manager.getLanguage(default_value); 460 395 } 461 396 if(selected != null) { 462 ((JComboBox)value).setSelectedItem(selected );397 ((JComboBox)value).setSelectedItem(selected.getCode()); 463 398 } 464 399 break; 465 case Argument.METADAT A:466 value = new JComboBox( gatherer.c_man.msm.getAssignedElements());400 case Argument.METADATUM: 401 value = new JComboBox(Gatherer.c_man.getCollection().msm.getAssignedElements()); 467 402 /** @TODO - figure out a smarter way of allowing Greenstone extracted metadata to be selected. */ 468 403 ((JComboBox)value).setEditable(true); … … 475 410 } 476 411 break; 477 case Argument.METADAT UM:412 case Argument.METADATA: 478 413 // Comma separated metadata values. 479 414 ArrayList values = argument.getValues(); 480 value = new JComboBox( gatherer.c_man.msm.getAssignedElements());415 value = new JComboBox(Gatherer.c_man.getCollection().msm.getAssignedElements()); 481 416 DefaultListModel model = new DefaultListModel(); 482 417 list = new JList(model); … … 566 501 add(inner_pane, BorderLayout.CENTER); 567 502 } 503 568 504 public Object getValue() { 569 505 if(value instanceof JComboBox) { … … 650 586 // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted. 651 587 return true; 652 case Argument.METADATA: 653 // I feel like a cast-away 654 argument.setElementValue((ElementWrapper)((JComboBox)value).getSelectedItem()); 655 return true; 588 case Argument.METADATUM: 656 589 case Argument.HIERARCHY: 657 590 argument.setValue(((JComboBox)value).getSelectedItem().toString()); 658 591 // Kinda lucked out here. Its impossible not to choose an entry from these comboboxes as they are restricted. 659 592 return true; 660 case Argument.METADAT UM:593 case Argument.METADATA: 661 594 DefaultListModel model = (DefaultListModel)list.getModel(); 662 595 ArrayList values = new ArrayList(); … … 743 676 this.target = target; 744 677 } 745 746 747 748 678 /** When the add button is clicked, we attempt to add the selected metadata from the source into the target. 679 * @param event An <strong>ActionEvent</strong> containing information about the event. 680 * @see org.greenstone.gatherer.msm.ElementWrapper 681 */ 749 682 public void actionPerformed(ActionEvent event) { 750 683 ElementWrapper element = (ElementWrapper) source.getSelectedItem(); 751 String name = element. getName();684 String name = element.toString(); 752 685 if(!model.contains(name)) { 753 686 boolean found = false; -
trunk/gli/src/org/greenstone/gatherer/cdm/ArgumentContainer.java
r4675 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: 20/05/02 50 * Revised: 30 * Revised: 03/07/03 51 31 **************************************************************************************/ 52 32 import java.util.ArrayList; … … 57 37 public interface ArgumentContainer { 58 38 /** Method to retrieve the list of arguments from this container. Note that this method returns both the containers arguments plus its 'supers' arguments if any, and alphabetically orders them. 59 * @return The arguments within a <strong>ArrayList</strong>. 39 * @param include_normal true to filter so normal arguments are returned 40 * @param include_custom true to filter so custom arguments are returned 41 * @return the arguments within a ArrayList 60 42 */ 61 public ArrayList getArguments( );43 public ArrayList getArguments(boolean include_normal, boolean include_custom); 62 44 /** Method to retrieve this containers custom argument string. 63 * @return The custom arguments as a <strong>String</strong>.45 * @return the custom arguments as a String 64 46 */ 65 47 public String getCustom(); 66 48 /** Method to retrieve the name associated with this argument container. 67 * @return The name as a <strong>String</strong>.49 * @return the name as a String 68 50 */ 69 51 public String getName(); 70 52 /** Method to set the custom arguments string. 71 * @param custom The new custom argument <strong>String</strong>.53 * @param custom the new custom argument String 72 54 */ 73 55 public void setCustom(String custom); -
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 -
trunk/gli/src/org/greenstone/gatherer/cdm/ClassifierManager.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 … … 36 26 */ 37 27 package org.greenstone.gatherer.cdm; 38 39 import java.awt.BorderLayout; 40 import java.awt.Color; 41 import java.awt.Component; 42 import java.awt.Dimension; 43 import java.awt.GridLayout; 44 import java.awt.event.ActionEvent; 45 import java.awt.event.ActionListener; 46 import java.awt.event.MouseAdapter; 47 import java.awt.event.MouseEvent; 48 import java.io.BufferedReader; 49 import java.io.File; 50 import java.io.FileInputStream; 51 import java.io.FileOutputStream; 52 import java.io.InputStream; 53 import java.io.InputStreamReader; 54 import java.io.ObjectInputStream; 55 import java.io.ObjectOutputStream; 56 import java.io.StringReader; 57 import java.lang.Exception; 58 import java.util.ArrayList; 59 import java.util.Collections; 60 import java.util.Enumeration; 61 import java.util.jar.JarFile; 62 import javax.swing.BorderFactory; 63 import javax.swing.DefaultListCellRenderer; 64 import javax.swing.JButton; 65 import javax.swing.JComboBox; 66 import javax.swing.JLabel; 67 import javax.swing.JList; 68 import javax.swing.JOptionPane; 69 import javax.swing.JPanel; 70 import javax.swing.JScrollPane; 71 import javax.swing.JTextArea; 72 import javax.swing.ListSelectionModel; 73 import javax.swing.event.ListSelectionEvent; 74 import javax.swing.event.ListSelectionListener; 75 import org.apache.xerces.parsers.DOMParser; 28 /************************************************************************************** 29 * Written: 01/05/02 30 * Revised: 16/08/02 Optimized and Commented. 31 * 11/07/03 DOM support 32 **************************************************************************************/ 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.io.*; 36 import java.util.*; 37 import java.util.jar.*; 38 import javax.swing.*; 39 import javax.swing.event.*; 40 import org.apache.xerces.parsers.*; 76 41 import org.greenstone.gatherer.Gatherer; 77 42 import org.greenstone.gatherer.cdm.Argument; 43 import org.greenstone.gatherer.cdm.CollectionConfiguration; 78 44 import org.greenstone.gatherer.cdm.CollectionDesignManager; 79 45 import org.greenstone.gatherer.cdm.CommandTokenizer; 46 import org.greenstone.gatherer.cdm.Control; 80 47 import org.greenstone.gatherer.cdm.Classifier; 81 48 import org.greenstone.gatherer.cdm.CustomClassifier; 82 import org.greenstone.gatherer.cdm.D ynamicListModel;49 import org.greenstone.gatherer.cdm.DOMProxyListModel; 83 50 import org.greenstone.gatherer.file.FileNode; 84 import org.greenstone.gatherer. msm.ElementWrapper;51 import org.greenstone.gatherer.gui.GComboBox; 85 52 import org.greenstone.gatherer.msm.MSMEvent; 86 53 import org.greenstone.gatherer.msm.MSMListener; 87 54 import org.greenstone.gatherer.msm.MSMUtils; 88 55 import org.greenstone.gatherer.util.Utility; 89 import org.w3c.dom.Document; 90 import org.w3c.dom.Node; 91 import org.xml.sax.InputSource; 56 import org.w3c.dom.*; 57 import org.xml.sax.*; 92 58 /** This class is responsible for keeping track of all the classifiers assigned to this collection, and providing methods for adding and removing them. 93 59 * @author John Thompson, Greenstone Digital Library, University of Waikato 94 60 * @version 2.3 95 61 */ 96 // ####################################################################################97 // Optimization Saving98 // ####################################################################################99 // Vector -> ArrayList + Memory, + Processor, (pos. - Processor)100 // Unnecessary global references + Memory (5Kb+)101 // ####################################################################################102 62 public class ClassifierManager 103 implements MSMListener { 104 /** An interface to the Gatherer, the creator of this cdm module, for access to the Greenstone installation directory. */ 105 private Gatherer gatherer = null; 106 /** A reference to the CollectionDesignManager for access to other configuration managers. */ 107 private CollectionDesignManager manager = null; 63 extends DOMProxyListModel { 64 65 /** The default size for a label. */ 66 static final private Dimension LABEL_SIZE = new Dimension(140, 20); 67 68 /** A list of known, but currently unassigned, classifiers. */ 69 private ArrayList library = null; 108 70 /** The controls for editing the contents of this manager. */ 109 71 private Control controls = null; 110 /** A list of assigned classifiers. */ 111 private DynamicListModel assigned = null; 112 /** A list of known, but currently unassigned, classifiers. */ 113 private DynamicListModel reserve = null; 114 /** We may have somehow recieved a classifier command that are, in fact, custom classifiers which can refer to classifiers that haven't been parsed yet, so this holds a list of failed commands which are retried after the loading is complete. */ 115 private ArrayList unresolved_commands = null; 72 73 private DOMProxyListModel model; 74 116 75 /** Constructor. 117 * @param gatherer A reference to the <strong>Gatherer</strong> for access to the Dictionary.118 * @param manager A reference to the <strong>CollectionDesignManager</strong> itself.119 * @see org.greenstone.gatherer.Gatherer120 76 * @see org.greenstone.gatherer.cdm.DynamicListModel 121 77 * @see org.greenstone.gatherer.collection.CollectionManager … … 123 79 * @see org.greenstone.gatherer.msm.MSMListener 124 80 */ 125 public ClassifierManager( Gatherer gatherer, CollectionDesignManager manager) {126 this.assigned = new DynamicListModel();127 this. gatherer = gatherer;128 this.manager = manager;129 this.unresolved_commands = new ArrayList();81 public ClassifierManager() { 82 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.CLASSIFY_ELEMENT, new Classifier()); 83 this.model = this; 84 Gatherer.println("ClassifierManager: " + getSize() + " classifiers parsed."); 85 // Reload/Create the library 130 86 loadClassifiers(); 131 87 saveClassifiers(); 132 // Register as a MSMListener. 133 Gatherer.c_man.getCollection().msm.addMSMListener(this); 134 } 135 /** Method to add a new classifier to reserve. 136 * @param classifier The new <strong>Classifier</strong>. 88 } 89 90 /** Method to add a new classifier to library. 91 * @param classifier The new <strong>Classifier</strong>. 92 * @see org.greenstone.gatherer.cdm.DynamicListModel 93 */ 94 public void addClassifier(Classifier classifier) { 95 if(!library.contains(classifier)) { 96 library.add(classifier); 97 } 98 } 99 100 /** Method to assign a classifier. 101 * @param classifier The base <strong>Classifier</strong> to assign. 102 * @see org.greenstone.gatherer.cdm.DynamicListModel 103 */ 104 public void assignClassifier(Classifier classifier) { 105 if(!contains(classifier)) { 106 Element element = classifier.getElement(); 107 // Locate where we should insert this new classifier. 108 Node target_node = CollectionConfiguration.findInsertionPoint(element); 109 add(root, classifier, target_node); 110 Gatherer.c_man.configurationChanged(); 111 } 112 } 113 114 /** Destructor. 115 * @see org.greenstone.gatherer.Gatherer 116 * @see org.greenstone.gatherer.cdm.CollectionDesignManager 117 * @see org.greenstone.gatherer.cdm.DynamicListModel 118 */ 119 public void destroy() { 120 if(controls != null) { 121 controls.destroy(); 122 controls = null; 123 } 124 library.clear(); 125 library = null; 126 } 127 128 public Classifier getBaseClassifier(String name) { 129 int library_size = library.size(); 130 for(int i = 0; i < library_size; i++) { 131 Classifier classifier = (Classifier) library.get(i); 132 if(classifier.getName().equals(name)) { 133 return classifier; 134 } 135 } 136 // No success. 137 return null; 138 } 139 140 /** Method to retrieve the classifier with the given index. 141 * @param index The index of the desired classifier as an <i>int</i>. 142 * @return The requested Classifier or <i>null</i> if no such classifier exists. 143 */ 144 public Classifier getClassifier(int index) { 145 if(0 <= index && index < getSize()) { 146 return (Classifier) getElementAt(index); 147 } 148 return null; 149 } 150 151 /** Method to retrieve the control for this manager. 152 * @return the Control for editing classifiers 153 */ 154 public Control getControls() { 155 if(controls == null) { 156 // Build controls 157 this.controls = new ClassifierControl(); 158 } 159 return controls; 160 } 161 162 /** Method to move a classifier in the list order. 163 * @param classifier the Classifier you want to move. 164 * @param direction true to move the classifier up, false to move it down. 165 * @param all true to move to move all the way, false for a single step. 166 */ 167 public void moveClassifier(Classifier classifier, boolean direction, boolean all) { 168 if(getSize() < 2) { 169 Gatherer.println("Not enough classifiers to allow moving."); 170 return; 171 } 172 if(all) { 173 // Move to top 174 if(direction) { 175 // Remove the moving classifier 176 remove(classifier); 177 // Retrieve the first classifier 178 Classifier first_classifier = (Classifier) getElementAt(0); 179 // Add the moving classifier before the first classifier 180 addBefore(classifier, first_classifier); 181 first_classifier = null; 182 Gatherer.c_man.configurationChanged(); 183 } 184 else { 185 // Remove the moving classifier 186 remove(classifier); 187 // And add after last classifier 188 add(getSize(), classifier); 189 } 190 } 191 else { 192 // Try to move the classifier one step in the desired direction. 193 int index = indexOf(classifier); 194 ///ystem.err.println("Index of " + classifier + " = " + index); 195 if(direction) { 196 index--; 197 if(index < 0) { 198 String args[] = new String[2]; 199 args[0] = get("CDM.ClassifierManager.Classifier"); 200 args[1] = classifier.getName(); 201 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.Move.At_Top", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 202 return; 203 } 204 remove(classifier); 205 add(index, classifier); 206 Gatherer.c_man.configurationChanged(); 207 } 208 else { 209 index++; 210 if(index >= getSize()) { 211 String args[] = new String[2]; 212 args[0] = get("CDM.ClassifierManager.Classifier_Str"); 213 args[1] = classifier.getName(); 214 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.Move.At_Bottom", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 215 return; 216 } 217 remove(classifier); 218 add(index, classifier); 219 Gatherer.c_man.configurationChanged(); 220 } 221 } 222 } 223 224 /** This method removes an assigned classifier. I was tempted to call it unassign, but remove is more consistant. Note that there is no way to remove a classifier from the library. 225 * @param classifier The Classifier to remove 137 226 * @see org.greenstone.gatherer.cdm.DynamicListModel 138 227 */ 139 public void addClassifier(Classifier classifier) { 140 if(!reserve.contains(classifier)) { 141 reserve.addElement(classifier); 142 } 143 } 144 /** Method to assign a classifier. 145 * @param classifier The reserve <strong>Classifier</strong> to assign. 146 * @see org.greenstone.gatherer.cdm.DynamicListModel 228 public void removeClassifier(Classifier classifier) { 229 remove(classifier); 230 Gatherer.c_man.configurationChanged(); 231 } 232 233 /** Method to cache the current contents of library (known classifiers) to file. 234 * @see org.greenstone.gatherer.util.Utility 235 */ 236 public void saveClassifiers() { 237 try { 238 FileOutputStream file = new FileOutputStream(Utility.BASE_DIR + "classifiers.dat"); 239 ObjectOutputStream out = new ObjectOutputStream(file); 240 out.writeObject(library); 241 out.close(); 242 } 243 catch (Exception error) { 244 } 245 } 246 247 /** Retrieve a phrase from the dictionary based on a certain key. 248 * @param key The search <strong>String</strong>. 249 * @return The matching phrase from the Dictionary. 147 250 */ 148 public void assignClassifier(Classifier classifier) { 149 if(!assigned.contains(classifier)) { 150 assigned.addElement(classifier); 151 classifier.setManager(this); 152 gatherer.c_man.configurationChanged(); 153 } 154 } 155 /** Method to assign a classifier. 156 * @param classifier The <strong>CustomClassifier</strong> to assign. 157 * @see org.greenstone.gatherer.cdm.DynamicListModel 251 private String get(String key) { 252 return get(key, (String[])null); 253 } 254 /** Retrieve a phrase from the dictionary based on a certain key and certain arguments. 255 * @param key The search <strong>String</strong>. 256 * @param args A <strong>String[]</strong> used to complete and format the returned phrase. 257 * @return The matching phrase from the Dictionary. 258 * @see org.greenstone.gatherer.Dictionary 259 * @see org.greenstone.gatherer.Gatherer 158 260 */ 159 public void assignClassifier(CustomClassifier classifier) { 160 if(!assigned.contains(classifier)) { 161 assigned.addElement(classifier); 162 classifier.setManager(this); 163 gatherer.c_man.configurationChanged(); 164 } 165 } 166 /** Destructor. 167 * @see org.greenstone.gatherer.Gatherer 168 * @see org.greenstone.gatherer.cdm.CollectionDesignManager 169 * @see org.greenstone.gatherer.cdm.DynamicListModel 170 */ 171 public void destroy() { 172 // Deregister as a listener 173 if(gatherer.c_man != null && gatherer.c_man.msm != null) { 174 gatherer.c_man.msm.removeMSMListener(this); 175 } 176 // Null globals 177 assigned = null; 178 controls = null; 179 gatherer = null; 180 manager = null; 181 reserve = null; 182 unresolved_commands = null; 183 } 184 /** Method to retrieve the classifier with the given index. 185 * @param index The index of the desired classifier as an <i>int</i>. 186 * @return The requested Classifier as an <strong>Object</strong> or <i>null</i> if no such classifier exists. 187 * @see org.greenstone.gatherer.cdm.DynamicListModel 188 */ 189 public Object getClassifier(int index) { 190 if(0 <= index && index < assigned.size()) { 191 return assigned.get(index); 192 } 193 return null; 194 } 195 /** Method to retrieve the named classifier. 196 * @param name The name of the desired classifier as a <strong>String</strong>. 197 * @return The requested <strong>Classifier</strong> or <i>null</i> if no such classifier exists. 198 * @see org.greenstone.gatherer.cdm.DynamicListModel 199 */ 200 public Classifier getClassifier(String name) { 201 for(int i = 0; i < reserve.size(); i++) { 202 Classifier classifier = (Classifier)reserve.get(i); 203 if(classifier.getName().equals(name)) { 204 return classifier; 205 } 206 } 207 // No success. 208 return null; 209 } 210 /** Method to retrieve the control for this manager. 211 * @return A <strong>JPanel</strong> containing the controls. 212 */ 213 public JPanel getControls() { 214 if(controls == null) { 215 controls = new Control(); 216 } 217 return controls; 218 } 219 /** Called whenever a metadata element changes significantly. 220 * @param event A <strong>MSMEvent</strong> choc' full of event informationy goodness. 221 */ 222 public void elementChanged(MSMEvent event) { 223 // Don't really care, as the elements dealt with here are all live references so changes like identifier change will propagate immediately. 224 } 225 /** Method to find the index of the given classifier within the assigned classifiers. 226 * @param classifier The <strong>Classifier</strong> whose index you wish to find. 227 * @return The index of the classifier as an <i>int</i>, which has a value of -1 if the classifier was not found. 228 * @see org.greenstone.gatherer.cdm.DynamicListModel 229 */ 230 public int indexOf(Classifier classifier) { 231 for(int i = 0; i < assigned.size(); i++) { 232 Object elem = assigned.get(i); 233 if (elem instanceof Classifier) { 234 Classifier sibling = (Classifier)elem; 235 if(sibling.equals(classifier)) { 236 return i; 237 } 238 } 239 } 240 return -1; 241 } 242 // these two methods assume that a custome classifier can never be the same as a classifier 243 public int indexOf(CustomClassifier classifier) { 244 for(int i = 0; i < assigned.size(); i++) { 245 Object elem = assigned.get(i); 246 if (elem instanceof CustomClassifier) { 247 CustomClassifier sibling = (CustomClassifier) assigned.get(i); 248 if(sibling.equals(classifier)) { 249 return i; 250 } 251 } 252 } 253 return -1; 254 } 255 /** Method to invalidate controls after a significant change in the system state. 256 */ 257 public void invalidateControls() { 258 if(controls != null) { 259 controls.destroy(); 260 } 261 controls = null; 262 } 261 private String get(String key, String arg) { 262 String[] args = null; 263 if(arg != null) { 264 args = new String[1]; 265 args[0] = arg; 266 } 267 return get(key, args); 268 } 269 270 private String get(String key, String[] args) { 271 if(key.indexOf(".") == -1) { 272 key = "CDM.ClassifierManager." + key; 273 } 274 return Gatherer.dictionary.get(key, args); 275 } 276 277 /** Method to extract just the classifiers name from a file object. 278 * @param classifier The <strong>File</strong> which references a certain classifier. 279 * @return A <strong>String</strong> containing just the classifiers name, without extension. 280 */ 281 private String getClassifierName(File classifier) { 282 String name = classifier.getName(); 283 if(name.indexOf(".") != -1) { 284 name = name.substring(0, name.indexOf(".")); 285 } 286 return name; 287 } 288 263 289 /** Method to load the details of a single plug-in. 264 265 266 p ublicvoid loadClassifier(File classifier) {290 * @param classifier The classifier <strong>File</strong> you wish to load. 291 */ 292 private void loadClassifier(File classifier) { 267 293 ///ystem.err.println("Attempting to parse " + classifier.toString()); 268 294 Document document = null; … … 274 300 if(Utility.isWindows()) { 275 301 args = new String[4]; 276 if( gatherer.config.perl_path != null) {277 args[0] = gatherer.config.perl_path;302 if(Gatherer.config.perl_path != null) { 303 args[0] = Gatherer.config.perl_path; 278 304 } 279 305 else { 280 306 args[0] = "Perl.exe"; 281 307 } 282 args[1] = gatherer.config.gsdl_path + "bin" + File.separator + "script" + File.separator + "classinfo.pl";308 args[1] = Gatherer.config.gsdl_path + "bin" + File.separator + "script" + File.separator + "classinfo.pl"; 283 309 args[2] = "-xml"; 284 310 args[3] = getClassifierName(classifier); … … 334 360 } 335 361 if(document != null) { 336 parse(document.getDocumentElement()); 337 } 338 } 339 /** Called whenever the metadata value associated to a certain record changes. */ 340 public void metadataChanged(MSMEvent event) { 341 FileNode record = event.getRecord(); 342 if(record != null) { 343 for(int i = 0; i < assigned.size(); i++) { 344 Object object = assigned.get(i); 345 if(object instanceof CustomClassifier) { 346 CustomClassifier classifier = (CustomClassifier) object; 347 if(!classifier.isProcessing()) { // are we already in the middle of processing?? 348 classifier.process(record); 349 } 350 } 351 } 352 } 353 } 354 /** This method attempts to parse a classifier command from a command string taken from the collection configuration file. This process is quite complex as not only must the correct classifier be matched but also all of the parameters given must be legal. If such a command is found, the classifier is immediately assigned. 355 * @param command The command <strong>String</strong> that may include classifier information. 356 * @return <i>true</i> if a classifier command was parsed, <i>false</i> otherwise. 357 * @see org.greenstone.gatherer.cdm.Argument 358 * @see org.greenstone.gatherer.cdm.Classifier 359 * @see org.greenstone.gatherer.cdm.CommandTokenizer 360 */ 361 public boolean parse(String command) { 362 String command_lc = command.toLowerCase(); 363 if(command_lc.startsWith("classify")) { 364 CommandTokenizer tokenizer = new CommandTokenizer(command); 365 if(tokenizer.countTokens() >= 2) { 366 tokenizer.nextToken(); // Throw away 'classifier' 367 String name = tokenizer.nextToken(); 368 // Try to locate the classifier with this name. 369 Classifier classifier = getClassifier(name); 370 // And if successful start to parse the arguments. 371 if(classifier != null) { 372 // Take a copy. 373 classifier = classifier.copy(); 374 String key = null; 375 while((key = tokenizer.nextToken()) != null) { 376 // Try to retrieve a matching argument. 377 Argument argument = classifier.getArgument(key); 378 if(argument != null) { 379 // Set as assigned. 380 argument.setAssigned(true); 381 // And if the argument is of a parameter type, parse a parameter. 382 if(argument.getType() != Argument.FLAG && tokenizer.hasMoreTokens()) { 383 String value = tokenizer.nextToken(); 384 ElementWrapper element = null; 385 // special check for metadata 386 if (argument.getType() == Argument.METADATA) { 387 value = value.replace(':', MSMUtils.NS_SEP); 388 if (value.indexOf(MSMUtils.NS_SEP)==-1){ 389 value = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + value; 390 } 391 // Now retrieve the element this refers to, if available. 392 element = Gatherer.c_man.getCollection().msm.getElement(value); 393 } 394 if(element != null) { 395 argument.setElementValue(element); 396 element = null; 397 } 398 else { 399 argument.setValue(value); 400 } 401 } 402 } 403 // Argument cannot be matched. 404 else { 405 String cur_key = key; 406 String value = tokenizer.nextToken(); 407 if(value.startsWith("-")) { 408 key = value; 409 value = null; 410 } 411 else { 412 key = null; 413 } 414 String custom = classifier.getCustom(); 415 if(custom == null) { 416 if(value == null) { 417 classifier.setCustom(cur_key); 418 } 419 else { 420 classifier.setCustom(cur_key + " " + value); 421 } 422 } 423 else { 424 if(value == null) { 425 classifier.setCustom(custom + " " + cur_key); 426 } 427 else { 428 classifier.setCustom(custom + " " + cur_key + " " + value); 429 } 430 } 431 } 432 } 433 assignClassifier(classifier); 434 return true; 435 } 436 else { 437 ///ystem.err.println("Unknown classifier"); 438 } 439 } 440 } 441 else if(command_lc.startsWith("customclassifier")) { 442 unresolved_commands.add(command); 443 return true; 444 } 445 return false; 446 } 447 /** This method removes an assigned classifier. I was tempted to call it unassign, but remove is more consistant. Note that there is no way to remove a classifier from the reserve. 448 * @param classifier The Classifier or CustomClassifier, as an <strong>Object</strong>, to remove. 449 * @see org.greenstone.gatherer.cdm.DynamicListModel 450 */ 451 public void removeClassifier(Object classifier) { 452 assigned.removeElement(classifier); 453 gatherer.c_man.configurationChanged(); 454 } 455 /** Method which attempts to reparse obvious classifier commands which previously referenced unresovable Classifiers. 456 * @see org.greenstone.gatherer.cdm.Classifier 457 * @see org.greenstone.gatherer.cdm.CommandTokenizer 458 * @see org.greenstone.gatherer.cdm.CustomClassifier 459 */ 460 public void reparseUnresolved() { 461 for(int i = 0; i < unresolved_commands.size(); i++) { 462 String command = (String) unresolved_commands.get(i); 463 CommandTokenizer tokenizer = new CommandTokenizer(command); 464 if(tokenizer.countTokens() >= 6) { 465 tokenizer.nextToken();// Lose customclassifier 466 // Get class name. 467 String class_name = tokenizer.nextToken(); 468 // Parse arguments. 469 String replaces = null; 470 String separations = null; 471 while(tokenizer.hasMoreTokens()) { 472 String arg_name = tokenizer.nextToken(); 473 if(arg_name.equalsIgnoreCase("-replaces")) { 474 replaces = tokenizer.nextToken(); 475 } 476 else if (arg_name.equalsIgnoreCase("-separations")){ 477 separations = tokenizer.nextToken(); 478 } 479 } 480 try { 481 replaces = replaces.substring(2); 482 int index = Integer.parseInt(replaces); 483 Classifier original = (Classifier)getClassifier(index); 484 if(original != null) { 485 Class custom_classifier_class = Class.forName("org.greenstone.gatherer.cdm.custom." + class_name); 486 CustomClassifier custom_classifier = (CustomClassifier) custom_classifier_class.newInstance(); 487 custom_classifier.setGatherer(gatherer); 488 custom_classifier.recreate(original, separations); 489 assigned.add(index, custom_classifier); 490 assigned.removeElement(original); 491 } 492 else { 493 ///ystem.err.println("Missing original."); 494 } 495 } 496 catch (Exception error) { 497 error.printStackTrace(); 498 } 499 } 500 } 501 // Regardless of if they work, clear the commands. 502 unresolved_commands.clear(); 503 } 504 /** Method to cache the current contents of reserve (known classifiers) to file. 505 * @see org.greenstone.gatherer.util.Utility 506 */ 507 public void saveClassifiers() { 508 try { 509 FileOutputStream file = new FileOutputStream(Utility.BASE_DIR + "classifiers.dat"); 510 ObjectOutputStream out = new ObjectOutputStream(file); 511 out.writeObject(reserve); 512 out.close(); 513 } 514 catch (Exception error) { 515 } 516 } 517 /** Called when a metadata set changed significantly. 518 * @param event A <strong>MSMEvent</strong> containing information about the set change. 519 */ 520 public void setChanged(MSMEvent event) { 521 // Again, we would only worry about this if we contained 'inanimate' references to elements or something, but our references are live, and controls are rebuilt everytime a pop-up is needed. 522 } 523 /** Method used to determine the number of classifiers that have been assigned. 524 * @return An <i>int</i> which is the number of classifiers. 525 */ 526 public int size() { 527 return assigned.size(); 528 } 529 /** Method to print out a block of classifier commands, much like you'd find in a collection configuration file. 530 * @return A <strong>String</strong> containing a series of classifier commands separated by new lines. 531 * @see org.greenstone.gatherer.cdm.Classifier 532 * @see org.greenstone.gatherer.cdm.CustomClassifier 533 */ 534 public String toString() { 535 StringBuffer text = new StringBuffer(); 536 for(int i = 0; i < assigned.size(); i++) { 537 Object object = assigned.get(i); 538 if(object instanceof Classifier) { 539 Classifier classifier = (Classifier) object; 540 text.append(classifier.toStringConfig()); 541 } 542 else if(object instanceof CustomClassifier) { 543 CustomClassifier classifier = (CustomClassifier) object; 544 text.append(classifier.getCommand()); 545 text.append("\n"); 546 text.append(classifier.getCustomCommand(i)); 547 } 548 text.append("\n"); 549 } 550 text.append("\n"); 551 return text.toString(); 552 } 553 /** Called when a significant change has occured to a value tree for a certain element, however we take no further action. 554 * @param event A <strong>MSMEvent</strong> containing information relevant to the event. 555 */ 556 public void valueChanged(MSMEvent event) { 557 } 558 /** Retrieve a phrase from the dictionary based on a certain key. 559 * @param key The search <strong>String</strong>. 560 * @return The matching phrase from the Dictionary. 561 */ 562 private String get(String key) { 563 return get(key, null); 564 } 565 /** Retrieve a phrase from the dictionary based on a certain key and certain arguments. 566 * @param key The search <strong>String</strong>. 567 * @param args A <strong>String[]</strong> used to complete and format the returned phrase. 568 * @return The matching phrase from the Dictionary. 569 * @see org.greenstone.gatherer.Dictionary 570 * @see org.greenstone.gatherer.Gatherer 571 */ 572 private String get(String key, String arg) { 573 String[] args = null; 574 if(arg != null) { 575 args = new String[1]; 576 args[0] = arg; 577 } 578 if(key.indexOf(".") == -1) { 579 key = "CDM.ClassifierManager." + key; 580 } 581 return gatherer.dictionary.get(key, args); 582 } 583 /** Method to extract just the classifiers name from a file object. 584 * @param classifier The <strong>File</strong> which references a certain classifier. 585 * @return A <strong>String</strong> containing just the classifiers name, without extension. 586 */ 587 private String getClassifierName(File classifier) { 588 String name = classifier.getName(); 589 if(name.indexOf(".") != -1) { 590 name = name.substring(0, name.indexOf(".")); 591 } 592 return name; 593 } 362 parseXML(document.getDocumentElement()); 363 } 364 } 365 594 366 /** Method to initially load information from the standard plug-ins within the gsdl Perl library. 595 * @see org.greenstone.gatherer.cdm.DynamicListModel 596 * @see org.greenstone.gatherer.util.Utility 597 */ 367 * @see org.greenstone.gatherer.util.Utility 368 */ 598 369 private void loadClassifiers() { 599 370 // Attempt to restore the cached file. … … 601 372 FileInputStream file = new FileInputStream(Utility.BASE_DIR + "classifiers.dat"); 602 373 ObjectInputStream input = new ObjectInputStream(file); 603 reserve = (DynamicListModel) input.readObject();374 library = (ArrayList) input.readObject(); 604 375 } 605 376 catch (Exception error) { 606 377 } 607 if( reserve== null) {608 reserve = new DynamicListModel();609 610 String directory = gatherer.config.gsdl_path;378 if(library == null) { 379 library = new ArrayList(); 380 // Retrieve the gsdl home directory... 381 String directory = Gatherer.config.gsdl_path; 611 382 directory = directory + "perllib" + File.separator + "classify" + File.separator; 612 loadClassifiers(new File(directory)); 613 } 614 } 615 /** Method to load plug-in information from a specified directory. Of course no plug-ins may be found at this location. 616 * @param directory A <strong>File</strong> indicating the directory to be scanned for plug-ins. 617 * @see org.greenstone.gatherer.cdm.ParsingProgress 618 */ 619 private void loadClassifiers(File directory) { 620 File files[] = directory.listFiles(); 621 if(files != null) { 622 // Create a progress indicator. 623 ParsingProgress progress = new ParsingProgress(get("CDM.ClassifierManager.Parsing.Title"), get("CDM.ClassifierManager.Parsing.Message"), files.length); 624 for(int i = 0; i < files.length; i++) { 625 // We only want to check Perl Modules. 626 if(files[i].getName().endsWith(".pm")) { 627 loadClassifier(files[i]); 628 } 629 progress.inc(); 630 } 631 progress.dispose(); 632 progress.destroy(); 633 progress = null; 634 } 635 } 383 File files[] = (new File(directory)).listFiles(); 384 if(files != null) { 385 // Create a progress indicator. 386 ParsingProgress progress = new ParsingProgress(get("CDM.ClassifierManager.Parsing.Title"), get("CDM.ClassifierManager.Parsing.Message"), files.length); 387 for(int i = 0; i < files.length; i++) { 388 // We only want to check Perl Modules. 389 if(files[i].getName().endsWith(".pm")) { 390 loadClassifier(files[i]); 391 } 392 progress.inc(); 393 } 394 progress.dispose(); 395 progress.destroy(); 396 progress = null; 397 } 398 } 399 } 400 636 401 /** Parses a DOM tree model turning it into a Classifier and its associated arguments. 637 402 * @param root The <strong>Node</strong> at the root of the DOM model. … … 639 404 * @see org.greenstone.gatherer.cdm.Argument 640 405 */ 641 private Classifier parse (Node root) {406 private Classifier parseXML(Node root) { 642 407 Classifier classifier = new Classifier(); 643 408 String node_name = null; … … 648 413 String name = MSMUtils.getValue(node); 649 414 // We can save ourselves some processing time if a classifier with this name already exists in our manager. If so retrieve it and return it. 650 Classifier existing = get Classifier(name);415 Classifier existing = getBaseClassifier(name); 651 416 if(existing != null) { 652 417 return existing; … … 655 420 } 656 421 else if(node_name.equals("Desc")) { 657 classifier.setDesc (MSMUtils.getValue(node));422 classifier.setDescription(MSMUtils.getValue(node)); 658 423 } 659 424 // Parse the multitude of arguments. … … 671 436 } 672 437 else if(node_name.equals("Desc")) { 673 argument.setDesc (MSMUtils.getValue(det));438 argument.setDescription(MSMUtils.getValue(det)); 674 439 } 675 440 else if(node_name.equals("Type")) { … … 677 442 } 678 443 else if(node_name.equals("Default")) { 679 argument.setDefault (MSMUtils.getValue(det));444 argument.setDefaultValue(MSMUtils.getValue(det)); 680 445 } 681 446 else if(node_name.equals("List")) { … … 713 478 // A super classifier class. 714 479 else if(node_name.equals("ClasInfo")) { 715 Classifier super_classifier = parse (arg);480 Classifier super_classifier = parseXML(arg); 716 481 classifier.setSuper(super_classifier); 717 482 } … … 726 491 } 727 492 /** A class which provides controls for assigned and editing classifiers. */ 728 private class Control 729 extends JPanel { 493 private class ClassifierControl 494 extends JPanel 495 implements Control { 496 /** A combobox containing all of the known classifiers, including those that may have already been assigned. */ 497 private GComboBox classifier = null; 730 498 /** Button for adding classifiers. */ 731 499 private JButton add = null; 732 500 /** Button for configuring the selected classifier. */ 733 501 private JButton configure = null; 502 503 private JButton move_bottom_button; 504 505 private JButton move_down_button; 506 507 private JButton move_top_button; 508 509 private JButton move_up_button; 510 734 511 /** Button to remove the selected classifier. */ 735 512 private JButton remove = null; 736 /** A combobox containing all of the known classifiers, including those that may have already been assigned. */ 737 private JComboBox classifier = null; 513 738 514 /** A list of assigned classifiers. */ 739 515 private JList classifier_list = null; … … 745 521 * @see org.greenstone.gatherer.cdm.ClassifierManager.Control.RemoveListener 746 522 */ 747 public Control() { 748 Object classifiers[] = reserve.toArray(); 749 ArrayList classifier_model = new ArrayList(); 750 for(int i = 0; i < classifiers.length; i++) { 751 classifier_model.add(((Classifier)classifiers[i]).getName()); 752 } 753 // Now we add custom classifiers. 754 addCustomClassifiers(classifier_model); 755 Collections.sort(classifier_model); 523 public ClassifierControl() { 524 Collections.sort(library); 756 525 // Create 757 526 add = new JButton(get("Add")); … … 766 535 instructions.setRows(5); 767 536 instructions.setWrapStyleWord(true); 768 classifier = new JComboBox(classifier_model.toArray()); 769 classifier.setEditable(false); 537 538 classifier = new GComboBox(library.toArray()); 539 classifier.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.editable", false)); 540 classifier.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false)); 541 classifier.setEditable(true); 542 classifier.setSelectedIndex(0); 543 classifier.setTextNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_foreground", false)); 544 classifier.setTextSelectionColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false)); 545 770 546 JLabel classifier_label = new JLabel(get("Classifier")); 771 classifier_list = new JList( assigned);547 classifier_list = new JList(model); 772 548 classifier_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 773 549 JLabel classifier_list_label = new JLabel(get("Assigned")); … … 782 558 title.setOpaque(true); 783 559 JPanel temp = new JPanel(new BorderLayout()); 560 561 JPanel move_button_pane = new JPanel(); 562 563 move_bottom_button = new JButton(); 564 JLabel move_bottom_label = new JLabel(get("CDM.Move.Move_Bottom")); 565 move_bottom_label.setHorizontalAlignment(JLabel.CENTER); 566 move_bottom_label.setPreferredSize(LABEL_SIZE); 567 ImageIcon move_bottom_icon = Utility.getImage("arrow-bottom.gif"); 568 move_bottom_button.setLayout(new BorderLayout()); 569 move_bottom_button.add(new JLabel(move_bottom_icon), BorderLayout.WEST); 570 move_bottom_button.add(move_bottom_label, BorderLayout.CENTER); 571 move_bottom_button.add(new JLabel(move_bottom_icon), BorderLayout.EAST); 572 move_bottom_button.setMnemonic(KeyEvent.VK_B); 573 574 move_down_button = new JButton(); 575 JLabel move_down_label = new JLabel(get("CDM.Move.Move_Down")); 576 move_down_label.setHorizontalAlignment(JLabel.CENTER); 577 move_down_label.setPreferredSize(LABEL_SIZE); 578 ImageIcon move_down_icon = Utility.getImage("arrow-down.gif"); 579 move_down_button.setLayout(new BorderLayout()); 580 move_down_button.add(new JLabel(move_down_icon), BorderLayout.WEST); 581 move_down_button.add(move_down_label, BorderLayout.CENTER); 582 move_down_button.add(new JLabel(move_down_icon), BorderLayout.EAST); 583 move_down_button.setMnemonic(KeyEvent.VK_D); 584 585 move_top_button = new JButton(); 586 JLabel move_top_label = new JLabel(get("CDM.Move.Move_Top")); 587 move_top_label.setHorizontalAlignment(JLabel.CENTER); 588 move_top_label.setPreferredSize(LABEL_SIZE); 589 ImageIcon move_top_icon = Utility.getImage("arrow-top.gif"); 590 move_top_button.setLayout(new BorderLayout()); 591 move_top_button.add(new JLabel(move_top_icon), BorderLayout.WEST); 592 move_top_button.add(move_top_label, BorderLayout.CENTER); 593 move_top_button.add(new JLabel(move_top_icon), BorderLayout.EAST); 594 move_top_button.setMnemonic(KeyEvent.VK_T); 595 596 move_up_button = new JButton(); 597 JLabel move_up_label = new JLabel(get("CDM.Move.Move_Up")); 598 move_up_label.setHorizontalAlignment(JLabel.CENTER); 599 move_up_label.setPreferredSize(LABEL_SIZE); 600 ImageIcon move_up_icon = Utility.getImage("arrow-up.gif"); 601 move_up_button.setLayout(new BorderLayout()); 602 move_up_button.add(new JLabel(move_up_icon), BorderLayout.WEST); 603 move_up_button.add(move_up_label, BorderLayout.CENTER); 604 move_up_button.add(new JLabel(move_up_icon), BorderLayout.EAST); 605 move_up_button.setMnemonic(KeyEvent.VK_U); 606 784 607 // Listeners 785 608 add.addActionListener(new AddListener()); … … 788 611 classifier_list.addMouseListener(new ClickListener()); 789 612 classifier_list.addListSelectionListener(new ListListener()); 613 614 MoveListener ml = new MoveListener(); 615 move_bottom_button.addActionListener(ml); 616 move_down_button.addActionListener(ml); 617 move_top_button.addActionListener(ml); 618 move_up_button.addActionListener(ml); 790 619 // Layout 791 620 title.setBorder(BorderFactory.createEmptyBorder(0,0,2,0)); 621 792 622 instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5)); 623 793 624 header_pane.setLayout(new BorderLayout()); 794 625 header_pane.add(title, BorderLayout.NORTH); 795 626 header_pane.add(new JScrollPane(instructions), BorderLayout.CENTER); 627 628 move_button_pane.setLayout(new GridLayout(4,1)); 629 move_button_pane.add(move_top_button); 630 move_button_pane.add(move_up_button); 631 move_button_pane.add(move_down_button); 632 move_button_pane.add(move_bottom_button); 633 796 634 classifier_list_label.setBorder(BorderFactory.createEmptyBorder(0,2,0,2)); 635 797 636 classifier_list_pane.setLayout(new BorderLayout()); 798 637 classifier_list_pane.add(classifier_list_label, BorderLayout.NORTH); 799 638 classifier_list_pane.add(new JScrollPane(classifier_list), BorderLayout.CENTER); 639 classifier_list_pane.add(move_button_pane, BorderLayout.EAST); 640 800 641 classifier_label.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); 642 801 643 classifier_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0)); 802 644 classifier_pane.setLayout(new GridLayout(1,2)); 803 645 classifier_pane.add(classifier_label); 804 646 classifier_pane.add(classifier); 647 805 648 button_pane.setLayout(new GridLayout(3,1)); 806 649 button_pane.add(add); 807 650 button_pane.add(configure); 808 651 button_pane.add(remove); 652 809 653 // Scope these mad bordering skillz. 810 654 temp.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,0,5,0), BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Controls")), BorderFactory.createEmptyBorder(2,2,2,2)))); 811 655 temp.add(classifier_pane, BorderLayout.NORTH); 812 656 temp.add(button_pane, BorderLayout.SOUTH); 657 813 658 central_pane.setLayout(new BorderLayout()); 814 659 central_pane.add(classifier_list_pane, BorderLayout.CENTER); 815 660 central_pane.add(temp, BorderLayout.SOUTH); 661 816 662 setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 817 663 setLayout(new BorderLayout()); … … 831 677 /** This method is overridden to ensure the instructions are scrolled to top, before the super classes updateUI() is called. 832 678 */ 833 public void updateUI() {679 public void gainFocus() { 834 680 if(instructions != null) { 835 681 instructions.setCaretPosition(0); 836 682 } 837 super.updateUI(); 838 } 839 /** Searches and adds a list of dynamically located CustomClassifiers. Note that the classes must be located under org.greenstone.gatherer.cdm.custom and have accompaning properties files which are used as dictionaries. 840 * @param classifier_model An <strong>ArrayList</strong> which will be used as the model for the combobox listing all known Classifiers. 841 */ 842 private void addCustomClassifiers(ArrayList classifier_model) { 843 //classifier_model.add("CustomAZList"); 844 // Search for classifiers under the org.greenstone.gatherer.cdm.custom directory. 845 File custom_directory = new File(Utility.BASE_DIR + "classes" + File.separator + "org" + File.separator + "greenstone" + File.separator + "gatherer" + File.separator + "cdm" + File.separator + "custom"); 846 if(custom_directory.exists()) { 847 File children[] = custom_directory.listFiles(); 848 for(int i = 0; i < children.length; i++) { 849 String temp = children[i].getName().toLowerCase(); 850 // There are a whole bunch of conditions about what files are custom classifier main classes. 851 if(temp.endsWith(".class") && temp.indexOf("$") == -1) { 852 // Determine the name of this custom classifier. 853 String name = children[i].getName(); 854 name = name.substring(0, name.indexOf(".")); 855 classifier_model.add(name); 856 } 857 } 858 } 859 // Search for any other CustomClassifiers within the jar file (if present) 860 File jar_file = new File(Utility.GLI_ARCHIVE); 861 if(jar_file.exists()) { 862 try { 863 JarFile jar = new JarFile(jar_file); 864 for(Enumeration entries = jar.entries(); entries.hasMoreElements(); ) { 865 String name = entries.nextElement().toString(); 866 if(name.startsWith("org/greenstone/gatherer/cdm/custom/") && name.endsWith(".class") && name.indexOf("$") == -1) { 867 name = name.substring(35, name.length() - 6); 868 if(!classifier_model.contains(name)) { 869 classifier_model.add(name); 870 } 871 } 872 name = null; 873 } 874 jar = null; 875 } 876 catch (Exception error) { 877 error.printStackTrace(); 878 } 879 } 880 jar_file = null; 881 } 683 } 684 685 public void loseFocus() { 686 } 687 882 688 /** This class listens for actions upon the add button in the controls, and if detected calls the assignClassifier() method. 883 689 */ 884 690 private class AddListener 885 691 implements ActionListener { … … 892 698 */ 893 699 public void actionPerformed(ActionEvent event) { 894 String name = (String)classifier.getSelectedItem(); 895 Classifier target = getClassifier(name); 896 Classifier classifier = null; 897 CustomClassifier custom_classifier = null; 898 if(target != null) { 899 classifier = target.copy(); 900 } 901 else { 902 // Try to retrieve custom classifier for name. 903 try { 904 Class custom_class = Class.forName("org.greenstone.gatherer.cdm.custom." + name); 905 custom_classifier = (CustomClassifier)custom_class.newInstance(); 906 custom_classifier.setGatherer(gatherer); 907 } 908 catch (Exception error) { 909 Gatherer.println("Error in ClassifierManager.AddListener.actionPerformed(): " + error); 910 Gatherer.printStackTrace(error); 911 912 } 913 // And if all else fails create a new classifier. 914 if(classifier == null && custom_classifier == null) { 915 classifier = new Classifier(name, "", null); 916 } 917 } 918 if(classifier != null) { 700 Object selected_object = classifier.getSelectedItem(); 701 // If there is something in the combobox, but we haven't registered a selection, then add the object and select it! 702 if(selected_object != null && classifier.getSelectedIndex() == -1) { 703 classifier.insertItemAt(selected_object, classifier.getItemCount()); 704 } 705 if(selected_object != null) { 706 // Create a new element in the DOM 707 Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.CLASSIFY_ELEMENT); 708 Classifier new_classifier = null; 709 if(selected_object instanceof Classifier) { 710 Classifier base_classifier = (Classifier) selected_object; 711 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, base_classifier.getName()); 712 new_classifier = new Classifier(element, base_classifier); 713 base_classifier = null; 714 } 715 else { 716 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, selected_object.toString()); 717 new_classifier = new Classifier(element, null); 718 } 719 element = null; 919 720 // Automatically chain to configuration. This ensures required arguments are filled out. 920 ArgumentConfiguration ac = new ArgumentConfiguration( gatherer, manager,classifier);721 ArgumentConfiguration ac = new ArgumentConfiguration(new_classifier); 921 722 if(ac.display()) { 922 assignClassifier(classifier); 923 } 924 ac.destroy(); 723 if(!model.contains(new_classifier)) { 724 assignClassifier(new_classifier); 725 classifier_list.setSelectedValue(new_classifier, true); 726 } 727 else { 728 JOptionPane.showMessageDialog(Gatherer.g_man, get("Classifier_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE); 729 } 730 } 925 731 ac = null; 926 } 927 // Custom classifier 928 else { 929 // Spawn a new thread to handle this, as custom_classifiers can be processor heavy. 930 CustomClassifierTask task = new CustomClassifierTask(custom_classifier); 931 task.start(); 732 new_classifier = null; 733 classifier.setSelectedIndex(0); 932 734 } 933 735 } … … 936 738 private class ClickListener 937 739 extends MouseAdapter { 938 939 940 740 /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt. 741 * @param event A <strong>MouseEvent</strong> containing information about the mouse click. 742 */ 941 743 public void mouseClicked(MouseEvent event) { 942 744 if(event.getClickCount() == 2 ) { 943 745 if(!classifier_list.isSelectionEmpty()) { 944 Object object = classifier_list.getSelectedValue(); 945 if(object instanceof Classifier) { 946 ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, (Classifier)object); 947 if(ac.display()) { 948 assigned.refresh(); 949 } 950 ac.destroy(); 951 ac = null; 746 Classifier classifier = (Classifier) classifier_list.getSelectedValue(); 747 ArgumentConfiguration ac = new ArgumentConfiguration(classifier); 748 if(ac.display()) { 749 refresh(classifier); 952 750 } 953 else if(object instanceof CustomClassifier) { 954 CustomClassifier cc = (CustomClassifier)object; 955 if(cc.display(true)) { 956 assigned.refresh(); 957 } 958 cc.hide(); // Remove gui prompt or else. 959 cc = null; 960 } 751 ac.destroy(); 752 ac = null; 961 753 } 962 754 } … … 975 767 public void actionPerformed(ActionEvent event) { 976 768 if(!classifier_list.isSelectionEmpty()) { 977 Object object = classifier_list.getSelectedValue(); 978 if(object instanceof Classifier) { 979 ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, (Classifier)object); 980 if(ac.display()) { 981 assigned.refresh(); 982 } 983 ac.destroy(); 984 ac = null; 985 } 986 else if(object instanceof CustomClassifier) { 987 CustomClassifier cc = (CustomClassifier)object; 988 if(cc.display(true)) { 989 assigned.refresh(); 990 } 991 cc.hide(); // Remove gui prompt or else. 992 cc = null; 993 } 994 } 995 } 996 } 997 998 private class CustomClassifierTask 999 extends Thread { 1000 1001 private CustomClassifier custom_classifier; 1002 1003 CustomClassifierTask(CustomClassifier custom_classifier) { 1004 this.custom_classifier = custom_classifier; 1005 } 1006 1007 public void run() { 1008 if(custom_classifier.display(true)) { 1009 assignClassifier(custom_classifier); 1010 } 1011 custom_classifier.hide(); // Remove gui prompt or else. 1012 custom_classifier = null; 769 Classifier classifier = (Classifier) classifier_list.getSelectedValue(); 770 ArgumentConfiguration ac = new ArgumentConfiguration(classifier); 771 if(ac.display()) { 772 refresh(classifier); 773 } 774 ac.destroy(); 775 ac = null; 776 } 1013 777 } 1014 778 } … … 1030 794 } 1031 795 } 796 797 /** Listens for actions apon the move buttons in the manager controls, and if detected calls the <i>moveClassifier()</i> method of the manager with the appropriate details. */ 798 private class MoveListener 799 implements ActionListener { 800 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls. 801 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action. 802 */ 803 public void actionPerformed(ActionEvent event) { 804 if(!classifier_list.isSelectionEmpty()) { 805 Object object = classifier_list.getSelectedValue(); 806 if(object instanceof Classifier) { 807 Classifier classifier = (Classifier) object; 808 if(event.getSource() == move_top_button) { 809 moveClassifier(classifier, true, true); 810 } 811 else if(event.getSource() == move_up_button) { 812 moveClassifier(classifier, true, false); 813 } 814 else if(event.getSource() == move_down_button) { 815 moveClassifier(classifier, false, false); 816 } 817 else { 818 moveClassifier(classifier, false, true); 819 } 820 classifier_list.setSelectedValue(classifier, true); 821 } 822 } 823 } 824 } 825 1032 826 /** This class listens for actions upon the remove button in the controls, and if detected calls the removeClassifier() method. 1033 827 */ … … 1041 835 public void actionPerformed(ActionEvent event) { 1042 836 if(!classifier_list.isSelectionEmpty()) { 1043 Object object = classifier_list.getSelectedValue(); 1044 if(object instanceof Classifier || object instanceof CustomClassifier) { 1045 removeClassifier(object); 837 Object [] objects = classifier_list.getSelectedValues(); 838 for(int i = 0; i < objects.length; i++) { 839 if(objects[i] instanceof Classifier) { 840 removeClassifier((Classifier)objects[i]); 841 } 1046 842 } 1047 843 } … … 1050 846 } 1051 847 } 1052 1053 1054 1055 1056 1057 -
trunk/gli/src/org/greenstone/gatherer/cdm/CollectionDesignManager.java
r4675 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 /************************************************************************************** 46 * Title: Gatherer 47 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 48 * Company: The University of Waikato 49 * Written: 02/05/02 50 * Revised: 16/08/02 Optimized and added Destructor. 51 **************************************************************************************/ 52 import java.awt.BorderLayout; 53 import java.awt.Rectangle; 54 import java.io.BufferedReader; 55 import java.io.File; 56 import java.io.FileReader; 57 import java.io.FileOutputStream; 58 import java.lang.Exception; 59 import java.lang.String; 60 import java.lang.StringBuffer; 61 import java.util.ArrayList; 62 import java.util.StringTokenizer; 63 import javax.swing.JPanel; 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.io.*; 31 import javax.swing.*; 32 import javax.swing.event.*; 64 33 import org.greenstone.gatherer.Gatherer; 65 34 import org.greenstone.gatherer.cdm.ClassifierManager; 35 import org.greenstone.gatherer.cdm.CollectionConfiguration; 66 36 import org.greenstone.gatherer.cdm.CollectionMetaManager; 67 37 import org.greenstone.gatherer.cdm.FormatManager; 68 import org.greenstone.gatherer.cdm.GUI; 69 import org.greenstone.gatherer.cdm.Index; 38 import org.greenstone.gatherer.cdm.GeneralManager; 70 39 import org.greenstone.gatherer.cdm.IndexManager; 71 import org.greenstone.gatherer.cdm.MetadataSet Manager;40 import org.greenstone.gatherer.cdm.MetadataSetView; 72 41 import org.greenstone.gatherer.cdm.PlugInManager; 73 42 import org.greenstone.gatherer.cdm.SubcollectionManager; 74 import org.greenstone.gatherer. util.EmailAddress;43 import org.greenstone.gatherer.cdm.TranslationView; 75 44 /** This manager provides access to submanagers, which in turn provide tools for the designing of Greenstone collections via the information stored in etc/collect.cfg. This class acts as a hub for the managers that handle specific parts of the configuration such as classifiers, format strings and language settings. 76 45 * @author John Thompson, Greenstone Digital Library, University of Waikato 77 * @version 2.3 46 * @version 2.3d 78 47 */ 79 // ####################################################################################80 // Optimization Saving81 // ####################################################################################82 // Vector -> ArrayList + Processor83 // String -> StringBuffer + Memory, + Processor84 // ####################################################################################85 48 public class CollectionDesignManager { 86 /** Whether this collection is to be made public or not. */ 87 public boolean public_col = false; 88 /** Whether this collection is a beta version or not. */ 89 public boolean beta = true; 49 /** This listener listens for any event on any of the components in any of the sub-views, and marks the collection as needing saving if any change occurs. */ 50 static public CDMChangeListener change_listener; 90 51 /** A list of classifiers to use at build time. */ 91 public ClassifierManager classifiers = null; 52 static public ClassifierManager classifier_manager; 53 /** The CollectionConfiguration object on which this CDM will be based. */ 54 static public CollectionConfiguration collect_config; 92 55 /** A manager of collection level metadata. */ 93 public CollectionMetaManager collectionmetadatum = null; 94 /** E-mail address of the collection's creator. */ 95 public EmailAddress creator = null; 96 /** E-mail address of the collection's maintainer. */ 97 public EmailAddress maintainer = null; 98 /** The collection configuration file. */ 99 public File in_file = null; 56 static public CollectionMetaManager collectionmeta_manager; 100 57 /** A list of formating strings to use at build time. */ 101 public FormatManager formats = null;58 static public FormatManager format_manager; 102 59 /** The manager in charge of displaying this manager and the controls for other managers. */ 103 public GUI gui = null;60 static public GeneralManager general_manager; 104 61 /** List of indexes to be built, and the default index. */ 105 public IndexManager indexes = null;62 static public IndexManager index_manager; 106 63 /** Contains instructions dealing with the collection language. */ 107 public LanguageManager languages = null;64 static public LanguageManager language_manager; 108 65 /** A simple manager for the visual review of metadata sets. */ 109 public MetadataSetManager metadatasets = null;66 static public MetadataSetView metadataset_view; 110 67 /** A list of plugins to use at build time. */ 111 public PlugInManager plugins = null;68 static public PlugInManager plugin_manager; 112 69 /** Contains: A list of subcollections, (defined on metadatadata), a list of which subcollection indexes to build and the default subcollection index. */ 113 public SubcollectionManager subcollections = null; 70 static public SubcollectionManager subcollection_manager; 71 72 static public SubcollectionIndexManager subcollectionindex_manager; 114 73 /** A supercollection command allows a single search to be conducted across several collections. It is a very basic command and so avoids all the crazy model stuff that exists in most of the design managers. */ 115 public SuperCollectionManager superman; // Just cause I could ;p74 static public SuperCollectionManager supercollection_manager; // Just cause I could ;p 116 75 /** The text translation manager. */ 117 public TranslationManager transman; 118 /** A list of whatever commands could not be parsed at all. */ 119 private ArrayList rest = null; 120 /** A reference to the Gatherer. */ 121 private Gatherer gatherer = null; 122 /** Constructor. 123 * @param gatherer The <strong>Gatherer</strong> that created this class. 124 * @see org.greenstone.gatherer.cdm.ClassifierManager 125 * @see org.greenstone.gatherer.cdm.CollectionMetaManager 126 * @see org.greenstone.gatherer.cdm.FormatManager 127 * @see org.greenstone.gatherer.cdm.IndexManager 128 * @see org.greenstone.gatherer.cdm.LanguageManager 129 * @see org.greenstone.gatherer.cdm.MetadataSetManager 130 * @see org.greenstone.gatherer.cdm.PlugInManager 131 * @see org.greenstone.gatherer.cdm.SubcollectionManager 132 */ 133 public CollectionDesignManager() { 134 this.gatherer = Gatherer.self; 135 this.classifiers = new ClassifierManager(gatherer, this); 136 this.collectionmetadatum = new CollectionMetaManager(gatherer, this); 137 this.formats = new FormatManager(gatherer, this); 138 this.indexes = new IndexManager(gatherer, this); 139 this.languages = new LanguageManager(gatherer, this); 140 this.metadatasets = new MetadataSetManager(gatherer); 141 this.plugins = new PlugInManager(gatherer, this); 142 this.rest = new ArrayList(); 143 this.subcollections = new SubcollectionManager(gatherer, this); 144 this.superman = new SuperCollectionManager(); 145 this.transman = new TranslationManager(this); 146 } 147 /** In order to prevent Components that have registered themselves wasting memory, this method invalidates each of the sub-managers controls, causing them to unregister listeners. 148 * @see org.greenstone.gatherer.cdm.ClassifierManager 149 * @see org.greenstone.gatherer.cdm.CollectionMetaManager 150 * @see org.greenstone.gatherer.cdm.FormatManager 151 * @see org.greenstone.gatherer.cdm.IndexManager 152 * @see org.greenstone.gatherer.cdm.LanguageManager 153 * @see org.greenstone.gatherer.cdm.MetadataSetManager 154 * @see org.greenstone.gatherer.cdm.PlugInManager 155 * @see org.greenstone.gatherer.cdm.SubcollectionManager 76 static public TranslationView translation_view; 77 /** Constructor. Loads a certain collection configuration file, which is parsed into a DOM. This model is then registered with the command information managers, each of whom knows how to, and provides controls to, alter certain commands. 78 * @param collect_config_file the File representing a collection configuration file either in its text (G2) or xml (G3) form 79 */ 80 public CollectionDesignManager(File collect_config_file) { 81 Gatherer.println("Initializaing CollectionDesignModule."); 82 change_listener = new CDMChangeListener(); 83 // Parse the collection configuration 84 collect_config = new CollectionConfiguration(collect_config_file); 85 if(Gatherer.debug != null) { 86 collect_config.display(); 87 } 88 // Create the command information managers, registering the config file with each as necessary 89 language_manager = new LanguageManager(collect_config.getLanguages()); 90 collectionmeta_manager = new CollectionMetaManager(); 91 classifier_manager = new ClassifierManager(); 92 general_manager = new GeneralManager(); 93 index_manager = new IndexManager(collect_config.getIndexes()); 94 metadataset_view = new MetadataSetView(); 95 plugin_manager = new PlugInManager(); 96 plugin_manager.placeSeparator(); 97 subcollection_manager = new SubcollectionManager(); 98 subcollectionindex_manager = new SubcollectionIndexManager(collect_config.getSubIndexes()); 99 supercollection_manager = new SuperCollectionManager(collect_config.getSuperCollection()); 100 translation_view = new TranslationView(); 101 format_manager = new FormatManager(); // Parse formats at the very end, given that they depend upon several other managers to appear properly. 102 Gatherer.println("CollectionDesignModule loaded."); 103 } 104 /** This method deconstructs each of the managers, causing them to dispose of their controls. 156 105 */ 157 106 public void destroy() { 158 107 // Remove visual the component from its parent. 159 if(g ui.getParent() != null) {160 g ui.getParent().remove(gui);108 if(general_manager.getParent() != null) { 109 general_manager.getParent().remove(general_manager); 161 110 } 162 111 // Remove references from persistant listeners. 163 if(classifiers != null && formats != null && gui != null && indexes != null && languages != null && metadatasets != null && plugins != null && subcollections != null) { 164 classifiers.invalidateControls(); 165 formats.invalidateControls(); 166 gui.invalidateControls(); 167 indexes.invalidateControls(); 168 languages.invalidateControls(); 169 metadatasets.invalidateControls(); 170 plugins.invalidateControls(); 171 subcollections.invalidateControls(); 172 superman.invalidateControls(); 173 } 174 // Null globals. 175 classifiers = null; 176 collectionmetadatum = null; 177 creator = null; 178 maintainer = null; 179 in_file = null; 180 formats = null; 181 gui = null; 182 indexes = null; 183 languages = null; 184 metadatasets = null; 185 plugins = null; 186 subcollections = null; 187 superman = null; 188 rest = null; 189 gatherer = null; 112 classifier_manager.destroy(); 113 classifier_manager = null; 114 format_manager.destroy(); 115 format_manager = null; 116 general_manager.destroy(); 117 general_manager = null; 118 index_manager.destroy(); 119 index_manager = null; 120 language_manager.destroy(); 121 language_manager = null; 122 metadataset_view.destroy(); 123 metadataset_view = null; 124 plugin_manager.destroy(); 125 plugin_manager = null; 126 subcollection_manager.destroy(); 127 subcollection_manager = null; 128 supercollection_manager.destroy(); 129 supercollection_manager = null; 130 translation_view.destroy(); 131 translation_view = null; 190 132 } 191 133 192 134 /** Display the GUI interface for the CollectionDesignManager in the centre of the indicated panel. 193 * @param target The <strong>JPanel</strong> you wish to display the GUI on. 194 * @see org.greenstone.gatherer.cdm.GUI 135 * @param target the JPanel you wish to display the gui on 195 136 */ 196 137 public void display(JPanel target) { 197 this.gui = new GUI(gatherer, this); 198 target.add(gui, BorderLayout.CENTER); 138 target.add(general_manager, BorderLayout.CENTER); 199 139 } 200 140 /** When the tab on the JTabbedPane that contains the GUI is selected, this method is called to ensure that the controls are all up to date, in terms of references to metadata etc. 201 * @see org.greenstone.gatherer.cdm.GUI202 141 */ 203 142 public void gainFocus() { 204 gui.updateUI(); 205 } 206 /** Retrieve the current set of indexes as defined by the user configuration. 207 * @return An <strong>ArrayList</strong> of indexes. 208 * @see org.greenstone.gatherer.cdm.Index 209 * @see org.greenstone.gatherer.cdm.IndexManager 210 */ 211 public ArrayList getIndexes() { 212 ArrayList result = new ArrayList(); 213 int size = indexes.size(); 214 for(int i = 0; i < size; i++) { 215 result.add(indexes.getIndex(i)); 216 } 217 return result; 143 general_manager.gainFocus(); 218 144 } 219 145 /** Retrieve the name of the collection configuration file which is being used as the source of the information in this object. … … 221 147 */ 222 148 public String getFilename() { 223 return in_file.getAbsolutePath();224 } 225 /** Used to parse the given file as if it was a collection configuration file, passing any parsed commands to the relevant submanager. Currently ignores any comments, and marks any other lines as being unrecognizable if they can't be parsed. 226 * @param filename The name of the file you wish to attempt to pass as a <strong>String</strong>.149 return collect_config.getFile().getAbsolutePath(); 150 } 151 152 /** Cause the current collection configuration to be written out to disk. 227 153 * @see org.greenstone.gatherer.cdm.ClassifierManager 228 154 * @see org.greenstone.gatherer.cdm.CollectionMetaManager … … 235 161 * @see org.greenstone.gatherer.util.EmailAddress 236 162 */ 237 private BufferedReader in;238 /** If one of the submanagers detects that it hasn't been provided enough arguments (such as format which always requires at least three) it can call this method to request another line of text from the collect.cfg. If the collect.cfg was not well formed this will cause some problems, but that can't be helped.239 * @param prefix the String we have so far240 * @return a String with a further line form the collect.cfg appended241 */242 public String parseMore(String prefix) {243 ///ystem.err.println("Command incomplete: " + prefix);244 try {245 String suffix = in.readLine();246 ///ystem.err.println("Adding: " + suffix);247 if(suffix != null) {248 prefix = prefix + " " + suffix;249 }250 suffix = null;251 }252 catch(Exception error) {253 error.printStackTrace();254 }255 return prefix;256 }257 258 public void parse(String filename) {259 try {260 in_file = new File(filename);261 FileReader in_reader = new FileReader(in_file);262 in = new BufferedReader(in_reader);263 String command = null;264 while((command = in.readLine()) != null) {265 if(command.length() > 0) {266 // Now we've finished parsing a command line, see what manager wants a piece of it.267 // We have to test the end of command for the special character '\'. If found, remove it and append the next line, then repeat.268 while(command.trim().endsWith("\\")) {269 String next_line = (in.readLine()).trim();270 if(next_line != null && next_line.length() > 0) {271 command = command.substring(0, command.lastIndexOf("\\"));272 command = command + next_line;273 }274 }275 // Now we've finished parsing a command line, see what manager wants a piece of it.276 boolean found = false;277 String command_lc = command.toLowerCase();278 if(command_lc.startsWith("creator")) {279 creator = new EmailAddress(gatherer, command);280 found = true;281 }282 if(command_lc.startsWith("maintainer")) {283 maintainer = new EmailAddress(gatherer, command);284 found = true;285 }286 if(command_lc.startsWith("public")) {287 if(command_lc.endsWith("true")) {288 public_col = true;289 }290 else {291 public_col = false;292 }293 found = true;294 }295 if(command_lc.startsWith("beta")) {296 if(command_lc.endsWith("false")) {297 beta = false;298 }299 else {300 beta = true;301 }302 found = true;303 }304 if(!found) {305 found = indexes.parse(command);306 }307 if(!found) {308 found = subcollections.parse(command, false);309 }310 if(!found) {311 found = languages.parse(command);312 }313 if(!found) {314 found = plugins.parse(command);315 }316 if(!found) {317 found = classifiers.parse(command);318 }319 if(!found) {320 found = formats.parse(command, false);321 }322 if(!found) {323 found = collectionmetadatum.parse(command, false);324 }325 if(!found) {326 found = superman.parse(command);327 }328 // Metadataset commands329 if(command_lc.startsWith("metadataset")) {330 // Nothing yet. Eventually used to import metadata.331 found = true;332 }333 // Comments we ignore.334 if(command_lc.startsWith("# these instructions are not recognized by the gatherer.")) {335 // Ignore336 found = true;337 }338 // We have been unable to parse this command, add it to rest.339 if(!found) {340 rest.add(command);341 }342 }343 }344 in.close();345 // Now attempt to finalize any commands that were not immediately parsed as they were waiting for unresolved references.346 subcollections.reparseUnresolved();347 classifiers.reparseUnresolved();348 formats.reparseUnresolved();349 collectionmetadatum.reparseUnresolved();350 }351 catch(Exception error) {352 error.printStackTrace();353 }354 }355 /** Cause the current definitions within the Collection Design Manager to be written back out to whatever collect.cfg it is based upon, taking care to change reference pointers into something more sensible within the text file.356 * @see org.greenstone.gatherer.cdm.ClassifierManager357 * @see org.greenstone.gatherer.cdm.CollectionMetaManager358 * @see org.greenstone.gatherer.cdm.FormatManager359 * @see org.greenstone.gatherer.cdm.IndexManager360 * @see org.greenstone.gatherer.cdm.LanguageManager361 * @see org.greenstone.gatherer.cdm.MetadataSetManager362 * @see org.greenstone.gatherer.cdm.PlugInManager363 * @see org.greenstone.gatherer.cdm.SubcollectionManager364 * @see org.greenstone.gatherer.util.EmailAddress365 */366 163 public void save() { 367 try { 368 // If the file already exists (it should) rename it. 369 if(in_file.exists()) { 370 String filename = in_file.getAbsolutePath(); 371 File backup = new File(filename + "~"); 372 backup.deleteOnExit(); 373 if(!in_file.renameTo(backup)) { 374 Gatherer.println("Error in CollectionDesignManager.parse(): FileRenamedException"); 375 } 376 in_file = new File(filename); // Just in case we moved it. 377 } 378 FileOutputStream out = new FileOutputStream(in_file); 379 380 StringBuffer text = new StringBuffer(""); 381 if(creator != null) { 382 text.append(creator.toString()); 383 text.append("\n"); 384 } 385 if(maintainer != null) { 386 text.append(maintainer.toString()); 387 text.append("\n"); 388 } 389 if(public_col) { 390 text.append("public true\n"); 391 } 392 else { 393 text.append("public false\n"); 394 } 395 if(beta) { 396 text.append("beta true\n"); 397 } 398 else { 399 text.append("beta false\n"); 400 } 401 if(text.length() > 0) { 402 text.append("\n"); 403 } 404 if(plugins.size() > 0) { 405 text.append(plugins.toString()); 406 } 407 if(indexes.size() > 0) { 408 text.append(indexes.toString()); 409 } 410 if(languages.size() > 0) { 411 text.append(languages.toString()); 412 } 413 if(subcollections.size() > 0) { 414 text.append(subcollections.toString()); 415 } 416 String super_collections_command = superman.toString(); 417 if(super_collections_command != null) { 418 text.append(super_collections_command); 419 } 420 if(classifiers.size() > 0) { 421 text.append(classifiers.toString()); 422 } 423 if(formats.size() > 0) { 424 text.append(formats.toString()); 425 } 426 if(collectionmetadatum.size() > 0) { 427 text.append(collectionmetadatum.toString()); 428 } 429 text.append(metadatasets.toString()); 430 if(rest.size() > 0) { 431 // Write out rest at the bottom. 432 text.append("# These instructions are not recognized by the Gatherer.\n"); 433 for(int i = 0; i < rest.size(); i++) { 434 text.append(rest.get(i)); 435 text.append("\n"); 436 } 437 } 438 out.write(text.toString().getBytes()); 439 out.close(); 440 out = null; 441 } 442 catch(Exception error) { 443 error.printStackTrace(); 444 } 164 general_manager.loseFocus(); 165 collect_config.save(); 445 166 } 446 167 /** Method used during a global search and replace to highlight the appropriate record within the Collection Design Managers version of the Metadata Set Manager (view only). … … 451 172 public Rectangle setSelectedElement(String element) { 452 173 // First ensure that the metadata set controls are visible. 453 g ui.setSelectedView("CDM.GUI.MetadataSets");174 general_manager.setSelectedView("CDM.GUI.MetadataSets"); 454 175 // Then tell them to select the given element. 455 return metadatasets.setSelectedElement(element); 176 return metadataset_view.setSelectedElement(element); 177 } 178 179 private class CDMChangeListener 180 implements ActionListener, DocumentListener { 181 182 public void actionPerformed(ActionEvent event) { 183 Gatherer.c_man.getCollection().setSaved(false); 184 } 185 186 /** Gives notification that an attribute or set of attributes changed. */ 187 public void changedUpdate(DocumentEvent e) { 188 Gatherer.c_man.getCollection().setSaved(false); 189 } 190 191 /** Gives notification that there was an insert into the document. */ 192 public void insertUpdate(DocumentEvent e) { 193 Gatherer.c_man.getCollection().setSaved(false); 194 } 195 196 /** Gives notification that a portion of the document has been removed. */ 197 public void removeUpdate(DocumentEvent e) { 198 Gatherer.c_man.getCollection().setSaved(false); 199 } 456 200 } 457 201 } -
trunk/gli/src/org/greenstone/gatherer/cdm/CollectionMeta.java
r4675 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: Gatherer 47 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 48 * Copyright: Copyright (c) 2001 49 * Company: The University of Waikato 50 * Written: /05/02 51 * Revised: 22/08/02 Revamped, Optimized and Commented. 29 * Written: 30 * Revised: 28/06/03 - DOM support 52 31 **************************************************************************************/ 32 import org.greenstone.gatherer.Configuration; 33 import org.greenstone.gatherer.Gatherer; 34 import org.greenstone.gatherer.cdm.CollectionConfiguration; 35 import org.greenstone.gatherer.cdm.CollectionDesignManager; 36 import org.greenstone.gatherer.cdm.DOMProxyListEntry; 53 37 import org.greenstone.gatherer.cdm.Index; 54 import org.greenstone.gatherer.cdm.Language; 38 import org.greenstone.gatherer.msm.MSMUtils; 39 import org.greenstone.gatherer.util.StaticStrings; 55 40 import org.greenstone.gatherer.util.Utility; 41 import org.w3c.dom.*; 56 42 /** This class encapsulates a single collection level metadata assignment, which constitutes a name, language and value. 57 43 * @author John Thompson, Greenstone Digital Library, University of Waikato 58 * @version 2. 344 * @version 2.4 59 45 */ 60 46 public class CollectionMeta 61 implements Comparable { 62 /** A reference to the collection design manager for access to the language manager. */ 63 private CollectionDesignManager manager = null; 64 /** The language of this metadata. Should be a two letter code. */ 65 private Language language = null; 66 /** The name of the thing this metadata is assigned to, which may also refer to an Index or a Partition. */ 67 private Object name = null; 68 /** The value of this metadata. */ 69 private String value = null; 47 implements DOMProxyListEntry { 48 private Element element; 49 private String text; 50 70 51 /** Constructor. 71 * @param name The object the metadata is assigned to as an <strong>Object</strong>. 72 * @param language The language of the metadata as a <strong>Language</strong>. Should be a two letter code. 73 * @param value The value of this metadata, as a <strong>String</strong>. 74 */ 75 public CollectionMeta(CollectionDesignManager manager, Object name, Language language, String value) { 76 this.language = language; 77 this.manager = manager; 78 this.name = name; 79 this.value = value; 52 * @param element the Element from which we will determine metadata details 53 */ 54 public CollectionMeta(Element element) { 55 this.element = element; 80 56 } 57 58 /** Constructor to create a new piece of metadata given its name. */ 59 public CollectionMeta(String name) { 60 element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 61 element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name); 62 element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, Gatherer.config.interface_language); 63 } 64 65 /** Constructor to create a new piece of metadata given its name. */ 66 public CollectionMeta(String name, String language) { 67 element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.COLLECTIONMETADATA_ELEMENT); 68 element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name); 69 element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, language); 70 } 71 81 72 /** Method to compare two collection metadata objects to calculate their respective ordering. 82 * @param object The other metadata to compare to, as an <strong>Object</strong>. 83 * @return An <i>int</i>which is less than 0 if this object proceeds the given object, 0 if they are equal and greater than 0 otherwise.84 85 73 * @param object the other metadata to compare to, as an Object 74 * @return an int which is less than 0 if this object proceeds the given object, 0 if they are equal and greater than 0 otherwise. 75 * @see org.greenstone.gatherer.cdm.Language 76 */ 86 77 public int compareTo(Object object) { 87 if(object instanceof CollectionMeta) {88 CollectionMeta metadata = (CollectionMeta) object;89 int result = name.toString().compareTo(metadata.getName().toString());90 if(result == 0) {91 Language other_language = metadata.getLanguage();92 if(language != null && other_language != null) {93 result = language.compareTo(metadata.getLanguage());94 if(result == 0) {95 return value.compareTo(metadata.getValue());96 }97 }98 else if(language != null) {99 return -1;100 }101 else if(other_language != null) {102 return 1;103 }104 }105 return result;106 }107 78 return toString().compareTo(object.toString()); 108 79 } 80 81 /** Factory constructor. */ 82 public DOMProxyListEntry create(Element element) { 83 return new CollectionMeta(element); 84 } 85 109 86 /** Method to compare two collection metadata objects for equality. 110 111 112 87 * @param object The other metadata to compare to, as an <strong>Object</strong>. 88 * @return A <i>boolean</i> value of <i>true</i> if the object are equal, <i>false</i> otherwise. 89 */ 113 90 public boolean equals(Object object) { 114 if(compareTo(object) == 0) { 115 return true; 116 } 117 return false; 91 return (compareTo(object) == 0); 118 92 } 93 94 public Element getElement() { 95 return element; 96 } 97 119 98 /** Method to retrieve the value of language. 120 * @return The value of language as a <strong> Language</strong>.99 * @return The value of language as a <strong>String</strong>. 121 100 */ 122 public Language getLanguage() { 123 return language; 101 public String getLanguage() { 102 // Retrieve the language string 103 return element.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE); 124 104 } 105 125 106 /** Method to retrieve the value of name. 126 * @return The value of name as an <strong>Object</strong>.107 * @return 127 108 */ 128 public ObjectgetName() {129 return name;109 public String getName() { 110 return element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 130 111 } 131 112 /** Method to retrieve the value of value (well great choice of name there). 132 133 113 * @return The value of value as a <strong>String</strong>. 114 */ 134 115 public String getValue() { 135 return value; 116 // We have to replace the string made of '\' 'n' with the '\n' character! Also watch for other greenstone magic 117 return Utility.decodeGreenstone(MSMUtils.getValue(element)); 136 118 } 137 /** Method to print out this class as it would appear within the collection configuration file. 138 * @return A <strong>String</strong> containing the text value of this class. 139 */ 140 public String toString() { 141 String text = "collectionmeta "; 142 if(name instanceof Index) { 143 text = text + "."; 144 Index index = (Index)name; 145 text = text + index.toStringConfig() + " "; 119 120 public boolean isAssigned() { 121 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR)); 122 } 123 124 /** Determine if this metadata is one of the four special pieces of metadata. 125 * @return true if this metadata is special, false otherwise. 126 */ 127 public boolean isSpecial() { 128 return (element != null && element.getAttribute(StaticStrings.SPECIAL_ATTRIBUTE).equals(StaticStrings.TRUE_STR)); 129 } 130 131 public void setAssigned(boolean assigned) { 132 if(element != null) { 133 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 146 134 } 147 else if(name instanceof SubIndex) {148 text = text + ".";149 SubIndex index = (SubIndex)name;150 text = text + index.toString() + " ";151 }152 else {153 text = text + name.toString() + " ";154 }155 if(language != null && manager.languages.size() > 0 && !manager.languages.isDefaultLanguage(language)) {156 text = text + "[l=" + language.getCode() + "] ";157 }158 text = text + "\"" + Utility.encodeGreenstone(value) + "\"\n";159 return text;160 135 } 161 /** Used to update the contents of this collection level metadata to the given 'new' values. 162 * @param name The new name of the metadata, as a <strong>Object</strong>. 163 * @param language The new <strong>Language</strong> of the metadata. 164 * @param value And the value the metadata is assigned, as a <strong>String</strong>. 165 */ 166 public void update(Object name, Language language, String value) { 167 this.name = name; 168 this.language = language; 169 this.value = value; 136 137 public void setElement(Element element) { 138 this.element = element; 139 text = null; 170 140 } 171 141 … … 174 144 */ 175 145 public void setValue(String value) { 176 this.value = value; 146 MSMUtils.setValue(element, Utility.encodeGreenstone(value)); 147 text = null; // Reset text 177 148 } 178 149 179 /** Ensure this is a valid metadata entry by checking that the value is non-null and non-zero length (after having removed whitespace). 180 * @return <i>true</i> if this metadata has a valid value and should be added to the config, <i>false</i> otherwise. 181 */ 182 public boolean valid() { 183 return(value != null && value.trim().length() > 0); 150 /** Method to print out this class as it would appear within the collection configuration file. 151 * @return A <strong>String</strong> containing the text value of this class. 152 */ 153 public String toString() { 154 if(text == null) { 155 text = CollectionConfiguration.toString(element, true); 156 } 157 return text; 184 158 } 185 159 } -
trunk/gli/src/org/greenstone/gatherer/cdm/CollectionMetaManager.java
r4675 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 /**************************************************************************************46 * Title: Gatherer47 * Description: The Gatherer: a tool for gathering and enriching a digital collection.48 * Copyright: Copyright (c) 200149 * Company: The University of Waikato50 * Written: /05/0251 * Revised: 22/08/02 Revamped, Optimized and Commented.52 **************************************************************************************/53 28 import java.awt.*; 54 29 import java.awt.event.*; … … 59 34 import org.greenstone.gatherer.cdm.CollectionDesignManager; 60 35 import org.greenstone.gatherer.cdm.CollectionMeta; 36 import org.greenstone.gatherer.cdm.DOMProxyListModel; 61 37 import org.greenstone.gatherer.cdm.Index; 62 import org.greenstone.gatherer.cdm.Language;63 38 import org.greenstone.gatherer.gui.EditorDialog; 39 import org.greenstone.gatherer.util.StaticStrings; 64 40 import org.greenstone.gatherer.util.Utility; 41 import org.w3c.dom.*; 65 42 /** This class is responsible for maintaining a list of assigned collection level metadata, and for allows manipulations on the aforementioned data. 66 43 * @author John Thompson, Greenstone Digital Library, University of Waikato 67 * @version 2.3 44 * @version 2.3d 68 45 */ 69 // #################################################################################### 70 // Optimization Saving 71 // #################################################################################### 72 // Removed Vector and Hashtable + Memory, + Processor 73 // #################################################################################### 74 public class CollectionMetaManager 75 extends DefaultListModel { 76 /** A reference to the cdm manager so we can access indexes and languages. */ 77 private CollectionDesignManager manager = null; 78 /** A reference to ourself so that inner classes can use us as a model. */ 79 private DefaultListModel model = null; 80 /** A reference to the Gatherer. */ 81 private Gatherer gatherer = null; 82 /** The language the most recent metadata returned was in. */ 83 private Language current_language = null; 84 /** We can't safely parse metadata commands until after all the other commands have been parsed, so we store commands here for now. */ 85 private ArrayList unresolved_commands = null; 86 /** Constructor. 87 * @param gatherer A reference to the <strong>Gatherer</strong>. 88 * @param manager A reference to the <strong>CollectionDesignManager</strong> for access to other configuration managers. 89 */ 90 public CollectionMetaManager(Gatherer gatherer, CollectionDesignManager manager) { 91 super(); 92 this.gatherer = gatherer; 93 this.manager = manager; 94 this.model = this; 95 this.unresolved_commands = new ArrayList(); 46 public class CollectionMetaManager 47 extends DOMProxyListModel { 48 49 /** Constructor. */ 50 public CollectionMetaManager() { 51 super(CollectionDesignManager.collect_config.getDocumentElement(), StaticStrings.COLLECTIONMETADATA_ELEMENT, new CollectionMeta("")); 52 Gatherer.println("CollectionMetaManager: " + getSize() + " metadata parsed."); 96 53 } 97 54 /** Method to add a new piece of metadata. 98 * @param metadata The new <strong>CollectionMeta</strong>. 99 */ 100 public void addMetadata(CollectionMeta metadata) { 101 CollectionMeta existing = getMetadata(metadata.getName().toString(), metadata.getLanguage(), false); 102 if(existing != null) { 103 removeElement(existing); 55 * @param metadata the new CollectionMeta 56 */ 57 public void addMetadatum(CollectionMeta metadata) { 58 if(!contains(metadata)) { 59 Element element = metadata.getElement(); 60 // Locate where we should insert this new subcollection. 61 Node target_node = CollectionConfiguration.findInsertionPoint(element); 62 // Failing that we insert immediately after a language string 63 add(root, metadata, target_node); 64 Gatherer.c_man.configurationChanged(); 104 65 } 105 addElement(metadata); 106 gatherer.c_man.configurationChanged(); 66 Gatherer.c_man.configurationChanged(); 107 67 } 108 /** Retrieve the collectionextra metadata in the default language, if present. 109 * @return A <strong>CollectionMeta</strong> containing the collectionextra in the default language if present, or else the first collectionextra of any language, otherwise <i>null</i>. 110 * @see org.greenstone.gatherer.cdm.Language 111 */ 112 public CollectionMeta getCollectionExtra() { 113 CollectionMeta result = getMetadata("collectionextra", Gatherer.config.interface_language, true); 114 if(result == null) { 115 result = new CollectionMeta(manager, "collectionextra", Gatherer.config.interface_language, ""); 116 addMetadata(result); 68 69 public CollectionMeta get(int i) { 70 return (CollectionMeta) getElementAt(i); 71 } 72 73 /** Retrieve all of the general metadata. */ 74 public ArrayList getMetadata() { 75 ArrayList result = new ArrayList(); 76 int size = getSize(); 77 for(int i = 0; i < size; i++) { 78 CollectionMeta metadata = (CollectionMeta) getElementAt(i); 79 if(!metadata.getName().startsWith(StaticStrings.STOP_CHARACTER)) { 80 result.add(metadata); 81 } 117 82 } 118 83 return result; 119 84 } 120 /** Retrieve the collectionname metadata in the default language, if present.121 * @return A <strong>CollectionMeta</strong> containing the collectionname in the default language if present, or else the first collectionname of any language, otherwise <i>null</i>.122 * @see org.greenstone.gatherer.cdm.Language123 */124 public CollectionMeta getCollectionName() {125 return getMetadata("collectionname", Gatherer.config.interface_language, true);126 }127 /** Retrieve the iconcollection metadata in the default language, if present.128 * @return A <strong>CollectionMeta</strong> containing the iconcollection in the default language if present, or else the first iconcollection of any language, otherwise <i>null</i>.129 * @see org.greenstone.gatherer.cdm.Language130 */131 public CollectionMeta getIconCollection() {132 CollectionMeta result = getMetadata("iconcollection", Gatherer.config.interface_language, true);133 if(result == null) {134 result = new CollectionMeta(manager, "iconcollection", Gatherer.config.interface_language, "");135 addMetadata(result);136 }137 return result;138 }139 /** Retrieve the iconcollection metadata in the default language, if present.140 * @return A <strong>CollectionMeta</strong> containing the iconcollectionsmall in the default language if present, or else the first iconcollectionsmall of any language, otherwise <i>null</i>.141 * @see org.greenstone.gatherer.cdm.Language142 */143 public CollectionMeta getIconCollectionSmall() {144 CollectionMeta result = getMetadata("iconcollectionsmall", Gatherer.config.interface_language, true);145 if(result == null) {146 result = new CollectionMeta(manager, "iconcollectionsmall", Gatherer.config.interface_language, "");147 addMetadata(result);148 }149 return result;150 }151 /** Method to retrieve the list of metadata.152 * @return An <strong>ArrayList</strong> containing the metadata.153 */154 public ArrayList getMetadata() {155 ArrayList metadata = new ArrayList();156 for(int i = 0; i < size(); i++) {157 metadata.add(get(i));158 }159 Collections.sort(metadata);160 return metadata;161 }162 85 163 86 /** Retrieve all of the metadata for the given feature, regardless of language. */ 164 public ArrayList getMetadata( Objectname) {87 public ArrayList getMetadata(String name) { 165 88 ArrayList result = new ArrayList(); 166 for(int i = 0; i < size(); i++) { 167 CollectionMeta metadata = (CollectionMeta) get(i); 89 int size = getSize(); // Refresh DOM Model 90 for(int i = 0; i < size; i++) { 91 CollectionMeta metadata = (CollectionMeta) getElementAt(i); 168 92 if(metadata.getName().equals(name)) { 169 93 result.add(metadata); … … 172 96 return result; 173 97 } 98 99 /** Retrieve the named piece of metadata, in the default language, if available. If no such metadata is available then it is created. 100 * @param name the name of the metadatum to retrieve as a String 101 * @return the dom Element containing the specified metadatum 102 */ 103 public CollectionMeta getMetadatum(String name) { 104 return getMetadatum(name, true); 105 } 106 107 public CollectionMeta getMetadatum(String name, boolean add_if_not_found) { 108 ///atherer.println("Get the metadata for " + name + " in the default language."); 109 int size = getSize(); 110 for(int i = 0; i < size; i++) { 111 CollectionMeta metadatum = (CollectionMeta) getElementAt(i); 112 if(metadatum.getName().equals(name) && metadatum.getLanguage().equals(Gatherer.config.interface_language)) { 113 ///atherer.println("Found '" + metadatum + "'"); 114 return metadatum; 115 } 116 else { 117 ///atherer.println("No match with: " + metadatum.getName() + " [l=" + metadatum.getLanguage() + "] \"" + metadatum.getValue() + "\""); 118 } 119 metadatum = null; 120 } 121 if(add_if_not_found) { 122 CollectionMeta result = new CollectionMeta(name); 123 addMetadatum(result); 124 ///atherer.println("Added new metadata."); 125 return result; 126 } 127 else { 128 return null; 129 } 130 } 131 174 132 /** Method to retrieve a certain piece of metadata based on its name and language. 175 176 * @param language The <strong>Language</strong>of the metadata.177 178 179 180 public CollectionMeta getMetadata( Object name, Languagelanguage, boolean partial) {133 * @param name the name of the metadata as an Object (as it may actually be a refernce to an Index or SubIndex) 134 * @param language the language of the metadata. 135 * @param partial <i>true</i> to return the first partial match (ie matches name but not language). 136 * @return The <strong>CollectionMeta</strong> requested, or <i>null</i> if no such metadata. 137 */ 138 public CollectionMeta getMetadata(String name, String language, boolean partial) { 181 139 CollectionMeta partial_match = null; 182 for(int i = 0; i < size(); i++) {183 CollectionMeta metadata = (CollectionMeta) get (i);140 for(int i = 0; i < getSize(); i++) { 141 CollectionMeta metadata = (CollectionMeta) getElementAt(i); 184 142 Object metadata_name = metadata.getName(); 185 143 // We test the case of an object match (ie Index to Index)... 186 144 if(metadata_name.equals(name)) { 187 if (metadata.getLanguage().equals(language)) {188 return metadata;189 }190 partial_match = metadata;191 }192 // But if that fails we also try a string match such that "section:dls.Title" == Index193 if(metadata_name.toString().equals(name.toString())) {194 145 if (metadata.getLanguage().equals(language)) { 195 146 return metadata; … … 203 154 return null; 204 155 } 205 /** Method that attempts to parse a collection metadata command from the given text. If a command is parsed successfully it is immediately added to the the collections metadata. 206 * @param command The command text we wish to parse, as a <strong>String</strong>. 207 * @return A <i>boolean</i> which is <i>true</i> if a collection metadata command was successfully parsed, <i>false</i> otherwise. 208 * @see org.greenstone.gatherer.cdm.CollectionDesignManager 209 * @see org.greenstone.gatherer.cdm.CommandTokenizer 210 * @see org.greenstone.gatherer.cdm.Language 211 * @see org.greenstone.gatherer.cdm.LanguageManager 212 * @see org.greenstone.gatherer.util.Utility 213 */ 214 public boolean parse(String command, boolean finished) { 215 String temp = command.toLowerCase(); 216 if(temp.startsWith("collectionmeta")) { 217 if(finished) { 218 CommandTokenizer ct = new CommandTokenizer(command); 219 if(ct.countTokens() >= 3) { 220 ct.nextToken(); // Throw away collectionmeta 221 Object key = ct.nextToken(); 222 Language language = null; 223 String language_code = null; 224 String value = ct.nextToken(); 225 // Arg. Remember a language token will be '[l=<code>]' 226 if(value.startsWith("[") && value.endsWith("]")) { 227 language_code = value.substring(3, value.length() - 1); 228 ///ystem.err.println("Language code = " + language_code); 229 value = ct.nextToken(); 230 } 231 // Check if the key is an index, and if so retrieve it. 232 if(((String)key).startsWith(".")) { 233 ///ystem.err.println("Detected '.' prefix."); 234 String key_str = (String)key; 235 key = null; 236 key_str = key_str.substring(1); 237 Index ind = Index.parseIndexConfig(key_str, manager); 238 if (ind != null) { 239 240 key = manager.indexes.getIndex(ind.toString(false)); 241 } 242 243 // If that didn't work, then it might be a subindex so have a bash at retrieving that instead. 244 if(key == null) { 245 key = manager.subcollections.getSubIndex(key_str); 246 //if(key != null) { 247 ///ystem.err.println("Its a subindex."); 248 //} 249 //else { 250 ///ystem.err.println("Error Will Robinson."); 251 //} 252 } 253 //else { 254 ///ystem.err.println("Its an index."); 255 //} 256 } 257 // An if we have a language code, retrieve its object too. 258 if(language_code != null) { 259 language = manager.languages.getLanguage(language_code, false); 260 } 261 // Otherwise set language to the default language. 262 else { 263 language = Gatherer.config.interface_language; 264 } 265 if(key != null) { 266 // Trim any " 267 if(value.equals("\"\"")) { 268 value = ""; 269 } 270 else { 271 if(value.startsWith("\"")) { 272 value = value.substring(1); 273 } 274 if(value.endsWith("\"")) { 275 value = value.substring(0, value.length() - 1); 276 } 277 } 278 CollectionMeta meta = new CollectionMeta(manager, key, language, Utility.decodeGreenstone(value)); 279 addMetadata(meta); 280 } 281 return true; 156 157 /** Method to remove a piece of metadata. 158 * @param metadata metadata 159 */ 160 public void removeMetadata(CollectionMeta metadata) { 161 if(metadata != null) { 162 String name = metadata.getName(); 163 String language = metadata.getLanguage(); 164 for(int i = 0; i < getSize(); i++) { 165 CollectionMeta other = (CollectionMeta) getElementAt(i); 166 if(name.equals(other.getName()) && language.equals(other.getLanguage())) { 167 remove(i); 168 Gatherer.c_man.configurationChanged(); 169 return; 282 170 } 283 } 284 else { 285 unresolved_commands.add(command); 286 return true; 287 } 171 other = null; 172 } 173 language = null; 174 name = null; 288 175 } 289 return false;290 }291 /** Ensure that the values being showed are the most up to date. */292 public void refresh() {293 fireContentsChanged(this, 0, size());294 176 } 295 177 296 /** Method to remove a piece of metadata. 297 * @param metadata The <strong>CollectionMeta</strong> you wish to remove. 298 */ 299 public void removeMetadata(CollectionMeta metadata) { 300 removeElement(metadata); 301 gatherer.c_man.configurationChanged(); 302 } 303 /** Method which attempts to reparse obvious metadata commands which used unresovable references. 304 */ 305 public void reparseUnresolved() { 306 for(int i = 0; i < unresolved_commands.size(); i++) { 307 parse((String)unresolved_commands.get(i), true); 178 /** Removes all of the metadata with a certain name, regardless of language or value. */ 179 public void removeMetadata(String name) { 180 boolean removed_entry = false; 181 for(int i = getSize(); i != 0; i--) { 182 CollectionMeta other = (CollectionMeta) getElementAt(i - 1); 183 if(name.equals(other.getName())) { 184 remove(i - 1); 185 removed_entry = true; 186 } 187 other = null; 188 } 189 if(removed_entry) { 190 Gatherer.c_man.configurationChanged(); 308 191 } 309 // Regardless of if they work, clear the commands.310 unresolved_commands.clear();311 }312 /** Sets the value of a certain metadata.313 * @param name The name of the metadata as a <strong>String</strong>.314 * @param language The <strong>Language</strong> to use.315 * @param value The value of the metadata also as a <strong>String</strong>.316 */317 public void setMetadata(String name, Language language, String value) {318 addMetadata(new CollectionMeta(manager, name, language, value));319 }320 /** Method to produce the list of metadata in a string such as you would find in the collection configuration file.321 * @return A <strong>String</strong> containing the list of collection metadata.322 */323 public String toString() {324 // We sort the metadata first.325 ArrayList metadatum = new ArrayList();326 for(int i = 0; i < size(); i++) {327 metadatum.add(get(i));328 }329 Collections.sort(metadatum, new CollectionMetaComparator());330 // Now we print them331 StringBuffer text = new StringBuffer("");332 for(int i = 0; i < metadatum.size(); i++) {333 CollectionMeta data = (CollectionMeta) metadatum.get(i);334 if(data.valid()) {335 text.append(data.toString());336 }337 }338 metadatum = null;339 text.append("\n");340 return text.toString();341 }342 /** Overloaded to call get with both a key and an empty argument array.343 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle.344 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call.345 */346 private String get(String key) {347 return get(key, null);348 }349 /** Used to retrieve a property value from the Locale specific ResourceBundle, based upon the key and arguments supplied. If the key cannot be found or if some other part of the call fails a default (English) error message is returned. <BR>350 * Here the get recieves a second argument which is an array of Strings used to populate argument fields, denoted {<I>n</I>}, within the value String returned. Note that argument numbers greater than or equal to 32 are automatically mapped to the formatting String named Farg<I>n</I>.351 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle.352 * @param args A <strong>String[]</strong> used to populate argument fields within the complete String.353 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call.354 * @see org.greenstone.gatherer.Gatherer355 * @see org.greenstone.gatherer.Dictionary356 */357 private String get(String key, String args[]) {358 if(key.indexOf('.') == -1) {359 key = "CDM.CollectionMetaManager." + key;360 }361 return gatherer.dictionary.get(key, args);362 192 } 363 193 364 private class CollectionMetaComparator 365 implements Comparator { 366 public int compare(Object o1, Object o2) { 367 String s1 = o1.toString(); 368 String s2 = o2.toString(); 369 if(s1.startsWith(".")) { 370 return 1; 371 } 372 else if(s2.startsWith(".")) { 373 return -1; 374 } 375 return o1.toString().compareTo(o2.toString()); 376 } 377 public boolean equals(Object o2) { 378 return (compare(this, o2) == 0); 379 } 194 public int size() { 195 return getSize(); 380 196 } 381 197 } -
trunk/gli/src/org/greenstone/gatherer/cdm/Format.java
r4675 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: 06/05/02 50 30 * Revised: 04/10/02 - Commented 31 * 14/07/03 - DOM Support 51 32 **************************************************************************************/ 33 import org.greenstone.gatherer.cdm.CollectionConfiguration; 34 import org.greenstone.gatherer.cdm.CollectionDesignManager; 52 35 import org.greenstone.gatherer.cdm.Classifier; 53 /** This class encapsulates all the information about a format command from the collection configuration. This includes both the 'general' formatting commands, and the commands targetted at specific classifiers or classification component types. 36 import org.greenstone.gatherer.cdm.DOMProxyListEntry; 37 import org.greenstone.gatherer.msm.MSMUtils; 38 import org.w3c.dom.*; 39 /** This class encapsulates all the information about a format command from the collection configuration. This includes both the 'general' formatting commands, and the commands targetted at specific classifiers or classification component types. This class is, unfortunately, the most complex in terms of DOM model support, since we have to maintain a live reference to any classifier this format applies to. We temporarily use the feature name as the format name attribute but since the order of classifiers can change, this of course gets horribly out of date. Before the CollectionDesignManager saves the CollectionConfiguration it calls a method in the FormatManager to force all of the Formats to update their name attributes. 54 40 * @author John Thompson, Greenstone Digital Library, University of Waikato 55 41 * @version 2.3 56 42 */ 57 public class Format { 58 /** If this format is of a true/false type, the current state. */ 59 private boolean state = false; 60 /** The type of this format command, either FLAG, FORMAT or PARAM. */ 61 private int type = -1; 62 /** The feature this format command affects. */ 63 private Object feature = null; 64 /** If this format refers to a specific part of a feature, this indicates the part. */ 65 private String part = null; 66 /** A command string, which may include a specific HTML chunk used to format a control. */ 67 private String value = null; 68 /** An element of the format type enumeration. A true/false option. */ 69 static final public int FLAG = 0; 70 /** An element of the format type enumeration. A string parameter. */ 71 static final public int VALUE = 1; 43 public class Format 44 implements DOMProxyListEntry { 45 72 46 /** The default features as specified by the Greenstone Developers manual. */ 73 47 static final public String DEFAULT_FEATURES[] = {"", "DocumentArrowsBottom","DocumentButtons","DocumentContents","DocumentHeading","DocumentImages","DocumentText","DocumentUseHTML","Search"}; 74 48 /** The list of known feature parts. */ 75 49 static final public String DEFAULT_PARTS[] = {"","DateList","HList","Invisible","VList"}; 50 51 /** Not all features have an associated part, such as those in the default features list (apart from Search which does have parts!) */ 52 static public boolean canHavePart(String name) { 53 return !(name.equalsIgnoreCase(DEFAULT_FEATURES[1]) || name.equalsIgnoreCase(DEFAULT_FEATURES[2]) || name.equalsIgnoreCase(DEFAULT_FEATURES[3]) || name.equalsIgnoreCase(DEFAULT_FEATURES[4]) || name.equalsIgnoreCase(DEFAULT_FEATURES[5]) || name.equalsIgnoreCase(DEFAULT_FEATURES[6]) || name.equalsIgnoreCase(DEFAULT_FEATURES[7])); 54 } 55 56 static public boolean isParamType(String name) { 57 return (name.equalsIgnoreCase(DEFAULT_FEATURES[1]) || name.equalsIgnoreCase(DEFAULT_FEATURES[3]) || name.equalsIgnoreCase(DEFAULT_FEATURES[5]) || name.equalsIgnoreCase(DEFAULT_FEATURES[7])); 58 } 59 60 /** If this format is altering a Classifier then this is the classifier in question. */ 61 private Classifier classifier = null; 62 /** The element this format is based on. */ 63 private Element element = null; 64 /** We keep a copy of the part because its slightly more computationally tricky to calculate. */ 65 private String part = null; 66 /** Cached result of toString. */ 67 private String text = null; 68 69 /** Constructor only to be used during DOMProxyListModel initialization. */ 70 public Format() { 71 } 72 73 public Format(Element element) { 74 this.element = element; 75 // Immediately check if we are dealing with a classifier, by retrieving the feature name. If it is a classifier, then restore the live reference immediately before anything changes it. 76 Object object = getFeature(); 77 if(object instanceof Classifier) { 78 classifier = (Classifier) object; 79 } 80 else { 81 String feature = (String) object; 82 if(feature.toUpperCase().startsWith(Classifier.CLASSIFIER_PREFIX)) { 83 // Extract the integer index 84 int index = Integer.parseInt(feature.substring(Classifier.CLASSIFIER_PREFIX.length())); 85 // Subtract one (as java is 0-2 where G2 is 1-3) 86 index = index - 1; 87 // Retrieve the appropriate classifier 88 classifier = CollectionDesignManager.classifier_manager.getClassifier(index); 89 } 90 } 91 } 92 76 93 /** Constructor for a flag format command. 77 94 * @param feature The <Strong>Object</strong> this format affects. … … 80 97 */ 81 98 public Format(Object feature, String part, boolean state) { 82 this.feature = feature;83 this.part = part;84 this.state = state;85 this.type = FLAG; 86 } 99 element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.FORMAT_ELEMENT); 100 setName(feature, part); 101 setState(state); 102 } 103 87 104 /** Constructor for a format-string format command. 88 105 * @param feature The <Strong>Object</strong> this format affects. … … 91 108 */ 92 109 public Format(Object feature, String part, String value) { 93 this.feature = feature; 94 this.part = part; 95 this.type = VALUE; 96 this.value = value; 97 } 110 element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.FORMAT_ELEMENT); 111 setName(feature, part); 112 setValue(value); 113 } 114 115 public boolean canHavePart() { 116 return canHavePart(getName()); 117 } 118 119 public int compareTo(Object object) { 120 if(object == null) { // It seems that occasionally compareTo is called and somehow null ends up in comparison. 121 return -1; 122 } 123 if(object instanceof Format && element != null) { 124 return element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE).compareTo(((Format)object).getName()); 125 } 126 return toString().compareTo(object.toString()); 127 } 128 129 public DOMProxyListEntry create(Element element) { 130 return new Format(element); 131 } 132 133 public boolean equals(Object object) { 134 return (compareTo(object) == 0); 135 } 136 137 public Element getElement() { 138 return element; 139 } 140 98 141 /** Method to retrieve the value of feature, which may either be a String or a Classifier. 99 142 * @return The value of feature as an <strong>Object</strong>. 100 143 */ 101 144 public Object getFeature() { 102 return feature; 103 } 104 /** Method to retrieve the value of part. 145 if(classifier != null) { 146 return classifier; 147 } 148 else if(element != null) { 149 String name = element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE); 150 // Remove part 151 String part = getPart(); 152 String feature; 153 if(part != null) { 154 feature = name.substring(0, name.length() - part.length()); 155 } 156 else { 157 feature = name; 158 } 159 part = null; 160 name = null; 161 // If the feature now refers to a classifier, retrieve it. 162 if(feature.toUpperCase().startsWith(Classifier.CLASSIFIER_PREFIX)) { 163 // Extract the integer index 164 int index = Integer.parseInt(feature.substring(Classifier.CLASSIFIER_PREFIX.length())); 165 // Subtract one (as java is 0-2 where G2 is 1-3) 166 index = index - 1; 167 // Retrieve the appropriate classifier 168 classifier = CollectionDesignManager.classifier_manager.getClassifier(index); 169 return classifier; 170 } 171 else { 172 return feature; 173 } 174 } 175 else { 176 return "Error"; 177 } 178 } 179 180 public String getName() { 181 if(element != null) { 182 return element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE); 183 } 184 return "Error"; 185 } 186 187 /** Method to retrieve the value of part. Of course there may not be one, in which case return "" 105 188 * @return The value of part as a <Strong>String</strong>. 106 189 */ 107 190 public String getPart() { 191 if(part == null && element != null) { 192 // To determine a part, we retrieve the Format name, then look for one of our recognized parts 193 String name = element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE); 194 // DEFAULT_PARTS[0] is an empty string to correctly enable comboboxes. 195 name = name.toLowerCase(); 196 for(int i = 1; part == null && i < DEFAULT_PARTS.length; i++) { 197 if(name.endsWith(DEFAULT_PARTS[i].toLowerCase())) { 198 part = DEFAULT_PARTS[i]; 199 } 200 } 201 if(part == null) { 202 part = DEFAULT_PARTS[0]; 203 } 204 } 108 205 return part; 109 206 } 110 /** Method to retrieve this formats special Greenstone position code. 111 * @return A <strong>String</strong> which distinctly indicates this classifiers position. 112 * @see org.greenstone.gatherer.cdm.Classifier 113 */ 114 public String getPosition() { 115 ///ystem.err.println("Retrieving the name of feature " + feature); 116 String position = null; 117 if(feature instanceof Classifier) { 118 position = ((Classifier)feature).getPositionString(); 119 } 120 else { 121 position = feature.toString(); 122 } 123 ///ystem.err.println("Result: " + position + part); 124 return position + part; 125 } 207 126 208 /** Method to retrieve the value of state. 127 * @ param Thevalue of state as a <i>boolean</i>.209 * @return value of state as a <i>boolean</i>. 128 210 */ 129 211 public boolean getState() { 130 return state; 131 } 132 /** Method to retrieve the value of type. 133 * @param The value of type as an <i>int</i>. 134 */ 135 public int getType() { 136 return type; 137 } 212 return (element != null && element.getAttribute(CollectionConfiguration.VALUE_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR)); 213 } 214 138 215 /** Retrieve the value of value. 139 216 * @return A <strong>String</strong> which is the value of value. 140 217 */ 141 218 public String getValue() { 219 String value = "Error"; 220 if(element != null) { 221 value = MSMUtils.getValue(element); 222 } 142 223 return value; 143 224 } 225 226 public boolean isAssigned() { 227 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR)); 228 } 229 230 public boolean isParamType() { 231 return (element != null && element.getAttribute(CollectionConfiguration.VALUE_ATTRIBUTE).length() > 0); 232 } 233 234 public void setAssigned(boolean assigned) { 235 if(element != null) { 236 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 237 } 238 } 239 240 public void setElement(Element element) { 241 this.element = element; 242 part = null; 243 text = null; 244 // Establish the classifier reference, if necessary 245 getFeature(); 246 } 247 248 public void setName(Object feature, String part) { 249 // Can't do anything unless an element exists. 250 if(element != null) { 251 this.part = part; // Easier for later on. 252 if(feature instanceof Classifier) { 253 classifier = (Classifier) feature; 254 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, classifier.getPositionString() + part); 255 } 256 else { 257 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, feature.toString() + part); 258 } 259 text = null; 260 } 261 } 262 144 263 /** Set the value of state. 145 264 * @param state The new value for state as a <i>boolean</i>. 146 265 */ 147 266 public void setState(boolean state) { 148 this.state = state; 149 } 150 /** Set the value of type. 151 * @param type The new value for type as an <i>int</i>. 152 */ 153 public void setType(int type) { 154 this.type = type; 155 } 267 if(element != null) { 268 element.setAttribute(CollectionConfiguration.VALUE_ATTRIBUTE, (state ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 269 text = null; 270 } 271 } 272 156 273 /** Set the value of value. Hmmm. 157 274 * @param value The new value from value as a <strong>String</strong>. 158 275 */ 159 276 public void setValue(String value) { 160 this.value = value; 161 } 277 if(element != null) { 278 MSMUtils.setValue(element, value); 279 text = null; 280 } 281 } 282 162 283 /** Method to translate this classes information into a line of text as you would expect in the collection configuration file. 163 284 * @return A <strong>String</strong> containing the format command. 164 285 */ 165 286 public String toString() { 166 String text = "format "; 167 text = text + getPosition() + " "; 168 switch(type) { 169 case FLAG: 170 if(state) { 171 text = text + "true"; 287 if(text == null && element != null) { 288 StringBuffer temp = new StringBuffer(CollectionConfiguration.FORMAT_STR); 289 temp.append(" "); 290 temp.append(element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE)); 291 temp.append(" "); 292 String value = element.getAttribute(CollectionConfiguration.VALUE_ATTRIBUTE); 293 if(value.length() > 0) { 294 temp.append(value); 172 295 } 173 296 else { 174 text = text + "false"; 175 } 176 break; 177 default: 178 text = text + "\"" + value + "\""; 297 temp.append("\""); 298 temp.append(MSMUtils.getValue(element)); 299 temp.append("\""); 300 } 301 text = temp.toString(); 302 temp = null; 179 303 } 180 304 return text; 181 305 } 182 /** Retrieve the type of a certain named feature. 183 * @param name The name of the feature as a <strong>String</strong>. 184 * @return An <i>int</i> indicating the type, and hence the controls needed to edit this type. 185 */ 186 static public int getType(String name) { 187 int index = -1; 188 for(int i = 1; i < DEFAULT_FEATURES.length; i++) { 189 if(name.equalsIgnoreCase(DEFAULT_FEATURES[i])) { 190 index = i; 191 } 192 } 193 if(index == 1 || index == 3 || index == 5 || index == 7) { 194 return FLAG; 195 } 196 return VALUE; 306 307 public void update() { 308 if(classifier != null) { 309 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, classifier.getPositionString() + getPart()); 310 text = null; 311 } 197 312 } 198 313 } -
trunk/gli/src/org/greenstone/gatherer/cdm/FormatManager.java
r4675 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: Gatherer 47 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 48 * Company: The University of Waikato 49 * Written: /05/02 50 * Revised: 04/10/02 - Commented 29 * Written: 06/05/02 30 * Revised: 04/10/02 - Commented 31 * 14/07/03 - DOM support 51 32 **************************************************************************************/ 52 import java.awt.BorderLayout; 53 import java.awt.CardLayout; 54 import java.awt.Color; 55 import java.awt.Dimension; 56 import java.awt.GridLayout; 57 import java.awt.event.ActionEvent; 58 import java.awt.event.ActionListener; 59 import java.awt.event.KeyAdapter; 60 import java.awt.event.KeyEvent; 61 import java.util.ArrayList; 62 import java.util.Collections; 63 import java.util.Vector; 64 import javax.swing.BorderFactory; 65 import javax.swing.BoxLayout; 66 import javax.swing.ButtonGroup; 67 import javax.swing.DefaultComboBoxModel; 68 import javax.swing.JButton; 69 import javax.swing.JCheckBox; 70 import javax.swing.JComboBox; 71 import javax.swing.JLabel; 72 import javax.swing.JList; 73 import javax.swing.JPanel; 74 import javax.swing.JScrollPane; 75 import javax.swing.JTabbedPane; 76 import javax.swing.JTextArea; 77 import javax.swing.JTextField; 78 import javax.swing.JToggleButton; 79 import javax.swing.ListSelectionModel; 80 import javax.swing.event.ListSelectionEvent; 81 import javax.swing.event.ListSelectionListener; 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.util.*; 36 import javax.swing.*; 37 import javax.swing.event.*; 82 38 import org.greenstone.gatherer.Gatherer; 83 39 import org.greenstone.gatherer.cdm.Classifier; 84 40 import org.greenstone.gatherer.cdm.ClassifierManager; 41 import org.greenstone.gatherer.cdm.CollectionConfiguration; 85 42 import org.greenstone.gatherer.cdm.CollectionDesignManager; 86 43 import org.greenstone.gatherer.cdm.CommandTokenizer; 87 import org.greenstone.gatherer.cdm.DynamicListModel; 44 import org.greenstone.gatherer.cdm.Control; 45 import org.greenstone.gatherer.cdm.DOMProxyListModel; 88 46 import org.greenstone.gatherer.cdm.Format; 89 47 import org.greenstone.gatherer.msm.ElementWrapper; 90 48 import org.greenstone.gatherer.util.Utility; 49 import org.w3c.dom.*; 91 50 /** This class maintains a list of format statements, and allows the addition and removal of these statements. 92 51 * @author John Thompson, Greenstone Digital Library, University of Waikato … … 94 53 */ 95 54 public class FormatManager 96 extends DynamicListModel { 97 /** The main manager so we can get to ClassifierManager which is needed to turn position reference such as "CL1" into the appropriate Classifier. */ 98 private CollectionDesignManager manager = null; 55 extends DOMProxyListModel { 56 99 57 /** The controls used to edit the format commands. */ 100 58 private Control controls = null; 101 59 /** A reference to ourselves so inner classes can get at the model. */ 102 private DynamicListModel model = null; 103 /** A reference to the Gatherer. */ 104 private Gatherer gatherer = null; 105 /** We may have somehow recieved a format command which references a classifier that hasn't been parsed yet, so this variable holds a list of failed commands which are retried after the loading is complete. */ 106 private Vector unresolved_commands = null; 107 /** Constructor. 108 * @param gatherer A reference to the <strong>Gatherer</strong>. 109 * @param manager A reference to the <strong>CollectionDesignManager</strong> that created this manager. 110 */ 111 public FormatManager(Gatherer gatherer, CollectionDesignManager manager) { 112 super(); 113 this.gatherer = gatherer; 114 this.manager = manager; 60 private DOMProxyListModel model = null; 61 62 /** Constructor. */ 63 public FormatManager() { 64 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.FORMAT_ELEMENT, new Format()); 115 65 this.model = this; 116 this.unresolved_commands = new Vector(); 66 Gatherer.println("FormatManager: parsed " + getSize() + " format statements."); 67 // Establish all of the format objects, so that classifier indexes are initially correct (subsequent refreshes of the model will be sufficient to keep these up to date, as long as we start with a live reference to a classifier. 68 int size = getSize(); 69 for(int i = 0; i < size; i++) { 70 getElementAt(i); 71 } 117 72 } 118 73 /** Method to add a new format to this manager. … … 120 75 */ 121 76 public void addFormat(Format format) { 122 if(formatExists(format) == null) { 123 addElement(format); 124 gatherer.c_man.configurationChanged(); 125 } 126 } 127 /** Method which determines if a certain format exists, in which case it must be removed before a new format of the same component is added. For general formatting statements this compares types, for 'custom' ones it compares list and part. 128 * @param format The <strong>Format</strong> whose uniqueness we want to check. 129 * @return The <strong>Format</strong> that matches the one given, or <i>null</i> if no such format exists. 130 */ 131 public Format formatExists(Format format) { 132 for(int i = 0; i < size(); i++) { 133 Format current = (Format) get(i); 134 if(format.getPosition().equals(current.getPosition())) { 135 return current; 136 } 137 } 138 return null; 139 } 77 if(!contains(format)) { 78 Element element = format.getElement(); 79 // Locate where we should insert this new classifier. 80 Node target_node = CollectionConfiguration.findInsertionPoint(element); 81 add(root, format, target_node); 82 Gatherer.c_man.configurationChanged(); 83 } 84 } 85 86 public void destroy() { 87 if(controls != null) { 88 controls.destroy(); 89 controls = null; 90 } 91 } 92 140 93 /** Gets the format indicated by the index. 141 142 94 * @param index The location of the desired format, as an <i>int</i>. 95 */ 143 96 public Format getFormat(int index) { 144 return (Format)get(index); 145 } 97 Format result = null; 98 if(0 < index && index < getSize()) { 99 result = (Format) getElementAt(index); 100 } 101 return result; 102 } 103 146 104 /** Method to retrieve this managers controls. 147 * @return The <strong>Control</strong>for this collection.148 105 * @return the Control for this collection. 106 */ 149 107 public Control getControls() { 150 108 if(controls == null) { 151 controls = new Control();109 controls = new FormatControl(); 152 110 } 153 111 return controls; 154 112 } 155 /** Method to invalidate controls when some significant change has occured within the collection. */ 156 public void invalidateControls() { 157 if(controls != null) { 158 controls.destroy(); 159 } 160 controls = null; 161 } 162 /** This method attempts to parse a format command from the given string. If a format is parsed, it is immediately added to this managers list of format commands. 163 * @param command The <strong>String</strong> we are trying to parse a command from. 164 * @param finished A <i>boolean</i> which is <i>true</i> if we are calling this after the the input has been completely parsed (i.e all legal Classifiers are know to exist), or <i>false</i> otherwise. 165 * @return A <i>boolean</i> which is <i>true</i> if we managed to parse a command, <i>false</i> otherwise. 166 * @see org.greenstone.gatherer.cdm.Classifier 167 * @see org.greenstone.gatherer.cdm.CommandTokenizer 168 * @see org.greenstone.gatherer.cdm.Format 169 */ 170 public boolean parse(String command, boolean finished) { 171 String temp = command.toLowerCase(); 172 if(temp.startsWith("format")) { 173 if(finished) { 174 CommandTokenizer ct = new CommandTokenizer(command); 175 ct.nextToken(); // Throw away 'format' 176 String position = ct.nextToken(); 177 String value = ct.nextToken(); 178 // String speech marks. 179 if(value.startsWith("\"") && value.endsWith("\"")) { 180 if(value.equals("\"\"")) { 181 value = ""; 182 } 183 else { 184 value = value.substring(1, value.length() - 1); 185 } 186 } 187 // Ensure we parsed a good command. 188 if(position != null && value != null) { 189 // The trickiest bit of parsing format commands is figuring out how much of the position is feature, and how much part. Since the parts are far less likely to change or be customized in any way, we'll try to match them first (except "" of course). 190 String feature_name = null; 191 String part = null; 192 // If this works, then we're all finished. Yay. 193 for(int i = 1; i < Format.DEFAULT_PARTS.length; i++) { 194 if(position.endsWith(Format.DEFAULT_PARTS[i])) { 195 part = Format.DEFAULT_PARTS[i]; 196 feature_name = position.substring(0, position.length() - part.length()); 197 } 198 } 199 // Otherwise we can attempt to find the default features, but we have less chance of success. 200 if(feature_name == null || part == null) { 201 for(int i = 1; i < Format.DEFAULT_FEATURES.length; i++) { 202 if(position.startsWith(Format.DEFAULT_FEATURES[i])) { 203 feature_name = Format.DEFAULT_FEATURES[i]; 204 if(position.length() > feature_name.length()) { 205 part = position.substring(feature_name.length()); 206 } 207 else { 208 part = ""; 209 } 210 } 211 } 212 } 213 // Otherwise we can assume we are dealing with a classifier and split the position using... 214 // position ::= <classifier_position><part> 215 // classifier_position ::= <alphanum>[0-9]$ 216 // part ::= ^![0-9]<alpha> 217 // But I don't like my chances of this working if someone does a scary like CL4Part8B. I just have 218 // to hope no-one uses numbers, and no-one expects CustomFeatureCustomPart to parse properly. 219 if(feature_name == null || part == null) { 220 part = ""; 221 boolean found = false; 222 int index = position.length() - 1; 223 while(index >= 0 && !found) { 224 if(Character.isDigit(position.charAt(index))) { 225 found = true; 226 } 227 else { 228 part = position.charAt(index) + part; 229 index--; 230 } 231 } 232 if(found) { 233 feature_name = position.substring(0, index + 1); 234 } 235 // We ran out of string. No digits. Arg! 236 else { 237 part = null; 238 } 239 } 240 // And if all else fails, stick it all in feature. 241 if(feature_name == null || part == null) { 242 feature_name = position; 243 part = ""; 244 } 245 // Now try to retrieve a classifier with the feature name. 246 Object feature = null; 247 String feature_name_lc = feature_name.toLowerCase(); 248 if(feature_name_lc.startsWith("cl") && feature_name.length() >= 3) { 249 String raw_index = feature_name.substring(2); // Lose the 'CL' 250 int index = -1; 251 try { 252 index = Integer.parseInt(raw_index); 253 } 254 catch(NumberFormatException nfe) { 255 nfe.printStackTrace(); 256 } 257 feature = manager.classifiers.getClassifier(index - 1); 258 } 259 else { 260 ///ystem.err.println("name to short for classifier."); 261 } 262 if(feature == null) { 263 feature = feature_name; 264 } 265 ///ystem.err.println("Feature name = " + feature_name + "\nPart = " + part); 266 if(feature instanceof Classifier) { 267 ///ystem.err.println("Feature is a classifier."); 268 } 269 else { 270 ///ystem.err.println("Feature is a String."); 271 } 272 // Now we have a quick look at value. If its true or false we create a FLAG type 273 if(value.equalsIgnoreCase("true")) { 274 addFormat(new Format(feature, part, true)); 275 } 276 else if(value.equalsIgnoreCase("false")) { 277 addFormat(new Format(feature, part, false)); 278 } 279 // Otherwise add a plain old value based format 280 else { 281 addFormat(new Format(feature, part, value)); 282 } 283 return true; 284 } 285 // Somethings gone terribly, terribly wrong. 286 return false; 287 } 288 else { 289 // Ensure we have enough tokens for a format command 290 CommandTokenizer ct = new CommandTokenizer(command); 291 while(ct.countTokens() < 3) { 292 command = manager.parseMore(command); 293 ct = new CommandTokenizer(command); 294 } 295 unresolved_commands.add(command); 296 } 297 return true; 298 } 299 return false; 300 } 113 301 114 /** Method to remove a format. 302 303 115 * @param format The <strong>Format</strong> to remove. 116 */ 304 117 public void removeFormat(Format format) { 305 removeElement(format); 306 gatherer.c_man.configurationChanged(); 307 } 308 /** Method which attempts to reparse obvious format commands which previously referenced unresovable Classifiers. 309 */ 310 public void reparseUnresolved() { 311 for(int i = 0; i < unresolved_commands.size(); i++) { 312 if(!parse((String)unresolved_commands.get(i), true)) { 313 ///ystem.err.println("*** Error: Command " + unresolved_commands.get(i)); 314 } 315 } 316 // Regardless of if they work, clear the commands. 317 unresolved_commands.clear(); 318 } 319 /** Method to produce a block of text representing the format commands in this manager, ready to be used in the collection configuration file. 320 * @return A <strong>String</strong> containing a series of format commands. 321 */ 322 public String toString() { 323 StringBuffer text = new StringBuffer(""); 324 for(int i = 0; i < size(); i++) { 325 Format format = (Format) get(i); 326 text.append(format.toString()); 327 text.append("\n"); 328 } 329 text.append("\n"); 330 return text.toString(); 331 } 118 remove(format); 119 Gatherer.c_man.configurationChanged(); 120 } 121 332 122 /** Overloaded to call get with both a key and an empty argument array. 333 334 335 123 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 124 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 125 */ 336 126 private String get(String key) { 337 127 return get(key, null); 338 128 } 129 339 130 /** Used to retrieve a property value from the Locale specific ResourceBundle, based upon the key and arguments supplied. If the key cannot be found or if some other part of the call fails a default (English) error message is returned. <BR> 340 341 342 343 344 345 346 131 * Here the get recieves a second argument which is an array of Strings used to populate argument fields, denoted {<I>n</I>}, within the value String returned. Note that argument numbers greater than or equal to 32 are automatically mapped to the formatting String named Farg<I>n</I>. 132 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 133 * @param args A <strong>String[]</strong> used to populate argument fields within the complete String. 134 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 135 * @see org.greenstone.gatherer.Gatherer 136 * @see org.greenstone.gatherer.Dictionary 137 */ 347 138 private String get(String key, String args[]) { 348 139 if(key.indexOf('.') == -1) { 349 140 key = "CDM.FormatManager." + key; 350 141 } 351 return gatherer.dictionary.get(key, args); 352 } 353 private class Control 354 extends JPanel { 142 return Gatherer.dictionary.get(key, args); 143 } 144 145 private class FormatControl 146 extends JPanel 147 implements Control { 355 148 /** Do we ignore selection changing events (mainly because we're generating them!) */ 356 149 private boolean ignore = false; … … 404 197 private Vector part_model = null; 405 198 private Vector special_model = null; 406 public Control() { 407 ArrayList feature_model = new ArrayList(); 408 // Add the set options 409 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) { 410 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i])); 411 } 412 // Now the classifiers. 413 for(int j = 0; j < manager.classifiers.size(); j++) { 414 feature_model.add(new Entry(manager.classifiers.getClassifier(j))); 415 } 416 Collections.sort(feature_model); 199 public FormatControl() { 200 ArrayList feature_model = buildFeatureModel(); 417 201 part_model = new Vector(); 418 202 part_model.add("");//get("Custom")); … … 430 214 special_model.add("[parent(Top):_]"); 431 215 special_model.add("[parent(All'_'):_]"); 432 Vector elements = gatherer.c_man.msm.getAssignedElements();216 Vector elements = Gatherer.c_man.getCollection().msm.getAssignedElements(); 433 217 for(int i = 0; i < elements.size(); i++) { 434 218 special_model.add("[" + ((ElementWrapper)elements.get(i)).toString() + "]"); 435 219 } 436 220 Collections.sort(special_model); 437 221 // Create 438 222 add = new JButton(get("Add")); 439 223 add.setEnabled(false); … … 443 227 control_pane = new JPanel(); 444 228 editor = new JTextArea(); 445 editor.setBackground( Color.white);229 editor.setBackground(Gatherer.config.getColor("coloring.editable", false)); 446 230 editor.setCaretPosition(0); 447 231 editor.setLineWrap(true); 448 editor.setWrapStyleWord( true);232 editor.setWrapStyleWord(false); 449 233 editor_label = new JLabel(get("Editor")); 450 234 editor_label.setHorizontalAlignment(JLabel.CENTER); … … 496 280 value_pane = new JPanel(); 497 281 view_pane = new JPanel(); 498 282 // Connect 499 283 add.addActionListener(new AddListener()); 500 284 button_group.add(on); 501 285 button_group.add(off); 502 editor. addKeyListener(new EditorListener());286 editor.getDocument().addDocumentListener(new EditorListener()); 503 287 feature.addActionListener(new FeatureListener()); 504 288 format_list.addListSelectionListener(new FormatListListener()); … … 596 380 ready = true; 597 381 } 382 598 383 public void destroy() { 599 384 } 385 600 386 /** Overriden to ensure that the instructions pane is scrolled to the top. 601 */ 602 public void updateUI() { 387 */ 388 public void gainFocus() { 389 // This is only necessary if the components have been realized 603 390 if(ready) { 604 // Rebuild feature model. 605 ArrayList feature_model = new ArrayList(); 606 // Add the set options 607 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) { 608 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i])); 609 } 610 // Now the classifiers. 611 for(int j = 0; j < manager.classifiers.size(); j++) { 612 feature_model.add(new Entry(manager.classifiers.getClassifier(j))); 613 } 391 model.refresh(); 392 ArrayList feature_model = buildFeatureModel(); 393 // Remember the current selection 394 Object selected_object = feature.getSelectedItem(); 614 395 feature.setModel(new DefaultComboBoxModel(feature_model.toArray())); 396 // Now resotre the selected object as best as possible 397 feature.setSelectedItem(selected_object); 615 398 if(instructions != null) { 616 399 instructions.setCaretPosition(0); 617 400 } 618 } 619 super.updateUI(); 620 } 621 622 401 } 402 } 403 404 public void loseFocus() { 405 // Force all of the Formats to update their names with the correct values. 406 int size = model.getSize(); 407 for(int i = 0; i < size; i++) { 408 Format format = (Format) model.getElementAt(i); 409 format.update(); 410 } 411 } 412 413 private ArrayList buildFeatureModel() { 414 // Rebuild feature model. 415 ArrayList feature_model = new ArrayList(); 416 // Add the set options 417 for(int i = 0; i < Format.DEFAULT_FEATURES.length; i++) { 418 feature_model.add(new Entry(Format.DEFAULT_FEATURES[i])); 419 } 420 // Now the classifiers. 421 for(int j = 0; j < CollectionDesignManager.classifier_manager.getSize(); j++) { 422 feature_model.add(new Entry(CollectionDesignManager.classifier_manager.getClassifier(j))); 423 } 424 Collections.sort(feature_model); 425 return feature_model; 426 } 623 427 624 428 /** Formats the formatting string so that it contains safe characters and isn't enclosed in speech marks etc. (Ironic eh?) 625 626 429 * @see java.lang.StringBuffer 430 */ 627 431 private String format(String raw) { 628 432 String safe = null; … … 665 469 return raw; 666 470 } 471 667 472 /** Listens for clicks on the add button, and if the relevant details are provided adds a new format. */ 668 473 private class AddListener 669 474 implements ActionListener { 670 475 public void actionPerformed(ActionEvent event) { 671 ignore = true;476 //ignore = true; 672 477 Entry entry = (Entry)feature.getSelectedItem(); 673 478 Object f = entry.getFeature(); … … 685 490 format_list.setSelectedValue(current_format, true); 686 491 new_entry = false; 687 ignore = false; 688 } 689 } 492 //ignore = false; 493 } 494 } 495 690 496 private class EditorListener 691 extends KeyAdapter { 692 public void keyReleased(KeyEvent event) { 497 implements DocumentListener { 498 499 public void changedUpdate(DocumentEvent e) { 500 update(); 501 } 502 503 public void insertUpdate(DocumentEvent e) { 504 update(); 505 } 506 507 public void removeUpdate(DocumentEvent e) { 508 update(); 509 } 510 511 public void update() { 693 512 String safe = format(editor.getText()); 694 513 if(!ignore && current_format != null) { … … 700 519 current_format.setValue(""); 701 520 } 702 gatherer.c_man.configurationChanged();703 model.refresh( );521 Gatherer.c_man.configurationChanged(); 522 model.refresh(current_format); 704 523 } 705 524 Entry entry = (Entry) feature.getSelectedItem(); … … 713 532 } 714 533 } 534 715 535 /** This object provides a wrapping around an entry in the format target control, which is tranparent as to whether it is backed by a String or a Classifier. */ 716 536 private class Entry … … 781 601 } 782 602 } 603 783 604 private class FeatureListener 784 605 implements ActionListener { … … 788 609 Entry entry = (Entry) feature.getSelectedItem(); 789 610 String name = entry.toString(); 790 int type = Format.getType(name); 791 switch(type) { 792 case Format.FLAG: 611 if(Format.isParamType(name)) { 793 612 // Flags first. 794 613 part.setEnabled(false); … … 797 616 view_type = FLAG; 798 617 add.setEnabled(true); // One of the options must be selected. 799 break;800 default:618 } 619 else { 801 620 part.setEnabled(true); 802 621 part_pane.add(part, BorderLayout.CENTER); … … 815 634 } 816 635 } 636 817 637 private class FormatListListener 818 638 implements ListSelectionListener { … … 825 645 Entry an_entry = new Entry(current_format.getFeature()); 826 646 feature.setSelectedItem(an_entry); 827 // Try to match the part. 828 part.setSelectedItem(current_format.getPart()); 647 // If we didn't match anything, add it and select it again 648 Entry result_entry = (Entry) feature.getSelectedItem(); 649 if(!an_entry.equals(result_entry)) { 650 feature.insertItemAt(an_entry, feature.getItemCount()); 651 feature.setSelectedItem(an_entry); 652 } 653 654 if(current_format.canHavePart()) { 655 part.setEnabled(true); 656 // Try to match the part. 657 String part_entry = current_format.getPart(); 658 part.setSelectedItem(part_entry); 659 // If we didn't match anything, add it and select it again 660 String selected_part = (String)part.getSelectedItem(); 661 if(!part_entry.equals(selected_part)) { 662 part.insertItemAt(part_entry, part.getItemCount()); 663 feature.setSelectedItem(part_entry); 664 } 665 } 666 else { 667 part.setEnabled(false); 668 } 829 669 // Now use type to determine what controls are visible, and what have initial values. 830 switch(current_format.getType()) { 831 case Format.FLAG: 670 if(current_format.isParamType()) { 832 671 // Flags first. 833 672 part.setEnabled(false); … … 839 678 off.setSelected(!current_format.getState()); 840 679 add.setEnabled(false); // Can only update 841 break;842 default:680 } 681 else { 843 682 part.setEnabled(true); 844 683 part_pane.add(part, BorderLayout.CENTER); … … 907 746 // We have just performed an edit. Immediately update the format and model. 908 747 current_format.setState(on.isSelected()); 909 model.refresh( );748 model.refresh(current_format); 910 749 } 911 750 } … … 917 756 // We have just performed an edit. Immediately update the format and model. 918 757 current_format.setValue(value.getText()); 919 model.refresh( );758 model.refresh(current_format); 920 759 } 921 760 } -
trunk/gli/src/org/greenstone/gatherer/cdm/Index.java
r4675 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 27 package org.greenstone.gatherer.cdm; 44 /************************************************************************************** 45 * Title: Gatherer 46 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 47 * Copyright: Copyright (c) 2001 48 * Company: The University of Waikato 49 * Written: 03/05/02 50 * Revised: 17/11/02 51 **************************************************************************************/ 52 import java.util.Collections; 53 import java.util.Comparator; 54 import java.util.StringTokenizer; 55 import java.util.Vector; 28 29 import java.util.*; 30 import org.greenstone.gatherer.Gatherer; 31 import org.greenstone.gatherer.cdm.CollectionConfiguration; 32 import org.greenstone.gatherer.cdm.CollectionDesignManager; 56 33 import org.greenstone.gatherer.cdm.CollectionMeta; 34 import org.greenstone.gatherer.cdm.DOMProxyListEntry; 35 import org.greenstone.gatherer.msm.ElementWrapper; 57 36 import org.greenstone.gatherer.msm.MSMUtils; 37 import org.greenstone.gatherer.util.StaticStrings; 58 38 import org.greenstone.gatherer.util.Utility; 59 import org.w3c.dom. Element;39 import org.w3c.dom.*; 60 40 /** This class encapsulates a single indexing pair. 61 41 * @author John Thompson, Greenstone Digital Library, University of Waikato 62 * @version 2. 242 * @version 2.3d 63 43 */ 64 44 public class Index 65 implements Comparable { 66 /** A refernce to the main manager for access to other sub-managers. */ 67 private CollectionDesignManager manager = null; 68 /** The level of this index. */ 69 private int level = 0; 70 /** The sources for data this index is built apon, which are either fully qualified metadata element names or 'text'. */ 71 private Vector sources = null; 72 /** An element in the index level enumeration. */ 73 static public final int DOCUMENT = 0; 74 /** An element in the index level enumeration. */ 75 static public final int PARAGRAPH = 1; 76 /** An element in the index level enumeration. */ 77 static public final int SECTION = 2; 45 implements Comparable, DOMProxyListEntry { 78 46 /** An values of items in the index level enumeration. */ 79 47 static public final String LEVEL[] = {"document","paragraph","section"}; 80 48 81 /** Constructor. 82 * @param level The level of this index as a <strong>String</string>. 83 * @param metadata The fully qualified name of the metadata this index is built on as a <strong>String</strong>, or <i>null</i> in which case the data defaults to "text". 84 */ 85 public Index(int level, Vector sources, CollectionDesignManager manager) { 49 private ArrayList sources = null; 50 /** The level of this index (if old sckool MG). */ 51 private int level = -1; 52 /** The element this index is based upon. */ 53 private Element element = null; 54 /** The unique, if cryptic, identifier of an index. */ 55 private String id = null; 56 57 /** Default constructor, which should only be used during DOMProxyListModel creation. */ 58 public Index() { 59 } 60 61 /** Constructor. */ 62 public Index(Element element) { 63 this.element = element; 64 } 65 66 /** Constructor for a newly assigned index. */ 67 public Index(ArrayList sources) { 68 this.sources = sources; 69 // Create a new element 70 Document document = CollectionDesignManager.collect_config.document; 71 element = document.createElement(CollectionConfiguration.INDEX_ELEMENT); 72 // For each source add a content element 73 int size = sources.size(); 74 for(int i = 0; i < size; i++) { 75 Element content_element = document.createElement(CollectionConfiguration.CONTENT_ELEMENT); 76 Object source_object = sources.get(i); 77 if(source_object instanceof ElementWrapper) { 78 content_element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, ((ElementWrapper)source_object).getName()); 79 } 80 else { 81 content_element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, source_object.toString()); 82 } 83 element.appendChild(content_element); 84 content_element = null; 85 } 86 document = null; 87 } 88 89 /** Constructor for a newly assigned index with specified level (old skool). */ 90 public Index(int level, ArrayList sources) { 91 this(sources); 86 92 this.level = level; 87 this.manager = manager; 88 this.sources = sources; 89 if(this.sources == null) { 90 this.sources = new Vector(); 91 this.sources.add("text"); 92 } 93 } 93 element.setAttribute(CollectionConfiguration.LEVEL_ATTRIBUTE, LEVEL[level]); 94 } 95 94 96 /** Method to compare two indexes. 95 96 97 98 97 * @param object The other index as an <strong>Object</strong>. 98 * @return An <i>int</i> which indicates how the indexes compare. 99 * @see java.lang.String 100 */ 99 101 public int compareTo(Object object) { 100 return toString(false).compareTo(object.toString()); 101 } 102 return id.compareTo(((Index)object).getID()); 103 } 104 105 public DOMProxyListEntry create(Element element) { 106 return new Index(element); 107 } 108 102 109 /** Method to test for the equality of two indexes. 103 104 105 110 * @param object The other index as an <strong>Object</strong>. 111 * @return A <i>boolean</i> which is <i>true</i> if the two indexes are equal, <i>false</i> otherwise. 112 */ 106 113 public boolean equals(Object object) { 107 if(compareTo(object) == 0) { 108 return true; 109 } 110 return false; 111 } 112 /** Method to get the data source of this index. 113 * @return A <strong>String</string> which is a comma separated list of either fully qualified names of an assigned metadata elements, or "text". 114 */ 115 public String getData() { 116 String result = ""; 117 Collections.sort(sources, new IndexComparator()); 118 for(int i = 0; i < sources.size(); i++) { 119 result = result + sources.get(i).toString(); 120 if(i < sources.size() - 1) { 121 result = result + ","; 122 } 123 } 124 return result; 125 } 126 /** Method to get the data source of this index. 127 * @return A <strong>String</string> which is a comma separated list of either fully qualified names of an assigned metadata elements, or "text". 128 * Note, greenstone extracted metadata do not have the ex. 129 */ 130 public String getDataConfig() { 131 String result = ""; 132 Collections.sort(sources, new IndexComparator()); 133 for(int i = 0; i < sources.size(); i++) { 134 String source = sources.get(i).toString(); 135 if (source.startsWith(Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP)) { 136 // remove the ex. bit 137 source = source.substring(source.indexOf(MSMUtils.NS_SEP)+1); 138 } 139 result = result + source; 140 if(i < sources.size() - 1) { 141 result = result + ","; 142 } 143 } 144 return result; 145 } 146 114 return (compareTo(object) == 0); 115 } 116 117 public Element getElement() { 118 return element; 119 } 120 147 121 /** Method to get the value of level. 148 * @return The value of level as a <strong>String</strong>. 149 122 * @return the level as a int 123 */ 150 124 public int getLevel() { 125 if(level == -1) { 126 String level_str = element.getAttribute(CollectionConfiguration.LEVEL_ATTRIBUTE); 127 for(int i = 0; level == -1 && i < LEVEL.length; i++) { 128 if(level_str.equals(LEVEL[i])) { 129 level = i; 130 } 131 } 132 level_str = null; 133 } 151 134 return level; 152 135 } 153 /** Method to get the value of metadata. 154 * @return The value of metadata as an <strong>Vector</strong>. 155 */ 156 public Vector getMetadata() { 136 137 public String getID() { 138 if(id == null) { 139 StringBuffer id_buffer = new StringBuffer(); 140 // Write level information, if any. 141 int level = getLevel(); 142 if(0 <= level && level < 3) { 143 id_buffer.append(LEVEL[level]); 144 id_buffer.append(StaticStrings.COLON_CHARACTER); 145 } 146 // Write data information. Retrieve each of the content sources and add them in a comma separated list. 147 ArrayList sources = getSources(); 148 int sources_size = sources.size(); 149 for(int i = 0; i < sources_size; i++) { 150 Object source_object = sources.get(i); 151 if(source_object instanceof ElementWrapper) { 152 id_buffer.append(((ElementWrapper)source_object).getName()); 153 } 154 else { 155 id_buffer.append(source_object.toString()); 156 } 157 id_buffer.append(StaticStrings.COMMA_CHARACTER); 158 } 159 sources = null; 160 id = id_buffer.substring(0, id_buffer.length() - 1); 161 } 162 return id; 163 } 164 165 /** Retrieve the sources of this index. 166 * @return the sources as an ArrayList 167 */ 168 public ArrayList getSources() { 169 if(sources == null) { 170 sources = new ArrayList(); 171 NodeList content_elements = element.getElementsByTagName(CollectionConfiguration.CONTENT_ELEMENT); 172 int content_elements_length = content_elements.getLength(); 173 for(int i = 0; i < content_elements_length; i++) { 174 Element content_element = (Element) content_elements.item(i); 175 sources.add(content_element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE)); 176 } 177 content_elements = null; 178 Collections.sort(sources); 179 } 157 180 return sources; 158 181 } 159 /** Method to retrieve this indexes name. 160 * @return A <strong>String</strong>. 161 */ 162 public String getName() { 163 if(manager != null) { 164 String name = LEVEL[level] + ":" + getData(); 165 Language language = manager.languages.getDefaultLanguage(); 166 CollectionMeta metadata = manager.collectionmetadatum.getMetadata(name, language, true); 167 if(metadata != null) { 168 return metadata.getValue(); 169 } 170 } 171 return ""; 172 173 } 182 183 public boolean isAssigned() { 184 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR)); 185 } 186 187 public void setAssigned(boolean assigned) { 188 if(element != null) { 189 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 190 } 191 } 192 193 public void setElement(Element element) { 194 this.element = element; 195 this.level = -1; 196 this.id = null; 197 this.sources = null; 198 } 199 200 /** Method to set the level of this index which can only be used for the default index. 201 * @param level the new level as an int 202 */ 203 public void setLevel(int new_level) { 204 if(element != null && element.getNodeName().equals(CollectionConfiguration.INDEX_DEFAULT_ELEMENT)) { 205 element.setAttribute(CollectionConfiguration.LEVEL_ATTRIBUTE, LEVEL[new_level]); 206 this.id = null; // Regenerate ID. 207 this.level = new_level; 208 } 209 else { 210 Gatherer.println("Error! Called setLevel() of index other than the default."); 211 } 212 } 213 214 /** Method to set the sources for this index which can only be used for the default index. 215 * @param sources an ArrayList of source names 216 */ 217 public void setSources(ArrayList sources) { 218 if(element != null && element.getNodeName().equals(CollectionConfiguration.INDEX_DEFAULT_ELEMENT)) { 219 // Erase old sources 220 MSMUtils.clear(element); 221 // For each entry in the sources array add a new content element. 222 int size = sources.size(); 223 for(int i = 0; i < size; i++) { 224 Element content_element = element.getOwnerDocument().createElement(CollectionConfiguration.CONTENT_ELEMENT); 225 content_element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, (String) sources.get(i)); 226 element.appendChild(content_element); 227 content_element = null; 228 } 229 this.id = null; // Regenerate ID. 230 this.sources = sources; 231 } 232 else { 233 Gatherer.println("Error! Called setSource() of index other than the default."); 234 } 235 } 236 174 237 /** Method to turn this object into a string representation ready to be placed in the collection configuration file. 175 176 238 * @return A <strong>String</strong> containing the information of this class. 239 */ 177 240 public String toString() { 178 return LEVEL[level] + ":" + getData(); 179 } 180 /** Retrieve a textual representation of this index. 181 * @param show_name <i>true</i> if you want the name of this index, <i>false</i> for the gsdl index reference. 182 */ 183 public String toString(boolean show_name) { 184 if(show_name) { 185 return getName(); 186 } 187 return LEVEL[level] + ":" + getData(); 188 } 189 190 /** Retrieve a textual representation of this index, specifically for the configuration files. Extracted metadata is shown to teh user and stored as ex.MD, however in the config file it should have no namespace */ 191 public String toStringConfig() { 192 193 return LEVEL[level] + ":" + getDataConfig(); 194 } 195 196 /** Method to parse a configuration file index specification into an Index 197 * object. returns null if invalid syntax */ 198 public static Index parseIndexConfig(String entry, CollectionDesignManager manager) { 199 // all (mg) indexes must start with level: 200 if(entry.indexOf(":") == -1) { 201 return null; 202 } 203 204 String level_str = entry.substring(0, entry.indexOf(":")); 205 String sources_raw = entry.substring(entry.indexOf(":") + 1); 206 Vector sources = new Vector(); 207 StringTokenizer st = new StringTokenizer(sources_raw, ","); 208 while(st.hasMoreTokens()) { 209 String token = st.nextToken(); 210 // We may have to replace old : with whatever namespace separator we are using. 211 token = token.replace(':', MSMUtils.NS_SEP); 212 // if there is no namespace, we need to add one, except for text 213 if (token.indexOf(MSMUtils.NS_SEP)==-1) { 214 if (!token.equals("text")) { 215 token = Utility.EXTRACTED_METADATA_NAMESPACE+MSMUtils.NS_SEP+token; 216 } 217 } 218 219 sources.add(token); 220 } 221 Index index = null; 222 for(int i = 0; i < Index.LEVEL.length; i++) { 223 if(level_str.equals(Index.LEVEL[i])) { 224 return new Index(i, sources, manager); 225 226 } 227 } 228 // somethings gone wrong 229 return null; 230 231 } 232 233 /** A custom comparator for comparing Indexes. */ 234 private class IndexComparator 235 implements Comparator { 236 /** Method to compare two objects, which may be either indexes or strings. 237 * @param object1 One object as an <strong>Object</strong>. 238 * @param object2 Another object as an <strong>Object</strong>. 239 * @return An <i>int</i> which indicates how they compare. 240 * @see java.lang.String 241 */ 242 public int compare(Object object1, Object object2) { 243 if(object1 instanceof Index && object2 instanceof Index) { 244 Index index1 = (Index)object1; 245 Index index2 = (Index)object2; 246 return index1.toString(false).compareTo(index2.toString(false)); 247 } 248 else if(object1 instanceof Index) { 249 Index index = (Index) object1; 250 return index.toString(false).compareTo(object2.toString()); 251 } 252 else if(object2 instanceof Index) { 253 Index index = (Index) object2; 254 return object1.toString().compareTo(index.toString(false)); 255 } 256 return object1.toString().compareTo(object2.toString()); 257 } 258 /** Method to test for the equality of two objects, which may be indexes or strings. 259 * @param object Another object as an <strong>Object</strong>. 260 * @return A <i>boolean</i> which is <i>true</i> if the two objects are equal, <i>false</i> otherwise. 261 */ 262 public boolean equals(Object object) { 263 if(compareTo(object) == 0) { 264 return true; 265 } 266 return false; 267 } 241 String id = getID(); 242 StringBuffer text = new StringBuffer(id); 243 CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(StaticStrings.STOP_CHARACTER + id, false); 244 if(metadatum != null) { 245 text.append(" \""); 246 text.append(metadatum.getValue()); 247 text.append("\""); 248 } 249 return text.toString(); 268 250 } 269 251 } -
trunk/gli/src/org/greenstone/gatherer/cdm/IndexManager.java
r4675 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 27 package org.greenstone.gatherer.cdm; 44 /************************************************************************************** 45 * Title: Gatherer 46 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 47 * Copyright: Copyright (c) 2001 48 * Company: The University of Waikato 49 * Written: 03/05/02 50 * Revised: 17/11/02 - Commented 51 **************************************************************************************/ 52 import java.awt.BorderLayout; 53 import java.awt.Color; 54 import java.awt.Component; 55 import java.awt.Dimension; 56 import java.awt.GridLayout; 57 import java.awt.event.ActionEvent; 58 import java.awt.event.ActionListener; 59 import java.awt.event.KeyAdapter; 60 import java.awt.event.KeyEvent; 61 import java.util.Collections; 62 import java.util.StringTokenizer; 63 import java.util.Vector; 64 import javax.swing.BorderFactory; 65 import javax.swing.DefaultListCellRenderer; 66 import javax.swing.DefaultListModel; 67 import javax.swing.JButton; 68 import javax.swing.JComboBox; 69 import javax.swing.JLabel; 70 import javax.swing.JList; 71 import javax.swing.JOptionPane; 72 import javax.swing.JPanel; 73 import javax.swing.JScrollPane; 74 import javax.swing.JTextArea; 75 import javax.swing.JTextField; 76 import javax.swing.event.ListDataEvent; 77 import javax.swing.event.ListDataListener; 78 import javax.swing.event.ListSelectionEvent; 79 import javax.swing.event.ListSelectionListener; 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.util.*; 31 import javax.swing.*; 32 import javax.swing.event.*; 80 33 import org.greenstone.gatherer.Gatherer; 34 import org.greenstone.gatherer.cdm.CollectionMeta; 81 35 import org.greenstone.gatherer.cdm.CommandTokenizer; 36 import org.greenstone.gatherer.cdm.Control; 37 import org.greenstone.gatherer.cdm.DOMProxyListModel; 82 38 import org.greenstone.gatherer.cdm.Index; 83 39 import org.greenstone.gatherer.msm.ElementWrapper; 84 40 import org.greenstone.gatherer.msm.MSMUtils; 85 41 import org.greenstone.gatherer.util.ExclusiveListSelectionListener; 86 import org.w3c.dom.Element; 42 import org.greenstone.gatherer.util.StaticStrings; 43 import org.w3c.dom.*; 87 44 /** This class is resposible for storing the indexes which have been assigned to this collection and the default index, and providing methods for interacting with both these data pools. It also knows how to turn itself into a String as it would be displayed in the collection configuration file. 88 45 * @author John Thompson, Greenstone Digital Library, University of Waikato … … 90 47 */ 91 48 public class IndexManager 92 extends DefaultListModel { 93 /** A reference to our creator, the collection design manager. */ 94 private CollectionDesignManager manager = null; 49 extends DOMProxyListModel { 95 50 /** The controls for editing the indexes. */ 96 51 private Control controls = null; 97 52 /** A reference to ourselves so our inner methods have access. */ 98 private DefaultListModel model = null; 99 /** A reference to the Gatherer, for access to the Dictionary and messaging purposes. */ 100 private Gatherer gatherer = null; 53 private DOMProxyListModel model = null; 101 54 /** The default index. */ 102 55 private Index default_index = null; 103 /** Constructor. 104 * @param gatherer A reference to the <strong>Gatherer</strong>. 105 * @param manager A reference to the <strong>CollectionDesignManager</strong>. 106 */ 107 public IndexManager(Gatherer gatherer, CollectionDesignManager manager) { 108 super(); 109 this.gatherer = gatherer; 110 this.manager = manager; 111 this.model = this; 56 /** Constructor. */ 57 public IndexManager(Element indexes) { 58 super(indexes, CollectionConfiguration.INDEX_ELEMENT, new Index()); 59 Gatherer.println("IndexManager: " + getSize() + " indexes parsed."); 60 model = this; 61 // Parse and retrieve the default index 62 NodeList default_index_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.INDEX_DEFAULT_ELEMENT); 63 if(default_index_elements.getLength() > 0) { 64 default_index = new Index((Element)default_index_elements.item(0)); 65 } 112 66 } 113 67 /** Method to add a new index. 114 * @param index The <strong>Index</strong> to add. 115 * @see org.greenstone.gatherer.Gatherer 116 * @see org.greenstone.gatherer.collection.CollectionManager 117 */ 118 public void addIndex(Index index) { 68 * @param index The <strong>Index</strong> to add. 69 * @see org.greenstone.gatherer.Gatherer 70 * @see org.greenstone.gatherer.collection.CollectionManager 71 */ 72 public void addIndex(Index index, CollectionMeta metadatum) { 73 ///ystem.err.println("Adding an index: " + index.toString()); 119 74 if(!contains(index)) { 120 String index_str = index.toString(false).toLowerCase(); 121 // Add alphabetically. 122 for(int i = 0; i < size(); i++) { 123 Index sibling = (Index) get(i); 124 String sibling_str = sibling.toString(false).toLowerCase(); 125 int position = index_str.compareTo(sibling_str); 126 // Sibling is before index. 127 if(position > 0) { 128 // Carry on. 129 } 130 // Index is equal to, or before sibling. Insert it. 131 else if(position == 0 || position < 0) { 132 add(i, index); 133 gatherer.c_man.configurationChanged(); 134 return; 135 } 136 } 137 // If we got this far, we haven't inserted index, and we are out of model so. 138 addElement(index); 139 gatherer.c_man.configurationChanged(); 75 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum); 76 // Retrieve the currently last index 77 Index last_index = (Index)getElementAt(getSize() - 1); 78 addAfter(index, last_index); 79 Gatherer.c_man.configurationChanged(); 140 80 } 141 81 else { 142 JOptionPane.showMessageDialog(manager.gui, get("CDM.IndexManager.Index_Exists"), get("General.Warning"), JOptionPane.WARNING_MESSAGE); 143 } 144 } 145 /** Method to acquire the controls for editing the indexes. 146 * @return A <strong>JPanel</strong> containing the controls. 147 * @see org.greenstone.gatherer.cdm.IndexManager.Control 148 */ 149 public JPanel getControls() { 150 if(controls == null) { 151 controls = new Control(); 152 } 153 return controls; 154 } 155 /** Method to get the default index. 156 * @return The default <strong>Index</strong>. 157 */ 158 public Index getDefault() { 159 return default_index; 160 } 161 /** Method to retrieve a certain index, as referenced by an index number. 162 * @param index An <i>int</i> which indicates the position of the desired index. 163 * @return The <strong>Index</strong> at the given index, or <i>null</i> if no such index exists. 164 */ 165 public Index getIndex(int index) { 166 if(0 <= index && index < size()) { 167 return (Index)get(index); 168 } 169 return null; 170 } 171 /** Method to retrieve a certain index, given its name. 172 * @param name The name of the index as a <Strong>String</strong>. 173 * @return The <strong>Index</strong> that matches name, or <i>null</i> if no such index exists. 174 */ 175 public Index getIndex(String name) { 176 ///ystem.err.println("Searching for index " + name); 177 for(int i = 0; i < size(); i++) { 178 Index index = (Index) get(i); 179 if(index.toString(false).equals(name)) { 180 ///ystem.err.println("Found."); 181 return (Index)get(i); 182 } 183 } 184 ///ystem.err.println("No such index."); 185 return null; 186 } 187 /** A method to retrieve all of the indexes associated with this manager. 188 * @return A <strong>Vector</strong> of <strong>Index</strong>es. 189 */ 190 public Vector getIndexes() { 191 Vector indexes = new Vector(); 192 for(int i = 0; i < size(); i++) { 193 indexes.add(get(i)); 194 } 195 Collections.sort(indexes); 196 return indexes; 197 } 198 /** Mark the current set of controls, if any, as obsolete and deallocate them. If further need of the controls will cause new controls to be created. 199 * @see org.greenstone.gatherer.cdm.IndexManager.Control 200 */ 201 public void invalidateControls() { 82 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.IndexManager.Index_Exists"), get("General.Warning"), JOptionPane.WARNING_MESSAGE); 83 } 84 } 85 86 public void destroy() { 202 87 if(controls != null) { 203 88 controls.destroy(); 204 } 205 controls = null; 206 } 207 /** Method that attempts to parse an index related command from the given command. If such a command is parsed, it is immediately registered with this manager. 208 * @param command The <strong>String</strong> to parse. 209 * @return A <i>boolean</i> which is <i>true</i> if a command was parsed, <i>false</i> otherwise. 210 * @see org.greenstone.gatherer.cdm.CommandTokenizer 211 * @see org.greenstone.gatherer.cdm.Index 212 */ 213 public boolean parse(String command) { 214 String temp = command.toLowerCase(); 215 if(temp.startsWith("indexes")) { 216 CommandTokenizer ct = new CommandTokenizer(command); 217 ct.nextToken(); // Throw away indexes. 218 while(ct.hasMoreTokens()) { 219 String entry = ct.nextToken(); 220 Index index = Index.parseIndexConfig(entry, manager); 221 if (index != null) { 222 addIndex(index); 223 224 } else { // return false if there is one error?? 225 return false; 226 } 227 } 228 229 return true; 230 } 231 else if(temp.startsWith("defaultindex")) { 232 CommandTokenizer ct = new CommandTokenizer(command); 233 ct.nextToken(); 234 String entry = ct.nextToken(); 235 Index index = Index.parseIndexConfig(entry, manager); 236 if (index != null) { 237 setDefault(index); 238 return true; 239 } 240 return false; 241 } 242 243 return false; 244 } 245 246 public void removeAll() { 247 removeAllElements(); 89 controls = null; 90 } 248 91 default_index = null; 249 gatherer.c_man.configurationChanged(); 92 model = null; 93 } 94 95 /** Method to acquire the controls for editing the indexes. 96 * @return the Control 97 */ 98 public Control getControls() { 99 if(controls == null) { 100 // Build controls 101 controls = new IndexControl(); 102 } 103 return controls; 104 } 105 106 /** Method to get the default index. 107 * @return The default <strong>Index</strong>. 108 */ 109 public Index getDefault() { 110 if(default_index != null && default_index.isAssigned()) { 111 return default_index; 112 } 113 else { 114 return null; 115 } 116 } 117 118 /** Method to retrieve a certain index, as referenced by an index number. 119 * @param index An <i>int</i> which indicates the position of the desired index. 120 * @return The <strong>Index</strong> at the given index, or <i>null</i> if no such index exists. 121 */ 122 public Index getIndex(int index) { 123 if(0 <= index && index < getSize()) { 124 return (Index)getElementAt(index); 125 } 126 return null; 127 } 128 129 /** Method to retrieve a certain index, given its id. 130 * @param id the id of the index as a String 131 * @return the Index that matches id, or null if no such index exists 132 */ 133 public Index getIndex(String id) { 134 int size = getSize(); 135 for(int i = 0; i < size; i++) { 136 Index index = (Index) getElementAt(i); 137 if(index.getID().equals(id)) { 138 return index; 139 } 140 } 141 return null; 142 } 143 144 public ArrayList getIndexes() { 145 return children(); 250 146 } 251 147 252 148 /** Method to remove a certain index. 253 * @param index The <Strong>Index</strong>to remove.254 255 256 257 258 149 * @param index the Index to remove. 150 * @see org.greenstone.gatherer.Gatherer 151 * @see org.greenstone.gatherer.cdm.CollectionDesignManager 152 * @see org.greenstone.gatherer.cdm.CollectionMetaManager 153 * @see org.greenstone.gatherer.collection.CollectionManager 154 */ 259 155 public void removeIndex(Index index) { 260 156 if(index != null) { 261 String name = index.getName(); 262 if(name != null) { 263 Language default_language = manager.languages.getDefaultLanguage(); 264 CollectionMeta metadata = new CollectionMeta(manager, index, default_language, name); 265 manager.collectionmetadatum.removeMetadata(metadata); 266 } 267 removeElement(index); 157 // Remove any current metadata from this index 158 CollectionDesignManager.collectionmeta_manager.removeMetadata(StaticStrings.STOP_CHARACTER + index.getID()); 159 // Check if the index removed happens to be the default index 268 160 if(default_index != null && default_index.equals(index)) { 269 default_index = null; 270 } 271 gatherer.c_man.configurationChanged(); 272 } 273 } 161 default_index.setAssigned(false); 162 } 163 // Remove the index 164 remove(index); 165 Gatherer.c_man.configurationChanged(); 166 } 167 } 168 274 169 /** Method to set the default index. 275 * @param index The new default <strong>Index</strong>. 276 277 278 170 * @param index the new default Index 171 * @see org.greenstone.gatherer.Gatherer 172 * @see org.greenstone.gatherer.collection.CollectionManager 173 */ 279 174 public void setDefault(Index index) { 280 default_index = index; 281 if(index != null && !contains(index)) { 282 addElement(index); 283 } 284 gatherer.c_man.configurationChanged(); 285 } 286 /** Method to print out the contents of this class as a string. 287 * @return A <strong>String</strong> just as it would appear in the colleciton configuration file. 288 */ 289 public String toString() { 290 String text = ""; 291 // First the indexes. 292 if(size() > 0) { 293 text = "indexes "; 294 for(int i = 0; i < size(); i++) { 295 Index index = (Index) get(i); 296 text = text + index.toStringConfig(); 297 if(i < size() - 1) { 298 text = text + " "; 299 } 300 } 301 // Now the default index if there is one, or just the first index 302 // if there isn't 175 if(index != null) { 176 if(default_index == null) { 177 // Create the default index element, and place immediately after indexes element. 178 Element default_index_element = root.getOwnerDocument().createElement(CollectionConfiguration.INDEX_DEFAULT_ELEMENT); 179 default_index = new Index(default_index_element); 180 Node target_node = CollectionConfiguration.findInsertionPoint(default_index_element); 181 if(target_node != null) { 182 root.getOwnerDocument().getDocumentElement().insertBefore(default_index_element, target_node); 183 } 184 else { 185 root.getOwnerDocument().getDocumentElement().appendChild(default_index_element); 186 } 187 } 188 default_index.setAssigned(true); 189 default_index.setLevel(index.getLevel()); 190 default_index.setSources(index.getSources()); 191 } 192 else { 303 193 if(default_index != null) { 304 text = text + "\ndefaultindex " + default_index.toStringConfig() + "\n"; 305 } 306 text = text + "\n"; 307 } 308 return text; 309 } 310 311 312 313 194 default_index.setAssigned(false); 195 } 196 } 197 Gatherer.c_man.configurationChanged(); 198 } 314 199 315 200 /** Overloaded to call get with both a key and an empty argument array. 316 317 318 201 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 202 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 203 */ 319 204 private String get(String key) { 320 205 return get(key, null); 321 206 } 207 322 208 /** Used to retrieve a property value from the Locale specific ResourceBundle, based upon the key and arguments supplied. If the key cannot be found or if some other part of the call fails a default (English) error message is returned. <BR> 323 324 325 326 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call.327 328 329 209 * Here the get recieves a second argument which is an array of Strings used to populate argument fields, denoted {<I>n</I>}, within the value String returned. Note that argument numbers greater than or equal to 32 are automatically mapped to the formatting String named Farg<I>n</I>. 210 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 211 * @param args A <strong>String[]</strong> used to populate argument fields within the complete String. 212 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatically populated with formatting Strings of with argument String provided in the get call. 213 * @see org.greenstone.gatherer.Gatherer 214 * @see org.greenstone.gatherer.Dictionary 215 */ 330 216 private String get(String key, String args[]) { 331 217 if(key.indexOf('.') == -1) { 332 218 key = "CDM.IndexManager." + key; 333 219 } 334 return gatherer.dictionary.get(key, args); 335 } 220 return Gatherer.dictionary.get(key, args); 221 } 222 336 223 /** This class creates a set of controls for editing the indexes. */ 337 private class Control 338 extends JPanel { 224 private class IndexControl 225 extends JPanel 226 implements Control { 339 227 /** The default size of a label on this control. */ 340 228 private Dimension LABEL_SIZE = new Dimension(120,25); … … 406 294 * @see org.greenstone.gatherer.util.ExclusiveListSelectionListener 407 295 */ 408 public Control() {296 public IndexControl() { 409 297 super(); 410 298 source_model = new Vector(); 411 299 source_model.add("text"); 412 source_model.addAll(gatherer.c_man.msm.getAssignedElements()); 413 //source_model.addAll(gatherer.c_man.msm.getElements()); 300 source_model.addAll(Gatherer.c_man.getCollection().msm.getAssignedElements()); 414 301 // Creation 415 302 add = new JButton(get("Add")); … … 428 315 default_pane = new JPanel(); 429 316 if(default_index != null) { 430 default_value = new JTextField(default_index.toString( true));317 default_value = new JTextField(default_index.toString()); 431 318 default_value.setCaretPosition(0); 432 319 } … … 440 327 index_label = new JLabel(get("Indexes")); 441 328 index_list = new JList(model); 442 index_list.setCellRenderer(new IndexListCellRenderer());443 329 instructions = new JTextArea(get("Instructions")); 444 330 instructions.setEditable(false); … … 550 436 } 551 437 /* Destructor, removes persistant listeners from the Dictionary. 552 438 */ 553 439 public void destroy() { 554 440 } 555 /** We override the updateUI method so that we can ensure we are scrolled to the top of the instructions box first. 556 * @see org.greenstone.gatherer.Gatherer 557 * @see org.greenstone.gatherer.collection.CollectionManager 558 * @see org.greenstone.gatherer.msm.MetadataSetManager 559 */ 560 public void updateUI() { 441 442 public void gainFocus() { 561 443 if(instructions != null) { 562 444 instructions.setCaretPosition(0); … … 566 448 source_model.clear(); 567 449 source_model.add("text"); 568 source_model.addAll( gatherer.c_man.msm.getAssignedElements());450 source_model.addAll(Gatherer.c_man.getCollection().msm.getAssignedElements()); 569 451 // reset the model in the list - needed if the model is larger than when it was first created, the list doesn't display 570 452 source_list.setListData(source_model); 571 453 572 454 } 573 // Faster than a NPE its the - 'Super class'. 574 super.updateUI(); 575 } 455 } 456 457 public void loseFocus() { 458 } 459 576 460 /** Listens for actions apon the 'add' button in the IndexManager controls, and if detected calls the add method of the manager with a newly created index. */ 577 461 private class AddListener … … 589 473 if(!source_list.isSelectionEmpty() && name.getText().length() != 0) { 590 474 Object object[] = source_list.getSelectedValues(); 591 Vector sources = new Vector();475 ArrayList sources = new ArrayList(); 592 476 for(int i = 0; i < object.length; i++) { 593 477 sources.add(object[i]); 594 478 } 595 Index index = new Index(level.getSelectedIndex(), sources, manager); 479 object = null; 480 Index index = new Index(level.getSelectedIndex(), sources); 481 sources = null; 596 482 // Before we add the index to the model, we have to add the collection metadata for this. 597 Language language = manager.languages.getDefaultLanguage(); 598 CollectionMeta metadata = new CollectionMeta(manager, index, language, name.getText()); 599 manager.collectionmetadatum.addMetadata(metadata); 483 CollectionMeta metadatum = new CollectionMeta(StaticStrings.STOP_CHARACTER + index.getID()); 484 metadatum.setValue(name.getText()); 600 485 // Finally add index. 601 addIndex(index); 486 addIndex(index, metadatum); 487 metadatum = null; 488 index = null; 602 489 } 603 490 } … … 606 493 private class ClearDefaultListener 607 494 implements ActionListener { 608 609 610 495 /** If called when an action occurs on a registered component, we clear the default index. 496 * @param event An <strong>ActionEvent</strong> containing extra information about the action that occured. 497 */ 611 498 public void actionPerformed(ActionEvent event) { 612 499 setDefault(null); … … 643 530 if(default_index != null) { 644 531 clear_default.setEnabled(true); 645 default_value.setText(default_index.toString( true));532 default_value.setText(default_index.toString()); 646 533 default_value.setCaretPosition(0); 647 534 } … … 698 585 } 699 586 } 700 701 702 private class IndexListCellRenderer703 extends DefaultListCellRenderer {704 705 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {706 StringBuffer text = new StringBuffer(value.toString());707 // Retrieve the indexes name if any.708 CollectionMeta metadata = manager.collectionmetadatum.getMetadata(value, manager.languages.getDefaultLanguage(), true);709 if(metadata != null) {710 text.append(" \"");711 text.append(metadata.getValue());712 text.append("\"");713 }714 return super.getListCellRendererComponent(list, text.toString(), index, isSelected, cellHasFocus);715 }716 717 }718 719 587 } 720 588 } -
trunk/gli/src/org/greenstone/gatherer/cdm/Language.java
r4675 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 27 package org.greenstone.gatherer.cdm; 44 28 /************************************************************************************** 45 * Title: Gatherer46 * Description: The Gatherer: a tool for gathering and enriching a digital collection.47 * Copyright: Copyright (c) 200148 * Company: The University of Waikato49 29 * Written: 08/05/02 50 30 * Revised: 17/11/02 - Commented 31 * 07/07/03 - DOM support 51 32 **************************************************************************************/ 52 33 import org.greenstone.gatherer.cdm.CollectionConfiguration; 34 import org.greenstone.gatherer.cdm.CollectionDesignManager; 35 import org.greenstone.gatherer.cdm.DOMProxyListEntry; 36 import org.greenstone.gatherer.msm.MSMUtils; 37 import org.w3c.dom.*; 53 38 /** A pretty unexciting extension of a two character string, in that it has a field which details if its the default language. 54 39 * @author John Thompson, Greenstone Digital Library, University of Waikato … … 56 41 */ 57 42 public class Language 58 implements Comparable { 59 /** Is this language the default one. */ 60 private boolean default_language = false; 43 implements Comparable, DOMProxyListEntry { 44 /** The Element this language entry is based upon. */ 45 private Element element = null; 46 /** The two character code for this language. */ 47 private String code = null; 61 48 /** The name of this language. */ 62 49 private String name = null; 63 /** The two character code for this language. */ 64 private String value = null; 65 /** Constructor. 66 * @param value A <strong>String</strong> representing the code for this language. 67 * @param name A <strong>String</strong> representing the name of this language. 68 * @param default_language A <i>boolean</i> which is <i>true</i> if this language is the default one. 69 */ 70 public Language(String value, String name, boolean default_language) { 71 this.default_language = default_language; 72 this.name = name; 73 this.value = value.substring(0, 2); 50 51 public Language() { 74 52 } 75 /** Copy constructor. 76 * @param language The <strong>Language</strong> we want to copy. 77 */ 78 public Language(Language language) { 79 this.default_language = language.isDefault(); 80 this.name = language.toString(); 81 this.value = language.getCode(); 53 54 public Language(Element element) { 55 this.element = element; 82 56 } 57 58 /** Constructor for a brand new language. */ 59 public Language(String code) { 60 this.code = code; 61 // Create the new element 62 element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.LANGUAGE_ELEMENT); 63 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, code); 64 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR); 65 } 66 83 67 /** Method to compare two languages for ordering purposes. 84 * @param object The other language as an <strong>Object</strong>. 85 * @return An <i>int</i> which indicates order using the same values as in String.compareTo(). 86 * @see java.lang.String#compareTo 87 */ 68 * @param object the other language as an Object 69 * @return an int which indicates the order between this language and the given one: < 0, 0 or > 0 for before, equal to or after respectively 70 */ 88 71 public int compareTo(Object object) { 89 72 return toString().compareTo(object.toString()); 90 73 } 74 75 public DOMProxyListEntry create(Element element) { 76 return new Language(element); 77 } 78 91 79 /** Method to test for the equality of two languages. 92 93 94 80 * @param object The other language as an <strong>Object</strong>. 81 * @return <i>true</i> if the languages are equal, <i>false</i> otherwise. 82 */ 95 83 public boolean equals(Object object) { 96 if(compareTo(object) == 0) { 97 return true; 84 return (compareTo(object) == 0); 85 } 86 87 /** Method to retrieve the code of this language. 88 * @return A <strong>String</strong> representing the two letter code. 89 */ 90 public String getCode() { 91 if(code == null && element != null) { 92 code = element.getAttribute(CollectionConfiguration.NAME_ATTRIBUTE); 98 93 } 99 return false;94 return code; 100 95 } 101 /** Method to retrieve the code of this language. 102 * @return A <strong>String</strong> representing the two letter code. 103 */ 104 public String getCode() { 105 return value; 96 97 public Element getElement() { 98 return element; 106 99 } 107 /** Method to determine if this language is the default one. 108 * @return A <i>boolean</i> which is <i>true</i> if this language is the default one. 109 */ 110 public boolean isDefault() { 111 return default_language; 100 101 public String getName() { 102 if(name == null) { 103 String code = getCode(); 104 name = CollectionDesignManager.language_manager.getLanguageName(code); 105 } 106 return name; 112 107 } 113 /** Method to set the value of default. 114 * @param value The new value of default as a <i>boolean</i>. 115 */ 116 public void setDefault(boolean value) { 117 this.default_language = default_language; 108 109 public boolean isAssigned() { 110 return (element != null && element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR)); 118 111 } 112 113 public void setAssigned(boolean value) { 114 if(element != null) { 115 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (value ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 116 } 117 } 118 119 public void setCode(String new_code) { 120 code = new_code; 121 // Set element 122 if(element != null) { 123 element.setAttribute(CollectionConfiguration.NAME_ATTRIBUTE, new_code); 124 } 125 // Reset name 126 name = null; 127 } 128 129 public void setElement(Element new_element) { 130 element = new_element; 131 code = null; 132 name = null; 133 } 134 119 135 /** Method to display the language code. 120 121 136 * @return A <strong>String</strong> representing the language code. 137 */ 122 138 public String toString() { 123 return name;139 return getName(); 124 140 } 125 141 } -
trunk/gli/src/org/greenstone/gatherer/cdm/LanguageManager.java
r4675 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 27 package org.greenstone.gatherer.cdm; 44 28 /************************************************************************************** 45 * Title: Gatherer46 * Description: The Gatherer: a tool for gathering and enriching a digital collection.47 * Copyright: Copyright (c) 200148 * Company: The University of Waikato49 29 * Written: 08/05/02 50 30 * Revised: 17/11/02 - Commented 31 * 07/07/03 - DOM support 51 32 **************************************************************************************/ 52 import java.awt.BorderLayout; 53 import java.awt.Color; 54 import java.awt.Component; 55 import java.awt.Dimension; 56 import java.awt.GridLayout; 57 import java.awt.event.ActionEvent; 58 import java.awt.event.ActionListener; 59 import java.awt.event.KeyEvent; 60 import java.io.BufferedReader; 61 import java.io.File; 62 import java.io.FileReader; 63 import java.util.ArrayList; 64 import java.util.Collections; 65 import java.util.Enumeration; 66 import java.util.Iterator; 67 import java.util.LinkedHashMap; 68 import java.util.StringTokenizer; 69 import java.util.Vector; 70 import javax.swing.BorderFactory; 71 import javax.swing.DefaultListCellRenderer; 72 import javax.swing.DefaultListModel; 73 import javax.swing.ListModel; 74 import javax.swing.JButton; 75 import javax.swing.JComboBox; 76 import javax.swing.JLabel; 77 import javax.swing.JList; 78 import javax.swing.JPanel; 79 import javax.swing.JScrollPane; 80 import javax.swing.JTextArea; 81 import javax.swing.JTextField; 82 import javax.swing.event.ListSelectionEvent; 83 import javax.swing.event.ListSelectionListener; 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.io.*; 36 import java.util.*; 37 import javax.swing.*; 38 import javax.swing.event.*; 84 39 import org.greenstone.gatherer.Gatherer; 40 import org.greenstone.gatherer.cdm.CollectionConfiguration; 41 import org.greenstone.gatherer.cdm.CollectionDesignManager; 42 import org.greenstone.gatherer.cdm.Control; 43 import org.greenstone.gatherer.cdm.DOMProxyListModel; 85 44 import org.greenstone.gatherer.cdm.Language; 45 import org.greenstone.gatherer.cdm.LanguageListCellRenderer; 46 import org.w3c.dom.*; 86 47 /** This class manages the language commands, remembering both a list of languages to build indexes in, plus the default language. 87 48 * @author John Thompson, Greenstone Digital Library, University of Waikato … … 89 50 */ 90 51 public class LanguageManager 91 extends DefaultListModel { 92 /** A reference to the collection design manager. */ 93 private CollectionDesignManager manager = null; 52 extends DOMProxyListModel { 53 54 static final private Dimension LABEL_SIZE = new Dimension(125,25); 55 94 56 /** The visual controls for this manager. */ 95 57 private Control controls = null; 96 /** A reference to the Gatherer. */97 private Gatherer gatherer = null;98 58 /** A reference to this class as a model, for the inner controls class. */ 99 private ListModel model = null;59 private DOMProxyListModel model = null; 100 60 /** A hashtable of code->name mappings of known languages. */ 101 61 private LinkedHashMap known_languages = null; 102 62 /** The default language object. */ 103 63 private Language default_language = null; 104 105 static final private Dimension LABEL_SIZE = new Dimension(125,25); 106 /** Constructor. 107 * @param gatherer A reference to the <strong>Gatherer</strong>. 108 * @param manager A reference to the <strong>CollectionDesignManager</strong>. 109 */ 110 public LanguageManager(Gatherer gatherer, CollectionDesignManager manager) { 111 super(); 112 this.gatherer = gatherer; 113 this.known_languages = new LinkedHashMap(); 114 this.manager = manager; 64 65 /** Constructor. */ 66 public LanguageManager(Element languages_element) { 67 super(languages_element, CollectionConfiguration.LANGUAGE_ELEMENT, new Language()); 68 69 Gatherer.println("LanguageManager: " + getSize() + " languages parsed."); 70 115 71 this.model = this; 116 loadLanguages(); 117 } 118 /** Method to add a new language. 119 * @param language The <strong>Language</strong> to add. 120 * @see org.greenstone.gatherer.Gatherer 121 * @see org.greenstone.gatherer.collection.CollectionManager 122 */ 123 public void addLanguage(Language language) { 124 if(!contains(language)) { 125 // Add alphabetically. 126 for(int index = 0; index < size(); index++) { 127 Language sibling = (Language) get(index); 128 int position = language.compareTo(sibling); 129 // Sibling is before language. 130 if(position > 0) { 131 // Carry on. 132 } 133 // Language is equal to, or before sibling. Insert it. 134 else if(position == 0 || position < 0) { 135 add(index, language); 136 gatherer.c_man.configurationChanged(); 137 return; 138 } 139 } 140 // If we got this far, we haven't inserted language, and we are out of model so. 141 addElement(language); 142 gatherer.c_man.configurationChanged(); 143 } 144 } 145 /** Method to retrieve the control for this manager. 146 * @return A <strong>JPanel</strong> containing the controls. 147 */ 148 public JPanel getControls() { 149 if(controls == null) { 150 controls = new Control(); 151 } 152 return controls; 153 } 154 /** Method to retrieve the default language code. 155 * @return A <strong>Language</strong> containing a two letter code. 156 */ 157 public Language getDefaultLanguage() { 158 // If no default is set... 159 if(default_language == null) { 160 // And we have other assigned languages, use the first one of them. 161 if(size() >= 1) { 162 default_language = (Language) get(0); 163 } 164 // And we have nothing else, use English. 165 else { 166 default_language = getLanguage("en", false); 167 // Remember to add it. 168 addLanguage(default_language); 169 } 170 } 171 return default_language; 172 } 173 /** Method to retrieve a certain language object by its code. 174 * @param code The two letter code of a language, as a <strong>String</strong>. 175 * @param assigned_only If <i>true</i> only those languages currently having indexes built for them are checked, otherwise the known languages buffer is checked. 176 * @return The <strong>Language</strong> that matches the given code, or <i>null</i> if no such language exists. 177 */ 178 public Language getLanguage(String code, boolean assigned_only) { 179 if(assigned_only) { 180 for(int i = 0; i < size(); i++) { 181 Language pos = (Language)get(i); 182 ///ystem.err.println("Comparing " + pos.getCode() + " and " + code); 183 if(pos.getCode().equals(code)) { 184 return pos; 185 } 186 } 187 } 188 else { 189 if(known_languages.containsKey(code)) { 190 return new Language((Language)known_languages.get(code)); 191 } 192 } 193 return null; 194 } 195 /** Method to return a list of the known language codes. 196 * @return An <strong>ArrayList</strong> containing a series of alphabetically sorted two letter codes. 197 */ 198 public ArrayList getLanguageCodes() { 199 ArrayList result = new ArrayList(); 200 Iterator key_iter = known_languages.keySet().iterator(); 201 while(key_iter.hasNext()) { 202 result.add(known_languages.get(key_iter.next())); 203 } 204 //for(Enumeration keys = known_languages.keys(); keys.hasMoreElements(); ) { 205 // result.add(known_languages.get(keys.nextElement())); 206 //} 207 //Collections.sort(result); 208 return result; 209 } 210 /** Mark the current set of controls, if any, as obsolete and deallocate them. If further need of the controls will cause new controls to be created. 211 * @see org.greenstone.gatherer.cdm.IndexManager.Control 212 */ 213 public void invalidateControls() { 214 if(controls != null) { 215 controls.destroy(); 216 } 217 controls = null; 218 } 219 220 /** Determine if the given language is the current default language. 221 * @param language The <strong>Language</strong> to test. 222 * @return <i>true</i> if the language is the default one, <i>false</i> otherwise. 223 */ 224 public boolean isDefaultLanguage(Language language) { 225 return (language.equals(default_language)); 226 } 227 /** This method attempts to parse a language command from the given string. If such a command is parsed, it is immediately added to the list of languages. 228 * @param command The <strong>String</strong> containing a possible language command. 229 * @return A <i>boolean</i> which is <i>true</i> if a command was parsed, <i>false</i> otherwise. 230 * @see org.greenstone.gatherer.cdm.Language 231 */ 232 public boolean parse(String command) { 233 String command_lc = command.toLowerCase(); 234 if(command_lc.startsWith("languages")) { 235 StringTokenizer tokenizer = new StringTokenizer(command); 236 tokenizer.nextToken(); 237 while(tokenizer.hasMoreTokens()) { 238 String code = tokenizer.nextToken(); 239 if(known_languages.containsKey(code)) { 240 Language language = (Language)known_languages.get(code); 241 addElement(new Language(language)); 242 } 243 else { 244 addElement(new Language(code, code, false)); 245 } 246 } 247 return true; 248 } 249 if(command_lc.startsWith("defaultlanguage")) { 250 StringTokenizer tokenizer = new StringTokenizer(command); 251 tokenizer.nextToken(); 252 if(tokenizer.hasMoreTokens()) { 253 String code = tokenizer.nextToken(); 254 Language language = getLanguage(code, true); 255 if(language == null) { 256 language = new Language(code, (String)known_languages.get(code), true); 257 addElement(language); 258 } 259 else { 260 language.setDefault(true); 261 } 262 setDefault(language); 263 } 264 return true; 265 } 266 return false; 267 } 268 /** Method to cause the list appearance to update if the selection changes. */ 269 public void refreshAppearance() { 270 fireContentsChanged(this, 0, size()); 271 } 272 /** Method to remove a certain language. 273 * @param language The <strong>Language</strong> to remove. 274 * @see org.greenstone.gatherer.Gatherer 275 * @see org.greenstone.gatherer.collection.CollectionManager 276 */ 277 public void removeLanguage(Language language) { 278 removeElement(language); 279 if(default_language != null && default_language.equals(language)) { 280 default_language = null; 281 } 282 gatherer.c_man.configurationChanged(); 283 } 284 /** Method to set the default language. 285 * @param language The <strong>Language</strong> to use as a default, or <i>null</i> for no default. 286 * @see org.greenstone.gatherer.Gatherer 287 * @see org.greenstone.gatherer.collection.CollectionManager 288 */ 289 public void setDefault(Language language) { 290 // Unset existing. 291 Language old = null; 292 if(default_language != null) { 293 old = default_language; 294 default_language.setDefault(false); 295 default_language = null; 296 } 297 // Now set the new if its not null. 298 if(language != null) { 299 default_language = language; 300 default_language.setDefault(true); 301 } 302 // Now cause the model to refresh any lists that are listening. 303 int start = 0; 304 int end = size() - 1; 305 if(default_language != null && old != null) { 306 int index_default = indexOf(default_language); 307 int index_old = indexOf(old); 308 if(index_default < index_old) { 309 start = index_default; 310 end = index_old; 311 } 312 else { 313 start = index_old; 314 end = index_default; 315 } 316 } 317 else if(default_language != null) { 318 start = end = indexOf(default_language); 319 } 320 else { 321 start = end = indexOf(old); 322 } 323 fireContentsChanged(this, 0, size()); 324 gatherer.c_man.configurationChanged(); 325 } 326 /** Method to translate this object into a block of commands as you you expect to find in the collection configuration file. 327 * @return A <strong>String</string> containing a series of commands. 328 */ 329 public String toString() { 330 StringBuffer text = new StringBuffer(); 331 if(size() > 1) { 332 text.append("languages "); 333 for(int i = 0; i < size(); i++) { 334 Language language = (Language) get(i); 335 text.append(language.getCode()); 336 if(i < size() - 1) { 337 text.append(" "); 338 } 339 else { 340 text.append("\n"); 341 } 342 } 343 // Only bother with default language if there is more than one language. 344 if(default_language != null) { 345 text.append("defaultlanguage "); 346 text.append(default_language.getCode()); 347 text.append("\n"); 348 } 349 text.append("\n"); 350 } 351 return text.toString(); 352 } 353 /** Overloaded to call get with both a key and an empty argument array. 354 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 355 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 356 */ 357 private String get(String key) { 358 return get(key, null); 359 } 360 /** Used to retrieve a property value from the Locale specific ResourceBundle, based upon the key and arguments supplied. If the key cannot be found or if some other part of the call fails a default (English) error message is returned. <BR> 361 * Here the get recieves a second argument which is an array of Strings used to populate argument fields, denoted {<I>n</I>}, within the value String returned. Note that argument numbers greater than or equal to 32 are automatically mapped to the formatting String named Farg<I>n</I>. 362 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 363 * @param args A <strong>String[]</strong> used to populate argument fields within the complete String. 364 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 365 * @see org.greenstone.gatherer.Gatherer 366 * @see org.greenstone.gatherer.Dictionary 367 */ 368 private String get(String key, String args[]) { 369 if(key.indexOf('.') == -1) { 370 key = "CDM.LanguageManager." + key; 371 } 372 return gatherer.dictionary.get(key, args); 373 } 374 /** This method loads a series of code->language mappings into known_languages, by reading from the 'languages.dat' file, which is essentially a verbatim copy of the ISO 639 Standard. 375 * @see org.greenstone.gatherer.cdm.Language 376 */ 377 private void loadLanguages() { 72 // Retrieve the default language 73 NodeList default_language_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT); 74 if(default_language_elements.getLength() > 0) { 75 default_language = new Language((Element)default_language_elements.item(0)); 76 } 77 // Load a series of code->language mappings into known_languages, by reading from the 'languages.dat' file, which is essentially a subset of the ISO 639 Standard. 78 known_languages = new LinkedHashMap(); 378 79 try { 379 80 File in_file = new File("languages.dat"); … … 384 85 if(!entry.startsWith("#")) { 385 86 StringTokenizer tokenizer = new StringTokenizer(entry); 386 String name = tokenizer.nextToken(); 387 String code = tokenizer.nextToken().toLowerCase(); 388 Language language = new Language(code, name, false); 389 known_languages.put(code, language); 87 if(tokenizer.countTokens() >= 2) { 88 String name = tokenizer.nextToken(); 89 String code = tokenizer.nextToken().toLowerCase(); 90 known_languages.put(code, name); 91 } 390 92 } 391 93 } 392 94 in.close(); 95 in_reader.close(); 96 in = null; 97 in_reader = null; 98 in_file = null; 393 99 } 394 100 catch (Exception error) { … … 397 103 } 398 104 105 /** Method to add a new language. 106 * @param language The <strong>Language</strong> to add. 107 * @see org.greenstone.gatherer.Gatherer 108 * @see org.greenstone.gatherer.collection.CollectionManager 109 */ 110 public void addLanguage(Language language) { 111 if(!contains(language)) { 112 Element element = language.getElement(); 113 // Locate where we should insert this new subcollection. 114 Node target_node = CollectionConfiguration.findInsertionPoint(element); 115 // Failing that we insert immediately after a language string 116 add(root, language, target_node); 117 Gatherer.c_man.configurationChanged(); 118 } 119 } 120 121 public void destroy() { 122 if(controls != null) { 123 controls.destroy(); 124 controls = null; 125 } 126 known_languages.clear(); 127 known_languages = null; 128 } 129 130 /** Method to retrieve the control for this manager. 131 * @return the Control for editing the language partitions 132 */ 133 public Control getControls() { 134 if(controls == null) { 135 // Build controls 136 controls = new LanguageControl(); 137 } 138 return controls; 139 } 140 141 /** Method to retrieve the default language code. 142 * @return A <strong>Language</strong> containing a two letter code. 143 */ 144 public Language getDefaultLanguage() { 145 // If no default is set... 146 if(default_language != null && default_language.isAssigned()) { 147 return default_language; 148 } 149 return null; 150 } 151 152 /** Method to retrieve a certain language object by its code. 153 * @param code The two letter code of a language, as a <strong>String</strong>. 154 * @param assigned_only If <i>true</i> only those languages currently having indexes built for them are checked, otherwise the known languages buffer is checked. 155 * @return The <strong>Language</strong> that matches the given code, or <i>null</i> if no such language exists. 156 */ 157 public Language getLanguage(String code) { 158 int size = getSize(); 159 for(int i = 0; i < size; i++) { 160 Language language = (Language) getElementAt(i); 161 if(language.getCode().equals(code)) { 162 return language; 163 } 164 } 165 return null; 166 } 167 168 public ArrayList getLanguages() { 169 return children(); 170 } 171 172 /** Method to return a list of the known language codes. 173 * @return an ArrayList containing the series of known language codes as per the languages.dat file 174 */ 175 public ArrayList getLanguageCodes() { 176 return new ArrayList(known_languages.keySet()); 177 } 178 179 public String getLanguageName(String code) { 180 return (String) known_languages.get(code); 181 } 182 183 /** Method to remove a certain language. 184 * @param language The <strong>Language</strong> to remove. 185 * @see org.greenstone.gatherer.Gatherer 186 * @see org.greenstone.gatherer.collection.CollectionManager 187 */ 188 public void removeLanguage(Language language) { 189 remove(language); 190 if(default_language != null && default_language.equals(language)) { 191 default_language = null; 192 } 193 Gatherer.c_man.configurationChanged(); 194 } 195 196 /** Method to set the default language. 197 * @param language The <strong>Language</strong> to use as a default, or <i>null</i> for no default. 198 * @see org.greenstone.gatherer.Gatherer 199 * @see org.greenstone.gatherer.collection.CollectionManager 200 */ 201 public void setDefault(Language language) { 202 if(language != null) { 203 if(default_language == null) { 204 // Create the default index element, and place immediately after indexes element. 205 Element default_language_element = root.getOwnerDocument().createElement(CollectionConfiguration.LANGUAGE_DEFAULT_ELEMENT); 206 default_language = new Language(default_language_element); 207 Node target_node = CollectionConfiguration.findInsertionPoint(default_language_element); 208 if(target_node != null) { 209 root.getOwnerDocument().getDocumentElement().insertBefore(default_language_element, target_node); 210 } 211 else { 212 root.getOwnerDocument().getDocumentElement().appendChild(default_language_element); 213 } 214 } 215 default_language.setAssigned(true); 216 default_language.setCode(language.getCode()); 217 } 218 else { 219 if(default_language != null) { 220 default_language.setAssigned(false); 221 } 222 } 223 Gatherer.c_man.configurationChanged(); 224 } 225 226 /** Overloaded to call get with both a key and an empty argument array. 227 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle. 228 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call. 229 */ 230 private String get(String key) { 231 if(key.indexOf('.') == -1) { 232 key = "CDM.LanguageManager." + key; 233 } 234 return Gatherer.dictionary.get(key, (String[])null); 235 } 236 399 237 /** This class represents the visual component of the Language Manager. */ 400 private class Control 401 extends JPanel { 238 private class LanguageControl 239 extends JPanel 240 implements Control { 402 241 /** The button to add a new language support. */ 403 private JButton add = null;242 private JButton add_button = null; 404 243 /** The button to clear the current default language. */ 405 private JButton clear_ default= null;244 private JButton clear_button = null; 406 245 /** The button to remove a supported language. */ 407 private JButton remove = null;246 private JButton remove_button = null; 408 247 /** The button to set the current language as the default one. */ 409 private JButton set_ default= null;248 private JButton set_button = null; 410 249 /** A combobox listing the available supported languages. */ 411 private JComboBox selector = null;250 private JComboBox selector_combobox = null; 412 251 /** A list of currently supported languages. */ 413 private JList l ist = null;252 private JList language_list = null; 414 253 /** A description of the language currently selected. */ 415 private JTextArea description = null;254 private JTextArea description_textarea = null; 416 255 /** The text field showing the currently name of the default language. Non-editable. */ 417 private JTextField default_language_ value= null;256 private JTextField default_language_field = null; 418 257 /** Constructor. 419 258 * @see org.greenstone.gatherer.cdm.LanguageManager.Control.AddListener … … 425 264 * @see org.greenstone.gatherer.cdm.LanguageManager.Control.TranslateListener 426 265 */ 427 public Control() {266 public LanguageControl() { 428 267 super(); 429 268 // Creation. … … 434 273 title_label.setOpaque(true); 435 274 436 list = new JList(model); 437 list.setCellRenderer(new ListRenderer()); 275 language_list = new JList(model); 438 276 439 277 JPanel details_panel = new JPanel(); … … 446 284 447 285 if(default_language == null) { 448 default_language_ value= new JTextField();286 default_language_field = new JTextField(); 449 287 } 450 288 else { 451 default_language_ value= new JTextField(default_language.toString());452 } 453 default_language_ value.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));454 default_language_ value.setEditable(false);289 default_language_field = new JTextField(default_language.toString()); 290 } 291 default_language_field.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 292 default_language_field.setEditable(false); 455 293 456 294 JPanel control_panel = new JPanel(); … … 459 297 selector_label.setPreferredSize(LABEL_SIZE); 460 298 461 selector = new JComboBox(getLanguageCodes().toArray()); 462 selector.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 299 selector_combobox = new JComboBox(getLanguageCodes().toArray()); 300 selector_combobox.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 301 selector_combobox.setRenderer(new LanguageListCellRenderer()); 463 302 464 303 JPanel button_panel = new JPanel(); 465 304 466 add = new JButton(get("Add")); 467 add.setMnemonic(KeyEvent.VK_A); 468 if(selector.getSelectedItem() != null) { 469 add.setEnabled(true); 470 } 471 else { 472 add.setEnabled(false); 473 } 474 475 remove = new JButton(get("Remove")); 476 remove.setMnemonic(KeyEvent.VK_R); 477 remove.setEnabled(false); 478 479 clear_default = new JButton(get("Clear_Default")); 480 clear_default.setMnemonic(KeyEvent.VK_C); 481 clear_default.setEnabled(false); 482 483 set_default = new JButton(get("Set_Default")); 484 set_default.setMnemonic(KeyEvent.VK_S); 485 set_default.setEnabled(false); 305 add_button = new JButton(get("Add")); 306 add_button.setMnemonic(KeyEvent.VK_A); 307 308 remove_button = new JButton(get("Remove")); 309 remove_button.setMnemonic(KeyEvent.VK_R); 310 remove_button.setEnabled(false); 311 312 clear_button = new JButton(get("Clear_Default")); 313 clear_button.setMnemonic(KeyEvent.VK_C); 314 clear_button.setEnabled(false); 315 316 set_button = new JButton(get("Set_Default")); 317 set_button.setMnemonic(KeyEvent.VK_S); 318 set_button.setEnabled(false); 486 319 487 320 // Set up and connect listeners. 488 add .addActionListener(new AddListener());489 clear_ default.addActionListener(new ClearDefaultListener());490 remove .addActionListener(new RemoveListener());491 selector .addActionListener(new SelectorListener());492 set_ default.addActionListener(new SetDefaultListener());493 l ist.addListSelectionListener(new ListListener());321 add_button.addActionListener(new AddListener()); 322 clear_button.addActionListener(new ClearDefaultListener()); 323 remove_button.addActionListener(new RemoveListener()); 324 selector_combobox.addActionListener(new SelectorListener()); 325 set_button.addActionListener(new SetDefaultListener()); 326 language_list.addListSelectionListener(new ListListener()); 494 327 // Layout components. 495 328 default_panel.setBorder(BorderFactory.createRaisedBevelBorder()); 496 329 default_panel.setLayout(new BorderLayout()); 497 330 default_panel.add(default_label, BorderLayout.WEST); 498 default_panel.add(default_language_ value, BorderLayout.CENTER);331 default_panel.add(default_language_field, BorderLayout.CENTER); 499 332 500 333 control_panel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 501 334 control_panel.setLayout(new BorderLayout()); 502 335 control_panel.add(selector_label, BorderLayout.WEST); 503 control_panel.add(selector , BorderLayout.CENTER);336 control_panel.add(selector_combobox, BorderLayout.CENTER); 504 337 505 338 details_panel.setBorder(BorderFactory.createEmptyBorder(5,0,5,0)); … … 510 343 center_panel.setLayout(new BorderLayout()); 511 344 center_panel.add(title_label, BorderLayout.NORTH); 512 center_panel.add(new JScrollPane(l ist), BorderLayout.CENTER);345 center_panel.add(new JScrollPane(language_list), BorderLayout.CENTER); 513 346 center_panel.add(details_panel, BorderLayout.SOUTH); 514 347 515 348 button_panel.setLayout(new GridLayout(2,2,5,5)); 516 button_panel.add(add );517 button_panel.add(remove );518 button_panel.add(clear_ default);519 button_panel.add(set_ default);349 button_panel.add(add_button); 350 button_panel.add(remove_button); 351 button_panel.add(clear_button); 352 button_panel.add(set_button); 520 353 521 354 setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); … … 524 357 add(button_panel, BorderLayout.SOUTH); 525 358 } 526 /** Destructor. 527 */ 359 /** Destructor. */ 528 360 public void destroy() { 529 361 } 362 363 public void gainFocus() { 364 } 365 366 public void loseFocus() { 367 } 368 530 369 /** Listens for actions apon the 'add' button in the LanguageManager controls, and if detected calls the add method of the manager with a newly created language. */ 531 370 private class AddListener … … 536 375 */ 537 376 public void actionPerformed(ActionEvent event) { 538 Language language = (Language)selector.getSelectedItem(); 539 if(language != null) { 540 addLanguage(new Language(language)); 541 } 542 } 543 } 377 String language_code = (String) selector_combobox.getSelectedItem(); 378 if(language_code != null) { 379 addLanguage(new Language(language_code)); 380 } 381 add_button.setEnabled(false); 382 } 383 } 384 544 385 /** Listens for actions apon the 'clear default' button in the LanguageManager controls, and if detected calls the setDefault method of the manager with <i>null</i>. */ 545 386 private class ClearDefaultListener … … 550 391 public void actionPerformed(ActionEvent event) { 551 392 setDefault(null); 552 clear_default.setEnabled(false); 553 default_language_value.setText(""); 554 } 555 } 393 clear_button.setEnabled(false); 394 default_language_field.setText(""); 395 } 396 } 397 556 398 /** Listens for actions apon the 'remove' button in the LanguageManager controls, and if detected calls the remove method of the manager with the language selected for removal. */ 557 399 private class RemoveListener … … 562 404 */ 563 405 public void actionPerformed(ActionEvent event) { 564 if(!list.isSelectionEmpty()) { 565 removeLanguage((Language)list.getSelectedValue()); 566 if(default_language == null) { 567 clear_default.setEnabled(false); 568 default_language_value.setText(""); 406 Language delete_me = (Language)language_list.getSelectedValue(); 407 if(delete_me != null) { 408 removeLanguage(delete_me); 409 if(default_language != null && default_language.equals(delete_me)) { 410 setDefault(null); 411 clear_button.setEnabled(false); 412 default_language_field.setText(""); 569 413 } 570 414 } 571 } 572 } 573 /** Listens for selections wihtin the combobox on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */ 415 remove_button.setEnabled(false); 416 } 417 } 418 419 /** Listens for selections within the combobox on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */ 574 420 private class SelectorListener 575 421 implements ActionListener { … … 578 424 */ 579 425 public void actionPerformed(ActionEvent event) { 580 if(selector.getSelectedItem() != null) { 581 add.setEnabled(true); 582 //description.setText((String)known_languages.get(code)); 426 if(selector_combobox.getSelectedItem() != null) { 427 add_button.setEnabled(true); 583 428 } 584 429 else { 585 add .setEnabled(false);586 //description.setText("");587 588 589 } 430 add_button.setEnabled(false); 431 } 432 } 433 } 434 590 435 /** Listens for actions apon the 'set default' button in the LanguageManager controls, and if detected calls the <i>setDefault()</i> method of the manager with the language selected for default. */ 591 436 private class SetDefaultListener 592 437 implements ActionListener { 593 594 595 596 438 /** Set the default index to the one currently selected, if any. 439 * @param event An <strong>ActionEvent</strong>. 440 * @see org.greenstone.gatherer.cdm.Language 441 */ 597 442 public void actionPerformed(ActionEvent event) { 598 if(!list.isSelectionEmpty()) { 599 setDefault((Language)list.getSelectedValue()); 600 clear_default.setEnabled(true); 601 default_language_value.setText(default_language.toString()); 602 } 603 } 604 } 443 if(!language_list.isSelectionEmpty()) { 444 setDefault((Language)language_list.getSelectedValue()); 445 clear_button.setEnabled(true); 446 default_language_field.setText(default_language.toString()); 447 } 448 } 449 } 450 605 451 /** Listens for selections within the list on the LanguageManager controls, and if a change is detected enables, or disables, controls appropriately. */ 606 452 private class ListListener … … 610 456 */ 611 457 public void valueChanged(ListSelectionEvent event) { 612 if(l ist.isSelectionEmpty()) {613 remove .setEnabled(false);614 set_ default.setEnabled(false);458 if(language_list.isSelectionEmpty()) { 459 remove_button.setEnabled(false); 460 set_button.setEnabled(false); 615 461 } 616 462 else { 617 remove.setEnabled(true); 618 set_default.setEnabled(true); 619 } 620 refreshAppearance(); 621 } 622 } 623 /** Our list cel renderer which renders the default cell just a little different. */ 624 private class ListRenderer 625 extends DefaultListCellRenderer { 626 /** Method to produce the component used to display an entry in the list. 627 * @param list The <strong>JList</strong> the component will be placed in. 628 * @param value A value to be displayed for this component, as a <strong>Object</strong>. 629 * @param index The position in the list it will occupy as an <i>int</i>. 630 * @param isSelected Whether the user has currently selected this component, as a <i>boolean</i>. 631 * @param cellHasFocus Whether the component currently has focus, again as a <i>boolean</i>. 632 * @return A <strong>Component</strong> to be used as the entry in the list. 633 * @see org.greenstone.gatherer.cdm.Language 634 */ 635 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 636 Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 637 Language language = (Language) value; 638 if(language.isDefault() && !isSelected) { 639 component.setBackground(Gatherer.config.getColor("coloring.workspace_selection_background", false)); 640 } 641 if(component instanceof JLabel) { 642 ((JLabel)component).setOpaque(true); 643 } 644 return component; 463 remove_button.setEnabled(true); 464 set_button.setEnabled(true); 465 } 645 466 } 646 467 } -
trunk/gli/src/org/greenstone/gatherer/cdm/PlugIn.java
r4675 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 27 package org.greenstone.gatherer.cdm; 44 /** 45 * Title: The Gatherer<br> 46 * Description: The Gatherer: a tool for gathering and enriching digital collections.<br> 47 * Copyright: Copyright (c) 2001<br> 48 * Company: The University of Waikato<br> 49 * First Coded: 01/05/02 50 * @author John Thompson, Greenstone Digital Libraries 51 * @version 2.1 52 */ 53 import java.io.Serializable; 54 import java.util.ArrayList; 55 import java.util.Collections; 28 29 import java.io.*; 30 import java.util.*; 31 import org.greenstone.gatherer.Gatherer; 56 32 import org.greenstone.gatherer.cdm.Argument; 57 33 import org.greenstone.gatherer.cdm.ArgumentContainer; 34 import org.greenstone.gatherer.cdm.DOMProxyListEntry; 35 import org.greenstone.gatherer.util.StaticStrings; 36 import org.w3c.dom.*; 58 37 /** This class is responsible for storing information from a parsed pluginfo call in such a way that it allows easy access to parsed details for the purposes of user design and specification of plugins. */ 59 // ####################################################################################60 // Optimization Saving61 // ####################################################################################62 // Vector -> ArrayList + Memory, + Processor (pos. - Processor)63 // ####################################################################################64 38 public class PlugIn 65 extends ArrayList 66 implements ArgumentContainer, Comparable, Serializable { 67 /** A reference to the plugin that this one inherits from. */ 68 private PlugIn super_plugin = null; 69 /** A string of custom arguments to pass to the plugin. */ 70 private String custom = null; 71 /** A description of this plugin. */ 72 private String desc = null; 73 /** The name of the plugin as it would appear in the collect.cfg file. */ 74 private String name = null; 75 /** Default Constructor. 39 extends ArrayList 40 implements ArgumentContainer, Comparable, DOMProxyListEntry, Serializable { 41 /** The DOM Element this assigned PlugIn is modelled on. */ 42 private Element element; 43 /** The parent PlugIn this one inherits from, if any. */ 44 private PlugIn super_plugin; 45 private String description; 46 private String name; 47 48 /** Constructor used only in DOMProxyListModel initializations. 76 49 */ 77 50 public PlugIn() { 51 } 52 53 public PlugIn(Element element, PlugIn base_plugin) { 78 54 super(); 79 } 80 /** Constructor. 81 * @param name The name of this plugin as a <strong>String</strong>. 82 * @param desc A description of this plugin as a <strong>String</strong>. 83 * @param super_plugin The super class of this plugin, as a <strong>PlugIn</strong>. 84 */ 85 public PlugIn(String name, String desc, PlugIn super_plugin) { 55 this.element = element; 56 this.name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 57 ///atherer.println("Establishing Plugin: " + name); 58 // Parse in any argument options for this plugin, keeping a list of the ones found 59 HashMap known_arguments = new HashMap(); 60 NodeList option_elements = element.getElementsByTagName(StaticStrings.OPTION_ELEMENT); 61 int option_elements_length = option_elements.getLength(); 62 for(int i = 0; i < option_elements_length; i++) { 63 Element option_element = (Element) option_elements.item(i); 64 Argument argument = new Argument(option_element); 65 ///atherer.println("Rebuilding existing argument: " + argument.getName()); 66 argument.setOwner(name); 67 add(argument); 68 known_arguments.put(argument.getName(), argument); 69 } 70 // If a base plugin was given 71 if(base_plugin != null) { 72 // Copy the details, and add a reference to whatever base_plugins super plugin is. 73 description = base_plugin.getDescription(); 74 // Now search through the 'dummy' arguments belonging to the base plugin. 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 plugin, copy them and add them, but without a value. 75 ArrayList all_arguments = base_plugin.getArguments(true, true); 76 int argument_count = all_arguments.size(); 77 for(int j = 0; j < argument_count; j++) { 78 Argument base_argument = (Argument) all_arguments.get(j); 79 String base_argument_name = base_argument.getName(); 80 ///atherer.println("Library indicates this plugin should have an argument: " + base_argument_name); 81 Argument existing_argument = (Argument) known_arguments.get(base_argument_name); 82 // Found an existing argument. Complete its details 83 if(existing_argument != null) { 84 ///atherer.println("Found existing argument. Filling out details."); 85 existing_argument.setCustomArgument(false); 86 existing_argument.setDefaultValue(base_argument.getDefaultValue()); 87 existing_argument.setDescription(base_argument.getDescription()); 88 existing_argument.setOptions(base_argument.getOptions()); 89 existing_argument.setRequired(base_argument.isRequired()); 90 existing_argument.setType(base_argument.getType()); 91 } 92 // 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. 93 else { 94 ///atherer.println("No such argument. Adding new, unassigned, argument."); 95 // The trick thing is that we have to create a new element in the DOM as well. 96 Argument new_argument = base_argument.copy(); 97 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT); 98 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, base_argument_name); 99 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.FALSE_STR); 100 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.FALSE_STR); 101 new_argument.setElement(argument_element); 102 // All done. Add it. 103 element.appendChild(argument_element); 104 add(new_argument); 105 } 106 } 107 } 108 } 109 110 /** This constructor is only used for library level Plugins. 111 * @param name 112 * @param description 113 * @param super_plugin 114 */ 115 public PlugIn(String name, String description, PlugIn super_plugin) { 86 116 super(); 87 this.desc = desc;117 this.description = description; 88 118 this.name = name; 89 119 this.super_plugin = super_plugin; 90 120 } 91 /** Method to add an argument to this plugin. Only adds the argument if it isn't already present. 92 * @param argument The <strong>Argument</strong> to add. 93 */ 121 122 /** Method to add an argument to this base plugin. Only adds the argument if it isn't already present, and only if this is a base plugin (ie not based on DOM). 123 * @param argument the Argument to add 124 */ 94 125 public void addArgument(Argument argument) { 95 if( !contains(argument)) {126 if(element == null && !contains(argument)) { 96 127 add(argument); 97 128 argument.setOwner(name); 98 129 } 99 130 } 131 100 132 /** Method to compare two plugins for ordering. 101 102 103 104 133 * @param object The plugin we are comparing to, as an <strong>Object</strong>. 134 * @return An <i>int</i> specifying the plugin order, using values as set out in <strong>String</strong>. 135 * @see java.lang.String#compareTo 136 */ 105 137 public int compareTo(Object object) { 106 if(object != null && object instanceof PlugIn) { 107 PlugIn plugin = (PlugIn) object; 108 return name.compareTo(plugin.getName()); 138 if(object instanceof PlugIn) { 139 return name.compareTo(((PlugIn)object).getName()); 109 140 } 110 141 return -1; 111 142 } 112 /** This method produces a deep copy of this plugin. Note that this also creates a new copy of each of the super classes of plugins as well. This is the way it should be, as each assigned plugin may have different values for the higher plugins (such as BasPlug). 113 * @return A newly created <strong>PlugIn</strong> with the same details and <strong>Argument</strong>s as this one. 114 */ 115 public PlugIn copy() { 116 PlugIn copy = null; 117 if(super_plugin == null) { 118 copy = new PlugIn(name, desc, null); 119 } 120 else { 121 copy = new PlugIn(name, desc, super_plugin.copy()); 122 } 123 for(int i = 0; i < size(); i++) { 124 copy.addArgument(((Argument)get(i)).copy()); 125 } 126 return copy; 127 } 143 144 /** The assigned plugin constructor. 145 * @param element the DOM Element this plugin is based upon 146 * @param base_plugin the PlugIn from the stored library showing details about this plugin, may be null 147 */ 148 public DOMProxyListEntry create(Element element) { 149 String plugin_name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 150 // Determine the base plugin from the plugin name 151 PlugIn base_plugin = CollectionDesignManager.plugin_manager.getBasePlugIn(plugin_name); 152 PlugIn plugin = new PlugIn(element, base_plugin); 153 base_plugin = null; 154 plugin_name = null; 155 return plugin; 156 } 157 128 158 /** Method to determine if two plugins are equal. 129 130 131 159 * @param object The plugin to test against, as an <strong>Object</strong>. 160 * @return <i>true</i> if the plugin names match, <i>false</i> otherwise. 161 */ 132 162 public boolean equals(Object object) { 133 if(object != null && compareTo(object) == 0) { 134 return true; 135 } 136 return false; 137 } 163 return (compareTo(object) == 0); 164 } 165 138 166 /** Method to retrieve an argument by its name. 139 140 141 167 * @param name The name of the argument as a <strong>String</strong>. 168 * @return The <strong>Argument</strong> requested, or <i>null</i> if no such argument. 169 */ 142 170 public Argument getArgument(String name) { 143 171 // The name given may still include the '-' … … 145 173 name = name.substring(1); 146 174 } 147 ArrayList arguments = getArguments( );175 ArrayList arguments = getArguments(true, true); 148 176 for(int i = 0; i < arguments.size(); i++) { 149 177 Argument argument = (Argument)arguments.get(i); … … 154 182 return null; 155 183 } 156 /** Method to retrieve all of the arguments available to a plugin, including both specific and general ones. 157 * @return A <strong>Hashtable</strong> of arguments, with <name> -> <argument> entries. 158 */ 159 public ArrayList getArguments() { 160 ArrayList all_arguments = new ArrayList(this); 161 Collections.sort(all_arguments); 184 185 /** Retrieve all of the arguments available to this base plugin, including its super plugins arguments. Some complexity is added by allowing the caller to choose whether they want normal arguments, custom arguments, or both. 186 * @return an ArrayList of all of the arguments, starting with those for this plugin and ending with the arguments for basplug or similiar root plugin 187 */ 188 public ArrayList getArguments(boolean include_normal, boolean include_custom) { 189 ArrayList arguments = new ArrayList(); 190 if(include_normal && include_custom) { 191 arguments.addAll(this); 192 } 193 else { 194 int size = size(); 195 for(int i = 0; i < size; i++) { 196 Argument argument = (Argument) get(i); 197 if(argument.isCustomArgument()) { 198 if(include_custom && !arguments.contains(argument)) { 199 arguments.add(argument); 200 } 201 } 202 else { 203 if(include_normal && !arguments.contains(argument)) { 204 arguments.add(argument); 205 } 206 } 207 argument = null; 208 } 209 } 162 210 if(super_plugin != null) { 163 ArrayList super_arguments = super_plugin.getArguments(); 164 for(int i = 0; i < super_arguments.size(); i++) { 165 Object argument = super_arguments.get(i); 166 if(!all_arguments.contains(argument)) { 167 all_arguments.add(argument); 168 } 169 } 170 } 171 return all_arguments; 172 } 173 /** Method to retrieve a plugins custom argument information. 174 * @return The custom arguments as a <strong>String</strong>. 175 */ 211 ArrayList remainder = super_plugin.getArguments(include_normal, include_custom); 212 remainder.removeAll(arguments); 213 arguments.addAll(remainder); 214 } 215 return arguments; 216 } 217 218 /** Method to retrieve a plugins custom argument information. Custom arguments are defined to be those that have not got matching arguments in the base reference plugin from the library. Of course if there is no base plugin then all arguments are considered to be custom. 219 * @return the custom arguments as a String 220 */ 176 221 public String getCustom() { 177 return custom; 178 } 222 StringBuffer custom_text = new StringBuffer(); 223 // Retrieve all of the arguments, and append any that are custom into one long string 224 ArrayList arguments = getArguments(false, true); 225 int arguments_size = arguments.size(); 226 boolean first = true; 227 for(int i = 0; i < arguments_size; i++) { 228 Argument argument = (Argument) arguments.get(i); 229 if(argument.isAssigned()) { 230 if(!first) { 231 custom_text.append(" "); 232 } 233 custom_text.append(argument.toString()); 234 first = false; 235 } 236 } 237 return custom_text.toString(); 238 } 239 240 public String getDescription() { 241 return description; 242 } 243 244 public Element getElement() { 245 return element; 246 } 247 179 248 /** Method to retrieve a plugins name. 180 181 249 * @return A <strong>String</strong> containing the plugins name. 250 */ 182 251 public String getName() { 252 if(name == null && element != null) { 253 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 254 } 183 255 return name; 184 256 } 185 public void setCustom(String custom) { 186 this.custom = custom; 187 } 257 258 public boolean isAssigned() { 259 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR)); 260 } 261 262 public boolean isSeparator() { 263 return (element != null && element.getAttribute(StaticStrings.SEPARATOR_ATTRIBUTE).equals(StaticStrings.TRUE_STR)); 264 } 265 266 public void setAssigned(boolean assigned) { 267 if(element != null) { 268 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 269 } 270 } 271 272 /** 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!). 273 * @param custom_str the custom arguments all splodged together in one String 274 */ 275 public void setCustom(String custom_str) { 276 HashMap raw_arguments = CollectionConfiguration.parseArguments(new CommandTokenizer(custom_str)); 277 ArrayList custom_arguments = getArguments(false, true); 278 int size = custom_arguments.size(); 279 for(int i = 0; i < size; i++) { 280 Argument argument = (Argument) custom_arguments.get(i); 281 String original_argument_name = StaticStrings.MINUS_CHARACTER + argument.getName(); 282 if(raw_arguments.containsKey(original_argument_name)) { 283 // Set as assigned 284 argument.setAssigned(true); 285 String argument_value = (String)raw_arguments.remove(original_argument_name); 286 if(argument_value != null) { 287 argument.setValue(argument_value); 288 argument_value = null; 289 } 290 } 291 // We've removed it from our custom statement, so unassign 292 else { 293 argument.setAssigned(false); 294 } 295 argument = null; 296 } 297 // Any left over, add to the plugin 298 Iterator argument_names = raw_arguments.keySet().iterator(); 299 while(argument_names.hasNext()) { 300 String argument_name = (String) argument_names.next(); 301 String argument_value = (String) raw_arguments.get(argument_name); 302 // The tricky thing is that we have to create a new element in the DOM as well. 303 Element argument_element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.OPTION_ELEMENT); 304 argument_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, argument_name.substring(1)); 305 argument_element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, StaticStrings.TRUE_STR); 306 argument_element.setAttribute(StaticStrings.CUSTOM_ATTRIBUTE, StaticStrings.TRUE_STR); 307 Argument argument = new Argument(argument_element); 308 argument_name = null; 309 if(argument_value != null) { 310 argument.setValue(argument_value); 311 argument_value = null; 312 } 313 // All done. Add it. 314 element.appendChild(argument_element); 315 add(argument); 316 argument_element = null; 317 } 318 raw_arguments = null; 319 } 320 188 321 /** Method to set the value of desc. 189 * @param desc The new value of desc as a <strong>String</strong>. 190 */ 191 public void setDesc(String desc) { 192 this.desc = desc; 193 } 322 * @param desc The new value of desc as a <strong>String</strong>. 323 */ 324 public void setDescription(String desc) { 325 this.description = description; 326 } 327 328 public void setElement(Element element) { 329 this.element = element; 330 } 331 194 332 /** Method to set the value of name. 195 196 333 * @param name The new value of name as a <strong>String</strong>. 334 */ 197 335 public void setName(String name) { 198 336 this.name = name; 199 337 } 338 200 339 /** Method to set the value of the super_plugin. 201 202 340 * @param super_plugin The new value of super_plugin as a <strong>PlugIn</strong>, or <i>null</i> if this class has no inheritance. 341 */ 203 342 public void setSuper(PlugIn super_plugin) { 204 343 this.super_plugin = super_plugin; 205 344 } 345 206 346 /** Method to print out this plugin as it would appear as a command within the collection configuration file. 207 208 347 * @return A <strong>String</strong> containing a single plugin command. 348 */ 209 349 public String toString() { 210 String text = "plugin " + name + " "; 211 ArrayList arguments = getArguments(); 212 for(int i = 0; i < arguments.size(); i++) { 213 Argument argument = (Argument)arguments.get(i); 214 if(argument.isAssigned()) { 215 text = text + argument.toString(); 216 if(i < arguments.size() - 1) { 217 text = text + " "; 218 } 219 } 220 } 221 // Now print custom arguments if any. 222 if(custom != null) { 223 text = text + " " + custom; 224 } 225 return text; 350 if(element != null) { 351 if(name == null) { 352 name = element.getAttribute(StaticStrings.TYPE_ATTRIBUTE); 353 } 354 StringBuffer text = new StringBuffer(StaticStrings.PLUGIN_STR); 355 text.append(" "); 356 text.append(name); 357 text.append(" "); 358 ArrayList arguments = getArguments(true, true); 359 int arguments_size = arguments.size(); 360 for(int i = 0; i < arguments_size; i++) { 361 Argument argument = (Argument)arguments.get(i); 362 if(argument.isAssigned()) { 363 text.append(argument.toString()); 364 text.append(" "); 365 } 366 argument = null; 367 } 368 return text.substring(0, text.length() - 1); 369 } 370 // Basic Plugin 371 else { 372 return name; 373 } 226 374 } 227 375 } -
trunk/gli/src/org/greenstone/gatherer/cdm/PlugInManager.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 27 package org.greenstone.gatherer.cdm; 44 /** 45 * Title: The Gatherer<br> 46 * Description: The Gatherer: a tool for gathering and enriching digital collections.<br> 47 * Copyright: Copyright (c) 2001<br> 48 * Company: The University of Waikato<br> 49 * First Coded: 01/05/02 50 * @author John Thompson, Greenstone Digital Libraries 51 * @version 2.1 52 */ 28 53 29 import java.awt.*; 54 30 import java.awt.event.*; … … 57 33 import javax.swing.*; 58 34 import javax.swing.event.*; 59 import javax.swing.plaf.basic. BasicArrowButton;60 import org.apache.xerces.parsers. DOMParser;35 import javax.swing.plaf.basic.*; 36 import org.apache.xerces.parsers.*; 61 37 import org.greenstone.gatherer.Gatherer; 62 38 import org.greenstone.gatherer.cdm.Argument; 63 39 import org.greenstone.gatherer.cdm.ArgumentConfiguration; 40 import org.greenstone.gatherer.cdm.CollectionDesignManager; 64 41 import org.greenstone.gatherer.cdm.CommandTokenizer; 42 import org.greenstone.gatherer.cdm.Control; 65 43 import org.greenstone.gatherer.cdm.DynamicListModel; 66 44 import org.greenstone.gatherer.cdm.PlugIn; 67 import org.greenstone.gatherer. msm.ElementWrapper;45 import org.greenstone.gatherer.gui.GComboBox; 68 46 import org.greenstone.gatherer.msm.MSMUtils; 47 import org.greenstone.gatherer.util.StaticStrings; 69 48 import org.greenstone.gatherer.util.Utility; 70 49 import org.w3c.dom.*; 71 import org.xml.sax. InputSource;50 import org.xml.sax.*; 72 51 /** This class is resposible for maintaining a list of known plug-ins, and importing new plugins using the parser. */ 73 public class PlugInManager { 74 /** A reference to the main manager for this module. */ 75 private CollectionDesignManager manager = null; 52 public class PlugInManager 53 extends DOMProxyListModel { 54 /** The library 'reserve' of base plugins. */ 55 private ArrayList library = null; 76 56 /** The controls for editing the contents of this manager. */ 77 57 private Control controls = null; 78 /** A list of assigned plugins. */ 79 private DynamicListModel assigned = null; 80 /** A list of those plugins that have not yet been assigned. Begins as a copy of reserve. */ 81 private DynamicListModel available = null; 82 /** A list of known, but currently unassigned, plug-ins. */ 83 private DynamicListModel reserve = null; 84 /** A reference to the Gatherer. */ 85 private Gatherer gatherer = null; 86 /** The current index of the separator. */ 87 private JPanel separator = null; 58 private DOMProxyListModel model; 59 private JPanel separator; 60 private PlugIn separator_plugin; 88 61 /** The default size for a label. */ 89 62 static final private Dimension LABEL_SIZE = new Dimension(140, 20); 90 63 /** Constructor. 91 64 */ 92 public PlugInManager(Gatherer gatherer, CollectionDesignManager manager) { 93 this.assigned = new DynamicListModel(); 94 this.gatherer = gatherer; 95 this.manager = manager; 96 this.separator = getSeparator(); 97 // Add the movement separator 98 assigned.addElement(separator); 65 public PlugInManager() { 66 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.PLUGIN_ELEMENT, new PlugIn()); 67 Gatherer.println("PlugInManager: " + getSize() + " plugins parsed."); 68 model = this; 69 // Reload/Create the library 99 70 loadPlugIns(); 100 71 savePlugIns(); 101 } 102 /** Method to add a new plugin to reserve. 103 * @param plugin The new <strong>PlugIn</strong>. 104 */ 72 // Create the separator, cause we can reuse it. 73 separator = getSeparator(); 74 } 75 /** Method to add a new plugin to the library 76 * @param plugin the new base PlugIn 77 */ 105 78 public void addPlugIn(PlugIn plugin) { 106 if(! reserve.contains(plugin)) {107 reserve.addElement(plugin);108 available.addElement(plugin);109 110 } 111 /** Method to assign a plugin .112 * @param plugin The reserve <strong>PlugIn</strong> to assign. 113 79 if(!library.contains(plugin)) { 80 library.add(plugin); 81 } 82 } 83 84 /** Method to assign a plugin 85 * @param plugin the PlugIn to assign 86 */ 114 87 public void assignPlugIn(PlugIn plugin) { 115 if(!assigned.contains(plugin)) { 116 if(plugin.getName().equals("RecPlug") || plugin.getName().equals("ArcPlug")) { 117 assigned.addElement(plugin); // Adds after separator 118 } 119 else { 120 int index = assigned.indexOf(separator); 121 assigned.add(index, plugin); 122 } 123 // Remove from available 124 available.removeElement(plugin); 125 gatherer.c_man.configurationChanged(); 126 } 127 } 88 if(plugin.getName().equals(StaticStrings.RECPLUG_STR) || plugin.getName().equals(StaticStrings.ARCPLUG_STR)) { 89 addAfter(plugin, separator_plugin); // Adds after separator 90 } 91 else { 92 addBefore(plugin, separator_plugin); 93 } 94 Gatherer.c_man.configurationChanged(); 95 } 96 97 /** Destructor. */ 98 public void destroy() { 99 if(controls != null) { 100 controls.destroy(); 101 controls = null; 102 } 103 library.clear(); 104 library = null; 105 } 106 128 107 /** Method to retrieve the control for this manager. 129 * @return A <strong>JPanel</strong> containing the controls. 130 131 public JPanel getControls() {108 * @return the Control 109 */ 110 public Control getControls() { 132 111 if(controls == null) { 133 controls = new Control(); 112 // Build controls 113 controls = new PlugInControl(); 134 114 } 135 115 return controls; 136 116 } 137 /** Method to retrieve the named plugin. 138 * @param name The name of the desired plugin as a <strong>String</strong>. 139 * @return The requested <strong>PlugIn</strong> or <i>null</i> if no such plugin exists. 140 */ 141 public PlugIn getPlugIn(String name) { 142 for(int i = 0; i < reserve.size(); i++) { 143 Object object = reserve.get(i); 144 if(object instanceof PlugIn) { 145 PlugIn plugin = (PlugIn) object; 146 if(plugin.getName().equals(name)) { 147 return plugin; 148 } 117 118 /** Retrieve the base pluging of the given name, or null if no such plugin. 119 * @param name the name of the base plugin to retrieve as a String 120 * @return the PlugIn requested or null if no such plugin 121 */ 122 public PlugIn getBasePlugIn(String name) { 123 int library_size = library.size(); 124 for(int i = 0; i < library_size; i++) { 125 PlugIn plugin = (PlugIn) library.get(i); 126 if(plugin.getName().equals(name)) { 127 return plugin; 149 128 } 150 129 } … … 152 131 return null; 153 132 } 154 /** Method to invalidate controls after a significant change in the system state. 155 */ 156 public void invalidateControls() { 157 if(controls != null) { 158 controls.destroy(); 159 } 160 controls = null; 161 } 133 134 /** Method to move a plugin in the list order. 135 * @param plugin the PlugIn you want to move. 136 * @param direction true to move the plugin up, false to move it down. 137 * @param all true to move to move all the way, false for a single step. 138 */ 139 public void movePlugIn(PlugIn plugin, boolean direction, boolean all) { 140 // Can't ever move RecPlug or ArcPlug. 141 if(getSize() < 3) { 142 Gatherer.println("Not enough plugins to allow moving."); 143 return; 144 } 145 if(plugin.getName().equals(StaticStrings.ARCPLUG_STR) || plugin.getName().equals(StaticStrings.RECPLUG_STR)) { 146 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.Move.Fixed"), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 147 return; 148 } 149 if(all) { 150 // Move to top 151 if(direction) { 152 // Remove the moving plugin 153 remove(plugin); 154 // Retrieve the first plugin 155 PlugIn first_plugin = (PlugIn) getElementAt(0); 156 // Add the moving plugin before the first plugin 157 addBefore(plugin, first_plugin); 158 first_plugin = null; 159 Gatherer.c_man.configurationChanged(); 160 } 161 else { 162 // Remove the moving plugin 163 remove(plugin); 164 // Locate the plugin immediately before the separator. We have to ensure the separator index is up to date, given we've just removed a plugin. 165 int separator_index = -1; 166 if((separator_index = findSeparatorIndex()) != -1) { 167 PlugIn separator_plugin = (PlugIn) getElementAt(separator_index); 168 // Add the moving plugin before the separator 169 addBefore(plugin, separator_plugin); 170 Gatherer.c_man.configurationChanged(); 171 } 172 // Otherwise we aren't moving anywhere! 173 } 174 } 175 else { 176 // Try to move the plugin one step in the desired direction. 177 int index = indexOf(plugin); 178 ///ystem.err.println("Index of " + plugin + " = " + index); 179 if(direction) { 180 index--; 181 if(index < 0) { 182 String args[] = new String[2]; 183 args[0] = get("CDM.PlugInManager.PlugIn_Str"); 184 args[1] = plugin.getName(); 185 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.Move.At_Top", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 186 return; 187 } 188 remove(plugin); 189 add(index, plugin); 190 Gatherer.c_man.configurationChanged(); 191 } 192 else { 193 index++; 194 PlugIn next_plugin = (PlugIn) getElementAt(index); 195 if(next_plugin.isSeparator()) { 196 String args[] = new String[1]; 197 args[0] = plugin.getName(); 198 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.Move.Cannot", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 199 // Still not going to move RecPlug or ArcPlug. 200 return; 201 } 202 remove(plugin); 203 add(index, plugin); 204 Gatherer.c_man.configurationChanged(); 205 } 206 } 207 } 208 209 /** We attempt to place the separator between the unfixed and the fixed plugins. Since we only know of two fixed plugins, we search for either of them, and place the separator before them. 210 */ 211 public void placeSeparator() { 212 ///ystem.err.println("Placing separator."); 213 int separator_index = getSize(); 214 if(separator_index > 0) { 215 boolean found_fixed = false; 216 int index = separator_index - 1; 217 while(index > 0) { 218 PlugIn plugin = (PlugIn) getElementAt(index); 219 String name = plugin.getName(); 220 if(name.equals(StaticStrings.RECPLUG_STR) || name.equals(StaticStrings.ARCPLUG_STR)) { 221 found_fixed = true; 222 index--; 223 } 224 else { 225 if(found_fixed) { 226 separator_index = index + 1; 227 index = -1; 228 } 229 else { 230 index--; 231 } 232 } 233 name = null; 234 plugin = null; 235 } 236 } 237 Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.PLUGIN_ELEMENT); 238 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, CollectionConfiguration.SEPARATOR_ATTRIBUTE); 239 element.setAttribute(CollectionConfiguration.SEPARATOR_ATTRIBUTE, CollectionConfiguration.TRUE_STR); 240 separator_plugin = new PlugIn(element, null); 241 ///atherer.println("Adding plugin separator at: " + separator_index); 242 add(separator_index, separator_plugin); 243 } 244 245 /** This method removes an assigned plugin. I was tempted to call it unassign, but remove is more consistant. Note that there is no way to remove a plugin from the library. 246 * @param plugin The <strong>PlugIn</strong> to remove. 247 */ 248 public void removePlugIn(PlugIn plugin) { 249 remove(plugin); 250 Gatherer.c_man.configurationChanged(); 251 } 252 253 /** Method to cache the current contents of library (known plugins) to file. 254 */ 255 public void savePlugIns() { 256 try { 257 FileOutputStream file = new FileOutputStream(Utility.BASE_DIR + "plugins.dat"); 258 ObjectOutputStream out = new ObjectOutputStream(file); 259 out.writeObject(library); 260 out.close(); 261 } 262 catch (Exception error) { 263 Gatherer.printStackTrace(error); 264 } 265 } 266 267 /** Determine the current separator index. */ 268 private int findSeparatorIndex() { 269 int separator_index = getSize() - 1; 270 while(separator_index >= 0) { 271 PlugIn search = (PlugIn) getElementAt(separator_index); 272 if(search.isSeparator()) { 273 return separator_index; 274 } 275 separator_index--; 276 } 277 return separator_index; 278 } 279 280 /* Retrieve a phrase from the dictionary based on a certain key. 281 * @param key The search <strong>String</strong>. 282 * @return The matching phrase from the Dictionary. 283 */ 284 private String get(String key) { 285 return get(key, (String[])null); 286 } 287 288 private String get(String key, String arg) { 289 String args[] = new String[1]; 290 args[0] = arg; 291 return get(key, args); 292 } 293 294 /* Retrieve a phrase from the dictionary based on a certain key and arguments. 295 * @param key The search <strong>String</strong>. 296 * @param args A <strong>String[]</strong> of arguments used to complete and format the choosen phrase. 297 * @return The matching phrase from the Dictionary. 298 */ 299 private String get(String key, String args[]) { 300 if(key.indexOf(".") == -1) { 301 key = "CDM.PlugInManager." + key; 302 } 303 return Gatherer.dictionary.get(key, args); 304 } 305 306 /** Retrieve a list of those plugins that are in library but not in the assigned plugins. */ 307 private Object[] getAvailable() { 308 ArrayList available = new ArrayList(); 309 available.addAll(library); 310 // Now go through the assigned plugins, and remove any that match. 311 available.removeAll(children()); 312 return available.toArray(); 313 } 314 315 /** Method to extract just the plugins name from a file object. 316 * @param plugin The <strong>File</strong> which references a certain plugin. 317 * @return A <strong>String</strong> containing just the plugins name, without extension. 318 */ 319 private String getPlugInName(File plugin) { 320 String name = plugin.getName(); 321 if(name.indexOf(".") != -1) { 322 name = name.substring(0, name.indexOf(".")); 323 } 324 return name; 325 } 326 162 327 /** Method to load the details of a single plug-in. 163 164 165 p ublicvoid loadPlugIn(File plugin) {328 * @param plugin The plugin <strong>File</strong> you wish to load. 329 */ 330 private void loadPlugIn(File plugin) { 166 331 Document document = null; 167 332 // Run pluginfo on this plugin, and then send the results for parsing. … … 170 335 if(Utility.isWindows()) { 171 336 args = new String[4]; 172 if( gatherer.config.perl_path != null) {173 args[0] = gatherer.config.perl_path;337 if(Gatherer.config.perl_path != null) { 338 args[0] = Gatherer.config.perl_path; 174 339 } 175 340 else { 176 341 args[0] = "Perl.exe"; 177 342 } 178 args[1] = gatherer.config.gsdl_path + "bin" + File.separator + "script" + File.separator + "pluginfo.pl";343 args[1] = Gatherer.config.gsdl_path + "bin" + File.separator + "script" + File.separator + "pluginfo.pl"; 179 344 args[2] = "-xml"; 180 345 args[3] = getPlugInName(plugin); … … 229 394 } 230 395 if(document != null) { 231 parse(document.getDocumentElement()); 232 } 233 } 234 /** Method to move a plugin higher in the list order. 235 * @param plugin The <strong>PlugIn</strong> you want to move. 236 * @param direction <i>true</i> to move the plugin up, <i>false</i> to move it down. 237 * @param all <i>true</i> to move to move all the way, <i>false</i> for a single step. 238 */ 239 public void movePlugIn(PlugIn plugin, boolean direction, boolean all) { 240 // Can't ever move RecPlug or ArcPlug. 241 if(plugin.getName().equals("ArcPlug") || plugin.getName().equals("RecPlug")) { 242 JOptionPane.showMessageDialog(manager.gui, get("CDM.Move.Fixed"), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 243 return; 244 } 245 if(all) { 246 if(direction) { 247 assigned.removeElement(plugin); 248 assigned.add(0, plugin); 249 gatherer.c_man.configurationChanged(); 250 } 251 else { 252 assigned.removeElement(plugin); 253 int index = assigned.size() - 1; 254 boolean found = false; 255 while(!found) { 256 Object temp = assigned.get(index); 257 if(temp instanceof PlugIn) { 258 PlugIn current = (PlugIn) temp; 259 if(current.getName().equals("ArcPlug") || current.getName().equals("RecPlug")) { 260 index--; 261 } 262 else { 263 found = true; 264 } 265 } 266 else { 267 found = true; 268 } 269 } 270 assigned.add(index, plugin); 271 gatherer.c_man.configurationChanged(); 272 } 273 } 274 else { 275 // Try to move the plugin one step in the desired direction. 276 int index = assigned.indexOf(plugin); 277 ///ystem.err.println("Index of " + plugin + " = " + index); 278 if(direction) { 279 index--; 280 if(index < 0) { 281 String args[] = new String[1]; 282 args[0] = plugin.getName(); 283 JOptionPane.showMessageDialog(manager.gui, get("CDM.Move.At_Top", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 284 return; 285 } 286 assigned.removeElement(plugin); 287 assigned.add(index, plugin); 288 gatherer.c_man.configurationChanged(); 289 } 290 else { 291 index++; 292 Object object = assigned.get(index); 293 if(index == assigned.size()) { 294 String args[] = new String[1]; 295 args[0] = plugin.getName(); 296 JOptionPane.showMessageDialog(manager.gui, get("CDM.Move.At_Bottom", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 297 // Still not going to move RecPlug or ArcPlug. 298 return; 299 } 300 else if(!(object instanceof PlugIn) || ((PlugIn)object).getName().equals("ArcPlug") || ((PlugIn)object).getName().equals("RecPlug")) { 301 String args[] = new String[1]; 302 args[0] = plugin.getName(); 303 JOptionPane.showMessageDialog(manager.gui, get("CDM.Move.Cannot", args), get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE); 304 // Still not going to move RecPlug or ArcPlug. 305 return; 306 } 307 assigned.removeElement(plugin); 308 assigned.add(index, plugin); 309 gatherer.c_man.configurationChanged(); 310 } 311 } 312 } 313 314 /** This method attempts to parse a plugin command from a command string taken from the collection configuration file. This process is quite complex as not only must the correct plugin be matched by also all of the parameters given must be legal. If such a command is found, the plugin is immediately assigned. 315 * @param command The coomand <strong>String</strong> that may include plugin information. 316 * @return <i>true</i> if a plugin command was parsed, <i>false</i> otherwise. 317 */ 318 public boolean parse(String command) { 319 String command_lc = command.toLowerCase(); 320 if(command_lc.startsWith("plugin")) { 321 CommandTokenizer tokenizer = new CommandTokenizer(command); 322 if(tokenizer.countTokens() >= 2) { 323 tokenizer.nextToken(); // Throw away 'plugin' 324 String name = tokenizer.nextToken(); 325 // Try to locate the plugin with this name. 326 PlugIn plugin = getPlugIn(name); 327 // And if successful start to parse the arguments. 328 if(plugin != null) { 329 // Take a copy. 330 plugin = plugin.copy(); 331 String key = null; 332 while(tokenizer.hasMoreTokens()) { 333 if(key == null) { 334 key = tokenizer.nextToken(); 335 } 336 // Try to retrieve a matching argument. 337 Argument argument = plugin.getArgument(key); 338 if(argument != null) { 339 // Set as assigned. 340 argument.setAssigned(true); 341 // And if the argument is of a parameter type, parse a parameter. 342 if(argument.getType() != Argument.FLAG && tokenizer.hasMoreTokens()) { 343 String value = tokenizer.nextToken(); 344 ElementWrapper element = null; 345 if(argument.getType() == Argument.METADATA) { 346 value = value.replace(':', MSMUtils.NS_SEP); 347 if (value.indexOf(MSMUtils.NS_SEP)==-1){ 348 value = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + value; 349 } 350 // Now retrieve the element this refers to, if available. 351 element = Gatherer.c_man.getCollection().msm.getElement(value); 352 } 353 if(element != null) { 354 argument.setElementValue(element); 355 element = null; 356 } 357 else { 358 argument.setValue(value); 359 } 360 } 361 key = null; 362 } 363 // Argument cannot be matched. 364 else { 365 String cur_key = key; 366 String value = tokenizer.nextToken(); 367 if(value.startsWith("-")) { 368 key = value; 369 value = null; 370 } 371 else { 372 key = null; 373 } 374 String custom = plugin.getCustom(); 375 if(custom == null) { 376 if(value == null) { 377 plugin.setCustom(cur_key); 378 } 379 else { 380 plugin.setCustom(cur_key + " " + value); 381 } 382 } 383 else { 384 if(value == null) { 385 plugin.setCustom(custom + " " + cur_key); 386 } 387 else { 388 plugin.setCustom(custom + " " + cur_key + " " + value); 389 } 390 } 391 } 392 } 393 // Slight tweak. If the plugin is the RecPlug we want to set use_metadata_files by default. 394 if(plugin.getName().equalsIgnoreCase("RecPlug")) { 395 Argument argument = plugin.getArgument("-use_metadata_files"); 396 if(argument != null) { 397 argument.setAssigned(true); 398 } 399 } 400 // Second tweak. If the plugin is the HTMLPlug we want to modify the block expression so our backup files are ignored. 401 if(plugin.getName().equalsIgnoreCase("HTMLPlug")) { 402 Argument argument = plugin.getArgument("-block_exp"); 403 if(argument != null) { 404 argument.setValue(argument.getDefaultValue() + "|(~$)"); 405 } 406 } 407 // Add the plugin to our reserve 408 assignPlugIn(plugin); 409 return true; 410 } 411 else { 412 //ystem.err.println("Unknown plugin"); 413 } 414 } 415 } 416 return false; 417 } 418 /** This method removes an assigned plugin. I was tempted to call it unassign, by remove is more consistant. Note that there is no way to remove a plugin from the reserve. 419 * @param plugin The <strong>PlugIn</strong> to remove. 420 */ 421 public void removePlugIn(PlugIn plugin) { 422 assigned.removeElement(plugin); 423 available.addElement(plugin); 424 gatherer.c_man.configurationChanged(); 425 } 426 /** Method to cache the current contents of reserve (known plugins) to file. 427 */ 428 public void savePlugIns() { 429 try { 430 FileOutputStream file = new FileOutputStream(Utility.BASE_DIR + "plugins.dat"); 431 ObjectOutputStream out = new ObjectOutputStream(file); 432 out.writeObject(reserve); 433 out.close(); 434 } 435 catch (Exception error) { 436 } 437 } 438 /** Method used to determine the number of plugins that have been assigned. 439 * @return An <i>int</i> which is the number of plugins. 440 */ 441 public int size() { 442 return assigned.size(); 443 } 444 /** Method to print out a block of plugin commands, much like you'd find in a collection configuration file. 445 * @return A <strong>String</strong> containing a series of plugin commands separated by new lines. 446 */ 447 public String toString() { 448 String text = ""; 449 for(int i = 0; i < assigned.size(); i++) { 450 Object object = assigned.get(i); 451 if(object instanceof PlugIn) { 452 PlugIn plugin = (PlugIn) object; 453 text = text + plugin.toString() + "\n"; 454 } 455 } 456 text = text + "\n"; 457 return text; 458 } 459 /* Retrieve a phrase from the dictionary based on a certain key. 460 * @param key The search <strong>String</strong>. 461 * @return The matching phrase from the Dictionary. 462 */ 463 private String get(String key) { 464 return get(key, (String[])null); 465 } 466 467 private String get(String key, String arg) { 468 String args[] = new String[1]; 469 args[0] = arg; 470 return get(key, args); 471 } 472 473 /* Retrieve a phrase from the dictionary based on a certain key and arguments. 474 * @param key The search <strong>String</strong>. 475 * @param args A <strong>String[]</strong> of arguments used to complete and format the choosen phrase. 476 * @return The matching phrase from the Dictionary. 477 */ 478 private String get(String key, String args[]) { 479 if(key.indexOf(".") == -1) { 480 key = "CDM.PlugInManager." + key; 481 } 482 return gatherer.dictionary.get(key, args); 483 } 484 /** Method to extract just the plugins name from a file object. 485 * @param plugin The <strong>File</strong> which references a certain plugin. 486 * @return A <strong>String</strong> containing just the plugins name, without extension. 487 */ 488 private String getPlugInName(File plugin) { 489 String name = plugin.getName(); 490 if(name.indexOf(".") != -1) { 491 name = name.substring(0, name.indexOf(".")); 492 } 493 return name; 494 } 495 /** Method to retrieve the CData value from a node. Requires a search for the #text node. 496 * @param node The <strong>Node</strong> whose value we wish to find. 497 * @return The value of node as a <strong>String</strong>, or <i>null</i> if no value exists. 498 */ 499 private String getValue(Node node) { 500 if(node.hasChildNodes()) { 501 Node text = node.getFirstChild(); 502 //ystem.err.println("Value of " + node.getNodeName() + " = " + text.getNodeValue()); 503 return text.getNodeValue(); 504 } 505 return node.getNodeValue(); 506 } 396 parseXML(document.getDocumentElement()); 397 } 398 } 399 507 400 /** Method to initially load information from the standard plug-ins within the gsdl Perl library. 508 401 */ … … 512 405 FileInputStream file = new FileInputStream(Utility.BASE_DIR + "plugins.dat"); 513 406 ObjectInputStream input = new ObjectInputStream(file); 514 reserve = (DynamicListModel) input.readObject(); 515 available = reserve.shallowCopy(); 407 library = (ArrayList) input.readObject(); 516 408 } 517 409 catch (Exception error) { 518 410 } 519 if(reserve == null) { 520 available = new DynamicListModel(); 521 reserve = new DynamicListModel(); 522 reserve.setAutoOrder(true); 523 // Retrieve the gsdl home directory... 524 String directory = gatherer.config.gsdl_path; 411 if(library == null) { 412 library = new ArrayList(); 413 // Retrieve the gsdl home directory... 414 String directory = Gatherer.config.gsdl_path; 525 415 directory = directory + "perllib" + File.separator + "plugins" + File.separator; 526 416 loadPlugIns(new File(directory)); … … 533 423 File files[] = directory.listFiles(); 534 424 if(files != null) { 535 425 // Create a progress indicator. 536 426 ParsingProgress progress = new ParsingProgress(get("CDM.PlugInManager.Parsing.Title"), get("CDM.PlugInManager.Parsing.Message"), files.length); 537 427 for(int i = 0; i < files.length; i++) { … … 546 436 } 547 437 548 private PlugIn parse (Node root) {438 private PlugIn parseXML(Node root) { 549 439 PlugIn plugin = new PlugIn(); 550 440 String node_name = null; … … 553 443 node_name = node.getNodeName(); 554 444 if(node_name.equals("Name")) { 555 String name = getValue(node);445 String name = MSMUtils.getValue(node); 556 446 // We can save ourselves some processing time if a plugin with this name already exists in our manager. If so retrieve it and return it. 557 PlugIn existing = get PlugIn(name);447 PlugIn existing = getBasePlugIn(name); 558 448 if(existing != null) { 559 449 return existing; … … 562 452 } 563 453 else if(node_name.equals("Desc")) { 564 plugin.setDesc (getValue(node));454 plugin.setDescription(MSMUtils.getValue(node)); 565 455 } 566 456 // Parse the multitude of arguments. … … 575 465 node_name = det.getNodeName(); 576 466 if(node_name.equals("Name")) { 577 argument.setName( getValue(det));467 argument.setName(MSMUtils.getValue(det)); 578 468 } 579 469 else if(node_name.equals("Desc")) { 580 argument.setDesc (getValue(det));470 argument.setDescription(MSMUtils.getValue(det)); 581 471 } 582 472 else if(node_name.equals("Type")) { 583 argument.setType( getValue(det));473 argument.setType(MSMUtils.getValue(det)); 584 474 } 585 475 else if(node_name.equals("Default")) { 586 argument.setDefault (getValue(det));476 argument.setDefaultValue(MSMUtils.getValue(det)); 587 477 } 588 478 else if(node_name.equals("List")) { … … 595 485 node_name = subvalue.getNodeName(); 596 486 if(node_name.equals("Name")) { 597 key = getValue(subvalue);487 key = MSMUtils.getValue(subvalue); 598 488 } 599 489 else if(node_name.equals("Desc")) { 600 desc = getValue(subvalue);490 desc = MSMUtils.getValue(subvalue); 601 491 } 602 492 } … … 608 498 } 609 499 else if(node_name.equals("Required")) { 610 String v = getValue(det);500 String v = MSMUtils.getValue(det); 611 501 if(v != null && v.equals("yes")) { 612 502 argument.setRequired(true); … … 618 508 // A super plugin class. 619 509 else if(node_name.equals("PlugInfo")) { 620 PlugIn super_plugin = parse (arg);510 PlugIn super_plugin = parseXML(arg); 621 511 plugin.setSuper(super_plugin); 622 512 } … … 632 522 633 523 /** A class which provodes controls for assigned and editing plugins. */ 634 private class Control 635 extends JPanel { 524 private class PlugInControl 525 extends JPanel 526 implements Control { 636 527 /** Button for adding plugins. */ 637 528 private JButton add = null; … … 649 540 private JButton remove = null; 650 541 /** A combobox containing all of the known plugins, including those that may have already been assigned. */ 651 private JComboBox plugin = null;542 private GComboBox plugin = null; 652 543 /** The label next to the plugin combobox. */ 653 544 private JLabel plugin_label = null; … … 674 565 /** Constructor. 675 566 */ 676 public Control() {677 Object plugins[] = reserve.toArray();567 public PlugInControl() { 568 Object plugins[] = library.toArray(); 678 569 Vector plugin_model = new Vector(); 679 570 for(int i = 0; i < plugins.length; i++) { … … 681 572 } 682 573 Collections.sort(plugin_model); 683 574 // Create 684 575 add = new JButton(get("Add")); 685 576 add.setMnemonic(KeyEvent.VK_A); … … 697 588 instructions.setWrapStyleWord(true); 698 589 move_bottom = new JButton(); 699 JLabel move_bottom_label = new JLabel(get(" Move_Bottom"));590 JLabel move_bottom_label = new JLabel(get("CDM.Move.Move_Bottom")); 700 591 move_bottom_label.setHorizontalAlignment(JLabel.CENTER); 701 592 move_bottom_label.setPreferredSize(LABEL_SIZE); … … 706 597 move_bottom.setMnemonic(KeyEvent.VK_B); 707 598 move_down = new JButton(); 708 JLabel move_down_label = new JLabel(get(" Move_Down"));599 JLabel move_down_label = new JLabel(get("CDM.Move.Move_Down")); 709 600 move_down_label.setHorizontalAlignment(JLabel.CENTER); 710 601 move_down_label.setPreferredSize(LABEL_SIZE); … … 715 606 move_down.setMnemonic(KeyEvent.VK_D); 716 607 move_top = new JButton(); 717 JLabel move_top_label = new JLabel(get(" Move_Top"));608 JLabel move_top_label = new JLabel(get("CDM.Move.Move_Top")); 718 609 move_top_label.setHorizontalAlignment(JLabel.CENTER); 719 610 move_top_label.setPreferredSize(LABEL_SIZE); … … 724 615 move_top.setMnemonic(KeyEvent.VK_T); 725 616 move_up = new JButton(); 726 JLabel move_up_label = new JLabel(get(" Move_Up"));617 JLabel move_up_label = new JLabel(get("CDM.Move.Move_Up")); 727 618 move_up_label.setHorizontalAlignment(JLabel.CENTER); 728 619 move_up_label.setPreferredSize(LABEL_SIZE); … … 733 624 move_up.setMnemonic(KeyEvent.VK_U); 734 625 movement_pane = new JPanel(); 735 plugin = new JComboBox(available); 736 //plugin.setEditable(true); 626 627 plugin = new GComboBox(getAvailable()); 628 plugin.setBackgroundNonSelectionColor(Gatherer.config.getColor("coloring.editable", false)); 629 plugin.setBackgroundSelectionColor(Gatherer.config.getColor("coloring.collection_selection_background", false)); 630 plugin.setEditable(true); 737 631 plugin.setSelectedIndex(0); 632 plugin.setTextNonSelectionColor(Gatherer.config.getColor("coloring.workspace_tree_foreground", false)); 633 plugin.setTextSelectionColor(Gatherer.config.getColor("coloring.collection_selection_foreground", false)); 634 738 635 plugin_label = new JLabel(get("PlugIn")); 739 plugin_list = new JList( assigned);636 plugin_list = new JList(model); 740 637 plugin_list.setCellRenderer(new ListRenderer()); 741 638 plugin_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); … … 822 719 public void destroy() { 823 720 } 824 /** This method is overridden in some control classes to allow for the updating of collection configuration when the focus is lost to another view. In this case however the updates are asynchronous and so no 'has the configuration changed without the user updating' check is needed. 825 * @return <i>true</i> if this control has focus, <i>false</i> otherwise. 826 */ 827 public boolean hasFocus() { 828 return super.hasFocus(); 829 } 721 830 722 /** This method is overridden to ensure the instructions are scrolled to top, before the super classes updateUI() is called. 831 832 public void updateUI() {723 */ 724 public void gainFocus() { 833 725 if(instructions != null) { 834 726 instructions.setCaretPosition(0); … … 836 728 super.updateUI(); 837 729 } 838 /** This class listens for actions upon the add button in the controls, and if detected calls the <i>assignPlugIn()</i> method. 839 */ 730 731 public void loseFocus() { 732 733 } 734 735 /** This class listens for actions upon the add button in the controls, and if detected calls the <i>assignPlugIn()</i> method. */ 840 736 private class AddListener 841 737 implements ActionListener { 842 843 844 738 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls. 739 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action. 740 */ 845 741 public void actionPerformed(ActionEvent event) { 846 PlugIn new_plugin = null; 847 Object object = plugin.getSelectedItem(); 848 if(object instanceof PlugIn) { 849 PlugIn target = (PlugIn)object; 850 new_plugin = target.copy(); 851 } 852 else { 853 new_plugin = new PlugIn(object.toString(), "", null); 854 } 855 object = null; 856 // Automatically chain to configuration. This ensures required arguments are filled out. 857 ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, new_plugin); 858 if(ac.display()) { 859 assignPlugIn(new_plugin); 860 plugin_list.setSelectedValue(new_plugin, true); 861 } 862 ac = null; 863 new_plugin = null; 864 plugin.setSelectedIndex(0); 865 } 866 } 867 /** This class listens for actions upon the configure button in the controls, and if detected creates a new <strong>ArgumentConfiguration</strong> dialog box to allow for configuration. 868 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration 869 */ 870 private class ConfigureListener 871 implements ActionListener { 872 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls. 873 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action. 874 */ 875 public void actionPerformed(ActionEvent event) { 876 if(!plugin_list.isSelectionEmpty()) { 877 Object object = plugin_list.getSelectedValue(); 878 if(object instanceof PlugIn) { 879 ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, (PlugIn)object); 742 Object selected_object = plugin.getSelectedItem(); 743 // If there is something in the combobox, but we haven't registered a selection, then add the object and select it! 744 if(selected_object != null && plugin.getSelectedIndex() == -1) { 745 plugin.insertItemAt(selected_object, plugin.getItemCount()); 746 } 747 if(selected_object != null) { 748 // Create a new element in the DOM 749 Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.PLUGIN_ELEMENT); 750 // Remember that the plugin supplied might be a custom string rather than a base plugin 751 PlugIn new_plugin = null; 752 if(selected_object instanceof PlugIn) { 753 PlugIn base_plugin = (PlugIn) selected_object; 754 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, base_plugin.getName()); 755 new_plugin = new PlugIn(element, base_plugin); 756 base_plugin = null; 757 } 758 else { 759 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, selected_object.toString()); 760 new_plugin = new PlugIn(element, null); 761 } 762 if(!model.contains(new_plugin)) { 763 // Automatically chain to configuration. This ensures required arguments are filled out. 764 ArgumentConfiguration ac = new ArgumentConfiguration(new_plugin); 880 765 if(ac.display()) { 881 assigned.refresh(); 766 assignPlugIn(new_plugin); 767 plugin_list.setSelectedValue(new_plugin, true); 882 768 } 883 } 884 } 885 } 886 } 887 /** A special list renderer which is able to render separating lines as well. */ 888 private class ListRenderer 889 extends DefaultListCellRenderer { 890 /** Return a component that has been configured to display the specified value. That component's paint method is then called to "render" the cell. If it is necessary to compute the dimensions of a list because the list cells do not have a fixed size, this method is called to generate a component on which getPreferredSize can be invoked. 891 * @param list - The <strong>JList</strong> we're painting. 892 * @param value - The value returned by list.getModel().getElementAt(index) as an <strong>Object</strong>. 893 * @param index - The cells index as an <i>int</i>. 894 * @param isSelected - <i>true</i> if the specified cell was selected. 895 * @param cellHasFocus - <i>true</i> if the specified cell has the focus. 896 * @return A <strong>Component</strong> whose paint() method will render the specified value. 897 * @see javax.swing.JList 898 * @see javax.swing.JSeparator 899 * @see javax.swing.ListModel 900 * @see javax.swing.ListSelectionModel 901 */ 902 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 903 if(value instanceof JPanel) { 904 return (JPanel) value; 905 } 906 else { 907 return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 908 } 909 } 910 } 769 ac = null; 770 new_plugin = null; 771 plugin.setSelectedIndex(0); 772 } 773 else { 774 JOptionPane.showMessageDialog(Gatherer.g_man, get("PlugIn_Exists"), get("General.Error"), JOptionPane.ERROR_MESSAGE); 775 } 776 } 777 } 778 } 779 911 780 /** Listens for double clicks apon the list and react as if the configure button was pushed. */ 912 781 private class ClickListener 913 782 extends MouseAdapter { 914 915 916 783 /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt. 784 * @param event A <strong>MouseEvent</strong> containing information about the mouse click. 785 */ 917 786 public void mouseClicked(MouseEvent event) { 918 787 if(event.getClickCount() == 2 ) { 919 788 if(!plugin_list.isSelectionEmpty()) { 920 Object object =plugin_list.getSelectedValue();921 if( object instanceof PlugIn) {922 ArgumentConfiguration ac = new ArgumentConfiguration( gatherer, manager, (PlugIn)object);789 PlugIn plugin = (PlugIn) plugin_list.getSelectedValue(); 790 if(!plugin.isSeparator()) { 791 ArgumentConfiguration ac = new ArgumentConfiguration(plugin); 923 792 if(ac.display()) { 924 assigned.refresh();793 refresh(plugin); 925 794 } 795 ac.destroy(); 796 ac = null; 926 797 } 798 } 799 } 800 } 801 } 802 803 /** This class listens for actions upon the configure button in the controls, and if detected creates a new <strong>ArgumentConfiguration</strong> dialog box to allow for configuration. 804 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration 805 */ 806 private class ConfigureListener 807 implements ActionListener { 808 /** Any implementation of <i>ActionListener</i> must include this method so that we can be informed when an action has occured on one of our target controls. 809 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action. 810 */ 811 public void actionPerformed(ActionEvent event) { 812 if(!plugin_list.isSelectionEmpty()) { 813 PlugIn plugin = (PlugIn) plugin_list.getSelectedValue(); 814 if(!plugin.isSeparator()) { 815 ArgumentConfiguration ac = new ArgumentConfiguration(plugin); 816 if(ac.display()) { 817 refresh(plugin); 818 } 819 ac.destroy(); 820 ac = null; 927 821 } 928 822 } … … 946 840 } 947 841 } 842 843 /** A special list renderer which is able to render separating lines as well. */ 844 private class ListRenderer 845 extends DefaultListCellRenderer { 846 /** Return a component that has been configured to display the specified value. That component's paint method is then called to "render" the cell. If it is necessary to compute the dimensions of a list because the list cells do not have a fixed size, this method is called to generate a component on which getPreferredSize can be invoked. 847 * @param list - The <strong>JList</strong> we're painting. 848 * @param value - The value returned by list.getModel().getElementAt(index) as an <strong>Object</strong>. 849 * @param index - The cells index as an <i>int</i>. 850 * @param isSelected - <i>true</i> if the specified cell was selected. 851 * @param cellHasFocus - <i>true</i> if the specified cell has the focus. 852 * @return A <strong>Component</strong> whose paint() method will render the specified value. 853 * @see javax.swing.JList 854 * @see javax.swing.JSeparator 855 * @see javax.swing.ListModel 856 * @see javax.swing.ListSelectionModel 857 */ 858 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 859 PlugIn plugin = (PlugIn) value; 860 if(plugin.isSeparator()) { 861 return separator; 862 } 863 else { 864 return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 865 } 866 } 867 } 868 948 869 949 870 /** Listens for actions apon the move buttons in the manager controls, and if detected calls the <i>movePlugIn()</i> method of the manager with the appropriate details. */ … … 999 920 } 1000 921 /** Creates a list separator. 1001 1002 922 * Code courtesy of Farwell, Paul. Contact <a href="mailto:[email protected]">[email protected]</a> 923 */ 1003 924 static private JPanel getSeparator() { 1004 925 // we put the separator inside a panel to control … … 1014 935 } 1015 936 } 1016 1017 1018 1019 -
trunk/gli/src/org/greenstone/gatherer/cdm/Subcollection.java
r4675 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 27 package org.greenstone.gatherer.cdm; 44 28 /************************************************************************************** 45 * Title: Gatherer46 * Description: The Gatherer: a tool for gathering and enriching a digital collection.47 * Copyright: Copyright (c) 200148 * Company: The University of Waikato49 29 * Written: 03/05/02 50 30 * Revised: 17/11/02 - Commenting 31 * 04/07/03 - Completely rewritten to support DOM 51 32 **************************************************************************************/ 33 import org.greenstone.gatherer.Gatherer; 34 import org.greenstone.gatherer.cdm.CollectionConfiguration; 35 import org.greenstone.gatherer.cdm.CollectionDesignManager; 36 import org.greenstone.gatherer.cdm.DOMProxyListEntry; 37 import org.greenstone.gatherer.msm.ElementWrapper; 52 38 import org.greenstone.gatherer.msm.MSMUtils; 53 import org.w3c.dom.Element; 39 import org.greenstone.gatherer.util.StaticStrings; 40 import org.greenstone.gatherer.util.Troolean; 41 import org.w3c.dom.*; 54 42 /** This class encapsulates one subcollection entry in the collection configuration file. 55 43 * @author John Thompson, Greenstone Digital Library, University of Waikato 56 * @version 2. 344 * @version 2.4 57 45 */ 58 46 public class Subcollection 59 implements Comparable {47 implements Comparable, DOMProxyListEntry { 60 48 /** A <i>boolean</i> which is <i>true</i> if the condition is an include one, <i>false</i> otherwise. */ 61 private boolean include = true;62 /** Either the fully qualified name of the metadata whose value should be matched against the given expression, or <i>null</i> if you wish to match against the file name. */63 private Stringelement = null;64 /** A String containing a Perl expression which is used as the filter for this subcollection. */65 private String exp= null;49 private Troolean include = new Troolean(); 50 /** The DOM Element this Subcollection is based upon. */ 51 private Element element = null; 52 /** A String containing a Perl expression which is used as the pattern by which to filter this subcollection. */ 53 private String pattern = null; 66 54 /** A series of flags to be used when matching the expression. */ 67 55 private String flags = null; 68 56 /** A String which is a unique identifier of a subcollection. */ 69 57 private String name = null; 70 /** Constructor. 71 * @param name A <strong>String</strong> which is a unique identifier of a subcollection. 72 * @param pattern A <strong>String</strong> containing the inclusion, the element to filter, a Perl expression which is used as the filter for this subcollection, and a series of argument flags. 73 */ 74 public Subcollection(String name, String pattern) { 58 /** Either the fully qualified name of the metadata whose value should be matched against the given expression, or <i>null</i> if you wish to match against the file name. */ 59 private String source = null; 60 private String text = null; 61 62 /** Default constructor which should only be used during DOMProxyListModel initialization. */ 63 public Subcollection() { 64 } 65 66 /** Constructor for representing an existing assigned Subcollection. 67 * @param element the Element this subcollection is based upon 68 */ 69 public Subcollection(Element element) { 70 this.element = element; 71 } 72 73 /** Constructor for assigning a brand new Subcollection. 74 * @param name a unique identifier for this collection as a String 75 * @param include true if this the pattern should be an inclusion filter, false for exclusion 76 * @param source either the fully qualified name of an element as a String, or null to filter filenames 77 * @param pattern the matching pattern as a String 78 * @param flags any flags to use while matching, as a String 79 */ 80 public Subcollection(String name, boolean include, String source, String pattern, String flags) { 81 // Cache the details 82 this.flags = flags; 83 this.include.set(include); 75 84 this.name = name; 76 // Have to do some work on pattern. 77 // Remove quote marks. 78 if(pattern.startsWith("\"") || pattern.startsWith("'")) { 79 pattern = pattern.substring(1, pattern.length() - 1); 80 } 81 // Test for exclusion 82 if(pattern.startsWith("!")) { 83 this.include = false; 84 pattern = pattern.substring(1, pattern.length()); 85 this.pattern = pattern; 86 if(source != null) { 87 this.source = source; 85 88 } 86 89 else { 87 this.include = true; 88 } 89 if(pattern.indexOf("/") != -1) { 90 // Now element (which may be Filename) 91 this.element = pattern.substring(0, pattern.indexOf("/")); 92 if(this.element.toLowerCase().equals("filename")) { 93 this.element = null; 90 this.source = StaticStrings.FILENAME_STR; 91 } 92 // Create a new DOM Element with the appropriate attributes and text value 93 element = CollectionDesignManager.collect_config.document.createElement(StaticStrings.SUBCOLLECTION_ELEMENT); 94 element.setAttribute(StaticStrings.CONTENT_ATTRIBUTE, source); 95 element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name); 96 element.setAttribute(StaticStrings.OPTIONS_ATTRIBUTE, flags); 97 element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, (include ? StaticStrings.INCLUDE_STR : StaticStrings.EXCLUDE_STR)); 98 MSMUtils.setValue(element, pattern); 99 } 100 101 /** Method to compare two subcollections. 102 * @param object he other subcollection to compare to, as an Object 103 * @return an int which is >0, 0, or <0 if this subcollection is before, equal to, or after the target object respectively. 104 */ 105 public int compareTo(Object object) { 106 return getName().compareTo(((Subcollection)object).getName()); 107 } 108 109 public DOMProxyListEntry create(Element element) { 110 return new Subcollection(element); 111 } 112 113 /** Method to check two subcollections for equality. 114 * @param object the other subcollection to compare to, as an Object 115 * @return true if the subcollections are equal, false otherwise. 116 */ 117 public boolean equals(Object object) { 118 return (compareTo(object) == 0); 119 } 120 121 /** Retrieve the DOM Element this Subcollection is based upon. 122 * @return an Element 123 */ 124 public Element getElement() { 125 return element; 126 } 127 128 /** Method to get the value of flags. 129 * @return the value of flags as a String 130 */ 131 public String getFlags() { 132 if(flags == null && element != null) { 133 flags = element.getAttribute(StaticStrings.OPTIONS_ATTRIBUTE); 134 } 135 return flags; 136 } 137 138 /** Method to get the value of name. 139 * @param String The value of name as a <strong>String</string>. 140 */ 141 public String getName() { 142 if(name == null && element != null) { 143 name = element.getAttribute(StaticStrings.NAME_ATTRIBUTE); 144 } 145 return name; 146 } 147 148 public String getPattern() { 149 if(pattern == null && element != null) { 150 pattern = MSMUtils.getValue(element); 151 } 152 return pattern; 153 } 154 155 /** Method to get the name of the source of the strings used in pattern matching. 156 * @return a String which is either the fully qualified name of a metadata element, or filename 157 */ 158 public String getSource() { 159 if(source == null &&element != null) { 160 source = element.getAttribute(StaticStrings.CONTENT_ATTRIBUTE); 161 // If this is a MSM Element then retrieve the appropriate ElementWrapper and use the language specific name 162 if(!source.equals(StaticStrings.FILENAME_STR)) { 163 ElementWrapper element_wrapper = Gatherer.c_man.getCollection().msm.getElement(source); 164 if(element_wrapper != null) { 165 source = element_wrapper.toString(); 166 } 94 167 } 95 // Extract Perl expression 96 if(pattern.indexOf("/") != pattern.lastIndexOf("/")) { 97 this.exp = pattern.substring(pattern.indexOf("/") + 1, 98 pattern.lastIndexOf("/")); 99 this.flags = pattern.substring(pattern.lastIndexOf("/") + 1); 100 } 101 else { 102 this.exp = pattern.substring(pattern.indexOf("/") + 1); 103 } 104 } 105 else { 106 // Hmmm. Well I don't know what this is but it isn't a proper subcollection definition. Can't really 'return null' or something. So I'll just not set include, element, exp and flag expressions. 107 } 108 } 109 /** Constructor. 110 * @param name A <strong>String</strong> which is a unique identifier of a subcollection. 111 * @param include A <i>boolean</i> which is <i>true</i> if the condition is an include one, <i>false</i> otherwise. 112 * @param exp A <strong>String</strong> containing a Perl expression which is used as the filter for this subcollection. 113 */ 114 public Subcollection(String name, boolean include, String exp, String flags) { 115 this.element = null; 116 this.exp = exp; 117 this.flags = flags; 118 this.include = include; 119 this.name = name; 120 } 121 /** Constructor. 122 * @param name A <strong>String</strong> which is a unique identifier of a subcollection. 123 * @param include A <i>boolean</i> which is <i>true</i> if the condition is an include one, <i>false</i> otherwise. 124 * @param element Either the fully qualified name of the metadata whose value should be matched against the given expression, or <i>null</i> if you wish to match against the file name. 125 * @param exp A <strong>String</strong> containing a Perl expression which is used as the filter for this subcollection. 126 * @param flags A <strong>String</strong> of flags to be taken into account when matching the expression. 127 */ 128 public Subcollection(String name, boolean include, String element, String exp, String flags) { 168 } 169 return source; 170 } 171 172 public boolean isAssigned() { 173 return (element != null && !element.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.FALSE_STR)); 174 } 175 176 /** Method to get the value of include. 177 * @param boolean true if this is an inclusion filter, false otherwise 178 */ 179 public boolean isInclusive() { 180 if(!include.isDecided() && element != null) { 181 include.set(element.getAttribute(StaticStrings.TYPE_ATTRIBUTE).equals(StaticStrings.INCLUDE_STR)); 182 } 183 return include.isTrue(); 184 } 185 186 public void setAssigned(boolean assigned) { 187 if(element != null) { 188 element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (assigned ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR)); 189 } 190 } 191 192 public void setElement(Element element) { 129 193 this.element = element; 130 this.exp = exp; 131 this.flags = flags; 132 this.include = include; 133 this.name = name; 134 } 135 /** Method to compare two subcollections. 136 * @param object The other subcollection to compare to, as an <strong>Object</strong>. 137 * @return An <i>int</i> which is greater than, equal to or less than zero if the this object is before, equal to, or after the target object respectively. 138 */ 139 public int compareTo(Object object) { 140 Subcollection sub = (Subcollection) object; 141 return getName().compareTo(sub.getName()); 142 } 143 /** Method to check two subcollections for equality. 144 * @param object The other subcollection to compare to, as an <strong>Object</strong>. 145 * @return A <i>boolean</i> which is <i>true</i> if the subcollections are equal, <i>false</i> otherwise. 146 */ 147 public boolean equals(Object object) { 148 if(compareTo(object) == 0) { 149 return true; 150 } 151 return false; 152 } 153 /** Method to get the value of element. 154 * @return The value of element as an <strong>String</strong>. 155 */ 156 public String getElement() { 157 return element; 158 } 159 /** Method to get the value of expression. 160 * @return The value of exp as a <strong>String</strong>. 161 */ 162 public String getExpression() { 163 return exp; 164 } 165 /** Method to get the value of flags. 166 * @return The value of flags as a <strong>String</strong>. 167 */ 168 public String getFlags() { 169 return flags; 170 } 171 /** Method to get the value of include. 172 * @param boolean The value of include as a <i>boolean</i>. 173 */ 174 public boolean getInclude() { 175 return include; 176 } 177 /** Method to get the value of name. 178 * @param String The value of name as a <strong>String</string>. 179 */ 180 public String getName() { 181 return name; 182 } 183 /** Method to get the name of the source of the strings used in pattern matching. 184 * @return A <strong>String</strong> which is either the fully qualified name of a metadata element, or "Filename". 185 */ 186 public String getSource() { 187 if(element != null) { 188 return element; 189 } 190 return "Filename"; 191 } 194 include.reset(); 195 flags = null; 196 name = null; 197 pattern = null; 198 source = null; 199 text = null; 200 } 201 202 public void setFlags(String new_flags) { 203 if(element != null) { 204 // Change element 205 element.setAttribute(StaticStrings.OPTIONS_ATTRIBUTE, new_flags); 206 flags = new_flags; 207 text = null; 208 } 209 } 210 211 public void setInclusive(boolean new_include) { 212 if(element != null) { 213 // Change element 214 element.setAttribute(StaticStrings.TYPE_ATTRIBUTE, (new_include ? StaticStrings.INCLUDE_STR : StaticStrings.EXCLUDE_STR)); 215 include.set(new_include); 216 text = null; 217 } 218 } 219 220 public void setName(String new_name) { 221 if(element != null) { 222 // Change element 223 element.setAttribute(StaticStrings.NAME_ATTRIBUTE, new_name); 224 name = new_name; 225 text = null; 226 } 227 } 228 229 public void setPattern(String new_pattern) { 230 if(element != null) { 231 // Change element 232 MSMUtils.setValue(element, new_pattern); 233 pattern = new_pattern; 234 text = null; 235 } 236 } 237 238 public void setSource(String new_source) { 239 if(element != null) { 240 // Change element 241 element.setAttribute(StaticStrings.CONTENT_ATTRIBUTE, new_source); 242 source = new_source; 243 text = null; 244 } 245 } 246 192 247 /** Method to display the contents of this class as it would appear in the collection configuration file. 193 * @return A <strong>String</strong> which could be used as a subcollection entry in collect.cfg. 194 248 * @return a String representing this subcollection 249 */ 195 250 public String toString() { 196 String text = "subcollection "; 197 text = text + name + " "; 198 text = text + "\""; 199 if(!include) { 200 text = text + "!"; 201 } 202 if(element != null) { 203 text = text + element; 204 } 205 else { 206 text = text + "Filename"; 207 } 208 text = text + "/"; 209 text = text + exp; 210 text = text + "/"; 211 if(flags != null) { 212 text = text + flags; 213 } 214 text = text + "\"\n"; 251 if(text == null && element != null) { 252 text = CollectionConfiguration.toString(element, true); 253 } 215 254 return text; 216 255 } 217 218 /** Update certain fields of this subcollection.219 * @param name A <strong>String</strong> which is a unique identifier of a subcollection.220 * @param source Either the fully qualified name of the metadata whose value should be matched against the given expression, or <i>null</i> if you wish to match against the file name.221 * @param exp A <strong>String</strong> containing a Perl expression which is used as the filter for this subcollection.222 * @param include A <i>boolean</i> which is <i>true</i> if the condition is an include one, <i>false</i> otherwise.223 * @param flags A <strong>String</strong> of flags to be taken into account when matching the expression.224 */225 public void update(String name, String source, String exp, boolean include, String flags) {226 this.name = name;227 this.element = source;228 this.exp = exp;229 this.include = include;230 this.flags = flags;231 }232 233 /** Method to update the name of a metadata element, if it changes.234 * @param old_name The current name of the element as a <strong>String</strong>.235 * @param new_name The new name of the element as a <strong>String</strong>.236 */237 public void updateElement(String old_name, String new_name) {238 if(element.equals(old_name)) {239 element = new_name;240 }241 }242 256 } 243 257 -
trunk/gli/src/org/greenstone/gatherer/cdm/SubcollectionManager.java
r4675 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 27 package org.greenstone.gatherer.cdm; 44 28 /************************************************************************************** 45 * Title: Gatherer 46 * Description: The Gatherer: a tool for gathering and enriching a digital collection. 47 * Copyright: Copyright (c) 2001 48 * Company: The University of Waikato 49 * Written: 02/05/02 50 * Revised: 17/11/02 - Commented 29 * Written: ??/??/02 30 * Revised: 04/07/03 - DOM support 51 31 **************************************************************************************/ 52 32 import java.awt.*; … … 56 36 import javax.swing.event.*; 57 37 import org.greenstone.gatherer.Gatherer; 38 import org.greenstone.gatherer.cdm.CollectionConfiguration; 39 import org.greenstone.gatherer.cdm.CollectionDesignManager; 40 import org.greenstone.gatherer.cdm.Control; 41 import org.greenstone.gatherer.cdm.DOMProxyListModel; 58 42 import org.greenstone.gatherer.cdm.Subcollection; 59 import org.greenstone.gatherer.cdm.SubIndex; 60 import org.greenstone.gatherer.cdm.SubIndexes; 43 import org.greenstone.gatherer.gui.NonWhitespaceField; 61 44 import org.greenstone.gatherer.msm.ElementWrapper; 45 import org.greenstone.gatherer.msm.MSMUtils; 62 46 import org.greenstone.gatherer.util.ExclusiveListSelectionListener; 63 import org.w3c.dom.Element; 64 /** This class maintains a list of subcollections within our collection, and also records which of these subcollections we are building indexes for. 47 import org.greenstone.gatherer.util.StaticStrings; 48 import org.greenstone.gatherer.util.Utility; 49 import org.w3c.dom.*; 50 /** This class maintains a list of subcollections within our collection. 65 51 * @author John Thompson, Greenstone Digital Library, University of Waikato 66 * @version 2. 152 * @version 2.4 67 53 */ 68 54 public class SubcollectionManager 69 extends DefaultListModel { 70 /** A reference to the manager so we can get access to languages. */ 71 private CollectionDesignManager manager; 55 extends DOMProxyListModel { 56 57 static final private String CLASS_DICTIONARY_NAME = "CDM.SubcollectionManager."; 58 72 59 /** The controls used to edit the settings of this manager. */ 73 60 private Control controls = null; 74 /** A reference to this class so we can use it as a model in our inner classes. */ 75 private DefaultListModel model = null; 76 /** The default index for the subcollections. */ 77 private DefaultSubIndex default_index = null; 78 /** A reference to the Gatherer. */ 79 private Gatherer gatherer = null; 80 /** A hashtable of subcollections, with mappings from name to subcollection. */ 81 private Hashtable subcollections = null; 82 /** A vector-type structure of subcollection indexes. */ 83 private SubIndexes subindexes = null; 84 /** A vector containing all of the subcollection commands that are unresolved, or in other words require that all 'subcollection <name> "<exp>"' to have been previously parsed before we can be certain their references will make sense. */ 85 private ArrayList unresolved = null; 86 /** Constructor. 87 * @param gatherer A reference to the <Strong>Gatherer</strong>. 88 * @see org.greenstone.gatherer.cdm.SubIndexes 89 */ 90 public SubcollectionManager(Gatherer gatherer, CollectionDesignManager manager) { 91 super(); 92 this.gatherer = gatherer; 93 this.manager = manager; 61 62 private DOMProxyListModel model; 63 64 /** Constructor. 65 * @see org.greenstone.gatherer.Gatherer 66 * @see org.greenstone.gatherer.cdm.CollectionConfiguration 67 * @see org.greenstone.gatherer.cdm.CollectionDesignManager 68 * @see org.greenstone.gatherer.cdm.DOMProxyListModel 69 * @see org.greenstone.gatherer.cdm.Subcollection 70 */ 71 public SubcollectionManager() { 72 super(CollectionDesignManager.collect_config.getDocumentElement(), StaticStrings.SUBCOLLECTION_ELEMENT, new Subcollection()); 73 Gatherer.println("SubcollectionManager: " + getSize() + " subcollections parsed."); 94 74 this.model = this; 95 this.subcollections = new Hashtable(); 96 this.subindexes = new SubIndexes(); 97 this.unresolved = new ArrayList(); 98 } 99 /** Method to add a subindex. 100 * @param subindex A <strong>SubIndex</strong>. 75 } 76 77 /** Method to add a new subcollection. 78 * @param subcollection the Subcollection to add 101 79 * @see org.greenstone.gatherer.Gatherer 80 * @see org.greenstone.gatherer.cdm.CollectionConfiguration 81 * @see org.greenstone.gatherer.cdm.DOMProxyListModel 102 82 * @see org.greenstone.gatherer.collection.CollectionManager 103 83 */ 104 public void addSubIndex(SubIndex subindex) { 105 if(!subindexes.contains(subindex)) { 106 subindexes.addElement(subindex); 107 gatherer.c_man.configurationChanged(); 108 } 109 } 110 /** Method to add a new subcollection. Adds it to both the underlying list model and the hashtable mapping names to subcollections. 111 * @param sub The <strong>Subcollection</strong> to add. 112 * @return A <i>boolean</i> indicating if the addition was successful (<i>true</i>) or not (<i>false</i>). 113 * @see org.greenstone.gatherer.Gatherer 114 * @see org.greenstone.gatherer.collection.CollectionManager 115 */ 116 public boolean addSubcollection(Subcollection sub) { 117 if(!contains(sub)) { 118 addElement(sub); 119 subcollections.put(sub.getName(), sub); 120 gatherer.c_man.configurationChanged(); 121 return true; 122 } 123 return false; 124 } 125 /** A method to add a new subcollection, by specifying its name, metadata element if applicable and Perl expression to filter pages into or out of this collection. 126 * @param name A <>>String</>> which is a unique identifier of a subcollection. 127 * @param include A <i>boolean</i> indicating whether this is an inclusion filter (<i>true</i>) or an exclusion one (<i>false</i>). 128 * @param element An <>>Element</>> which is either the metadata whose value should be matched against the given expression, or <i>null</i> if you wish to match against the file name. 129 * @param exp A <>>String</>> containing a Perl expression which is used as the filter for this subcollection. 130 * @param flags A <strong>String<strong> listing any special flags to be applied when matching the expression. 131 * @return A <i>boolean</i> with a value of <i>true</i> if the addition was successful. 132 * @see org.greenstone.gatherer.cdm.Subcollection 133 */ 134 public boolean addSubcollection(String name, boolean include, String element, String exp, String flags) { 135 Subcollection sub = null; 136 if(element != null) { 137 sub = new Subcollection(name, include, element, exp, flags); 138 } 139 else { 140 sub = new Subcollection(name, include, exp, flags); 141 } 142 return addSubcollection(sub); 143 } 144 /** Refresh all derived components using this manager as a model. 145 */ 146 public void changed() { 147 fireContentsChanged(this, 0, getSize() - 1); 148 } 149 /** Method to retrieve the controls for this manager. 150 * @return A <Strong>Control</strong> object which contains the controls used to edit the subcollection data. 151 */ 152 public Control getControls() { 153 if(controls == null) { 154 controls = new Control(); 155 } 156 return controls; 157 } 158 /** Method to retrieve the default index. 159 * @return A <strong>DefaultSubIndex</strong> object. 160 */ 161 public DefaultSubIndex getDefaultSubIndex() { 162 return default_index; 163 } 164 /** Method to retrieve a certain subcollection by its name. 165 * @param name A <strong>String</strong> which is used as the key for finding the matching subcollection. 166 * @return The requested <strong>Subcollection</strong> or <i>null</i> if no such subcollection exists. 167 */ 168 public Subcollection getSubcollection(String name) { 169 return (Subcollection) subcollections.get(name); 170 } 171 172 /** Retrieve a certain subindex given its name. 173 * @param name the String representation of a subindex. 174 * @return the SubIndex requested or null if no such subindex. 175 */ 176 public SubIndex getSubIndex(String name) { 177 for(int i = 0; i < subindexes.size(); i++) { 178 SubIndex subindex = (SubIndex) subindexes.get(i); 179 if(subindex.toString().equals(name)) { 180 return subindex; 181 } 182 } 183 return null; 184 } 185 186 /** Method to get all of the subindexes set. 187 * @return A <strong>SubIndexes</strong> object containing all the defined indexes. 188 */ 189 public SubIndexes getSubIndexes() { 190 return subindexes; 191 } 192 /** Method to get all of the subcollections defined. 193 * @return A <strong>Vector</strong> of subcollections. 194 */ 195 public Vector getSubcollections() { 196 Vector subcollections = new Vector(); 197 for(int i = 0; i < size(); i++) { 198 subcollections.add(get(i)); 199 } 200 return subcollections; 201 } 202 /** Mark the current controls, if any, as invalid and deallocate them. Any further use of the controls will requires them being rebuilt. 203 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control 204 */ 205 public void invalidateControls() { 84 public void addSubcollection(Subcollection subcollection) { 85 if(!contains(subcollection)) { 86 Element element = subcollection.getElement(); 87 // Locate where we should insert this new subcollection. 88 Node target_node = CollectionConfiguration.findInsertionPoint(element); 89 // Failing that we insert immediately after a language string 90 add(root, subcollection, target_node); 91 Gatherer.c_man.configurationChanged(); 92 } 93 } 94 95 public void destroy() { 206 96 if(controls != null) { 207 97 controls.destroy(); … … 209 99 } 210 100 } 211 /** This method attempts to parse a subcollection related command from the given command string. If such a string is successfully parsed, it is immediately added to the data within this collection. 212 * @param command The <strong>String</strong> to be parsed. 213 * @param finished This <i>boolean</i> is usually <i>false</i> when called, unless this parse call is being made -after- the entire collection configuration file has been read in in which case it is <i>true</i>. 214 * @return A <i>boolean</i> which is <i>true</i> if a command was parsed, <i>false</i> otherwise. 215 * @see org.greenstone.gatherer.cdm.CommandTokenizer 216 * @see org.greenstone.gatherer.cdm.DefaultSubIndex 217 * @see org.greenstone.gatherer.cdm.Subcollection 218 * @see org.greenstone.gatherer.cdm.SubIndex 219 */ 220 public boolean parse(String command, boolean finished) { 221 String temp = command.toLowerCase(); 222 CommandTokenizer tokenizer = new CommandTokenizer(command); 223 tokenizer.nextToken(); // Throw away head. 224 if(temp.startsWith("subcollection")) { 225 if(tokenizer.countTokens() >= 2) { 226 String name = tokenizer.nextToken(); 227 String pattern = tokenizer.nextToken(); 228 addSubcollection(new Subcollection(name, pattern)); 229 return true; 230 } 231 } 232 else if(temp.startsWith("indexsubcollections")) { 233 // These entries depend on what subcollections have previously been set, so we cannot safely parse them until after the file is complete. 234 if(!finished) { 235 unresolved.add(command); 236 } 237 else { 238 while(tokenizer.hasMoreTokens()) { 239 addSubIndex(new SubIndex(tokenizer.nextToken(), this)); 240 } 241 } 242 return true; 243 } 244 else if(temp.startsWith("defaultsubcollection")) { 245 // These entries depend on what subcollections have previously been set, so we cannot safely parse them until after the file is complete. 246 if(!finished) { 247 unresolved.add(command); 248 } 249 else { 250 if(tokenizer.hasMoreTokens()) { 251 setDefaultSubIndex(new DefaultSubIndex(tokenizer.nextToken(), this)); 252 } 253 } 254 return true; 255 } 256 return false; 257 } 258 /** Method to remove a certain subindex. 259 * @param subindex The <strong>SubIndex</strong> you wish to remove. 260 * @see org.greenstone.gatherer.Gatherer 261 * @see org.greenstone.gatherer.collection.CollectionManager 262 */ 263 public void removeSubIndex(SubIndex subindex) { 264 subindexes.removeElement(subindex); 265 gatherer.c_man.configurationChanged(); 266 } 267 /** Method to remove all of the subindexes that contain a certain subcollection. 268 * @param sub The <strong>Subcollection</strong> that you wish to remove. 269 * @see org.greenstone.gatherer.Gatherer 270 * @see org.greenstone.gatherer.cdm.SubIndex 271 * @see org.greenstone.gatherer.collection.CollectionManager 272 */ 273 public void removeSubIndexes(Subcollection sub) { 274 for(int i = subindexes.size() - 1; i >= 0; i--) { 275 SubIndex subindex = (SubIndex)subindexes.get(i); 276 if(subindex.containsSubcollection(sub.getName())) { 277 subindexes.removeElement(subindex); 278 } 279 } 280 gatherer.c_man.configurationChanged(); 281 } 101 102 /** Method to retrieve the controls for this manager. 103 * @return the Control used to edit the subcollection data 104 */ 105 public Control getControls() { 106 if(controls == null) { 107 controls = new SubcollectionControl(); 108 } 109 return controls; 110 } 111 112 /** Method to retrieve a certain subcollection by its name. 113 * @param name a String which is used as the key for finding the matching subcollection 114 * @return the requested Subcollection or null if no such subcollection exists. 115 */ 116 public Subcollection getSubcollection(String name) { 117 Subcollection result = null; 118 int size = getSize(); 119 for(int i = 0; i < size; i++) { 120 Subcollection subcollection = (Subcollection) getElementAt(i); 121 if(subcollection.getName().equals(name)) { 122 result = subcollection; 123 } 124 } 125 return result; 126 } 127 128 /** Method to get all of the subcollections defined. 129 * @return an ArrayList of subcollections 130 */ 131 public ArrayList getSubcollections() { 132 return children(); 133 } 134 282 135 /** Method to remove the given subcollection. 283 * @param sub The <strong>Subcollection</strong> you want to remove. 284 * @see org.greenstone.gatherer.Gatherer 285 * @see org.greenstone.gatherer.collection.CollectionManager 286 */ 287 public void removeSubcollection(Subcollection sub) { 288 removeElement(sub); 289 subcollections.remove(sub); 290 gatherer.c_man.configurationChanged(); 291 } 292 /** Method to retry the parsing of commands that were previously unable to be parsed as they referenced subcollections that may not have been instantiated. 293 */ 294 public void reparseUnresolved() { 295 for(int i = 0; i < unresolved.size(); i++) { 296 parse((String)unresolved.get(i), true); 297 } 298 unresolved.clear(); 299 } 300 /** Method to set the default subcollection index. 301 * @param subcollection The <strong>Subcollection</strong> to use as the default index. 302 * @see org.greenstone.gatherer.Gatherer 303 * @see org.greenstone.gatherer.collection.CollectionManager 304 */ 305 public void setDefaultSubIndex(DefaultSubIndex subindex) { 306 this.default_index = subindex; 307 if(subindex != null) { 308 addSubIndex(subindex.getSubIndex()); 309 } 310 gatherer.c_man.configurationChanged(); 311 } 312 /** This method causes the contents of this manager to be converted to a string, which is accomplished by calling <i>toString()</i> on each subcollection, then printing out the contents of the index vector. 313 * @return A <strong>String</strong> containing a block of configuration commands. 314 * @see org.greenstone.gatherer.cdm.SubIndex 315 * @see org.greenstone.gatherer.cdm.Subcollection 316 */ 317 public String toString() { 318 String text = ""; 319 // Retrieve the subcollection names and sort them. 320 if(subcollections.size() > 0) { 321 Vector names = new Vector(subcollections.keySet()); 322 Collections.sort(names); 323 for(int i = 0; i < names.size(); i++) { 324 Subcollection sub = 325 (Subcollection) subcollections.get(names.get(i)); 326 text = text + sub.toString(); 327 } 328 // Now add a entry, separated by spaces for each subcollection 329 // index. 330 if(subindexes.size() > 0) { 331 text = text + subindexes.toString(); 332 } 333 // Finally add the default subcollection index if necessary. 334 if(default_index != null) { 335 text = text + default_index.toString(); 336 } 337 text = text + "\n"; 338 } 339 // Otherwise if there were no subcollections, there aren't going to be 340 // subcollection indexes, nor a default subcollection index are there. 341 return text; 342 } 136 * @param subcollection the Subcollection you want to remove 137 * @see org.greenstone.gatherer.Gatherer 138 * @see org.greenstone.gatherer.collection.CollectionManager 139 */ 140 public void removeSubcollection(Subcollection subcollection) { 141 remove(subcollection); 142 Gatherer.c_man.configurationChanged(); 143 } 144 145 public void updateSubcollection(Subcollection subcollection, String name, boolean include, String source, String pattern, String flags) { 146 subcollection.setFlags(flags); 147 subcollection.setInclusive(include); 148 subcollection.setName(name); 149 subcollection.setPattern(pattern); 150 subcollection.setSource(source); 151 refresh(subcollection); 152 Gatherer.c_man.configurationChanged(); 153 } 154 343 155 /** Method to retrieve a phrase from the dictionary based on a key. 344 345 346 347 156 * @param key A <strong>String</strong> used to find the correct phrase. 157 * @param args A <strong>String[]</strong> of arguments used in formatting and filling out the phrase. 158 * @return A <strong>String</strong> containing the correct phrase with the correct formatting. 159 */ 348 160 private String get(String key) { 349 return get(key, null);350 }351 /** Method to retrieve a phrase from the dictionary based on a key.352 * @param key A <strong>String</strong> used to find the correct phrase.353 * @return A <strong>String</strong> containing the correct phrase with the correct formatting.354 * @see org.greenstone.gatherer.Dictionary355 * @see org.greenstone.gatherer.Gatherer356 */357 private String get(String key, String args[]) {358 161 if(key.indexOf(".") == -1) { 359 key = "CDM.SubcollectionManager." + key; 360 } 361 return gatherer.dictionary.get(key, args); 362 } 162 key = CLASS_DICTIONARY_NAME + key; 163 } 164 return Gatherer.dictionary.get(key); 165 } 166 363 167 /** This class creates a JPanel containing serveral more controls used for editing subcollection information. */ 364 private class Control 365 extends JPanel { 366 /** <i>true</i> if the current selection has changed. */ 367 private boolean changed = false; 368 /** Button to add a subcollection. */ 369 private JButton add = null; 370 /** Button to add a subindex. */ 371 private JButton add_index = null; 372 /** Button to clear the default subindex. */ 373 private JButton clear_default = null; 374 /** Button to remove a subcollection. */ 375 private JButton remove = null; 376 /** Button to remove a subindex. */ 377 private JButton remove_index = null; 378 /** Button to set the default subindex. */ 379 private JButton set_default = null; 380 /** Button to cause an update of the subcollections. */ 381 private JButton update = null; 382 /** A combobox allowing you to choose which field the data for matching should be taken from. Includes text body and filename, as well as all assigned metadata elements. */ 383 private JComboBox source = null; 384 /** The list of assigned subcollections. */ 385 private JList subcollection_list = null; 386 /** The list of subcollections available for the creation of subindexes. */ 387 private JList subcollection_list_2 = null; 388 /** The list of assigned subindexes. */ 389 private JList subindexes_list = null; 390 /** The label denoting the list of subindexes. */ 391 private JLabel subindexes_label = null; 392 /** The panel containing the subcollection controls. */ 393 private JPanel subcollection_pane = null; 394 /** The panel containing the subindex controls. */ 395 private JPanel subindex_pane = null; 396 /** The tabbed pane used to store the subcollection and subindex controls. */ 397 private JTabbedPane tabbed_pane = null; 398 /** The area used to display inline instructions. */ 399 private JTextArea instructions = null; 400 /** The field displaying the name of the default subindex. */ 401 private JTextField default_value = null; 402 /** A field used for specifying flags for the PERL expression matching, such as 'i' for case insensitive. */ 403 private JTextField flags = null; 404 /** The pattern the source text must match. */ 405 private JTextField match = null; 406 /** The name of this subcollection. */ 407 private JTextField name = null; 408 /** The name of this subindex. */ 409 private JTextField subindex_name; 410 /** When this button is selected the filter matching files are excluded. */ 411 private JToggleButton exclude = null; 412 /** When this button is selected the filter matching files are included. */ 413 private JToggleButton include = null; 414 /** The existing subcollection whose details you are reviewing, if any. */ 415 private Subcollection current = null; 416 /** Constructor, creates the outer parts of the view, then calls two methods in turn to create the subcollection controls and subindex controls. 417 */ 418 public Control() { 168 private class SubcollectionControl 169 extends JPanel 170 implements Control { 171 172 private JButton add_button; 173 private JButton remove_button; 174 private JButton update_button; 175 private JComboBox source_combobox; 176 private JList subcollection_list; 177 private JTabbedPane tabbed_pane; 178 private JTextArea instructions_area; 179 private JTextField flags_field; 180 private JTextField match_field; 181 private JTextField name_field; 182 private JToggleButton exclude_button; 183 private JToggleButton include_button; 184 185 /** Constructor */ 186 public SubcollectionControl() { 419 187 // Create 420 188 JPanel border_pane = new JPanel(); 421 189 JPanel header_pane = new JPanel(); 422 instructions = new JTextArea(get("Instructions"));423 instructions .setEditable(false);424 instructions .setLineWrap(true);425 instructions .setRows(5);426 instructions .setWrapStyleWord(true);190 instructions_area = new JTextArea(get("Instructions")); 191 instructions_area.setEditable(false); 192 instructions_area.setLineWrap(true); 193 instructions_area.setRows(5); 194 instructions_area.setWrapStyleWord(true); 427 195 tabbed_pane = new JTabbedPane(); 428 196 JLabel title = new JLabel(get("Title")); 429 197 title.setHorizontalAlignment(JLabel.CENTER); 430 createSubCollection(); 431 createSubIndex(); 198 199 JPanel button_pane_3 = new JPanel(); 200 add_button = new JButton(get("Add")); 201 add_button.setMnemonic(KeyEvent.VK_A); 202 add_button.setEnabled(false); 203 remove_button = new JButton(get("Remove")); 204 remove_button.setMnemonic(KeyEvent.VK_R); 205 remove_button.setEnabled(false); 206 update_button = new JButton(get("Update")); 207 update_button.setMnemonic(KeyEvent.VK_C); 208 update_button.setEnabled(false); 209 210 JPanel button_pane = new JPanel(); 211 JPanel button_pane_1 = new JPanel(); 212 exclude_button = new JToggleButton(get("Exclude")); 213 exclude_button.setMnemonic(KeyEvent.VK_X); 214 flags_field = new NonWhitespaceField(); 215 JLabel flags_label = new JLabel(get("Flags")); 216 include_button = new JToggleButton(get("Include")); 217 include_button.setMnemonic(KeyEvent.VK_I); 218 JLabel inclusive_label = new JLabel(get("Inclusive")); 219 JPanel inclusive_pane = new JPanel(); 220 match_field = new JTextField(); 221 JLabel match_label = new JLabel(get("Match")); 222 name_field = new NonWhitespaceField(); 223 JLabel name_label = new JLabel(get("Name")); 224 Vector source_model = Gatherer.c_man.getCollection().msm.getAssignedElements(); 225 source_model.add(0, StaticStrings.FILENAME_STR); 226 source_combobox = new JComboBox(source_model); 227 JLabel source_label = new JLabel(get("Source")); 228 subcollection_list = new JList(model); 229 subcollection_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 230 JPanel subcollection_pane = new JPanel(); 231 ButtonGroup bg = new ButtonGroup(); 232 bg.add(include_button); 233 bg.add(exclude_button); 234 include_button.setSelected(true); 235 JPanel subcollection_list_pane = new JPanel(); 236 JLabel subcollection_list_label = new JLabel(get("Assigned")); 237 432 238 // Add listeners 239 SubCollectionChangeListener cl = new SubCollectionChangeListener(); 240 add_button.addActionListener(new AddSubCollectionListener()); 241 remove_button.addActionListener(new RemoveSubCollectionListener()); 242 update_button.addActionListener(new UpdateSubCollectionListener()); 243 exclude_button.addActionListener(cl); 244 include_button.addActionListener(cl); 245 source_combobox.addActionListener(cl); 246 flags_field.getDocument().addDocumentListener(cl); 247 match_field.getDocument().addDocumentListener(cl); 248 name_field.getDocument().addDocumentListener(cl); 249 subcollection_list.addListSelectionListener(new SubCollectionListListener()); 250 433 251 // Layout 434 instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5)); 252 instructions_area.setBorder(BorderFactory.createEmptyBorder(2,5,2,5)); 253 435 254 header_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 436 255 header_pane.setLayout(new BorderLayout()); 437 256 header_pane.add(title, BorderLayout.NORTH); 438 header_pane.add(new JScrollPane(instructions), BorderLayout.CENTER); 439 tabbed_pane.addTab(get("Subcollection_Controls"), subcollection_pane); 440 tabbed_pane.addTab(get("Subindex_Controls"), subindex_pane); 441 tabbed_pane.addTab(get("Language_Controls"), manager.languages.getControls()); 442 border_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5)); 443 border_pane.setLayout(new BorderLayout()); 444 border_pane.add(tabbed_pane, BorderLayout.CENTER); 445 setLayout(new BorderLayout()); 446 add(header_pane, BorderLayout.NORTH); 447 add(border_pane, BorderLayout.CENTER); 448 } 449 /** Create the subcollection controls. 450 * @see org.greenstone.gatherer.Gatherer 451 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.AddListener 452 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.ListListener 453 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.RemoveListener 454 * @see org.greenstone.gatherer.collection.CollectionManager 455 * @see org.greenstone.gatherer.msm.MetadataSetManager 456 */ 457 public void createSubCollection() { 458 // Create 459 add = new JButton(get("Add")); 460 add.setMnemonic(KeyEvent.VK_A); 461 add.setEnabled(false); 462 JPanel button_pane = new JPanel(); 463 JPanel button_pane_1 = new JPanel(); 464 JPanel button_pane_3 = new JPanel(); 465 exclude = new JToggleButton(get("Exclude")); 466 exclude.setMnemonic(KeyEvent.VK_X); 467 flags = new JTextField(); 468 JLabel flags_label = new JLabel(get("Flags")); 469 include = new JToggleButton(get("Include")); 470 include.setMnemonic(KeyEvent.VK_I); 471 JLabel inclusive_label = new JLabel(get("Inclusive")); 472 JPanel inclusive_pane = new JPanel(); 473 match = new JTextField(); 474 JLabel match_label = new JLabel(get("Match")); 475 name = new JTextField(); 476 JLabel name_label = new JLabel(get("Name")); 477 remove = new JButton(get("Remove")); 478 remove.setMnemonic(KeyEvent.VK_R); 479 remove.setEnabled(false); 480 Vector source_model = gatherer.c_man.msm.getAssignedElements(); 481 source_model.add(0, "Filename"); 482 source = new JComboBox(source_model); 483 JLabel source_label = new JLabel(get("Source")); 484 subcollection_list = new JList(model); 485 subcollection_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 486 subcollection_pane = new JPanel(); 487 ButtonGroup bg = new ButtonGroup(); 488 bg.add(include); 489 bg.add(exclude); 490 include.setSelected(true); 491 JPanel subcollection_list_pane = new JPanel(); 492 JLabel subcollection_list_label = new JLabel(get("Assigned")); 493 494 // Add listeners 495 SubCollectionChangeListener cl = new SubCollectionChangeListener(); 496 add.addActionListener(new AddSubCollectionListener()); 497 remove.addActionListener(new RemoveSubCollectionListener()); 498 subcollection_list.addListSelectionListener(new SubCollectionListListener()); 499 //exclude.addActionListener(cl); 500 //include.addActionListener(cl); 501 //source.addActionListener(cl); 502 //flags.addDocumentListener(cl); 503 match.getDocument().addDocumentListener(cl); 504 name.getDocument().addDocumentListener(cl); 505 506 // Layout 257 header_pane.add(new JScrollPane(instructions_area), BorderLayout.CENTER); 258 507 259 inclusive_pane.setLayout(new GridLayout()); 508 inclusive_pane.add(include); 509 inclusive_pane.add(exclude); 260 inclusive_pane.add(include_button); 261 inclusive_pane.add(exclude_button); 262 510 263 button_pane_1.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 511 264 button_pane_1.setLayout(new GridLayout(5, 2)); 512 265 button_pane_1.add(name_label); 513 button_pane_1.add(name );266 button_pane_1.add(name_field); 514 267 button_pane_1.add(source_label); 515 button_pane_1.add(source );268 button_pane_1.add(source_combobox); 516 269 button_pane_1.add(match_label); 517 button_pane_1.add(match );270 button_pane_1.add(match_field); 518 271 button_pane_1.add(inclusive_label); 519 272 button_pane_1.add(inclusive_pane); 520 273 button_pane_1.add(flags_label); 521 button_pane_1.add(flags); 274 button_pane_1.add(flags_field); 275 522 276 button_pane_3.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); 523 button_pane_3.setLayout(new GridLayout(1,2)); 524 button_pane_3.add(add); 525 button_pane_3.add(remove); 277 button_pane_3.setLayout(new GridLayout(1,3)); 278 button_pane_3.add(add_button); 279 button_pane_3.add(update_button); 280 button_pane_3.add(remove_button); 281 526 282 button_pane.setLayout(new BorderLayout()); 527 283 button_pane.add(button_pane_1, BorderLayout.CENTER); 528 284 button_pane.add(button_pane_3, BorderLayout.SOUTH); 285 529 286 subcollection_list_pane.setLayout(new BorderLayout()); 530 287 subcollection_list_pane.add(subcollection_list_label, BorderLayout.NORTH); … … 534 291 subcollection_pane.add(subcollection_list_pane, BorderLayout.CENTER); 535 292 subcollection_pane.add(button_pane, BorderLayout.SOUTH); 536 } 537 /** Create the subindex controls. 538 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.AddSubIndexListener 539 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.ClearDefaultListener 540 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.ChangeListener 541 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.RemoveSubIndexListener 542 * @see org.greenstone.gatherer.cdm.SubcollectionManager.Control.SetDefaultListener 543 * @see org.greenstone.gatherer.util.ExclusiveListListener 544 */ 545 public void createSubIndex() { 546 // Creation 547 JPanel subindex_name_panel = new JPanel(); 548 JLabel subindex_name_label = new JLabel(get("PartitionName")); 549 subindex_name = new JTextField(); 550 551 add_index = new JButton(get("Add_Subindex")); 552 add_index.setMnemonic(KeyEvent.VK_A); 553 add_index.setEnabled(false); 554 JPanel button_pane_2 = new JPanel(); 555 clear_default = new JButton(get("Clear_Default_Subindex")); 556 clear_default.setMnemonic(KeyEvent.VK_C); 557 if(default_index == null) { 558 clear_default.setEnabled(false); 559 } 560 JLabel default_label = new JLabel(get("Default_Subindex")); 561 JPanel default_pane = new JPanel(); 562 if(default_index == null) { 563 default_value = new JTextField(); 564 } 565 else { 566 default_value = new JTextField(default_index.getSubIndex().toString()); 567 } 568 default_value.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false)); 569 default_value.setEditable(false); 570 JPanel subindex_inner_pane_1 = new JPanel(); 571 JPanel subindex_inner_pane_2 = new JPanel(); 572 remove_index = new JButton(get("Remove_Subindex")); 573 remove_index.setMnemonic(KeyEvent.VK_R); 574 set_default = new JButton(get("Set_Default_Subindex")); 575 set_default.setMnemonic(KeyEvent.VK_S); 576 JLabel subcollection_label = new JLabel(get("Subcollection")); 577 subcollection_list_2 = new JList(model); 578 JPanel list_2_pane = new JPanel(); 579 subindex_pane = new JPanel(); 580 JLabel subindexes_label = new JLabel(get("Subindexes")); 581 subindexes_list = new JList(subindexes); 582 subindexes_list.setCellRenderer(new SubIndexListCellRenderer()); 583 subindexes_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 584 JPanel subindexes_pane = new JPanel(); 585 586 // Add listeners 587 ExclusiveListSelectionListener ell = new ExclusiveListSelectionListener(); 588 ell.add(subcollection_list_2); 589 ell.add(subindexes_list); 590 add_index.addActionListener(new AddSubIndexListener()); 591 clear_default.addActionListener(new ClearDefaultSubIndexListener()); 592 remove_index.addActionListener(new RemoveSubIndexListener()); 593 set_default.addActionListener(new SetDefaultSubIndexListener()); 594 595 subindex_name.getDocument().addDocumentListener(new SubIndexNameDocumentListener()); 596 subcollection_list_2.addListSelectionListener(new SubCollectionList2Listener()); 597 598 // Layout 599 subindex_name_panel.setLayout(new BorderLayout()); 600 subindex_name_panel.add(subindex_name_label, BorderLayout.WEST); 601 subindex_name_panel.add(subindex_name, BorderLayout.CENTER); 602 603 list_2_pane.setLayout(new BorderLayout()); 604 list_2_pane.add(subcollection_label, BorderLayout.NORTH); 605 list_2_pane.add(new JScrollPane(subcollection_list_2), BorderLayout.CENTER); 606 607 subindexes_pane.setLayout(new BorderLayout()); 608 subindexes_pane.add(subindexes_label, BorderLayout.NORTH); 609 subindexes_pane.add(new JScrollPane(subindexes_list), BorderLayout.CENTER); 610 611 subindex_inner_pane_2.setLayout(new GridLayout(1,2,0,5)); 612 subindex_inner_pane_2.add(list_2_pane); 613 subindex_inner_pane_2.add(subindexes_pane); 614 615 default_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5)); 616 default_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createRaisedBevelBorder()), BorderFactory.createEmptyBorder(2,2,2,2))); 617 default_pane.setLayout(new BorderLayout()); 618 default_pane.add(default_label, BorderLayout.WEST); 619 default_pane.add(default_value, BorderLayout.CENTER); 620 621 subindex_inner_pane_1.setLayout(new BorderLayout()); 622 subindex_inner_pane_1.add(subindex_name_panel, BorderLayout.NORTH); 623 subindex_inner_pane_1.add(subindex_inner_pane_2, BorderLayout.CENTER); 624 subindex_inner_pane_1.add(default_pane, BorderLayout.SOUTH); 625 626 button_pane_2.setLayout(new GridLayout(2,2)); 627 button_pane_2.add(add_index); 628 button_pane_2.add(remove_index); 629 button_pane_2.add(clear_default); 630 button_pane_2.add(set_default); 631 632 subindex_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 633 subindex_pane.setLayout(new BorderLayout()); 634 subindex_pane.add(subindex_inner_pane_1, BorderLayout.CENTER); 635 subindex_pane.add(button_pane_2, BorderLayout.SOUTH); 636 } 637 638 293 294 tabbed_pane.addTab(get("Subcollection_Controls"), subcollection_pane); 295 tabbed_pane.addTab(get("Subindex_Controls"), (JPanel) CollectionDesignManager.subcollectionindex_manager.getControls()); 296 tabbed_pane.addTab(get("Language_Controls"), (JPanel) CollectionDesignManager.language_manager.getControls()); 297 298 border_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5)); 299 border_pane.setLayout(new BorderLayout()); 300 border_pane.add(tabbed_pane, BorderLayout.CENTER); 301 302 setLayout(new BorderLayout()); 303 add(header_pane, BorderLayout.NORTH); 304 add(border_pane, BorderLayout.CENTER); 305 } 306 639 307 /** Method to unregister any listeners to avoid memory leaks. 640 308 */ 641 309 public void destroy() { 642 310 } 643 /** We have overriden this method to provide completely different functionality, given that our JPanel will never actually have focus. We call this method in GUI on the view we are about to replace, and this method checks if a change has occured and if so updates the current object. 644 * @return A <i>boolean</i> which is always <i>false</i>. 645 * @see org.greenstone.gatherer.msm.ElementWrapper 646 */ 647 public boolean hasFocus() { 648 // If we have a current metadata open, and something has changed then save the change. 649 if(changed && current != null) { 650 String n = name.getText(); 651 String s = null; 652 Object o = source.getSelectedItem(); 653 if(o instanceof ElementWrapper) { 654 ElementWrapper e = (ElementWrapper)o; 655 s = e.toString(); 656 } 657 String e = match.getText(); 658 String f = flags.getText(); 659 if(n != null && n.length() > 0 && (s == null || s.length() > 0) && e != null && e.length() > 0) { 660 current.update(n, s, e, include.isSelected(), f); 661 int index = model.indexOf(current); 662 changed(); 663 subindexes.changed(); 664 if(default_index != null) { 665 default_value.setText(default_index.getSubIndex().toString()); 666 } 667 } 668 changed = false; 669 } 670 return false; 671 } 672 /** Overriden to ensure the instructions are scrolled to top. 673 */ 674 public void updateUI() { 675 if(instructions != null) { 676 instructions.setCaretPosition(0); 677 } 678 super.updateUI(); 679 } 680 681 /** Method to validate the current subcollection editor values, and enable or disable controls (add button) based on said values. 682 * we want to disable add until a new name is present 683 */ 684 protected void validateAdd() { 685 if(changed && name.getText().length() > 0 && match.getText().length() > 0) { 686 if (subcollections.containsKey(name.getText())) { 687 add.setEnabled(false); 688 } else { 689 add.setEnabled(true); 690 } 691 } 692 else { 693 add.setEnabled(false); 694 } 695 } 311 312 public void gainFocus() { 313 // Rebuild the sources combobox 314 Vector source_model = Gatherer.c_man.getCollection().msm.getAssignedElements(); 315 source_model.add(0, "Filename"); // Add filename as a possible source. 316 source_combobox.setModel(new DefaultComboBoxModel(source_model)); 317 } 318 319 public void loseFocus() { 320 } 321 696 322 /** Listens for actions apon the 'add' button in the SubcollectionManager controls, and if detected calls the addSubcollection method of the manager with a newly created subcollection. */ 697 323 private class AddSubCollectionListener … … 703 329 */ 704 330 public void actionPerformed(ActionEvent event) { 705 String n = name.getText(); // not allowed spaces! 706 if (n.indexOf(' ')!=-1) { 707 n = n.substring(0, n.indexOf(' ')); 708 name.setText(n); 709 } 710 String s = null; 711 Object o = source.getSelectedItem(); 712 if(o instanceof ElementWrapper) { 713 ElementWrapper e = (ElementWrapper)o; 714 s = e.toString(); 715 } 716 String e = match.getText(); 717 String f = flags.getText(); 718 if(n != null && n.length() > 0 && (s == null || s.length() > 0) && e != null && e.length() > 0) { 719 Subcollection sub = new Subcollection(n, include.isSelected(), s, e, f); 720 addSubcollection(sub); 721 } 722 changed = false; 723 validateAdd(); 724 } 725 } 726 /** Listens for actions apon the 'add subindex' button in the SubcollectionManager controls, and if detected calls the addSubindex method of the manager with a newly created subindex. */ 727 private class AddSubIndexListener 728 implements ActionListener { 729 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to check if they have a series of subcollections selected, and if so build an new subindex based apon them. 730 * @param event An <strong>ActionEvent</strong> containing information about the event. 731 * @see org.greenstone.gatherer.cdm.SubIndex 732 */ 733 public void actionPerformed(ActionEvent event) { 734 if(!subcollection_list_2.isSelectionEmpty() && subindex_name.getText().length() > 0) { 735 Vector selected = new Vector(); 736 Object raw[] = subcollection_list_2.getSelectedValues(); 737 for(int i = 0; i < raw.length; i++) { 738 selected.add(raw[i]); 331 String name = name_field.getText(); 332 String source = null; 333 Object object = source_combobox.getSelectedItem(); 334 if(object instanceof ElementWrapper) { 335 ElementWrapper element_wrapper = (ElementWrapper)object; 336 source = element_wrapper.getName(); 337 if(source.indexOf(MSMUtils.NS_SEP) == -1) { 338 source = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + source; 739 339 } 740 SubIndex subindex = new SubIndex(selected); 741 addSubIndex(subindex); 742 // Add the subindexes name. 743 CollectionMeta metadata = new CollectionMeta(manager, subindex, manager.languages.getDefaultLanguage(), subindex_name.getText()); 744 manager.collectionmetadatum.addMetadata(metadata); 745 } 746 } 747 } 748 /** This class listens for any key entry in a text field, selection change in a combobox or button click, and when detected sets the changed flag to true. Its also convenient to use this class to test if the add button should be active yet. */ 340 } 341 else { 342 source = object.toString(); 343 } 344 String pattern = match_field.getText(); 345 String flags = flags_field.getText(); 346 if(name.length() > 0 && (source == null || source.length() > 0) && pattern.length() > 0) { 347 Subcollection subcollection = new Subcollection(name, include_button.isSelected(), source, pattern, flags); 348 addSubcollection(subcollection); 349 // Change the selection to the new subcollection 350 subcollection_list.setSelectedValue(subcollection, true); 351 } 352 add_button.setEnabled(false); 353 } 354 } 355 356 /** This class listens for any key entry in a text field, selection change in a combobox or button click, and updates a subcollection as appropriate. Its also convenient to use this class to test if the add button should be active yet. */ 749 357 private class SubCollectionChangeListener 750 358 implements DocumentListener, ActionListener { … … 753 361 */ 754 362 public void actionPerformed(ActionEvent event) { 755 changed = true;756 363 validateAdd(); 757 364 } 758 365 759 366 public void changedUpdate(DocumentEvent event) { 760 changed = true;761 367 validateAdd(); 762 368 } 369 763 370 public void insertUpdate(DocumentEvent event) { 764 changed = true;765 371 validateAdd(); 766 372 … … 768 374 769 375 public void removeUpdate(DocumentEvent event) { 770 changed = true;771 376 validateAdd(); 772 377 } 773 } 774 /** Listens for actions apon the 'clear default subindex' button in the SubcollectionManager controls, and if detected calls the setDefaultSubIndex() method of the manager with <i>null</i>. */ 775 private class ClearDefaultSubIndexListener 776 implements ActionListener { 777 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to clear the default subindex. 778 * @param event An <strong>ActionEvent</strong> containing information about the event. 779 */ 780 public void actionPerformed(ActionEvent event) { 781 setDefaultSubIndex(null); 782 clear_default.setEnabled(false); 783 default_value.setText(""); 784 } 785 } 378 379 /** Method to validate the current subcollection editor values, and enable or disable controls (add button) based on said values. */ 380 private void validateAdd() { 381 if(name_field.getText().length() > 0 && match_field.getText().length() > 0) { 382 if (getSubcollection(name_field.getText()) == null) { 383 add_button.setEnabled(true); 384 } else { 385 add_button.setEnabled(false); 386 } 387 } 388 else { 389 add_button.setEnabled(false); 390 } 391 } 392 } 393 786 394 /** Listens for actions apon the 'remove' button in the SubcollectionManager controls, and if detected calls the remove method of the manager with the SubIndex selected for removal. */ 787 395 private class RemoveSubCollectionListener … … 793 401 public void actionPerformed(ActionEvent event) { 794 402 if(!subcollection_list.isSelectionEmpty()) { 795 Subcollection sub_col = (Subcollection)subcollection_list.getSelectedValue(); 796 removeSubIndexes(sub_col); 797 removeSubcollection(sub_col); 798 } 799 } 800 } 801 /** Listens for actions apon the 'remove subindex' button in the SubcollectionManager controls, and if detected calls the removeSubIndex method of the manager with the SubIndex selected for removal. */ 802 private class RemoveSubIndexListener 403 Subcollection subcollection = (Subcollection)subcollection_list.getSelectedValue(); 404 removeSubcollection(subcollection); 405 // And remove subcollection indexes dependant on this subcollection 406 CollectionDesignManager.subcollectionindex_manager.removeSubcollectionIndexes(subcollection); 407 } 408 remove_button.setEnabled(false); 409 } 410 } 411 412 private class UpdateSubCollectionListener 803 413 implements ActionListener { 804 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to check if they have a subindex selected, and if so remove it.805 * @param event An <strong>ActionEvent</strong> containing information about the event.806 * @see org.greenstone.gatherer.cdm.SubIndex807 */808 414 public void actionPerformed(ActionEvent event) { 809 if(!subindexes_list.isSelectionEmpty()) { 810 removeSubIndex((SubIndex)subindexes_list.getSelectedValue()); 811 } 812 } 813 } 814 /** Listens for actions apon the 'set default subindex' button in the SubcollectionManager controls, and if detected calls the setDefaultSubIndex method of the manager with the SubIndex selected for default. */ 815 private class SetDefaultSubIndexListener 816 implements ActionListener { 817 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to check if they have a subindex selected, and if so set it as default. 818 * @param event An <strong>ActionEvent</strong> containing information about the event. 819 * @see org.greenstone.gatherer.cdm.DefaultSubIndex 820 * @see org.greenstone.gatherer.cdm.SubIndex 821 */ 822 public void actionPerformed(ActionEvent event) { 823 if(!subindexes_list.isSelectionEmpty()) { 824 setDefaultSubIndex(new DefaultSubIndex((SubIndex)subindexes_list.getSelectedValue())); 825 clear_default.setEnabled(true); 826 default_value.setText(default_index.getSubIndex().toString()); 827 } 828 } 829 } 830 415 if(!subcollection_list.isSelectionEmpty()) { 416 Subcollection subcollection = (Subcollection)subcollection_list.getSelectedValue(); 417 String name = name_field.getText(); 418 String source = null; 419 Object object = source_combobox.getSelectedItem(); 420 if(object instanceof ElementWrapper) { 421 ElementWrapper element_wrapper = (ElementWrapper)object; 422 source = element_wrapper.getName(); 423 if(source.indexOf(MSMUtils.NS_SEP) == -1) { 424 source = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + source; 425 } 426 } 427 else { 428 source = object.toString(); 429 } 430 String pattern = match_field.getText(); 431 String flags = flags_field.getText(); 432 if(name.length() > 0 && (source == null || source.length() > 0) && pattern.length() > 0) { 433 updateSubcollection(subcollection, name, include_button.isSelected(), source, pattern, flags); 434 } 435 } 436 } 437 } 831 438 832 439 /** This class listens for selections in the list on the subcollections pane of the SubcollectionManager, and updates the controls as necessary to reflect selection. */ … … 839 446 */ 840 447 public void valueChanged(ListSelectionEvent event) { 841 // If we have a previous collection and the users changed something, but not added, then update subcollection. 842 if(changed && current != null) { 843 String n = name.getText(); 844 String s = null; 845 Object o = source.getSelectedItem(); 846 if(o instanceof ElementWrapper) { 847 ElementWrapper e = (ElementWrapper)o; 848 s = e.toString(); 849 } 850 String e = match.getText(); 851 String f = flags.getText(); 852 if(n != null && n.length() > 0 && (s == null || s.length() > 0) && e != null && e.length() > 0) { 853 current.update(n, s, e, include.isSelected(), f); 854 int index = model.indexOf(current); 855 changed(); 856 subindexes.changed(); 857 if(default_index != null) { 858 default_value.setText(default_index.getSubIndex().toString()); 859 } 860 } 861 } 862 // Now load the new entry. 448 // Now the entry 863 449 if(!subcollection_list.isSelectionEmpty()) { 864 current= (Subcollection) subcollection_list.getSelectedValue();865 flags .setText(current.getFlags());866 include .setSelected(current.getInclude());867 exclude .setSelected(!current.getInclude());868 match .setText(current.getExpression());869 name .setText(current.getName());870 String s = current.getSource();450 Subcollection subcollection = (Subcollection) subcollection_list.getSelectedValue(); 451 flags_field.setText(subcollection.getFlags()); 452 include_button.setSelected(subcollection.isInclusive()); 453 exclude_button.setSelected(!subcollection.isInclusive()); 454 match_field.setText(subcollection.getPattern()); 455 name_field.setText(subcollection.getName()); 456 String s = subcollection.getSource(); 871 457 int pos = 0; 872 Object value = source.getItemAt(pos); 458 Object value = source_combobox.getItemAt(pos); 459 //ystem.err.println("Search for: " + s); 873 460 while(value != null) { 874 461 if(value instanceof ElementWrapper) { 875 462 ElementWrapper e = (ElementWrapper) value; 876 if(e.toString().equals(s)) { 877 source.setSelectedIndex(pos); 463 String e_name = e.getName(); 464 if(e_name.indexOf(MSMUtils.NS_SEP) == -1) { 465 e_name = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + e_name; 466 } 467 //ystem.err.print("Compare to: " + e_name); 468 if(e_name.equals(s)) { 469 source_combobox.setSelectedIndex(pos); 878 470 value = null; 471 //ystem.err.println(" - Match"); 879 472 } 880 473 else { 881 474 pos++; 882 value = source.getItemAt(pos); 475 value = source_combobox.getItemAt(pos); 476 //ystem.err.println(" - Fail"); 883 477 } 884 478 } 885 479 else if(value.toString().equals(s)) { 886 source .setSelectedIndex(pos);480 source_combobox.setSelectedIndex(pos); 887 481 value = null; 888 482 } 889 483 else { 890 484 pos++; 891 value = source .getItemAt(pos);485 value = source_combobox.getItemAt(pos); 892 486 } 893 487 } 894 488 // Can't add one thats already there. 895 add.setEnabled(false); 896 // You can remove it though... 897 remove.setEnabled(true); 489 add_button.setEnabled(false); 490 // You can update or remove it though... 491 remove_button.setEnabled(true); 492 update_button.setEnabled(true); 898 493 } 899 494 else { 900 flags.setText(""); 901 include.setSelected(true); 902 match.setText(""); 903 name.setText(""); 904 source.setSelectedIndex(0); 905 remove.setEnabled(false); 906 } 907 // Have to do this after so we don't get called when nothings actually changed. 908 changed = false; 909 910 } 911 } 912 913 private class SubCollectionList2Listener 914 implements ListSelectionListener { 915 916 public void valueChanged(ListSelectionEvent event) { 917 if(!event.getValueIsAdjusting()) { 918 add_index.setEnabled(!subcollection_list_2.isSelectionEmpty() && subindex_name.getText().length() > 0); 919 } 920 } 921 } 922 923 private class SubIndexListCellRenderer 924 extends DefaultListCellRenderer { 925 926 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 927 StringBuffer text = new StringBuffer(value.toString()); 928 // Retrieve the indexes name if any. 929 CollectionMeta metadata = manager.collectionmetadatum.getMetadata(value, manager.languages.getDefaultLanguage(), true); 930 if(metadata != null) { 931 text.append(" \""); 932 text.append(metadata.getValue()); 933 text.append("\""); 934 } 935 return super.getListCellRendererComponent(list, text.toString(), index, isSelected, cellHasFocus); 936 } 937 938 } 939 940 private class SubIndexNameDocumentListener 941 implements DocumentListener { 942 /** Gives notification that an attribute or set of attributes changed. */ 943 public void changedUpdate(DocumentEvent e) { 944 update(); 945 } 946 /** Gives notification that there was an insert into the document. */ 947 public void insertUpdate(DocumentEvent e) { 948 update(); 949 } 950 /** Gives notification that a portion of the document has been removed. */ 951 public void removeUpdate(DocumentEvent e) { 952 update(); 953 } 954 /** The text area has changed in some way. Given that this can only happed when we are editing or adding a text fragment we better respond appropriately. */ 955 private void update() { 956 add_index.setEnabled(!subcollection_list_2.isSelectionEmpty() && subindex_name.getText().length() > 0); 957 } 958 } 959 495 flags_field.setText(""); 496 include_button.setSelected(true); 497 match_field.setText(""); 498 name_field.setText(""); 499 source_combobox.setSelectedIndex(0); 500 remove_button.setEnabled(false); 501 update_button.setEnabled(false); 502 } 503 } 504 } 960 505 } 961 506 } -
trunk/gli/src/org/greenstone/gatherer/cdm/SuperCollectionManager.java
r4675 r4932 28 28 29 29 import java.awt.*; 30 import java.awt.event.*;31 30 import java.io.*; 32 31 import java.util.*; 33 32 import javax.swing.*; 33 import javax.swing.event.*; 34 34 import org.greenstone.gatherer.Configuration; 35 35 import org.greenstone.gatherer.Dictionary; 36 36 import org.greenstone.gatherer.Gatherer; 37 import org.greenstone.gatherer.cdm.DOMProxyListModel; 37 38 import org.greenstone.gatherer.checklist.CheckList; 38 39 import org.greenstone.gatherer.checklist.Entry; 39 40 import org.greenstone.gatherer.collection.CollectionConfiguration; 41 import org.greenstone.gatherer.util.StaticStrings; 40 42 import org.greenstone.gatherer.util.Utility; 41 42 public class SuperCollectionManager { 43 import org.w3c.dom.*; 44 /** This class contains the information about what supercollection has been specified (if any) and methods for changing this information. Note that there is a major difference between this manager and the others in that its DOM model is never used directly in any list component. It is only used to decide whether a certain entry in the actual checklist is checked. */ 45 public class SuperCollectionManager 46 extends DOMProxyListModel { 43 47 44 48 static final public String SUPERCOLLECTION_COMMAND = "supercollection"; … … 46 50 47 51 private String current_coll_name = null; 48 private Control controls; 49 private ArrayList collection_checklist_model; 50 51 SuperCollectionManager() { 52 // We start by building a model of the installed collections. 53 collection_checklist_model = new ArrayList(); 54 File gsdl_collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path)); 55 current_coll_name = Gatherer.c_man.getCollection().getName(); 56 File[] possible_collections = gsdl_collection_directory.listFiles(); 57 for(int i = 0; possible_collections != null && i < possible_collections.length; i++) { 58 // The simpliest case is if the directory etc/collect.cfg file and a metadata/ in it. Thus it can easily be built upon. 59 File collect_cfg_file = new File(possible_collections[i], Utility.CONFIG_DIR); 60 if(collect_cfg_file.exists()) { 61 CollectionConfiguration collect_cfg = new CollectionConfiguration(collect_cfg_file); 62 String collection_title = collect_cfg.getName(); 63 String collection_name = possible_collections[i].getName(); 64 // We do have to block the model collection. 65 if(!collection_title.equals("**title**")) { 66 Entry entry = new Entry(collection_title); 67 entry.setProperty(collection_name); 68 if (collection_name.equals(current_coll_name)) { 69 // the current collection is always selected 70 entry.setFixed(true); 71 entry.setSelected(true); 72 } 73 collection_checklist_model.add(entry); 74 entry = null; 75 76 } 77 collection_name = null; 78 collection_title = null; 79 collect_cfg = null; 52 private Control controls = null; 53 private ArrayList collection_checklist_model = null; // Model used to actually populate list 54 55 public SuperCollectionManager(Element supercollections_element) { 56 super(supercollections_element, StaticStrings.COLLECTION_ELEMENT, new SuperCollection()); 57 Gatherer.println("SuperCollectionManager: " + getSize() + " supercollection members parsed."); 58 } 59 60 public void destroy() { 61 if(controls != null) { 62 controls.destroy(); 63 controls = null; 64 } 65 if(collection_checklist_model != null) { 66 collection_checklist_model.clear(); 67 collection_checklist_model = null; 68 } 69 } 70 71 public void addSuperCollection(SuperCollection supercollection) { 72 if(!contains(supercollection)) { 73 add(getSize(), supercollection); 74 } 75 } 76 77 /** Method to retrieve the control for this manager. 78 * @return the Control for editing supercollection settings 79 */ 80 public Control getControls() { 81 if(controls == null) { 82 // Build controls 83 this.controls = new SuperCollectionControl(); 84 } 85 return controls; 86 } 87 88 public SuperCollection getSuperCollection(String collection_name) { 89 SuperCollection result = null; 90 int size = getSize(); 91 for(int i = 0; result == null && i < size; i++) { 92 SuperCollection supercollection = (SuperCollection) getElementAt(i); 93 if(supercollection.getName().equals(collection_name)) { 94 result = supercollection; 80 95 } 81 collect_cfg_file = null; 82 } 83 possible_collections = null; 84 gsdl_collection_directory = null; 85 // Sort the result. 86 Collections.sort(collection_checklist_model); 87 } 88 89 public boolean parse(String command) { 90 String command_lc = command.toLowerCase(); 91 if(command_lc.startsWith(SUPERCOLLECTION_COMMAND) || command_lc.startsWith(CCS_COMMAND)) { 92 StringTokenizer tokenizer = new StringTokenizer(command); 93 tokenizer.nextToken(); 94 // Read in each of the collection names. 95 ArrayList collection_names = new ArrayList(); 96 while(tokenizer.hasMoreTokens()) { 97 collection_names.add(tokenizer.nextToken()); 98 } 99 // Now that we have the collection names, select any entries in the checklist that match. 100 for(int i = 0; i < collection_checklist_model.size(); i++) { 101 Entry entry = (Entry) collection_checklist_model.get(i); 102 String collection_name = entry.getProperty(); 103 if(collection_names.contains(collection_name)) { 104 entry.setSelected(true); 105 collection_names.remove(collection_name); // Makes successive runs faster. 106 } 107 collection_name = null; 108 entry = null; 109 } 110 // Done. 111 return true; 112 } 113 return false; 114 } 115 116 /** Method to retrieve the control for this manager. 117 * @return A JPanel containing the controls. 118 */ 119 public JPanel getControls() { 120 if(controls == null) { 121 controls = new Control(); 122 } 123 return controls; 124 } 125 126 public void invalidateControls() { 127 controls = null; 128 } 129 130 /** Return the contents of this manager as a command or block of commands ready to be written to the collection configuration file. 131 * @return A String containing a configuration command or block of commands, terminated with a new line. This value will be null if there was no supercollection command set. */ 132 public String toString() { 133 StringBuffer command = new StringBuffer(SUPERCOLLECTION_COMMAND); 134 // Now for each entry selected output its collection name (property setting) 135 boolean found_entry = false; 136 for(int i = 0; i < collection_checklist_model.size(); i++) { 137 Entry entry = (Entry) collection_checklist_model.get(i); 138 if(entry.isSelected()) { 139 if (!entry.getProperty().equals(current_coll_name)){ 140 found_entry = true; 141 } 142 command.append(" "); 143 command.append(entry.getProperty()); 144 } 145 entry = null; 146 } 147 command.append("\n"); 148 command.append("\n"); 149 150 // It is possible that there was only one entry - the current collection - in which case we return null. 151 if(found_entry) { 152 return command.toString(); 153 } 154 else { 155 return null; 156 } 96 supercollection = null; 97 } 98 return result; 99 } 100 101 public void removeSuperCollection(SuperCollection supercollection) { 102 remove(supercollection); 157 103 } 158 104 … … 169 115 170 116 /** Provides controls for altering the SuperCollection settings. */ 171 private class Control 172 extends JPanel { 117 private class SuperCollectionControl 118 extends JPanel 119 implements Control { 173 120 174 121 private boolean init = true; 122 private CheckList collection_checklist = null; 175 123 //private JSplitPane center_pane; 176 124 177 Control() {125 SuperCollectionControl() { 178 126 super(); 127 128 buildModel(); 179 129 // Creation 180 130 JPanel header_panel = new JPanel(); … … 194 144 instructions.setWrapStyleWord(true); 195 145 196 CheckList collection_checklist = new CheckList(collection_checklist_model); 146 collection_checklist = new CheckList(collection_checklist_model); 147 197 148 // Layout 198 149 //center_pane.setTopComponent(new JScrollPane(instructions)); … … 209 160 } 210 161 211 public void paint(Graphics g) { 212 super.paint(g); 213 // If this is the first time we've painted this control, then set the divider 1/3:2/3 214 //if(init) { 215 // init = false; 216 // center_pane.setDividerLocation(0.3); 217 // super.paint(g); 218 //} 162 public void destroy() { 163 } 164 165 public void gainFocus() { 166 } 167 168 public void loseFocus() { 169 // Retrieve the current supercollections 170 ArrayList supercollections = children(); 171 // Now iterate through the checklist, and for each checked box found ensure the Supercollection exists, and ensure its assigned. Remove any supercollections altered in this way from the temporary array list 172 int size = collection_checklist_model.size(); 173 for(int i = 0; i < size; i++) { 174 Entry entry = (Entry) collection_checklist_model.get(i); 175 if(entry.isSelected()) { 176 String collection_name = (String) entry.getProperty(); 177 SuperCollection supercollection = getSuperCollection(collection_name); 178 // Create the supercollection element if necessary 179 if(supercollection == null) { 180 Element supercollection_element = root.getOwnerDocument().createElement(StaticStrings.COLLECTION_ELEMENT); 181 supercollection = new SuperCollection(supercollection_element); 182 supercollection.setName(collection_name); 183 addSuperCollection(supercollection); 184 } 185 else { 186 supercollections.remove(supercollection); 187 } 188 supercollection.setAssigned(true); 189 } 190 } 191 // Any collections left in the temporary list have been unselected, so delete them 192 for(int j = supercollections.size(); j > 0; j--) { 193 SuperCollection supercollection = (SuperCollection) supercollections.get(j - 1); 194 removeSuperCollection(supercollection); 195 } 196 } 197 198 private void buildModel() { 199 // We start by building a model of the installed collections. 200 collection_checklist_model = new ArrayList(); 201 File gsdl_collection_directory = new File(Utility.getCollectionDir(Gatherer.config.gsdl_path)); 202 current_coll_name = Gatherer.c_man.getCollection().getName(); 203 File[] possible_collections = gsdl_collection_directory.listFiles(); 204 for(int i = 0; possible_collections != null && i < possible_collections.length; i++) { 205 // The simpliest case is if the directory etc/collect.cfg file and a metadata/ in it. Thus it can easily be built upon. 206 File collect_cfg_file = new File(possible_collections[i], Utility.CONFIG_DIR); 207 if(collect_cfg_file.exists()) { 208 CollectionConfiguration collect_cfg = new CollectionConfiguration(collect_cfg_file); 209 String collection_title = collect_cfg.getName(); 210 String collection_name = possible_collections[i].getName(); 211 // We do have to block the model collection. 212 if(!collection_title.equals("**title**")) { 213 Entry entry = new Entry(collection_title); 214 entry.setProperty(collection_name); 215 // Check if a collection with this name exists. The current collection is always selected. 216 entry.setSelected(getSuperCollection(collection_name) != null || collection_name.equals(current_coll_name)); 217 entry.setFixed(collection_name.equals(current_coll_name)); 218 collection_checklist_model.add(entry); 219 entry = null; 220 221 } 222 collection_name = null; 223 collection_title = null; 224 collect_cfg = null; 225 } 226 collect_cfg_file = null; 227 } 228 possible_collections = null; 229 gsdl_collection_directory = null; 230 // Sort the result. 231 Collections.sort(collection_checklist_model); 219 232 } 220 233 } -
trunk/gli/src/org/greenstone/gatherer/cdm/custom/CustomAZList.java
r4656 r4932 45 45 import org.greenstone.gatherer.cdm.ClassifierManager; 46 46 import org.greenstone.gatherer.cdm.CustomClassifier; 47 import org.greenstone.gatherer.cdm.Language;48 47 import org.greenstone.gatherer.file.FileNode; 49 48 import org.greenstone.gatherer.msm.ElementWrapper; … … 629 628 } 630 629 else { 631 String language_code = Gatherer.config.interface_language .getCode();630 String language_code = Gatherer.config.interface_language; 632 631 hidden_mde = hidden_mds.addElement(element.toString().replace('.','_'), language_code); 633 632 found = false; -
trunk/gli/src/org/greenstone/gatherer/checklist/CheckList.java
r4572 r4932 219 219 private class CheckListListener 220 220 extends MouseAdapter { 221 221 222 //private Entry previous_checkbox = null; 222 223 /** Called whenever the mouse is clicked over our list. We find the nearest checkbox and change its state. … … 227 228 int index = list.locationToIndex(e.getPoint()); 228 229 Entry checkbox = (Entry)list.getModel().getElementAt(index); 229 // If this is the same checkbox as was recently selected, change the tick. 230 if (list.isSelectedIndex(index)) { 231 if(!checkbox.isFixed()) { 232 checkbox.setSelected(!checkbox.isSelected()); 233 } 234 checkbox.grabFocus(); 235 } 236 /* 237 if(list.isSelectedIndex(index) && checkbox == previous_checkbox) { 238 if(!checkbox.isFixed()) { 239 checkbox.setSelected(!checkbox.isSelected()); 240 } 241 checkbox.grabFocus(); 242 } 243 // Otherwise the selection has just changed, so select the new checkbox 244 else if(list.isSelectedIndex(index)) { 245 previous_checkbox = checkbox; 246 } 247 else { 248 previous_checkbox = null; 249 } 250 */ 230 if(!checkbox.isFixed()) { 231 checkbox.setSelected(!checkbox.isSelected()); 232 } 233 checkbox.grabFocus(); 251 234 } 252 235 }
Note:
See TracChangeset
for help on using the changeset viewer.