KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > i18n > MessagesManager


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2005 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.cms.i18n;
14
15 import info.magnolia.cms.beans.config.ContentRepository;
16 import info.magnolia.cms.core.Content;
17 import info.magnolia.cms.core.HierarchyManager;
18 import info.magnolia.cms.core.ItemType;
19 import info.magnolia.cms.core.NodeData;
20
21 import java.util.ArrayList JavaDoc;
22 import java.util.Collection JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Locale JavaDoc;
25
26 import javax.jcr.RepositoryException;
27 import javax.jcr.observation.Event;
28 import javax.jcr.observation.EventIterator;
29 import javax.jcr.observation.EventListener;
30 import javax.jcr.observation.ObservationManager;
31 import javax.servlet.ServletContext JavaDoc;
32 import javax.servlet.http.HttpServletRequest JavaDoc;
33 import javax.servlet.http.HttpSession JavaDoc;
34 import javax.servlet.jsp.PageContext JavaDoc;
35 import javax.servlet.jsp.jstl.core.Config;
36
37 import org.apache.commons.lang.StringUtils;
38 import org.apache.log4j.Logger;
39
40
41 /**
42  * From this class you get the i18n messages. You should pass a a request, but if you can't the getMessages method will
43  * handle it properly. The get() methods are easy to use.
44  * @author philipp
45  */

46 public final class MessagesManager {
47
48     /**
49      * Use this locale if no other provided
50      */

51     public static final String JavaDoc FALLBACK_LOCALE = "en"; //$NON-NLS-1$
52

53     /**
54      * Use this basename if no other is provided
55      */

56     public static final String JavaDoc DEFAULT_BASENAME = "info.magnolia.module.admininterface.messages"; //$NON-NLS-1$
57

58     /**
59      * Logger.
60      */

61     protected static Logger log = Logger.getLogger(Messages.class);
62
63     /**
64      * The node name where the configuration for i18n is stored
65      */

66     private static final String JavaDoc I18N_CONFIG_NAME = "i18n"; //$NON-NLS-1$
67

68     /**
69      * The name of the property to store the current system language
70      */

71     private static final String JavaDoc LOCALE_CONFIG_NAME = "language"; //$NON-NLS-1$
72

73     /**
74      * Under this node all the available languages are stored. They are showed in the user dialog.
75      */

76     private static final String JavaDoc AVAILABLE_LOCALES_CONFIG_NAME = "availableLanguages"; //$NON-NLS-1$
77

78     /**
79      * The current locale of the application
80      */

81     private static Locale JavaDoc applicationLocale;
82
83     /**
84      * List of the available locales
85      */

86     private static Collection JavaDoc availableLocales = new ArrayList JavaDoc();
87
88     /**
89      * The context used for the messages
90      */

91     private static ServletContext JavaDoc context;
92
93     /**
94      * Util has no public constructor
95      */

96     private MessagesManager() {
97     }
98
99     /**
100      * Called through the initialization process (startup of the container)
101      * @param context servlet context
102      */

103     public static void init(ServletContext JavaDoc context) {
104         MessagesManager.context = context;
105
106         // setting fallback
107
context.setAttribute(Config.FMT_FALLBACK_LOCALE + ".application", FALLBACK_LOCALE); //$NON-NLS-1$
108
// setting basename
109
context.setAttribute(Config.FMT_LOCALIZATION_CONTEXT + ".application", MessagesManager.DEFAULT_BASENAME); //$NON-NLS-1$
110
// for Resin and other J2EE Containers
111
context.setAttribute(Config.FMT_LOCALIZATION_CONTEXT, MessagesManager.DEFAULT_BASENAME);
112
113         // setting default language (en)
114
MessagesManager.setDefaultLocale(FALLBACK_LOCALE);
115
116         load();
117         registerEventListener();
118     }
119
120     /**
121      * Load i18n configuration.
122      */

123     public static void load() {
124
125         // reading the configuration from the repository
126
HierarchyManager configHierarchyManager = ContentRepository.getHierarchyManager(ContentRepository.CONFIG);
127         try {
128             log.info("Config : loading i18n configuration - " + I18N_CONFIG_NAME); //$NON-NLS-1$
129

130             Content serverNode = configHierarchyManager.getContent("/server"); //$NON-NLS-1$
131

132             Content configNode;
133             try {
134                 configNode = serverNode.getContent(I18N_CONFIG_NAME);
135             }
136             catch (javax.jcr.PathNotFoundException e) {
137                 configNode = serverNode.createContent(I18N_CONFIG_NAME, ItemType.CONTENTNODE);
138                 configHierarchyManager.save();
139             }
140
141             NodeData languageNodeData = configNode.getNodeData(LOCALE_CONFIG_NAME);
142
143             if (StringUtils.isEmpty(languageNodeData.getName())) {
144                 languageNodeData = configNode.createNodeData(LOCALE_CONFIG_NAME);
145                 languageNodeData.setValue(MessagesManager.FALLBACK_LOCALE);
146                 configHierarchyManager.save();
147             }
148
149             MessagesManager.setDefaultLocale(languageNodeData.getString());
150
151             // get the available languages
152
Content availableLanguagesContentNode;
153
154             NodeData availableLanguage;
155
156             try {
157                 availableLanguagesContentNode = configNode.getContent(AVAILABLE_LOCALES_CONFIG_NAME);
158             }
159             catch (javax.jcr.PathNotFoundException e) {
160                 availableLanguagesContentNode = configNode.createContent(
161                     AVAILABLE_LOCALES_CONFIG_NAME,
162                     ItemType.CONTENTNODE);
163
164                 availableLanguage = availableLanguagesContentNode.createNodeData(MessagesManager.FALLBACK_LOCALE);
165                 availableLanguage.setValue(MessagesManager.FALLBACK_LOCALE);
166                 configHierarchyManager.save();
167             }
168
169             Collection JavaDoc locales = availableLanguagesContentNode.getNodeDataCollection();
170
171             // clear collection for reload
172
MessagesManager.availableLocales.clear();
173
174             for (Iterator JavaDoc iter = locales.iterator(); iter.hasNext();) {
175                 availableLanguage = (NodeData) iter.next();
176                 String JavaDoc name = availableLanguage.getString();
177                 String JavaDoc language = name;
178                 String JavaDoc country = StringUtils.EMPTY;
179
180                 if (name.indexOf("_") == 2) { //$NON-NLS-1$
181
language = name.substring(0, 2);
182                     country = name.substring(3);
183                 }
184                 Locale JavaDoc locale = new Locale JavaDoc(language, country);
185                 MessagesManager.availableLocales.add(locale);
186             }
187
188         }
189         catch (RepositoryException re) {
190             log.error("Config : Failed to load i18n configuration - " + I18N_CONFIG_NAME); //$NON-NLS-1$
191
log.error(re.getMessage(), re);
192         }
193     }
194
195     /**
196      * Register an event listener: reload configuration when something changes.
197      */

198     private static void registerEventListener() {
199
200         log.info("Registering event listener for i18n"); //$NON-NLS-1$
201

202         try {
203             ObservationManager observationManager = ContentRepository
204                 .getHierarchyManager(ContentRepository.CONFIG)
205                 .getWorkspace()
206                 .getObservationManager();
207
208             observationManager.addEventListener(new EventListener() {
209
210                 public void onEvent(EventIterator iterator) {
211                     // reload everything
212
reload();
213                 }
214             }, Event.NODE_ADDED
215                 | Event.NODE_REMOVED
216                 | Event.PROPERTY_ADDED
217                 | Event.PROPERTY_CHANGED
218                 | Event.PROPERTY_REMOVED, "/server/" + I18N_CONFIG_NAME, true, null, null, false); //$NON-NLS-1$
219
}
220         catch (RepositoryException e) {
221             log.error("Unable to add event listeners for i18n", e); //$NON-NLS-1$
222
}
223     }
224
225     /**
226      * Reload i18n configuration.
227      */

228     public static void reload() {
229         load();
230     }
231
232     /**
233      * Trys to make a new ContextMessages object. if not possible it creates a new Messages object.
234      * @param req uses the request to find the configuration
235      * @return Messages
236      */

237     public static Messages getMessages(HttpServletRequest JavaDoc req) {
238         if (req != null) {
239             return new ContextMessages(req);
240         }
241
242         log.debug("using i18n-messages without a request!"); //$NON-NLS-1$
243
return new Messages(MessagesManager.DEFAULT_BASENAME, applicationLocale);
244
245     }
246
247     /**
248      * Provide a basename
249      * @param req request
250      * @param basename basename
251      * @return Messages object to get the messages from
252      */

253     public static Messages getMessages(HttpServletRequest JavaDoc req, String JavaDoc basename) {
254         if (req != null) {
255             return new ContextMessages(req, basename);
256         }
257
258         log.debug("using i18n-messages without a request!"); //$NON-NLS-1$
259
return new Messages(basename, applicationLocale);
260
261     }
262
263     /**
264      * Provide a special locale
265      * @param req request
266      * @param basename basename
267      * @param locale locale
268      * @return Messages object to get the messages from
269      */

270     public static Messages getMessages(HttpServletRequest JavaDoc req, String JavaDoc basename, Locale JavaDoc locale) {
271         if (req != null) {
272             return new ContextMessages(req, basename, locale);
273         }
274
275         log.debug("using i18n-messages without a request!"); //$NON-NLS-1$
276
return new Messages(basename, locale);
277
278     }
279
280     /**
281      * Trys to make a new ContextMessages object. if not possible it creates a new Messages object.
282      * @param pc the page context to start the lookup
283      * @return Messages
284      */

285     public static Messages getMessages(PageContext JavaDoc pc) {
286         if (pc != null && pc.getRequest() instanceof HttpServletRequest JavaDoc) {
287             return new ContextMessages((HttpServletRequest JavaDoc) pc.getRequest());
288         }
289
290         log.debug("using i18n-messages without a request inside a control!"); //$NON-NLS-1$
291
return new Messages(MessagesManager.DEFAULT_BASENAME, applicationLocale);
292
293     }
294
295     /**
296      * Get a message.
297      * @param req request
298      * @param key key to find
299      * @return message
300      */

301
302     public static String JavaDoc get(HttpServletRequest JavaDoc req, String JavaDoc key) {
303         return getMessages(req).get(key);
304     }
305
306     /**
307      * Get a message with parameters inside: the value {0} must be a number
308      * @param req request
309      * @param key key to find
310      * @param args replacement strings
311      * @return message
312      */

313
314     public static String JavaDoc get(HttpServletRequest JavaDoc req, String JavaDoc key, Object JavaDoc[] args) {
315         return getMessages(req).get(key, args);
316     }
317
318     /**
319      * Use a default string.
320      * @param req request
321      * @param key key to find
322      * @param defaultMsg default message
323      * @return message
324      */

325
326     public static String JavaDoc getWithDefault(HttpServletRequest JavaDoc req, String JavaDoc key, String JavaDoc defaultMsg) {
327         return getMessages(req).getWithDefault(key, defaultMsg);
328     }
329
330     /**
331      * Get a message with parameters inside: the value {0} must be a number. Use a default message.
332      * @param req request
333      * @param key key to find
334      * @param args replacement strings
335      * @param defaultMsg default message
336      * @return message
337      */

338     public static String JavaDoc getWithDefault(HttpServletRequest JavaDoc req, String JavaDoc key, Object JavaDoc[] args, String JavaDoc defaultMsg) {
339         return getMessages(req).getWithDefault(key, args, defaultMsg);
340     }
341
342     /**
343      * @return Returns the defaultLocale.
344      */

345     public static Locale JavaDoc getDefaultLocale() {
346         return applicationLocale;
347     }
348
349     /**
350      * @return Returns the current locale for the current user
351      */

352     public static Locale JavaDoc getCurrentLocale(HttpServletRequest JavaDoc req) {
353         try {
354             return ContextMessages.getCurrentLocale(req);
355         }
356         catch (Exception JavaDoc e) {
357             return getDefaultLocale();
358         }
359     }
360
361     /**
362      * @param defaultLocale The defaultLocale to set.
363      */

364     public static void setDefaultLocale(String JavaDoc defaultLocale) {
365         MessagesManager.applicationLocale = new Locale JavaDoc(defaultLocale);
366         context.setAttribute(Config.FMT_LOCALE + ".application", defaultLocale); //$NON-NLS-1$
367
}
368
369     /**
370      * @return Returns the availableLocals.
371      */

372     public static Collection JavaDoc getAvailableLocales() {
373         return availableLocales;
374     }
375
376     /**
377      * Set the user language in the session
378      * @param language lagnguage to ste
379      * @param session current session
380      */

381     public static void setUserLanguage(String JavaDoc language, HttpSession JavaDoc session) {
382         session.setAttribute(Config.FMT_LOCALE + ".session", language); //$NON-NLS-1$
383
}
384 }
Popular Tags