/**
*#########################################################################
*
* A component of the Gatherer application, part of the Greenstone digital
* library suite from the New Zealand Digital Library Project at the
* University of Waikato, New Zealand.
*
* Author: John Thompson, Greenstone Digital Library, University of Waikato
*
* Copyright (C) 1999 New Zealand Digital Library Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*########################################################################
*/
package org.greenstone.gatherer.cdm;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import org.greenstone.gatherer.Configuration;
import org.greenstone.gatherer.DebugStream;
import org.greenstone.gatherer.Dictionary;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.gui.DesignPaneHeader;
import org.greenstone.gatherer.gui.GComboBox;
import org.greenstone.gatherer.gui.GLIButton;
import org.greenstone.gatherer.metadata.MetadataElement;
import org.greenstone.gatherer.metadata.MetadataSetManager;
import org.greenstone.gatherer.util.CheckList;
import org.greenstone.gatherer.util.JarTools;
import org.greenstone.gatherer.util.StaticStrings;
import org.w3c.dom.*;
/** 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.
* @author John Thompson, Greenstone Digital Library, University of Waikato
* @version 2.3
*/
public class IndexManager
extends DOMProxyListModel {
static final private Dimension FIELD_SIZE = new Dimension(200,30);
static final private String ALLFIELDS = "allfields";
/** The controls for editing the indexes. */
private Control controls = null;
/** A model of the levels, also based on the DOM. */
private DOMProxyListModel levels_model = null;
/** A reference to ourselves so our inner methods have access. */
private DOMProxyListModel model = null;
/** The default index. */
private Index default_index = null;
/** Constructor. */
public IndexManager(Element indexes) {
super(indexes, CollectionConfiguration.INDEX_ELEMENT, new Index());
DebugStream.println("IndexManager: " + getSize() + " indexes parsed.");
model = this;
// Parse and retrieve the default index
NodeList default_index_elements = CollectionDesignManager.collect_config.getDocumentElement().getElementsByTagName(CollectionConfiguration.INDEX_DEFAULT_ELEMENT);
if(default_index_elements.getLength() > 0) {
default_index = new Index((Element)default_index_elements.item(0));
}
// Parse and retrieve the levels element
Element levels_element = CollectionDesignManager.collect_config.getLevels();
levels_model = new DOMProxyListModel(levels_element, CollectionConfiguration.CONTENT_ELEMENT, new Level());
DebugStream.println(" + " + levels_model.getSize() + " levels parsed.");
}
/** Method to add a new index.
* @param index The Index to add.
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.collection.CollectionManager
*/
private void addIndex(Index index, CollectionMeta metadatum) {
///ystem.err.println("Adding an index: " + index.toString());
if(!contains(index)) {
CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
// Retrieve the currently last index
if(getSize() > 0) {
Index last_index = (Index)getElementAt(getSize() - 1);
addAfter(index, last_index);
}
else {
add(index);
// Also set this index as the default one,
setDefault(index);
}
Gatherer.c_man.configurationChanged();
}
else {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.IndexManager.Index_Exists"), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
}
}
private void addLevel(Level level, CollectionMeta metadatum) {
if(!levels_model.contains(level)) {
CollectionDesignManager.collectionmeta_manager.addMetadatum(metadatum);
// Retrieve the currently last level
if(levels_model.getSize() > 0) {
Level last_level = (Level)levels_model.getElementAt(levels_model.getSize() - 1);
levels_model.addAfter(level, last_level);
}
else {
levels_model.add(level);
}
Gatherer.c_man.configurationChanged();
}
else {
JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("CDM.IndexManager.Level_Exists"), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
}
}
public void destroy() {
if(controls != null) {
controls.destroy();
controls = null;
}
default_index = null;
model = null;
}
/** Method to acquire the controls for editing the indexes.
* @return the Control
*/
public Control getControls() {
if(controls == null) {
// Build controls
controls = new IndexControl();
}
return controls;
}
/** Method to get the default index.
* @return The default Index.
*/
public Index getDefault() {
if(default_index != null && default_index.isAssigned()) {
return default_index;
}
else {
return null;
}
}
/** Method to retrieve a certain index, as referenced by an index number.
* @param index An int which indicates the position of the desired index.
* @return The Index at the given index, or null if no such index exists.
*/
public Index getIndex(int index) {
if(0 <= index && index < getSize()) {
return (Index)getElementAt(index);
}
return null;
}
/** Method to retrieve a certain index, given its id.
* @param id the id of the index as a String
* @return the Index that matches id, or null if no such index exists
*/
public Index getIndex(String id) {
int size = getSize();
for(int i = 0; i < size; i++) {
Index index = (Index) getElementAt(i);
if(index.getID().equals(id)) {
return index;
}
}
return null;
}
public ArrayList getIndexes() {
return children();
}
public Level getLevel(String name) {
int levels_model_size = levels_model.getSize();
for(int i = 0; i < levels_model_size; i++) {
Level level = (Level) levels_model.getElementAt(i);
if(level.getLevel().equals(name)) {
return level;
}
}
return null;
}
public int getNumLevels() {
return levels_model.getSize();
}
private void moveIndex(Index index, boolean move_up)
{
// Determine the current position of the index
int position = indexOf(index);
// Determine if it can be moved, ie if its not already at the top trying to move up, or at the bottom trying to move down.
if(position == -1) {
return;
}
if(position == 0 && move_up) {
return;
}
if(position == (getSize()) - 1 && !move_up) {
return;
}
// Ok, move up
if (move_up) {
position--;
remove(index);
add(position, index);
}
// Or move down
else {
position++;
remove(index);
add(position, index);
}
// Schedule the collection for saving
Gatherer.c_man.configurationChanged();
}
private void moveLevel(Level level, boolean move_up) {
// Determine the leveles current position
int position = levels_model.indexOf(level);
// Determine if it can be moved, ie if its not already at the top trying to move up, or at the bottom trying to move down.
if(position == -1) {
return;
}
if(position == 0 && move_up) {
return;
}
if(position == (levels_model.getSize()) - 1 && !move_up) {
return;
}
// Ok, move up
if(move_up) {
position--;
levels_model.remove(level);
levels_model.add(position, level);
}
// Or move down
else {
position++;
levels_model.remove(level);
levels_model.add(position, level);
}
// Schedule the collection for saving
Gatherer.c_man.configurationChanged();
}
/** Method to remove a certain index.
* @param index the Index to remove.
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.cdm.CollectionDesignManager
* @see org.greenstone.gatherer.cdm.CollectionMetaManager
* @see org.greenstone.gatherer.collection.CollectionManager
*/
private void removeIndex(Index index) {
if(index != null) {
// Remove any current metadata from this index
CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + index.getID());
// Remove the index
remove(index);
// Check if the index removed happens to be the default index
if(default_index != null && default_index.equals(index)) {
// If so our first solution is to set the first index to be default
if(getSize() > 0) {
Index another_index = (Index) getElementAt(0);
setDefault(another_index);
another_index = null;
}
else {
default_index.setAssigned(false);
}
}
Gatherer.c_man.configurationChanged();
}
}
private void removeLevel(Level level) {
if(level != null) {
// Remove any current metadata from this level
CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + level.getLevel());
// Remove the level
levels_model.remove(level);
Gatherer.c_man.configurationChanged();
}
}
/* replace an index in the list. new index may have the same sources but a
different name, or may be a new index altogether */
private void replaceIndex(Index old_index, Index new_index,
CollectionMeta coll_meta) {
if (old_index == null || new_index == null || coll_meta == null) {
return;
}
if (!old_index.getID().equals(new_index.getID()) && contains(new_index)) {
// shoudl we output an error??
return;
}
// Remove the old index coll meta
CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + old_index.getID());
// Add the new coll meta
CollectionDesignManager.collectionmeta_manager.addMetadatum(coll_meta);
// get the position of the old one
int position = indexOf(old_index);
// remove it
remove(old_index);
// add the new one at that position
add(position, new_index);
// Schedule the collection for saving
Gatherer.c_man.configurationChanged();
}
/** Method to set the default index.
* @param index the new default Index
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.collection.CollectionManager
*/
public void setDefault(Index index) {
if(index != null) {
if(default_index == null) {
// Create the default index element, and place immediately after indexes element.
Element default_index_element = root.getOwnerDocument().createElement(CollectionConfiguration.INDEX_DEFAULT_ELEMENT);
default_index = new Index(default_index_element);
Node target_node = CollectionConfiguration.findInsertionPoint(default_index_element);
if(target_node != null) {
root.getOwnerDocument().getDocumentElement().insertBefore(default_index_element, target_node);
}
else {
root.getOwnerDocument().getDocumentElement().appendChild(default_index_element);
}
}
default_index.setAssigned(true);
default_index.setLevel(index.getLevel());
default_index.setSources(index.getSources());
}
else {
if(default_index != null) {
default_index.setAssigned(false);
}
}
Gatherer.c_man.configurationChanged();
}
/** This method is reponsible for changing the underlying Index commands from MG to MGPP and back again. This turns out to be easyish for MG->MGPP and very hard for the reverse. For the former we remove the level fragment and make sure the same levels are set, then we produce a list of the sources involved, breaking down comma seperated lists and making sure each item it unique. Changing back the other way turns out to be impossible, so we don't (beyond generating document:text, section:text and paragraph:text if text is an index and the respective levels are present). In either case we start by creating a comment containing the old index information.
* @param state true to enable MGPP indexes, false to use standard MG style ones
*/
public void setMGPPEnabled(boolean state) {
if(state == root.getAttribute(CollectionConfiguration.MGPP_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR)) {
// we are not changing state
return;
}
// change MG -> MGPP
if(state) {
Element mg_element = root;
// Retrieve and assign the MGPP indexes element.
Element mgpp_element = CollectionDesignManager.collect_config.getMGPPIndexes();
mgpp_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
levels_model.root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
// If the MGPP indexes element is empty (ie was created by CollectionConfiguration), generate new MGPP index from the existing index
NodeList indexes = mgpp_element.getElementsByTagName(CollectionConfiguration.INDEX_ELEMENT);
if(indexes.getLength() == 0) {
ArrayList levels_list = new ArrayList();
ArrayList sources_list = new ArrayList();
// We first use details from the default index if any
if(default_index != null) {
int level_int = default_index.getLevel();
if(0 <= level_int && level_int < 3) {
String level = Index.LEVEL[level_int];
levels_list.add(level);
level = null;
}
ArrayList sources = default_index.getSources();
sources_list.addAll(sources);
}
int size = getSize();
for(int i = 0; i < size; i++) {
Index index = (Index) getElementAt(i);
int level_int = index.getLevel();
if(0 <= level_int && level_int < 3) {
String level = Index.LEVEL[level_int];
if(!levels_list.contains(level)) {
levels_list.add(level);
}
level = null;
}
ArrayList sources = index.getSources();
sources.removeAll(sources_list);
sources_list.addAll(sources);
index = null;
}
// Replace mg element with mgpp element
setRoot(mgpp_element);
// We now have a list of sources and a list of levels, so create new indexes and levels based on these
int sources_list_size = sources_list.size();
for(int j = 0; j < sources_list_size; j++) {
Object source_object = sources_list.get(j);
String source_str = null;
if(source_object instanceof MetadataElement) {
source_str = ((MetadataElement) source_object).getFullName();
}
else {
source_str = source_object.toString();
}
ArrayList new_sources = new ArrayList();
new_sources.add(source_object);
source_object = null;
Index new_index = new Index(new_sources);
// Try to retrieve existing metadatum
source_str = new_index.getID();
CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + source_str, false);
// If no metadata was found, add new pseudo metadata using the id
if(metadatum == null) {
metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source_str);
metadatum.setAssigned(true);
metadatum.setValue(source_str);
}
// If it was found, ensure it is assigned
else {
metadatum.setAssigned(true);
}
source_str = null;
addIndex(new_index, metadatum);
metadatum = null;
new_index = null;
new_sources = null;
source_str = null;
}
int levels_list_size = levels_list.size();
for(int k = 0; k < levels_list_size; k++) {
String level_name = (String)levels_list.get(k);
Level new_level = new Level(level_name);
if(!levels_model.contains(new_level)) {
CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + level_name, false);
// If no metadata was found, add new pseudo metadata using the id
if(metadatum == null) {
metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + level_name);
metadatum.setAssigned(true);
metadatum.setValue(level_name);
}
addLevel(new_level, metadatum);
}
new_level = null;
}
}
else {
// we already have mgpp indexes assigned
// Replace mg element with mgpp element
setRoot(mgpp_element);
}
// Unassign MG element and default index
mg_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
mg_element = null;
}
// change MGPP -> MG
else {
Element mgpp_element = root;
// Retrieve and assign MG element and default index element
Element mg_element = CollectionDesignManager.collect_config.getMGIndexes();
mg_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.TRUE_STR);
// If mg element has no indexes, and the current mgpp index include a text one, then generate text indexes for each of the registered levels.
NodeList indexes = mg_element.getElementsByTagName(CollectionConfiguration.INDEX_ELEMENT);
if(indexes.getLength() == 0) {
Index index = getIndex(CollectionConfiguration.TEXT_STR);
if(index != null) {
// Replace mgpp element with mg element
setRoot(mg_element);
int level_size = levels_model.getSize();
for(int i = 0; i < level_size; i++) {
Level level = (Level) levels_model.getElementAt(i);
Index new_index = new Index(level.getLevel(), index.getSources());
// Try to retrieve existing metadatum
String source_str = new_index.getID();
CollectionMeta metadatum = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER + source_str, false);
// If no metadata was found, add new pseudo metadata using the id
if(metadatum == null) {
metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source_str);
metadatum.setAssigned(true);
metadatum.setValue(source_str);
}
// If it was found, ensure it is assigned
else {
metadatum.setAssigned(true);
}
source_str = null;
addIndex(new_index, metadatum);
new_index = null;
level = null;
}
}
}
else {
// Replace mgpp element with mg element
setRoot(mg_element);
}
// Unassign mgpp element and levels
mgpp_element.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
levels_model.root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, CollectionConfiguration.FALSE_STR);
}
// its really hard to transfer defaults between mg and mgpp. so we'll just assign the first one to be the default.
Index first_index = (Index) getElementAt(0);
setDefault(first_index);
first_index = null;
}
/** This class creates a set of controls for editing the indexes. */
private class IndexControl
extends JPanel
implements Control {
// private JTextArea instruction_textarea;
private JList index_list;
private JButton move_down_button;
private JButton move_up_button;
private JButton set_default_button;
private JTextField name_textfield ;
private CheckList source_list;
// mg uses a level box
private JComboBox level_combobox;
// mgpp has a allfields selector
private JCheckBox allfields_box;
private JButton add_button;
private JButton add_all_button;
private JButton remove_button;
private JButton replace_button;
// soem panels that we need to manipulate later on
private JPanel boxes_pane;
private JPanel labels_pane;
private JLabel level_label;
private JPanel allfields_pane;
// we add in a tabbed pane for mgpp mode
private JTabbedPane tabbed_pane;
// the main index set up pane
private JPanel main_index_pane;
// for the levels tab in mgpp mode
private MGPPLevelsPanel mgpplevels_pane;
private boolean mgpp_enabled = false;
/** Constructor.
* @see org.greenstone.gatherer.Configuration
* @see org.greenstone.gatherer.Gatherer
* @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.AddListener
* @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.NameListener
* @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.RemoveListener
* @see org.greenstone.gatherer.cdm.IndexManager.IndexControl.SetDefaultListener
* @see org.greenstone.gatherer.collection.CollectionManager
*/
public IndexControl() {
super();
ArrayList new_data = new ArrayList();
new_data.add(CollectionConfiguration.TEXT_STR);
new_data.addAll(MetadataSetManager.getEveryMetadataSetElement());
// Creation
JPanel header_pane = new DesignPaneHeader("CDM.GUI.Indexes", "searchindexes");
JPanel assigned_indexes_pane = new JPanel();
JLabel index_label = new JLabel();
Dictionary.registerText(index_label, "CDM.IndexManager.Indexes");
index_list = new JList(model);
index_list.setCellRenderer(new IndexListRenderer());
index_list.setVisibleRowCount(2);
index_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JPanel movement_pane = new JPanel();
move_up_button = new JButton("", JarTools.getImage("arrow-up.gif"));
move_up_button.setEnabled(false);
move_up_button.setMnemonic(KeyEvent.VK_U);
Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
move_down_button = new JButton("", JarTools.getImage("arrow-down.gif"));
move_down_button.setEnabled(false);
move_down_button.setMnemonic(KeyEvent.VK_D);
Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
set_default_button = new GLIButton();
set_default_button.setEnabled(false);
set_default_button.setMnemonic(KeyEvent.VK_S);
Dictionary.registerBoth(set_default_button, "CDM.IndexManager.Set_Default", "CDM.IndexManager.Set_Default_Tooltip");
JPanel new_index_pane = new JPanel();
JPanel details_pane = new JPanel();
labels_pane = new JPanel();
boxes_pane = new JPanel();
main_index_pane = new JPanel();
JLabel name_label = new JLabel();
Dictionary.registerText(name_label, "CDM.IndexManager.Index_Name");
name_textfield = new JTextField();
name_textfield.setPreferredSize(FIELD_SIZE);
Dictionary.registerTooltip(name_textfield, "CDM.IndexManager.Index_Name_Tooltip");
JLabel source_label = new JLabel();
Dictionary.registerText(source_label, "CDM.IndexManager.Source");
source_list = new CheckList(false);
source_list.setListData(new_data);
Dictionary.registerTooltip(source_list, "CDM.IndexManager.Source_Tooltip");
level_label = new JLabel();
Dictionary.registerText(level_label, "CDM.IndexManager.Level");
level_combobox = new JComboBox();
level_combobox.setPreferredSize(FIELD_SIZE);
level_combobox.addItem(CollectionConfiguration.DOCUMENT_STR);//Dictionary.get("CDM.IndexManager.Document"));
level_combobox.addItem(CollectionConfiguration.PARAGRAPH_STR);//Dictionary.get("CDM.IndexManager.Paragraph"));
level_combobox.addItem(CollectionConfiguration.SECTION_STR);//Dictionary.get("CDM.IndexManager.Section"));
level_combobox.setEditable(false);
Dictionary.registerTooltip(level_combobox, "CDM.IndexManager.Level_Tooltip");
JPanel button_pane = new JPanel();
add_button = new GLIButton();
add_button.setEnabled(false);
add_button.setMnemonic(KeyEvent.VK_A);
Dictionary.registerBoth(add_button, "CDM.IndexManager.Add_Index", "CDM.IndexManager.Add_Index_Tooltip");
add_all_button = new GLIButton();
add_all_button.setEnabled(true);
add_all_button.setMnemonic(KeyEvent.VK_L);
Dictionary.registerBoth(add_all_button, "CDM.IndexManager.MGPP.Add_All_Metadata", "CDM.IndexManager.MGPP.Add_All_Metadata_Tooltip");
remove_button = new GLIButton();
remove_button.setEnabled(false);
remove_button.setMnemonic(KeyEvent.VK_R);
Dictionary.registerBoth(remove_button, "CDM.IndexManager.Remove_Index", "CDM.IndexManager.Remove_Index_Tooltip");
replace_button = new GLIButton();
replace_button.setEnabled(false);
replace_button.setMnemonic(KeyEvent.VK_P);
Dictionary.registerBoth(replace_button, "CDM.IndexManager.MGPP.Replace_Index", "CDM.IndexManager.MGPP.Replace_Index_Tooltip");
allfields_pane = new JPanel();
allfields_box = new JCheckBox();
JLabel allfields_label = new JLabel();
Dictionary.registerText(allfields_label, "CDM.IndexManager.Allfields_Index");
allfields_pane.setLayout(new BorderLayout());
allfields_pane.add(allfields_box, BorderLayout.WEST);
allfields_pane.add(allfields_label, BorderLayout.CENTER);
// Listeners
add_button.addActionListener(new AddListener());
add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
add_all_button.addActionListener(new AddAllActionListener());
add_all_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
remove_button.addActionListener(new RemoveListener());
remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
replace_button.addActionListener(new ReplaceListener());
replace_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
move_down_button.addActionListener(new MoveListener(false));
move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
move_up_button.addActionListener(new MoveListener(true));
move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
set_default_button.addActionListener(new SetDefaultListener());
set_default_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
name_textfield.getDocument().addDocumentListener(new NameListener());
level_combobox.addItemListener(new LevelListener());
index_list.addListSelectionListener(new IndexListListener());
source_list.addListSelectionListener(new SourceListListener());
allfields_box.addItemListener(new AllfieldsCheckBoxListener());
// Layout
movement_pane.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
movement_pane.setLayout(new GridLayout(3,1));
movement_pane.add(move_up_button);
movement_pane.add(move_down_button);
movement_pane.add(set_default_button);
assigned_indexes_pane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0));
assigned_indexes_pane.setLayout(new BorderLayout());
assigned_indexes_pane.add(index_label, BorderLayout.NORTH);
assigned_indexes_pane.add(new JScrollPane(index_list), BorderLayout.CENTER);
assigned_indexes_pane.add(movement_pane, BorderLayout.EAST);
labels_pane.setLayout(new BorderLayout());
labels_pane.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 5));
labels_pane.add(name_label, BorderLayout.NORTH);
labels_pane.add(source_label, BorderLayout.CENTER);
labels_pane.add(level_label, BorderLayout.SOUTH);
boxes_pane.setLayout(new BorderLayout());
boxes_pane.add(name_textfield, BorderLayout.NORTH);
boxes_pane.add(new JScrollPane(source_list), BorderLayout.CENTER);
boxes_pane.add(level_combobox, BorderLayout.SOUTH);
details_pane.setLayout(new BorderLayout());
details_pane.add(labels_pane, BorderLayout.WEST);
details_pane.add(boxes_pane, BorderLayout.CENTER);
button_pane.setLayout(new GridLayout(2,2,5,0));
button_pane.add(add_button);
button_pane.add(add_all_button);
button_pane.add(replace_button);
button_pane.add(remove_button);
new_index_pane.setLayout(new BorderLayout());
new_index_pane.add(details_pane, BorderLayout.CENTER);
new_index_pane.add(button_pane, BorderLayout.SOUTH);
main_index_pane.setLayout(new BorderLayout());
main_index_pane.add(assigned_indexes_pane, BorderLayout.NORTH);
main_index_pane.add(new_index_pane, BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
setLayout(new BorderLayout());
add(header_pane, BorderLayout.NORTH);
add(main_index_pane, BorderLayout.CENTER);
// for later, if we go to MGPP mode
tabbed_pane = new JTabbedPane();
}
/* Destructor, removes persistant listeners from the Dictionary.
*/
public void destroy() {
}
public void gainFocus() {
boolean old_mgpp_enabled = mgpp_enabled;
mgpp_enabled = CollectionDesignManager.searchtype_manager.isSearchTypeEnabled();
boolean changed_state = (old_mgpp_enabled != mgpp_enabled);
if (changed_state) {
// reset the underlying indexes and levels elements
setMGPPEnabled(mgpp_enabled);
}
/* reset the source list - may have built between then and now */
ArrayList new_data = new ArrayList();
new_data.add(CollectionConfiguration.TEXT_STR);
new_data.addAll(MetadataSetManager.getEveryMetadataSetElement());
source_list.setListData(new_data);
new_data = null;
if(mgpp_enabled) {
if (changed_state) {
// switch the variable bits
boxes_pane.remove(level_combobox);
labels_pane.remove(level_label);
boxes_pane.add(allfields_pane, BorderLayout.SOUTH);
//put back the tabbed pane
remove(main_index_pane);
add(tabbed_pane, BorderLayout.CENTER);
tabbed_pane.insertTab(Dictionary.get("CDM.IndexManager.MGPP.Indexes"), null, main_index_pane, null, 0);
if (mgpplevels_pane == null) {
mgpplevels_pane = new MGPPLevelsPanel();
tabbed_pane.insertTab(Dictionary.get("CDM.IndexManager.MGPP.Levels"), null, mgpplevels_pane, null, 1);
}
index_list.setSelectedIndex(0);
}
}
else {
if (changed_state) {
boxes_pane.remove(allfields_pane);
boxes_pane.add(level_combobox, BorderLayout.SOUTH);
labels_pane.add(level_label, BorderLayout.SOUTH);
remove(tabbed_pane);
tabbed_pane.remove(0);
add(main_index_pane, BorderLayout.CENTER);
source_list.setEnabled(true); // in case it had been disabled
allfields_box.setSelected(false);
index_list.setSelectedIndex(0);
}
}
updateControlsWithSelectedIndex();
}
public void loseFocus() {
}
private void updateControlsWithSelectedIndex() {
Index selected_index = (Index)index_list.getSelectedValue();
if (selected_index == null) {
return;
}
String id = selected_index.getID();
if (id == null || id.equals("")) {
return;
}
String name = CollectionDesignManager.collectionmeta_manager.getMetadatum("." + id).getValue(true);
name_textfield.setText(name);
if (!mgpp_enabled) {
level_combobox.setSelectedIndex(selected_index.getLevel());
}
source_list.clearTicked();
ArrayList sources = selected_index.getSources();
if (mgpp_enabled && sources.get(0).equals(ALLFIELDS)) {
source_list.setEnabled(false);
allfields_box.setSelected(true);
} else {
source_list.setTickedObjects(sources.toArray());
source_list.setEnabled(true);
allfields_box.setSelected(false);
}
}
private void validateAddButton() {
String new_index_name = name_textfield.getText();
// indexes must have a name
if (new_index_name.length() == 0) {
add_button.setEnabled(false);
replace_button.setEnabled(false);
return;
}
boolean add_enabled = false;
boolean replace_enabled = false;
Index index;
ArrayList sources;
if (mgpp_enabled && allfields_box.isSelected()) {
sources = new ArrayList();
sources.add(ALLFIELDS);
index = new Index(sources);
} else if (!source_list.isNothingTicked()) {
Object object[] = source_list.getTicked().toArray();
sources = new ArrayList();
for(int i = 0; i < object.length; i++) {
sources.add(object[i]);
}
object = null;
if (mgpp_enabled) {
index = new Index(sources);
} else {
index = new Index(level_combobox.getSelectedIndex(), sources);
}
} else {
add_button.setEnabled(false);
replace_button.setEnabled(false);
return;
}
sources = null;
if (model.contains(index)) {
add_enabled = false;
// may be able to replace if the index selected is the same but with a different name
if (index_list.getSelectedIndex() != -1) {
String id = index.getID();
String selected_index_id = ((Index)index_list.getSelectedValue()).getID();
if (id.equals(selected_index_id)) {
// check the name
String existing_index_name = CollectionDesignManager.collectionmeta_manager.getMetadatum(CollectionConfiguration.STOP_CHARACTER+id).getValue(true);
if (!existing_index_name.equals(new_index_name)) {
replace_enabled = true;
}
}
}
} else {
add_enabled = true;
if (index_list.getSelectedIndex() != -1) {
// there is something selected, so we can replace
replace_enabled = true;
}
}
// We should now know the button state
add_button.setEnabled(add_enabled);
replace_button.setEnabled(replace_enabled);
}
private class AddListener
implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String name = name_textfield.getText();
if (name.length() == 0) return;
Index index;
if (mgpp_enabled && allfields_box.isSelected()) {
ArrayList sources = new ArrayList();
sources.add(ALLFIELDS);
index = new Index(sources);
}
else if (!source_list.isNothingTicked()) {
ArrayList sources = source_list.getTicked();
if(mgpp_enabled) {
index = new Index(sources);
} else {
index = new Index(level_combobox.getSelectedIndex(), sources);
}
} else {
return;
}
// Before we add the index to the model, we have to add the collection metadata for this
CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + index.getID());
metadatum.setValue(name);
// Finally, add the index
addIndex(index, metadatum);
index_list.setSelectedValue(index, true);
add_button.setEnabled(false);
}
}
/** add all sources as indexes. for MG, this adds them in one combined
index, for MGPP this adds them as individual indexes (fields) */
private class AddAllActionListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
ArrayList all_sources = source_list.getAll();
if (!mgpp_enabled) {
Index index = new Index(level_combobox.getSelectedIndex(), all_sources);
if (!model.contains(index)) {
CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + index.getID());
metadatum.setValue("all fields"); // need a good name
addIndex(index, metadatum);
}
all_sources = null;
index = null;
return;
}
ArrayList new_sources = new ArrayList();
for(int i = 0; i < all_sources.size(); i++) {
Object source = all_sources.get(i);
// Create new index
new_sources.clear();
new_sources.add(source);
Index index = new Index(new_sources);
if(!model.contains(index)) {
// Determine the metadatum value
String name = source.toString();
if(name.startsWith(StaticStrings.EXTRACTED_NAMESPACE)) {
name = name.substring(StaticStrings.EXTRACTED_NAMESPACE.length());
}
// Create new metadatum
CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + index.getID());
metadatum.setValue(name);
name = null;
// Assign new index
addIndex(index, metadatum);
}
source = null;
index = null;
}
new_sources = null;
// Done. Disable add
add_button.setEnabled(false);
}
}
private class AllfieldsCheckBoxListener
implements ItemListener
{
public void itemStateChanged(ItemEvent event) {
if (event.getStateChange() == ItemEvent.SELECTED) {
source_list.setEnabled(false);
} else if (event.getStateChange() == ItemEvent.DESELECTED) {
source_list.setEnabled(true);
}
validateAddButton();
}
}
/** Listens for selections within the list on the IndexManager controls, and if a change is detected enables, or disables, controls appropriately. */
private class IndexListListener
implements ListSelectionListener
{
/** This method is called whenever the source list selection changes. When it does we need to fill in the various parts of the list description panel
* @param event A ListSelectionEvent containing further information about the list selection.
*/
public void valueChanged(ListSelectionEvent event)
{
if (event.getValueIsAdjusting()) {
return;
}
Object value = index_list.getSelectedValue();
if (value == null) {
move_down_button.setEnabled(false);
move_up_button.setEnabled(false);
remove_button.setEnabled(false);
replace_button.setEnabled(false);
set_default_button.setEnabled(false);
return;
}
// Enable the buttons appropriately
remove_button.setEnabled(true);
set_default_button.setEnabled(default_index == null || !default_index.equals(value));
int i = index_list.getSelectedIndex();
int size = index_list.getModel().getSize();
move_up_button.setEnabled((i>0));
move_down_button.setEnabled((i 0 && selected_object != null) {
add_level_button.setEnabled(getLevel((String)selected_object) == null);
}
else {
add_level_button.setEnabled(false);
}
}
private class AddLevelActionListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
// Retrieve the name
String name = level_name_field.getText();
// Retrieve the source
String source = (String)level_combobox.getSelectedItem();
Level level = new Level(source);
// Create new metadatum
CollectionMeta metadatum = new CollectionMeta(CollectionConfiguration.STOP_CHARACTER + source);
metadatum.setValue(name);
// Assign new level
int size = levels_model.getSize();
addLevel(level, metadatum);
current_levels_list.setSelectedValue(level, true);
add_level_button.setEnabled(false);
}
}
private class CurrentLevelsListSelectionListener
implements ListSelectionListener {
public void valueChanged(ListSelectionEvent event) {
if(event.getValueIsAdjusting()) {
return;
}
Level level = (Level)current_levels_list.getSelectedValue();
if(level != null) {
String full_text = level.toString();
if(full_text.indexOf("\"") != -1) {
level_name_field.setText(level.getName());
}
String level_id = level.getLevel();
level_combobox.setSelectedItem(level_id);
move_level_down_button.setEnabled((levels_model.indexOf(level) < levels_model.getSize() - 1));
move_level_up_button.setEnabled((levels_model.indexOf(level) > 0));
remove_level_button.setEnabled(true);
}
else {
move_level_down_button.setEnabled(false);
move_level_up_button.setEnabled(false);
remove_level_button.setEnabled(false);
}
}
}
private class EnableAddLevelListener
implements ActionListener, DocumentListener {
/** Called whenever a selection action occurs on the combobox.
* @param event an ActionEvent containing information about the selection event
*/
public void actionPerformed(ActionEvent event) {
validateAddButtonLevel();
}
/** Gives notification that an attribute or set of attributes changed.
* @param event a DocumentEvent containing information about the text changed
*/
public void changedUpdate(DocumentEvent event) {
validateAddButtonLevel();
}
/** Gives notification that there was an insert into the document.
* @param event a DocumentEvent containing information about the text added
*/
public void insertUpdate(DocumentEvent event) {
validateAddButtonLevel();
}
/** Gives notification that a portion of the document has been removed.
* @param event a DocumentEvent containing information about the text removed
*/
public void removeUpdate(DocumentEvent event) {
validateAddButtonLevel();
}
}
private class MoveLevelDownListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
// Retrieve the first selected item
Level level = (Level) current_levels_list.getSelectedValue();
moveLevel(level, false);
current_levels_list.setSelectedValue(level, true);
}
}
private class MoveLevelUpListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
// Retrieve the first selected item
Level level = (Level) current_levels_list.getSelectedValue();
moveLevel(level, true);
current_levels_list.setSelectedValue(level, true);
}
}
private class RemoveLevelActionListener
implements ActionListener {
public void actionPerformed(ActionEvent event) {
int i = current_levels_list.getSelectedIndex();
if (i != -1) {
Level level = (Level) current_levels_list.getSelectedValue();
CollectionDesignManager.collectionmeta_manager.removeMetadata(CollectionConfiguration.STOP_CHARACTER + level.getLevel());
removeLevel(level);
if (i == current_levels_list.getModel().getSize()) {
i--;
}
current_levels_list.setSelectedIndex(i);
}
if (i==-1) {
// Disable remove button
remove_level_button.setEnabled(false);
}
validateAddButtonLevel();
}
}
}
}