KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > roller > presentation > LanguageUtil


1 /*
2  * Filename: LanguageUtil.java
3  *
4  * Created on 04-May-04
5  */

6 package org.roller.presentation;
7
8 import java.security.Principal JavaDoc;
9 import java.util.Arrays JavaDoc;
10 import java.util.Locale JavaDoc;
11 import java.util.StringTokenizer JavaDoc;
12 import java.util.Vector JavaDoc;
13
14 import javax.servlet.ServletContext JavaDoc;
15 import javax.servlet.http.HttpServletRequest JavaDoc;
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.apache.struts.Globals;
20 import org.roller.pojos.WebsiteData;
21
22 /**
23  * This class provides utility methods to deal with
24  * multiple languages and other i18n stuff.
25  *
26  * @author <a HREF="mailto:molen@mail.com">Jaap van der Molen</a>
27  * @version $Revision: 1.8 $
28  */

29 public class LanguageUtil
30 {
31     private static Log mLogger =
32        LogFactory.getFactory().getInstance(LanguageUtil.class);
33
34     /**
35      * reference to supported languages
36      */

37     public static final String JavaDoc SUPPORTED_LANGUAGES =
38         "org.roller.presentation.supported.languages";
39
40     /**
41      * Extracts langauges from the ServletContext. If
42      * not present, returns null.
43      *
44      * @param ctx
45      * @return
46      */

47     public static Locale JavaDoc[] getSupportedLanguages(ServletContext JavaDoc ctx)
48     {
49         return (Locale JavaDoc[]) ctx.getAttribute(SUPPORTED_LANGUAGES);
50     }
51
52     /**
53      * Tests if a language is supported by roller as configured
54      * in the LanguageServlet init paramater.
55      *
56      * @param lang
57      * @param ctx
58      * @return
59      */

60     public static boolean isSupported(String JavaDoc lang, ServletContext JavaDoc ctx)
61     {
62         return isSupported(createLocale(lang), ctx);
63     }
64         
65     /**
66      * Tests if a language is supported by roller as configured
67      * in the LanguageServlet init paramater.
68      *
69      * If no supported languages are available, false is returned.
70      *
71      * @param locale
72      * @param ctx
73      * @return
74      */

75     public static boolean isSupported(Locale JavaDoc locale, ServletContext JavaDoc ctx)
76     {
77         mLogger.debug("isSupported( locale = "+locale+" )");
78         boolean isSupported = false;
79         Locale JavaDoc[] supportedLanguages = getSupportedLanguages(ctx);
80
81         if (supportedLanguages == null)
82         {
83             return false;
84         }
85         
86         for (int i=0; i<supportedLanguages.length; i++)
87         {
88             Locale JavaDoc l = (Locale JavaDoc) supportedLanguages[i];
89             if (l.equals(locale)) {
90                 isSupported = true;
91                 break;
92             } else {
93                 Locale JavaDoc langOnly = new Locale JavaDoc(locale.getLanguage());
94                 if (l.equals(langOnly)) {
95                     isSupported = true;
96                     break;
97                 }
98             }
99         }
100
101         return isSupported;
102     }
103
104     /**
105      * This method returns the Locale in which the current viewer wants
106      * to view the website. This 'View Locale' is derived as follows:
107      * <ul>
108      * <li>look for existing Locale in Session</li>
109      * <li>if not available, get Locale from request</li>
110      * <li>if not available, use {@link org.roller.presentation.LanguageUtil.getDefaultLocale()}
111      * (= Locale from <code>WebsiteData</code>)</li>
112      * <li>if a Locale is available in the request, verify it against the locales that
113      * are supported by Roller; if it is not supported replace it with the default Locale</li>
114      *
115      * The reason why I don't want to resort to the standard default mechanism of the
116      * Java ResourceBundles, is that this only works for the messages and not for
117      * other things like the dates and calendars (standard Java classes supports all locales).
118      * I think it looks silly to have the dates and calendars appear in French (e.g.) while
119      * the messages appear in English.
120      *
121      * @param request
122      * @return
123      */

124     public static Locale JavaDoc getViewLocale(HttpServletRequest JavaDoc request)
125     {
126         mLogger.debug("getViewLocale()");
127         Locale JavaDoc viewLocale = null;
128
129         // if user is logged in and the user looking at his own website, take website-locale
130
if (isWebsiteOfPrincipal(request))
131         {
132             viewLocale = getDefaultLocale(request);
133             mLogger.debug("websiteLocale = "+viewLocale);
134         }
135         else if (request.getSession(false) != null)
136         {
137             // check session for existing Locale
138
viewLocale = (Locale JavaDoc) request.getSession().getAttribute(Globals.LOCALE_KEY);
139             mLogger.debug("sessionLocale = "+viewLocale);
140         }
141
142         // if not found, look in many places
143
if (viewLocale == null)
144         {
145             // get from request
146
viewLocale = request.getLocale();
147             mLogger.debug("requestLocale = "+viewLocale);
148
149             //still not there? take default
150
if (viewLocale == null)
151             {
152                 viewLocale = getDefaultLocale(request);
153                 mLogger.debug("defaultLocale = "+viewLocale);
154             }
155         }
156         
157         /*
158          * If viewLocale is not supported, switch back to default.
159          *
160          * Note: I do this here under the assumption
161          * that the Locale in the Session is always supported. So,
162          * no checks on the Session Locale.
163          */

164         ServletContext JavaDoc ctx = RollerContext.getServletContext();
165         if (!LanguageUtil.isSupported(viewLocale, ctx))
166         {
167             viewLocale = Locale.getDefault();
168         }
169         mLogger.debug("return Locale = "+viewLocale);
170         
171         // add to session (for Velocity text tool)
172
request.getSession().setAttribute(Globals.LOCALE_KEY, viewLocale);
173         return viewLocale;
174     }
175     
176     /**
177      * Returns the default website locale using <code>WebsiteData.getLocaleInstance()</code> and
178      * returns <code>null</code> if the WebsiteData object is <code>null</code>.
179      *
180      * Note: This <code>null</code> situation occurs if a User logs in, but his or her website has
181      * been disabled. The website data is not loaded in that case.
182      *
183      * @param request
184      * @return
185      */

186     public static Locale JavaDoc getDefaultLocale(HttpServletRequest JavaDoc request) {
187         mLogger.debug("getDefaultLocale()");
188         RollerRequest rreq = RollerRequest.getRollerRequest(request);
189         WebsiteData website = rreq.getWebsite();
190         if (website==null) {
191             return null;
192         } else {
193             return website.getLocaleInstance();
194         }
195     }
196     
197     /**
198      * Verifies if the user is logged in and if so, if the website he
199      * is currently viewing, is the user's website. In that case, true is returned.
200      * Otherwise false.
201      *
202      * The reason for this additional check is that I only want to enforce the
203      * user's own locale if he at his own website. If I didn't, a logged-in user would be forced to
204      * view other sites in their default locale. That could lead to confusing situations.
205      *
206      * TODO: Maybe what I am saying is: shouldn't we store the user's locale as the user's locale,
207      * instead of as the website's locale?
208      *
209      * @param request
210      * @return
211      */

212     public static boolean isWebsiteOfPrincipal(HttpServletRequest JavaDoc request) {
213         boolean result = false;
214         RollerRequest rreq = RollerRequest.getRollerRequest(request);
215         if (rreq != null) {
216             WebsiteData website = rreq.getWebsite();
217             Principal JavaDoc principal = request.getUserPrincipal();
218             if (website != null && principal != null) {
219                 return website.getUser().getUserName().equals(principal.getName());
220             }
221         }
222         return result;
223     }
224     
225     /**
226      * Helper method to convert a language string to a <code>Locale</code> object.
227      * Example language stringds are 'en' or 'en_US'.
228      *
229      * @param lang
230      * @return
231      */

232     public static Locale JavaDoc createLocale(String JavaDoc lang) {
233         mLogger.debug("createLocale( lang = "+lang+" )");
234         Locale JavaDoc l = null;
235         if (lang.indexOf("_")>0) {
236             String JavaDoc tmpLang = lang.substring(0, lang.indexOf("_"));
237             String JavaDoc tmpCoun = lang.substring(lang.indexOf("_")+1, lang.length());
238             l = new Locale JavaDoc(tmpLang, tmpCoun);
239         } else
240         {
241             l = new Locale JavaDoc(lang);
242         }
243         return l;
244     }
245
246     /**
247      * Helper method to extract a collection of <code>Locale</code> from the
248      * supported languages config string for the LanguageServlet.
249      *
250      * @param supportedLanguages
251      * @return
252      */

253     public static Locale JavaDoc[] extractLanguages(String JavaDoc supportedLanguages) {
254         mLogger.debug("extractLanguages( lang = "+supportedLanguages+" )");
255         
256         Vector JavaDoc langs = new Vector JavaDoc();
257         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(supportedLanguages, ",");
258         while (st.hasMoreTokens())
259         {
260             Locale JavaDoc l = LanguageUtil.createLocale(st.nextToken());
261             langs.add(l);
262         }
263         mLogger.debug("supported languages: "+langs);
264         
265         return (Locale JavaDoc[]) langs.toArray(new Locale JavaDoc[langs.size()]);
266     }
267
268 }
269
Popular Tags