From 3778b44588648fed2f50b6ff15026cac53087d31 Mon Sep 17 00:00:00 2001 From: Athou Date: Sat, 11 May 2013 19:21:53 +0200 Subject: [PATCH] backbone for i18n support (#55) --- pom.xml | 6 +- ...InternationalizationDevelopmentFilter.java | 132 ++++++++++++++++++ src/main/resources/i18n/en.properties | 1 + src/main/resources/i18n/fr.properties | 1 + src/main/script/HTMLConcat.groovy | 40 ++++-- src/main/webapp/WEB-INF/web.xml | 10 +- src/main/webapp/templates/_toolbar.html | 2 +- 7 files changed, 181 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java create mode 100644 src/main/resources/i18n/en.properties create mode 100644 src/main/resources/i18n/fr.properties diff --git a/pom.xml b/pom.xml index 067e489d..9806bf1f 100644 --- a/pom.xml +++ b/pom.xml @@ -467,6 +467,7 @@ ${basedir}/src/main/webapp/templates templates/ ${basedir}/target/generated-sources/angularjs/all-templates.html + ${basedir}/src/main/resources/i18n/ ${basedir}/src/main/script @@ -477,8 +478,11 @@ project.properties['prefix']; def dest = project.properties['destination']; + def i18n = + project.properties['i18nPath']; new - HTMLConcat().concat(source, prefix, dest); + HTMLConcat().concat(source, + prefix, dest, i18n); diff --git a/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java b/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java new file mode 100644 index 00000000..1ebb4794 --- /dev/null +++ b/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java @@ -0,0 +1,132 @@ +package com.commafeed.frontend.utils; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; +import java.util.Properties; +import java.util.ResourceBundle; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.commafeed.frontend.CommaFeedSession; + +/** + * Replace variables from templates on the fly in dev mode only. In production + * the substitution is done at build-time. + * + */ +public class InternationalizationDevelopmentFilter implements Filter { + + private static Logger log = LoggerFactory + .getLogger(InternationalizationDevelopmentFilter.class); + + private boolean production = true; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + if (production) { + chain.doFilter(request, response); + return; + } + + final ServletOutputStream wrapper = new ServletOutputStreamWrapper(); + ServletResponse interceptor = new HttpServletResponseWrapper( + (HttpServletResponse) response) { + + @Override + public ServletOutputStream getOutputStream() throws IOException { + return wrapper; + } + }; + chain.doFilter(request, interceptor); + Locale locale = CommaFeedSession.get().getLocale(); + + byte[] bytes = translate(wrapper.toString(), locale).getBytes(); + response.getOutputStream().write(bytes); + response.setContentLength(bytes.length); + response.getOutputStream().close(); + + } + + private String translate(String content, Locale locale) { + Properties props = new Properties(); + InputStream is = null; + try { + is = getClass().getResourceAsStream( + "/i18n/" + locale.getLanguage() + ".properties"); + if (is == null) { + is = getClass().getResourceAsStream("/i18n/en.properties"); + } + if (is == null) { + throw new Exception("Locale file not found for locale " + + locale.getLanguage()); + } + props.load(is); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + IOUtils.closeQuietly(is); + } + + return replace(content, props); + } + + private static final Pattern PATTERN = Pattern.compile("\\$\\{(.+?)\\}"); + + public String replace(String content, Properties props) { + Matcher m = PATTERN.matcher(content); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + String var = m.group(1); + Object replacement = props.get(var); + m.appendReplacement(sb, replacement.toString()); + } + m.appendTail(sb); + return sb.toString(); + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + String prod = ResourceBundle.getBundle("application").getString( + "production"); + production = Boolean.valueOf(prod); + } + + @Override + public void destroy() { + // do nothing + } + + private static class ServletOutputStreamWrapper extends ServletOutputStream { + + private ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + @Override + public void write(int b) throws IOException { + baos.write(b); + } + + @Override + public String toString() { + return baos.toString(); + } + } + +} diff --git a/src/main/resources/i18n/en.properties b/src/main/resources/i18n/en.properties new file mode 100644 index 00000000..b0d962cb --- /dev/null +++ b/src/main/resources/i18n/en.properties @@ -0,0 +1 @@ +toolbar.refresh=Refresh \ No newline at end of file diff --git a/src/main/resources/i18n/fr.properties b/src/main/resources/i18n/fr.properties new file mode 100644 index 00000000..07811439 --- /dev/null +++ b/src/main/resources/i18n/fr.properties @@ -0,0 +1 @@ +toolbar.refresh=Rafraichir \ No newline at end of file diff --git a/src/main/script/HTMLConcat.groovy b/src/main/script/HTMLConcat.groovy index da32dca2..3e740e1b 100644 --- a/src/main/script/HTMLConcat.groovy +++ b/src/main/script/HTMLConcat.groovy @@ -3,26 +3,50 @@ import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.SystemUtils; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class HTMLConcat { - public void concat(String source, String prefix, String destination) + + private static final Pattern PATTERN = Pattern.compile('\\$\\{(.+?)\\}'); + + public void concat(String source, String prefix, String destination, String i18nPath) throws IOException { - StringBuilder sb = new StringBuilder(); - sb.append("
"); - for (File file : new File(source).listFiles()) { - if (file.isFile()) { + for(File i18n : new File(i18nPath).listFiles()) { + StringBuilder sb = new StringBuilder(); + sb.append("
"); + for (File file : new File(source).listFiles()) { sb.append(SystemUtils.LINE_SEPARATOR); sb.append(String.format( ""); sb.append(SystemUtils.LINE_SEPARATOR); } + sb.append("
"); + String dest = destination.substring(0, destination.lastIndexOf(".")) + "." + i18n.getName().split("\\.")[0] + ".html"; + FileUtils.writeStringToFile(new File(dest), sb.toString()); } - sb.append("
"); - FileUtils.writeStringToFile(new File(destination), sb.toString()); + } + + public String translate(String content, File i18n) { + Properties props = new Properties(); + props.load(new FileInputStream(i18n)); + return replace(content, props); + } + + public String replace(String content, Properties props) { + Matcher m = PATTERN.matcher(content); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + String var = m.group(1); + Object replacement = props.get(var); + m.appendReplacement(sb, replacement.toString()); + } + m.appendTail(sb); + return sb.toString(); } } diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 29b072ba..3f06ce33 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -15,6 +15,10 @@ WebResourceOptimizer ro.isdc.wro.http.WroFilter + + i18n + com.commafeed.frontend.utils.InternationalizationDevelopmentFilter + WebResourceOptimizer @@ -24,7 +28,11 @@ Wicket /* - + + i18n + /templates/* + + com.commafeed.frontend.resources.WroListener diff --git a/src/main/webapp/templates/_toolbar.html b/src/main/webapp/templates/_toolbar.html index 5313bf4a..a0dcc6a8 100644 --- a/src/main/webapp/templates/_toolbar.html +++ b/src/main/webapp/templates/_toolbar.html @@ -15,7 +15,7 @@ - +