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

Last change on this file since 11031 was 11031, checked in by kjdon, 18 years ago

removed instructions, changed title to be the same string as in the contents, and use a new class DesignPaneHeader to create teh header which has title and help button

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