db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From banda...@apache.org
Subject svn commit: r165178 [8/26] - in /incubator/derby/code/trunk: ./ java/client/ java/client/org/ java/client/org/apache/ java/client/org/apache/derby/ java/client/org/apache/derby/client/ java/client/org/apache/derby/client/am/ java/client/org/apache/derby/client/net/ java/client/org/apache/derby/client/resources/ java/client/org/apache/derby/jdbc/ tools/ant/properties/
Date Thu, 28 Apr 2005 19:05:45 GMT
Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DateTime.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DateTime.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DateTime.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DateTime.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,639 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.DateTime
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+package org.apache.derby.client.am;
+
+
+/**
+ * High performance converters from date/time byte encodings to JDBC Date, Time and Timestamp objects.
+ * <p>
+ * Using this class for direct date/time conversions from bytes offers
+ * superior performance over the alternative method of first constructing
+ * a Java String from the encoded bytes, and then using
+ * {@link java.sql.Date#valueOf java.sql.Date.valueOf()},
+ * {@link java.sql.Time#valueOf java.sql.Time.valueOf()} or
+ * {@link java.sql.Timestamp#valueOf java.sql.Timestamp.valueOf()}.
+ * <p>
+ */
+public class DateTime
+{
+
+  // Hide the default constructor
+  private DateTime () {}
+
+  private static final int dateRepresentationLength = 10;
+  private static final int timeRepresentationLength = 8;
+  private static final int timestampRepresentationLength = 26;
+
+  // *********************************************************
+  // ********** Output converters (byte[] -> class) **********
+  // *********************************************************
+
+  /**
+   * Expected character representation is DERBY string representation
+   * of a date, which is in one of the following format.
+   */
+  public static final java.sql.Date dateBytesToDate (byte[] buffer,
+                                               int offset,
+                                               java.sql.Date recyclableDate)
+  {
+    int year, month, day;
+
+    String date = new String (buffer, offset, DateTime.dateRepresentationLength);
+    int yearIndx, monthIndx, dayIndx;
+    if (date.charAt (4) == '-') {
+      // JIS format: yyyy-mm-dd.
+      yearIndx = 0;
+      monthIndx = 5;
+      dayIndx = 8;
+    }
+    else throw new java.lang.IllegalArgumentException ("Unsupported date format!");
+
+    int zeroBase = ((int) '0');
+    // Character arithmetic is used rather than
+    // the less efficient Integer.parseInt (date.substring()).
+    year =
+      1000*(((int) date.charAt (yearIndx)) - zeroBase) +
+      100*(((int) date.charAt (yearIndx+1)) - zeroBase) +
+      10*(((int) date.charAt (yearIndx+2)) - zeroBase) +
+      (((int) date.charAt (yearIndx+3)) - zeroBase) -
+      1900;
+    month =
+      10*(((int) date.charAt (monthIndx)) - zeroBase) +
+      (((int) date.charAt (monthIndx+1)) - zeroBase) -
+      1;
+    day =
+      10*(((int) date.charAt (dayIndx)) - zeroBase) +
+      (((int) date.charAt (dayIndx+1)) - zeroBase);
+
+    if (recyclableDate == null)
+      return new java.sql.Date (year, month, day);
+    else {
+      recyclableDate.setYear (year);
+      recyclableDate.setMonth (month);
+      recyclableDate.setDate (day);
+      return recyclableDate;
+    }
+  }
+
+  /**
+   * Expected character representation is DERBY string representation
+   * of a time, which is in one of the following format: hh.mm.ss.
+   */
+  public static final java.sql.Time timeBytesToTime (byte[] buffer,
+                                               int offset,
+                                               java.sql.Time recyclableTime)
+  {
+    int hour, minute, second;
+
+    String time = new String (buffer, offset, DateTime.timeRepresentationLength);
+    int zeroBase = ((int) '0');
+
+    // compute hour.
+    hour =
+      10*(((int) time.charAt (0)) - zeroBase) +
+      (((int) time.charAt (1)) - zeroBase);
+    // compute minute.
+    minute =
+      10*(((int) time.charAt (3)) - zeroBase) +
+      (((int) time.charAt (4)) - zeroBase);
+    // compute second.
+    second =
+        10*(((int) time.charAt (6)) - zeroBase) +
+        (((int) time.charAt (7)) - zeroBase);
+
+    if (recyclableTime == null)
+      return new java.sql.Time (hour, minute, second);
+    else {
+      recyclableTime.setHours (hour);
+      recyclableTime.setMinutes (minute);
+      recyclableTime.setSeconds (second);
+      return recyclableTime;
+    }
+  }
+
+  /**
+   * Expected character representation is DERBY string representation
+   * of a timestamp: <code>yyyy-mm-dd-hh.mm.ss.ffffff</code>.
+   *
+   */
+  public static final java.sql.Timestamp timestampBytesToTimestamp (byte[] buffer,
+                                                              int offset,
+                                                              java.sql.Timestamp recyclableTimestamp)
+  {
+    int year, month, day, hour, minute, second, fraction;
+
+    String timestamp = new String (buffer, offset, DateTime.timestampRepresentationLength);
+    int zeroBase = ((int) '0');
+
+    year =
+      1000*(((int) timestamp.charAt (0)) - zeroBase) +
+      100*(((int) timestamp.charAt (1)) - zeroBase) +
+      10*(((int) timestamp.charAt (2)) - zeroBase) +
+      (((int) timestamp.charAt (3)) - zeroBase) -
+      1900;
+    month =
+      10*(((int) timestamp.charAt (5)) - zeroBase) +
+      (((int) timestamp.charAt (6)) - zeroBase) -
+      1;
+    day =
+      10*(((int) timestamp.charAt (8)) - zeroBase) +
+      (((int) timestamp.charAt (9)) - zeroBase);
+    hour =
+      10*(((int) timestamp.charAt (11)) - zeroBase) +
+      (((int) timestamp.charAt (12)) - zeroBase);
+    minute =
+      10*(((int) timestamp.charAt (14)) - zeroBase) +
+      (((int) timestamp.charAt (15)) - zeroBase);
+    second =
+      10*(((int) timestamp.charAt (17)) - zeroBase) +
+      (((int) timestamp.charAt (18)) - zeroBase);
+    fraction =
+      100000*(((int) timestamp.charAt (20)) - zeroBase) +
+      10000*(((int) timestamp.charAt (21)) - zeroBase) +
+      1000*(((int) timestamp.charAt (22)) - zeroBase) +
+      100*(((int) timestamp.charAt (23)) - zeroBase) +
+      10*(((int) timestamp.charAt (24)) - zeroBase) +
+      (((int) timestamp.charAt (25)) - zeroBase);
+
+    if (recyclableTimestamp == null)
+      return new java.sql.Timestamp (year, month, day, hour, minute, second, fraction*1000);
+    else {
+      recyclableTimestamp.setYear (year);
+      recyclableTimestamp.setMonth (month);
+      recyclableTimestamp.setDate (day);
+      recyclableTimestamp.setHours (hour);
+      recyclableTimestamp.setMinutes (minute);
+      recyclableTimestamp.setSeconds (second);
+      recyclableTimestamp.setNanos (fraction*1000);
+      return recyclableTimestamp;
+    }
+  }
+
+  // ********************************************************
+  // ********** Input converters (class -> byte[]) **********
+  // ********************************************************
+
+  /**
+   * The returned character representation is in JDBC date format:
+   * <code>yyyy-mm-dd</code> date format in
+   * DERBY string representation of a date.
+   *
+   */
+  public static final int dateToDateBytes (byte[] buffer,
+                                     int offset,
+                                     java.sql.Date date
+                                     ) throws ConversionException
+  {
+    int year = date.getYear () + 1900;
+    if (year > 9999) throw new ConversionException ("Year exceeds the maximum \"9999\".");
+    int month = date.getMonth () + 1;
+    int day = date.getDate ();
+
+    char[] dateChars = new char[DateTime.dateRepresentationLength];
+    int zeroBase = (int) '0';
+    dateChars[0] = (char) (year/1000 + zeroBase);
+    dateChars[1] = (char) ((year%1000)/100 + zeroBase);
+    dateChars[2] = (char) ((year%100)/10 + zeroBase);
+    dateChars[3] = (char) (year%10 + + zeroBase);
+    dateChars[4] = '-';
+    dateChars[5] = (char) (month/10 + zeroBase);
+    dateChars[6] = (char) (month%10 + zeroBase);
+    dateChars[7] = '-';
+    dateChars[8] = (char) (day/10 + zeroBase);
+    dateChars[9] = (char) (day%10 + zeroBase);
+    byte[] dateBytes = (new String(dateChars)).getBytes ();
+    System.arraycopy(dateBytes, 0, buffer, offset, DateTime.dateRepresentationLength);
+
+    return DateTime.dateRepresentationLength;
+  }
+
+  /**
+   * The returned character representation is in JDBC time escape format:
+   * <code>hh:mm:ss</code>, which is the same as JIS time format in
+   * DERBY string representation of a time.
+   *
+   */
+  public static final int timeToTimeBytes (byte[] buffer,
+                                     int offset,
+                                     java.sql.Time time)
+  {
+    int hour = time.getHours();
+    int minute = time.getMinutes();
+    int second = time.getSeconds();
+
+    char[] timeChars = new char[DateTime.timeRepresentationLength];
+    int zeroBase = (int) '0';
+    timeChars[0] = (char) (hour/10 + zeroBase);
+    timeChars[1] = (char) (hour%10 + + zeroBase);
+    timeChars[2] = ':';
+    timeChars[3] = (char) (minute/10 + zeroBase);
+    timeChars[4] = (char) (minute%10 + zeroBase);
+    timeChars[5] = ':';
+    timeChars[6] = (char) (second/10 + zeroBase);
+    timeChars[7] = (char) (second%10 + zeroBase);
+    byte[] timeBytes = (new String(timeChars)).getBytes ();
+    System.arraycopy(timeBytes, 0, buffer, offset, DateTime.timeRepresentationLength);
+
+    return DateTime.timeRepresentationLength;
+  }
+
+  /**
+   * The returned character representation is in DERBY string representation of
+   * a timestamp: <code>yyyy-mm-dd-hh.mm.ss.ffffff</code>.
+   */
+  public static final int timestampToTimestampBytes (byte[] buffer,
+                                               int offset,
+                                               java.sql.Timestamp timestamp
+                                               ) throws ConversionException
+  {
+    int year = timestamp.getYear () + 1900;
+    if (year > 9999) throw new ConversionException ("Year exceeds the maximum \"9999\".");
+    int month = timestamp.getMonth () + 1;
+    int day = timestamp.getDate ();
+    int hour = timestamp.getHours();
+    int minute = timestamp.getMinutes();
+    int second = timestamp.getSeconds();
+    int microsecond = timestamp.getNanos()/1000;
+
+    char[] timestampChars = new char[DateTime.timestampRepresentationLength];
+    int zeroBase = (int) '0';
+    timestampChars[0]  = (char) (year/1000 + zeroBase);
+    timestampChars[1]  = (char) ((year%1000)/100 + zeroBase);
+    timestampChars[2]  = (char) ((year%100)/10 + zeroBase);
+    timestampChars[3]  = (char) (year%10 + + zeroBase);
+    timestampChars[4]  = '-';
+    timestampChars[5]  = (char) (month/10 + zeroBase);
+    timestampChars[6]  = (char) (month%10 + zeroBase);
+    timestampChars[7]  = '-';
+    timestampChars[8]  = (char) (day/10 + zeroBase);
+    timestampChars[9]  = (char) (day%10 + zeroBase);
+    timestampChars[10] = '-';
+    timestampChars[11] = (char) (hour/10 + zeroBase);
+    timestampChars[12] = (char) (hour%10 + zeroBase);
+    timestampChars[13] = '.';
+    timestampChars[14] = (char) (minute/10 + zeroBase);
+    timestampChars[15] = (char) (minute%10 + zeroBase);
+    timestampChars[16] = '.';
+    timestampChars[17] = (char) (second/10 + zeroBase);
+    timestampChars[18] = (char) (second%10 + zeroBase);
+    timestampChars[19] = '.';
+    timestampChars[20] = (char) (microsecond/100000 + zeroBase);
+    timestampChars[21] = (char) ((microsecond%100000)/10000 + zeroBase);
+    timestampChars[22] = (char) ((microsecond%10000)/1000 + zeroBase);
+    timestampChars[23] = (char) ((microsecond%1000)/100 + zeroBase);
+    timestampChars[24] = (char) ((microsecond%100)/10 + zeroBase);
+    timestampChars[25] = (char) (microsecond%10 + zeroBase);
+
+    byte[] timestampBytes = (new String(timestampChars)).getBytes ();
+    System.arraycopy(timestampBytes, 0, buffer, offset, DateTime.timestampRepresentationLength);
+
+    return DateTime.timestampRepresentationLength;
+  }
+
+  // *********************************************************
+  // ******* CROSS output converters (byte[] -> class) *******
+  // *********************************************************
+
+  /**
+   * Expected character representation is DERBY string representation
+   * of a date, which is in one of the following format.
+   */
+  public static final java.sql.Timestamp dateBytesToTimestamp (byte[] buffer,
+                                                         int offset,
+                                                         java.sql.Timestamp recyclableTimestamp)
+  {
+    int year, month, day;
+
+    String date = new String (buffer, offset, DateTime.dateRepresentationLength);
+    int yearIndx, monthIndx, dayIndx;
+
+    yearIndx = 0;
+    monthIndx = 5;
+    dayIndx = 8;
+
+    int zeroBase = ((int) '0');
+    // Character arithmetic is used rather than
+    // the less efficient Integer.parseInt (date.substring()).
+    year =
+      1000*(((int) date.charAt (yearIndx)) - zeroBase) +
+      100*(((int) date.charAt (yearIndx+1)) - zeroBase) +
+      10*(((int) date.charAt (yearIndx+2)) - zeroBase) +
+      (((int) date.charAt (yearIndx+3)) - zeroBase) -
+      1900;
+    month =
+      10*(((int) date.charAt (monthIndx)) - zeroBase) +
+      (((int) date.charAt (monthIndx+1)) - zeroBase) -
+      1;
+    day =
+      10*(((int) date.charAt (dayIndx)) - zeroBase) +
+      (((int) date.charAt (dayIndx+1)) - zeroBase);
+
+    if (recyclableTimestamp == null)
+      return new java.sql.Timestamp (year, month, day, 0, 0, 0, 0);
+    else {
+      recyclableTimestamp.setYear (year);
+      recyclableTimestamp.setMonth (month);
+      recyclableTimestamp.setDate (day);
+      recyclableTimestamp.setHours (0);
+      recyclableTimestamp.setMinutes (0);
+      recyclableTimestamp.setSeconds (0);
+      recyclableTimestamp.setNanos (0);
+      return recyclableTimestamp;
+    }
+  }
+
+  /**
+   * Expected character representation is DERBY string representation
+   * of a time, which is in one of the following format.
+   */
+  public static final java.sql.Timestamp timeBytesToTimestamp (byte[] buffer,
+                                                         int offset,
+                                                         java.sql.Timestamp recyclableTimestamp)
+  {
+    int hour, minute, second;
+
+    String time = new String (buffer, offset, DateTime.timeRepresentationLength);
+    int zeroBase = ((int) '0');
+
+    // compute hour.
+    hour =
+      10*(((int) time.charAt (0)) - zeroBase) +
+      (((int) time.charAt (1)) - zeroBase);
+    // compute minute.
+    minute =
+      10*(((int) time.charAt (3)) - zeroBase) +
+      (((int) time.charAt (4)) - zeroBase);
+    // compute second   JIS format: hh:mm:ss.
+    second =
+        10*(((int) time.charAt (6)) - zeroBase) +
+        (((int) time.charAt (7)) - zeroBase);
+
+    if (recyclableTimestamp == null)
+      return new java.sql.Timestamp (0, 0, 1, hour, minute, second, 0);
+    else {
+      recyclableTimestamp.setYear (0);
+      recyclableTimestamp.setMonth (0);
+      recyclableTimestamp.setDate (1);
+      recyclableTimestamp.setHours (hour);
+      recyclableTimestamp.setMinutes (minute);
+      recyclableTimestamp.setSeconds (second);
+      recyclableTimestamp.setNanos (0);
+      return recyclableTimestamp;
+    }
+  }
+
+  /**
+   * Expected character representation is DERBY string representation
+   * of a timestamp: <code>yyyy-mm-dd-hh.mm.ss.ffffff</code>.
+   */
+  public static final java.sql.Date timestampBytesToDate (byte[] buffer,
+                                                    int offset,
+                                                    java.sql.Date recyclableDate)
+  {
+    int year, month, day;
+
+    String timestamp = new String (buffer, offset, DateTime.timestampRepresentationLength);
+    int zeroBase = ((int) '0');
+
+    year =
+      1000*(((int) timestamp.charAt (0)) - zeroBase) +
+      100*(((int) timestamp.charAt (1)) - zeroBase) +
+      10*(((int) timestamp.charAt (2)) - zeroBase) +
+      (((int) timestamp.charAt (3)) - zeroBase) -
+      1900;
+    month =
+      10*(((int) timestamp.charAt (5)) - zeroBase) +
+      (((int) timestamp.charAt (6)) - zeroBase) -
+      1;
+    day =
+      10*(((int) timestamp.charAt (8)) - zeroBase) +
+      (((int) timestamp.charAt (9)) - zeroBase);
+
+    if (recyclableDate == null)
+      return new java.sql.Date (year, month, day);
+    else {
+      recyclableDate.setYear (year);
+      recyclableDate.setMonth (month);
+      recyclableDate.setDate (day);
+      return recyclableDate;
+    }
+  }
+
+  /**
+   * Expected character representation is DERBY string representation
+   * of a timestamp: <code>yyyy-mm-dd-hh.mm.ss.ffffff</code>.
+   */
+  public static final java.sql.Time timestampBytesToTime (byte[] buffer,
+                                                    int offset,
+                                                    java.sql.Time recyclableTime)
+  {
+    int hour, minute, second;
+
+    String timestamp = new String (buffer, offset, DateTime.timestampRepresentationLength);
+    int zeroBase = ((int) '0');
+
+    hour =
+      10*(((int) timestamp.charAt (11)) - zeroBase) +
+      (((int) timestamp.charAt (12)) - zeroBase);
+    minute =
+      10*(((int) timestamp.charAt (14)) - zeroBase) +
+      (((int) timestamp.charAt (15)) - zeroBase);
+    second =
+      10*(((int) timestamp.charAt (17)) - zeroBase) +
+      (((int) timestamp.charAt (18)) - zeroBase);
+
+    if (recyclableTime == null)
+      return new java.sql.Time (hour, minute, second);
+    else {
+      recyclableTime.setYear (hour);
+      recyclableTime.setMonth (minute);
+      recyclableTime.setDate (second);
+      return recyclableTime;
+    }
+  }
+
+  // *********************************************************
+  // ******* CROSS input converters (class -> byte[]) ********
+  // *********************************************************
+
+  /**
+   * The returned character representation is in JDBC date escape format:
+   * <code>yyyy-mm-dd</code>, which is the same as JIS date format in
+   * DERBY string representation of a date.
+   *
+   */
+  public static final int timestampToDateBytes (byte[] buffer,
+                                          int offset,
+                                          java.sql.Timestamp timestamp
+                                          ) throws ConversionException
+  {
+    int year = timestamp.getYear () + 1900;
+    if (year > 9999) throw new ConversionException ("Year exceeds the maximum \"9999\".");
+    int month = timestamp.getMonth () + 1;
+    int day = timestamp.getDate ();
+
+    char[] dateChars = new char[DateTime.dateRepresentationLength];
+    int zeroBase = (int) '0';
+    dateChars[0] = (char) (year/1000 + zeroBase);
+    dateChars[1] = (char) ((year%1000)/100 + zeroBase);
+    dateChars[2] = (char) ((year%100)/10 + zeroBase);
+    dateChars[3] = (char) (year%10 + + zeroBase);
+    dateChars[4] = '-';
+    dateChars[5] = (char) (month/10 + zeroBase);
+    dateChars[6] = (char) (month%10 + zeroBase);
+    dateChars[7] = '-';
+    dateChars[8] = (char) (day/10 + zeroBase);
+    dateChars[9] = (char) (day%10 + zeroBase);
+    byte[] dateBytes = (new String(dateChars)).getBytes ();
+    System.arraycopy(dateBytes, 0, buffer, offset, DateTime.dateRepresentationLength);
+
+    return DateTime.dateRepresentationLength;
+  }
+
+  /**
+   * The returned character representation is in JDBC time escape format:
+   * <code>hh:mm:ss</code>, which is the same as JIS time format in
+   * DERBY string representation of a time.
+   *
+   */
+  public static final int timestampToTimeBytes (byte[] buffer,
+                                          int offset,
+                                          java.sql.Timestamp timestamp)
+  {
+    int hour = timestamp.getHours();
+    int minute = timestamp.getMinutes();
+    int second = timestamp.getSeconds();
+
+    char[] timeChars = new char[DateTime.timeRepresentationLength];
+    int zeroBase = (int) '0';
+    timeChars[0] = (char) (hour/10 + zeroBase);
+    timeChars[1] = (char) (hour%10 + + zeroBase);
+    timeChars[2] = ':';
+    timeChars[3] = (char) (minute/10 + zeroBase);
+    timeChars[4] = (char) (minute%10 + zeroBase);
+    timeChars[5] = ':';
+    timeChars[6] = (char) (second/10 + zeroBase);
+    timeChars[7] = (char) (second%10 + zeroBase);
+    byte[] timeBytes = (new String(timeChars)).getBytes ();
+    System.arraycopy(timeBytes, 0, buffer, offset, DateTime.timeRepresentationLength);
+
+    return DateTime.timeRepresentationLength;
+  }
+
+  /**
+   * The returned character representation is in DERBY string representation of
+   * a timestamp: <code>yyyy-mm-dd-hh.mm.ss.ffffff</code>.
+   *
+   */
+  public static final int dateToTimestampBytes (byte[] buffer,
+                                          int offset,
+                                          java.sql.Date date
+                                          ) throws ConversionException
+  {
+    int year = date.getYear () + 1900;
+    if (year > 9999) throw new ConversionException ("Year exceeds the maximum \"9999\".");
+    int month = date.getMonth () + 1;
+    int day = date.getDate ();
+
+    char[] timestampChars = new char[DateTime.timestampRepresentationLength];
+    int zeroBase = (int) '0';
+    timestampChars[0]  = (char) (year/1000 + zeroBase);
+    timestampChars[1]  = (char) ((year%1000)/100 + zeroBase);
+    timestampChars[2]  = (char) ((year%100)/10 + zeroBase);
+    timestampChars[3]  = (char) (year%10 + + zeroBase);
+    timestampChars[4]  = '-';
+    timestampChars[5]  = (char) (month/10 + zeroBase);
+    timestampChars[6]  = (char) (month%10 + zeroBase);
+    timestampChars[7]  = '-';
+    timestampChars[8]  = (char) (day/10 + zeroBase);
+    timestampChars[9]  = (char) (day%10 + zeroBase);
+    timestampChars[10] = '-';
+    timestampChars[11] = '0';
+    timestampChars[12] = '0';
+    timestampChars[13] = '.';
+    timestampChars[14] = '0';
+    timestampChars[15] = '0';
+    timestampChars[16] = '.';
+    timestampChars[17] = '0';
+    timestampChars[18] = '0';
+    timestampChars[19] = '.';
+    timestampChars[20] = '0';
+    timestampChars[21] = '0';
+    timestampChars[22] = '0';
+    timestampChars[23] = '0';
+    timestampChars[24] = '0';
+    timestampChars[25] = '0';
+
+    byte[] timestampBytes = (new String(timestampChars)).getBytes ();
+    System.arraycopy(timestampBytes, 0, buffer, offset, DateTime.timestampRepresentationLength);
+
+    return DateTime.timestampRepresentationLength;
+  }
+
+  /**
+   * The returned character representation is in DERBY string representation of
+   * a timestamp: <code>yyyy-mm-dd-hh.mm.ss.ffffff</code>.
+   *
+   */
+  public static final int timeToTimestampBytes (byte[] buffer,
+                                          int offset,
+                                          java.sql.Time time
+                                          )
+  {
+    int hour = time.getHours();
+    int minute = time.getMinutes();
+    int second = time.getSeconds();
+
+    char[] timestampChars = new char[DateTime.timestampRepresentationLength];
+    int zeroBase = (int) '0';
+    timestampChars[0]  = '1';
+    timestampChars[1]  = '9';
+    timestampChars[2]  = '0';
+    timestampChars[3]  = '0';
+    timestampChars[4]  = '-';
+    timestampChars[5]  = '0';
+    timestampChars[6]  = '1';
+    timestampChars[7]  = '-';
+    timestampChars[8]  = '0';
+    timestampChars[9]  = '1';
+    timestampChars[10] = '-';
+    timestampChars[11] = (char) (hour/10 + zeroBase);
+    timestampChars[12] = (char) (hour%10 + zeroBase);
+    timestampChars[13] = '.';
+    timestampChars[14] = (char) (minute/10 + zeroBase);
+    timestampChars[15] = (char) (minute%10 + zeroBase);
+    timestampChars[16] = '.';
+    timestampChars[17] = (char) (second/10 + zeroBase);
+    timestampChars[18] = (char) (second%10 + zeroBase);
+    timestampChars[19] = '.';
+    timestampChars[20] = '0';
+    timestampChars[21] = '0';
+    timestampChars[22] = '0';
+    timestampChars[23] = '0';
+    timestampChars[24] = '0';
+    timestampChars[25] = '0';
+
+    byte[] timestampBytes = (new String(timestampChars)).getBytes ();
+    System.arraycopy(timestampBytes, 0, buffer, offset, DateTime.timestampRepresentationLength);
+
+    return DateTime.timestampRepresentationLength;
+  }
+}
+

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DateTime.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Decimal.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Decimal.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Decimal.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Decimal.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,489 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.Decimal
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+package org.apache.derby.client.am;
+
+/**
+ * Converters from fixed point decimal bytes to <code>java.math.BigDecimal</code>,
+ * <code>double</code>, or <code>long</code>.
+ */
+public class Decimal
+{
+  /**
+   * Packed Decimal representation
+   */
+  public final static int PACKED_DECIMAL = 0x30;
+
+  //--------------------------private constants---------------------------------
+
+  private static final int[][] tenRadixMagnitude = {
+    { 0x3b9aca00 }, // 10^9
+    { 0x0de0b6b3, 0xa7640000 }, // 10^18
+    { 0x033b2e3c, 0x9fd0803c, 0xe8000000 }, // 10^27
+  };
+
+  //--------------------------constructors--------------------------------------
+
+  // Hide the default constructor, this is a static class.
+  private Decimal() {}
+
+  //--------------------------private helper methods----------------------------
+
+  /**
+   * Convert a range of packed nybbles (up to 9 digits without overflow) to an int.
+   * Note that for performance purpose, it does not do array-out-of-bound checking.
+  */
+  private static final int packedNybblesToInt (byte[] buffer,
+                                         int offset,
+                                         int startNybble,
+                                         int numberOfNybbles)
+  {
+    int value = 0;
+
+    int i = startNybble / 2;
+    if ((startNybble % 2) != 0) {
+      // process low nybble of the first byte if necessary.
+      value += buffer[offset+i] & 0x0F;
+      i++;
+    }
+
+    int endNybble = startNybble + numberOfNybbles -1;
+    for (; i<(endNybble+1)/2; i++) {
+      value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); // high nybble.
+      value = value*10 +  (buffer[offset+i] & 0x0F);        // low nybble.
+    }
+
+    if ((endNybble % 2) == 0) {
+      // process high nybble of the last byte if necessary.
+      value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4);
+    }
+
+    return value;
+  }
+
+  /**
+   * Convert a range of packed nybbles (up to 18 digits without overflow) to a long.
+   * Note that for performance purpose, it does not do array-out-of-bound checking.
+  */
+  private static final long packedNybblesToLong (byte[] buffer,
+                                           int offset,
+                                           int startNybble,
+                                           int numberOfNybbles)
+  {
+    long value = 0;
+
+    int i = startNybble / 2;
+    if ((startNybble % 2) != 0) {
+      // process low nybble of the first byte if necessary.
+      value += buffer[offset+i] & 0x0F;
+      i++;
+    }
+
+    int endNybble = startNybble + numberOfNybbles -1;
+    for (; i<(endNybble+1)/2; i++) {
+      value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4); // high nybble.
+      value = value*10 +  (buffer[offset+i] & 0x0F);        // low nybble.
+    }
+
+    if ((endNybble % 2) == 0) {
+      // process high nybble of the last byte if necessary.
+      value = value*10 + ((buffer[offset+i] & 0xF0) >>> 4);
+    }
+
+    return value;
+  }
+
+  /**
+   * Compute the int array of magnitude from input value segments.
+   */
+  private static final int[] computeMagnitude(int[] input)
+  {
+      int length = input.length;
+      int[] mag = new int[length];
+
+      mag[length-1] = input[length-1];
+      for (int i=0; i<length-1; i++) {
+        int carry = 0;
+        int j = tenRadixMagnitude[i].length-1;
+        int k = length-1;
+        for (; j>=0; j--, k--) {
+          long product = (input[length-2-i] & 0xFFFFFFFFL) * (tenRadixMagnitude[i][j] & 0xFFFFFFFFL)
+                       + (mag[k] & 0xFFFFFFFFL) // add previous value
+                       + (carry & 0xFFFFFFFFL); // add carry
+          carry  = (int) (product >>> 32);
+          mag[k] = (int) (product & 0xFFFFFFFFL);
+        }
+        mag[k] = (int) carry;
+      }
+      return mag;
+  }
+
+  //--------------entry points for runtime representation-----------------------
+
+  /**
+   * Build a <code>java.math.BigDecimal</code> from a fixed point decimal byte representation.
+   *
+   * @exception IllegalArgumentException if the specified representation is not recognized.
+   */
+  public static final java.math.BigDecimal getBigDecimal (byte[] buffer,
+                                                    int offset,
+                                                    int precision,
+                                                    int scale
+                                                    ) throws java.io.UnsupportedEncodingException
+  {
+    // The byte-length of a packed decimal with precision <code>p</code> is always <code>p/2 + 1</code>
+    int length = precision / 2 + 1;
+
+    // check for sign.
+    int signum;
+    if ((buffer[offset+length-1] & 0x0F) == 0x0D)
+      signum = -1;
+    else
+      signum =  1;
+
+    if (precision <= 9) {
+      // can be handled by int without overflow.
+      int value = packedNybblesToInt(buffer, offset, 0, length*2-1);
+
+      // convert value to a byte array of magnitude.
+      byte[] magnitude = new byte[4];
+      magnitude[0] = (byte)(value >>> 24);
+      magnitude[1] = (byte)(value >>> 16);
+      magnitude[2] = (byte)(value >>> 8);
+      magnitude[3] = (byte)(value);
+
+      return new java.math.BigDecimal (new java.math.BigInteger(signum, magnitude), scale);
+    }
+    else if (precision <= 18) {
+      // can be handled by long without overflow.
+      long value = packedNybblesToLong(buffer, offset, 0, length*2-1);
+
+      // convert value to a byte array of magnitude.
+      byte[] magnitude = new byte[8];
+      magnitude[0] = (byte)(value >>> 56);
+      magnitude[1] = (byte)(value >>> 48);
+      magnitude[2] = (byte)(value >>> 40);
+      magnitude[3] = (byte)(value >>> 32);
+      magnitude[4] = (byte)(value >>> 24);
+      magnitude[5] = (byte)(value >>> 16);
+      magnitude[6] = (byte)(value >>>  8);
+      magnitude[7] = (byte)(value);
+
+      return new java.math.BigDecimal (new java.math.BigInteger(signum, magnitude), scale);
+    }
+    else if (precision <= 27) {
+      // get the value of last 9 digits (5 bytes).
+      int lo = packedNybblesToInt(buffer, offset, (length-5)*2, 9);
+      // get the value of another 9 digits (5 bytes).
+      int me = packedNybblesToInt(buffer, offset, (length-10)*2+1, 9);
+      // get the value of the rest digits.
+      int hi = packedNybblesToInt(buffer, offset, 0, (length-10)*2+1);
+
+      // compute the int array of magnitude.
+      int[] value = computeMagnitude(new int[] {hi, me, lo});
+
+      // convert value to a byte array of magnitude.
+      byte[] magnitude = new byte[12];
+      magnitude[0]  = (byte)(value[0] >>> 24);
+      magnitude[1]  = (byte)(value[0] >>> 16);
+      magnitude[2]  = (byte)(value[0] >>> 8);
+      magnitude[3]  = (byte)(value[0]);
+      magnitude[4]  = (byte)(value[1] >>> 24);
+      magnitude[5]  = (byte)(value[1] >>> 16);
+      magnitude[6]  = (byte)(value[1] >>> 8);
+      magnitude[7]  = (byte)(value[1]);
+      magnitude[8]  = (byte)(value[2] >>> 24);
+      magnitude[9]  = (byte)(value[2] >>> 16);
+      magnitude[10] = (byte)(value[2] >>> 8);
+      magnitude[11] = (byte)(value[2]);
+
+      return new java.math.BigDecimal (new java.math.BigInteger(signum, magnitude), scale);
+    }
+    else if (precision <= 31) {
+      // get the value of last 9 digits (5 bytes).
+      int lo   = packedNybblesToInt(buffer, offset, (length-5)*2, 9);
+      // get the value of another 9 digits (5 bytes).
+      int meLo = packedNybblesToInt(buffer, offset, (length-10)*2+1, 9);
+      // get the value of another 9 digits (5 bytes).
+      int meHi = packedNybblesToInt(buffer, offset, (length-14)*2, 9);
+      // get the value of the rest digits.
+      int hi   = packedNybblesToInt(buffer, offset, 0, (length-14)*2);
+
+      // compute the int array of magnitude.
+      int[] value = computeMagnitude(new int[] {hi, meHi, meLo, lo});
+
+      // convert value to a byte array of magnitude.
+      byte[] magnitude = new byte[16];
+      magnitude[0]  = (byte)(value[0] >>> 24);
+      magnitude[1]  = (byte)(value[0] >>> 16);
+      magnitude[2]  = (byte)(value[0] >>> 8);
+      magnitude[3]  = (byte)(value[0]);
+      magnitude[4]  = (byte)(value[1] >>> 24);
+      magnitude[5]  = (byte)(value[1] >>> 16);
+      magnitude[6]  = (byte)(value[1] >>> 8);
+      magnitude[7]  = (byte)(value[1]);
+      magnitude[8]  = (byte)(value[2] >>> 24);
+      magnitude[9]  = (byte)(value[2] >>> 16);
+      magnitude[10] = (byte)(value[2] >>> 8);
+      magnitude[11] = (byte)(value[2]);
+      magnitude[12] = (byte)(value[3] >>> 24);
+      magnitude[13] = (byte)(value[3] >>> 16);
+      magnitude[14] = (byte)(value[3] >>> 8);
+      magnitude[15] = (byte)(value[3]);
+
+      return new java.math.BigDecimal (new java.math.BigInteger(signum, magnitude), scale);
+    }
+    else {
+      // throw an exception here if nibbles is greater than 31
+      throw new java.lang.IllegalArgumentException("Decimal may only be up to 31 digits!");
+    }
+  }
+
+  /**
+   * Build a Java <code>double</code> from a fixed point decimal byte representation.
+   *
+   * @exception IllegalArgumentException if the specified representation is not recognized.
+   */
+  public static final double getDouble (byte[] buffer,
+                                  int offset,
+                                  int precision,
+                                  int scale
+                                  ) throws java.io.UnsupportedEncodingException
+  {
+    // The byte-length of a packed decimal with precision <code>p</code> is always <code>p/2 + 1</code>
+    int length = precision / 2 + 1;
+
+    // check for sign.
+    int signum;
+    if ((buffer[offset+length-1] & 0x0F) == 0x0D)
+      signum = -1;
+    else
+      signum =  1;
+
+    if (precision <= 9) {
+      // can be handled by int without overflow.
+      int value = packedNybblesToInt(buffer, offset, 0, length*2-1);
+
+      return signum * value / Math.pow(10, scale);
+    }
+    else if (precision <= 18) {
+      // can be handled by long without overflow.
+      long value = packedNybblesToLong(buffer, offset, 0, length*2-1);
+
+      return signum * value / Math.pow(10, scale);
+    }
+    else if (precision <= 27) {
+      // get the value of last 9 digits (5 bytes).
+      int lo = packedNybblesToInt(buffer, offset, (length-5)*2, 9);
+      // get the value of another 9 digits (5 bytes).
+      int me = packedNybblesToInt(buffer, offset, (length-10)*2+1, 9);
+      // get the value of the rest digits.
+      int hi = packedNybblesToInt(buffer, offset, 0, (length-10)*2+1);
+
+      return signum * (lo / Math.pow(10, scale) +
+                       me * Math.pow(10, 9-scale) +
+                       hi * Math.pow(10, 18-scale));
+    }
+    else if (precision <= 31) {
+      // get the value of last 9 digits (5 bytes).
+      int lo   = packedNybblesToInt(buffer, offset, (length-5)*2, 9);
+      // get the value of another 9 digits (5 bytes).
+      int meLo = packedNybblesToInt(buffer, offset, (length-10)*2+1, 9);
+      // get the value of another 9 digits (5 bytes).
+      int meHi = packedNybblesToInt(buffer, offset, (length-14)*2, 9);
+      // get the value of the rest digits.
+      int hi   = packedNybblesToInt(buffer, offset, 0, (length-14)*2);
+
+      return signum * (lo   / Math.pow(10, scale) +
+                       meLo * Math.pow(10, 9-scale) +
+                       meHi * Math.pow(10, 18-scale) +
+                       hi   * Math.pow(10, 27-scale));
+    }
+    else {
+      // throw an exception here if nibbles is greater than 31
+      throw new java.lang.IllegalArgumentException ("Decimal may only be up to 31 digits!");
+    }
+  }
+
+  /**
+   * Build a Java <code>long</code> from a fixed point decimal byte representation.
+   *
+   * @exception IllegalArgumentException if the specified representation is not recognized.
+   */
+  public static final long getLong (byte[] buffer,
+                              int offset,
+                              int precision,
+                              int scale
+                              ) throws java.io.UnsupportedEncodingException
+  {
+    if (precision > 31) {
+      // throw an exception here if nibbles is greater than 31
+      throw new java.lang.IllegalArgumentException ("Decimal may only be up to 31 digits!");
+    }
+
+    // The byte-length of a packed decimal with precision <code>p</code> is always <code>p/2 + 1</code>
+    int length = precision / 2 + 1;
+
+    // check for sign.
+    int signum;
+    if ((buffer[offset+length-1] & 0x0F) == 0x0D)
+      signum = -1;
+    else
+      signum =  1;
+
+    // compute the integer part only.
+    int leftOfDecimalPoint = length*2-1-scale;
+    long integer = 0;
+    if (leftOfDecimalPoint > 0) {
+      int i = 0;
+      for (; i<leftOfDecimalPoint/2; i++) {
+        integer = integer*10 + signum*((buffer[offset+i] & 0xF0) >>> 4); // high nybble.
+        integer = integer*10 + signum* (buffer[offset+i] & 0x0F);        // low nybble.
+      }
+      if ((leftOfDecimalPoint % 2) == 1) {
+        // process high nybble of the last byte if necessary.
+        integer = integer*10 + signum*((buffer[offset+i] & 0xF0) >>> 4);
+      }
+    }
+
+    return integer;
+  }
+
+  //--------------entry points for runtime representation-----------------------
+
+  /**
+    Write a Java <code>java.math.BigDecimal</code> to packed decimal bytes.
+  */
+  public static final int bigDecimalToPackedDecimalBytes (byte[] buffer,
+                                                    int offset,
+                                                    java.math.BigDecimal b,
+                                                    int declaredPrecision,
+                                                    int declaredScale)
+                                                    throws ConversionException
+  {
+    // packed decimal may only be up to 31 digits.
+    if (declaredPrecision > 31)  
+      throw new ConversionException ("Packed decimal may only be up to 31 digits!");
+
+    // get absolute unscaled value of the BigDecimal as a String.
+    String unscaledStr = b.unscaledValue().abs().toString();
+
+    // get precision of the BigDecimal.
+    int bigPrecision = unscaledStr.length();
+
+    if (bigPrecision > 31)
+      throw new ConversionException ("The numeric literal \"" +
+                             b.toString() +
+                             "\" is not valid because its value is out of range.",
+                             "42820",
+                             -405);
+
+    int bigScale = b.scale();
+    int bigWholeIntegerLength = bigPrecision - bigScale;
+    if ( (bigWholeIntegerLength > 0) && (!unscaledStr.equals ("0")) ) {
+      // if whole integer part exists, check if overflow.
+      int declaredWholeIntegerLength = declaredPrecision - declaredScale;
+      if (bigWholeIntegerLength > declaredWholeIntegerLength)
+        throw new ConversionException ("Overflow occurred during numeric data type conversion of \"" +
+                                       b.toString() +
+                                       "\".",
+                                       "22003",
+                                       -413);
+    }
+
+    // convert the unscaled value to a packed decimal bytes.
+
+    // get unicode '0' value.
+    int zeroBase = '0';
+
+    // start index in target packed decimal.
+    int packedIndex = declaredPrecision-1;
+
+    // start index in source big decimal.
+    int bigIndex;
+
+    if (bigScale >= declaredScale) {
+      // If target scale is less than source scale,
+      // discard excessive fraction.
+
+      // set start index in source big decimal to ignore excessive fraction.
+      bigIndex = bigPrecision-1-(bigScale-declaredScale);
+
+      if (bigIndex < 0) {
+        // all digits are discarded, so only process the sign nybble.
+        buffer[offset+(packedIndex+1)/2] =
+          (byte) ( (b.signum()>=0)?12:13 ); // sign nybble
+      }
+      else {
+        // process the last nybble together with the sign nybble.
+        buffer[offset+(packedIndex+1)/2] =
+          (byte) ( ( (unscaledStr.charAt(bigIndex)-zeroBase) << 4 ) + // last nybble
+                 ( (b.signum()>=0)?12:13 ) ); // sign nybble
+      }
+      packedIndex-=2;
+      bigIndex-=2;
+    }
+    else {
+      // If target scale is greater than source scale,
+      // pad the fraction with zero.
+
+      // set start index in source big decimal to pad fraction with zero.
+      bigIndex = declaredScale-bigScale-1;
+
+      // process the sign nybble.
+      buffer[offset+(packedIndex+1)/2] =
+        (byte) ( (b.signum()>=0)?12:13 ); // sign nybble
+
+      for (packedIndex-=2, bigIndex-=2; bigIndex>=0; packedIndex-=2, bigIndex-=2)
+        buffer[offset+(packedIndex+1)/2] = (byte) 0;
+
+      if (bigIndex == -1) {
+        buffer[offset+(packedIndex+1)/2] =
+          (byte) ( (unscaledStr.charAt(bigPrecision-1)-zeroBase) << 4 ); // high nybble
+
+        packedIndex-=2;
+        bigIndex = bigPrecision-3;
+      }
+      else {
+        bigIndex = bigPrecision-2;
+      }
+    }
+
+    // process the rest.
+    for (; bigIndex>=0; packedIndex-=2, bigIndex-=2) {
+      buffer[offset+(packedIndex+1)/2] =
+        (byte) ( ( (unscaledStr.charAt(bigIndex)-zeroBase) << 4 ) + // high nybble
+               ( unscaledStr.charAt(bigIndex+1)-zeroBase ) ); // low nybble
+    }
+
+    // process the first nybble when there is one left.
+    if (bigIndex == -1) {
+      buffer[offset+(packedIndex+1)/2] =
+        (byte) (unscaledStr.charAt(0) - zeroBase);
+
+      packedIndex-=2;
+    }
+
+    // pad zero in front of the big decimal if necessary.
+    for (; packedIndex>=-1; packedIndex-=2)
+      buffer[offset+(packedIndex+1)/2] = (byte) 0;
+
+    return declaredPrecision/2 + 1;
+  }
+}

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Decimal.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Diagnosable.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Diagnosable.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Diagnosable.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Diagnosable.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,28 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.Diagnosable
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+public interface Diagnosable
+{
+  public Sqlca getSqlca();
+  public java.lang.Throwable getThrowable ();
+  public void printTrace (java.io.PrintWriter printWriter, String messageHeader);
+}

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/Diagnosable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DisconnectException.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DisconnectException.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DisconnectException.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DisconnectException.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,72 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.DisconnectException
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+public class DisconnectException extends SqlException
+{
+
+  public DisconnectException (Agent agent, String reason, SqlState sqlstate, SqlCode sqlcode) 
+  {
+    super (agent.logWriter_, reason, sqlstate, sqlcode);
+  }  
+    
+  public DisconnectException (Agent agent, String reason, SqlState sqlstate)
+  {
+    super (agent.logWriter_, reason, sqlstate, SqlCode.disconnectError);
+    // make the call to close the streams and socket.
+    if (agent != null) agent.disconnectEvent();
+  }
+
+  public DisconnectException (java.lang.Throwable throwable, Agent agent, String reason, SqlState sqlstate)
+  {
+    super (agent.logWriter_, throwable, reason, sqlstate, SqlCode.disconnectError);
+    // make the call to close the streams and socket.
+    if (agent != null) agent.disconnectEvent();
+  }
+
+  public DisconnectException (Agent agent)
+  {
+    this (agent, null, SqlState.undefined);
+  }
+
+  public DisconnectException (java.lang.Throwable throwable, Agent agent)
+  {
+    this (throwable, agent, null, SqlState.undefined);
+  }
+
+  public DisconnectException (Agent agent, String reason)
+  {
+    this (agent, reason, SqlState.undefined);
+  }
+
+  public DisconnectException (Throwable throwable, Agent agent, String reason)
+  {
+    this (throwable, agent, reason, SqlState.undefined);
+  }
+
+  public DisconnectException (Agent agent, SqlException e)
+  {
+    this (agent, e.getMessage());
+    setNextException (e);
+  }
+}
+
+

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/DisconnectException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/EncryptionManager.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/EncryptionManager.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/EncryptionManager.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/EncryptionManager.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,528 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.EncryptionManager
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+import java.security.Security;
+import java.security.Provider;
+
+// This class is get used when using encrypted password and/or userid mechanism.
+// The <b>EncryptionManager</b> classs uses Diffie_Hellman algorithm to get the publick key and
+// secret key, and then DES encryption is done using certain token (based on security
+// mechanism) and server side's public key. Basically, this class is called when using
+// security mechanism User ID and encrypted password (usrencpwd) and Encrypted user ID and password
+// (eusridpwd).
+// This class uses JCE provider to do Diffie_Hellman algorithm and DES encryption,
+// obtainPublicKey(), calculateEncryptionToken(int, byte[]) and encryptData(byte[], int, byte[], byte[])
+// The agreed public value for the Diffie-Hellman prime is 256 bits
+// and hence the encrytion will work only if the jce provider supports a 256 bits prime
+
+public class EncryptionManager
+{
+  transient Agent agent_; // for obtaining an exception log writer only
+
+  // PROTOCOL's Diffie-Hellman agreed public value: prime.
+  private static final byte modulusBytes__[] = {
+    (byte)0xC6, (byte)0x21, (byte)0x12, (byte)0xD7,
+    (byte)0x3E, (byte)0xE6, (byte)0x13, (byte)0xF0,
+    (byte)0x94, (byte)0x7A, (byte)0xB3, (byte)0x1F,
+    (byte)0x0F, (byte)0x68, (byte)0x46, (byte)0xA1,
+    (byte)0xBF, (byte)0xF5, (byte)0xB3, (byte)0xA4,
+    (byte)0xCA, (byte)0x0D, (byte)0x60, (byte)0xBC,
+    (byte)0x1E, (byte)0x4C, (byte)0x7A, (byte)0x0D,
+    (byte)0x8C, (byte)0x16, (byte)0xB3, (byte)0xE3
+  };
+
+  //the prime value in BigInteger form. It has to be in BigInteger form because this
+  //is the form used in JCE library.
+  private static final java.math.BigInteger modulus__
+  = new java.math.BigInteger (1, modulusBytes__);
+
+  //  PROTOCOL's Diffie-Hellman agreed public value: base.
+  private static final byte baseBytes__[] = {
+    (byte)0x46, (byte)0x90, (byte)0xFA, (byte)0x1F,
+    (byte)0x7B, (byte)0x9E, (byte)0x1D, (byte)0x44,
+    (byte)0x42, (byte)0xC8, (byte)0x6C, (byte)0x91,
+    (byte)0x14, (byte)0x60, (byte)0x3F, (byte)0xDE,
+    (byte)0xCF, (byte)0x07, (byte)0x1E, (byte)0xDC,
+    (byte)0xEC, (byte)0x5F, (byte)0x62, (byte)0x6E,
+    (byte)0x21, (byte)0xE2, (byte)0x56, (byte)0xAE,
+    (byte)0xD9, (byte)0xEA, (byte)0x34, (byte)0xE4
+  };
+
+  // The base value in BigInteger form.
+  private static final java.math.BigInteger base__ =
+    new java.math.BigInteger (1, baseBytes__);
+
+  //PROTOCOL's Diffie-Hellman agreed exponential length
+  private static final int exponential_length__ = 255;
+
+  private javax.crypto.spec.DHParameterSpec paramSpec_;
+  private java.security.KeyPairGenerator keyPairGenerator_;
+  private java.security.KeyPair keyPair_;
+  private javax.crypto.KeyAgreement keyAgreement_;
+
+  private byte[] token_; // init vector
+  private byte[] secKey_; // security key
+  private javax.crypto.SecretKeyFactory secretKeyFactory_ = null;
+  private String providerName; // security provider name
+  private Provider provider;
+
+  // EncryptionManager constructor. In this constructor,DHParameterSpec,
+  // KeyPairGenerator, KeyPair, and KeyAgreement  are initialized.
+  public EncryptionManager (Agent agent) throws SqlException
+  {
+    agent_ = agent;
+    try
+    {
+      // get a security provider that supports the diffie helman key agreement algorithm
+      Provider[] list = Security.getProviders("KeyAgreement.DH");
+      if(list == null)
+		 throw new java.security.NoSuchProviderException();
+      provider = list[0];
+      providerName = provider.getName();
+
+      java.security.Security.addProvider ((java.security.Provider) provider);
+
+      paramSpec_ = new javax.crypto.spec.DHParameterSpec (modulus__, base__, exponential_length__);
+      keyPairGenerator_ = java.security.KeyPairGenerator.getInstance ("DH", providerName);
+      keyPairGenerator_.initialize (paramSpec_);
+      keyPair_ = keyPairGenerator_.generateKeyPair();
+      keyAgreement_ = javax.crypto.KeyAgreement.getInstance ("DH", providerName);
+      keyAgreement_.init (keyPair_.getPrivate());
+    }
+    catch (java.security.NoSuchProviderException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchProviderException is caught" +
+                              " when initializing EncryptionManager '" + e.getMessage() + "'");
+    }
+    catch (java.security.NoSuchAlgorithmException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchAlgorithmException is caught" +
+            " when initializing EncryptionManager '" + e.getMessage() + "'");
+    }
+    catch (java.security.InvalidAlgorithmParameterException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.InvalidAlgorithmParameterException is caught" +
+            " when initializing EncryptionManager '" + e.getMessage() + "'");
+    }
+
+    catch (java.security.InvalidKeyException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.InvalidKeyException is caught" +
+            " when initializing EncryptionManager '" + e.getMessage() + "'");
+    }
+  }
+
+  // This method generates the public key and returns it. This
+  // shared public key is the application requester's connection key and will
+  // be exchanged with the application server's connection key. This connection
+  // key will be put in the sectkn in ACCSEC command and send to the application
+  // server.
+  // @param   null
+  // @return  a byte array that is the application requester's public key
+  public byte[] obtainPublicKey ()
+  {
+
+    //we need to get the plain form public key because PROTOCOL accepts plain form
+    //public key only.
+    java.math.BigInteger aPub = ((javax.crypto.interfaces.DHPublicKey) keyPair_.getPublic()).getY();
+    byte[] aPubKey = aPub.toByteArray();
+
+    //the following lines of code is to adjust the length of the key. PublicKey
+    //in JCE is in the form of BigInteger and it's a signed value. When tranformed
+    //to a Byte array form, normally this array is 32 bytes. However, if the
+    //value happens to take up all 32 X 8 bits and it is positive, an extra
+    //bit is needed and then a 33 byte array will be returned. Since PROTOCOL can't
+    //recogize the 33 byte key, we check the length here, if the length is 33,
+    //we will just trim off the first byte (0) and get the rest of 32 bytes.
+    if (aPubKey.length == 33 && aPubKey[0]==0) {
+      //System.out.println ("Adjust length");
+      byte[] newKey = new byte[32];
+      for (int i=0; i < newKey.length; i++)
+  newKey[i] = aPubKey[i+1];
+      return newKey;
+    }
+
+    //the following lines of code is to adjust the length of the key. Occasionally,
+    //the length of the public key is less than 32, the reason of this is that the 0 byte
+    //in the beginning is somehow not returned. So we check the length here, if the length
+    //is less than 32, we will pad 0 in the beginning to make the public key 32 bytes
+    if (aPubKey.length < 32) {
+      byte[] newKey = new byte[32];
+      int i;
+      for (i=0; i < 32-aPubKey.length; i++) {
+  newKey[i] = 0;
+      }
+      for (int j=i; j<newKey.length; j++)
+  newKey[j] = aPubKey[j-i];
+      return newKey;
+    }
+    return aPubKey;
+  }
+
+  // This method is used to calculate the encryption token. DES encrypts the
+  // data using a token and the generated shared private key. The token used
+  // depends on the type of security mechanism being used:
+  // USRENCPWD - The userid is used as the token. The USRID is zero-padded to
+  // 8 bytes if less than 8 bytes or truncated to 8 bytes if greater than 8 bytes.
+  // EUSRIDPWD - The middle 8 bytes of the server's connection key is used as
+  // the token.
+  // @param  int     securityMechanism
+  // @param  byte[]  userid or server's connection key
+  // @return byte[]  the encryption token
+  private byte[] calculateEncryptionToken (int securityMechanism, byte[] initVector)
+  {
+    byte[] token = new byte[8];
+
+    //USRENCPWD, the userid is used as token
+    if (securityMechanism == 7) {
+      if (initVector.length < 8) { //shorter than 8 bytes, zero padded to 8 bytes
+  for (int i=0; i<initVector.length; i++)
+    token[i] = initVector[i];
+  for (int i=initVector.length; i<8; i++)
+    token[i] = 0;
+      }
+      else {  //longer than 8 bytes, truncated to 8 bytes
+  for (int i=0; i<8; i++)
+    token[i] = initVector[i];
+      }
+    }
+    //EUSRIDPWD - The middle 8 bytes of the server's connection key is used as
+    //the token.
+    else if (securityMechanism == 9) {
+      for (int i = 0; i < 8; i++) {
+  token[i] = initVector[i + 12];
+      }
+    }
+    return token;
+  }
+
+  //JDK 1.4 has a parity check on the DES encryption key. Each byte needs to have an odd number
+  //of "1"s in it, and this is required by DES. Otherwise JDK 1.4 throws InvalidKeyException.
+  //Older JDK doesn't check this. In order to make encryption work with JDK1.4, we are going to
+  //check each of the 8 byte of our key and flip the last bit if it has even number of 1s.
+  private void keyParityCheck(byte[] key) throws SqlException
+  {
+     byte temp;
+     int changeParity;
+     if (key.length!=8)
+       throw new SqlException (agent_.logWriter_, "DES key has the wrong length");
+     for (int i=0; i<8; i++)
+     {
+  temp = key[i];
+  changeParity = 1;
+  for (int j=0; j<8; j++)
+  {
+    if (temp < 0)
+      changeParity = 1 - changeParity;
+    temp = (byte) (temp << 1);
+  }
+  if (changeParity == 1)
+  {
+    if ((key[i] & 1) != 0)
+      key[i] &= 0xfe;
+    else
+      key[i] |= 1;
+  }
+      }
+    }
+
+  // This method generates a secret key using the application server's
+  // public key
+  private byte[] generatePrivateKey (byte[] targetPublicKey) throws SqlException
+  {
+    try {
+
+      //initiate a Diffie_Hellman KeyFactory object.
+      java.security.KeyFactory keyFac = java.security.KeyFactory.getInstance ("DH", provider);
+
+      //Use server's public key to initiate a DHPublicKeySpec and then use
+      //this DHPublicKeySpec to initiate a publicKey object
+      java.math.BigInteger publicKey = new java.math.BigInteger (1, targetPublicKey);
+      javax.crypto.spec.DHPublicKeySpec dhKeySpec =
+        new javax.crypto.spec.DHPublicKeySpec (publicKey, modulus__, base__);
+      java.security.PublicKey pubKey = keyFac.generatePublic (dhKeySpec);
+
+      //Execute the first phase of DH keyagreement protocal.
+      keyAgreement_.doPhase (pubKey, true);
+
+      //generate the shared secret key. The application requestor's shared secret
+      //key should be exactly the same as the application server's shared secret
+      //key
+      byte[] sharedSecret = keyAgreement_.generateSecret();
+      byte[] newKey = new byte[32];
+
+      //We adjust the length here. If the length of secret key is 33 and the first byte is 0,
+      //we trim off the frist byte. If the length of secret key is less than 32, we will
+      //pad 0 to the beginning of the byte array tho make the secret key 32 bytes.
+      if (sharedSecret.length == 33 && sharedSecret[0] == 0) {
+  for (int i=0; i<newKey.length; i++)
+    newKey[i] = sharedSecret[i+1];
+
+      }
+      if (sharedSecret.length < 32) {
+  int i;
+  for (i=0; i<(32 - sharedSecret.length); i++) {
+    newKey[i] = 0;
+  }
+  for (int j=i; j<sharedSecret.length; j++)
+    newKey[j] = sharedSecret[j-i];
+      }
+
+      //The Data Encryption Standard (DES) is going to be used to encrypt userid
+      //and password. DES is a block cipher; it encrypts data in 64-bit blocks.
+      //PROTOCOL encryption uses DES CBC mode as defined by the FIPS standard
+      //DES CBC requires an encryption key and an 8 byte token to encrypt the data.
+      //The middle 8 bytes of Diffie-Hellman shared private key is used as the
+      //encryption key. The following code retrieves middle 8 bytes of the shared
+      //private key.
+      byte[] key = new byte[8];
+
+      //if secret key is not 32, we will use the adjust length secret key
+      if (sharedSecret.length==32) {
+  for (int i=0; i< 8;i++)
+    key[i] = sharedSecret[i+12];
+      }
+      else if (sharedSecret.length==33 || sharedSecret.length < 32) {
+  for (int i=0; i< 8;i++)
+    key[i] = newKey[i+12];
+      }
+      else
+  throw new SqlException (agent_.logWriter_, "sharedSecret key length error " + sharedSecret.length);
+
+      //we do parity check here and flip the parity bit if the byte has even number of 1s
+      keyParityCheck(key);
+      return key;
+      }/*
+      catch (java.security.NoSuchProviderException e) {
+        throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchProviderException is caught "
+                                + "when encrypting data '" + e.getMessage() + "'");
+      }*/
+      catch (java.security.NoSuchAlgorithmException e) {
+        throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchAlgorithmException is caught "
+                                + "when encrypting data '" + e.getMessage() + "'");
+      }
+      catch (java.security.spec.InvalidKeySpecException e) {
+        throw new SqlException (agent_.logWriter_, e, "java.security.InvalidKeySpecException is caught "
+                                + "when encrypting data");
+      }
+      catch (java.security.InvalidKeyException e) {
+        throw new SqlException (agent_.logWriter_, e, "java.security.InvalidKeyException is caught "
+                                + "when encrypting data '" + e.getMessage() + "'");
+      }
+
+
+  }
+
+  // This method encrypts the usreid/password with the middle 8 bytes of
+  // the generated secret key and an encryption token. Then it returns the
+  // encrypted data in a byte array.
+  // plainText   The byte array form userid/password to encrypt.
+  // initVector  The byte array which is used to calculate the
+  //                             encryption token.
+  // targetPublicKey   DERBY' public key.
+  // Returns the encrypted data in a byte array.
+  public byte[] encryptData (byte[] plainText,
+           int    securityMechanism,
+           byte[] initVector,
+           byte[] targetPublicKey) throws SqlException
+  {
+
+    byte[] cipherText = null;
+    java.security.Key key = null;
+
+    if (token_ == null)
+      token_ = calculateEncryptionToken (securityMechanism, initVector);
+
+    try{
+      if (secKey_ == null)
+      {
+        //use this encryption key to initiate a SecretKeySpec object
+        secKey_ = generatePrivateKey (targetPublicKey);
+        javax.crypto.spec.SecretKeySpec desKey = new javax.crypto.spec.SecretKeySpec (secKey_, "DES");
+        key = desKey;
+      }
+      else
+      {
+      //use this encryption key to initiate a SecretKeySpec object
+        javax.crypto.spec.DESKeySpec desKey = new javax.crypto.spec.DESKeySpec (secKey_);
+        if (secretKeyFactory_ == null)
+          secretKeyFactory_ = javax.crypto.SecretKeyFactory.getInstance("DES", providerName);
+        key = secretKeyFactory_.generateSecret(desKey);
+      }
+
+      //We use DES in CBC mode because this is the mode used in PROTOCOL. The
+      //encryption mode has to be consistent for encryption and decryption.
+      //CBC mode requires an initialization vector(IV) parameter. In CBC mode
+      //we need to initialize the Cipher object with an IV, which can be supplied
+      // using the javax.crypto.spec.IvParameterSpec class.
+      javax.crypto.Cipher cipher= javax.crypto.Cipher.getInstance ("DES/CBC/PKCS5Padding", providerName);
+
+      //generate a IVParameterSpec object and use it to initiate the
+      //Cipher object.
+      javax.crypto.spec.IvParameterSpec ivParam = new javax.crypto.spec.IvParameterSpec (token_);
+
+      //initiate the Cipher using encryption mode, encryption key and the
+      //IV parameter.
+      cipher.init (javax.crypto.Cipher.ENCRYPT_MODE, key, ivParam);
+
+      //Execute the final phase of encryption
+      cipherText = cipher.doFinal (plainText);
+    }
+    catch (java.security.NoSuchProviderException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchProviderException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.NoSuchAlgorithmException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchAlgorithmException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.InvalidKeyException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.InvalidKeyException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (javax.crypto.NoSuchPaddingException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.NoSuchPaddingException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (javax.crypto.BadPaddingException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.BadPaddingException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.InvalidAlgorithmParameterException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.InvalidAlgorithmParameterException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (javax.crypto.IllegalBlockSizeException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.IllegalBlockSizeException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.spec.InvalidKeySpecException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.IllegalBlockSizeException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    return cipherText;
+  }
+
+
+  // This method decrypts the usreid/password with the middle 8 bytes of
+  // the generated secret key and an encryption token. Then it returns the
+  // decrypted data in a byte array.
+  // plainText   The byte array form userid/password to encrypt.
+  // initVector  The byte array which is used to calculate the
+  //                             encryption token.
+  // targetPublicKey   DERBY' public key.
+  // Returns the decrypted data in a byte array.
+  public byte[] decryptData (byte[] cipherText,
+                             int    securityMechanism,
+                             byte[] initVector,
+                             byte[] targetPublicKey) throws SqlException
+  {
+
+    byte[] plainText = null;
+    java.security.Key key = null;
+
+    if (token_ == null)
+      token_ = calculateEncryptionToken (securityMechanism, initVector);
+
+    try{
+      if (secKey_ == null)
+      {
+        //use this encryption key to initiate a SecretKeySpec object
+        secKey_ = generatePrivateKey (targetPublicKey);
+        javax.crypto.spec.SecretKeySpec desKey = new javax.crypto.spec.SecretKeySpec (secKey_, "DES");
+        key = desKey;
+      }
+      else
+      {
+      //use this encryption key to initiate a SecretKeySpec object
+        javax.crypto.spec.DESKeySpec desKey = new javax.crypto.spec.DESKeySpec (secKey_);
+        if (secretKeyFactory_ == null)
+          secretKeyFactory_ = javax.crypto.SecretKeyFactory.getInstance("DES", providerName);
+        key = secretKeyFactory_.generateSecret(desKey);
+      }
+
+      //We use DES in CBC mode because this is the mode used in PROTOCOL. The
+      //encryption mode has to be consistent for encryption and decryption.
+      //CBC mode requires an initialization vector(IV) parameter. In CBC mode
+      //we need to initialize the Cipher object with an IV, which can be supplied
+      // using the javax.crypto.spec.IvParameterSpec class.
+      javax.crypto.Cipher cipher= javax.crypto.Cipher.getInstance ("DES/CBC/PKCS5Padding", providerName);
+
+      //generate a IVParameterSpec object and use it to initiate the
+      //Cipher object.
+      javax.crypto.spec.IvParameterSpec ivParam = new javax.crypto.spec.IvParameterSpec (token_);
+
+      //initiate the Cipher using encryption mode, encryption key and the
+      //IV parameter.
+      cipher.init (javax.crypto.Cipher.DECRYPT_MODE, key,ivParam);
+
+      //Execute the final phase of encryption
+      plainText = cipher.doFinal (cipherText);
+    }
+    catch (java.security.NoSuchProviderException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchProviderException is caught "
+                              + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.NoSuchAlgorithmException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.NoSuchAlgorithmException is caught "
+                              + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.InvalidKeyException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.InvalidKeyException is caught "
+                              + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (javax.crypto.NoSuchPaddingException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.NoSuchPaddingException is caught "
+                              + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (javax.crypto.BadPaddingException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.BadPaddingException is caught "
+                              + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.InvalidAlgorithmParameterException e) {
+      throw new SqlException (agent_.logWriter_, e, "java.security.InvalidAlgorithmParameterException is caught "
+                              + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (javax.crypto.IllegalBlockSizeException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.IllegalBlockSizeException is caught "
+                              + "when encrypting data '" + e.getMessage() + "'");
+    }
+    catch (java.security.spec.InvalidKeySpecException e) {
+      throw new SqlException (agent_.logWriter_, e, "javax.crypto.IllegalBlockSizeException is caught "
+            + "when encrypting data '" + e.getMessage() + "'");
+    }
+    return plainText;
+  }
+
+  public void setInitVector(byte[] initVector)
+  {
+     token_ = initVector;
+  }
+
+  public void setSecKey(byte[] secKey)
+  {
+    secKey_ = secKey;
+  }
+
+  public void resetSecurityKeys()
+  {
+    token_ = null;
+    secKey_ = null;
+  }
+
+}
+

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/EncryptionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ErrorKey.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ErrorKey.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ErrorKey.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ErrorKey.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,49 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.ErrorKey
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+
+package org.apache.derby.client.am;
+
+
+// This class associates the SQL states and error codes with every possible exception
+// as distinguished by a unique resourceKey.
+public class ErrorKey
+{
+  private String resourceKey_;
+  private String sqlState_;
+  private int errorCode_;
+
+
+  String getResourceKey ()
+  {
+    return resourceKey_;
+  }
+
+  String getSQLState ()
+  {
+    return sqlState_;
+  }
+
+  int getErrorCode ()
+  {
+    return errorCode_;
+  }
+}
+
+

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ErrorKey.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ExceptionFormatter.java
URL: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ExceptionFormatter.java?rev=165178&view=auto
==============================================================================
--- incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ExceptionFormatter.java (added)
+++ incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ExceptionFormatter.java Thu Apr 28 12:05:42 2005
@@ -0,0 +1,214 @@
+/*
+
+   Derby - Class org.apache.derby.client.am.ExceptionFormatter
+
+   Copyright (c) 2001, 2005 The Apache Software Foundation or its licensors, where applicable.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+*/
+package org.apache.derby.client.am;
+
+public class ExceptionFormatter
+{
+  // returnTokensOnly is true only when exception tracing is enabled so
+  // that we don't try to go to the server for a message while we're in
+  // the middle of parsing an Sqlca reply.
+  // Without this, if e.getMessage() fails, we would have infinite recursion
+  // when TRACE_DIAGNOSTICS is on  because tracing occurs within the exception constructor.
+  static public void printTrace (java.sql.SQLException e,
+                                 java.io.PrintWriter printWriter,
+                                 String messageHeader,
+                                 boolean returnTokensOnly)
+  {
+    String header;
+    synchronized (printWriter) {
+      while (e != null) {
+        if (e instanceof java.sql.DataTruncation) {
+          header = messageHeader + "[" + "DataTruncation@" + Integer.toHexString (e.hashCode()) + "]";
+          printWriter.println (header + " java.sql.DataTruncation");
+        }
+        else if (e instanceof java.sql.SQLWarning) {
+          header = messageHeader + "[" + "SQLWarning@" + Integer.toHexString (e.hashCode()) + "]";
+          printWriter.println (header  + " java.sql.SQLWarning");
+        }
+        else if (e instanceof java.sql.BatchUpdateException) {
+          header = messageHeader + "[" + "BatchUpdateException@" + Integer.toHexString (e.hashCode()) + "]";
+          printWriter.println (header  + " java.sql.BatchUpdateException");
+        }
+        else { // e instanceof java.sql.SQLException
+          header = messageHeader + "[" + "SQLException@" + Integer.toHexString (e.hashCode()) + "]";
+          printWriter.println (header  + " java.sql.SQLException");
+        }
+
+        if (e instanceof Diagnosable) {
+          java.lang.Throwable throwable = null;
+          try {
+            throwable = ((Diagnosable) e).getThrowable();
+          }
+          catch (java.lang.NoSuchMethodError doNothing) {
+          }
+          if (throwable != null) {
+            printTrace (throwable, printWriter, header);
+          }
+          Sqlca sqlca = ((Diagnosable) e).getSqlca();
+          if (sqlca != null) {
+            printTrace (sqlca, printWriter, header);
+            // JDK stack trace calls e.getMessage(), so we must set some state on the sqlca that says return tokens only.
+           ((Sqlca) sqlca).returnTokensOnlyInMessageText (returnTokensOnly);
+          }
+        }
+
+        printWriter.println (header +   " SQL state  = " + e.getSQLState ());
+        printWriter.println (header +   " Error code = " + String.valueOf (e.getErrorCode ()));
+        if (!(e instanceof Diagnosable)) {
+          printWriter.println (header +   " Message    = " + e.getMessage());
+        }
+        else {
+          if (((Diagnosable) e).getSqlca() == null)
+	  { // Too much has changed, so escape out here.
+            printWriter.println (header +   " Message    = " + e.getMessage());
+          }
+          else { // This is server-side error.
+            Sqlca sqlca = (Sqlca) ((Diagnosable) e).getSqlca();
+            if (returnTokensOnly) {
+              // print message tokens directly.
+              printWriter.println (header + " Tokens     = " + sqlca.getSqlErrmc()); // a string containing error tokens only
+            }
+            else {
+              // Try to get message text from server.
+              String message = e.getMessage();
+              if (!sqlca.messageTextRetrievedContainsTokensOnly_) { // got the message text.
+                printWriter.println (header + " Message    = " + message);
+              }
+              else { // got only message tokens.
+                java.sql.SQLException mysteryException = sqlca.exceptionThrownOnStoredProcInvocation_;
+                if (mysteryException != null &&
+                    (mysteryException.getErrorCode() == -440 || mysteryException.getErrorCode() == -444)) {
+                  printWriter.println (header + " Unable to obtain message text from server." +
+                                                " Only message tokens are available." +
+                                                " The stored procedure SYSIBM.SQLCAMESSAGE is not installed on server." +
+                                                " Contact your DBA.");
+                }
+                else {
+                  printWriter.println (header + " Error occurred while trying to obtain message text from server. " +
+                                                "Only message tokens are available.");
+                }
+                printWriter.println (header + " Tokens     = " + message);
+              }
+            }
+          }
+        }
+
+        if (e instanceof java.sql.DataTruncation) {
+          printWriter.println (header + " Index         = " + ((java.sql.DataTruncation) e).getIndex());
+          printWriter.println (header + " Parameter     = " + ((java.sql.DataTruncation) e).getParameter());
+          printWriter.println (header + " Read          = " + ((java.sql.DataTruncation) e).getRead());
+          printWriter.println (header + " Data size     = " + ((java.sql.DataTruncation) e).getDataSize());
+          printWriter.println (header + " Transfer size = " + ((java.sql.DataTruncation) e).getTransferSize());
+        }
+
+        if (e instanceof java.sql.BatchUpdateException) {
+          printWriter.println (header + " Update counts = " + Utils.getStringFromInts (((java.sql.BatchUpdateException) e).getUpdateCounts()));
+        }
+
+        printWriter.println (header + " Stack trace follows");
+        e.printStackTrace (printWriter);
+
+        if (e instanceof Diagnosable) {
+          Sqlca sqlca = (Sqlca) ((Diagnosable) e).getSqlca();
+          if (sqlca != null) {
+            // JDK stack trace calls e.getMessage(), now that it is finished,
+            // we can reset the state on the sqlca that says return tokens only.
+            sqlca.returnTokensOnlyInMessageText (false);
+          }
+        }
+
+        e = e.getNextException ();
+      }
+
+      printWriter.flush();
+    }
+  }
+
+  static public void printTrace (Sqlca sqlca,
+                                 java.io.PrintWriter printWriter,
+                                 String messageHeader)
+  {
+    String header = messageHeader + "[" + "Sqlca@" + Integer.toHexString (sqlca.hashCode()) + "]";
+    synchronized (printWriter) {
+      printWriter.println (header + " DERBY SQLCA from server");
+      printWriter.println (header + " SqlCode        = " + sqlca.getSqlCode());
+      printWriter.println (header + " SqlErrd        = " + Utils.getStringFromInts (sqlca.getSqlErrd()));
+      printWriter.println (header + " SqlErrmc       = " + sqlca.getSqlErrmc());
+      printWriter.println (header + " SqlErrmcTokens = " + Utils.getStringFromStrings (sqlca.getSqlErrmcTokens()));
+      printWriter.println (header + " SqlErrp        = " + sqlca.getSqlErrp());
+      printWriter.println (header + " SqlState       = " + sqlca.getSqlState());
+      printWriter.println (header + " SqlWarn        = " + new String (sqlca.getSqlWarn()));
+    }
+  }
+
+  static public void printTrace (java.lang.Throwable e,
+                                 java.io.PrintWriter printWriter,
+                                 String messageHeader)
+  {
+    String header = messageHeader + "[" + "Throwable@" + Integer.toHexString (e.hashCode()) + "]";
+    synchronized (printWriter) {
+      printWriter.println (header + " " + e.getClass().getName());
+      printWriter.println (header + " Message = " + e.getMessage ());
+      printWriter.println (header + " Stack trace follows");
+      e.printStackTrace (printWriter);
+    }
+  }
+
+  static public void printTrace (javax.transaction.xa.XAException e,
+                                 java.io.PrintWriter printWriter,
+                                 String messageHeader)
+  {
+    String header = messageHeader + "[" + "XAException@" + Integer.toHexString (e.hashCode()) + "]";
+    synchronized (printWriter) {
+      printWriter.println (header + " javax.transaction.xa.XAException");
+      printWriter.println (header + " Message = " + e.getMessage ());
+      printWriter.println (header + " Stack trace follows");
+
+      e.printStackTrace (printWriter);
+
+      if(! ((org.apache.derby.client.am.Configuration.jreLevelMajor == 1) &&
+           (org.apache.derby.client.am.Configuration.jreLevelMinor >= 4)) ||
+          (org.apache.derby.client.am.Configuration.jreLevelMajor > 1) )
+      { // If not jre 1.4 or above, we need to print the cause if there is one
+        // For jre 1.4 or above, e.printStackTrace() will print the cause automatically
+        if (e instanceof Diagnosable) {
+          java.lang.Throwable throwable = null;
+          try {
+            throwable = ((Diagnosable) e).getThrowable();
+          }
+          catch (java.lang.NoSuchMethodError doNothing) {
+          }
+          if (throwable != null)
+          {
+            printWriter.print ("Caused by: ");
+            if (throwable instanceof java.sql.SQLException)
+            {
+              throwable.printStackTrace (printWriter);
+            }
+            else
+            {
+              printTrace (throwable, printWriter, header);
+            }
+          }
+        }
+      }
+    }
+  }
+}

Propchange: incubator/derby/code/trunk/java/client/org/apache/derby/client/am/ExceptionFormatter.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message