001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.resources;
019    
020    import java.io.Serializable;
021    import java.text.MessageFormat;
022    import java.util.Locale;
023    
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    import org.apache.commons.resources.impl.ResourceBundleResourcesFactory;
027    
028    /**
029     * <p>Wrapper around any {@link Resources} object that performs message
030     * string lookups from the {@link Resources} instance, and parameter
031     * replacement via <code>java.text.MessageFormat</code>.  For convenience,
032     * the same functionality is also available via static methods that accept
033     * a {@link Resources} parameter.</p>
034     *
035     * <p>Calls to <code>getMessage()</code> variants without a <code>Locale</code>
036     * argument are presumed to be requesting a message string in the default
037     * <code>Locale</code> for this JVM.</p>
038     *
039     * <p>When a <code>getString()</code> call to the underlying {@link Resources}
040     * instance fails or returns null, a suitable error message String will be
041     * returned.</p>
042     */
043    public class Messages implements Serializable {
044    
045    
046        // ----------------------------------------------------------- Constructors
047    
048    
049        /**
050         * <p>Construct a {@link Messages} instance that wraps the specified
051         * {@link Resources} instance.</p>
052         *
053         * @param resources The {@link Resources} instance from which
054         *  message strings are to be retrieved
055         */
056        public Messages(Resources resources) {
057    
058            this.resources = resources;
059    
060        }
061    
062    
063        // ----------------------------------------------------- Instance Variables
064    
065    
066        /**
067         * <p>The {@link Resources} instance that we are wrapping.</p>
068         */
069        private Resources resources = null;
070    
071    
072        // ------------------------------------------------------------- Properties
073    
074    
075        /**
076         * <p>Return the {@link Resources} instance that we are wrapping.</p>
077         *
078         * @return The wrapped resources.
079         */
080        public Resources getResources() {
081    
082            return (this.resources);
083    
084        }
085    
086    
087        // --------------------------------------------------------- Public Methods
088    
089    
090        /**
091         * <p>Return a text message for the specified key, for the default
092         * <code>Locale</code>.</p>
093         *
094         * @param key Message key to retrieve
095         * @return The text message for the specified key.
096         */
097        public String getMessage(String key) {
098    
099            return (getMessage(resources, key));
100    
101        }
102    
103    
104        /**
105         * <p>Return a text message for the specified key, for the specified
106         * <code>Locale</code>.</p>
107         *
108         * @param locale <code>Locale</code> for which to retrieve the message
109         * @param key Message key to retrieve
110         * @return The text message for the specified key and locale.
111         */
112        public String getMessage(Locale locale, String key) {
113    
114            return (getMessage(resources, locale, key));
115    
116        }
117    
118    
119        /**
120         * <p>Return a text message for the specified key, for the default
121         * <code>Locale</code>, with parametric replacement.</p>
122         *
123         * @param key Message key to retrieve
124         * @param args Array of replacement values
125         * @return The text message with parametric replacement.
126         */
127        public String getMessage(String key, Object[] args) {
128            return getMessage(resources, key, args);
129        }
130    
131    
132        /**
133         * <p>Return a text message for the specified key, for the specified
134         * <code>Locale</code>, with parametric replacement.</p>
135         *
136         * @param locale <code>Locale</code> for which to retrieve the message
137         * @param key Message key to retrieve
138         * @param args Array of replacement values
139         * @return The text message for a spcified locale with parametric replacement.
140         */
141        public String getMessage(Locale locale, String key, Object[] args) {
142            return getMessage(resources, locale, key, args);
143        }
144    
145    
146        /**
147         * <p>Return a text message for the specified key, for the default
148         * <code>Locale</code>, with parametric replacement.</p>
149         *
150         * @param key Message key to retrieve
151         * @param arg0 Individual parameter replacement value
152         * @return The text message with parametric replacement.
153         */
154        public String getMessage(String key, Object arg0) {
155    
156            return (getMessage(resources, key, arg0));
157    
158        }
159    
160    
161        /**
162         * <p>Return a text message for the specified key, for the specified
163         * <code>Locale</code>, with parametric replacement.</p>
164         *
165         * @param locale <code>Locale</code> for which to retrieve the message
166         * @param key Message key to retrieve
167         * @param arg0 Individual parameter replacement value
168         * @return The text message for a spcified locale with parametric replacement.
169         */
170        public String getMessage(Locale locale, String key, Object arg0) {
171    
172            return (getMessage(resources, locale, key, arg0));
173    
174        }
175    
176    
177        // ------------------------------------------------------- Static Variables
178    
179    
180        /**
181         * <p>The {@link org.apache.commons.resources.ResourcesFactory} that will be used by the
182         * <code>getMessages()</code> method.</p>
183         */
184        private static ResourcesFactory factory = null;
185    
186    
187        // --------------------------------------------------------- Static Methods
188    
189        /**
190         * <p>Set the {@link org.apache.commons.resources.ResourcesFactory} that
191         *  will be used by the <code>getMessages()</code> method.</p>
192         *
193         * @param factory ResourcesFactory instance to set.
194         */
195        public static void setFactory(ResourcesFactory factory) {
196            Messages.factory = factory;
197        }
198    
199        /**
200         * <p>Return a text message for the specified key, for the default
201         * <code>Locale</code>.</p>
202         *
203         * @param resources {@link Resources} instance to retrieve the message from
204         * @param key Message key to retrieve
205         * @return The text message.
206         */
207        public static String getMessage(Resources resources, String key) {
208    
209            return (getMessage(resources, (Locale) null, key));
210    
211        }
212    
213    
214        /**
215         * <p>Return a text message for the specified key, for the specified
216         * <code>Locale</code>.</p>
217         *
218         * @param resources {@link Resources} instance to retrieve the message from
219         * @param locale <code>Locale</code> for which to retrieve the message
220         * @param key Message key to retrieve
221         * @return The text message.
222         */
223        public static String getMessage(
224            Resources resources,
225            Locale locale,
226            String key) {
227    
228            String message = null;
229            try {
230                message = resources.getString(key, locale);
231            } catch (ResourcesException e) {
232                Log log = LogFactory.getLog(Messages.class);
233                if (log.isDebugEnabled()) {
234                   log.debug("Failed retrieving message for key: '" + key + "'.", e);
235                }
236            }
237    
238            if (message == null && !resources.isReturnNull()) {
239                message = "???" + key + "???";
240            }
241    
242            return message;
243        }
244    
245    
246        /**
247         * <p>Return a text message for the specified key, for the default
248         * <code>Locale</code>, with parametric replacement.</p>
249         *
250         * @param resources {@link Resources} instance to retrieve the message from
251         * @param key Message key to retrieve
252         * @param args Array of replacement values
253         * @return The text message.
254         */
255        public static String getMessage(
256            Resources resources,
257            String key,
258            Object[] args) {
259    
260            return getMessage(resources, (Locale) null, key, args);
261        }
262    
263    
264        /**
265         * <p>Return a text message for the specified key, for the specified
266         * <code>Locale</code>, with parametric replacement.</p>
267         *
268         * @param resources {@link Resources} instance to retrieve the message from
269         * @param locale <code>Locale</code> for which to retrieve the message
270         * @param key Message key to retrieve
271         * @param args Array of replacement values
272         * @return The text message.
273         */
274        public static String getMessage(
275            Resources resources,
276            Locale locale,
277            String key,
278            Object[] args) {
279    
280            // TODO - Cache MessageFormat instances?
281            String message = getMessage(resources, locale, key);
282            MessageFormat format = new MessageFormat(message);
283            return (format.format(args));
284        }
285    
286    
287        /**
288         * <p>Return a text message for the specified key, for the default
289         * <code>Locale</code>, with parametric replacement.</p>
290         *
291         * @param resources {@link Resources} instance to retrieve the message from
292         * @param key Message key to retrieve
293         * @param arg0 Individual parameter replacement value
294         * @return The text message.
295         */
296        public static String getMessage(Resources resources,
297                                        String key, Object arg0) {
298    
299            return (getMessage(resources, (Locale) null, key, arg0));
300    
301        }
302    
303        /**
304         * <p>Return a text message for the specified key, for the specified
305         * <code>Locale</code>, with parametric replacement.</p>
306         *
307         * @param resources {@link Resources} instance to retrieve the message from
308         * @param locale <code>Locale</code> for which to retrieve the message
309         * @param key Message key to retrieve
310         * @param arg0 Individual parameter replacement value
311         * @return The text message.
312         */
313        public static String getMessage(
314            Resources resources,
315            Locale locale,
316            String key,
317            Object arg0) {
318    
319            return getMessage(resources, locale, key, new Object[] { arg0 });
320        }
321    
322        /**
323         * <p>Convenience factory method to create a {@link Messages} instance
324         * that wraps a {@link Resources} instance that contains message resources
325         * for the specified properties file.  It is expected that the resources
326         * for each package will be in properties files that are nested in the
327         * package directory, with names like <code>LocalStrings.properties</code>
328         * for the default messages, and names like
329         * <code>LocalStrings_en_US.properties</code> for messages localized to
330         * a particular <code>Locale</code>.</p>
331         *
332         * @param name Package + file name of the properties file for which
333         *  local message resources are desired (ie. org.apache.commons.resources.LocalStrings).
334         * @return The text messages.
335         */
336        public static Messages getMessages(String name) {
337    
338            if (factory == null) {
339                factory = new ResourceBundleResourcesFactory();
340            }
341    
342            try {
343                Resources resources = factory.getResources(name);
344                return (new Messages(resources));
345    
346            } catch (ResourcesException e) {
347                return (null);
348            }
349    
350        }
351    
352    
353    }