/** *######################################################################### * * 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(); } } } }