Clover Coverage Report - Liquibase Core 2.0.3-SNAPSHOT
Coverage timestamp: Sat Aug 6 2011 11:33:15 EDT
../../img/srcFileCovDistChart7.png 19% of files have more coverage
68   199   36   4
34   151   0.53   17
17     2.12  
1    
 
  SqlGeneratorFactory       Line # 27 68 0% 36 40 66.4% 0.66386557
 
  (106)
 
1    package liquibase.sqlgenerator;
2   
3    import java.lang.reflect.ParameterizedType;
4    import java.lang.reflect.Type;
5    import java.lang.reflect.TypeVariable;
6    import java.util.ArrayList;
7    import java.util.Collection;
8    import java.util.HashSet;
9    import java.util.List;
10    import java.util.Set;
11    import java.util.SortedSet;
12    import java.util.TreeSet;
13   
14    import liquibase.database.Database;
15    import liquibase.database.structure.DatabaseObject;
16    import liquibase.exception.ValidationErrors;
17    import liquibase.exception.Warnings;
18    import liquibase.servicelocator.ServiceLocator;
19    import liquibase.sql.Sql;
20    import liquibase.statement.SqlStatement;
21   
22    /**
23    * SqlGeneratorFactory is a singleton registry of SqlGenerators. Use the register(SqlGenerator) method to add custom
24    * SqlGenerators, and the getBestGenerator() method to retrieve the SqlGenerator that should be used for a given
25    * SqlStatement.
26    */
 
27    public class SqlGeneratorFactory {
28   
29    private static SqlGeneratorFactory instance;
30   
31    private List<SqlGenerator> generators = new ArrayList<SqlGenerator>();
32   
 
33  10 toggle private SqlGeneratorFactory() {
34  10 Class[] classes;
35  10 try {
36  10 classes = ServiceLocator.getInstance().findClasses(SqlGenerator.class);
37   
38  10 for (Class clazz : classes) {
39  1000 register((SqlGenerator) clazz.getConstructor().newInstance());
40    }
41   
42    } catch (Exception e) {
43  0 throw new RuntimeException(e);
44    }
45   
46    }
47   
48    /**
49    * Return singleton SqlGeneratorFactory
50    */
 
51  1839 toggle public static SqlGeneratorFactory getInstance() {
52  1839 if (instance == null) {
53  1 instance = new SqlGeneratorFactory();
54    }
55  1839 return instance;
56    }
57   
 
58  9 toggle public static void reset() {
59  9 instance = new SqlGeneratorFactory();
60    }
61   
 
62  1010 toggle public void register(SqlGenerator generator) {
63  1010 generators.add(generator);
64    }
65   
 
66  3 toggle public void unregister(SqlGenerator generator) {
67  3 generators.remove(generator);
68    }
69   
 
70  2 toggle public void unregister(Class generatorClass) {
71  2 SqlGenerator toRemove = null;
72  2 for (SqlGenerator existingGenerator : generators) {
73  6 if (existingGenerator.getClass().equals(generatorClass)) {
74  1 toRemove = existingGenerator;
75    }
76    }
77   
78  2 unregister(toRemove);
79    }
80   
 
81  1842 toggle protected Collection<SqlGenerator> getGenerators() {
82  1842 return generators;
83    }
84   
 
85  1825 toggle protected SortedSet<SqlGenerator> getGenerators(SqlStatement statement, Database database) {
86  1825 SortedSet<SqlGenerator> validGenerators = new TreeSet<SqlGenerator>(new SqlGeneratorComparator());
87   
88  1825 for (SqlGenerator generator : getGenerators()) {
89  182500 Class clazz = generator.getClass();
90  182500 Type classType = null;
91  793875 while (clazz != null) {
92  611375 if (classType instanceof ParameterizedType) {
93  182500 checkType(classType, statement, generator, database, validGenerators);
94    }
95   
96  611375 for (Type type : clazz.getGenericInterfaces()) {
97  182500 if (type instanceof ParameterizedType) {
98  182500 checkType(type, statement, generator, database, validGenerators);
99  0 } else if (isTypeEqual(type, SqlGenerator.class)) {
100    // noinspection unchecked
101  0 if (generator.supports(statement, database)) {
102  0 validGenerators.add(generator);
103    }
104    }
105    }
106  611375 classType = clazz.getGenericSuperclass();
107  611375 clazz = clazz.getSuperclass();
108    }
109    }
110  1825 return validGenerators;
111    }
112   
 
113  365000 toggle private boolean isTypeEqual(Type aType, Class aClass) {
114  365000 if (aType instanceof Class) {
115  365000 return ((Class) aType).getName().equals(aClass.getName());
116    }
117  0 return aType.equals(aClass);
118    }
119   
 
120  365000 toggle private void checkType(Type type, SqlStatement statement, SqlGenerator generator, Database database,
121    SortedSet<SqlGenerator> validGenerators) {
122  365000 for (Type typeClass : ((ParameterizedType) type).getActualTypeArguments()) {
123  365000 if (typeClass instanceof TypeVariable) {
124  182500 typeClass = ((TypeVariable) typeClass).getBounds()[0];
125    }
126   
127  365000 if (isTypeEqual(typeClass, SqlStatement.class)) {
128  182500 return;
129    }
130   
131  182500 if (((Class) typeClass).isAssignableFrom(statement.getClass())) {
132  2843 if (generator.supports(statement, database)) {
133  1784 validGenerators.add(generator);
134    }
135    }
136    }
137   
138    }
139   
 
140  427 toggle private SqlGeneratorChain createGeneratorChain(SqlStatement statement, Database database) {
141  427 SortedSet<SqlGenerator> sqlGenerators = getGenerators(statement, database);
142  427 if (sqlGenerators == null || sqlGenerators.size() == 0) {
143  0 return null;
144    }
145    // noinspection unchecked
146  427 return new SqlGeneratorChain(sqlGenerators);
147    }
148   
 
149  0 toggle public Sql[] generateSql(SqlStatement statement, Database database) {
150  0 SqlGeneratorChain generatorChain = createGeneratorChain(statement, database);
151  0 if (generatorChain == null) {
152  0 throw new IllegalStateException("Cannot find generators for database " + database.getClass()
153    + ", statement: " + statement);
154    }
155  0 return generatorChain.generateSql(statement, database);
156    }
157   
 
158  0 toggle public boolean requiresCurrentDatabaseMetadata(SqlStatement statement, Database database) {
159  0 for (SqlGenerator generator : getGenerators(statement, database)) {
160  0 if (generator.requiresUpdatedDatabaseMetadata(database)) {
161  0 return true;
162    }
163    }
164  0 return false;
165    }
166   
 
167  1397 toggle public boolean supports(SqlStatement statement, Database database) {
168  1397 return getGenerators(statement, database).size() > 0;
169    }
170   
 
171  423 toggle public ValidationErrors validate(SqlStatement statement, Database database) {
172    // noinspection unchecked
173  423 return createGeneratorChain(statement, database).validate(statement, database);
174    }
175   
 
176  4 toggle public Warnings warn(SqlStatement statement, Database database) {
177    // noinspection unchecked
178  4 return createGeneratorChain(statement, database).warn(statement, database);
179    }
180   
 
181  0 toggle public Set<DatabaseObject> getAffectedDatabaseObjects(SqlStatement statement, Database database) {
182  0 Set<DatabaseObject> affectedObjects = new HashSet<DatabaseObject>();
183   
184  0 SqlGeneratorChain sqlGeneratorChain = createGeneratorChain(statement, database);
185  0 if (sqlGeneratorChain != null) {
186    // noinspection unchecked
187  0 Sql[] sqls = sqlGeneratorChain.generateSql(statement, database);
188  0 if (sqls != null) {
189  0 for (Sql sql : sqls) {
190  0 affectedObjects.addAll(sql.getAffectedDatabaseObjects());
191    }
192    }
193    }
194   
195  0 return affectedObjects;
196   
197    }
198   
199    }