source: trunk/gli/src/org/greenstone/gatherer/cdm/SubcollectionManager.java@ 11039

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

Removed a bit of dead code.

  • Property svn:keywords set to Author Date Id Revision
File size: 23.1 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
29
30import java.awt.*;
31import java.awt.event.*;
32import java.util.*;
33import javax.swing.*;
34import javax.swing.event.*;
35import org.greenstone.gatherer.Configuration;
36import org.greenstone.gatherer.DebugStream;
37import org.greenstone.gatherer.Dictionary;
38import org.greenstone.gatherer.Gatherer;
39import org.greenstone.gatherer.gui.DesignPaneHeader;
40import org.greenstone.gatherer.gui.GLIButton;
41import org.greenstone.gatherer.gui.NonWhitespaceField;
42import org.greenstone.gatherer.metadata.MetadataElement;
43import org.greenstone.gatherer.metadata.MetadataSetManager;
44import org.greenstone.gatherer.util.StaticStrings;
45import org.w3c.dom.*;
46
47/** This class maintains a list of subcollections within our collection.
48 * @author John Thompson, Greenstone Digital Library, University of Waikato
49 * @version 2.4
50 */
51public class SubcollectionManager
52 extends DOMProxyListModel {
53
54 static final private String DISABLED_CONTROLS = "Disabled";
55 static final private String ENABLED_CONTROLS = "Normal";
56 static final private String CLASS_DICTIONARY_NAME = "CDM.SubcollectionManager.";
57
58 /** The controls used to edit the settings of this manager. */
59 private Control controls = null;
60
61 private DOMProxyListModel model;
62
63 /** Constructor.
64 * @see org.greenstone.gatherer.Gatherer
65 * @see org.greenstone.gatherer.cdm.CollectionConfiguration
66 * @see org.greenstone.gatherer.cdm.CollectionDesignManager
67 * @see org.greenstone.gatherer.cdm.DOMProxyListModel
68 * @see org.greenstone.gatherer.cdm.Subcollection
69 */
70 public SubcollectionManager() {
71 super(CollectionDesignManager.collect_config.getDocumentElement(), StaticStrings.SUBCOLLECTION_ELEMENT, new Subcollection());
72 DebugStream.println("SubcollectionManager: " + getSize() + " subcollections parsed.");
73 this.model = this;
74 }
75
76 /** Method to add a new subcollection.
77 * @param subcollection the Subcollection to add
78 * @see org.greenstone.gatherer.Gatherer
79 * @see org.greenstone.gatherer.cdm.CollectionConfiguration
80 * @see org.greenstone.gatherer.cdm.DOMProxyListModel
81 * @see org.greenstone.gatherer.collection.CollectionManager
82 */
83 private void addSubcollection(Subcollection subcollection) {
84 if(!contains(subcollection)) {
85 Element element = subcollection.getElement();
86 // Locate where we should insert this new subcollection.
87 Node target_node = CollectionConfiguration.findInsertionPoint(element);
88 // Failing that we insert immediately after a language string
89 add(root, subcollection, target_node);
90 Gatherer.c_man.configurationChanged();
91 }
92 }
93
94 public void destroy() {
95 if(controls != null) {
96 controls.destroy();
97 controls = null;
98 }
99 }
100
101 /** Method to retrieve the controls for this manager.
102 * @return the Control used to edit the subcollection data
103 */
104 public Control getControls() {
105 if(controls == null) {
106 controls = new SubcollectionControl();
107 }
108 return controls;
109 }
110
111 /** Method to retrieve a certain subcollection by its name.
112 * @param name a String which is used as the key for finding the matching subcollection
113 * @return the requested Subcollection or null if no such subcollection exists.
114 */
115 private Subcollection getSubcollection(String name) {
116 Subcollection result = null;
117 int size = getSize();
118 for(int i = 0; i < size; i++) {
119 Subcollection subcollection = (Subcollection) getElementAt(i);
120 if(subcollection.getName().equals(name)) {
121 result = subcollection;
122 }
123 }
124 return result;
125 }
126
127
128 /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
129 * @param mode the new mode as an int
130 */
131 public void modeChanged(int mode) {
132 if(controls != null) {
133 ((SubcollectionControl)controls).modeChanged(mode);
134 }
135 }
136
137 /** Method to remove the given subcollection.
138 * @param subcollection the Subcollection you want to remove
139 * @see org.greenstone.gatherer.Gatherer
140 * @see org.greenstone.gatherer.collection.CollectionManager
141 */
142 private void removeSubcollection(Subcollection subcollection) {
143 remove(subcollection);
144 Gatherer.c_man.configurationChanged();
145 }
146
147 private void updateSubcollection(Subcollection subcollection, String name, boolean include, String source, String pattern, String flags) {
148 subcollection.setFlags(flags);
149 subcollection.setInclusive(include);
150 subcollection.setName(name);
151 subcollection.setPattern(pattern);
152 subcollection.setSource(source);
153 refresh(subcollection);
154 Gatherer.c_man.configurationChanged();
155 }
156
157 /** This class creates a JPanel containing serveral more controls used for editing subcollection information. */
158 private class SubcollectionControl
159 extends JPanel
160 implements Control, ChangeListener
161 {
162 private CardLayout card_layout;
163 private JButton add_button;
164 private JButton remove_button;
165 private JButton update_button;
166 private JComboBox source_combobox;
167 private JList subcollection_list;
168 private JPanel border_pane;
169 private JTabbedPane tabbed_pane;
170 private JTextField flags_field;
171 private JTextField match_field;
172 private JTextField name_field;
173 private JRadioButton exclude_button;
174 private JRadioButton include_button;
175
176 /** Constructor */
177 public SubcollectionControl() {
178 // Create
179 JPanel header_pane = new DesignPaneHeader("CDM.GUI.Subcollections", "partitionindexes");
180
181 border_pane = new JPanel();
182 card_layout = new CardLayout();
183
184 tabbed_pane = new JTabbedPane();
185 tabbed_pane.addChangeListener(this);
186
187 JPanel button_pane_3 = new JPanel();
188 add_button = new GLIButton();
189 add_button.setMnemonic(KeyEvent.VK_A);
190 add_button.setEnabled(false);
191 Dictionary.registerBoth(add_button, "CDM.SubcollectionManager.Add", "CDM.SubcollectionManager.Add_Tooltip");
192 remove_button = new GLIButton();
193 remove_button.setMnemonic(KeyEvent.VK_R);
194 remove_button.setEnabled(false);
195 Dictionary.registerBoth(remove_button, "CDM.SubcollectionManager.Remove", "CDM.SubcollectionManager.Remove_Tooltip");
196 update_button = new GLIButton();
197 update_button.setMnemonic(KeyEvent.VK_C);
198 update_button.setEnabled(false);
199 Dictionary.registerBoth(update_button, "CDM.SubcollectionManager.Replace", "CDM.SubcollectionManager.Replace_Tooltip");
200
201 JPanel button_pane = new JPanel();
202 JPanel button_pane_1 = new JPanel();
203 include_button = new JRadioButton();
204 include_button.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
205 include_button.setMnemonic(KeyEvent.VK_I);
206 include_button.setOpaque(false);
207 Dictionary.registerText(include_button, "CDM.SubcollectionManager.Include");
208 exclude_button = new JRadioButton();
209 exclude_button.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
210 exclude_button.setMnemonic(KeyEvent.VK_X);
211 exclude_button.setOpaque(false);
212 Dictionary.registerText(exclude_button, "CDM.SubcollectionManager.Exclude");
213
214 JLabel flags_label = new JLabel();
215 Dictionary.registerText(flags_label, "CDM.SubcollectionManager.Flags");
216 flags_field = new NonWhitespaceField();
217 Dictionary.registerTooltip(flags_field, "CDM.SubcollectionManager.Flags_Tooltip");
218
219 JPanel inclusive_pane = new JPanel();
220 JLabel inclusive_label = new JLabel();
221 Dictionary.registerText(inclusive_label, "CDM.SubcollectionManager.Inclusive");
222
223 JLabel match_label = new JLabel();
224 Dictionary.registerText(match_label, "CDM.SubcollectionManager.Match");
225 match_field = new JTextField();
226 Dictionary.registerTooltip(match_field, "CDM.SubcollectionManager.Match_Tooltip");
227
228 JLabel name_label = new JLabel();
229 Dictionary.registerText(name_label, "CDM.SubcollectionManager.Name");
230 name_field = new NonWhitespaceField();
231 Dictionary.registerTooltip(name_field, "CDM.SubcollectionManager.Name_Tooltip");
232
233 JLabel source_label = new JLabel();
234 Dictionary.registerText(source_label, "CDM.SubcollectionManager.Source");
235 ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
236 Vector source_model = new Vector(every_metadata_set_element);
237 source_model.add(0, StaticStrings.FILENAME_STR);
238 source_combobox = new JComboBox(source_model);
239 Dictionary.registerTooltip(source_combobox, "CDM.SubcollectionManager.Source_Tooltip");
240
241 subcollection_list = new JList(model);
242 subcollection_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
243 JPanel subcollection_pane = new JPanel();
244 ButtonGroup bg = new ButtonGroup();
245 bg.add(include_button);
246 bg.add(exclude_button);
247 include_button.setSelected(true);
248 JPanel subcollection_list_pane = new JPanel();
249 JLabel subcollection_list_label = new JLabel();
250 Dictionary.registerText(subcollection_list_label, "CDM.SubcollectionManager.Assigned");
251
252 // Create a message pane which explains why these controls are not currently active
253 JPanel message_pane = new JPanel();
254 String args[] = new String[3];
255 args[0] = Configuration.getModeAsString();
256 args[1] = Dictionary.get("Preferences.Mode.Systems");
257 args[2] = Dictionary.get("Preferences.Mode.Expert");
258 JTextArea message_textarea = new JTextArea();
259 Dictionary.registerText(message_textarea, "CDM.SubcollectionManager.Partitions_Disabled", args);
260 message_textarea.setEditable(false);
261 message_textarea.setHighlighter(null); // Prevent highlighting
262 message_textarea.setLineWrap(true);
263 message_textarea.setOpaque(false); // Make it transparent
264 message_textarea.setWrapStyleWord(true);
265
266 // Add listeners
267 SubCollectionChangeListener cl = new SubCollectionChangeListener();
268 add_button.addActionListener(new AddSubCollectionListener());
269 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
270 remove_button.addActionListener(new RemoveSubCollectionListener());
271 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
272 update_button.addActionListener(new UpdateSubCollectionListener());
273 update_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
274 exclude_button.addActionListener(cl);
275 include_button.addActionListener(cl);
276 source_combobox.addActionListener(cl);
277 flags_field.getDocument().addDocumentListener(cl);
278 match_field.getDocument().addDocumentListener(cl);
279 name_field.getDocument().addDocumentListener(cl);
280 subcollection_list.addListSelectionListener(new SubCollectionListListener());
281
282 inclusive_pane.setLayout(new GridLayout());
283 inclusive_pane.add(include_button);
284 inclusive_pane.add(exclude_button);
285
286 button_pane_1.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
287 button_pane_1.setLayout(new GridLayout(5, 2));
288 button_pane_1.add(name_label);
289 button_pane_1.add(name_field);
290 button_pane_1.add(source_label);
291 button_pane_1.add(source_combobox);
292 button_pane_1.add(match_label);
293 button_pane_1.add(match_field);
294 button_pane_1.add(inclusive_label);
295 button_pane_1.add(inclusive_pane);
296 button_pane_1.add(flags_label);
297 button_pane_1.add(flags_field);
298
299 button_pane_3.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
300 button_pane_3.setLayout(new GridLayout(1,3));
301 button_pane_3.add(add_button);
302 button_pane_3.add(update_button);
303 button_pane_3.add(remove_button);
304
305 button_pane.setLayout(new BorderLayout());
306 button_pane.add(button_pane_1, BorderLayout.CENTER);
307 button_pane.add(button_pane_3, BorderLayout.SOUTH);
308
309 subcollection_list_pane.setLayout(new BorderLayout());
310 subcollection_list_pane.add(subcollection_list_label, BorderLayout.NORTH);
311 subcollection_list_pane.add(new JScrollPane(subcollection_list), BorderLayout.CENTER);
312 subcollection_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
313 subcollection_pane.setLayout(new BorderLayout());
314 subcollection_pane.add(subcollection_list_pane, BorderLayout.CENTER);
315 subcollection_pane.add(button_pane, BorderLayout.SOUTH);
316
317 tabbed_pane.addTab(Dictionary.get("CDM.SubcollectionManager.Subcollection_Controls"), subcollection_pane);
318 tabbed_pane.addTab(Dictionary.get("CDM.SubcollectionManager.Subindex_Controls"), (JPanel) CollectionDesignManager.subcollectionindex_manager.getControls());
319 tabbed_pane.addTab(Dictionary.get("CDM.SubcollectionManager.Language_Controls"), (JPanel) CollectionDesignManager.language_manager.getControls());
320
321 message_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
322 message_pane.setLayout(new GridLayout(3,1,0,0));
323 message_pane.add(new JPanel());
324 message_pane.add(message_textarea);
325 message_pane.add(new JPanel());
326
327 border_pane.setLayout(card_layout);
328 if(Configuration.getMode() > Configuration.LIBRARIAN_MODE) {
329 border_pane.add(tabbed_pane, ENABLED_CONTROLS);
330 border_pane.add(message_pane, DISABLED_CONTROLS);
331 }
332 else {
333 border_pane.add(message_pane, DISABLED_CONTROLS);
334 border_pane.add(tabbed_pane, ENABLED_CONTROLS);
335 }
336
337 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
338 setLayout(new BorderLayout());
339 add(header_pane, BorderLayout.NORTH);
340 add(border_pane, BorderLayout.CENTER);
341 }
342
343 /** Method to unregister any listeners to avoid memory leaks.
344 */
345 public void destroy() {
346 }
347
348 public void gainFocus() {
349 // Rebuild the sources combobox
350 ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
351 Vector source_model = new Vector(every_metadata_set_element);
352 source_model.add(0, "Filename"); // Add filename as a possible source.
353 source_combobox.setModel(new DefaultComboBoxModel(source_model));
354 }
355
356 public void loseFocus() {
357 }
358
359 /** Called when the detail mode has changed which in turn controls if any of the partition controls are visible, or if they are instead replaced with a message explaining why they are not.
360 * @param mode the new mode as an int
361 */
362 public void modeChanged(int mode) {
363 if(mode > Configuration.LIBRARIAN_MODE) {
364 card_layout.show(border_pane, ENABLED_CONTROLS);
365 }
366 else {
367 card_layout.show(border_pane, DISABLED_CONTROLS);
368 }
369 }
370
371 public void stateChanged(ChangeEvent event)
372 {
373 if (tabbed_pane.getSelectedIndex() == 1) {
374 CollectionDesignManager.subcollectionindex_manager.getControls().gainFocus();
375 }
376 if (tabbed_pane.getSelectedIndex() == 2) {
377 CollectionDesignManager.language_manager.getControls().gainFocus();
378 }
379 }
380
381 /** Listens for actions apon the 'add' button in the SubcollectionManager controls, and if detected calls the addSubcollection method of the manager with a newly created subcollection. */
382 private class AddSubCollectionListener
383 implements ActionListener {
384 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we wish to retrieve information from the various edit controls, and if we have sufficient data to build a new subcollection do so.
385 * @param event An <strong>ActionEvent</strong> containing information about the event.
386 * @see org.greenstone.gatherer.cdm.Subcollection
387 */
388 public void actionPerformed(ActionEvent event) {
389 String name = name_field.getText();
390 String source = null;
391 Object object = source_combobox.getSelectedItem();
392 if (object instanceof MetadataElement) {
393 MetadataElement metadata_element = (MetadataElement) object;
394 source = metadata_element.getFullName();
395 }
396 else {
397 source = object.toString();
398 }
399 String pattern = match_field.getText();
400 String flags = flags_field.getText();
401 if(name.length() > 0 && (source == null || source.length() > 0) && pattern.length() > 0) {
402 Subcollection subcollection = new Subcollection(name, include_button.isSelected(), source, pattern, flags);
403 addSubcollection(subcollection);
404 // Change the selection to the new subcollection
405 subcollection_list.setSelectedValue(subcollection, true);
406 }
407 add_button.setEnabled(false);
408 }
409 }
410
411 /** This class listens for any key entry in a text field, selection change in a combobox or button click, and updates a subcollection as appropriate. Its also convenient to use this class to test if the add button should be active yet. */
412 private class SubCollectionChangeListener
413 implements DocumentListener, ActionListener {
414 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to record that somethings changed, then validate the controls.
415 * @param event An <strong>ActionEvent</strong> containing information about the event.
416 */
417 public void actionPerformed(ActionEvent event) {
418 validateAdd();
419 }
420
421 public void changedUpdate(DocumentEvent event) {
422 validateAdd();
423 }
424
425 public void insertUpdate(DocumentEvent event) {
426 validateAdd();
427
428 }
429
430 public void removeUpdate(DocumentEvent event) {
431 validateAdd();
432 }
433
434 /** Method to validate the current subcollection editor values, and enable or disable controls (add button) based on said values. */
435 private void validateAdd() {
436 if(name_field.getText().length() > 0 && match_field.getText().length() > 0) {
437 if (getSubcollection(name_field.getText()) == null) {
438 add_button.setEnabled(true);
439 } else {
440 add_button.setEnabled(false);
441 }
442 }
443 else {
444 add_button.setEnabled(false);
445 }
446 }
447 }
448
449 /** Listens for actions apon the 'remove' button in the SubcollectionManager controls, and if detected calls the remove method of the manager with the SubIndex selected for removal. */
450 private class RemoveSubCollectionListener
451 implements ActionListener {
452 /** Any implementation of ActionListener must include this method so we can be informed when an action has been performed on one of our target controls. In this case we want to check if they have a subcolleciton selected, and if so remove both it and any subindexes based on it.
453 * @param event An <strong>ActionEvent</strong> containing information about the event.
454 * @see org.greenstone.gatherer.cdm.Subcollection
455 */
456 public void actionPerformed(ActionEvent event) {
457 if(!subcollection_list.isSelectionEmpty()) {
458 Subcollection subcollection = (Subcollection)subcollection_list.getSelectedValue();
459 removeSubcollection(subcollection);
460 // And remove subcollection indexes dependant on this subcollection
461 CollectionDesignManager.subcollectionindex_manager.removeSubcollectionIndexes(subcollection);
462 }
463 remove_button.setEnabled(false);
464 }
465 }
466
467 private class UpdateSubCollectionListener
468 implements ActionListener {
469 public void actionPerformed(ActionEvent event) {
470 if(!subcollection_list.isSelectionEmpty()) {
471 Subcollection subcollection = (Subcollection)subcollection_list.getSelectedValue();
472 String name = name_field.getText();
473 String source = null;
474 Object object = source_combobox.getSelectedItem();
475 if (object instanceof MetadataElement) {
476 MetadataElement metadata_element = (MetadataElement) object;
477 source = metadata_element.getFullName();
478 }
479 else {
480 source = object.toString();
481 }
482 String pattern = match_field.getText();
483 String flags = flags_field.getText();
484 if(name.length() > 0 && (source == null || source.length() > 0) && pattern.length() > 0) {
485 updateSubcollection(subcollection, name, include_button.isSelected(), source, pattern, flags);
486 }
487 }
488 }
489 }
490
491 /** This class listens for selections in the list on the subcollections pane of the SubcollectionManager, and updates the controls as necessary to reflect selection. */
492 private class SubCollectionListListener
493 implements ListSelectionListener {
494 /** Any implementation of ListSelectionListener must include this method so we can be informed when the selection changes. In this case we want to execute any changes the users made to the entry, then update the controls with details of the new selection.
495 * @param event A <strong>ListSelectionEvent</strong> containing information related to this event.
496 * @see org.greenstone.gatherer.cdm.Subcollection
497 */
498 public void valueChanged(ListSelectionEvent event) {
499 // Wait until the event stabilises to avoid processing it multiple times
500 if (event.getValueIsAdjusting() == true) {
501 return;
502 }
503 // Now the entry
504 if(!subcollection_list.isSelectionEmpty()) {
505 Subcollection subcollection = (Subcollection) subcollection_list.getSelectedValue();
506 flags_field.setText(subcollection.getFlags());
507 include_button.setSelected(subcollection.isInclusive());
508 exclude_button.setSelected(!subcollection.isInclusive());
509 match_field.setText(subcollection.getPattern());
510 name_field.setText(subcollection.getName());
511 String s = subcollection.getSource();
512 int pos = 0;
513 Object value = source_combobox.getItemAt(pos);
514 //ystem.err.println("Search for: " + s);
515 while (value != null) {
516 if (value instanceof MetadataElement) {
517 MetadataElement metadata_element = (MetadataElement) value;
518 String metadata_element_name = metadata_element.getFullName();
519 //ystem.err.print("Compare to: " + e_name);
520 if (metadata_element_name.equals(s)) {
521 source_combobox.setSelectedIndex(pos);
522 value = null;
523 //ystem.err.println(" - Match");
524 }
525 else {
526 pos++;
527 value = source_combobox.getItemAt(pos);
528 //ystem.err.println(" - Fail");
529 }
530 }
531 else if(value.toString().equals(s)) {
532 source_combobox.setSelectedIndex(pos);
533 value = null;
534 }
535 else {
536 pos++;
537 value = source_combobox.getItemAt(pos);
538 }
539 }
540 // Can't add one thats already there.
541 add_button.setEnabled(false);
542 // You can update or remove it though...
543 remove_button.setEnabled(true);
544 update_button.setEnabled(true);
545 }
546 else {
547 flags_field.setText("");
548 include_button.setSelected(true);
549 match_field.setText("");
550 name_field.setText("");
551 source_combobox.setSelectedIndex(0);
552 remove_button.setEnabled(false);
553 update_button.setEnabled(false);
554 }
555 }
556 }
557 }
558}
Note: See TracBrowser for help on using the repository browser.