/*
* @author Reghu
* @version 1.2
*
* Development Environment : JDeveloper 2.0
* Name of the Application : LongSample.java
* Creation/Modification History :
*
* rkrishna.in 04-Jan-1999 Created
* neshastr 22-May-2002 Certified on Oracle9i JDeveloper
* Savitha 10-Jan-2003 Certified on Linux
* Included checkTables() method
*/
package oracle.otnsamples.jdbc.longsample;

//java IO classes
import java.io.IOException;
import java.io.InputStream;

// java SQL classes
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.SQLException;

// java utility classes
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Enumeration;

// Oracle JDBC classes
import oracle.jdbc.pool.OracleDataSource;

/**
* This sample application illustrates accessing the long column in a
* Oracle database table using JDBC.
*/
public class LongSample {

/** Database Connection Object */ private Connection connection = null;


/** GUI handler for this sample */ private LongFrame gui;

/**
* Constructor of LongSample class, instantiates GUI.
**/
public LongSample() {
gui = new LongFrame(this); //Instantiate GUI
gui.setVisible(true);
}

/**
* Main entry point for the class. Instantiates the LongSample class
* and sets up the database connection.
**/
public static void main(String args[]) {
LongSample lSample = new LongSample(); // Instantiate LongSample class
// Setup the DB connection
lSample.dbConnection();

if( lSample.connection != null ) {

// Check if 'otn_airlines_long' table is present, else create it
lSample.checkTables();

// Select records
lSample.selectRows();
}
}

/**
* Dispatches the GUI events to the appropriate method, which performs
* the required JDBC operations. This method is invoked when event occurs
* in the GUI (like table Selection, Button clicks etc.). This method
* is invoked from the setupListeners method of LongFrame.java
**/
public void dispatchEvent(String eventName) {
if( eventName.equals("DISPLAY LONG DATA") ) {

// Get the row selected from the JTable in the GUI
int selectedRow = gui.jtable.getSelectedRow();

// Get the value of code from the row selected in the GUI table
String code = (String)gui.tmodel.getValueAt(selectedRow, 0);
displayLongData(code);
} else {
if(eventName.equals("EXIT")) {
exitApplication();
}
}
}

/**
* This method reads a properties file which is passed as
* the parameter to it and load it into a java Properties
* object and returns it.
*/
private Properties loadParams(String file) throws IOException {

// Loads a ResourceBundle and creates Properties from it
Properties prop = new Properties();
ResourceBundle bundle = ResourceBundle.getBundle(file);
Enumeration enum = bundle.getKeys();
String key = null;
while(enum.hasMoreElements()) {
key = (String)enum.nextElement();
prop.put(key, bundle.getObject(key));
}
return prop;
}

/**
* Creates a database connection object using DataSource object. Please
* substitute the database connection parameters with appropriate values in
* Connection.properties file
*/
private void dbConnection() {
try {
gui.putStatus("Trying to connect to the Database");

// Load the properties file to get the connection information
Properties prop = this.loadParams("Connection");

// Create a OracleDataSource instance
OracleDataSource ods = new OracleDataSource();

// Sets the driver type
ods.setDriverType("thin");

// Sets the database server name
ods.setServerName((String)prop.get("HostName"));

// Sets the database name
ods.setDatabaseName((String)prop.get("SID"));

// Sets the port number
ods.setPortNumber(new Integer((String)prop.get("Port")).intValue());

// Sets the user name
ods.setUser((String)prop.get("UserName"));

// Sets the password
ods.setPassword((String)prop.get("Password"));
connection=ods.getConnection();
gui.putStatus(" Connected to " + prop.get("SID") +
" Database as " + prop.get("UserName"));

} catch(SQLException ex) { // Trap SQL errors
gui.putStatus(
"Error in Connecting to the Database "+'\n'+ex.toString());
} catch(IOException ex) { // Trap IO errors
gui.putStatus(
"Error in reading the properties file "+'\n'+ex.toString());
}
}

/**
* Checks if the table ('otn_airlines_long') is present, else creates it.
* Look into PopulateTable.java class methods for more details
*/
private void checkTables() {
Statement stmt = null;
ResultSet rset = null;
try {
stmt = connection.createStatement();

// check from User_tables data dictionary table if the table is existing.
rset = stmt.executeQuery(" SELECT Table_Name FROM User_Tables "+
" WHERE Table_Name = 'OTN_AIRLINES_LONG' ");

// if the resultset of the above query does not have any record, it means
// table is not existing. So the table is created.
if (!rset.next()) {
// call the class to create the table
PopulateTable createTab = new PopulateTable(connection, gui);
createTab.createSchemaTable();
gui.putStatus( " otn_airlines_long Table created. Click on the table row to see corresponding LONG data. " );
}
} catch (SQLException sqlEx) {
gui.putStatus(" Could not create table otn_airlines_long : "+sqlEx.toString());
} finally {
try {
if( rset != null ) rset.close( );
if( stmt != null ) stmt.close( );
} catch(SQLException ex) { }
}
}

/**
* Method obtains all rows from the airlines_long_table table
**/
private void selectRows() {
try {

// Create a PreparedStatement object to execute the QUERY
PreparedStatement pst = connection.prepareStatement("SELECT code, name, partner "+
"FROM otn_airlines_long ");

// Eexecute the Query
ResultSet result = pst.executeQuery();

// Clear JTable in GUI
gui.tmodel.clearTable();

// Populating the Result set, retrieve rows, and update GUI to
// Reflect each selected record
while(result.next()) { //Point result set to next row
// Retrieve column values for this row
String code = result.getString(1);
String name = result.getString(2);
String partner = result.getString(3);
gui.addToJTable(code, name, partner); // Update Jtable
}

// Close the PreparedStatement
pst.close();
gui.putStatus("Click on the table row to see corresponding LONG data");
} catch(SQLException ex) { //Trap SQL errors
gui.putStatus("Error in selecting from the Database " + ex.toString());
}
}

/**
* Retrieve the LONG data in the AIRLINE_INSURANCE_DATA column, and
* displays in the TextArea
**/
private void displayLongData(String code) {
int chunk;
try {

// Create a PreparedStatement object to execute the QUERY
PreparedStatement pst = connection.prepareStatement("SELECT airline_insurance_data"+
" FROM otn_airlines_long WHERE code = ?");

// Bind the airline code to the query
pst.setString(1, code);
gui.putStatus("Reading Long Column from the DB, Please wait...");

// Excute the Query
ResultSet resultSet = pst.executeQuery();

// Populate the ResultSet
while(resultSet.next()) {
InputStream insurancedata; // Holds the LONG data
StringBuffer dataBuffer = new StringBuffer();

// Obtain the LONG data into a byte array. LONG data can be accessed in
// two ways: 1) By retrieving all the data in one shot (getBytes method)
// 2) By using streams. The LONG data is made available to the program
// as an Ascii or Unicode stream, and the data can be retrieved chunk by
// chunk, which is more eficient in terms of memory usage
// In this sample we illustrate retrieval using streams
insurancedata = resultSet.getAsciiStream(1);
while((chunk = insurancedata.read()) != -1) {
dataBuffer.append((char)chunk);
}
gui.display.setText(new String(dataBuffer));
gui.putStatus("Long Column is fetched from the DB successfully!");
}

// Close the PreparedStatement
pst.close();
} catch(Exception ex) { //Trap SQL errors
gui.putStatus("Error in selecting from the Database " + ex.toString());
}
}

/**
* Closing the Database Connection Object and exit the application
**/
private void exitApplication() {
try {
gui.putStatus("Closing the connection....please wait.....");
if(connection != null) {
connection.close(); //Closing the connection object.
}
} catch(SQLException ex) { //Trap SQLException
gui.putStatus(ex.toString());
}
System.exit(0); //Exit the aplication
}
}