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

Last change on this file since 23433 was 23433, checked in by ak19, 13 years ago

GLI now has a gs.FilenameEncoding metadata field which appears like all the others in GLI's EnrichPane, but is unique in that this metadata (once set, changed or removed) must be applied to the affected filenames in the Collection Tree. More importantly, the changes made for this are to allow GLI's java code to interact with the recent changes to Perl where strings were made unicode-aware (for proper regex matching) but which required other changes elsewhere. To still support filenames with different encodings Perl used URL encoded versions of filenames representing characters' code point values in URL encoding. This required that GLI write out URL encoded filenames to the metadata.xml files that are associated with each folder level of a collection, so that Perl can read them. In this way, they can both speak of the same filenames. Only works on unicode 16 (such as latin-1), non-UTF8 systems. The latter is a requirement since Java uses the filesystem encoding from startup. If it is UTF8, non-recognised characters are replaced by the invalid char for UTF8. This process being destructive, we can't get the original filenames' bytecodes back. The changes made to GLI will work on Windows which is UTF-16 (windows codepage 1252), presumably also Macs (some kind of UTF-16) and also works on Native Latin 1 Linux systems. UTF-8 Linux systems need to be reconfigured to Native Latin-1, or if not installed, an administrator can install it easily.

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