View Javadoc
1   /**
2    *    Copyright 2006-2016 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.mybatis.generator.internal.types;
17  
18  import java.math.BigDecimal;
19  import java.sql.Types;
20  import java.util.Date;
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Properties;
25  
26  import org.mybatis.generator.api.IntrospectedColumn;
27  import org.mybatis.generator.api.JavaTypeResolver;
28  import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
29  import org.mybatis.generator.config.Context;
30  import org.mybatis.generator.config.PropertyRegistry;
31  import org.mybatis.generator.internal.util.StringUtility;
32  
33  /**
34   * 
35   * @author Jeff Butler
36   */
37  public class JavaTypeResolverDefaultImpl implements JavaTypeResolver {
38  
39      protected List<String> warnings;
40  
41      protected Properties properties;
42  
43      protected Context context;
44  
45      protected boolean forceBigDecimals;
46  
47      protected Map<Integer, JdbcTypeInformation> typeMap;
48      
49      public JavaTypeResolverDefaultImpl() {
50          super();
51          properties = new Properties();
52          typeMap = new HashMap<Integer, JdbcTypeInformation>();
53  
54          typeMap.put(Types.ARRAY, new JdbcTypeInformation("ARRAY", //$NON-NLS-1$
55                  new FullyQualifiedJavaType(Object.class.getName())));
56          typeMap.put(Types.BIGINT, new JdbcTypeInformation("BIGINT", //$NON-NLS-1$
57                  new FullyQualifiedJavaType(Long.class.getName())));
58          typeMap.put(Types.BINARY, new JdbcTypeInformation("BINARY", //$NON-NLS-1$
59                  new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
60          typeMap.put(Types.BIT, new JdbcTypeInformation("BIT", //$NON-NLS-1$
61                  new FullyQualifiedJavaType(Boolean.class.getName())));
62          typeMap.put(Types.BLOB, new JdbcTypeInformation("BLOB", //$NON-NLS-1$
63                  new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
64          typeMap.put(Types.BOOLEAN, new JdbcTypeInformation("BOOLEAN", //$NON-NLS-1$
65                  new FullyQualifiedJavaType(Boolean.class.getName())));
66          typeMap.put(Types.CHAR, new JdbcTypeInformation("CHAR", //$NON-NLS-1$
67                  new FullyQualifiedJavaType(String.class.getName())));
68          typeMap.put(Types.CLOB, new JdbcTypeInformation("CLOB", //$NON-NLS-1$
69                  new FullyQualifiedJavaType(String.class.getName())));
70          typeMap.put(Types.DATALINK, new JdbcTypeInformation("DATALINK", //$NON-NLS-1$
71                  new FullyQualifiedJavaType(Object.class.getName())));
72          typeMap.put(Types.DATE, new JdbcTypeInformation("DATE", //$NON-NLS-1$
73                  new FullyQualifiedJavaType(Date.class.getName())));
74          typeMap.put(Types.DECIMAL, new JdbcTypeInformation("DECIMAL", //$NON-NLS-1$
75                  new FullyQualifiedJavaType(BigDecimal.class.getName())));
76          typeMap.put(Types.DISTINCT, new JdbcTypeInformation("DISTINCT", //$NON-NLS-1$
77                  new FullyQualifiedJavaType(Object.class.getName())));
78          typeMap.put(Types.DOUBLE, new JdbcTypeInformation("DOUBLE", //$NON-NLS-1$
79                  new FullyQualifiedJavaType(Double.class.getName())));
80          typeMap.put(Types.FLOAT, new JdbcTypeInformation("FLOAT", //$NON-NLS-1$
81                  new FullyQualifiedJavaType(Double.class.getName())));
82          typeMap.put(Types.INTEGER, new JdbcTypeInformation("INTEGER", //$NON-NLS-1$
83                  new FullyQualifiedJavaType(Integer.class.getName())));
84          typeMap.put(Types.JAVA_OBJECT, new JdbcTypeInformation("JAVA_OBJECT", //$NON-NLS-1$
85                  new FullyQualifiedJavaType(Object.class.getName())));
86          typeMap.put(Types.LONGNVARCHAR, new JdbcTypeInformation("LONGNVARCHAR", //$NON-NLS-1$
87                  new FullyQualifiedJavaType(String.class.getName())));
88          typeMap.put(Types.LONGVARBINARY, new JdbcTypeInformation(
89                  "LONGVARBINARY", //$NON-NLS-1$
90                  new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
91          typeMap.put(Types.LONGVARCHAR, new JdbcTypeInformation("LONGVARCHAR", //$NON-NLS-1$
92                  new FullyQualifiedJavaType(String.class.getName())));
93          typeMap.put(Types.NCHAR, new JdbcTypeInformation("NCHAR", //$NON-NLS-1$
94                  new FullyQualifiedJavaType(String.class.getName())));
95          typeMap.put(Types.NCLOB, new JdbcTypeInformation("NCLOB", //$NON-NLS-1$
96                  new FullyQualifiedJavaType(String.class.getName())));
97          typeMap.put(Types.NVARCHAR, new JdbcTypeInformation("NVARCHAR", //$NON-NLS-1$
98                  new FullyQualifiedJavaType(String.class.getName())));
99          typeMap.put(Types.NULL, new JdbcTypeInformation("NULL", //$NON-NLS-1$
100                 new FullyQualifiedJavaType(Object.class.getName())));
101         typeMap.put(Types.NUMERIC, new JdbcTypeInformation("NUMERIC", //$NON-NLS-1$
102                 new FullyQualifiedJavaType(BigDecimal.class.getName())));
103         typeMap.put(Types.OTHER, new JdbcTypeInformation("OTHER", //$NON-NLS-1$
104                 new FullyQualifiedJavaType(Object.class.getName())));
105         typeMap.put(Types.REAL, new JdbcTypeInformation("REAL", //$NON-NLS-1$
106                 new FullyQualifiedJavaType(Float.class.getName())));
107         typeMap.put(Types.REF, new JdbcTypeInformation("REF", //$NON-NLS-1$
108                 new FullyQualifiedJavaType(Object.class.getName())));
109         typeMap.put(Types.SMALLINT, new JdbcTypeInformation("SMALLINT", //$NON-NLS-1$
110                 new FullyQualifiedJavaType(Short.class.getName())));
111         typeMap.put(Types.STRUCT, new JdbcTypeInformation("STRUCT", //$NON-NLS-1$
112                 new FullyQualifiedJavaType(Object.class.getName())));
113         typeMap.put(Types.TIME, new JdbcTypeInformation("TIME", //$NON-NLS-1$
114                 new FullyQualifiedJavaType(Date.class.getName())));
115         typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP", //$NON-NLS-1$
116                 new FullyQualifiedJavaType(Date.class.getName())));
117         typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT", //$NON-NLS-1$
118                 new FullyQualifiedJavaType(Byte.class.getName())));
119         typeMap.put(Types.VARBINARY, new JdbcTypeInformation("VARBINARY", //$NON-NLS-1$
120                 new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
121         typeMap.put(Types.VARCHAR, new JdbcTypeInformation("VARCHAR", //$NON-NLS-1$
122                 new FullyQualifiedJavaType(String.class.getName())));
123     }
124 
125     public void addConfigurationProperties(Properties properties) {
126         this.properties.putAll(properties);
127         forceBigDecimals = StringUtility
128                 .isTrue(properties
129                         .getProperty(PropertyRegistry.TYPE_RESOLVER_FORCE_BIG_DECIMALS));
130     }
131 
132     public FullyQualifiedJavaType calculateJavaType(
133             IntrospectedColumn introspectedColumn) {
134         FullyQualifiedJavaType answer = null;
135         JdbcTypeInformation jdbcTypeInformation = typeMap
136                 .get(introspectedColumn.getJdbcType());
137 
138         if (jdbcTypeInformation != null) {
139             answer = jdbcTypeInformation.getFullyQualifiedJavaType();
140             answer = overrideDefaultType(introspectedColumn, answer);
141         }
142 
143         return answer;
144     }
145     
146     protected FullyQualifiedJavaType overrideDefaultType(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
147         FullyQualifiedJavaType answer = defaultType;
148         
149         switch (column.getJdbcType()) {
150         case Types.BIT:
151             answer = calculateBitReplacement(column, defaultType);
152             break;
153         case Types.DECIMAL:
154         case Types.NUMERIC:
155             answer = calculateBigDecimalReplacement(column, defaultType);
156             break;
157         }
158 
159         return answer;
160     }
161     
162     protected FullyQualifiedJavaType calculateBitReplacement(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
163         FullyQualifiedJavaType answer;
164         
165         if (column.getLength() > 1) {
166             answer = new FullyQualifiedJavaType("byte[]"); //$NON-NLS-1$
167         } else {
168             answer = defaultType;
169         }
170         
171         return answer;
172     }
173     
174     protected FullyQualifiedJavaType calculateBigDecimalReplacement(IntrospectedColumn column, FullyQualifiedJavaType defaultType) {
175         FullyQualifiedJavaType answer;
176         
177         if (column.getScale() > 0 || column.getLength() > 18 || forceBigDecimals) {
178             answer = defaultType;
179         } else if (column.getLength() > 9) {
180             answer = new FullyQualifiedJavaType(Long.class.getName());
181         } else if (column.getLength() > 4) {
182             answer = new FullyQualifiedJavaType(Integer.class.getName());
183         } else {
184             answer = new FullyQualifiedJavaType(Short.class.getName());
185         }
186         
187         return answer;
188     }
189 
190     public String calculateJdbcTypeName(IntrospectedColumn introspectedColumn) {
191         String answer = null;
192         JdbcTypeInformation jdbcTypeInformation = typeMap
193                 .get(introspectedColumn.getJdbcType());
194 
195         if (jdbcTypeInformation != null) {
196             answer = jdbcTypeInformation.getJdbcTypeName();
197         }
198 
199         return answer;
200     }
201 
202     public void setWarnings(List<String> warnings) {
203         this.warnings = warnings;
204     }
205 
206     public void setContext(Context context) {
207         this.context = context;
208     }
209 
210     public static class JdbcTypeInformation {
211         private String jdbcTypeName;
212 
213         private FullyQualifiedJavaType fullyQualifiedJavaType;
214 
215         public JdbcTypeInformation(String jdbcTypeName,
216                 FullyQualifiedJavaType fullyQualifiedJavaType) {
217             this.jdbcTypeName = jdbcTypeName;
218             this.fullyQualifiedJavaType = fullyQualifiedJavaType;
219         }
220 
221         public String getJdbcTypeName() {
222             return jdbcTypeName;
223         }
224 
225         public FullyQualifiedJavaType getFullyQualifiedJavaType() {
226             return fullyQualifiedJavaType;
227         }
228     }
229 }