/*-----------------------------------------------------------------------------
 *
 * Enhydra JdbcS
 * The Initial Developer of the Original Code is Lutris Technologies Inc.
 * Portions created by Lutris are Copyright 1997-2000 Lutris Technologies Inc.
 * All Rights Reserved.
 *
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * www.enhydra.org/license/epl.html
 *
 * Software distributed under the License is distributed on an "ASIS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * -----------------------------------------------------------------------------
 * $Id$
 * -----------------------------------------------------------------------------
 */
package org.enhydra.jdbc.core;

//import java.io.*;
//import java.math.*;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.CallableStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Map;


/**
 * A very simple implementation of Statement. When created
 * it is supplied with another Statement to which all
 * of this class' methods delegate their work. 
 */
public abstract class CoreCallableStatement implements CallableStatement {
    
    // the CallableStatement which does most of the work.
    protected CallableStatement cs; 

    public Array getArray(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getArray(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public java.math.BigDecimal getBigDecimal(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getBigDecimal(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public java.math.BigDecimal getBigDecimal(int i, int scale) throws SQLException {
	preInvoke();
	try {
	    return cs.getBigDecimal(i, scale);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public Blob getBlob(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getBlob(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public boolean getBoolean(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getBoolean(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return false;
    }
    public byte getByte(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getByte(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    }
    public byte[] getBytes(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getBytes(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public Clob getClob(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getClob(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public Date getDate(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getDate(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public Date getDate(int i, java.util.Calendar cal) throws SQLException {
	preInvoke();
	try {
	    return cs.getDate(i, cal);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public double getDouble(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getDouble(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    }
    public float getFloat(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getFloat(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    }
    public int getInt(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getInt(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    }
    public long getLong(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getLong(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    }
    public Object getObject(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getObject(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public Object getObject(int i, java.util.Map map) throws SQLException {
	preInvoke();
	try {
	    return cs.getObject(i, map);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public Ref getRef(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getRef(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public short getShort(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getShort(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    }
    public java.lang.String getString(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getString(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public java.sql.Time getTime(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getTime(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public java.sql.Time getTime(int i, java.util.Calendar cal) throws SQLException {
	preInvoke();
	try {
	    return cs.getTime(i, cal);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public java.sql.Timestamp getTimestamp(int i) throws SQLException {
	preInvoke();
	try {
	    return cs.getTimestamp(i);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public java.sql.Timestamp getTimestamp(int i, java.util.Calendar cal) throws SQLException {
	preInvoke();
	try {
	    return cs.getTimestamp(i, cal);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    }
    public void registerOutParameter(int i, int sqlType) throws SQLException {
	preInvoke();
	try {
	    cs.registerOutParameter(i, sqlType);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    }
    public void registerOutParameter(int i, int sqlType, int scale) throws SQLException {
	preInvoke();
	try {
	    cs.registerOutParameter(i, sqlType, scale);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    }
    public void registerOutParameter(int i, int sqlType, String typeName) throws SQLException {
	preInvoke();
	try {
	    cs.registerOutParameter(i, sqlType, typeName);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    }
    public boolean wasNull() throws SQLException {
	preInvoke();
	try {
	    return cs.wasNull();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return false;
    }
   
    public void addBatch() throws SQLException {
	preInvoke();
	try {
	    cs.addBatch();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method addBatch
    
    public void clearParameters() throws SQLException {
	preInvoke();
	try {
	    cs.clearParameters();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method clearParameters
    
    public boolean execute() throws SQLException {
	preInvoke();
	try {
	    return cs.execute();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return false;
    } // method execute

    public ResultSet executeQuery() throws SQLException {
	preInvoke();
	try {
	    return cs.executeQuery();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method executeQuery

    public int executeUpdate() throws SQLException {
	preInvoke();
	try {
	    return cs.executeUpdate();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method executeUpdate
    
    public ResultSetMetaData getMetaData() throws SQLException {
	preInvoke();
	try {
	    return cs.getMetaData();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getMetaData
	
    public void setArray(int i,Array x) throws SQLException {
	preInvoke();
	try {
	    cs.setArray(i,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setArray

    public void setAsciiStream(int parameterIndex,InputStream x,int length) throws SQLException {
	preInvoke();
	try {
	    cs.setAsciiStream(parameterIndex,x,length);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setAsciiStream
    
    public void setBigDecimal(int parameterIndex,BigDecimal x) throws SQLException {
	preInvoke();
	try {
	    cs.setBigDecimal(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setBigDecimal
    
    public void setBinaryStream(int parameterIndex,InputStream x,int length) throws SQLException {
	preInvoke();
	try {
	    cs.setBinaryStream(parameterIndex,x,length);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setBinaryStream
    
    public void setBlob(int i,Blob x) throws SQLException {
	preInvoke();
	try {
	    cs.setBlob(i,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setBlob
    
    public void setBoolean(int parameterIndex,boolean x) throws SQLException {
	preInvoke();
	try {
	    cs.setBoolean(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setBoolean
	
    public void setByte(int parameterIndex,byte x) throws SQLException {
	preInvoke();
	try {
	    cs.setByte(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setByte
    
    public void setBytes(int parameterIndex,byte x[]) throws SQLException {
	preInvoke();
	try {
	    cs.setBytes(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setBytes

    public void setCharacterStream(int parameterIndex,Reader reader,int length) throws SQLException {
	preInvoke();
	try {
	    cs.setCharacterStream(parameterIndex,reader,length);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setCharacterStream
	
    public void setClob(int i,Clob x) throws SQLException {
	preInvoke();
	try {
	    cs.setClob(i,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setClob
    
    public void setDate(int parameterIndex,Date x) throws SQLException {
	preInvoke();
	try {
	    cs.setDate(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setDate
    
    public void setDate(int parameterIndex,Date x,Calendar cal) throws SQLException {
	preInvoke();
	try {
	    cs.setDate(parameterIndex,x,cal);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setDate
    
    public void setDouble(int parameterIndex,double x) throws SQLException {
	preInvoke();
	try {
	    cs.setDouble(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setDouble
	
    public void setFloat(int parameterIndex,float x) throws SQLException {
	preInvoke();
	try {
	    cs.setFloat(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setFloat
	
    public void setInt(int parameterIndex,int x) throws SQLException {
	preInvoke();
	try {
	    cs.setInt(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setInt

    public void setLong(int parameterIndex,long x) throws SQLException {
	preInvoke();
	try {
	    cs.setLong(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setLong

    public void setNull(int parameterIndex,int sqlType) throws SQLException {
	preInvoke();
	try {
	    cs.setNull(parameterIndex,sqlType);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setNull

    public void setNull(int paramIndex,int sqlType,String typeName) throws SQLException {
	preInvoke();
	try {
	    cs.setNull(paramIndex,sqlType,typeName);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setNull
    
    public void setObject(int parameterIndex,Object x) throws SQLException {
	preInvoke();
	try {
	    cs.setObject(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setObject

    public void setObject(int parameterIndex,Object x,int targetSqlType) throws SQLException {
	preInvoke();
	try {
	    cs.setObject(parameterIndex,x,targetSqlType);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setObject

    public void setObject(int parameterIndex,Object x,int targetSqlType,int scale) throws SQLException {
	preInvoke();
	try {
	    cs.setObject(parameterIndex,x,targetSqlType,scale);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setObject
    
    public void setRef(int i,Ref x) throws SQLException {
	preInvoke();
	try {
	    cs.setRef(i,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setRef

    public void setShort(int parameterIndex,short x) throws SQLException {
	preInvoke();
	try {
	    cs.setShort(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setShort

    public void setString(int parameterIndex,String x) throws SQLException {
	preInvoke();
	try {
	    cs.setString(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setString
    
    public void setTime(int parameterIndex,Time x) throws SQLException {
	preInvoke();
	try {
	    cs.setTime(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method 
    
    public void setTime(int parameterIndex,Time x,Calendar cal) throws SQLException  {
	preInvoke();
	try {
	    cs.setTime(parameterIndex,x,cal);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setTime

    public void setTimestamp(int parameterIndex,Timestamp x) throws SQLException {
	preInvoke();
	try {
	    cs.setTimestamp(parameterIndex,x);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setTimestamp

    public void setTimestamp(int parameterIndex,Timestamp x,Calendar cal) throws SQLException {
	preInvoke();
	try {
	    cs.setTimestamp(parameterIndex,x,cal);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setTimestamp
    
    public void setUnicodeStream(int parameterIndex,InputStream x,int length) throws SQLException {
	preInvoke();
	try {
	    cs.setUnicodeStream(parameterIndex,x,length);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setUnicodeStream


    // From Statement

    public void close() throws SQLException {
	if (cs != null) {
	    cs.close();
	}
    } // method close
    
    public int[] executeBatch() throws SQLException {
	preInvoke();
	try {
	    return cs.executeBatch();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method executeBatch

    public int getMaxFieldSize() throws SQLException {
	 preInvoke();
	 try {
	    return cs.getMaxFieldSize();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getMaxFieldSize

    public void setMaxFieldSize(int max) throws SQLException {
	preInvoke();
	try {
	    cs.setMaxFieldSize(max);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setMaxFieldSize

    public int getMaxRows() throws SQLException {
	 preInvoke();
	 try {
	    return cs.getMaxRows();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getMaxRows

    public void setMaxRows(int max) throws SQLException {
	preInvoke();
	try {
	    cs.setMaxRows(max);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setMaxRows

    public void setEscapeProcessing(boolean enable) throws SQLException {
	 preInvoke();
	 try {
	    cs.setEscapeProcessing(enable);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setEscapeProcessing

    public int getQueryTimeout() throws SQLException {
	 preInvoke();
	 try {
	    return cs.getQueryTimeout();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getQueryTimeout

    public void setQueryTimeout(int seconds) throws SQLException {
	preInvoke();
	try {
	    cs.setQueryTimeout(seconds);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setQueryTimeout
	
    public void cancel() throws SQLException {
	preInvoke();
	try {
	    cs.cancel();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method cancel
	
    public SQLWarning getWarnings() throws SQLException {
	preInvoke();
	try {
	    return cs.getWarnings();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getWarnings

    public void clearWarnings() throws SQLException {
	preInvoke();
	try {
	    cs.clearWarnings();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method clearWarnings

    public void setCursorName(String name) throws SQLException {
	preInvoke();
	try {
	    cs.setCursorName(name);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setCursorName
    
    public ResultSet getResultSet() throws SQLException {
	preInvoke();
	try {
	    return cs.getResultSet();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getResultSet

    public int getUpdateCount() throws SQLException {
	preInvoke();
	try {
	    return cs.getUpdateCount();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getUpdateCount

    public boolean getMoreResults() throws SQLException {
	preInvoke();
	try {
	    return cs.getMoreResults();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return false;
    } // method getMoreResults

    public void setFetchDirection(int direction) throws SQLException {
	preInvoke();
	try {
	    cs.setFetchDirection(direction);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setFetchDirection
    
    public int getFetchDirection() throws SQLException {
	preInvoke();
	try {
	    return cs.getFetchDirection();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getFetchDirection
	
    public void setFetchSize(int rows) throws SQLException {
	preInvoke();
	try {
	    cs.setFetchSize(rows);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method setFetchSize
	
    public int getFetchSize() throws SQLException {
	preInvoke();
	try {
	    return cs.getFetchSize();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getFetchSize
	
    public int getResultSetConcurrency() throws SQLException {
	preInvoke();
	try {
	    return cs.getResultSetConcurrency();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getResultSetConcurrency
	
    public int getResultSetType() throws SQLException {
	preInvoke();
	try {
	    return cs.getResultSetType();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method getResultSetType
	
    public Connection getConnection() throws SQLException {
	preInvoke();
	try {
	    return cs.getConnection();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method getConnection
	
    public void clearBatch() throws SQLException {
	preInvoke();
	try {
	    cs.clearBatch();
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method clearBatch
	
    public void addBatch(String s) throws SQLException {
	preInvoke();
	try {
	    cs.addBatch(s);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
    } // method addBatch
	
    public boolean execute(String s) throws SQLException {
	preInvoke();
	try {
	    return cs.execute(s);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return false;
    } // method execute
    
    public ResultSet executeQuery(String s) throws SQLException {
	preInvoke();
	try {
	    return cs.executeQuery(s);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return null;
    } // method executeQuery
    
    public int executeUpdate(String s) throws SQLException {
	preInvoke();
	try {
	    return cs.executeUpdate(s);
	} catch (SQLException e) {
	    catchInvoke(e);
	}
	return 0;
    } // method executeUpdate

    /**
     * Methods used to do some works before and during the catch
     * clause, to prevent the pool that a connection is broken.
     */
    abstract public void preInvoke() throws SQLException;
    abstract public void catchInvoke(SQLException e) throws SQLException;

}
