package ilarkesto.locale;
import ilarkesto.base.Cache;
import ilarkesto.base.Str;
import ilarkesto.core.logging.Log;
import ilarkesto.io.IO;
import ilarkesto.swing.Swing;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.Properties;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public final class LearningLocalizer extends Localizer {
private static final Log LOG = Log.get(LearningLocalizer.class);
private static final String RESOURCE_BUNDLE = "strings";
private Properties templates;
private JFrame frame;
// --- dependencies ---
private Locale locale;
private boolean developmentMode = false;
public void setDevelopmentMode(boolean value) {
developmentMode = value;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
// --- ---
private Cache<String, MessageFormat> formatsCache = new Cache<String, MessageFormat>(
new Cache.Factory<String, MessageFormat>() {
public MessageFormat create(String template) {
return new MessageFormat(template);
}
});
public String string(Object context, String string, Object... parameters) {
return string(context.getClass().getName() + "." + string, parameters);
}
@Override
public String string(String key, Object... parameters) {
if (!developmentMode) locale = Locale.GERMAN;
if (parameters != null) {
for (int i = 0; i < parameters.length; i++) {
if (parameters[i] instanceof Throwable) parameters[i] = Str.format(parameters[i]);
}
}
String template = getTemplate(locale, key);
if (template == null) {
StringBuilder sb = new StringBuilder();
sb.append("@@@");
sb.append(key);
for (int i = 0; i < parameters.length; i++) {
sb.append(", ").append(parameters[i]);
}
return sb.toString();
}
return format(template, parameters);
}
private String getTemplate(Locale locale, String key) {
String template = getTemplates(locale).getProperty(key);
if (template != null) return template;
if (developmentMode) {
template = learnTemplate(key);
if (template != null) return template;
} else {
LOG.error("missing " + locale + "-local string: ", key);
}
return template;
}
private String format(String template, Object... parameters) {
if (template.startsWith("<html")) {
for (int i = 0; i < parameters.length; i++) {
if (parameters[i] instanceof String) {
parameters[i] = Str.replaceForHtml((String) parameters[i]);
}
}
}
MessageFormat f = formatsCache.get(template);
return f.format(parameters);
}
private Properties getTemplates(Locale locale) {
if (templates == null) {
String localeSuffix = locale.toString();
if (localeSuffix.length() > 2) localeSuffix = localeSuffix.substring(0, 2);
String resource = RESOURCE_BUNDLE + "_" + localeSuffix + ".properties";
ClassLoader classLoader = getClass().getClassLoader();
LOG.debug("Loading localizer data:", resource, classLoader);
try {
templates = IO.loadProperties(classLoader.getResource(resource), IO.UTF_8);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
return templates;
}
private String learnTemplate(String key) {
if (frame == null) frame = new JFrame(getClass().getSimpleName());
Swing.center(frame);
frame.setVisible(true);
String template = JOptionPane.showInputDialog(frame, key, "Lokalisierung", JOptionPane.QUESTION_MESSAGE);
frame.setVisible(false);
if (template == null) return null;
template = template.trim();
if (template.length() == 0) template = null;
if (template != null) {
templates.put(key, template);
String localeSuffix = locale.toString();
if (localeSuffix.length() > 2) localeSuffix = localeSuffix.substring(0, 2);
try {
IO.appendLine("src/main/java/" + RESOURCE_BUNDLE + "_" + localeSuffix + ".properties", key + "="
+ Str.replaceUnicodeCharsWithJavaNotation(template));
} catch (IOException ex1) {
throw new RuntimeException(ex1);
}
}
return template;
}
@Override
public Locale getLocale() {
return locale;
}
@Override
public String toString() {
return locale == null ? getClass().getSimpleName() : locale.toString();
}
}