Mercurial > projects > dwt2
annotate org.eclipse.osgi/supplement/src/org/eclipse/osgi/util/NLS.d @ 105:bbe49769ec18
...
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 08 Nov 2009 12:42:30 +0100 |
parents | 8594250b1d1c |
children |
rev | line source |
---|---|
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
1 /******************************************************************************* |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
2 * Copyright (c) 2005, 2008 IBM Corporation and others. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
3 * All rights reserved. This program and the accompanying materials |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
4 * are made available under the terms of the Eclipse Public License v1.0 |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
5 * which accompanies this distribution, and is available at |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
6 * http://www.eclipse.org/legal/epl-v10.html |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
7 * |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
8 * Contributors: |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
9 * IBM - Initial API and implementation |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
10 *******************************************************************************/ |
105 | 11 // Port to the D programming language: |
12 // Frank Benoit <benoit@tionex.de> | |
87 | 13 module org.eclipse.osgi.util.NLS; |
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
14 |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
15 import java.lang.all; |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
16 |
105 | 17 |
18 import java.io.IOException; | |
19 import java.io.InputStream; | |
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.util.ArrayList; | |
25 import java.util.HashMap; | |
26 import java.util.Locale; | |
27 import java.util.Map; | |
28 import java.util.Properties; | |
29 | |
30 import org.eclipse.osgi.framework.debug_.Debug; | |
31 import org.eclipse.osgi.framework.log.FrameworkLog; | |
32 import org.eclipse.osgi.framework.log.FrameworkLogEntry; | |
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
33 |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
34 /** |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
35 * Common superclass for all message bundle classes. Provides convenience |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
36 * methods for manipulating messages. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
37 * <p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
38 * The <code>#bind</code> methods perform string substitution and should be considered a |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
39 * convenience and <em>not</em> a full substitute replacement for <code>MessageFormat#format</code> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
40 * method calls. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
41 * </p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
42 * <p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
43 * Text appearing within curly braces in the given message, will be interpreted |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
44 * as a numeric index to the corresponding substitution object in the given array. Calling |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
45 * the <code>#bind</code> methods with text that does not map to an integer will result in an |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
46 * {@link IllegalArgumentException}. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
47 * </p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
48 * <p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
49 * Text appearing within single quotes is treated as a literal. A single quote is escaped by |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
50 * a preceeding single quote. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
51 * </p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
52 * <p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
53 * Clients who wish to use the full substitution power of the <code>MessageFormat</code> class should |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
54 * call that class directly and not use these <code>#bind</code> methods. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
55 * </p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
56 * <p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
57 * Clients may subclass this type. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
58 * </p> |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
59 * |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
60 * @since 3.1 |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
61 */ |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
62 public abstract class NLS { |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
63 |
105 | 64 private static final Object[] EMPTY_ARGS = null; |
65 private static final String EXTENSION = ".properties"; //$NON-NLS-1$ | |
66 private static String[] nlSuffixes; | |
67 /* | |
68 * NOTE do not change the name of this field; it is set by the Framework using reflection | |
69 */ | |
70 private static FrameworkLog frameworkLog; | |
71 | |
72 static final int SEVERITY_ERROR = 0x04; | |
73 static final int SEVERITY_WARNING = 0x02; | |
74 /* | |
75 * This object is assigned to the value of a field map to indicate | |
76 * that a translated message has already been assigned to that field. | |
77 */ | |
78 static final Object ASSIGNED = new Object(); | |
79 | |
80 /** | |
81 * Creates a new NLS instance. | |
82 */ | |
83 protected this() { | |
84 super(); | |
85 } | |
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
86 |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
87 /** |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
88 * Bind the given message's substitution locations with the given string value. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
89 * |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
90 * @param message the message to be manipulated |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
91 * @param binding the object to be inserted into the message |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
92 * @return the manipulated String |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
93 * @throws IllegalArgumentException if the text appearing within curly braces in the given message does not map to an integer |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
94 */ |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
95 public static String bind(String message, Object binding) { |
105 | 96 return internalBind(message, null, String.valueOf(binding), null); |
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
97 } |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
98 |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
99 /** |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
100 * Bind the given message's substitution locations with the given string values. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
101 * |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
102 * @param message the message to be manipulated |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
103 * @param binding1 An object to be inserted into the message |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
104 * @param binding2 A second object to be inserted into the message |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
105 * @return the manipulated String |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
106 * @throws IllegalArgumentException if the text appearing within curly braces in the given message does not map to an integer |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
107 */ |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
108 public static String bind(String message, Object binding1, Object binding2) { |
105 | 109 return internalBind(message, null, String.valueOf(binding1), String.valueOf(binding2)); |
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
110 } |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
111 |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
112 /** |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
113 * Bind the given message's substitution locations with the given string values. |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
114 * |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
115 * @param message the message to be manipulated |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
116 * @param bindings An array of objects to be inserted into the message |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
117 * @return the manipulated String |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
118 * @throws IllegalArgumentException if the text appearing within curly braces in the given message does not map to an integer |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
119 */ |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
120 public static String bind(String message, Object[] bindings) { |
105 | 121 return internalBind(message, bindings, null, null); |
122 } | |
123 | |
124 /** | |
125 * Initialize the given class with the values from the specified message bundle. | |
126 * | |
127 * @param bundleName fully qualified path of the class name | |
128 * @param clazz the class where the constants will exist | |
129 */ | |
130 public static void initializeMessages(/+FIXFINAL+/ String bundleName, /+FIXFINAL+/ Class clazz) { | |
131 if (System.getSecurityManager() is null) { | |
132 load(bundleName, clazz); | |
133 return; | |
134 } | |
135 AccessController.doPrivileged(new class() PrivilegedAction { | |
136 public Object run() { | |
137 load(bundleName, clazz); | |
138 return null; | |
139 } | |
140 }); | |
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
141 } |
105 | 142 |
143 /* | |
144 * Perform the string substitution on the given message with the specified args. | |
145 * See the class comment for exact details. | |
146 */ | |
147 private static String internalBind(String message, Object[] args, String argZero, String argOne) { | |
148 if (message is null) | |
149 return "No message available."; //$NON-NLS-1$ | |
150 if (args is null || args.length_ is 0) | |
151 args = EMPTY_ARGS; | |
152 | |
153 int length_ = message.length(); | |
154 //estimate correct size of string buffer to avoid growth | |
155 int bufLen = length_ + (args.length_ * 5); | |
156 if (argZero !is null) | |
157 bufLen += argZero.length() - 3; | |
158 if (argOne !is null) | |
159 bufLen += argOne.length() - 3; | |
160 StringBuffer buffer = new StringBuffer(bufLen < 0 ? 0 : bufLen); | |
161 for (int i = 0; i < length_; i++) { | |
162 char c = message.charAt(i); | |
163 switch (c) { | |
164 case '{' : | |
165 int index = message.indexOf('}', i); | |
166 // if we don't have a matching closing brace then... | |
167 if (index is -1) { | |
168 buffer.append(c); | |
169 break; | |
170 } | |
171 i++; | |
172 if (i >= length_) { | |
173 buffer.append(c); | |
174 break; | |
175 } | |
176 // look for a substitution | |
177 int number = -1; | |
178 try { | |
179 number = Integer.parseInt(message.substring(i, index)); | |
180 } catch (NumberFormatException e) { | |
181 throw new IllegalArgumentException(); | |
182 } | |
183 if (number is 0 && argZero !is null) | |
184 buffer.append(argZero); | |
185 else if (number is 1 && argOne !is null) | |
186 buffer.append(argOne); | |
187 else { | |
188 if (number >= args.length_ || number < 0) { | |
189 buffer.append("<missing argument>"); //$NON-NLS-1$ | |
190 i = index; | |
191 break; | |
192 } | |
193 buffer.append(args[number]); | |
194 } | |
195 i = index; | |
196 break; | |
197 case '\'' : | |
198 // if a single quote is the last char on the line then skip it | |
199 int nextIndex = i + 1; | |
200 if (nextIndex >= length_) { | |
201 buffer.append(c); | |
202 break; | |
203 } | |
204 char next = message.charAt(nextIndex); | |
205 // if the next char is another single quote then write out one | |
206 if (next is '\'') { | |
207 i++; | |
208 buffer.append(c); | |
209 break; | |
210 } | |
211 // otherwise we want to read until we get to the next single quote | |
212 index = message.indexOf('\'', nextIndex); | |
213 // if there are no more in the string, then skip it | |
214 if (index is -1) { | |
215 buffer.append(c); | |
216 break; | |
217 } | |
218 // otherwise write out the chars inside the quotes | |
219 buffer.append(message.substring(nextIndex, index)); | |
220 i = index; | |
221 break; | |
222 default : | |
223 buffer.append(c); | |
224 } | |
225 } | |
226 return buffer.toString(); | |
227 } | |
228 | |
229 /* | |
230 * Build an array of property files to search. The returned array contains | |
231 * the property fields in order from most specific to most generic. | |
232 * So, in the FR_fr locale, it will return file_fr_FR.properties, then | |
233 * file_fr.properties, and finally file.properties. | |
234 */ | |
235 private static String[] buildVariants(String root) { | |
236 if (nlSuffixes is null) { | |
237 //build list of suffixes for loading resource bundles | |
238 String nl = Locale.getDefault().toString(); | |
239 ArrayList result = new ArrayList(4); | |
240 int lastSeparator; | |
241 while (true) { | |
242 result.add('_' + nl + EXTENSION); | |
243 lastSeparator = nl.lastIndexOf('_'); | |
244 if (lastSeparator is -1) | |
245 break; | |
246 nl = nl.substring(0, lastSeparator); | |
247 } | |
248 //add the empty suffix last (most general) | |
249 result.add(EXTENSION); | |
250 nlSuffixes = stringcast( result.toArray)(new String[result.size()]); | |
251 } | |
252 root = root.replace('.', '/'); | |
253 String[] variants = new String[nlSuffixes.length_]; | |
254 for (int i = 0; i < variants.length_; i++) | |
255 variants[i] = root + nlSuffixes[i]; | |
256 return variants; | |
12
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
257 } |
bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
Frank Benoit <benoit@tionex.de>
parents:
diff
changeset
|
258 |
105 | 259 private static void computeMissingMessages(String bundleName, Class clazz, Map fieldMap, Field[] fieldArray, bool isAccessible) { |
260 // iterate over the fields in the class to make sure that there aren't any empty ones | |
261 final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC; | |
262 final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL; | |
263 final int numFields = fieldArray.length_; | |
264 for (int i = 0; i < numFields; i++) { | |
265 Field field = fieldArray[i]; | |
266 if ((field.getModifiers() & MOD_MASK) !is MOD_EXPECTED) | |
267 continue; | |
268 //if the field has a a value assigned, there is nothing to do | |
269 if (fieldMap.get(field.getName()) is ASSIGNED) | |
270 continue; | |
271 try { | |
272 // Set a value for this empty field. We should never get an exception here because | |
273 // we know we have a public static non-final field. If we do get an exception, silently | |
274 // log it and continue. This means that the field will (most likely) be un-initialized and | |
275 // will fail later in the code and if so then we will see both the NPE and this error. | |
276 String value = "NLS missing message: " + field.getName() + " in_: " + bundleName; //$NON-NLS-1$ //$NON-NLS-2$ | |
277 if (Debug.DEBUG_MESSAGE_BUNDLES) | |
278 System.out_.println(value); | |
279 log(SEVERITY_WARNING, value, null); | |
280 if (!isAccessible) | |
281 field.setAccessible(true); | |
282 field.set(null, value); | |
283 } catch (Exception e) { | |
284 log(SEVERITY_ERROR, "Error setting the missing message value for: " + field.getName(), e); //$NON-NLS-1$ | |
285 } | |
286 } | |
287 } | |
288 | |
289 /* | |
290 * Load the given resource bundle using the specified class loader. | |
291 */ | |
292 static void load(/+FIXFINAL+/ String bundleName, Class clazz) { | |
293 long start = System.currentTimeMillis(); | |
294 final Field[] fieldArray = clazz.getDeclaredFields(); | |
295 ClassLoader loader = clazz.getClassLoader(); | |
296 | |
297 bool isAccessible = (clazz.getModifiers() & Modifier.PUBLIC) !is 0; | |
298 | |
299 //build a map of field names to Field objects | |
300 final int len = fieldArray.length_; | |
301 Map fields = new HashMap(len * 2); | |
302 for (int i = 0; i < len; i++) | |
303 fields.put(fieldArray[i].getName(), fieldArray[i]); | |
304 | |
305 // search the variants from most specific to most general, since | |
306 // the MessagesProperties.put method will mark assigned fields | |
307 // to prevent them from being assigned twice | |
308 final String[] variants = buildVariants(bundleName); | |
309 for (int i = 0; i < variants.length_; i++) { | |
310 // loader==null if we're launched off the Java boot classpath | |
311 final InputStream input = loader is null ? ClassLoader.getSystemResourceAsStream(variants[i]) : loader.getResourceAsStream(variants[i]); | |
312 if (input is null) | |
313 continue; | |
314 try { | |
315 final MessagesProperties properties = new MessagesProperties(fields, bundleName, isAccessible); | |
316 properties.load(input); | |
317 } catch (IOException e) { | |
318 log(SEVERITY_ERROR, "Error loading " + variants[i], e); //$NON-NLS-1$ | |
319 } finally { | |
320 if (input !is null) | |
321 try { | |
322 input.close(); | |
323 } catch (IOException e) { | |
324 // ignore | |
325 } | |
326 } | |
327 } | |
328 computeMissingMessages(bundleName, clazz, fields, fieldArray, isAccessible); | |
329 if (Debug.DEBUG_MESSAGE_BUNDLES) | |
330 System.out_.println("Time to load message bundle: " + bundleName + " was " + (System.currentTimeMillis() - start) + "ms."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
331 } | |
332 | |
333 /* | |
334 * The method adds a log entry based on the error message and exception. | |
335 * The output is written to the System.err. | |
336 * | |
337 * This method is only expected to be called if there is a problem in | |
338 * the NLS mechanism. As a result, translation facility is not available | |
339 * here and messages coming out of this log are generally not translated. | |
340 * | |
341 * @param severity - severity of the message (SEVERITY_ERROR or SEVERITY_WARNING) | |
342 * @param message - message to log | |
343 * @param e - exception to log | |
344 */ | |
345 static void log(int severity, String message, Exception e) { | |
346 if (frameworkLog !is null) { | |
347 frameworkLog.log(new FrameworkLogEntry("org.eclipse.osgi", severity, 1, message, 0, e, null)); //$NON-NLS-1$ | |
348 return; | |
349 } | |
350 String statusMsg; | |
351 switch (severity) { | |
352 case SEVERITY_ERROR : | |
353 statusMsg = "Error: "; //$NON-NLS-1$ | |
354 break; | |
355 case SEVERITY_WARNING : | |
356 // intentionally fall through: | |
357 default : | |
358 statusMsg = "Warning: "; //$NON-NLS-1$ | |
359 } | |
360 if (message !is null) | |
361 statusMsg += message; | |
362 if (e !is null) | |
363 statusMsg += ": " + e.getMessage(); //$NON-NLS-1$ | |
364 System.err.println(statusMsg); | |
365 if (e !is null) | |
366 e.printStackTrace(); | |
367 } | |
368 | |
369 /* | |
370 * Class which sub-classes java.util.Properties and uses the #put method | |
371 * to set field values rather than storing the values in the table. | |
372 */ | |
373 private static class MessagesProperties : Properties { | |
374 | |
375 private static final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC; | |
376 private static final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL; | |
377 private static final long serialVersionUID = 1L; | |
378 | |
379 private final String bundleName; | |
380 private final Map fields; | |
381 private final bool isAccessible; | |
382 | |
383 public this(Map fieldMap, String bundleName, bool isAccessible) { | |
384 super(); | |
385 this.fields = fieldMap; | |
386 this.bundleName = bundleName; | |
387 this.isAccessible = isAccessible; | |
388 } | |
389 | |
390 /* (non-Javadoc) | |
391 * @see java.util.Hashtable#put(java.lang.Object, java.lang.Object) | |
392 */ | |
393 public synchronized Object put(Object key, Object value) { | |
394 Object fieldObject = fields.put(key, ASSIGNED); | |
395 // if already assigned, there is nothing to do | |
396 if (fieldObject is ASSIGNED) | |
397 return null; | |
398 if (fieldObject is null) { | |
399 final String msg = "NLS unused message: " + key + " in_: " + bundleName;//$NON-NLS-1$ //$NON-NLS-2$ | |
400 if (Debug.DEBUG_MESSAGE_BUNDLES) | |
401 System.out_.println(msg); | |
402 log(SEVERITY_WARNING, msg, null); | |
403 return null; | |
404 } | |
405 final Field field = cast(Field) fieldObject; | |
406 //can only set value of public static non-final fields | |
407 if ((field.getModifiers() & MOD_MASK) !is MOD_EXPECTED) | |
408 return null; | |
409 try { | |
410 // Check to see if we are allowed to modify the field. If we aren't (for instance | |
411 // if the class is not public) then change the accessible attribute of the field | |
412 // before trying to set the value. | |
413 if (!isAccessible) | |
414 field.setAccessible(true); | |
415 // Set the value into the field. We should never get an exception here because | |
416 // we know we have a public static non-final field. If we do get an exception, silently | |
417 // log it and continue. This means that the field will (most likely) be un-initialized and | |
418 // will fail later in the code and if so then we will see both the NPE and this error. | |
419 field.set(null, value); | |
420 } catch (Exception e) { | |
421 log(SEVERITY_ERROR, "Exception setting field value.", e); //$NON-NLS-1$ | |
422 } | |
423 return null; | |
424 } | |
425 } | |
426 } |