/*******************************************************************************
 * 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:
	 * </p>
	 * <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>
	 *
	 * @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().isEmpty()) {
				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.isEmpty()) {
					// 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:
	 * </p>
	 * <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>
	 * <p>
	 * 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:
	 * </p>
	 * <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.
	 * </p>
	 *
	 * @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.isEmpty() && 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:
	 * </p>
	 * <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>
	 * <p>
	 * 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:
	 * </p>
	 * <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.
	 * </p>
	 *
	 * @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:
	 * </p>
	 * <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>
	 * <p>
	 * 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:
	 * </p>
	 * <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.
	 * </p>
	 *
	 * @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.isEmpty() && 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].isEmpty())) {
			logInvalidFormat(localeString, logger);
			return defaultLocale;
		}

		if (!localeParts[0].isEmpty() && !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].isEmpty() && !localeParts[1].matches("[a-zA-Z]{2}|[0-9]{3}")) { //$NON-NLS-1$
				if (!language.isEmpty()) {
					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].isEmpty()) {
				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((PrivilegedExceptionAction<InputStream>) () -> {
								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;
		}
	}
}
