Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 372119 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF (-2 / +2 lines)
Lines 16-22 Import-Package: org.eclipse.jgit.api;version="[2.0.0,2.1.0)", Link Here
16
 org.eclipse.jgit.iplog;version="[2.0.0,2.1.0)",
16
 org.eclipse.jgit.iplog;version="[2.0.0,2.1.0)",
17
 org.eclipse.jgit.lib;version="[2.0.0,2.1.0)",
17
 org.eclipse.jgit.lib;version="[2.0.0,2.1.0)",
18
 org.eclipse.jgit.merge;version="2.0.0",
18
 org.eclipse.jgit.merge;version="2.0.0",
19
 org.eclipse.jgit.nls;version="[2.0.0,2.1.0)",
20
 org.eclipse.jgit.notes;version="[2.0.0,2.1.0)",
19
 org.eclipse.jgit.notes;version="[2.0.0,2.1.0)",
21
 org.eclipse.jgit.revplot;version="[2.0.0,2.1.0)",
20
 org.eclipse.jgit.revplot;version="[2.0.0,2.1.0)",
22
 org.eclipse.jgit.revwalk;version="[2.0.0,2.1.0)",
21
 org.eclipse.jgit.revwalk;version="[2.0.0,2.1.0)",
Lines 39-44 Export-Package: org.eclipse.jgit.pgm;version="2.0.0"; Link Here
39
   javax.swing,
38
   javax.swing,
40
   org.eclipse.jgit.pgm.opt,
39
   org.eclipse.jgit.pgm.opt,
41
   org.eclipse.jgit.awtui,
40
   org.eclipse.jgit.awtui,
42
   org.eclipse.jgit.transport"
41
   org.eclipse.jgit.transport",
42
 org.eclipse.jgit.pgm.opt;version="2.0.0"
43
Main-Class: org.eclipse.jgit.pgm.Main
43
Main-Class: org.eclipse.jgit.pgm.Main
44
Implementation-Title: JGit Command Line Interface
44
Implementation-Title: JGit Command Line Interface
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/CLIText.java (-2 / +2 lines)
Lines 43-50 Link Here
43
43
44
package org.eclipse.jgit.pgm;
44
package org.eclipse.jgit.pgm;
45
45
46
import org.eclipse.jgit.nls.NLS;
46
import org.eclipse.jgit.pgm.nls.NLS;
47
import org.eclipse.jgit.nls.TranslationBundle;
47
import org.eclipse.jgit.pgm.nls.TranslationBundle;
48
48
49
/**
49
/**
50
 * Translation bundle for JGit command line interface
50
 * Translation bundle for JGit command line interface
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Clone.java (-1 / +1 lines)
Lines 89-95 Link Here
89
	private FileRepository dst;
89
	private FileRepository dst;
90
90
91
	@Override
91
	@Override
92
	protected final boolean requiresRepository() {
92
	public final boolean requiresRepository() {
93
		return false;
93
		return false;
94
	}
94
	}
95
95
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java (-1 / +1 lines)
Lines 94-100 Link Here
94
	final List<File> directory = new ArrayList<File>();
94
	final List<File> directory = new ArrayList<File>();
95
95
96
	@Override
96
	@Override
97
	protected boolean requiresRepository() {
97
	public boolean requiresRepository() {
98
		return false;
98
		return false;
99
	}
99
	}
100
100
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java (-1 / +1 lines)
Lines 61-67 Link Here
61
	private boolean bare;
61
	private boolean bare;
62
62
63
	@Override
63
	@Override
64
	protected final boolean requiresRepository() {
64
	public final boolean requiresRepository() {
65
		return false;
65
		return false;
66
	}
66
	}
67
67
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/ReceivePack.java (-1 / +1 lines)
Lines 58-64 Link Here
58
	File dstGitdir;
58
	File dstGitdir;
59
59
60
	@Override
60
	@Override
61
	protected final boolean requiresRepository() {
61
	public final boolean requiresRepository() {
62
		return false;
62
		return false;
63
	}
63
	}
64
64
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/TextBuiltin.java (-3 / +3 lines)
Lines 80-86 Link Here
80
	private boolean help;
80
	private boolean help;
81
81
82
	/** Stream to output to, typically this is standard output. */
82
	/** Stream to output to, typically this is standard output. */
83
	protected PrintWriter out;
83
	public PrintWriter out;
84
84
85
	/** Git repository the command was invoked within. */
85
	/** Git repository the command was invoked within. */
86
	protected Repository db;
86
	protected Repository db;
Lines 96-102 final void setCommandName(final String name) { Link Here
96
	}
96
	}
97
97
98
	/** @return true if {@link #db}/{@link #getRepository()} is required. */
98
	/** @return true if {@link #db}/{@link #getRepository()} is required. */
99
	protected boolean requiresRepository() {
99
	public boolean requiresRepository() {
100
		return true;
100
		return true;
101
	}
101
	}
102
102
Lines 109-115 protected boolean requiresRepository() { Link Here
109
	 *            value of the {@code --git-dir} command line option, if
109
	 *            value of the {@code --git-dir} command line option, if
110
	 *            {@code repository} is null.
110
	 *            {@code repository} is null.
111
	 */
111
	 */
112
	protected void init(final Repository repository, final String gitDir) {
112
	public void init(final Repository repository, final String gitDir) {
113
		try {
113
		try {
114
			final String outputEncoding = repository != null ? repository
114
			final String outputEncoding = repository != null ? repository
115
					.getConfig()
115
					.getConfig()
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/UploadPack.java (-1 / +1 lines)
Lines 62-68 Link Here
62
	File srcGitdir;
62
	File srcGitdir;
63
63
64
	@Override
64
	@Override
65
	protected final boolean requiresRepository() {
65
	public final boolean requiresRepository() {
66
		return false;
66
		return false;
67
	}
67
	}
68
68
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Version.java (-1 / +1 lines)
Lines 57-63 protected void run() throws Exception { Link Here
57
	}
57
	}
58
58
59
	@Override
59
	@Override
60
	protected final boolean requiresRepository() {
60
	public final boolean requiresRepository() {
61
		return false;
61
		return false;
62
	}
62
	}
63
}
63
}
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/DiffAlgorithms.java (-1 / +1 lines)
Lines 123-129 DiffAlgorithm create() { Link Here
123
	private ThreadMXBean mxBean;
123
	private ThreadMXBean mxBean;
124
124
125
	@Override
125
	@Override
126
	protected boolean requiresRepository() {
126
	public boolean requiresRepository() {
127
		return false;
127
		return false;
128
	}
128
	}
129
129
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/debug/TextHashFunctions.java (-1 / +1 lines)
Lines 258-264 public int fold(int hash, int bits) { Link Here
258
	List<File> gitDirs = new ArrayList<File>();
258
	List<File> gitDirs = new ArrayList<File>();
259
259
260
	@Override
260
	@Override
261
	protected boolean requiresRepository() {
261
	public boolean requiresRepository() {
262
		return false;
262
		return false;
263
	}
263
	}
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/nls/GlobalBundleCache.java (+105 lines)
Added Link Here
1
/*
2
 * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com>
3
 * and other copyright owners as documented in the project's IP log.
4
 *
5
 * This program and the accompanying materials are made available
6
 * under the terms of the Eclipse Distribution License v1.0 which
7
 * accompanies this distribution, is reproduced below, and is
8
 * available at http://www.eclipse.org/org/documents/edl-v10.php
9
 *
10
 * All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or
13
 * without modification, are permitted provided that the following
14
 * conditions are met:
15
 *
16
 * - Redistributions of source code must retain the above copyright
17
 *   notice, this list of conditions and the following disclaimer.
18
 *
19
 * - Redistributions in binary form must reproduce the above
20
 *   copyright notice, this list of conditions and the following
21
 *   disclaimer in the documentation and/or other materials provided
22
 *   with the distribution.
23
 *
24
 * - Neither the name of the Eclipse Foundation, Inc. nor the
25
 *   names of its contributors may be used to endorse or promote
26
 *   products derived from this software without specific prior
27
 *   written permission.
28
 *
29
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
 */
43
44
package org.eclipse.jgit.pgm.nls;
45
46
import java.util.HashMap;
47
import java.util.Locale;
48
import java.util.Map;
49
50
import org.eclipse.jgit.errors.TranslationBundleLoadingException;
51
import org.eclipse.jgit.errors.TranslationStringMissingException;
52
53
/**
54
 * Global cache of translation bundles.
55
 * <p>
56
 * Every translation bundle will be cached here when it gets loaded for the
57
 * first time from a thread. Another lookup for the same translation bundle
58
 * (same locale and type) from the same or a different thread will return the
59
 * cached one.
60
 * <p>
61
 * Note that NLS instances maintain per-thread Map of loaded translation
62
 * bundles. Once a thread accesses a translation bundle it will keep reference
63
 * to it and will not call {@link #lookupBundle(Locale, Class)} again for the
64
 * same translation bundle as long as its locale doesn't change.
65
 */
66
class GlobalBundleCache {
67
	private static final Map<Locale, Map<Class, TranslationBundle>> cachedBundles
68
		= new HashMap<Locale, Map<Class, TranslationBundle>>();
69
70
	/**
71
	 * Looks up for a translation bundle in the global cache. If found returns
72
	 * the cached bundle. If not found creates a new instance puts it into the
73
	 * cache and returns it.
74
	 *
75
	 * @param <T>
76
	 *            required bundle type
77
	 * @param locale
78
	 *            the preferred locale
79
	 * @param type
80
	 *            required bundle type
81
	 * @return an instance of the required bundle type
82
	 * @exception TranslationBundleLoadingException see {@link TranslationBundle#load(Locale)}
83
	 * @exception TranslationStringMissingException see {@link TranslationBundle#load(Locale)}
84
	 */
85
	static synchronized <T extends TranslationBundle> T lookupBundle(Locale locale, Class<T> type) {
86
		try {
87
			Map<Class, TranslationBundle> bundles = cachedBundles.get(locale);
88
			if (bundles == null) {
89
				bundles = new HashMap<Class, TranslationBundle>();
90
				cachedBundles.put(locale, bundles);
91
			}
92
			TranslationBundle bundle = bundles.get(type);
93
			if (bundle == null) {
94
				bundle = type.newInstance();
95
				bundle.load(locale);
96
				bundles.put(type, bundle);
97
			}
98
			return (T) bundle;
99
		} catch (InstantiationException e) {
100
			throw new Error(e);
101
		} catch (IllegalAccessException e) {
102
			throw new Error(e);
103
		}
104
	}
105
}
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/nls/NLS.java (+141 lines)
Added Link Here
1
/*
2
 * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com>
3
 * and other copyright owners as documented in the project's IP log.
4
 *
5
 * This program and the accompanying materials are made available
6
 * under the terms of the Eclipse Distribution License v1.0 which
7
 * accompanies this distribution, is reproduced below, and is
8
 * available at http://www.eclipse.org/org/documents/edl-v10.php
9
 *
10
 * All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or
13
 * without modification, are permitted provided that the following
14
 * conditions are met:
15
 *
16
 * - Redistributions of source code must retain the above copyright
17
 *   notice, this list of conditions and the following disclaimer.
18
 *
19
 * - Redistributions in binary form must reproduce the above
20
 *   copyright notice, this list of conditions and the following
21
 *   disclaimer in the documentation and/or other materials provided
22
 *   with the distribution.
23
 *
24
 * - Neither the name of the Eclipse Foundation, Inc. nor the
25
 *   names of its contributors may be used to endorse or promote
26
 *   products derived from this software without specific prior
27
 *   written permission.
28
 *
29
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
 */
43
44
package org.eclipse.jgit.pgm.nls;
45
46
import java.util.Locale;
47
import java.util.concurrent.ConcurrentHashMap;
48
49
import org.eclipse.jgit.errors.TranslationBundleLoadingException;
50
import org.eclipse.jgit.errors.TranslationStringMissingException;
51
52
/**
53
 * The purpose of this class is to provide NLS (National Language Support)
54
 * configurable per thread.
55
 *
56
 * <p>
57
 * The {@link #setLocale(Locale)} method is used to configure locale for the
58
 * calling thread. The locale setting is thread inheritable. This means that a
59
 * child thread will have the same locale setting as its creator thread until it
60
 * changes it explicitly.
61
 *
62
 * <p>
63
 * Example of usage:
64
 *
65
 * <pre>
66
 * NLS.setLocale(Locale.GERMAN);
67
 * TransportText t = NLS.getBundleFor(TransportText.class);
68
 * </pre>
69
 */
70
public class NLS {
71
	/** The root locale constant. It is defined here because the Locale.ROOT is not defined in Java 5 */
72
	public static final Locale ROOT_LOCALE = new Locale("", "", "");
73
74
	private static final InheritableThreadLocal<NLS> local = new InheritableThreadLocal<NLS>() {
75
		protected NLS initialValue() {
76
			return new NLS(Locale.getDefault());
77
		}
78
	};
79
80
	/**
81
	 * Sets the locale for the calling thread.
82
	 * <p>
83
	 * The {@link #getBundleFor(Class)} method will honor this setting if if it
84
	 * is supported by the provided resource bundle property files. Otherwise,
85
	 * it will use a fall back locale as described in the
86
	 * {@link TranslationBundle}
87
	 *
88
	 * @param locale
89
	 *            the preferred locale
90
	 */
91
	public static void setLocale(Locale locale) {
92
		local.set(new NLS(locale));
93
	}
94
95
	/**
96
	 * Sets the JVM default locale as the locale for the calling thread.
97
	 * <p>
98
	 * Semantically this is equivalent to <code>NLS.setLocale(Locale.getDefault())</code>.
99
	 */
100
	public static void useJVMDefaultLocale() {
101
		local.set(new NLS(Locale.getDefault()));
102
	}
103
104
	/**
105
	 * Returns an instance of the translation bundle of the required type. All
106
	 * public String fields of the bundle instance will get their values
107
	 * injected as described in the {@link TranslationBundle}.
108
	 *
109
	 * @param <T>
110
	 *            required bundle type
111
	 * @param type
112
	 *            required bundle type
113
	 * @return an instance of the required bundle type
114
	 * @exception TranslationBundleLoadingException see {@link TranslationBundleLoadingException}
115
	 * @exception TranslationStringMissingException see {@link TranslationStringMissingException}
116
	 */
117
	public static <T extends TranslationBundle> T getBundleFor(Class<T> type) {
118
		return local.get().get(type);
119
	}
120
121
	final private Locale locale;
122
	final private ConcurrentHashMap<Class, TranslationBundle> map = new ConcurrentHashMap<Class, TranslationBundle>();
123
124
	private NLS(Locale locale) {
125
		this.locale = locale;
126
	}
127
128
	@SuppressWarnings("unchecked")
129
	private <T extends TranslationBundle> T get(Class<T> type) {
130
		TranslationBundle bundle = map.get(type);
131
		if (bundle == null) {
132
			bundle = GlobalBundleCache.lookupBundle(locale, type);
133
			// There is a small opportunity for a race, which we may
134
			// lose. Accept defeat and return the winner's instance.
135
			TranslationBundle old = map.putIfAbsent(type, bundle);
136
			if (old != null)
137
				bundle = old;
138
		}
139
		return (T) bundle;
140
	}
141
}
(-)a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/nls/TranslationBundle.java (+183 lines)
Added Link Here
1
/*
2
 * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com>
3
 * and other copyright owners as documented in the project's IP log.
4
 *
5
 * This program and the accompanying materials are made available
6
 * under the terms of the Eclipse Distribution License v1.0 which
7
 * accompanies this distribution, is reproduced below, and is
8
 * available at http://www.eclipse.org/org/documents/edl-v10.php
9
 *
10
 * All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or
13
 * without modification, are permitted provided that the following
14
 * conditions are met:
15
 *
16
 * - Redistributions of source code must retain the above copyright
17
 *   notice, this list of conditions and the following disclaimer.
18
 *
19
 * - Redistributions in binary form must reproduce the above
20
 *   copyright notice, this list of conditions and the following
21
 *   disclaimer in the documentation and/or other materials provided
22
 *   with the distribution.
23
 *
24
 * - Neither the name of the Eclipse Foundation, Inc. nor the
25
 *   names of its contributors may be used to endorse or promote
26
 *   products derived from this software without specific prior
27
 *   written permission.
28
 *
29
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42
 */
43
44
package org.eclipse.jgit.pgm.nls;
45
46
import java.lang.reflect.Field;
47
import java.util.Locale;
48
import java.util.MissingResourceException;
49
import java.util.ResourceBundle;
50
51
import org.eclipse.jgit.errors.TranslationBundleLoadingException;
52
import org.eclipse.jgit.errors.TranslationStringMissingException;
53
54
/**
55
 * Base class for all translation bundles that provides injection of translated
56
 * texts into public String fields.
57
 *
58
 * <p>
59
 * The usage pattern is shown with the following example. First define a new
60
 * translation bundle:
61
 *
62
 * <pre>
63
 * public class TransportText extends TranslationBundle {
64
 * 	public static TransportText get() {
65
 * 		return NLS.getBundleFor(TransportText.class);
66
 * 	}
67
 *
68
 * 	public String repositoryNotFound;
69
 *
70
 * 	public String transportError;
71
 * }
72
 * </pre>
73
 *
74
 * Second, define one or more resource bundle property files.
75
 *
76
 * <pre>
77
 * TransportText_en_US.properties:
78
 * 		repositoryNotFound=repository {0} not found
79
 * 		transportError=unknown error talking to {0}
80
 * TransportText_de.properties:
81
 * 		repositoryNotFound=repository {0} nicht gefunden
82
 * 		transportError=unbekannter Fehler während der Kommunikation mit {0}
83
 * ...
84
 * </pre>
85
 *
86
 * Then make use of it:
87
 *
88
 * <pre>
89
 * NLS.setLocale(Locale.GERMAN); // or skip this call to stick to the JVM default locale
90
 * ...
91
 * throw new TransportException(uri, TransportText.get().transportError);
92
 * </pre>
93
 *
94
 * The translated text is automatically injected into the public String fields
95
 * according to the locale set with {@link NLS#setLocale(Locale)}. However, the
96
 * {@link NLS#setLocale(Locale)} method defines only prefered locale which will
97
 * be honored only if it is supported by the provided resource bundle property
98
 * files. Basically, this class will use
99
 * {@link ResourceBundle#getBundle(String, Locale)} method to load a resource
100
 * bundle. See the documentation of this method for a detailed explanation of
101
 * resource bundle loading strategy. After a bundle is created the
102
 * {@link #effectiveLocale()} method can be used to determine whether the
103
 * bundle really corresponds to the requested locale or is a fallback.
104
 *
105
 * <p>
106
 * To load a String from a resource bundle property file this class uses the
107
 * {@link ResourceBundle#getString(String)}. This method can throw the
108
 * {@link MissingResourceException} and this class is not making any effort to
109
 * catch and/or translate this exception.
110
 *
111
 * <p>
112
 * To define a concrete translation bundle one has to:
113
 * <ul>
114
 * <li>extend this class
115
 * <li>define a public static get() method like in the example above
116
 * <li>define public static String fields for each text message
117
 * <li>make sure the translation bundle class provide public no arg constructor
118
 * <li>provide one or more resource bundle property files in the same package
119
 * where the translation bundle class resides
120
 * </ul>
121
 */
122
public abstract class TranslationBundle {
123
124
	private Locale effectiveLocale;
125
	private ResourceBundle resourceBundle;
126
127
	/**
128
	 * @return the locale locale used for loading the resource bundle from which
129
	 *         the field values were taken
130
	 */
131
	public Locale effectiveLocale() {
132
		return effectiveLocale;
133
	}
134
135
	/**
136
	 * @return the resource bundle on which this translation bundle is based
137
	 */
138
	public ResourceBundle resourceBundle() {
139
		return resourceBundle;
140
	}
141
142
	/**
143
	 * Injects locale specific text in all instance fields of this instance.
144
	 * Only public instance fields of type <code>String</code> are considered.
145
	 * <p>
146
	 * The name of this (sub)class plus the given <code>locale</code> parameter
147
	 * define the resource bundle to be loaded. In other words the
148
	 * <code>this.getClass().getName()</code> is used as the
149
	 * <code>baseName</code> parameter in the
150
	 * {@link ResourceBundle#getBundle(String, Locale)} parameter to load the
151
	 * resource bundle.
152
	 * <p>
153
	 *
154
	 * @param locale
155
	 *            defines the locale to be used when loading the resource bundle
156
	 * @exception TranslationBundleLoadingException see {@link TranslationBundleLoadingException}
157
	 * @exception TranslationStringMissingException see {@link TranslationStringMissingException}
158
	 */
159
	void load(Locale locale) throws TranslationBundleLoadingException {
160
		Class bundleClass = getClass();
161
		try {
162
			resourceBundle = ResourceBundle.getBundle(bundleClass.getName(), locale);
163
		} catch (MissingResourceException e) {
164
			throw new TranslationBundleLoadingException(bundleClass, locale, e);
165
		}
166
		this.effectiveLocale = resourceBundle.getLocale();
167
168
		for (Field field : bundleClass.getFields()) {
169
			if (field.getType().equals(String.class)) {
170
				try {
171
					String translatedText = resourceBundle.getString(field.getName());
172
					field.set(this, translatedText);
173
				} catch (MissingResourceException e) {
174
					throw new TranslationStringMissingException(bundleClass, locale, field.getName(), e);
175
				} catch (IllegalArgumentException e) {
176
					throw new Error(e);
177
				} catch (IllegalAccessException e) {
178
					throw new Error(e);
179
				}
180
			}
181
		}
182
	}
183
}

Return to bug 372119