source: trunk/gli/src/org/greenstone/gatherer/cdm/SearchTypeManager.java@ 10332

Last change on this file since 10332 was 10237, checked in by mdewsnip, 19 years ago

New code for "incremental" building, by Matthew Whyte.

I've only had time to look at this briefly; I've fixed a few obvious problems but I imagine this will be pretty flaky for a while.

  • Property svn:keywords set to Author Date Id Revision
File size: 21.5 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29/**************************************************************************************
30 * Written: 16/07/03
31 * Revised:
32 **************************************************************************************/
33import java.awt.*;
34import java.awt.event.*;
35import java.util.*;
36import javax.swing.*;
37import javax.swing.event.*;
38import org.greenstone.gatherer.Configuration;
39import org.greenstone.gatherer.DebugStream;
40import org.greenstone.gatherer.Dictionary;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.gui.GComboBox;
43import org.greenstone.gatherer.gui.GLIButton;
44import org.greenstone.gatherer.util.JarTools;
45import org.w3c.dom.*;
46
47/** This class maintains an ordered list of the search types available in the collection (MGPP/lucene command available in G2.39 or later). Currently only 'form' and 'plain' are valid.
48 * @author John Thompson, Greenstone Digital Library, University of Waikato
49 * @version 2.4
50 */
51public class SearchTypeManager
52 extends DOMProxyListModel
53{
54 static final private Dimension LABEL_SIZE = new Dimension(150, 25);
55
56 static final public String[] SEARCH_TYPES = { "plain" , "form"};
57 static final public String[] BUILD_TYPES = { "lucene", "mgpp" };
58
59 /** the buildtype element in the config file - searchtypemanager looks
60 * after this now */
61 public CollectionMeta build_type = null;
62 /** The controls used to edit the search types. */
63 private Control controls = null;
64 /** A reference to ourselves so our inner classes have access. */
65 private DOMProxyListModel model;
66
67 public SearchTypeManager(Element searchtypes_element) {
68 super(searchtypes_element, CollectionConfiguration.CONTENT_ELEMENT, new SearchType());
69 this.model = this;
70 DebugStream.println("SearchTypeManager: parsed " + getSize() + " search types.");
71 build_type = new CollectionMeta(CollectionDesignManager.collect_config.getBuildType());
72
73 }
74
75 private void addSearchType(SearchType searchtype) {
76 if(!contains(searchtype)) {
77 add(getSize(), searchtype);
78 Gatherer.c_man.configurationChanged();
79 }
80 }
81
82 public Control getControls() {
83 if(controls == null) {
84 controls = new SearchTypeControl();
85 }
86 return controls;
87 }
88
89 /** Return a list of the currently assigned search types as a comma separated string.
90 * @return a String
91 */
92 public String getSearchTypes() {
93 StringBuffer search_types = new StringBuffer();
94 ArrayList types = children();
95 for (int i = 0; i < types.size(); i++) {
96 if (i>0) {
97 search_types.append(",");
98 }
99 search_types.append(((SearchType)types.get(i)).getName());
100 }
101 return search_types.toString();
102 }
103
104 /** By examining the SearchType 'root' we were created with, determine if mgpp is enabled.
105 * @return true if MGPP is enabled, false otherwise
106 */
107 public boolean isMGPPEnabled() {
108 return root.getAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE).equals(CollectionConfiguration.TRUE_STR);
109 }
110
111 private void moveSearchType(SearchType search_type, boolean direction) {
112 // Try to move the classifier one step in the desired direction.
113 int index = indexOf(search_type);
114 if(direction) {
115 index--;
116 }
117 else {
118 index++;
119 }
120 // Check we aren't at an edge
121 if((direction && index < 0) || (!direction && index >= getSize())) {
122 String args[] = new String[2];
123 args[0] = Dictionary.get("CDM.SearchTypeManager.SearchType");
124 args[1] = search_type.toString();
125 String message = null;
126 if (direction) {
127 message = Dictionary.get("CDM.Move.At_Top", args);
128 }
129 else {
130 message = Dictionary.get("CDM.Move.At_Bottom", args);
131 }
132 JOptionPane.showMessageDialog(Gatherer.g_man, message, Dictionary.get("CDM.Move.Title"), JOptionPane.ERROR_MESSAGE);
133 return;
134 }
135 remove(search_type);
136 add(index, search_type);
137 Gatherer.c_man.configurationChanged();
138 }
139
140 private void removeSearchType(SearchType searchtype) {
141 if(contains(searchtype)) {
142 remove(searchtype);
143 Gatherer.c_man.configurationChanged();
144 }
145 }
146
147 private class SearchTypeControl
148 extends JPanel
149 implements Control {
150
151 private GComboBox search_type_combobox;
152 private GComboBox build_type_combobox;
153
154 private JButton add_button;
155 private JButton move_down_button;
156 private JButton move_up_button;
157 private JButton remove_button;
158
159 private JCheckBox enable_advanced_searches_checkbox;
160
161 private JLabel current_search_types_label;
162 private JLabel search_type_label;
163 private JLabel title_label;
164
165 private JList current_search_types_list;
166
167 private JTextArea instructions_textarea;
168
169 public SearchTypeControl() {
170
171 // Creation
172 title_label = new JLabel();
173 title_label.setHorizontalAlignment(JLabel.CENTER);
174 Dictionary.registerText(title_label, "CDM.SearchTypeManager.Title");
175
176 JPanel instructions_panel = new JPanel();
177 instructions_textarea = new JTextArea();
178 instructions_textarea.setCaretPosition(0);
179 instructions_textarea.setEditable(false);
180 instructions_textarea.setLineWrap(true);
181 instructions_textarea.setRows(6);
182 instructions_textarea.setWrapStyleWord(true);
183 Dictionary.registerText(instructions_textarea, "CDM.SearchTypeManager.Instructions");
184
185 JPanel spacer_panel = new JPanel();
186
187 JPanel empty_panel = new JPanel();
188
189 JPanel inner_panel = new JPanel();
190
191 JPanel indexer_type_panel = new JPanel();
192 JPanel build_type_panel = new JPanel();
193
194 enable_advanced_searches_checkbox = new JCheckBox();
195 Dictionary.registerText(enable_advanced_searches_checkbox, "CDM.SearchTypeManager.Enable");
196
197 build_type_combobox = new GComboBox(BUILD_TYPES);
198 build_type_combobox.setPreferredSize(LABEL_SIZE);
199 build_type_combobox.setBackgroundNonSelectionColor(Configuration.getColor("coloring.editable_background", false));
200 build_type_combobox.setBackgroundSelectionColor(Configuration.getColor("coloring.collection_selection_background", false));
201 build_type_combobox.setEditable(true);
202 build_type_combobox.setSelectedIndex(1);// mgpp is at 1
203 String selected_value = build_type.getValue(CollectionMeta.TEXT);
204 if (!selected_value.equals("")) {
205 for (int i=0; i<build_type_combobox.getItemCount();i++) {
206 String item = (String)build_type_combobox.getItemAt(i);
207 if (item.equals(selected_value)) {
208 build_type_combobox.setSelectedIndex(i);
209 break;
210 }
211 }
212 } else {
213 build_type.setValue((String)build_type_combobox.getSelectedItem());
214 build_type.setAssigned(isMGPPEnabled());
215
216 }
217 build_type_combobox.setTextNonSelectionColor(Configuration.getColor("coloring.workspace_tree_foreground", false));
218 build_type_combobox.setTextSelectionColor(Configuration.getColor("coloring.collection_selection_foreground", false));
219 Dictionary.registerTooltip(build_type_combobox, "CDM.SearchTypeManager.BuildType_Selection_Tooltip");
220
221 JLabel build_type_label = new JLabel();
222 Dictionary.registerText(build_type_label, "CDM.SearchTypeManager.BuildType_Selection");
223 JPanel current_search_types_panel = new JPanel();
224 current_search_types_label = new JLabel();
225 Dictionary.registerText(current_search_types_label, "CDM.SearchTypeManager.Assigned");
226 current_search_types_list = new JList(model);
227 current_search_types_list.setVisibleRowCount(3);
228
229 JPanel movement_panel = new JPanel();
230
231 move_up_button = new JButton("", JarTools.getImage("arrow-up.gif"));
232 move_up_button.setEnabled(false);
233 move_up_button.setMnemonic(KeyEvent.VK_U);
234
235 Dictionary.registerBoth(move_up_button, "CDM.Move.Move_Up", "CDM.Move.Move_Up_Tooltip");
236
237 move_down_button = new JButton("", JarTools.getImage("arrow-down.gif"));
238 move_down_button.setEnabled(false);
239 move_down_button.setMnemonic(KeyEvent.VK_D);
240
241 Dictionary.registerBoth(move_down_button, "CDM.Move.Move_Down", "CDM.Move.Move_Down_Tooltip");
242
243 JPanel search_type_panel = new JPanel();
244 search_type_label = new JLabel();
245 Dictionary.registerText(search_type_label, "CDM.SearchTypeManager.SearchType_Selection");
246 search_type_combobox = new GComboBox(SEARCH_TYPES);
247 search_type_combobox.setPreferredSize(LABEL_SIZE);
248 search_type_combobox.setBackgroundNonSelectionColor(Configuration.getColor("coloring.editable_background", false));
249 search_type_combobox.setBackgroundSelectionColor(Configuration.getColor("coloring.collection_selection_background", false));
250 search_type_combobox.setEditable(true);
251 search_type_combobox.setSelectedIndex(0);
252 search_type_combobox.setTextNonSelectionColor(Configuration.getColor("coloring.workspace_tree_foreground", false));
253 search_type_combobox.setTextSelectionColor(Configuration.getColor("coloring.collection_selection_foreground", false));
254 Dictionary.registerTooltip(search_type_combobox, "CDM.SearchTypeManager.SearchType_Selection_Tooltip");
255
256 JPanel button_panel = new JPanel();
257 add_button = new GLIButton();
258 add_button.setEnabled(false);
259 add_button.setMnemonic(KeyEvent.VK_A);
260 Dictionary.registerBoth(add_button, "CDM.SearchTypeManager.Add", "CDM.SearchTypeManager.Add_Tooltip");
261
262 remove_button = new GLIButton();
263 remove_button.setEnabled(false);
264 remove_button.setMnemonic(KeyEvent.VK_R);
265 Dictionary.registerBoth(remove_button, "CDM.SearchTypeManager.Remove", "CDM.SearchTypeManager.Remove_Tooltip");
266
267
268 // Connection
269 add_button.addActionListener(new AddActionListener());
270 add_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
271 build_type_combobox.addActionListener(new BuildTypeActionListener());
272 build_type_combobox.addActionListener(CollectionDesignManager.buildcol_change_listener);
273 current_search_types_list.addListSelectionListener(new CurrentSearchTypesListSelectionListener());
274 enable_advanced_searches_checkbox.addActionListener(new EnableAdvancedSearchesActionListener());
275 enable_advanced_searches_checkbox.addActionListener(CollectionDesignManager.buildcol_change_listener);
276 move_up_button.addActionListener(new MoveListener(true));
277 move_up_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
278 move_down_button.addActionListener(new MoveListener(false));
279 move_down_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
280 remove_button.addActionListener(new RemoveActionListener());
281 remove_button.addActionListener(CollectionDesignManager.buildcol_change_listener);
282 SearchTypesActionDocumentListener stadl = new SearchTypesActionDocumentListener();
283 search_type_combobox.addActionListener(stadl);
284 search_type_combobox.addActionListener(CollectionDesignManager.buildcol_change_listener);
285 ((JTextField)search_type_combobox.getEditor().getEditorComponent()).getDocument().addDocumentListener(stadl);
286
287 // Layout
288 instructions_panel.setBorder(BorderFactory.createEmptyBorder(0,0,2,0));
289 instructions_panel.setLayout(new BorderLayout());
290 instructions_panel.add(title_label, BorderLayout.NORTH);
291 instructions_panel.add(new JScrollPane(instructions_textarea), BorderLayout.CENTER);
292
293 movement_panel.setBorder(BorderFactory.createEmptyBorder(0,2,0,0));
294 movement_panel.setLayout(new GridLayout(2,1,5,0));
295 movement_panel.add(move_up_button);
296 movement_panel.add(move_down_button);
297
298 current_search_types_panel.setBorder(BorderFactory.createEmptyBorder(2,0,2,0));
299 current_search_types_panel.setLayout(new BorderLayout());
300 current_search_types_panel.add(current_search_types_label, BorderLayout.NORTH);
301 current_search_types_panel.add(new JScrollPane(current_search_types_list), BorderLayout.CENTER);
302 current_search_types_panel.add(movement_panel, BorderLayout.EAST);
303
304 build_type_panel.setLayout(new BorderLayout());
305 build_type_panel.add(build_type_label, BorderLayout.WEST);
306 build_type_panel.add(build_type_combobox, BorderLayout.CENTER);
307
308 indexer_type_panel.setLayout(new GridLayout(1,2,0,5));
309 indexer_type_panel.add(enable_advanced_searches_checkbox);
310 indexer_type_panel.add(build_type_panel);
311
312 button_panel.setBorder(BorderFactory.createEmptyBorder(2,0,0,0));
313 button_panel.setLayout(new GridLayout(1,2,0,5));
314 button_panel.add(add_button);
315 button_panel.add(remove_button);
316
317 search_type_panel.setLayout(new BorderLayout(5,3));
318 search_type_panel.add(search_type_label, BorderLayout.WEST);
319 search_type_panel.add(search_type_combobox, BorderLayout.CENTER);
320 search_type_panel.add(button_panel, BorderLayout.SOUTH);
321
322 inner_panel.setLayout(new BorderLayout());
323 inner_panel.add(indexer_type_panel, BorderLayout.NORTH);
324 inner_panel.add(current_search_types_panel, BorderLayout.CENTER);
325 inner_panel.add(search_type_panel, BorderLayout.SOUTH);
326
327 spacer_panel.setLayout(new BorderLayout());
328 spacer_panel.add(inner_panel, BorderLayout.NORTH);
329 spacer_panel.add(empty_panel, BorderLayout.CENTER);
330
331 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
332 setLayout(new BorderLayout());
333 add(instructions_panel, BorderLayout.NORTH);
334 add(spacer_panel, BorderLayout.CENTER);
335 }
336
337 public void destroy() {
338 }
339
340 public void gainFocus() {
341 instructions_textarea.setCaretPosition(0);
342 validateControls(isMGPPEnabled());
343 }
344
345 public void loseFocus() {
346
347 }
348
349 private void validateControls(boolean advanced_search_enabled) {
350 // Enable or disable controls based on whether MGPP is enabled
351 // validate add button, which depends on the current combobox selection and the contents of the assigned search types list
352 Object selected_item = search_type_combobox.getSelectedItem();
353 add_button.setEnabled(advanced_search_enabled && selected_item != null && !model.contains(selected_item));
354 // validate other controls.
355 current_search_types_list.setEnabled(advanced_search_enabled);
356 build_type_combobox.setEnabled(advanced_search_enabled);
357 enable_advanced_searches_checkbox.setSelected(advanced_search_enabled);
358 search_type_combobox.setEnabled(advanced_search_enabled);
359 remove_button.setEnabled(current_search_types_list.getModel().getSize() > 1 && !current_search_types_list.isSelectionEmpty() && advanced_search_enabled);
360 }
361
362 /** Listenes for actions on the Add button, and if detected adds a new search type. */
363 private class AddActionListener
364 implements ActionListener {
365 /** Called when someone actions the Add button.
366 * @param event an ActionEvent containing information about the add button click
367 */
368 public void actionPerformed(ActionEvent event) {
369 Object selected_item = search_type_combobox.getSelectedItem();
370 if(selected_item != null) {
371 if(search_type_combobox.getSelectedIndex() == -1) {
372 search_type_combobox.insertItemAt(selected_item, search_type_combobox.getItemCount());
373 }
374 // Add the search type
375 SearchType new_searchtype = new SearchType((String)selected_item);
376 addSearchType(new_searchtype);
377 }
378 add_button.setEnabled(false);
379 }
380 }
381
382 /** Listens for selections within the search types list and updates the remove button appropriately. */
383 private class CurrentSearchTypesListSelectionListener
384 implements ListSelectionListener {
385 /** Called when the selection in the list changes.
386 * @param event a ListSelectionEvent containing information about the selection change
387 */
388 public void valueChanged(ListSelectionEvent event) {
389 if(!event.getValueIsAdjusting()) {
390 SearchType search_type = null;
391 if ((search_type = (SearchType) current_search_types_list.getSelectedValue()) != null) {
392 int index = model.indexOf(search_type);
393 // Move up is only enabled if the current selection isn't at index 0
394 move_up_button.setEnabled(index != 0);
395 // Move down is only enabled if the current selection isn't at index getSize() - 1
396 move_down_button.setEnabled(index != model.getSize() - 1);
397 // Remove is only enabled if this isn't the last search type
398 remove_button.setEnabled(current_search_types_list.getModel().getSize() > 1);
399 }
400 else {
401 move_up_button.setEnabled(false);
402 move_down_button.setEnabled(false);
403 remove_button.setEnabled(false);
404 }
405 }
406 }
407 }
408
409 /** The most complex listener in this class, this listens for changes to the enable advanced searches checkbox, and when they occur it not only updates the controls on this page, but asks the IndexManager to action the appropriate changes to the underlying DOM so as to support either MG or MGPP styles of indexes. */
410 private class EnableAdvancedSearchesActionListener
411 implements ActionListener {
412 /** Called whenever the checkbox is checked or unchecked.
413 * @param event an ActionEvent containing information about the checking action
414 */
415 public void actionPerformed(ActionEvent event) {
416 Gatherer.g_man.wait(true);
417 boolean advanced_search_enabled = enable_advanced_searches_checkbox.isSelected();
418 model.root.setAttribute(CollectionConfiguration.ASSIGNED_ATTRIBUTE, (advanced_search_enabled ? CollectionConfiguration.TRUE_STR : CollectionConfiguration.FALSE_STR));
419 CollectionDesignManager.index_manager.setMGPPEnabled(advanced_search_enabled);
420 validateControls(advanced_search_enabled);
421 build_type.setAssigned(advanced_search_enabled);
422 Gatherer.g_man.wait(false);
423 }
424 }
425
426 private class BuildTypeActionListener
427 implements ActionListener {
428
429 public void actionPerformed(ActionEvent event) {
430 build_type.setValue((String)build_type_combobox.getSelectedItem());
431 }
432
433 }
434 /** Listenes for actions on the Remove button, and if detected removes the currently selected search types. */
435 private class RemoveActionListener
436 implements ActionListener {
437 /** Called when someone actions the Remove button.
438 * @param event an ActionEvent containing information about the remove button click
439 */
440 public void actionPerformed(ActionEvent event) {
441 if(!current_search_types_list.isSelectionEmpty()) {
442 Object[] selected_items = current_search_types_list.getSelectedValues();
443 for(int i = 0; model.getSize() > 1 && i < selected_items.length; i++) {
444 removeSearchType((SearchType)selected_items[i]);
445 }
446 }
447 Object selected_object = search_type_combobox.getSelectedItem();
448 if(selected_object != null) {
449 add_button.setEnabled(!model.contains(selected_object));
450 }
451 else {
452 add_button.setEnabled(false);
453 }
454 remove_button.setEnabled(false);
455 }
456 }
457
458 private class MoveListener
459 implements ActionListener {
460 private boolean move_up;
461 public MoveListener(boolean move_up) {
462 this.move_up = move_up;
463 }
464 public void actionPerformed(ActionEvent event) {
465 // Retrieve the first selected search type (if any)
466 SearchType search_type = null;
467 if((search_type = (SearchType) current_search_types_list.getSelectedValue()) != null) {
468 // Move search type
469 moveSearchType(search_type, move_up);
470 // Reselect the moved search type
471 current_search_types_list.setSelectedValue(search_type, true);
472 }
473 // No selection - no movement
474 else {
475 move_up_button.setEnabled(false);
476 move_down_button.setEnabled(false);
477 }
478 }
479 }
480
481 /** Listens for changes in the search types combobox, and enabled add button appropriately. */
482 private class SearchTypesActionDocumentListener
483 implements ActionListener, DocumentListener {
484 /** Called whenever a selection action occurs on the combobox.
485 * @param event an ActionEvent containing information about the selection event
486 */
487 public void actionPerformed(ActionEvent event) {
488 validateAddButton();
489 }
490
491 /** Gives notification that an attribute or set of attributes changed.
492 * @param event a DocumentEvent containing information about the text changed
493 */
494 public void changedUpdate(DocumentEvent event) {
495 validateAddButton();
496 }
497 /** Gives notification that there was an insert into the document.
498 * @param event a DocumentEvent containing information about the text added
499 */
500 public void insertUpdate(DocumentEvent event) {
501 validateAddButton();
502 }
503
504 /** Gives notification that a portion of the document has been removed.
505 * @param event a DocumentEvent containing information about the text removed
506 */
507 public void removeUpdate(DocumentEvent event) {
508 validateAddButton();
509 }
510
511 /** Change the enable state of the add button depending on the current value in the search type combobox. */
512 private void validateAddButton() {
513 Object selected_object = search_type_combobox.getSelectedItem();
514 if(selected_object != null) {
515 add_button.setEnabled(!model.contains(selected_object));
516 }
517 else {
518 add_button.setEnabled(false);
519 }
520 }
521 }
522 }
523}
Note: See TracBrowser for help on using the repository browser.