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

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

More improvements to the new metadata code, including language-specific metadata element display and a 5x speed up in the skimming of the doc.xml files.

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