1
package org.apache.lucene.messages;
4
* Licensed to the Apache Software Foundation (ASF) under one or more
5
* contributor license agreements. See the NOTICE file distributed with
6
* this work for additional information regarding copyright ownership.
7
* The ASF licenses this file to You under the Apache License, Version 2.0
8
* (the "License"); you may not use this file except in compliance with
9
* the License. You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
20
import java.lang.reflect.Field;
21
import java.lang.reflect.Modifier;
22
import java.security.AccessController;
23
import java.security.PrivilegedAction;
24
import java.text.MessageFormat;
25
import java.util.HashMap;
26
import java.util.Iterator;
27
import java.util.Locale;
29
import java.util.MissingResourceException;
30
import java.util.ResourceBundle;
33
* MessageBundles classes extend this class, to implement a bundle.
35
* For Native Language Support (NLS), system of software internationalization.
37
* This interface is similar to the NLS class in eclipse.osgi.util.NLS class -
38
* initializeMessages() method resets the values of all static strings, should
39
* only be called by classes that extend from NLS (see TestMessages.java for
40
* reference) - performs validation of all message in a bundle, at class load
41
* time - performs per message validation at runtime - see NLSTest.java for
44
* MessageBundle classes may subclass this type.
48
private static Map<String, Class<? extends NLS>> bundles =
49
new HashMap<String, Class<? extends NLS>>(0);
55
public static String getLocalizedMessage(String key) {
56
return getLocalizedMessage(key, Locale.getDefault());
59
public static String getLocalizedMessage(String key, Locale locale) {
60
Object message = getResourceBundleObject(key, locale);
61
if (message == null) {
62
return "Message with key:" + key + " and locale: " + locale
65
return message.toString();
68
public static String getLocalizedMessage(String key, Locale locale,
70
String str = getLocalizedMessage(key, locale);
72
if (args.length > 0) {
73
str = MessageFormat.format(str, args);
79
public static String getLocalizedMessage(String key, Object... args) {
80
return getLocalizedMessage(key, Locale.getDefault(), args);
84
* Initialize a given class with the message bundle Keys Should be called from
85
* a class that extends NLS in a static block at class load time.
88
* Property file with that contains the message bundle
90
* where constants will reside
92
protected static void initializeMessages(String bundleName, Class<? extends NLS> clazz) {
95
if (!bundles.containsKey(bundleName))
96
bundles.put(bundleName, clazz);
97
} catch (Throwable e) {
98
// ignore all errors and exceptions
99
// because this function is supposed to be called at class load time.
103
private static Object getResourceBundleObject(String messageKey, Locale locale) {
105
// slow resource checking
106
// need to loop thru all registered resource bundles
107
for (Iterator<String> it = bundles.keySet().iterator(); it.hasNext();) {
108
Class<? extends NLS> clazz = bundles.get(it.next());
109
ResourceBundle resourceBundle = ResourceBundle.getBundle(clazz.getName(),
111
if (resourceBundle != null) {
113
Object obj = resourceBundle.getObject(messageKey);
116
} catch (MissingResourceException e) {
117
// just continue it might be on the next resource bundle
121
// if resource is not found
128
private static void load(Class<? extends NLS> clazz) {
129
final Field[] fieldArray = clazz.getDeclaredFields();
131
boolean isFieldAccessible = (clazz.getModifiers() & Modifier.PUBLIC) != 0;
133
// build a map of field names to Field objects
134
final int len = fieldArray.length;
135
Map<String, Field> fields = new HashMap<String, Field>(len * 2);
136
for (int i = 0; i < len; i++) {
137
fields.put(fieldArray[i].getName(), fieldArray[i]);
138
loadfieldValue(fieldArray[i], isFieldAccessible, clazz);
144
* @param isFieldAccessible
146
private static void loadfieldValue(Field field, boolean isFieldAccessible,
147
Class<? extends NLS> clazz) {
148
int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
149
int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
150
if ((field.getModifiers() & MOD_MASK) != MOD_EXPECTED)
153
// Set a value for this empty field.
154
if (!isFieldAccessible)
155
makeAccessible(field);
157
field.set(null, field.getName());
158
validateMessage(field.getName(), clazz);
159
} catch (IllegalArgumentException e) {
161
} catch (IllegalAccessException e) {
170
private static void validateMessage(String key, Class<? extends NLS> clazz) {
171
// Test if the message is present in the resource bundle
173
ResourceBundle resourceBundle = ResourceBundle.getBundle(clazz.getName(),
174
Locale.getDefault());
175
if (resourceBundle != null) {
176
Object obj = resourceBundle.getObject(key);
178
System.err.println("WARN: Message with key:" + key + " and locale: "
179
+ Locale.getDefault() + " not found.");
181
} catch (MissingResourceException e) {
182
System.err.println("WARN: Message with key:" + key + " and locale: "
183
+ Locale.getDefault() + " not found.");
184
} catch (Throwable e) {
185
// ignore all other errors and exceptions
186
// since this code is just a test to see if the message is present on the
192
* Make a class field accessible
194
private static void makeAccessible(final Field field) {
195
if (System.getSecurityManager() == null) {
196
field.setAccessible(true);
198
AccessController.doPrivileged(new PrivilegedAction<Void>() {
200
field.setAccessible(true);