package net.sf.openrocket.l10n;
import java.util.MissingResourceException;
import net.sf.openrocket.util.BugException;
/**
* A translator that prepends a pre-defined class name in front of a translation key
* and retrieves the translator for that key, and only if that is missing reverts to
* the base key name. The base class name can either be provided to the constructor
* or retrieved from the stack.
*
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
public class ClassBasedTranslator implements Translator {
private final Translator translator;
private String className;
private int levels;
/**
* Construct a translator by obtaining the base class name from the stack
* on the first execution of the get() method.
*
* @param translator the translator from which to obtain the translations.
*/
public ClassBasedTranslator(Translator translator, int levels) {
this.translator = translator;
this.levels = levels;
}
/**
* Construct a translator using a specified class name.
*
* @param translator the translator from which to obtain the translations.
* @param className the base class name to prepend.
*/
public ClassBasedTranslator(Translator translator, String className) {
this.translator = translator;
this.className = className;
}
@Override
public String get(String key) {
if (className == null) {
className = findClassName();
}
String classKey = className + "." + key;
try {
return translator.get(classKey);
} catch (MissingResourceException e) {
// Ignore
}
try {
return translator.get(key);
} catch (MissingResourceException e) {
MissingResourceException mre = new MissingResourceException(
"Neither key '" + classKey + "' nor '" + key + "' could be found", e.getClassName(), key);
mre.initCause(e);
throw mre;
}
}
@Override
public String get(String base, String text) {
return translator.get(base, text);
}
@Override
public String getBaseText(String base, String translation) {
return translator.getBaseText(base, translation);
}
private String findClassName() {
Throwable trace = new Throwable();
StackTraceElement stack[] = trace.getStackTrace();
final int index = 2 + levels;
if (stack.length <= index) {
throw new BugException("Stack trace is too short, length=" + stack.length + ", expected=" + index, trace);
}
StackTraceElement element = stack[index];
String cn = element.getClassName();
int pos = cn.lastIndexOf('.');
if (pos >= 0) {
cn = cn.substring(pos + 1);
}
pos = cn.indexOf('$');
if (pos >= 0) {
cn = cn.substring(0, pos);
}
return cn;
}
// For unit testing purposes
String getClassName() {
return className;
}
}