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

Last change on this file since 13577 was 13577, checked in by mdewsnip, 17 years ago

Sped up repeated operations on the same metadata.xml file by keeping the last accessed metadata.xml file in memory. This greatly speeds up metadata access on large metadata.xml files, and when multiple files are selected in the Enrich pane.

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