/* * Copyright (c) 2012, grossmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the jo-widgets.org nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL jo-widgets.org BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.jowidgets.i18n.api; import java.io.Serializable; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.jowidgets.i18n.api.LocaleLocal.IValueFactory; public final class MessageProvider { private MessageProvider() {} public interface IClassLoaderProvider { ClassLoader get(); } /** * Creates a new message provider for a given resource bundle name. * * @param resourceBundleName The resource bundle name to get the message provider for, never empty * * @return The new created message provider */ public static IMessageProvider create(final String resourceBundleName) { return create(resourceBundleName, (IClassLoaderProvider) null); } /** * Creates a new message provider for a given resource bundle name and a class that provides the class loader * * @param resourceBundleName The resource bundle name to get the message provider for, never empty * @param classLoaderProvider The class that provides the class loader that should be used to load the resource bundle with * * @return The new created message provider */ public static IMessageProvider create(final String resourceBundleName, final Class<?> classLoaderProviderClass) { return create(resourceBundleName, new ClassLoaderFromClassProvider(classLoaderProviderClass)); } /** * Creates a new message provider for a given resource bundle name and a class loader provider * * @param resourceBundleName The resource bundle name to get the message provider for, never empty * @param classLoaderProvider A provider that provides the class loader that should be used to load the resource bundle * The class loader will be resolved when the resource bundle will be created * * @return The new created message provider */ public static IMessageProvider create(final String resourceBundleName, final IClassLoaderProvider classLoaderProvider) { return new MessageProviderImpl(resourceBundleName, classLoaderProvider); } private static final class MessageProviderImpl implements IMessageProvider, Serializable { private static final long serialVersionUID = -6035175048306441676L; private final String resourceBundleName; private final IClassLoaderProvider classLoaderProvider; private final ILocaleLocal<LocalizedMessageProvider> messageProviders; private MessageProviderImpl(final String resourceBundleName, final IClassLoaderProvider classLoaderProvider) { Assert.paramNotNull(resourceBundleName, "resourceBundleName"); this.resourceBundleName = resourceBundleName; this.classLoaderProvider = classLoaderProvider; this.messageProviders = LocaleLocal.create(new MessageProviderFactory()); } @Override public String getString(final String key) { return messageProviders.get().getString(key); } @Override public IMessage getMessage(final String key) { return new MessageImpl(this, key); } private final class MessageProviderFactory implements IValueFactory<LocalizedMessageProvider>, Serializable { private static final long serialVersionUID = -1926402720150772928L; @Override public LocalizedMessageProvider create() { return new LocalizedMessageProvider(resourceBundleName, classLoaderProvider); } } } private static final class LocalizedMessageProvider implements Serializable { private static final long serialVersionUID = 7013591522278151364L; private final String resourceBundleName; private final IClassLoaderProvider classLoaderProvider; private transient ResourceBundle resourceBundle; private LocalizedMessageProvider(final String resourceBundleName, final IClassLoaderProvider classLoaderProvider) { this.resourceBundleName = resourceBundleName; this.classLoaderProvider = classLoaderProvider; } private String getString(final String key) { try { return getResourceBundle().getString(key); } catch (final MissingResourceException e) { return '!' + key + '!'; } } private ResourceBundle getResourceBundle() { if (resourceBundle == null) { resourceBundle = createResourceBundle(); } return resourceBundle; } private ResourceBundle createResourceBundle() { if (classLoaderProvider != null) { final ClassLoader classLoader = classLoaderProvider.get(); if (classLoader != null) { return ResourceBundle.getBundle(resourceBundleName, LocaleHolder.getUserLocale(), classLoader); } } return ResourceBundle.getBundle(resourceBundleName, LocaleHolder.getUserLocale()); } } private static final class MessageImpl implements IMessage, Serializable { private static final long serialVersionUID = -8081080214256066849L; private final IMessageProvider messageProvider; private final String key; private MessageImpl(final IMessageProvider messageProvider, final String key) { Assert.paramNotNull(messageProvider, "messageProvider"); Assert.paramNotEmpty(key, "key"); this.messageProvider = messageProvider; this.key = key; } @Override public String get() { return messageProvider.getString(key); } @Override public String toString() { return "MessageImpl [key=" + key + "]"; } } private static final class ClassLoaderFromClassProvider implements IClassLoaderProvider, Serializable { private static final long serialVersionUID = 235793306640902023L; private final Class<?> clazz; private ClassLoaderFromClassProvider(final Class<?> clazz) { Assert.paramNotNull(clazz, "clazz"); this.clazz = clazz; } @Override public ClassLoader get() { return clazz.getClassLoader(); } } }