/*******************************************************************************
 * Copyright (c) 2012, 2018 Dirk Fauth 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:
 *     Dirk Fauth <dirk.fauth@gmail.com> - initial API and implementation
 ******************************************************************************/
package org.eclipse.e4.core.internal.services;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.ResourceBundle.Control;
import org.eclipse.e4.core.services.translation.ResourceBundleProvider;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogService;
import org.osgi.service.log.Logger;
import org.osgi.service.log.LoggerFactory;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

/**
 * Helper class for retrieving {@link ResourceBundle}s out of OSGi {@link Bundle}s.
 */
public class ResourceBundleHelper {

	/**
	 * The schema identifier used for Eclipse platform references
	 */
	private static final String PLATFORM_SCHEMA = "platform"; //$NON-NLS-1$
	/**
	 * The schema identifier used for Eclipse bundle class references
	 */
	private static final String BUNDLECLASS_SCHEMA = "bundleclass"; //$NON-NLS-1$
	/**
	 * Identifier part of the Eclipse platform schema to point to a plugin
	 */
	private static final String PLUGIN_SEGMENT = "/plugin/"; //$NON-NLS-1$
	/**
	 * Identifier part of the Eclipse platform schema to point to a fragment
	 */
	private static final String FRAGMENT_SEGMENT = "/fragment/"; //$NON-NLS-1$
	/**
	 * The separator character for paths in the platform schema
	 */
	private static final String PATH_SEPARATOR = "/"; //$NON-NLS-1$

	private static final ServiceTracker<LogService, LogService> logTracker = openLogTracker();

	private static ServiceTracker<LogService, LogService> openLogTracker() {
		try {
			ServiceTracker<LogService, LogService> st = new ServiceTracker<>(
					FrameworkUtil.getBundle(ResourceBundleHelper.class).getBundleContext(), LogService.class, null);
			st.open();
			return st;
		} catch (Throwable t) {
			return null;
		}
	}

	private static ServiceTracker<LoggerFactory, Logger> loggerTracker = openLoggerTracker();

	private static ServiceTracker<LoggerFactory, Logger> openLoggerTracker() {
		try {
			BundleContext context = FrameworkUtil.getBundle(ResourceBundleHelper.class).getBundleContext();
			ServiceTracker<LoggerFactory, Logger> tracker = new ServiceTracker<>(
					context, LoggerFactory.class,
					new ServiceTrackerCustomizer<LoggerFactory, Logger>() {

						@Override
						public Logger addingService(ServiceReference<LoggerFactory> reference) {
							LoggerFactory factory = context.getService(reference);
							if (factory != null) {
								return factory.getLogger(ResourceBundleHelper.class);
							}
							return null;
						}

						@Override
						public void modifiedService(ServiceReference<LoggerFactory> reference, Logger service) {
						}

						@Override
						public void removedService(ServiceReference<LoggerFactory> reference, Logger service) {
							context.ungetService(reference);
						}
					});
			tracker.open();
			return tracker;
		} catch (Throwable t) {
			return null;
		}
	}

	/**
	 * Parses the specified contribution URI and loads the {@link ResourceBundle} for the specified
	 * {@link Locale} out of an OSGi {@link Bundle}.
	 * <p>
	 * Following URIs are supported:
	 * <ul>
	 * <li>platform:/[plugin|fragment]/[Bundle-SymbolicName]<br>
	 * Load the OSGi resource bundle out of the bundle/fragment named [Bundle-SymbolicName]</li>
	 * <li>platform:/[plugin|fragment]/[Bundle-SymbolicName]/[Path]/[Basename]<br>
	 * Load the resource bundle specified by [Path] and [Basename] out of the bundle/fragment named
	 * [Bundle-SymbolicName].</li>
	 * <li>bundleclass://[plugin|fragment]/[Full-Qualified-Classname]<br>
	 * Instantiate the class specified by [Full-Qualified-Classname] out of the bundle/fragment
	 * named [Bundle-SymbolicName]. Note that the class needs to be a subtype of
	 * {@link ResourceBundle}.</li>
	 * </ul>
	 * </p>
	 *
	 * @param contributionURI
	 *            The URI that points to a {@link ResourceBundle}
	 * @param locale
	 *            The {@link Locale} to use for loading the {@link ResourceBundle}
	 * @param provider
	 *            The service for retrieving a {@link ResourceBundle} for a given {@link Locale} out
	 *            of the given {@link Bundle} which is specified by URI.
	 * @return
	 */
	public static ResourceBundle getResourceBundleForUri(String contributionURI, Locale locale,
			ResourceBundleProvider provider) {
		if (contributionURI == null)
			return null;

		Logger logger = loggerTracker.getService();

		URI uri;
		try {
			uri = new URI(contributionURI);
		} catch (URISyntaxException e) {
			if (logger != null) {
				logger.error("Invalid contribution URI: {}", contributionURI); //$NON-NLS-1$
			}
			return null;
		}

		String bundleName = null;
		Bundle bundle = null;
		String resourcePath = null;
		String classPath = null;

		// the uri follows the platform schema, so we search for .properties files in the bundle
		if (PLATFORM_SCHEMA.equals(uri.getScheme())) {
			bundleName = uri.getPath();
			if (bundleName.startsWith(PLUGIN_SEGMENT))
				bundleName = bundleName.substring(PLUGIN_SEGMENT.length());
			else if (bundleName.startsWith(FRAGMENT_SEGMENT))
				bundleName = bundleName.substring(FRAGMENT_SEGMENT.length());

			resourcePath = ""; //$NON-NLS-1$
			if (bundleName.contains(PATH_SEPARATOR)) {
				resourcePath = bundleName.substring(bundleName.indexOf(PATH_SEPARATOR) + 1);
				bundleName = bundleName.substring(0, bundleName.indexOf(PATH_SEPARATOR));
			}
		} else if (BUNDLECLASS_SCHEMA.equals(uri.getScheme())) {
			if (uri.getAuthority() == null) {
				if (logger != null) {
					logger.error("Failed to get bundle for: {}", contributionURI); //$NON-NLS-1$
				}
			}
			bundleName = uri.getAuthority();
			// remove the leading /
			if (uri.getPath() != null && uri.getPath().length() > 0) {
				classPath = uri.getPath().substring(1);
			} else {
				if (logger != null) {
					logger.error("Called with invalid contribution URI: {}", contributionURI); //$NON-NLS-1$
				}
			}
		}

		ResourceBundle result = null;

		if (bundleName != null) {
			bundle = getBundleForName(bundleName);

			if (bundle != null) {
				if (resourcePath == null && classPath != null) {
					// the URI points to a class within the bundle classpath
					// therefore we are trying to instantiate the class
					try {
						Class<?> resourceBundleClass = bundle.loadClass(classPath);
						result = getEquinoxResourceBundle(classPath, locale,
								resourceBundleClass.getClassLoader());
					} catch (Exception e) {
						if (logger != null) {
							logger.error("Failed to load specified ResourceBundle: {}", contributionURI, e); //$NON-NLS-1$
						}
					}
				} else if (resourcePath != null && resourcePath.length() > 0) {
					// the specified URI points to a resource
					// therefore we try to load the .properties files into a ResourceBundle
					result = getEquinoxResourceBundle(resourcePath.replace('.', '/'), locale,
							bundle);
				} else {
					// There is no class and no special resource specified within the URI
					// therefore we load the OSresource bundle out of the specified Bundle
					// for the current Locale. Typically this will be the OSGi ResourceBundle
					result = provider.getResourceBundle(bundle, locale.toString());
				}
			}
		}

		return result;
	}

	/**
	 * This method searches for the {@link ResourceBundle} in a modified way by inspecting the
	 * configuration option <code>equinox.root.locale</code>.
	 * <p>
	 * If the value for this system property is set to an empty String the default search order for
	 * ResourceBundles is used:
	 * <ul>
	 * <li>bn + Ls + "_" + Cs + "_" + Vs</li>
	 * <li>bn + Ls + "_" + Cs</li>
	 * <li>bn + Ls</li>
	 * <li>bn + Ld + "_" + Cd + "_" + Vd</li>
	 * <li>bn + Ld + "_" + Cd</li>
	 * <li>bn + Ld</li>
	 * <li>bn</li>
	 * </ul>
	 * Where bn is this bundle's localization basename, Ls, Cs and Vs are the specified locale
	 * (language, country, variant) and Ld, Cd and Vd are the default locale (language, country,
	 * variant).
	 * </p>
	 * <p>
	 * If Ls equals the value of <code>equinox.root.locale</code> then the following search order is
	 * used:
	 * <ul>
	 * <li>bn + Ls + "_" + Cs + "_" + Vs</li>
	 * <li>bn + Ls + "_" + Cs</li>
	 * <li>bn + Ls</li>
	 * <li>bn</li>
	 * <li>bn + Ld + "_" + Cd + "_" + Vd</li>
	 * <li>bn + Ld + "_" + Cd</li>
	 * <li>bn + Ld</li>
	 * <li>bn</li>
	 * </ul>
	 * </p>
	 * If <code>equinox.root.locale=en</code> and en_XX or en is asked for then this allows the root
	 * file to be used instead of falling back to the default locale.
	 *
	 * @param baseName
	 *            the base name of the resource bundle, a fully qualified class name
	 * @param locale
	 *            the locale for which a resource bundle is desired
	 * @param loader
	 *            the class loader from which to load the resource bundle
	 * @return a resource bundle for the given base name and locale
	 *
	 * @see ResourceBundle#getBundle(String, Locale, ClassLoader)
	 */
	public static ResourceBundle getEquinoxResourceBundle(String baseName, Locale locale,
			ClassLoader loader) {
		ResourceBundle resourceBundle = null;

		String equinoxLocale = getEquinoxRootLocale();
		// if the equinox.root.locale is not empty and the specified locale equals the
		// equinox.root.locale
		// -> use the special search order
		if (equinoxLocale.length() > 0 && locale.toString().startsWith(equinoxLocale)) {
			// there is a equinox.root.locale configured that matches the specified locale
			// so the special search order is used
			// to achieve this we first search without a fallback to the default locale
			try {
				resourceBundle = ResourceBundle.getBundle(baseName, locale, loader,
						ResourceBundle.Control.getNoFallbackControl(Control.FORMAT_DEFAULT));
			} catch (MissingResourceException e) {
				// do nothing
			}
			// if there is no ResourceBundle found for that path, we will now search for the default
			// locale ResourceBundle
			if (resourceBundle == null) {
				try {
					resourceBundle = ResourceBundle.getBundle(baseName, Locale.getDefault(),
							loader,
							ResourceBundle.Control.getNoFallbackControl(Control.FORMAT_DEFAULT));
				} catch (MissingResourceException e) {
					// do nothing
				}
			}
		} else {
			// there is either no equinox.root.locale configured or it does not match the specified
			// locale
			// -> use the default search order
			try {
				resourceBundle = ResourceBundle.getBundle(baseName, locale, loader);
			} catch (MissingResourceException e) {
				// do nothing
			}
		}

		return resourceBundle;
	}

	/**
	 * This method searches for the {@link ResourceBundle} in a modified way by inspecting the
	 * configuration option <code>equinox.root.locale</code>. It uses the
	 * {@link BundleResourceBundleControl} to load the resources out of a {@link Bundle}.
	 * <p>
	 * <b>Note: This method will only search for ResourceBundles based on properties files.</b>
	 * </p>
	 * <p>
	 * If the value for this system property is set to an empty String the default search order for
	 * ResourceBundles is used:
	 * <ul>
	 * <li>bn + Ls + "_" + Cs + "_" + Vs</li>
	 * <li>bn + Ls + "_" + Cs</li>
	 * <li>bn + Ls</li>
	 * <li>bn + Ld + "_" + Cd + "_" + Vd</li>
	 * <li>bn + Ld + "_" + Cd</li>
	 * <li>bn + Ld</li>
	 * <li>bn</li>
	 * </ul>
	 * Where bn is this bundle's localization basename, Ls, Cs and Vs are the specified locale
	 * (language, country, variant) and Ld, Cd and Vd are the default locale (language, country,
	 * variant).
	 * </p>
	 * <p>
	 * If Ls equals the value of <code>equinox.root.locale</code> then the following search order is
	 * used:
	 * <ul>
	 * <li>bn + Ls + "_" + Cs + "_" + Vs</li>
	 * <li>bn + Ls + "_" + Cs</li>
	 * <li>bn + Ls</li>
	 * <li>bn</li>
	 * <li>bn + Ld + "_" + Cd + "_" + Vd</li>
	 * <li>bn + Ld + "_" + Cd</li>
	 * <li>bn + Ld</li>
	 * <li>bn</li>
	 * </ul>
	 * </p>
	 * If <code>equinox.root.locale=en</code> and en_XX or en is asked for then this allows the root
	 * file to be used instead of falling back to the default locale.
	 *
	 * @param baseName
	 *            the base name of the resource bundle, a fully qualified class name
	 * @param locale
	 *            the locale for which a resource bundle is desired
	 * @param bundle
	 *            The OSGi {@link Bundle} to lookup the {@link ResourceBundle}
	 * @return a resource bundle for the given base name and locale
	 *
	 * @see ResourceBundle#getBundle(String, Locale, Control)
	 */
	public static ResourceBundle getEquinoxResourceBundle(String baseName, Locale locale,
			Bundle bundle) {
		return getEquinoxResourceBundle(baseName, locale, new BundleResourceBundleControl(bundle,
				true), new BundleResourceBundleControl(bundle, false));
	}

	/**
	 * This method searches for the {@link ResourceBundle} in a modified way by inspecting the
	 * configuration option <code>equinox.root.locale</code>.
	 * <p>
	 * <b>Note: This method will only search for ResourceBundles based on properties files.</b>
	 * </p>
	 * <p>
	 * If the value for this system property is set to an empty String the default search order for
	 * ResourceBundles is used:
	 * <ul>
	 * <li>bn + Ls + "_" + Cs + "_" + Vs</li>
	 * <li>bn + Ls + "_" + Cs</li>
	 * <li>bn + Ls</li>
	 * <li>bn + Ld + "_" + Cd + "_" + Vd</li>
	 * <li>bn + Ld + "_" + Cd</li>
	 * <li>bn + Ld</li>
	 * <li>bn</li>
	 * </ul>
	 * Where bn is this bundle's localization basename, Ls, Cs and Vs are the specified locale
	 * (language, country, variant) and Ld, Cd and Vd are the default locale (language, country,
	 * variant).
	 * </p>
	 * <p>
	 * If Ls equals the value of <code>equinox.root.locale</code> then the following search order is
	 * used:
	 * <ul>
	 * <li>bn + Ls + "_" + Cs + "_" + Vs</li>
	 * <li>bn + Ls + "_" + Cs</li>
	 * <li>bn + Ls</li>
	 * <li>bn</li>
	 * <li>bn + Ld + "_" + Cd + "_" + Vd</li>
	 * <li>bn + Ld + "_" + Cd</li>
	 * <li>bn + Ld</li>
	 * <li>bn</li>
	 * </ul>
	 * </p>
	 * If <code>equinox.root.locale=en</code> and en_XX or en is asked for then this allows the root
	 * file to be used instead of falling back to the default locale.
	 *
	 * @param baseName
	 *            the base name of the resource bundle, a fully qualified class name
	 * @param locale
	 *            the locale for which a resource bundle is desired
	 * @param withFallback
	 *            The {@link Control} that uses the default locale fallback on searching for
	 *            resource bundles.
	 * @param withoutFallback
	 *            The {@link Control} that doesn't use the default locale fallback on searching for
	 *            resource bundles.
	 * @return a resource bundle for the given base name and locale
	 *
	 * @see ResourceBundle#getBundle(String, Locale, Control)
	 */
	public static ResourceBundle getEquinoxResourceBundle(String baseName, Locale locale,
			Control withFallback, Control withoutFallback) {
		ResourceBundle resourceBundle = null;

		String equinoxLocale = getEquinoxRootLocale();
		// if the equinox.root.locale is not empty and the specified locale equals the
		// equinox.root.locale
		// -> use the special search order
		if (equinoxLocale.length() > 0 && locale.toString().startsWith(equinoxLocale)) {
			// there is a equinox.root.locale configured that matches the specified locale
			// so the special search order is used
			// to achieve this we first search without a fallback to the default locale
			try {
				resourceBundle = ResourceBundle.getBundle(baseName, locale, withoutFallback);
			} catch (MissingResourceException e) {
				// do nothing
			}
			// if there is no ResourceBundle found for that path, we will now search for the default
			// locale ResourceBundle
			if (resourceBundle == null) {
				try {
					resourceBundle = ResourceBundle.getBundle(baseName, Locale.getDefault(),
							withoutFallback);
				} catch (MissingResourceException e) {
					// do nothing
				}
			}
		} else {
			// there is either no equinox.root.locale configured or it does not match the specified
			// locale
			// -> use the default search order
			try {
				resourceBundle = ResourceBundle.getBundle(baseName, locale, withFallback);
			} catch (MissingResourceException e) {
				// do nothing
			}
		}

		return resourceBundle;
	}

	/**
	 * @return The value for the system property for key <code>equinox.root.locale</code>. If none
	 *         is specified than <b>en</b> will be returned as default.
	 */
	private static String getEquinoxRootLocale() {
		// Logic from FrameworkProperties.getProperty("equinox.root.locale", "en")
		String root = System.getProperties().getProperty("equinox.root.locale"); //$NON-NLS-1$
		if (root == null) {
			root = "en"; //$NON-NLS-1$
		}
		return root;
	}

	/**
	 * This method is copied out of org.eclipse.e4.ui.internal.workbench.Activator because as it is
	 * a internal resource, it is not accessible for us.
	 *
	 * @param bundleName
	 *            the bundle id
	 * @return A bundle if found, or <code>null</code>
	 */
	public static Bundle getBundleForName(String bundleName) {
		if (bundleName == null) {
			return null;
		}
		Bundle bundle = FrameworkUtil.getBundle(ResourceBundleHelper.class);
		BundleContext context = bundle == null ? null : bundle.getBundleContext();

		Bundle[] bundles = context.getBundles();
		if (bundles == null) {
			return null;
		}
		// Return the first bundle that is not installed or uninstalled
		for (Bundle localBundle : bundles) {
			if (bundleName.equals(localBundle.getSymbolicName())
					&& (localBundle.getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
				return localBundle;
			}
		}
		return null;
	}

	/**
	 * <p>
	 * Converts a String to a Locale.
	 * </p>
	 *
	 * <p>
	 * This method takes the string format of a locale and creates the locale object from it.
	 * </p>
	 *
	 * <pre>
	 *   MessageFactoryServiceImpl.toLocale("en")         = new Locale("en", "")
	 *   MessageFactoryServiceImpl.toLocale("en_GB")      = new Locale("en", "GB")
	 *   MessageFactoryServiceImpl.toLocale("en_GB_xxx")  = new Locale("en", "GB", "xxx")
	 * </pre>
	 *
	 * <p>
	 * This method validates the input strictly. The language code must be lowercase. The country
	 * code must be uppercase. The separator must be an underscore. The length must be correct.
	 * </p>
	 *
	 * <p>
	 * This method is inspired by <code>org.apache.commons.lang.LocaleUtils.toLocale(String)</code>
	 * by fixing the parsing error for uncommon Locales like having a language and a variant code
	 * but no country code, or a Locale that only consists of a country code.
	 * </p>
	 *
	 * @param str
	 *            the locale String to convert
	 * @return a Locale that matches the specified locale String. If the given input String is
	 *         <code>null</code> or can not be parsed because of an invalid format,
	 *         {@link Locale#getDefault()} will be returned.
	 */
	public static Locale toLocale(String str) {
		return toLocale(str, Locale.getDefault());
	}

	/**
	 * <p>
	 * Converts a String to a Locale.
	 * </p>
	 *
	 * <p>
	 * This method takes the string format of a locale and creates the locale object from it.
	 * </p>
	 *
	 * <pre>
	 *   MessageFactoryServiceImpl.toLocale("en")         = new Locale("en", "")
	 *   MessageFactoryServiceImpl.toLocale("en_GB")      = new Locale("en", "GB")
	 *   MessageFactoryServiceImpl.toLocale("en_GB_xxx")  = new Locale("en", "GB", "xxx")
	 * </pre>
	 *
	 * <p>
	 * This method validates the input strictly. The language code must be lowercase. The country
	 * code must be uppercase. The separator must be an underscore. The length must be correct.
	 * </p>
	 *
	 * <p>
	 * This method is inspired by <code>org.apache.commons.lang.LocaleUtils.toLocale(String)</code>
	 * by fixing the parsing error for uncommon Locales like having a language and a variant code
	 * but no country code, or a Locale that only consists of a country code.
	 * </p>
	 *
	 * <p>
	 * <b>Note:</b> This is the same logic as used in <code>EquinoxConfiguration.toLocale()</code>
	 * </p>
	 *
	 * @param localeString
	 *            the locale String to convert
	 * @param defaultLocale
	 *            the Locale that should be returned in case of an invalid Locale String
	 * @return a Locale that matches the specified locale String. If the given input String is
	 *         <code>null</code> or can not be parsed because of an invalid format, the given
	 *         default {@link Locale} will be returned.
	 */
	public static Locale toLocale(String localeString, Locale defaultLocale) {
		Logger logger = loggerTracker.getService();

		if (localeString == null) {
			if (logger != null) {
				logger.error("Given locale String is null - Default Locale will be used instead."); //$NON-NLS-1$
			}
			return defaultLocale;
		}

		String language = ""; //$NON-NLS-1$
		String country = ""; //$NON-NLS-1$
		String variant = ""; //$NON-NLS-1$

		String[] localeParts = localeString.split("_"); //$NON-NLS-1$
		if (localeParts.length == 0 || localeParts.length > 3
				|| (localeParts.length == 1 && localeParts[0].length() == 0)) {
			logInvalidFormat(localeString, logger);
			return defaultLocale;
		}

		if (localeParts[0].length() > 0 && !localeParts[0].matches("[a-zA-Z]{2,8}")) { //$NON-NLS-1$
			logInvalidFormat(localeString, logger);
			return defaultLocale;
		}

		language = localeParts[0];

		if (localeParts.length > 1) {
			if (localeParts[1].length() > 0 && !localeParts[1].matches("[a-zA-Z]{2}|[0-9]{3}")) { //$NON-NLS-1$
				if (language.length() > 0) {
					if (logger != null) {
						logger.error(
								"Invalid locale format: {} - Only language part will be used to create the Locale.", //$NON-NLS-1$
								localeString);
					}
					return new Locale(language);
				}
				logInvalidFormat(localeString, logger);
				return defaultLocale;
			}

			country = localeParts[1];
		}

		if (localeParts.length == 3) {
			if (localeParts[2].length() == 0) {
				if (logger != null) {
					logger.error(
							"Invalid locale format: {} - Only language and country part will be used to create the Locale.", //$NON-NLS-1$
							localeString);
				}
				return new Locale(language, country);
			}
			variant = localeParts[2];
		}

		return new Locale(language, country, variant);
	}

	private static HashSet<String> invalidLocalesLogged = new HashSet<>();

	static void logInvalidFormat(String str, Logger log) {
		if (log != null && !invalidLocalesLogged.contains(str)) {
			invalidLocalesLogged.add(str);
			log.error("Invalid locale format: {} - Default Locale will be used instead.", str); //$NON-NLS-1$
		}
	}

	@Deprecated
	public static LogService getLogService() {
		return logTracker.getService();
	}

	/**
	 * Specialization of {@link Control} which loads the {@link ResourceBundle} out of an OSGi
	 * {@link Bundle} instead of using a classloader.
	 *
	 * <p>
	 * It only supports properties based {@link ResourceBundle}s. If you want to use source based
	 * {@link ResourceBundle}s you have to use the bundleclass URI with the Message annotation.
	 */
	static class BundleResourceBundleControl extends ResourceBundle.Control {

		/**
		 * Flag to determine whether the default locale should be used as fallback locale in case
		 * there is no {@link ResourceBundle} found for the specified locale.
		 */
		private final boolean useFallback;

		/**
		 * The OSGi {@link Bundle} to lookup the {@link ResourceBundle}
		 */
		private final Bundle osgiBundle;

		/**
		 *
		 * @param osgiBundle
		 *            The OSGi {@link Bundle} to lookup the {@link ResourceBundle}
		 * @param useFallback
		 *            <code>true</code> if the default locale should be used as fallback locale in
		 *            the search path or <code>false</code> if there should be no fallback.
		 */
		public BundleResourceBundleControl(Bundle osgiBundle, boolean useFallback) {
			this.osgiBundle = osgiBundle;
			this.useFallback = useFallback;
		}

		@Override
		public ResourceBundle newBundle(String baseName, Locale locale, String format,
				ClassLoader loader, boolean reload) throws IllegalAccessException,
				InstantiationException, IOException {

			String bundleName = toBundleName(baseName, locale);
			ResourceBundle bundle = null;
			if (format.equals("java.properties")) { //$NON-NLS-1$
				final String resourceName = toResourceName(bundleName, "properties"); //$NON-NLS-1$
				InputStream stream = null;
				try {
					stream = AccessController
							.doPrivileged(new PrivilegedExceptionAction<InputStream>() {
								@Override
								public InputStream run() throws IOException {
									InputStream is = null;
									URL url = osgiBundle.getEntry(resourceName);
									if (url != null) {
										URLConnection connection = url.openConnection();
										if (connection != null) {
											// Disable caches to get fresh data for
											// reloading.
											connection.setUseCaches(false);
											is = connection.getInputStream();
										}
									}
									return is;
								}
							});
				} catch (PrivilegedActionException e) {
					throw (IOException) e.getException();
				}
				if (stream != null) {
					try {
						bundle = new PropertyResourceBundle(stream);
					} finally {
						stream.close();
					}
				}
			} else {
				throw new IllegalArgumentException("unknown format: " + format); //$NON-NLS-1$
			}
			return bundle;
		}

		@Override
		public List<String> getFormats(String baseName) {
			return FORMAT_PROPERTIES;
		}

		@Override
		public Locale getFallbackLocale(String baseName, Locale locale) {
			return this.useFallback ? super.getFallbackLocale(baseName, locale) : null;
		}
	}
}
