Material localization support
[debian/openrocket] / core / src / net / sf / openrocket / l10n / ClassBasedTranslator.java
1 package net.sf.openrocket.l10n;
2
3 import java.util.MissingResourceException;
4
5 import net.sf.openrocket.logging.TraceException;
6 import net.sf.openrocket.util.BugException;
7
8 /**
9  * A translator that prepends a pre-defined class name in front of a translation key
10  * and retrieves the translator for that key, and only if that is missing reverts to
11  * the base key name.  The base class name can either be provided to the constructor
12  * or retrieved from the stack.
13  * 
14  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
15  */
16 public class ClassBasedTranslator implements Translator {
17         
18         
19         private final Translator translator;
20         private final String className;
21         
22         /**
23          * Construct a translator using a specified class name.
24          * 
25          * @param translator    the translator from which to obtain the translations.
26          * @param className             the base class name to prepend.
27          */
28         public ClassBasedTranslator(Translator translator, String className) {
29                 this.translator = translator;
30                 this.className = className;
31         }
32         
33         /**
34          * Construct a translator by obtaining the base class name from the stack.
35          * 
36          * @param translator    the translator from which to obtain the translations.
37          * @param levels                the number of levels to move upwards in the stack from the point where this method is called.
38          */
39         public ClassBasedTranslator(Translator translator, int levels) {
40                 this(translator, getStackClass(levels));
41         }
42         
43         
44         
45         @Override
46         public String get(String key) {
47                 String classKey = className + "." + key;
48                 
49                 try {
50                         return translator.get(classKey);
51                 } catch (MissingResourceException e) {
52                         // Ignore
53                 }
54                 
55                 try {
56                         return translator.get(key);
57                 } catch (MissingResourceException e) {
58                         MissingResourceException mre = new MissingResourceException(
59                                         "Neither key '" + classKey + "' nor '" + key + "' could be found", e.getClassName(), key);
60                         mre.initCause(e);
61                         throw mre;
62                 }
63         }
64         
65         
66         
67         @Override
68         public String get(String base, String text) {
69                 return translator.get(base, text);
70         }
71         
72         @Override
73         public String getBaseText(String base, String translation) {
74                 return translator.getBaseText(base, translation);
75         }
76         
77         
78         
79         
80         private static String getStackClass(int levels) {
81                 TraceException trace = new TraceException();
82                 StackTraceElement stack[] = trace.getStackTrace();
83                 final int index = levels + 2;
84                 if (stack.length <= index) {
85                         throw new BugException("Stack trace is too short, length=" + stack.length + ", expected=" + index, trace);
86                 }
87                 
88                 StackTraceElement element = stack[index];
89                 String cn = element.getClassName();
90                 int pos = cn.lastIndexOf('.');
91                 if (pos >= 0) {
92                         cn = cn.substring(pos + 1);
93                 }
94                 return cn;
95         }
96         
97         
98         
99         
100         // For unit testing purposes
101         String getClassName() {
102                 return className;
103         }
104 }