source: gli/branches/rtl-gli/src/org/greenstone/gatherer/cdm/DepositorMetadataManager.java@ 18352

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

updated the rtl-gli branch with files from trunk. Result of a merge 14807:18318

File size: 18.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
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
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.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
132 central_pane.setLayout(new BoxLayout(central_pane, BoxLayout.Y_AXIS));
133
134 // build the central pane, ie. create gui component for each metadata element
135 buildPane();
136
137 JPanel collection_checklist_pane = new JPanel();
138 collection_checklist_pane.setBorder(BorderFactory.createEmptyBorder(5,0,0,0));
139 collection_checklist_pane.setLayout(new BorderLayout());
140 collection_checklist_pane.add(new JScrollPane(central_pane), BorderLayout.CENTER);
141
142 setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
143 setLayout(new BorderLayout());
144 add(header_panel, BorderLayout.NORTH);
145 add(collection_checklist_pane, BorderLayout.CENTER);
146 }
147
148 public void destroy() {
149 }
150
151 public void gainFocus() {
152 }
153
154 public void loseFocus() {
155 StringBuffer converted_javascript = new StringBuffer();
156
157 // get currently selected metadata elements and create the javascript associative array variable
158 if (metadata_checklist_model != null) {
159 int size = metadata_checklist_model.size();
160 for(int i = 0; i < size; i++) {
161 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
162
163 if (entry.isSelected()) {
164 StringBuffer element = new StringBuffer();
165 element.append("{\"name\":\"").append(entry.name).append("\",");
166 element.append("\"label\":\"").append(entry.label).append("\",");
167 element.append("\"tooltip\":\"").append(entry.name).append(": ").append(entry.tooltip).append("\",");
168 element.append("\"type\":\"").append(entry.getType()).append("\"}");
169 if(converted_javascript.length() != 0) {
170 converted_javascript.append(", ");
171 }
172 converted_javascript.append(element);
173 element = null;
174 }
175 }
176
177 // if none of the elements were selected, use the default setting
178 if (converted_javascript.length() == 0) {
179 System.err.println("Error: DepositorMetadataMananger should have at least one selected metadata element.");
180 }
181
182 // save to the configuration file
183 CollectionMeta depositor_metadata_meta = collmeta_manager.getMetadatum("depositormetadata", true);
184 depositor_metadata_meta.setValue(converted_javascript.toString());
185 }
186 }
187
188 private void buildModel()
189 {
190 metadata_checklist_model = new ArrayList();
191 String current_coll_name = CollectionManager.getLoadedCollectionName();
192
193 // get the elements that have already been used in depositor
194 // add the "depositormetadata" meta if not found in the configuration file
195 CollectionMeta depositor_metadata_meta = collmeta_manager.getMetadatum("depositormetadata", true);
196 String selected_metadata_javascript = depositor_metadata_meta.getValue(true);
197
198 // load all MDSets in the collection, ie. .mds files in the collection's metadata directory
199 String file_name = Gatherer.getCollectDirectoryPath() + File.separator + current_coll_name + File.separator + "metadata";
200 ArrayList metadata_sets = MetadataSetManager.listMetadataSets(new File(file_name));
201
202 // if the collection doesn't have a metadata directory, load all the MDSets in the global GLI/metadata directory
203 if (metadata_sets == null) {
204 file_name = org.greenstone.gatherer.gems.MetadataSetManager.getGLIMetadataDirectoryPath();
205 metadata_sets = MetadataSetManager.listMetadataSets(new File(file_name));
206 }
207
208 // always load the dc mds
209 boolean found = false;
210 for (int i = 0, j = metadata_sets.size(); i < j; i++) {
211 if (((MetadataSet) metadata_sets.get(i)).getNamespace().equals("dc")) {
212 found = true;
213 break;
214 }
215 }
216 if (found == false) {
217 file_name = org.greenstone.gatherer.gems.MetadataSetManager.getGLIMetadataDirectoryPath();
218 file_name += "dublin.mds";
219 File dublin_mds_file = new File(file_name);
220 if (dublin_mds_file.exists()) {
221 MetadataSetManager.loadMetadataSet(dublin_mds_file);
222 metadata_sets = MetadataSetManager.getMetadataSets();
223 }
224 }
225
226 // unload the ex mds
227 for (int i = 0, j = metadata_sets.size(); i < j; i++) {
228 if (((MetadataSet) metadata_sets.get(i)).getNamespace().equals("ex")) {
229 metadata_sets.remove(i);
230 break;
231 }
232 }
233
234 if (metadata_sets == null) {
235 System.err.println("Error: DepositorMetadataMananger can't find any valid metadata set files.");
236 return;
237 }
238
239 // load all the metadata elements
240 for (int i = 0, j = metadata_sets.size(); i < j; i++) {
241 MetadataSet metadata_set = (MetadataSet) metadata_sets.get(i);
242 ArrayList elements = metadata_set.getMetadataSetElements();
243
244 for (int k = 0; elements != null && k < elements.size(); k++) {
245 MetadataElement element = (MetadataElement) elements.get(k);
246 // all names are language independent at the moment.
247 MetadataElementEntry entry = new MetadataElementEntry (element.getFullName(), element.getName(), false);
248 entry.setToolTip(element.getAttribute(DEFINITION, "en"));
249 metadata_checklist_model.add(entry);
250 }
251 }
252
253 if (!selected_metadata_javascript.equals("")) {
254 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
255 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
256
257 String temp = "\"name\":\"" + entry.name + "\"";
258 if (selected_metadata_javascript.indexOf(temp) != -1) {
259 entry.setSelected(true);
260 entry.type = getValueFromJSAssociatedArray(selected_metadata_javascript, entry.name, "type");
261 }
262 temp = null;
263 }
264 } else {
265 // use default elements
266 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
267 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
268 if (DEFAULT_METADATA_ELEMENTS.indexOf(entry.name) != -1) {
269 entry.setSelected(true);
270 entry.type = TYPEOPTIONS[0];
271 }
272 }
273 }
274 }
275
276 private void buildPane() {
277 // use different background color for two adjacent metadata sets
278 String current_namespace = null;
279 String current_bgcolor_name = null;
280 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
281 MetadataElementEntry entry = (MetadataElementEntry) metadata_checklist_model.get(i);
282
283 if (current_namespace == null) {
284 current_namespace = entry.namespace;
285 current_bgcolor_name = "coloring.collection_tree_background";
286 } else {
287 if (!entry.namespace.equals(current_namespace)) {
288 current_namespace = entry.namespace;
289 current_bgcolor_name = (current_bgcolor_name == "coloring.collection_tree_background") ? "coloring.collection_heading_background" : "coloring.collection_tree_background";
290 }
291 }
292
293 if (entry.getGUIControl() == null) {
294 MetadataElementControl element_control = entry.initGUIControl(current_bgcolor_name);
295 central_pane.add(element_control, BorderLayout.NORTH);
296 }
297 }
298
299 }
300
301 /**
302 * Retrieve the value for the specified element in the given javascript associative array expression
303 *
304 * @param text
305 * @param identifier
306 * @param elem_name
307 * @return
308 */
309 private String getValueFromJSAssociatedArray(String text, String identifier, String elem_name) {
310 int p = text.indexOf(elem_name, text.indexOf(identifier));
311 if (p == -1) {
312 return null;
313 }
314 p = text.indexOf("\":\"", p);
315 if (p == -1) {
316 return null;
317 }
318 p += 3;
319
320 return text.substring(p, text.indexOf("\"", p));
321 }
322 }
323
324 private class MetadataElementControl extends JPanel {
325
326 private JCheckBox enabled = null;
327 private JComponent value_control = null;
328
329 public MetadataElementControl (MetadataElementEntry entry, String background_color_name) {
330
331 String tip = "<html>" + entry.tooltip + "</html>";
332 tip = Utility.formatHTMLWidth(tip, 80);
333
334 setBackground(Configuration.getColor(background_color_name, false));
335 setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
336 setLayout(new BorderLayout());
337 setPreferredSize(ROW_SIZE);
338
339 // the checkbox component
340 enabled = new JCheckBox(entry.name);
341 enabled.setSelected(entry.selected);
342 enabled.setOpaque(false);
343 enabled.setPreferredSize(LABEL_SIZE);
344 enabled.setToolTipText(entry.tooltip);
345 add(enabled, BorderLayout.WEST);
346
347 // the drop down list component
348 ArrayList option_list = new ArrayList();
349 for (int i = 0; i < TYPEOPTIONS.length; i++) {
350 option_list.add(TYPEOPTIONS[i]);
351 }
352 value_control = new GComboBox(option_list.toArray(), false, false);
353 selectValue((JComboBox)value_control, entry.type);
354 value_control.setOpaque(true);
355 if (entry.selected) {
356 value_control.setBackground(Color.white);
357 value_control.setEnabled(true);
358 } else {
359 value_control.setBackground(Color.lightGray);
360 value_control.setEnabled(false);
361 value_control.setVisible(false);
362 }
363 add(value_control, BorderLayout.CENTER);
364
365 enabled.addActionListener(new EnabledListener(value_control));
366 }
367
368 private boolean selectValue(JComboBox combobox, String target) {
369 if (target == null) {
370 combobox.setSelectedIndex(0);
371 return false;
372 }
373
374 for (int i = 0; i < combobox.getItemCount(); i++) {
375 if (combobox.getItemAt(i).toString().equals(target)) {
376 combobox.setSelectedIndex(i);
377 return true;
378 }
379 }
380 return false;
381 }
382
383 private class EnabledListener
384 implements ActionListener {
385 private JComponent target = null;
386
387 public EnabledListener(JComponent target) {
388 this.target = target;
389 }
390
391 public void actionPerformed(ActionEvent event) {
392 JCheckBox source = (JCheckBox)event.getSource();
393
394 // check at least one of the elements should be ticked
395 checkTickedElements(source);
396
397 // update the status of the drop-down list component associated with the current checkbox
398 if (this.target == null) {
399 return;
400 }
401
402 if(source.isSelected()) {
403 target.setBackground(Color.white);
404 target.setEnabled(true);
405 target.setVisible(true);
406 }
407 else {
408 target.setBackground(Color.lightGray);
409 target.setEnabled(false);
410 target.setVisible(false);
411 }
412 }
413
414 private void checkTickedElements(JCheckBox source) {
415 if (source.isSelected()) {
416 return;
417 }
418
419 boolean b = false;
420 for (int i = 0, j = metadata_checklist_model.size(); i < j; i++) {
421 if (((MetadataElementEntry) metadata_checklist_model.get(i)).gui_object.enabled.isSelected()) {
422 b = true;
423 break;
424 }
425 }
426
427 // there must be at least one element selected in the list
428 if (b == false) {
429 Object[] options = {Dictionary.get("General.OK")};
430 JOptionPane.showOptionDialog(Gatherer.g_man, Dictionary.get("CDM.DepositorMetadataManager.Warning"), Dictionary.get("General.Warning"), JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
431
432 source.setSelected(true);
433 }
434 }
435 }
436
437 }
438
439 private class MetadataElementEntry implements Comparable {
440 /** namespace, used to distinguish different metadata sets and use different colors when displaying */
441 String namespace = null;
442 /** identifier, with namespace */
443 String name = null;
444 /** language independent label, without namespace, used for display in the depositor web page, eg. Title */
445 String label = null;
446 /** type of the element: text or textarea */
447 String type = null;
448 /** description of the element, used in web page */
449 String tooltip = null;
450 /** whether current element is selected or not */
451 boolean selected ;
452 /** GUI component object associated with this element */
453 MetadataElementControl gui_object = null;
454
455 /**
456 * Constructor
457 * @param name Language independent identifier of the element with namespace, eg. dc.Title
458 * @param label Language independent label of the element, without namespace, eg. Title
459 * @param selected Whether the current element has been selected as depositor metadata element
460 */
461 public MetadataElementEntry(String name, String label, boolean selected) {
462 this.name = name;
463 this.label = label;
464 this.selected = selected;
465
466 if (name.indexOf(".") != -1) {
467 namespace = name.substring(0, name.indexOf("."));
468 }
469 }
470
471 /**
472 * Initiate the <code>MetadataElementControl<code> GUI component object associated with this element, with the specified background color
473 * @param background_color_name System configured color name for the background, eg. "coloring.collection_heading_background", or "coloring.collection_tree_background"
474 * @return the initialized component object
475 */
476 public MetadataElementControl initGUIControl (String background_color_name) {
477 gui_object = new MetadataElementControl(this, background_color_name);
478 return gui_object;
479 }
480
481 /**
482 * Get the associated GUI component
483 * @return
484 */
485 public MetadataElementControl getGUIControl() {
486 return gui_object;
487 }
488
489 /**
490 * Set selected
491 * @param b
492 */
493 public void setSelected(boolean b) {
494 this.selected = b;
495 }
496
497 public boolean isSelected() {
498 return gui_object.enabled.isSelected();
499 }
500
501 /**
502 * Get the selected type for the element
503 * @return type
504 */
505 public String getType() {
506 return ((JComboBox) gui_object.value_control).getSelectedItem().toString();
507 }
508
509 public void setToolTip (String tip) {
510 if (tip == null) {
511 tooltip = "";
512 return;
513 }
514 this.tooltip = tip;
515 }
516
517 public int compareTo(Object obj) {
518 return compareTo((MetadataElementEntry) obj);
519 }
520
521 public int compareTo(MetadataElementEntry obj) {
522 return this.name.compareTo(obj.name);
523 }
524
525 }
526
527}
Note: See TracBrowser for help on using the repository browser.