source: trunk/gli/src/org/greenstone/gatherer/msm/GDMDocument.java@ 6318

Last change on this file since 6318 was 6202, checked in by jmt12, 20 years ago

As well as implementing a removeExtractedNodes method, also fixed error where not all metadata was removed when a file was

  • Property svn:keywords set to Author Date Id Revision
File size: 29.2 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer.msm;
28
29import java.io.*;
30import java.util.*;
31import org.greenstone.gatherer.Gatherer;
32import org.greenstone.gatherer.msm.GDMManager;
33import org.greenstone.gatherer.msm.MSMUtils;
34import org.greenstone.gatherer.util.Codec;
35import org.greenstone.gatherer.util.HashMap3D;
36import org.greenstone.gatherer.util.StaticStrings;
37import org.greenstone.gatherer.util.Utility;
38import org.greenstone.gatherer.valuetree.GValueModel;
39import org.greenstone.gatherer.valuetree.GValueNode;
40import org.w3c.dom.*;
41
42/** This class wraps around a DOM Document providing methods for accessing the data within. In this case the DOM represents a Greenstone Directory metadata file. It provides the necessary functionality to create a new metadata.xml file.
43 * @author John Thompson, Greenstone Digital Library, University of Waikato
44 * @version 2.3b
45 */
46public class GDMDocument {
47 /** Record if the document this object is based on is up to date. */
48 private boolean up_to_date = true;
49 /** The document this class sources its data from. */
50 private Document base_document;
51 static final private String ACCUMULATE = "accumulate";
52 /** The pattern to match when searching for directory level assignments. */
53 static final private String DIRECTORY_FILENAME = ".*";
54 static final private String DESCRIPTION_ELEMENT = "Description";
55 static final private String FILENAME_ELEMENT = "FileName";
56 static final private String FILESET_ELEMENT = "FileSet";
57 static final private String HVALUE_ATTRIBUTE = "hvalue";
58 static final private String MODE_ATTRIBUTE = "mode";
59 static final private String OVERWRITE = "overwrite";
60 static final private String[] ALL_METADATA_TYPES = {StaticStrings.METADATA_ELEMENT, StaticStrings.EXTRACTED_METADATA_ELEMENT};
61
62 /** Constructor which creates a brand new metadata.xml document. */
63 public GDMDocument() {
64 // Create new document. We do this by loading a copy of the template. */
65 this.base_document = Utility.parse(Utility.GREENSTONEDIRECTORYMETADATA_TEMPLATE, true);
66 }
67
68 /** Constructor which parses an existing metadata.xml document. */
69 public GDMDocument(File file) {
70 try {
71 this.base_document = Utility.parse(file.getAbsolutePath(), false);
72 }
73 catch (Exception error) {
74 // Poorly formed, or completely invalid metadata.xml file!
75 }
76 }
77
78 /** Constructor which wraps around an existing metadata.xml document. */
79 public GDMDocument(Document base_document) {
80 this.base_document = base_document;
81 }
82
83 /** Add this metadata to the named file. There is one tricky thing to consider. Whenever a metadata entry is added it is taken to be accumulating except if it is the first added, in which case it overwrites! Actually this gets worse, as we could have been told to append this metadata to a document which already inherits metadata. Thus we need a new argument to determine whether this add was triggered by an append or a replace. */
84 public void addMetadata(String filename, Metadata metadata, boolean force_accumulate) {
85 ///atherer.println("Add '" + metadata + "' to " + (filename != null ? filename : "directory."));
86 try {
87 // Retrieve the document element.
88 Element directorymetadata_element = base_document.getDocumentElement();
89 // Iterate through the filesets looking for one that matches the given filename.
90 Element fileset_element = null;
91 boolean found = false;
92 NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
93 for(int i = 0; !found && i < fileset_elements.getLength(); i++) {
94 fileset_element = (Element) fileset_elements.item(i);
95 NodeList filename_elements = fileset_element.getElementsByTagName(FILENAME_ELEMENT);
96 for(int j = 0; !found && j < filename_elements.getLength(); j++) {
97 Element filename_element = (Element) filename_elements.item(j);
98 String filename_pattern = MSMUtils.getValue(filename_element);
99 // Have we found a match. If so break out of for loop.
100 if(filename != null && filename.matches(filename_pattern) && !filename_pattern.equals(DIRECTORY_FILENAME)) {
101 ///ystem.err.println("Adding to existing file fileset!");
102 found = true;
103 }
104 else if(filename == null && filename_pattern.equals(DIRECTORY_FILENAME)) {
105 ///ystem.err.println("Adding to existing folder fileset!");
106 ///ystem.err.println("filename_pattern = '" + filename_pattern + "'");
107 found = true;
108 }
109 // No match. On to the next one.
110 else {
111 fileset_element = null;
112 }
113 filename_pattern = null;
114 filename_element = null;
115 }
116 }
117 fileset_elements = null;
118 // If we still haven't found an existing fileset, then its time to create one.
119 if(fileset_element == null) {
120 ///ystem.err.println("Creating a new fileset.");
121 fileset_element = base_document.createElement(FILESET_ELEMENT);
122 Element filename_element = base_document.createElement(FILENAME_ELEMENT);
123 Element description_element = base_document.createElement(DESCRIPTION_ELEMENT);
124 fileset_element.appendChild(filename_element);
125 fileset_element.appendChild(description_element);
126 Text filename_text = null;
127 // If the filename is null then we add a directory metadata set as directorymetadata_element's first child
128 if(filename == null) {
129 filename_text = base_document.createTextNode(DIRECTORY_FILENAME);
130 if(directorymetadata_element.hasChildNodes()) {
131 directorymetadata_element.insertBefore(fileset_element, directorymetadata_element.getFirstChild());
132 }
133 else {
134 directorymetadata_element.appendChild(fileset_element);
135 }
136 }
137 // Otherwise we just append the new fileset to directorymetadata_element's children.
138 else {
139 filename_text = base_document.createTextNode(filename);
140 directorymetadata_element.appendChild(fileset_element);
141 }
142 filename_element.appendChild(filename_text);
143 filename_text = null;
144 description_element = null;
145 filename_element = null;
146 }
147 // Now, finally, we can add the metadata.
148 Element metadata_element = null;
149 String name = metadata.getElement().getName();
150 // If this is extracted metadata, we use a special element name that won't be recognized by greenstone
151 if(name.startsWith(Utility.EXTRACTED_METADATA_NAMESPACE)) {
152 metadata_element = base_document.createElement(ALL_METADATA_TYPES[1]);
153 name = name.substring(Utility.EXTRACTED_METADATA_NAMESPACE.length() + 1);
154 }
155 else {
156 metadata_element = base_document.createElement(ALL_METADATA_TYPES[0]);
157 }
158 metadata_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
159
160 // To determine if this metadata entry should overwrite or accumulate we check if there are other entries with the same element in this fileset.
161 boolean will_accumulate = false;
162 NodeList sibling_description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
163 for(int k = 0; !will_accumulate && k < sibling_description_elements.getLength(); k++) {
164 Element sibling_description_element = (Element) sibling_description_elements.item(k);
165 // We have to do this for each type of metadata
166 for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
167 NodeList sibling_metadata_elements = sibling_description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
168 for(int l = 0; !will_accumulate && l < sibling_metadata_elements.getLength(); l++) {
169 Element sibling_metadata_element = (Element) sibling_metadata_elements.item(l);
170 // It appears that its possible that we can be asked to add the same metadata twice (especially after a copy action is cancelled then repeated). So we check if we have been asked to add exactly the same value twice.
171 if(sibling_metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE).equals(metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE))) {
172 // Check the values and return if they are the same.
173 if(metadata.getAbsoluteValue().equals(MSMUtils.getValue(sibling_metadata_element))) {
174 return;
175 }
176 will_accumulate = true;
177 }
178 sibling_metadata_element = null;
179 }
180 sibling_metadata_elements = null;
181 }
182 sibling_description_element = null;
183 }
184 sibling_description_elements = null;
185 if(will_accumulate || force_accumulate) { //mode.equals(ACCUMULATE)) {
186 metadata_element.setAttribute(MODE_ATTRIBUTE, ACCUMULATE);
187 }
188 // As we can't possibly store all the metadata in memory, nor can we ensure that the indexes written to file remain the same until the new time we look at this file, and to avoid having to open a rewrite every collection document whenever any value tree changes, I'm writing the value out as a full path string
189 GValueModel model = Gatherer.c_man.getCollection().msm.getValueTree(metadata.getElement());
190 String node_value = null;
191 if(model != null && model.isHierarchy()) {
192 //node_value = /odec.transform(metadata.getValueNode().getFullPath(false), /odec.TEXT_TO_DOM);
193 node_value = metadata.getValueNode().getFullPath(false);
194 }
195 else {
196 node_value = metadata.getAbsoluteValue();
197 }
198 ///ystem.err.println("Creating node in GDMDocument: '" + node_value + "'");
199 metadata_element.appendChild(base_document.createTextNode(node_value));
200 // Retrieve the first description element for this fileset (there should only be one, but I'll play it safe).
201 NodeList description_elements = fileset_element.getElementsByTagName("Description");
202 Element description_element = (Element) description_elements.item(0);
203 description_element.appendChild(metadata_element);
204 description_element = null;
205 metadata_element = null;
206 //mode = null;
207 fileset_element = null;
208 directorymetadata_element = null;
209 up_to_date = false;
210 }
211 catch (Exception error) {
212 Gatherer.printStackTrace(error);
213 }
214 }
215
216 public int countMetadata() {
217 int count = 0;
218 try {
219 // Retrieve the document element.
220 Element directorymetadata_element = base_document.getDocumentElement();
221 // Iterate through the filesets, checking the FileName child element against the target file's name using regular expression matching.
222 NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
223 for(int i = 0; i < fileset_elements.getLength(); i++) {
224 Element fileset_element = (Element) fileset_elements.item(i);
225 NodeList description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
226 for(int k = 0; k < description_elements.getLength(); k++) {
227 Element description_element = (Element) description_elements.item(k);
228 // We have to do this for each type of metadata
229 for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
230 NodeList metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
231 count = count + metadata_elements.getLength();
232 metadata_elements = null;
233 }
234 description_element = null;
235 }
236 description_elements = null;
237 fileset_element = null;
238 }
239 fileset_elements = null;
240 directorymetadata_element = null;
241 }
242 catch (Exception error) {
243 Gatherer.printStackTrace(error);
244 }
245 return count;
246 }
247
248 /** Retrieve the document this class is wrapping. */
249 public Document getDocument() {
250 return base_document;
251 }
252
253 /** Get all of the metadata, including directory level, associated with this file. */
254 public ArrayList getMetadata(String filename, boolean remove, ArrayList metadatum_so_far, File file, boolean append_folder_level) {
255 return getMetadata(filename, remove, metadatum_so_far, file, append_folder_level, false);
256 }
257 /** Retrieve the metadata associated with the given filename. Keep track of what metadata should be overwritten and what should be accumulated. Also make note of the source file, and remove the metadata if required. Finally if purge is set retrieve every piece of metadata in this file. */
258 public ArrayList getMetadata(String filename, boolean remove, ArrayList metadatum_so_far, File file, boolean append_folder_level, boolean purge) {
259 Gatherer.println("Get metadata for " + filename);
260 Gatherer.println("append_folder_level: " + append_folder_level);
261 Gatherer.println("purge: " + purge);
262 ArrayList metadatum = null;
263 ArrayList queued_for_removal = new ArrayList();
264 if(metadatum_so_far == null) {
265 metadatum = new ArrayList();
266 }
267 else {
268 metadatum = metadatum_so_far;
269 }
270 try {
271 // Retrieve the document element.
272 Element directorymetadata_element = base_document.getDocumentElement();
273 // Iterate through the filesets, checking the FileName child element against the target file's name using regular expression matching.
274 NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
275 for(int i = 0; i < fileset_elements.getLength(); i++) {
276 Element fileset_element = (Element) fileset_elements.item(i);
277 NodeList filename_elements = fileset_element.getElementsByTagName(FILENAME_ELEMENT);
278 for(int j = 0; j < filename_elements.getLength(); j++) {
279 Element filename_element = (Element) filename_elements.item(j);
280 String filename_text = MSMUtils.getValue(filename_element);
281 if((filename != null && (filename.matches(filename_text) || (append_folder_level && filename.indexOf(File.separator) != -1 && filename_text.equals(filename.substring(0, filename.indexOf(File.separator)))))) || ((filename == null || append_folder_level) && filename_text.equals(DIRECTORY_FILENAME)) || purge) {
282 // If they match add all of the metadata found in the Description child element, remembering to abide by desired mode (accumulate vs. overwrite).
283 // Normal metadata
284 NodeList description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
285 for(int k = 0; k < description_elements.getLength(); k++) {
286 Element description_element = (Element) description_elements.item(k);
287 // We have to do this for each type of metadata
288 for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
289 NodeList metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
290 for(int l = 0; l < metadata_elements.getLength(); l++) {
291 Element metadata_element = (Element) metadata_elements.item(l);
292 String raw_element = metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
293 //String language = metadata_element.getAttribute("language");
294 String mode = metadata_element.getAttribute(MODE_ATTRIBUTE);
295 String raw_value = MSMUtils.getValue(metadata_element);
296 //
297 //raw_value = Codec.transform(raw_value, Codec.DOM_TO_);
298 ///ystem.err.println("Retrieved raw value: " + raw_value);
299 // ***** LEGACY SUPPORT *****
300 // If this raw_value contains a '\' character, but no '\\', '[' or ']' characters, then replace the '\' with a '\\'
301 if(raw_value.indexOf(StaticStrings.ESCAPE_STR) != -1) {
302 ///ystem.err.println("Blarg");
303 Gatherer.println("Detected Legacy Path: " + raw_value);
304 raw_value = raw_value.replaceAll(StaticStrings.ESCAPE_PATTERN, StaticStrings.PIPE_STR);
305 Gatherer.println("Updated Path To: " + raw_value);
306 MSMUtils.setValue(metadata_element, raw_value);
307 }
308 // **************************
309 // Using the element string and value, retrieve a matching Metadata object from the cache
310 Metadata metadata = null;
311 // If this element has hierarchy values then we must ensure the raw value is a full path, not an index.
312 // Try to retrieve an already comstructed piece of metadata from file - but not if we are purging, as this will stuff up anything that is still using that metadata - such as the GTable
313 if(GDMManager.metadata_cache.contains(raw_element, raw_value) && !purge) {
314 ///ystem.err.println("HIT! Retrieve metadata from cache: " + raw_element + " -> " + raw_value + "\n");
315 metadata = (Metadata) GDMManager.metadata_cache.get(raw_element, raw_value);
316 }
317 else {
318 ElementWrapper element = Gatherer.c_man.getCollection().msm.getElement(raw_element);
319 if (element != null) {
320 GValueNode value = Metadata.getDefaultValueNode(element, raw_value);
321 ///ystem.err.println("Miss. Create new metadata: " + raw_element + " -> " + raw_value + "\n");
322 metadata = new Metadata(element, value);
323 if(!purge) {
324 GDMManager.metadata_cache.put(raw_element, raw_value, metadata);
325 }
326 ///ystem.err.println("Added metadata to cache: " + raw_element + " -> " + raw_value + "\n");
327 value = null;
328 element = null;
329 }
330 }
331 // check whether the metadata is null
332 if (metadata != null) {
333 // We determine whether this metadata is file or folder level
334 if(filename != null) {
335 ///ystem.err.println("Filename = " + filename);
336 ///ystem.err.println("filename_text = " + filename_text);
337 // If can only be file level if there is no folder path details in filename and if the filename matched the filename text node (it may have matched .* instead)!
338 if(filename.indexOf(File.separator) == -1 && filename.equals(filename_text)) {
339 metadata.setFileLevel(true);
340 ///ystem.err.println("File level!!!");
341 }
342 else {
343 metadata.setFileLevel(false);
344 ///ystem.err.println("Inherited!!!");
345 }
346 }
347 else {
348 ///ystem.err.println("Filename is null therefore this is file level metadata.");
349 metadata.setFileLevel(true);
350 }
351 metadata.setFile(file);
352 // If mode is overwrite, then remove any previous values for this metadata element.
353 if(mode.equals("accumulate")) {
354 metadata.setAccumulate(true);
355 }
356 else {
357 metadata.setAccumulate(false);
358 ///ystem.err.println("Metadata overwrites: " + metadata);
359 for(int m = metadatum.size() - 1; m >= 0; m--) {
360 Metadata old_metadata = (Metadata) metadatum.get(m);
361 if(old_metadata.getElement().equals(metadata.getElement())) {
362 metadatum.remove(m);
363 ///ystem.err.println("Removing overridden metadata: " + old_metadata);
364 }
365 old_metadata = null;
366 }
367 }
368 mode = null;
369 // Add the completed metadata and clean up
370 ///ystem.err.println("Adding metadata: " + metadata);
371 metadatum.add(metadata);
372 // Having found our metadata check if the value from the xml matches the one from the gvaluenode. If not update it. This happens whenever hierarchy information is involved (indexes rapidly become obsolete).
373 // If remove was set, remove it. We can only remove pure file level metadata, or folder level iff we were asked for folder level.
374 ///atherer.println("Have we been asked to remove the metadata: " + metadata);
375 ///atherer.println("Given:");
376 ///atherer.println("\tremove = " + remove);
377 ///atherer.println("\tfilename = " + filename);
378 ///atherer.println("\tfilename_text = " + filename_text + "?");
379 if(remove && ((filename != null && filename.matches(filename_text) && !filename_text.equals(DIRECTORY_FILENAME)) || (filename == null && filename_text.equals(DIRECTORY_FILENAME)))) {
380 ///atherer.println("Yes! Queuing for Removal.");
381 queued_for_removal.add(metadata_element);
382 }
383 else {
384 ///atherer.println("No. Updating.");
385 String current_value = metadata.getValueNode().getFullPath(false);
386 ///ystem.err.println("Checking the current mdv path: " + current_value);
387 ///ystem.err.println("Against whats in the metadata file: " + raw_value);
388 if(!raw_value.equals(current_value)) {
389 // Remove old text
390 while(metadata_element.hasChildNodes()) {
391 metadata_element.removeChild(metadata_element.getFirstChild());
392 }
393 // Add new.
394 metadata_element.appendChild(base_document.createTextNode(current_value));
395 }
396 }
397 }
398 metadata = null;
399 raw_value = null;
400 raw_element = null;
401 metadata_element = null;
402 }
403 metadata_elements = null;
404 }
405
406 // Now we remove any elements that have been queued for deletion
407 for(int a = 0; a < queued_for_removal.size(); a++) {
408 Element metadata_element = (Element) queued_for_removal.get(a);
409 description_element.removeChild(metadata_element);
410 up_to_date = false;
411 }
412 queued_for_removal.clear();
413 queued_for_removal = null;
414
415 // If the description_element no longer has any children remove it
416 NodeList metadata_elements = description_element.getElementsByTagName(StaticStrings.METADATA_ELEMENT);
417 NodeList extracted_elements = description_element.getElementsByTagName(StaticStrings.EXTRACTED_METADATA_ELEMENT);
418 if(metadata_elements.getLength() == 0 && extracted_elements.getLength() == 0) {
419 fileset_element.removeChild(description_element);
420 up_to_date = false;
421 }
422 description_element = null;
423 }
424 description_elements = null;
425 }
426 filename_text = null;
427 filename_element = null;
428 }
429 // If the file set no longer has any description entries, remove it entirely
430 NodeList description_elements = fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT);
431 if(description_elements.getLength() == 0) {
432 directorymetadata_element.removeChild(fileset_element);
433 up_to_date = false;
434 }
435 description_elements = null;
436 filename_elements = null;
437 fileset_element = null;
438 }
439 fileset_elements = null;
440 directorymetadata_element = null;
441 }
442 catch (Exception error) {
443 Gatherer.self.printStackTrace(error);
444 }
445 ///ystem.err.println("Found " + metadatum.size() + " pieces of metadata.");
446 return metadatum;
447 }
448
449 /** Determine if this document has been saved recently, and thus xml file version is up to date. */
450 public boolean isUpToDate() {
451 return false;
452 }
453
454 /** Determine is this is a valid Greenstone Directory Metadata file. It may of course just be some xml file with the name metadata.xml. */
455 public boolean isValid() {
456 // Just determine if the doctype is GreenstoneDirectoryMetadata and root node is called DirectoryMetadata.
457 String doctype_name = base_document.getDoctype().getName();
458 String root_name = base_document.getDocumentElement().getTagName();
459 return ((doctype_name.equals("GreenstoneDirectoryMetadata") && root_name.equals("GreenstoneDirectoryMetadata")) || (doctype_name.equals("DirectoryMetadata") && root_name.equals("DirectoryMetadata")));
460 }
461
462 /** Remove all of the extracted metadata (XMetadata) from this document. */
463 public void removeExtractedMetadata() {
464 try {
465 Element document_element = base_document.getDocumentElement();
466 NodeList extracted_metadata_elements = document_element.getElementsByTagName(StaticStrings.EXTRACTED_METADATA_ELEMENT);
467 document_element = null;
468 for(int i = extracted_metadata_elements.getLength(); i != 0; i--) {
469 Element extracted_metadata_element = (Element) extracted_metadata_elements.item(i - 1);
470 String element_name = extracted_metadata_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
471 ElementWrapper element = Gatherer.c_man.getCollection().msm.getElement(element_name);
472 if(element != null) {
473 element.dec();
474 }
475 element = null;
476 ///ystem.err.println("Removing extracted metadata: " + element_name + "=" + MSMUtils.getValue(extracted_metadata_element));
477 element_name = null;
478 Node parent_node = extracted_metadata_element.getParentNode();
479 parent_node.removeChild(extracted_metadata_element);
480 parent_node = null;
481 extracted_metadata_element = null;
482 }
483 extracted_metadata_elements = null;
484 up_to_date = false;
485 }
486 catch(Exception exception) {
487 Gatherer.println("Exception in GDMDocument.removeExtractedMetadata() - unexpected");
488 Gatherer.printStackTrace(exception);
489 }
490 }
491
492 /** Remove the given directory level metadata from this document. All directory level metadata is available under the FileSet with filename '.*'. There is at least one nasty case to consider, where the first overwriting metadata entry, of several with the same element, is removed. In this case the next entry must become overwrite to ensure proper inheritance. */
493 public void removeMetadata(String filename, Metadata metadata) {
494 Gatherer.println("Remove metadata: " + metadata + "\nFrom filename: " + filename);
495 try {
496 boolean found = false;
497 boolean first_metadata_element_found = true;
498 boolean make_next_metadata_element_overwrite = false;
499 boolean remove_fileset = false;
500 // Retrieve the document element.
501 Element directorymetadata_element = base_document.getDocumentElement();
502 // Iterate through the filesets looking for the directory level one.
503 NodeList fileset_elements = directorymetadata_element.getElementsByTagName(FILESET_ELEMENT);
504 for(int i = 0; !found && i < fileset_elements.getLength(); i++) {
505 Element fileset_element = (Element) fileset_elements.item(i);
506 NodeList filename_elements = fileset_element.getElementsByTagName(FILENAME_ELEMENT);
507 for(int j = 0; !found && j < filename_elements.getLength(); j++) {
508 Element filename_element = (Element) filename_elements.item(j);
509 String filename_text = MSMUtils.getValue(filename_element);
510 if((filename != null && filename.matches(filename_text) && !filename.equals(DIRECTORY_FILENAME)) || (filename == null && filename_text.equals(DIRECTORY_FILENAME))) {
511 // Retrieve the Metadata Element for this fileset, and iterate through them looking for the one which we are to remove.
512 NodeList description_elements = fileset_element.getElementsByTagName("Description");
513 for(int k = 0; !found && k < description_elements.getLength(); k++) {
514 Element description_element = (Element) description_elements.item(k);
515 // We have to do this for each type of metadata
516 for(int z = 0; z < ALL_METADATA_TYPES.length; z++) {
517 NodeList metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[z]);
518 for(int l = 0; (!found || !make_next_metadata_element_overwrite) && l < metadata_elements.getLength(); l++) {
519 Element metadata_element = (Element) metadata_elements.item(l);
520 String element = metadata_element.getAttribute("name");
521 String value = MSMUtils.getValue(metadata_element);
522 // See if this is the metadata we wish to remove
523 if(element.equals(metadata.getElement().getName())) {
524 if(value.equals(metadata.getValueNode().getFullPath(false))) {
525 // Remove it
526 ///ystem.err.println("Remove " + element + "-" + value);
527 description_element.removeChild(metadata_element);
528 found = true;
529 // If this was the first metadata with this element found, and it was set to overwrite, then we have to ensure that the next metadata with this element found (if any) is changed to be overwrite now.
530 if(first_metadata_element_found && !metadata.accumulates()) {
531 ///ystem.err.println("First of this element found!");
532 make_next_metadata_element_overwrite = true;
533 }
534 }
535 // If this was the first metadata we've found with the element of the one to be removed set first found to false.
536 else if(first_metadata_element_found) {
537 ///ystem.err.println("Found a matching element: " + element + "=" + value);
538 first_metadata_element_found = false;
539 }
540 // Otherwise we should make this metadata overwrite as requested.
541 else if(make_next_metadata_element_overwrite) {
542 ///ystem.err.println("Changing to overwrite: " + element + "=" + value);
543 metadata_element.setAttribute(MODE_ATTRIBUTE, "");
544 }
545 }
546 value = null;
547 element = null;
548 metadata_element = null;
549 }
550 NodeList normal_metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[0]);
551 NodeList extracted_metadata_elements = description_element.getElementsByTagName(ALL_METADATA_TYPES[1]);
552 // If we found it, removed it, and now the description tag has no children, mark the fileset for removal
553 if(normal_metadata_elements.getLength() == 0 && extracted_metadata_elements.getLength() == 0) {
554 remove_fileset = true;
555 }
556 extracted_metadata_elements = null;
557 normal_metadata_elements = null;
558 metadata_elements = null;
559 }
560 description_element = null;
561 }
562 description_elements = null;
563 }
564 filename_text = null;
565 filename_element = null;
566 }
567 filename_elements = null;
568 if(found && remove_fileset) {
569 directorymetadata_element.removeChild(fileset_element);
570 }
571 fileset_element = null;
572 }
573 fileset_elements = null;
574 directorymetadata_element = null;
575 up_to_date = false;
576 }
577 catch (Exception error) {
578 Gatherer.printStackTrace(error);
579 }
580 }
581
582 /** Change the up to date flag.
583 * @param up_to_date true if the document on the filesystem is the same as the one in memory, false otherwise
584 */
585 public void setUpToDate(boolean up_to_date) {
586 this.up_to_date = up_to_date;
587 }
588}
Note: See TracBrowser for help on using the repository browser.