package com.tecnick.tmxjavabridge; import java.io.*; import java.util.*; import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; /** * <p> * Reads resource text data directly from a TMX (XML) file. * </p> * <p> * First, the TMXResourceBundle 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. * </p> * <p> * <b>TMX info: </b> http://www.lisa.org/tmx/ * </p> * * <h4>Implementation notes</h4> * <p> * You instantiate the TMXResourceBundle 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. <br> * 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). * </p> * * Copyright (c) 2004-2005 * Tecnick.com S.r.l (www.tecnick.com) * Via Ugo Foscolo n.19 - 09045 Quartu Sant'Elena (CA) - ITALY * www.tecnick.com - info@tecnick.com <br/> * Project homepage: <a href="http://tmxjavabridge.sourceforge.net" target="_blank">http://tmxjavabridge.sourceforge.net</a><br/> * License: http://www.gnu.org/copyleft/lesser.html LGPL * * @author Nicola Asuni [www.tecnick.com]. * @version 1.1.005 */ 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, supports also URI resources or JAR resources * @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 <tu> attributes Attr temp_attr = null; // <tu> attribute NodeList listOfTUVs = null; // list of <tuv> elements NodeList listOfSEG = null; // list of <seg> elements Element SEGElements = null; // <seg> element int numberOfTUVs = 0; // number of <tuv> 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().equalsIgnoreCase(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 <seg> value on <tu tuid=\"" + temp_key + "\"> 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 Document parseXmlFile(String filename, boolean validating) { Document doc = null; DocumentBuilderFactory factory = null; // Create a builder factory try { factory = DocumentBuilderFactory.newInstance(); } catch (FactoryConfigurationError e) { System.err.println(e); return null; } factory.setValidating(validating); // Create the builder and parse the file try { try { // try to get the file from jar InputStream instream = getClass().getResourceAsStream(filename); doc = factory.newDocumentBuilder().parse(instream); } catch (Exception ejar) { try { // try to get the file as external URI doc = factory.newDocumentBuilder().parse(filename); } catch (IOException euri) { try { // try to get the file as local filename doc = factory.newDocumentBuilder().parse(new File(filename)); } catch (IOException efile) { try { // try to resolve the path as relative to local class folder String[] classPath = System.getProperties().getProperty("java.class.path", ".").split(";"); String newpath = classPath[0] + "/" + filename; doc = factory.newDocumentBuilder().parse(new File(newpath)); } catch (IOException epath) { // unable to get the input file System.err.println("IOException:" + epath); } } } } } catch (ParserConfigurationException e) { System.err.println("[" + filename + "] ParserConfigurationException:" + e); } catch (SAXException e) { System.err.println("[" + filename + "] SAXException:" + e); } return doc; } /** * 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(); } }