source: trunk/gli/src/org/greenstone/gatherer/metadata/MetadataXMLFile.java@ 13817

Last change on this file since 13817 was 13817, checked in by shaoqun, 17 years ago

added unknown elements to metadata set because the user might disable skimfile in collection's .col file

  • Property svn:keywords set to Author Date Id Revision
File size: 28.4 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.io.*;
31import java.util.*;
32import org.greenstone.gatherer.DebugStream;
33import org.greenstone.gatherer.util.XMLTools;
34import org.w3c.dom.*;
35
36
37/** This class represents one metadata.xml file */
38public class MetadataXMLFile
39 extends File
40{
41 static final private String DESCRIPTION_ELEMENT = "Description";
42 static final private String DIRECTORY_FILENAME = ".*";
43 static final private String FILENAME_ELEMENT = "FileName";
44 static final private String FILESET_ELEMENT = "FileSet";
45 static final private String METADATA_ELEMENT = "Metadata";
46
47 // To speed things up a bit we keep the last accessed metadata.xml file in memory
48 static private File loaded_file = null;
49 static private Document loaded_file_document = null;
50 static private boolean loaded_file_changed = false;
51
52
53 public MetadataXMLFile(String metadata_xml_file_path)
54 {
55 super(metadata_xml_file_path);
56 }
57
58
59 public void addMetadata(File file, ArrayList metadata_values)
60 {
61 // If this metadata.xml file isn't the one currently loaded, load it now
62 if (loaded_file != this) {
63 // First we must save out the currently loaded file
64 saveLoadedFile();
65
66 // Parse the metadata.xml file
67 Document document = XMLTools.parseXMLFile(this);
68 if (document == null) {
69 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
70 return;
71 }
72
73 loaded_file = this;
74 loaded_file_document = document;
75 }
76
77 // Determine the file's path relative to the location of the metadata.xml file
78 String metadata_xml_file_directory_path = getParentFile().getAbsolutePath();
79 String file_relative_path = file.getAbsolutePath().substring(metadata_xml_file_directory_path.length());
80 if (file_relative_path.startsWith(File.separator)) {
81 file_relative_path = file_relative_path.substring(File.separator.length());
82 }
83
84 // Form a regular expression that specifies the scope of the metadata
85 String file_path_regexp;
86 if (file_relative_path.equals("")) {
87 // Special case for matching all files in the directory
88 file_path_regexp = DIRECTORY_FILENAME;
89 }
90 else {
91 // Convert the file path into a regular expression that will match it
92 file_path_regexp = MetadataTools.getRegularExpressionThatMatchesFilePath(file_relative_path);
93 }
94
95 // Find the appropriate FileSet element for this file
96 Element appropriate_fileset_element = null;
97
98 // Read all the FileSet elements in the file
99 NodeList fileset_elements_nodelist = loaded_file_document.getElementsByTagName(FILESET_ELEMENT);
100 for (int i = 0; i < fileset_elements_nodelist.getLength(); i++) {
101 Element current_fileset_element = (Element) fileset_elements_nodelist.item(i);
102
103 // Check the FileName elements of the FileSet to see if we have a match
104 NodeList filename_elements_nodelist = current_fileset_element.getElementsByTagName(FILENAME_ELEMENT);
105 for (int j = 0; j < filename_elements_nodelist.getLength(); j++) {
106 Element current_filename_element = (Element) filename_elements_nodelist.item(j);
107 String current_filename_element_value = XMLTools.getElementTextValue(current_filename_element);
108
109 // Only exact matches can be extended with new metadata
110 if (current_filename_element_value.equals(file_path_regexp)) {
111 appropriate_fileset_element = current_fileset_element;
112 break;
113 }
114 }
115 }
116
117 // If no appropriate FileSet element exists create a new one for this file
118 if (appropriate_fileset_element == null) {
119 DebugStream.println("Creating new FileSet element for file since none exists...");
120 appropriate_fileset_element = loaded_file_document.createElement(FILESET_ELEMENT);
121
122 Element new_filename_element = loaded_file_document.createElement(FILENAME_ELEMENT);
123 new_filename_element.appendChild(loaded_file_document.createTextNode(file_path_regexp));
124 appropriate_fileset_element.appendChild(new_filename_element);
125
126 Element new_description_element = loaded_file_document.createElement(DESCRIPTION_ELEMENT);
127 appropriate_fileset_element.appendChild(new_description_element);
128
129 loaded_file_document.getDocumentElement().appendChild(appropriate_fileset_element);
130 }
131
132 // Add each of the metadata values to the FileSet's Description element
133 Element description_element = (Element) appropriate_fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT).item(0);
134 for (int i = 0; i < metadata_values.size(); i++) {
135 MetadataValue metadata_value = (MetadataValue) metadata_values.get(i);
136 String metadata_element_name_full = metadata_value.getMetadataElement().getFullName();
137
138 // Remove any characters that are invalid in XML
139 String metadata_value_string = XMLTools.removeInvalidCharacters(metadata_value.getFullValue());
140
141 // Square brackets need to be escaped because they are a special character in Greenstone
142 metadata_value_string = metadata_value_string.replaceAll("\\[", "&#091;");
143 metadata_value_string = metadata_value_string.replaceAll("\\]", "&#093;");
144
145 // Check if this piece of metadata has already been assigned to this FileSet element
146 boolean metadata_already_assigned = false;
147 NodeList metadata_elements_nodelist = description_element.getElementsByTagName(METADATA_ELEMENT);
148 for (int k = 0; k < metadata_elements_nodelist.getLength(); k++) {
149 Element current_metadata_element = (Element) metadata_elements_nodelist.item(k);
150
151 // Check if the metadata element name matches
152 String current_metadata_element_name_full = current_metadata_element.getAttribute("name");
153 if (current_metadata_element_name_full.equals(metadata_element_name_full)) {
154 // Check if the metadata element value matches
155 String current_metadata_value_string = XMLTools.getElementTextValue(current_metadata_element);
156 if (current_metadata_value_string.equals(metadata_value_string)) {
157 // Metadata already assigned
158 metadata_already_assigned = true;
159 break;
160 }
161 }
162 }
163
164 // If the piece of metadata hasn't already been assigned, add it now
165 if (!metadata_already_assigned) {
166 // Create a new Metadata element to record this metadata
167 Element new_metadata_element = loaded_file_document.createElement(METADATA_ELEMENT);
168 new_metadata_element.setAttribute("name", metadata_value.getMetadataElement().getFullName());
169 new_metadata_element.setAttribute("mode", (metadata_value.isAccumulatingMetadata() ? "accumulate" : "override"));
170 new_metadata_element.appendChild(loaded_file_document.createTextNode(metadata_value_string));
171
172 // Accumulating metadata: add at the end
173 if (metadata_value.isAccumulatingMetadata()) {
174 description_element.appendChild(new_metadata_element);
175 }
176 // Override metadata: add at the start (so it overrides inherited metadata without affecting other assigned metadata)
177 else {
178 description_element.insertBefore(new_metadata_element, description_element.getFirstChild());
179 }
180 }
181 }
182
183 // Remember that we've changed the file so it gets saved when a new one is loaded
184 loaded_file_changed = true;
185 }
186
187
188 public ArrayList getMetadataAssignedToFile(File file)
189 {
190 // If this metadata.xml file isn't the one currently loaded, load it now
191 if (loaded_file != this) {
192 // First we must save out the currently loaded file
193 saveLoadedFile();
194
195 // Parse the metadata.xml file
196 Document document = XMLTools.parseXMLFile(this);
197 if (document == null) {
198 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
199 return new ArrayList();
200 }
201
202 loaded_file = this;
203 loaded_file_document = document;
204 }
205
206 // Determine the file's path relative to the location of the metadata.xml file
207 File metadata_xml_file_directory = getParentFile();
208 String file_relative_path = file.getAbsolutePath().substring(metadata_xml_file_directory.getAbsolutePath().length());
209 if (file_relative_path.startsWith(File.separator)) {
210 file_relative_path = file_relative_path.substring(File.separator.length());
211 }
212
213 // Build up a list of metadata assigned to this file
214 ArrayList metadata_values = new ArrayList();
215
216 // Read all the FileSet elements in the file
217 NodeList fileset_elements_nodelist = loaded_file_document.getElementsByTagName(FILESET_ELEMENT);
218 for (int i = 0; i < fileset_elements_nodelist.getLength(); i++) {
219 Element current_fileset_element = (Element) fileset_elements_nodelist.item(i);
220 boolean current_fileset_matches = false;
221 boolean is_one_file_only_metadata = true;
222 File folder_metadata_inherited_from = null;
223
224 // Check the FileName elements of the FileSet to see if we have a match
225 NodeList filename_elements_nodelist = current_fileset_element.getElementsByTagName(FILENAME_ELEMENT);
226 for (int j = 0; j < filename_elements_nodelist.getLength(); j++) {
227 Element current_filename_element = (Element) filename_elements_nodelist.item(j);
228 String current_filename_element_value = XMLTools.getElementTextValue(current_filename_element);
229
230 // Does this fileset specify metadata for one file only?
231 is_one_file_only_metadata = true;
232 if (current_filename_element_value.indexOf("*") != -1 && !current_filename_element_value.equals(DIRECTORY_FILENAME)) {
233 // No, it specifies metadata for multiple files (but not all the files in the directory)
234 is_one_file_only_metadata = false;
235 }
236
237 // This fileset specifies metadata for the file
238 if (file_relative_path.matches(current_filename_element_value)) {
239 current_fileset_matches = true;
240 if (!file_relative_path.equals("") && current_filename_element_value.equals(DIRECTORY_FILENAME)) {
241 folder_metadata_inherited_from = metadata_xml_file_directory;
242 }
243 break;
244 }
245
246 // This fileset specifies metadata for the folder the file is in
247 if (file_relative_path.startsWith(current_filename_element_value + File.separator)) {
248 current_fileset_matches = true;
249 folder_metadata_inherited_from = new File(metadata_xml_file_directory, current_filename_element_value);
250 break;
251 }
252 }
253
254 // The FileSet doesn't apply, so move onto the next one
255 if (current_fileset_matches == false) {
256 continue;
257 }
258
259 // Read all the Metadata elements in the fileset
260 NodeList metadata_elements_nodelist = current_fileset_element.getElementsByTagName(METADATA_ELEMENT);
261 for (int k = 0; k < metadata_elements_nodelist.getLength(); k++) {
262 Element current_metadata_element = (Element) metadata_elements_nodelist.item(k);
263 String metadata_element_name_full = current_metadata_element.getAttribute("name");
264 String metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
265
266 // Ignore legacy crap
267 if (metadata_set_namespace.equals("hidden")) {
268 continue;
269 }
270
271 MetadataSet metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
272 if (metadata_set == null) {
273 // The metadata set isn't loaded, so give the option of mapping the element into a loaded set
274 String target_metadata_element_name_full = MetadataSetManager.mapUnloadedMetadataElement(metadata_element_name_full);
275 if (target_metadata_element_name_full == null || target_metadata_element_name_full.equals("")) {
276 // Skip this element if we still don't have a loaded element for it
277 continue;
278 }
279
280 metadata_element_name_full = target_metadata_element_name_full;
281 metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
282 metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
283 }
284
285 MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(metadata_element_name_full);
286
287 String metadata_element_name = MetadataTools.getMetadataElementName(metadata_element_name_full);
288 // If the element doesn't exist in the metadata set, we're not interested
289 //Shaoqun modified. It needs to be added to metadata_set because the user might disable skim file
290 if (metadata_element == null) {
291 metadata_element = metadata_set.addMetadataElementForThisSession(metadata_element_name);
292 // continue;
293 }
294
295 // Square brackets need to be escaped because they are a special character in Greenstone
296 String metadata_value_string = XMLTools.getElementTextValue(current_metadata_element);
297 metadata_value_string = metadata_value_string.replaceAll("&#091;", "[");
298 metadata_value_string = metadata_value_string.replaceAll("&#093;", "]");
299
300 MetadataValueTreeNode metadata_value_tree_node = metadata_element.getMetadataValueTreeNode(metadata_value_string);
301
302 // If there is no metadata value tree node for this value, create it
303 if (metadata_value_tree_node == null) {
304 DebugStream.println("Note: No value tree node for metadata value \"" + metadata_value_string + "\"");
305 metadata_element.addMetadataValue(metadata_value_string);
306 metadata_value_tree_node = metadata_element.getMetadataValueTreeNode(metadata_value_string);
307 }
308
309 MetadataValue metadata_value = new MetadataValue(metadata_element, metadata_value_tree_node);
310 metadata_value.inheritsMetadataFromFolder(folder_metadata_inherited_from);
311 metadata_value.setIsOneFileOnlyMetadata(is_one_file_only_metadata);
312
313 // Is this accumulating metadata?
314 if (current_metadata_element.getAttribute("mode").equals("accumulate")) {
315 metadata_value.setIsAccumulatingMetadata(true);
316 }
317
318 // Add the new metadata value to the list
319 metadata_values.add(metadata_value);
320 }
321 }
322
323 return metadata_values;
324 }
325
326
327 public void removeMetadata(File file, ArrayList metadata_values)
328 {
329 // If this metadata.xml file isn't the one currently loaded, load it now
330 if (loaded_file != this) {
331 // First we must save out the currently loaded file
332 saveLoadedFile();
333
334 // Parse the metadata.xml file
335 Document document = XMLTools.parseXMLFile(this);
336 if (document == null) {
337 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
338 return;
339 }
340
341 loaded_file = this;
342 loaded_file_document = document;
343 }
344
345 // Determine the file's path relative to the location of the metadata.xml file
346 String metadata_xml_file_directory_path = getParentFile().getAbsolutePath();
347 String file_relative_path = file.getAbsolutePath().substring(metadata_xml_file_directory_path.length());
348 if (file_relative_path.startsWith(File.separator)) {
349 file_relative_path = file_relative_path.substring(File.separator.length());
350 }
351
352 // Form a regular expression that specifies the scope of the metadata
353 String file_path_regexp;
354 if (file_relative_path.equals("")) {
355 // Special case for matching all files in the directory
356 file_path_regexp = DIRECTORY_FILENAME;
357 }
358 else {
359 // Convert the file path into a regular expression that will match it
360 file_path_regexp = MetadataTools.getRegularExpressionThatMatchesFilePath(file_relative_path);
361 }
362
363 // Find the appropriate FileSet element for this file
364 Element appropriate_fileset_element = null;
365
366 // Read all the FileSet elements in the file
367 NodeList fileset_elements_nodelist = loaded_file_document.getElementsByTagName(FILESET_ELEMENT);
368 for (int i = 0; i < fileset_elements_nodelist.getLength(); i++) {
369 Element current_fileset_element = (Element) fileset_elements_nodelist.item(i);
370
371 // Check the FileName elements of the FileSet to see if we have a match
372 NodeList filename_elements_nodelist = current_fileset_element.getElementsByTagName(FILENAME_ELEMENT);
373 for (int j = 0; j < filename_elements_nodelist.getLength(); j++) {
374 Element current_filename_element = (Element) filename_elements_nodelist.item(j);
375 String current_filename_element_value = XMLTools.getElementTextValue(current_filename_element);
376
377 // Only exact matches can be extended with new metadata
378 if (current_filename_element_value.equals(file_path_regexp)) {
379 appropriate_fileset_element = current_fileset_element;
380 break;
381 }
382 }
383 }
384
385 // If no appropriate FileSet element exists the metadata isn't assigned in this metadata.xml file
386 if (appropriate_fileset_element == null) {
387 DebugStream.println("Note: No appropriate FileSet element found when removing metadata from " + this);
388 return;
389 }
390
391 // Remove each of the metadata values from the FileSet's Description element
392 for (int i = 0; i < metadata_values.size(); i++) {
393 MetadataValue metadata_value = (MetadataValue) metadata_values.get(i);
394
395 // Remove any characters that are invalid in XML
396 String metadata_value_string = XMLTools.removeInvalidCharacters(metadata_value.getFullValue());
397
398 // Square brackets need to be escaped because they are a special character in Greenstone
399 metadata_value_string = metadata_value_string.replaceAll("\\[", "&#091;");
400 metadata_value_string = metadata_value_string.replaceAll("\\]", "&#093;");
401
402 // Find the Metadata element to delete from the fileset
403 String metadata_element_name_full = metadata_value.getMetadataElement().getFullName();
404 NodeList metadata_elements_nodelist = appropriate_fileset_element.getElementsByTagName(METADATA_ELEMENT);
405 for (int k = 0; k < metadata_elements_nodelist.getLength(); k++) {
406 Element current_metadata_element = (Element) metadata_elements_nodelist.item(k);
407
408 // Check the metadata element name matches
409 String current_metadata_element_name_full = current_metadata_element.getAttribute("name");
410 if (current_metadata_element_name_full.equals(metadata_element_name_full)) {
411 // Check the metadata element value matches
412 String current_metadata_value_string = XMLTools.getElementTextValue(current_metadata_element);
413 if (current_metadata_value_string.equals(metadata_value_string)) {
414 // Remove this Metadata element
415 current_metadata_element.getParentNode().removeChild(current_metadata_element);
416
417 // If there are no Metadata elements left now, remove the (empty) FileSet element
418 if (metadata_elements_nodelist.getLength() == 0) {
419 appropriate_fileset_element.getParentNode().removeChild(appropriate_fileset_element);
420 }
421
422 break;
423 }
424 }
425 }
426 }
427
428 // Remember that we've changed the file so it gets saved when a new one is loaded
429 loaded_file_changed = true;
430 }
431
432
433 public void replaceMetadata(File file, MetadataValue old_metadata_value, MetadataValue new_metadata_value)
434 {
435 // If this metadata.xml file isn't the one currently loaded, load it now
436 if (loaded_file != this) {
437 // First we must save out the currently loaded file
438 saveLoadedFile();
439
440 // Parse the metadata.xml file
441 Document document = XMLTools.parseXMLFile(this);
442 if (document == null) {
443 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
444 return;
445 }
446
447 loaded_file = this;
448 loaded_file_document = document;
449 }
450
451 // Determine the file's path relative to the location of the metadata.xml file
452 String metadata_xml_file_directory_path = getParentFile().getAbsolutePath();
453 String file_relative_path = file.getAbsolutePath().substring(metadata_xml_file_directory_path.length());
454 if (file_relative_path.startsWith(File.separator)) {
455 file_relative_path = file_relative_path.substring(File.separator.length());
456 }
457
458 // Form a regular expression that specifies the scope of the metadata
459 String file_path_regexp;
460 if (file_relative_path.equals("")) {
461 // Special case for matching all files in the directory
462 file_path_regexp = DIRECTORY_FILENAME;
463 }
464 else {
465 // Convert the file path into a regular expression that will match it
466 file_path_regexp = MetadataTools.getRegularExpressionThatMatchesFilePath(file_relative_path);
467 }
468
469 // Remove any characters that are invalid in XML
470 String old_metadata_value_string = XMLTools.removeInvalidCharacters(old_metadata_value.getFullValue());
471 String new_metadata_value_string = XMLTools.removeInvalidCharacters(new_metadata_value.getFullValue());
472
473 // Square brackets need to be escaped because they are a special character in Greenstone
474 old_metadata_value_string = old_metadata_value_string.replaceAll("\\[", "&#091;");
475 old_metadata_value_string = old_metadata_value_string.replaceAll("\\]", "&#093;");
476 new_metadata_value_string = new_metadata_value_string.replaceAll("\\[", "&#091;");
477 new_metadata_value_string = new_metadata_value_string.replaceAll("\\]", "&#093;");
478
479 // Read all the FileSet elements in the file
480 NodeList fileset_elements_nodelist = loaded_file_document.getElementsByTagName(FILESET_ELEMENT);
481 for (int i = 0; i < fileset_elements_nodelist.getLength(); i++) {
482 Element current_fileset_element = (Element) fileset_elements_nodelist.item(i);
483 boolean current_fileset_matches = false;
484
485 // Check the FileName elements of the FileSet to see if we have a match
486 NodeList filename_elements_nodelist = current_fileset_element.getElementsByTagName(FILENAME_ELEMENT);
487 for (int j = 0; j < filename_elements_nodelist.getLength(); j++) {
488 Element current_filename_element = (Element) filename_elements_nodelist.item(j);
489 String current_filename_element_value = XMLTools.getElementTextValue(current_filename_element);
490
491 // Only exact matches can be edited
492 if (current_filename_element_value.equals(file_path_regexp)) {
493 current_fileset_matches = true;
494 break;
495 }
496 }
497
498 // The FileSet doesn't apply, so move onto the next one
499 if (current_fileset_matches == false) {
500 continue;
501 }
502
503 // Each metadata value is only allowed to be assigned once
504 boolean new_metadata_value_already_exists = false;
505 Element metadata_element_to_edit = null;
506
507 // Find the Metadata element to replace in the fileset
508 String metadata_element_name_full = old_metadata_value.getMetadataElement().getFullName();
509 NodeList metadata_elements_nodelist = current_fileset_element.getElementsByTagName(METADATA_ELEMENT);
510 for (int k = 0; k < metadata_elements_nodelist.getLength(); k++) {
511 Element current_metadata_element = (Element) metadata_elements_nodelist.item(k);
512
513 // Check the metadata element name matches
514 String current_metadata_element_name_full = current_metadata_element.getAttribute("name");
515 if (!current_metadata_element_name_full.equals(metadata_element_name_full)) {
516 continue;
517 }
518
519 // Check the new metadata value doesn't already exist
520 String current_metadata_value_string = XMLTools.getElementTextValue(current_metadata_element);
521 if (current_metadata_value_string.equals(new_metadata_value_string)) {
522 new_metadata_value_already_exists = true;
523 }
524
525 // Check the metadata element value matches
526 if (current_metadata_value_string.equals(old_metadata_value_string)) {
527 metadata_element_to_edit = current_metadata_element;
528 }
529 }
530
531 // If the new metadata value already existed, remove the original value
532 if (new_metadata_value_already_exists) {
533 metadata_element_to_edit.getParentNode().removeChild(metadata_element_to_edit);
534 }
535 // Otherwise replace the old value with the new value
536 // Ensure metadata_element_to_edit isn't null (may occur when multiple files are selected)
537 else if (metadata_element_to_edit != null) {
538 XMLTools.setElementTextValue(metadata_element_to_edit, new_metadata_value_string);
539 }
540 }
541
542 // Remember that we've changed the file so it gets saved when a new one is loaded
543 loaded_file_changed = true;
544 }
545
546
547 static public void saveLoadedFile()
548 {
549 // If we have a file loaded into memory and it has been modified, save it now
550 if (loaded_file != null && loaded_file_changed == true) {
551 XMLTools.writeXMLFile(loaded_file, loaded_file_document);
552 loaded_file_changed = false;
553 }
554 }
555
556
557 /**
558 * Every metadata.xml file must be skimmed when a collection is opened, for three very important reasons:
559 * - To handle any non-namespaced metadata in the metadata.xml files (this is mapped and the files rewritten)
560 * - To get a complete list of the metadata elements in the collection (used in Design and Format panes)
561 * - To build complete and accurate metadata value trees (used in the Enrich pane)
562 */
563 public void skimFile()
564 {
565 boolean file_changed = false;
566
567 // Parse the metadata.xml file
568 DebugStream.println("Skimming metadata.xml file " + this + "...");
569
570 Document document = XMLTools.parseXMLFile(this);
571 if (document == null) {
572 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
573 return;
574 }
575
576 // Read all the Metadata elements in the file
577 HashMap target_metadata_element_name_attrs_cache = new HashMap();
578 NodeList metadata_elements_nodelist = document.getElementsByTagName(METADATA_ELEMENT);
579 for (int i = 0; i < metadata_elements_nodelist.getLength(); i++) {
580 Element current_metadata_element = (Element) metadata_elements_nodelist.item(i);
581 String metadata_element_name_full = current_metadata_element.getAttribute("name");
582 String metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
583
584 // Ignore legacy crap
585 if (metadata_set_namespace.equals("hidden")) {
586 continue;
587 }
588
589 MetadataSet metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
590 if (metadata_set == null) {
591 // The metadata set isn't loaded, so give the option of mapping the element into a loaded set
592 String target_metadata_element_name_full = MetadataSetManager.mapUnloadedMetadataElement(metadata_element_name_full);
593 if (target_metadata_element_name_full == null || target_metadata_element_name_full.equals("")) {
594 // Skip this element if we still don't have a loaded element for it
595 continue;
596 }
597
598 // Update the metadata.xml file to have the new (namespaced) element name
599 // Instead of using current_metadata_element.setAttribute("name", target_metadata_element_name_full)
600 // we create an Attr object for each target metadata element name, and cache them
601 // This makes a *huge* difference (namespacing a metadata.xml file with 45000 metadata entries now
602 // takes 45 seconds instead of 30 minutes!) -- why is setting the value of a Node so slow?
603 Attr target_metadata_element_name_attr = (Attr) target_metadata_element_name_attrs_cache.get(target_metadata_element_name_full);
604 if (target_metadata_element_name_attr == null) {
605 target_metadata_element_name_attr = document.createAttribute("name");
606 target_metadata_element_name_attr.setValue(target_metadata_element_name_full);
607 target_metadata_element_name_attrs_cache.put(target_metadata_element_name_full, target_metadata_element_name_attr);
608 }
609
610 // Remove the old name attribute and add the new (namespaced) one
611 current_metadata_element.removeAttribute("name");
612 current_metadata_element.setAttributeNode((Attr) target_metadata_element_name_attr.cloneNode(false));
613 file_changed = true;
614
615 metadata_element_name_full = target_metadata_element_name_full;
616 metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
617 metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
618 }
619
620 String metadata_element_name = MetadataTools.getMetadataElementName(metadata_element_name_full);
621 MetadataElement metadata_element = metadata_set.getMetadataElementWithName(metadata_element_name);
622
623 // If the element doesn't exist in the metadata set, add it
624 if (metadata_element == null) {
625 metadata_element = metadata_set.addMetadataElementForThisSession(metadata_element_name);
626 }
627
628 // Square brackets need to be escaped because they are a special character in Greenstone
629 String metadata_value_string = XMLTools.getElementTextValue(current_metadata_element);
630 metadata_value_string = metadata_value_string.replaceAll("&#091;", "[");
631 metadata_value_string = metadata_value_string.replaceAll("&#093;", "]");
632
633 metadata_element.addMetadataValue(metadata_value_string);
634 }
635
636 // Rewrite the metadata.xml file if it has changed
637 if (file_changed) {
638 XMLTools.writeXMLFile(this, document);
639 }
640 }
641}
Note: See TracBrowser for help on using the repository browser.