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

Last change on this file since 13591 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
RevLine 
[4932]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.*;
[8236]34import org.greenstone.gatherer.DebugStream;
[5590]35import org.greenstone.gatherer.Dictionary;
[4932]36import org.greenstone.gatherer.Gatherer;
[6318]37import org.greenstone.gatherer.gui.GLIButton;
[9161]38import org.greenstone.gatherer.util.CheckList;
[10011]39import org.greenstone.gatherer.util.JarTools;
[12641]40import org.greenstone.gatherer.util.StaticStrings;
[4932]41import org.w3c.dom.*;
[9161]42
43
[4932]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
[9161]49 extends DOMProxyListModel
50{
51 static final private Dimension FIELD_SIZE = new Dimension(200, 30);
[4932]52
53 private Control controls;
54 private DOMProxyListModel model;
55 private SubcollectionIndex default_index;
56
[9161]57
[4932]58 /** Constructor. */
[9161]59 public SubcollectionIndexManager(Element subindexes)
60 {
[12641]61 super(subindexes, StaticStrings.INDEX_ELEMENT, new SubcollectionIndex());
[8236]62 DebugStream.println("SubcollectionIndexManager: " + getSize() + " subcollection indexes parsed.");
[12283]63 this.model = this;
[9161]64
[4932]65 // Parse and retrieve the default index
[12800]66 NodeList default_index_elements = CollectionConfiguration.getElementsByTagName(StaticStrings.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
[9161]67 if (default_index_elements.getLength() > 0) {
68 default_index = new SubcollectionIndex((Element) default_index_elements.item(0));
[4932]69 }
70 }
71
[9161]72
[4932]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 */
[9161]78 private void addSubcollectionIndex(SubcollectionIndex subcollection_index)
79 {
80 if (!contains(subcollection_index)) {
[12283]81 // add a pseudo metadata
[12641]82 CollectionMeta metadatum = new CollectionMeta(StaticStrings.STOP_CHARACTER + subcollection_index.getID());
[12283]83 metadatum.setValue(subcollection_index.getID());
84 CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
[9161]85 add(getSize(), subcollection_index);
[4932]86 }
87 }
88
[9161]89
90 public void destroy()
91 {
92 if (controls != null) {
[4932]93 controls.destroy();
94 controls = null;
95 }
96 default_index = null;
97 model = null;
98 }
99
[9161]100
101 public Control getControls()
102 {
103 if (controls == null) {
104 controls = new SubcollectionIndexControls();
[4932]105 }
106 return controls;
107 }
108
[9161]109
110 /** Method to get all of the subindexes set.
111 * @return an ArrayList containing all the defined indexes
[4932]112 */
[9161]113 public ArrayList getSubcollectionIndexes()
114 {
115 return children();
116 }
117
[12283]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 }
[9161]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));
[4932]141 }
[9161]142
143 // Attempt to move the subcollection index down
[4932]144 else {
[9161]145 // Check it's not already at the bottom
146 if (position == (getSize()) - 1) {
147 return position;
148 }
[4932]149
[9161]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));
[4932]153 }
154
[9161]155 return new_position;
[4932]156 }
157
[9161]158
159 /** Method to remove a certain subcollection index. */
160 private void removeSubcollectionIndex(SubcollectionIndex subcollection_index)
161 {
162 if (subcollection_index != null) {
[4932]163 // Remove any current metadata from this index
[12641]164 CollectionDesignManager.collectionmeta_manager.removeMetadata(StaticStrings.STOP_CHARACTER + subcollection_index.getID());
[9161]165
[4932]166 // Check if the index removed happens to be the default index
[9161]167 if (default_index != null && default_index.equals(subcollection_index)) {
[12283]168 setDefault(null);
[4932]169 }
[12283]170
[4932]171 // Remove the index
[9161]172 remove(subcollection_index);
[4932]173 }
174 }
[5590]175
[9161]176
[4932]177 /** Method to remove all of the subindexes that contain a certain subcollection.
[6770]178 * @param subcollection the Subcollection that has been removed
[4932]179 * @see org.greenstone.gatherer.cdm.Subcollection
180 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
181 */
[9161]182 public void removeSubcollectionIndexes(Subcollection subcollection)
183 {
[4932]184 String subcollection_name = subcollection.getName();
185 int size = getSize();
186 for(int i = size - 1; i >= 0; i--) {
[9161]187 SubcollectionIndex subcollection_index = (SubcollectionIndex) getElementAt(i);
188 if (subcollection_index.getSources().contains(subcollection_name)) {
189 removeSubcollectionIndex(subcollection_index);
[4932]190 }
191 }
192 }
193
[12283]194 private void replaceSubcollectionIndex(SubcollectionIndex old_subcollection, SubcollectionIndex new_subcollection) {
195 // Remove old collection meta
[12641]196 CollectionDesignManager.collectionmeta_manager.removeMetadata(StaticStrings.STOP_CHARACTER + old_subcollection.getID());
[12283]197 // Add new one
[12641]198 CollectionMeta metadatum = new CollectionMeta(StaticStrings.STOP_CHARACTER + new_subcollection.getID());
[12283]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 }
[9161]204
[12283]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
[4932]211 /** Method to set the default subcollection index.
[6770]212 * @param index The <strong>SubcollectionIndex</strong> to use as the default index.
[5590]213 * @see org.greenstone.gatherer.Gatherer
214 * @see org.greenstone.gatherer.collection.CollectionManager
[6770]215 * @see org.greenstone.gatherer.cdm.SubcollectionIndex
[5590]216 */
[12283]217 private void setDefault(SubcollectionIndex subcollection_index)
[9161]218 {
219 if (subcollection_index != null) {
220 if (default_index == null) {
[4932]221 // Create the default index element, and place immediately after indexes element.
[12641]222 Element default_index_element = root.getOwnerDocument().createElement(StaticStrings.SUBCOLLECTION_DEFAULT_INDEX_ELEMENT);
[4932]223 default_index = new SubcollectionIndex(default_index_element);
224 Node target_node = CollectionConfiguration.findInsertionPoint(default_index_element);
[9161]225 if (target_node != null) {
[4932]226 root.getOwnerDocument().getDocumentElement().insertBefore(default_index_element, target_node);
227 }
228 else {
229 root.getOwnerDocument().getDocumentElement().appendChild(default_index_element);
230 }
[9161]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 }
[4932]240 }
241
[9161]242
243 /** This class creates a set of controls for editing the indexes. */
244 private class SubcollectionIndexControls
[4932]245 extends JPanel
[9161]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;
[4932]254 private JButton set_default_button;
[9161]255 private JList subcollection_index_list;
256 private JTextField subcollection_index_name_textfield;
[4932]257
[9161]258
259 /** Constructor.
260 */
261 public SubcollectionIndexControls()
262 {
[4932]263 super();
264
[9161]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 }
[5590]270
[9161]271 // Creation
272 JPanel assigned_indexes_pane = new JPanel();
[12123]273 JLabel index_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Subindexes"));
274 subcollection_index_list = new JList(model);
[9161]275 subcollection_index_list.setCellRenderer(new SubcollectionIndexListCellRenderer());
276 subcollection_index_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
277 subcollection_index_list.setVisibleRowCount(2);
[4932]278
[9161]279 JPanel movement_pane = new JPanel();
[12123]280 move_up_button = new GLIButton(Dictionary.get("CDM.Move.Move_Up"), JarTools.getImage("arrow-up.gif"), Dictionary.get("CDM.Move.Move_Up_Tooltip"));
[9562]281 move_up_button.setEnabled(false);
[12123]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"));
[9562]284 move_down_button.setEnabled(false);
[12123]285
286 set_default_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Set_Default_Subindex_Tooltip"));
[9161]287 set_default_button.setEnabled(false);
[12123]288
[9161]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();
[4932]294
[12123]295 JLabel source_label = new JLabel(Dictionary.get("CDM.SubcollectionIndexManager.Source"));
296
[9161]297 source_list = new CheckList(false);
298 source_list.setListData(sources);
[12123]299 source_list.setToolTipText(Dictionary.get("CDM.SubcollectionIndexManager.Source_Tooltip"));
300
[9161]301 JPanel button_pane = new JPanel();
[12123]302 add_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Add_Subindex_Tooltip"));
[9161]303 add_button.setEnabled(false);
[12123]304
305 remove_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Remove_Subindex_Tooltip"));
[9161]306 remove_button.setEnabled(false);
[12123]307
308 replace_button = new GLIButton(Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex"), Dictionary.get("CDM.SubcollectionIndexManager.Replace_Subindex_Tooltip"));
[9161]309 replace_button.setEnabled(false);
[12123]310
[9161]311 // Listeners
312 add_button.addActionListener(new AddListener());
[10237]313 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]314 move_down_button.addActionListener(new MoveListener(false));
[10237]315 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]316 move_up_button.addActionListener(new MoveListener(true));
[10237]317 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]318 remove_button.addActionListener(new RemoveListener());
[10237]319 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]320 replace_button.addActionListener(new ReplaceListener());
[10237]321 replace_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[9161]322 set_default_button.addActionListener(new SetDefaultListener());
[10237]323 set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
[12283]324 subcollection_index_list.addListSelectionListener(new AssignedListListener());
[9161]325 source_list.addListSelectionListener(new SourceListListener());
326
[4932]327 // Layout
[9161]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);
[4932]333
[9161]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);
[4932]339
[9161]340 labels_pane.setLayout(new BorderLayout());
341 labels_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
342 labels_pane.add(source_label, BorderLayout.CENTER);
[4932]343
[9161]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);
[4932]350
[9161]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);
[5236]355
[9161]356 index_pane.setLayout(new BorderLayout());
357 index_pane.add(details_pane, BorderLayout.CENTER);
358 index_pane.add(button_pane, BorderLayout.SOUTH);
[5212]359
[9161]360 content_pane.setLayout(new BorderLayout());
361 content_pane.add(assigned_indexes_pane, BorderLayout.NORTH);
362 content_pane.add(index_pane, BorderLayout.CENTER);
363
[4932]364 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
365 setLayout(new BorderLayout());
[9161]366 add(content_pane, BorderLayout.CENTER);
[4932]367 }
368
[9161]369
370 public void destroy()
371 {
[5903]372 }
373
[9161]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
[12283]388 clearControls();
389
[4932]390 }
391
[9161]392
[12283]393 public void loseFocus() {
[4932]394 }
395
[12283]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);
[9161]405
[12283]406 }
407
[9161]408 private void updateControlsWithSelectedIndex()
409 {
410 SubcollectionIndex selected_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
411 if (selected_index == null) {
[12283]412 source_list.clearTicked();
[9161]413 return;
414 }
415
416 // Display the selected subcollection index's sources
[9200]417 source_list.clearTicked();
418 source_list.setTickedObjects(selected_index.getSources().toArray());
[4932]419 }
420
[9161]421
[12283]422 private void validateButtons() {
423
[9161]424 boolean add_enabled = false;
425 boolean replace_enabled = false;
426
427 // Can't add a new index if no sources are selected
[12283]428 if (!source_list.isNothingTicked()) {
429 ArrayList sources = source_list.getTicked();
[9161]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
[12283]433 if (!model.contains(subcollection_index)) {
[9161]434 add_enabled = true;
[12283]435 if (!subcollection_index_list.isSelectionEmpty()) {
[9161]436 replace_enabled = true;
437 }
438 }
[4932]439 }
[9161]440
441 // We should now know the add_button state
442 add_button.setEnabled(add_enabled);
443 replace_button.setEnabled(replace_enabled);
[4932]444 }
445
[9161]446
447 private class AddListener
[12283]448 implements ActionListener {
449
[9161]450 public void actionPerformed(ActionEvent event)
451 {
[12283]452 if (!source_list.isNothingTicked()) {
[9200]453 ArrayList sources = source_list.getTicked();
[9161]454 SubcollectionIndex subcollection_index = new SubcollectionIndex(sources.toArray());
455 addSubcollectionIndex(subcollection_index);
[12283]456 clearControls();
[9161]457 }
[4932]458 }
459 }
460
[9161]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;
[4932]470 }
[9161]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);
[4932]480 }
481 }
482 }
483
[9161]484 private class RemoveListener
485 implements ActionListener
486 {
[12283]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);
[4932]492 }
493 }
[9161]494 }
[4932]495
[9161]496
497 private class ReplaceListener
[12283]498 implements ActionListener {
499
500 public void actionPerformed(ActionEvent event) {
501
502 if (subcollection_index_list.isSelectionEmpty()|| source_list.isNothingTicked()) {
[9161]503 // This should never happen, but just in case...
504 replace_button.setEnabled(false);
505 return;
[4932]506 }
[12283]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);
[9161]511 }
512 }
513
514
515 private class SetDefaultListener
[12283]516 implements ActionListener {
517
[9161]518 public void actionPerformed(ActionEvent event)
519 {
520 SubcollectionIndex subcollection_index = (SubcollectionIndex) subcollection_index_list.getSelectedValue();
521 if (subcollection_index != null) {
[12283]522 setDefault(subcollection_index);
[9161]523 // This should cause a repaint of just the desired row
524 subcollection_index_list.setSelectedValue(subcollection_index, true);
[4932]525 }
[9161]526 set_default_button.setEnabled(false);
[4932]527 }
528 }
[5236]529
530
[9161]531 private class SourceListListener
[12283]532 implements ListSelectionListener {
533
534 public void valueChanged(ListSelectionEvent event) {
535 if (event.getValueIsAdjusting()) {
536 return;
537 }
538 validateButtons();
[9161]539 }
540 }
541
542
[12283]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
[9161]549 if (event.getValueIsAdjusting()) {
550 return;
[5236]551 }
[9161]552
[12283]553 if (subcollection_index_list.isSelectionEmpty()) {
554 clearControls();
555 return;
556 }
557
[9161]558 int i = subcollection_index_list.getSelectedIndex();
559 int size = subcollection_index_list.getModel().getSize();
[12283]560
[9161]561 // Enable the buttons appropriately
562 remove_button.setEnabled(true);
[12283]563 replace_button.setEnabled(false);
564 add_button.setEnabled(false);
[9161]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();
[5236]582 }
583 }
[9161]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 }
[4932]598 }
599}
Note: See TracBrowser for help on using the repository browser.