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

Last change on this file since 8142 was 8142, checked in by mdewsnip, 20 years ago

Added some comments for the skimFile functions.

  • Property svn:keywords set to Author Date Id Revision
File size: 15.7 KB
Line 
1package org.greenstone.gatherer.metadata;
2
3
4import java.io.*;
5import java.util.*;
6import org.greenstone.gatherer.util.XMLTools;
7import org.w3c.dom.*;
8
9
10/** This class represents one metadata.xml file */
11public class MetadataXMLFile
12 extends File
13{
14 static final private String DESCRIPTION_ELEMENT = "Description";
15 static final private String DIRECTORY_FILENAME = ".*";
16 static final private String FILENAME_ELEMENT = "FileName";
17 static final private String FILESET_ELEMENT = "FileSet";
18 static final private String METADATA_ELEMENT = "Metadata";
19
20
21 public MetadataXMLFile(String metadata_xml_file_path)
22 {
23 super(metadata_xml_file_path);
24 }
25
26
27 public void addMetadata(File file, MetadataValue metadata_value)
28 {
29 // Parse the metadata.xml file
30 Document document = XMLTools.parseXMLFile(this);
31 if (document == null) {
32 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
33 return;
34 }
35
36 // Determine the file's path relative to the location of the metadata.xml file
37 File metadata_xml_file_directory = getParentFile();
38 String file_relative_path = file.getAbsolutePath().substring(metadata_xml_file_directory.getAbsolutePath().length());
39 if (file_relative_path.startsWith(File.separator)) {
40 file_relative_path = file_relative_path.substring(File.separator.length());
41 }
42
43 // Convert the file path into a regular expression that will match it
44 String file_path_regexp = file_relative_path.replaceAll("\\.", "\\\\.");
45 if (file_relative_path.equals("")) {
46 file_path_regexp = DIRECTORY_FILENAME;
47 }
48
49 // Square brackets need to be escaped because they are a special character in Greenstone
50 String metadata_value_string = metadata_value.getFullValue();
51 metadata_value_string = metadata_value_string.replaceAll("\\[", "[");
52 metadata_value_string = metadata_value_string.replaceAll("\\]", "]");
53
54 // Create a new Metadata element to record this metadata
55 Element new_metadata_value_element = document.createElement(METADATA_ELEMENT);
56 new_metadata_value_element.setAttribute("name", metadata_value.getMetadataElement().getFullName());
57 new_metadata_value_element.setAttribute("mode", (metadata_value.isAccumulatingMetadata() ? "accumulate" : "override"));
58 new_metadata_value_element.appendChild(document.createTextNode(metadata_value_string));
59 boolean have_added_metadata = false;
60
61 // Read all the FileSet elements in the file
62 NodeList fileset_elements_nodelist = document.getElementsByTagName(FILESET_ELEMENT);
63 for (int i = 0; i < fileset_elements_nodelist.getLength(); i++) {
64 Element current_fileset_element = (Element) fileset_elements_nodelist.item(i);
65
66 // Check the FileName elements of the FileSet to see if we have a match
67 NodeList filename_elements_nodelist = current_fileset_element.getElementsByTagName(FILENAME_ELEMENT);
68 for (int j = 0; j < filename_elements_nodelist.getLength(); j++) {
69 Element current_filename_element = (Element) filename_elements_nodelist.item(j);
70 String current_filename_element_value = XMLTools.getElementTextValue(current_filename_element);
71
72 // Only exact matches can be extended with new metadata
73 if (current_filename_element_value.equals(file_path_regexp)) {
74 // Append the new Metadata element to the Description element of this FileSet
75 Element description_element = (Element) current_fileset_element.getElementsByTagName(DESCRIPTION_ELEMENT).item(0);
76
77 // Accumulating metadata: add at the end
78 if (metadata_value.isAccumulatingMetadata()) {
79 description_element.appendChild(new_metadata_value_element);
80 }
81 // Override metadata: add at the start (so it overrides inherited metadata without affecting other assigned metadata)
82 else {
83 description_element.insertBefore(new_metadata_value_element, description_element.getFirstChild());
84 }
85
86 have_added_metadata = true;
87 break;
88 }
89 }
90 }
91
92 // Check if the metadata was added to an existing FileSet
93 if (!have_added_metadata) {
94 // It wasn't, so create a new FileSet element for it
95 Element new_fileset_element = document.createElement(FILESET_ELEMENT);
96
97 Element new_filename_element = document.createElement(FILENAME_ELEMENT);
98 new_filename_element.appendChild(document.createTextNode(file_path_regexp));
99 new_fileset_element.appendChild(new_filename_element);
100
101 // Append the new Metadata element to the Description element of this FileSet
102 Element new_description_element = document.createElement(DESCRIPTION_ELEMENT);
103 new_description_element.appendChild(new_metadata_value_element);
104 new_fileset_element.appendChild(new_description_element);
105
106 document.getDocumentElement().appendChild(new_fileset_element);
107 }
108
109 // Rewrite the metadata.xml file
110 XMLTools.writeXMLFile(this, document);
111 }
112
113
114 public ArrayList getMetadataAssignedToFile(File file)
115 {
116 // Parse the metadata.xml file
117 Document document = XMLTools.parseXMLFile(this);
118 if (document == null) {
119 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
120 return null;
121 }
122
123 // Determine the file's path relative to the location of the metadata.xml file
124 File metadata_xml_file_directory = getParentFile();
125 String file_relative_path = file.getAbsolutePath().substring(metadata_xml_file_directory.getAbsolutePath().length());
126 if (file_relative_path.startsWith(File.separator)) {
127 file_relative_path = file_relative_path.substring(File.separator.length());
128 }
129
130 // Build up a list of metadata assigned to this file
131 ArrayList metadata_values = new ArrayList();
132
133 // Read all the FileSet elements in the file
134 NodeList fileset_elements_nodelist = document.getElementsByTagName(FILESET_ELEMENT);
135 for (int i = 0; i < fileset_elements_nodelist.getLength(); i++) {
136 Element current_fileset_element = (Element) fileset_elements_nodelist.item(i);
137 boolean current_fileset_matches = false;
138 File folder_metadata_inherited_from = null;
139
140 // Check the FileName elements of the FileSet to see if we have a match
141 NodeList filename_elements_nodelist = current_fileset_element.getElementsByTagName(FILENAME_ELEMENT);
142 for (int j = 0; j < filename_elements_nodelist.getLength(); j++) {
143 Element current_filename_element = (Element) filename_elements_nodelist.item(j);
144 String current_filename_element_value = XMLTools.getElementTextValue(current_filename_element);
145
146 // This fileset specifies metadata for the file
147 if (file_relative_path.matches(current_filename_element_value)) {
148 current_fileset_matches = true;
149 if (!file_relative_path.equals("") && current_filename_element_value.equals(DIRECTORY_FILENAME)) {
150 folder_metadata_inherited_from = metadata_xml_file_directory;
151 }
152 break;
153 }
154
155 // This fileset specifies metadata for the folder the file is in
156 if (file_relative_path.startsWith(current_filename_element_value + File.separator)) {
157 current_fileset_matches = true;
158 folder_metadata_inherited_from = new File(metadata_xml_file_directory, current_filename_element_value);
159 break;
160 }
161 }
162
163 // The FileSet doesn't apply, so move onto the next one
164 if (current_fileset_matches == false) {
165 continue;
166 }
167
168 // Read all the Metadata elements in the fileset
169 NodeList metadata_elements_nodelist = current_fileset_element.getElementsByTagName(METADATA_ELEMENT);
170 for (int k = 0; k < metadata_elements_nodelist.getLength(); k++) {
171 Element current_metadata_element = (Element) metadata_elements_nodelist.item(k);
172 String metadata_element_name_full = current_metadata_element.getAttribute("name");
173
174 String metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
175 MetadataSet metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
176
177 // If the metadata set isn't loaded give the option of mapping the element into a loaded set
178 if (metadata_set == null) {
179 String target_metadata_element_name_full = MetadataSetManager.mapUnloadedMetadataElement(metadata_element_name_full);
180 if (target_metadata_element_name_full == null || target_metadata_element_name_full.equals("")) {
181 // Skip this element if we still don't have a loaded element for it
182 continue;
183 }
184
185 metadata_element_name_full = target_metadata_element_name_full;
186 metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
187 metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
188 }
189
190 String metadata_element_name = MetadataTools.getMetadataElementName(metadata_element_name_full);
191 MetadataElement metadata_element = metadata_set.getMetadataElement(metadata_element_name);
192
193 // If the element doesn't exist in the metadata set, we're not interested
194 if (metadata_element == null) {
195 continue;
196 }
197
198 // Square brackets need to be escaped because they are a special character in Greenstone
199 String metadata_element_value = XMLTools.getElementTextValue(current_metadata_element);
200 metadata_element_value = metadata_element_value.replaceAll("&#091;", "[");
201 metadata_element_value = metadata_element_value.replaceAll("&#093;", "]");
202
203 MetadataValueTreeNode metadata_value_tree_node = metadata_element.getMetadataValueTreeNode(metadata_element_value);
204
205 // If there is no metadata value tree node for this value, create it
206 if (metadata_value_tree_node == null) {
207 System.err.println("Note: No value tree node for metadata value \"" + metadata_element_value + "\"");
208 metadata_element.addMetadataValue(metadata_element_value);
209 metadata_value_tree_node = metadata_element.getMetadataValueTreeNode(metadata_element_value);
210 }
211
212 MetadataValue metadata_value = new MetadataValue(metadata_element, metadata_value_tree_node);
213 metadata_value.inheritsMetadataFromFolder(folder_metadata_inherited_from);
214
215 // Is this accumulating metadata?
216 if (current_metadata_element.getAttribute("mode").equals("accumulate")) {
217 metadata_value.setIsAccumulatingMetadata(true);
218 }
219
220 // Add the new metadata value to the list
221 metadata_values.add(metadata_value);
222 }
223 }
224
225 return metadata_values;
226 }
227
228
229 public void removeMetadata(File file, MetadataValue metadata_value)
230 {
231 // Parse the metadata.xml file
232 Document document = XMLTools.parseXMLFile(this);
233 if (document == null) {
234 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
235 return;
236 }
237
238 // Determine the file's path relative to the location of the metadata.xml file
239 File metadata_xml_file_directory = getParentFile();
240 String file_relative_path = file.getAbsolutePath().substring(metadata_xml_file_directory.getAbsolutePath().length());
241 if (file_relative_path.startsWith(File.separator)) {
242 file_relative_path = file_relative_path.substring(File.separator.length());
243 }
244
245 // Convert the file path into a regular expression that will match it
246 String file_path_regexp = file_relative_path.replaceAll("\\.", "\\\\.");
247 if (file_relative_path.equals("")) {
248 file_path_regexp = DIRECTORY_FILENAME;
249 }
250
251 // Read all the FileSet elements in the file
252 NodeList fileset_elements_nodelist = document.getElementsByTagName(FILESET_ELEMENT);
253 for (int i = 0; i < fileset_elements_nodelist.getLength(); i++) {
254 Element current_fileset_element = (Element) fileset_elements_nodelist.item(i);
255 boolean current_fileset_matches = false;
256
257 // Check the FileName elements of the FileSet to see if we have a match
258 NodeList filename_elements_nodelist = current_fileset_element.getElementsByTagName(FILENAME_ELEMENT);
259 for (int j = 0; j < filename_elements_nodelist.getLength(); j++) {
260 Element current_filename_element = (Element) filename_elements_nodelist.item(j);
261 String current_filename_element_value = XMLTools.getElementTextValue(current_filename_element);
262
263 // Only exact matches can be edited
264 if (current_filename_element_value.equals(file_path_regexp)) {
265 current_fileset_matches = true;
266 break;
267 }
268 }
269
270 // The FileSet doesn't apply, so move onto the next one
271 if (current_fileset_matches == false) {
272 continue;
273 }
274
275 // Find the Metadata element to delete from the fileset
276 String metadata_element_name_full = metadata_value.getMetadataElement().getFullName();
277 String metadata_element_value = metadata_value.getFullValue();
278 NodeList metadata_elements_nodelist = current_fileset_element.getElementsByTagName(METADATA_ELEMENT);
279 for (int k = 0; k < metadata_elements_nodelist.getLength(); k++) {
280 Element current_metadata_element = (Element) metadata_elements_nodelist.item(k);
281
282 // Check the metadata element name matches
283 String current_metadata_element_name_full = current_metadata_element.getAttribute("name");
284 if (!current_metadata_element_name_full.equals(metadata_element_name_full)) {
285 continue;
286 }
287
288 // Check the metadata element value matches
289 String current_metadata_element_value = XMLTools.getElementTextValue(current_metadata_element);
290 if (!current_metadata_element_value.equals(metadata_element_value)) {
291 continue;
292 }
293
294 // Remove this Metadata element
295 current_metadata_element.getParentNode().removeChild(current_metadata_element);
296 }
297 }
298
299 // Rewrite the metadata.xml file
300 XMLTools.writeXMLFile(this, document);
301 }
302
303
304 /**
305 * Every metadata.xml file must be skimmed when a collection is opened, for two reasons:
306 * - To build complete and accurate metadata value trees (needed for Enrich pane and hierarchy files)
307 * - To handle any non-namespaced metadata in the file
308 */
309 public void skimFile()
310 {
311 boolean file_changed = false;
312
313 // Parse the metadata.xml file
314 System.err.println("Skimming metadata.xml file " + this + "...");
315 Document document = XMLTools.parseXMLFile(this);
316 if (document == null) {
317 System.err.println("Error: Could not parse metadata.xml file " + getAbsolutePath());
318 return;
319 }
320
321 // Read all the Metadata elements in the file
322 NodeList metadata_elements_nodelist = document.getElementsByTagName(METADATA_ELEMENT);
323 for (int i = 0; i < metadata_elements_nodelist.getLength(); i++) {
324 Element current_metadata_element = (Element) metadata_elements_nodelist.item(i);
325 String metadata_element_name_full = current_metadata_element.getAttribute("name");
326
327 String metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
328 MetadataSet metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
329
330 // If the metadata set isn't loaded give the option of mapping the element into a loaded set
331 if (metadata_set == null) {
332 String target_metadata_element_name_full = MetadataSetManager.mapUnloadedMetadataElement(metadata_element_name_full);
333 if (target_metadata_element_name_full == null || target_metadata_element_name_full.equals("")) {
334 // Skip this element if we still don't have a loaded element for it
335 continue;
336 }
337
338 // Update the metadata.xml file to have the new element name
339 current_metadata_element.setAttribute("name", target_metadata_element_name_full);
340 file_changed = true;
341
342 metadata_element_name_full = target_metadata_element_name_full;
343 metadata_set_namespace = MetadataTools.getMetadataSetNamespace(metadata_element_name_full);
344 metadata_set = MetadataSetManager.getMetadataSet(metadata_set_namespace);
345 }
346
347 String metadata_element_name = MetadataTools.getMetadataElementName(metadata_element_name_full);
348 MetadataElement metadata_element = metadata_set.getMetadataElement(metadata_element_name);
349
350 // If the element doesn't exist in the metadata set, add it
351 if (metadata_element == null) {
352 metadata_element = metadata_set.addMetadataElementForThisSession(metadata_element_name);
353 }
354
355 String metadata_element_value = XMLTools.getElementTextValue(current_metadata_element);
356 metadata_element.addMetadataValue(metadata_element_value);
357 }
358
359 // Rewrite the metadata.xml file if it has changed
360 if (file_changed) {
361 XMLTools.writeXMLFile(this, document);
362 }
363 }
364}
Note: See TracBrowser for help on using the repository browser.