source: trunk/gli/src/org/greenstone/gatherer/gems/MetadataSet.java@ 8971

Last change on this file since 8971 was 8971, checked in by mdewsnip, 19 years ago

More GEMS fixes, by Matthew Whyte. Can now create subelements of subelements.

  • Property svn:keywords set to Author Date Id Revision
File size: 28.4 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 * <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 */
37package org.greenstone.gatherer.gems;
38
39import java.io.*;
40import java.net.*;
41import java.util.*;
42import org.apache.xerces.dom.*;
43import org.greenstone.gatherer.Configuration;
44import org.greenstone.gatherer.DebugStream;
45import org.greenstone.gatherer.Dictionary;
46import org.greenstone.gatherer.util.StaticStrings;
47import org.greenstone.gatherer.util.Utility;
48import org.greenstone.gatherer.util.XMLTools;
49import org.w3c.dom.*;
50/** An semi-data class to hold details about a loaded metadata set, it also provides some methods to manipulating the data within.
51 * @author John Thompson, Greenstone Digital Library, University of Waikato
52 * @version 2.3b
53 */
54public class MetadataSet {
55 /** The <Strong>Document</strong> of the DOM model. */
56 private Document document = null;
57 /** The document <strong>Element</strong> of the DOM model. */
58 private Element root = null;
59 /** The <strong>File</strong> this metadata set was loaded from. */
60 public String old_filename = null;
61 private File file = null;
62 /** A mapping from metadata elements to the root element of the value trees for that element. */
63 private Hashtable value_trees = null;
64 /** The list of metadata elements which are, of course, children of the root node. */
65 private ArrayList elements = null;
66
67 // the nmae of the collection if this set is collection-specific
68 private String collection = null;
69 //set_changed is check in msm(metadatasetmanager).save() and if this is true then we save
70 //the collection, otherwise we leave it as is
71 private boolean setChanged = false;
72 private String current_language_code;
73 /** The description of this metadata set. Cached as it takes more computation time. */
74 private String description = null;
75 /** The name of this metadata set. Cached as it takes more computation time. */
76 private String name = null;
77 /** An element of the tree pruning filter enumeration, that indicates all nodes in the tree should be retained. */
78 static final int ALL_VALUES = 1;
79 /** An element of the tree pruning filter enumeration, that indicates only metadata Subject nodes or higher should remain after pruning. */
80 static final int SUBJECTS_ONLY = 2;
81 /** An element of the tree pruning filter enumeration, that indicates no value nodes i.e. the entire AssignedValues subtree, should remain after pruning. */
82 static final int NO_VALUES = 3;
83
84 public MetadataSet(String metadata_template) {
85
86 this.file = new File(metadata_template);
87 this.value_trees = new Hashtable();
88 this.document = Utility.parse(metadata_template, true);
89
90 init(true); // use class loader
91 }
92
93 /** Constructor.
94 * @param file The file the metadata set should be loaded from.
95 */
96 public MetadataSet(File file) {
97 this.file = file;
98 this.value_trees = new Hashtable();
99 this.document = XMLTools.parse(file, false);
100
101 init(false); // don't use class loader
102 }
103
104 /** Copy constructor.
105 * @param original The original metadata set to copy from.
106 */
107 public MetadataSet(MetadataSet original) {
108 this.value_trees = new Hashtable();
109 // We have to create a new document.
110 document = new DocumentImpl(original.getDocument().getDoctype());
111 root = (Element) document.importNode(original.getDocument().getDocumentElement(), true);
112 document.appendChild(root);
113 elements = XMLTools.getChildElementsByTagName(root, "Element");
114 //elements = root.getElementsByTagName("Element");
115 file = original.getFile();
116 // Now for each element read in its value tree if present.
117 for(int i = elements.size() - 1; i >= 0; i--) {
118 ElementWrapper value_element_wrapper = new ElementWrapper((Element)elements.get(i));
119 GValueModel value_tree = original.getValueTree(value_element_wrapper);
120 Document value_document = value_tree.getDocument();
121 Document value_document_copy = new DocumentImpl(value_document.getDoctype());
122 Element value_element = value_document.getDocumentElement();
123 Element value_element_copy = (Element) value_document_copy.importNode(value_element, true);
124 value_document_copy.appendChild(value_element_copy);
125 GValueModel value_tree_copy = new GValueModel(value_element_wrapper, value_document_copy);
126 value_trees.put(value_element_wrapper, value_tree_copy);
127 }
128 }
129
130 public boolean getSetChanged() {
131
132 return setChanged;
133 }
134 public void setSetChanged(boolean val) {
135
136 setChanged = val;
137 }
138 /** Conditional copy constructor.
139 * @param original The original metadata set to copy from.
140 * @param condition An <i>int</i> which matches one of the tree pruning filter types.
141 */
142 public MetadataSet(MetadataSet original, int condition) {
143 this(original);
144 // Now based on condition, we may have to remove some nodes from
145 // this model.
146 switch(condition) {
147 case ALL_VALUES:
148 // Do nothing.
149 break;
150 case SUBJECTS_ONLY:
151 // For each element retrieve its AssignedValues element.
152 for(Enumeration keys = value_trees.keys(); keys.hasMoreElements(); ) {
153 ElementWrapper value_element = (ElementWrapper)keys.nextElement();
154 GValueModel value_tree = (GValueModel)value_trees.get(value_element);
155 Document value_tree_document = value_tree.getDocument();
156 Element value_tree_root_element = value_tree_document.getDocumentElement();
157 // Traverse tree and remove leaf nodes.
158 MSMUtils.traverseTree(value_tree_root_element, MSMUtils.NONE, true);
159 }
160 break;
161 case NO_VALUES:
162 // Remove assigned values trees.
163 value_trees.clear();
164 break;
165 }
166 }
167
168 public void setCollection(String coll) {
169 collection = coll;
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
181 /** Add a new default metadata element with the given name to this metadata set.
182 This method also handles the addtion of 'subelements'
183 * @param name The name of this element as a <strong>String</strong>.
184 * @param parent The parent element as an <strong>GEMSNode</strong>. If null, the parent is the metadataset root.
185 * @return An <strong>ElementWrapper</strong> around the newly created element or null if the element was not created.
186 */
187 public ElementWrapper addElement(String name, String language, GEMSNode parent)
188 {
189 Element parent_element = null;
190
191 //The element that we are creating
192 Element element = document.createElementNS("","Element");
193 element.setAttribute("name",name);
194
195 //Add identifier attribute. This handles if we use the new or old language identification
196 MSMUtils.addElementAttribute(element, "identifier", language, name);
197
198 if(parent == null) //A element
199 {
200 parent_element = root;
201 elements.add(element); //Add the new element to the list of 'em
202 }
203 else //A subelement!
204 {
205 //Add the new subelement to the list of 'em
206 parent.getElement().addSubelementToList(element);
207 parent_element = parent.getElement().getElement(); //get the parent as an Element
208 }
209
210 parent_element.appendChild(element);
211
212 return new ElementWrapper(element);
213 }
214
215
216 /** Method to add a new metadata element to this metadata set, if and only if the element is not already present.
217 * @param others_element An <strong>Element</strong> we wish to add to this metadata set, that currently belongs to some other set.
218 * @param model A <strong>GValueModel</strong> value tree
219 * @return <i>null</i> if the add is successful, otherwise a <strong>String</strong> containing an error message (phrase key).
220 */
221 public String addElement(Element others_element, GValueModel model) {
222 if(!containsElement(others_element.getAttribute("name"))) {
223 // First get ownership of the new element, then add it.
224 Element our_element = (Element)document.importNode(others_element, true);
225 // add the value tree
226 root.appendChild(our_element);
227 if (model != null) {
228 addValueTree(new ElementWrapper(our_element), model);
229 }
230 return null;
231 }
232 else {
233 return "MSMPrompt.Name_Exists";
234 }
235 }
236
237 /** 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.
238 * @param others_element An <strong>Element</strong> we wish to add to this metadata set, that currently belongs to some other set.
239 * @param new_name The new name to be given this element, as a <strong>String</strong>.
240 * @param model A <strong>GValueModel</strong> value tree
241 * @return <i>null</i> if the add is successful, otherwise a <strong>String</strong> containing an error message (phrase key).
242 */
243 public String addElement(Element others_element, String new_name, GValueModel model) {
244 if(!containsElement(new_name)) {
245 // First get ownership of the new element, then add it.
246 Element our_element =
247 (Element) document.importNode(others_element, true);
248 // Change name
249 our_element.setAttribute("name", new_name);
250 // we also want to change the english identifier of this element
251 MSMUtils.setIdentifier(our_element, new_name);
252 // Add it to teh set
253 root.appendChild(our_element);
254 // add the value tree
255 if (model != null) {
256 addValueTree(new ElementWrapper(our_element), model);
257 }
258 return null;
259 }
260 else {
261 return "MSMPrompt.Name_Exists";
262 }
263 }
264 /** Add a value tree to a given metadata element.
265 * @param element The <strong>ElementWrapper</strong> containing the element you wish to add a value tree for.
266 * @param model A <strong>GValueModel</strong> value tree
267 */
268 public void addValueTree(ElementWrapper element, GValueModel model) {
269 ///ystem.err.println("Adding value tree for " + element.toString());
270 value_trees.put(element, model);
271 }
272
273 public int compare(Element e1, Element e2) {
274 int result = 0;
275 // Check that they're not the same element.
276 if(e1 != e2) {
277 int index_e1 = -1;
278 int index_e2 = -1;
279 // Locate the indexes for each element.
280 for(int i = 0; i < elements.size(); i++) {
281 Node element = (Node)elements.get(i);
282 if(element == e1) {
283 index_e1 = i;
284 }
285 if(element == e2) {
286 index_e2 = i;
287 }
288 }
289 if(index_e1 < index_e2) {
290 result = -1;
291 }
292 else {
293 result = 1;
294 }
295 }
296 return result;
297 }
298
299 /** A method to determine if this metadata set contains an element with a certain name (case sensitive).
300 * @param name A <strong>String</strong> which is the name of the element whose presence we are checking.
301 * @return A <i>boolean</i> which is <i>true</i> if the named element exists, <i>false</i> otherwise.
302 */
303 public boolean containsElement(String name) {
304 for(int i = 0; i < elements.size(); i++) {
305 Element sibling = (Element) elements.get(i);
306 String sibling_name = sibling.getAttribute("name");
307 if(sibling_name.equals(name)) {
308 return true;
309 }
310 }
311 return false;
312 }
313
314 public NamedNodeMap getAttributes() {
315 return root.getAttributes();
316 }
317
318 /** Method to retrieve the contact address of the metadata set creator.
319 * @return A <strong>String</strong> containing the address.
320 */
321 /* private String getContact() {
322 return root.getAttribute("contact");
323 } */
324 /** Method to retrieve the name of the creator of this metadata set.
325 * @return A <strong>String</strong> containing the name.
326 */
327 public String getCreator() {
328 return root.getAttribute("creator");
329 }
330 /** 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.
331 * @return The description as a <strong>String</strong>.
332 */
333 public String getDescription() {
334 if(current_language_code != null && !Configuration.getLanguage().equals(current_language_code)) {
335 description = null;
336 }
337 if(description == null) {
338 description = getAttribute(StaticStrings.DESCRIPTION_ELEMENT, Dictionary.get("MSM.No_Description"));
339 }
340 return description;
341 }
342
343 /** Method to retrieve the <strong>Document</strong> associated with this metadata set.
344 * @return The <strong>Document</strong> representing this metadata set.
345 */
346 public Document getDocument() {
347 return document;
348 }
349 /** Method to retrieve the metadata element indicated by an index.
350 * @param index An <i>int</i> specifying the required element.
351 * @return The <strong>Element</strong> at the index.
352 */
353 public Element getElement(int index) {
354 return (Element)elements.get(index);
355 }
356 /** 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.
357 * @param metadata A <strong>Metadata</strong> object representing an element and value assignment.
358 * @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.
359 */
360// public Element getElement(Metadata metadata) {
361// return metadata.getElement().getElement();
362// }
363 /** 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.
364 * @param name A <strong>String</strong> stating the desired objects name.
365 * @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.
366 */
367 public Element getElement(String name) {
368 // Strip any namespace.
369 while(name.indexOf(".") != -1 && !name.equals(".")) {
370 name = name.substring(name.indexOf(".") + 1);
371 }
372 ///ystem.err.println("Get element named " + name);
373 for(int i = 0; i < elements.size(); i++) {
374 Element element = (Element) elements.get(i);
375 ///ystem.err.println("Compare to: " + element.getAttribute("name"));
376 if(element.getAttribute("name").equals(name)) {
377 return element;
378 }
379 }
380 return null;
381 }
382
383 public Element getElement(Element parent_element, String name) {
384 DebugStream.println("Get element named " + name + " from " + parent_element.getAttribute("name"));
385 ArrayList elements = XMLTools.getChildElementsByTagName(parent_element, "Element");
386 for(int i = 0; i < elements.size(); i++) {
387 Element element = (Element) elements.get(i);
388 if(element.getAttribute("name").equals(name) && element.getParentNode() == parent_element) {
389 elements = null;
390 return element;
391 }
392 }
393 elements = null;
394 return null;
395 }
396 /** Method to acquire a list of all the elements in this metadata set.
397 * @return A <strong>NodeList</strong> containing all of this sets elements.
398 */
399 public ArrayList getElements() {
400 return elements;
401 }
402
403 /** Method to retrieve a list of all the elements in this metadata set, sorted.
404 * @return A <strong>Vector</strong> containing all of the elements of this sets, sorted.
405 */
406// public Vector getElementsSorted() {
407// Vector elements_list = new Vector();
408// for (int i = 0; i < elements.size(); i++) {
409// elements_list.add(new ElementWrapper((Element) elements.get(i)));
410// }
411// Collections.sort(elements_list, MSMUtils.METADATA_COMPARATOR);
412// return elements_list;
413// }
414
415 /** Method to retrieve the original file this metadata set was created from.
416 * @return A <strong>File</strong>.
417 */
418 public File getFile() {
419 return file;
420 }
421 /** Get the last changed attribute.
422 * @return Last changed as a <strong>String</strong>.
423 */
424 public String getLastChanged() {
425 return root.getAttribute("lastchanged");
426 }
427
428 /** Method to get this metadata sets name. Note that this is language specific, so we determine the desired language from the Dictionary.
429 If no such entry exists, first try returning the english version and failing that the first name found.
430 * @return A <strong>String</strong> which contains its name.
431 */
432 public String getName() {
433 if(current_language_code != null && !Configuration.getLanguage().equals(current_language_code)) {
434 // name = null;
435 return null;
436 }
437 if(name == null) {
438
439 //name = getAttribute(StaticStrings.NAME_ELEMENT, Dictionary.get("MSM.No_Name"));
440 return getAttribute(StaticStrings.NAME_ELEMENT, Dictionary.get("MSM.No_Name"));
441
442 }
443
444 return name;
445 }
446 /** Method to retrieve this metadata sets namespace.
447 * @return The namespace as a <strong>String</strong>.
448 */
449 public String getNamespace() {
450 return root.getAttribute("namespace");
451 }
452
453 /**
454 Method to change this metadata set's namespace
455 @param: The new namespace as a <strong>String</strong>
456 */
457 public void setNamespace(String new_namespace)
458 {
459 root.setAttribute("namespace", new_namespace);
460 }
461
462 /** Method to retrieve the root element, i.e. the Document Element, of the DOM model behind this metadata set.
463 * @return An <strong>Element</strong> which is at the root of the modal.
464 */
465 public Element getRoot() {
466 return root;
467 }
468 /** Retrieve the value tree from this set that matches the given element.
469 * @param element The target <strong>ElementWrapper</strong>.
470 * @return A <strong>GValueModel</strong> value tree, or <i>null</i> if no such element or value tree.
471 */
472 public GValueModel getValueTree(ElementWrapper element) {
473 GValueModel value_tree = null;
474 // 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.
475 for(Enumeration keys = value_trees.keys(); keys.hasMoreElements(); ) {
476 ElementWrapper sibling = (ElementWrapper) keys.nextElement();
477 if(sibling.equals(element)) {
478 value_tree = (GValueModel) value_trees.get(sibling);
479 break;
480 }
481 }
482 // If we've found no value tree, create a new one.
483 if(value_tree == null) {
484 value_tree = new GValueModel(element);
485 value_trees.put(element, value_tree);
486 }
487 return value_tree;
488 }
489 /** Remove a mds level attribute.
490 * @param name The name of the attribute to remove.
491 */
492 public void removeAttribute(String name) {
493 root.removeAttribute(name);
494 }
495
496 /** Method to remove the given element from this metadata set.
497 * @param element The <strong>Element</strong> to be removed.
498 * @param parent The parent element (wrapped, so can access its subelement list), as an <strong>ElementWrapper</strong>. If null, the parent is root.
499 */
500 public void removeElement(Element element, ElementWrapper parent) {
501 try {
502 ElementWrapper element_wrapped = new ElementWrapper(element);
503 removeValueTree(element_wrapped);
504
505 if(parent == null)
506 {
507 elements.remove(element);
508 root.removeChild(element);
509 }
510 else
511 {
512 parent.removeSubelementFromList(element);
513 parent.getElement().removeChild(element);
514 }
515
516 } catch(Exception DOMException) { //The element does not exist!!
517 System.err.println("Exception: '"+ DOMException + "' occured. Cannot remove element because it does not exist.");
518 }
519 }
520
521 /**
522 Rename the metadata element.
523 @param oldElement An <strong>Element</strong> we wish to rename
524 @param newName A <strong>String</strong> which contains the new name of the element.
525 @return An <strong>ElementWrapper</strong> around the newly named element
526 */
527 public void renameElement(Element oldElement, String newName)
528 {
529 oldElement.setAttribute("name", newName); //Rename the element
530 }
531
532
533 /** Used to remove the value tree for a specific element.
534 * @param element The <strong>ElementWrapper</strong> whose tree you wish to remove.
535 * @return The <strong>GValueModel</strong> we just removed
536 */
537 public GValueModel removeValueTree(ElementWrapper element) {
538 for(Enumeration keys = value_trees.keys(); keys.hasMoreElements(); )
539 {
540 ElementWrapper sibling = (ElementWrapper) keys.nextElement();
541 if(sibling.equals(element))
542 {
543 GValueModel value_tree = (GValueModel) value_trees.get(sibling);
544 value_trees.remove(sibling);
545 return value_tree;
546 }
547 }
548 return null;
549 }
550 /** Set one of the mds level attributes.
551 * @param name The attribute to change.
552 * @param value its new value.
553 */
554 public void setAttribute(String name, String value) {
555 root.setAttribute(name, value);
556 }
557 /** Once the metadata set has been saved to a different location, this is used to update the file parameter.
558 * @param file The new location of this metadata set <strong>File</strong>.
559 */
560 public void setFile(File file) {
561 this.file = file;
562 }
563
564 public void setName(String name) {
565 // Retrieve the name element. We look for the first english one.
566 boolean found_it = false;
567 Element name_element = null;
568 Element metadataset_element = document.getDocumentElement();
569 NodeList name_elements = metadataset_element.getElementsByTagName(StaticStrings.NAME_ELEMENT);
570 for(int i = 0; (i < name_elements.getLength() && !found_it); i++) {
571 Element possible_name_element = (Element) name_elements.item(i);
572 if(possible_name_element.getAttribute(StaticStrings.LANGUAGE_ATTRIBUTE).equals("en")) {
573 // Found it.
574 found_it = true;
575 name_element = possible_name_element;
576 //System.out.println("Found english name: " + name_element); //debug
577 }
578 }
579 // 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.
580 if(name_element == null) {
581 name_element = document.createElement(StaticStrings.NAME_ELEMENT);
582 name_element.setAttribute(StaticStrings.LANGUAGE_ATTRIBUTE, "en");
583 metadataset_element.insertBefore(name_element, metadataset_element.getFirstChild());
584 }
585 // Replace the text node
586 while(name_element.hasChildNodes()) {
587 name_element.removeChild(name_element.getFirstChild());
588 }
589 name_element.appendChild(document.createTextNode(name));
590 }
591
592 /** Method to determine the number of elements in this set.
593 * @return An <i>int</i> specifying the element count.
594 */
595 public int size() {
596 return elements.size();
597 }
598 /** Method to translate this class into a meaningful string, which in this case is the metadata sets name.
599 * @return The metadata sets name as a <strong>String</strong>.
600 */
601 public String toString() {
602
603 String name = getName();
604 // If there is no given name, then use the namespace as there is garaunteed to be one of them.
605 if(name == null || name.length() == 0) {
606 name = root.getAttribute("namespace");
607 }
608 // Append namespace
609 String namespace = root.getAttribute("namespace");
610 if(namespace == null || namespace.equals("")) {
611 namespace = Utility.EXTRACTED_METADATA_NAMESPACE;
612 }
613 name = name + " (" + namespace + ")";
614 if (collection == null)
615 return name;
616 return "["+collection+"] "+name;
617 }
618
619 /** This method retrieves the required attribute from the Metadata Set, typically it's name or it's description. Note that this method is language dependant, and moreover supports both legacy metadata sets and the new sets optimized for multiple languages.
620 * @param element_name the name of the type of element the required information is in as a String
621 * @param default_string the value to return if no such element is found also as a String
622 * @see org.greenstone.gatherer.Configuration#getLanguage()
623 * @see org.greenstone.gatherer.msm.MSMUtils#getValue(Node)
624 * @see org.greenstone.gatherer.util.StaticStrings#CODE_ATTRIBUTE
625 * @see org.greenstone.gatherer.util.StaticStrings#SETLANGUAGE_ELEMENT
626 */
627 private String getAttribute(String element_name, String default_string) {
628 String result = null;
629
630 // Determine the language code.
631 current_language_code = Configuration.getLanguage();
632
633 ///ystem.err.println("Searching for the " + element_name + " in " + current_language_code);
634
635 // New Metadata Set Format makes use of deferred-node-expansion to save memory - rather than create nodes for a name and description in each language, nodes which have potentially huge strings, we instead create simplier SETLANGUAGE nodes, and then only expand the one in the desired language. Of course if a user happens to change to every available language slightly more memory will be used than in the old method. For instance consider the DLS with 25 languages, each with a name node of 50 bytes and an descriptions of 500. Thus old style > 13750 bytes while new style < 600.
636 NodeList set_language_elements = document.getElementsByTagName(StaticStrings.SETLANGUAGE_ELEMENT);
637 for(int b = 0; b < set_language_elements.getLength(); b++) {
638 Element set_language_element = (Element) set_language_elements.item(b);
639 String code = set_language_element.getAttribute(StaticStrings.CODE_ATTRIBUTE).toLowerCase();
640 if(code.equals(current_language_code)) {
641 NodeList specific_elements = set_language_element.getElementsByTagName(element_name);
642 if(specific_elements.getLength() > 0) {
643 Element specific_element = (Element) specific_elements.item(0);
644 result = MSMUtils.getValue(specific_element);
645 specific_element = null;
646 }
647 specific_elements = null;
648 }
649 code = null;
650 set_language_element = null;
651 }
652 set_language_elements = null;
653 // And we may be all done
654 if(result != null) {
655 return result;
656 }
657
658 // Failing that we move on to an older style search - start by recovering all Name elements
659 NodeList possible_elements = document.getElementsByTagName(element_name);
660 // Iterate through the available names looking for the appropriate one. Also make note of the first name, then overwrite it with any english one.
661 boolean found = false;
662 for(int i = 0; !found && i < possible_elements.getLength(); i++) {
663 Element possible_element = (Element) possible_elements.item(i);
664 String possible_element_code = possible_element.getAttribute("language").toLowerCase();
665 if(possible_element_code.equals(current_language_code) || name == null) {
666 result = MSMUtils.getValue(possible_element);
667 found = true;
668 }
669 possible_element_code = null;
670 possible_element = null;
671 }
672 possible_elements = null;
673 // Failing all that set an error message
674 if(result == null) {
675 result = default_string;
676 }
677 return result;
678 }
679
680 private void init(boolean use_classloader) {
681
682 if(this.document != null) {
683 this.root = document.getDocumentElement();
684 this.elements = XMLTools.getChildElementsByTagName(root, "Element");
685 // Now for each element read in its value tree if present.
686 for(int i = elements.size() - 1; i >= 0; i--) {
687 ElementWrapper value_element = new ElementWrapper((Element)elements.get(i));
688 File value_file = new File(file.getParentFile(), value_element.getName() + ".mdv");
689 ///ystem.err.println("Searching for " + value_file.getAbsolutePath());
690 if(value_file.exists()) {
691 Document value_document;
692 if (use_classloader) {
693 value_document = Utility.parse(value_file.toString(), true);
694 }
695 else {
696 value_document = XMLTools.parse(value_file, false);
697 }
698 if(value_document != null) {
699 value_trees.put(value_element, new GValueModel(value_element, value_document));
700 }
701 else {
702 DebugStream.println("Error! Missing mdv file: " + value_file.getAbsolutePath());
703 }
704 }
705 }
706 }
707 else {
708 DebugStream.println("Error! Missing mds file: " + file.getAbsolutePath());
709 }
710 }
711}
Note: See TracBrowser for help on using the repository browser.