/[schmitzm]/trunk/src/skrueger/i8n/Translation.java
ViewVC logotype

Contents of /trunk/src/skrueger/i8n/Translation.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 453 - (show annotations)
Fri Oct 9 21:50:48 2009 UTC (15 years, 4 months ago) by mojays
Original Path: branches/1.0-gt2-2.6/src/skrueger/i8n/Translation.java
File size: 11214 byte(s)
Bugs with Copyable (Feature)ChartStyles fixed. Should work now!
1 /*******************************************************************************
2 * Copyright (c) 2009 Martin O. J. Schmitz.
3 *
4 * This file is part of the SCHMITZM library - a collection of utility
5 * classes based on Java 1.6, focusing (not only) on Java Swing
6 * and the Geotools library.
7 *
8 * The SCHMITZM project is hosted at:
9 * http://wald.intevation.org/projects/schmitzm/
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 3
14 * of the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License (license.txt)
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 * or try this link: http://www.gnu.org/licenses/lgpl.html
25 *
26 * Contributors:
27 * Martin O. J. Schmitz - initial API and implementation
28 * Stefan A. Krüger - additional utility classes
29 ******************************************************************************/
30 package skrueger.i8n;
31
32 import java.awt.event.ActionEvent;
33 import java.awt.event.ActionListener;
34 import java.beans.PropertyChangeEvent;
35 import java.beans.PropertyChangeListener;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Locale;
40 import java.util.Random;
41
42 import javax.swing.JComponent;
43
44 import org.apache.log4j.Logger;
45 import org.opengis.util.InternationalString;
46
47 import skrueger.geotools.Copyable;
48
49 /**
50 * Represents a {@link HashMap} of translations. toString() returns the
51 * appropriate translation
52 *
53 * @author @author <a href="mailto:[email protected]">Stefan Alfons
54 * Kr&uuml;ger</a>
55 */
56
57 public class Translation extends HashMap<String, String> implements Copyable<Translation>{
58 public static final String LOCALECHANGE_PROPERTY = "localechange";
59 public static final String NO_TRANSLATION = "NO TRANSLATION";
60 public static final String DEFAULT_KEY = "default";
61 static final Logger log = Logger.getLogger(Translation.class);
62 static String activeLang = Locale.getDefault().getLanguage();
63
64 static protected List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
65
66 static {
67
68 // TODO default aus Locale auslesen und mit möglichen vergleichen...
69 // mmm.. vor laden von atlasml immer DEFAULT_KEY, also hier nicht
70
71 // Get default locale
72 Locale locale = Locale.getDefault();
73 setActiveLang(locale.getLanguage());
74 }
75
76 private List<ActionListener> actionListeners = new ArrayList<ActionListener>();
77
78 @Override
79 /*
80 * @comment To make a copy of a translation see methods toOneLine() and
81 * fromOneLine()
82 */
83 public Translation clone() {
84 throw new RuntimeException("use copy()");
85 // return (Translation) super.clone();
86 }
87
88 /**
89 * Get the two-letter language sting that is active
90 */
91 public static String getActiveLang() {
92 return activeLang;
93 }
94
95 /**
96 * Set up the {@link Translation}-system to use language. If a change is
97 * performed, events are fired to listeners. Nothing is done if the new
98 * language equals the old language. The system's default locale is changed.
99 *
100 * @param newLang
101 * The ISO Code of the new active language
102 */
103 public static void setActiveLang(String newLang) {
104 setActiveLang(newLang, true);
105 }
106
107 /**
108 * Set up the {@link Translation}-system to use language. If a change is
109 * performed, events are fired to listeners. Nothing is done if the new
110 * language equals the old language.
111 *
112 * @param newLang
113 * The ISO Code of the new active language
114 *
115 * @param setDefaultLocale
116 * Shall the system's default locale be changed?
117 */
118 public static void setActiveLang(String newLang, boolean setDefaultLocale) {
119 if (getActiveLang().equals(newLang)) {
120 return;
121 }
122
123 if (!I8NUtil.isValidISOLangCode(newLang)) {
124 throw new IllegalArgumentException("'" + newLang
125 + "' is not a valid ISO language code.");
126 }
127
128 Locale newLocale = new Locale(newLang);
129 if (setDefaultLocale)
130 Locale.setDefault(newLocale);
131
132 /**
133 * Setting default locale for Swing JComponents to work around bug
134 * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4884480
135 */
136 JComponent.setDefaultLocale(newLocale);
137
138 Translation.activeLang = newLang;
139
140 fireLocaleChangeEvents();
141
142 log.info("skrueger.i8n.Translation switched ActiveLang to " + newLang);
143 }
144
145 /**
146 * Initializes a new {@link Translation} with a default translation if a
147 * simple text is passed. If a "oneLine" text is parsed, it is interpreted.
148 * Other translations may be added later - this is a HashMap<br/>
149 *
150 * @param defaultTranslation
151 *
152 * @see public Translation(List<String> languages, String
153 * defaultTranslation) {
154 *
155 */
156 public Translation(String defaultTranslation) {
157
158 fromOneLine(defaultTranslation);
159
160 }
161
162 /**
163 * Initializes a new {@link Translation}, an uses the given String to
164 * initialize the {@link Translation} for all languages codes passed.
165 *
166 * The translations can be changed later
167 */
168 public Translation(List<String> languages, String defaultTranslation) {
169 // put(DEFAULT_KEY, defaultTranslation);
170 if (languages == null) {
171 put(DEFAULT_KEY, defaultTranslation);
172 } else
173 for (String code : languages) {
174 if (code.equals(getActiveLang())) {
175 put(code, defaultTranslation);
176 }
177 }
178 }
179
180 /**
181 * Sometimes Translations are optional, like for keywords.
182 */
183 public Translation() {
184 }
185
186 /**
187 * Fills the {@link Translation} with the values coded into the String
188 * Format of {@link String} is: "de{Baum}en{tree}"
189 * <p>
190 * <ul>
191 * <li>If <code>oneLineCoded</code> is empty or null, NO TRANSLATION is set.
192 * <li>If format can't be recognized, the {@link String} is interpreted as
193 * the translation in the <code>{@value #DEFAULT_KEY}</code> language
194 *
195 * @author Stefan Alfons Krüger
196 */
197 public void fromOneLine(final String oneLineCoded) {
198
199 clear();
200
201 try {
202
203 if ((oneLineCoded == null) || (oneLineCoded.equals(""))) {
204 put(DEFAULT_KEY, "");
205 return;
206 }
207
208 if (oneLineCoded.indexOf("}") == -1) {
209 // log.warn("The String '"+oneLineCoded+"' is not in oneLine coded => put(DEFAULT_KEY,oneLineCoded);");
210 put(DEFAULT_KEY, oneLineCoded);
211 }
212
213 String eatUp = oneLineCoded;
214 while (eatUp.indexOf("}") != -1) {
215 String substring = eatUp.substring(0, eatUp.indexOf("}"));
216
217 // log.debug("substring = "+substring);
218 String key = substring.substring(0, substring.indexOf("{"));
219 String value = substring.substring(substring.indexOf("{") + 1,
220 substring.length());
221 // log.debug("key="+key);
222 // log.debug("value="+value);
223 put(key, value);
224 eatUp = eatUp.substring(eatUp.indexOf("}") + 1);
225 }
226 } catch (Exception e) {
227 log.warn("Error while reading the oneLineCode '"+oneLineCoded+"'", e);
228 log.warn("Translation will be empty!");
229 }
230 }
231
232 /**
233 * Exports the Translations to a String of the Format: "de{Baum}en{tree}"
234 *
235 * @author Stefan Alfons Krüger
236 */
237 public String toOneLine() {
238 return I8NUtil.toOneLine(this);
239 }
240
241 /**
242 * Returns the right translation by using the {@link #activeLang} field. If
243 * no translation is set, an ugly String {@link #NO_TRANSLATION} will re
244 * returned. This might be changed for the final release. If the correct
245 * language was not found, any entry in the {@link Translation}
246 * {@link HashMap} will be returned, that contains more than an empty
247 * string.
248 */
249 @Override
250 public String toString() {
251 if (get(activeLang) != null) {
252 return get(activeLang);
253 }
254 // ****************************************************************************
255 // MS: The ISDSS needs the concept of the default lang!! So I took the
256 // following in again!!
257 // ****************************************************************************
258 // else return "";
259 // //****************************************************************************
260 // // The following is commented out.. the concept of the default lang
261 // seems to be bad....
262 // //****************************************************************************
263 // MS:
264 else {
265 if (get(DEFAULT_KEY) != null) {
266 return get(DEFAULT_KEY);
267 }
268
269 // log.debug("return first best <> '' ");
270 if (size() > 0)
271 for (String s : values()) {
272 if ((s != null) && (s.trim().length() > 0))
273 return s;
274 }
275 }
276 // log.warn("No translation found!");
277 return NO_TRANSLATION;
278 }
279
280
281 /**
282 * {@link PropertyChangeListener} can be registered to be informed when the
283 * {@link Locale} changed.
284 *
285 * @param propertyChangeListener
286 */
287 public static void addLocaleChangeListener(
288 PropertyChangeListener propertyChangeListener) {
289 listeners.add(propertyChangeListener);
290 }
291
292 /**
293 * Informs all registered {@link PropertyChangeListener}s about a change of
294 * the the {@link Locale}.
295 */
296 public static void fireLocaleChangeEvents() {
297 PropertyChangeEvent pce = new PropertyChangeEvent(new Translation(
298 new ArrayList<String>(), "fakeSource"), LOCALECHANGE_PROPERTY,
299 null, getActiveLang());
300 for (PropertyChangeListener pcl : listeners) {
301 if (pcl != null)
302 pcl.propertyChange(pce);
303 }
304 }
305
306 public void addTranslationChangeListener(ActionListener actionListener) {
307 actionListeners.add(actionListener);
308 }
309
310 public boolean removeTranslationChangeListener(ActionListener actionListener) {
311 return actionListeners.remove(actionListener);
312 }
313
314 public void fireTranslationChangedEvents(String lang) {
315 ActionEvent ae = new ActionEvent(this, new Random().nextInt(), lang);
316
317 for (ActionListener al : actionListeners) {
318 al.actionPerformed( ae);
319 }
320 }
321
322 @Override
323 public String put(String lang, String value) {
324 String result = super.put(lang, value);
325 fireTranslationChangedEvents(lang);
326 return result;
327 }
328
329 public void fromOneLine(InternationalString iString) {
330 if (iString != null)
331 fromOneLine(iString.toString());
332 else
333 fromOneLine((String)null);
334 }
335
336 /**
337 * Copy this {@link Translation} to another {@link Translation} e.g. for
338 * editing
339 *
340 * @return the destination {@link Translation}
341 */
342 @Override
343 public Translation copyTo(Translation translation2) {
344
345 if (translation2 == null)
346 // throw new IllegalArgumentException(
347 // "Target translation may not be null.");
348 return copy();
349 for (String s : keySet()) {
350 translation2.put(s, get(s));
351 }
352
353 return translation2;
354 }
355
356
357 @Override
358 public Translation copy() {
359 return copyTo(new Translation());
360 }
361
362 /**
363 * Checks if the {@link String}s stored in the {@link Translation} are all valid.
364 * @return <code>true</code> if all good
365 */
366 public static boolean checkValid(Translation translationToCheck) {
367
368 for (String l : translationToCheck.values()) {
369
370 if (l.contains("{") || l.contains("}")) {
371
372 return false;
373 }
374 }
375 return true;
376 }
377
378
379 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26