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 | */
|
---|
27 | package org.greenstone.gatherer.cdm;
|
---|
28 |
|
---|
29 | import java.awt.*;
|
---|
30 | import java.awt.event.*;
|
---|
31 | import java.io.*;
|
---|
32 | import java.net.*;
|
---|
33 | import java.util.*;
|
---|
34 | import java.util.jar.*;
|
---|
35 | import javax.swing.*;
|
---|
36 | import javax.swing.event.*;
|
---|
37 | import org.apache.xerces.parsers.*;
|
---|
38 | import org.greenstone.gatherer.Configuration;
|
---|
39 | import org.greenstone.gatherer.DebugStream;
|
---|
40 | import org.greenstone.gatherer.Dictionary;
|
---|
41 | import org.greenstone.gatherer.Gatherer;
|
---|
42 | import org.greenstone.gatherer.LocalGreenstone;
|
---|
43 | import org.greenstone.gatherer.gui.DesignPaneHeader;
|
---|
44 | import org.greenstone.gatherer.gui.GComboBox;
|
---|
45 | import org.greenstone.gatherer.gui.GLIButton;
|
---|
46 | import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
|
---|
47 | import org.greenstone.gatherer.util.JarTools;
|
---|
48 | import org.greenstone.gatherer.util.StaticStrings;
|
---|
49 | import org.greenstone.gatherer.util.Utility;
|
---|
50 | import org.greenstone.gatherer.util.XMLTools;
|
---|
51 | import org.w3c.dom.*;
|
---|
52 | import 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 | */
|
---|
58 | public class ClassifierManager
|
---|
59 | extends DOMProxyListModel
|
---|
60 | {
|
---|
61 | // A list of all the classifiers in the core Greenstone "perllib/classify" folder (arguments may not be loaded)
|
---|
62 | private ArrayList core_greenstone_classifiers_list = null;
|
---|
63 |
|
---|
64 | /** The controls for editing the contents of this manager. */
|
---|
65 | private Control controls = null;
|
---|
66 |
|
---|
67 | private DOMProxyListModel model;
|
---|
68 |
|
---|
69 | /** Constructor.
|
---|
70 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
71 | * @see org.greenstone.gatherer.collection.CollectionManager
|
---|
72 | */
|
---|
73 | public ClassifierManager() {
|
---|
74 | super(CollectionDesignManager.collect_config.getDocumentElement(), CollectionConfiguration.CLASSIFY_ELEMENT, new Classifier());
|
---|
75 | this.model = this;
|
---|
76 | DebugStream.println("ClassifierManager: " + getSize() + " classifiers parsed.");
|
---|
77 |
|
---|
78 | core_greenstone_classifiers_list = loadClassifiersList();
|
---|
79 | }
|
---|
80 |
|
---|
81 |
|
---|
82 | // --------------------------------------------------------------------------------------------------------
|
---|
83 |
|
---|
84 |
|
---|
85 | /** Retrieve a list of the classifiers that are available to be added to the collection. */
|
---|
86 | private Object[] getAvailableClassifiers()
|
---|
87 | {
|
---|
88 | ArrayList available = new ArrayList();
|
---|
89 |
|
---|
90 | // Add all the non-abstract core Greenstone classifiers
|
---|
91 | for (int i = 0; i < core_greenstone_classifiers_list.size(); i++) {
|
---|
92 | Classifier classifier = (Classifier) core_greenstone_classifiers_list.get(i);
|
---|
93 | if (!classifier.isAbstract()) {
|
---|
94 | available.add(classifier);
|
---|
95 | }
|
---|
96 | }
|
---|
97 |
|
---|
98 | // Sort the available classifiers into alphabetical order
|
---|
99 | Collections.sort(available);
|
---|
100 |
|
---|
101 | return available.toArray();
|
---|
102 | }
|
---|
103 |
|
---|
104 |
|
---|
105 | public Classifier getClassifier(String classifier_name, boolean arguments_required)
|
---|
106 | {
|
---|
107 | for (int i = 0; i < core_greenstone_classifiers_list.size(); i++) {
|
---|
108 | Classifier classifier = (Classifier) core_greenstone_classifiers_list.get(i);
|
---|
109 | if (classifier.getName().equals(classifier_name)) {
|
---|
110 | if (arguments_required) {
|
---|
111 | if (classifier.getArguments().size() == 0) {
|
---|
112 | loadClassifierInfo(classifier);
|
---|
113 | }
|
---|
114 | else {
|
---|
115 | System.err.println("Already loaded arguments for " + classifier_name + "!");
|
---|
116 | }
|
---|
117 | }
|
---|
118 | return classifier;
|
---|
119 | }
|
---|
120 | }
|
---|
121 |
|
---|
122 | return null;
|
---|
123 | }
|
---|
124 |
|
---|
125 |
|
---|
126 | private void loadClassifierInfo(Classifier classifier)
|
---|
127 | {
|
---|
128 | System.err.println("Loading arguments for " + classifier.getName() + "...");
|
---|
129 |
|
---|
130 | // Run classifierfo.pl to get the list of classifiers
|
---|
131 | try {
|
---|
132 | StringBuffer xml = null;
|
---|
133 | if (Gatherer.isGsdlRemote) {
|
---|
134 | // !! TO DO
|
---|
135 | }
|
---|
136 | else {
|
---|
137 | ArrayList args = new ArrayList();
|
---|
138 | if (Utility.isWindows()) {
|
---|
139 | args.add(Configuration.perl_path);
|
---|
140 | args.add("-S");
|
---|
141 | }
|
---|
142 | args.add(LocalGreenstone.getBinScriptDirectoryPath() + "classinfo.pl");
|
---|
143 | args.add("-xml");
|
---|
144 | args.add("-language");
|
---|
145 | args.add(Configuration.getLanguage());
|
---|
146 | args.add(classifier.getName());
|
---|
147 |
|
---|
148 | // Run the classinfo.pl process
|
---|
149 | Runtime runtime = Runtime.getRuntime();
|
---|
150 | Process process = runtime.exec((String[]) args.toArray(new String[] { }));
|
---|
151 | InputStream input_stream = process.getErrorStream();
|
---|
152 | xml = XMLTools.readXMLStream(input_stream);
|
---|
153 | }
|
---|
154 |
|
---|
155 | if (xml.length() > 0) {
|
---|
156 | parseClassifierInfoXML(classifier, xml.toString());
|
---|
157 | }
|
---|
158 | else {
|
---|
159 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_XML_Parse_Failed", classifier.getName()), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
160 | }
|
---|
161 | }
|
---|
162 | catch (Exception exception) {
|
---|
163 | DebugStream.printStackTrace(exception);
|
---|
164 | }
|
---|
165 | }
|
---|
166 |
|
---|
167 |
|
---|
168 | private ArrayList loadClassifiersList()
|
---|
169 | {
|
---|
170 | System.err.println("In loadClassifiersList()...");
|
---|
171 |
|
---|
172 | // Run classifierfo.pl to get the list of classifiers
|
---|
173 | try {
|
---|
174 | StringBuffer xml = null;
|
---|
175 | if (Gatherer.isGsdlRemote) {
|
---|
176 | // !! TO DO
|
---|
177 | }
|
---|
178 | else {
|
---|
179 | ArrayList args = new ArrayList();
|
---|
180 | if (Utility.isWindows()) {
|
---|
181 | args.add(Configuration.perl_path);
|
---|
182 | args.add("-S");
|
---|
183 | }
|
---|
184 | args.add(LocalGreenstone.getBinScriptDirectoryPath() + "classinfo.pl");
|
---|
185 | args.add("-listall");
|
---|
186 | args.add("-xml");
|
---|
187 |
|
---|
188 | // Run the classinfo.pl process
|
---|
189 | Runtime runtime = Runtime.getRuntime();
|
---|
190 | Process process = runtime.exec((String[]) args.toArray(new String[] { }));
|
---|
191 | InputStream input_stream = process.getErrorStream();
|
---|
192 | xml = XMLTools.readXMLStream(input_stream);
|
---|
193 | }
|
---|
194 |
|
---|
195 | if (xml.length() > 0) {
|
---|
196 | return parseClassifiersListXML(xml.toString());
|
---|
197 | }
|
---|
198 | else {
|
---|
199 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_List_XML_Parse_Failed"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
200 | }
|
---|
201 | }
|
---|
202 | catch (Exception exception) {
|
---|
203 | DebugStream.printStackTrace(exception);
|
---|
204 | }
|
---|
205 |
|
---|
206 | return null;
|
---|
207 | }
|
---|
208 |
|
---|
209 |
|
---|
210 | private void parseClassifierInfoXML(Classifier classifier, String xml)
|
---|
211 | {
|
---|
212 | Document document = XMLTools.parseXML(new StringReader(xml));
|
---|
213 | parseClassifierInfoXMLNode(classifier, document.getDocumentElement());
|
---|
214 | }
|
---|
215 |
|
---|
216 |
|
---|
217 | private void parseClassifierInfoXMLNode(Classifier classifier, Node root_node)
|
---|
218 | {
|
---|
219 | for (Node node = root_node.getFirstChild(); node != null; node = node.getNextSibling()) {
|
---|
220 | String node_name = node.getNodeName();
|
---|
221 |
|
---|
222 | if (node_name.equalsIgnoreCase("Name")) {
|
---|
223 | classifier.setName(XMLTools.getValue(node));
|
---|
224 | }
|
---|
225 | else if (node_name.equals("Desc")) {
|
---|
226 | classifier.setDescription(XMLTools.getValue(node));
|
---|
227 | }
|
---|
228 | else if (node_name.equals("Abstract")) {
|
---|
229 | classifier.setIsAbstract(XMLTools.getValue(node).equalsIgnoreCase(CollectionConfiguration.YES_STR));
|
---|
230 | }
|
---|
231 | // Parse the classifier arguments
|
---|
232 | else if (node_name.equalsIgnoreCase("Arguments")) {
|
---|
233 | for (Node argument_node = node.getFirstChild(); argument_node != null; argument_node = argument_node.getNextSibling()) {
|
---|
234 | // An option
|
---|
235 | if (argument_node.getNodeName().equalsIgnoreCase("Option")) {
|
---|
236 | Argument argument = new Argument();
|
---|
237 | argument.parseXML((Element) argument_node);
|
---|
238 | classifier.addArgument(argument);
|
---|
239 | }
|
---|
240 | }
|
---|
241 | }
|
---|
242 | // A super classifier class
|
---|
243 | else if (node_name.equalsIgnoreCase("ClassInfo")) {
|
---|
244 | Classifier super_classifier = new Classifier();
|
---|
245 | parseClassifierInfoXMLNode(super_classifier, node);
|
---|
246 | classifier.setSuper(super_classifier);
|
---|
247 | }
|
---|
248 | }
|
---|
249 | }
|
---|
250 |
|
---|
251 |
|
---|
252 | private ArrayList parseClassifiersListXML(String xml)
|
---|
253 | {
|
---|
254 | ArrayList classifiers_list = new ArrayList();
|
---|
255 |
|
---|
256 | Document document = XMLTools.parseXML(new StringReader(xml));
|
---|
257 | Node root = document.getDocumentElement();
|
---|
258 | for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
|
---|
259 | String node_name = node.getNodeName();
|
---|
260 |
|
---|
261 | if (node_name.equals("ClassInfo")) {
|
---|
262 | Classifier classifier = new Classifier();
|
---|
263 | parseClassifierInfoXMLNode(classifier, node);
|
---|
264 | classifiers_list.add(classifier);
|
---|
265 | }
|
---|
266 | }
|
---|
267 |
|
---|
268 | return classifiers_list;
|
---|
269 | }
|
---|
270 |
|
---|
271 |
|
---|
272 | // --------------------------------------------------------------------------------------------------------
|
---|
273 |
|
---|
274 |
|
---|
275 | /** Method to assign a classifier.
|
---|
276 | * @param classifier The base <strong>Classifier</strong> to assign.
|
---|
277 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
278 | */
|
---|
279 | private void assignClassifier(Classifier classifier) {
|
---|
280 | if(!contains(classifier)) {
|
---|
281 | Element element = classifier.getElement();
|
---|
282 | // Locate where we should insert this new classifier.
|
---|
283 | Node target_node = CollectionConfiguration.findInsertionPoint(element);
|
---|
284 | add(root, classifier, target_node);
|
---|
285 | Gatherer.c_man.configurationChanged();
|
---|
286 | }
|
---|
287 | }
|
---|
288 |
|
---|
289 |
|
---|
290 | /** Destructor. */
|
---|
291 | public void destroy()
|
---|
292 | {
|
---|
293 | if (controls != null) {
|
---|
294 | controls.destroy();
|
---|
295 | controls = null;
|
---|
296 | }
|
---|
297 | }
|
---|
298 |
|
---|
299 |
|
---|
300 | /** Method to retrieve the classifier with the given index.
|
---|
301 | * @param index The index of the desired classifier as an <i>int</i>.
|
---|
302 | * @return The requested Classifier or <i>null</i> if no such classifier exists.
|
---|
303 | */
|
---|
304 | public Classifier getClassifier(int index) {
|
---|
305 | if(0 <= index && index < getSize()) {
|
---|
306 | return (Classifier) getElementAt(index);
|
---|
307 | }
|
---|
308 | return null;
|
---|
309 | }
|
---|
310 |
|
---|
311 | /** Method to retrieve the control for this manager.
|
---|
312 | * @return the Control for editing classifiers
|
---|
313 | */
|
---|
314 | public Control getControls() {
|
---|
315 | if(controls == null) {
|
---|
316 | // Build controls
|
---|
317 | this.controls = new ClassifierControl();
|
---|
318 | }
|
---|
319 | return controls;
|
---|
320 | }
|
---|
321 |
|
---|
322 | /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
|
---|
323 | * @param mode the new mode as an int
|
---|
324 | */
|
---|
325 | public void modeChanged(int mode) {
|
---|
326 |
|
---|
327 | }
|
---|
328 |
|
---|
329 |
|
---|
330 |
|
---|
331 | /** Determine if the Phind classifier has been assigned.
|
---|
332 | * @return true if it has, false otherwise
|
---|
333 | */
|
---|
334 | public boolean isPhindClassifierAssigned() {
|
---|
335 | for(int i = 0; i < getSize(); i++) {
|
---|
336 | Classifier classifier = (Classifier) getElementAt(i);
|
---|
337 | if(classifier.getName().equalsIgnoreCase(StaticStrings.PHIND_CLASSIFIER)) {
|
---|
338 | return true;
|
---|
339 | }
|
---|
340 | classifier = null;
|
---|
341 | }
|
---|
342 | return false;
|
---|
343 | }
|
---|
344 |
|
---|
345 | /** Method to move a classifier in the list order.
|
---|
346 | * @param classifier the Classifier you want to move.
|
---|
347 | * @param direction true to move the classifier up, false to move it down.
|
---|
348 | * @param all true to move to move all the way, false for a single step.
|
---|
349 | */
|
---|
350 | private void moveClassifier(Classifier classifier, boolean direction, boolean all) {
|
---|
351 | if(getSize() < 2) {
|
---|
352 | DebugStream.println("Not enough classifiers to allow moving.");
|
---|
353 | return;
|
---|
354 | }
|
---|
355 | if(all) {
|
---|
356 | // Move to top
|
---|
357 | if(direction) {
|
---|
358 | // Remove the moving classifier
|
---|
359 | remove(classifier);
|
---|
360 | // Retrieve the first classifier
|
---|
361 | Classifier first_classifier = (Classifier) getElementAt(0);
|
---|
362 | // Add the moving classifier before the first classifier
|
---|
363 | addBefore(classifier, first_classifier);
|
---|
364 | first_classifier = null;
|
---|
365 | }
|
---|
366 | else {
|
---|
367 | // Remove the moving classifier
|
---|
368 | remove(classifier);
|
---|
369 | // And add after last classifier
|
---|
370 | add(getSize(), classifier);
|
---|
371 | }
|
---|
372 | }
|
---|
373 | else {
|
---|
374 | // Try to move the classifier one step in the desired direction.
|
---|
375 | int index = indexOf(classifier);
|
---|
376 | ///ystem.err.println("Index of " + classifier + " = " + index);
|
---|
377 | if(direction) {
|
---|
378 | index--;
|
---|
379 | if(index < 0) {
|
---|
380 | String args[] = new String[2];
|
---|
381 | args[0] = Dictionary.get("CDM.ClassifierManager.Classifier");
|
---|
382 | args[1] = classifier.getName();
|
---|
383 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Top", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
|
---|
384 | return;
|
---|
385 | }
|
---|
386 | remove(classifier);
|
---|
387 | add(index, classifier);
|
---|
388 | }
|
---|
389 | else {
|
---|
390 | index++;
|
---|
391 | if(index >= getSize()) {
|
---|
392 | String args[] = new String[2];
|
---|
393 | args[0] = Dictionary.get("CDM.ClassifierManager.Classifier_Str");
|
---|
394 | args[1] = classifier.getName();
|
---|
395 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.Move.At_Bottom", args), Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
|
---|
396 | return;
|
---|
397 | }
|
---|
398 | remove(classifier);
|
---|
399 | add(index, classifier);
|
---|
400 | }
|
---|
401 | }
|
---|
402 |
|
---|
403 | Gatherer.c_man.configurationChanged();
|
---|
404 | // tell the format manager to update the names of its format statements
|
---|
405 | Gatherer.c_man.getCollection().cdm.format_manager.refresh();
|
---|
406 | }
|
---|
407 |
|
---|
408 | /** 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.
|
---|
409 | * @param classifier The Classifier to remove
|
---|
410 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
411 | */
|
---|
412 | private void removeClassifier(Classifier classifier) {
|
---|
413 | remove(classifier);
|
---|
414 | Gatherer.c_man.configurationChanged();
|
---|
415 | }
|
---|
416 |
|
---|
417 |
|
---|
418 | /** A class which provides controls for assigned and editing classifiers. */
|
---|
419 | private class ClassifierControl
|
---|
420 | extends JPanel
|
---|
421 | implements Control {
|
---|
422 | /** A combobox containing all of the known classifiers, including those that may have already been assigned. */
|
---|
423 | private JComboBox classifier_combobox = null;
|
---|
424 | /** Button for adding classifiers. */
|
---|
425 | private JButton add = null;
|
---|
426 | /** Button for configuring the selected classifier. */
|
---|
427 | private JButton configure = null;
|
---|
428 | private JButton move_down_button;
|
---|
429 | private JButton move_up_button;
|
---|
430 |
|
---|
431 | /** Button to remove the selected classifier. */
|
---|
432 | private JButton remove = null;
|
---|
433 |
|
---|
434 | /** A list of assigned classifiers. */
|
---|
435 | private JList classifier_list = null;
|
---|
436 |
|
---|
437 | /** Constructor.
|
---|
438 | * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.AddListener
|
---|
439 | * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.ConfigureListener
|
---|
440 | * @see org.greenstone.gatherer.cdm.ClassifierManager.ClassifierControl.RemoveListener
|
---|
441 | */
|
---|
442 | public ClassifierControl()
|
---|
443 | {
|
---|
444 | // Create
|
---|
445 | add = new GLIButton(Dictionary.get("CDM.ClassifierManager.Add"), Dictionary.get("CDM.ClassifierManager.Add_Tooltip"));
|
---|
446 |
|
---|
447 | JPanel button_pane = new JPanel();
|
---|
448 | JPanel central_pane = new JPanel();
|
---|
449 |
|
---|
450 | configure = new GLIButton(Dictionary.get("CDM.ClassifierManager.Configure"), Dictionary.get("CDM.ClassifierManager.Configure_Tooltip"));
|
---|
451 | configure.setEnabled(false);
|
---|
452 |
|
---|
453 | JPanel header_pane = new DesignPaneHeader("CDM.GUI.Classifiers", "classifiers");
|
---|
454 |
|
---|
455 | ClassifierComboboxListener ccl = new ClassifierComboboxListener();
|
---|
456 | classifier_combobox = new JComboBox(getAvailableClassifiers());
|
---|
457 | classifier_combobox.setEditable(false);
|
---|
458 | if(classifier_combobox.getItemCount() > 0) {
|
---|
459 | classifier_combobox.setSelectedIndex(0);
|
---|
460 | ccl.itemStateChanged(new ItemEvent(classifier_combobox, 0, null, ItemEvent.SELECTED));
|
---|
461 | }
|
---|
462 |
|
---|
463 | JLabel classifier_label = new JLabel(Dictionary.get("CDM.ClassifierManager.Classifier"));
|
---|
464 |
|
---|
465 | classifier_list = new JList(model);
|
---|
466 | classifier_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
---|
467 | JLabel classifier_list_label = new JLabel(Dictionary.get("CDM.ClassifierManager.Assigned"));
|
---|
468 |
|
---|
469 | classifier_list_label.setOpaque(true);
|
---|
470 |
|
---|
471 | JPanel classifier_list_pane = new JPanel();
|
---|
472 | JPanel classifier_pane = new JPanel();
|
---|
473 | remove = new GLIButton(Dictionary.get("CDM.ClassifierManager.Remove"), Dictionary.get("CDM.ClassifierManager.Remove_Tooltip"));
|
---|
474 | remove.setEnabled(false);
|
---|
475 |
|
---|
476 | JPanel temp = new JPanel(new BorderLayout());
|
---|
477 |
|
---|
478 | JPanel move_button_pane = new JPanel();
|
---|
479 |
|
---|
480 | move_up_button = new GLIButton(Dictionary.get("CDM.Move.Move_Up"), JarTools.getImage("arrow-up.gif"), Dictionary.get("CDM.Move.Move_Up_Tooltip"));
|
---|
481 | move_up_button.setEnabled(false);
|
---|
482 |
|
---|
483 | move_down_button = new GLIButton(Dictionary.get("CDM.Move.Move_Down"), JarTools.getImage("arrow-down.gif"), Dictionary.get("CDM.Move.Move_Down_Tooltip"));
|
---|
484 | move_down_button.setEnabled(false);
|
---|
485 |
|
---|
486 | // Listeners
|
---|
487 | add.addActionListener(new AddListener());
|
---|
488 | add.addActionListener(CollectionDesignManager.buildcol_change_listener);
|
---|
489 | classifier_combobox.addItemListener(ccl);
|
---|
490 | configure.addActionListener(new ConfigureListener());
|
---|
491 | configure.addActionListener(CollectionDesignManager.buildcol_change_listener);
|
---|
492 | remove.addActionListener(new RemoveListener());
|
---|
493 | remove.addActionListener(CollectionDesignManager.buildcol_change_listener);
|
---|
494 | classifier_list.addMouseListener(new ClickListener());
|
---|
495 | classifier_list.addListSelectionListener(new ListListener());
|
---|
496 | ccl = null;
|
---|
497 |
|
---|
498 | MoveListener ml = new MoveListener();
|
---|
499 | move_down_button.addActionListener(ml);
|
---|
500 | move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
|
---|
501 | move_up_button.addActionListener(ml);
|
---|
502 | move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
|
---|
503 |
|
---|
504 | // Layout
|
---|
505 | move_button_pane.setLayout(new GridLayout(4,1));
|
---|
506 | move_button_pane.add(move_up_button);
|
---|
507 | move_button_pane.add(new JPanel());
|
---|
508 | move_button_pane.add(new JPanel());
|
---|
509 | move_button_pane.add(move_down_button);
|
---|
510 |
|
---|
511 | classifier_list_label.setBorder(BorderFactory.createEmptyBorder(0,2,0,2));
|
---|
512 |
|
---|
513 | classifier_list_pane.setLayout(new BorderLayout());
|
---|
514 | classifier_list_pane.add(classifier_list_label, BorderLayout.NORTH);
|
---|
515 | classifier_list_pane.add(new JScrollPane(classifier_list), BorderLayout.CENTER);
|
---|
516 | classifier_list_pane.add(move_button_pane, BorderLayout.EAST);
|
---|
517 |
|
---|
518 | classifier_label.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
|
---|
519 |
|
---|
520 | classifier_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
|
---|
521 | classifier_pane.setLayout(new BorderLayout(5,0));
|
---|
522 | classifier_pane.add(classifier_label, BorderLayout.WEST);
|
---|
523 | classifier_pane.add(classifier_combobox, BorderLayout.CENTER);
|
---|
524 |
|
---|
525 | button_pane.setLayout(new GridLayout(1, 3));
|
---|
526 | button_pane.add(add);
|
---|
527 | button_pane.add(configure);
|
---|
528 | button_pane.add(remove);
|
---|
529 |
|
---|
530 | temp.add(classifier_pane, BorderLayout.NORTH);
|
---|
531 | temp.add(button_pane, BorderLayout.SOUTH);
|
---|
532 |
|
---|
533 | central_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
|
---|
534 | central_pane.setLayout(new BorderLayout());
|
---|
535 | central_pane.add(classifier_list_pane, BorderLayout.CENTER);
|
---|
536 | central_pane.add(temp, BorderLayout.SOUTH);
|
---|
537 |
|
---|
538 | setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
|
---|
539 | setLayout(new BorderLayout());
|
---|
540 | add(header_pane, BorderLayout.NORTH);
|
---|
541 | add(central_pane, BorderLayout.CENTER);
|
---|
542 | }
|
---|
543 |
|
---|
544 | /** Method which acts like a destructor, tidying up references to persistant objects.
|
---|
545 | */
|
---|
546 | public void destroy() {
|
---|
547 | add = null;
|
---|
548 | classifier_combobox = null;
|
---|
549 | classifier_list = null;
|
---|
550 | configure = null;
|
---|
551 | //instructions = null;
|
---|
552 | remove = null;
|
---|
553 | }
|
---|
554 |
|
---|
555 | public void gainFocus() {
|
---|
556 | }
|
---|
557 |
|
---|
558 | public void loseFocus() {
|
---|
559 | }
|
---|
560 |
|
---|
561 | /** This class listens for actions upon the add button in the controls, and if detected calls the assignClassifier() method.
|
---|
562 | */
|
---|
563 | private class AddListener
|
---|
564 | implements ActionListener {
|
---|
565 | /** 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.
|
---|
566 | * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
|
---|
567 | * @see org.greenstone.gatherer.Gatherer
|
---|
568 | * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
|
---|
569 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
570 | */
|
---|
571 | public void actionPerformed(ActionEvent event) {
|
---|
572 | Object selected_object = classifier_combobox.getSelectedItem();
|
---|
573 | // If there is something in the combobox, but we haven't registered a selection, then add the object and select it!
|
---|
574 | if(selected_object != null) {
|
---|
575 | // Retrieve the base classifier
|
---|
576 | Classifier base_classifier = getClassifier(selected_object.toString(), true);
|
---|
577 |
|
---|
578 | // Create a new element in the DOM
|
---|
579 | Element element = CollectionDesignManager.collect_config.document.createElement(CollectionConfiguration.CLASSIFY_ELEMENT);
|
---|
580 | element.setAttribute(CollectionConfiguration.TYPE_ATTRIBUTE, base_classifier.getName());
|
---|
581 | Classifier new_classifier = new Classifier(element, base_classifier);
|
---|
582 |
|
---|
583 | element = null;
|
---|
584 | // Automatically chain to configuration. This ensures required arguments are filled out.
|
---|
585 | ArgumentConfiguration ac = new ArgumentConfiguration(new_classifier);
|
---|
586 | if(ac.display()) {
|
---|
587 | if(!model.contains(new_classifier)) {
|
---|
588 | assignClassifier(new_classifier);
|
---|
589 | classifier_list.setSelectedValue(new_classifier, true);
|
---|
590 | }
|
---|
591 | else {
|
---|
592 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.ClassifierManager.Classifier_Exists"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
|
---|
593 | }
|
---|
594 | }
|
---|
595 | ac = null;
|
---|
596 | new_classifier = null;
|
---|
597 | }
|
---|
598 | }
|
---|
599 | }
|
---|
600 |
|
---|
601 | /** This listener reacts to changes in the current selection of the classifier combobox. */
|
---|
602 | private class ClassifierComboboxListener
|
---|
603 | implements ItemListener {
|
---|
604 | /** When a user selects a certain classifier, update the tooltip to show the classifier description. */
|
---|
605 | public void itemStateChanged(ItemEvent event) {
|
---|
606 | if(event.getStateChange() == ItemEvent.SELECTED) {
|
---|
607 | // Retrieve the selected classifier
|
---|
608 | Classifier current_selection = (Classifier) classifier_combobox.getSelectedItem();
|
---|
609 | // And reset the tooltip.
|
---|
610 | classifier_combobox.setToolTipText(Utility.formatHTMLWidth(current_selection.getDescription(), 40));
|
---|
611 | current_selection = null;
|
---|
612 | }
|
---|
613 | }
|
---|
614 | }
|
---|
615 |
|
---|
616 | /** Listens for double clicks apon the list and react as if the configure button was pushed. */
|
---|
617 | private class ClickListener
|
---|
618 | extends MouseAdapter {
|
---|
619 | /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt.
|
---|
620 | * @param event A <strong>MouseEvent</strong> containing information about the mouse click.
|
---|
621 | */
|
---|
622 | public void mouseClicked(MouseEvent event) {
|
---|
623 | if(event.getClickCount() == 2 ) {
|
---|
624 | if(!classifier_list.isSelectionEmpty()) {
|
---|
625 | Classifier classifier = (Classifier) classifier_list.getSelectedValue();
|
---|
626 | ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
|
---|
627 | if(ac.display()) {
|
---|
628 | refresh(classifier);
|
---|
629 | }
|
---|
630 | ac.destroy();
|
---|
631 | ac = null;
|
---|
632 | // 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
|
---|
633 | Gatherer.c_man.configurationChanged();
|
---|
634 | }
|
---|
635 | }
|
---|
636 | }
|
---|
637 | }
|
---|
638 |
|
---|
639 | /** 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.
|
---|
640 | */
|
---|
641 | private class ConfigureListener
|
---|
642 | implements ActionListener {
|
---|
643 | /** 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.
|
---|
644 | * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
|
---|
645 | * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
|
---|
646 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
647 | */
|
---|
648 | public void actionPerformed(ActionEvent event) {
|
---|
649 | if(!classifier_list.isSelectionEmpty()) {
|
---|
650 | Classifier classifier = (Classifier) classifier_list.getSelectedValue();
|
---|
651 | ArgumentConfiguration ac = new ArgumentConfiguration(classifier);
|
---|
652 | if(ac.display()) {
|
---|
653 | refresh(classifier);
|
---|
654 | }
|
---|
655 | ac.destroy();
|
---|
656 | ac = null;
|
---|
657 | // 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
|
---|
658 | Gatherer.c_man.configurationChanged();
|
---|
659 | }
|
---|
660 | }
|
---|
661 | }
|
---|
662 |
|
---|
663 | /** 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 */
|
---|
664 | private class ListListener
|
---|
665 | implements ListSelectionListener {
|
---|
666 |
|
---|
667 | public void valueChanged(ListSelectionEvent e) {
|
---|
668 | if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one)
|
---|
669 | if (classifier_list.isSelectionEmpty()) {
|
---|
670 | move_up_button.setEnabled(false);
|
---|
671 | move_down_button.setEnabled(false);
|
---|
672 | configure.setEnabled(false);
|
---|
673 | remove.setEnabled(false);
|
---|
674 | }
|
---|
675 | else {
|
---|
676 | configure.setEnabled(true);
|
---|
677 | remove.setEnabled(true);
|
---|
678 | int selected_index = classifier_list.getSelectedIndex();
|
---|
679 | move_up_button.setEnabled(selected_index !=0);
|
---|
680 | move_down_button.setEnabled(selected_index != model.getSize()-1);
|
---|
681 | }
|
---|
682 | }
|
---|
683 | }
|
---|
684 | }
|
---|
685 |
|
---|
686 | /** 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. */
|
---|
687 | private class MoveListener
|
---|
688 | implements ActionListener {
|
---|
689 | /** 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.
|
---|
690 | * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
|
---|
691 | */
|
---|
692 | public void actionPerformed(ActionEvent event) {
|
---|
693 | if(!classifier_list.isSelectionEmpty()) {
|
---|
694 | Object object = classifier_list.getSelectedValue();
|
---|
695 | if(object instanceof Classifier) {
|
---|
696 | Classifier classifier = (Classifier) object;
|
---|
697 | if(event.getSource() == move_up_button) {
|
---|
698 | moveClassifier(classifier, true, false);
|
---|
699 | }
|
---|
700 | else if(event.getSource() == move_down_button) {
|
---|
701 | moveClassifier(classifier, false, false);
|
---|
702 | }
|
---|
703 | classifier_list.setSelectedValue(classifier, true);
|
---|
704 | }
|
---|
705 | }
|
---|
706 | }
|
---|
707 | }
|
---|
708 |
|
---|
709 | /** This class listens for actions upon the remove button in the controls, and if detected calls the <i>removeClassifier()</i> method.
|
---|
710 | */
|
---|
711 | private class RemoveListener
|
---|
712 | implements ActionListener {
|
---|
713 | /** 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.
|
---|
714 | * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
|
---|
715 | */
|
---|
716 | public void actionPerformed(ActionEvent event) {
|
---|
717 | if(classifier_list.isSelectionEmpty()) {
|
---|
718 | remove.setEnabled(false);
|
---|
719 | return;
|
---|
720 | }
|
---|
721 | int selected_index = classifier_list.getSelectedIndex();
|
---|
722 | Object selected_classifier = classifier_list.getSelectedValue();
|
---|
723 | if (!(selected_classifier instanceof Classifier)) {
|
---|
724 | return; // what else could we have here???
|
---|
725 | }
|
---|
726 | removeClassifier((Classifier)selected_classifier);
|
---|
727 |
|
---|
728 | if (selected_index >= classifier_list.getModel().getSize()) {
|
---|
729 | selected_index--;
|
---|
730 | }
|
---|
731 | if (selected_index >=0) {
|
---|
732 | classifier_list.setSelectedIndex(selected_index);
|
---|
733 | } else {
|
---|
734 | // no more classifiers in the list
|
---|
735 | remove.setEnabled(false);
|
---|
736 | }
|
---|
737 | }
|
---|
738 | }
|
---|
739 | }
|
---|
740 | }
|
---|