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

Last change on this file since 10377 was 10370, checked in by mdewsnip, 19 years ago

Added a new LocalGreenstone class which contains functions that only make sense with a local Greenstone.

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