1 package org.apache.turbine.services.localization; 2 3 18 19 import java.util.HashMap ; 20 import java.util.Locale ; 21 import java.util.Map ; 22 import java.util.MissingResourceException ; 23 import java.util.ResourceBundle ; 24 25 import javax.servlet.http.HttpServletRequest ; 26 27 import org.apache.commons.configuration.Configuration; 28 29 import org.apache.commons.lang.StringUtils; 30 31 import org.apache.commons.logging.Log; 32 import org.apache.commons.logging.LogFactory; 33 34 import org.apache.turbine.Turbine; 35 import org.apache.turbine.services.InitializationException; 36 import org.apache.turbine.services.TurbineBaseService; 37 import org.apache.turbine.util.RunData; 38 39 69 public class TurbineLocalizationService 70 extends TurbineBaseService 71 implements LocalizationService 72 { 73 74 private static Log log = LogFactory.getLog(TurbineLocalizationService.class); 75 76 80 private static final Object [] NO_ARGS = new Object [0]; 81 82 88 private Map bundles = null; 89 90 93 private String [] bundleNames = null; 94 95 99 private Locale defaultLocale = null; 100 101 102 private String defaultLanguage = null; 103 104 105 private String defaultCountry = null; 106 107 110 public TurbineLocalizationService() 111 { 112 bundles = new HashMap (); 113 } 114 115 118 public void init() 119 throws InitializationException 120 { 121 Configuration conf = Turbine.getConfiguration(); 122 123 initBundleNames(null); 124 125 Locale jvmDefault = Locale.getDefault(); 126 127 defaultLanguage = conf.getString("locale.default.language", 128 jvmDefault.getLanguage()).trim(); 129 defaultCountry = conf.getString("locale.default.country", 130 jvmDefault.getCountry()).trim(); 131 132 defaultLocale = new Locale (defaultLanguage, defaultCountry); 133 setInit(true); 134 } 135 136 141 protected void initBundleNames(String [] ignored) 142 { 143 Configuration conf = Turbine.getConfiguration(); 144 bundleNames = conf.getStringArray("locale.default.bundles"); 145 String name = conf.getString("locale.default.bundle"); 146 147 if (name != null && name.length() > 0) 148 { 149 if (bundleNames == null || bundleNames.length <= 0) 151 { 152 bundleNames = new String [] {name}; 153 } 154 else 155 { 156 String [] array = new String [bundleNames.length + 1]; 158 array[0] = name; 159 System.arraycopy(bundleNames, 0, array, 1, bundleNames.length); 160 bundleNames = array; 161 } 162 } 163 if (bundleNames == null) 164 { 165 bundleNames = new String [0]; 166 } 167 } 168 169 172 public String getDefaultLanguage() 173 { 174 return defaultLanguage; 175 } 176 177 180 public String getDefaultCountry() 181 { 182 return defaultCountry; 183 } 184 185 190 public String getDefaultBundleName() 191 { 192 return (bundleNames.length > 0 ? bundleNames[0] : ""); 193 } 194 195 198 public String [] getBundleNames() 199 { 200 return (String []) bundleNames.clone(); 201 } 202 203 210 public ResourceBundle getBundle() 211 { 212 return getBundle(getDefaultBundleName(), (Locale ) null); 213 } 214 215 222 public ResourceBundle getBundle(String bundleName) 223 { 224 return getBundle(bundleName, (Locale ) null); 225 } 226 227 236 public ResourceBundle getBundle(String bundleName, String languageHeader) 237 { 238 return getBundle(bundleName, getLocale(languageHeader)); 239 } 240 241 249 public ResourceBundle getBundle(HttpServletRequest req) 250 { 251 return getBundle(getDefaultBundleName(), getLocale(req)); 252 } 253 254 264 public ResourceBundle getBundle(String bundleName, HttpServletRequest req) 265 { 266 return getBundle(bundleName, getLocale(req)); 267 } 268 269 277 public ResourceBundle getBundle(RunData data) 278 { 279 return getBundle(getDefaultBundleName(), getLocale(data.getRequest())); 280 } 281 282 291 public ResourceBundle getBundle(String bundleName, RunData data) 292 { 293 return getBundle(bundleName, getLocale(data.getRequest())); 294 } 295 296 306 public ResourceBundle getBundle(String bundleName, Locale locale) 307 { 308 bundleName = (StringUtils.isEmpty(bundleName) ? getDefaultBundleName() : bundleName.trim()); 310 if (locale == null) 311 { 312 locale = getLocale((String ) null); 313 } 314 315 ResourceBundle rb = null; 317 Map bundlesByLocale = (Map ) bundles.get(bundleName); 318 if (bundlesByLocale != null) 319 { 320 rb = (ResourceBundle ) bundlesByLocale.get(locale); 323 324 if (rb == null) 325 { 326 rb = cacheBundle(bundleName, locale); 328 } 329 } 330 else 331 { 332 rb = cacheBundle(bundleName, locale); 333 } 334 return rb; 335 } 336 337 344 private synchronized ResourceBundle cacheBundle(String bundleName, 345 Locale locale) 346 throws MissingResourceException 347 { 348 Map bundlesByLocale = (HashMap ) bundles.get(bundleName); 349 ResourceBundle rb = (bundlesByLocale == null ? null : 350 (ResourceBundle ) bundlesByLocale.get(locale)); 351 352 if (rb == null) 353 { 354 bundlesByLocale = (bundlesByLocale == null ? new HashMap (3) : 355 new HashMap (bundlesByLocale)); 356 try 357 { 358 rb = ResourceBundle.getBundle(bundleName, locale); 359 } 360 catch (MissingResourceException e) 361 { 362 rb = findBundleByLocale(bundleName, locale, bundlesByLocale); 363 if (rb == null) 364 { 365 throw (MissingResourceException ) e.fillInStackTrace(); 366 } 367 } 368 369 if (rb != null) 370 { 371 bundlesByLocale.put(rb.getLocale(), rb); 373 374 Map bundlesByName = new HashMap (bundles); 375 bundlesByName.put(bundleName, bundlesByLocale); 376 this.bundles = bundlesByName; 377 } 378 } 379 return rb; 380 } 381 382 397 private ResourceBundle findBundleByLocale(String bundleName, Locale locale, 398 Map bundlesByLocale) 399 { 400 ResourceBundle rb = null; 401 if ( !StringUtils.isNotEmpty(locale.getCountry()) && 402 defaultLanguage.equals(locale.getLanguage()) ) 403 { 404 409 Locale withDefaultCountry = new Locale (locale.getLanguage(), 410 defaultCountry); 411 rb = (ResourceBundle ) bundlesByLocale.get(withDefaultCountry); 412 if (rb == null) 413 { 414 rb = getBundleIgnoreException(bundleName, withDefaultCountry); 415 } 416 } 417 else if ( !StringUtils.isNotEmpty(locale.getLanguage()) && 418 defaultCountry.equals(locale.getCountry()) ) 419 { 420 Locale withDefaultLanguage = new Locale (defaultLanguage, 421 locale.getCountry()); 422 rb = (ResourceBundle ) bundlesByLocale.get(withDefaultLanguage); 423 if (rb == null) 424 { 425 rb = getBundleIgnoreException(bundleName, withDefaultLanguage); 426 } 427 } 428 429 if (rb == null && !defaultLocale.equals(locale)) 430 { 431 rb = getBundleIgnoreException(bundleName, defaultLocale); 432 } 433 434 return rb; 435 } 436 437 443 private final ResourceBundle getBundleIgnoreException(String bundleName, 444 Locale locale) 445 { 446 try 447 { 448 return ResourceBundle.getBundle(bundleName, locale); 449 } 450 catch (MissingResourceException ignored) 451 { 452 return null; 453 } 454 } 455 456 462 public void setBundle(String defaultBundle) 463 { 464 if (bundleNames.length > 0) 465 { 466 bundleNames[0] = defaultBundle; 467 } 468 else 469 { 470 synchronized (this) 471 { 472 if (bundleNames.length <= 0) 473 { 474 bundleNames = new String [] {defaultBundle}; 475 } 476 } 477 } 478 } 479 480 483 public final Locale getLocale(HttpServletRequest req) 484 { 485 return getLocale(req.getHeader(ACCEPT_LANGUAGE)); 486 } 487 488 491 public Locale getLocale(String header) 492 { 493 if (!StringUtils.isEmpty(header)) 494 { 495 LocaleTokenizer tok = new LocaleTokenizer(header); 496 if (tok.hasNext()) 497 { 498 return (Locale ) tok.next(); 499 } 500 } 501 502 return defaultLocale; 504 } 505 506 510 public String getString(String bundleName, Locale locale, String key) 511 { 512 String value = null; 513 514 if (locale == null) 515 { 516 locale = getLocale((String ) null); 517 } 518 519 ResourceBundle rb = getBundle(bundleName, locale); 521 value = getStringOrNull(rb, key); 522 523 if (value == null && bundleNames.length > 0) 525 { 526 String name; 527 for (int i = 0; i < bundleNames.length; i++) 528 { 529 name = bundleNames[i]; 530 if (!name.equals(bundleName)) 533 { 534 rb = getBundle(name, locale); 535 value = getStringOrNull(rb, key); 536 if (value != null) 537 { 538 locale = rb.getLocale(); 539 break; 540 } 541 } 542 } 543 } 544 545 if (value == null) 546 { 547 String loc = locale.toString(); 548 String mesg = LocalizationService.SERVICE_NAME + 549 " noticed missing resource: " + 550 "bundleName=" + bundleName + ", locale=" + loc + 551 ", key=" + key; 552 log.debug(mesg); 553 throw new MissingResourceException (mesg, bundleName, key); 555 } 556 557 return value; 558 } 559 560 565 protected final String getStringOrNull(ResourceBundle rb, String key) 566 { 567 if (rb != null) 568 { 569 try 570 { 571 return rb.getString(key); 572 } 573 catch (MissingResourceException ignored) 574 { 575 } 576 } 577 return null; 578 } 579 580 } 581 | Popular Tags |