
The branch, master has been updated via ae58838ee39924f8a587778d6745d6c7f33845ff (commit) from 975f8f73e55bf77415329423c298c164ab611c87 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://git.qos.ch/gitweb/?p=cal10n.git;a=commit;h=ae58838ee39924f8a587778d67... http://github.com/ceki/cal10n/commit/ae58838ee39924f8a587778d6745d6c7f33845f... commit ae58838ee39924f8a587778d6745d6c7f33845ff Author: Ceki Gulcu <ceki@qos.ch> Date: Thu Sep 3 23:52:22 2009 +0200 - adding encoding/charset support in Annotations - relevant testing diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/Locale.java b/cal10n-api/src/main/java/ch/qos/cal10n/Locale.java index 46eb612..f655d39 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/Locale.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/Locale.java @@ -61,5 +61,5 @@ import ch.qos.cal10n.verifier.MessageKeyVerifier; @Target(ElementType.TYPE) public @interface Locale { String value(); - String encoding() default "UTF-8"; + String charset() default ""; } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/LocaleData.java b/cal10n-api/src/main/java/ch/qos/cal10n/LocaleData.java index 1aeb2a3..c4912f0 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/LocaleData.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/LocaleData.java @@ -61,4 +61,5 @@ import ch.qos.cal10n.verifier.MessageKeyVerifier; @Target(ElementType.TYPE) public @interface LocaleData { Locale[] value(); + String defaultCharset() default ""; } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java b/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java index fbf25d9..11395c9 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java @@ -29,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap; import ch.qos.cal10n.util.AnnotationExtractor; import ch.qos.cal10n.util.CAL10NResourceBundle; -import ch.qos.cal10n.util.PropertyResourceBundleFinder; +import ch.qos.cal10n.util.CAL10NResourceBundleFinder; /** * The default implementation for {@link IMessageConveyor} based on resource @@ -68,10 +68,11 @@ public class MessageConveyor implements IMessageConveyor { * an enum instance used as message key * */ - public <E extends Enum<?>> String getMessage(E key, Object... args) throws MessageConveyorException { + public <E extends Enum<?>> String getMessage(E key, Object... args) + throws MessageConveyorException { String declararingClassName = key.getDeclaringClass().getName(); - CAL10NResourceBundle rb = cache.get(declararingClassName); + CAL10NResourceBundle rb = cache.get(declararingClassName); if (rb == null || rb.hasChanged()) { rb = lookup(key); cache.put(declararingClassName, rb); @@ -90,7 +91,10 @@ public class MessageConveyor implements IMessageConveyor { } } - private <E extends Enum<?>> CAL10NResourceBundle lookup(E key) throws MessageConveyorException { + private <E extends Enum<?>> CAL10NResourceBundle lookup(E key) + throws MessageConveyorException { + Class<?> declaringClass = key.getDeclaringClass(); + String baseName = AnnotationExtractor.getBaseName(key.getDeclaringClass()); if (baseName == null) { throw new MessageConveyorException( @@ -98,18 +102,21 @@ public class MessageConveyor implements IMessageConveyor { + key.getClass().getName() + "]. See also " + Cal10nConstants.MISSING_BN_ANNOTATION_URL); } - CAL10NResourceBundle rb = PropertyResourceBundleFinder.getBundle(this.getClass() - .getClassLoader(), baseName, locale); - if(rb == null) { - throw new MessageConveyorException("Failed to locate resource bundle [" + baseName - + "] for locale [" + locale + "] for enum type [" + key.getDeclaringClass().getName() - + "]"); + String charset = AnnotationExtractor.getCharset(declaringClass, locale); + CAL10NResourceBundle rb = CAL10NResourceBundleFinder.getBundle(this + .getClass().getClassLoader(), baseName, locale, charset); + + if (rb == null) { + throw new MessageConveyorException("Failed to locate resource bundle [" + + baseName + "] for locale [" + locale + "] for enum type [" + + key.getDeclaringClass().getName() + "]"); } return rb; } - public String getMessage(MessageParameterObj mpo) throws MessageConveyorException { + public String getMessage(MessageParameterObj mpo) + throws MessageConveyorException { if (mpo == null) { throw new IllegalArgumentException( "MessageParameterObj argumument cannot be null"); diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/AnnotationExtractor.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/AnnotationExtractor.java index 6244c63..0601594 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/util/AnnotationExtractor.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/AnnotationExtractor.java @@ -28,14 +28,12 @@ import ch.qos.cal10n.LocaleData; /** * * @author Ceki Gülcü - * + * */ public class AnnotationExtractor { - static public <E extends Enum<?>> String getBaseName( - Class<E> enumClass) { - BaseName rbnAnnotation = (BaseName) enumClass - .getAnnotation(BaseName.class); + static public <E extends Enum<?>> String getBaseName(Class<E> enumClass) { + BaseName rbnAnnotation = (BaseName) enumClass.getAnnotation(BaseName.class); if (rbnAnnotation == null) { return null; } @@ -43,20 +41,19 @@ public class AnnotationExtractor { } static public <E extends Enum<?>> String[] getLocaleNames(Class<E> enumClass) { - Locale[] localeDataArray = getLocaleData(enumClass); - - if(localeDataArray == null) { + Locale[] localeDataArray = getLocaleData(enumClass); + + if (localeDataArray == null) { return null; } - + String[] names = new String[localeDataArray.length]; - for(int i = 0; i < localeDataArray.length; i++) { + for (int i = 0; i < localeDataArray.length; i++) { names[i] = localeDataArray[i].value(); } return names; } - static public <E extends Enum<?>> Locale[] getLocaleData(Class<E> enumClass) { LocaleData localeDataArrayAnnotation = (LocaleData) enumClass .getAnnotation(LocaleData.class); @@ -66,4 +63,43 @@ public class AnnotationExtractor { return localeDataArrayAnnotation.value(); } + public static String getCharset(Class<?> enumClass, + java.util.Locale juLocale) { + LocaleData localeDataArrayAnnotation = (LocaleData) enumClass + .getAnnotation(LocaleData.class); + if (localeDataArrayAnnotation == null) { + return ""; + } + + String defaultCharset = localeDataArrayAnnotation.defaultCharset(); + + Locale la = findLocaleAnnotation(juLocale, localeDataArrayAnnotation); + String localeCharset = null; + if(la != null) { + localeCharset = la.charset(); + } + if(!isEmttyString(localeCharset)) { + return localeCharset; + } + + return defaultCharset; + } + + static Locale findLocaleAnnotation(java.util.Locale julocale, LocaleData localeDataArrayAnnotation) { + Locale[] localeAnnotationArray = localeDataArrayAnnotation.value(); + if(localeAnnotationArray == null) { + return null; + } + for(Locale la: localeAnnotationArray) { + if(la.value().equals(julocale.toString())) { + return la; + } + } + + return null; + } + + static boolean isEmttyString(String s) { + return s == null || s.length() == 0; + } } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/PropertyResourceBundleFinder.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundleFinder.java similarity index 75% rename from cal10n-api/src/main/java/ch/qos/cal10n/util/PropertyResourceBundleFinder.java rename to cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundleFinder.java index 3c767ce..031efc7 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/util/PropertyResourceBundleFinder.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundleFinder.java @@ -25,20 +25,22 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLConnection; import java.util.Locale; -public class PropertyResourceBundleFinder { +public class CAL10NResourceBundleFinder { - public static CAL10NResourceBundle getBundle(ClassLoader classLoader, String baseName, - Locale locale) { + public static CAL10NResourceBundle getBundle(ClassLoader classLoader, + String baseName, Locale locale, String charset) { // same as the JDK convention // - // It generates a path name from the candidate bundle name by replacing all "." + // It generates a path name from the candidate bundle name by replacing all + // "." // characters with "/" and appending the string ".properties". - /// see also http: // tinyurl.com/ldgej8 + // / see also http: // tinyurl.com/ldgej8 baseName = baseName.replace('.', '/'); String languageAndCountryCandidate = computeLanguageAndCountryCandidate( @@ -47,12 +49,12 @@ public class PropertyResourceBundleFinder { locale); CAL10NResourceBundle cprbLanguageOnly = makePropertyResourceBundle( - classLoader, languageOnlyCandidate); + classLoader, languageOnlyCandidate, charset); CAL10NResourceBundle cprbLanguageAndCountry = null; if (languageAndCountryCandidate != null) { cprbLanguageAndCountry = makePropertyResourceBundle(classLoader, - languageAndCountryCandidate); + languageAndCountryCandidate, charset); } if (cprbLanguageAndCountry != null) { @@ -63,7 +65,7 @@ public class PropertyResourceBundleFinder { } private static CAL10NResourceBundle makePropertyResourceBundle( - ClassLoader classLoader, String resourceCandiate) { + ClassLoader classLoader, String resourceCandiate, String charset) { CAL10NResourceBundle prb = null; @@ -71,7 +73,13 @@ public class PropertyResourceBundleFinder { if (url != null) { try { InputStream in = openConnectionForUrl(url); - Reader reader = new InputStreamReader(in); + + Reader reader = toReader(in, charset); + if (charset == null || charset.length() == 0) + reader = new InputStreamReader(in); + else + reader = new InputStreamReader(in, charset); + prb = new CAL10NResourceBundle(reader, MiscUtil.urlToFile(url)); in.close(); } catch (IOException e) { @@ -80,6 +88,18 @@ public class PropertyResourceBundleFinder { return prb; } + static Reader toReader(InputStream in, String charset) { + if (charset == null || charset.length() == 0) + return new InputStreamReader(in); + else { + try { + return new InputStreamReader(in, charset); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException("Failed to open reader", e); + } + } + } + private static String computeLanguageAndCountryCandidate(String baseName, Locale locale) { String language = locale.getLanguage(); @@ -91,7 +111,8 @@ public class PropertyResourceBundleFinder { } } - private static String computeLanguageOnlyCandidate(String baseName, Locale locale) { + private static String computeLanguageOnlyCandidate(String baseName, + Locale locale) { String language = locale.getLanguage(); return baseName + "_" + language + ".properties"; } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/verifier/MessageKeyVerifier.java b/cal10n-api/src/main/java/ch/qos/cal10n/verifier/MessageKeyVerifier.java index c72e09d..deec78f 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/verifier/MessageKeyVerifier.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/verifier/MessageKeyVerifier.java @@ -31,7 +31,7 @@ import java.util.ResourceBundle; import java.util.Set; import ch.qos.cal10n.util.AnnotationExtractor; -import ch.qos.cal10n.util.PropertyResourceBundleFinder; +import ch.qos.cal10n.util.CAL10NResourceBundleFinder; import ch.qos.cal10n.util.MiscUtil; import ch.qos.cal10n.verifier.Cal10nError.ErrorType; @@ -84,8 +84,9 @@ public class MessageKeyVerifier implements IMessageKeyVerifier { return errorList; } - ResourceBundle rb = PropertyResourceBundleFinder.getBundle(this.getClass() - .getClassLoader(), baseName, locale); + String charset = AnnotationExtractor.getCharset(enumType, Locale.FRENCH); + ResourceBundle rb = CAL10NResourceBundleFinder.getBundle(this.getClass() + .getClassLoader(), baseName, locale, charset); ErrorFactory errorFactory = new ErrorFactory(enumType, locale, baseName); diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/util/Fruit.java b/cal10n-api/src/test/java/ch/qos/cal10n/util/Fruit.java index c48082b..f2515fb 100644 --- a/cal10n-api/src/test/java/ch/qos/cal10n/util/Fruit.java +++ b/cal10n-api/src/test/java/ch/qos/cal10n/util/Fruit.java @@ -26,11 +26,7 @@ import ch.qos.cal10n.BaseName; import ch.qos.cal10n.LocaleData; @BaseName("fruits") -@LocaleData({ - @Locale("fr"), - @Locale("en") - }) +@LocaleData(defaultCharset="", value = { @Locale("fr"), @Locale(value = "en", charset = "UTF8") }) public enum Fruit { - APPLE, - ORANGE; + APPLE, ORANGE; } diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/util/PropertyResourceBundleFinderTest.java b/cal10n-api/src/test/java/ch/qos/cal10n/util/PropertyResourceBundleFinderTest.java index 628f096..478e5b5 100644 --- a/cal10n-api/src/test/java/ch/qos/cal10n/util/PropertyResourceBundleFinderTest.java +++ b/cal10n-api/src/test/java/ch/qos/cal10n/util/PropertyResourceBundleFinderTest.java @@ -29,35 +29,43 @@ import java.util.ResourceBundle; import org.junit.Test; +import ch.qos.cal10n.sample.Colors; + public class PropertyResourceBundleFinderTest { ResourceBundle rb; - + String encoding; + + Class<?> enumTyoe = Colors.BLUE.getDeclaringClass(); + @Test public void smoke() throws IOException { - rb = PropertyResourceBundleFinder.getBundle(this.getClass().getClassLoader(), - "colors", Locale.FRENCH); + encoding = AnnotationExtractor.getCharset(enumTyoe, Locale.FRENCH); + rb = CAL10NResourceBundleFinder.getBundle(this.getClass().getClassLoader(), + "colors", Locale.FRENCH, encoding); assertEquals("les roses sont rouges", rb.getString("RED")); } @Test public void withCountry() throws IOException { - rb = PropertyResourceBundleFinder.getBundle(this.getClass().getClassLoader(), - "colors", Locale.FRENCH); + encoding = AnnotationExtractor.getCharset(enumTyoe, Locale.FRENCH); + rb = CAL10NResourceBundleFinder.getBundle(this.getClass().getClassLoader(), + "colors", Locale.FRENCH, encoding); assertEquals("les roses sont rouges", rb.getString("RED")); - rb = PropertyResourceBundleFinder.getBundle(this.getClass().getClassLoader(), - "colors", Locale.FRANCE); + rb = CAL10NResourceBundleFinder.getBundle(this.getClass().getClassLoader(), + "colors", Locale.FRANCE, encoding); assertEquals("les roses sont rouges, et alors?", rb.getString("RED")); } @Test public void inDirectory() throws IOException { - rb = PropertyResourceBundleFinder.getBundle(this.getClass().getClassLoader(), - "foobar/sample", Locale.ENGLISH); + encoding = AnnotationExtractor.getCharset(enumTyoe, Locale.ENGLISH); + rb = CAL10NResourceBundleFinder.getBundle(this.getClass().getClassLoader(), + "foobar/sample", Locale.ENGLISH, encoding); assertEquals("A is the first letter of the alphabet", rb.getString("A")); - rb = PropertyResourceBundleFinder.getBundle(this.getClass().getClassLoader(), - "foobar.sample", Locale.ENGLISH); + rb = CAL10NResourceBundleFinder.getBundle(this.getClass().getClassLoader(), + "foobar.sample", Locale.ENGLISH, encoding); assertEquals("A is the first letter of the alphabet", rb.getString("A")); } ----------------------------------------------------------------------- Summary of changes: cal10n-api/src/main/java/ch/qos/cal10n/Locale.java | 2 +- .../src/main/java/ch/qos/cal10n/LocaleData.java | 1 + .../main/java/ch/qos/cal10n/MessageConveyor.java | 29 ++++++---- .../ch/qos/cal10n/util/AnnotationExtractor.java | 58 ++++++++++++++++---- ...Finder.java => CAL10NResourceBundleFinder.java} | 41 +++++++++++---- .../ch/qos/cal10n/verifier/MessageKeyVerifier.java | 7 ++- .../src/test/java/ch/qos/cal10n/util/Fruit.java | 8 +-- .../util/PropertyResourceBundleFinderTest.java | 30 +++++++---- 8 files changed, 123 insertions(+), 53 deletions(-) rename cal10n-api/src/main/java/ch/qos/cal10n/util/{PropertyResourceBundleFinder.java => CAL10NResourceBundleFinder.java} (75%) hooks/post-receive -- Compiler assisted localization library