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

Last change on this file since 5593 was 5593, checked in by mdewsnip, 21 years ago

Changed calls to the Dictionary.

  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29/**************************************************************************************
30 * Written: ??/??/02
31 * Revised: 04/07/03 - DOM support
32 **************************************************************************************/
33import java.awt.*;
34import java.awt.event.*;
35import java.util.*;
36import javax.swing.*;
37import javax.swing.event.*;
38import org.greenstone.gatherer.Dictionary;
39import org.greenstone.gatherer.Gatherer;
40import org.greenstone.gatherer.cdm.CollectionConfiguration;
41import org.greenstone.gatherer.cdm.CollectionDesignManager;
42import org.greenstone.gatherer.cdm.Control;
43import org.greenstone.gatherer.cdm.DOMProxyListModel;
44import org.greenstone.gatherer.cdm.Subcollection;
45import org.greenstone.gatherer.gui.NonWhitespaceField;
46import org.greenstone.gatherer.msm.ElementWrapper;
47import org.greenstone.gatherer.msm.MSMUtils;
48import org.greenstone.gatherer.util.ExclusiveListSelectionListener;
49import org.greenstone.gatherer.util.StaticStrings;
50import org.greenstone.gatherer.util.Utility;
51import org.w3c.dom.*;
52
53/** This class maintains a list of subcollections within our collection.
54 * @author John Thompson, Greenstone Digital Library, University of Waikato
55 * @version 2.4
56 */
57public class SubcollectionManager
58 extends DOMProxyListModel {
59
60 static final private String CLASS_DICTIONARY_NAME = "CDM.SubcollectionManager.";
61
62 /** The controls used to edit the settings of this manager. */
63 private Control controls = null;
64
65 private DOMProxyListModel model;
66
67 /** Constructor.
68 * @see org.greenstone.gatherer.Gatherer
69 * @see org.greenstone.gatherer.cdm.CollectionConfiguration
70 * @see org.greenstone.gatherer.cdm.CollectionDesignManager
71 * @see org.greenstone.gatherer.cdm.DOMProxyListModel
72 * @see org.greenstone.gatherer.cdm.Subcollection
73 */
74 public SubcollectionManager() {
75 super(CollectionDesignManager.collect_config.getDocumentElement(), StaticStrings.SUBCOLLECTION_ELEMENT, new Subcollection());
76 Gatherer.println("SubcollectionManager: " + getSize() + " subcollections parsed.");
77 this.model = this;
78 }
79
80 /** Method to add a new subcollection.
81 * @param subcollection the Subcollection to add
82 * @see org.greenstone.gatherer.Gatherer
83 * @see org.greenstone.gatherer.cdm.CollectionConfiguration
84 * @see org.greenstone.gatherer.cdm.DOMProxyListModel
85 * @see org.greenstone.gatherer.collection.CollectionManager
86 */
87 public void addSubcollection(Subcollection subcollection) {
88 if(!contains(subcollection)) {
89 Element element = subcollection.getElement();
90 // Locate where we should insert this new subcollection.
91 Node target_node = CollectionConfiguration.findInsertionPoint(element);
92 // Failing that we insert immediately after a language string
93 add(root, subcollection, target_node);
94 Gatherer.c_man.configurationChanged();
95 }
96 }
97
98 public void destroy() {
99 if(controls != null) {
100 controls.destroy();
101 controls = null;
102 }
103 }
104
105 /** Method to retrieve the controls for this manager.
106 * @return the Control used to edit the subcollection data
107 */
108 public Control getControls() {
109 if(controls == null) {
110 controls = new SubcollectionControl();
111 }
112 return controls;
113 }
114
115 /** Method to retrieve a certain subcollection by its name.
116 * @param name a String which is used as the key for finding the matching subcollection
117 * @return the requested Subcollection or null if no such subcollection exists.
118 */
119 public Subcollection getSubcollection(String name) {
120 Subcollection result = null;
121 int size = getSize();
122 for(int i = 0; i < size; i++) {
123 Subcollection subcollection = (Subcollection) getElementAt(i);
124 if(subcollection.getName().equals(name)) {
125 result = subcollection;
126 }
127 }
128 return result;
129 }
130
131 /** Method to get all of the subcollections defined.
132 * @return an ArrayList of subcollections
133 */
134 public ArrayList getSubcollections() {
135 return children();
136 }
137
138 /** Method to remove the given subcollection.
139 * @param subcollection the Subcollection you want to remove
140 * @see org.greenstone.gatherer.Gatherer
141 * @see org.greenstone.gatherer.collection.CollectionManager
142 */
143 public void removeSubcollection(Subcollection subcollection) {
144 remove(subcollection);
145 Gatherer.c_man.configurationChanged();
146 }
147
148 public void updateSubcollection(Subcollection subcollection, String name, boolean include, String source, String pattern, String flags) {
149 subcollection.setFlags(flags);
150 subcollection.setInclusive(include);
151 subcollection.setName(name);
152 subcollection.setPattern(pattern);
153 subcollection.setSource(source);
154 refresh(subcollection);
155 Gatherer.c_man.configurationChanged();
156 }
157
158 /** This class creates a JPanel containing serveral more controls used for editing subcollection information. */
159 private class SubcollectionControl
160 extends JPanel
161 implements Control {
162
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 JTabbedPane tabbed_pane;
169 private JTextArea instructions_area;
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 border_pane = new JPanel();
180 JPanel header_pane = new JPanel();
181 instructions_area = new JTextArea();
182 instructions_area.setEditable(false);
183 instructions_area.setLineWrap(true);
184 instructions_area.setRows(6);
185 instructions_area.setWrapStyleWord(true);
186 Dictionary.registerText(instructions_area, "CDM.SubcollectionManager.Instructions");
187
188 tabbed_pane = new JTabbedPane();
189 JLabel title = new JLabel();
190 title.setHorizontalAlignment(JLabel.CENTER);
191 Dictionary.registerText(title, "CDM.SubcollectionManager.Title");
192
193 JPanel button_pane_3 = new JPanel();
194 add_button = new JButton();
195 add_button.setMnemonic(KeyEvent.VK_A);
196 add_button.setEnabled(false);
197 Dictionary.registerBoth(add_button, "CDM.SubcollectionManager.Add", "CDM.SubcollectionManager.Add_Tooltip");
198 remove_button = new JButton();
199 remove_button.setMnemonic(KeyEvent.VK_R);
200 remove_button.setEnabled(false);
201 Dictionary.registerBoth(remove_button, "CDM.SubcollectionManager.Remove", "CDM.SubcollectionManager.Remove_Tooltip");
202 update_button = new JButton();
203 update_button.setMnemonic(KeyEvent.VK_U);
204 update_button.setEnabled(false);
205 Dictionary.registerBoth(update_button, "CDM.SubcollectionManager.Replace", "CDM.SubcollectionManager.Replace_Tooltip");
206
207 JPanel button_pane = new JPanel();
208 JPanel button_pane_1 = new JPanel();
209 include_button = new JRadioButton();
210 include_button.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
211 include_button.setMnemonic(KeyEvent.VK_I);
212 include_button.setOpaque(false);
213 Dictionary.registerText(include_button, "CDM.SubcollectionManager.Include");
214 exclude_button = new JRadioButton();
215 exclude_button.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
216 exclude_button.setMnemonic(KeyEvent.VK_X);
217 exclude_button.setOpaque(false);
218 Dictionary.registerText(exclude_button, "CDM.SubcollectionManager.Exclude");
219
220 JLabel flags_label = new JLabel();
221 Dictionary.registerText(flags_label, "CDM.SubcollectionManager.Flags");
222 flags_field = new NonWhitespaceField();
223 Dictionary.registerTooltip(flags_field, "CDM.SubcollectionManager.Flags_Tooltip");
224
225 JPanel inclusive_pane = new JPanel();
226 JLabel inclusive_label = new JLabel();
227 Dictionary.registerText(inclusive_label, "CDM.SubcollectionManager.Inclusive");
228
229 JLabel match_label = new JLabel();
230 Dictionary.registerText(match_label, "CDM.SubcollectionManager.Match");
231 match_field = new JTextField();
232 Dictionary.registerTooltip(match_field, "CDM.SubcollectionManager.Match_Tooltip");
233
234 JLabel name_label = new JLabel();
235 Dictionary.registerText(name_label, "CDM.SubcollectionManager.Name");
236 name_field = new NonWhitespaceField();
237 Dictionary.registerTooltip(name_field, "CDM.SubcollectionManager.Name_Tooltip");
238
239 JLabel source_label = new JLabel();
240 Dictionary.registerText(source_label, "CDM.SubcollectionManager.Source");
241 Vector source_model = Gatherer.c_man.getCollection().msm.getAssignedElements();
242 source_model.add(0, StaticStrings.FILENAME_STR);
243 source_combobox = new JComboBox(source_model);
244 Dictionary.registerTooltip(source_combobox, "CDM.SubcollectionManager.Source_Tooltip");
245
246 subcollection_list = new JList(model);
247 subcollection_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
248 JPanel subcollection_pane = new JPanel();
249 ButtonGroup bg = new ButtonGroup();
250 bg.add(include_button);
251 bg.add(exclude_button);
252 include_button.setSelected(true);
253 JPanel subcollection_list_pane = new JPanel();
254 JLabel subcollection_list_label = new JLabel();
255 Dictionary.registerText(subcollection_list_label, "CDM.SubcollectionManager.Assigned");
256
257 // Add listeners
258 SubCollectionChangeListener cl = new SubCollectionChangeListener();
259 add_button.addActionListener(new AddSubCollectionListener());
260 remove_button.addActionListener(new RemoveSubCollectionListener());
261 update_button.addActionListener(new UpdateSubCollectionListener());
262 exclude_button.addActionListener(cl);
263 include_button.addActionListener(cl);
264 source_combobox.addActionListener(cl);
265 flags_field.getDocument().addDocumentListener(cl);
266 match_field.getDocument().addDocumentListener(cl);
267 name_field.getDocument().addDocumentListener(cl);
268 subcollection_list.addListSelectionListener(new SubCollectionListListener());
269
270 // Layout
271 instructions_area.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
272
273 header_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
274 header_pane.setLayout(new BorderLayout());
275 header_pane.add(title, BorderLayout.NORTH);
276 header_pane.add(new JScrollPane(instructions_area), BorderLayout.CENTER);
277
278 inclusive_pane.setLayout(new GridLayout());
279 inclusive_pane.add(include_button);
280 inclusive_pane.add(exclude_button);
281
282 button_pane_1.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
283 button_pane_1.setLayout(new GridLayout(5, 2));
284 button_pane_1.add(name_label);
285 button_pane_1.add(name_field);
286 button_pane_1.add(source_label);
287 button_pane_1.add(source_combobox);
288 button_pane_1.add(match_label);
289 button_pane_1.add(match_field);
290 button_pane_1.add(inclusive_label);
291 button_pane_1.add(inclusive_pane);
292 button_pane_1.add(flags_label);
293 button_pane_1.add(flags_field);
294
295 button_pane_3.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
296 button_pane_3.setLayout(new GridLayout(1,3));
297 button_pane_3.add(add_button);
298 button_pane_3.add(update_button);
299 button_pane_3.add(remove_button);
300
301 button_pane.setLayout(new BorderLayout());
302 button_pane.add(button_pane_1, BorderLayout.CENTER);
303 button_pane.add(button_pane_3, BorderLayout.SOUTH);
304
305 subcollection_list_pane.setLayout(new BorderLayout());
306 subcollection_list_pane.add(subcollection_list_label, BorderLayout.NORTH);
307 subcollection_list_pane.add(new JScrollPane(subcollection_list), BorderLayout.CENTER);
308 subcollection_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
309 subcollection_pane.setLayout(new BorderLayout());
310 subcollection_pane.add(subcollection_list_pane, BorderLayout.CENTER);
311 subcollection_pane.add(button_pane, BorderLayout.SOUTH);
312
313 tabbed_pane.addTab(Dictionary.get("CDM.SubcollectionManager.Subcollection_Controls"), subcollection_pane);
314 tabbed_pane.addTab(Dictionary.get("CDM.SubcollectionManager.Subindex_Controls"), (JPanel) CollectionDesignManager.subcollectionindex_manager.getControls());
315 tabbed_pane.addTab(Dictionary.get("CDM.SubcollectionManager.Language_Controls"), (JPanel) CollectionDesignManager.language_manager.getControls());
316
317 border_pane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
318 border_pane.setLayout(new BorderLayout());
319 border_pane.add(tabbed_pane, BorderLayout.CENTER);
320
321 setLayout(new BorderLayout());
322 add(header_pane, BorderLayout.NORTH);
323 add(border_pane, BorderLayout.CENTER);
324 }
325
326 /** Method to unregister any listeners to avoid memory leaks.
327 */
328 public void destroy() {
329 }
330
331 public void gainFocus() {
332 // Rebuild the sources combobox
333 Vector source_model = Gatherer.c_man.getCollection().msm.getAssignedElements();
334 source_model.add(0, "Filename"); // Add filename as a possible source.
335 source_combobox.setModel(new DefaultComboBoxModel(source_model));
336 }
337
338 public void loseFocus() {
339 }
340
341 /** 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. */
342 private class AddSubCollectionListener
343 implements ActionListener {
344 /** 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.
345 * @param event An <strong>ActionEvent</strong> containing information about the event.
346 * @see org.greenstone.gatherer.cdm.Subcollection
347 * @see org.greenstone.gatherer.msm.ElementWrapper
348 */
349 public void actionPerformed(ActionEvent event) {
350 String name = name_field.getText();
351 String source = null;
352 Object object = source_combobox.getSelectedItem();
353 if(object instanceof ElementWrapper) {
354 ElementWrapper element_wrapper = (ElementWrapper)object;
355 source = element_wrapper.getName();
356 if(source.indexOf(MSMUtils.NS_SEP) == -1) {
357 source = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + source;
358 }
359 }
360 else {
361 source = object.toString();
362 }
363 String pattern = match_field.getText();
364 String flags = flags_field.getText();
365 if(name.length() > 0 && (source == null || source.length() > 0) && pattern.length() > 0) {
366 Subcollection subcollection = new Subcollection(name, include_button.isSelected(), source, pattern, flags);
367 addSubcollection(subcollection);
368 // Change the selection to the new subcollection
369 subcollection_list.setSelectedValue(subcollection, true);
370 }
371 add_button.setEnabled(false);
372 }
373 }
374
375 /** 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. */
376 private class SubCollectionChangeListener
377 implements DocumentListener, ActionListener {
378 /** 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.
379 * @param event An <strong>ActionEvent</strong> containing information about the event.
380 */
381 public void actionPerformed(ActionEvent event) {
382 validateAdd();
383 }
384
385 public void changedUpdate(DocumentEvent event) {
386 validateAdd();
387 }
388
389 public void insertUpdate(DocumentEvent event) {
390 validateAdd();
391
392 }
393
394 public void removeUpdate(DocumentEvent event) {
395 validateAdd();
396 }
397
398 /** Method to validate the current subcollection editor values, and enable or disable controls (add button) based on said values. */
399 private void validateAdd() {
400 if(name_field.getText().length() > 0 && match_field.getText().length() > 0) {
401 if (getSubcollection(name_field.getText()) == null) {
402 add_button.setEnabled(true);
403 } else {
404 add_button.setEnabled(false);
405 }
406 }
407 else {
408 add_button.setEnabled(false);
409 }
410 }
411 }
412
413 /** 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. */
414 private class RemoveSubCollectionListener
415 implements ActionListener {
416 /** 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.
417 * @param event An <strong>ActionEvent</strong> containing information about the event.
418 * @see org.greenstone.gatherer.cdm.Subcollection
419 */
420 public void actionPerformed(ActionEvent event) {
421 if(!subcollection_list.isSelectionEmpty()) {
422 Subcollection subcollection = (Subcollection)subcollection_list.getSelectedValue();
423 removeSubcollection(subcollection);
424 // And remove subcollection indexes dependant on this subcollection
425 CollectionDesignManager.subcollectionindex_manager.removeSubcollectionIndexes(subcollection);
426 }
427 remove_button.setEnabled(false);
428 }
429 }
430
431 private class UpdateSubCollectionListener
432 implements ActionListener {
433 public void actionPerformed(ActionEvent event) {
434 if(!subcollection_list.isSelectionEmpty()) {
435 Subcollection subcollection = (Subcollection)subcollection_list.getSelectedValue();
436 String name = name_field.getText();
437 String source = null;
438 Object object = source_combobox.getSelectedItem();
439 if(object instanceof ElementWrapper) {
440 ElementWrapper element_wrapper = (ElementWrapper)object;
441 source = element_wrapper.getName();
442 if(source.indexOf(MSMUtils.NS_SEP) == -1) {
443 source = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + source;
444 }
445 }
446 else {
447 source = object.toString();
448 }
449 String pattern = match_field.getText();
450 String flags = flags_field.getText();
451 if(name.length() > 0 && (source == null || source.length() > 0) && pattern.length() > 0) {
452 updateSubcollection(subcollection, name, include_button.isSelected(), source, pattern, flags);
453 }
454 }
455 }
456 }
457
458 /** This class listens for selections in the list on the subcollections pane of the SubcollectionManager, and updates the controls as necessary to reflect selection. */
459 private class SubCollectionListListener
460 implements ListSelectionListener {
461 /** 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.
462 * @param event A <strong>ListSelectionEvent</strong> containing information related to this event.
463 * @see org.greenstone.gatherer.cdm.Subcollection
464 * @see org.greenstone.gatherer.msm.ElementWrapper
465 */
466 public void valueChanged(ListSelectionEvent event) {
467 // Now the entry
468 if(!subcollection_list.isSelectionEmpty()) {
469 Subcollection subcollection = (Subcollection) subcollection_list.getSelectedValue();
470 flags_field.setText(subcollection.getFlags());
471 include_button.setSelected(subcollection.isInclusive());
472 exclude_button.setSelected(!subcollection.isInclusive());
473 match_field.setText(subcollection.getPattern());
474 name_field.setText(subcollection.getName());
475 String s = subcollection.getSource();
476 int pos = 0;
477 Object value = source_combobox.getItemAt(pos);
478 //ystem.err.println("Search for: " + s);
479 while(value != null) {
480 if(value instanceof ElementWrapper) {
481 ElementWrapper e = (ElementWrapper) value;
482 String e_name = e.getName();
483 if(e_name.indexOf(MSMUtils.NS_SEP) == -1) {
484 e_name = Utility.EXTRACTED_METADATA_NAMESPACE + MSMUtils.NS_SEP + e_name;
485 }
486 //ystem.err.print("Compare to: " + e_name);
487 if(e_name.equals(s)) {
488 source_combobox.setSelectedIndex(pos);
489 value = null;
490 //ystem.err.println(" - Match");
491 }
492 else {
493 pos++;
494 value = source_combobox.getItemAt(pos);
495 //ystem.err.println(" - Fail");
496 }
497 }
498 else if(value.toString().equals(s)) {
499 source_combobox.setSelectedIndex(pos);
500 value = null;
501 }
502 else {
503 pos++;
504 value = source_combobox.getItemAt(pos);
505 }
506 }
507 // Can't add one thats already there.
508 add_button.setEnabled(false);
509 // You can update or remove it though...
510 remove_button.setEnabled(true);
511 update_button.setEnabled(true);
512 }
513 else {
514 flags_field.setText("");
515 include_button.setSelected(true);
516 match_field.setText("");
517 name_field.setText("");
518 source_combobox.setSelectedIndex(0);
519 remove_button.setEnabled(false);
520 update_button.setEnabled(false);
521 }
522 }
523 }
524 }
525}
Note: See TracBrowser for help on using the repository browser.