Search code examples
javaandroidtranslationproperties-fileresourcebundle

Convert Android Studio strings.xml to Eclipse MessagesBundle_en_US.properties


I have a Java game that has a (Android Studio app client) and (Eclipse pc client). I am working on language translation. I set up ResourceBundles.properties via Eclipse and strings.xml for Android Studio. I like the UI of the Android Studio Translations Editor, but need a way to convert it out into Resource Bundles OR use the strings.xml files. Is there an easy way to convert or load the Android Studio outputs so I can manage one master list of translated strings? Any free web based approach that allows me to export to .properties and .xml works too.

Eclipse Java code to use language files

enter image description here

public static void updateLocale() {
    Locale currentLocale = new Locale(language, country);
    try{
        File file = new File("res/gamedata");
        URL[] urls = {file.toURI().toURL()};
        ClassLoader loader = new URLClassLoader(urls);
        messages = ResourceBundle.getBundle("MessagesBundle", currentLocale, loader);
        //messages = ResourceBundle.getBundle("res/gamedata/MessagesBundle", currentLocale); //old way - needs to be in classpath
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                theDesktop.repaint(); //TODO:: test this when changing languages
            }
        });
    } catch (MissingResourceException e){
        KisnardOnline.LOGGER.error("Language files missing", e);
        //hardcoded values if you can't open the String lookups
        JOptionPane.showMessageDialog(theDesktop, "Language files missing. Please reload game.", "Error", JOptionPane.ERROR_MESSAGE);
    } catch (MalformedURLException e) {
        KisnardOnline.LOGGER.error("Language files missing", e);
        JOptionPane.showMessageDialog(theDesktop, "Language files missing. Please reload game.", "Error", JOptionPane.ERROR_MESSAGE);
    }
}

Android Studio code to use language files

public final String getString(@StringRes int resId) Returns a localized string from the application's package's default string table.

enter image description here


Solution

  • Here is how I was able to do this for anyone else with this question:

    Sample Android Studio strings.xml:

    <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
        <string name="app_name" translatable="false">Kisnard Online</string>
        <string name="drawable_banner_stacked_kisnard_online_description" translatable="false">Kisnard Online Banner</string>
        <string name="general_file_locks">"Can't open or access necessary game files.  Please ensure you are not modifying any game files."</string>
        <string name="general_success">Success</string>
        <string name="general_confirm">Confirm</string>
        <string name="general_error">Error</string>
    </resources>
    

    Java code to read from this syntax:

    public static void loadStringsXML() {
        loadStringXML("res/gamedata/strings_de.xml", de_DE_Messages);
        loadStringXML("res/gamedata/strings.xml", en_US_Messages);
        loadStringXML("res/gamedata/strings_es.xml", es_ES_Messages);
        loadStringXML("res/gamedata/strings_fr.xml", fr_FR_Messages);
        loadStringXML("res/gamedata/strings_it.xml", it_IT_Messages);
        loadStringXML("res/gamedata/strings_ko.xml", ko_KR_Messages);
    }
    
    public static void loadStringXML(String filename, HashMap<String, String> hashMap) {
        // Instantiate the Factory
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            // optional, but recommended
            // process XML securely, avoid attacks like XML External Entities (XXE)
            dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
    
            // parse XML file
            DocumentBuilder db = dbf.newDocumentBuilder();
    
            Document doc = db.parse(new File(filename));
    
            // optional, but recommended
            // http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
            doc.getDocumentElement().normalize();
    
            NodeList list = doc.getElementsByTagName("string");
            for (int temp = 0; temp < list.getLength(); temp++) {
                Node node = list.item(temp);
    
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
    
                    String name = element.getAttribute("name");
                    String value = node.getTextContent();
                    value = value.replace("\\'", "'"); //Android string file requires single quotes to be escaped
                    //System.out.println(name + "=" + value);
                    hashMap.put(name, value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }