1 12 package info.magnolia.cms.i18n; 13 14 import java.util.Enumeration ; 15 import java.util.ListResourceBundle ; 16 import java.util.Locale ; 17 import java.util.MissingResourceException ; 18 import java.util.ResourceBundle ; 19 20 import javax.servlet.http.HttpServletRequest ; 21 import javax.servlet.http.HttpSession ; 22 import javax.servlet.jsp.PageContext ; 23 import javax.servlet.jsp.jstl.core.Config; 24 import javax.servlet.jsp.jstl.fmt.LocalizationContext; 25 26 import org.apache.commons.lang.StringUtils; 27 import org.apache.log4j.Logger; 28 import org.apache.taglibs.standard.resources.Resources; 29 30 31 38 39 public class ContextMessages extends Messages { 40 41 44 private static Logger log = Logger.getLogger(ContextMessages.class); 45 46 49 private static final char HYPHEN = '-'; 50 51 54 private static final char UNDERSCORE = '_'; 55 56 59 private static final Locale EMPTY_LOCALE = new Locale (StringUtils.EMPTY, StringUtils.EMPTY); 60 61 64 private static final String REQUEST_SCOPE_SUFFIX = ".request"; 66 69 private static final String SESSION_SCOPE_SUFFIX = ".session"; 71 74 private static final String APPLICATION_SCOPE_SUFFIX = ".application"; 76 79 private LocalizationContext loc; 80 81 85 protected ContextMessages(HttpServletRequest req) { 86 loc = getLocalizationContext(req); 87 } 88 89 94 protected ContextMessages(HttpServletRequest req, String basename) { 95 this.setBasename(basename); 96 loc = getLocalizationContext(req, basename); 97 } 98 99 105 protected ContextMessages(HttpServletRequest req, String basename, Locale locale) { 106 this.setBasename(basename); 107 loc = getLocalizationContext(req, basename, locale); 108 } 109 110 113 public Locale getLocale() { 114 return loc.getLocale(); 115 } 116 117 120 public ResourceBundle getBundle() { 121 ResourceBundle bundle = loc.getResourceBundle(); 122 if (bundle == null) { 123 log.error("bundle: " + this.getBasename() + " not found"); bundle = new ListResourceBundle () { 125 126 protected Object [][] getContents() { 127 return new String [][]{}; 128 } 129 }; 130 } 131 return bundle; 132 } 133 134 139 public static Locale getCurrentLocale(HttpServletRequest req) { 140 return getLocalizationContext(req).getLocale(); 141 } 142 143 148 private static LocalizationContext getLocalizationContext(HttpServletRequest req) { 149 LocalizationContext locCtxt = null; 150 151 Object obj = find(req, Config.FMT_LOCALIZATION_CONTEXT); 152 if (obj == null) { 153 return null; 154 } 155 156 if (obj instanceof LocalizationContext) { 157 locCtxt = (LocalizationContext) obj; 158 } 159 else { 160 locCtxt = getLocalizationContext(req, (String ) obj); 162 } 163 164 return locCtxt; 165 } 166 167 173 private static LocalizationContext getLocalizationContext(HttpServletRequest req, String basename) { 174 return getLocalizationContext(req, basename, null); 175 } 176 177 195 private static LocalizationContext getLocalizationContext(HttpServletRequest req, String basename, Locale locale) { 196 LocalizationContext locCtxt = null; 197 ResourceBundle bundle = null; 198 199 if (StringUtils.isEmpty(basename)) { 200 return new LocalizationContext(); 201 } 202 203 Locale pref; 205 206 if (locale != null) { 207 pref = locale; 208 } 209 else { 210 pref = getLocale(req, Config.FMT_LOCALE); 211 } 212 213 if (pref != null) { 214 bundle = findMatch(basename, pref); 216 if (bundle != null) { 217 locCtxt = new LocalizationContext(bundle, pref); 218 } 219 } 220 else { 221 locCtxt = findMatch(req, basename); 223 } 224 225 if (locCtxt == null) { 226 pref = getLocale(req, Config.FMT_FALLBACK_LOCALE); 228 if (pref != null) { 229 bundle = findMatch(basename, pref); 230 if (bundle != null) { 231 locCtxt = new LocalizationContext(bundle, pref); 232 } 233 } 234 } 235 236 if (locCtxt == null) { 237 try { 239 bundle = ResourceBundle.getBundle(basename, EMPTY_LOCALE, Thread 240 .currentThread() 241 .getContextClassLoader()); 242 if (bundle != null) { 243 locCtxt = new LocalizationContext(bundle, null); 244 } 245 } 246 catch (MissingResourceException mre) { 247 } 249 } 250 251 if (locCtxt == null) { 252 locCtxt = new LocalizationContext(); 253 } 254 255 return locCtxt; 256 } 257 258 268 private static LocalizationContext findMatch(HttpServletRequest req, String basename) { 269 LocalizationContext locCtxt = null; 270 271 for (Enumeration en = req.getLocales(); en.hasMoreElements();) { 273 277 Locale pref = (Locale ) en.nextElement(); 278 ResourceBundle match = findMatch(basename, pref); 279 if (match != null) { 280 locCtxt = new LocalizationContext(match, pref); 281 break; 282 } 283 } 284 285 return locCtxt; 286 } 287 288 300 private static ResourceBundle findMatch(String basename, Locale pref) { 301 ResourceBundle match = null; 302 303 try { 304 ResourceBundle bundle = ResourceBundle.getBundle(basename, pref, Thread 305 .currentThread() 306 .getContextClassLoader()); 307 Locale avail = bundle.getLocale(); 308 if (pref.equals(avail)) { 309 match = bundle; 311 } 312 else { 313 322 if (pref.getLanguage().equals(avail.getLanguage()) 323 && (StringUtils.isEmpty(avail.getCountry()) || pref.getCountry().equals(avail.getCountry()))) { 324 333 match = bundle; 334 } 335 } 336 } 337 catch (MissingResourceException mre) { 338 } 340 341 return match; 342 } 343 344 357 private static Locale getLocale(HttpServletRequest req, String name) { 358 Locale loc = null; 359 360 Object obj = find(req, name); 361 if (obj != null) { 362 if (obj instanceof Locale ) { 363 loc = (Locale ) obj; 364 } 365 else { 366 loc = parseLocale((String ) obj); 367 } 368 } 369 370 return loc; 371 } 372 373 378 private static Locale parseLocale(String locale) { 379 return parseLocale(locale, null); 380 } 381 382 393 private static Locale parseLocale(String locale, String variant) throws IllegalArgumentException { 394 395 Locale ret = null; 396 String language = locale; 397 String country = null; 398 int index; 399 400 if (((index = locale.indexOf(HYPHEN)) > -1) || ((index = locale.indexOf(UNDERSCORE)) > -1)) { 401 language = locale.substring(0, index); 402 country = locale.substring(index + 1); 403 } 404 405 if (StringUtils.isEmpty(language)) { 406 throw new IllegalArgumentException (Resources.getMessage("LOCALE_NO_LANGUAGE")); } 408 409 if (country == null) { 410 if (variant != null) { 411 ret = new Locale (language, StringUtils.EMPTY, variant); 412 } 413 else { 414 ret = new Locale (language, StringUtils.EMPTY); 415 } 416 } 417 else if (country.length() > 0) { 418 if (variant != null) { 419 ret = new Locale (language, country, variant); 420 } 421 else { 422 ret = new Locale (language, country); 423 } 424 } 425 else { 426 throw new IllegalArgumentException (Resources.getMessage("LOCALE_EMPTY_COUNTRY")); } 428 429 return ret; 430 } 431 432 444 private static Object find(HttpServletRequest req, String name) { 445 Object ret = get(req, name, PageContext.REQUEST_SCOPE); 446 if (ret == null) { 447 if (req.getSession() != null) { 448 ret = get(req, name, PageContext.SESSION_SCOPE); 450 } 451 if (ret == null) { 452 ret = get(req, name, PageContext.APPLICATION_SCOPE); 453 if (ret == null) { 454 ret = req.getSession().getServletContext().getInitParameter(name); 455 } 456 } 457 } 458 return ret; 459 } 460 461 471 private static Object get(HttpServletRequest req, String name, int scope) { 472 switch (scope) { 473 case PageContext.REQUEST_SCOPE: 474 return req.getAttribute(name + REQUEST_SCOPE_SUFFIX); 475 case PageContext.SESSION_SCOPE: 476 return get(req.getSession(), name); 477 case PageContext.APPLICATION_SCOPE: 478 return req.getSession().getServletContext().getAttribute(name + APPLICATION_SCOPE_SUFFIX); 479 default: 480 throw new IllegalArgumentException ("unknown scope"); } 482 } 483 484 494 private static Object get(HttpSession session, String name) { 495 Object ret = null; 496 if (session != null) { 497 try { 498 ret = session.getAttribute(name + SESSION_SCOPE_SUFFIX); 499 } 500 catch (IllegalStateException ex) { 501 } 503 } 504 return ret; 505 } 506 507 510 public void reloadBundles() throws Exception { 511 reloadBundle(loc.getResourceBundle()); 512 } 513 514 } | Popular Tags |