All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.liveSense.server.i18n.service.I18nService.I18nServiceImpl Maven / Gradle / Ivy

The newest version!
package org.liveSense.server.i18n.service.I18nService;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang.LocaleUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.i18n.ResourceBundleProvider;
import org.liveSense.core.BundleProxyClassLoader;
import org.liveSense.core.service.OSGIClassLoaderManager;
import org.liveSense.server.i18n.CompositeProxyResourceBundle;
import org.liveSense.server.i18n.I18N;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(immediate=true)
@Service
public class I18nServiceImpl implements I18nService {

	Logger log = LoggerFactory.getLogger(I18nServiceImpl.class);

	@Reference(cardinality=ReferenceCardinality.MANDATORY_UNARY, policy=ReferencePolicy.DYNAMIC)
	private OSGIClassLoaderManager dynamicClassLoaderManager;

	@Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC)
	ResourceBundleProvider slingI18nService;

	BundleContext context = null;
	ClassLoader classLoader = I18nServiceImpl.class.getClassLoader();
	
	Map bundleResourceCaches = new ConcurrentHashMap();
	
	private ClassLoader getClassLoader(String resourceName, ClassLoader classLoader) {
//		if (classLoader != null) {
//			return classLoader;
//		} else {
//			if (bundleResourceCaches.containsKey(resourceName)) {
//				return bundleResourceCaches.get(resourceName);
//			}
		return this.classLoader;
	}
	
	@Activate
	protected void activate(BundleContext context) {
		I18N.resetCache();
		this.context = context;
		this.classLoader = dynamicClassLoaderManager.getPackageAdminClassLoader(context);
	}

	@Override
	public  T create(Class itf) throws IOException {
		return I18N.create(itf, (Locale)null, getClassLoader(itf.getName(), null), getResourceBundleInternal(itf.getName(), getLocale(null), getClassLoader(itf.getName(), null)));
	}

	@Override
	public  T create(Class itf, Locale locale) throws IOException {
		return I18N.create(itf, locale, getClassLoader(itf.getName(), null), getResourceBundleInternal(itf.getName(), getLocale(locale), getClassLoader(itf.getName(), null)));
	}

	@Override
	public  T create(Class itf, Locale locale, ClassLoader classLoader) throws IOException {
		return I18N.create(itf, locale, classLoader, getResourceBundleInternal(itf.getName(), getLocale(locale), getClassLoader(itf.getName(), classLoader)));
	}

	@Override
	public  T create(Class itf, String lang) throws IOException {
		return I18N.create(itf, lang, getResourceBundleInternal(itf.getName(), getLocale(LocaleUtils.toLocale(lang)), getClassLoader(itf.getName(), null)));
	}

	@Override
	public  T create(Class itf, String lang, ClassLoader classLoader) throws IOException {
		return I18N.create(itf, lang, classLoader, getResourceBundleInternal(itf.getName(), getLocale(LocaleUtils.toLocale(lang)), getClassLoader(itf.getName(), classLoader)));
	}


	private Locale getLocale(Locale locale) {
		if (locale != null) {
			return locale;
		} else 
			return Locale.getDefault();
	}

	@SuppressWarnings("unchecked")
	private  T getClassByName(String className, ClassLoader classLoader) throws ClassNotFoundException, ClassCastException {
		Object ret = null;
		if (classLoader != null) {
			try {
				ret = classLoader.loadClass(className);
			} catch (ClassNotFoundException e) {
			}
		}
		if (ret == null) {
			try {
				ret = getClassLoader(className, null).loadClass(className);
			} catch (ClassNotFoundException e) {
				throw new ClassNotFoundException("Class not found: "+className+" (liveSense I18N Service)");
			}
		}
		return (T)ret;
	}

	private  T getClassByName(String className) throws ClassNotFoundException {
		return getClassByName(className, null);
	}

	@Override
	public Object create(String className) throws IOException, ClassNotFoundException {
		return I18N.create((Class) getClassByName(className), getResourceBundleInternal(className, getLocale(null), getClassLoader(className, null)));
	}

	@Override
	public Object create(String className, Locale locale) throws IOException, ClassNotFoundException {
		return I18N.create((Class)getClassByName(className), locale, getResourceBundleInternal(className, getLocale(locale), getClassLoader(className, null)));
	}

	@Override
	public Object create(String className, Locale locale, ClassLoader classLoader) throws IOException, ClassNotFoundException {
		return I18N.create((Class)getClassByName(className, classLoader), locale, getClassLoader(className, classLoader), getResourceBundleInternal(className, getLocale(locale), getClassLoader(className, classLoader)));
	}

	@Override
	public Object create(String className, String lang) throws IOException, ClassNotFoundException {
		return I18N.create((Class)getClassByName(className), lang, getResourceBundleInternal(className, getLocale(LocaleUtils.toLocale(lang)), getClassLoader(className, null)));
	}

	@Override
	public Object create(String className, String lang, ClassLoader classLoader) throws IOException, ClassNotFoundException {
		return I18N.create((Class)getClassByName(className, classLoader), lang, getClassLoader(className, classLoader), getResourceBundleInternal(className, getLocale(LocaleUtils.toLocale(lang)), getClassLoader(className, classLoader)));				
	}

	private ResourceBundle getResourceBundleInternal(String className, Locale locale, ClassLoader classLoader) {
		if (slingI18nService != null) {
			return slingI18nService.getResourceBundle(className, locale);
		} else {
			return ResourceBundle.getBundle(className.replaceAll("\\.", "/"), locale, classLoader);
		}
	}
	
	// Resource Bundle specific
	@Override
	public ResourceBundle getResourceBundle(String className) throws IOException, ClassNotFoundException {
		return getResourceBundleInternal(className, getLocale(null), getClassLoader(className, null));
	}

	@Override
	public ResourceBundle getResourceBundle(String className, Locale locale) throws IOException, ClassNotFoundException {
		return getResourceBundleInternal(className, getLocale(locale), getClassLoader(className, null));
	}

	@Override
	public ResourceBundle getResourceBundle(String className, Locale locale, ClassLoader classLoader)
			throws IOException, ClassNotFoundException {
		return getResourceBundleInternal(className, getLocale(locale), getClassLoader(className, classLoader));
	}

	@Override
	public ResourceBundle getResourceBundle(String className, String lang) throws IOException, ClassNotFoundException {
		return getResourceBundleInternal(className, getLocale(I18N.createLocaleFromLang(lang)), getClassLoader(className, null));
	}

	@Override
	public ResourceBundle getResourceBundle(String className, String lang, ClassLoader classLoader) throws IOException,
	ClassNotFoundException {
		return getResourceBundleInternal(className, getLocale(I18N.createLocaleFromLang(lang)), getClassLoader(className, classLoader));
	}	

	// Composite Resource Loader
	Map resourceBundles = new HashMap();
	Set classNames = new  HashSet();

	private void addToCache(String className, Locale locale, CompositeProxyResourceBundle crb) {
		if (locale == null) locale = Locale.getDefault();
		try {
			crb.addToCache(className, getResourceBundle(className, locale, getClassLoader(className, null)));
		} catch (IOException e) {
			log.error("Could not refresh bundle: "+className+" Locale: "+locale == null ? "" : locale.toString()+" Is the resource in the Export-Package list?", e);
		} catch (ClassNotFoundException e) {
			log.error("Could not refresh bundle: "+className+" Locale: "+locale == null ? "" : locale.toString()+" Is the resource in the Export-Package list?", e);
		}
	}

	private void removeFromCache(String className, Locale locale, CompositeProxyResourceBundle crb) {		
		if (locale == null) locale = Locale.getDefault();
		crb.removeFromCache(className);
	}

	private CompositeProxyResourceBundle getCompositeProxyResourceBundleFromCache(Locale locale) {
		
		
		// If CompositeResource bundle does not exists for the given locale, load all message classes for
		// the given locale
		if (resourceBundles.get(locale) == null) {
			CompositeProxyResourceBundle crb = new CompositeProxyResourceBundle();
			resourceBundles.put(locale, crb);
			
			// Iterate over all registered classNames and load ResourceBundles for it.
			for (String cn : classNames) {
				addToCache(cn, locale, crb);
			}
		}
		return resourceBundles.get(locale);
	}

	@Override
	public ResourceBundle getDynamicResourceBundle(Locale locale) {
		synchronized (classNames) {
			return getCompositeProxyResourceBundleFromCache(locale);
		}
	}

	@Override
	public ResourceBundle getDynamicResourceBundle() {
		synchronized (classNames) {
			return getCompositeProxyResourceBundleFromCache(Locale.getDefault());
		}
	}

	@Override
	public void registerResourceBundle(Bundle bundle, String className) {
		synchronized (classNames) {
			ResourceBundle.clearCache(getClassLoader(className, null));
			classNames.add(className);
			bundleResourceCaches.put(className, new BundleProxyClassLoader(bundle));

			// Iterate over existing locales in cache and add new entry
			for (Locale locale : resourceBundles.keySet()) {
				addToCache(className, locale, getCompositeProxyResourceBundleFromCache(locale));
			}			
		}
	}

	@Override
	public void unregisterResourceBundle(Bundle bundle, String className) {
		synchronized (classNames) {
			ResourceBundle.clearCache(getClassLoader(className, null));
			classNames.remove(className);
			bundleResourceCaches.remove(className);

			// Iterate over existing locales in cache and add new entry
			for (Locale locale : resourceBundles.keySet()) {
				removeFromCache(className, locale, getCompositeProxyResourceBundleFromCache(locale));
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy