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 -> 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(""");
393 break;
394 case '<':
395 sBuf.append("<");
396 break;
397 case '>':
398 sBuf.append(">");
399 break;
400 case '&':
401 sBuf.append("&");
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