package restx.i18n;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.Files;
import restx.common.MoreResources;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
/**
* Date: 25/1/14
* Time: 15:31
*/
public class DefaultMutableMessages extends DefaultMessages implements MutableMessages {
public DefaultMutableMessages(String baseName) {
super(baseName);
}
public DefaultMutableMessages(String baseName, Charset charset) {
super(baseName, charset);
}
@Override
public MutableMessages setMessageTemplate(String key, String messageTemplate, Locale locale) throws IOException {
Optional<ResourceBundle> b = getBundle(locale);
if (!b.isPresent()) {
throw new IllegalStateException("bundle not found: " + getBaseName() + " - " + locale);
}
MutablePropertyResourceBundle bundle = (MutablePropertyResourceBundle) b.get();
bundle.setMessageTemplate(key, messageTemplate);
invalidateCachedKeysFor(locale);
return this;
}
@Override
protected PropertyResourceBundle newResourceBundle(final URL resource, Reader input) throws IOException {
return new MutablePropertyResourceBundle(input, resource, getCharset());
}
protected long getTimeToLive() {
return ResourceBundle.Control.TTL_DONT_CACHE;
}
protected URL getResource(String resourceName) {
return MoreResources.getResource(resourceName, true);
}
private static class MutablePropertyResourceBundle extends PropertyResourceBundle {
private final URL resource;
private final Charset charset;
public MutablePropertyResourceBundle(Reader input, URL resource, Charset charset) throws IOException {
super(input);
this.resource = resource;
this.charset = charset;
}
public void setMessageTemplate(String key, String value) throws IOException {
if (!resource.getProtocol().equals("file")) {
throw new IllegalStateException(
"can't set message when resource bundle is not loaded from a file." +
" It was loaded from " + resource);
}
File f;
try {
f = new File(resource.toURI());
} catch(URISyntaxException e) {
f = new File(resource.getPath());
}
updateProperties(f, charset, ImmutableMap.of(key, value));
}
}
private static void updateProperties(File file, Charset charset, ImmutableMap<String, String> properties) throws IOException {
Map<String, String> props = new LinkedHashMap<>(properties);
String s = Files.toString(file, charset);
StringBuilder out = new StringBuilder();
boolean updated = false;
String[] lines = s.split("(?m)$");
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
if (line.indexOf('=') != -1) {
String p = line.substring(0, line.indexOf('='));
if (props.containsKey(p.trim())) {
updated = true;
out.append(p).append("=").append(properties.get(p.trim()));
props.remove(p.trim());
} else {
out.append(line);
}
} else {
out.append(line);
}
}
if (!props.isEmpty()) {
updated = true;
for (Map.Entry<String, String> entry : props.entrySet()) {
out.append("\n").append(entry.getKey()).append("=").append(entry.getValue());
}
out.append("\n");
}
if (updated) {
Files.write(out.toString(), file, charset);
}
}
}