View Javadoc

1   /*
2    *  Copyright (c) 2005, 2006 2007 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.jbi4ejb.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      @SuppressWarnings("unchecked")
54      private Messages(final Class clazz, final Locale locale) {
55          bundle = ResourceBundle.getBundle(getBundleName(clazz), locale,
56                                            clazz.getClassLoader());
57      }
58  
59      /**
60       * Factory method to create a <code>Messages</code> object from a
61       * <code>Class</code>.
62       *
63       * @param   clazz   the class used to find the resource bundle. Must not be
64       *                  <code>null</code>.
65       * @return  a <code>Messages</code> object related to <code>clazz</code>,
66       *          never <code>null</code>. The messages bundle used is related to
67       *          the default locale.
68       */
69      @SuppressWarnings("unchecked")
70      public static Messages getMessages(final Class clazz) {
71          return new Messages(clazz, Locale.getDefault());
72      }
73  
74      /**
75       * Factory method to create a <code>Messages</code> object from a
76       * <code>Class</code> and a <code>Locale</code>.
77       *
78       * @param   clazz   the class used to find the resource bundle. Must not be
79       *                  <code>null</code>.
80       * @param   locale  the <code>Locale</code> to find the correct resource
81       *                  bundle. If <code>null</code>, the default locale will be
82       *                  used.
83       * @return  a <code>Messages</code> object related to <code>clazz</code> and
84       *          <code>locale</code>, never <code>null</code>.
85       */
86      @SuppressWarnings("unchecked")
87      public static Messages getMessages(final Class clazz, final Locale locale) {
88          if (locale == null) {
89              return new Messages(clazz, Locale.getDefault());
90          }
91          return new Messages(clazz, locale);
92      }
93  
94      /**
95       * Retrieves a localized <code>String</code> which may contains parameters.
96       * This method applies a <code>MessageFormat</code> to the value with the
97       * arguments provided.
98       *
99       * @param   key   the resource key to retrieve the (localized) message.
100      * @param   args  the optional <code>MessageFormat</code> arguments.
101      * @return  the localized messaged related to the key <code>key</code> after
102      *          the substitution of its parameters with values
103      *          <code>args</code>.
104      */
105     public String getString(final String key, final Object ... args) {
106         String rawValue;
107 
108         try {
109             synchronized (bundle) {
110                 rawValue = bundle.getString(key);
111             }
112         } catch (MissingResourceException e) {
113             return key;
114         }
115         try {
116             return MessageFormat.format(rawValue, args);
117         } catch (IllegalArgumentException e) {
118             return rawValue;
119         }
120     }
121 
122     /**
123      * Determines the bundle name for a <code>Class</code>.
124      *
125      * @param   clazz  the <code>Class</code> object used to find the
126      *                 <code>ResourceBundle</code>. Must not be
127      *                 <code>null</code>.
128      * @return  the name of the <code>ResourceBundle</code> related to
129      *          <code>clazz</code>, ever different from <code>null</code>.
130      */
131     @SuppressWarnings("unchecked")
132     private static String getBundleName(final Class clazz) {
133         String packageName = getPackageName(clazz);
134 
135         if (packageName.length() == 0) {
136             return BUNDLE_NAME;
137         }
138         return packageName.concat(BUNDLE_NAME_SUFFIX);
139     }
140 
141     /**
142      * Retrieves the package name for a <code>Class</code> object.
143      * If the class doesn't have a package, the empty string is returned.
144      *
145      * @param   clazz  the class to retrieve its package name. Must not be
146      *                 <code>null</code>.
147      * @return  the package name for <code>clazz</code> if it exists, otherwise
148      *          the empty string.
149      */
150     @SuppressWarnings("unchecked")
151     private static String getPackageName(final Class clazz) {
152         Package pack = clazz.getPackage();
153         String className;
154         int lastDotIndex;
155 
156         if (pack != null) {
157             return pack.getName();
158         }
159 
160         if (clazz.isArray()) {
161             className = clazz.getComponentType().getName();
162         } else {
163             className = clazz.getName();
164         }
165         lastDotIndex = className.lastIndexOf(".");
166         if (lastDotIndex > 0) {
167             return className.substring(0, lastDotIndex);
168         }
169         return "";
170     }
171 }