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

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

Changed all access to the static strings through CollectionConfiguration to directly use StaticStrings.

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