diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index 47b028066..98e2b650b 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -10,13 +10,14 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: com.jcraft.jsch;version="[0.1.41,0.2.0)", junit.framework;version="[3.8.2,4.0.0)", junit.textui;version="[3.8.2,4.0.0)", - org.eclipse.jgit.junit;version="[0.6.0,0.7.0)", org.eclipse.jgit.diff;version="[0.6.0,0.7.0)", org.eclipse.jgit.dircache;version="[0.6.0,0.7.0)", org.eclipse.jgit.errors;version="[0.6.0,0.7.0)", org.eclipse.jgit.fnmatch;version="[0.6.0,0.7.0)", + org.eclipse.jgit.junit;version="[0.6.0,0.7.0)", org.eclipse.jgit.lib;version="[0.6.0,0.7.0)", org.eclipse.jgit.merge;version="[0.6.0,0.7.0)", + org.eclipse.jgit.nls;version="[0.6.0,0.7.0)", org.eclipse.jgit.patch;version="[0.6.0,0.7.0)", org.eclipse.jgit.revplot;version="[0.6.0,0.7.0)", org.eclipse.jgit.revwalk;version="[0.6.0,0.7.0)", diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle.java new file mode 100644 index 000000000..579b57acd --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +public class GermanTranslatedBundle extends TranslationBundle { + public static GermanTranslatedBundle get() { + return NLS.getBundleFor(GermanTranslatedBundle.class); + } + + public String goodMorning; +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle.properties b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle.properties new file mode 100644 index 000000000..0e8cfc124 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle.properties @@ -0,0 +1 @@ +goodMorning=Good morning {0} \ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle_de.properties b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle_de.properties new file mode 100644 index 000000000..6b22bf66b --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/GermanTranslatedBundle_de.properties @@ -0,0 +1 @@ +goodMorning=Guten Morgen {0} \ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/MissingPropertyBundle.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/MissingPropertyBundle.java new file mode 100644 index 000000000..0459b80d2 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/MissingPropertyBundle.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +public class MissingPropertyBundle extends TranslationBundle { + public static MissingPropertyBundle get() { + return NLS.getBundleFor(MissingPropertyBundle.class); + } + + public String goodMorning; + public String nonTranslatedKey; +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/MissingPropertyBundle.properties b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/MissingPropertyBundle.properties new file mode 100644 index 000000000..0e8cfc124 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/MissingPropertyBundle.properties @@ -0,0 +1 @@ +goodMorning=Good morning {0} \ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NoPropertiesBundle.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NoPropertiesBundle.java new file mode 100644 index 000000000..f0232cad4 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NoPropertiesBundle.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +public class NoPropertiesBundle extends TranslationBundle { + public static NoPropertiesBundle get() { + return NLS.getBundleFor(NoPropertiesBundle.class); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NonTranslatedBundle.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NonTranslatedBundle.java new file mode 100644 index 000000000..9251af280 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NonTranslatedBundle.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +import org.eclipse.jgit.nls.NLS; +import org.eclipse.jgit.nls.TranslationBundle; + + +public class NonTranslatedBundle extends TranslationBundle { + public static NonTranslatedBundle get() { + return NLS.getBundleFor(NonTranslatedBundle.class); + } + + public String goodMorning; +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NonTranslatedBundle.properties b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NonTranslatedBundle.properties new file mode 100644 index 000000000..0e8cfc124 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/NonTranslatedBundle.properties @@ -0,0 +1 @@ +goodMorning=Good morning {0} \ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/TestNLS.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/TestNLS.java new file mode 100644 index 000000000..b6377c920 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/TestNLS.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +import java.util.Locale; +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +import junit.framework.TestCase; + + +public class TestNLS extends TestCase { + + public void testNLSLocale() { + NLS.setLocale(Locale.ROOT); + GermanTranslatedBundle bundle = GermanTranslatedBundle.get(); + assertEquals(Locale.ROOT, bundle.getEffectiveLocale()); + + NLS.setLocale(Locale.GERMAN); + bundle = GermanTranslatedBundle.get(); + assertEquals(Locale.GERMAN, bundle.getEffectiveLocale()); + } + + public void testJVMDefaultLocale() { + Locale.setDefault(Locale.ROOT); + NLS.useJVMDefaultLocale(); + GermanTranslatedBundle bundle = GermanTranslatedBundle.get(); + assertEquals(Locale.ROOT, bundle.getEffectiveLocale()); + + Locale.setDefault(Locale.GERMAN); + NLS.useJVMDefaultLocale(); + bundle = GermanTranslatedBundle.get(); + assertEquals(Locale.GERMAN, bundle.getEffectiveLocale()); + } + + public void testThreadTranslationBundleInheritance() throws InterruptedException { + + class T extends Thread { + GermanTranslatedBundle bundle; + @Override + public void run() { + bundle = GermanTranslatedBundle.get(); + } + } + + NLS.setLocale(Locale.ROOT); + GermanTranslatedBundle mainThreadsBundle = GermanTranslatedBundle.get(); + T t = new T(); + t.start(); + t.join(); + assertSame(mainThreadsBundle, t.bundle); + + NLS.setLocale(Locale.GERMAN); + mainThreadsBundle = GermanTranslatedBundle.get(); + t = new T(); + t.start(); + t.join(); + assertSame(mainThreadsBundle, t.bundle); + } + + public void testParallelThreadsWithDifferentLocales() throws InterruptedException { + + final CyclicBarrier barrier = new CyclicBarrier(2); + + class T extends Thread { + Locale locale; + GermanTranslatedBundle bundle; + Exception e; + + T(Locale locale) { + this.locale = locale; + } + + @Override + public void run() { + try { + NLS.setLocale(locale); + barrier.await(); // wait for the other thread to set its locale + bundle = GermanTranslatedBundle.get(); + } catch (InterruptedException e) { + this.e = e; + } catch (BrokenBarrierException e) { + this.e = e; + } + } + } + + T t1 = new T(Locale.ROOT); + T t2 = new T(Locale.GERMAN); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + assertNull("t1 was interrupted or barrier was broken", t1.e); + assertNull("t2 was interrupted or barrier was broken", t2.e); + assertEquals(Locale.ROOT, t1.bundle.getEffectiveLocale()); + assertEquals(Locale.GERMAN, t2.bundle.getEffectiveLocale()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/TestTranslationBundle.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/TestTranslationBundle.java new file mode 100644 index 000000000..58b42c9d4 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/nls/TestTranslationBundle.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +import java.util.Locale; + +import org.eclipse.jgit.errors.TranslationBundleLoadingException; +import org.eclipse.jgit.errors.TranslationStringMissingException; + +import junit.framework.TestCase; + +public class TestTranslationBundle extends TestCase { + + public void testMissingPropertiesFile() { + try { + new NoPropertiesBundle().load(Locale.ROOT); + fail("Expected TranslationBundleLoadingException"); + } catch (TranslationBundleLoadingException e) { + assertEquals(NoPropertiesBundle.class, e.getBundleClass()); + assertEquals(Locale.ROOT, e.getLocale()); + // pass + } + } + + public void testMissingString() { + try { + new MissingPropertyBundle().load(Locale.ROOT); + fail("Expected TranslationStringMissingException"); + } catch (TranslationStringMissingException e) { + assertEquals("nonTranslatedKey", e.getKey()); + assertEquals(MissingPropertyBundle.class, e.getBundleClass()); + assertEquals(Locale.ROOT, e.getLocale()); + // pass + } + } + + public void testNonTranslatedBundle() { + NonTranslatedBundle bundle = new NonTranslatedBundle(); + + bundle.load(Locale.ROOT); + assertEquals(Locale.ROOT, bundle.getEffectiveLocale()); + assertEquals("Good morning {0}", bundle.goodMorning); + + bundle.load(Locale.ENGLISH); + assertEquals(Locale.ROOT, bundle.getEffectiveLocale()); + assertEquals("Good morning {0}", bundle.goodMorning); + + bundle.load(Locale.GERMAN); + assertEquals(Locale.ROOT, bundle.getEffectiveLocale()); + assertEquals("Good morning {0}", bundle.goodMorning); + } + + public void testGermanTranslation() { + GermanTranslatedBundle bundle = new GermanTranslatedBundle(); + + bundle.load(Locale.ROOT); + assertEquals(Locale.ROOT, bundle.getEffectiveLocale()); + assertEquals("Good morning {0}", bundle.goodMorning); + + bundle.load(Locale.GERMAN); + assertEquals(Locale.GERMAN, bundle.getEffectiveLocale()); + assertEquals("Guten Morgen {0}", bundle.goodMorning); + } + +} diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index 93e0702f4..d2708ba64 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -11,6 +11,7 @@ Export-Package: org.eclipse.jgit.diff;version="0.6.0", org.eclipse.jgit.fnmatch;version="0.6.0", org.eclipse.jgit.lib;version="0.6.0", org.eclipse.jgit.merge;version="0.6.0", + org.eclipse.jgit.nls;version="0.6.0", org.eclipse.jgit.patch;version="0.6.0", org.eclipse.jgit.revplot;version="0.6.0", org.eclipse.jgit.revwalk;version="0.6.0", diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleException.java new file mode 100644 index 000000000..dc5f7a43c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleException.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.errors; + +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * Common base class for all translation bundle related exceptions. + */ +public abstract class TranslationBundleException extends RuntimeException { + private static final long serialVersionUID = 1L; + + private final Class bundleClass; + private final Locale locale; + + /** + * To construct an instance of {@link TranslationBundleException} + * + * @param message + * exception message + * @param bundleClass + * bundle class for which the exception occurred + * @param locale + * locale for which the exception occurred + * @param cause + * original exception that caused this exception. Usually thrown + * from the {@link ResourceBundle} class. + */ + protected TranslationBundleException(String message, Class bundleClass, Locale locale, Exception cause) { + super(message, cause); + this.bundleClass = bundleClass; + this.locale = locale; + } + + /** + * @return bundle class for which the exception occurred + */ + final public Class getBundleClass() { + return bundleClass; + } + + /** + * @return locale for which the exception occurred + */ + final public Locale getLocale() { + return locale; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleLoadingException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleLoadingException.java new file mode 100644 index 000000000..6bfe90048 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationBundleLoadingException.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.errors; + +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * This exception will be thrown when a translation bundle loading + * fails. + */ +public class TranslationBundleLoadingException extends TranslationBundleException { + private static final long serialVersionUID = 1L; + + /** + * Construct a {@link TranslationBundleLoadingException} for the specified + * bundle class and locale. + * + * @param bundleClass + * the bundle class for which the loading failed + * @param locale + * the locale for which the loading failed + * @param cause + * the original exception thrown from the + * {@link ResourceBundle#getBundle(String, Locale)} method. + */ + public TranslationBundleLoadingException(Class bundleClass, Locale locale, Exception cause) { + super("Loading of translation bundle failed for [" + + bundleClass.getName() + ", " + locale.toString() + "]", + bundleClass, locale, cause); + } +} \ No newline at end of file diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationStringMissingException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationStringMissingException.java new file mode 100644 index 000000000..a3c35b8da --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TranslationStringMissingException.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.errors; + +import java.util.Locale; +import java.util.ResourceBundle; + +/** + * This exception will be thrown when a translation string for a translation + * bundle and locale is missing. + */ +public class TranslationStringMissingException extends TranslationBundleException { + private static final long serialVersionUID = 1L; + + private final String key; + + /** + * Construct a {@link TranslationStringMissingException} for the specified + * bundle class, locale and translation key + * + * @param bundleClass + * the bundle class for which a translation string was missing + * @param locale + * the locale for which a translation string was missing + * @param key + * the key of the missing translation string + * @param cause + * the original exception thrown from the + * {@link ResourceBundle#getString(String)} method. + */ + public TranslationStringMissingException(Class bundleClass, Locale locale, String key, Exception cause) { + super("Translation missing for [" + bundleClass.getName() + ", " + + locale.toString() + ", " + key + "]", bundleClass, locale, + cause); + this.key = key; + } + + /** + * @return the key of the missing translation string + */ + public String getKey() { + return key; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java new file mode 100644 index 000000000..c95689ccb --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/GlobalBundleCache.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.eclipse.jgit.errors.TranslationBundleLoadingException; +import org.eclipse.jgit.errors.TranslationStringMissingException; + +/** + * Global cache of translation bundles. + *

+ * Every translation bundle will be cached here when it gets loaded for the + * first time from a thread. Another lookup for the same translation bundle + * (same locale and type) from the same or a different thread will return the + * cached one. + *

+ * Note that NLS instances maintain per-thread Map of loaded translation + * bundles. Once a thread accesses a translation bundle it will keep reference + * to it and will not call {@link #lookupBundle(Locale, Class)} again for the + * same translation bundle as long as its locale doesn't change. + */ +class GlobalBundleCache { + private static final Map> cachedBundles + = new HashMap>(); + + /** + * Looks up for a translation bundle in the global cache. If found returns + * the cached bundle. If not found creates a new instance puts it into the + * cache and returns it. + * + * @param + * required bundle type + * @param locale + * the preferred locale + * @param type + * required bundle type + * @return an instance of the required bundle type + * @exception TranslationBundleLoadingException see {@link TranslationBundle#load(Locale)} + * @exception TranslationStringMissingException see {@link TranslationBundle#load(Locale)} + */ + static synchronized T lookupBundle(Locale locale, Class type) { + try { + Map bundles = cachedBundles.get(locale); + if (bundles == null) { + bundles = new HashMap(); + cachedBundles.put(locale, bundles); + } + TranslationBundle bundle = bundles.get(type); + if (bundle == null) { + bundle = type.newInstance(); + bundle.load(locale); + bundles.put(type, bundle); + } + return (T) bundle; + } catch (InstantiationException e) { + throw new Error(e); + } catch (IllegalAccessException e) { + throw new Error(e); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java new file mode 100644 index 000000000..ece20bdb3 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/NLS.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +import java.util.Locale; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.jgit.errors.TranslationBundleLoadingException; +import org.eclipse.jgit.errors.TranslationStringMissingException; + +/** + * The purpose of this class is to provide NLS (National Language Support) + * configurable per thread. + * + *

+ * The {@link #setLocale(Locale)} method is used to configure locale for the + * calling thread. The locale setting is thread inheritable. This means that a + * child thread will have the same locale setting as its creator thread until it + * changes it explicitly. + * + *

+ * Example of usage: + * + *

+ * NLS.setLocale(Locale.GERMAN);
+ * TransportText t = NLS.getBundleFor(TransportText.class);
+ * 
+ */ +public class NLS { + + private static final InheritableThreadLocal local = new InheritableThreadLocal() { + protected NLS initialValue() { + return new NLS(Locale.getDefault()); + } + }; + + /** + * Sets the locale for the calling thread. + *

+ * The {@link #getBundleFor(Class)} method will honor this setting if if it + * is supported by the provided resource bundle property files. Otherwise, + * it will use a fall back locale as described in the + * {@link TranslationBundle} + * + * @param locale + * the preferred locale + */ + public static void setLocale(Locale locale) { + local.set(new NLS(locale)); + } + + /** + * Sets the JVM default locale as the locale for the calling thread. + *

+ * Semantically this is equivalent to NLS.setLocale(Locale.getDefault()). + */ + public static void useJVMDefaultLocale() { + local.set(new NLS(Locale.getDefault())); + } + + /** + * Returns an instance of the translation bundle of the required type. All + * public String fields of the bundle instance will get their values + * injected as described in the {@link TranslationBundle}. + * + * @param + * required bundle type + * @param type + * required bundle type + * @return an instance of the required bundle type + * @exception TranslationBundleLoadingException see {@link TranslationBundleLoadingException} + * @exception TranslationStringMissingException see {@link TranslationStringMissingException} + */ + public static T getBundleFor(Class type) { + return local.get().get(type); + } + + final private Locale locale; + final private ConcurrentHashMap map = new ConcurrentHashMap(); + + private NLS(Locale locale) { + this.locale = locale; + } + + private T get(Class type) { + TranslationBundle bundle = map.get(type); + if (bundle == null) { + bundle = GlobalBundleCache.lookupBundle(locale, type); + map.putIfAbsent(type, bundle); + } + return (T) bundle; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/nls/TranslationBundle.java b/org.eclipse.jgit/src/org/eclipse/jgit/nls/TranslationBundle.java new file mode 100644 index 000000000..c908aa055 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/nls/TranslationBundle.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2010, Sasa Zivkov + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.nls; + +import java.lang.reflect.Field; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import org.eclipse.jgit.errors.TranslationBundleLoadingException; +import org.eclipse.jgit.errors.TranslationStringMissingException; + +/** + * Base class for all translation bundles that provides injection of translated + * texts into public String fields. + * + *

+ * The usage pattern is shown with the following example. First define a new + * translation bundle: + * + *

+ * public class TransportText extends TranslationBundle {
+ * 	public static TransportText get() {
+ * 		return NLS.getBundleFor(TransportText.class);
+ * 	}
+ *
+ * 	public String repositoryNotFound;
+ *
+ * 	public String transportError;
+ * }
+ * 
+ * + * Second, define one or more resource bundle property files. + * + *
+ * TransportText_en_US.properties:
+ * 		repositoryNotFound=repository {0} not found
+ * 		transportError=unknown error talking to {0}
+ * TransportText_de.properties:
+ * 		repositoryNotFound=repository {0} nicht gefunden
+ * 		transportError=unbekannter Fehler während der Kommunikation mit {0}
+ * ...
+ * 
+ * + * Then make use of it: + * + *
+ * NLS.setLocale(Locale.GERMAN); // or skip this call to stick to the JVM default locale
+ * ...
+ * throw new TransportException(uri, TransportText.get().transportError);
+ * 
+ * + * The translated text is automatically injected into the public String fields + * according to the locale set with {@link NLS#setLocale(Locale)}. However, the + * {@link NLS#setLocale(Locale)} method defines only prefered locale which will + * be honored only if it is supported by the provided resource bundle property + * files. Basically, this class will use + * {@link ResourceBundle#getBundle(String, Locale)} method to load a resource + * bundle. See the documentation of this method for a detailed explanation of + * resource bundle loading strategy. After a bundle is created the + * {@link #getEffectiveLocale()} method can be used to determine whether the + * bundle really corresponds to the requested locale or is a fallback. + * + *

+ * To load a String from a resource bundle property file this class uses the + * {@link ResourceBundle#getString(String)}. This method can throw the + * {@link MissingResourceException} and this class is not making any effort to + * catch and/or translate this exception. + * + *

+ * To define a concrete translation bundle one has to: + *

    + *
  • extend this class + *
  • define a public static get() method like in the example above + *
  • define public static String fields for each text message + *
  • make sure the translation bundle class provide public no arg constructor + *
  • provide one or more resource bundle property files in the same package + * where the translation bundle class resides + *
+ */ +public abstract class TranslationBundle { + + private Locale effectiveLocale; + + /** + * @return the locale locale used for loading the resource bundle from which + * the field values were taken + */ + public Locale getEffectiveLocale() { + return effectiveLocale; + } + + /** + * Injects locale specific text in all instance fields of this instance. + * Only public instance fields of type String are considered. + *

+ * The name of this (sub)class plus the given locale parameter + * define the resource bundle to be loaded. In other words the + * this.getClass().getName() is used as the + * baseName parameter in the + * {@link ResourceBundle#getBundle(String, Locale)} parameter to load the + * resource bundle. + *

+ * + * @param locale + * defines the locale to be used when loading the resource bundle + * @exception TranslationBundleLoadingException see {@link TranslationBundleLoadingException} + * @exception TranslationStringMissingException see {@link TranslationStringMissingException} + */ + void load(Locale locale) throws TranslationBundleLoadingException { + Class bundleClass = getClass(); + ResourceBundle bundle; + try { + bundle = ResourceBundle.getBundle(bundleClass.getName(), locale); + } catch (MissingResourceException e) { + throw new TranslationBundleLoadingException(bundleClass, locale, e); + } + this.effectiveLocale = bundle.getLocale(); + + for (Field field : bundleClass.getFields()) { + if (field.getType().equals(String.class)) { + try { + String translatedText = bundle.getString(field.getName()); + field.set(this, translatedText); + } catch (MissingResourceException e) { + throw new TranslationStringMissingException(bundleClass, locale, field.getName(), e); + } catch (IllegalArgumentException e) { + throw new Error(e); + } catch (IllegalAccessException e) { + throw new Error(e); + } + } + } + } +} \ No newline at end of file