// Point4.java

/*
 * This sample shows how to call an instance method from SQL
 */

import java.math.BigDecimal;
import java.sql.SQLException;
import oracle.jdbc.driver.OracleConnection;
import oracle.sql.STRUCT;
import oracle.sql.Datum;
import oracle.sql.CustomDatum;
import oracle.sql.CustomDatumFactory;
import oracle.sql.StructDescriptor;

public class Point4 implements CustomDatum, CustomDatumFactory
{
  int x = 0;
  int y = 0;

  /*
   * instance method to calculate the distance between this point
   * and point p. It won't change the values of x and y in this
   * java object.
   */
  public double distance (Point4 p) 
  {
    return Math.sqrt ((y - p.y) * (y - p.y) + (x - p.x) * (x - p.x));
  }

  /*
   * this method changes the value of x and y of this Java object,
   * and it will also change the value of the attributes of the
   * SQL Point object. (p1 in the PL/SQL block in point4.sql)
   */
  public void moveBy (Point4 p) 
  {
    x += p.x;
    y += p.y;
  }

  //
  // implementations of CustomDatum and CustomDatumFactory interface
  // methods. These are needed to create a Point object from an
  // SQL object of type Point, and to update the value of a SQL object
  // of type Point from a Java Point object.
  //
  public CustomDatum create (Datum d, int sqlType) throws SQLException 
  {
    if (d == null) return null;
    
    Point4 cd = new Point4();
    
    Object[] attributes = (Object[]) ((STRUCT)d).getAttributes ();
    cd.x = ((BigDecimal)attributes[0]).intValue();
    cd.y = ((BigDecimal)attributes[1]).intValue();
    System.out.println ("Finish call create()...."+cd.x+" "+cd.y+" "+cd);
    return cd;
  }

  public static CustomDatumFactory getFactory () 
  {
    return new Point4();
  }

  public Datum toDatum (OracleConnection conn) throws SQLException 
  {
    // Greate type descriptor
    StructDescriptor type_descriptor =
      StructDescriptor.createDescriptor ("POINT", conn);

    // Create attribute array 
    Object [] attributes = { new BigDecimal (x), new BigDecimal (y) };

    // Create the STRUCT object
    STRUCT struct = new STRUCT (type_descriptor, conn, attributes);

    return struct;
  }
}
