| 
001 /*002  * Copyright 2008-2015 the original author or authors.
 003  *
 004  * Licensed under the Apache License, Version 2.0 (the "License");
 005  * you may not use this file except in compliance with the License.
 006  * You may obtain a copy of the License at
 007  *
 008  *     http://www.apache.org/licenses/LICENSE-2.0
 009  *
 010  * Unless required by applicable law or agreed to in writing, software
 011  * distributed under the License is distributed on an "AS IS" BASIS,
 012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 013  * See the License for the specific language governing permissions and
 014  * limitations under the License.
 015  */
 016 package org.codehaus.griffon.runtime.core.i18n;
 017
 018 import griffon.core.CallableWithArgs;
 019 import griffon.core.i18n.MessageSource;
 020 import griffon.core.i18n.NoSuchMessageException;
 021
 022 import javax.annotation.Nonnull;
 023 import javax.annotation.Nullable;
 024 import java.text.MessageFormat;
 025 import java.util.List;
 026 import java.util.Locale;
 027 import java.util.Map;
 028 import java.util.MissingResourceException;
 029
 030 import static griffon.util.GriffonNameUtils.requireNonBlank;
 031 import static java.util.Objects.requireNonNull;
 032
 033 /**
 034  * @author Andres Almiray
 035  * @author Alexander Klein
 036  * @since 2.0.0
 037  */
 038 public abstract class AbstractMessageSource implements MessageSource {
 039     protected static final String ERROR_KEY_BLANK = "Argument 'key' must not be blank";
 040     protected static final String ERROR_LOCALE_NULL = "Argument 'locale' must not be null";
 041     protected static final String ERROR_ARGS_NULL = "Argument 'args' must not be null";
 042     protected static final String ERROR_MESSAGE_BLANK = "Argument 'message' must not be blank";
 043
 044     protected static final Object[] EMPTY_OBJECT_ARGS = new Object[0];
 045
 046     @Nonnull
 047     @Override
 048     public String getMessage(@Nonnull String key) throws NoSuchMessageException {
 049         return getMessage(key, EMPTY_OBJECT_ARGS, Locale.getDefault());
 050     }
 051
 052     @Nonnull
 053     @Override
 054     public String getMessage(@Nonnull String key, @Nonnull Locale locale) throws NoSuchMessageException {
 055         return getMessage(key, EMPTY_OBJECT_ARGS, locale);
 056     }
 057
 058     @Nonnull
 059     @Override
 060     public String getMessage(@Nonnull String key, @Nonnull Object[] args) throws NoSuchMessageException {
 061         return getMessage(key, args, Locale.getDefault());
 062     }
 063
 064     @Nonnull
 065     @Override
 066     public String getMessage(@Nonnull String key, @Nonnull Object[] args, @Nonnull Locale locale) throws NoSuchMessageException {
 067         requireNonBlank(key, ERROR_KEY_BLANK);
 068         requireNonNull(args, ERROR_ARGS_NULL);
 069         requireNonNull(locale, ERROR_LOCALE_NULL);
 070         Object message = resolveMessageValue(key, locale);
 071         Object result = evalMessageWithArguments(message, args);
 072         if (result != null) return result.toString();
 073         throw new NoSuchMessageException(key, locale);
 074     }
 075
 076     @Nonnull
 077     @Override
 078     public String getMessage(@Nonnull String key, @Nonnull List<?> args) throws NoSuchMessageException {
 079         return getMessage(key, toObjectArray(args), Locale.getDefault());
 080     }
 081
 082     @Nonnull
 083     @Override
 084     public String getMessage(@Nonnull String key, @Nonnull List<?> args, @Nonnull Locale locale) throws NoSuchMessageException {
 085         return getMessage(key, toObjectArray(args), locale);
 086     }
 087
 088     @Nullable
 089     @Override
 090     public String getMessage(@Nonnull String key, @Nullable String defaultMessage) {
 091         return getMessage(key, EMPTY_OBJECT_ARGS, Locale.getDefault(), defaultMessage);
 092     }
 093
 094     @Nullable
 095     @Override
 096     public String getMessage(@Nonnull String key, @Nonnull Locale locale, @Nullable String defaultMessage) {
 097         return getMessage(key, EMPTY_OBJECT_ARGS, locale, defaultMessage);
 098     }
 099
 100     @Nullable
 101     @Override
 102     public String getMessage(@Nonnull String key, @Nonnull Object[] args, @Nullable String defaultMessage) {
 103         return getMessage(key, args, Locale.getDefault(), defaultMessage);
 104     }
 105
 106     @Nullable
 107     @Override
 108     public String getMessage(@Nonnull String key, @Nonnull Object[] args, @Nonnull Locale locale, @Nullable String defaultMessage) {
 109         try {
 110             return getMessage(key, args, locale);
 111         } catch (NoSuchMessageException nsme) {
 112             return null == defaultMessage ? key : defaultMessage;
 113         }
 114     }
 115
 116     @Nullable
 117     @Override
 118     public String getMessage(@Nonnull String key, @Nonnull List<?> args, @Nullable String defaultMessage) {
 119         return getMessage(key, toObjectArray(args), Locale.getDefault(), defaultMessage);
 120     }
 121
 122     @Nullable
 123     @Override
 124     public String getMessage(@Nonnull String key, @Nonnull List<?> args, @Nonnull Locale locale, @Nullable String defaultMessage) {
 125         return getMessage(key, toObjectArray(args), locale, defaultMessage);
 126     }
 127
 128     @Nonnull
 129     @Override
 130     public String getMessage(@Nonnull String key, @Nonnull Map<String, Object> args) throws NoSuchMessageException {
 131         return getMessage(key, args, Locale.getDefault());
 132     }
 133
 134     @Nonnull
 135     @Override
 136     public String getMessage(@Nonnull String key, @Nonnull Map<String, Object> args, @Nonnull Locale locale) throws NoSuchMessageException {
 137         requireNonBlank(key, ERROR_KEY_BLANK);
 138         requireNonNull(args, ERROR_ARGS_NULL);
 139         requireNonNull(locale, ERROR_LOCALE_NULL);
 140         Object message = resolveMessageValue(key, locale);
 141         Object result = evalMessageWithArguments(message, args);
 142         if (result != null) return result.toString();
 143         throw new NoSuchMessageException(key, locale);
 144     }
 145
 146     @Nullable
 147     @Override
 148     public String getMessage(@Nonnull String key, @Nonnull Map<String, Object> args, @Nullable String defaultMessage) {
 149         return getMessage(key, args, Locale.getDefault(), defaultMessage);
 150     }
 151
 152     @Nullable
 153     @Override
 154     public String getMessage(@Nonnull String key, @Nonnull Map<String, Object> args, @Nonnull Locale locale, @Nullable String defaultMessage) {
 155         try {
 156             return getMessage(key, args, locale);
 157         } catch (NoSuchMessageException nsme) {
 158             return null == defaultMessage ? key : defaultMessage;
 159         }
 160     }
 161
 162     @Nonnull
 163     @Override
 164     public Object resolveMessageValue(@Nonnull String key, @Nonnull Locale locale) throws NoSuchMessageException {
 165         requireNonBlank(key, ERROR_KEY_BLANK);
 166         requireNonNull(locale, ERROR_LOCALE_NULL);
 167         try {
 168             Object message = doResolveMessageValue(key, locale);
 169             if (message instanceof CharSequence) {
 170                 String msg = message.toString();
 171                 if (msg.length() >= 4 && msg.startsWith(REF_KEY_START) && msg.endsWith(REF_KEY_END)) {
 172                     String refKey = msg.substring(2, msg.length() - 1);
 173                     message = resolveMessageValue(refKey, locale);
 174                 }
 175             }
 176             return message;
 177         } catch (MissingResourceException mre) {
 178             throw new NoSuchMessageException(key, locale);
 179         }
 180     }
 181
 182     @Nonnull
 183     @Override
 184     public String formatMessage(@Nonnull String message, @Nonnull List<?> args) {
 185         requireNonBlank(message, ERROR_MESSAGE_BLANK);
 186         requireNonNull(args, ERROR_ARGS_NULL);
 187         return formatMessage(message, args.toArray(new Object[args.size()]));
 188     }
 189
 190     @Nonnull
 191     @Override
 192     public String formatMessage(@Nonnull String message, @Nonnull Object[] args) {
 193         requireNonBlank(message, ERROR_MESSAGE_BLANK);
 194         requireNonNull(args, ERROR_ARGS_NULL);
 195         if (args.length == 0) return message;
 196         return MessageFormat.format(message, args);
 197     }
 198
 199     @Nonnull
 200     @Override
 201     public String formatMessage(@Nonnull String message, @Nonnull Map<String, Object> args) {
 202         requireNonBlank(message, ERROR_MESSAGE_BLANK);
 203         requireNonNull(args, ERROR_ARGS_NULL);
 204         for (Map.Entry<String, Object> variable : args.entrySet()) {
 205             String var = variable.getKey();
 206             String value = variable.getValue() != null ? variable.getValue().toString() : null;
 207             if (value != null) {
 208                 message = message.replace("{:" + var + "}", value);
 209             }
 210         }
 211         return message;
 212     }
 213
 214     @Nonnull
 215     protected abstract Object doResolveMessageValue(@Nonnull String key, @Nonnull Locale locale) throws NoSuchMessageException;
 216
 217     @Nullable
 218     protected Object evalMessageWithArguments(@Nonnull Object message, @Nonnull Object[] args) {
 219         if (message instanceof CallableWithArgs) {
 220             CallableWithArgs<?> callable = (CallableWithArgs<?>) message;
 221             return callable.call(args);
 222         } else if (message instanceof CharSequence) {
 223             return formatMessage(String.valueOf(message), args);
 224         }
 225         return null;
 226     }
 227
 228     @Nullable
 229     protected Object evalMessageWithArguments(@Nonnull Object message, @Nonnull Map<String, Object> args) {
 230         if (message instanceof CallableWithArgs) {
 231             CallableWithArgs<?> callable = (CallableWithArgs<?>) message;
 232             return callable.call(args);
 233         } else if (message instanceof CharSequence) {
 234             return formatMessage(String.valueOf(message), args);
 235         }
 236         return null;
 237     }
 238
 239     @Nonnull
 240     protected Object[] toObjectArray(@Nonnull List<?> args) {
 241         if (args.isEmpty()) {
 242             return EMPTY_OBJECT_ARGS;
 243         }
 244         return args.toArray(new Object[args.size()]);
 245     }
 246 }
 |