View Javadoc

1   package pl.aislib.tools.mapping.generators;
2   
3   import java.io.File;
4   import java.io.FileWriter;
5   import java.io.IOException;
6   import java.io.Writer;
7   import java.util.ArrayList;
8   import java.util.Iterator;
9   import java.util.List;
10  
11  import pl.aislib.tools.mapping.Generator;
12  import pl.aislib.tools.mapping.structure.Field;
13  import pl.aislib.tools.mapping.structure.Fields;
14  import pl.aislib.tools.mapping.structure.JavaClass;
15  import pl.aislib.tools.mapping.structure.JavaMethod;
16  import pl.aislib.tools.mapping.structure.JavaParam;
17  import pl.aislib.tools.mapping.structure.Operations;
18  import pl.aislib.tools.mapping.structure.Select;
19  import pl.aislib.tools.mapping.structure.SqlQuery;
20  import pl.aislib.tools.mapping.structure.SqlTable;
21  import pl.aislib.tools.mapping.structure.Structure;
22  
23    /***
24     * Database test generator.
25     *
26     * @author Milosz Tylenda, AIS.PL (milosz@ais.pl)
27     * $Revision: 1.6 $
28     */
29  public class DatabaseTestGenerator extends Generator {
30  
31    private Writer writer;
32    private File   baseDir;
33  
34    protected String databaseClassName = "ApplicationDatabaseTest";
35    protected boolean useManagerHelper = false;
36  
37    private MiscPutter miscPutter        = new MiscPutter();
38    private List operationTestPutterList = new ArrayList();
39    private List fieldTestPutterList     = new ArrayList();
40  
41    /***
42     * Sets the name of the generated class.
43     */
44    public void setDatabaseClassName(String databaseClassName) {
45      this.databaseClassName = databaseClassName;
46    }
47  
48    /***
49     * To use or not to use the ManagerHelper class. This is the question.
50     */
51    public void setUseManagerHelper(boolean umh) {
52      useManagerHelper = umh;
53    }
54  
55    private File initDirectory(File destinationDir) throws IOException {
56      File dir = new File(destinationDir.getPath() + File.separator + "test");
57      if (!dir.exists()) {
58        dir.mkdirs();
59      }
60      return dir;
61    }
62  
63    private void initWriter(String className) throws IOException {
64      writer = new FileWriter(baseDir.getPath() + File.separator + className + ".java");
65    }
66  
67    private void closeWriter() throws IOException {
68      writer.close();
69    }
70  
71    /***
72     * The core method.
73     */
74    public void generate() throws IOException {
75  
76      if (database == null) {
77        throw new IOException("Database object is null! (structure.xml not parsed?)");
78      }
79      baseDir = initDirectory(destinationDir);
80      initWriter(databaseClassName);
81  
82      // Operations testing
83      List structureList = database.getStructureList();
84      for (int i = 0, size = structureList.size() ; i < size ; i++) {  // all structures
85        Structure  structure   = (Structure) structureList.get(i);
86        Operations operations  = structure.getOperations(); // get operations from structure
87        if (operations == null) {continue;} // skip this structure if it has no operations defined
88        JavaClass javaClass    = structure.getJavaClass();  // get javaClass from structure
89        SqlTable  sqlTable     = structure.getSqlTable();  // get SqlTable from structure
90        List      selectList   = operations.getSelectList();  // iterate thru selects
91        for (Iterator selectIter = selectList.listIterator() ; selectIter.hasNext() ; ) {
92          Select select = (Select) selectIter.next(); // create op.putter for each select
93          OperationTestPutter operationTestPutter = new OperationTestPutter(writer);
94          SqlQuery   sqlQuery   = select.getSqlQuery();  // get sqlQuery from select
95          JavaMethod javaMethod = select.getJavaMethod();// get javaMethod from select
96          operationTestPutter.setJavaClassName(javaClass.getName());
97          operationTestPutter.setTableName(sqlTable.getName());
98          operationTestPutter.setQueryWhere(sqlQuery.getWhere());
99          operationTestPutter.setQueryOrder(sqlQuery.getOrderBy());
100         operationTestPutter.setJavaMethodName(javaMethod.getName());
101         List javaParamList = javaMethod.getJavaParamList(); // iterate thru javaParams
102         for (Iterator paramIter = javaParamList.listIterator() ; paramIter.hasNext() ; ) {
103           JavaParam javaParam = (JavaParam) paramIter.next();
104           operationTestPutter.addJavaParamType(javaParam.getType());
105         }
106         operationTestPutterList.add(operationTestPutter); // add op.putter to the list
107       }
108 
109     }
110 
111     // Field testing
112     structureList = database.getStructureList();
113     for (Iterator structureIter = structureList.listIterator() ; structureIter.hasNext() ; ) {
114       Structure structure = (Structure) structureIter.next();
115       JavaClass javaClass = structure.getJavaClass();
116       SqlTable  sqlTable  = structure.getSqlTable();
117       Fields    fields    = structure.getFields();
118       List fieldList      = fields.getFieldList();
119       for (Iterator fieldIter = fieldList.listIterator() ; fieldIter.hasNext() ; ) {
120         Field field = (Field) fieldIter.next(); // allocate a new putter for each field, it's
121         FieldTestPutter fieldTestPutter = new FieldTestPutter(writer); // not efficient...
122         fieldTestPutter.setProperties(javaClass, sqlTable, field);
123         fieldTestPutterList.add(fieldTestPutter); // add putter to the list
124       }
125     }
126 
127     // Now we flush all the source code to a file
128     miscPutter.setWriter(writer);
129     miscPutter.putHeader(packageName, useManagerHelper);  // package, imports
130     miscPutter.putClassHeader(databaseClassName, useManagerHelper); // class beginning, setUp(), tearDown()
131     for (int i = 0 ; i < operationTestPutterList.size() ; i++) {// operation tests
132       ((OperationTestPutter) operationTestPutterList.get(i)).put();
133     }
134     for (int i = 0 ; i < fieldTestPutterList.size() ; i++) {// field tests
135       ((FieldTestPutter) fieldTestPutterList.get(i)).put();
136     }
137     miscPutter.putClassEndBrace();  // and, at last, the final brace!
138     closeWriter();
139     log(databaseClassName + " class generated: ");
140     log("  " + operationTestPutterList.size() + " operation-test method(s) generated");
141     log("  " + fieldTestPutterList.size() + " field-test method(s) generated");
142     log("  " + "UseManagerHelper = " + useManagerHelper);
143   }
144 
145 
146   //#############################  OPERATION TEST  ###########################
147   /***
148    *
149    * @author Milosz Tylenda, AIS.PL
150    */
151   class OperationTestPutter {
152 
153     private StringBuffer str;
154     private Writer writer;
155     private String javaClassName;
156     private String queryWhere;
157     private String queryOrder;
158     private String javaMethodName;
159     private String tableName;
160     private List javaParamTypes;
161 
162     public OperationTestPutter(Writer awriter) {
163       str = new StringBuffer(512);
164       javaParamTypes = new ArrayList();
165       reset();
166       setWriter(awriter);
167     }
168 
169     private void reset() {
170       str.delete(0, str.length());
171       // tableName and javaClassName are per structure vars, others are per select.
172       queryWhere = null;
173       queryOrder = null;
174       javaMethodName = "(NO java-method name SPECIFIED)";
175       javaParamTypes.clear();
176     }
177 
178     private void setWriter(Writer awriter) {
179       writer = awriter;
180     }
181 
182     public void put() throws IOException {
183       int i;
184 
185       str.append("  public void testSelect" + javaClassName + Utils.capitalize(javaMethodName));
186       //str.append("  public void testSelect" + javaClassName + javaMethodName);
187       str.append("() throws SQLException {\n");
188       str.append("    Statement stmt = null;\n");
189       str.append("    ResultSet rs = null;\n");
190       str.append("    try {\n");
191       str.append("      PreparedStatement pstmt = con.prepareStatement(\"select count(*) \" +\n");
192       str.append("        \"from " + tableName);
193 
194       if ((queryWhere != null) && (queryWhere.length() > 0)) {
195         str.append(" where " + queryWhere);
196       }
197       if ((queryOrder != null) && (queryOrder.length() > 0)) {
198         str.append(" order by " + queryOrder);
199       }
200       str.append("\");\n");
201       if (!javaParamTypes.isEmpty()) {
202         str.append("      int counter = 1;\n");
203         for (i = 0 ; i < javaParamTypes.size() ; i++) {
204           str.append("      pstmt.setNull(counter++, " + Utils.getSQLType((String) javaParamTypes.get(i)) + ");\n");
205           //str.append("      pstmt.setNull(counter++, " + ((String) javaParamTypes.get(i)) + ");\n");
206         }
207       }
208       str.append("      rs = pstmt.executeQuery();\n");
209       str.append("      rs.close();\n");
210       str.append("    } catch (SQLException sqle) { \n");
211       str.append("      fail(\"Can't execute select" + javaClassName + Utils.capitalize(javaMethodName) + " operation!\");\n");
212       //str.append("      fail(\"Can't execute select" + javaClassName + javaMethodName + " operation!\");\n");
213       str.append("    } finally { \n");
214       str.append("      if (rs != null) rs.close();\n");
215       str.append("      if (stmt != null) stmt.close();\n");
216       str.append("    }\n");
217       str.append("  }\n\n");
218 
219       writer.write(str.toString());
220       reset();
221     }
222 
223     public void setJavaClassName(String aJavaClassName) {
224       javaClassName = aJavaClassName;
225     }
226 
227     public void setJavaMethodName(String aJavaMethodName) {
228       javaMethodName = aJavaMethodName;
229     }
230 
231     public void setTableName(String aTableName) {
232       tableName = aTableName;
233     }
234 
235     public void setQueryWhere(String aQueryWhere) {
236       queryWhere = aQueryWhere;
237     }
238 
239     public void setQueryOrder(String aQueryOrder) {
240       queryOrder = aQueryOrder;
241     }
242 
243     public void addJavaParamType(String aJavaParamType) {
244       javaParamTypes.add(aJavaParamType);
245     }
246   } // class OperationTestPutter
247 
248 
249   //#############################  FIELD TEST  ###########################
250   /***
251    *
252    * @author Milosz Tylenda, AIS.PL
253    */
254   class FieldTestPutter {
255 
256     private Writer writer;
257     private JavaClass javaClass;
258     private Field     field;
259     private SqlTable  sqlTable;
260 
261     public FieldTestPutter(Writer awriter) {
262       writer = awriter;
263     }
264 
265     public void put() throws IOException {
266       writer.write("  public void test");
267       writer.write(javaClass.getName());
268       writer.write(Utils.capitalize(field.getJavaField().getName()));
269       //writer.write(field.getJavaField().getName());
270       writer.write("() throws SQLException {\n");
271       writer.write("    Statement stmt = null;\n");
272       writer.write("    ResultSet rs = null;\n");
273       writer.write("    try {\n");
274       writer.write("      stmt = con.createStatement();\n");
275       writer.write("      rs = stmt.executeQuery(\"SELECT ");
276       writer.write(field.getSqlField().getName());
277       writer.write(" FROM ");
278       writer.write(sqlTable.getName());
279       writer.write("\");\n");
280       writer.write("    } catch (SQLException sqle) {\n");
281       writer.write("      fail(\"field " + field.getSqlField().getName() +
282         " in " + sqlTable.getName() + " doesn't exist\");\n");
283       writer.write("    } finally {\n");
284       writer.write("      if (rs != null) rs.close();\n");
285       writer.write("      if (stmt != null) stmt.close();\n");
286       writer.write("    }\n");
287       writer.write("  }\n");
288       writer.write("\n");
289     }
290 
291     public void setProperties(JavaClass javaClass, SqlTable sqlTable, Field field) {
292       this.javaClass = javaClass;
293       this.sqlTable = sqlTable;
294       this.field = field;
295     }
296   } // class FieldTestPutter
297 
298 
299 
300   //#############################  MISC  ###########################
301   /***
302    * Puts some little things like <CODE>package</CODE> string and class end brace.
303    * @author Milosz Tylenda, AIS.PL
304    */
305   class MiscPutter {
306 
307     private Writer writer;
308 
309     public void setWriter(Writer awriter) {
310       writer = awriter;
311     }
312 
313     publicong> void putHeader(String packagePrefix, boolean useManagerHelper) throws IOException {
314       writer.write("package " + packagePrefix + ";\n\n");
315       writer.write(" // THIS FILE HAS BEEN GENERATED AUTOMAGICALLY BY DatabaseTestGenerator\n");
316       //writer.write(" // ON ");
317       //writer.write( new SimpleDateFormat("dd-MMM-yyyy HH:mm").format(new Date()) + "\n");
318       writer.write(" // DO NOT EDIT!\n\n");
319       writer.write("import java.sql.Connection;\n");
320       writer.write("import java.sql.DriverManager;\n");
321       writer.write("import java.sql.PreparedStatement;\n");
322       writer.write("import java.sql.ResultSet;\n");
323       writer.write("import java.sql.SQLException;\n");
324       writer.write("import java.sql.Statement;\n");
325       writer.write("import java.sql.Timestamp;\n\n");
326       writer.write("import java.util.List;\n\n");
327       writer.write("import junit.framework.TestCase;\n\n");
328       if (useManagerHelper) {
329         writer.write("import pl.aislib.fm.jdbc.Manager;\n\n");
330       }
331     }
332 
333     public void putClassHeader(String databaseClassName, boolean useManagerHelper) throws IOException {
334       writer.write("\n");
335       writer.write("\n");
336       writer.write("public class " + databaseClassName + " extends TestCase {\n");
337       writer.write("  public " + databaseClassName + "(String testName) {\n");
338       writer.write("    super(testName);\n");
339       writer.write("  }\n");
340       writer.write("  \n");
341       writer.write("  private Connection con;\n");
342       if (!useManagerHelper) {
343         writer.write("  public void setUp() throws Exception {\n");
344         writer.write("    con = DriverManager.getConnection(\"jdbc:apache:commons:dbcp:test\");\n");
345         writer.write("  }\n");
346         writer.write("  \n");
347       } else {
348         writer.write("  protected Manager manager;\n\n");
349         writer.write("  public void setUp() throws Exception {\n");
350         writer.write("    manager = DatabaseTestHelper.createManager();\n");
351         writer.write("    con     = manager.getConnection();\n");
352         writer.write("  }\n");
353         writer.write("  \n");
354       }
355       writer.write("  public void tearDown() throws Exception {\n");
356       writer.write("    con.close();\n");
357       writer.write("  }\n");
358       writer.write("  \n");
359     }
360 
361     public void putClassEndBrace() throws IOException {
362       writer.write("}\n");
363     }
364 
365   } // class MiscPutter
366 
367 }
368 
369 /***
370  * $Log: DatabaseTestGenerator.java,v $
371  * Revision 1.6  2004/08/11 12:41:01  wswiatek
372  * Database and map handlers location are now parametrizable.
373  * Maven plugin version changed to 1.0.1
374  *
375  * Revision 1.5  2003/10/29 11:47:02  pikus
376  * use ant logger where possible
377  *
378  * Revision 1.4  2003/05/26 08:36:03  pikus
379  * cleanup imports
380  *
381  * Revision 1.3  2002/10/08 08:27:10  milosz
382  * Generators became AntTasks(?). Ufff...
383  *
384  * Revision 1.2  2002/10/04 13:07:22  milosz
385  * Reaching old mapping's functionality.
386  *
387  */
388