source: trunk/gli/src/org/greenstone/gatherer/cdm/IndexManager.java@ 4932

Last change on this file since 4932 was 4932, checked in by jmt12, 21 years ago

Major CDM rewrite so it uses DOM.

  • Property svn:keywords set to Author Date Id Revision
File size: 24.0 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28import java.awt.*;
29import java.awt.event.*;
30import java.util.*;
31import javax.swing.*;
32import javax.swing.event.*;
33import org.greenstone.gatherer.Gatherer;
34import org.greenstone.gatherer.cdm.CollectionMeta;
35import org.greenstone.gatherer.cdm.CommandTokenizer;
36import org.greenstone.gatherer.cdm.Control;
37import org.greenstone.gatherer.cdm.DOMProxyListModel;
38import org.greenstone.gatherer.cdm.Index;
39import org.greenstone.gatherer.msm.ElementWrapper;
40import org.greenstone.gatherer.msm.MSMUtils;
41import org.greenstone.gatherer.util.ExclusiveListSelectionListener;
42import org.greenstone.gatherer.util.StaticStrings;
43import org.w3c.dom.*;
44/** This class is resposible for storing the indexes which have been assigned to this collection and the default index, and providing methods for interacting with both these data pools. It also knows how to turn itself into a String as it would be displayed in the collection configuration file.
45 * @author John Thompson, Greenstone Digital Library, University of Waikato
46 * @version 2.3
47 */
48public class IndexManager
49 extends DOMProxyListModel {
50 /** The controls for editing the indexes. */
51 private Control controls = null;
52 /** A reference to ourselves so our inner methods have access. */
53 private DOMProxyListModel model = null;
54 /** The default index. */
55 private Index default_index = null;
56 /** Constructor. */
57 public IndexManager(Element indexes) {
58 super(indexes, CollectionConfiguration.INDEX_ELEMENT, new Index());
59 Gatherer.println("IndexManager: " + getSize() + " indexes parsed.");
60 model = this;
61 // Parse and retrieve the default index
62 NodeList default_index_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.INDEX_DEFAULT_ELEMENT);
63 if(default_index_elements.getLength() > 0) {
64 default_index = new Index((Element)default_index_elements.item(0));
65 }
66 }
67 /** Method to add a new index.
68 * @param index The <strong>Index</strong> to add.
69 * @see org.greenstone.gatherer.Gatherer
70 * @see org.greenstone.gatherer.collection.CollectionManager
71 */
72 public void addIndex(Index index, CollectionMeta metadatum) {
73 ///ystem.err.println("Adding an index: " + index.toString());
74 if(!contains(index)) {
75 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
76 // Retrieve the currently last index
77 Index last_index = (Index)getElementAt(getSize() - 1);
78 addAfter(index, last_index);
79 Gatherer.c_man.configurationChanged();
80 }
81 else {
82 JOptionPane.showMessageDialog(Gatherer.g_man, get("CDM.IndexManager.Index_Exists"), get("General.Warning"), JOptionPane.WARNING_MESSAGE);
83 }
84 }
85
86 public void destroy() {
87 if(controls != null) {
88 controls.destroy();
89 controls = null;
90 }
91 default_index = null;
92 model = null;
93 }
94
95 /** Method to acquire the controls for editing the indexes.
96 * @return the Control
97 */
98 public Control getControls() {
99 if(controls == null) {
100 // Build controls
101 controls = new IndexControl();
102 }
103 return controls;
104 }
105
106 /** Method to get the default index.
107 * @return The default <strong>Index</strong>.
108 */
109 public Index getDefault() {
110 if(default_index != null && default_index.isAssigned()) {
111 return default_index;
112 }
113 else {
114 return null;
115 }
116 }
117
118 /** Method to retrieve a certain index, as referenced by an index number.
119 * @param index An <i>int</i> which indicates the position of the desired index.
120 * @return The <strong>Index</strong> at the given index, or <i>null</i> if no such index exists.
121 */
122 public Index getIndex(int index) {
123 if(0 <= index && index < getSize()) {
124 return (Index)getElementAt(index);
125 }
126 return null;
127 }
128
129 /** Method to retrieve a certain index, given its id.
130 * @param id the id of the index as a String
131 * @return the Index that matches id, or null if no such index exists
132 */
133 public Index getIndex(String id) {
134 int size = getSize();
135 for(int i = 0; i < size; i++) {
136 Index index = (Index) getElementAt(i);
137 if(index.getID().equals(id)) {
138 return index;
139 }
140 }
141 return null;
142 }
143
144 public ArrayList getIndexes() {
145 return children();
146 }
147
148 /** Method to remove a certain index.
149 * @param index the Index to remove.
150 * @see org.greenstone.gatherer.Gatherer
151 * @see org.greenstone.gatherer.cdm.CollectionDesignManager
152 * @see org.greenstone.gatherer.cdm.CollectionMetaManager
153 * @see org.greenstone.gatherer.collection.CollectionManager
154 */
155 public void removeIndex(Index index) {
156 if(index != null) {
157 // Remove any current metadata from this index
158 CollectionDesignManager.collectionmeta_manager.removeMetadata(StaticStrings.STOP_CHARACTER + index.getID());
159 // Check if the index removed happens to be the default index
160 if(default_index != null && default_index.equals(index)) {
161 default_index.setAssigned(false);
162 }
163 // Remove the index
164 remove(index);
165 Gatherer.c_man.configurationChanged();
166 }
167 }
168
169 /** Method to set the default index.
170 * @param index the new default Index
171 * @see org.greenstone.gatherer.Gatherer
172 * @see org.greenstone.gatherer.collection.CollectionManager
173 */
174 public void setDefault(Index index) {
175 if(index != null) {
176 if(default_index == null) {
177 // Create the default index element, and place immediately after indexes element.
178 Element default_index_element = root.getOwnerDocument().createElement(CollectionConfiguration.INDEX_DEFAULT_ELEMENT);
179 default_index = new Index(default_index_element);
180 Node target_node = CollectionConfiguration.findInsertionPoint(default_index_element);
181 if(target_node != null) {
182 root.getOwnerDocument().getDocumentElement().insertBefore(default_index_element, target_node);
183 }
184 else {
185 root.getOwnerDocument().getDocumentElement().appendChild(default_index_element);
186 }
187 }
188 default_index.setAssigned(true);
189 default_index.setLevel(index.getLevel());
190 default_index.setSources(index.getSources());
191 }
192 else {
193 if(default_index != null) {
194 default_index.setAssigned(false);
195 }
196 }
197 Gatherer.c_man.configurationChanged();
198 }
199
200 /** Overloaded to call get with both a key and an empty argument array.
201 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle.
202 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatiically populated with formatting Strings of with argument String provided in the get call.
203 */
204 private String get(String key) {
205 return get(key, null);
206 }
207
208 /** Used to retrieve a property value from the Locale specific ResourceBundle, based upon the key and arguments supplied. If the key cannot be found or if some other part of the call fails a default (English) error message is returned. <BR>
209 * Here the get recieves a second argument which is an array of Strings used to populate argument fields, denoted {<I>n</I>}, within the value String returned. Note that argument numbers greater than or equal to 32 are automatically mapped to the formatting String named Farg<I>n</I>.
210 * @param key A <strong>String</strong> which is mapped to a initial String within the ResourceBundle.
211 * @param args A <strong>String[]</strong> used to populate argument fields within the complete String.
212 * @return A <strong>String</strong> which has been referenced by the key String and that either contains no argument fields, or has had the argument fields automatically populated with formatting Strings of with argument String provided in the get call.
213 * @see org.greenstone.gatherer.Gatherer
214 * @see org.greenstone.gatherer.Dictionary
215 */
216 private String get(String key, String args[]) {
217 if(key.indexOf('.') == -1) {
218 key = "CDM.IndexManager." + key;
219 }
220 return Gatherer.dictionary.get(key, args);
221 }
222
223 /** This class creates a set of controls for editing the indexes. */
224 private class IndexControl
225 extends JPanel
226 implements Control {
227 /** The default size of a label on this control. */
228 private Dimension LABEL_SIZE = new Dimension(120,25);
229 /** The button used to add a new index. */
230 private JButton add = null;
231 /** The button used to clear the default index. */
232 private JButton clear_default = null;
233 /** The button used to remove an index. */
234 private JButton remove = null;
235 /** The button used to set the default index. */
236 private JButton set_default = null;
237 /** The combobox used to adjust what level the new index will built on. */
238 private JComboBox level = null;
239 /** The label denoting the default index to be built for this collection. */
240 private JLabel default_label = null;
241 /** The label denoting the list of assigned indexes. */
242 private JLabel index_label = null;
243 /** The label denoting the control for choosing index level. */
244 private JLabel level_label = null;
245 /** The label denoting the name of the index. */
246 private JLabel name_label = null;
247 /** The label denoting the list of possible sources for the index. */
248 private JLabel source_label = null;
249 /** The title shown at the top of the index controls. */
250 private JLabel title = null;
251 /** The list of assigned indexes. */
252 private JList index_list = null;
253 /** The list of possible sources on which the index could be built. */
254 private JList source_list = null;
255 /** The panel used to display the list of assigned indexes. */
256 private JPanel assigned_pane = null;
257 /** The panel which contains the buttons used to edit indexes. */
258 private JPanel button_pane = null;
259 /** The panel on which all other panels are displayed. */
260 private JPanel central_pane = null;
261 /** The control pane showing the editable controls. */
262 private JPanel control_pane = null;
263 /** The edit pane contains the list of possible sources. */
264 private JPanel edit_pane = null;
265 /** A panel used to correctly lay out the default index label. */
266 private JPanel default_pane = null;
267 /** The panel containing the title label and instructions. */
268 private JPanel header_pane = null;
269 /** The lvel panel contains the control for adjusting index level. */
270 private JPanel level_pane = null;
271 /** The pane in which the name control is set. */
272 private JPanel name_pane = null;
273 /** The scrollpane containing the instructions text area. */
274 private JScrollPane instructions_scroll = null;
275 /** A text area containing inline instructions. */
276 private JTextArea instructions = null;
277 /** A text field naming the default index. Non-editable. */
278 private JTextField default_value = null;
279 /** A text field for controlling the name of the new index. */
280 private JTextField name = null;
281 /** A model containing all of the available index sources. */
282 private Vector source_model = null;
283 /** Constructor.
284 * @see org.greenstone.gatherer.Configuration
285 * @see org.greenstone.gatherer.Gatherer
286 * @see org.greenstone.gatherer.cdm.IndexManager.Control.AddListener
287 * @see org.greenstone.gatherer.cdm.IndexManager.Control.ClearDefaultListener
288 * @see org.greenstone.gatherer.cdm.IndexManager.Control.NameListener
289 * @see org.greenstone.gatherer.cdm.IndexManager.Control.RemoveListener
290 * @see org.greenstone.gatherer.cdm.IndexManager.Control.SetDefaultListener
291 * @see org.greenstone.gatherer.collection.CollectionManager
292 * @see org.greenstone.gatherer.gui.Coloring
293 * @see org.greenstone.gatherer.msm.MetadataSetManager
294 * @see org.greenstone.gatherer.util.ExclusiveListSelectionListener
295 */
296 public IndexControl() {
297 super();
298 source_model = new Vector();
299 source_model.add("text");
300 source_model.addAll(Gatherer.c_man.getCollection().msm.getAssignedElements());
301 // Creation
302 add = new JButton(get("Add"));
303 add.setEnabled(false);
304 add.setMnemonic(KeyEvent.VK_A);
305 assigned_pane = new JPanel();
306 button_pane = new JPanel();
307 central_pane = new JPanel();
308 control_pane = new JPanel();
309 clear_default = new JButton(get("Clear_Default"));
310 clear_default.setMnemonic(KeyEvent.VK_C);
311 if(default_index == null) {
312 clear_default.setEnabled(false);
313 }
314 default_label = new JLabel(get("Default_Index"));
315 default_pane = new JPanel();
316 if(default_index != null) {
317 default_value = new JTextField(default_index.toString());
318 default_value.setCaretPosition(0);
319 }
320 else {
321 default_value = new JTextField();
322 }
323 default_value.setBackground(Gatherer.config.getColor("coloring.collection_tree_background", false));
324 default_value.setEditable(false);
325 edit_pane = new JPanel();
326 header_pane = new JPanel();
327 index_label = new JLabel(get("Indexes"));
328 index_list = new JList(model);
329 instructions = new JTextArea(get("Instructions"));
330 instructions.setEditable(false);
331 instructions.setLineWrap(true);
332 instructions.setRows(5);
333 instructions.setWrapStyleWord(true);
334 level = new JComboBox();
335 level.addItem(get("Document"));
336 level.addItem(get("Paragraph"));
337 level.addItem(get("Section"));
338 level.setEditable(false);
339 level_label = new JLabel(get("Level"));
340 level_label.setPreferredSize(LABEL_SIZE);
341 level_pane = new JPanel();
342 name = new JTextField();
343 name_label = new JLabel(get("Name"));
344 name_label.setPreferredSize(LABEL_SIZE);
345 name_pane = new JPanel();
346 remove = new JButton(get("Remove"));
347 remove.setEnabled(false);
348 remove.setMnemonic(KeyEvent.VK_R);
349 set_default = new JButton(get("Set_Default"));
350 set_default.setEnabled(false);
351 set_default.setMnemonic(KeyEvent.VK_S);
352 source_label = new JLabel(get("Source"));
353 source_list = new JList(source_model);
354 title = new JLabel(get("Title"));
355 title.setHorizontalAlignment(JLabel.CENTER);
356
357 // Listeners
358 add.addActionListener(new AddListener());
359 clear_default.addActionListener(new ClearDefaultListener());
360 remove.addActionListener(new RemoveListener());
361 set_default.addActionListener(new SetDefaultListener());
362 name.addKeyListener(new NameListener());
363 ListListener ll = new ListListener();
364 index_list.addListSelectionListener(ll);
365 source_list.addListSelectionListener(ll);
366 ExclusiveListSelectionListener elsl = new ExclusiveListSelectionListener();
367 elsl.add(index_list);
368 elsl.add(source_list);
369
370 // Layout
371 title.setBorder(BorderFactory.createEmptyBorder(0,0,2,0));
372
373 instructions.setBorder(BorderFactory.createEmptyBorder(2,5,2,5));
374
375 header_pane.setLayout(new BorderLayout());
376 header_pane.add(title, BorderLayout.NORTH);
377 header_pane.add(new JScrollPane(instructions), BorderLayout.CENTER);
378
379 name_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
380
381 name_pane.setBorder(BorderFactory.createEmptyBorder(4,2,4,2));
382 name_pane.setLayout(new BorderLayout());
383 name_pane.add(name_label, BorderLayout.WEST);
384 name_pane.add(name, BorderLayout.CENTER);
385
386 control_pane.setLayout(new BorderLayout());
387 control_pane.add(source_label, BorderLayout.NORTH);
388 control_pane.add(new JScrollPane(source_list), BorderLayout.CENTER);
389
390 level_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
391
392 level_pane.setBorder(BorderFactory.createEmptyBorder(4,2,4,2));
393 level_pane.setLayout(new BorderLayout());
394 level_pane.add(level_label, BorderLayout.WEST);
395 level_pane.add(level, BorderLayout.CENTER);
396
397 edit_pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
398 edit_pane.setLayout(new BorderLayout());
399 edit_pane.add(name_pane, BorderLayout.NORTH);
400 edit_pane.add(control_pane, BorderLayout.CENTER);
401 edit_pane.add(level_pane, BorderLayout.SOUTH);
402
403 default_label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
404
405 default_pane.setBorder
406 (BorderFactory.createCompoundBorder
407 (BorderFactory.createCompoundBorder
408 (BorderFactory.createEmptyBorder(2,2,2,2),
409 BorderFactory.createRaisedBevelBorder()),
410 BorderFactory.createEmptyBorder(2,2,2,2)));
411 default_pane.setLayout(new BorderLayout());
412 default_pane.add(default_label, BorderLayout.WEST);
413 default_pane.add(default_value, BorderLayout.CENTER);
414
415 assigned_pane.setLayout(new BorderLayout());
416 assigned_pane.add(index_label, BorderLayout.NORTH);
417 assigned_pane.add(new JScrollPane(index_list), BorderLayout.CENTER);
418 assigned_pane.add(default_pane, BorderLayout.SOUTH);
419
420 central_pane.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
421 central_pane.setLayout(new GridLayout(1,2));
422 central_pane.add(edit_pane);
423 central_pane.add(assigned_pane);
424
425 button_pane.setLayout(new GridLayout(2,2));
426 button_pane.add(add);
427 button_pane.add(remove);
428 button_pane.add(clear_default);
429 button_pane.add(set_default);
430
431 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
432 setLayout(new BorderLayout());
433 add(header_pane, BorderLayout.NORTH);
434 add(central_pane, BorderLayout.CENTER);
435 add(button_pane, BorderLayout.SOUTH);
436 }
437 /* Destructor, removes persistant listeners from the Dictionary.
438 */
439 public void destroy() {
440 }
441
442 public void gainFocus() {
443 if(instructions != null) {
444 instructions.setCaretPosition(0);
445 }
446 // Reload the assigned indexes list.
447 if(source_model != null) {
448 source_model.clear();
449 source_model.add("text");
450 source_model.addAll(Gatherer.c_man.getCollection().msm.getAssignedElements());
451 // reset the model in the list - needed if the model is larger than when it was first created, the list doesn't display
452 source_list.setListData(source_model);
453
454 }
455 }
456
457 public void loseFocus() {
458 }
459
460 /** Listens for actions apon the 'add' button in the IndexManager controls, and if detected calls the add method of the manager with a newly created index. */
461 private class AddListener
462 implements ActionListener {
463 /** Method called when an action is performed on a registered component, and when it does we check if we have enough data to create a new index, and if so we create one.
464 * @param event An <strong>ActionEvent</strong> providing extra information about the event.
465 * @see org.greenstone.gatherer.cdm.CollectionDesignManager
466 * @see org.greenstone.gatherer.cdm.CollectionMeta
467 * @see org.greenstone.gatherer.cdm.CollectionMetaManager
468 * @see org.greenstone.gatherer.cdm.Index
469 * @see org.greenstone.gatherer.cdm.Language
470 * @see org.greenstone.gatherer.cdm.LanguageManager
471 */
472 public void actionPerformed(ActionEvent event) {
473 if(!source_list.isSelectionEmpty() && name.getText().length() != 0) {
474 Object object[] = source_list.getSelectedValues();
475 ArrayList sources = new ArrayList();
476 for(int i = 0; i < object.length; i++) {
477 sources.add(object[i]);
478 }
479 object = null;
480 Index index = new Index(level.getSelectedIndex(), sources);
481 sources = null;
482 // Before we add the index to the model, we have to add the collection metadata for this.
483 CollectionMeta metadatum = new CollectionMeta(StaticStrings.STOP_CHARACTER + index.getID());
484 metadatum.setValue(name.getText());
485 // Finally add index.
486 addIndex(index, metadatum);
487 metadatum = null;
488 index = null;
489 }
490 }
491 }
492 /** Listens for actions apon the 'clear default' button in the IndexManager controls, and if detected calls the setDefault method of the manager with <i>null</i>. */
493 private class ClearDefaultListener
494 implements ActionListener {
495 /** If called when an action occurs on a registered component, we clear the default index.
496 * @param event An <strong>ActionEvent</strong> containing extra information about the action that occured.
497 */
498 public void actionPerformed(ActionEvent event) {
499 setDefault(null);
500 clear_default.setEnabled(false);
501 default_value.setText("");
502 }
503 }
504 /** Listens for actions apon the 'remove' button in the IndexManager controls, and if detected calls the remove method of the manager with the index selected for removal. */
505 private class RemoveListener
506 implements ActionListener {
507 /** If called when an action occurs on a registered component, we remove the currently selected index, if there is one.
508 * @param event An <strong>ActionEvent</strong> containing extra information about the action that occured.
509 * @see org.greenstone.gatherer.cdm.Index
510 */
511 public void actionPerformed(ActionEvent event) {
512 if(!index_list.isSelectionEmpty()) {
513 removeIndex((Index)index_list.getSelectedValue());
514 if(default_index == null) {
515 clear_default.setEnabled(false);
516 default_value.setText("");
517 }
518 }
519 }
520 }
521 /** Listens for actions apon the 'set default' button in the IndexManager controls, and if detected calls the setDefault method of the manager with the index selected for default. */
522 private class SetDefaultListener
523 implements ActionListener {
524 /** If called when an action occurs on a registered component, we set the default index to the index currently selected.
525 * @param event An <strong>ActionEvent</strong> containing extra information about the action that occured.
526 * @see org.greenstone.gatherer.cdm.Index
527 */
528 public void actionPerformed(ActionEvent event) {
529 setDefault((Index)index_list.getSelectedValue());
530 if(default_index != null) {
531 clear_default.setEnabled(true);
532 default_value.setText(default_index.toString());
533 default_value.setCaretPosition(0);
534 }
535 else {
536 clear_default.setEnabled(false);
537 default_value.setText("");
538 }
539 }
540 }
541 /** Listens for key presses within the name field, and enabled or disables controls as appropriate. */
542 private class NameListener
543 extends KeyAdapter {
544 /** Called when a key is released, this is the perfect time to enable the add button if the fields are appropriately set.
545 * @param event A <strong>KeyEvent</strong> containing information about the key released.
546 */
547 public void keyReleased(KeyEvent event) {
548 if(source_list.isSelectionEmpty() || name.getText().length() == 0) {
549 add.setEnabled(false);
550 }
551 else {
552 add.setEnabled(true);
553 }
554 if(index_list.isSelectionEmpty()) {
555 remove.setEnabled(false);
556 set_default.setEnabled(false);
557 }
558 else {
559 remove.setEnabled(true);
560 set_default.setEnabled(true);
561 }
562 }
563 }
564 /** Listens for selections within the list on the IndexManager controls, and if a change is detected enables, or disables, controls appropriately. */
565 private class ListListener
566 implements ListSelectionListener {
567 /** This method is called whenever the source list selection changes. When it does we need to check if the add button should now be enabled.
568 * @param event A <strong>ListSelectionEvent</strong> containing further information about the list selection.
569 */
570 public void valueChanged(ListSelectionEvent event) {
571 if(source_list.isSelectionEmpty() || name.getText().length() == 0) {
572 add.setEnabled(false);
573 }
574 else {
575 add.setEnabled(true);
576 }
577 if(index_list.isSelectionEmpty()) {
578 remove.setEnabled(false);
579 set_default.setEnabled(false);
580 }
581 else {
582 remove.setEnabled(true);
583 set_default.setEnabled(true);
584 }
585 }
586 }
587 }
588}
589
590
Note: See TracBrowser for help on using the repository browser.