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 }