View Javadoc

1   /*
2    *  Copyright (c) 2005, 2006 Imola Informatica.
3    *  All rights reserved. This program and the accompanying materials
4    *  are made available under the terms of the LGPL License v2.1
5    *  which accompanies this distribution, and is available at
6    *  http://www.gnu.org/licenses/lgpl.html
7    */
8   
9   
10  package it.imolinfo.jbi4cics.jbi;
11  
12  import java.text.MessageFormat;
13  import java.util.Locale;
14  import java.util.MissingResourceException;
15  import java.util.ResourceBundle;
16  
17  /**
18   * Class dedicated to the internationalization of application messages.
19   * <br>
20   *
21   * @author  <a href="mailto:mcimatti@imolinfo.it">Marco Cimatti</a>
22   */
23  public final class Messages {
24      /*
25       * DON'T ADD LOGGING TO THIS CLASS, because this class is used by logging
26       * itself, so it will cause java.lang.StackOverflowError while initializing
27       * the logging system
28       */
29  
30      /**
31       * The bundle name for a class.
32       */
33      private static final String BUNDLE_NAME = "messages.Bundle";
34  
35      /**
36       * The suffix added to the package name of a class to identify the correct
37       * resource bundle to be used by the class itself.
38       */
39      private static final String BUNDLE_NAME_SUFFIX = "." + BUNDLE_NAME;
40  
41      /**
42       * The resource bundle containing all localized strings.
43       */
44      private final ResourceBundle bundle;
45  
46      /**
47       * Retrieves the <code>ResourceBundle</code> used by this instance.
48       *
49       * @param  clazz   the class used to identify the resource bundle. Must not
50       *                 be <code>null</code>.
51       * @param  locale  the locale to use. Must not be <code>null</code>.
52       */
53      private Messages(final Class clazz, final Locale locale) {
54          bundle = ResourceBundle.getBundle(getBundleName(clazz), locale,
55                                            clazz.getClassLoader());
56      }
57  
58      /**
59       * Factory method to create a <code>Messages</code> object from a
60       * <code>Class</code>.
61       *
62       * @param   clazz   the class used to find the resource bundle. Must not be
63       *                  <code>null</code>.
64       * @return  a <code>Messages</code> object related to <code>clazz</code>,
65       *          never <code>null</code>. The messages bundle used is related to
66       *          the default locale.
67       */
68      public static Messages getMessages(final Class clazz) {
69          return new Messages(clazz, Locale.getDefault());
70      }
71  
72      /**
73       * Factory method to create a <code>Messages</code> object from a
74       * <code>Class</code> and a <code>Locale</code>.
75       *
76       * @param   clazz   the class used to find the resource bundle. Must not be
77       *                  <code>null</code>.
78       * @param   locale  the <code>Locale</code> to find the correct resource
79       *                  bundle. If <code>null</code>, the default locale will be
80       *                  used.
81       * @return  a <code>Messages</code> object related to <code>clazz</code> and
82       *          <code>locale</code>, never <code>null</code>.                                   <code>ResourceBundle</code>.
83       */
84      public static Messages getMessages(final Class clazz, final Locale locale) {
85          if (locale == null) {
86              return new Messages(clazz, Locale.getDefault());
87          }
88          return new Messages(clazz, locale);
89      }
90  
91      /**
92       * Retrieves a localized <code>String</code> which may contains parameters.
93       * This method applies a <code>MessageFormat</code> to the value with the
94       * arguments provided.
95       *
96       * @param   key   the resource key to retrieve the (localized) message.
97       * @param   args  the optional <code>MessageFormat</code> arguments.
98       * @return  the localized messaged related to the key <code>key</code> after
99       *          the substitution of its parameters with values
100      *          <code>args</code>.
101      */
102     public String getString(final String key, final Object ... args) {
103         String rawValue;
104 
105         try {
106             synchronized (bundle) {
107                 rawValue = bundle.getString(key);
108             }
109         } catch (MissingResourceException e) {
110             return key;
111         }
112         try {
113             return MessageFormat.format(rawValue, args);
114         } catch (IllegalArgumentException e) {
115             return rawValue;
116         }
117     }
118 
119     /**
120      * Determines the bundle name for a <code>Class</code>.
121      *
122      * @param   clazz  the <code>Class</code> object used to find the
123      *                 <code>ResourceBundle</code>. Must not be
124      *                 <code>null</code>.
125      * @return  the name of the <code>ResourceBundle</code> related to
126      *          <code>clazz</code>, ever different from <code>null</code>.
127      */
128     private static String getBundleName(final Class clazz) {
129         String packageName = getPackageName(clazz);
130 
131         if (packageName.length() == 0) {
132             return BUNDLE_NAME;
133         }
134         return packageName.concat(BUNDLE_NAME_SUFFIX);
135     }
136 
137     /**
138      * Retrieves the package name for a <code>Class</code> object.
139      * If the class doesn't have a package, the empty string is returned.
140      *
141      * @param   clazz  the class to retrieve its package name. Must not be
142      *                 <code>null</code>.
143      * @return  the package name for <code>clazz</code> if it exists, otherwise
144      *          the empty string.
145      */
146     private static String getPackageName(final Class clazz) {
147         Package pack = clazz.getPackage();
148         String className;
149         int lastDotIndex;
150 
151         if (pack != null) {
152             return pack.getName();
153         }
154 
155         if (clazz.isArray()) {
156             className = clazz.getComponentType().getName();
157         } else {
158             className = clazz.getName();
159         }
160         lastDotIndex = className.lastIndexOf(".");
161         if (lastDotIndex > 0) {
162             return className.substring(0, lastDotIndex);
163         }
164         return "";
165     }
166 }