/* * * * Copyright (c) 2016. David Sowerby * * * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * * the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * * specific language governing permissions and limitations under the License. * */ package uk.q3c.krail.core.i18n; import com.google.inject.Inject; import uk.q3c.util.MessageFormat; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.text.Collator; import java.util.*; /** * Translates from an {@link I18NKey} to a value from a {@link PatternSource}, expanding its arguments if it has them. * Using the standard Krail method for I18N, the keys will be defined as Enum, implementing I18NKey. However, this * Translate implementation should also work for any other object used as a key, although it has not been tested. * * @author David Sowerby 24 October 2014 - all translation made in this class, removing dependency on key itself * @author David Sowerby 3 Aug 2013 */ public class DefaultTranslate implements Translate { private final CurrentLocale currentLocale; private final Set<Locale> supportedLocales; private final PatternSource patternSource; /** * @param patternSource * the source for I18N patterns * @param currentLocale * the locale for the current user * @param supportedLocales * the Locales that this application supports */ @Inject protected DefaultTranslate(PatternSource patternSource, CurrentLocale currentLocale, @SupportedLocales Set<Locale> supportedLocales) { super(); this.patternSource = patternSource; this.supportedLocales = supportedLocales; this.currentLocale = currentLocale; } /** * {@inheritDoc} */ @Nonnull @Override public String from(@Nullable I18NKey key, Object... arguments) { return from(key, currentLocale.getLocale(), arguments); } /** * Iterates through {@link #patternSource} in ascending order (the order need not be sequential), and returns the * first pattern found for {@code key}. * <p> * <p> * If the key does not provide a pattern from any of the sources, and key is an Enum, the enum.name() is returned. * Before returning the enum.name(), underscores are replaced with spaces. * <p> * If the key does not provide a pattern from any of the sources, and key is not an Enum, the key.toString() is * returned * <p> * If arguments are supplied, these are applied to the pattern. If key is null, a String "key is null" * is returned. Any arguments which are also I18NKey types are also translated * * @param key * the key to look up the I18N pattern * @param arguments * the arguments used to expand the pattern, if required * * @return the translated value as described above, or "key is null" if {@code key} is null * * @throws UnsupportedLocaleException * if locale is not in {@link #supportedLocales} and checkLocaleIsSupported is true */ @Nonnull @Override public String from(boolean checkLocaleIsSupported, @Nullable I18NKey key, @Nonnull Locale locale, Object... arguments) { if (checkLocaleIsSupported) { if (!supportedLocales.contains(locale)) { throw new UnsupportedLocaleException(locale); } } if (key == null) { return "key is null"; } // E k = typeBridge(key); String pattern = patternSource.retrievePattern((Enum) key, locale); //If no arguments, return the pattern as it is if ((arguments == null) || (arguments.length == 0)) { return pattern; } // If any of the arguments are I18NKeys, translate them as well List<Object> args = new ArrayList<>(Arrays.asList(arguments)); for (int i = 0; i < args.size(); i++) { if (args.get(i) instanceof I18NKey) { @SuppressWarnings("unchecked") String translation = from((I18NKey) args.get(i)); args.remove(i); args.add(i, translation); } } return MessageFormat.format(pattern, args.toArray()); } /** * {@inheritDoc} */ @Override public String from(@Nullable I18NKey key, @Nonnull Locale locale, Object... arguments) { return from(true, key, locale, arguments); } @Override public Collator collator() { return Collator.getInstance(currentLocale.getLocale()); } }