- Timestamp:
- 2003-07-15T13:55:22+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/cdm/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
Note:
See TracChangeset
for help on using the changeset viewer.