source: trunk/gli/src/org/greenstone/gatherer/metadata/MetadataValueTableModel.java@ 10971

Last change on this file since 10971 was 10971, checked in by kjdon, 18 years ago

metadata elements can now have predefined values, defined in the metadata set xml file. An element can have attributes predefined (have predefined metadata) and restricted (only allowed these predefined values). If there are predefined values, load them into the value tree, if its restricted, don't allow the user to add any other values

  • Property svn:keywords set to Author Date Id Revision
File size: 16.3 KB
Line 
1/**
2 *############################################################################
3 * A component of the Greenstone Librarian Interface, part of the Greenstone
4 * digital library suite from the New Zealand Digital Library Project at the
5 * University of Waikato, New Zealand.
6 *
7 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
8 *
9 * Copyright (C) 2004 New Zealand Digital Library Project
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *############################################################################
25 */
26
27package org.greenstone.gatherer.metadata;
28
29
30import java.awt.*;
31import java.io.*;
32import java.util.*;
33import javax.swing.*;
34import javax.swing.table.*;
35import org.greenstone.gatherer.Configuration;
36import org.greenstone.gatherer.DebugStream;
37import org.greenstone.gatherer.Dictionary;
38import org.greenstone.gatherer.Gatherer;
39import org.greenstone.gatherer.collection.CollectionTreeNode;
40import org.greenstone.gatherer.gui.WarningDialog;
41
42
43public class MetadataValueTableModel
44 extends AbstractTableModel
45{
46 /** The CollectionTreeNodes this model is built for */
47 private CollectionTreeNode[] file_nodes = null;
48 /** The list of MetadataValueTableEntries in the table */
49 private ArrayList metadata_value_table_entries = new ArrayList();
50
51 static final private String[] COLUMN_NAMES = { "", Dictionary.get("Metadata.Element"), Dictionary.get("Metadata.Value") };
52
53
54 public int addBlankRowForMetadataElement(MetadataElement metadata_element)
55 {
56 MetadataValueTableModelBuilder metadata_value_table_model_builder = new MetadataValueTableModelBuilder();
57 MetadataValue blank_metadata_value = new MetadataValue(metadata_element, new MetadataValueTreeNode(""));
58 return metadata_value_table_model_builder.insertMetadataValue(blank_metadata_value);
59 }
60
61
62 public int findMetadataValueTableEntryToSelect(MetadataValueTableEntry metadata_value_table_entry)
63 {
64 MetadataElement metadata_element = metadata_value_table_entry.getMetadataElement();
65
66 // Find the correct entry to select
67 for (int i = 0; i < metadata_value_table_entries.size(); i++) {
68 MetadataValueTableEntry current_metadata_value_table_entry = (MetadataValueTableEntry) metadata_value_table_entries.get(i);
69 int element_comparison = MetadataSetManager.compareMetadataElements(current_metadata_value_table_entry.getMetadataElement(), metadata_element);
70
71 // We've found the right element, so check if the value already exists
72 if (element_comparison == 0) {
73 int value_comparison = current_metadata_value_table_entry.compareTo(metadata_value_table_entry);
74 if (value_comparison == 0) {
75 // Entry found!
76 return i;
77 }
78 }
79
80 // We've just gone past the correct entry to select
81 if (element_comparison > 0) {
82 return i - 1;
83 }
84 }
85
86 // Have to select the last entry
87 return metadata_value_table_entries.size() - 1;
88 }
89
90
91 public Class getColumnClass(int col)
92 {
93 return getValueAt(0, col).getClass();
94 }
95
96
97 /** Returns the number of columns in this table. */
98 public int getColumnCount()
99 {
100 return COLUMN_NAMES.length;
101 }
102
103
104 /** Retrieves the name of the specified column. */
105 public String getColumnName(int col)
106 {
107 return COLUMN_NAMES[col];
108 }
109
110
111 /* Called to retrieve the MetadataValueTableEntry at a certain row. Usually caused by the user selecting a row in the table. It is synchronized so that the model doesn't up and change while we're trying to retrieve the indicated element. */
112 public synchronized MetadataValueTableEntry getMetadataValueTableEntry(int row)
113 {
114 if (row >= 0 && row < metadata_value_table_entries.size()) {
115 return (MetadataValueTableEntry) metadata_value_table_entries.get(row);
116 }
117
118 return null;
119 }
120
121
122 /** Returns the number of rows in this table. */
123 public int getRowCount()
124 {
125 return metadata_value_table_entries.size();
126 }
127
128
129 /** Returns the cell value at a given row and column as an Object. */
130 public Object getValueAt(int row, int col)
131 {
132 // Check values are reasonable
133 if (row < 0 || row >= metadata_value_table_entries.size() || col < 0 || col >= COLUMN_NAMES.length) {
134 return null;
135 }
136
137 MetadataValueTableEntry metadata_value_table_entry = (MetadataValueTableEntry) metadata_value_table_entries.get(row);
138 if (col == 0 && metadata_value_table_entry.isInheritedMetadata()) {
139 return metadata_value_table_entry.getFolderMetadataInheritedFrom();
140 }
141
142 if (col == 1) {
143 return metadata_value_table_entry.getMetadataElement();
144 }
145
146 if (col == 2) {
147 return metadata_value_table_entry.getFullValue();
148 }
149
150 return null;
151 }
152
153
154 public boolean isCellEditable(int row, int col)
155 {
156 // The inherited and element columns are never editable
157 if (col < 2) {
158 return false;
159 }
160
161 // Extracted and inherited metadata is not editable
162 MetadataValueTableEntry metadata_value_table_entry = (MetadataValueTableEntry) metadata_value_table_entries.get(row);
163 if (metadata_value_table_entry.getMetadataElement().isExtractedMetadataElement() || metadata_value_table_entry.isInheritedMetadata()) {
164 return false;
165 }
166
167 return true;
168 }
169
170
171 /** Determine if the given metadata is common to all selected file nodes. */
172 public boolean isCommon(MetadataValueTableEntry metadata_value_table_entry)
173 {
174 return (file_nodes != null && metadata_value_table_entry.getOccurrences() == file_nodes.length);
175 }
176
177
178 /** Determine if the given metadata is common to all selected file nodes. */
179 public boolean isCommon(int row)
180 {
181 if (row >= 0 && row < metadata_value_table_entries.size()) {
182 return isCommon((MetadataValueTableEntry) metadata_value_table_entries.get(row));
183 }
184
185 return false;
186 }
187
188
189 public void rebuild(CollectionTreeNode[] file_nodes)
190 {
191 this.file_nodes = file_nodes;
192 metadata_value_table_entries.clear();
193
194 // Collection is in a state of flux
195 if (!Gatherer.c_man.ready()) {
196 return;
197 }
198
199 if (file_nodes == null || file_nodes.length == 0) {
200 return;
201 }
202
203 // Create model builder
204 MetadataValueTableModelBuilder builder = new MetadataValueTableModelBuilder();
205 builder.run();
206 }
207
208
209 public void setValueAt(Object new_metadata_value, int row, int col)
210 {
211 MetadataValueTableEntry metadata_value_table_entry = getMetadataValueTableEntry(row);
212
213 // If nothing has changed no action is necessary
214 String old_metadata_value = metadata_value_table_entry.getFullValue();
215 if (new_metadata_value.equals(old_metadata_value)) {
216 return;
217 }
218
219 // Lock the interface so nothing can be changed while the metadata edit is being processed
220 Gatherer.g_man.wait(true);
221
222
223 // Check for a restricted metadata element
224 MetadataElement metadata_element = metadata_value_table_entry.getMetadataElement();
225 if (!new_metadata_value.equals("") && metadata_element.isRestricted()) {
226 if (metadata_element.getMetadataValueTreeNode((String)new_metadata_value)==null) {
227 WarningDialog dialog = new WarningDialog("warning.InvalidMetadata", "InvalidMetadata.Title", Dictionary.get("InvalidMetadata.Message"), null, false);
228 int dialog_result = dialog.display();
229 dialog.dispose();
230 Gatherer.g_man.wait(false);
231 return;
232
233 }
234 }
235
236 // Metadata value added
237 if (old_metadata_value.equals("") && !new_metadata_value.equals("")) {
238 // If we're adding metadata to folders display the warning
239 if (!file_nodes[0].isLeaf()) {
240 WarningDialog dialog = new WarningDialog("warning.DirectoryLevelMetadata", "DirectoryLevelMetadata.Title", Dictionary.get("DirectoryLevelMetadata.Message"), null, true);
241 int dialog_result = dialog.display();
242 dialog.dispose();
243 if (dialog_result != JOptionPane.OK_OPTION) {
244 Gatherer.g_man.wait(false);
245 return;
246 }
247 }
248
249 MetadataValueTreeNode metadata_value_tree_node = metadata_element.addMetadataValue((String) new_metadata_value);
250 MetadataValue metadata_value = new MetadataValue(metadata_element, metadata_value_tree_node);
251 metadata_value.setIsAccumulatingMetadata(true);
252 (new AppendMetadataTask(metadata_value)).run();
253 }
254
255 // Metadata value removed
256 else if (!old_metadata_value.equals("") && new_metadata_value.equals("")) {
257 (new RemoveMetadataTask(metadata_value_table_entry)).run();
258 }
259
260 // Metadata value replaced
261 else {
262 MetadataValueTreeNode metadata_value_tree_node = metadata_element.addMetadataValue((String) new_metadata_value);
263 MetadataValue metadata_value = new MetadataValue(metadata_element, metadata_value_tree_node);
264 metadata_value.setIsAccumulatingMetadata(!metadata_value_table_entry.isInheritedMetadata());
265 (new ReplaceMetadataTask(metadata_value_table_entry, metadata_value)).run();
266 }
267 }
268
269
270 private class AppendMetadataTask
271 // extends Thread
272 {
273 private MetadataValue metadata_value = null;
274
275 private AppendMetadataTask(MetadataValue metadata_value)
276 {
277 this.metadata_value = metadata_value;
278 }
279
280 public void run()
281 {
282 try {
283 // Edit metadata.xml files to add the metadata
284 MetadataXMLFileManager.addMetadata(file_nodes, metadata_value);
285 }
286 catch (Exception exception) {
287 // We need to catch any exceptions here so the interface is unlocked below
288 DebugStream.printStackTrace(exception);
289 }
290
291 // Operation finished, so turn busy cursor off and unlock interface
292 Gatherer.g_man.wait(false);
293 }
294 }
295
296
297 private class ReplaceMetadataTask
298 // extends Thread
299 {
300 private MetadataValueTableEntry selected_metadata_value_table_entry = null;
301 private MetadataValue metadata_value = null;
302
303 private ReplaceMetadataTask(MetadataValueTableEntry selected_metadata_value_table_entry, MetadataValue metadata_value)
304 {
305 this.selected_metadata_value_table_entry = selected_metadata_value_table_entry;
306 this.metadata_value = metadata_value;
307 }
308
309 public void run()
310 {
311 try {
312 // Edit metadata.xml files to replace the metadata
313 MetadataXMLFileManager.replaceMetadata(file_nodes, selected_metadata_value_table_entry, metadata_value);
314 }
315 catch (Exception exception) {
316 // We need to catch any exceptions here so the interface is unlocked below
317 DebugStream.printStackTrace(exception);
318 }
319
320 // Operation finished, so turn busy cursor off and unlock interface
321 Gatherer.g_man.wait(false);
322 }
323 }
324
325
326 private class RemoveMetadataTask
327 // extends Thread
328 {
329 private MetadataValueTableEntry selected_metadata_value_table_entry = null;
330
331 private RemoveMetadataTask(MetadataValueTableEntry selected_metadata_value_table_entry)
332 {
333 this.selected_metadata_value_table_entry = selected_metadata_value_table_entry;
334 }
335
336 public void run()
337 {
338 try {
339 // Edit metadata.xml files to remove the metadata
340 MetadataXMLFileManager.removeMetadata(file_nodes, selected_metadata_value_table_entry);
341 }
342 catch (Exception exception) {
343 // We need to catch any exceptions here so the interface is unlocked below
344 DebugStream.printStackTrace(exception);
345 }
346
347 // Operation finished, so turn busy cursor off and unlock interface
348 Gatherer.g_man.wait(false);
349 }
350 }
351
352
353 private class MetadataValueTableModelBuilder
354 {
355 public void run()
356 {
357 // System.err.println("Building MetadataValueTableModel...");
358
359 // Build a list of MetadataValueTableEntries that represent the metadata asssigned to the selected files
360 boolean hid_extracted_metadata = false;
361 ArrayList metadata_elements_seen = new ArrayList();
362
363 // Process each of the selected files in turn
364 for (int i = 0; i < file_nodes.length; i++) {
365 File current_file = file_nodes[i].getFile();
366
367 // Get the metadata assigned to this file
368 ArrayList assigned_metadata = MetadataXMLFileManager.getMetadataAssignedToFile(current_file);
369 for (int j = 0; j < assigned_metadata.size(); j++) {
370 MetadataValue metadata_value = (MetadataValue) assigned_metadata.get(j);
371 MetadataElement metadata_element = metadata_value.getMetadataElement();
372
373 // Insert this metadata value into the table, unless it already exists (in which case increment its count)
374 insertMetadataValue(metadata_value);
375
376 // Remember we have seen this metadata element
377 if (metadata_elements_seen.contains(metadata_element) == false) {
378 metadata_elements_seen.add(metadata_element);
379 }
380 }
381
382 // Get the extracted metadata for this file, if desired
383 if (Configuration.get("general.view_extracted_metadata", Configuration.COLLECTION_SPECIFIC) == true) {
384 ArrayList extracted_metadata = DocXMLFileManager.getMetadataExtractedFromFile(current_file);
385 for (int k = 0; k < extracted_metadata.size(); k++) {
386 MetadataValue metadata_value = (MetadataValue) extracted_metadata.get(k);
387
388 // Insert this metadata value into the table, unless it already exists (in which case increment its count)
389 insertMetadataValue(metadata_value);
390 }
391 }
392 }
393
394 // Make sure each non-extracted metadata element appears in the table (even if blank)
395 ArrayList every_metadata_set_element = MetadataSetManager.getEveryMetadataSetElement();
396 for (int i = 0; i < every_metadata_set_element.size(); i++) {
397 MetadataElement metadata_element = (MetadataElement) every_metadata_set_element.get(i);
398
399 // If we haven't seen this metadata element and it isn't extracted, add it now
400 if (!metadata_elements_seen.contains(metadata_element) && !metadata_element.isExtractedMetadataElement()) {
401 MetadataValueTableEntry metadata_value_table_entry = new MetadataValueTableEntry(metadata_element, new MetadataValueTreeNode(""));
402
403 // Blank metadata is common to all selected files (otherwise it wouldn't be blank!)
404 metadata_value_table_entry.setOccurrences(file_nodes.length);
405
406 // Add it to the table
407 insertMetadataValueTableEntry(metadata_value_table_entry);
408 }
409 }
410
411 // If extracted metadata was hidden, display the warning
412 if (hid_extracted_metadata) {
413 showExtractedMetadataWarning();
414 }
415 }
416
417
418 /** Inserts the new metadata value into the table */
419 private int insertMetadataValue(MetadataValue metadata_value)
420 {
421 return insertMetadataValueTableEntry(new MetadataValueTableEntry(metadata_value));
422 }
423
424
425 /** Inserts the new metadata value table entry into the table */
426 private int insertMetadataValueTableEntry(MetadataValueTableEntry metadata_value_table_entry)
427 {
428 MetadataElement metadata_element = metadata_value_table_entry.getMetadataElement();
429
430 // Find the correct place to insert the table entry
431 for (int i = 0; i < metadata_value_table_entries.size(); i++) {
432 MetadataValueTableEntry current_metadata_value_table_entry = (MetadataValueTableEntry) metadata_value_table_entries.get(i);
433 int element_comparison = MetadataSetManager.compareMetadataElements(current_metadata_value_table_entry.getMetadataElement(), metadata_element);
434
435 // We've found the right element, so check if the value already exists
436 if (element_comparison == 0) {
437 int value_comparison = current_metadata_value_table_entry.compareTo(metadata_value_table_entry);
438 if (value_comparison == 0) {
439 // Entry already exists, so increment count (except for blank entries)
440 if (!metadata_value_table_entry.getFullValue().equals("")) {
441 current_metadata_value_table_entry.anotherOccurrence();
442 }
443 return i;
444 }
445 }
446
447 // Found insertion point
448 if (element_comparison > 0) {
449 metadata_value_table_entries.add(i, metadata_value_table_entry);
450 fireTableRowsInserted(i, i);
451 return i;
452 }
453 }
454
455 // Must go at the end of the table
456 metadata_value_table_entries.add(metadata_value_table_entry);
457 fireTableRowsInserted(metadata_value_table_entries.size() - 1, metadata_value_table_entries.size() - 1);
458 return metadata_value_table_entries.size() - 1;
459 }
460
461
462 private void showExtractedMetadataWarning()
463 {
464 Runnable task = new Runnable() {
465 public void run() {
466 WarningDialog dialog = new WarningDialog("warning.ExtractedMetadata", "ExtractedMetadata.Title", Dictionary.get("ExtractedMetadata.Message"), null, false);
467 dialog.display();
468 dialog.dispose();
469 dialog = null;
470 }
471 };
472 SwingUtilities.invokeLater(task);
473 }
474 }
475}
Note: See TracBrowser for help on using the repository browser.