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 | * <BR><BR>
|
---|
9 | *
|
---|
10 | * Author: John Thompson, Greenstone Digital Library, University of Waikato
|
---|
11 | *
|
---|
12 | * <BR><BR>
|
---|
13 | *
|
---|
14 | * Copyright (C) 1999 New Zealand Digital Library Project
|
---|
15 | *
|
---|
16 | * <BR><BR>
|
---|
17 | *
|
---|
18 | * This program is free software; you can redistribute it and/or modify
|
---|
19 | * it under the terms of the GNU General Public License as published by
|
---|
20 | * the Free Software Foundation; either version 2 of the License, or
|
---|
21 | * (at your option) any later version.
|
---|
22 | *
|
---|
23 | * <BR><BR>
|
---|
24 | *
|
---|
25 | * This program is distributed in the hope that it will be useful,
|
---|
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
28 | * GNU General Public License for more details.
|
---|
29 | *
|
---|
30 | * <BR><BR>
|
---|
31 | *
|
---|
32 | * You should have received a copy of the GNU General Public License
|
---|
33 | * along with this program; if not, write to the Free Software
|
---|
34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
35 | *########################################################################
|
---|
36 | */
|
---|
37 |
|
---|
38 |
|
---|
39 |
|
---|
40 |
|
---|
41 |
|
---|
42 |
|
---|
43 | /* GPL_HEADER */
|
---|
44 | package org.greenstone.gatherer.cdm;
|
---|
45 | /**************************************************************************************
|
---|
46 | * Title: Gatherer
|
---|
47 | * Description: The Gatherer: a tool for gathering and enriching a digital collection.
|
---|
48 | * Company: The University of Waikato
|
---|
49 | * Written: 01/05/02
|
---|
50 | * Revised: 16/08/02 Optimized and Commented.
|
---|
51 | **************************************************************************************/
|
---|
52 | import java.awt.BorderLayout;
|
---|
53 | import java.awt.Color;
|
---|
54 | import java.awt.Component;
|
---|
55 | import java.awt.Dimension;
|
---|
56 | import java.awt.GridLayout;
|
---|
57 | import java.awt.event.ActionEvent;
|
---|
58 | import java.awt.event.ActionListener;
|
---|
59 | import java.awt.event.MouseAdapter;
|
---|
60 | import java.awt.event.MouseEvent;
|
---|
61 | import java.io.BufferedReader;
|
---|
62 | import java.io.File;
|
---|
63 | import java.io.FileInputStream;
|
---|
64 | import java.io.FileOutputStream;
|
---|
65 | import java.io.InputStream;
|
---|
66 | import java.io.InputStreamReader;
|
---|
67 | import java.io.ObjectInputStream;
|
---|
68 | import java.io.ObjectOutputStream;
|
---|
69 | import java.io.StringReader;
|
---|
70 | import java.lang.Exception;
|
---|
71 | import java.util.ArrayList;
|
---|
72 | import java.util.Collections;
|
---|
73 | import java.util.Enumeration;
|
---|
74 | import java.util.jar.JarFile;
|
---|
75 | import javax.swing.BorderFactory;
|
---|
76 | import javax.swing.DefaultListCellRenderer;
|
---|
77 | import javax.swing.JButton;
|
---|
78 | import javax.swing.JComboBox;
|
---|
79 | import javax.swing.JLabel;
|
---|
80 | import javax.swing.JList;
|
---|
81 | import javax.swing.JOptionPane;
|
---|
82 | import javax.swing.JPanel;
|
---|
83 | import javax.swing.JScrollPane;
|
---|
84 | import javax.swing.JTextArea;
|
---|
85 | import javax.swing.event.ListSelectionEvent;
|
---|
86 | import javax.swing.event.ListSelectionListener;
|
---|
87 | import org.apache.xerces.parsers.DOMParser;
|
---|
88 | import org.greenstone.gatherer.Gatherer;
|
---|
89 | import org.greenstone.gatherer.cdm.Argument;
|
---|
90 | import org.greenstone.gatherer.cdm.CollectionDesignManager;
|
---|
91 | import org.greenstone.gatherer.cdm.CommandTokenizer;
|
---|
92 | import org.greenstone.gatherer.cdm.Classifier;
|
---|
93 | import org.greenstone.gatherer.cdm.CustomClassifier;
|
---|
94 | import org.greenstone.gatherer.cdm.DynamicListModel;
|
---|
95 | import org.greenstone.gatherer.file.FileNode;
|
---|
96 | import org.greenstone.gatherer.msm.MSMEvent;
|
---|
97 | import org.greenstone.gatherer.msm.MSMListener;
|
---|
98 | import org.greenstone.gatherer.msm.MSMUtils;
|
---|
99 | import org.greenstone.gatherer.util.Utility;
|
---|
100 | import org.w3c.dom.Document;
|
---|
101 | import org.w3c.dom.Node;
|
---|
102 | import org.xml.sax.InputSource;
|
---|
103 | /** This class is responsible for keeping track of all the classifiers assigned to this collection, and providing methods for adding and removing them.
|
---|
104 | * @author John Thompson, Greenstone Digital Library, University of Waikato
|
---|
105 | * @version 2.3
|
---|
106 | */
|
---|
107 | // ####################################################################################
|
---|
108 | // Optimization Saving
|
---|
109 | // ####################################################################################
|
---|
110 | // Vector -> ArrayList + Memory, + Processor, (pos. - Processor)
|
---|
111 | // Unnecessary global references + Memory (5Kb+)
|
---|
112 | // ####################################################################################
|
---|
113 | public class ClassifierManager
|
---|
114 | implements MSMListener {
|
---|
115 | /** An interface to the Gatherer, the creator of this cdm module, for access to the Greenstone installation directory. */
|
---|
116 | private Gatherer gatherer = null;
|
---|
117 | /** A reference to the CollectionDesignManager for access to other configuration managers. */
|
---|
118 | private CollectionDesignManager manager = null;
|
---|
119 | /** The controls for editing the contents of this manager. */
|
---|
120 | private Control controls = null;
|
---|
121 | /** A list of assigned classifiers. */
|
---|
122 | private DynamicListModel assigned = null;
|
---|
123 | /** A list of known, but currently unassigned, classifiers. */
|
---|
124 | private DynamicListModel reserve = null;
|
---|
125 | /** We may have somehow recieved a classifier command that are, in fact, custom classifiers which can refer to classifiers that haven't been parsed yet, so this holds a list of failed commands which are retried after the loading is complete. */
|
---|
126 | private ArrayList unresolved_commands = null;
|
---|
127 | /** Constructor.
|
---|
128 | * @param gatherer A reference to the <strong>Gatherer</strong> for access to the Dictionary.
|
---|
129 | * @param manager A reference to the <strong>CollectionDesignManager</strong> itself.
|
---|
130 | * @see org.greenstone.gatherer.Gatherer
|
---|
131 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
132 | * @see org.greenstone.gatherer.collection.CollectionManager
|
---|
133 | * @see org.greenstone.gatherer.msm.MetadataSetManager
|
---|
134 | * @see org.greenstone.gatherer.msm.MSMListener
|
---|
135 | */
|
---|
136 | public ClassifierManager(Gatherer gatherer, CollectionDesignManager manager) {
|
---|
137 | this.assigned = new DynamicListModel();
|
---|
138 | this.gatherer = gatherer;
|
---|
139 | this.manager = manager;
|
---|
140 | this.unresolved_commands = new ArrayList();
|
---|
141 | loadClassifiers();
|
---|
142 | saveClassifiers();
|
---|
143 | // Register as a MSMListener.
|
---|
144 | Gatherer.c_man.getCollection().msm.addMSMListener(this);
|
---|
145 | }
|
---|
146 | /** Method to add a new classifier to reserve.
|
---|
147 | * @param classifier The new <strong>Classifier</strong>.
|
---|
148 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
149 | */
|
---|
150 | public void addClassifier(Classifier classifier) {
|
---|
151 | if(!reserve.contains(classifier)) {
|
---|
152 | reserve.addElement(classifier);
|
---|
153 | }
|
---|
154 | }
|
---|
155 | /** Method to assign a classifier.
|
---|
156 | * @param classifier The reserve <strong>Classifier</strong> to assign.
|
---|
157 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
158 | */
|
---|
159 | public void assignClassifier(Classifier classifier) {
|
---|
160 | if(!assigned.contains(classifier)) {
|
---|
161 | assigned.addElement(classifier);
|
---|
162 | classifier.setManager(this);
|
---|
163 | gatherer.c_man.configurationChanged();
|
---|
164 | }
|
---|
165 | }
|
---|
166 | /** Method to assign a classifier.
|
---|
167 | * @param classifier The <strong>CustomClassifier</strong> to assign.
|
---|
168 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
169 | */
|
---|
170 | public void assignClassifier(CustomClassifier classifier) {
|
---|
171 | if(!assigned.contains(classifier)) {
|
---|
172 | assigned.addElement(classifier);
|
---|
173 | classifier.setManager(this);
|
---|
174 | gatherer.c_man.configurationChanged();
|
---|
175 | }
|
---|
176 | }
|
---|
177 | /** Destructor.
|
---|
178 | * @see org.greenstone.gatherer.Gatherer
|
---|
179 | * @see org.greenstone.gatherer.cdm.CollectionDesignManager
|
---|
180 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
181 | */
|
---|
182 | public void destroy() {
|
---|
183 | // Deregister as a listener
|
---|
184 | if(gatherer.c_man != null && gatherer.c_man.msm != null) {
|
---|
185 | gatherer.c_man.msm.removeMSMListener(this);
|
---|
186 | }
|
---|
187 | // Null globals
|
---|
188 | assigned = null;
|
---|
189 | controls = null;
|
---|
190 | gatherer = null;
|
---|
191 | manager = null;
|
---|
192 | reserve = null;
|
---|
193 | unresolved_commands = null;
|
---|
194 | }
|
---|
195 | /** Method to retrieve the classifier with the given index.
|
---|
196 | * @param index The index of the desired classifier as an <i>int</i>.
|
---|
197 | * @return The requested Classifier as an <strong>Object</strong> or <i>null</i> if no such classifier exists.
|
---|
198 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
199 | */
|
---|
200 | public Object getClassifier(int index) {
|
---|
201 | if(0 <= index && index < assigned.size()) {
|
---|
202 | return assigned.get(index);
|
---|
203 | }
|
---|
204 | return null;
|
---|
205 | }
|
---|
206 | /** Method to retrieve the named classifier.
|
---|
207 | * @param name The name of the desired classifier as a <strong>String</strong>.
|
---|
208 | * @return The requested <strong>Classifier</strong> or <i>null</i> if no such classifier exists.
|
---|
209 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
210 | */
|
---|
211 | public Classifier getClassifier(String name) {
|
---|
212 | for(int i = 0; i < reserve.size(); i++) {
|
---|
213 | Classifier classifier = (Classifier)reserve.get(i);
|
---|
214 | if(classifier.getName().equals(name)) {
|
---|
215 | return classifier;
|
---|
216 | }
|
---|
217 | }
|
---|
218 | // No success.
|
---|
219 | return null;
|
---|
220 | }
|
---|
221 | /** Method to retrieve the control for this manager.
|
---|
222 | * @return A <strong>JPanel</strong> containing the controls.
|
---|
223 | */
|
---|
224 | public JPanel getControls() {
|
---|
225 | if(controls == null) {
|
---|
226 | controls = new Control();
|
---|
227 | }
|
---|
228 | return controls;
|
---|
229 | }
|
---|
230 | /** Called whenever a metadata element changes significantly.
|
---|
231 | * @param event A <strong>MSMEvent</strong> choc' full of event informationy goodness.
|
---|
232 | */
|
---|
233 | public void elementChanged(MSMEvent event) {
|
---|
234 | // Don't really care, as the elements dealt with here are all live references so changes like identifier change will propagate immediately.
|
---|
235 | }
|
---|
236 | /** Method to find the index of the given classifier within the assigned classifiers.
|
---|
237 | * @param classifier The <strong>Classifier</strong> whose index you wish to find.
|
---|
238 | * @return The index of the classifier as an <i>int</i>, which has a value of -1 if the classifier was not found.
|
---|
239 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
240 | */
|
---|
241 | public int indexOf(Classifier classifier) {
|
---|
242 | for(int i = 0; i < assigned.size(); i++) {
|
---|
243 | Classifier sibling = (Classifier) assigned.get(i);
|
---|
244 | if(sibling.equals(classifier)) {
|
---|
245 | return i;
|
---|
246 | }
|
---|
247 | }
|
---|
248 | return -1;
|
---|
249 | }
|
---|
250 | /** Method to invalidate controls after a significant change in the system state.
|
---|
251 | */
|
---|
252 | public void invalidateControls() {
|
---|
253 | if(controls != null) {
|
---|
254 | controls.destroy();
|
---|
255 | }
|
---|
256 | controls = null;
|
---|
257 | }
|
---|
258 | /** Method to load the details of a single plug-in.
|
---|
259 | * @param classifier The classifier <strong>File</strong> you wish to load.
|
---|
260 | */
|
---|
261 | public void loadClassifier(File classifier) {
|
---|
262 | ///ystem.err.println("Attempting to parse " + classifier.toString());
|
---|
263 | Document document = null;
|
---|
264 | long start;
|
---|
265 | long end;
|
---|
266 | // Run classinfo on this classifier, and then send the results for parsing.
|
---|
267 | try {
|
---|
268 | String args[] = null;
|
---|
269 | if(Utility.isWindows()) {
|
---|
270 | args = new String[4];
|
---|
271 | if(Gatherer.config.perl_path != null) {
|
---|
272 | args[0] = gatherer.config.perl_path + "Perl.exe";
|
---|
273 | }
|
---|
274 | else {
|
---|
275 | args[0] = "Perl.exe";
|
---|
276 | }
|
---|
277 | args[1] = gatherer.config.gsdl_path + "bin" + File.separator + "script" + File.separator + "classinfo.pl";
|
---|
278 | args[2] = "-xml";
|
---|
279 | args[3] = getClassifierName(classifier);
|
---|
280 | }
|
---|
281 | else {
|
---|
282 | args = new String[3];
|
---|
283 | args[0] = "classinfo.pl";
|
---|
284 | args[1] = "-xml";
|
---|
285 | args[2] = getClassifierName(classifier);
|
---|
286 | }
|
---|
287 |
|
---|
288 | // Create the process.
|
---|
289 | Runtime runtime = Runtime.getRuntime();
|
---|
290 | Process process = runtime.exec(args);
|
---|
291 | InputStream input_stream = process.getErrorStream();
|
---|
292 | BufferedReader error_in = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
---|
293 | String line = "";
|
---|
294 | StringBuffer xml = new StringBuffer("");
|
---|
295 | while((line = error_in.readLine()) != null) {
|
---|
296 | xml.append(line);
|
---|
297 | xml.append("\n");
|
---|
298 | }
|
---|
299 | // Then read the xml from the piped input stream.
|
---|
300 | InputSource source = new InputSource(new StringReader(xml.toString()));
|
---|
301 | DOMParser parser = new DOMParser();
|
---|
302 | parser.parse(source);
|
---|
303 | document = parser.getDocument();
|
---|
304 | }
|
---|
305 | catch (Exception error) {
|
---|
306 | error.printStackTrace();
|
---|
307 | //ystem.err.println("Error: Cannot parse " + getClassifierName(classifier));
|
---|
308 | }
|
---|
309 | if(document != null) {
|
---|
310 | parse(document.getDocumentElement());
|
---|
311 | }
|
---|
312 | }
|
---|
313 | /** Called whenever the metadata value associated to a certain record changes. */
|
---|
314 | public void metadataChanged(MSMEvent event) {
|
---|
315 | FileNode record = event.getRecord();
|
---|
316 | if(record != null) {
|
---|
317 | for(int i = 0; i < assigned.size(); i++) {
|
---|
318 | Object object = assigned.get(i);
|
---|
319 | if(object instanceof CustomClassifier) {
|
---|
320 | CustomClassifier classifier = (CustomClassifier) object;
|
---|
321 | classifier.process(record);
|
---|
322 | }
|
---|
323 | }
|
---|
324 | }
|
---|
325 | }
|
---|
326 | /** This method attempts to parse a classifier command from a command string taken from the collection configuration file. This process is quite complex as not only must the correct classifier be matched but also all of the parameters given must be legal. If such a command is found, the classifier is immediately assigned.
|
---|
327 | * @param command The command <strong>String</strong> that may include classifier information.
|
---|
328 | * @return <i>true</i> if a classifier command was parsed, <i>false</i> otherwise.
|
---|
329 | * @see org.greenstone.gatherer.cdm.Argument
|
---|
330 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
331 | * @see org.greenstone.gatherer.cdm.CommandTokenizer
|
---|
332 | */
|
---|
333 | public boolean parse(String command) {
|
---|
334 | String command_lc = command.toLowerCase();
|
---|
335 | if(command_lc.startsWith("classify")) {
|
---|
336 | CommandTokenizer tokenizer = new CommandTokenizer(command);
|
---|
337 | if(tokenizer.countTokens() >= 2) {
|
---|
338 | tokenizer.nextToken(); // Throw away 'classifier'
|
---|
339 | String name = tokenizer.nextToken();
|
---|
340 | // Try to locate the classifier with this name.
|
---|
341 | Classifier classifier = getClassifier(name);
|
---|
342 | // And if successful start to parse the arguments.
|
---|
343 | if(classifier != null) {
|
---|
344 | // Take a copy.
|
---|
345 | classifier = classifier.copy();
|
---|
346 | String key = null;
|
---|
347 | while((key = tokenizer.nextToken()) != null) {
|
---|
348 | // Try to retrieve a matching argument.
|
---|
349 | Argument argument = classifier.getArgument(key);
|
---|
350 | if(argument != null) {
|
---|
351 | // Set as assigned.
|
---|
352 | argument.setAssigned(true);
|
---|
353 | // And if the argument is of a parameter type, parse a parameter.
|
---|
354 | if(argument.getType() != Argument.FLAG && tokenizer.hasMoreTokens()) {
|
---|
355 | String value = tokenizer.nextToken();
|
---|
356 | value = value.replace(':', MSMUtils.NS_SEP);
|
---|
357 | argument.setValue(value);
|
---|
358 | }
|
---|
359 | }
|
---|
360 | // Argument cannot be matched.
|
---|
361 | else {
|
---|
362 | String cur_key = key;
|
---|
363 | String value = tokenizer.nextToken();
|
---|
364 | if(value.startsWith("-")) {
|
---|
365 | key = value;
|
---|
366 | value = null;
|
---|
367 | }
|
---|
368 | else {
|
---|
369 | key = null;
|
---|
370 | }
|
---|
371 | String custom = classifier.getCustom();
|
---|
372 | if(custom == null) {
|
---|
373 | if(value == null) {
|
---|
374 | classifier.setCustom(cur_key);
|
---|
375 | }
|
---|
376 | else {
|
---|
377 | classifier.setCustom(cur_key + " " + value);
|
---|
378 | }
|
---|
379 | }
|
---|
380 | else {
|
---|
381 | if(value == null) {
|
---|
382 | classifier.setCustom(custom + " " + cur_key);
|
---|
383 | }
|
---|
384 | else {
|
---|
385 | classifier.setCustom(custom + " " + cur_key + " " + value);
|
---|
386 | }
|
---|
387 | }
|
---|
388 | }
|
---|
389 | }
|
---|
390 | assignClassifier(classifier);
|
---|
391 | return true;
|
---|
392 | }
|
---|
393 | else {
|
---|
394 | ///ystem.err.println("Unknown classifier");
|
---|
395 | }
|
---|
396 | }
|
---|
397 | }
|
---|
398 | else if(command_lc.startsWith("customclassifier")) {
|
---|
399 | unresolved_commands.add(command);
|
---|
400 | return true;
|
---|
401 | }
|
---|
402 | return false;
|
---|
403 | }
|
---|
404 | /** 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 reserve.
|
---|
405 | * @param classifier The Classifier or CustomClassifier, as an <strong>Object</strong>, to remove.
|
---|
406 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
407 | */
|
---|
408 | public void removeClassifier(Object classifier) {
|
---|
409 | assigned.removeElement(classifier);
|
---|
410 | gatherer.c_man.configurationChanged();
|
---|
411 | }
|
---|
412 | /** Method which attempts to reparse obvious classifier commands which previously referenced unresovable Classifiers.
|
---|
413 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
414 | * @see org.greenstone.gatherer.cdm.CommandTokenizer
|
---|
415 | * @see org.greenstone.gatherer.cdm.CustomClassifier
|
---|
416 | */
|
---|
417 | public void reparseUnresolved() {
|
---|
418 | for(int i = 0; i < unresolved_commands.size(); i++) {
|
---|
419 | String command = (String) unresolved_commands.get(i);
|
---|
420 | CommandTokenizer tokenizer = new CommandTokenizer(command);
|
---|
421 | if(tokenizer.countTokens() >= 6) {
|
---|
422 | tokenizer.nextToken();// Loose customclassifier
|
---|
423 | // Get class name.
|
---|
424 | String class_name = tokenizer.nextToken();
|
---|
425 | // Parse arguments.
|
---|
426 | String replaces = null;
|
---|
427 | String separations = null;
|
---|
428 | while(tokenizer.hasMoreTokens()) {
|
---|
429 | String arg_name = tokenizer.nextToken();
|
---|
430 | if(arg_name.equalsIgnoreCase("-replaces")) {
|
---|
431 | replaces = tokenizer.nextToken();
|
---|
432 | }
|
---|
433 | else {
|
---|
434 | separations = tokenizer.nextToken();
|
---|
435 | }
|
---|
436 | }
|
---|
437 | try {
|
---|
438 | replaces = replaces.substring(2);
|
---|
439 | int index = Integer.parseInt(replaces);
|
---|
440 | Classifier original = (Classifier)getClassifier(index);
|
---|
441 | if(original != null) {
|
---|
442 | Class custom_classifier_class = Class.forName("org.greenstone.gatherer.cdm.custom." + class_name);
|
---|
443 | CustomClassifier custom_classifier = (CustomClassifier) custom_classifier_class.newInstance();
|
---|
444 | custom_classifier.setGatherer(gatherer);
|
---|
445 | custom_classifier.recreate(original, separations);
|
---|
446 | assigned.add(indexOf(original), custom_classifier);
|
---|
447 | assigned.removeElement(original);
|
---|
448 | }
|
---|
449 | else {
|
---|
450 | ///ystem.err.println("Missing original.");
|
---|
451 | }
|
---|
452 | }
|
---|
453 | catch (Exception error) {
|
---|
454 | error.printStackTrace();
|
---|
455 | }
|
---|
456 | }
|
---|
457 | }
|
---|
458 | // Regardless of if they work, clear the commands.
|
---|
459 | unresolved_commands.clear();
|
---|
460 | }
|
---|
461 | /** Method to cache the current contents of reserve (known classifiers) to file.
|
---|
462 | * @see org.greenstone.gatherer.util.Utility
|
---|
463 | */
|
---|
464 | public void saveClassifiers() {
|
---|
465 | try {
|
---|
466 | FileOutputStream file = new FileOutputStream(Utility.BASE_DIR + "classifiers.dat");
|
---|
467 | ObjectOutputStream out = new ObjectOutputStream(file);
|
---|
468 | out.writeObject(reserve);
|
---|
469 | out.close();
|
---|
470 | }
|
---|
471 | catch (Exception error) {
|
---|
472 | }
|
---|
473 | }
|
---|
474 | /** Called when a metadata set changed significantly.
|
---|
475 | * @param event A <strong>MSMEvent</strong> containing information about the set change.
|
---|
476 | */
|
---|
477 | public void setChanged(MSMEvent event) {
|
---|
478 | // Again, we would only worry about this if we contained 'inanimate' references to elements or something, but our references are live, and controls are rebuilt everytime a pop-up is needed.
|
---|
479 | }
|
---|
480 | /** Method used to determine the number of classifiers that have been assigned.
|
---|
481 | * @return An <i>int</i> which is the number of classifiers.
|
---|
482 | */
|
---|
483 | public int size() {
|
---|
484 | return assigned.size();
|
---|
485 | }
|
---|
486 | /** Method to print out a block of classifier commands, much like you'd find in a collection configuration file.
|
---|
487 | * @return A <strong>String</strong> containing a series of classifier commands separated by new lines.
|
---|
488 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
489 | * @see org.greenstone.gatherer.cdm.CustomClassifier
|
---|
490 | */
|
---|
491 | public String toString() {
|
---|
492 | StringBuffer text = new StringBuffer();
|
---|
493 | for(int i = 0; i < assigned.size(); i++) {
|
---|
494 | Object object = assigned.get(i);
|
---|
495 | if(object instanceof Classifier) {
|
---|
496 | Classifier classifier = (Classifier) object;
|
---|
497 | text.append(classifier.toString());
|
---|
498 | }
|
---|
499 | else if(object instanceof CustomClassifier) {
|
---|
500 | CustomClassifier classifier = (CustomClassifier) object;
|
---|
501 | text.append(classifier.getCommand());
|
---|
502 | text.append("\n");
|
---|
503 | text.append(classifier.getCustomCommand(i));
|
---|
504 | }
|
---|
505 | text.append("\n");
|
---|
506 | }
|
---|
507 | text.append("\n");
|
---|
508 | return text.toString();
|
---|
509 | }
|
---|
510 | /** Called when a significant change has occured to a value tree for a certain element, however we take no further action.
|
---|
511 | * @param event A <strong>MSMEvent</strong> containing information relevant to the event.
|
---|
512 | */
|
---|
513 | public void valueChanged(MSMEvent event) {
|
---|
514 | }
|
---|
515 | /** Retrieve a phrase from the dictionary based on a certain key.
|
---|
516 | * @param key The search <strong>String</strong>.
|
---|
517 | * @return The matching phrase from the Dictionary.
|
---|
518 | */
|
---|
519 | private String get(String key) {
|
---|
520 | return get(key, null);
|
---|
521 | }
|
---|
522 | /** Retrieve a phrase from the dictionary based on a certain key and certain arguments.
|
---|
523 | * @param key The search <strong>String</strong>.
|
---|
524 | * @param args A <strong>String[]</strong> used to complete and format the returned phrase.
|
---|
525 | * @return The matching phrase from the Dictionary.
|
---|
526 | * @see org.greenstone.gatherer.Dictionary
|
---|
527 | * @see org.greenstone.gatherer.Gatherer
|
---|
528 | */
|
---|
529 | private String get(String key, String args[]) {
|
---|
530 | if(key.indexOf(".") == -1) {
|
---|
531 | key = "CDM.ClassifierManager." + key;
|
---|
532 | }
|
---|
533 | return gatherer.dictionary.get(key, args);
|
---|
534 | }
|
---|
535 | /** Method to extract just the classifiers name from a file object.
|
---|
536 | * @param classifier The <strong>File</strong> which references a certain classifier.
|
---|
537 | * @return A <strong>String</strong> containing just the classifiers name, without extension.
|
---|
538 | */
|
---|
539 | private String getClassifierName(File classifier) {
|
---|
540 | String name = classifier.getName();
|
---|
541 | if(name.indexOf(".") != -1) {
|
---|
542 | name = name.substring(0, name.indexOf("."));
|
---|
543 | }
|
---|
544 | return name;
|
---|
545 | }
|
---|
546 | /** Method to initially load information from the standard plug-ins within the gsdl Perl library.
|
---|
547 | * @see org.greenstone.gatherer.cdm.DynamicListModel
|
---|
548 | * @see org.greenstone.gatherer.util.Utility
|
---|
549 | */
|
---|
550 | private void loadClassifiers() {
|
---|
551 | // Attempt to restore the cached file.
|
---|
552 | try {
|
---|
553 | FileInputStream file = new FileInputStream(Utility.BASE_DIR + "classifiers.dat");
|
---|
554 | ObjectInputStream input = new ObjectInputStream(file);
|
---|
555 | reserve = (DynamicListModel) input.readObject();
|
---|
556 | }
|
---|
557 | catch (Exception error) {
|
---|
558 | }
|
---|
559 | if(reserve == null) {
|
---|
560 | reserve = new DynamicListModel();
|
---|
561 | // Retrieve the gsdl home directory...
|
---|
562 | String directory = gatherer.config.gsdl_path;
|
---|
563 | directory = directory + "perllib" + File.separator + "classify" + File.separator;
|
---|
564 | loadClassifiers(new File(directory));
|
---|
565 | }
|
---|
566 | }
|
---|
567 | /** Method to load plug-in information from a specified directory. Of course no plug-ins may be found at this location.
|
---|
568 | * @param directory A <strong>File</strong> indicating the directory to be scanned for plug-ins.
|
---|
569 | * @see org.greenstone.gatherer.cdm.ParsingProgress
|
---|
570 | */
|
---|
571 | private void loadClassifiers(File directory) {
|
---|
572 | File files[] = directory.listFiles();
|
---|
573 | if(files != null) {
|
---|
574 | // Create a progress indicator.
|
---|
575 | ParsingProgress progress = new ParsingProgress(get("CDM.ClassifierManager.Parsing.Title"), get("CDM.ClassifierManager.Parsing.Message"), files.length);
|
---|
576 | for(int i = 0; i < files.length; i++) {
|
---|
577 | // We only want to check Perl Modules.
|
---|
578 | if(files[i].getName().endsWith(".pm")) {
|
---|
579 | loadClassifier(files[i]);
|
---|
580 | }
|
---|
581 | progress.inc();
|
---|
582 | }
|
---|
583 | progress.dispose();
|
---|
584 | progress.destroy();
|
---|
585 | progress = null;
|
---|
586 | }
|
---|
587 | }
|
---|
588 | /** Parses a DOM tree model turning it into a Classifier and its associated arguments.
|
---|
589 | * @param root The <strong>Node</strong> at the root of the DOM model.
|
---|
590 | * @return A newly created <strong>Classifier</strong> based on the information parsed from the DOM model.
|
---|
591 | * @see org.greenstone.gatherer.cdm.Argument
|
---|
592 | */
|
---|
593 | private Classifier parse(Node root) {
|
---|
594 | Classifier classifier = new Classifier();
|
---|
595 | String node_name = null;
|
---|
596 | for(Node node = root.getFirstChild(); node != null;
|
---|
597 | node = node.getNextSibling()) {
|
---|
598 | node_name = node.getNodeName();
|
---|
599 | if(node_name.equals("Name")) {
|
---|
600 | String name = MSMUtils.getValue(node);
|
---|
601 | // 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.
|
---|
602 | Classifier existing = getClassifier(name);
|
---|
603 | if(existing != null) {
|
---|
604 | return existing;
|
---|
605 | }
|
---|
606 | classifier.setName(name);
|
---|
607 | }
|
---|
608 | else if(node_name.equals("Desc")) {
|
---|
609 | classifier.setDesc(MSMUtils.getValue(node));
|
---|
610 | }
|
---|
611 | // Parse the multitude of arguments.
|
---|
612 | else if(node_name.equals("Arguments")) {
|
---|
613 | for(Node arg = node.getFirstChild(); arg != null; arg = arg.getNextSibling()) {
|
---|
614 | node_name = arg.getNodeName();
|
---|
615 | // An option.
|
---|
616 | if(node_name.equals("Option")) {
|
---|
617 | Argument argument = new Argument();
|
---|
618 | // If its an option we parse the multitude of details an options might have.
|
---|
619 | for(Node det = arg.getFirstChild(); det != null; det = det.getNextSibling()) {
|
---|
620 | node_name = det.getNodeName();
|
---|
621 | if(node_name.equals("Name")) {
|
---|
622 | argument.setName(MSMUtils.getValue(det));
|
---|
623 | }
|
---|
624 | else if(node_name.equals("Desc")) {
|
---|
625 | argument.setDesc(MSMUtils.getValue(det));
|
---|
626 | }
|
---|
627 | else if(node_name.equals("Type")) {
|
---|
628 | argument.setType(MSMUtils.getValue(det));
|
---|
629 | }
|
---|
630 | else if(node_name.equals("Default")) {
|
---|
631 | argument.setDefault(MSMUtils.getValue(det));
|
---|
632 | }
|
---|
633 | else if(node_name.equals("List")) {
|
---|
634 | // Two final loops are required to parse lists.
|
---|
635 | for(Node value = det.getFirstChild(); value != null; value = value.getNextSibling()) {
|
---|
636 | if(value.getNodeName().equals("Value")) {
|
---|
637 | String key = null;
|
---|
638 | String desc = "";
|
---|
639 | for(Node subvalue = value.getFirstChild(); subvalue != null; subvalue = subvalue.getNextSibling()) {
|
---|
640 | node_name = subvalue.getNodeName();
|
---|
641 | if(node_name.equals("Name")) {
|
---|
642 | key = MSMUtils.getValue(subvalue);
|
---|
643 | }
|
---|
644 | else if(node_name.equals("Desc")) {
|
---|
645 | desc = MSMUtils.getValue(subvalue);
|
---|
646 | }
|
---|
647 | }
|
---|
648 | if(key != null) {
|
---|
649 | argument.addOption(key, desc);
|
---|
650 | }
|
---|
651 | }
|
---|
652 | }
|
---|
653 | }
|
---|
654 | else if(node_name.equals("Required")) {
|
---|
655 | String v = MSMUtils.getValue(det);
|
---|
656 | ///ystem.err.println("Required = " + v);
|
---|
657 | if(v.equalsIgnoreCase("yes")) {
|
---|
658 | ///ystem.err.println("Setting required to true.");
|
---|
659 | argument.setRequired(true);
|
---|
660 | }
|
---|
661 | }
|
---|
662 | }
|
---|
663 | classifier.addArgument(argument);
|
---|
664 | }
|
---|
665 | // A super classifier class.
|
---|
666 | else if(node_name.equals("ClasInfo")) {
|
---|
667 | Classifier super_classifier = parse(arg);
|
---|
668 | classifier.setSuper(super_classifier);
|
---|
669 | }
|
---|
670 | }
|
---|
671 | }
|
---|
672 | }
|
---|
673 | if(classifier.getName() != null) {
|
---|
674 | addClassifier(classifier);
|
---|
675 | return classifier;
|
---|
676 | }
|
---|
677 | return null;
|
---|
678 | }
|
---|
679 | /** A class which provides controls for assigned and editing classifiers. */
|
---|
680 | private class Control
|
---|
681 | extends JPanel {
|
---|
682 | /** Button for adding classifiers. */
|
---|
683 | private JButton add = null;
|
---|
684 | /** Button for configuring the selected classifier. */
|
---|
685 | private JButton configure = null;
|
---|
686 | /** Button to remove the selected classifier. */
|
---|
687 | private JButton remove = null;
|
---|
688 | /** A combobox containing all of the known classifiers, including those that may have already been assigned. */
|
---|
689 | private JComboBox classifier = null;
|
---|
690 | /** A list of assigned classifiers. */
|
---|
691 | private JList classifier_list = null;
|
---|
692 | /** The text area containing instructions on the use of this control. */
|
---|
693 | private JTextArea instructions = null;
|
---|
694 | /** Constructor.
|
---|
695 | * @see org.greenstone.gatherer.cdm.ClassifierManager.Control.AddListener
|
---|
696 | * @see org.greenstone.gatherer.cdm.ClassifierManager.Control.ConfigureListener
|
---|
697 | * @see org.greenstone.gatherer.cdm.ClassifierManager.Control.RemoveListener
|
---|
698 | */
|
---|
699 | public Control() {
|
---|
700 | Object classifiers[] = reserve.toArray();
|
---|
701 | ArrayList classifier_model = new ArrayList();
|
---|
702 | for(int i = 0; i < classifiers.length; i++) {
|
---|
703 | classifier_model.add(((Classifier)classifiers[i]).getName());
|
---|
704 | }
|
---|
705 | // Now we add custom classifiers.
|
---|
706 | addCustomClassifiers(classifier_model);
|
---|
707 | Collections.sort(classifier_model);
|
---|
708 | // Create
|
---|
709 | add = new JButton(get("Add"));
|
---|
710 | JPanel button_pane = new JPanel();
|
---|
711 | JPanel central_pane = new JPanel();
|
---|
712 | configure = new JButton(get("Configure"));
|
---|
713 | JPanel header_pane = new JPanel();
|
---|
714 | instructions = new JTextArea(get("Instructions"));
|
---|
715 | instructions.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
|
---|
716 | instructions.setEditable(false);
|
---|
717 | instructions.setLineWrap(true);
|
---|
718 | instructions.setRows(5);
|
---|
719 | instructions.setWrapStyleWord(true);
|
---|
720 | classifier = new JComboBox(classifier_model.toArray());
|
---|
721 | classifier.setEditable(true);
|
---|
722 | JLabel classifier_label = new JLabel(get("Classifier"));
|
---|
723 | classifier_list = new JList(assigned);
|
---|
724 | JLabel classifier_list_label = new JLabel(get("Assigned"));
|
---|
725 | classifier_list_label.setHorizontalAlignment(JLabel.CENTER);
|
---|
726 | classifier_list_label.setOpaque(true);
|
---|
727 | JPanel classifier_list_pane = new JPanel();
|
---|
728 | JPanel classifier_pane = new JPanel();
|
---|
729 | remove = new JButton(get("Remove"));
|
---|
730 | JLabel title = new JLabel(get("Title"));
|
---|
731 | title.setHorizontalAlignment(JLabel.CENTER);
|
---|
732 | title.setOpaque(true);
|
---|
733 | JPanel temp = new JPanel(new BorderLayout());
|
---|
734 | // Listeners
|
---|
735 | add.addActionListener(new AddListener());
|
---|
736 | configure.addActionListener(new ConfigureListener());
|
---|
737 | remove.addActionListener(new RemoveListener());
|
---|
738 | classifier_list.addMouseListener(new ClickListener());
|
---|
739 | // Layout
|
---|
740 | title.setBorder(BorderFactory.createEmptyBorder(0,0,2,0));
|
---|
741 | instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
|
---|
742 | header_pane.setLayout(new BorderLayout());
|
---|
743 | header_pane.add(title, BorderLayout.NORTH);
|
---|
744 | header_pane.add(new JScrollPane(instructions), BorderLayout.CENTER);
|
---|
745 | classifier_list_label.setBorder(BorderFactory.createEmptyBorder(0,2,0,2));
|
---|
746 | classifier_list_pane.setLayout(new BorderLayout());
|
---|
747 | classifier_list_pane.add(classifier_list_label, BorderLayout.NORTH);
|
---|
748 | classifier_list_pane.add(new JScrollPane(classifier_list), BorderLayout.CENTER);
|
---|
749 | classifier_label.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
|
---|
750 | classifier_pane.setBorder(BorderFactory.createEmptyBorder(5,0,5,0));
|
---|
751 | classifier_pane.setLayout(new GridLayout(1,2));
|
---|
752 | classifier_pane.add(classifier_label);
|
---|
753 | classifier_pane.add(classifier);
|
---|
754 | button_pane.setLayout(new GridLayout(3,1));
|
---|
755 | button_pane.add(add);
|
---|
756 | button_pane.add(configure);
|
---|
757 | button_pane.add(remove);
|
---|
758 | // Scope these mad bordering skillz.
|
---|
759 | temp.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,0,5,0), BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(get("Controls")), BorderFactory.createEmptyBorder(2,2,2,2))));
|
---|
760 | temp.add(classifier_pane, BorderLayout.NORTH);
|
---|
761 | temp.add(button_pane, BorderLayout.SOUTH);
|
---|
762 | central_pane.setLayout(new BorderLayout());
|
---|
763 | central_pane.add(classifier_list_pane, BorderLayout.CENTER);
|
---|
764 | central_pane.add(temp, BorderLayout.SOUTH);
|
---|
765 | setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
---|
766 | setLayout(new BorderLayout());
|
---|
767 | add(header_pane, BorderLayout.NORTH);
|
---|
768 | add(central_pane, BorderLayout.CENTER);
|
---|
769 | }
|
---|
770 | /** Method which acts like a destructor, tidying up references to persistant objects.
|
---|
771 | */
|
---|
772 | public void destroy() {
|
---|
773 | add = null;
|
---|
774 | classifier = null;
|
---|
775 | classifier_list = null;
|
---|
776 | configure = null;
|
---|
777 | instructions = null;
|
---|
778 | remove = null;
|
---|
779 | }
|
---|
780 | /** This method is overridden to ensure the instructions are scrolled to top, before the super classes updateUI() is called.
|
---|
781 | */
|
---|
782 | public void updateUI() {
|
---|
783 | if(instructions != null) {
|
---|
784 | instructions.setCaretPosition(0);
|
---|
785 | }
|
---|
786 | super.updateUI();
|
---|
787 | }
|
---|
788 | /** Searches and adds a list of dynamically located CustomClassifiers. Note that the classes must be located under org.greenstone.gatherer.cdm.custom and have accompaning properties files which are used as dictionaries.
|
---|
789 | * @param classifier_model An <strong>ArrayList</strong> which will be used as the model for the combobox listing all known Classifiers.
|
---|
790 | */
|
---|
791 | private void addCustomClassifiers(ArrayList classifier_model) {
|
---|
792 | //classifier_model.add("CustomAZList");
|
---|
793 | // Search for classifiers under the org.greenstone.gatherer.cdm.custom directory.
|
---|
794 | File custom_directory = new File(Utility.BASE_DIR + "classes" + File.separator + "org" + File.separator + "greenstone" + File.separator + "gatherer" + File.separator + "cdm" + File.separator + "custom");
|
---|
795 | if(custom_directory.exists()) {
|
---|
796 | File children[] = custom_directory.listFiles();
|
---|
797 | for(int i = 0; i < children.length; i++) {
|
---|
798 | String temp = children[i].getName().toLowerCase();
|
---|
799 | // There are a whole bunch of conditions about what files are custom classifier main classes.
|
---|
800 | if(temp.endsWith(".class") && temp.indexOf("$") == -1) {
|
---|
801 | // Determine the name of this custom classifier.
|
---|
802 | String name = children[i].getName();
|
---|
803 | name = name.substring(0, name.indexOf("."));
|
---|
804 | classifier_model.add(name);
|
---|
805 | }
|
---|
806 | }
|
---|
807 | }
|
---|
808 | // Search for any other CustomClassifiers within the jar file (if present)
|
---|
809 | File jar_file = new File("Gatherer.jar");
|
---|
810 | if(jar_file.exists()) {
|
---|
811 | try {
|
---|
812 | JarFile jar = new JarFile(jar_file);
|
---|
813 | for(Enumeration entries = jar.entries(); entries.hasMoreElements(); ) {
|
---|
814 | String name = entries.nextElement().toString();
|
---|
815 | if(name.startsWith("org/greenstone/gatherer/cdm/custom/") && name.endsWith(".class") && name.indexOf("$") == -1) {
|
---|
816 | name = name.substring(35, name.length() - 6);
|
---|
817 | if(!classifier_model.contains(name)) {
|
---|
818 | classifier_model.add(name);
|
---|
819 | }
|
---|
820 | }
|
---|
821 | name = null;
|
---|
822 | }
|
---|
823 | jar = null;
|
---|
824 | }
|
---|
825 | catch (Exception error) {
|
---|
826 | error.printStackTrace();
|
---|
827 | }
|
---|
828 | }
|
---|
829 | jar_file = null;
|
---|
830 | }
|
---|
831 | /** This class listens for actions upon the add button in the controls, and if detected calls the assignClassifier() method.
|
---|
832 | */
|
---|
833 | private class AddListener
|
---|
834 | implements ActionListener {
|
---|
835 | /** 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.
|
---|
836 | * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
|
---|
837 | * @see org.greenstone.gatherer.Gatherer
|
---|
838 | * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
|
---|
839 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
840 | * @see org.greenstone.gatherer.cdm.CustomClassifier
|
---|
841 | */
|
---|
842 | public void actionPerformed(ActionEvent event) {
|
---|
843 | String name = (String)classifier.getSelectedItem();
|
---|
844 | Classifier target = getClassifier(name);
|
---|
845 | Classifier classifier = null;
|
---|
846 | CustomClassifier custom_classifier = null;
|
---|
847 | if(target != null) {
|
---|
848 | classifier = target.copy();
|
---|
849 | }
|
---|
850 | else {
|
---|
851 | // Try to retrieve custom classifier for name.
|
---|
852 | try {
|
---|
853 | Class custom_class = Class.forName("org.greenstone.gatherer.cdm.custom." + name);
|
---|
854 | custom_classifier = (CustomClassifier)custom_class.newInstance();
|
---|
855 | custom_classifier.setGatherer(gatherer);
|
---|
856 | }
|
---|
857 | catch (Exception error) {
|
---|
858 | gatherer.debug(error, "Error in ClassifierManager.AddListener.actionPerformed(): " + error);
|
---|
859 | }
|
---|
860 | // And if all else fails create a new classifier.
|
---|
861 | if(classifier == null && custom_classifier == null) {
|
---|
862 | classifier = new Classifier(name, "", null);
|
---|
863 | }
|
---|
864 | }
|
---|
865 | if(classifier != null) {
|
---|
866 | // Automatically chain to configuration. This ensures required arguments are filled out.
|
---|
867 | ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, classifier);
|
---|
868 | if(ac.display()) {
|
---|
869 | assignClassifier(classifier);
|
---|
870 | }
|
---|
871 | ac.destroy();
|
---|
872 | ac = null;
|
---|
873 | }
|
---|
874 | // Custom classifier
|
---|
875 | else {
|
---|
876 | if(custom_classifier.display(true)) {
|
---|
877 | assignClassifier(custom_classifier);
|
---|
878 | }
|
---|
879 | custom_classifier.destroy(); // Remove gui prompt or else.
|
---|
880 | custom_classifier = null;
|
---|
881 | }
|
---|
882 | }
|
---|
883 | }
|
---|
884 | /** Listens for double clicks apon the list and react as if the configure button was pushed. */
|
---|
885 | private class ClickListener
|
---|
886 | extends MouseAdapter {
|
---|
887 | /** Called whenever the mouse is clicked over a registered component, we use this to chain through to the configure prompt.
|
---|
888 | * @param event A <strong>MouseEvent</strong> containing information about the mouse click.
|
---|
889 | */
|
---|
890 | public void mouseClicked(MouseEvent event) {
|
---|
891 | if(event.getClickCount() == 2 ) {
|
---|
892 | if(!classifier_list.isSelectionEmpty()) {
|
---|
893 | Object object = classifier_list.getSelectedValue();
|
---|
894 | if(object instanceof Classifier) {
|
---|
895 | ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, (Classifier)object);
|
---|
896 | if(ac.display()) {
|
---|
897 | assigned.refresh();
|
---|
898 | }
|
---|
899 | ac.destroy();
|
---|
900 | ac = null;
|
---|
901 | }
|
---|
902 | else if(object instanceof CustomClassifier) {
|
---|
903 | CustomClassifier cc = (CustomClassifier)object;
|
---|
904 | if(cc.display(true)) {
|
---|
905 | assigned.refresh();
|
---|
906 | }
|
---|
907 | cc.destroy(); // Remove gui prompt or else.
|
---|
908 | cc = null;
|
---|
909 | }
|
---|
910 | }
|
---|
911 | }
|
---|
912 | }
|
---|
913 | }
|
---|
914 | /** 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.
|
---|
915 | */
|
---|
916 | private class ConfigureListener
|
---|
917 | implements ActionListener {
|
---|
918 | /** 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.
|
---|
919 | * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
|
---|
920 | * @see org.greenstone.gatherer.cdm.ArgumentConfiguration
|
---|
921 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
922 | * @see org.greenstone.gatherer.cdm.CustomClassifier
|
---|
923 | */
|
---|
924 | public void actionPerformed(ActionEvent event) {
|
---|
925 | if(!classifier_list.isSelectionEmpty()) {
|
---|
926 | Object object = classifier_list.getSelectedValue();
|
---|
927 | if(object instanceof Classifier) {
|
---|
928 | ArgumentConfiguration ac = new ArgumentConfiguration(gatherer, manager, (Classifier)object);
|
---|
929 | if(ac.display()) {
|
---|
930 | assigned.refresh();
|
---|
931 | }
|
---|
932 | ac.destroy();
|
---|
933 | ac = null;
|
---|
934 | }
|
---|
935 | else if(object instanceof CustomClassifier) {
|
---|
936 | CustomClassifier cc = (CustomClassifier)object;
|
---|
937 | if(cc.display(true)) {
|
---|
938 | assigned.refresh();
|
---|
939 | }
|
---|
940 | cc.destroy(); // Remove gui prompt or else.
|
---|
941 | cc = null;
|
---|
942 | }
|
---|
943 | }
|
---|
944 | }
|
---|
945 | }
|
---|
946 | /** This class listens for actions upon the remove button in the controls, and if detected calls the removeClassifier() method.
|
---|
947 | */
|
---|
948 | private class RemoveListener
|
---|
949 | implements ActionListener {
|
---|
950 | /** 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, so we can remove the selected Classifier.
|
---|
951 | * @param event An <strong>ActionEvent</strong> containing information garnered from the control action.
|
---|
952 | * @see org.greenstone.gatherer.cdm.Classifier
|
---|
953 | * @see org.greenstone.gatherer.cdm.CustomClassifier
|
---|
954 | */
|
---|
955 | public void actionPerformed(ActionEvent event) {
|
---|
956 | if(!classifier_list.isSelectionEmpty()) {
|
---|
957 | Object object = classifier_list.getSelectedValue();
|
---|
958 | if(object instanceof Classifier || object instanceof CustomClassifier) {
|
---|
959 | removeClassifier(object);
|
---|
960 | }
|
---|
961 | }
|
---|
962 | }
|
---|
963 | }
|
---|
964 | }
|
---|
965 | }
|
---|
966 |
|
---|
967 |
|
---|
968 |
|
---|
969 |
|
---|
970 |
|
---|
971 |
|
---|