File: BigDecimalHandler.java

package info (click to toggle)
derby 10.14.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 78,740 kB
  • sloc: java: 691,931; sql: 42,686; xml: 20,511; sh: 3,373; sed: 96; makefile: 46
file content (348 lines) | stat: -rw-r--r-- 12,430 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/*

Derby - Class org.apache.derbyTesting.junit.BigDecimalHandler

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/
package org.apache.derbyTesting.junit;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.math.BigDecimal;
import java.lang.reflect.*;

/**
 *  BigDecimalHandler provides wrappers for JDBC API methods which use BigDecimal.
 *  When writing tests which use BigDecimal, the methods in this class can be called
 *  instead of directly calling JDBC methods. This way the same test can be used in JVMs 
 *  like J2ME/CDC/Foundation Profile 1.0, which do not have BigDecimal class, or
 *  JSR169 Profile, which does not support method calls using BigDecimal (such 
 *  as ResultSet.getBigDecimal(..).
 *  
 * 
 *
 */
public class BigDecimalHandler {
	
	public static int representation;
	public static final int STRING_REPRESENTATION = 1;
	public static final int BIGDECIMAL_REPRESENTATION = 2;
	
	static{
		try{
			Class.forName("java.math.BigDecimal");
			representation = BIGDECIMAL_REPRESENTATION;
			// This class will attempt calls to ResultSet.getBigDecimal,
			// which may not be available with jvms that support JSR169,
			// even if BigDecimal itself has been made available (e.g. 
			// supporting J2ME/CDC/Foundation Profile 1.1).
			Method getbd = ResultSet.class.getMethod("getBigDecimal", new Class[] {int.class});
			representation = BIGDECIMAL_REPRESENTATION;
		}
		catch(ClassNotFoundException e){
			//Used for J2ME/Foundation
			representation = STRING_REPRESENTATION;
		}
		catch(NoSuchMethodException e){
			//Used for J2ME/Foundation
			representation = STRING_REPRESENTATION;
		}

	}
	
	//Type conversions supported by ResultSet getBigDecimal method - JDBC3.0 Table B-6 
	private static final int[] bdConvertibleTypes = 
	{	java.sql.Types.TINYINT,
		java.sql.Types.SMALLINT,
		java.sql.Types.INTEGER,
		java.sql.Types.BIGINT,
		java.sql.Types.REAL,
		java.sql.Types.FLOAT,
		java.sql.Types.DOUBLE,
		java.sql.Types.DECIMAL,
		java.sql.Types.NUMERIC,
		java.sql.Types.BIT,
		//java.sql.Types.BOOLEAN,	//Not supported in jdk13
		java.sql.Types.CHAR,
		java.sql.Types.VARCHAR,
		java.sql.Types.LONGVARCHAR
	};
	
	/** This method is a wrapper for the ResultSet method getBigDecimal(int columnIndex).
	 * 
	 * @param rs ResultSet 
	 * @param columnIndex Column Index 
	 * @return String value of getXXX(columnIndex)method on the ResultSet
	 * @throws SQLException
	 */
	public static String getBigDecimalString(ResultSet rs, int columnIndex) throws SQLException{
		String bigDecimalString=null;
		
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				//Call toString() only for non-null values, else return null
				if(rs.getBigDecimal(columnIndex) != null)
					bigDecimalString = rs.getBigDecimal(columnIndex).toString();
				break;
			case STRING_REPRESENTATION:
				bigDecimalString = rs.getString(columnIndex);
				int columnType= rs.getMetaData().getColumnType(columnIndex);
				if((bigDecimalString != null) && !canConvertToDecimal(columnType))
					throw new SQLException("Invalid data conversion. Method not called.");
				break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
		return bigDecimalString;
	}
	
	/** This method is a wrapper for ResultSet method getBigDecimal(String columnName).
	 * 
	 * @param rs ResultSet
	 * @param columnName Column Name
	 * @param columnIndex Coulumn Index
	 * @return String value of getXXX(columnName)method on the ResultSet
	 * @throws SQLException
	 */
	public static String getBigDecimalString(ResultSet rs, String columnName, int columnIndex) throws SQLException{
		String bigDecimalString = null;
				
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				//Call toString() only for non-null values, else return null
				if(rs.getBigDecimal(columnName) != null){
					bigDecimalString = rs.getBigDecimal(columnName).toString();
				}
				break;
			case STRING_REPRESENTATION:
				bigDecimalString = rs.getString(columnName);
				int columnType= rs.getMetaData().getColumnType(columnIndex);
				if((bigDecimalString != null) && !canConvertToDecimal(columnType))
					throw new SQLException("Invalid data conversion. Method not called.");
				break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
		return bigDecimalString;
	}
	
	/** This method is a wrapper for ResultSet method getObject(int columnIndex) 
	 * 
	 * @param rs ResultSet
	 * @param columnIndex ColumnIndex
	 * @return String value of getXXX(columnIndex) method on the ResultSet
	 * @throws SQLException
	 */
	public static String getObjectString(ResultSet rs, int columnIndex) throws SQLException{
		String objectString = null;
		
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				//Call toString() only for non-null values, else return null
				if(rs.getObject(columnIndex) != null)
					objectString = rs.getObject(columnIndex).toString();
				break;
			case STRING_REPRESENTATION:
				int columnType= rs.getMetaData().getColumnType(columnIndex);
				if(columnType == java.sql.Types.DECIMAL){
					objectString = rs.getString(columnIndex);
				}	
				else
					//Call toString() only for non-null values, else return null
					if(rs.getObject(columnIndex) != null)
						objectString = rs.getObject(columnIndex).toString();
					break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
		return objectString;
	}	
	
	/** This method is a wrapper for ResultSet method getObject(String columnName)
	 * @param rs ResultSet
	 * @param columnName Column Name
	 * @param columnIndex Column Index
	 * @return String value of getXXX(columnName) method on the ResultSet
	 * @throws SQLException
	 */
	public static String getObjectString(ResultSet rs, String columnName, int columnIndex) throws SQLException{
		String objectString = null;
				
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				//Call toString() only for non-null values, else return null
				if(rs.getObject(columnName) != null)
					objectString = rs.getObject(columnName).toString();
				break;
			case STRING_REPRESENTATION:
				int columnType= rs.getMetaData().getColumnType(columnIndex);
				if(columnType == java.sql.Types.DECIMAL){
					objectString = rs.getString(columnName);
				}	
				else
					//Call toString() only for non-null values, else return null					
					if(rs.getObject(columnName) != null)
						objectString = rs.getObject(columnName).toString();
					break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
		return objectString;
	}
	
	/** This method is a wrapper for ResultSet method 
	 * updateBigDecimal(int columnIndex, BigDecimal x)
	 * @param rs ResultSet
	 * @param columnIndex Column Index
	 * @param bdString String to be used in updateXXX method
	 * @throws SQLException
	 */
	public static void updateBigDecimalString(ResultSet rs, int columnIndex, String bdString) throws SQLException{
				
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				BigDecimal bd = (bdString == null) ? null : new BigDecimal(bdString);
				rs.updateBigDecimal(columnIndex, bd);
				break;
			case STRING_REPRESENTATION:
				rs.updateString(columnIndex, bdString);
				break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
	}
	
	/** This method is a wrapper for ResultSet method 
	 * updateBigDecimal(String columnName, BigDecimal x)
	 * @param rs ResultSet
	 * @param columnName Column Name
	 * @param bdString String to be used in updateXXX method
	 * @throws SQLException
	 */
	public static void updateBigDecimalString(ResultSet rs, String columnName,String bdString) throws SQLException{
				
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				BigDecimal bd = (bdString == null) ? null : new BigDecimal(bdString);
				rs.updateBigDecimal(columnName, bd);
				break;
			case STRING_REPRESENTATION:
				rs.updateString(columnName, bdString);
				break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
	}

	/** This method is a wrapper for the CallableStatement method getBigDecimal(int parameterIndex).
	 * The wrapper method needs the parameterType as an input since ParameterMetaData is not available in JSR169.
	 * 
	 * @param cs CallableStatement 
	 * @param parameterIndex Parameter Index
	 * @param parameterType Parameter Type
	 * @return String value of getXXX(parameterIndex)method on the CallableStatement
	 * @throws SQLException
	 */
	public static String getBigDecimalString(CallableStatement cs, int parameterIndex, int parameterType) throws SQLException{
		String bigDecimalString = null;
		
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				//Call toString() only for non-null values, else return null
				if(cs.getBigDecimal(parameterIndex) != null)
					bigDecimalString = cs.getBigDecimal(parameterIndex).toString();
				break;
			case STRING_REPRESENTATION:
				bigDecimalString = cs.getString(parameterIndex);
				if((bigDecimalString != null) && !canConvertToDecimal(parameterType))
					throw new SQLException("Invalid data conversion. Method not called.");
				break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
		return bigDecimalString;
	}	

	/** This method is a wrapper for the PreparedStatement method setBigDecimal(int parameterIndex,BigDecimal x)
	 * 
	 * @param ps PreparedStatement 
	 * @param parameterIndex Parameter Index
	 * @param bdString String to be used in setXXX method
	 * @throws SQLException
	 */
	public static void setBigDecimalString(PreparedStatement ps, int parameterIndex, String bdString) throws SQLException{
		
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				BigDecimal bd = (bdString == null) ? null : new BigDecimal(bdString);
				ps.setBigDecimal(parameterIndex, bd);
				break;
			case STRING_REPRESENTATION:
				//setString is used since setBigDecimal is not available in JSR169
				//If bdString cannot be converted to short,int or long, this will throw
				//"Invalid character string format exception" 
				ps.setString(parameterIndex,bdString);
				break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
	}
	
	/** This method is a wrapper for the PreparedStatement method setObject(int parameterIndex, Object x) 
	 * 
	 * @param ps PreparedStatement 
	 * @param parameterIndex Parameter Index
	 * @param objectString String to be used in setObject method
	 * @throws SQLException
	 */
	public static void setObjectString(PreparedStatement ps, int parameterIndex, String objectString) throws SQLException{
		
		switch(representation){
			case BIGDECIMAL_REPRESENTATION:
				BigDecimal bd = (objectString == null) ? null : new BigDecimal(objectString);
				ps.setObject(parameterIndex,bd);
				break;
			case STRING_REPRESENTATION:
				ps.setObject(parameterIndex,objectString);
				break;
			default:	
				new Exception("Failed: Invalid Big Decimal representation").printStackTrace();
		}
	}	
	
	/** This method checks that the SQL type can be converted to Decimal
	 * 
	 * @param type the SQL type to check
	 * @return true if the SQL type is convertible to DECIMAL, false otherwise.
	 * @throws SQLException
	 */
	protected static boolean canConvertToDecimal(int type) throws SQLException{
		boolean  canConvert = false;
		
		for (int bdType = 0; bdType < bdConvertibleTypes.length; bdType++){
			if(type == bdConvertibleTypes[bdType]){
				canConvert = true;
				break;
			}
		}
		
		return canConvert;
	}
	
}