killbill-memoizeit

invoice: revisit configuration for templates and translations Allow

6/16/2012 8:53:29 PM

Details

diff --git a/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java b/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java
index 506c8bc..a72d778 100644
--- a/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java
+++ b/api/src/main/java/com/ning/billing/util/template/translation/TranslatorConfig.java
@@ -20,7 +20,15 @@ import org.skife.config.Config;
 import org.skife.config.Default;
 
 public interface TranslatorConfig {
-    @Config("email.default.locale")
+    @Config("killbill.template.default.locale")
     @Default("en_US")
     public String getDefaultLocale();
+
+    @Config("killbill.template.bundlePath")
+    @Default("com/ning/billing/util/template/translation/InvoiceTranslation")
+    public String getBundlePath();
+
+    @Config("killbill.template.name")
+    @Default("com/ning/billing/util/email/templates/HtmlInvoiceTemplate.mustache")
+    String getTemplateName();
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index d13e740..8228898 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -116,6 +116,6 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     public String getInvoiceAsHTML(final UUID invoiceId) throws AccountApiException, IOException {
         final Invoice invoice = getInvoice(invoiceId);
         final Account account = accountUserApi.getAccountById(invoice.getAccountId());
-        return generator.generateInvoice(account, invoice, "HtmlInvoiceTemplate");
+        return generator.generateInvoice(account, invoice);
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
index 22926e0..4a58ab3 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/notification/EmailInvoiceNotifier.java
@@ -59,7 +59,7 @@ public class EmailInvoiceNotifier implements InvoiceNotifier {
 
         final String htmlBody;
         try {
-            htmlBody = generator.generateInvoice(account, invoice, "HtmlInvoiceTemplate");
+            htmlBody = generator.generateInvoice(account, invoice);
         } catch (IOException e) {
             throw new InvoiceApiException(e, ErrorCode.EMAIL_SENDING_FAILED);
         }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java b/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java
index ddfe39a..f27bce7 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/template/HtmlInvoiceGenerator.java
@@ -42,7 +42,7 @@ public class HtmlInvoiceGenerator {
         this.config = config;
     }
 
-    public String generateInvoice(final Account account, final Invoice invoice, final String templateName) throws IOException {
+    public String generateInvoice(final Account account, final Invoice invoice) throws IOException {
         final Map<String, Object> data = new HashMap<String, Object>();
         final DefaultInvoiceTranslator invoiceTranslator = new DefaultInvoiceTranslator(config);
         final Locale locale = new Locale(account.getLocale());
@@ -53,6 +53,6 @@ public class HtmlInvoiceGenerator {
         final InvoiceFormatter formattedInvoice = factory.createInvoiceFormatter(config, invoice, locale);
         data.put("invoice", formattedInvoice);
 
-        return templateEngine.executeTemplate(templateName, data);
+        return templateEngine.executeTemplate(config.getTemplateName(), data);
     }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java b/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java
index 3a18f2e..aeb6b49 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/template/translator/DefaultInvoiceTranslator.java
@@ -36,7 +36,7 @@ public class DefaultInvoiceTranslator extends DefaultTranslatorBase implements I
 
     @Override
     protected String getBundlePath() {
-        return "com/ning/billing/util/template/translation/InvoiceTranslation";
+        return config.getBundlePath();
     }
 
     @Override
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java b/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
index 0bc2d9f..27ea80c 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/migration/MockModuleNoEntitlement.java
@@ -16,6 +16,8 @@
 
 package com.ning.billing.invoice.api.migration;
 
+import org.skife.config.ConfigurationObjectFactory;
+
 import com.ning.billing.invoice.MockModule;
 import com.ning.billing.invoice.api.InvoiceNotifier;
 import com.ning.billing.invoice.glue.DefaultInvoiceModule;
@@ -25,6 +27,7 @@ import com.ning.billing.invoice.notification.NullInvoiceNotifier;
 import com.ning.billing.mock.BrainDeadProxyFactory;
 import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
 import com.ning.billing.util.email.templates.TemplateModule;
+import com.ning.billing.util.template.translation.TranslatorConfig;
 
 public class MockModuleNoEntitlement extends MockModule {
 //	@Override
@@ -50,6 +53,9 @@ public class MockModuleNoEntitlement extends MockModule {
                 ((ZombieControl) poster).addResult("insertNextBillingNotification", BrainDeadProxyFactory.ZOMBIE_VOID);
                 bind(NextBillingDatePoster.class).toInstance(poster);
                 bind(InvoiceNotifier.class).to(NullInvoiceNotifier.class).asEagerSingleton();
+
+                final TranslatorConfig config = new ConfigurationObjectFactory(System.getProperties()).build(TranslatorConfig.class);
+                bind(TranslatorConfig.class).toInstance(config);
             }
 
 
diff --git a/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java b/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java
index c9ca94b..2cb1ad7 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/HtmlInvoiceGeneratorTest.java
@@ -44,7 +44,6 @@ import static org.testng.Assert.assertNotNull;
 @Test(groups = {"fast", "email"})
 public class HtmlInvoiceGeneratorTest {
     private HtmlInvoiceGenerator g;
-    private static final String TEST_TEMPLATE_NAME = "HtmlInvoiceTemplate";
 
     @BeforeClass
     public void setup() {
@@ -56,7 +55,7 @@ public class HtmlInvoiceGeneratorTest {
 
     @Test
     public void testGenerateInvoice() throws Exception {
-        final String output = g.generateInvoice(createAccount(), createInvoice(), TEST_TEMPLATE_NAME);
+        final String output = g.generateInvoice(createAccount(), createInvoice());
         assertNotNull(output);
         System.out.print(output);
     }
diff --git a/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java b/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java
index 9fbeee3..e641917 100644
--- a/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java
+++ b/util/src/main/java/com/ning/billing/util/email/templates/MustacheTemplateEngine.java
@@ -19,10 +19,12 @@ package com.ning.billing.util.email.templates;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringWriter;
+import java.net.URISyntaxException;
 import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
 
+import com.ning.billing.util.config.UriAccessor;
 import com.samskivert.mustache.Mustache;
 import com.samskivert.mustache.Template;
 
@@ -35,7 +37,12 @@ public class MustacheTemplateEngine implements TemplateEngine {
     }
 
     private String getTemplateText(final String templateName) throws IOException {
-        final InputStream templateStream = this.getClass().getResourceAsStream(templateName + ".mustache");
+        final InputStream templateStream;
+        try {
+            templateStream = UriAccessor.accessUri(templateName);
+        } catch (URISyntaxException e) {
+            throw new IOException(e);
+        }
         final StringWriter writer = new StringWriter();
         IOUtils.copy(templateStream, writer, "UTF-8");
         return writer.toString();
diff --git a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
index 859c96a..71c87fc 100644
--- a/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
+++ b/util/src/main/java/com/ning/billing/util/template/translation/DefaultTranslatorBase.java
@@ -16,8 +16,12 @@
 
 package com.ning.billing.util.template.translation;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
 import java.util.Locale;
 import java.util.MissingResourceException;
+import java.util.PropertyResourceBundle;
 import java.util.ResourceBundle;
 
 import org.slf4j.Logger;
@@ -25,6 +29,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 import com.ning.billing.ErrorCode;
+import com.ning.billing.util.config.UriAccessor;
 
 public abstract class DefaultTranslatorBase implements Translator {
     protected final TranslatorConfig config;
@@ -44,19 +49,15 @@ public abstract class DefaultTranslatorBase implements Translator {
 
     @Override
     public String getTranslation(final Locale locale, final String originalText) {
-        ResourceBundle bundle = null;
-        try {
-            bundle = ResourceBundle.getBundle(getBundlePath(), locale);
-        } catch (MissingResourceException mrex) {
-            log.warn(String.format(ErrorCode.MISSING_TRANSLATION_RESOURCE.toString(), getTranslationType()));
-        }
+        final String bundlePath = getBundlePath();
+        ResourceBundle bundle = getBundle(locale, bundlePath);
 
         if ((bundle != null) && (bundle.containsKey(originalText))) {
             return bundle.getString(originalText);
         } else {
+            final Locale defaultLocale = new Locale(config.getDefaultLocale());
             try {
-                final Locale defaultLocale = new Locale(config.getDefaultLocale());
-                bundle = ResourceBundle.getBundle(getBundlePath(), defaultLocale);
+                bundle = getBundle(defaultLocale, bundlePath);
 
                 if ((bundle != null) && (bundle.containsKey(originalText))) {
                     return bundle.getString(originalText);
@@ -69,4 +70,40 @@ public abstract class DefaultTranslatorBase implements Translator {
             }
         }
     }
+
+    private ResourceBundle getBundle(final Locale locale, final String bundlePath) {
+        try {
+            // Try to load the bundle from the classpath first
+            return ResourceBundle.getBundle(bundlePath, locale);
+        } catch (MissingResourceException ignored) {
+        }
+
+        // Try to load it from a properties file
+        final String propertiesFileNameWithCountry = bundlePath + "_" + locale.getLanguage() + "_" + locale.getCountry() + ".properties";
+        ResourceBundle bundle = getBundleFromPropertiesFile(propertiesFileNameWithCountry);
+        if (bundle != null) {
+            return bundle;
+        } else {
+            final String propertiesFileName = bundlePath + "_" + locale.getLanguage() + ".properties";
+            bundle = getBundleFromPropertiesFile(propertiesFileName);
+        }
+
+        if (bundle == null) {
+            log.warn(String.format(ErrorCode.MISSING_TRANSLATION_RESOURCE.toString(), getTranslationType()));
+        }
+        return bundle;
+    }
+
+    private ResourceBundle getBundleFromPropertiesFile(final String propertiesFileName) {
+        try {
+            final InputStream inputStream = UriAccessor.accessUri(propertiesFileName);
+            return new PropertyResourceBundle(inputStream);
+        } catch (MissingResourceException mrex) {
+            return null;
+        } catch (URISyntaxException e) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
 }