svn commit: r959470 - in /ofbiz/trunk/framework/entity: dtd/ entitydef/ fieldtype/ src/org/ofbiz/entity/jdbc/ src/org/ofbiz/entity/model/ src/org/ofbiz/entity/test/

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r959470 - in /ofbiz/trunk/framework/entity: dtd/ entitydef/ fieldtype/ src/org/ofbiz/entity/jdbc/ src/org/ofbiz/entity/model/ src/org/ofbiz/entity/test/

adrianc
Author: adrianc
Date: Wed Jun 30 23:27:24 2010
New Revision: 959470

URL: http://svn.apache.org/viewvc?rev=959470&view=rev
Log:
Some work on the entity engine:

1. Removed the conversion framework from the entity engine. Type conversions should be done higher up in the stack. The basic pattern is the same, but instead of each ModelFieldType containing a converter instance, it now contains a JdbcValueHandler instance. The JdbcValueHandler performs the same task as the original switch statement - in effect each ModelFieldType contains its own piece of the switch statement.

2. Added two new field types: byte[] and Object. Originally, the Blob field type was a catch-all for multiple Java data types. This change disambiguates the field's contents.

This has been tested on Advantage, Derby, and MySQL. It should be completely backward compatible. I will be monitoring the dev mailing list closely for any problems.


Added:
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java   (with props)
Modified:
    ofbiz/trunk/framework/entity/dtd/fieldtypemodel.xsd
    ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypeadvantage.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypeaxion.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypecloudscape.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypedaffodil.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypederby.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypefirebird.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypehsql.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypemssql.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypemysql.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypeoracle.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypepostgres.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypepostnew.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypesapdb.xml
    ofbiz/trunk/framework/entity/fieldtype/fieldtypesybase.xml
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelFieldType.java
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java

Modified: ofbiz/trunk/framework/entity/dtd/fieldtypemodel.xsd
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/dtd/fieldtypemodel.xsd?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/dtd/fieldtypemodel.xsd (original)
+++ ofbiz/trunk/framework/entity/dtd/fieldtypemodel.xsd Wed Jun 30 23:27:24 2010
@@ -41,7 +41,95 @@ under the License.
         <xs:attribute type="xs:string" name="type" use="required"/>
         <xs:attribute type="xs:string" name="sql-type" use="required"/>
         <xs:attribute type="xs:string" name="sql-type-alias"/>
-        <xs:attribute type="xs:string" name="java-type" use="required"/>
+        <xs:attribute name="java-type" use="required">
+            <xs:annotation><xs:documentation>
+                The java-type attribute must contain a Java data type
+                recognized by the JDBC driver (ResultSet getXxx methods
+                or PreparedStatement setXxx methods).
+            </xs:documentation></xs:annotation>
+            <!-- Developers Note: SQL type to Java type mapping taken from
+            http://java.sun.com/j2se/1.4.2/docs/guide/jdbc/getstart/mapping.html -->
+         <xs:simpleType>
+                <xs:restriction base="xs:string">
+                    <xs:enumeration value="byte[]">
+                        <xs:annotation><xs:documentation>
+                            Use with BLOB, BINARY, VARBINARY, and LONGVARBINARY SQL types
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="Boolean">
+                        <xs:annotation><xs:documentation>
+                            Use with BIT and BOOLEAN SQL types
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="Double">
+                        <xs:annotation><xs:documentation>
+                            Use with DOUBLE and FLOAT SQL types
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="Float">
+                        <xs:annotation><xs:documentation>
+                            Use with REAL SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="Integer">
+                        <xs:annotation><xs:documentation>
+                            Use with INTEGER SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="Long">
+                        <xs:annotation><xs:documentation>
+                            Use with BIGINT SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="Object">
+                        <xs:annotation><xs:documentation>
+                            Use with BLOB and LONGVARBINARY SQL types
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="Short">
+                        <xs:annotation><xs:documentation>
+                            Use with SMALLINT and TINYINT SQL types
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+         <xs:enumeration value="String">
+            <xs:annotation><xs:documentation>
+                Use with CLOB, CHAR, VARCHAR,
+                and LONGVARCHAR SQL types
+            </xs:documentation></xs:annotation>
+         </xs:enumeration>
+                    <xs:enumeration value="java.math.BigDecimal">
+                        <xs:annotation><xs:documentation>
+                            Use with DECIMAL and NUMERIC SQL types
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="java.sql.Blob">
+                        <xs:annotation><xs:documentation>
+                            Use with BLOB SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="java.sql.Clob">
+                        <xs:annotation><xs:documentation>
+                            Use with CLOB SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="java.sql.Date">
+                        <xs:annotation><xs:documentation>
+                            Use with DATE SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="java.sql.Time">
+                        <xs:annotation><xs:documentation>
+                            Use with TIME SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+                    <xs:enumeration value="java.sql.Timestamp">
+                        <xs:annotation><xs:documentation>
+                            Use with TIMESTAMP SQL type
+                        </xs:documentation></xs:annotation>
+                    </xs:enumeration>
+         </xs:restriction>
+         </xs:simpleType>
+        </xs:attribute>
     </xs:attributeGroup>
     <xs:element name="validate">
         <xs:complexType>

Modified: ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml (original)
+++ ofbiz/trunk/framework/entity/entitydef/entitymodel_test.xml Wed Jun 30 23:27:24 2010
@@ -90,6 +90,8 @@ under the License.
         <description>An entity for testing the field data types</description>
         <field name="testFieldTypeId" type="id-ne"/>
         <field name="blobField" type="blob"/>
+        <field name="byteArrayField" type="byte-array"/>
+        <field name="objectField" type="object"/>
         <field name="dateField" type="date"/>
         <field name="timeField" type="time"/>
         <field name="dateTimeField" type="date-time"/>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypeadvantage.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypeadvantage.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypeadvantage.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypeadvantage.xml Wed Jun 30 23:27:24 2010
@@ -26,6 +26,8 @@ under the License.
     <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="Blob" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="Blob" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="Blob" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TimeStamp" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="Date" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypeaxion.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypeaxion.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypeaxion.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypeaxion.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
    <!-- General Types -->
     <field-type-def type="blob" sql-type="BLOB" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="BLOB" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="BLOB" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMP" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypecloudscape.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypecloudscape.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypecloudscape.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypecloudscape.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
    <!-- General Types -->
     <field-type-def type="blob" sql-type="LONG VARBINARY" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="LONG VARBINARY" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="LONG VARBINARY" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="DATE" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypedaffodil.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypedaffodil.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypedaffodil.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypedaffodil.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
    <!-- General Types -->
     <field-type-def type="blob" sql-type="BLOB" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="BLOB" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="BLOB" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMP" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypederby.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypederby.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypederby.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypederby.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="BLOB" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="BLOB" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="BLOB" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMP" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypefirebird.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypefirebird.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypefirebird.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypefirebird.xml Wed Jun 30 23:27:24 2010
@@ -23,7 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
    <!-- General Types -->
     <field-type-def type="blob" sql-type="BLOB" java-type="java.sql.Blob"></field-type-def>
-    <field-type-def type="blob" sql-type="BLOB SUB_TYPE 2" java-type="java.lang.Object"></field-type-def>
+    <field-type-def type="byte-array" sql-type="BLOB" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="BLOB SUB_TYPE 2" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMP" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypehsql.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypehsql.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypehsql.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypehsql.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="OBJECT" sql-type-alias="OTHER" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="OBJECT" sql-type-alias="OTHER" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="OBJECT" sql-type-alias="OTHER" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMP" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypemssql.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypemssql.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypemssql.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypemssql.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="IMAGE" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="IMAGE" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="IMAGE" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="DATETIME" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATETIME" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypemysql.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypemysql.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypemysql.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypemysql.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="LONGBLOB" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="LONGBLOB" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="LONGBLOB" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="DATETIME" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypeoracle.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypeoracle.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypeoracle.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypeoracle.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="BLOB" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="BLOB" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="BLOB" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMP" sql-type-alias="TIMESTAMP(6)" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypepostgres.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypepostgres.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypepostgres.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypepostgres.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="BYTEA" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="BYTEA" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="BYTEA" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMPTZ" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypepostnew.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypepostnew.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypepostnew.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypepostnew.xml Wed Jun 30 23:27:24 2010
@@ -54,6 +54,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="BYTEA" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="BYTEA" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="BYTEA" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMPTZ" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypesapdb.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypesapdb.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypesapdb.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypesapdb.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
    <!-- General Types -->
     <field-type-def type="blob" sql-type="LONG BYTE" sql-type-alias="LONG BYTE" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="LONG BYTE" sql-type-alias="LONG BYTE" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="LONG BYTE" sql-type-alias="LONG BYTE" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="TIMESTAMP" java-type="java.sql.Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATE" java-type="java.sql.Date"></field-type-def>

Modified: ofbiz/trunk/framework/entity/fieldtype/fieldtypesybase.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/fieldtype/fieldtypesybase.xml?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/fieldtype/fieldtypesybase.xml (original)
+++ ofbiz/trunk/framework/entity/fieldtype/fieldtypesybase.xml Wed Jun 30 23:27:24 2010
@@ -23,6 +23,8 @@ under the License.
   <!-- ===================== field-type-def ==================== -->
     <!-- General Types -->
     <field-type-def type="blob" sql-type="IMAGE" java-type="java.sql.Blob"></field-type-def>
+    <field-type-def type="byte-array" sql-type="IMAGE" java-type="byte[]"></field-type-def>
+    <field-type-def type="object" sql-type="IMAGE" java-type="Object"></field-type-def>
 
     <field-type-def type="date-time" sql-type="DATETIME" java-type="Timestamp"></field-type-def>
     <field-type-def type="date" sql-type="DATETIME" java-type="java.sql.Date"></field-type-def>

Added: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java?rev=959470&view=auto
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java (added)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java Wed Jun 30 23:27:24 2010
@@ -0,0 +1,719 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.ofbiz.entity.jdbc;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Reader;
+import java.sql.Blob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+
+import javax.sql.rowset.serial.SerialBlob;
+
+import javolution.util.FastMap;
+
+import org.ofbiz.base.util.Debug;
+
+/**
+ * An object that handles getting/setting column values in JDBC
+ * <code>PreparedStatement</code> and <code>ResultSet</code> objects.
+ *
+ */
+public abstract class JdbcValueHandler {
+    public static final String module = JdbcValueHandler.class.getName();
+    private static final Map<String, JdbcValueHandler> JdbcValueHandlerMap = createJdbcValueHandlerMap();
+    private static final Map<String, Integer> SqlTypeMap = createSqlTypeMap();
+
+    private static Map<String, JdbcValueHandler> createJdbcValueHandlerMap() {
+        /*
+        This Map is used to select the correct JdbcValueHandler
+        for the specified Java type. The JdbcValueHandler instances are
+        initialized with the SQL type recommended by Sun/Oracle.
+         */
+        Map<String, JdbcValueHandler> result = FastMap.newInstance();
+        // JDBC 1
+        result.put("byte[]", new ByteArrayJdbcValueHandler(Types.LONGVARBINARY));
+        result.put("java.lang.Boolean", new BooleanJdbcValueHandler(Types.BOOLEAN));
+        result.put("Boolean", new BooleanJdbcValueHandler(Types.BOOLEAN));
+        result.put("java.lang.Double", new DoubleJdbcValueHandler(Types.DOUBLE));
+        result.put("Double", new DoubleJdbcValueHandler(Types.DOUBLE));
+        result.put("java.lang.Float", new FloatJdbcValueHandler(Types.FLOAT));
+        result.put("Float", new FloatJdbcValueHandler(Types.FLOAT));
+        result.put("java.lang.Integer", new IntegerJdbcValueHandler(Types.INTEGER));
+        result.put("Integer", new IntegerJdbcValueHandler(Types.INTEGER));
+        result.put("java.lang.Long", new LongJdbcValueHandler(Types.BIGINT));
+        result.put("Long", new LongJdbcValueHandler(Types.BIGINT));
+        result.put("java.lang.Short", new ShortJdbcValueHandler(Types.SMALLINT));
+        result.put("Short", new ShortJdbcValueHandler(Types.SMALLINT));
+        result.put("java.lang.String", new StringJdbcValueHandler(Types.CHAR));
+        result.put("String", new StringJdbcValueHandler(Types.CHAR));
+        result.put("java.sql.Date", new DateJdbcValueHandler(Types.DATE));
+        result.put("Date", new DateJdbcValueHandler(Types.DATE));
+        result.put("java.sql.Time", new TimeJdbcValueHandler(Types.TIME));
+        result.put("Time", new TimeJdbcValueHandler(Types.TIME));
+        result.put("java.sql.Timestamp", new TimestampJdbcValueHandler(Types.TIMESTAMP));
+        result.put("Timestamp", new TimestampJdbcValueHandler(Types.TIMESTAMP));
+        // JDBC 2
+        result.put("java.math.BigDecimal", new BigDecimalJdbcValueHandler(Types.DECIMAL));
+        result.put("BigDecimal", new BigDecimalJdbcValueHandler(Types.DECIMAL));
+        result.put("java.sql.Blob", new BlobJdbcValueHandler(Types.BLOB));
+        result.put("Blob", new BlobJdbcValueHandler(Types.BLOB));
+        result.put("java.sql.Clob", new ClobJdbcValueHandler(Types.CLOB));
+        result.put("Clob", new ClobJdbcValueHandler(Types.CLOB));
+        // Non-JDBC Types
+        result.put("java.lang.Object", new ObjectJdbcValueHandler(Types.BLOB));
+        result.put("Object", new ObjectJdbcValueHandler(Types.BLOB));
+        return result;
+    }
+
+    private static Map<String, Integer> createSqlTypeMap() {
+        /*
+        This Map is used to select the correct SQL data type
+        for the PreparedStatement.setNull method. The setNull
+        method must be called with the correct type, or an
+        exception will be thrown.
+         */
+        Map<String, Integer> result = FastMap.newInstance();
+        // SQL 99 Data Types
+        result.put("BIT", Types.BIT);
+        result.put("BLOB", Types.BLOB);
+        result.put("BOOLEAN", Types.BOOLEAN);
+        result.put("CHAR", Types.CHAR);
+        result.put("CHARACTER", Types.CHAR);
+        result.put("CLOB", Types.CLOB);
+        result.put("DATE", Types.DATE);
+        result.put("DEC", Types.DECIMAL);
+        result.put("DECIMAL", Types.DECIMAL);
+        result.put("DOUBLE", Types.DOUBLE);
+        result.put("DOUBLE PRECISION", Types.DOUBLE);
+        result.put("FLOAT", Types.FLOAT);
+        result.put("INT", Types.INTEGER);
+        result.put("INTEGER", Types.INTEGER);
+        result.put("NUMERIC", Types.NUMERIC);
+        result.put("REAL", Types.REAL);
+        result.put("SMALLINT", Types.SMALLINT);
+        result.put("TIME", Types.TIME);
+        result.put("TIMESTAMP", Types.TIMESTAMP);
+        result.put("VARCHAR", Types.VARCHAR);
+        result.put("CHAR VARYING", Types.VARCHAR);
+        result.put("CHARACTER VARYING", Types.VARCHAR);
+        // DB2, MS SQL Data Types
+        result.put("LONGVARCHAR", Types.LONGVARCHAR);
+        result.put("LONG VARCHAR", Types.LONGVARCHAR);
+        result.put("BIGINT", Types.BIGINT);
+        result.put("TEXT", Types.LONGVARCHAR);
+        result.put("IMAGE", Types.BLOB);
+        result.put("BINARY", Types.BINARY);
+        result.put("VARBINARY", Types.VARBINARY);
+        result.put("LONGVARBINARY", Types.LONGVARBINARY);
+        result.put("LONG VARBINARY", Types.LONGVARBINARY);
+        // Note: Do NOT map the DATETIME SQL data type, the
+        // java-type will be used to select the correct data type
+        return result;
+    }
+
+    /** Returns the <code>JdbcValueHandler</code> that corresponds to a field
+     * type.
+     *  
+     * @param javaType The Java type specified in fieldtype*.xml
+     * @param sqlType The SQL type specified in fieldtype*.xml
+     * @return A <code>JdbcValueHandler</code> instance
+     */
+    public static JdbcValueHandler getInstance(String javaType, String sqlType) {
+        JdbcValueHandler handler = JdbcValueHandlerMap.get(javaType);
+        if (handler != null) {
+            String key = parseSqlType(sqlType);
+            Integer sqlTypeInt = SqlTypeMap.get(key);
+            if (sqlTypeInt != null) {
+                handler = handler.create(sqlTypeInt);
+            }
+        }
+        return handler;
+    }
+
+    protected static String parseSqlType(String sqlType) {
+        String result = sqlType.toUpperCase();
+        int pos = result.indexOf("(");
+        if (pos != -1) {
+            result = result.substring(0, pos);
+        }
+        return result;
+    }
+
+    protected static byte[] serializeObject(Object obj) throws SQLException {
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        ObjectOutputStream oos = null;
+        try {
+            oos = new ObjectOutputStream(os);
+            oos.writeObject(obj);
+            os.close();
+        } catch (IOException e) {
+            throw new SQLException(e);
+        } finally {
+            if (oos != null) {
+                try {
+                    oos.close();
+                } catch (IOException e) {}
+            }
+        }
+        return os.toByteArray();
+    }
+
+    protected static byte[] toByteArray(java.sql.Blob blob) throws SQLException {
+        InputStream inStream = null;
+        try {
+            inStream = blob.getBinaryStream();
+            int blobLength = (int) blob.length();
+            byte[] byteBuffer = new byte[blobLength];
+            int offset = 0;
+            int bytesRead = inStream.read(byteBuffer, offset, blobLength);
+            while (bytesRead > 0) {
+                offset += bytesRead;
+                bytesRead = inStream.read(byteBuffer, offset, blobLength);
+            }
+            return byteBuffer;
+        } catch (Exception e) {
+            throw new SQLException(e);
+        }
+        finally {
+            if (inStream != null) {
+                try {
+                    inStream.close();
+                } catch (IOException e) {}
+            }
+        }
+    }
+
+    // The target database SQL type to be used for the
+    // PreparedStatement.setNull method.
+    private final int sqlType;
+
+    protected JdbcValueHandler(int sqlType) {
+        this.sqlType = sqlType;
+    }
+
+    /** Sets a value in a <code>PreparedStatement</code>. The
+     * <code>obj</code> argument is converted to the correct data
+     * type. Subclasses override this method to cast <code>obj</code>
+     * to the correct data type and call the appropriate
+     * <code>PreparedStatement.setXxx</code> method.
+     *
+     * @param ps
+     * @param parameterIndex
+     * @param obj
+     * @throws SQLException
+     */
+    protected abstract void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException;
+
+    protected JdbcValueHandler create(int sqlType) {
+        if (sqlType == this.getSqlType()) {
+            return this;
+        }
+        return newInstance(sqlType);
+    }
+
+    /**
+     * Returns the SQL type for this handler.
+     * @return
+     * @see <code>java.sql.Types</code>
+     */
+    public int getSqlType() {
+        return this.sqlType;
+    }
+
+    /** Returns a value from a <code>ResultSet</code>. The returned
+     * object is converted to the Java data type specified in the fieldtype
+     * file.
+     *
+     * @param rs
+     * @param columnIndex
+     * @return
+     * @throws SQLException
+     */
+    public abstract Object getValue(ResultSet rs, int columnIndex) throws SQLException;
+
+    /**
+     * Returns a new instance of the object - initialized with
+     * the specified SQL type.
+     * @param sqlType
+     * @return
+     */
+    protected abstract JdbcValueHandler newInstance(int sqlType);
+
+    /** Sets a value in a <code>PreparedStatement</code>. The
+     * <code>obj</code> argument is converted to the correct data
+     * type.
+     *
+     * @param ps
+     * @param parameterIndex
+     * @param obj
+     * @throws SQLException
+     */
+    public void setValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+        if (obj == null) {
+            ps.setNull(parameterIndex, this.getSqlType());
+            return;
+        }
+        this.castAndSetValue(ps, parameterIndex, obj);
+    }
+
+    /**
+     * A <code>java.math.BigDecimal</code> JDBC value handler.
+     */
+    protected static class BigDecimalJdbcValueHandler extends JdbcValueHandler {
+        protected BigDecimalJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setBigDecimal(parameterIndex, (java.math.BigDecimal) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            return rs.getBigDecimal(columnIndex);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new BigDecimalJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.sql.Blob</code> JDBC value handler.
+     */
+    protected static class BlobJdbcValueHandler extends JdbcValueHandler {
+        protected BlobJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            try {
+                // FIXME: This is here for backwards compatibility. Client code
+                // that uses a Blob java-type for a byte array should use a
+                // byte[] java-type instead.
+                byte[] bytes = (byte[]) obj;
+                Debug.logWarning("Blob java-type used for byte array. Use byte[] java-type instead.", module);
+                ps.setBytes(parameterIndex, bytes);
+                return;
+            } catch (ClassCastException e) {}
+            ps.setBlob(parameterIndex, (Blob) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            // FIXME: This code is here for backwards compatibility. Client code
+            // that uses a Blob java-type for non-Blob types should be updated
+            // to use the correct type.
+            Object originalObject;
+            byte[] fieldBytes;
+            try {
+                Blob theBlob = rs.getBlob(columnIndex);
+                fieldBytes = toByteArray(theBlob);
+                originalObject = theBlob;
+            } catch (SQLException e) {
+                // for backward compatibility if getBlob didn't work try getBytes
+                fieldBytes = rs.getBytes(columnIndex);
+                originalObject = fieldBytes;
+            }
+            if (originalObject != null) {
+                // for backward compatibility, check to see if there is a serialized object and if so return that
+                Object blobObject = null;
+                ObjectInputStream in = null;
+                try {
+                    in = new ObjectInputStream(new ByteArrayInputStream(fieldBytes));
+                    blobObject = in.readObject();
+                } catch (IOException e) {
+                    if (Debug.verboseOn()) Debug.logVerbose(e, "Unable to read BLOB data from input stream", module);
+                } catch (ClassNotFoundException e) {
+                    if (Debug.verboseOn()) Debug.logVerbose(e, "Class not found: Unable to cast BLOB data to an Java object while getting value, most likely because it is a straight byte[], so just using the raw bytes", module);
+                } finally {
+                    if (in != null) {
+                        try {
+                            in.close();
+                        } catch (IOException e) {}
+                    }
+                }
+                if (blobObject != null) {
+                    Debug.logWarning("Blob java-type used for java.lang.Object. Use java.lang.Object java-type instead.", module);
+                    return blobObject;
+                } else {
+                    if (originalObject instanceof Blob) {
+                        // NOTE using SerialBlob here instead of the Blob from the database to make sure we can pass it around, serialize it, etc
+                        return new SerialBlob((Blob) originalObject);
+                    } else {
+                        Debug.logWarning("Blob java-type used for byte array. Use byte[] java-type instead.", module);
+                        return originalObject;
+                    }
+                }
+            }
+            return null;
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new BlobJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.Boolean</code> JDBC value handler.
+     */
+    protected static class BooleanJdbcValueHandler extends JdbcValueHandler {
+        protected BooleanJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setBoolean(parameterIndex, (Boolean) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            boolean value = rs.getBoolean(columnIndex);
+            return rs.wasNull() ? null : Boolean.valueOf(value);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new BooleanJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>byte[]</code> JDBC value handler.
+     */
+    protected static class ByteArrayJdbcValueHandler extends JdbcValueHandler {
+        protected ByteArrayJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setBytes(parameterIndex, (byte[]) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            byte[] value = rs.getBytes(columnIndex);
+            return rs.wasNull() ? null : value;
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new ByteArrayJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.sql.Clob</code> JDBC value handler.
+     */
+    protected static class ClobJdbcValueHandler extends JdbcValueHandler {
+        protected ClobJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            try {
+                // FIXME: This is here for backwards compatibility. Client code
+                // that uses a Clob java-type for a java.lang.String should use a
+                // java.lang.String java-type instead.
+                String str = (String) obj;
+                Debug.logWarning("Clob java-type used for java.lang.String. Use java.lang.String java-type instead.", module);
+                ps.setString(parameterIndex, str);
+                return;
+            } catch (ClassCastException e) {}
+            ps.setClob(parameterIndex, (java.sql.Clob) obj);
+            return;
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            java.sql.Clob clob = rs.getClob(columnIndex);
+            if (clob == null || clob.length() == 0) {
+                return null;
+            }
+            Reader clobReader = null;
+            try {
+                clobReader = clob.getCharacterStream();
+                int clobLength = (int) clob.length();
+                char[] charBuffer = new char[clobLength];
+                int offset = 0;
+                int charsRead = clobReader.read(charBuffer, offset, clobLength);
+                while (charsRead > 0) {
+                    offset += charsRead;
+                    charsRead = clobReader.read(charBuffer, offset, clobLength);
+                }
+                // FIXME: This is here for backwards compatibility. Client code
+                // that uses a Clob java-type for a java.lang.String should use a
+                // java.lang.String java-type instead.
+                return new String(charBuffer);
+            } catch (IOException e) {
+                throw new SQLException(e);
+            }
+            finally {
+                if (clobReader != null) {
+                    try {
+                        clobReader.close();
+                    } catch (IOException e) {}
+                }
+            }
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new ClobJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.sql.Date</code> JDBC value handler.
+     */
+    protected static class DateJdbcValueHandler extends JdbcValueHandler {
+        protected DateJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setDate(parameterIndex, (java.sql.Date) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            return rs.getDate(columnIndex);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new DateJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.Double</code> JDBC value handler.
+     */
+    protected static class DoubleJdbcValueHandler extends JdbcValueHandler {
+        protected DoubleJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setDouble(parameterIndex, (Double) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            double value = rs.getDouble(columnIndex);
+            return rs.wasNull() ? null : Double.valueOf(value);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new DoubleJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.Float</code> JDBC value handler.
+     */
+    protected static class FloatJdbcValueHandler extends JdbcValueHandler {
+        protected FloatJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setFloat(parameterIndex, (Float) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            float value = rs.getFloat(columnIndex);
+            return rs.wasNull() ? null : Float.valueOf(value);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new FloatJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.Integer</code> JDBC value handler.
+     */
+    protected static class IntegerJdbcValueHandler extends JdbcValueHandler {
+        protected IntegerJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setInt(parameterIndex, (Integer) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            int value = rs.getInt(columnIndex);
+            return rs.wasNull() ? null : Integer.valueOf(value);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new IntegerJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.Long</code> JDBC value handler.
+     */
+    protected static class LongJdbcValueHandler extends JdbcValueHandler {
+        protected LongJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setLong(parameterIndex, (Long) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            long value = rs.getLong(columnIndex);
+            return rs.wasNull() ? null : Long.valueOf(value);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new LongJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.Object</code> JDBC value handler.
+     */
+    protected static class ObjectJdbcValueHandler extends JdbcValueHandler {
+        protected ObjectJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setBytes(parameterIndex, serializeObject(obj));
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            ObjectInputStream in = null;
+            InputStream bis = null;
+            try {
+                bis = rs.getBinaryStream(columnIndex);
+                if (bis == null) {
+                    return null;
+                }
+                in = new ObjectInputStream(bis);
+                return in.readObject();
+            } catch (Exception e) {
+                throw new SQLException(e);
+            } finally {
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {}
+                }
+                if (bis != null) {
+                    try {
+                        bis.close();
+                    } catch (IOException e) {}
+                }
+            }
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new ObjectJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.Short</code> JDBC value handler.
+     */
+    protected static class ShortJdbcValueHandler extends JdbcValueHandler {
+        protected ShortJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setShort(parameterIndex, (Short) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            short value = rs.getShort(columnIndex);
+            return rs.wasNull() ? null : Short.valueOf(value);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new ShortJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.lang.String</code> JDBC value handler.
+     */
+    protected static class StringJdbcValueHandler extends JdbcValueHandler {
+        protected StringJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setString(parameterIndex, (String) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            return rs.getString(columnIndex);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new StringJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.sql.Time</code> JDBC value handler.
+     */
+    protected static class TimeJdbcValueHandler extends JdbcValueHandler {
+        protected TimeJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setTime(parameterIndex, (java.sql.Time) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            return rs.getTime(columnIndex);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new TimeJdbcValueHandler(sqlType);
+        }
+    }
+
+    /**
+     * A <code>java.sql.Timestamp</code> JDBC value handler.
+     */
+    protected static class TimestampJdbcValueHandler extends JdbcValueHandler {
+        protected TimestampJdbcValueHandler(int jdbcType) {
+            super(jdbcType);
+        }
+        @Override
+        protected void castAndSetValue(PreparedStatement ps, int parameterIndex, Object obj) throws SQLException {
+            ps.setTimestamp(parameterIndex, (java.sql.Timestamp) obj);
+        }
+        @Override
+        public Object getValue(ResultSet rs, int columnIndex) throws SQLException {
+            return rs.getTimestamp(columnIndex);
+        }
+        @Override
+        protected JdbcValueHandler newInstance(int sqlType) {
+            return new TimestampJdbcValueHandler(sqlType);
+        }
+    }
+}

Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/JdbcValueHandler.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SQLProcessor.java Wed Jun 30 23:27:24 2010
@@ -34,6 +34,8 @@ import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
 import java.util.List;
+
+import org.ofbiz.base.conversion.ConversionException;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.entity.GenericDataSourceException;
 import org.ofbiz.entity.GenericEntityException;
@@ -526,6 +528,19 @@ public class SQLProcessor {
     /**
      * Set the next binding variable of the currently active prepared statement.
      *
+     * @param handler
+     * @param field
+     *
+     * @throws SQLException
+     */
+    public void setValue(JdbcValueHandler handler, Object field) throws SQLException {
+        handler.setValue(_ps, _ind, field);
+        _ind++;
+    }
+
+    /**
+     * Set the next binding variable of the currently active prepared statement.
+     *
      * @param field
      *
      * @throws SQLException

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/jdbc/SqlJdbcUtil.java Wed Jun 30 23:27:24 2010
@@ -42,8 +42,6 @@ import javax.sql.rowset.serial.SerialClo
 
 import javolution.util.FastMap;
 
-import org.ofbiz.base.conversion.Converter;
-import org.ofbiz.base.conversion.Converters;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.ObjectType;
 import org.ofbiz.base.util.UtilGenerics;
@@ -57,6 +55,7 @@ import org.ofbiz.entity.GenericValue;
 import org.ofbiz.entity.condition.EntityConditionParam;
 import org.ofbiz.entity.condition.OrderByList;
 import org.ofbiz.entity.config.DatasourceInfo;
+import org.ofbiz.entity.jdbc.JdbcValueHandler;
 import org.ofbiz.entity.model.ModelEntity;
 import org.ofbiz.entity.model.ModelField;
 import org.ofbiz.entity.model.ModelFieldType;
@@ -492,7 +491,6 @@ public class SqlJdbcUtil {
         }
     }
 
-    @SuppressWarnings("unchecked")
     public static void getValue(ResultSet rs, int ind, ModelField curField, GenericEntity entity, ModelFieldTypeReader modelFieldTypeReader) throws GenericEntityException {
         ModelFieldType mft = modelFieldTypeReader.getModelFieldType(curField.getType());
 
@@ -501,48 +499,21 @@ public class SqlJdbcUtil {
                     entity.getEntityName() + "." + curField.getName() + ".");
         }
 
-        // ----- Try out the new converter code -----
+        // ----- Try out the new handler code -----
 
-        Object sourceObject = null;
-        try {
-            sourceObject = rs.getObject(ind);
-            if (sourceObject == null) {
-                entity.dangerousSetNoCheckButFast(curField, null);
-                return;
-            }
-        } catch (SQLException e) {
-            throw new GenericEntityException(e);
-        }
-        Class<?> targetClass = mft.getJavaClass();
-        if (targetClass != null) {
-            Class<?> sourceClass = sourceObject.getClass();
-            if (targetClass.equals(sourceClass)) {
-                entity.dangerousSetNoCheckButFast(curField, sourceObject);
+        JdbcValueHandler handler = mft.getJdbcValueHandler();
+        if (handler != null) {
+            try {
+                entity.dangerousSetNoCheckButFast(curField, handler.getValue(rs, ind));
                 return;
+            } catch (Exception e) {
+                Debug.logError(e, module);
             }
-            Converter<Object, Object> converter = (Converter<Object, Object>) mft.getSqlToJavaConverter();
-            if (converter == null) {
-                if (mft.getSqlClass() == null) {
-                    mft.setSqlClass(sourceClass);
-                }
-                try {
-                    converter = (Converter<Object, Object>) Converters.getConverter(sourceClass, targetClass);
-                    mft.setSqlToJavaConverter(converter);
-                } catch (Exception e) {
-                    Debug.logError(e, module);
-                }
-            }
-            if (converter != null) {
-                try {
-                    entity.dangerousSetNoCheckButFast(curField, converter.convert(sourceObject));
-                    return;
-                } catch (ClassCastException e) {
-                    Debug.logError(e.toString(), module);
-                } catch (Exception e) {
-                    Debug.logError(e, module);
-                }
-            }
-            Debug.logInfo("Unable to convert, falling back on switch statement", module);
+        } else {
+            Debug.logWarning("JdbcValueHandler not found for java-type " + mft.getJavaType() +
+                    ", falling back on switch statement. Entity = " +
+                    curField.getModelEntity().getEntityName() +
+                    ", field = " + curField.getName() + ".", module);
         }
 
         // ------------------------------------------
@@ -777,6 +748,25 @@ public class SqlJdbcUtil {
             fieldValue = null;
         }
 
+        // ----- Try out the new handler code -----
+
+        JdbcValueHandler handler = mft.getJdbcValueHandler();
+        if (handler != null) {
+            try {
+                sqlP.setValue(handler, fieldValue);
+                return;
+            } catch (SQLException e) {
+                throw new GenericDataSourceException("SQL Exception while setting value on field [" + modelField.getName() + "] of entity " + entityName + ": ", e);
+            }
+        } else {
+            Debug.logWarning("JdbcValueHandler not found for java-type " + mft.getJavaType() +
+                    ", falling back on switch statement. Entity = " +
+                    modelField.getModelEntity().getEntityName() +
+                    ", field = " + modelField.getName() + ".", module);
+        }
+
+        // ------------------------------------------
+
         String fieldType = mft.getJavaType();
         if (fieldValue != null) {
             if (!ObjectType.instanceOf(fieldValue, fieldType)) {

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelFieldType.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelFieldType.java?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelFieldType.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/model/ModelFieldType.java Wed Jun 30 23:27:24 2010
@@ -22,11 +22,9 @@ import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.ofbiz.base.conversion.Converter;
-import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
-
+import org.ofbiz.entity.jdbc.JdbcValueHandler;
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
@@ -46,20 +44,15 @@ public class ModelFieldType implements S
     /** The java-type of the Field */
     protected String javaType = null;
 
-    /** The Java class of the Field */
-    protected Class<?> javaClass = null;
+    /** The JDBC value handler for this Field */
+    protected JdbcValueHandler jdbcValueHandler = null;
 
     /** The sql-type of the Field */
     protected String sqlType = null;
 
-    /** The sql class of the Field */
-    protected Class<?> sqlClass = null;
-
     /** The sql-type-alias of the Field, this is optional */
     protected String sqlTypeAlias = null;
 
-    protected Converter<?, ?> sqlToJavaConverter = null;
-
     /** validators to be called when an update is done */
     protected List<ModelFieldValidator> validators = new ArrayList<ModelFieldValidator>();
 
@@ -82,14 +75,7 @@ public class ModelFieldType implements S
             }
         }
         ((ArrayList<ModelFieldValidator>)this.validators).trimToSize();
-        if (this.javaType != null) {
-            ClassLoader loader = Thread.currentThread().getContextClassLoader();
-            try {
-                this.javaClass = loader.loadClass(this.javaType);
-            } catch (ClassNotFoundException e) {
-                Debug.logError(e, module);
-            }
-        }
+        this.jdbcValueHandler = JdbcValueHandler.getInstance(this.javaType, this.sqlType);
     }
 
     /** The type of the Field */
@@ -102,23 +88,9 @@ public class ModelFieldType implements S
         return this.javaType;
     }
 
-    /** The Java class of the Field */
-    public Class<?> getJavaClass() {
-        return this.javaClass;
-    }
-
-    /** Returns the SQL <code>Class</code> of the Field. The returned value might
-     * be <code>null</code>. The SQL class is unknown until a connection is made
-     * to the database. */
-    public Class<?> getSqlClass() {
-        return this.sqlClass;
-    }
-
-    /** Returns the SQL-object-type to Java-object-type <code>Converter</code> for
-     * the Field. The returned value might be <code>null</code>. The converter
-     * type is unknown until a connection is made to the database. */
-    public Converter<?, ?> getSqlToJavaConverter() {
-        return this.sqlToJavaConverter;
+    /** Returns the JDBC value handler for this field type */
+    public JdbcValueHandler getJdbcValueHandler() {
+        return this.jdbcValueHandler;
     }
 
     /** The sql-type of the Field */
@@ -136,21 +108,6 @@ public class ModelFieldType implements S
         return this.validators;
     }
 
-    /** Sets the SQL <code>Class</code> for this field.
-     *
-     * @param sqlClass
-     */
-    public synchronized void setSqlClass(Class<?> sqlClass) {
-        this.sqlClass = sqlClass;
-    }
-
-    /** Sets the SQL-object-type to Java-object-type <code>Converter</code> for
-     * the Field.
-     */
-    public synchronized void setSqlToJavaConverter(Converter<?, ?> converter) {
-        this.sqlToJavaConverter = converter;
-    }
-
     /** A simple function to derive the max length of a String created from the field value, based on the sql-type
      * @return max length of a String representing the Field value
      */

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java?rev=959470&r1=959469&r2=959470&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/test/EntityTestSuite.java Wed Jun 30 23:27:24 2010
@@ -518,6 +518,8 @@ public class EntityTestSuite extends Ent
             GenericValue testValue = delegator.makeValue("TestFieldType", "testFieldTypeId", id);
             testValue.create();
             testValue.set("blobField", b);
+            testValue.set("byteArrayField", b);
+            testValue.set("objectField", currentTimestamp);
             testValue.set("dateField", currentDate);
             testValue.set("timeField", currentTime);
             testValue.set("dateTimeField", currentTimestamp);
@@ -539,6 +541,12 @@ public class EntityTestSuite extends Ent
             for (int i = 0; i < b.length; i++) {
                 assertEquals("Byte array data[" + i + "]", b[i], c[i]);
             }
+            c = (byte[]) testValue.get("byteArrayField");
+            assertEquals("Byte array read from entity is the same length", b.length, c.length);
+            for (int i = 0; i < b.length; i++) {
+                assertEquals("Byte array data[" + i + "]", b[i], c[i]);
+            }
+            assertEquals("objectField", currentTimestamp, testValue.get("objectField"));
             assertEquals("dateField", currentDate, testValue.get("dateField"));
             assertEquals("timeField", currentTime, testValue.get("timeField"));
             assertEquals("dateTimeField", currentTimestamp, testValue.get("dateTimeField"));
@@ -547,6 +555,8 @@ public class EntityTestSuite extends Ent
             assertEquals("numericField", numeric, testValue.get("numericField"));
             assertEquals("clobField", clobStr, testValue.get("clobField"));
             testValue.set("blobField", null);
+            testValue.set("byteArrayField", null);
+            testValue.set("objectField", null);
             testValue.set("dateField", null);
             testValue.set("timeField", null);
             testValue.set("dateTimeField", null);
@@ -558,6 +568,8 @@ public class EntityTestSuite extends Ent
             testValue = delegator.findOne("TestFieldType", UtilMisc.toMap("testFieldTypeId", id), false);
             assertEquals("testFieldTypeId", id, testValue.get("testFieldTypeId"));
             assertNull("blobField null", testValue.get("blobField"));
+            assertNull("byteArrayField null", testValue.get("byteArrayField"));
+            assertNull("objectField null", testValue.get("objectField"));
             assertNull("dateField null", testValue.get("dateField"));
             assertNull("timeField null", testValue.get("timeField"));
             assertNull("dateTimeField null", testValue.get("dateTimeField"));