/* Copyright (c) 2002, Oracle Corporation. All Rights Reserved. */
package oracle.portal.sample.portalTools.devguide.jcasample;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.io.InputStream;
import java.io.Reader;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.Ref;
import java.sql.SQLException;
import java.math.BigDecimal;
import java.util.Calendar;
import java.sql.Timestamp;
import java.sql.Time;
import java.sql.SQLWarning;
import java.sql.SQLException;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.text.SimpleDateFormat;

/**
 * This class represents the returned result set from the adapter. 
 *
 * It stores the data of a row by field name and stores the list in a row. The 
 * <code>next()</code> call moves the rows to the next.
 * This class handles only values called by the field names. Oracle portal JCA
 * data source driver always asks data by field name, never by its index.
 * 
 */
public class SampleResultSet implements javax.resource.cci.ResultSet
{
  /** Row index. Starts from 0. */
  private int mRowIndex = -1;   // row index starts from 0
  
  /**
   * Data buffer of the result set. It is List of List of object values.
   * <pre>next</pre> method will iterates through the rows in the 
   * data buffer.
   */
  private List mData = new ArrayList(10); // Initial capacity 10

  /**
   * Flag to indicate last fetched valus is null. 
   * Used by <pre>wasNull</pre> method.
   */
  private boolean mWasNull = true;

  /** Current row. It is a Map of object values. */
  private Map mCurrentRow = null;

  /** Name of the record, required by the <code>Record</code> interface. */
  private String mName = "";
  /** Description of the record, required by the <code>Record</code> interface. */
  private String mShortDescription = "";

  

  //////////////////////////// Set values /////////////////////////////////////

  /**
   * Add a row to the result set. 
   * @param row A <code>Map</code> object to hold values of the fields. The 
   *            field names are the keys to the map.
   */
  public void addRow(Map row)
  {
    mData.add(row);
  }


  ///////////////////// javax.resource.cci.Record implementtaion ///////////////

  /** 
   * Get the name of the rescord.
   * @return Name of the record.
   */
  public String getRecordName()
  {
    return mName;
  }

  /** 
   * Set the name of the rescord.
   * @param name Name to set.
   */
  public void setRecordName(String name)
  {
    mName = name;
  }

  /** 
   * Get the short description of the record.
   * @return Description of the record.
   */
  public String getRecordShortDescription()
  {
    return mShortDescription;
  }

  /** 
   * Set the record's description.
   * @param descp Description to set.
   */
  public void setRecordShortDescription(String descp)
  {
    mShortDescription = descp;
  }

  /** 
   * This sample does not support this method.
   */
  public java.lang.Object clone()
    throws java.lang.CloneNotSupportedException
  {
    throw new java.lang.CloneNotSupportedException("Sample adapter does not support this method.");
  }


  ///////////////////// java.sql.ResultSet implementation /////////////////////

  /**
   *  Returns true if last fetched value was null.
   */
  public boolean wasNull() throws SQLException 
  {
    return mWasNull;
  }

  /**
   * Moves the cursor down one row from its current position.
   * ResultSet cursor is initially positioned before the first row; the
   * first call to next makes the first row the current row; the
   * second call makes the second row the current row, and so on.
   * @return True if successful to proceed to the next row. Otherwise returns
   * false.
   * @exception SQLException if the result set is already closed.
   */
  public boolean next() throws SQLException 
  {
    if (null == mData) 
      throw new SQLException("ResultSet is already closed.");
      
    int dataSize = mData.size(); 
    if ((mRowIndex + 1) >= dataSize) 
    {
      mCurrentRow = null;
      return false;
    }
    mRowIndex++;
    mCurrentRow = (Map) mData.get(mRowIndex);
    return true;
  }

  /** 
   * Get the value of the field identified by the given column name. 
   * @param columnName Name of the column.
   * @return The value of the column.
   * @exception SQLException If no row is available.
   */
  public Object getObject(String columnName) throws SQLException 
  {
    if (mCurrentRow == null) 
    {
      throw new SQLException("Current row not available.");
    } 
    else 
    {
      Object val = mCurrentRow.get(columnName);
      mWasNull = (null == val) ? true : false;
      return val;
    }
  }

  /** 
   * Get the value of the field identified by the given column index. 
   * @param columnIndex Index of the column.
   * @return The value of the column.
   * @exception SQLException If no row is available.
   */
  public Object getObject(int columnIndex) throws SQLException 
  {
    if (mCurrentRow == null) 
    {
      throw new SQLException("Current row not available.");
    } 
    else 
    {
      Iterator it = mCurrentRow.entrySet().iterator();
      for (int ndx = 1; it.hasNext(); ndx++)
      {
        if (columnIndex == ndx)
        {
          Object val = ((java.util.Map.Entry)it.next()).getValue();
          mWasNull = (null == val) ? true : false;
          return val;
        }
      }
    }
    return null;
  }

  /**
   * Get the metadata for the result.
   */
  public ResultSetMetaData getMetaData() 
  {
    // We always return null here.
    return null;
  }

  /**
   * Find column index given column name
   *
   * @param columnName column name
   * @return column index, -1 if no column of such name exists 
   */
  public int findColumn(String columnName) 
  {
    if (null == mCurrentRow)
      return -1;

    Iterator it = mCurrentRow.keySet().iterator();
    for (int ndx = 1; it.hasNext(); ndx++)
    {
      String name = (String) it.next();
      if (columnName.equals(name))
        return ndx;
    }

    return -1;
  }

  /**
   *  Clean up the resource of the ResultSet.
   */
  public void close() 
  {
    mData = null;
    mCurrentRow = null;
  }

  /**
   *  Returns Date value.
   */
  public Date getDate(String columnName) throws SQLException 
  {
    return (Date) getObject(columnName);
  }

  /**
   *  Returns Time value.
   */
  public Time getTime(String columnName) throws SQLException 
  {
    return (Time) getObject(columnName);
  }

  /**
   *  Returns Timestamp value.
   */
  public Timestamp getTimestamp(String columnName) throws SQLException 
  {
    return (Timestamp) getObject(columnName);
  }

  /**
   *  Returns String value.
   */
  public String getString(String columnName) throws SQLException 
  {
    return (String) getObject(columnName);
  }

  /**
   *  Returns long value.
   */
  public long getLong(String columnName) throws SQLException 
  {
    Long val = (Long) getObject(columnName);

    if (val != null) 
    {
      return val.longValue();
    } 
    else 
    {
      return 0;
    }
  }

  /**
   *  Returns boolean value.
   */
  public boolean getBoolean(String columnName) throws SQLException 
  {
    Boolean val = (Boolean) getObject(columnName);

    if (val != null) 
    {
      return val.booleanValue();
    } 
    else 
    {
      return false;
    }
  }

  /**
   *  Returns BigDecimal value.
   */
  public BigDecimal getBigDecimal(String columnName) throws SQLException 
  {
    return (BigDecimal) getObject(columnName);
  }

  /**
   *  Returns double value.
   */
  public double getDouble(String columnName) throws SQLException 
  {
    Double val = (Double) getObject(columnName);

    if (val != null) 
    {
      return val.doubleValue();
    } 
    else 
    {
      return 0;
    }
  }

  /**
   *  Returns float value.
   */
  public float getFloat(String columnName) throws SQLException 
  {
    Float val = (Float) getObject(columnName);

    if (val != null) 
    {
      return val.floatValue();
    } 
    else 
    {
      return 0;
    }
  }

  /**
   *  Returns int value.
   */
  public int getInt(String columnName) throws SQLException 
  {
    Integer val = (Integer) getObject(columnName);

    if (val != null) 
    {
      return val.intValue();
    } 
    else 
    {
      return 0;
    }
  }

  /**
   *  Returns short value.
   */
  public short getShort(String columnName) throws SQLException 
  {
    Short val = (Short) getObject(columnName);

    if (val != null) 
    {
      return val.shortValue();
    } 
    else 
    {
      return 0;
    }
  }

  /**
   * Returns String type value 
   */
  public String getString(int columnNdx) throws SQLException 
  {    
    return (String) getObject(columnNdx);
  }

  /**
   * This sample does not support this method. 
   */
  public boolean absolute(int row) 
  {
    return false;
  }

  /**
   * This sample does not support this method. 
   */
  public void afterLast() { }

  /**
   * This sample does not support this method. 
   */
  public void beforeFirst() { }

  /**
   * This sample does not support this method. 
   */
  public void cancelRowUpdates() { }

  /**
   * This sample does not support this method. 
   */
  public void clearWarnings() {  }

  /**
   * This sample does not support this method. 
   */
  public void deleteRow() {}

  /**
   * This sample does not support this method. 
   */
  public boolean first() { return false;}

  /**
   * This sample does not support this method. 
   */
  public Array getArray( int i) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Array getArray(String colName) {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public InputStream getAsciiStream(int columnIndex) {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public InputStream getAsciiStream(String columnName) {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public BigDecimal getBigDecimal(int columnIndex, int scale) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public BigDecimal getBigDecimal(int columnIndex) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public BigDecimal getBigDecimal(String columnName, int scale) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public InputStream getBinaryStream(int columnIndex) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public InputStream getBinaryStream(String columnName) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Blob getBlob(int i) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Blob getBlob(String colName) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public boolean getBoolean(int columnIndex) 
  {
    return false;
  }

  /**
   * This sample does not support this method. 
   */
  public byte getByte(int columnIndex) 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public byte getByte(String columnName) 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public byte[] getBytes(int columnIndex) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public byte[] getBytes(String columnName) 
  {
     return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Reader getCharacterStream(int columnIndex) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Reader getCharacterStream(String columnName) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Clob getClob(int i) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Clob getClob(String colName) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public int getConcurrency() 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public String getCursorName() 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Date getDate(int columnIndex, Calendar cal) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Date getDate(int columnIndex) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Date getDate(String columnName, Calendar cal) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public double getDouble(int columnIndex) 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public int getFetchDirection() 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public int getFetchSize() 
  {
    return 0;
  }

  /**
   * This sample does not support this method. 
   */
  public float getFloat(int columnIndex) 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public int getInt(int columnIndex) 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public long getLong(int columnIndex) 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public Object getObject(int i, Map map) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Object getObject(String colName, Map map) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Ref getRef(int i) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Ref getRef(String colName) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public int getRow() 
  {
    return 0;
  }

  /**
   * This sample does not support this method. 
   */
  public short getShort(int columnIndex) 
  {
    return -1;
  }

  /**
   * This sample does not support this method. 
   */
  public Statement getStatement() 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Time getTime(int columnIndex, Calendar cal) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Time getTime(int columnIndex) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Time getTime(String columnName, Calendar cal) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Timestamp getTimestamp(int columnIndex, Calendar cal) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Timestamp getTimestamp(int columnIndex) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public Timestamp getTimestamp(String columnName, Calendar cal) 
  {
    return null;
  }

  /**
   * This sample does not support this method. 
   */
  public int getType() 
  {
    return 0;
  }

  /**
   * This sample does not support this method. 
   */
  public InputStream getUnicodeStream(int columnIndex) 
  {
    return null;
  }

  /**
   *  Not used by Reformlet Open Data Source API, simply stub it.
   */
  public InputStream getUnicodeStream(String columnName) 
  {
    return null;
  }

  /**
   *  This sample does not support this method.
   */
  public SQLWarning getWarnings() 
  {
    return null;
  }

  /**
   *  This sample does not support this method.
   */
  public void insertRow() {}

  /**
   *  This sample does not support this method.
   */
  public boolean isAfterLast()
  {
    return false;
  }

  /**
   *  This sample does not support this method.
   */
  public boolean isBeforeFirst() 
  {
    return false;
  }

  /**
   *  This sample does not support this method.
   */
  public boolean isFirst() 
  {
    return false;
  }

  /**
   *  This sample does not support this method.
   */
  public boolean isLast() 
  {
    return false;
  }

  /**
   *  This sample does not support this method.
   */
  public boolean last() 
  {
    return false;
  }

  /**
   *  This sample does not support this method.
   */
  public void moveToCurrentRow() {}

  /**
   *  This sample does not support this method.
   */
  public void moveToInsertRow() {}

  /**
   *  This sample does not support this method.
   */
  public boolean previous() 
  {
    return false; 
  }

  /**
   *  This sample does not support this method.
   */
  public void refreshRow() {}

  /**
   *  This sample does not support this method.
   */  
  public boolean relative(int rows) 
  {
    return false; 
  }

  /**
   *  This sample does not support this method.
   */
  public boolean rowDeleted() 
  {
    return false; 
  }

  /**
   *  This sample does not support this method.
   */
  public boolean rowInserted() 
  {
    return false; 
  }

  /**
   *  This sample does not support this method.
   */
  public boolean rowUpdated() 
  {
    return false; 
  }

  /**
   *  This sample does not support this method.
   */
  public void setFetchDirection(int direction) {}

  /**
   *  This sample does not support this method.
   */
  public void setFetchSize(int rows) { }

  /**
   *  This sample does not support this method.
   */
  public void updateAsciiStream(int columnIndex, InputStream x, int length){}

  /**
   *  This sample does not support this method.
   */
  public void updateAsciiStream(String columnName, InputStream x, int length){}

  /**
   *  This sample does not support this method.
   */
  public void updateBigDecimal(int columnIndex, BigDecimal x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateBigDecimal(String columnName, BigDecimal x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateBinaryStream(int columnIndex, InputStream x, int length) {}

  /**
   *  This sample does not support this method.
   */
  public void updateBinaryStream(String columnName, InputStream x, int length){}

  /**
   *  This sample does not support this method.
   */
  public void updateBoolean(int columnIndex, boolean x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateBoolean(String columnName, boolean x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateByte(int columnIndex, byte x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateByte(String columnName, byte x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateBytes(int columnIndex, byte[] x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateBytes(String columnName, byte[] x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateCharacterStream(int columnIndex,Reader x,int length) {}
  
  /**
   *  This sample does not support this method.
   */
  public void updateCharacterStream(String columnName,int length) {}

  /**
   *  This sample does not support this method.
   */
  public void updateCharacterStream
   (String columnName, Reader reader, int length) {}
  
  /**
   *  This sample does not support this method.
   */
  public void updateDate(int columnIndex, Date x) {}

  /**
   *  This sample does not support this method.
   */
  public void updateDate(String columnName, Date x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateDouble(int columnIndex, double x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateDouble(String columnName, double x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateFloat(int columnIndex, float x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateFloat(String columnName, float x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateInt(int columnIndex, int x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateInt(String columnName, int x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateLong(int columnIndex, long x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateLong(String columnName, long x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateNull(int columnIndex) { }

  /**
   *  This sample does not support this method.
   */
  public void updateNull(String columnName) { }

  /**
   *  This sample does not support this method.
   */
  public void updateObject(int columnIndex, Object x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateObject(int columnIndex, Object x, int scale) { }

  /**
   *  This sample does not support this method.
   */
  public void updateObject(String columnName, Object x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateObject(String columnName, Object x, int scale) { }

  /**
   *  This sample does not support this method.
   */
  public void updateRow() { }

  /**
   *  This sample does not support this method.
   */
  public void updateShort(int columnIndex, short x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateShort(String columnName, short x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateString(int columnIndex, String x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateString(String columnName, String x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateTime(int columnIndex, Time x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateTime(String columnName, Time x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateTimestamp(int columnIndex, Timestamp x) { }

  /**
   *  This sample does not support this method.
   */
  public void updateTimestamp(String columnName, Timestamp x) { }
}




