1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.xnap.commons.i18n;
22
23 import java.lang.ref.WeakReference;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Locale;
28
29 /**
30 * Manager class that maintains a set of {@link org.xnap.commons.i18n.I18n}
31 * objects and {@link org.xnap.commons.i18n.LocaleChangeListener} objects.
32 * <p>
33 * The locale of all managed <code>I18n</code> objects can be changed by
34 * invoking {@link org.xnap.commons.i18n.I18nManager#setDefaultLocale(Locale)}.
35 *
36 * @author Felix Berger
37 * @author Steffen Pingel
38 * @since 0.9
39 */
40 public class I18nManager {
41
42 private static I18nManager instance = new I18nManager();
43
44 /** List of managed {@link I18n} objects. */
45 List i18ns = new ArrayList();
46
47 /** List of managed {@link LocaleChangeListener} objects. */
48 List localeChangeListeners = new ArrayList();
49
50 private I18nManager()
51 {
52 }
53
54 /**
55 * Returns the global <code>I18Manger</code> singleton.
56 *
57 * @return the <code>I18Manger</code> instance
58 * @since 0.9
59 */
60 public static I18nManager getInstance()
61 {
62 return instance;
63 }
64
65 /**
66 * Adds <code>i18n</code> to the list of managed <code>I18n</code>
67 * objects.
68 *
69 * @param i18n
70 * the <code>I18n</code> instance
71 * @see #setDefaultLocale(Locale)
72 * @see #remove(I18n)
73 * @since 0.9
74 */
75 public void add(I18n i18n)
76 {
77 i18ns.add(i18n);
78 }
79
80 /**
81 * Sets the locale for all I18n instances that were instantiated through the
82 * factory.
83 * <p>
84 * Use this method to globally change the locale for all I18n based
85 * translations.
86 * <p>
87 * NOTE: This only works if the objects that display messages do not cache
88 * translated messages.
89 * <p>
90 *
91 * @param locale
92 * the new default locale
93 * @see I18n#setLocale(Locale)
94 * @since 0.9
95 */
96 public void setDefaultLocale(Locale locale)
97 {
98 for (Iterator it = i18ns.iterator(); it.hasNext();) {
99 I18n i18n = (I18n)it.next();
100 i18n.setLocale(locale);
101 }
102
103 fireLocaleChangedEvent(locale);
104 }
105
106 /**
107 * Adds a listener that is notified when the default locale has been
108 * changed.
109 *
110 * @param listener
111 * the listener
112 * @see #setDefaultLocale(Locale)
113 * @since 0.9
114 */
115 public void addLocaleChangeListener(LocaleChangeListener listener)
116 {
117 synchronized (localeChangeListeners) {
118 localeChangeListeners.add(listener);
119 }
120 }
121
122 /**
123 * Adds a listener that is notified when the default locale has been changed
124 * using a {@link WeakReference}. The listener is removed when it has been
125 * cleaned up by the garbage collection.
126 * <p>
127 * This is useful for temporary objects that may have an indeterminate
128 * lifetime such as dialogs.
129 *
130 * @param listener
131 * the listener
132 * @see #setDefaultLocale(Locale)
133 * @since 0.9
134 */
135 public void addWeakLocaleChangeListener(LocaleChangeListener listener)
136 {
137 synchronized (localeChangeListeners) {
138 localeChangeListeners.add(new WeakLocaleChangeListener(listener));
139 }
140 }
141
142 /**
143 * Removes <code>i18n</code> from the list of managed <code>I18n</code>
144 * objects.
145 *
146 * @param i18n
147 * the <code>I18n</code> instance
148 * @see #add(I18n)
149 * @since 0.9
150 */
151 public void remove(I18n i18n)
152 {
153 i18ns.remove(i18n);
154 }
155
156 /**
157 * Removes <code>listener</code> from the list of objects that are
158 * notified when the locale has changed.
159 *
160 * @param listener
161 * the listener
162 * @since 0.9
163 */
164 public void removeLocaleChangeListener(LocaleChangeListener listener)
165 {
166 synchronized (localeChangeListeners) {
167 localeChangeListeners.remove(listener);
168 }
169 }
170
171 /**
172 * Notifies listeners of a locale change.
173 *
174 * @param newLocale
175 * new locale
176 * @since 0.9
177 */
178 protected void fireLocaleChangedEvent(Locale newLocale)
179 {
180 LocaleChangeListener[] listeners;
181 synchronized (localeChangeListeners) {
182 listeners = (LocaleChangeListener[])localeChangeListeners.toArray(new LocaleChangeListener[0]);
183 }
184 if (listeners.length > 0) {
185 LocaleChangeEvent event = new LocaleChangeEvent(I18nFactory.class, newLocale);
186 for (int i = listeners.length - 1; i >= 0; i--) {
187 listeners[i].localeChanged(event);
188 }
189 }
190 }
191
192 private static class WeakLocaleChangeListener implements LocaleChangeListener {
193
194 private WeakReference reference;
195
196 public WeakLocaleChangeListener(LocaleChangeListener listener)
197 {
198 reference = new WeakReference(listener);
199 }
200
201 public void localeChanged(LocaleChangeEvent event)
202 {
203 Object listener = reference.get();
204 if (listener != null) {
205 ((LocaleChangeListener)listener).localeChanged(event);
206 }
207 else {
208 I18nManager.getInstance().removeLocaleChangeListener(this);
209 }
210 }
211
212 }
213
214 }