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")); |
Free forum by Nabble | Edit this page |