/******************************************************************************* * Copyright (c) 2008 Ralf Ebert * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Ralf Ebert - initial API and implementation *******************************************************************************/ package com.swtxml.i18n; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.MissingResourceException; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; import org.apache.commons.lang.StringUtils; import org.eclipse.core.runtime.Assert; import com.swtxml.resources.IDocumentResource; import com.swtxml.util.lang.FilenameUtils; /** * ResourceBundleLabelTranslator translates label keys for the given document * and locale. * * It looks up resource bundles which are co-located with the document first * (same name, same package). So if you have a document "SomeFile.swtxml", it * looks for "SomeFile_[locale].properties". Then it looks for a file * "messages_[locale].properties" in the same package as the document. Then it * looks for "messages_[locale].properties" and "plugin_[locale].properties" in * the root of the bundle from which the document was loaded. * * Locales are resolved in the same way as Java resolves ResourceBundles, i.e. * for locale "en_US" it looks for: "messages_en_US.properties", then * "messages_en.properties", then "messages.properties" * * Should be created only when needed, as it loads and caches all relevant * resource bundle contents immediately. * * @author Ralf Ebert <info@ralfebert.de> */ public class ResourceBundleLabelTranslator implements ILabelTranslator { private final List<ResourceBundle> resourceBundles; public ResourceBundleLabelTranslator(IDocumentResource document, Locale locale) { Assert.isNotNull(document, "document"); String documentName = FilenameUtils.getBaseName(document.getDocumentName()); List<String> resourceBundleNames = getResourceBundleNames(documentName, locale); resourceBundleNames.addAll(getResourceBundleNames("messages", locale)); resourceBundleNames.addAll(getResourceBundleNames("bundle:messages", locale)); resourceBundleNames.addAll(getResourceBundleNames("bundle:plugin", locale)); this.resourceBundles = new ArrayList<ResourceBundle>(); for (String name : resourceBundleNames) { try { InputStream resource = document.resolve(name + ".properties"); if (resource != null) { resourceBundles.add(new PropertyResourceBundle(resource)); } } catch (MissingResourceException e) { // ignore missing resources } catch (IOException e) { // ignore invalid resource bundles } } } public String translate(String key) { for (ResourceBundle resourceBundle : resourceBundles) { try { String value = resourceBundle.getString(key); if (value != null) { return value; } } catch (MissingResourceException e) { // ignore missing resources } } return "??? " + key + " ???"; } private List<String> getResourceBundleNames(String baseName, Locale locale) { List<String> results = new ArrayList<String>(4); if (StringUtils.isNotEmpty(locale.getLanguage())) { if (StringUtils.isNotEmpty(locale.getCountry())) { if (StringUtils.isNotEmpty(locale.getVariant())) { results.add(baseName + "_" + locale.getLanguage() + "_" + locale.getCountry() + "_" + locale.getVariant()); } results.add(baseName + "_" + locale.getLanguage() + "_" + locale.getCountry()); } results.add(baseName + "_" + locale.getLanguage()); } results.add(baseName); return results; } }