/* * Freeplane - mind map editor * Copyright (C) 2008 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitry Polivaev * * This file is modified by Dimitry Polivaev in 2008. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.freeplane.core.resources; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.ResourceBundle; import org.freeplane.core.util.FileUtils; import org.freeplane.core.util.LogUtils; import org.freeplane.core.util.collection.MultipleValueMap; /** * Class for managing localized resources. See translation property files. */ public class ResourceBundles extends ResourceBundle { public static final String LANGUAGE_AUTOMATIC = "automatic"; private static final String DEFAULT_LANGUAGE = "en"; public static final String POSTFIX_TRANSLATE_ME = "[translate me]"; public static final String RESOURCE_LANGUAGE = "language"; /** * */ final private ResourceController controller; private Map<String, String> defaultResources; private final MultipleValueMap<String, URL> externalResources; private String lang; private Map<String, String> languageResources; final private boolean isUserDefined; ResourceBundles(final ResourceController controller) { this.controller = controller; final URL systemResource = getSystemResourceUrl(DEFAULT_LANGUAGE); isUserDefined = systemResource.getProtocol().equalsIgnoreCase("file"); externalResources = new MultipleValueMap<String, URL>(); try { loadLocalLanguageResources(); if(lang.equals(DEFAULT_LANGUAGE)) defaultResources = languageResources; else defaultResources = getLanguageResources(DEFAULT_LANGUAGE); } catch (final Exception ex) { LogUtils.severe(ex); LogUtils.severe("Error loading Resources"); } } public void addResources(final String language, final Map<String, String> resources) { if (language.equalsIgnoreCase(DEFAULT_LANGUAGE)) { defaultResources.putAll(resources); } else if (language.equalsIgnoreCase(lang)) { languageResources.putAll(resources); } } public void addResources(final String language, final URL url) { try { addResources(language, getLanguageResources(url)); externalResources.put(language, url); } catch (final IOException e) { LogUtils.severe(e); } } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public Enumeration getKeys() { final Iterator<String> iterator = defaultResources.keySet().iterator(); return new Enumeration() { public boolean hasMoreElements() { return iterator.hasNext(); } public Object nextElement() { return iterator.next(); } }; } public String getLanguageCode() { return lang; } public String getDefaultLanguageCode() { return DEFAULT_LANGUAGE; } /** * @throws IOException */ private Map<String, String> getLanguageResources(final String lang) throws IOException { final URL systemResource = getSystemResourceUrl(lang); if (systemResource == null) { // no double logging: System.out.println("core resource " + resourceName + " not found"); return null; } final Map<String, String> resources = getLanguageResources(systemResource); final Iterator<URL> iterator = externalResources.get(lang).iterator(); while (iterator.hasNext()) { resources.putAll(getLanguageResources(iterator.next())); } return resources; } protected URL getSystemResourceUrl(final String lang) { String resourceName = "/translations/Resources" + "_" + lang + ".properties"; final URL systemResource = ResourceController.getResourceController().getResource(resourceName); return systemResource; } @SuppressWarnings({ "unchecked", "rawtypes" }) private Map<String, String> getLanguageResources(final URL systemResource) throws IOException { InputStream in = null; try { in = new BufferedInputStream(systemResource.openStream()); final Properties bundle = new Properties(); bundle.load(in); return new HashMap(bundle); } finally { FileUtils.silentlyClose(in); } } public String getResourceString(final String key) { final String resourceString = getResourceString(key, key); if (resourceString == key) { if(isUserDefined) System.out.println("missing key " + key); else System.err.println("missing key " + key); return '[' + key + ']'; } return resourceString; } public String getResourceString(final String key, final String resource) { String value = languageResources.get(key); if (value != null) { return value; } value = defaultResources.get(key); if (value != null) { return value + ResourceBundles.POSTFIX_TRANSLATE_ME; } return resource; } public String putResourceString(final String key, final String resource) { return languageResources.put(key, resource); } @Override protected Object handleGetObject(final String key) { try { return languageResources.get(key); } catch (final Exception ex) { LogUtils.severe("Warning - resource string not found:" + key); return defaultResources.get(key) + ResourceBundles.POSTFIX_TRANSLATE_ME; } } private void loadLocalLanguageResources() throws IOException { lang = controller.getProperty(ResourceBundles.RESOURCE_LANGUAGE); if (lang == null || lang.equals(LANGUAGE_AUTOMATIC)) { final String country = Locale.getDefault().getCountry(); if(! country.equals("")){ lang = Locale.getDefault().getLanguage() + "_" + country; languageResources = getLanguageResources(lang); if (languageResources != null) { LogUtils.info("language resources for " + lang + " found"); return; } } lang = Locale.getDefault().getLanguage(); languageResources = getLanguageResources(lang); if (languageResources != null) { LogUtils.info("language resources for " + lang + " found"); return; } LogUtils.info("language resources for " + lang + " not found"); } if ("no".equals(lang)) { lang = "nb"; } languageResources = getLanguageResources(lang); if (languageResources != null) { return; } LogUtils.info("language resources for " + lang + " not found"); lang = DEFAULT_LANGUAGE; languageResources = getLanguageResources(lang); if (languageResources != null) { return; } LogUtils.severe("language resources for " + lang + " not found, aborting"); System.exit(1); } public void loadAnotherLanguage() { try { if(! lang.equals(controller.getProperty(ResourceBundles.RESOURCE_LANGUAGE))) loadLocalLanguageResources(); } catch (final IOException e) { LogUtils.severe(e); } } }