View Javadoc

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