killbill-memoizeit

util: register jDBI mappers globally on the DBI object This

5/12/2017 10:06:45 AM

Details

diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index ff6de44..d05cc24 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -66,8 +66,6 @@ import org.killbill.billing.subscription.glue.DefaultSubscriptionModule;
 import org.killbill.billing.tenant.glue.DefaultTenantModule;
 import org.killbill.billing.usage.glue.UsageModule;
 import org.killbill.billing.util.config.definition.NotificationConfig;
-import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
-import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
 import org.killbill.billing.util.email.EmailModule;
 import org.killbill.billing.util.email.templates.TemplateModule;
 import org.killbill.billing.util.glue.AuditModule;
@@ -79,6 +77,7 @@ import org.killbill.billing.util.glue.ConfigModule;
 import org.killbill.billing.util.glue.CustomFieldModule;
 import org.killbill.billing.util.glue.ExportModule;
 import org.killbill.billing.util.glue.GlobalLockerModule;
+import org.killbill.billing.util.glue.IDBISetup;
 import org.killbill.billing.util.glue.KillBillShiroAopModule;
 import org.killbill.billing.util.glue.KillbillApiAopModule;
 import org.killbill.billing.util.glue.NodesModule;
@@ -86,11 +85,9 @@ import org.killbill.billing.util.glue.NonEntityDaoModule;
 import org.killbill.billing.util.glue.RecordIdModule;
 import org.killbill.billing.util.glue.SecurityModule;
 import org.killbill.billing.util.glue.TagStoreModule;
-import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
 import org.killbill.clock.Clock;
 import org.killbill.clock.ClockMock;
 import org.killbill.commons.embeddeddb.EmbeddedDB;
-import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.jdbi.v2.ResultSetMapperFactory;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
@@ -124,11 +121,14 @@ public class KillbillServerModule extends KillbillPlatformModule {
         super.configureDao();
 
         final Multibinder<ResultSetMapperFactory> resultSetMapperFactorySetBinder = Multibinder.newSetBinder(binder(), ResultSetMapperFactory.class);
-        resultSetMapperFactorySetBinder.addBinding().toInstance(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+        for (final ResultSetMapperFactory resultSetMapperFactory : IDBISetup.mapperFactoriesToRegister()) {
+            resultSetMapperFactorySetBinder.addBinding().toInstance(resultSetMapperFactory);
+        }
 
         final Multibinder<ResultSetMapper> resultSetMapperSetBinder = Multibinder.newSetBinder(binder(), ResultSetMapper.class);
-        resultSetMapperSetBinder.addBinding().to(AuditLogModelDaoMapper.class).asEagerSingleton();
-        resultSetMapperSetBinder.addBinding().to(RecordIdIdMappingsMapper.class).asEagerSingleton();
+        for (final ResultSetMapper resultSetMapper : IDBISetup.mappersToRegister()) {
+            resultSetMapperSetBinder.addBinding().toInstance(resultSetMapper);
+        }
     }
 
     @Override

util/pom.xml 4(+4 -0)

diff --git a/util/pom.xml b/util/pom.xml
index f1616a7..c2a774b 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -196,6 +196,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
+            <artifactId>killbill-platform-lifecycle</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-platform-osgi</artifactId>
         </dependency>
         <dependency>
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoStringTemplate.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoStringTemplate.java
index ce2fd8d..dde1d56 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoStringTemplate.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoStringTemplate.java
@@ -24,20 +24,13 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 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.killbill.billing.util.dao.EntityHistoryModelDaoMapperFactory;
-import org.killbill.billing.util.entity.Entity;
-import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
-import org.skife.jdbi.v2.Query;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizer;
 import org.skife.jdbi.v2.sqlobject.SqlStatementCustomizingAnnotation;
-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;
@@ -99,32 +92,6 @@ public @interface EntitySqlDaoStringTemplate {
             return new SqlStatementCustomizer() {
                 public void apply(final SQLStatement statement) {
                     statement.setStatementLocator(l);
-
-                    if (statement instanceof Query) {
-                        final Query query = (Query) statement;
-
-                        // Find the model class associated with this sqlObjectType (which is a SqlDao class) to register its mapper
-                        // If a custom mapper is defined via @RegisterMapper, don't register our generic one
-                        if (sqlObjectType.getGenericInterfaces() != null &&
-                            sqlObjectType.getAnnotation(RegisterMapper.class) == null) {
-                            for (int i = 0; i < sqlObjectType.getGenericInterfaces().length; i++) {
-                                if (sqlObjectType.getGenericInterfaces()[i] instanceof ParameterizedType) {
-                                    final ParameterizedType type = (ParameterizedType) sqlObjectType.getGenericInterfaces()[i];
-                                    for (int j = 0; j < type.getActualTypeArguments().length; j++) {
-                                        final Type modelType = type.getActualTypeArguments()[j];
-                                        if (modelType instanceof Class) {
-                                            final Class modelClazz = (Class) modelType;
-                                            if (Entity.class.isAssignableFrom(modelClazz)) {
-                                                query.registerMapper(new LowerToCamelBeanMapperFactory(modelClazz));
-                                                query.registerMapper(new EntityHistoryModelDaoMapperFactory(modelClazz, sqlObjectType));
-                                            }
-                                        }
-                                    }
-                                }
-
-                            }
-                        }
-                    }
                 }
             };
         }
diff --git a/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
new file mode 100644
index 0000000..ec794cc
--- /dev/null
+++ b/util/src/main/java/org/killbill/billing/util/glue/IDBISetup.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.util.glue;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+import org.killbill.billing.lifecycle.ServiceFinder;
+import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
+import org.killbill.billing.util.dao.EntityHistoryModelDaoMapperFactory;
+import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
+import org.killbill.billing.util.entity.Entity;
+import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
+import org.killbill.billing.util.validation.dao.DatabaseSchemaSqlDao;
+import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
+import org.skife.jdbi.v2.ResultSetMapperFactory;
+import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+
+public class IDBISetup {
+
+    public static List<? extends ResultSetMapperFactory> mapperFactoriesToRegister() {
+        final Builder<ResultSetMapperFactory> builder = ImmutableList.<ResultSetMapperFactory>builder();
+        builder.add(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+
+        final ServiceFinder<EntitySqlDao> serviceFinder = new ServiceFinder<EntitySqlDao>(IDBISetup.class.getClassLoader(), EntitySqlDao.class.getName());
+        for (final Class<? extends EntitySqlDao> sqlObjectType : serviceFinder.getServices()) {
+            // Find the model class associated with this sqlObjectType (which is a SqlDao class) to register its mapper
+            // If a custom mapper is defined via @RegisterMapper, don't register our generic one
+            if (sqlObjectType.getGenericInterfaces() != null &&
+                sqlObjectType.getAnnotation(RegisterMapper.class) == null) {
+                for (int i = 0; i < sqlObjectType.getGenericInterfaces().length; i++) {
+                    if (sqlObjectType.getGenericInterfaces()[i] instanceof ParameterizedType) {
+                        final ParameterizedType type = (ParameterizedType) sqlObjectType.getGenericInterfaces()[i];
+                        for (int j = 0; j < type.getActualTypeArguments().length; j++) {
+                            final Type modelType = type.getActualTypeArguments()[j];
+                            if (modelType instanceof Class) {
+                                final Class modelClazz = (Class) modelType;
+                                if (Entity.class.isAssignableFrom(modelClazz)) {
+                                    builder.add(new LowerToCamelBeanMapperFactory(modelClazz));
+                                    builder.add(new EntityHistoryModelDaoMapperFactory(modelClazz, sqlObjectType));
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return builder.build();
+    }
+
+    public static List<? extends ResultSetMapper> mappersToRegister() {
+        return ImmutableList.<ResultSetMapper>builder()
+                .add(new AuditLogModelDaoMapper())
+                .add(new RecordIdIdMappingsMapper())
+                .add(new DatabaseSchemaSqlDao.ColumnInfoMapper())
+                .build();
+    }
+}
diff --git a/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java b/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
index 78e6d0f..0cd5142 100644
--- a/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
+++ b/util/src/main/java/org/killbill/billing/util/validation/dao/DatabaseSchemaSqlDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2015 Groupon, Inc
- * Copyright 2014-2015 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -29,11 +29,9 @@ import org.killbill.billing.util.validation.DefaultColumnInfo;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
-import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 @EntitySqlDaoStringTemplate
-@RegisterMapper(DatabaseSchemaSqlDao.ColumnInfoMapper.class)
 public interface DatabaseSchemaSqlDao {
 
     @SqlQuery
diff --git a/util/src/test/java/org/killbill/billing/DBTestingHelper.java b/util/src/test/java/org/killbill/billing/DBTestingHelper.java
index 7023039..7046879 100644
--- a/util/src/test/java/org/killbill/billing/DBTestingHelper.java
+++ b/util/src/test/java/org/killbill/billing/DBTestingHelper.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2017 Groupon, Inc
+ * Copyright 2014-2017 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -24,14 +24,13 @@ import java.util.Enumeration;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.killbill.billing.platform.test.PlatformDBTestingHelper;
-import org.killbill.billing.util.dao.AuditLogModelDaoMapper;
-import org.killbill.billing.util.dao.RecordIdIdMappingsMapper;
+import org.killbill.billing.util.glue.IDBISetup;
 import org.killbill.billing.util.io.IOUtils;
-import org.killbill.billing.util.security.shiro.dao.SessionModelDao;
 import org.killbill.commons.embeddeddb.EmbeddedDB;
-import org.killbill.commons.jdbi.mapper.LowerToCamelBeanMapperFactory;
 import org.skife.jdbi.v2.DBI;
 import org.skife.jdbi.v2.IDBI;
+import org.skife.jdbi.v2.ResultSetMapperFactory;
+import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.google.common.base.MoreObjects;
 
@@ -58,9 +57,13 @@ public class DBTestingHelper extends PlatformDBTestingHelper {
         final DBI dbi = (DBI) super.getDBI();
         // Register KB specific mappers
         if (initialized.compareAndSet(false, true)) {
-            dbi.registerMapper(new AuditLogModelDaoMapper());
-            dbi.registerMapper(new RecordIdIdMappingsMapper());
-            dbi.registerMapper(new LowerToCamelBeanMapperFactory(SessionModelDao.class));
+            for (final ResultSetMapperFactory resultSetMapperFactory : IDBISetup.mapperFactoriesToRegister()) {
+                dbi.registerMapper(resultSetMapperFactory);
+            }
+
+            for (final ResultSetMapper resultSetMapper : IDBISetup.mappersToRegister()) {
+                dbi.registerMapper(resultSetMapper);
+            }
         }
         return dbi;
     }