42 |
import java.io.ObjectInputStream; |
import java.io.ObjectInputStream; |
43 |
import java.io.ObjectOutputStream; |
import java.io.ObjectOutputStream; |
44 |
import java.io.Serializable; |
import java.io.Serializable; |
45 |
|
import java.lang.reflect.Constructor; |
46 |
import java.lang.reflect.InvocationTargetException; |
import java.lang.reflect.InvocationTargetException; |
47 |
|
|
48 |
/** |
/** |
437 |
return getInstance(TimeZone.getDefault(), locale); |
return getInstance(TimeZone.getDefault(), locale); |
438 |
} |
} |
439 |
|
|
440 |
|
/** |
441 |
|
* Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle |
442 |
|
* lookup for every getInstance call. |
443 |
|
*/ |
444 |
|
private static HashMap cache = new HashMap(); |
445 |
|
|
446 |
|
/** Preset argument types for calendar-class constructor lookup. */ |
447 |
|
private static Class[] ctorArgTypes |
448 |
|
= new Class[] {TimeZone.class, Locale.class}; |
449 |
|
|
450 |
/** |
/** |
451 |
* Creates a calendar representing the actual time, using the given |
* Creates a calendar representing the actual time, using the given |
452 |
* time zone and locale. |
* time zone and locale. |
455 |
*/ |
*/ |
456 |
public static synchronized Calendar getInstance(TimeZone zone, Locale locale) |
public static synchronized Calendar getInstance(TimeZone zone, Locale locale) |
457 |
{ |
{ |
458 |
String calendarClassName = null; |
Class calendarClass = (Class) cache.get(locale); |
459 |
ResourceBundle rb = getBundle(locale); |
Throwable exception = null; |
460 |
calendarClassName = rb.getString("calendarClass"); |
|
461 |
if (calendarClassName != null) |
try |
462 |
{ |
{ |
463 |
try |
if (calendarClass == null) |
464 |
{ |
{ |
465 |
Class calendarClass = Class.forName(calendarClassName); |
ResourceBundle rb = getBundle(locale); |
466 |
if (Calendar.class.isAssignableFrom(calendarClass)) |
String calendarClassName = rb.getString("calendarClass"); |
467 |
|
|
468 |
|
if (calendarClassName != null) |
469 |
{ |
{ |
470 |
return (Calendar) calendarClass.getConstructor( |
calendarClass = Class.forName(calendarClassName); |
471 |
new Class[] { TimeZone.class, Locale.class} |
if (Calendar.class.isAssignableFrom(calendarClass)) |
472 |
).newInstance(new Object[] {zone, locale} ); |
cache.put(locale, calendarClass); |
473 |
} |
} |
474 |
} |
} |
475 |
catch (ClassNotFoundException ex) {} |
|
476 |
catch (IllegalAccessException ex) {} |
// GregorianCalendar is by far the most common case. Optimize by |
477 |
catch (NoSuchMethodException ex) {} |
// avoiding reflection. |
478 |
catch (InstantiationException ex) {} |
if (calendarClass == GregorianCalendar.class) |
479 |
catch (InvocationTargetException ex) {} |
return new GregorianCalendar(zone, locale); |
480 |
// XXX should we ignore these errors or throw an exception ? |
|
481 |
|
if (Calendar.class.isAssignableFrom(calendarClass)) |
482 |
|
{ |
483 |
|
Constructor ctor = calendarClass.getConstructor(ctorArgTypes); |
484 |
|
return (Calendar) ctor.newInstance(new Object[] {zone, locale}); |
485 |
|
} |
486 |
|
} |
487 |
|
catch (ClassNotFoundException ex) |
488 |
|
{ |
489 |
|
exception = ex; |
490 |
|
} |
491 |
|
catch (IllegalAccessException ex) |
492 |
|
{ |
493 |
|
exception = ex; |
494 |
|
} |
495 |
|
catch (NoSuchMethodException ex) |
496 |
|
{ |
497 |
|
exception = ex; |
498 |
|
} |
499 |
|
catch (InstantiationException ex) |
500 |
|
{ |
501 |
|
exception = ex; |
502 |
|
} |
503 |
|
catch (InvocationTargetException ex) |
504 |
|
{ |
505 |
|
exception = ex; |
506 |
} |
} |
507 |
return new GregorianCalendar(zone, locale); |
|
508 |
|
throw new RuntimeException("Error instantiating calendar for locale " + |
509 |
|
locale, exception); |
510 |
} |
} |
511 |
|
|
512 |
/** |
/** |