package com.brightgenerous.datasource; import static com.brightgenerous.commons.ObjectUtils.*; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.net.URL; import java.sql.DatabaseMetaData; import java.sql.Driver; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import javax.xml.stream.XMLStreamException; import org.apache.ibatis.session.AutoMappingBehavior; import com.brightgenerous.datasource.mybatis.guice.bean._bean_; import com.brightgenerous.datasource.mybatis.guice.mapper._mapper_; import com.brightgenerous.datasource.mybatis.guice.mapper.derby._mapper_derby_; import com.brightgenerous.datasource.mybatis.guice.transaction.QueryTransaction; import com.brightgenerous.datasource.mybatis.guice.transaction._transaction_; import com.brightgenerous.injection.PackageGenerateImplResolver; import com.brightgenerous.injection.PatternClassFilter; import com.brightgenerous.injection.PatternMemberFilter; import com.brightgenerous.injection.mybatis.guice.InjectorConfig; import com.brightgenerous.injection.mybatis.guice.InjectorFactory; import com.brightgenerous.orm.mapper.MapperMethods; import com.brightgenerous.orm.mapper.TypeComparator; import com.google.inject.Injector; class MybatisGuiceDataSource extends DataSource { @Override protected InjectorFactory createInjectorFactory() { return new InjectorFactoryImpl(); } private List<String> createTables; private List<String> dropTables; private List<String> initSqls; private List<String> dummySqls; { Class<?> mapperPath = _mapper_derby_.class; { URL res = mapperPath.getResource("_create_tables.xml"); if (res != null) { try (InputStream stream = res.openStream()) { createTables = Loader.loadCreateTables(stream); } catch (IOException | XMLStreamException e) { throw new RuntimeException(e); } } } { URL res = mapperPath.getResource("_create_tables.xml"); if (res != null) { try (InputStream stream = res.openStream()) { dropTables = Loader.loadDropTables(stream); Collections.reverse(dropTables); } catch (IOException | XMLStreamException e) { throw new RuntimeException(e); } } } { URL res = mapperPath.getResource("_init_sqls.xml"); if (res != null) { try (InputStream stream = res.openStream()) { initSqls = Loader.loadInitSqls(stream); } catch (IOException | XMLStreamException e) { throw new RuntimeException(e); } } } { URL res = mapperPath.getResource("_dummy_sqls.xml"); if (res != null) { try (InputStream stream = res.openStream()) { dummySqls = Loader.loadDummySqls(stream); } catch (IOException | XMLStreamException e) { throw new RuntimeException(e); } } } } @Override protected Initializer createInitializer() { return new CompositeInitializer(super.createInitializer(), new Initializer() { @Override public void initialize(Injector injector) { try { Class.forName(MapperMethods.class.getName()); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } List<String> sqls = new ArrayList<>(); if (isNotNoSize(createTables)) { sqls.addAll(createTables); } if (isNotNoSize(initSqls)) { sqls.addAll(initSqls); } if (isNotNoSize(dummySqls)) { sqls.addAll(dummySqls); } if (isNotNoSize(sqls)) { injector.getInstance(QueryTransaction.class).edit(sqls); } } }); } @Override protected Destroyer createDestroyer() { return new CompositeDestroyer(new Destroyer() { @Override public void destroy(Injector injector) { if (isNotNoSize(dropTables)) { injector.getInstance(QueryTransaction.class).edit(dropTables); } } }, super.createDestroyer()); } static class InjectorFactoryImpl extends InjectorFactory { private static final long serialVersionUID = -8248458184709739906L; @Override protected InjectorConfig createConfig() { InjectorConfig config = new InjectorConfig(); { Map<String, String> dbProperties = new HashMap<>(); { dbProperties.put("JDBC.driver", "org.apache.derby.jdbc.EmbeddedDriver"); dbProperties.put("JDBC.url", "jdbc:derby:memory:patient;create=true"); dbProperties.put("JDBC.autoCommit", "false"); dbProperties.put("DBCP.defaultReadOnly", "true"); } config.setDbProperties(dbProperties); config.setEnvironmentId("test"); config.setUseGeneratedKeys(true); config.setLazyLoadingEnabled(true); config.setAutoMappingBehavior(AutoMappingBehavior.FULL); config.setMapUnderscoreToCamelCase(true); config.setFailFast(true); } config.setTransactionPackages(_transaction_.class); config.setTransactionClassFilter(new PatternClassFilter("^.*Transaction$")); config.setTransactionMethodFilter(new PatternMemberFilter<Method>( "^(add|edit|remove|initialize|destroy).*$")); config.setMapperPackages(_mapper_.class); config.setMapperClassFilter(new PatternClassFilter("^.*Mapper$")); config.setMapperImplResolver(new PackageGenerateImplResolver(_mapper_derby_.class)); config.setBeanPackages(_bean_.class); return config; } @Override public void onInitialize() { super.onInitialize(); try { Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance(); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } MapperMethods .set(com.brightgenerous.datasource.mybatis.guice.mapper.MapperMethods.class); } @Override protected boolean compareBeanToTable(DatabaseMetaData dmd, Set<Class<?>> beanClasses) throws SQLException { MapperMethods mapperMethods = MapperMethods.get(); Map<Class<?>, String> targetTables = mapperMethods.getTargetTables(); for (Class<?> beanClass : beanClasses) { String table = targetTables.get(beanClass); if (table != null) { Map<String, String> columnTypes = new TreeMap<>(new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.toLowerCase().compareTo(o2.toLowerCase()); } }); try (ResultSet rs = dmd.getColumns(null, "APP", table.toUpperCase(), "%")) { while (rs.next()) { String name = rs.getString("COLUMN_NAME"); String type = rs.getString("TYPE_NAME"); columnTypes.put(name, type); } } mapperMethods.verify(table, columnTypes, TypeComparator.DERBY); } } return true; } @Override public void onDestroy() { super.onDestroy(); try { DriverManager.getConnection("jdbc:derby:;shutdown=true"); } catch (Exception ex) { } Enumeration<Driver> drivers = DriverManager.getDrivers(); while (drivers.hasMoreElements()) { Driver driver = drivers.nextElement(); try { DriverManager.deregisterDriver(driver); } catch (SQLException e) { } } } } }