View Javadoc

1   package pl.aislib.tools.mapping.generators;
2   
3   import java.util.HashMap;
4   import java.util.List;
5   import java.util.Map;
6   
7   import pl.aislib.tools.mapping.structure.Field;
8   import pl.aislib.tools.mapping.structure.JavaField;
9   import pl.aislib.tools.mapping.structure.JavaParam;
10  import pl.aislib.tools.mapping.structure.SqlField;
11  
12  /***
13   * Some static methods used by generators.
14   *
15   * @author Milosz Tylenda, AIS.PL (milosz@ais.pl)
16   * $Revision: 1.15 $
17   */
18  public class Utils {
19    
20    private static final int MAX_STRING_LENGTH = 40;
21  
22    private static final Map typeMapping = new HashMap();
23  
24    static {
25      typeMapping.put("BigDecimal", "BigDecimal");
26      typeMapping.put("Double",     "Double");
27      typeMapping.put("Float",      "Float");
28      typeMapping.put("Integer",    "Int");
29      typeMapping.put("Long",       "Long");
30      typeMapping.put("String",     "String");
31      typeMapping.put("Timestamp",  "Timestamp");
32      typeMapping.put("Array",      "Array");
33    }
34  
35    /***
36     * Returns the given String splitted in terms of Java language (plus signs).
37     * Each chunk has maximum length defined in {@link #MAX_STRING_LENGTH}.
38     */
39    public static String equalLengthSplit(String s) {
40      if (s.length() == 0) {
41        return "\"\"";
42      }
43      StringBuffer result = new StringBuffer(512);
44      int sLength = s.length();
45      String subString;
46      String plus;
47      for (int i = 0 ; i < sLength ; i += MAX_STRING_LENGTH) {
48        if ((i + MAX_STRING_LENGTH) >= sLength) {
49          subString = s.substring(i);
50          plus = "";
51        } else {
52          subString = s.substring(i, i + MAX_STRING_LENGTH);
53          plus = " + ";
54        }
55        result.append("\"");
56        result.append(subString);
57        result.append("\"");
58        result.append(plus);
59      }
60      return result.toString();
61    }
62  
63    /***
64     * Returns the given string with first letter changed to uppercase.
65     */
66    public static String capitalize(String s) {
67      if ((s == null) || (s.equals(""))) {
68        return "";
69      }
70      StringBuffer sb = new StringBuffer(s);
71      sb.replace(0, 1, s.substring(0, 1).toUpperCase());
72      return sb.toString();
73    }
74  
75    /***
76     * Provides mapping between Java and SQL data types.
77     */
78    public static String getSQLType(String arg) {
79      if (arg.equals("Integer")) {
80        return "java.sql.Types.INTEGER";
81      } else if (arg.equals("Long")) {
82        return "java.sql.Types.BIGINT";
83      } else if (arg.equals("Double")) {
84        return "java.sql.Types.DOUBLE";
85      } else if (arg.equals("Float")) {
86        return "java.sql.Types.FLOAT";
87      } else if (arg.equals("String")) {
88        return "java.sql.Types.VARCHAR";
89      } else if (arg.equals("Timestamp")) {
90        return "java.sql.Types.TIMESTAMP";
91      } else if (arg.equals("BigDecimal")) {
92        return "java.sql.Types.NUMERIC";
93      } else if (arg.equals("Array")) {
94        return "java.sql.Types.ARRAY";
95      } else {
96        throw new RuntimeException("Unknown type: " + arg);
97      }
98    }
99  
100   /***
101    *
102    */
103   public static boolean isBaseType(String typeName) {
104     if (typeName.equals("String") ||
105         typeName.equals("Timestamp") ||
106         typeName.equals("BigDecimal") ||
107         typeName.equals("Array")) {
108       return false;
109     } else {
110       return true;
111     }
112   }
113 
114   /***
115    * Used to construct <code>PreparedStatement.setX</code> methods.
116    */
117   public static String mapTypeToMethod(String arg) {
118     String mapMethod = (String) typeMapping.get(arg);
119     if (mapMethod == null) {
120       throw new RuntimeException("unknown type: " + arg);
121     }
122     return mapMethod;
123   }
124 
125   /***
126    * Provides <code>Integer -&gt; intValue()</code> kind of mapping.
127    */
128   public static String castMethod(String arg) {
129     if (arg.equals("Integer")) {
130       return ".intValue()";
131     } else if (arg.equals("Long")) {
132       return ".longValue()";
133     } else if (arg.equals("Double")) {
134       return ".doubleValue()";
135     } else if (arg.equals("Float")) {
136       return ".floatValue()";
137     } else {
138       return "";
139     }
140   }
141 
142   /***
143    * Calls {@link #formatSqlListWithTablePrefix} with empty String as <code>tablePrefix</code>,
144    * then splits the String (i.e. produces one String with lots of plus signs and quotes),
145    * so Jalopy will be able to break long lines.
146    */
147   public static String formatSqlList(List fieldList) {
148     String longString = formatSqlListWithTablePrefix(fieldList, "");
149     return equalLengthSplit(longString);
150   }
151 
152   /***
153    * If <code>useTableName</code> is set
154    * calls {@link #formatSqlListWithTablePrefix} with <code>tableName + "."</code> as <code>tablePrefix</code>.
155    * Else
156    * calls {@link #formatSqlListWithTablePrefix} with empty String as <code>tablePrefix</code>.
157    */
158   public static String formatSqlList2(List fieldList, boolean useTableName, String tableName) {
159     if (useTableName) {
160       return formatSqlListWithTablePrefix(fieldList, tableName + ".");
161     }
162     return formatSqlListWithTablePrefix(fieldList, "");
163   }
164     
165   /***
166    * Formats arguments as column list for SELECT statement.
167    * @param fieldList the List of Field objects
168    * @param tablePrefix the prefix to append before column names
169    */
170   private static String formatSqlListWithTablePrefix(List fieldList, String tablePrefix) {
171     StringBuffer str = new StringBuffer(128);
172     for (int i = 0, size = fieldList.size() ; i < size ; i++) {
173       Field field = (Field) fieldList.get(i);
174       SqlField sqlField = field.getSqlField();
175       String name       = sqlField.getName();
176       str.append(tablePrefix);
177       str.append(name);
178       if (i < size - 1) {
179         str.append(", ");
180       }
181     }
182     return str.toString();
183   }
184 
185   /***
186    *
187    */
188   public static String formatSqlListForWhere(List fieldList) {
189     StringBuffer str = new StringBuffer(128);
190     for (int i = 0, size = fieldList.size() ; i < size ; i++) {
191       Field field = (Field) fieldList.get(i);
192       SqlField sqlField = field.getSqlField();
193       String name       = sqlField.getName();
194       str.append(name);
195       str.append(" = ? ");
196       if (i < size - 1) {
197         str.append("and ");
198       }
199     }
200     return str.toString();
201   }
202     
203   /***
204    * Formats arguments as column list for UPDATE statement.
205    * The returned String is splitted.
206    * @param fieldList the List of Field objects
207    */
208   public static String formatSqlListForUpdate(List fieldList) {
209     StringBuffer str = new StringBuffer(128);
210     for (int i = 0, size = fieldList.size() ; i < size ; i++) {
211       Field field = (Field) fieldList.get(i);
212       SqlField sqlField = field.getSqlField();
213       String name       = sqlField.getName();
214       str.append(name);
215       str.append(" = ? ");
216       if (i < size - 1) {
217         str.append(", ");
218       }
219     }
220     return equalLengthSplit(str.toString());
221   }
222     
223   /***
224    * Formats arguments for Java method declaration (Fields).
225    * @param fieldList the List of Field objects
226    */
227   public static String formatArgList(List fieldList) {
228     StringBuffer str = new StringBuffer(128);
229     for (int i = 0, size = fieldList.size() ; i < size ; i++) {
230       Field field         = (Field) fieldList.get(i);
231       JavaField javaField = field.getJavaField();
232       String name         = javaField.getName();
233       String type         = javaField.getType();
234       str.append(type + " " + name);
235       if (i < size - 1) {
236         str.append(", ");
237       }
238     }
239     return str.toString();
240   }
241     
242   /***
243    * Formats arguments for Java method declaration (JavaParams).
244    * @param javaParamList the List of JavaParam objects
245    */
246   public static String formatMethodArgs(List javaParamList) {
247     StringBuffer str = new StringBuffer(128);
248     for (int i = 0, size = javaParamList.size() ; i < size ; i++) {
249       JavaParam javaParam = (JavaParam) javaParamList.get(i);
250       str.append(javaParam.getType() + " " + javaParam.getName());
251       str.append(", ");
252     }
253     return str.toString();
254   }
255   
256   /***
257    * Formats arguments for Java method declaration without ending comma (JavaParams).
258    * @param javaParamList the List of JavaParam objects
259    */
260   public static String formatMethodArgsWithoutComma(List javaParamList) {
261     StringBuffer str = new StringBuffer(128);
262     for (int i = 0, size = javaParamList.size() ; i < size ; i++) {
263       JavaParam javaParam = (JavaParam) javaParamList.get(i);
264       str.append( " " + javaParam.getType() + " " + javaParam.getName());
265       if (i < size - 1) {
266         str.append(",");
267       } else {
268         str.append("\n");
269       }
270     }
271     return str.toString();
272   }
273     
274   /***
275    * Formats arguments for Java method invocation (JavaParams).
276    * Only param names, no types.
277    * @param javaParamList the List of JavaParam objects
278    */
279   public static String formatMethodParams(List javaParamList) {
280     StringBuffer str = new StringBuffer(128);
281     for (int i = 0, size = javaParamList.size() ; i < size ; i++) {
282       JavaParam javaParam = (JavaParam) javaParamList.get(i);
283       str.append(javaParam.getName() + ", ");
284     }
285     return str.toString();
286   }
287   
288   /***
289    * Formats arguments for JavaDoc (JavaParams).
290    * @param javaParamList the List of JavaParam objects
291    */
292   public static String formatMethodArgsForJavaDoc(List javaParamList) {
293     StringBuffer str = new StringBuffer(128);
294     for (int i = 0, size = javaParamList.size() ; i < size ; i++) {
295       JavaParam javaParam = (JavaParam) javaParamList.get(i);
296       str.append("   * @param " + javaParam.getName() + " the instance of ");
297       str.append("<code>" + javaParam.getType() + "</code>");
298       str.append("\n");
299     }
300     return str.toString();
301   }
302 
303   /***
304    * Generates PreparedStatement.setX related code.
305    * @param javaParamList the List of JavaParam objects
306    */
307   public static String generatePstmtSets(List javaParamList) {
308     StringBuffer str = new StringBuffer(256);
309     for (int i = 0, size = javaParamList.size() ; i < size ; i++) {
310       JavaParam javaParam = (JavaParam) javaParamList.get(i);
311       generatePstmtSet(str, javaParam, i + 1);
312     }
313     return str.toString();
314   }
315 
316   /***
317    * Generates one PreparedStatement.setX piece of code.
318    */
319   public static void generatePstmtSet(StringBuffer str, JavaParam javaParam, int position) {
320     if (!isBaseType(javaParam.getType())) {
321       str.append("        pstmt.set" + Utils.mapTypeToMethod(javaParam.getType()));
322       str.append("(" + position + ", " + javaParam.getName() + ");\n");
323     } else {
324       str.append("        if (" + javaParam.getName() + " != null) {\n");
325       str.append("          pstmt.set" + Utils.mapTypeToMethod(javaParam.getType()));
326       str.append("(" + position + ", " + javaParam.getName());
327       str.append(Utils.castMethod(javaParam.getType()));
328       str.append(");\n");
329       str.append("        } else {\n");
330       str.append("          pstmt.setNull(" + position + ", ");
331       str.append(Utils.getSQLType(javaParam.getType()));
332       str.append(");\n");
333       str.append("        }\n");
334     }
335   }
336 
337   /***
338    * Returns a methodName created by concatenating and capitalizing the given arguments.
339    */
340   public static String createMethodName(String prefix, String className, String suffix) {
341     if (prefix == null) {
342       prefix = "";
343     }
344     if (className == null) {
345       className = "";
346     }
347     if (suffix == null) {
348       suffix = "";
349     }
350     return prefix + className + capitalize(suffix);
351   }
352   
353   /***
354    * Returns a getter-method call for the given name.
355    */
356   public static String getter(String name) {
357     return "get" + capitalize(name) + "()";
358   }
359 
360   /***
361    * Escapes all HTML reserved chars.
362    *
363    * @param value the String to protect
364    * @return a value of type 'String'
365    */
366   public static String protectHTML(String value) {
367     if (value == null) {
368       return "";
369     }
370     boolean hasBadChar = false;
371     for (int i = 0, length = value.length(); i < length; i++) {
372       switch (value.charAt(i)) {
373         case '"':
374         case '<':
375         case '>':
376         case '&':
377           hasBadChar = true;
378           break;
379       }
380       if (hasBadChar) {
381         break;
382       }
383     }
384     if (!hasBadChar) {
385       return value;
386     }
387     StringBuffer sBuf = new StringBuffer();
388     for (int i = 0, length = value.length(); i < length; i++) {
389       char ch = value.charAt(i);
390       switch (ch) {
391         case '"':
392           sBuf.append("&quot;");
393           break;
394         case '<':
395           sBuf.append("&lt;");
396           break;
397         case '>':
398           sBuf.append("&gt;");
399           break;
400         case '&':
401           sBuf.append("&amp;");
402           break;
403         default:
404           sBuf.append(ch);
405       }
406     }
407     return sBuf.toString();
408   }
409 
410   /***
411    * Creates a fragment containing initialization of PreparedStatement.
412    * 
413    * @param query to pass as a method argument
414    * @return a fragment containing initialization of PreparedStatement
415    */
416   public static String createPreparedStatement(String query) {
417     String formattedQuery = equalLengthSplit(query);
418     if (containsRawParam(query)) {
419       return "      PreparedStatement pstmt = EnhancedStatement.getInstance(con, " + formattedQuery + ");\n";
420     } else {
421       return "      PreparedStatement pstmt = con.prepareStatement(" + formattedQuery + ");\n";
422     }
423   }
424 
425   /***
426    * Returns true if the given String contains '??' marker.
427    * 
428    * @param query the query to check
429    * @return true if the given String contains '??' marker
430    */
431   public static boolean containsRawParam(String query) {
432     return ((query != null) && (query.indexOf("??") != -1));
433   }
434   
435 }
436 
437 /***
438  * $Log: Utils.java,v $
439  * Revision 1.15  2004/09/27 10:36:47  milosz
440  * formatSqlListWithTablePrefix: method scope narrowed to private.
441  *
442  * Revision 1.14  2004/09/10 16:12:24  milosz
443  * createPreparedStatement and containsRawParam methods added.
444  *
445  * Revision 1.13  2003/09/10 07:30:51  milosz
446  * One version of generatePstmtSet removed.
447  *
448  * Revision 1.12  2003/09/09 13:23:13  milosz
449  * Some methods adjusted to support newly added operations/call element.
450  *
451  * Revision 1.11  2003/09/02 10:51:08  milosz
452  * equalLengthSplit method changed to return a two quotes String when an empty String passed.
453  *
454  * Revision 1.10  2003/09/02 10:14:16  milosz
455  * equalLengthSplit method added and used in some places.
456  *
457  * Revision 1.9  2003/05/28 13:10:09  milosz
458  * Support for 'from' attribute added in 'sql-query' element.
459  *
460  * Revision 1.8  2003/05/26 08:36:03  pikus
461  * cleanup imports
462  *
463  * Revision 1.7  2003/03/27 16:20:17  milosz
464  * createMethodName method added.
465  *
466  * Revision 1.6  2002/12/05 09:37:07  milosz
467  * protectHTML method added.
468  *
469  * Revision 1.5  2002/12/03 11:09:20  milosz
470  * operations/count element added.
471  *
472  * Revision 1.4  2002/12/02 14:28:13  milosz
473  * operations/delete element added.
474  *
475  * Revision 1.3  2002/11/20 09:18:25  wswiatek
476  * Changed oracle.sql.ARRAY to java.sql.Array
477  *
478  * Revision 1.2  2002/11/04 07:31:32  wswiatek
479  * Added oracle.sql.ARRAY type
480  *
481  * Revision 1.1  2002/10/04 13:07:22  milosz
482  * Reaching old mapping's functionality.
483  *
484  */
485