|
1 /* |
|
2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 package com.nokia.mj.impl.utils; |
|
20 |
|
21 import com.nokia.mj.impl.coreui.CoreUi; |
|
22 import java.util.Hashtable; |
|
23 |
|
24 |
|
25 /** |
|
26 * Resource loader to get localised strings and Formatter patterns. |
|
27 * <br> |
|
28 * Usage: |
|
29 * <pre> |
|
30 * ResourceLoader res = ResourceLoader.getInstance("javaapplicationinstaller", "txt_java_inst_"); |
|
31 * Label subjectLabel = createLabel( |
|
32 * res.format("subject").arg(certificate.getSubject()).toString(), |
|
33 * horizontalSpan, labelStyle); |
|
34 * </pre> |
|
35 * @see ResourceLoader |
|
36 */ |
|
37 class ResourceLoaderQt extends ResourceLoader |
|
38 { |
|
39 /** |
|
40 * Resource string map for the resources that have been fetched |
|
41 * at least once. |
|
42 */ |
|
43 private Hashtable iResourceMap = new Hashtable(); |
|
44 |
|
45 /** Resource name passed when ResourceLoader is constructed. */ |
|
46 private String iResourceName = null; |
|
47 |
|
48 /** Array of resource names. */ |
|
49 private String[] iResourceNames = null; |
|
50 |
|
51 /** Resource name prefix passed when ResourceLoader is constructed. */ |
|
52 private String iPrefix = null; |
|
53 |
|
54 /** Array of resource name prefixes. */ |
|
55 private String[] iPrefixes = null; |
|
56 |
|
57 /** Array of handles to native translator objects. */ |
|
58 private int[] iTranslators = null; |
|
59 |
|
60 /*** ----------------------------- PUBLIC ------------------------------ */ |
|
61 |
|
62 /** |
|
63 * Returns a resource loader instance. |
|
64 * |
|
65 * @param avkonFileName this parameter is ignored |
|
66 * @param avkonPrefix this parameter is ignored |
|
67 * @param qtFileName name of the Qt resource file |
|
68 * @param qtPrefix prefix added before each id when retrieving |
|
69 * @return resource loader instance |
|
70 */ |
|
71 public static ResourceLoader getInstance(String avkonFileName, |
|
72 String avkonPrefix, |
|
73 String qtFileName, |
|
74 String qtPrefix) |
|
75 { |
|
76 return getInstance(qtFileName, qtPrefix); |
|
77 } |
|
78 |
|
79 /** |
|
80 * Returns a resource loader instance. |
|
81 * |
|
82 * @param resourceName comma separated list of resource file names |
|
83 * @param prefix comma separated list of prefixes added before each |
|
84 * id when retrieving |
|
85 * @return resource loader instance |
|
86 */ |
|
87 public static ResourceLoader getInstance(String resourceName, String prefix) |
|
88 { |
|
89 String key = resourceName + ":" + prefix; |
|
90 ResourceLoader result = (ResourceLoader)iResourceLoaders.get(key); |
|
91 if (result == null) |
|
92 { |
|
93 result = new ResourceLoaderQt(resourceName, prefix); |
|
94 iResourceLoaders.put(key, result); |
|
95 } |
|
96 return result; |
|
97 } |
|
98 |
|
99 /** |
|
100 * Get a string formatter of a given resource id. |
|
101 * |
|
102 * @param id comma separated list of resource ids |
|
103 * @return formatter instance |
|
104 * @see Formatter |
|
105 */ |
|
106 public Formatter format(String id) |
|
107 { |
|
108 return new FormatterQt(this, id); |
|
109 } |
|
110 |
|
111 /** |
|
112 * Get a string formatter of a given resource id. |
|
113 * |
|
114 * @param id resource id |
|
115 * @return formatter instance |
|
116 * @see Formatter |
|
117 */ |
|
118 public Formatter format(Id id) |
|
119 { |
|
120 return new FormatterQt(this, id.getString(QT)); |
|
121 } |
|
122 |
|
123 /** |
|
124 * Formats localised text with specified parameters from an array. |
|
125 * |
|
126 * @param id comma separated list of resource ids |
|
127 * @param textParameters parameters to be filled into the text |
|
128 * @return localised text formatted with the provided parameters |
|
129 * @see Formatter |
|
130 */ |
|
131 public String format(String id, Object[] textParameters) |
|
132 { |
|
133 return new FormatterQt(this, id).format(textParameters); |
|
134 } |
|
135 |
|
136 /** |
|
137 * Formats localised text with specified parameters from an array. |
|
138 * |
|
139 * @param id resource id |
|
140 * @param textParameters parameters to be filled into the text |
|
141 * @return localised text formatted with the provided parameters |
|
142 * @see Formatter |
|
143 */ |
|
144 public String format(Id id, Object[] textParameters) |
|
145 { |
|
146 return new FormatterQt(this, id.getString(QT)).format(textParameters); |
|
147 } |
|
148 |
|
149 |
|
150 /*** ----------------------------- PACKAGE ---------------------------- */ |
|
151 |
|
152 /** |
|
153 * Releases resources and destroys this ResourceLoader instance. |
|
154 */ |
|
155 void destroy() |
|
156 { |
|
157 deleteTranslators(); |
|
158 } |
|
159 |
|
160 /** |
|
161 * Get a plain string resource with a given resource id. |
|
162 * |
|
163 * @param id resource id, either with prefix or without |
|
164 * @param n used to identify plural forms |
|
165 * @return resource string, or the id if does not exist |
|
166 */ |
|
167 synchronized String string(final String id, final int n) |
|
168 { |
|
169 String str = (String)iResourceMap.get(id+n); |
|
170 if (str == null) |
|
171 { |
|
172 str = getResourceStringByList(id, n); |
|
173 // Put to resource map with original key for quick retrieval. |
|
174 iResourceMap.put(id, str+n); |
|
175 } |
|
176 return str; |
|
177 } |
|
178 |
|
179 /*** ----------------------------- PRIVATE ---------------------------- */ |
|
180 |
|
181 /** |
|
182 * Creates resource loader, using the current locale of the environment. |
|
183 * |
|
184 * @param resourceName name of the resource |
|
185 * @param aPrefix prefix added before each id when retrieving |
|
186 */ |
|
187 private ResourceLoaderQt(String aResourceName, String aPrefix) |
|
188 { |
|
189 setResourceName(aResourceName); |
|
190 setPrefix(aPrefix); |
|
191 if (!loadTranslators()) |
|
192 { |
|
193 throw new IllegalArgumentException( |
|
194 "Translations not found for " + aResourceName); |
|
195 } |
|
196 } |
|
197 |
|
198 /** |
|
199 * Initializes member variables according to given resource name. |
|
200 * |
|
201 * @param aResourceName comma separated list of resource names |
|
202 */ |
|
203 private void setResourceName(String aResourceName) |
|
204 { |
|
205 iResourceName = aResourceName; |
|
206 iResourceNames = Tokenizer.split(iResourceName, SEPARATOR); |
|
207 if (iResourceNames == null) |
|
208 { |
|
209 iResourceNames = new String[0]; |
|
210 } |
|
211 for (int i = 0; i < iResourceNames.length; i++) |
|
212 { |
|
213 iResourceNames[i] = iResourceNames[i].trim(); |
|
214 } |
|
215 } |
|
216 |
|
217 /** |
|
218 * Initializes member variables according to given prefix. |
|
219 * |
|
220 * @param aPrefix comma separated list of text id prefixes |
|
221 */ |
|
222 private void setPrefix(String aPrefix) |
|
223 { |
|
224 iPrefix = aPrefix; |
|
225 iPrefixes = Tokenizer.split(iPrefix, SEPARATOR); |
|
226 if (iPrefixes == null) |
|
227 { |
|
228 iPrefixes = new String[0]; |
|
229 } |
|
230 for (int i = 0; i < iPrefixes.length; i++) |
|
231 { |
|
232 iPrefixes[i] = iPrefixes[i].trim(); |
|
233 } |
|
234 } |
|
235 |
|
236 /** |
|
237 * Initializes iTranslators array from given resource files. |
|
238 * |
|
239 * @param true if operation succeeds. |
|
240 */ |
|
241 private boolean loadTranslators() |
|
242 { |
|
243 if (iResourceName == null) |
|
244 { |
|
245 return false; |
|
246 } |
|
247 iTranslators = new int[iResourceNames.length]; |
|
248 CoreUi.runInSyncUiThread(new Runnable() { |
|
249 public void run() |
|
250 { |
|
251 for (int i = 0; i < iResourceNames.length; i++) |
|
252 { |
|
253 iTranslators[i] = _createTranslator(iResourceNames[i]); |
|
254 if (iTranslators[i] < 0) |
|
255 { |
|
256 Logger.ILOG(Logger.EUtils, |
|
257 "ResourceLoaderQt: Cannot load resource file " + |
|
258 iResourceNames[i] + ", error: " + |
|
259 iTranslators[i]); |
|
260 } |
|
261 } |
|
262 } |
|
263 }); |
|
264 boolean result = false; |
|
265 for (int i = 0; i < iTranslators.length; i++) |
|
266 { |
|
267 if (iTranslators[i] > 0) |
|
268 { |
|
269 // Return true if loading succeeds for at least one translator. |
|
270 result = true; |
|
271 break; |
|
272 } |
|
273 } |
|
274 return result; |
|
275 } |
|
276 |
|
277 /** |
|
278 * Deletes translator from iTranslators array. |
|
279 */ |
|
280 private void deleteTranslators() |
|
281 { |
|
282 CoreUi.runInSyncUiThread(new Runnable() { |
|
283 public void run() |
|
284 { |
|
285 for (int i = 0; i < iTranslators.length; i++) |
|
286 { |
|
287 if (iTranslators[i] <= 0) |
|
288 { |
|
289 continue; |
|
290 } |
|
291 int result = _deleteTranslator(iTranslators[i]); |
|
292 if (result < 0) |
|
293 { |
|
294 Logger.WLOG(Logger.EUtils, |
|
295 "ResourceLoaderQt: Deleting translator for resource " + |
|
296 iResourceNames[i] + " failed, error: " + |
|
297 result); |
|
298 } |
|
299 } |
|
300 } |
|
301 }); |
|
302 } |
|
303 |
|
304 /** |
|
305 * Get a string with a given comma separated resource id list. |
|
306 * |
|
307 * @param id comma separated resource id list, either with prefix or without |
|
308 * @param n used to identify plural forms |
|
309 * @return resource string, or the id if does not exist |
|
310 */ |
|
311 private String getResourceStringByList(String id, int n) |
|
312 { |
|
313 String str = null; |
|
314 String[] ids = Tokenizer.split(id, SEPARATOR); |
|
315 String strIn = null; |
|
316 String strOut = null; |
|
317 for (int i = 0; i < ids.length && str == null; i++) |
|
318 { |
|
319 for (int j = 0; j < iTranslators.length && str == null; j++) |
|
320 { |
|
321 if (iTranslators[j] <= 0) |
|
322 { |
|
323 // Skip invalid translator handles. |
|
324 continue; |
|
325 } |
|
326 // Check if id already has prefix. |
|
327 if (iPrefixes != null && iPrefixes.length > j && |
|
328 !ids[i].startsWith(iPrefixes[j])) |
|
329 { |
|
330 // Try with prefix and id. |
|
331 strIn = iPrefixes[j] + ids[i]; |
|
332 } |
|
333 else |
|
334 { |
|
335 // Try with id. |
|
336 strIn = ids[i]; |
|
337 } |
|
338 strOut = _translate(iTranslators[j], strIn, n); |
|
339 if (!strIn.equals(strOut)) |
|
340 { |
|
341 // Translation was found. |
|
342 str = strOut; |
|
343 } |
|
344 } |
|
345 } |
|
346 if (str == null) |
|
347 { |
|
348 // Not found. Use the id itself. |
|
349 str = id; |
|
350 Logger.WLOG(Logger.EUtils, |
|
351 "ResourceLoaderQt: Cannot find resource: " + id + |
|
352 ", prefix: " + iPrefix); |
|
353 } |
|
354 return str; |
|
355 } |
|
356 |
|
357 /*** ----------------------------- NATIVE ----------------------------- */ |
|
358 |
|
359 /** |
|
360 * Creates native translator object. |
|
361 * |
|
362 * @param aResourceFilename resource filename |
|
363 * @return handle to native side translator object, or negative |
|
364 * error code |
|
365 */ |
|
366 private static native int _createTranslator(String aResourceFilename); |
|
367 |
|
368 /** |
|
369 * Deletes native translator object. |
|
370 * |
|
371 * @param handle to native side translator object |
|
372 * @return 0 if deletion was successful, or negative error code |
|
373 */ |
|
374 private static native int _deleteTranslator(int aHandle); |
|
375 |
|
376 /** |
|
377 * Fetches localized text for given text id. |
|
378 * |
|
379 * @param aHandle translator to be used |
|
380 * @param aId text id |
|
381 * @param aN used to identify plural forms |
|
382 * @return localized text, or aId if text is not found |
|
383 */ |
|
384 private static native String _translate(int aHandle, String aId, int aN); |
|
385 } |