source: gli/trunk/src/org/greenstone/gatherer/cdm/DepositorMetadataManager.java@ 18412

Last change on this file since 18412 was 18412, checked in by kjdon, 15 years ago

more modifications for RTL GLI, thanks to Amin Hedjazi

File size: 18.8 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.cdm;
28
29import java.awt.BorderLayout;
30import java.awt.Color;
31import java.awt.Component;
32import java.awt.Dimension;
33import java.awt.event.ActionEvent;
34import java.awt.event.ActionListener;
35import java.io.File;
36import java.util.ArrayList;
37
38import javax.swing.BorderFactory;
39import javax.swing.BoxLayout;
40import javax.swing.JCheckBox;
41import javax.swing.JComboBox;
42import javax.swing.JComponent;
43import javax.swing.JOptionPane;
44import javax.swing.JPanel;
45import javax.swing.JScrollPane;
46
47import org.greenstone.gatherer.Configuration;
48import org.greenstone.gatherer.Dictionary;
49import org.greenstone.gatherer.Gatherer;
50import org.greenstone.gatherer.collection.CollectionManager;
51import org.greenstone.gatherer.gui.DesignPaneHeader;
52import org.greenstone.gatherer.gui.GComboBox;
53import org.greenstone.gatherer.metadata.MetadataElement;
54import org.greenstone.gatherer.metadata.MetadataSet;
55import org.greenstone.gatherer.metadata.MetadataSetManager;
56import org.greenstone.gatherer.util.Utility;
57
58/**
59 * This manager implements the "Depositor Metadata" section in GLI Format Panel, where
60 * users can customize which metadata elements will be used to describe an item when deposited in the Depositor.
61 *
62 * @author Anna Huang, Greenstone Digital Library, University of Waikato
63 * @version 1.0
64 */
65public class DepositorMetadataManager {
66 /** Display controls of the element */
67 static private Dimension LABEL_SIZE = new Dimension(150, 15);
68 static private Dimension ROW_SIZE = new Dimension(400, 20);
69
70 /** Available types, corresponds to the HTML input types */
71 static private String[] TYPEOPTIONS = new String[]{"text", "textarea"};
72 /** Default elements to be used in Depositor */
73 static private String DEFAULT_METADATA_ELEMENTS = "dc.Title, dc.Creator, dc.Description";
74 /** Definition attribute of a metadata element */
75 static private String DEFINITION = "definition";
76
77 /** Display controls */
78 private Control controls;
79 /** List of MetadataElementEntry objects, each represents a metadata element */
80 private ArrayList metadata_checklist_model = null;
81 /** Collection configuration file manager */
82 private CollectionMetaManager collmeta_manager = CollectionDesignManager.collectionmeta_manager;
83
84 public DepositorMetadataManager() {
85 }
86
87 /** Destructor. */
88 public void destroy() {
89 if (controls != null) {
90 controls.destroy();
91 controls = null;
92 }
93 if(metadata_checklist_model != null) {
94 metadata_checklist_model.clear();
95 metadata_checklist_model = null;
96 }
97 }
98
99 public Control getControls() {
100 if (controls == null) {
101 controls = new DepositorControl();
102 }
103 return controls;
104 }
105
106 /** Called when the detail mode has changed which in turn may cause several design elements to be available/hidden
107 * @param mode the new mode as an int
108 */
109 public void modeChanged(int mode) {
110 }
111
112 /**
113 * The implementation of this display control is similar to the <code>ArgumentConfiguration</code>,
114 * where each component in the central panel is another JPanel component consists of a checkbox and a drop down list.
115 */
116 private class DepositorControl
117 extends JPanel
118 implements Control {
119
120 private JPanel central_pane = null;
121
122 public DepositorControl() {
123 super();
124 this.setComponentOrientation(Dictionary.getOrientation());
125 JPanel header_panel = new DesignPaneHeader("CDM.GUI.DepositorMetadata", "depositormetadatasettings");
126
127 // load all possible metadata sets, and existing configuration
128 buildModel();
129
130 central_pane = new JPanel();
131 central_pane.setComponentOrientation(Dictionary.getOrientation());
132 central_pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
133 central_pane.setLayout(new BoxLayout(central_pane, BoxLayout.Y_AXIS));
134
135 // build the central pane, ie. create gui component for each metadata element
136 buildPane();
137
138 JPanel collection_checklist_pane = new JPanel();
139 collection_checklist_pane.setComponentOrientation(Dictionary.getOrientation());
140 collection_checklist_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
141 collection_checklist_pane.setLayout(new BorderLayout());
142 collection_checklist_pane.add(new JScrollPane(central_pane), BorderLayout.CENTER);
143
144 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
145 setLayout(new BorderLayout());
146 add(header_panel, BorderLayout.NORTH);
147 add(collection_checklist_pane, BorderLayout.CENTER);
148 }
149
150 public void destroy() {
151 }
152
153 public void gainFocus() {
154 }
155
156 public void loseFocus() {
157 StringBuffer converted_javascript = new StringBuffer();
158
159 // get currently selected metadata elements and create the javascript associative array variable
160 if (metadata_checklist_model != null) {
161 int size = metadata_checklist_model.size();
162 for(int i = 0; i < size; i++) {
163 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
164
165 if (entry.isSelected()) {
166 StringBuffer element = new StringBuffer();
167 element.append("{\"name\":\"").append(entry.name).append("\",");
168 element.append("\"label\":\"").append(entry.label).append("\",");
169 element.append("\"tooltip\":\"").append(entry.name).append(": ").append(entry.tooltip).append("\",");
170 element.append("\"type\":\"").append(entry.getType()).append("\"}");
171 if(converted_javascript.length() != 0) {
172 converted_javascript.append(", ");
173 }
174 converted_javascript.append(element);
175 element = null;
176 }
177 }
178
179 // if none of the elements were selected, use the default setting
180 if (converted_javascript.length() == 0) {
181 System.err.println("Error: DepositorMetadataMananger should have at least one selected metadata element.");
182 }
183
184 // save to the configuration file
185 CollectionMeta depositor_metadata_meta = collmeta_manager.getMetadatum("depositormetadata", true);
186 depositor_metadata_meta.setValue(converted_javascript.toString());
187 }
188 }
189
190 private void buildModel()
191 {
192 metadata_checklist_model = new ArrayList();
193 String current_coll_name = CollectionManager.getLoadedCollectionName();
194
195 // get the elements that have already been used in depositor
196 // add the "depositormetadata" meta if not found in the configuration file
197 CollectionMeta depositor_metadata_meta = collmeta_manager.getMetadatum("depositormetadata", true);
198 String selected_metadata_javascript = depositor_metadata_meta.getValue(true);
199
200 // load all MDSets in the collection, ie. .mds files in the collection's metadata directory
201 String file_name = Gatherer.getCollectDirectoryPath() + File.separator + current_coll_name + File.separator + "metadata";
202 ArrayList metadata_sets = MetadataSetManager.listMetadataSets(new File(file_name));
203
204 // if the collection doesn't have a metadata directory, load all the MDSets in the global GLI/metadata directory
205 if (metadata_sets == null) {
206 file_name = org.greenstone.gatherer.gems.MetadataSetManager.getGLIMetadataDirectoryPath();
207 metadata_sets = MetadataSetManager.listMetadataSets(new File(file_name));
208 }
209
210 // always load the dc mds
211 boolean found = false;
212 for (int i = 0, j = metadata_sets.size(); i < j; i++) {
213 if (((MetadataSet) metadata_sets.get(i)).getNamespace().equals("dc")) {
214 found = true;
215 break;
216 }
217 }
218 if (found == false) {
219 file_name = org.greenstone.gatherer.gems.MetadataSetManager.getGLIMetadataDirectoryPath();
220 file_name += "dublin.mds";
221 File dublin_mds_file = new File(file_name);
222 if (dublin_mds_file.exists()) {
223 MetadataSetManager.loadMetadataSet(dublin_mds_file);
224 metadata_sets = MetadataSetManager.getMetadataSets();
225 }
226 }
227
228 // unload the ex mds
229 for (int i = 0, j = metadata_sets.size(); i < j; i++) {
230 if (((MetadataSet) metadata_sets.get(i)).getNamespace().equals("ex")) {
231 metadata_sets.remove(i);
232 break;
233 }
234 }
235
236 if (metadata_sets == null) {
237 System.err.println("Error: DepositorMetadataMananger can't find any valid metadata set files.");
238 return;
239 }
240
241 // load all the metadata elements
242 for (int i = 0, j = metadata_sets.size(); i < j; i++) {
243 MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
244 ArrayList elements = metadata_set.getMetadataSetElements();
245
246 for (int k = 0; elements != null && k < elements.size(); k++) {
247 MetadataElement element = (MetadataElement) elements.get(k);
248 // all names are language independent at the moment.
249 MetadataElementEntry entry = new MetadataElementEntry (element.getFullName(), element.getName(), false);
250 entry.setToolTip(element.getAttribute(DEFINITION, "en"));
251 metadata_checklist_model.add(entry);
252 }
253 }
254
255 if (!selected_metadata_javascript.equals("")) {
256 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
257 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
258
259 String temp = "\"name\":\"" + entry.name + "\"";
260 if (selected_metadata_javascript.indexOf(temp) != -1) {
261 entry.setSelected(true);
262 entry.type = getValueFromJSAssociatedArray(selected_metadata_javascript, entry.name, "type");
263 }
264 temp = null;
265 }
266 } else {
267 // use default elements
268 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
269 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
270 if (DEFAULT_METADATA_ELEMENTS.indexOf(entry.name) != -1) {
271 entry.setSelected(true);
272 entry.type = TYPEOPTIONS[0];
273 }
274 }
275 }
276 }
277
278 private void buildPane() {
279 // use different background color for two adjacent metadata sets
280 String current_namespace = null;
281 String current_bgcolor_name = null;
282 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
283 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
284
285 if (current_namespace == null) {
286 current_namespace = entry.namespace;
287 current_bgcolor_name = "coloring.collection_tree_background";
288 } else {
289 if (!entry.namespace.equals(current_namespace)) {
290 current_namespace = entry.namespace;
291 current_bgcolor_name = (current_bgcolor_name == "coloring.collection_tree_background") ? "coloring.collection_heading_background" : "coloring.collection_tree_background";
292 }
293 }
294
295 if (entry.getGUIControl() == null) {
296 MetadataElementControl element_control = entry.initGUIControl(current_bgcolor_name);
297 central_pane.add(element_control, BorderLayout.NORTH);
298 }
299 }
300
301 }
302
303 /**
304 * Retrieve the value for the specified element in the given javascript associative array expression
305 *
306 * @param text
307 * @param identifier
308 * @param elem_name
309 * @return
310 */
311 private String getValueFromJSAssociatedArray(String text, String identifier, String elem_name) {
312 int p = text.indexOf(elem_name, text.indexOf(identifier));
313 if (p == -1) {
314 return null;
315 }
316 p = text.indexOf("\":\"", p);
317 if (p == -1) {
318 return null;
319 }
320 p += 3;
321
322 return text.substring(p, text.indexOf("\"", p));
323 }
324 }
325
326 private class MetadataElementControl extends JPanel {
327
328 private JCheckBox enabled = null;
329 private JComponent value_control = null;
330
331 public MetadataElementControl (MetadataElementEntry entry, String background_color_name) {
332
333 this.setComponentOrientation(Dictionary.getOrientation());
334 String tip = "<html>" + entry.tooltip + "</html>";
335 tip = Utility.formatHTMLWidth(tip, 80);
336
337 setBackground(Configuration.getColor(background_color_name, false));
338 setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
339 setLayout(new BorderLayout());
340 setPreferredSize(ROW_SIZE);
341
342 // the checkbox component
343 enabled = new JCheckBox(entry.name);
344 enabled.setSelected(entry.selected);
345 enabled.setOpaque(false);
346 enabled.setPreferredSize(LABEL_SIZE);
347 enabled.setToolTipText(entry.tooltip);
348 add(enabled, BorderLayout.WEST);
349
350 // the drop down list component
351 ArrayList option_list = new ArrayList();
352 for (int i = 0; i < TYPEOPTIONS.length; i++) {
353 option_list.add(TYPEOPTIONS[i]);
354 }
355 value_control = new GComboBox(option_list.toArray(), false, false);
356 selectValue((JComboBox)value_control, entry.type);
357 value_control.setOpaque(true);
358 if (entry.selected) {
359 value_control.setBackground(Color.white);
360 value_control.setEnabled(true);
361 } else {
362 value_control.setBackground(Color.lightGray);
363 value_control.setEnabled(false);
364 value_control.setVisible(false);
365 }
366 add(value_control, BorderLayout.CENTER);
367
368 enabled.addActionListener(new EnabledListener(value_control));
369 }
370
371 private boolean selectValue(JComboBox combobox, String target) {
372 if (target == null) {
373 combobox.setSelectedIndex(0);
374 return false;
375 }
376
377 for (int i = 0; i < combobox.getItemCount(); i++) {
378 if (combobox.getItemAt(i).toString().equals(target)) {
379 combobox.setSelectedIndex(i);
380 return true;
381 }
382 }
383 return false;
384 }
385
386 private class EnabledListener
387 implements ActionListener {
388 private JComponent target = null;
389
390 public EnabledListener(JComponent target) {
391 this.target = target;
392 }
393
394 public void actionPerformed(ActionEvent event) {
395 JCheckBox source = (JCheckBox)event.getSource();
396
397 // check at least one of the elements should be ticked
398 checkTickedElements(source);
399
400 // update the status of the drop-down list component associated with the current checkbox
401 if (this.target == null) {
402 return;
403 }
404
405 if(source.isSelected()) {
406 target.setBackground(Color.white);
407 target.setEnabled(true);
408 target.setVisible(true);
409 }
410 else {
411 target.setBackground(Color.lightGray);
412 target.setEnabled(false);
413 target.setVisible(false);
414 }
415 }
416
417 private void checkTickedElements(JCheckBox source) {
418 if (source.isSelected()) {
419 return;
420 }
421
422 boolean b = false;
423 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
424 if (((MetadataElementEntry) metadata_checklist_model.get(i)).gui_object.enabled.isSelected()) {
425 b = true;
426 break;
427 }
428 }
429
430 // there must be at least one element selected in the list
431 if (b == false) {
432 Object[] options = {Dictionary.get("General.OK")};
433 JOptionPane.showOptionDialog(Gatherer.g_man, Dictionary.get("CDM.DepositorMetadataManager.Warning"), Dictionary.get("General.Warning"), JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
434
435 source.setSelected(true);
436 }
437 }
438 }
439
440 }
441
442 private class MetadataElementEntry implements Comparable {
443 /** namespace, used to distinguish different metadata sets and use different colors when displaying */
444 String namespace = null;
445 /** identifier, with namespace */
446 String name = null;
447 /** language independent label, without namespace, used for display in the depositor web page, eg. Title */
448 String label = null;
449 /** type of the element: text or textarea */
450 String type = null;
451 /** description of the element, used in web page */
452 String tooltip = null;
453 /** whether current element is selected or not */
454 boolean selected ;
455 /** GUI component object associated with this element */
456 MetadataElementControl gui_object = null;
457
458 /**
459 * Constructor
460 * @param name Language independent identifier of the element with namespace, eg. dc.Title
461 * @param label Language independent label of the element, without namespace, eg. Title
462 * @param selected Whether the current element has been selected as depositor metadata element
463 */
464 public MetadataElementEntry(String name, String label, boolean selected) {
465 this.name = name;
466 this.label = label;
467 this.selected = selected;
468
469 if (name.indexOf(".") != -1) {
470 namespace = name.substring(0, name.indexOf("."));
471 }
472 }
473
474 /**
475 * Initiate the <code>MetadataElementControl<code> GUI component object associated with this element, with the specified background color
476 * @param background_color_name System configured color name for the background, eg. "coloring.collection_heading_background", or "coloring.collection_tree_background"
477 * @return the initialized component object
478 */
479 public MetadataElementControl initGUIControl (String background_color_name) {
480 gui_object = new MetadataElementControl(this, background_color_name);
481 return gui_object;
482 }
483
484 /**
485 * Get the associated GUI component
486 * @return
487 */
488 public MetadataElementControl getGUIControl() {
489 return gui_object;
490 }
491
492 /**
493 * Set selected
494 * @param b
495 */
496 public void setSelected(boolean b) {
497 this.selected = b;
498 }
499
500 public boolean isSelected() {
501 return gui_object.enabled.isSelected();
502 }
503
504 /**
505 * Get the selected type for the element
506 * @return type
507 */
508 public String getType() {
509 return ((JComboBox) gui_object.value_control).getSelectedItem().toString();
510 }
511
512 public void setToolTip (String tip) {
513 if (tip == null) {
514 tooltip = "";
515 return;
516 }
517 this.tooltip = tip;
518 }
519
520 public int compareTo(Object obj) {
521 return compareTo((MetadataElementEntry) obj);
522 }
523
524 public int compareTo(MetadataElementEntry obj) {
525 return this.name.compareTo(obj.name);
526 }
527
528 }
529
530}
Note: See TracBrowser for help on using the repository browser.