KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > persist > NoTableMapping


1 // $Id$
2

3 package net.sf.persist;
4
5 import java.lang.reflect.Method JavaDoc;
6 import java.util.HashMap JavaDoc;
7 import java.util.Map JavaDoc;
8 import java.util.Set JavaDoc;
9
10 /**
11  * Represents the mapping of columns to getters and setters of a POJO.
12  * <p>
13  * It is used when a class specifies a
14  * {@link net.sf.persist.annotations.NoTable NoTable} annotation, which means
15  * the class is not mapped to a table in the database, and will be only used to
16  * store data from queries.
17  */

18 public class NoTableMapping extends Mapping {
19
20     // POJO class
21
private final Class JavaDoc objectClass;
22
23     // map field names to setters
24
private final Map JavaDoc<String JavaDoc, Method JavaDoc> settersMap;
25
26     // map field names to getters
27
private final Map JavaDoc<String JavaDoc, Method JavaDoc> gettersMap;
28
29     // map possible column names to field names
30
private final Map JavaDoc<String JavaDoc, String JavaDoc> columnsMap;
31
32     public NoTableMapping(Class JavaDoc objectClass, NameGuesser nameGuesser) {
33
34         checkAnnotation(objectClass);
35
36         this.objectClass = objectClass;
37
38         // get the list of annotations, getters and setters
39
Map JavaDoc[] fieldsMaps = Mapping.getFieldsMaps(objectClass);
40         final Map JavaDoc<String JavaDoc, net.sf.persist.annotations.Column> annotationsMap = fieldsMaps[0];
41         gettersMap = fieldsMaps[1];
42         settersMap = fieldsMaps[2];
43
44         // create columns map by iterating through all fields in the object
45
// class
46
// if a field has a @Column annotation, use it, otherwise add all
47
// guessed names for the field in the map
48
columnsMap = new HashMap JavaDoc();
49         for (String JavaDoc fieldName : gettersMap.keySet()) {
50
51             net.sf.persist.annotations.Column annotation = annotationsMap.get(fieldName);
52
53             // autoGenerated is not supported on @NoTable mappings
54
if (annotation != null) {
55                 if (annotation.autoGenerated() == true) {
56                     throw new RuntimeSQLException("@Column(autoGenerated=true) is set for field [" + fieldName
57                             + "] of class [" + objectClass.getCanonicalName()
58                             + " which has been declared with @NoTable");
59                 }
60             }
61
62             // if there's a column name specified in the annotation, use it
63
if (annotation != null && annotation.name() != null) {
64
65                 // check if the column name is blank
66
if (annotation.name().trim().equals("")) {
67                     throw new RuntimeSQLException("@Column annotation for field [" + fieldName + "] of class ["
68                             + objectClass.getCanonicalName() + "] defines a blank column name");
69                 }
70
71                 // check for name conflicts
72
checkNameConflicts(fieldName, annotation.name());
73
74                 // add to map
75
columnsMap.put(annotation.name(), fieldName);
76             }
77
78             else { // no annotation, add all guessed column names for the field
79

80                 Set JavaDoc<String JavaDoc> guessedColumns = nameGuesser.guessColumn(fieldName);
81                 for (String JavaDoc guessedColumn : guessedColumns) {
82
83                     // check for name conflicts
84
checkNameConflicts(fieldName, guessedColumn);
85
86                     // add to map
87
columnsMap.put(guessedColumn, fieldName);
88                 }
89             }
90         }
91
92     }
93
94     /**
95      * Returns the field name associated with a given column. If a mapping can't
96      * be found, will throw a RuntimeSQLException.
97      */

98     public String JavaDoc getFieldNameForColumn(String JavaDoc columnName) {
99         String JavaDoc fieldName = columnsMap.get(columnName);
100         if (fieldName == null) {
101             throw new RuntimeSQLException("Could map field for column [" + columnName + "] on class ["
102                     + objectClass.getCanonicalName()
103                     + "]. Please specify an explict @Column annotation for that column.");
104         }
105         return fieldName;
106     }
107
108     /**
109      * Returns the setter method associated with a given column. If a mapping
110      * can't be found, will throw a RuntimeSQLException.
111      *
112      * @see Mapping
113      */

114     public Method JavaDoc getSetterForColumn(String JavaDoc columnName) {
115         String JavaDoc fieldName = getFieldNameForColumn(columnName);
116         return settersMap.get(fieldName);
117     }
118
119     /**
120      * Returns the getter method associated with a given column. If a mapping
121      * can't be found, will throw a RuntimeSQLException.
122      *
123      * @see Mapping
124      */

125     public Method JavaDoc getGetterForColumn(String JavaDoc columnName) {
126         String JavaDoc fieldName = getFieldNameForColumn(columnName);
127         return gettersMap.get(fieldName);
128     }
129
130     /**
131      * Checks if a given column name conflicts with an existing name in the
132      * columns map.
133      */

134     private void checkNameConflicts(String JavaDoc fieldName, String JavaDoc column) {
135         String JavaDoc existingFieldName = columnsMap.get(column);
136         if (existingFieldName != null) {
137             throw new RuntimeSQLException("Fields [" + fieldName + "] and [" + existingFieldName
138                             + "] have conflicting column name [" + column
139                             + "] either from guessed names or anotations. "
140                             + "Please specify @Column mappings for at least one of those fields");
141         }
142     }
143
144     /**
145      * Checks if {@link net.sf.persist.annotations.NoTable NoTable} is present
146      * and if a conflicting {@link net.sf.persist.annotations.Table Table} is
147      * not present.
148      */

149     private void checkAnnotation(Class JavaDoc objectClass) {
150         // get @NoTable annotation
151
final net.sf.persist.annotations.NoTable noTableAnnotation = (net.sf.persist.annotations.NoTable) objectClass
152                 .getAnnotation(net.sf.persist.annotations.NoTable.class);
153
154         // check if annotation is set
155
if (noTableAnnotation == null) {
156             throw new RuntimeSQLException("Class [" + objectClass.getCanonicalName()
157                     + "] does not specify a @NoTable annotation therefore it can't be mapped through NoTableMapping");
158         }
159
160         // check for conflicting @Table annotation
161
final net.sf.persist.annotations.Table tableAnnotation = (net.sf.persist.annotations.Table) objectClass
162                 .getAnnotation(net.sf.persist.annotations.Table.class);
163
164         if (tableAnnotation != null) {
165             throw new RuntimeSQLException("Class [" + objectClass.getCanonicalName()
166                     + "] specifies conflicting @Table and @NoTable annotations");
167         }
168     }
169
170 }
171
Popular Tags