/*

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;
	}
	
}
