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 | * <BR><BR>
|
---|
9 | *
|
---|
10 | * Author: John Thompson, Greenstone Digital Library, University of Waikato
|
---|
11 | *
|
---|
12 | * <BR><BR>
|
---|
13 | *
|
---|
14 | * Copyright (C) 1999 New Zealand Digital Library Project
|
---|
15 | *
|
---|
16 | * <BR><BR>
|
---|
17 | *
|
---|
18 | * This program is free software; you can redistribute it and/or modify
|
---|
19 | * it under the terms of the GNU General Public License as published by
|
---|
20 | * the Free Software Foundation; either version 2 of the License, or
|
---|
21 | * (at your option) any later version.
|
---|
22 | *
|
---|
23 | * <BR><BR>
|
---|
24 | *
|
---|
25 | * This program is distributed in the hope that it will be useful,
|
---|
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
28 | * GNU General Public License for more details.
|
---|
29 | *
|
---|
30 | * <BR><BR>
|
---|
31 | *
|
---|
32 | * You should have received a copy of the GNU General Public License
|
---|
33 | * along with this program; if not, write to the Free Software
|
---|
34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
35 | *########################################################################
|
---|
36 | */
|
---|
37 | package org.greenstone.gatherer.msm;
|
---|
38 |
|
---|
39 | import java.io.*;
|
---|
40 | import java.net.*;
|
---|
41 | import java.util.*;
|
---|
42 | import org.apache.xerces.dom.*;
|
---|
43 | import org.greenstone.gatherer.Dictionary;
|
---|
44 | import org.greenstone.gatherer.Gatherer;
|
---|
45 | import org.greenstone.gatherer.valuetree.GValueModel;
|
---|
46 | import org.greenstone.gatherer.valuetree.GValueNode;
|
---|
47 | import org.greenstone.gatherer.util.Utility;
|
---|
48 | import org.w3c.dom.*;
|
---|
49 | /** An semi-data class to hold details about a loaded metadata set, it also provides some methods to manipulating the data within.
|
---|
50 | * @author John Thompson, Greenstone Digital Library, University of Waikato
|
---|
51 | * @version 2.3b
|
---|
52 | */
|
---|
53 | public class MetadataSet {
|
---|
54 | /** The <Strong>Document</strong> of the DOM model. */
|
---|
55 | private Document document = null;
|
---|
56 | /** The document <strong>Element</strong> of the DOM model. */
|
---|
57 | private Element root = null;
|
---|
58 | /** The <strong>File</strong> this metadata set was loaded from. */
|
---|
59 | private File file = null;
|
---|
60 | /** A mapping from metadata elements to the root element of the value trees for that element. */
|
---|
61 | private Hashtable value_trees = null;
|
---|
62 | /** The list of metadata elements which are, of course, children of the root node. */
|
---|
63 | private NodeList elements = null;
|
---|
64 | /** The description of this metadata set. Cached as it takes more computation time. */
|
---|
65 | private String description = null;
|
---|
66 | /** The name of this metadata set. Cached as it takes more computation time. */
|
---|
67 | private String name = null;
|
---|
68 | /** An element of the tree pruning filter enumeration, that indicates all nodes in the tree should be retained. */
|
---|
69 | static final int ALL_VALUES = 1;
|
---|
70 | /** An element of the tree pruning filter enumeration, that indicates only metadata Subject nodes or higher should remain after pruning. */
|
---|
71 | static final int SUBJECTS_ONLY = 2;
|
---|
72 | /** An element of the tree pruning filter enumeration, that indicates no value nodes i.e. the entire AssignedValues subtree, should remain after pruning. */
|
---|
73 | static final int NO_VALUES = 3;
|
---|
74 |
|
---|
75 | public MetadataSet(String metadata_template) {
|
---|
76 | URL url = ClassLoader.getSystemResource(metadata_template);
|
---|
77 | try {
|
---|
78 | init(new File(URLDecoder.decode(url.getFile(), "UTF-8")));
|
---|
79 | }
|
---|
80 | catch(UnsupportedEncodingException exception) {
|
---|
81 | Gatherer.printStackTrace(exception);
|
---|
82 | }
|
---|
83 | }
|
---|
84 |
|
---|
85 | /** Constructor.
|
---|
86 | * @param file The file the metadata set should be loaded from.
|
---|
87 | */
|
---|
88 | public MetadataSet(File file) {
|
---|
89 | init(file);
|
---|
90 | }
|
---|
91 |
|
---|
92 | /** Metadata Set already parsed constructor.
|
---|
93 | * @param file The file the metadata was loaded from.
|
---|
94 | * @param document The DOM model <strong>Document</strong> containing the metadata set.
|
---|
95 | */
|
---|
96 | public MetadataSet(File file, Document document) {
|
---|
97 | this.document = document;
|
---|
98 | this.elements = document.getElementsByTagName("Element");
|
---|
99 | this.file = file;
|
---|
100 | this.root = document.getDocumentElement();
|
---|
101 | this.value_trees = new Hashtable();
|
---|
102 | // Now for each element read in its value tree if present.
|
---|
103 | for(int i = elements.getLength() - 1; i >= 0; i--) {
|
---|
104 | ElementWrapper value_element = new ElementWrapper((Element)elements.item(i));
|
---|
105 | File value_file = new File(file.getParentFile(), value_element.getName() + ".mdv");
|
---|
106 | ///ystem.err.println("Searching for " + value_file.getAbsolutePath());
|
---|
107 | if(value_file.exists()) {
|
---|
108 | Document value_document = Utility.parse(value_file, false);
|
---|
109 | if(value_document != null) {
|
---|
110 | value_trees.put(value_element, new GValueModel(value_element, value_document));
|
---|
111 | }
|
---|
112 | //else {
|
---|
113 | //atherer.println("Error! Missing mdv file: " + value_file.getAbsolutePath());
|
---|
114 | //}
|
---|
115 | }
|
---|
116 | }
|
---|
117 | }
|
---|
118 | /** Copy constructor.
|
---|
119 | * @param original The original metadata set to copy from.
|
---|
120 | */
|
---|
121 | public MetadataSet(MetadataSet original) {
|
---|
122 | this.value_trees = new Hashtable();
|
---|
123 | // We have to create a new document.
|
---|
124 | document = new DocumentImpl(original.getDocument().getDoctype());
|
---|
125 | root = (Element) document.importNode(original.getDocument().getDocumentElement(), true);
|
---|
126 | document.appendChild(root);
|
---|
127 | elements = root.getElementsByTagName("Element");
|
---|
128 | file = original.getFile();
|
---|
129 | // Now for each element read in its value tree if present.
|
---|
130 | for(int i = elements.getLength() - 1; i >= 0; i--) {
|
---|
131 | ElementWrapper value_element_wrapper = new ElementWrapper((Element)elements.item(i));
|
---|
132 | GValueModel value_tree = original.getValueTree(value_element_wrapper);
|
---|
133 | Document value_document = value_tree.getDocument();
|
---|
134 | Document value_document_copy = new DocumentImpl(value_document.getDoctype());
|
---|
135 | Element value_element = value_document.getDocumentElement();
|
---|
136 | Element value_element_copy = (Element) value_document_copy.importNode(value_element, true);
|
---|
137 | value_document_copy.appendChild(value_element_copy);
|
---|
138 | GValueModel value_tree_copy = new GValueModel(value_element_wrapper, value_document_copy);
|
---|
139 | value_trees.put(value_element_wrapper, value_tree_copy);
|
---|
140 | }
|
---|
141 | }
|
---|
142 | /** Conditional copy constructor.
|
---|
143 | * @param original The original metadata set to copy from.
|
---|
144 | * @param condition An <i>int</i> which matches one of the tree pruning filter types.
|
---|
145 | */
|
---|
146 | public MetadataSet(MetadataSet original, int condition) {
|
---|
147 | this(original);
|
---|
148 | // Now based on condition, we may have to remove some nodes from
|
---|
149 | // this model.
|
---|
150 | switch(condition) {
|
---|
151 | case ALL_VALUES:
|
---|
152 | // Do nothing.
|
---|
153 | break;
|
---|
154 | case SUBJECTS_ONLY:
|
---|
155 | // For each element retrieve its AssignedValues element.
|
---|
156 | for(Enumeration keys = value_trees.keys(); keys.hasMoreElements(); ) {
|
---|
157 | ElementWrapper value_element = (ElementWrapper)keys.nextElement();
|
---|
158 | GValueModel value_tree = (GValueModel)value_trees.get(value_element);
|
---|
159 | Document value_tree_document = value_tree.getDocument();
|
---|
160 | Element value_tree_root_element = value_tree_document.getDocumentElement();
|
---|
161 | // Traverse tree and remove leaf nodes.
|
---|
162 | MSMUtils.traverseTree(value_tree_root_element, MSMUtils.NONE, true);
|
---|
163 | }
|
---|
164 | break;
|
---|
165 | case NO_VALUES:
|
---|
166 | // Remove assigned values trees.
|
---|
167 | value_trees.clear();
|
---|
168 | break;
|
---|
169 | }
|
---|
170 | }
|
---|
171 |
|
---|
172 | /** Add a mds level attribute.
|
---|
173 | * @param name The name of the attribute to add as a <Strong>String</strong>.
|
---|
174 | * @param value The value as a <strong>String</strong>.
|
---|
175 | */
|
---|
176 | public void addAttribute(String name, String value) {
|
---|
177 | root.setAttribute(name, value);
|
---|
178 | }
|
---|
179 |
|
---|
180 | /** Add a new default metadata element with the given name to this metadata set.
|
---|
181 | * @param name The name of this element as a <strong>String</strong>.
|
---|
182 | * @return An <strong>ElementWrapper</strong> around the newly created element or null if the element was not created.
|
---|
183 | */
|
---|
184 | public ElementWrapper addElement(String name, String language)
|
---|
185 | {
|
---|
186 | Text text = document.createTextNode(name);
|
---|
187 | Element identifier = document.createElementNS("","Attribute");
|
---|
188 | identifier.setAttribute("name","identifier");
|
---|
189 | identifier.setAttribute("language", language);
|
---|
190 | identifier.appendChild(text);
|
---|
191 | Element element = document.createElementNS("","Element");
|
---|
192 | element.setAttribute("name",name);
|
---|
193 | element.appendChild(identifier);
|
---|
194 | root.appendChild(element);
|
---|
195 | return new ElementWrapper(element);
|
---|
196 | }
|
---|
197 |
|
---|
198 | /** Method to add a new metadata element to this metadata set, if and only if the element is not already present.
|
---|
199 | * @param others_element An <strong>Element</strong> we wish to add to this metadata set, that currently belongs to some other set.
|
---|
200 | * @param model A <strong>GValueModel</strong> value tree
|
---|
201 | * @return <i>null</i> if the add is successful, otherwise a <strong>String</strong> containing an error message (phrase key).
|
---|
202 | */
|
---|
203 | public String addElement(Element others_element, GValueModel model) {
|
---|
204 | if(!containsElement(others_element.getAttribute("name"))) {
|
---|
205 | // First get ownership of the new element, then add it.
|
---|
206 | Element our_element = (Element)document.importNode(others_element, true);
|
---|
207 | // add the value tree
|
---|
208 | root.appendChild(our_element);
|
---|
209 | if (model != null) {
|
---|
210 | addValueTree(new ElementWrapper(our_element), model);
|
---|
211 | }
|
---|
212 | return null;
|
---|
213 | }
|
---|
214 | else {
|
---|
215 | return "MSMPrompt.Name_Exists";
|
---|
216 | }
|
---|
217 | }
|
---|
218 |
|
---|
219 | /** Method to add a new metadata element with the specified new name to this metadata set, if and only if the name is not already in use.
|
---|
220 | * @param others_element An <strong>Element</strong> we wish to add to this metadata set, that currently belongs to some other set.
|
---|
221 | * @param new_name The new name to be given this element, as a <strong>String</strong>.
|
---|
222 | * @param model A <strong>GValueModel</strong> value tree
|
---|
223 | * @return <i>null</i> if the add is successful, otherwise a <strong>String</strong> containing an error message (phrase key).
|
---|
224 | */
|
---|
225 | public String addElement(Element others_element, String new_name, GValueModel model) {
|
---|
226 | if(!containsElement(new_name)) {
|
---|
227 | // First get ownership of the new element, then add it.
|
---|
228 | Element our_element =
|
---|
229 | (Element) document.importNode(others_element, true);
|
---|
230 | // Change name
|
---|
231 | our_element.setAttribute("name", new_name);
|
---|
232 | // we also want to change the english identifier of this element
|
---|
233 | MSMUtils.setIdentifier(our_element, new_name);
|
---|
234 | // Add it to teh set
|
---|
235 | root.appendChild(our_element);
|
---|
236 | // add the value tree
|
---|
237 | if (model != null) {
|
---|
238 | addValueTree(new ElementWrapper(our_element), model);
|
---|
239 | }
|
---|
240 | return null;
|
---|
241 | }
|
---|
242 | else {
|
---|
243 | return "MSMPrompt.Name_Exists";
|
---|
244 | }
|
---|
245 | }
|
---|
246 | /** Add a value tree to a given metadata element.
|
---|
247 | * @param element The <strong>ElementWrapper</strong> containing the element you wish to add a value tree for.
|
---|
248 | * @param model A <strong>GValueModel</strong> value tree
|
---|
249 | */
|
---|
250 | public void addValueTree(ElementWrapper element, GValueModel model) {
|
---|
251 | ///ystem.err.println("Adding value tree for " + element.toString());
|
---|
252 | value_trees.put(element, model);
|
---|
253 | }
|
---|
254 |
|
---|
255 | public int compare(Element e1, Element e2) {
|
---|
256 | int result = 0;
|
---|
257 | // Check that they're not the same element.
|
---|
258 | if(e1 != e2) {
|
---|
259 | int index_e1 = -1;
|
---|
260 | int index_e2 = -1;
|
---|
261 | // Locate the indexes for each element.
|
---|
262 | for(int i = 0; i < elements.getLength(); i++) {
|
---|
263 | Node element = elements.item(i);
|
---|
264 | if(element == e1) {
|
---|
265 | index_e1 = i;
|
---|
266 | }
|
---|
267 | if(element == e2) {
|
---|
268 | index_e2 = i;
|
---|
269 | }
|
---|
270 | }
|
---|
271 | if(index_e1 < index_e2) {
|
---|
272 | result = -1;
|
---|
273 | }
|
---|
274 | else {
|
---|
275 | result = 1;
|
---|
276 | }
|
---|
277 | }
|
---|
278 | return result;
|
---|
279 | }
|
---|
280 |
|
---|
281 | /** A method to determine if this metadata set contains an element with a certain name (case sensitive).
|
---|
282 | * @param name A <strong>String</strong> which is the name of the element whose presence we are checking.
|
---|
283 | * @return A <i>boolean</i> which is <i>true</i> if the named element exists, <i>false</i> otherwise.
|
---|
284 | */
|
---|
285 | public boolean containsElement(String name) {
|
---|
286 | for(int i = 0; i < elements.getLength(); i++) {
|
---|
287 | Element sibling = (Element) elements.item(i);
|
---|
288 | String sibling_name = sibling.getAttribute("name");
|
---|
289 | if(sibling_name.equals(name)) {
|
---|
290 | return true;
|
---|
291 | }
|
---|
292 | }
|
---|
293 | return false;
|
---|
294 | }
|
---|
295 |
|
---|
296 | public NamedNodeMap getAttributes() {
|
---|
297 | return root.getAttributes();
|
---|
298 | }
|
---|
299 |
|
---|
300 | /** Method to retrieve the contact address of the metadata set creator.
|
---|
301 | * @return A <strong>String</strong> containing the address.
|
---|
302 | */
|
---|
303 | public String getContact() {
|
---|
304 | return root.getAttribute("contact");
|
---|
305 | }
|
---|
306 | /** Method to retrieve the name of the creator of this metadata set.
|
---|
307 | * @return A <strong>String</strong> containing the name.
|
---|
308 | */
|
---|
309 | public String getCreator() {
|
---|
310 | return root.getAttribute("creator");
|
---|
311 | }
|
---|
312 | /** Method to retrieve the description of this metadata set. Note that this is language specific, so we determine the desired language from the Dictionary. If no such entry exists, first try returning the english version and failing that the first description found.
|
---|
313 | * @return The description as a <strong>String</strong>.
|
---|
314 | */
|
---|
315 | public String getDescription() {
|
---|
316 | if(description == null) {
|
---|
317 | // Determine the code.
|
---|
318 | String language_code = Gatherer.dictionary.getLanguage();
|
---|
319 | // Recover all Description elements
|
---|
320 | NodeList descriptions = document.getElementsByTagName("Description");
|
---|
321 | // Iterate through the available descriptions looking for the appropriate one. Also make note of the first description, then overwrite it with any english one.
|
---|
322 | boolean found = false;
|
---|
323 | for(int i = 0; !found && i < descriptions.getLength(); i++) {
|
---|
324 | Element pos_description = (Element) descriptions.item(i);
|
---|
325 | String pos_description_code = pos_description.getAttribute("language");
|
---|
326 | if(pos_description_code.equalsIgnoreCase(language_code)) {
|
---|
327 | description = MSMUtils.getValue(pos_description);
|
---|
328 | found = true;
|
---|
329 | }
|
---|
330 | else if(pos_description_code.equalsIgnoreCase("en")) {
|
---|
331 | description = MSMUtils.getValue(pos_description);
|
---|
332 | }
|
---|
333 | else if(description == null) {
|
---|
334 | description = MSMUtils.getValue(pos_description);
|
---|
335 | }
|
---|
336 | pos_description_code = null;
|
---|
337 | pos_description = null;
|
---|
338 | }
|
---|
339 | descriptions = null;
|
---|
340 | language_code = null;
|
---|
341 | // Failing all that set an error message
|
---|
342 | if(description == null) {
|
---|
343 | description = Dictionary.get("MSM.No_Description");
|
---|
344 | }
|
---|
345 | }
|
---|
346 | return description;
|
---|
347 | }
|
---|
348 | /** Method to retrieve the <strong>Document</strong> associated with this metadata set.
|
---|
349 | * @return The <strong>Document</strong> representing this metadata set.
|
---|
350 | */
|
---|
351 | public Document getDocument() {
|
---|
352 | return document;
|
---|
353 | }
|
---|
354 | /** Method to retrieve the metadata element indicated by an index.
|
---|
355 | * @param index An <i>int</i> specifying the required element.
|
---|
356 | * @return The <strong>Element</strong> at the index.
|
---|
357 | */
|
---|
358 | public Element getElement(int index) {
|
---|
359 | return (Element)elements.item(index);
|
---|
360 | }
|
---|
361 | /** This method is used to acquire a reference to the element which matches the given metadata. Note that this is not the same as <i>metadata.getElement()</i> as the reference returned by it may now be obsolete.
|
---|
362 | * @param metadata A <strong>Metadata</strong> object representing an element and value assignment.
|
---|
363 | * @return A 'live' reference to an <strong>Element</strong> which is the same as that referenced by the given metadata, or <i>null</i> if there is no such element.
|
---|
364 | */
|
---|
365 | public Element getElement(Metadata metadata) {
|
---|
366 | return metadata.getElement().getElement();
|
---|
367 | }
|
---|
368 | /** This method is used to acquire a reference to the element which has the name specified. Note that this is not the same as <i>metadata.getElement()</i> as the reference returned by it may now be obsolete.
|
---|
369 | * @param name A <strong>String</strong> stating the desired objects name.
|
---|
370 | * @return A 'live' reference to an <strong>Element</strong> which is the same as that referenced by the given metadata, or <i>null</i> if there is no such element.
|
---|
371 | */
|
---|
372 | public Element getElement(String name) {
|
---|
373 | // Strip any namespace.
|
---|
374 | while(name.indexOf(".") != -1 && !name.equals(".")) {
|
---|
375 | name = name.substring(name.indexOf(".") + 1);
|
---|
376 | }
|
---|
377 | ///ystem.err.println("Get element named " + name);
|
---|
378 | for(int i = 0; i < elements.getLength(); i++) {
|
---|
379 | Element element = (Element) elements.item(i);
|
---|
380 | ///ystem.err.println("Compare to: " + element.getAttribute("name"));
|
---|
381 | if(element.getAttribute("name").equals(name)) {
|
---|
382 | return element;
|
---|
383 | }
|
---|
384 | }
|
---|
385 | return null;
|
---|
386 | }
|
---|
387 |
|
---|
388 | public Element getElement(Element parent_element, String name) {
|
---|
389 | Gatherer.println("Get element named " + name + " from " + parent_element.getAttribute("name"));
|
---|
390 | NodeList elements = parent_element.getElementsByTagName("Element");
|
---|
391 | for(int i = 0; i < elements.getLength(); i++) {
|
---|
392 | Element element = (Element) elements.item(i);
|
---|
393 | if(element.getAttribute("name").equals(name) && element.getParentNode() == parent_element) {
|
---|
394 | elements = null;
|
---|
395 | return element;
|
---|
396 | }
|
---|
397 | }
|
---|
398 | elements = null;
|
---|
399 | return null;
|
---|
400 | }
|
---|
401 | /** Method to acquire a list of all the elements in this metadata set.
|
---|
402 | * @return A <strong>NodeList</strong> containing all of this sets elements.
|
---|
403 | */
|
---|
404 | public NodeList getElements() {
|
---|
405 | return elements;
|
---|
406 | }
|
---|
407 |
|
---|
408 | /** Method to retrieve a list of all the elements in this metadata set, sorted.
|
---|
409 | * @return A <strong>Vector</strong> containing all of the elements of this sets, sorted.
|
---|
410 | */
|
---|
411 | public Vector getElementsSorted() {
|
---|
412 | Vector elements_list = new Vector();
|
---|
413 | for (int i = 0; i < elements.getLength(); i++) {
|
---|
414 | elements_list.add(new ElementWrapper((Element) elements.item(i)));
|
---|
415 | }
|
---|
416 | Collections.sort(elements_list, MSMUtils.METADATA_COMPARATOR);
|
---|
417 | return elements_list;
|
---|
418 | }
|
---|
419 |
|
---|
420 | /** Method to retrieve the original file this metadata set was created from.
|
---|
421 | * @return A <strong>File</strong>.
|
---|
422 | */
|
---|
423 | public File getFile() {
|
---|
424 | return file;
|
---|
425 | }
|
---|
426 | /** Get the last changed attribute.
|
---|
427 | * @return Last changed as a <strong>String</strong>.
|
---|
428 | */
|
---|
429 | public String getLastChanged() {
|
---|
430 | return root.getAttribute("lastchanged");
|
---|
431 | }
|
---|
432 | /** Method to get this metadata sets name. Note that this is language specific, so we determine the desired language from the Dictionary. If no such entry exists, first try returning the english version and failing that the first name found.
|
---|
433 | * @return A <strong>String</strong> which contains its name.
|
---|
434 | */
|
---|
435 | public String getName() {
|
---|
436 | if(name == null) {
|
---|
437 | // Determine the code.
|
---|
438 | String language_code = Gatherer.dictionary.getLanguage();
|
---|
439 | // Recover all Name elements
|
---|
440 | NodeList names = document.getElementsByTagName("Name");
|
---|
441 | // Iterate through the available names looking for the appropriate one. Also make note of the first name, then overwrite it with any english one.
|
---|
442 | boolean found = false;
|
---|
443 | for(int i = 0; !found && i < names.getLength(); i++) {
|
---|
444 | Element pos_name = (Element) names.item(i);
|
---|
445 | String pos_name_code = pos_name.getAttribute("language");
|
---|
446 | if(pos_name_code.equalsIgnoreCase(language_code)) {
|
---|
447 | name = MSMUtils.getValue(pos_name);
|
---|
448 | found = true;
|
---|
449 | }
|
---|
450 | else if(pos_name_code.equalsIgnoreCase("en")) {
|
---|
451 | name = MSMUtils.getValue(pos_name);
|
---|
452 | }
|
---|
453 | else if(name == null) {
|
---|
454 | name = MSMUtils.getValue(pos_name);
|
---|
455 | }
|
---|
456 | pos_name_code = null;
|
---|
457 | pos_name = null;
|
---|
458 | }
|
---|
459 | names = null;
|
---|
460 | language_code = null;
|
---|
461 | // Failing all that set an error message
|
---|
462 | if(name == null) {
|
---|
463 | name = Dictionary.get("MSM.No_Name");
|
---|
464 | }
|
---|
465 | }
|
---|
466 | return name;
|
---|
467 | }
|
---|
468 | /** Method to retrieve this metadata sets namespace.
|
---|
469 | * @return The namespace as a <strong>String</strong>.
|
---|
470 | */
|
---|
471 | public String getNamespace() {
|
---|
472 | return root.getAttribute("namespace");
|
---|
473 | }
|
---|
474 | /** Method to retrieve the root element, i.e. the Document Element, of the DOM model behind this metadata set.
|
---|
475 | * @return An <strong>Element</strong> which is at the root of the modal.
|
---|
476 | */
|
---|
477 | public Element getRoot() {
|
---|
478 | return root;
|
---|
479 | }
|
---|
480 | /** Retrieve the value tree from this set that matches the given element.
|
---|
481 | * @param element The target <strong>ElementWrapper</strong>.
|
---|
482 | * @return A <strong>GValueModel</strong> value tree, or <i>null</i> if no such element or value tree.
|
---|
483 | */
|
---|
484 | public GValueModel getValueTree(ElementWrapper element) {
|
---|
485 | GValueModel value_tree = null;
|
---|
486 | // Stinking hashtable get doesn't use the overridden equals. So I'll do a loop, which should be pretty small ie O(n) for n metadata elements.
|
---|
487 | for(Enumeration keys = value_trees.keys(); keys.hasMoreElements(); ) {
|
---|
488 | ElementWrapper sibling = (ElementWrapper) keys.nextElement();
|
---|
489 | if(sibling.equals(element)) {
|
---|
490 | value_tree = (GValueModel) value_trees.get(sibling);
|
---|
491 | break;
|
---|
492 | }
|
---|
493 | }
|
---|
494 | // If we've found no value tree, create a new one.
|
---|
495 | if(value_tree == null) {
|
---|
496 | value_tree = new GValueModel(element);
|
---|
497 | value_trees.put(element, value_tree);
|
---|
498 | }
|
---|
499 | return value_tree;
|
---|
500 | }
|
---|
501 | /** Remove a mds level attribute.
|
---|
502 | * @param name The name of the attribute to remove.
|
---|
503 | */
|
---|
504 | public void removeAttribute(String name) {
|
---|
505 | root.removeAttribute(name);
|
---|
506 | }
|
---|
507 | /** Method to remove the given element from this metadata set.
|
---|
508 | * @param element The <strong>Element</strong> to be removed.
|
---|
509 | */
|
---|
510 | public void removeElement(Element element) {
|
---|
511 | // we need to remove the value tree too!!
|
---|
512 | removeValueTree(new ElementWrapper(element));
|
---|
513 | root.removeChild(element);
|
---|
514 | }
|
---|
515 | /** Used to remove the value tree for a specific element.
|
---|
516 | * @param element The <strong>ElementWrapper</strong> whose tree you wish to remove.
|
---|
517 | * @return The <strong>GValueModel</strong> we just removed
|
---|
518 | */
|
---|
519 | public GValueModel removeValueTree(ElementWrapper element) {
|
---|
520 | for(Enumeration keys = value_trees.keys(); keys.hasMoreElements(); ) {
|
---|
521 | ElementWrapper sibling = (ElementWrapper) keys.nextElement();
|
---|
522 | if(sibling.equals(element)) {
|
---|
523 | GValueModel value_tree = (GValueModel) value_trees.get(sibling);
|
---|
524 | value_trees.remove(sibling);
|
---|
525 | return value_tree;
|
---|
526 | }
|
---|
527 | }
|
---|
528 | return null;
|
---|
529 | }
|
---|
530 | /** Set one of the mds level attributes.
|
---|
531 | * @param name The attribute to change.
|
---|
532 | * @param value its new value.
|
---|
533 | */
|
---|
534 | public void setAttribute(String name, String value) {
|
---|
535 | root.setAttribute(name, value);
|
---|
536 | }
|
---|
537 | /** Once the metadata set has been saved to a different location, this is used to update the file parameter.
|
---|
538 | * @param file The new location of this metadata set <strong>File</strong>.
|
---|
539 | */
|
---|
540 | public void setFile(File file) {
|
---|
541 | this.file = file;
|
---|
542 | }
|
---|
543 |
|
---|
544 | public void setName(String name) {
|
---|
545 | // Retrieve the name element. We look for the first english one.
|
---|
546 | Element name_element = null;
|
---|
547 | Element metadataset_element = document.getDocumentElement();
|
---|
548 | NodeList name_elements = metadataset_element.getElementsByTagName(Utility.NAME_ELEMENT);
|
---|
549 | for(int i = 0; i < name_elements.getLength(); i++) {
|
---|
550 | Element possible_name_element = (Element) name_elements.item(i);
|
---|
551 | if(possible_name_element.getAttribute(Utility.LANGUAGE_ATTRIBUTE).equals(Utility.ENGLISH_VALUE)) {
|
---|
552 | // Found it.
|
---|
553 | name_element = possible_name_element;
|
---|
554 | }
|
---|
555 | }
|
---|
556 | // If there is none add one. Note that we can only add english metadata sets. Although others can edit them to add further names as necessary.
|
---|
557 | if(name_element == null) {
|
---|
558 | name_element = document.createElement(Utility.NAME_ELEMENT);
|
---|
559 | name_element.setAttribute(Utility.LANGUAGE_ATTRIBUTE, Utility.ENGLISH_VALUE);
|
---|
560 | metadataset_element.insertBefore(name_element, metadataset_element.getFirstChild());
|
---|
561 | }
|
---|
562 | // Replace the text node
|
---|
563 | while(name_element.hasChildNodes()) {
|
---|
564 | name_element.removeChild(name_element.getFirstChild());
|
---|
565 | }
|
---|
566 | name_element.appendChild(document.createTextNode(name));
|
---|
567 | }
|
---|
568 |
|
---|
569 | /** Method to determine the number of elements in this set.
|
---|
570 | * @return An <i>int</i> specifying the element count.
|
---|
571 | */
|
---|
572 | public int size() {
|
---|
573 | return elements.getLength();
|
---|
574 | }
|
---|
575 | /** Method to translate this class into a meaningful string, which in this case is the metadata sets name.
|
---|
576 | * @return The metadata sets name as a <strong>String</strong>.
|
---|
577 | */
|
---|
578 | public String toString() {
|
---|
579 | String name = getName();
|
---|
580 | // If there is no given name, then use the namespace as there is garaunteed to be one of them.
|
---|
581 | if(name == null || name.length() == 0) {
|
---|
582 | name = root.getAttribute("namespace");
|
---|
583 | }
|
---|
584 | // Append namespace
|
---|
585 | String namespace = root.getAttribute("namespace");
|
---|
586 | if(namespace == null || namespace.equals("")) {
|
---|
587 | namespace = Utility.EXTRACTED_METADATA_NAMESPACE;
|
---|
588 | }
|
---|
589 | name = name + " (" + namespace + ")";
|
---|
590 | return name;
|
---|
591 | }
|
---|
592 |
|
---|
593 | private void init(File file) {
|
---|
594 | this.file = file;
|
---|
595 | this.value_trees = new Hashtable();
|
---|
596 | this.document = Utility.parse(file, false);
|
---|
597 | if(document != null) {
|
---|
598 | this.elements = document.getElementsByTagName("Element");
|
---|
599 | this.root = document.getDocumentElement();
|
---|
600 | // Now for each element read in its value tree if present.
|
---|
601 | for(int i = elements.getLength() - 1; i >= 0; i--) {
|
---|
602 | ElementWrapper value_element = new ElementWrapper((Element)elements.item(i));
|
---|
603 | File value_file = new File(file.getParentFile(), value_element.getName() + ".mdv");
|
---|
604 | ///ystem.err.println("Searching for " + value_file.getAbsolutePath());
|
---|
605 | if(value_file.exists()) {
|
---|
606 | Document value_document = Utility.parse(value_file, false);
|
---|
607 | if(value_document != null) {
|
---|
608 | value_trees.put(value_element, new GValueModel(value_element, value_document));
|
---|
609 | }
|
---|
610 | else {
|
---|
611 | Gatherer.println("Error! Missing mdv file: " + value_file.getAbsolutePath());
|
---|
612 | }
|
---|
613 | }
|
---|
614 | }
|
---|
615 | }
|
---|
616 | else {
|
---|
617 | Gatherer.println("Error! Missing mds file: " + file.getAbsolutePath());
|
---|
618 | }
|
---|
619 | }
|
---|
620 | }
|
---|