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

com.github.fge.msgsimple.bundle.MessageBundle Maven / Gradle / Ivy

/*
 * Copyright (c) 2013, Francis Galiegue 
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Lesser GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Lesser GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

package com.github.fge.msgsimple.bundle;

import com.github.fge.Frozen;
import com.github.fge.msgsimple.InternalBundle;
import com.github.fge.msgsimple.locale.LocaleUtils;
import com.github.fge.msgsimple.provider.MessageSourceProvider;
import com.github.fge.msgsimple.provider.StaticMessageSourceProvider;
import com.github.fge.msgsimple.source.MessageSource;

import javax.annotation.concurrent.ThreadSafe;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.IllegalFormatException;
import java.util.List;
import java.util.Locale;

/**
 * A message bundle
 *
 * 

A bundle is a list of {@link MessageSourceProvider}s. When a message is * looked up, providers are queried in order for a {@link MessageSource} for * that locale; if a source is found, it is queried for the message.

* *

When a method is used which does not take a {@link Locale} as an argument, * the default locale is used (obtained via {@link Locale#getDefault()}). If no * match is found for the locale, the next, more general locale is tried.

* *

Finally, if no match was found for any provider/source, the key itself is * returned.

* *

You can generate a bundle from a single source using the {@link * #withSingleSource(MessageSource)} convenience static factory method; for more * elaborate bundles, use {@link #newBuilder()} to obtain a builder, then that * builder's {@link MessageBundleBuilder#freeze()} method to obtain the bundle; * alternatively, you can reuse an existing bundle and {@link #thaw()} it, * modify it and freeze it again.

* * @see LocaleUtils#getApplicable(Locale) * @see MessageSourceProvider */ @ThreadSafe public final class MessageBundle implements Frozen { private static final InternalBundle BUNDLE = InternalBundle.getInstance(); final List providers = new ArrayList(); /** * Create a new, empty builder for a bundle * * @return a builder */ public static MessageBundleBuilder newBuilder() { return new MessageBundleBuilder(); } /** * Convenience static factory method to create a bundle with a single * message source * * @since 0.7 * * @param source the message source * @return a new bundle * @see StaticMessageSourceProvider#withSingleSource(MessageSource) */ public static MessageBundle withSingleSource(final MessageSource source) { final MessageSourceProvider provider = StaticMessageSourceProvider.withSingleSource(source); return newBuilder().appendProvider(provider).freeze(); } MessageBundle(final MessageBundleBuilder builder) { providers.addAll(builder.providers); } /** * Get a message for the given key and locale * * @param locale the locale * @param key the key * @return a matching message if found; the key itself if no message is * found * @throws NullPointerException either the key or the locale is null */ public String getMessage(final Locale locale, final String key) { BUNDLE.checkNotNull(key, "query.nullKey"); BUNDLE.checkNotNull(locale, "query.nullLocale"); String ret; MessageSource source; for (final Locale l: LocaleUtils.getApplicable(locale)) for (final MessageSourceProvider provider: providers) { source = provider.getMessageSource(l); if (source == null) continue; ret = source.getKey(key); if (ret != null) return ret; } // No source found which has the key... Return the key itself. return key; } /** * Return a message for a given key, using the JVM's current locale * * @param key the key * @return a matching message if found; the key itself if no message is * found * @throws NullPointerException key is null * @see Locale#getDefault() * @see Locale#setDefault(Locale) */ public String getMessage(final String key) { return getMessage(Locale.getDefault(), key); } /** * Get a locale-dependent {@code printf()}-like formatted message * *

This is essentially a call to {@link String#format(Locale, String, * Object...)}.

* *

There is however one important difference: while {@code * String.format()} will throw an {@link IllegalFormatException} if an * argument is missing or a format specifier is incorrect, this method * returns the format itself (or the key, like {@link #getMessage(Locale, * String)}, if no match was found for that locale/key pair).

* * @param locale the locale * @param key the key * @param params the format parameters * @return the formatted message * @see Formatter */ public String printf(final Locale locale, final String key, final Object... params) { final String format = getMessage(locale, key); try { return String.format(locale, format, params); } catch (IllegalFormatException ignored) { return format; } } /** * Get a {@code printf()}-like message with the default locale * *

This calls {@link #printf(Locale, String, Object...)} with {@link * Locale#getDefault()} as the first argument.

* * @param key the key * @param params the format parameters * @return the formatted message */ public String printf(final String key, final Object... params) { return printf(Locale.getDefault(), key, params); } /** * Get a locale-dependent message formatted using {@link MessageFormat} * *

You should really consider using {@link #printf(Locale, String, * Object...)} instead.

* * @param locale the locale * @param key the key * @param params the format parameters * @return the formatted message */ public String format(final Locale locale, final String key, final Object... params) { final String pattern = getMessage(locale, key); try { return new MessageFormat(pattern, locale) .format(params, new StringBuffer(pattern.length()), null) .toString(); } catch (IllegalArgumentException ignored) { return pattern; } } /** * Get a {@link MessageFormat} formatted message with the current default * locale * *

You should really consider using {@link #printf(String, Object...)} * instead.

* * @param key the key * @param params the format parameters * @return the formatted message */ public String format(final String key, final Object... params) { return format(Locale.getDefault(), key, params); } /** * Check an object reference for {@code null} and return it * *

If the reference is null, a {@link NullPointerException} is thrown, * with its message set according to the given locale and key.

* * @param reference the reference to check * @param locale the locale to use * @param key the key to use * @param type of the reference * @return the reference * @throws NullPointerException see description * @see #getMessage(Locale, String) */ public T checkNotNull(final T reference, final Locale locale, final String key) { if (reference == null) throw new NullPointerException(getMessage(locale, key)); return reference; } /** * Check a reference for {@code null} and return it * *

This calls {@link #checkNotNull(Object, Locale, String)} with the * JVM's current locale.

* * @param reference the reference to check * @param key the key * @param type of the reference * @return the reference * @throws NullPointerException see description */ public T checkNotNull(final T reference, final String key) { return checkNotNull(reference, Locale.getDefault(), key); } /** * Check for a condition * *

When the condition is false, an {@link IllegalArgumentException} is * thrown with its message set using the given locale and key.

* * @param condition the condition to check * @param locale the locale to use * @param key the key * @throws IllegalArgumentException see description * @see #getMessage(Locale, String) */ public void checkArgument(final boolean condition, final Locale locale, final String key) { if (!condition) throw new IllegalArgumentException(getMessage(locale, key)); } /** * Check for a condition * *

This calls {@link #checkArgument(boolean, Locale, String)} using the * JVM's current locale.

* * @param condition the condition to check * @param key the key * @throws IllegalArgumentException see description */ public void checkArgument(final boolean condition, final String key) { checkArgument(condition, Locale.getDefault(), key); } /** * Check a reference for {@code null} and return it * *

Like {@link #checkNotNull(Object, Locale, String)}, except that this * will use {@link #printf(Locale, String, Object...)}

* * @param reference the reference to check * @param locale the locale to use * @param key the key * @param params arguments for the format string * @param type of the reference * @return the reference * @throws NullPointerException see description * @see #printf(Locale, String, Object...) */ public T checkNotNullPrintf(final T reference, final Locale locale, final String key, final Object... params) { if (reference == null) throw new NullPointerException(printf(locale, key, params)); return reference; } /** * Check a reference for {@code null} and return it * *

This calls {@link #checkNotNullPrintf(Object, Locale, String, * Object...)} with the JVM's current locale.

* * @param reference the reference * @param key the key * @param params arguments for the format string * @param type of the reference * @return the reference * @throws NullPointerException see description */ public T checkNotNullPrintf(final T reference, final String key, final Object... params) { return checkNotNullPrintf(reference, Locale.getDefault(), key, params); } /** * Check for a condition * *

Like {@link #checkArgument(boolean, Locale, String)}, except that * {@link #printf(Locale, String, Object...)} is used to fill the message. *

* * @param condition the condition to check * @param locale the locale * @param key the key * @param params arguments for the format string * @throws IllegalArgumentException see description * @see #printf(Locale, String, Object...) */ public void checkArgumentPrintf(final boolean condition, final Locale locale, final String key, final Object... params) { if (!condition) throw new IllegalArgumentException(printf(locale, key, params)); } /** * Check for a condition * *

This calls {@link #checkArgumentPrintf(boolean, Locale, String, * Object...)} with the JVM's current locale.

* * @param condition the condition to check * @param key the key * @param params arguments for the format string * @throws IllegalArgumentException see description */ public void checkArgumentPrintf(final boolean condition, final String key, final Object... params) { checkArgumentPrintf(condition, Locale.getDefault(), key, params); } /** * Check a reference for {@code null} and return it * *

Like {@link #checkNotNull(Object, Locale, String)}, except that this * will use {@link #format(Locale, String, Object...)}}

* * @param reference the reference to check * @param locale the locale to use * @param key the key * @param params arguments for the format string * @param type of the reference * @return the reference * @throws NullPointerException see description * @see #format(Locale, String, Object...) */ public T checkNotNullFormat(final T reference, final Locale locale, final String key, final Object... params) { if (reference == null) throw new NullPointerException(format(locale, key, params)); return reference; } /** * Check a reference for {@code null} and return it * *

This calls {@link #checkNotNullFormat(Object, Locale, String, * Object...)} with the JVM's current locale.

* * @param reference the reference * @param key the key * @param params arguments for the format string * @param type of the reference * @return the reference * @throws NullPointerException see description */ public T checkNotNullFormat(final T reference, final String key, final Object... params) { return checkNotNullFormat(reference, Locale.getDefault(), key, params); } /** * Check for a condition * *

Like {@link #checkArgument(boolean, Locale, String)}, except that * {@link #format(Locale, String, Object...)} is used to fill the message. *

* * @param condition the condition to check * @param locale the locale * @param key the key * @param params arguments for the format string * @throws IllegalArgumentException see description * @see #format(Locale, String, Object...) */ public void checkArgumentFormat(final boolean condition, final Locale locale, final String key, final Object... params) { if (!condition) throw new IllegalArgumentException(format(locale, key, params)); } /** * Check for a condition * *

This calls {@link #checkArgumentFormat(boolean, Locale, String, * Object...)} with the JVM's current locale.

* * @param condition the condition to check * @param key the key * @param params arguments for the format string * @throws IllegalArgumentException see description */ public void checkArgumentFormat(final boolean condition, final String key, final Object... params) { checkArgumentFormat(condition, Locale.getDefault(), key, params); } @Override public MessageBundleBuilder thaw() { return new MessageBundleBuilder(this); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy