package tmxtest; import java.io.*; import java.util.*; import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; /** *

Reads resource text data directly from a TMX (XML) file.

*

First, the XMLTMXResourceBundle class instantiates itself with two parameters: * a TMX file name and a target language name. Then, using a DOM parser, it * reads all of a translation unit's properties for the key information and * specified language data and populates a hashtable with them.

*

TMX info: http://www.lisa.org/tmx/

*

Reference: Masaki Itagaki article (http://www.lisa.org/tmx/m_itagaki.html)

* *

Implementation notes

*

You instantiate the XMLTMXResourceBundle class in a program to read data from a * TMX file. Once the class is instantiated, it reads all the data in a TMX file * and loads into a DOM tree. Then it populates a hashtable so the * handleGetObject() method can be called to find text information based on a * key just as a standard ResourceBundle class does.
* Instantiating the TMXResouceBundle class is the same as instantiating the * PropertyResourceBundle class. First you obtain a system language code (e.g.: * from a locale's information). In TMX the value of the attribute must be one of the * ISO language identifiers (a two- or three-letter code) or one of the standard * locale identifiers (a two- or three-letter language code, a dash, and a * two-letter region code).

* @author Nicola Asuni [www.tecnick.com]. * @version 1.0 */ public class TMXResourceBundle extends ResourceBundle { /** * The hastable that will contain data loaded from XML */ protected Hashtable hashcontents = null; /** * Number of translation units (tu) items */ protected int numberOfItems = 0; /** * Vector to store tu items keys */ protected Vector vectOfItems; /** * TMX to Hashtable conversion. * Reads XML and store data in HashTable. * @param xmlfile the TMX (XML) file to read * @param language ISO language identifier (a two- or three-letter code) */ public TMXResourceBundle(String xmlfile, String language) { String temp_key = null; // store hashtable key names String temp_value = null; // store hashtable values NamedNodeMap temp_list = null; // list of attributes Attr temp_attr = null; // attribute NodeList listOfTUVs = null; // list of elements NodeList listOfSEG = null; // list of elements Element SEGElements = null; // element int numberOfTUVs = 0; // number of elements // Create Document with parser Document document = parseXmlFile(xmlfile, false); // handle document error if (document == null) { hashcontents = new Hashtable(); //initialize a void hashtable return; } // Make a list of Term Units and count the number of items NodeList listOfTermUnits = document.getElementsByTagName("tu"); numberOfItems = listOfTermUnits.getLength(); // set tu keys vector size vectOfItems = new Vector(numberOfItems); // set hash size hashcontents = new Hashtable(numberOfItems); for (int i = 0; i < numberOfItems; i++) { temp_value = null; // set a key temp_list = listOfTermUnits.item(i).getAttributes(); temp_attr = (Attr) temp_list.getNamedItem("tuid"); temp_key = temp_attr.getValue(); vectOfItems.add(temp_key); // store key on vector // get a value // Make a TUV list => "listOfTUVs" Node TUVs = listOfTermUnits.item(i); if (TUVs.getNodeType() == Node.ELEMENT_NODE) { Element TUVElements = (Element) TUVs; listOfTUVs = TUVElements.getElementsByTagName("tuv"); numberOfTUVs = listOfTUVs.getLength(); } // Check each TUV. If it's a specified lang, then get a SEG value for (int j = 0; j < numberOfTUVs; j++) { temp_list = listOfTUVs.item(j).getAttributes(); temp_attr = (Attr) temp_list.getNamedItem("xml:lang"); if (temp_attr.getValue().equals(language)) { // -- Get a SEG value SEGElements = (Element) listOfTUVs.item(j); listOfSEG = SEGElements.getElementsByTagName("seg"); try { temp_value = listOfSEG.item(0).getFirstChild().getNodeValue(); } catch (Exception e) { // in case of error print error message and set value to void string System.err.println(this.getClass().getName() + "(\"" + xmlfile + "\", \"" + language + "\") :: " + "Void value on key"); temp_value = ""; } } } // Populate hashtable if ((temp_key != null) && (temp_value != null)) { hashcontents.put(temp_key, temp_value); } } // for loop } // convert /** * Parses an XML file and returns a DOM document. * * @param filename the name of XML file * @param validating If true, the contents is validated against the DTD specified in the file. * @return the parsed document */ public static Document parseXmlFile(String filename, boolean validating) { try { // Create a builder factory DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(validating); // Create the builder and parse the file Document doc = factory.newDocumentBuilder().parse(new File(filename)); return doc; } catch (SAXException e) { // A parsing error occurred; the xml input is not valid System.err.println("[" + filename + "] SAXException:" + e); } catch (ParserConfigurationException e) { System.err.println("[" + filename + "] ParserConfigurationException:" + e); } catch (IOException e) { System.err.println("[" + filename + "] IOException:" + e); } return null; } /** * Get key value, return default if void. * @param key name of key * @param def default value * @return parameter value or default */ public String getString(String key, String def) { String param_value = ""; try { param_value = this.getString(key); if ((param_value != null) && (param_value.length() > 0)) { return param_value; } } catch (Exception e) { // for any exception return the default value return def; } return def; } /** * handleGetObject implementation * @param key the resource key * @return the content associated to the specified key * @throws MissingResourceException */ public final Object handleGetObject(String key) throws MissingResourceException { return hashcontents.get(key); } /** * Returns the number of translation units * @return number of Items */ public int getNumberOfItems() { return numberOfItems; } /** * Define getKeys method * @return item elements */ public Enumeration getKeys() { return vectOfItems.elements(); } }