KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > api > LocalizedMessage


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2005 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19
package com.puppycrawl.tools.checkstyle.api;
20
21 import java.text.MessageFormat JavaDoc;
22 import java.util.Arrays JavaDoc;
23 import java.util.Collections JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.Locale JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.MissingResourceException JavaDoc;
28 import java.util.ResourceBundle JavaDoc;
29
30
31 /**
32  * Represents a message that can be localised. The translations come from
33  * message.properties files. The underlying implementation uses
34  * java.text.MessageFormat.
35  *
36  * @author Oliver Burn
37  * @author lkuehne
38  * @version 1.0
39  */

40 public final class LocalizedMessage
41     implements Comparable JavaDoc
42 {
43     /** hash function multiplicand */
44     private static final int HASH_MULT = 29;
45
46     /** the locale to localise messages to **/
47     private static Locale JavaDoc sLocale = Locale.getDefault();
48
49     /**
50      * A cache that maps bundle names to RessourceBundles.
51      * Avoids repetitive calls to ResourceBundle.getBundle().
52      * TODO: The cache should be cleared at some point.
53      */

54     private static final Map JavaDoc BUNDLE_CACHE =
55         Collections.synchronizedMap(new HashMap JavaDoc());
56
57     /** the line number **/
58     private final int mLineNo;
59     /** the column number **/
60     private final int mColNo;
61
62     /** the severity level **/
63     private final SeverityLevel mSeverityLevel;
64
65     /** the id of the module generating the message. */
66     private final String JavaDoc mModuleId;
67
68     /** the default severity level if one is not specified */
69     private static final SeverityLevel DEFAULT_SEVERITY = SeverityLevel.ERROR;
70
71     /** key for the message format **/
72     private final String JavaDoc mKey;
73
74     /** arguments for MessageFormat **/
75     private final Object JavaDoc[] mArgs;
76
77     /** name of the resource bundle to get messages from **/
78     private final String JavaDoc mBundle;
79
80     /** class of the source for this LocalizedMessage */
81     private final Class JavaDoc mSourceClass;
82
83     /** {@inheritDoc} */
84     public boolean equals(Object JavaDoc aObject)
85     {
86         if (this == aObject) {
87             return true;
88         }
89         if (!(aObject instanceof LocalizedMessage)) {
90             return false;
91         }
92
93         final LocalizedMessage localizedMessage = (LocalizedMessage) aObject;
94
95         if (mColNo != localizedMessage.mColNo) {
96             return false;
97         }
98         if (mLineNo != localizedMessage.mLineNo) {
99             return false;
100         }
101         if (!mKey.equals(localizedMessage.mKey)) {
102             return false;
103         }
104
105         if (!Arrays.equals(mArgs, localizedMessage.mArgs)) {
106             return false;
107         }
108         // ignoring mBundle for perf reasons.
109

110         // we currently never load the same error from different bundles.
111

112         return true;
113     }
114
115     /**
116      * {@inheritDoc}
117      */

118     public int hashCode()
119     {
120         int result;
121         result = mLineNo;
122         result = HASH_MULT * result + mColNo;
123         result = HASH_MULT * result + mKey.hashCode();
124         for (int i = 0; i < mArgs.length; i++) {
125             result = HASH_MULT * result + mArgs[i].hashCode();
126         }
127         return result;
128     }
129
130     /**
131      * Creates a new <code>LocalizedMessage</code> instance.
132      *
133      * @param aLineNo line number associated with the message
134      * @param aColNo column number associated with the message
135      * @param aBundle resource bundle name
136      * @param aKey the key to locate the translation
137      * @param aArgs arguments for the translation
138      * @param aSeverityLevel severity level for the message
139      * @param aModuleId the id of the module the message is associated with
140      * @param aSourceClass the Class that is the source of the message
141      */

142     public LocalizedMessage(int aLineNo,
143                             int aColNo,
144                             String JavaDoc aBundle,
145                             String JavaDoc aKey,
146                             Object JavaDoc[] aArgs,
147                             SeverityLevel aSeverityLevel,
148                             String JavaDoc aModuleId,
149                             Class JavaDoc aSourceClass)
150     {
151         mLineNo = aLineNo;
152         mColNo = aColNo;
153         mKey = aKey;
154         mArgs = aArgs;
155         mBundle = aBundle;
156         mSeverityLevel = aSeverityLevel;
157         mModuleId = aModuleId;
158         mSourceClass = aSourceClass;
159     }
160
161     /**
162      * Creates a new <code>LocalizedMessage</code> instance.
163      *
164      * @param aLineNo line number associated with the message
165      * @param aColNo column number associated with the message
166      * @param aBundle resource bundle name
167      * @param aKey the key to locate the translation
168      * @param aArgs arguments for the translation
169      * @param aModuleId the id of the module the message is associated with
170      * @param aSourceClass the Class that is the source of the message
171      */

172     public LocalizedMessage(int aLineNo,
173                             int aColNo,
174                             String JavaDoc aBundle,
175                             String JavaDoc aKey,
176                             Object JavaDoc[] aArgs,
177                             String JavaDoc aModuleId,
178                             Class JavaDoc aSourceClass)
179     {
180         this(aLineNo,
181              aColNo,
182              aBundle,
183              aKey,
184              aArgs,
185              DEFAULT_SEVERITY,
186              aModuleId,
187              aSourceClass);
188     }
189
190     /**
191      * Creates a new <code>LocalizedMessage</code> instance.
192      *
193      * @param aLineNo line number associated with the message
194      * @param aBundle resource bundle name
195      * @param aKey the key to locate the translation
196      * @param aArgs arguments for the translation
197      * @param aSeverityLevel severity level for the message
198      * @param aModuleId the id of the module the message is associated with
199      * @param aSourceClass the source class for the message
200      */

201     public LocalizedMessage(int aLineNo,
202                             String JavaDoc aBundle,
203                             String JavaDoc aKey,
204                             Object JavaDoc[] aArgs,
205                             SeverityLevel aSeverityLevel,
206                             String JavaDoc aModuleId,
207                             Class JavaDoc aSourceClass)
208     {
209         this(aLineNo, 0, aBundle, aKey, aArgs, aSeverityLevel, aModuleId,
210                 aSourceClass);
211     }
212
213     /**
214      * Creates a new <code>LocalizedMessage</code> instance. The column number
215      * defaults to 0.
216      *
217      * @param aLineNo line number associated with the message
218      * @param aBundle name of a resource bundle that contains error messages
219      * @param aKey the key to locate the translation
220      * @param aArgs arguments for the translation
221      * @param aModuleId the id of the module the message is associated with
222      * @param aSourceClass the name of the source for the message
223      */

224     public LocalizedMessage(
225         int aLineNo,
226         String JavaDoc aBundle,
227         String JavaDoc aKey,
228         Object JavaDoc[] aArgs,
229         String JavaDoc aModuleId,
230         Class JavaDoc aSourceClass)
231     {
232         this(aLineNo, 0, aBundle, aKey, aArgs, DEFAULT_SEVERITY, aModuleId,
233                 aSourceClass);
234     }
235
236     /** @return the translated message **/
237     public String JavaDoc getMessage()
238     {
239         try {
240             // Important to use the default class loader, and not the one in
241
// the GlobalProperties object. This is because the class loader in
242
// the GlobalProperties is specified by the user for resolving
243
// custom classes.
244
final ResourceBundle JavaDoc bundle = getBundle(mBundle);
245             final String JavaDoc pattern = bundle.getString(mKey);
246             return MessageFormat.format(pattern, mArgs);
247         }
248         catch (final MissingResourceException JavaDoc ex) {
249             // If the Check author didn't provide i18n resource bundles
250
// and logs error messages directly, this will return
251
// the author's original message
252
return MessageFormat.format(mKey, mArgs);
253         }
254     }
255
256     /**
257      * Find a ResourceBundle for a given bundle name. Uses the classloader
258      * of the class emitting this message, to be sure to get the correct
259      * bundle.
260      * @param aBundleName the bundle name
261      * @return a ResourceBundle
262      */

263     private ResourceBundle JavaDoc getBundle(String JavaDoc aBundleName)
264     {
265         synchronized (BUNDLE_CACHE) {
266             ResourceBundle JavaDoc bundle = (ResourceBundle JavaDoc) BUNDLE_CACHE
267                     .get(aBundleName);
268             if (bundle == null) {
269                 bundle = ResourceBundle.getBundle(aBundleName, sLocale,
270                         mSourceClass.getClassLoader());
271                 BUNDLE_CACHE.put(aBundleName, bundle);
272             }
273             return bundle;
274         }
275     }
276
277     /** @return the line number **/
278     public int getLineNo()
279     {
280         return mLineNo;
281     }
282
283     /** @return the column number **/
284     public int getColumnNo()
285     {
286         return mColNo;
287     }
288
289     /** @return the severity level **/
290     public SeverityLevel getSeverityLevel()
291     {
292         return mSeverityLevel;
293     }
294
295     /** @return the module identifier. */
296     public String JavaDoc getModuleId()
297     {
298         return mModuleId;
299     }
300
301     /**
302      * Returns the message key to locate the translation, can also be used
303      * in IDE plugins to map error messages to corrective actions.
304      *
305      * @return the message key
306      */

307     public String JavaDoc getKey()
308     {
309         return mKey;
310     }
311
312     /** @return the name of the source for this LocalizedMessage */
313     public String JavaDoc getSourceName()
314     {
315         return mSourceClass.getName();
316     }
317
318     /** @param aLocale the locale to use for localization **/
319     public static void setLocale(Locale JavaDoc aLocale)
320     {
321         sLocale = aLocale;
322     }
323
324     ////////////////////////////////////////////////////////////////////////////
325
// Interface Comparable methods
326
////////////////////////////////////////////////////////////////////////////
327

328     /** {@inheritDoc} */
329     public int compareTo(Object JavaDoc aOther)
330     {
331         final LocalizedMessage lt = (LocalizedMessage) aOther;
332         if (getLineNo() == lt.getLineNo()) {
333             if (getColumnNo() == lt.getColumnNo()) {
334                 return getMessage().compareTo(lt.getMessage());
335             }
336             return (getColumnNo() < lt.getColumnNo()) ? -1 : 1;
337         }
338
339         return (getLineNo() < lt.getLineNo()) ? -1 : 1;
340     }
341 }
342
Popular Tags