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

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

More work on opening legacy collections and dealing with non-namespaced metadata.

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