source: trunk/gli/src/org/greenstone/gatherer/cdm/ClassifierManager.java@ 11344

Last change on this file since 11344 was 11130, checked in by mdewsnip, 18 years ago

Removed some dead code.

  • Property svn:keywords set to Author Date Id Revision
File size: 32.2 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.io.*;
32import java.net.*;
33import java.util.*;
34import java.util.jar.*;
35import javax.swing.*;
36import javax.swing.event.*;
37import org.apache.xerces.parsers.*;
38import org.greenstone.gatherer.Configuration;
39import org.greenstone.gatherer.DebugStream;
40import org.greenstone.gatherer.Dictionary;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.LocalGreenstone;
43import org.greenstone.gatherer.gui.DesignPaneHeader;
44import org.greenstone.gatherer.gui.GComboBox;
45import org.greenstone.gatherer.gui.GLIButton;
46import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
47import org.greenstone.gatherer.util.JarTools;
48import org.greenstone.gatherer.util.StaticStrings;
49import org.greenstone.gatherer.util.Utility;
50import org.greenstone.gatherer.util.XMLTools;
51import org.w3c.dom.*;
52import org.xml.sax.*;
53
54/** This class is responsible for keeping track of all the classifiers assigned to this collection, and providing methods for adding and removing them.
55 * @author John Thompson, Greenstone Digital Library, University of Waikato
56 * @version 2.3
57 */
58public class ClassifierManager
59 extends DOMProxyListModel {
60
61 /** A list of known, but currently unassigned, classifiers. */
62 private ArrayList library = null;
63 /** The controls for editing the contents of this manager. */
64 private Control controls = null;
65
66 private DOMProxyListModel model;
67
68 /** Constructor.
69 * @see org.greenstone.gatherer.cdm.DynamicListModel
70 * @see org.greenstone.gatherer.collection.CollectionManager
71 */
72 public ClassifierManager() {
73 super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.CLASSIFY_ELEMENT, new Classifier());
74 this.model = this;
75 DebugStream.println("ClassifierManager: " + getSize() + " classifiers parsed.");
76 // Reload/Create the library
77 loadClassifiers();
78 saveClassifiers();
79 }
80
81 /** Method to add a new classifier to library.
82 * @param classifier The new <strong>Classifier</strong>.
83 * @see org.greenstone.gatherer.cdm.DynamicListModel
84 */
85 private void addClassifier(Classifier classifier) {
86 if(!library.contains(classifier)) {
87 library.add(classifier);
88 }
89 }
90
91 /** Method to assign a classifier.
92 * @param classifier The base <strong>Classifier</strong> to assign.
93 * @see org.greenstone.gatherer.cdm.DynamicListModel
94 */
95 private void assignClassifier(Classifier classifier) {
96 if(!contains(classifier)) {
97 Element element = classifier.getElement();
98 // Locate where we should insert this new classifier.
99 Node target_node = CollectionConfiguration.findInsertionPoint(element);
100 add(root, classifier, target_node);
101 Gatherer.c_man.configurationChanged();
102 }
103 }
104
105 public static boolean clearClassifierCache() {
106
107 DebugStream.println("deleting classifiers.dat");
108 File class_file = new File(Gatherer.getGLIUserDirectoryPath() + "classifiers.dat");
109 if (class_file.exists()) {
110 return Utility.delete(class_file);
111 }
112 return true;
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 /** Determine if the Phind classifier has been assigned.
163 * @return true if it has, false otherwise
164 */
165 public boolean isPhindClassifierAssigned() {
166 for(int i = 0; i < getSize(); i++) {
167 Classifier classifier = (Classifier) getElementAt(i);
168 if(classifier.getName().equalsIgnoreCase(StaticStrings.PHIND_CLASSIFIER)) {
169 return true;
170 }
171 classifier = null;
172 }
173 return false;
174 }
175
176 /** Method to move a classifier in the list order.
177 * @param classifier the Classifier you want to move.
178 * @param direction true to move the classifier up, false to move it down.
179 * @param all true to move to move all the way, false for a single step.
180 */
181 private void moveClassifier(Classifier classifier, boolean direction, boolean all) {
182 if(getSize() < 2) {
183 DebugStream.println("Not enough classifiers to allow moving.");
184 return;
185 }
186 if(all) {
187 // Move to top
188 if(direction) {
189 // Remove the moving classifier
190 remove(classifier);
191 // Retrieve the first classifier
192 Classifier first_classifier = (Classifier) getElementAt(0);
193 // Add the moving classifier before the first classifier
194 addBefore(classifier, first_classifier);
195 first_classifier = null;
196 }
197 else {
198 // Remove the moving classifier
199 remove(classifier);
200 // And add after last classifier
201 add(getSize(), classifier);
202 }
203 }
204 else {
205 // Try to move the classifier one step in the desired direction.
206 int index = indexOf(classifier);
207 ///ystem.err.println("Index of " + classifier + " = " + index);
208 if(direction) {
209 index--;
210 if(index < 0) {
211 String args[] = new String[2];
212 args[0] = Dictionary.get("CDM.ClassifierManager.Classifier");
213 args[1] = classifier.getName();
214 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Top", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
215 return;
216 }
217 remove(classifier);
218 add(index, classifier);
219 }
220 else {
221 index++;
222 if(index >= getSize()) {
223 String args[] = new String[2];
224 args[0] = Dictionary.get("CDM.ClassifierManager.Classifier_Str");
225 args[1] = classifier.getName();
226 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Bottom", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
227 return;
228 }
229 remove(classifier);
230 add(index, classifier);
231 }
232 }
233
234 Gatherer.c_man.configurationChanged();
235 // tell the format manager to update the names of its format statements
236 Gatherer.c_man.getCollection().cdm.format_manager.refresh();
237 }
238
239 /** 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.
240 * @param classifier The Classifier to remove
241 * @see org.greenstone.gatherer.cdm.DynamicListModel
242 */
243 private void removeClassifier(Classifier classifier) {
244 remove(classifier);
245 Gatherer.c_man.configurationChanged();
246 }
247
248 /** Method to cache the current contents of library (known classifiers) to file.
249 * @see org.greenstone.gatherer.util.Utility
250 */
251 private void saveClassifiers() {
252 try {
253 File classifiers_dat_file = new File(Gatherer.getGLIUserDirectoryPath() + "classifiers.dat");
254 FileOutputStream file = new FileOutputStream(classifiers_dat_file);
255 ObjectOutputStream out = new ObjectOutputStream(file);
256 out.writeObject(library);
257 out.close();
258 }
259 catch (Exception error) {
260 }
261 }
262
263 private Object[] getAvailable() {
264 ArrayList available = new ArrayList();
265 int library_size = library.size();
266 for(int i = 0; i < library_size; i++) {
267 Classifier classifier = (Classifier) library.get(i);
268 if(!classifier.isAbstract()) {
269 available.add(classifier);
270 }
271 classifier = null;
272 }
273 return available.toArray();
274 }
275
276 /** Method to extract just the classifiers name from a file object.
277 * @param classifier The <strong>File</strong> which references a certain classifier.
278 * @return A <strong>String</strong> containing just the classifiers name, without extension.
279 */
280 private String getClassifierName(String filename) {
281 String name = filename;
282 if(name.indexOf(".") != -1) {
283 name = name.substring(0, name.indexOf("."));
284 }
285 return name;
286 }
287
288 /** Method to load the details of a single plug-in.
289 * @param classifier The classifier <strong>File</strong> you wish to load.
290 */
291 private void loadClassifier(String classifier, String lang) {
292 ///ystem.err.println("Attempting to parse " + classifier);
293 Document document = null;
294 InputStream input_stream = null;
295
296 long start;
297 long end;
298 // Run classinfo on this classifier, and then send the results for parsing.
299 try {
300 StringBuffer xml = null;
301 if (Gatherer.isGsdlRemote) {
302 String classinfo_output = RemoteGreenstoneServer.getScriptOptions("classinfo.pl", "&classifier=" + classifier);
303 xml = new StringBuffer(classinfo_output);
304 }
305 else {
306 String args[] = null;
307 if(Utility.isWindows()) {
308 args = new String[6];
309 if(Configuration.perl_path != null) {
310 args[0] = Configuration.perl_path;
311 }
312 else {
313 args[0] = "Perl.exe";
314 }
315 args[1] = LocalGreenstone.getBinScriptDirectoryPath() + "classinfo.pl";
316 args[2] = "-xml";
317 args[3] = "-language";
318 args[4] = lang;
319 args[5] = getClassifierName(classifier);
320 }
321 else {
322 args = new String[5];
323 args[0] = "classinfo.pl";
324 args[1] = "-xml";
325 args[2] = "-language";
326 args[3] = lang;
327 args[4] = getClassifierName(classifier);
328 }
329
330 // Create the process.
331 Runtime runtime = Runtime.getRuntime();
332 Process process = runtime.exec(args);
333
334 input_stream = process.getErrorStream();
335 xml = Utility.readXMLStream(input_stream);
336 }
337
338 if (xml.length() > 0) {
339 document = CollectionDesignManager.XMLStringToDOM(xml, classifier);
340 }
341 else {
342 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_XML_Parse_Failed", classifier), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
343 }
344 }
345 catch (Exception exception) {
346 DebugStream.println("Failed when trying to parse: " + classifier);
347 DebugStream.printStackTrace(exception);
348 }
349
350 if (document != null) {
351 parseXML(document.getDocumentElement());
352 }
353 }
354
355 /** Method to initially load information from the standard classifiers within the gsdl Perl library.
356 * @see org.greenstone.gatherer.util.Utility
357 */
358 private void loadClassifiers() {
359 // Attempt to restore the cached file.
360 File classifiers_dat_file = new File(Gatherer.getGLIUserDirectoryPath() + "classifiers.dat");
361 try {
362 FileInputStream file = new FileInputStream(classifiers_dat_file);
363 ObjectInputStream input = new ObjectInputStream(file);
364 library = (ArrayList) input.readObject();
365 }
366 catch (Exception error) {
367 DebugStream.println("Unable to open " + classifiers_dat_file);
368 }
369
370 if(library == null) {
371 library = new ArrayList();
372
373 if (Gatherer.isGsdlRemote) {
374 String classinfo_output = RemoteGreenstoneServer.getScriptOptions("classinfo.pl", "&listall=");
375 loadClassifiers(new StringBuffer(classinfo_output));
376 }
377
378 else {
379 // Retrieve the gsdl home directory...
380 String directory = LocalGreenstone.getDirectoryPath();
381 directory = directory + "perllib" + File.separator + "classify" + File.separator;
382
383 String current_lang = Configuration.getLanguage();
384 File files[] = (new File(directory)).listFiles();
385 if(files != null) {
386 // Create a progress indicator.
387 ParsingProgress progress = new ParsingProgress(Dictionary.get("CDM.ClassifierManager.Parsing.Title"), Dictionary.get("CDM.ClassifierManager.Parsing.Message"), files.length);
388 for(int i = 0; i < files.length; i++) {
389 // We only want to check Perl Modules.
390 if(files[i].getName().endsWith(".pm")) {
391 loadClassifier(files[i].getName(), current_lang);
392 }
393 progress.inc();
394 }
395 progress.dispose();
396 progress.destroy();
397 progress = null;
398 }
399 }
400 }
401 }
402
403
404
405 /** Method to load classifier information from a specified input stream (could be local or through URL). Of course no classifiers may be found at this location.
406 * @param input_stream An <strong>InputStream</strong> indicating the where list of classifiers -- encoded in XML -- can be read from
407 */
408 private void loadClassifiers(StringBuffer xml)
409 {
410 Document document = CollectionDesignManager.XMLStringToDOM(xml, "-listall");
411
412 // Parse XML to build up list of classifier names
413 Node root = document.getDocumentElement();
414
415 NamedNodeMap attributes = root.getAttributes();
416 Node length_node = attributes.getNamedItem("length");
417 String num_classifiers_str = length_node.getNodeValue();
418 int num_classifiers = Integer.parseInt(num_classifiers_str);
419 String class_list[] = new String[num_classifiers];
420
421 Node node = root.getFirstChild();
422 int i = 0;
423 while (node != null) {
424 String node_name = node.getNodeName();
425 if (node_name.equalsIgnoreCase("ClassifyName")) {
426 String name = XMLTools.getValue(node);
427 class_list[i] = name;
428 i++;
429 }
430
431 node = node.getNextSibling();
432 }
433
434 String current_lang = Configuration.getLanguage();
435 if (num_classifiers>0) {
436 // Create a progress indicator.
437 ParsingProgress progress = new ParsingProgress(Dictionary.get("CDM.ClassifierManager.Parsing.Title"), Dictionary.get("CDM.ClassifierManager.Parsing.Message"), num_classifiers);
438
439 for (i=0; i<num_classifiers; i++) {
440 String classifier = class_list[i];
441 loadClassifier(classifier, current_lang);
442 progress.inc();
443 }
444 progress.dispose();
445 progress.destroy();
446 progress = null;
447 }
448 }
449
450
451 /** Parses a DOM tree model turning it into a Classifier and its associated arguments.
452 * @param root The <strong>Node</strong> at the root of the DOM model.
453 * @return A newly created <strong>Classifier</strong> based on the information parsed from the DOM model.
454 * @see org.greenstone.gatherer.cdm.Argument
455 */
456 private Classifier parseXML(Node root) {
457 Classifier classifier = new Classifier();
458 String node_name = null;
459 for(Node node = root.getFirstChild(); node != null;
460 node = node.getNextSibling()) {
461 node_name = node.getNodeName();
462 if(node_name.equals("Name")) {
463 String name = XMLTools.getValue(node);
464 // 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.
465 Classifier existing = getBaseClassifier(name);
466 if(existing != null) {
467 return existing;
468 }
469 classifier.setName(name);
470 }
471 else if(node_name.equals("Desc")) {
472 classifier.setDescription(XMLTools.getValue(node));
473 }
474 else if(node_name.equals("Abstract")) {
475 classifier.setIsAbstract(XMLTools.getValue(node).equalsIgnoreCase(CollectionConfiguration.YES_STR));
476 }
477 // Parse the multitude of arguments.
478 else if(node_name.equals("Arguments")) {
479 for(Node arg = node.getFirstChild(); arg != null; arg = arg.getNextSibling()) {
480 node_name = arg.getNodeName();
481 // An option.
482 if(node_name.equals("Option")) {
483 Argument argument = new Argument();
484 argument.parseXML((Element)arg);
485 classifier.addArgument(argument);
486 }
487 // A super classifier class.
488 else if(node_name.equals("ClassInfo")) {
489 Classifier super_classifier = parseXML(arg);
490 classifier.setSuper(super_classifier);
491 }
492 }
493 }
494 }
495 if(classifier.getName() != null) {
496 addClassifier(classifier);
497 return classifier;
498 }
499 return null;
500 }
501
502 /** A class which provides controls for assigned and editing classifiers. */
503 private class ClassifierControl
504 extends JPanel
505 implements Control {
506 /** A combobox containing all of the known classifiers, including those that may have already been assigned. */
507 private GComboBox classifier = null;
508 /** Button for adding classifiers. */
509 private JButton add = null;
510 /** Button for configuring the selected classifier. */
511 private JButton configure = null;
512 private JButton move_down_button;
513 private JButton move_up_button;
514
515 /** Button to remove the selected classifier. */
516 private JButton remove = null;
517
518 /** A list of assigned classifiers. */
519 private JList classifier_list = null;
520
521 /** Constructor.
522 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.AddListener
523 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.ConfigureListener
524 * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.RemoveListener
525 */
526 public ClassifierControl() {
527 Collections.sort(library);
528 // Create
529 add = new GLIButton();
530 add.setMnemonic(KeyEvent.VK_A);
531 Dictionary.registerBoth(add, "CDM.ClassifierManager.Add", "CDM.ClassifierManager.Add_Tooltip");
532 JPanel button_pane = new JPanel();
533 JPanel central_pane = new JPanel();
534 configure = new GLIButton();
535 configure.setEnabled(false);
536 configure.setMnemonic(KeyEvent.VK_C);
537 Dictionary.registerBoth(configure, "CDM.ClassifierManager.Configure", "CDM.ClassifierManager.Configure_Tooltip");
538 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Classifiers", "classifiers");
539
540 ClassifierComboboxListener ccl = new ClassifierComboboxListener();
541 classifier = new GComboBox(getAvailable());
542 classifier.setBackgroundNonSelectionColor(Configuration.getColor("coloring.editable_background", false));
543 classifier.setBackgroundSelectionColor(Configuration.getColor("coloring.collection_selection_background", false));
544 classifier.setEditable(true);
545 classifier.setTextNonSelectionColor(Configuration.getColor("coloring.workspace_tree_foreground", false));
546 classifier.setTextSelectionColor(Configuration.getColor("coloring.collection_selection_foreground", false));
547 if(classifier.getItemCount() > 0) {
548 classifier.setSelectedIndex(0);
549 ccl.itemStateChanged(new ItemEvent(classifier, 0, null, ItemEvent.SELECTED));
550 }
551
552 JLabel classifier_label = new JLabel();
553 Dictionary.registerText(classifier_label, "CDM.ClassifierManager.Classifier");
554 classifier_list = new JList(model);
555 classifier_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
556 JLabel classifier_list_label = new JLabel();
557 // classifier_list_label.setHorizontalAlignment(JLabel.CENTER);
558 classifier_list_label.setOpaque(true);
559 Dictionary.registerText(classifier_list_label, "CDM.ClassifierManager.Assigned");
560 JPanel classifier_list_pane = new JPanel();
561 JPanel classifier_pane = new JPanel();
562 remove = new GLIButton();
563 remove.setEnabled(false);
564 remove.setMnemonic(KeyEvent.VK_R);
565 Dictionary.registerBoth(remove, "CDM.ClassifierManager.Remove", "CDM.ClassifierManager.Remove_Tooltip");
566
567 JPanel temp = new JPanel(new BorderLayout());
568
569 JPanel move_button_pane = new JPanel();
570
571 move_up_button = new JButton("", JarTools.getImage("arrow-up.gif"));
572 move_up_button.setEnabled(false);
573 move_up_button.setMnemonic(KeyEvent.VK_U);
574 Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
575
576 move_down_button = new JButton("", JarTools.getImage("arrow-down.gif"));
577 move_down_button.setEnabled(false);
578 move_down_button.setMnemonic(KeyEvent.VK_D);
579 Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
580
581 // Listeners
582 add.addActionListener(new AddListener());
583 add.addActionListener(CollectionDesignManager.buildcol_change_listener);
584 classifier.addItemListener(ccl);
585 configure.addActionListener(new ConfigureListener());
586 configure.addActionListener(CollectionDesignManager.buildcol_change_listener);
587 remove.addActionListener(new RemoveListener());
588 remove.addActionListener(CollectionDesignManager.buildcol_change_listener);
589 classifier_list.addMouseListener(new ClickListener());
590 classifier_list.addListSelectionListener(new ListListener());
591 ccl = null;
592
593 MoveListener ml = new MoveListener();
594 move_down_button.addActionListener(ml);
595 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
596 move_up_button.addActionListener(ml);
597 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
598
599 // Layout
600 move_button_pane.setLayout(new GridLayout(4,1));
601 move_button_pane.add(move_up_button);
602 move_button_pane.add(new JPanel());
603 move_button_pane.add(new JPanel());
604 move_button_pane.add(move_down_button);
605
606 classifier_list_label.setBorder(BorderFactory.createEmptyBorder(0,2,0,2));
607
608 classifier_list_pane.setLayout(new BorderLayout());
609 classifier_list_pane.add(classifier_list_label, BorderLayout.NORTH);
610 classifier_list_pane.add(new JScrollPane(classifier_list), BorderLayout.CENTER);
611 classifier_list_pane.add(move_button_pane, BorderLayout.EAST);
612
613 classifier_label.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
614
615 classifier_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
616 classifier_pane.setLayout(new BorderLayout(5,0));
617 classifier_pane.add(classifier_label, BorderLayout.WEST);
618 classifier_pane.add(classifier, BorderLayout.CENTER);
619
620 button_pane.setLayout(new GridLayout(1, 3));
621 button_pane.add(add);
622 button_pane.add(configure);
623 button_pane.add(remove);
624
625 temp.add(classifier_pane, BorderLayout.NORTH);
626 temp.add(button_pane, BorderLayout.SOUTH);
627
628 central_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
629 central_pane.setLayout(new BorderLayout());
630 central_pane.add(classifier_list_pane, BorderLayout.CENTER);
631 central_pane.add(temp, BorderLayout.SOUTH);
632
633 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
634 setLayout(new BorderLayout());
635 add(header_pane, BorderLayout.NORTH);
636 add(central_pane, BorderLayout.CENTER);
637 }
638
639 /** Method which acts like a destructor, tidying up references to persistant objects.
640 */
641 public void destroy() {
642 add = null;
643 classifier = null;
644 classifier_list = null;
645 configure = null;
646 //instructions = null;
647 remove = null;
648 }
649
650 public void gainFocus() {
651 }
652
653 public void loseFocus() {
654 }
655
656 /** This class listens for actions upon the add button in the controls, and if detected calls the assignClassifier() method.
657 */
658 private class AddListener
659 implements ActionListener {
660 /** Any implementation of ActionListener must include this method so that we can be informed when an action has occured on one of our target controls, so that we can add the selected Classifier.
661 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
662 * @see org.greenstone.gatherer.Gatherer
663 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
664 * @see org.greenstone.gatherer.cdm.Classifier
665 */
666 public void actionPerformed(ActionEvent event) {
667 Object selected_object = classifier.getSelectedItem();
668 // If there is something in the combobox, but we haven't registered a selection, then add the object and select it!
669 if(selected_object != null) {
670 // Retrieve the base classifier
671 Classifier base_classifier = getBaseClassifier(selected_object.toString());
672
673 // Create a new element in the DOM
674 Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.CLASSIFY_ELEMENT);
675 Classifier new_classifier = null;
676 if(base_classifier != null) {
677 DebugStream.println("Creating Classifier based on existing Classifer.");
678 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, base_classifier.getName());
679 new_classifier = new Classifier(element, base_classifier);
680 }
681 else {
682 DebugStream.println("Creating new custom Classifier.");
683 element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, selected_object.toString());
684 new_classifier = new Classifier(element, null);
685 // Also we add the custom classifier name to the combobox for convienence.
686 classifier.addItem(selected_object);
687 }
688 element = null;
689 // Automatically chain to configuration. This ensures required arguments are filled out.
690 ArgumentConfiguration ac = new ArgumentConfiguration(new_classifier);
691 if(ac.display()) {
692 if(!model.contains(new_classifier)) {
693 assignClassifier(new_classifier);
694 classifier_list.setSelectedValue(new_classifier, true);
695 }
696 else {
697 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
698 }
699 }
700 ac = null;
701 new_classifier = null;
702 }
703 }
704 }
705
706 /** This listener reacts to changes in the current selection of the classifier combobox. */
707 private class ClassifierComboboxListener
708 implements ItemListener {
709 /** When a user selects a certain plugin, update the tooltip to show the plugin description. */
710 public void itemStateChanged(ItemEvent event) {
711 if(event.getStateChange() == ItemEvent.SELECTED) {
712 // Retrieve the selected plugin
713 Object current_selection = classifier.getSelectedItem();
714 // And reset the tooltip. If the plugin is null or is a string, then go back to the default message
715 if(current_selection == null || current_selection instanceof String) {
716 Dictionary.registerTooltip(classifier, "CDM.ClassifierManager.Classifier_Tooltip");
717 }
718 else {
719 Classifier current_classifier = (Classifier) current_selection;
720 Dictionary.registerTooltipText(classifier, Utility.formatHTMLWidth(current_classifier.getDescription(), 40));
721 current_classifier = null;
722 }
723 current_selection = null;
724 }
725 }
726 }
727
728 /** Listens for double clicks apon the list and react as if the configure button was pushed. */
729 private class ClickListener
730 extends MouseAdapter {
731 /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt.
732 * @param event A <strong>MouseEvent</strong> containing information about the mouse click.
733 */
734 public void mouseClicked(MouseEvent event) {
735 if(event.getClickCount() == 2 ) {
736 if(!classifier_list.isSelectionEmpty()) {
737 Classifier classifier = (Classifier) classifier_list.getSelectedValue();
738 ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
739 if(ac.display()) {
740 refresh(classifier);
741 }
742 ac.destroy();
743 ac = null;
744 // cos I can't be bothered checking every argument to see if it has changed or not, we'll asasume that the configuration has changed if someone has clicked configure
745 Gatherer.c_man.configurationChanged();
746 }
747 }
748 }
749 }
750
751 /** This class listens for actions upon the configure button in the controls, and if detected creates a new ArgumentConfiguration dialog box to allow for configuration.
752 */
753 private class ConfigureListener
754 implements ActionListener {
755 /** 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.
756 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
757 * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
758 * @see org.greenstone.gatherer.cdm.Classifier
759 */
760 public void actionPerformed(ActionEvent event) {
761 if(!classifier_list.isSelectionEmpty()) {
762 Classifier classifier = (Classifier) classifier_list.getSelectedValue();
763 ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
764 if(ac.display()) {
765 refresh(classifier);
766 }
767 ac.destroy();
768 ac = null;
769 // cos I can't be bothered checking every argument to see if it has changed or not, we'll asasume that the configuration has changed if someone has clicked configure
770 Gatherer.c_man.configurationChanged();
771 }
772 }
773 }
774
775 /** listens for changes in the list selection and enables the configure and remove buttons if there is a selection, disables them if there is no selection */
776 private class ListListener
777 implements ListSelectionListener {
778
779 public void valueChanged(ListSelectionEvent e) {
780 if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one)
781 if (classifier_list.isSelectionEmpty()) {
782 move_up_button.setEnabled(false);
783 move_down_button.setEnabled(false);
784 configure.setEnabled(false);
785 remove.setEnabled(false);
786 }
787 else {
788 configure.setEnabled(true);
789 remove.setEnabled(true);
790 int selected_index = classifier_list.getSelectedIndex();
791 move_up_button.setEnabled(selected_index !=0);
792 move_down_button.setEnabled(selected_index != model.getSize()-1);
793 }
794 }
795 }
796 }
797
798 /** 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. */
799 private class MoveListener
800 implements ActionListener {
801 /** 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.
802 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
803 */
804 public void actionPerformed(ActionEvent event) {
805 if(!classifier_list.isSelectionEmpty()) {
806 Object object = classifier_list.getSelectedValue();
807 if(object instanceof Classifier) {
808 Classifier classifier = (Classifier) object;
809 if(event.getSource() == move_up_button) {
810 moveClassifier(classifier, true, false);
811 }
812 else if(event.getSource() == move_down_button) {
813 moveClassifier(classifier, false, false);
814 }
815 classifier_list.setSelectedValue(classifier, true);
816 }
817 }
818 }
819 }
820
821 /** This class listens for actions upon the remove button in the controls, and if detected calls the <i>removeClassifier()</i> method.
822 */
823 private class RemoveListener
824 implements ActionListener {
825 /** 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.
826 * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
827 */
828 public void actionPerformed(ActionEvent event) {
829 if(classifier_list.isSelectionEmpty()) {
830 remove.setEnabled(false);
831 return;
832 }
833 int selected_index = classifier_list.getSelectedIndex();
834 Object selected_classifier = classifier_list.getSelectedValue();
835 if (!(selected_classifier instanceof Classifier)) {
836 return; // what else could we have here???
837 }
838 removeClassifier((Classifier)selected_classifier);
839
840 if (selected_index >= classifier_list.getModel().getSize()) {
841 selected_index--;
842 }
843 if (selected_index >=0) {
844 classifier_list.setSelectedIndex(selected_index);
845 } else {
846 // no more classifiers in the list
847 remove.setEnabled(false);
848 }
849 }
850 }
851 }
852}
Note: See TracBrowser for help on using the repository browser.