
The branch, master has been updated via c67c69e96c0f7b174f755a44eb4f60f1c8c5bd40 (commit) from 1ec0b269e1977256d9151568b0b5d6d634691848 (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=c67c69e96c0f7b174f755a44eb... http://github.com/ceki/cal10n/commit/c67c69e96c0f7b174f755a44eb4f60f1c8c5bd4... commit c67c69e96c0f7b174f755a44eb4f60f1c8c5bd40 Author: Ceki Gulcu <ceki@qos.ch> Date: Thu Sep 3 20:00:16 2009 +0200 Adding support for Reader based ResourceBunder population instead of InputStream diff --git a/cal10n-api/pom.xml b/cal10n-api/pom.xml index c40b7c1..34f8ee8 100644 --- a/cal10n-api/pom.xml +++ b/cal10n-api/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>ch.qos.cal10n</groupId> <artifactId>cal10n-parent</artifactId> - <version>0.6.5</version> + <version>0.7-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/LocaleNames.java b/cal10n-api/src/main/java/ch/qos/cal10n/Locale.java similarity index 93% copy from cal10n-api/src/main/java/ch/qos/cal10n/LocaleNames.java copy to cal10n-api/src/main/java/ch/qos/cal10n/Locale.java index 753441f..46eb612 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/LocaleNames.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/Locale.java @@ -59,6 +59,7 @@ import ch.qos.cal10n.verifier.MessageKeyVerifier; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface LocaleNames { - String[] value(); +public @interface Locale { + String value(); + String encoding() default "UTF-8"; } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/LocaleNames.java b/cal10n-api/src/main/java/ch/qos/cal10n/LocaleData.java similarity index 95% rename from cal10n-api/src/main/java/ch/qos/cal10n/LocaleNames.java rename to cal10n-api/src/main/java/ch/qos/cal10n/LocaleData.java index 753441f..1aeb2a3 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/LocaleNames.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/LocaleData.java @@ -59,6 +59,6 @@ import ch.qos.cal10n.verifier.MessageKeyVerifier; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface LocaleNames { - String[] value(); +public @interface LocaleData { + Locale[] value(); } 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 4d05573..fbf25d9 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyor.java @@ -28,7 +28,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import ch.qos.cal10n.util.AnnotationExtractor; -import ch.qos.cal10n.util.CAL10NPropertyResourceBundle; +import ch.qos.cal10n.util.CAL10NResourceBundle; import ch.qos.cal10n.util.PropertyResourceBundleFinder; /** @@ -44,7 +44,7 @@ public class MessageConveyor implements IMessageConveyor { final Locale locale; - final Map<String, CAL10NPropertyResourceBundle> cache = new ConcurrentHashMap<String, CAL10NPropertyResourceBundle>(); + final Map<String, CAL10NResourceBundle> cache = new ConcurrentHashMap<String, CAL10NResourceBundle>(); /** * The {@link Locale} associated with this instance. @@ -71,7 +71,7 @@ public class MessageConveyor implements IMessageConveyor { public <E extends Enum<?>> String getMessage(E key, Object... args) throws MessageConveyorException { String declararingClassName = key.getDeclaringClass().getName(); - CAL10NPropertyResourceBundle rb = cache.get(declararingClassName); + CAL10NResourceBundle rb = cache.get(declararingClassName); if (rb == null || rb.hasChanged()) { rb = lookup(key); cache.put(declararingClassName, rb); @@ -90,7 +90,7 @@ public class MessageConveyor implements IMessageConveyor { } } - private <E extends Enum<?>> CAL10NPropertyResourceBundle lookup(E key) throws MessageConveyorException { + private <E extends Enum<?>> CAL10NResourceBundle lookup(E key) throws MessageConveyorException { String baseName = AnnotationExtractor.getBaseName(key.getDeclaringClass()); if (baseName == null) { throw new MessageConveyorException( @@ -98,7 +98,7 @@ public class MessageConveyor implements IMessageConveyor { + key.getClass().getName() + "]. See also " + Cal10nConstants.MISSING_BN_ANNOTATION_URL); } - CAL10NPropertyResourceBundle rb = PropertyResourceBundleFinder.getBundle(this.getClass() + CAL10NResourceBundle rb = PropertyResourceBundleFinder.getBundle(this.getClass() .getClassLoader(), baseName, locale); if(rb == null) { diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyorException.java b/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyorException.java index bae5c6e..bce3cb5 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyorException.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/MessageConveyorException.java @@ -26,8 +26,11 @@ public class MessageConveyorException extends RuntimeException { private static final long serialVersionUID = 175752418665292427L; - MessageConveyorException(String msg) { + public MessageConveyorException(String msg) { super(msg); } + public MessageConveyorException(String msg, Throwable t) { + super(msg, t); + } } 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 3c555a5..6244c63 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 @@ -21,8 +21,9 @@ */ package ch.qos.cal10n.util; -import ch.qos.cal10n.LocaleNames; import ch.qos.cal10n.BaseName; +import ch.qos.cal10n.Locale; +import ch.qos.cal10n.LocaleData; /** * @@ -42,12 +43,27 @@ public class AnnotationExtractor { } static public <E extends Enum<?>> String[] getLocaleNames(Class<E> enumClass) { - LocaleNames localeNamesAnnotation = (LocaleNames) enumClass - .getAnnotation(LocaleNames.class); - if (localeNamesAnnotation == null) { + Locale[] localeDataArray = getLocaleData(enumClass); + + if(localeDataArray == null) { return null; } - return localeNamesAnnotation.value(); + + String[] names = new String[localeDataArray.length]; + 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); + if (localeDataArrayAnnotation == null) { + return null; + } + return localeDataArrayAnnotation.value(); } } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NPropertyResourceBundle.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundle.java similarity index 70% rename from cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NPropertyResourceBundle.java rename to cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundle.java index 45aecaf..a586380 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NPropertyResourceBundle.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/CAL10NResourceBundle.java @@ -23,25 +23,40 @@ package ch.qos.cal10n.util; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.util.PropertyResourceBundle; +import java.io.Reader; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Map; import java.util.ResourceBundle; +import java.util.concurrent.ConcurrentHashMap; -public class CAL10NPropertyResourceBundle extends PropertyResourceBundle { +/** + * + * @author Ceki Gülcü + * + */ +public class CAL10NResourceBundle extends ResourceBundle { static long CHECK_DELAY = 10 * 60 * 1000; // 10 minutes delay + Map<String, String> map = new ConcurrentHashMap<String, String>(); File hostFile; volatile long nextCheck; long lastModified; - public CAL10NPropertyResourceBundle(InputStream is, File file) + public CAL10NResourceBundle(Reader r, File file) throws IOException { - super(is); + read(r); this.hostFile = file; nextCheck = System.currentTimeMillis() + CHECK_DELAY; } + void read(Reader r) throws IOException { + Parser p = new Parser(r, map); + p.parseAndPopulate(); + } + + public void setParent(ResourceBundle parent) { super.setParent(parent); } @@ -73,4 +88,18 @@ public class CAL10NPropertyResourceBundle extends PropertyResourceBundle { nextCheck = 0; lastModified = 0; } + + @Override + public Enumeration<String> getKeys() { + Hashtable<String, String> ht = new Hashtable<String, String>(map); + return ht.keys(); + } + + @Override + protected Object handleGetObject(String key) { + if (key == null) { + throw new NullPointerException(); + } + return map.get(key); + } } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/Parser.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/Parser.java new file mode 100644 index 0000000..1aa0f9a --- /dev/null +++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/Parser.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2009 QOS.ch All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package ch.qos.cal10n.util; + +import java.io.Reader; +import java.util.List; +import java.util.Map; + + +/** + * + * @author Ceki Gülcü + * + */ +import ch.qos.cal10n.util.Token.TokenType; + +// Given tokens k,s,v, \, and EOL +// ^ denoting the null token +// here is the grammar + +// E = EOL | k s V | E | ^ +// V = v EOL | v '\' Vopt +// Vopt = EOL V + +public class Parser { + + final Reader reader; + final Map<String, String> map; + + List<Token> tokenList; + int pointer = 0; + + Parser(Reader r, Map<String, String> map) { + this.reader = r; + this.map = map; + TokenStream ts = new TokenStream(reader); + tokenList = ts.tokenize(); + } + + void parseAndPopulate() { + E(); + } + + private void E() { + Token t = getNextToken(); + if (t == null) { + // we are done + return; + } + switch (t.tokenType) { + case EOL: + break; + case KEY: + String k = t.getValue(); + t = getNextToken(); + if (t.tokenType != TokenType.SEPARATOR) { + throw new IllegalStateException("Unexpected token " + t); + } + StringBuilder buf = new StringBuilder(); + V(buf); + map.put(k, buf.toString()); + break; + } + E(); + } + + // V = v EOL | v '\' Vopt + // Vopt = EOL V + private void V(StringBuilder buf) { + + Token t = getNextToken(); + if (t.tokenType != TokenType.VALUE) { + throw new IllegalStateException("Unexpected token " + t); + } + buf.append(t.getValue()); + + t = getNextToken(); + if (t.tokenType == TokenType.EOL) { + return; + } else if (t.tokenType == TokenType.TRAILING_BACKSLASH) { + Vopt(buf); + + } + } + + private void Vopt(StringBuilder buf) { + Token t = getNextToken(); + if (t.tokenType != TokenType.EOL) { + throw new IllegalStateException("Unexpected token " + t); + } + V(buf); + } + + private Token getNextToken() { + if (pointer < tokenList.size()) { + return (Token) tokenList.get(pointer++); + } + return null; + } + +// private Token getCurentToken() { +// if (pointer < tokenList.size()) { +// return (Token) tokenList.get(pointer); +// } +// return null; +// } +// +// private void advanceTokenPointer() { +// pointer++; +// } +} diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/PropertyResourceBundleFinder.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/PropertyResourceBundleFinder.java index 9d4c094..3c767ce 100644 --- a/cal10n-api/src/main/java/ch/qos/cal10n/util/PropertyResourceBundleFinder.java +++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/PropertyResourceBundleFinder.java @@ -23,13 +23,15 @@ package ch.qos.cal10n.util; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; import java.net.URL; import java.net.URLConnection; import java.util.Locale; public class PropertyResourceBundleFinder { - public static CAL10NPropertyResourceBundle getBundle(ClassLoader classLoader, String baseName, + public static CAL10NResourceBundle getBundle(ClassLoader classLoader, String baseName, Locale locale) { // same as the JDK convention @@ -44,9 +46,9 @@ public class PropertyResourceBundleFinder { String languageOnlyCandidate = computeLanguageOnlyCandidate(baseName, locale); - CAL10NPropertyResourceBundle cprbLanguageOnly = makePropertyResourceBundle( + CAL10NResourceBundle cprbLanguageOnly = makePropertyResourceBundle( classLoader, languageOnlyCandidate); - CAL10NPropertyResourceBundle cprbLanguageAndCountry = null; + CAL10NResourceBundle cprbLanguageAndCountry = null; if (languageAndCountryCandidate != null) { cprbLanguageAndCountry = makePropertyResourceBundle(classLoader, @@ -60,16 +62,17 @@ public class PropertyResourceBundleFinder { return cprbLanguageOnly; } - private static CAL10NPropertyResourceBundle makePropertyResourceBundle( + private static CAL10NResourceBundle makePropertyResourceBundle( ClassLoader classLoader, String resourceCandiate) { - CAL10NPropertyResourceBundle prb = null; + CAL10NResourceBundle prb = null; URL url = classLoader.getResource(resourceCandiate); if (url != null) { try { InputStream in = openConnectionForUrl(url); - prb = new CAL10NPropertyResourceBundle(in, MiscUtil.urlToFile(url)); + Reader reader = new InputStreamReader(in); + prb = new CAL10NResourceBundle(reader, MiscUtil.urlToFile(url)); in.close(); } catch (IOException e) { } diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/Token.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/Token.java new file mode 100644 index 0000000..0f96852 --- /dev/null +++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/Token.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2009 QOS.ch All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package ch.qos.cal10n.util; + +/** + * + * @author Ceki Gülcü + * + */ +public class Token { + + final static Token EOL = new Token(TokenType.EOL); + final static Token TRAILING_BACKSLASH = new Token(TokenType.TRAILING_BACKSLASH); + + enum TokenType { + KEY, + SEPARATOR, + VALUE, + TRAILING_BACKSLASH, + EOL; + } + + final TokenType tokenType; + final String value; + + + Token(TokenType tokenType) { + this(tokenType, null); + } + + Token(TokenType tokenType, String value) { + this.tokenType = tokenType; + this.value = value; + } + + + public TokenType getTokenType() { + return tokenType; + } + + public String getValue() { + return value; + } + + public String toString() { + if (value == null) { + return "Token(" + tokenType + ")"; + } else { + return "Token(" + tokenType + ", \"" + value + "\")"; + } + } + + @Override + public int hashCode() { + return tokenType.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Token other = (Token) obj; + + if (!tokenType.equals(other.tokenType)) + return false; + + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + + +} diff --git a/cal10n-api/src/main/java/ch/qos/cal10n/util/TokenStream.java b/cal10n-api/src/main/java/ch/qos/cal10n/util/TokenStream.java new file mode 100644 index 0000000..32ecf0f --- /dev/null +++ b/cal10n-api/src/main/java/ch/qos/cal10n/util/TokenStream.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2009 QOS.ch All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package ch.qos.cal10n.util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +import ch.qos.cal10n.MessageConveyorException; +import ch.qos.cal10n.util.Token.TokenType; + +/** + * + * @author Ceki Gülcü + * + */ +public class TokenStream { + + enum State { + START, COMMENT, KEY, SEPARATOR, VAL, TRAILING_BACKSLASH; + } + + BufferedReader lineReader; + State state = State.START; + + TokenStream(Reader reader) { + this.lineReader = new BufferedReader(reader); + } + + List<Token> tokenize() { + List<Token> tokenList = new ArrayList<Token>(); + + while (true) { + String currentLine; + try { + currentLine = lineReader.readLine(); + } catch (IOException e) { + throw new MessageConveyorException("Failed to read input stream", e); + } + if (currentLine == null) { + break; + } + if(state != State.TRAILING_BACKSLASH) { + state = State.START; + } + tokenizeLine(tokenList, currentLine); + tokenList.add(Token.EOL); + } + + return tokenList; + } + + private void tokenizeLine(List<Token> tokenList, String line) { + int len = line.length(); + StringBuffer buf = new StringBuffer(); + + for (int pointer = 0; pointer < len; pointer++) { + char c = line.charAt(pointer); + switch (state) { + case START: + if (isWhiteSpace(c)) { + // same sate + } else if (c == '#') { + state = State.COMMENT; + return; + } else if (isNonWhiteSpaceSeparator(c)) { + state = State.SEPARATOR; + buf.append(c); + } else { + state = State.KEY; + buf.append(c); + } + break; + + case KEY: + if (isWhiteSpace(c) || isNonWhiteSpaceSeparator(c)) { + tokenList.add(new Token(TokenType.KEY, buf.toString())); + buf.setLength(0); + buf.append(c); + state = State.SEPARATOR; + } else { + buf.append(c); + } + break; + + case SEPARATOR: + + if (isWhiteSpace(c) || isNonWhiteSpaceSeparator(c)) { + buf.append(c); + } else { + tokenList.add(new Token(TokenType.SEPARATOR, buf.toString())); + buf.setLength(0); + buf.append(c); + state = State.VAL; + } + break; + + case VAL: + if(c == '\\') { + if(isTrailingBackSlash(line, pointer+1)) { + tokenList.add(new Token(TokenType.VALUE, buf.toString())); + buf.setLength(0); + state = State.TRAILING_BACKSLASH; + tokenList.add(Token.TRAILING_BACKSLASH); + return; + } else { + buf.append(c); + } + } else { + buf.append(c); + } + break; + + case TRAILING_BACKSLASH: + if (!isWhiteSpace(c)) { + buf.append(c); + state = State.VAL; + } + } + } + + if(state == State.VAL) { + tokenList.add(new Token(TokenType.VALUE, buf.toString())); + buf.setLength(0); + } + } + + boolean isTrailingBackSlash(String line, int next) { + int len = line.length(); + for(int i = next; i < len; i++) { + char c = line.charAt(i); + if(!isWhiteSpace(c)) + return false; + } + return true; + } + + boolean isWhiteSpace(char c) { + switch (c) { + case ' ': + case '\t': + return true; + default: + return false; + } + } + + boolean isNonWhiteSpaceSeparator(char c) { + switch (c) { + case ':': + case '=': + return true; + default: + return false; + } + } +} diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/Cal10nTestConstants.java b/cal10n-api/src/test/java/ch/qos/cal10n/Cal10nTestConstants.java new file mode 100644 index 0000000..828ed4c --- /dev/null +++ b/cal10n-api/src/test/java/ch/qos/cal10n/Cal10nTestConstants.java @@ -0,0 +1,6 @@ +package ch.qos.cal10n; + +public class Cal10nTestConstants { + + public static String TEST_CLASSES = "target/test-classes/"; +} diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/MessageConveyorReloadTest.java b/cal10n-api/src/test/java/ch/qos/cal10n/MessageConveyorReloadTest.java index 978e507..8d3c289 100644 --- a/cal10n-api/src/test/java/ch/qos/cal10n/MessageConveyorReloadTest.java +++ b/cal10n-api/src/test/java/ch/qos/cal10n/MessageConveyorReloadTest.java @@ -34,7 +34,7 @@ import java.util.ResourceBundle; import org.junit.Test; import ch.qos.cal10n.sample.Colors; -import ch.qos.cal10n.util.CAL10NPropertyResourceBundle; +import ch.qos.cal10n.util.CAL10NResourceBundle; import ch.qos.cal10n.util.MiscUtil; public class MessageConveyorReloadTest { @@ -50,7 +50,7 @@ public class MessageConveyorReloadTest { MessageConveyor mc = new MessageConveyor(new Locale("en")); mc.getMessage(Colors.BLUE); - CAL10NPropertyResourceBundle initalRB = mc.cache.get(Colors.BLUE.getDeclaringClass().getName()); + CAL10NResourceBundle initalRB = mc.cache.get(Colors.BLUE.getDeclaringClass().getName()); initalRB.resetCheckTimes(); File file = MiscUtil.urlToFile(url); file.setLastModified(System.currentTimeMillis()+60*60*1000); diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/sample/Colors.java b/cal10n-api/src/test/java/ch/qos/cal10n/sample/Colors.java index 8c026bb..33f9060 100644 --- a/cal10n-api/src/test/java/ch/qos/cal10n/sample/Colors.java +++ b/cal10n-api/src/test/java/ch/qos/cal10n/sample/Colors.java @@ -22,11 +22,15 @@ package ch.qos.cal10n.sample; -import ch.qos.cal10n.LocaleNames; import ch.qos.cal10n.BaseName; +import ch.qos.cal10n.Locale; +import ch.qos.cal10n.LocaleData; @BaseName("colors") -@LocaleNames({"en_UK", "fr"}) +@LocaleData({ + @Locale("en_UK"), + @Locale("fr") + }) public enum Colors { // sub-class for testing purposes RED { diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/sample/Countries.java b/cal10n-api/src/test/java/ch/qos/cal10n/sample/Countries.java index 333fbfa..785b1a9 100644 --- a/cal10n-api/src/test/java/ch/qos/cal10n/sample/Countries.java +++ b/cal10n-api/src/test/java/ch/qos/cal10n/sample/Countries.java @@ -21,16 +21,19 @@ */ package ch.qos.cal10n.sample; -import ch.qos.cal10n.LocaleNames; +import ch.qos.cal10n.Locale; import ch.qos.cal10n.BaseName; +import ch.qos.cal10n.LocaleData; @BaseName("countries") -@LocaleNames({"en", "fr"}) +@LocaleData({ + @Locale("en"), + @Locale("fr") + }) public enum Countries { CH, // Switzerland (Confederation Helvetique) CN, // China FR, // France US, // United States UK; // United Kingdom - } diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/sample/Furnitures.java b/cal10n-api/src/test/java/ch/qos/cal10n/sample/Furnitures.java index 07e91b9..fe6ea23 100644 --- a/cal10n-api/src/test/java/ch/qos/cal10n/sample/Furnitures.java +++ b/cal10n-api/src/test/java/ch/qos/cal10n/sample/Furnitures.java @@ -21,11 +21,15 @@ */ package ch.qos.cal10n.sample; -import ch.qos.cal10n.LocaleNames; +import ch.qos.cal10n.Locale; import ch.qos.cal10n.BaseName; +import ch.qos.cal10n.LocaleData; @BaseName("furnitures") -@LocaleNames({"en_UK", "fr"}) +@LocaleData({ + @Locale("en_UK"), + @Locale("fr") + }) public enum Furnitures { TABLE, CHAIR, 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 28dcab4..c48082b 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 @@ -21,11 +21,15 @@ */ package ch.qos.cal10n.util; -import ch.qos.cal10n.LocaleNames; +import ch.qos.cal10n.Locale; import ch.qos.cal10n.BaseName; +import ch.qos.cal10n.LocaleData; @BaseName("fruits") -@LocaleNames({"fr", "en"}) +@LocaleData({ + @Locale("fr"), + @Locale("en") + }) public enum Fruit { APPLE, ORANGE; diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/util/PackageTest.java b/cal10n-api/src/test/java/ch/qos/cal10n/util/PackageTest.java index 857db24..f5622df 100644 --- a/cal10n-api/src/test/java/ch/qos/cal10n/util/PackageTest.java +++ b/cal10n-api/src/test/java/ch/qos/cal10n/util/PackageTest.java @@ -28,6 +28,7 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses( { AnnotationExtractorTest.class, MiscUtilTest.class, - PropertyResourceBundleFinderTest.class }) + TokenStreamTest.class, ParserTest.class, + PropertyResourceBundleFinderTest.class }) public class PackageTest { } diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/util/ParserTest.java b/cal10n-api/src/test/java/ch/qos/cal10n/util/ParserTest.java new file mode 100644 index 0000000..a8bef1e --- /dev/null +++ b/cal10n-api/src/test/java/ch/qos/cal10n/util/ParserTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2009 QOS.ch All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package ch.qos.cal10n.util; + +import static org.junit.Assert.assertEquals; + +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; + +import ch.qos.cal10n.Cal10nTestConstants; + +public class ParserTest { + + Map<String, String> map = new HashMap<String, String>(); + Map<String, String> witness = new HashMap<String, String>(); + + + @Test + public void smoke() throws IOException { + FileReader fr = new FileReader(Cal10nTestConstants.TEST_CLASSES+"/parser/smoke.properties"); + Parser parser = new Parser(fr, map); + parser.parseAndPopulate(); + + witness.put("K0", "V0"); + witness.put("K1", "V1"); + assertEquals(witness, map); + } + + + @Test + public void medium() throws IOException { + FileReader fr = new FileReader(Cal10nTestConstants.TEST_CLASSES+"/parser/medium.properties"); + Parser parser = new Parser(fr, map); + parser.parseAndPopulate(); + + witness.put("K0", "V0 X"); + witness.put("K1", "V1"); + assertEquals(witness, map); + } + + @Test + public void full() throws IOException { + FileReader fr = new FileReader(Cal10nTestConstants.TEST_CLASSES+"/parser/full.properties"); + Parser parser = new Parser(fr, map); + parser.parseAndPopulate(); + + witness.put("K0", "V0 X"); + witness.put("K1", "V1"); + witness.put("K2", "V2 l1l2 l3"); + witness.put("K3", "V3 \\t a"); + assertEquals(witness, map); + } + + +} diff --git a/cal10n-api/src/test/java/ch/qos/cal10n/util/TokenStreamTest.java b/cal10n-api/src/test/java/ch/qos/cal10n/util/TokenStreamTest.java new file mode 100644 index 0000000..bc4c055 --- /dev/null +++ b/cal10n-api/src/test/java/ch/qos/cal10n/util/TokenStreamTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2009 QOS.ch All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package ch.qos.cal10n.util; + +import static org.junit.Assert.*; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import ch.qos.cal10n.Cal10nTestConstants; +import ch.qos.cal10n.util.Token.TokenType; + +/** + * + * @author Ceki Gülcü + * + */ +public class TokenStreamTest { + + + @Test + public void smoke() throws FileNotFoundException { + FileReader fr = new FileReader(Cal10nTestConstants.TEST_CLASSES+"/parser/smoke.properties"); + TokenStream ts = new TokenStream(fr); + List<Token> tokenList = ts.tokenize(); + + List<Token> witness = new ArrayList<Token>(); + witness.add(new Token(TokenType.KEY, "K0")); + witness.add(new Token(TokenType.SEPARATOR, "=")); + witness.add(new Token(TokenType.VALUE, "V0")); + witness.add(Token.EOL); + + witness.add(new Token(TokenType.KEY, "K1")); + witness.add(new Token(TokenType.SEPARATOR, "=")); + witness.add(new Token(TokenType.VALUE, "V1")); + witness.add(Token.EOL); + assertEquals(witness, tokenList); + } + + @Test + public void medium() throws FileNotFoundException { + FileReader fr = new FileReader(Cal10nTestConstants.TEST_CLASSES+"/parser/medium.properties"); + TokenStream ts = new TokenStream(fr); + List<Token> tokenList = ts.tokenize(); + + // K0=V0 \ + // X + // # comment + // K1=V1 + + + List<Token> witness = new ArrayList<Token>(); + witness.add(new Token(TokenType.KEY, "K0")); + witness.add(new Token(TokenType.SEPARATOR, "=")); + witness.add(new Token(TokenType.VALUE, "V0 ")); + witness.add(Token.TRAILING_BACKSLASH); + witness.add(Token.EOL); + witness.add(new Token(TokenType.VALUE, "X")); + witness.add(Token.EOL); + witness.add(Token.EOL); + + witness.add(new Token(TokenType.KEY, "K1")); + witness.add(new Token(TokenType.SEPARATOR, "=")); + witness.add(new Token(TokenType.VALUE, "V1")); + witness.add(Token.EOL); + assertEquals(witness, tokenList); + } + +} diff --git a/cal10n-api/src/test/resources/parser/full.properties b/cal10n-api/src/test/resources/parser/full.properties new file mode 100644 index 0000000..f2f00da --- /dev/null +++ b/cal10n-api/src/test/resources/parser/full.properties @@ -0,0 +1,20 @@ + + +# comment + # comment +K0=V0 \ + X +# comment +K1=V1 + + K2 : V2 \ +l1\ +l2 \ +l3 + +# +K3 = V3 \t a + + # comment + + diff --git a/cal10n-api/src/test/resources/parser/medium.properties b/cal10n-api/src/test/resources/parser/medium.properties new file mode 100644 index 0000000..74c0798 --- /dev/null +++ b/cal10n-api/src/test/resources/parser/medium.properties @@ -0,0 +1,4 @@ +K0=V0 \ + X +# comment +K1=V1 \ No newline at end of file diff --git a/cal10n-api/src/test/resources/parser/smoke.properties b/cal10n-api/src/test/resources/parser/smoke.properties new file mode 100644 index 0000000..565ee41 --- /dev/null +++ b/cal10n-api/src/test/resources/parser/smoke.properties @@ -0,0 +1,2 @@ +K0=V0 +K1=V1 \ No newline at end of file diff --git a/cal10n-site/pom.xml b/cal10n-site/pom.xml index c5fefa4..055e6f8 100644 --- a/cal10n-site/pom.xml +++ b/cal10n-site/pom.xml @@ -5,7 +5,7 @@ <parent> <groupId>ch.qos.cal10n</groupId> <artifactId>cal10n-parent</artifactId> - <version>0.6.5</version> + <version>0.7-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/cal10n-site/src/site/pages/manual.html b/cal10n-site/src/site/pages/manual.html index 88a8aa1..5699e42 100644 --- a/cal10n-site/src/site/pages/manual.html +++ b/cal10n-site/src/site/pages/manual.html @@ -208,7 +208,7 @@ colors_fr_FR.properties</pre> <p>When a resource bundle for a given locale is changed on the file system, <code>MessageConveyor</code> will automatically reload the - resource bundle. It may take at most 10 minutes for the change to be + resource bundle. It may take up to 10 minutes for the change to be detected.</p> <p>Automatic reloading applies if the resource bundle is a regular diff --git a/maven-cal10n-plugin-smoke/pom.xml b/maven-cal10n-plugin-smoke/pom.xml index a7f6cc8..7e58cb0 100644 --- a/maven-cal10n-plugin-smoke/pom.xml +++ b/maven-cal10n-plugin-smoke/pom.xml @@ -4,7 +4,7 @@ <parent> <groupId>ch.qos.cal10n</groupId> <artifactId>cal10n-parent</artifactId> - <version>0.6.5</version> + <version>0.7-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/maven-cal10n-plugin-smoke/src/main/java/ch/qos/cal10n/smoke/Countries.java b/maven-cal10n-plugin-smoke/src/main/java/ch/qos/cal10n/smoke/Countries.java index ea6f271..2038552 100644 --- a/maven-cal10n-plugin-smoke/src/main/java/ch/qos/cal10n/smoke/Countries.java +++ b/maven-cal10n-plugin-smoke/src/main/java/ch/qos/cal10n/smoke/Countries.java @@ -1,10 +1,14 @@ package ch.qos.cal10n.smoke; -import ch.qos.cal10n.LocaleNames; +import ch.qos.cal10n.Locale; import ch.qos.cal10n.BaseName; +import ch.qos.cal10n.LocaleData; @BaseName("countries") -@LocaleNames({"en", "fr"}) +@LocaleData({ + @Locale("en"), + @Locale("fr") + }) public enum Countries { CH, CN, diff --git a/maven-cal10n-plugin/pom.xml b/maven-cal10n-plugin/pom.xml index 476b445..d01ce41 100644 --- a/maven-cal10n-plugin/pom.xml +++ b/maven-cal10n-plugin/pom.xml @@ -8,7 +8,7 @@ <parent> <artifactId>cal10n-parent</artifactId> <groupId>ch.qos.cal10n</groupId> - <version>0.6.5</version> + <version>0.7-SNAPSHOT</version> </parent> <groupId>ch.qos.cal10n.plugins</groupId> diff --git a/pom.xml b/pom.xml index 236a95b..a024491 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ <groupId>ch.qos.cal10n</groupId> <artifactId>cal10n-parent</artifactId> <packaging>pom</packaging> - <version>0.6.5</version> + <version>0.7-SNAPSHOT</version> <name>Compiler assisted localization library (CAL10N) - Parent</name> <url>http://cal10n.qos.ch</url> ----------------------------------------------------------------------- Summary of changes: cal10n-api/pom.xml | 2 +- .../qos/cal10n/{LocaleNames.java => Locale.java} | 5 +- .../cal10n/{LocaleNames.java => LocaleData.java} | 4 +- .../main/java/ch/qos/cal10n/MessageConveyor.java | 10 +- .../ch/qos/cal10n/MessageConveyorException.java | 5 +- .../ch/qos/cal10n/util/AnnotationExtractor.java | 26 +++- ...sourceBundle.java => CAL10NResourceBundle.java} | 39 ++++- .../src/main/java/ch/qos/cal10n/util/Parser.java | 130 ++++++++++++++ .../cal10n/util/PropertyResourceBundleFinder.java | 15 +- .../src/main/java/ch/qos/cal10n/util/Token.java | 99 +++++++++++ .../main/java/ch/qos/cal10n/util/TokenStream.java | 178 ++++++++++++++++++++ .../java/ch/qos/cal10n/Cal10nTestConstants.java | 6 + .../ch/qos/cal10n/MessageConveyorReloadTest.java | 4 +- .../src/test/java/ch/qos/cal10n/sample/Colors.java | 8 +- .../test/java/ch/qos/cal10n/sample/Countries.java | 9 +- .../test/java/ch/qos/cal10n/sample/Furnitures.java | 8 +- .../src/test/java/ch/qos/cal10n/util/Fruit.java | 8 +- .../test/java/ch/qos/cal10n/util/PackageTest.java | 3 +- ...sourceBundleFinderTest.java => ParserTest.java} | 63 ++++--- .../java/ch/qos/cal10n/util/TokenStreamTest.java | 92 ++++++++++ .../src/test/resources/parser/full.properties | 20 +++ .../src/test/resources/parser/medium.properties | 4 + .../src/test/resources/parser/smoke.properties | 2 + cal10n-site/pom.xml | 2 +- cal10n-site/src/site/pages/manual.html | 2 +- maven-cal10n-plugin-smoke/pom.xml | 2 +- .../main/java/ch/qos/cal10n/smoke/Countries.java | 8 +- maven-cal10n-plugin/pom.xml | 2 +- pom.xml | 2 +- 29 files changed, 687 insertions(+), 71 deletions(-) copy cal10n-api/src/main/java/ch/qos/cal10n/{LocaleNames.java => Locale.java} (93%) rename cal10n-api/src/main/java/ch/qos/cal10n/{LocaleNames.java => LocaleData.java} (95%) rename cal10n-api/src/main/java/ch/qos/cal10n/util/{CAL10NPropertyResourceBundle.java => CAL10NResourceBundle.java} (70%) create mode 100644 cal10n-api/src/main/java/ch/qos/cal10n/util/Parser.java create mode 100644 cal10n-api/src/main/java/ch/qos/cal10n/util/Token.java create mode 100644 cal10n-api/src/main/java/ch/qos/cal10n/util/TokenStream.java create mode 100644 cal10n-api/src/test/java/ch/qos/cal10n/Cal10nTestConstants.java copy cal10n-api/src/test/java/ch/qos/cal10n/util/{PropertyResourceBundleFinderTest.java => ParserTest.java} (50%) create mode 100644 cal10n-api/src/test/java/ch/qos/cal10n/util/TokenStreamTest.java create mode 100644 cal10n-api/src/test/resources/parser/full.properties create mode 100644 cal10n-api/src/test/resources/parser/medium.properties create mode 100644 cal10n-api/src/test/resources/parser/smoke.properties hooks/post-receive -- Compiler assisted localization library