1 package org.tigris.scarab.tools; 2 3 48 49 import java.util.ArrayList ; 50 import java.util.HashMap ; 51 import java.util.Iterator ; 52 import java.util.List ; 53 import java.util.Locale ; 54 import java.util.Map ; 55 import java.util.MissingResourceException ; 56 import java.util.ResourceBundle ; 57 58 import javax.servlet.http.HttpServletRequest ; 59 60 import org.apache.fulcrum.localization.LocaleTokenizer; 61 import org.apache.fulcrum.localization.Localization; 62 import org.apache.fulcrum.localization.LocalizationService; 63 import org.apache.turbine.RunData; 64 import org.apache.turbine.tool.LocalizationTool; 65 import org.tigris.scarab.tools.localization.Localizable; 66 import org.tigris.scarab.tools.localization.LocalizationKey; 67 import org.tigris.scarab.util.Log; 68 import org.tigris.scarab.util.ReferenceInsertionFilter; 69 import org.tigris.scarab.util.SkipFiltering; 70 71 85 public class ScarabLocalizationTool extends LocalizationTool 86 { 87 91 public static Locale DEFAULT_LOCALE = new Locale ("en", ""); 92 93 96 private static final String TITLE_PROP = "Title"; 97 98 104 private RunData data; 105 106 110 private String bundlePrefix; 111 private String oldBundlePrefix; 112 113 121 private List locales; 122 123 128 private boolean filterEnabled = true; 129 130 134 public ScarabLocalizationTool() 135 { 136 } 137 138 144 public String get(Localizable key) 145 { 146 String theKey = key.toString(); 147 return this.get(theKey); 148 } 149 150 151 158 private String getInternal(String key) 159 throws Exception 160 { 161 String value = null; 162 163 Iterator iter = locales.iterator(); 165 while (value == null && iter.hasNext()) 166 { 167 Locale locale = (Locale ) iter.next(); 168 value = resolveKey(key, locale); 169 } 170 return value; 171 } 172 173 174 183 public String get(String key) 184 { 185 String value; 186 try 187 { 188 value = getInternal(key); 189 if (value == null) 190 { 191 value = createMissingResourceValue(key); 192 } 193 } 194 catch(Exception e) 195 { 196 value = createBadResourceValue(key, e); 197 } 198 return value; 199 } 200 201 210 public String getIgnoreMissingResource(String key) 211 { 212 String value; 213 try 214 { 215 value = getInternal(key); 216 if(value == null) 217 { 218 value = key; 219 } 220 } 221 catch(Exception e) 222 { 223 value = createBadResourceValue(key, e); 224 } 225 return value; 226 } 227 228 236 public String format(String key, Object arg1) 237 { 238 return format(key, new Object []{arg1}); 239 } 240 241 250 public String format(String key, Object arg1, Object arg2) 251 { 252 return format(key, new Object []{arg1, arg2}); 253 } 254 255 265 public String format(String key, Object arg1, Object arg2, Object arg3) 266 { 267 return format(key, new Object []{arg1, arg2, arg3}); 268 } 269 270 293 public String format(String key, List args) 294 { 295 Object [] array = (args == null) ? null : args.toArray(); 296 return format(key, array); 297 } 298 299 304 public void setFilterEnabled(boolean v) 305 { 306 filterEnabled = v; 307 } 308 309 312 public boolean isFilterEnabled() 313 { 314 return filterEnabled; 315 } 316 317 329 public String format(String key, Object [] args) 330 { 331 String value = null; 332 resolveArgumentTemplates(args); 333 try 334 { 335 Iterator iter = locales.iterator(); 337 while (value == null && iter.hasNext()) 338 { 339 Locale locale = (Locale ) iter.next(); 340 value = formatKey(key, args, locale); 341 } 342 357 } 358 catch (Exception e) 359 { 360 value = createBadResourceValue(key, e); 361 } 362 return value; 363 } 364 365 366 367 375 public String getTitle() 376 { 377 String title = findProperty(TITLE_PROP); 378 379 return title; 380 } 381 382 389 protected String findProperty(String property) 390 { 391 String value = null; 392 393 String templateName = data.getTarget().replace(',', '/'); 394 395 396 String l10nKey = property; 397 String prefix = getPrefix(templateName + '.'); 398 if (prefix != null) 399 { 400 l10nKey = prefix + l10nKey; 401 } 402 value = get(l10nKey); 403 Log.get().debug( "ScarabLocalizationTool: Localized value is '" 404 + value 405 + '\''); 406 407 return value; 408 } 409 410 415 public void setBundlePrefix(String prefix) 416 { 417 oldBundlePrefix = bundlePrefix; 418 bundlePrefix = prefix; 419 } 420 421 424 public void restoreBundlePrefix() 425 { 426 bundlePrefix = oldBundlePrefix; 427 } 428 429 430 433 protected String getBundleName() 434 { 435 String name = Localization.getDefaultBundleName(); 436 return (bundlePrefix == null) ? name : bundlePrefix + name; 437 } 438 439 446 public Locale getPrimaryLocale() 447 { 448 return (locales == null || locales.size() == 0) ? super.getLocale() 449 : (Locale ) locales.iterator().next(); 450 } 451 452 454 459 public void init(Object obj) 460 { 461 super.init(obj); 462 if (obj instanceof RunData) 463 { 464 data = (RunData) obj; 465 locales = getPreferredLocales(); 466 } 467 else if (obj instanceof Locale ) 468 { 469 locales = new ArrayList (); 470 locales.add(obj); 471 locales.add(DEFAULT_LOCALE); 472 locales.add(null); 473 } 474 } 475 476 480 public void refresh() 481 { 482 super.refresh(); 483 data = null; 484 bundlePrefix = null; 485 oldBundlePrefix = null; 486 locales = null; 487 setFilterEnabled(true); 488 } 489 490 491 495 503 private List getPreferredLocales() 504 { 505 List result = new ArrayList (3); 506 String localeAsString = getBrowserLocalesAsString(); 507 LocaleTokenizer localeTokenizer = new LocaleTokenizer(localeAsString); 508 while (localeTokenizer.hasNext()) 509 { 510 Locale browserLocale = (Locale ) localeTokenizer.next(); 511 Locale finalLocale = getFinalLocaleFor(browserLocale); 512 if (finalLocale != null) 513 { 514 result.add(finalLocale); 515 } 516 } 517 result.add(DEFAULT_LOCALE); 518 result.add(null); 519 return result; 520 } 521 522 523 527 static private Map supportedLocaleMap = new HashMap (); 528 532 static private Map unsupportedLocaleMap = new HashMap (); 533 534 542 private Locale getFinalLocaleFor(Locale browserLocale) 543 { 544 Locale result = (Locale ) supportedLocaleMap.get(browserLocale); 545 if (result == null) 546 { 547 if (unsupportedLocaleMap.get(browserLocale) == null) 548 { 549 ResourceBundle bundle; 550 try { 551 bundle = ResourceBundle.getBundle( 552 getBundleName(), browserLocale); 553 } 554 catch (Exception e) 555 { 556 bundle = null; 563 } 564 565 if (bundle != null) 566 { 567 Locale finalLocale = bundle.getLocale(); 568 String initialLanguage = browserLocale.getLanguage(); 569 String finalLanguage = finalLocale.getLanguage(); 570 if (initialLanguage.equals(finalLanguage)) 571 { 572 result = finalLocale; 573 supportedLocaleMap.put(browserLocale, finalLocale); 574 } 575 else 576 { 577 unsupportedLocaleMap.put(browserLocale, finalLocale); 578 } 579 } 580 else 581 { 582 Log.get().error("ScarabLocalizationTool: ResourceBundle '" + getBundleName() 583 + "' -> not resolved for Locale '" 584 + browserLocale 585 + "'."); 586 } 587 } 588 } 589 return result; 590 } 591 592 598 private String getBrowserLocalesAsString() 599 { 600 String acceptLanguage = LocalizationService.ACCEPT_LANGUAGE; 601 HttpServletRequest request = data.getRequest(); 602 String browserLocaleAsString = request.getHeader(acceptLanguage); 603 if (browserLocaleAsString == null) 604 { 605 browserLocaleAsString = ""; 606 } 607 return browserLocaleAsString; 608 } 609 610 617 private String resolveKey(String key, Locale locale) 618 { 619 String value; 620 try 621 { 622 value = Localization.getString(getBundleName(), locale, key); 623 } 624 catch (MissingResourceException noKey) 625 { 626 value = null; 628 } 629 return value; 630 } 631 632 633 642 private String formatKey(String key, Object [] args, Locale locale) 643 { 644 String value; 645 try 646 { 647 value = Localization.format(getBundleName(), locale, key, args); 648 } 649 catch (MissingResourceException noKey) 650 { 651 value = null; 652 } 653 return value; 654 } 655 656 664 private Object [] resolveArgumentTemplates(Object [] args) 665 { 666 672 Object [] result; 673 if (isFilterEnabled() && args != null && args.length > 0) 674 { 675 result = new Object [args.length]; 676 for (int i = 0; i < args.length; i++) 677 { 678 Object obj = args[i]; 679 if (obj != null) 683 { 684 if (!( (obj instanceof SkipFiltering) 685 || (obj instanceof Number )) 686 ) 687 { 688 obj = ReferenceInsertionFilter.filter(obj.toString()); 689 } 690 } 691 result[i] = obj; 692 } 693 } 694 else 695 { 696 result = args; 697 } 698 return result; 699 } 700 701 707 private String createMissingResourceValue(String key) 708 { 709 String value; 710 value = "ERROR! Missing resource (" 711 + key 712 + ")(" 713 + Locale.getDefault() 714 + ")"; 715 Log.get().error( 716 "ScarabLocalizationTool: ERROR! Missing resource: " + key); 717 return value; 718 } 719 720 727 private String createBadResourceValue(String key, Exception e) 728 { 729 String value; 730 value = "ERROR! Bad resource (" + key + ")"; 731 Log.get().error( "ScarabLocalizationTool: ERROR! Bad resource: " + key 732 + ". See log for details.", e); 733 return value; 734 } 735 736 737 745 public String getMessage(Throwable t) 746 { 747 String result; 748 if(t instanceof Localizable) 749 { 750 result = ((Localizable) t).getMessage(this); 751 } 752 else 753 { 754 result = t.getLocalizedMessage(); 768 } 769 return result; 770 } 771 772 773 } 774 | Popular Tags |