killbill-memoizeit

Upgrade jdbi version and modify EntitySqlDaoStringTemplate

1/2/2014 7:01:40 PM

Details

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index d61cf7e..332a2da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>com.ning.billing</groupId>
-        <version>0.5.9</version>
+        <version>0.5.10</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.8.7-SNAPSHOT</version>
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoStringTemplate.java b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoStringTemplate.java
index e70cfcd..57ab84b 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoStringTemplate.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/EntitySqlDaoStringTemplate.java
@@ -24,6 +24,9 @@ import java.lang.annotation.Target;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.regex.Matcher;
 
 import org.skife.jdbi.v2.Query;
 import org.skife.jdbi.v2.SQLStatement;
@@ -33,6 +36,8 @@ import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.StringTemplate3StatementLocator;
 import org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator;
 import org.skife.jdbi.v2.tweak.StatementLocator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.ning.billing.util.dao.LowerToCamelBeanMapperFactory;
 import com.ning.billing.util.entity.Entity;
@@ -48,19 +53,49 @@ public @interface EntitySqlDaoStringTemplate {
 
     public static class EntitySqlDaoLocatorFactory extends UseStringTemplate3StatementLocator.LocatorFactory {
 
+        final static boolean enableGroupTemplateCaching = Boolean.parseBoolean(System.getProperty("killbill.jdbi.allow.stringTemplateGroupCaching", "true"));
+
+        static ConcurrentMap<String, StatementLocator> locatorCache = new ConcurrentHashMap<String, StatementLocator>();
+
+        //
+        // This is only needed to compute the key for the cache -- whether we get a class or a pathname (string)
+        //
+        // (Similar to what jdbi is doing (StringTemplate3StatementLocator))
+        //
+        private final static String sep = "/"; // *Not* System.getProperty("file.separator"), which breaks in jars
+
+        public static String mungify(final Class claz) {
+            final String path = "/" + claz.getName();
+            return path.replaceAll("\\.", Matcher.quoteReplacement(sep)) + ".sql.stg";
+        }
+
+
+        private static StatementLocator getLocator(final String locatorPath) {
+
+            if (enableGroupTemplateCaching && locatorCache.containsKey(locatorPath)) {
+                return locatorCache.get(locatorPath);
+            }
+
+            final StringTemplate3StatementLocator.Builder builder = StringTemplate3StatementLocator.builder(locatorPath)
+                    .shouldCache()
+                    .withSuperGroup(EntitySqlDao.class)
+                    .allowImplicitTemplateGroup()
+                    .treatLiteralsAsTemplates();
+
+            final StatementLocator locator = builder.build();
+            if (enableGroupTemplateCaching) {
+                locatorCache.put(locatorPath, locator);
+            }
+            return locator;
+        }
+
+
         public SqlStatementCustomizer createForType(final Annotation annotation, final Class sqlObjectType) {
-            // From http://www.antlr.org/wiki/display/ST/ST+condensed+--+Templates+and+groups#STcondensed--Templatesandgroups-Withsupergroupfile:
-            //     there is no mechanism for automatically loading a mentioned super-group file
-            new StringTemplate3StatementLocator(EntitySqlDao.class, true, true);
 
             final EntitySqlDaoStringTemplate a = (EntitySqlDaoStringTemplate) annotation;
-            final StatementLocator l;
-            if (DEFAULT_VALUE.equals(a.value())) {
-                l = new StringTemplate3StatementLocator(sqlObjectType, true, true);
-            } else {
-                l = new StringTemplate3StatementLocator(a.value(), true, true);
-            }
 
+            final String locatorPath = DEFAULT_VALUE.equals(a.value()) ? mungify(sqlObjectType) : a.value();
+            final StatementLocator l = getLocator(locatorPath);
             return new SqlStatementCustomizer() {
                 public void apply(final SQLStatement statement) {
                     statement.setStatementLocator(l);