KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > plugins > cmp > jdbc > metadata > JDBCTypeMappingMetaData


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb.plugins.cmp.jdbc.metadata;
23
24 import java.util.HashMap JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.Collection JavaDoc;
27
28 import org.jboss.deployment.DeploymentException;
29 import org.jboss.metadata.MetaData;
30 import org.w3c.dom.Element JavaDoc;
31
32 /**
33  * Imutable class which holds a map between Java Classes and JDBCMappingMetaData.
34  *
35  * @author <a HREF="mailto:dain@daingroup.com">Dain Sundstrom</a>
36  * @author <a HREF="sebastien.alborini@m4x.org">Sebastien Alborini</a>
37  * @author <a HREF="mailto:loubyansky@ua.fm">Alex Loubyansky</a>
38  * @version $Revision: 41848 $
39  */

40 public final class JDBCTypeMappingMetaData
41 {
42    private static final String JavaDoc[] PRIMITIVES = {
43       "boolean", "byte", "char", "short", "int", "long", "float", "double"
44    };
45
46    private static final String JavaDoc[] PRIMITIVE_CLASSES = {
47       "java.lang.Boolean", "java.lang.Byte", "java.lang.Character",
48       "java.lang.Short", "java.lang.Integer", "java.lang.Long",
49       "java.lang.Float", "java.lang.Double"
50    };
51
52    public static final String JavaDoc CONCAT = "concat";
53    public static final String JavaDoc SUBSTRING = "substring";
54    public static final String JavaDoc LCASE = "lcase";
55    public static final String JavaDoc UCASE = "ucase";
56    public static final String JavaDoc LENGTH = "length";
57    public static final String JavaDoc LOCATE = "locate";
58    public static final String JavaDoc ABS = "abs";
59    public static final String JavaDoc SQRT = "sqrt";
60    public static final String JavaDoc COUNT = "count";
61
62    public static JDBCFunctionMappingMetaData COUNT_FUNC;
63    public static JDBCFunctionMappingMetaData MAX_FUNC;
64    public static JDBCFunctionMappingMetaData MIN_FUNC;
65    public static JDBCFunctionMappingMetaData AVG_FUNC;
66    public static JDBCFunctionMappingMetaData SUM_FUNC;
67    public static JDBCFunctionMappingMetaData MOD_FUNC;
68
69    static
70    {
71       try
72       {
73          COUNT_FUNC = new JDBCFunctionMappingMetaData("count", "count(?1 ?2)");
74          MAX_FUNC = new JDBCFunctionMappingMetaData("max", "max(?1 ?2)");
75          MIN_FUNC = new JDBCFunctionMappingMetaData("min", "min(?1 ?2)");
76          AVG_FUNC = new JDBCFunctionMappingMetaData("avg", "avg(?1 ?2)");
77          SUM_FUNC = new JDBCFunctionMappingMetaData("sum", "sum(?1 ?2)");
78          MOD_FUNC = new JDBCFunctionMappingMetaData("mod", "mod(?1, ?2)");
79       }
80       catch(DeploymentException e)
81       {
82          throw new IllegalStateException JavaDoc(e.getMessage());
83       }
84    }
85
86    private final String JavaDoc name;
87
88    private final HashMap JavaDoc mappings = new HashMap JavaDoc();
89
90    private final HashMap JavaDoc functionMappings = new HashMap JavaDoc();
91
92    private final String JavaDoc aliasHeaderPrefix;
93    private final String JavaDoc aliasHeaderSuffix;
94    private final int aliasMaxLength;
95
96    private final boolean subquerySupported;
97
98    private final String JavaDoc trueMapping;
99    private final String JavaDoc falseMapping;
100    private final int maxKeysInDelete;
101
102    private JDBCFunctionMappingMetaData rowLocking = null;
103    private JDBCFunctionMappingMetaData fkConstraint = null;
104    private JDBCFunctionMappingMetaData pkConstraint = null;
105    private JDBCFunctionMappingMetaData autoIncrement = null;
106    private JDBCFunctionMappingMetaData addColumn = null;
107    private JDBCFunctionMappingMetaData dropColumn = null;
108    private JDBCFunctionMappingMetaData alterColumn = null;
109
110    /**
111     * Constructs a mapping with the data contained in the type-mapping xml
112     * element from a jbosscmp-jdbc xml file.
113     *
114     * @param element the xml Element which contains the metadata about
115     * this type mapping
116     * @throws DeploymentException if the xml element is not semantically correct
117     */

118    public JDBCTypeMappingMetaData(Element JavaDoc element) throws DeploymentException
119    {
120       // get the name of this type-mapping
121
name = MetaData.getUniqueChildContent(element, "name");
122
123       // row-locking (i.e., select for update)
124
String JavaDoc rowLockingSQL = MetaData.getUniqueChildContent(element, "row-locking-template");
125       if(rowLockingSQL != null && !rowLockingSQL.trim().equals(""))
126       {
127          rowLocking = new JDBCFunctionMappingMetaData("row-locking", rowLockingSQL);
128       }
129
130       // pk constraint
131
String JavaDoc pkConstraintSQL = MetaData.getUniqueChildContent(element, "pk-constraint-template");
132       if(pkConstraintSQL != null && !pkConstraintSQL.trim().equals(""))
133       {
134          pkConstraint = new JDBCFunctionMappingMetaData("pk-constraint", pkConstraintSQL);
135       }
136
137       // fk constraint
138
String JavaDoc fkConstraintSQL = MetaData.getUniqueChildContent(element, "fk-constraint-template");
139       if(fkConstraintSQL != null && !fkConstraintSQL.trim().equals(""))
140       {
141          fkConstraint = new JDBCFunctionMappingMetaData("fk-constraint", fkConstraintSQL);
142       }
143
144       // alter table templates
145
String JavaDoc alterColumnSQL = MetaData.getOptionalChildContent(element, "add-column-template");
146       if(alterColumnSQL != null && !alterColumnSQL.trim().equals(""))
147       {
148          addColumn = new JDBCFunctionMappingMetaData("add-column-template", alterColumnSQL);
149       }
150       else
151       {
152          addColumn = new JDBCFunctionMappingMetaData("add-column-template", "ALTER TABLE ?1 ADD ?2 ?3");
153       }
154       alterColumnSQL = MetaData.getOptionalChildContent(element, "alter-column-template");
155       if(alterColumnSQL != null && !alterColumnSQL.trim().equals(""))
156       {
157          alterColumn = new JDBCFunctionMappingMetaData("alter-column-template", alterColumnSQL);
158       }
159       else
160       {
161          alterColumn = new JDBCFunctionMappingMetaData("alter-column-template", "ALTER TABLE ?1 ALTER ?2 TYPE ?3");
162       }
163       alterColumnSQL = MetaData.getOptionalChildContent(element, "drop-column-template");
164       if(alterColumnSQL != null && !alterColumnSQL.trim().equals(""))
165       {
166          dropColumn = new JDBCFunctionMappingMetaData("drop-column-template", alterColumnSQL);
167       }
168       else
169       {
170          dropColumn = new JDBCFunctionMappingMetaData("drop-column-template", "ALTER TABLE ?1 DROP ?2");
171       }
172
173       // auto increment
174
// WARN: it's optional
175
String JavaDoc autoIncrementSQL = MetaData.getOptionalChildContent(element, "auto-increment-template");
176       if(autoIncrementSQL != null && !autoIncrementSQL.trim().equals(""))
177       {
178          autoIncrement = new JDBCFunctionMappingMetaData("auto-increment", autoIncrementSQL);
179       }
180
181       // get the mappings
182
Iterator JavaDoc iterator = MetaData.getChildrenByTagName(element, "mapping");
183       while(iterator.hasNext())
184       {
185          Element JavaDoc mappingElement = (Element JavaDoc)iterator.next();
186          JDBCMappingMetaData mapping = new JDBCMappingMetaData(mappingElement);
187          mappings.put(mapping.getJavaType(), mapping);
188       }
189
190       addDefaultFunctionMapping();
191
192       // get the mappings
193
Iterator JavaDoc functions = MetaData.getChildrenByTagName(element, "function-mapping");
194       while(functions.hasNext())
195       {
196          Element JavaDoc mappingElement = (Element JavaDoc)functions.next();
197          JDBCFunctionMappingMetaData functionMapping = new JDBCFunctionMappingMetaData(mappingElement);
198          functionMappings.put(functionMapping.getFunctionName().toLowerCase(), functionMapping);
199       }
200
201       aliasHeaderPrefix = MetaData.getUniqueChildContent(element, "alias-header-prefix");
202
203       aliasHeaderSuffix = MetaData.getUniqueChildContent(element, "alias-header-suffix");
204
205       String JavaDoc aliasMaxLengthString = MetaData.getUniqueChildContent(element, "alias-max-length");
206       try
207       {
208          aliasMaxLength = Integer.parseInt(aliasMaxLengthString);
209       }
210       catch(NumberFormatException JavaDoc e)
211       {
212          throw new DeploymentException("Invalid number format in " +
213             "alias-max-length " + aliasMaxLengthString + "': " + e);
214       }
215
216       String JavaDoc subquerySupportedStr = MetaData.getUniqueChildContent(element, "subquery-supported");
217       subquerySupported = Boolean.valueOf(subquerySupportedStr).booleanValue();
218       trueMapping = MetaData.getUniqueChildContent(element, "true-mapping");
219       falseMapping = MetaData.getUniqueChildContent(element, "false-mapping");
220
221       String JavaDoc str = MetaData.getOptionalChildContent(element, "max-keys-in-delete");
222       if(str != null)
223       {
224          try
225          {
226             maxKeysInDelete = Integer.parseInt(str);
227          }
228          catch(NumberFormatException JavaDoc e)
229          {
230             throw new DeploymentException("Failed to parse int value '" + str + "' for max-keys-in-delete", e);
231          }
232
233          if(maxKeysInDelete < 0)
234          {
235             throw new DeploymentException("The value of max-keys-in-delete cannot be less than 0: " + maxKeysInDelete);
236          }
237       }
238       else
239       {
240          maxKeysInDelete = 0;
241       }
242    }
243
244    /**
245     * Gets the name of this mapping. The mapping name used to differentiate this
246     * mapping from other mappings and the mapping the application used is
247     * retrieved by name.
248     * @return the name of this mapping.
249     */

250    public String JavaDoc getName()
251    {
252       return name;
253    }
254
255    /**
256     * Gets the prefix for that is used when generating an alias header. An
257     * alias header is prepended to a generated table alias to prevent name
258     * collisions. An alias header is constructed as folows:
259     * aliasHeaderPrefix + int_counter + aliasHeaderSuffix
260     *
261     * @return the prefix for alias headers
262     */

263    public String JavaDoc getAliasHeaderPrefix()
264    {
265       return aliasHeaderPrefix;
266    }
267
268    /**
269     * Gets the suffix for that is used when generating an alias header. An
270     * alias header is prepended to a generated table alias to prevent name
271     * collisions. An alias header is constructed as folows:
272     * aliasHeaderPrefix + int_counter + aliasHeaderSuffix
273     *
274     * @return the suffix for alias headers
275     */

276    public String JavaDoc getAliasHeaderSuffix()
277    {
278       return aliasHeaderSuffix;
279    }
280
281    /**
282     * Gets maximum length of a table alias.
283     * An alias is constructed as folows: aliasHeader + ejb_ql_identifier_path
284     * @return the maximum length that a table alias can be
285     */

286    public int getAliasMaxLength()
287    {
288       return aliasMaxLength;
289    }
290
291    /**
292     * Does this type mapping support subqueries?
293     */

294    public boolean isSubquerySupported()
295    {
296       return subquerySupported;
297    }
298
299    /**
300     * Gets the value to which the boolean true value in EJB-QL will be mapped.
301     */

302    public String JavaDoc getTrueMapping()
303    {
304       return trueMapping;
305    }
306
307    /**
308     * Gets the value to which the boolean false value in EJB-QL will be mapped.
309     */

310    public String JavaDoc getFalseMapping()
311    {
312       return falseMapping;
313    }
314
315    public int getMaxKeysInDelete()
316    {
317       return maxKeysInDelete;
318    }
319
320    public JDBCMappingMetaData getTypeMappingMetaData(Class JavaDoc type)
321    {
322       String JavaDoc javaType = type.getName();
323
324       // Check primitive first
325
for(int i = 0; i < PRIMITIVES.length; i++)
326       {
327          if(javaType.equals(PRIMITIVES[i]))
328          {
329             // Translate into class
330
javaType = PRIMITIVE_CLASSES[i];
331             break;
332          }
333       }
334
335       // Check other types
336
JDBCMappingMetaData mapping = (JDBCMappingMetaData)mappings.get(javaType);
337
338       // if not found, return mapping for java.lang.object
339
if(mapping == null)
340       {
341          mapping = (JDBCMappingMetaData)mappings.get("java.lang.Object");
342       }
343
344       return mapping;
345    }
346
347    public JDBCFunctionMappingMetaData getFunctionMapping(String JavaDoc name)
348    {
349       JDBCFunctionMappingMetaData funcMapping = (JDBCFunctionMappingMetaData)functionMappings.get(name.toLowerCase());
350       if(funcMapping == null)
351          throw new IllegalStateException JavaDoc("Function " + name + " is not defined for " + this.name);
352       return funcMapping;
353    }
354
355
356    /**
357     * Returns rowLocking SQL template.
358     */

359    public JDBCFunctionMappingMetaData getRowLockingTemplate()
360    {
361       return rowLocking;
362    }
363
364    /**
365     * Returns pk constraint SQL template.
366     */

367    public JDBCFunctionMappingMetaData getPkConstraintTemplate()
368    {
369       return pkConstraint;
370    }
371
372    /**
373     * Returns fk constraint SQL template.
374     */

375    public JDBCFunctionMappingMetaData getFkConstraintTemplate()
376    {
377       return fkConstraint;
378    }
379
380    /**
381     * Returns auto increment SQL template.
382     */

383    public JDBCFunctionMappingMetaData getAutoIncrementTemplate()
384    {
385       return autoIncrement;
386    }
387
388    /**
389     * Returns add column SQL template.
390     */

391    public JDBCFunctionMappingMetaData getAddColumnTemplate()
392    {
393       return addColumn;
394    }
395
396    /**
397     * Returns auto increment SQL template.
398     */

399    public JDBCFunctionMappingMetaData getDropColumnTemplate()
400    {
401       return dropColumn;
402    }
403
404    /**
405     * Returns auto increment SQL template.
406     */

407    public JDBCFunctionMappingMetaData getAlterColumnTemplate()
408    {
409       return alterColumn;
410    }
411
412    public Collection JavaDoc getMappings()
413    {
414       return mappings.values();
415    }
416
417    private void addDefaultFunctionMapping()
418    {
419       JDBCFunctionMappingMetaData function;
420
421       // concat
422
function = new JDBCFunctionMappingMetaData("concat",
423          new String JavaDoc[]{
424             "{fn concat(",
425             ", ",
426             ")}"
427          },
428          new int[]{0, 1});
429       functionMappings.put(function.getFunctionName().toLowerCase(), function);
430
431       // substring
432
function = new JDBCFunctionMappingMetaData("substring",
433          new String JavaDoc[]{
434             "{fn substring(",
435             ", ",
436             ", ",
437             ")}"
438          },
439          new int[]{0, 1, 2});
440       functionMappings.put(function.getFunctionName().toLowerCase(), function);
441
442       // lcase
443
function = new JDBCFunctionMappingMetaData("lcase",
444          new String JavaDoc[]{
445             "{fn lcase(",
446             ")}"
447          },
448          new int[]{0});
449       functionMappings.put(function.getFunctionName().toLowerCase(), function);
450
451       // ucase
452
function = new JDBCFunctionMappingMetaData("ucase",
453          new String JavaDoc[]{
454             "{fn ucase(",
455             ")}"
456          },
457          new int[]{0});
458       functionMappings.put(function.getFunctionName().toLowerCase(), function);
459
460       // length
461
function = new JDBCFunctionMappingMetaData("length",
462          new String JavaDoc[]{
463             "{fn length(",
464             ")}"
465          },
466          new int[]{0});
467       functionMappings.put(function.getFunctionName().toLowerCase(), function);
468
469       // locate
470
function = new JDBCFunctionMappingMetaData("locate",
471          new String JavaDoc[]{
472             "{fn locate(",
473             ", ",
474             ", ",
475             ")}"
476          },
477          new int[]{0, 1, 2});
478       functionMappings.put(function.getFunctionName().toLowerCase(), function);
479
480       // abs
481
function = new JDBCFunctionMappingMetaData("abs",
482          new String JavaDoc[]{
483             "{fn abs(",
484             ")}"
485          },
486          new int[]{0});
487       functionMappings.put(function.getFunctionName().toLowerCase(), function);
488
489       // sqrt
490
function = new JDBCFunctionMappingMetaData("sqrt",
491          new String JavaDoc[]{
492             "{fn sqrt(",
493             ")}"
494          },
495          new int[]{0});
496       functionMappings.put(function.getFunctionName().toLowerCase(), function);
497    }
498 }
499
Popular Tags