blob: 8ae0dde403cdbe63ba9281c1cfcec443615418a5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.metatype.impl;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import org.osgi.framework.Bundle;
public abstract class LocalizationElement {
public static final char KEY_SIGN = '%';
public static final char LOCALE_SEP = '_';
/*
* Internal Method - to get resource bundle.
*/
private static ResourceBundle getResourceBundle(String resourceBase, String locale, Bundle bundle) {
// There are seven searching candidates possible:
// baseName +
// "_" + language1 + "_" + country1 + "_" + variation1 + ".properties"
// or "_" + language1 + "_" + country1 + ".properties"
// or "_" + language1 + ".properties"
// or "_" + language2 + "_" + country2 + "_" + variation2 + ".properties"
// or "_" + language2 + "_" + country2 + ".properties"
// or "_" + language2 + ".properties"
// or "" + ".properties"
//
// Where language1[_country1[_variation1]] is the requested locale,
// and language2[_country2[_variation2]] is the default locale.
String[] searchCandidates = new String[7];
// Candidates from passed locale:
if (locale != null && locale.length() > 0) {
int idx1_first = locale.indexOf(LOCALE_SEP);
if (idx1_first == -1) {
// locale has only language.
searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
} else {
// locale has at least language and country.
searchCandidates[2] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_first);
int idx1_second = locale.indexOf(LOCALE_SEP, idx1_first + 1);
if (idx1_second == -1) {
// locale just has both language and country.
searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
} else {
// locale has language, country, and variation all.
searchCandidates[1] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale.substring(0, idx1_second);
searchCandidates[0] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + locale;
}
}
}
// Candidates from Locale.getDefault():
String defaultLocale = Locale.getDefault().toString();
int idx2_first = defaultLocale.indexOf(LOCALE_SEP);
int idx2_second = defaultLocale.indexOf(LOCALE_SEP, idx2_first + 1);
if (idx2_second != -1) {
// default-locale is format of [language]_[country]_variation.
searchCandidates[3] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale;
if (searchCandidates[3].equalsIgnoreCase(searchCandidates[0])) {
searchCandidates[3] = null;
}
}
if ((idx2_first != -1) && (idx2_second != idx2_first + 1)) {
// default-locale is format of [language]_country[_variation].
searchCandidates[4] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + ((idx2_second == -1) ? defaultLocale : defaultLocale.substring(0, idx2_second));
if (searchCandidates[4].equalsIgnoreCase(searchCandidates[1])) {
searchCandidates[4] = null;
}
}
if ((idx2_first == -1) && (defaultLocale.length() > 0)) {
// default-locale has only language.
searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale;
} else if (idx2_first > 0) {
// default-locale is format of language_[...].
searchCandidates[5] = MetaTypeProviderImpl.RESOURCE_FILE_CONN + defaultLocale.substring(0, idx2_first);
}
if (searchCandidates[5] != null && searchCandidates[5].equalsIgnoreCase(searchCandidates[2])) {
searchCandidates[5] = null;
}
// The final candidate.
searchCandidates[6] = ""; //$NON-NLS-1$
URL resourceUrl = null;
URL[] urls = null;
for (int idx = 0; (idx < searchCandidates.length) && (resourceUrl == null); idx++) {
urls = (searchCandidates[idx] == null ? null : FragmentUtils.findEntries(bundle, resourceBase + searchCandidates[idx] + MetaTypeProviderImpl.RESOURCE_FILE_EXT));
if (urls != null && urls.length > 0)
resourceUrl = urls[0];
}
if (resourceUrl != null) {
try {
return new PropertyResourceBundle(resourceUrl.openStream());
} catch (IOException ioe) {
// Exception when creating PropertyResourceBundle object.
}
}
return null;
}
private final String localization;
// @GuardedBy("this")
private Bundle bundle;
// @GuardedBy("this")
private String locale;
// @GuardedBy("this")
private Map<String, ResourceBundle> resourceBundleCache;
public LocalizationElement(String localization) {
this.localization = localization;
}
String getLocalization() {
return localization;
}
/**
* Method to get the localized text of inputed String.
*/
protected String getLocalized(String key) {
if (key == null) {
return null;
}
if ((key.length() > 1) && (key.charAt(0) == KEY_SIGN)) {
ResourceBundle rb = getResourceBundle();
if (rb != null) {
try {
String transfered = rb.getString(key.substring(1));
if (transfered != null) {
return transfered;
}
} catch (MissingResourceException mre) {
// Nothing found for this key.
}
}
// If no localization file available or no localized value found
// for the key, then return the raw data without the key-sign.
return key.substring(1);
}
return key;
}
/*
* This method must be (and currently is) called after setLocaleAndBundle(String, Bundle).
* If the bundle is not set, an NPE will be generated by getResourceBundle(String, String, Bundle).
*/
protected synchronized ResourceBundle getResourceBundle() {
// Determine the base name of the bundle localization property files.
// If the <MetaData> 'localization' attribute was not specified,
// use the Bundle-Localization manifest header value instead if it exists.
String resourceBase = localization != null ? localization : MetaTypeProviderImpl.getBundleLocalization(bundle);
long bundleId = bundle.getBundleId();
String key = (locale != null) ? bundleId + ":" + locale + ":" + resourceBase : bundleId + ":" + resourceBase; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
ResourceBundle resourceBundle = resourceBundleCache.get(key);
if (resourceBundle == null) {
resourceBundle = getResourceBundle(resourceBase, locale, bundle);
if (resourceBundle != null) {
resourceBundleCache.put(key, resourceBundle);
}
}
return resourceBundle;
}
/*
* This method must be (and currently is) called before getResourceBundle().
* If the bundle is not set, an NPE will be generated by getResourceBundle(String, String, Bundle).
*/
protected synchronized void setLocaleAndBundle(String locale, Bundle bundle, Map<String, ResourceBundle> resourceBundleCache) {
this.locale = locale;
this.bundle = bundle;
this.resourceBundleCache = resourceBundleCache;
}
}