source: trunk/gli/src/org/greenstone/gatherer/cdm/SubcollectionIndexManager.java@ 12808

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

Removed CollectionManager.configurationChanged() and all 50 calls to it. The CollectionConfiguration class now works out itself whether it needs to be changed or not -- a far more reliable approach.

  • Property svn:keywords set to Author Date Id Revision
File size: 20.5 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
29import java.awt.*;
30import java.awt.event.*;
31import java.util.*;
32import javax.swing.*;
33import javax.swing.event.*;
34import org.greenstone.gatherer.DebugStream;
35import org.greenstone.gatherer.Dictionary;
36import org.greenstone.gatherer.Gatherer;
37import org.greenstone.gatherer.gui.GLIButton;
38import org.greenstone.gatherer.util.CheckList;
39import org.greenstone.gatherer.util.JarTools;
40import org.greenstone.gatherer.util.StaticStrings;
41import org.w3c.dom.*;
42
43
44/** This class maintains a list of indexes partitions for the purpose of defining subcollections.
45 * @author John Thompson, Greenstone Digital Library, University of Waikato
46 * @version 2.4
47 */
48public class SubcollectionIndexManager
49 extends DOMProxyListModel
50{
51 static final private Dimension FIELD_SIZE = new Dimension(200, 30);
52
53 private Control controls;
54 private DOMProxyListModel model;
55 private SubcollectionIndex default_index;
56
57
58 /** Constructor. */
59 public SubcollectionIndexManager(Element subindexes)
60 {
61 super(subindexes, StaticStrings.INDEX_ELEMENT, new SubcollectionIndex());
62 DebugStream.println("SubcollectionIndexManager: " + getSize() + " subcollection indexes parsed.");
63 this.model = this;
64
65 // Parse and retrieve the default index
66 NodeList default_index_elements = CollectionConfiguration.getElementsByTagName(StaticStrings.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
67 if (default_index_elements.getLength() > 0) {
68 default_index = new SubcollectionIndex((Element) default_index_elements.item(0));
69 }
70 }
71
72
73 /** Method to add a subindex.
74 * @param subindex a SubcollectionIndex
75 * @see org.greenstone.gatherer.Gatherer
76 * @see org.greenstone.gatherer.collection.CollectionManager
77 */
78 private void addSubcollectionIndex(SubcollectionIndex subcollection_index)
79 {
80 if (!contains(subcollection_index)) {
81 // add a pseudo metadata
82 CollectionMeta metadatum = new CollectionMeta(StaticStrings.STOP_CHARACTER + subcollection_index.getID());
83 metadatum.setValue(subcollection_index.getID());
84 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
85 add(getSize(), subcollection_index);
86 }
87 }
88
89
90 public void destroy()
91 {
92 if (controls != null) {
93 controls.destroy();
94 controls = null;
95 }
96 default_index = null;
97 model = null;
98 }
99
100
101 public Control getControls()
102 {
103 if (controls == null) {
104 controls = new SubcollectionIndexControls();
105 }
106 return controls;
107 }
108
109
110 /** Method to get all of the subindexes set.
111 * @return an ArrayList containing all the defined indexes
112 */
113 public ArrayList getSubcollectionIndexes()
114 {
115 return children();
116 }
117
118 /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
119 * @param mode the new mode as an int
120 */
121 public void modeChanged(int mode) {
122
123 }
124
125 private int moveSubcollectionIndex(SubcollectionIndex subcollection_index, boolean move_up)
126 {
127 // Determine the current position of the subcollection index
128 int position = indexOf(subcollection_index);
129 int new_position;
130
131 // Attempt to move the subcollection index up
132 if (move_up) {
133 // Check it's not already at the top
134 if (position == 0) {
135 return position;
136 }
137
138 // This automatically removes the index first, as an Element can only exist once in a particular document
139 new_position = position - 1;
140 addBefore(subcollection_index, (SubcollectionIndex) getElementAt(new_position));
141 }
142
143 // Attempt to move the subcollection index down
144 else {
145 // Check it's not already at the bottom
146 if (position == (getSize()) - 1) {
147 return position;
148 }
149
150 // This automatically removes the index first, as an Element can only exist once in a particular document
151 new_position = position + 1;
152 addAfter(subcollection_index, (SubcollectionIndex) getElementAt(new_position));
153 }
154
155 return new_position;
156 }
157
158
159 /** Method to remove a certain subcollection index. */
160 private void removeSubcollectionIndex(SubcollectionIndex subcollection_index)
161 {
162 if (subcollection_index != null) {
163 // Remove any current metadata from this index
164 CollectionDesignManager.collectionmeta_manager.removeMetadata(StaticStrings.STOP_CHARACTER + subcollection_index.getID());
165
166 // Check if the index removed happens to be the default index
167 if (default_index != null && default_index.equals(subcollection_index)) {
168 setDefault(null);
169 }
170
171 // Remove the index
172 remove(subcollection_index);
173 }
174 }
175
176
177 /** Method to remove all of the subindexes that contain a certain subcollection.
178 * @param subcollection the Subcollection that has been removed
179 * @see org.greenstone.gatherer.cdm.Subcollection
180 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
181 */
182 public void removeSubcollectionIndexes(Subcollection subcollection)
183 {
184 String subcollection_name = subcollection.getName();
185 int size = getSize();
186 for(int i = size - 1; i >= 0; i--) {
187 SubcollectionIndex subcollection_index = (SubcollectionIndex) getElementAt(i);
188 if (subcollection_index.getSources().contains(subcollection_name)) {
189 removeSubcollectionIndex(subcollection_index);
190 }
191 }
192 }
193
194 private void replaceSubcollectionIndex(SubcollectionIndex old_subcollection, SubcollectionIndex new_subcollection) {
195 // Remove old collection meta
196 CollectionDesignManager.collectionmeta_manager.removeMetadata(StaticStrings.STOP_CHARACTER + old_subcollection.getID());
197 // Add new one
198 CollectionMeta metadatum = new CollectionMeta(StaticStrings.STOP_CHARACTER + new_subcollection.getID());
199 metadatum.setValue(new_subcollection.getID());
200 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
201 if(default_index != null && default_index.equals(old_subcollection)) {
202 setDefault(new_subcollection);
203 }
204
205 // get the position of the old one
206 int position = indexOf(old_subcollection);
207 remove(old_subcollection);
208 add(position, new_subcollection);
209 }
210
211 /** Method to set the default subcollection index.
212 * @param index The <strong>SubcollectionIndex</strong> to use as the default index.
213 * @see org.greenstone.gatherer.Gatherer
214 * @see org.greenstone.gatherer.collection.CollectionManager
215 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
216 */
217 private void setDefault(SubcollectionIndex subcollection_index)
218 {
219 if (subcollection_index != null) {
220 if (default_index == null) {
221 // Create the default index element, and place immediately after indexes element.
222 Element default_index_element = root.getOwnerDocument().createElement(StaticStrings.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
223 default_index = new SubcollectionIndex(default_index_element);
224 Node target_node = CollectionConfiguration.findInsertionPoint(default_index_element);
225 if (target_node != null) {
226 root.getOwnerDocument().getDocumentElement().insertBefore(default_index_element, target_node);
227 }
228 else {
229 root.getOwnerDocument().getDocumentElement().appendChild(default_index_element);
230 }
231 }
232 default_index.setAssigned(true);
233 default_index.setSources(subcollection_index.getSources());
234 }
235 else {
236 if (default_index != null) {
237 default_index.setAssigned(false);
238 }
239 }
240 }
241
242
243 /** This class creates a set of controls for editing the indexes. */
244 private class SubcollectionIndexControls
245 extends JPanel
246 implements Control
247 {
248 private CheckList source_list;
249 private JButton add_button;
250 private JButton move_down_button;
251 private JButton move_up_button;
252 private JButton remove_button;
253 private JButton replace_button;
254 private JButton set_default_button;
255 private JList subcollection_index_list;
256 private JTextField subcollection_index_name_textfield;
257
258
259 /** Constructor.
260 */
261 public SubcollectionIndexControls()
262 {
263 super();
264
265 ArrayList sources = new ArrayList();
266 ListModel source_model = CollectionDesignManager.subcollection_manager;
267 for (int i = 0; i < source_model.getSize(); i++) {
268 sources.add(source_model.getElementAt(i));
269 }
270
271 // Creation
272 JPanel assigned_indexes_pane = new JPanel();
273 JLabel index_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Subindexes"));
274 subcollection_index_list = new JList(model);
275 subcollection_index_list.setCellRenderer(new SubcollectionIndexListCellRenderer());
276 subcollection_index_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
277 subcollection_index_list.setVisibleRowCount(2);
278
279 JPanel movement_pane = new JPanel();
280 move_up_button = new GLIButton(Dictionary.get("CDM.Move.Move_Up"), JarTools.getImage("arrow-up.gif"), Dictionary.get("CDM.Move.Move_Up_Tooltip"));
281 move_up_button.setEnabled(false);
282
283 move_down_button = new GLIButton(Dictionary.get("CDM.Move.Move_Down"), JarTools.getImage("arrow-down.gif"), Dictionary.get("CDM.Move.Move_Down_Tooltip"));
284 move_down_button.setEnabled(false);
285
286 set_default_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex_Tooltip"));
287 set_default_button.setEnabled(false);
288
289 JPanel index_pane = new JPanel();
290 JPanel details_pane = new JPanel();
291 JPanel labels_pane = new JPanel();
292 JPanel boxes_pane = new JPanel();
293 JPanel content_pane = new JPanel();
294
295 JLabel source_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Source"));
296
297 source_list = new CheckList(false);
298 source_list.setListData(sources);
299 source_list.setToolTipText(Dictionary.get("CDM.SubcollectionIndexManager.Source_Tooltip"));
300
301 JPanel button_pane = new JPanel();
302 add_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex_Tooltip"));
303 add_button.setEnabled(false);
304
305 remove_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex_Tooltip"));
306 remove_button.setEnabled(false);
307
308 replace_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex_Tooltip"));
309 replace_button.setEnabled(false);
310
311 // Listeners
312 add_button.addActionListener(new AddListener());
313 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
314 move_down_button.addActionListener(new MoveListener(false));
315 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
316 move_up_button.addActionListener(new MoveListener(true));
317 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
318 remove_button.addActionListener(new RemoveListener());
319 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
320 replace_button.addActionListener(new ReplaceListener());
321 replace_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
322 set_default_button.addActionListener(new SetDefaultListener());
323 set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
324 subcollection_index_list.addListSelectionListener(new AssignedListListener());
325 source_list.addListSelectionListener(new SourceListListener());
326
327 // Layout
328 movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
329 movement_pane.setLayout(new GridLayout(3,1));
330 movement_pane.add(move_up_button);
331 movement_pane.add(move_down_button);
332 movement_pane.add(set_default_button);
333
334 assigned_indexes_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
335 assigned_indexes_pane.setLayout(new BorderLayout());
336 assigned_indexes_pane.add(index_label, BorderLayout.NORTH);
337 assigned_indexes_pane.add(new JScrollPane(subcollection_index_list), BorderLayout.CENTER);
338 assigned_indexes_pane.add(movement_pane, BorderLayout.EAST);
339
340 labels_pane.setLayout(new BorderLayout());
341 labels_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
342 labels_pane.add(source_label, BorderLayout.CENTER);
343
344 boxes_pane.setLayout(new BorderLayout());
345 boxes_pane.add(new JScrollPane(source_list), BorderLayout.CENTER);
346
347 details_pane.setLayout(new BorderLayout());
348 details_pane.add(labels_pane, BorderLayout.WEST);
349 details_pane.add(boxes_pane, BorderLayout.CENTER);
350
351 button_pane.setLayout(new GridLayout(1,3));
352 button_pane.add(add_button);
353 button_pane.add(replace_button);
354 button_pane.add(remove_button);
355
356 index_pane.setLayout(new BorderLayout());
357 index_pane.add(details_pane, BorderLayout.CENTER);
358 index_pane.add(button_pane, BorderLayout.SOUTH);
359
360 content_pane.setLayout(new BorderLayout());
361 content_pane.add(assigned_indexes_pane, BorderLayout.NORTH);
362 content_pane.add(index_pane, BorderLayout.CENTER);
363
364 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
365 setLayout(new BorderLayout());
366 add(content_pane, BorderLayout.CENTER);
367 }
368
369
370 public void destroy()
371 {
372 }
373
374
375 public void gainFocus()
376 {
377 // Reload the source list
378 ArrayList sources = new ArrayList();
379 ListModel source_model = CollectionDesignManager.subcollection_manager;
380 for (int i = 0; i < source_model.getSize(); i++) {
381 sources.add(source_model.getElementAt(i));
382 }
383 source_list.setListData(sources);
384
385 // Refresh the subcollection index list
386 subcollection_index_list.updateUI();
387
388 clearControls();
389
390 }
391
392
393 public void loseFocus() {
394 }
395
396 private void clearControls() {
397 subcollection_index_list.clearSelection();
398 source_list.clearTicked();
399 add_button.setEnabled(false);
400 remove_button.setEnabled(false);
401 replace_button.setEnabled(false);
402 set_default_button.setEnabled(false);
403 move_down_button.setEnabled(false);
404 move_up_button.setEnabled(false);
405
406 }
407
408 private void updateControlsWithSelectedIndex()
409 {
410 SubcollectionIndex selected_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
411 if (selected_index == null) {
412 source_list.clearTicked();
413 return;
414 }
415
416 // Display the selected subcollection index's sources
417 source_list.clearTicked();
418 source_list.setTickedObjects(selected_index.getSources().toArray());
419 }
420
421
422 private void validateButtons() {
423
424 boolean add_enabled = false;
425 boolean replace_enabled = false;
426
427 // Can't add a new index if no sources are selected
428 if (!source_list.isNothingTicked()) {
429 ArrayList sources = source_list.getTicked();
430 SubcollectionIndex subcollection_index = new SubcollectionIndex(sources.toArray());
431
432 // Subcollection index already exists: can't add, but can replace if the name has changed
433 if (!model.contains(subcollection_index)) {
434 add_enabled = true;
435 if (!subcollection_index_list.isSelectionEmpty()) {
436 replace_enabled = true;
437 }
438 }
439 }
440
441 // We should now know the add_button state
442 add_button.setEnabled(add_enabled);
443 replace_button.setEnabled(replace_enabled);
444 }
445
446
447 private class AddListener
448 implements ActionListener {
449
450 public void actionPerformed(ActionEvent event)
451 {
452 if (!source_list.isNothingTicked()) {
453 ArrayList sources = source_list.getTicked();
454 SubcollectionIndex subcollection_index = new SubcollectionIndex(sources.toArray());
455 addSubcollectionIndex(subcollection_index);
456 clearControls();
457 }
458 }
459 }
460
461
462 private class MoveListener
463 implements ActionListener
464 {
465 private boolean move_up;
466
467 public MoveListener(boolean move_up)
468 {
469 this.move_up = move_up;
470 }
471
472 public void actionPerformed(ActionEvent event)
473 {
474 // Retrieve the selected subcollection index
475 SubcollectionIndex subcollection_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
476 if (subcollection_index != null) {
477 int new_position = moveSubcollectionIndex(subcollection_index, move_up);
478 // Ensure the subcollection index that moved is still selected
479 subcollection_index_list.setSelectedIndex(new_position);
480 }
481 }
482 }
483
484 private class RemoveListener
485 implements ActionListener
486 {
487 public void actionPerformed(ActionEvent event) {
488
489 SubcollectionIndex delete_me = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
490 if (delete_me != null) {
491 removeSubcollectionIndex(delete_me);
492 }
493 }
494 }
495
496
497 private class ReplaceListener
498 implements ActionListener {
499
500 public void actionPerformed(ActionEvent event) {
501
502 if (subcollection_index_list.isSelectionEmpty()|| source_list.isNothingTicked()) {
503 // This should never happen, but just in case...
504 replace_button.setEnabled(false);
505 return;
506 }
507 SubcollectionIndex old_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
508 ArrayList sources = source_list.getTicked();
509 SubcollectionIndex new_index = new SubcollectionIndex(sources.toArray());
510 replaceSubcollectionIndex(old_index, new_index);
511 }
512 }
513
514
515 private class SetDefaultListener
516 implements ActionListener {
517
518 public void actionPerformed(ActionEvent event)
519 {
520 SubcollectionIndex subcollection_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
521 if (subcollection_index != null) {
522 setDefault(subcollection_index);
523 // This should cause a repaint of just the desired row
524 subcollection_index_list.setSelectedValue(subcollection_index, true);
525 }
526 set_default_button.setEnabled(false);
527 }
528 }
529
530
531 private class SourceListListener
532 implements ListSelectionListener {
533
534 public void valueChanged(ListSelectionEvent event) {
535 if (event.getValueIsAdjusting()) {
536 return;
537 }
538 validateButtons();
539 }
540 }
541
542
543 /** Listens for selections within the assigned subcollection indexes list */
544 private class AssignedListListener
545 implements ListSelectionListener {
546
547 public void valueChanged(ListSelectionEvent event) {
548
549 if (event.getValueIsAdjusting()) {
550 return;
551 }
552
553 if (subcollection_index_list.isSelectionEmpty()) {
554 clearControls();
555 return;
556 }
557
558 int i = subcollection_index_list.getSelectedIndex();
559 int size = subcollection_index_list.getModel().getSize();
560
561 // Enable the buttons appropriately
562 remove_button.setEnabled(true);
563 replace_button.setEnabled(false);
564 add_button.setEnabled(false);
565 SubcollectionIndex selected_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
566 set_default_button.setEnabled(default_index == null || !default_index.equals(selected_index));
567 if (i > 0) {
568 move_up_button.setEnabled(true);
569 }
570 else {
571 move_up_button.setEnabled(false);
572 }
573 if (i < size-1){
574 move_down_button.setEnabled(true);
575 }
576 else {
577 move_down_button.setEnabled(false);
578 }
579
580 // Need to fill in the rest of the bits
581 updateControlsWithSelectedIndex();
582 }
583 }
584
585
586 private class SubcollectionIndexListCellRenderer
587 extends DefaultListCellRenderer
588 {
589 /** Return a component that has been configured to display the specified value. */
590 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
591 JLabel component = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
592 if (default_index != null && default_index.equals(value)) {
593 component.setText(component.getText() + " " + Dictionary.get("CDM.SubcollectionIndexManager.Default_Partition_Indicator"));
594 }
595 return component;
596 }
597 }
598 }
599}
Note: See TracBrowser for help on using the repository browser.