/**
 * @author  Elangovan

 * @version 1.0
 *
 * Development Environment        :  Oracle9i JDeveloper
 * Name of the Application        :  ObjectTypeInheritanceSample.java
 * Creation/Modification History  :
 *

 *     Elangovan       21-Aug-2001      Created
 *     Venky           21-Feb-2003      Certfied on Linux platform
 *
 * This sample illustrates
 *
 *     1. Overloading Methods: Here the method  getPersonDetails() is
 *     overloaded. When invoked on Student Object, this method returns

 *     the courses taken, grade etc information apart from Name, Address
 *     information. When invoked on Teacher Object, this method returns the
 *     information like courses taught, salary, department apart from Name and Address.
 *
 *     2. Dynamic Method Dispatch: This is nothing but run-time polymorphism.
 *     When an overridden method is invoked, the implementation of the methods is
 *     searched, beginning from the object from which it was invoked and then
 *     upwards in the type hierarchy (the type and all the super types of type).

 *     In other words, if setAddress() in invoked from a Student Object, then the
 *     method in Person Object is invoked, since there is no implementation of
 *     setAddress() in Student Object, but if the same method is called from
 *     a Teacher object, since an implementation is available in the Teacher
 *     Object, it is called (refer to ObjectTypeInheritanceSample.sql).
 *
 *     3. Substituting Types in a Type Hierarchy:  A base object type can hold
 *     any of its sub-types object (i.e) Person is the base type and it can hold
 *     either a Student, Teacher or a Part-time Student object which are

 *     sub-types of Person.
 *
 * In this sample the user can View/Edit person details.
 *
 * For viewing person details, the overridden getpersondetails() method is
 * called which returns a String representation of the Object attributes.
 *
 * For updating person details, the overridden setpersondetails() method is
 * called, which sets the attributes and internally calls the setaddress() method for
 * setting the address.

 *
 * The gui part of this sample is handled separately in ObjectTypeInheritanceFrame.java
 */

package oracle.otnsamples.oracle9ijdbc.objecttypeinheritance;

// import for JDBC classes
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.sql.Connection;

import java.sql.SQLException;

// SQLJ runtime
import sqlj.runtime.ref.DefaultContext;

// Oracle extensions
import oracle.jdbc.pool.OracleDataSource;

// Java Utility Classes
import java.util.Properties;
import java.util.Enumeration;
import java.util.ResourceBundle;


import java.io.IOException;


public class ObjectTypeInheritanceSample {

  // Handles the gui for the sample
  ObjectTypeInheritanceFrame gui;

  private Connection connection = null;

  private String userName   = null;



  /**
  *  Constructor. Initializes the gui.
  */
  public ObjectTypeInheritanceSample() {
    try {
      gui = new ObjectTypeInheritanceFrame(this);

    } catch(Exception ex) {
      System.out.println(" Error : Couldn't  Initialize gui : "+ex.toString());
    }
  }

  /**

  *  Main entry point for the class. Calls the dbConnect() method to establish
  *  connection to database. Sets the map between the java classes and
  *  object types in the database. Displays the Person details in the JTable.
  */
  public static void main(String args[])  {
    // Create an object of the main sample class
    ObjectTypeInheritanceSample sample = new ObjectTypeInheritanceSample();

    // Connect to the database
    sample.dbConnect();

    if(sample.connection != null) {
        // Populate JTable with person details
        sample.displayPersonDetails();
    }

  }

  /**
   * 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.
   */
  public static 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
   */
  public void dbConnect() {

    try {
      gui.putStatus("Trying to connect to the Database");

      // Load the properties file to get the connection information
      Properties prop = ObjectTypeInheritanceSample.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"));

      if(ods!=null) {

        // Retrieve a connection from the Datasource
        connection = ods.getConnection();

        userName = (String)prop.get("UserName");
        userName = userName.toUpperCase();

        // Set the type map between the sql objects and their corresponding
        // java classes.
        setTypeMap(connection);
      }

      gui.putStatus(" Connected to " + prop.get("SID") +
                    " Database as " + prop.get("UserName"));



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

  /**
  *   This method sets up a type map in the connection between the java classes and
  *   the Object types in the database. Whenever an object is accessed from the
  *   database, the entries in the type map is searched and the corresponding
  *   java class is used to hold the object.
  */
  private void setTypeMap(Connection conn) {
    try {
      // Get the existing Type map
      java.util.Map map = conn.getTypeMap();


      // SQL Type names are in the format DatabaseSchema.TypeName and must be
      // all uppercase.

      // populate the type map
      map.put (userName+".PERSON_TYPE",
          Class.forName("oracle.otnsamples.oracle9ijdbc.objecttypeinheritance.Person"));

      map.put (userName+".STUDENT_TYPE",
         Class.forName("oracle.otnsamples.oracle9ijdbc.objecttypeinheritance.Student"));

      map.put (userName+".TEACHER_TYPE",
         Class.forName("oracle.otnsamples.oracle9ijdbc.objecttypeinheritance.Teacher"));

      map.put (userName+".PARTTIME_STUDENT_TYPE",
         Class.forName("oracle.otnsamples.oracle9ijdbc.objecttypeinheritance.ParttimeStudent"));

    }  catch(Exception ex){        // Trap errors
      gui.putStatus("Error while Mapping : "+ex.toString());
    }
  }


  /**
  *   This method retrieves the objects from the PersonDetails table and displays
  *   Id, Name and Object type of objects in a JTable.
  */
  private void displayPersonDetails() {

    String Id=null;
    String fullName=null;
    String objType=null;

    Statement stmt = null;
    ResultSet rset = null;

    Person personObj;
    try {
      // Create a statement object
      stmt = connection.createStatement();

      // Retrieve the objects from PersonDetails table
      rset = stmt.executeQuery("SELECT p.person FROM PersonDetails p");


      while(rset.next()) {

        // Retrieve the object and assign it to a Person object, a Person object
        // can hold all its sub-type objects (substitutability)
        personObj = (Person)rset.getObject(1);

        //  Since Part-time Student is a sub-type of Student, an object of Part-time
        //  Student will also be an instance of Student. Hence the retrieved
        //  object is first compared with a PartimeStudent and then with a
        //  Student(a Student object will not be an instance of Part-time Student)

        // If the retrieved object is a Part-timeStudent
        if(personObj instanceof ParttimeStudent)
          objType=" P ";

        // If the retrieved object is a student
        else if(personObj instanceof Student)
          objType=" S ";

        // If the retrieved object is a teacher
        else if(personObj instanceof Teacher)
          objType=" T ";


        // Some other sub-type of person
        else
          objType=" O ";

        // Get the Id
        Id = personObj.getId();

        // Get the full name
        fullName = personObj.getFirstname() + "  " + personObj.getLastname();

        // Add a row in the person table
        gui.addToJTable(Id,fullName,objType);

        gui.putStatus(" Select a person ...");
      }
    } catch(Exception ex) {          // Trap errors
      gui.putStatus("Error while Displaying person  details : "+ex.toString());
    } finally {
      try{

        // Close the recordset and statement objects
        if(rset != null) rset.close();
        if(stmt != null) stmt.close();


      } catch(SQLException sqlEx) {
        gui.putStatus(" Error : "+sqlEx.toString());
      }
      gui.repaint();
    }
  }

  /**
  * Dispatches the gui events to the appropriate method, which performs

  * the required JDBC operations.
  */
  public void dispatchEvent (String eventName) {

    if (eventName.equals("SHOW PERSON DETAILS"))
      // Display the selected person details
      showPersonDetails();

    else if (eventName.equals("SET PERSON DETAILS"))
      //  Update the person details to the table
      setPersonDetails();

    else if (eventName.equals("EXIT"))
      // Perform clean up and close the application
      exitApplication();

  }

  /**
  *  This method retrieves the person details and displays it.
  */
  private void showPersonDetails() {

      // Get the selected Id in the JTable
      String Id = gui.getSelectedId();

      // Retrieve the Person object corresponding to the selected id.
      Person personObj = getPersonDetails(Id);

      if(personObj != null) {
      try {

        // Set a connection context for object, the object uses this
        // connection context to call its member functions
        personObj.setConnectionContext(new DefaultContext(connection));

       // Call the getpersondetails() member function of the corresponding
       // object, it returns all the attributes of the object type. Display
       // the attributes.
       // If the retrieved object is a ParttimeStudent
        if(personObj instanceof ParttimeStudent) {


          ParttimeStudent pstudent = (ParttimeStudent)personObj;
          gui.showPersonDetails(pstudent.getpersondetails(),'P');

        // If the retrieved object is a Student
        } else if(personObj instanceof Student) {

          Student student = (Student)personObj;
          gui.showPersonDetails(student.getpersondetails(),'S');

         // If the retrieved object is a Teacher
        } else if(personObj instanceof Teacher) {

          Teacher teacher = (Teacher)personObj;
          gui.showPersonDetails(teacher.getpersondetails(),'T');

        }
      }  catch(Exception ex) {       // Trap errors
        gui.putStatus("Error while retrieving person details :  "+ex.toString());
      }
    }
  }

  /**
  *  Update the person details to the PersonDetails table.
  */
  private void setPersonDetails() {


    // Prepare a person object with the updated data.
    Person personObj = preparePerson(getPersonDetails(gui.getId()));

    PreparedStatement pstmt = null;

    try {
      // Create a prepared statement object
      pstmt = connection.prepareStatement(" UPDATE PersonDetails p"+
                                      " SET p.person = ? "+
                                      " WHERE p.person.Id= ? ");

      // Set the object to be updated
      pstmt.setObject(1,personObj);

      // Set the Id of the person, whose details has to be updated
      pstmt.setString(2,personObj.getId());

      // Update the person object in the database
      int updated = pstmt.executeUpdate();

      gui.putStatus(updated + " Person Details Updated ");

    }  catch(Exception ex) {    // Trap errors
      gui.putStatus("Error while updating person details :  "+ex.toString());

    }  finally {
      try {
        if(pstmt != null) pstmt.close();

      } catch (SQLException sqlEx) {
        gui.putStatus(" Error : "+sqlEx.toString());
      }
    }
  }

  /**
  *  Prepare a person object with the updated values.
  */
  private Person preparePerson(Person person) {

    // The person object that was edited
    Person personObj = person;

    try {

      // Set a connection context for object, the object uses this
      // connection context to call its member functions
      personObj.setConnectionContext(new DefaultContext(connection));

      // if the person is a Part-timeStudent
      if(personObj instanceof ParttimeStudent) {

        // Get the Part-time student object
        ParttimeStudent ps = (ParttimeStudent)personObj;

        // Get the edited values
        String Grade = gui.getGrade();
        String Yearofcompletion = gui.getYearofCompletion();

        String Coursestaken = gui.getCoursesTaken();
        float Hours = gui.getHours();
        String Batchcode = gui.getBatchCode();
        String Starttime = gui.getStartTime();

        // Call the overridden setpersondetails() member procedure to set the
        // updated values to the object
        personObj = ps.setpersondetails(Grade,
                                        Yearofcompletion,
                                        Coursestaken,
                                        Hours,
                                        Batchcode,
                                        Starttime);

      } else if(personObj instanceof Student) {

        // Get the student object
        Student s = (Student)personObj;

        // Get the edited values
        String Grade = gui.getGrade();
        String Yearofcompletion = gui.getYearofCompletion();
        String Coursestaken = gui.getCoursesTaken();

        // Call the overridden setpersondetails() member procedure to set the
        // updated values to the object
        personObj = s.setpersondetails(Grade,
                                       Yearofcompletion,
                                       Coursestaken);


      }  else if(personObj instanceof Teacher) {

        // Get the student object
        Teacher t = (Teacher)personObj;

        // Get the edited values
        float Experience = gui.getExperience();
        float Salary = gui.getSalary();
        String Courseshandled = gui.getCoursesHandled();

        // Call the overridden setpersondetails() member procedure to set the
        // updated values to the object
        personObj = t.setpersondetails(Experience,
                                       Salary,
                                       Courseshandled);
      }
    } catch(Exception ex) {
      gui.putStatus(" Couldn't construct a Person Object : "+ex.toString());
    }

    // return the updated person object
    return(personObj);

  }

  /**
  *  This method gets the Id of the person who has been selected in the JTable
  *  and retrieves the corresponding person object from the PersonDetails table.
  */
  public Person getPersonDetails(String id) {


    Person personObj = null;
    PreparedStatement pstmt = null;
    ResultSet rset = null;
    try {

      pstmt = connection.prepareStatement(" SELECT p.person "+
                                      " FROM PersonDetails p "+
                                      " WHERE p.person.Id=? ");

      // The Id of the person to be retrieved
      pstmt.setString(1,id);

      // select the person object from PersonDetails table
      rset = pstmt.executeQuery ();

      // Move the resultset pointer
      rset.next();

      // Retrieve the object and assign it to a person object, a person object
      // can hold all its sub-type objects (substitutability)
      personObj = (Person)rset.getObject(1);

    }  catch(SQLException sqlEx) {       // Trap errors
      gui.putStatus("Error at Selecting person :  "+sqlEx.toString());

    } finally {
      // Close the recordset and the statement object
      try {
        if(rset != null) rset.close();
        if(pstmt != null) pstmt.close();
      } catch(SQLException e) {
        gui.putStatus(" Error : "+e.toString());

      }

    }
    // Return the person object
    return(personObj);
  }


  /**
  *  This method performs the clean up action and closes the application
  */
  private void exitApplication(){
    // if connected to database
    if (connection != null) {
      try {
        // close the connection
        connection.close();
      }
      catch (SQLException sqlEx){      // Trap errors
        gui.putStatus(" Error while Closing the connection: "+sqlEx.toString());
      }
    }
    // Close the application
    System.exit(0);
  }

}
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy