Author: kentam
Date: Thu Oct 28 18:21:48 2004
New Revision: 55921
Added:
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/Employee.java
- copied, changed from rev 55915,
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/Employee.java
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/TestDBControl.jcx
- copied, changed from rev 55915,
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/TestDBControl.jcx
incubator/beehive/branches/v1/alpha/samples/controls-db/
incubator/beehive/branches/v1/alpha/samples/controls-db/build.xml
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/DatabaseControl.java
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/DatabaseControlImpl.jcs
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/ResultSetExtractor.java
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLParameter.java
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLParser.java
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLStatement.java
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/JavaTypeHelper.java
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/PreparedStatementHelper.java
(contents, props changed)
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/ResultSetHelper.java
(contents, props changed)
Removed:
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControl.java
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControlImpl.jcs
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/ResultSetExtractor.java
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParameter.java
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParser.java
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLStatement.java
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/
Modified:
incubator/beehive/branches/v1/alpha/controls/test/build.xml
incubator/beehive/branches/v1/alpha/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/DriveDatabaseControl.java
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ParserTest.java
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ResultSetExtractorTest.java
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/SQLStatementTest.java
incubator/beehive/branches/v1/alpha/controls/test/webapps/build.xml
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/app.properties
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/database/Controller.jpf
Log:
Migrated the Database control from controls/test to samples
Modified: incubator/beehive/branches/v1/alpha/controls/test/build.xml
==============================================================================
--- incubator/beehive/branches/v1/alpha/controls/test/build.xml (original)
+++ incubator/beehive/branches/v1/alpha/controls/test/build.xml Thu Oct 28
18:21:48 2004
@@ -39,6 +39,8 @@
<property name="mantis.cases" location="${basedir}/mantis-cases"/>
<property name="mantis.logs" location="${basedir}/mantis-logs"/>
<property name="derby.data" location="${basedir}/test"/>
+ <property name="db.control.dir" location="../../samples/controls-db"/>
+ <property name="db.control.jar"
location="${db.control.dir}/build/dbControl.jar"/>
<condition property="test.os" value="windows" >
<os family="windows" />
@@ -62,6 +64,7 @@
<pathelement location="${velocitydep14.jar}"/>
<pathelement location="${servlet24.jar}"/>
<pathelement location="${derby.jar}"/>
+ <pathelement location="${db.control.jar}"/>
<pathelement path="../build/jars/controls.jar"/>
<pathelement path="${build.beans}"/>
</path>
@@ -80,6 +83,7 @@
<pathelement location="${velocitydep14.jar}"/>
<pathelement location="${servlet24.jar}"/>
<pathelement location="${derby.jar}"/>
+ <pathelement location="${db.control.jar}"/>
<pathelement location="../build/jars/controls.jar"/>
<pathelement path="${build.beans}"/>
@@ -129,7 +133,7 @@
<!-- build - target to build controls, test drivers and junit tests -->
<!-- ====================================================================
-->
- <target name="build" depends="dirs">
+ <target name="build" depends="dirs, dbControl">
<ant target="build-test-auxilaries"/>
<ant target="build-test-beans" />
<ant target="build-test-drivers" />
@@ -146,6 +150,14 @@
<mkdir dir="${build.testsrc}" />
<mkdir dir="${build.jars}" />
<mkdir dir="${test.logs}" />
+ </target>
+
+ <target name="dbControl">
+ <ant
+ dir="${db.control.dir}"
+ antfile="build.xml"
+ target="build"
+ inheritall="false"/>
</target>
<target name="build-test-beans" depends="dirs,build-test-auxilaries">
Copied:
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/Employee.java
(from rev 55915,
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/Employee.java)
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/Employee.java
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/Employee.java
Thu Oct 28 18:21:48 2004
@@ -1,4 +1,4 @@
-package org.apache.beehive.controls.test.controls.database.test;
+package org.apache.beehive.controls.test.controls.database;
public class Employee
{
Copied:
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/TestDBControl.jcx
(from rev 55915,
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/TestDBControl.jcx)
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/TestDBControl.jcx
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/TestDBControl.jcx
Thu Oct 28 18:21:48 2004
@@ -1,4 +1,4 @@
-package org.apache.beehive.controls.test.controls.database.test;
+package org.apache.beehive.controls.test.controls.database;
import java.sql.SQLException;
import java.io.Serializable;
@@ -6,8 +6,8 @@
import java.util.HashMap;
import org.apache.beehive.controls.api.bean.ControlExtension;
-import org.apache.beehive.controls.test.controls.database.DatabaseControl;
-import
org.apache.beehive.controls.test.controls.database.DatabaseControl.ConnectionDataSource;
+import dbControl.DatabaseControl;
+import dbControl.DatabaseControl.ConnectionDataSource;
@ControlExtension
@ConnectionDataSource(jndiName="jdbc:derby:build/databaseControlTestDB;create=true")
Modified:
incubator/beehive/branches/v1/alpha/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/DriveDatabaseControl.java
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/DriveDatabaseControl.java
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/DriveDatabaseControl.java
Thu Oct 28 18:21:48 2004
@@ -1,8 +1,8 @@
package org.apache.beehive.controls.test.driver.database;
import org.apache.beehive.test.tools.milton.common.Report;
-import
org.apache.beehive.controls.test.controls.database.test.TestDBControlBean;
-import org.apache.beehive.controls.test.controls.database.test.Employee;
+import org.apache.beehive.controls.test.controls.database.TestDBControl;
+import org.apache.beehive.controls.test.controls.database.Employee;
import java.util.Iterator;
import java.util.HashMap;
@@ -30,14 +30,14 @@
private static Employee[] emps = { new Employee(1, "John", "Doe",
"CEO"), new Employee(2, "Jane", "Doe", "CFO") };
- private TestDBControlBean testDBControl;
+ private TestDBControl testDBControl;
- public DriveDatabaseControl (TestDBControlBean aControl)
+ public DriveDatabaseControl (TestDBControl aControl)
{
this.testDBControl = aControl;
}
- public void setControl(TestDBControlBean aControl)
+ public void setControl(TestDBControl aControl)
{
this.testDBControl = aControl;
Modified:
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ParserTest.java
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ParserTest.java
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ParserTest.java
Thu Oct 28 18:21:48 2004
@@ -1,8 +1,8 @@
package org.apache.beehive.controls.test.java.database;
-import org.apache.beehive.controls.test.controls.database.SQLParameter;
-import org.apache.beehive.controls.test.controls.database.SQLParser;
-import org.apache.beehive.controls.test.controls.database.SQLStatement;
+import dbControl.SQLParameter;
+import dbControl.SQLParser;
+import dbControl.SQLStatement;
import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
Modified:
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ResultSetExtractorTest.java
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ResultSetExtractorTest.java
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/ResultSetExtractorTest.java
Thu Oct 28 18:21:48 2004
@@ -2,7 +2,7 @@
import junit.framework.Test;
import junit.framework.TestSuite;
-import org.apache.beehive.controls.test.controls.database.ResultSetExtractor;
+import dbControl.ResultSetExtractor;
import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
Modified:
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/SQLStatementTest.java
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/SQLStatementTest.java
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/src/units/org/apache/beehive/controls/test/java/database/SQLStatementTest.java
Thu Oct 28 18:21:48 2004
@@ -1,7 +1,7 @@
package org.apache.beehive.controls.test.java.database;
-import org.apache.beehive.controls.test.controls.database.SQLParameter;
-import org.apache.beehive.controls.test.controls.database.SQLStatement;
+import dbControl.SQLParameter;
+import dbControl.SQLStatement;
import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
Modified: incubator/beehive/branches/v1/alpha/controls/test/webapps/build.xml
==============================================================================
--- incubator/beehive/branches/v1/alpha/controls/test/webapps/build.xml
(original)
+++ incubator/beehive/branches/v1/alpha/controls/test/webapps/build.xml Thu Oct
28 18:21:48 2004
@@ -19,6 +19,8 @@
<property name="webapp.name" value="controlsWeb"/>
<property name="webapp.waitfor.url"
value="http://localhost:8080/${webapp.name}"/>
+ <property name="dbControl.jar"
location="../../../samples/controls-db/build/dbControl.jar"/>
+
<target name="usage">
<echo message="" />
@@ -61,6 +63,9 @@
<condition property="do.inject.derby">
<istrue value="${app.inject.derby}"/>
</condition>
+ <condition property="do.inject.dbControl">
+ <istrue value="${app.inject.dbControl}"/>
+ </condition>
<condition property="do.inject.test.controls">
<isset property="app.inject.test.controls"/>
</condition>
@@ -100,6 +105,7 @@
<antcall target="-inject.netui"/>
<antcall target="-inject.milton"/>
<antcall target="-inject.derby"/>
+ <antcall target="-inject.dbControl"/>
<antcall target="-inject.test.controls"/>
<antcall target="-inject.test.drivers"/>
<antcall target="-build.webapp"/>
@@ -150,6 +156,13 @@
<echo message="Injecting ${derby.jar} to ${webapp.name}"/>
<copy todir="${webapp.dir}/WEB-INF/lib"
file="${derby.jar}" verbose="true"
+ overwrite="true" failonerror="true"/>
+ </target>
+
+ <target name="-inject.dbControl" if="do.inject.dbControl">
+ <echo message="Injecting ${dbControl.jar} to ${webapp.name}"/>
+ <copy todir="${webapp.dir}/WEB-INF/lib"
+ file="${dbControl.jar}" verbose="true"
overwrite="true" failonerror="true"/>
</target>
Modified:
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/app.properties
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/app.properties
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/app.properties
Thu Oct 28 18:21:48 2004
@@ -1,6 +1,7 @@
app.inject.netui: true
app.inject.milton: true
app.inject.derby: true
+app.inject.dbControl: true
### these two can be set to 'jar' or 'src' ###
app.inject.test.drivers: jar
app.inject.test.controls: jar
Modified:
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/database/Controller.jpf
==============================================================================
---
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/database/Controller.jpf
(original)
+++
incubator/beehive/branches/v1/alpha/controls/test/webapps/controlsWeb/database/Controller.jpf
Thu Oct 28 18:21:48 2004
@@ -24,7 +24,7 @@
import org.apache.beehive.controls.api.bean.Control;
import org.apache.beehive.controls.api.bean.ControlBean;
-import
org.apache.beehive.controls.test.controls.database.test.TestDBControlBean;
+import org.apache.beehive.controls.test.controls.database.TestDBControl;
import org.apache.beehive.controls.test.driver.database.DriveDatabaseControl;
import org.apache.beehive.test.tools.milton.common.Report;
@@ -38,7 +38,7 @@
{
@Control
- private TestDBControlBean testDBControl;
+ private TestDBControl testDBControl;
transient private DriveDatabaseControl driver = new
DriveDatabaseControl(this.testDBControl);
Added: incubator/beehive/branches/v1/alpha/samples/controls-db/build.xml
==============================================================================
--- (empty file)
+++ incubator/beehive/branches/v1/alpha/samples/controls-db/build.xml Thu Oct
28 18:21:48 2004
@@ -0,0 +1,63 @@
+<?xml version="1.0" ?>
+
+<project name="controls-blank" default="usage">
+
+ <property environment="os"/>
+ <property file="${os.BEEHIVE_HOME}/beehive.properties"/>
+
+ <property name="source.dir" value="${basedir}/src"/>
+ <property name="build.dir" value="${basedir}/build"/>
+ <property name="build.classes" value="${build.dir}/classes"/>
+ <property name="build.beansrc" value="${build.dir}/beansrc"/>
+ <property name="build.jar" value="dbControl.jar"/>
+
+ <path id="build.classpath">
+ <pathelement location="${tools.jar}"/>
+ <pathelement location="${velocity14.jar}"/>
+ <pathelement location="${velocitydep14.jar}"/>
+ <pathelement location="${controls.jar}"/>
+ <pathelement path="${build.classes}"/>
+ </path>
+
+ <taskdef name="apt"
classname="org.apache.beehive.controls.runtime.generator.AptTask"
+ classpath="${controls.jar}" onerror="report" />
+ <taskdef name="control-jar"
+
classname="org.apache.beehive.controls.runtime.packaging.ControlJarTask"
+ classpath="${controls.jar}" onerror="report" />
+
+ <target name="usage">
+ <echo message=""/>
+ <echo message=""/>
+ <echo message="Controls Template Build file"/>
+ <echo
message="================================================================"/>
+ <echo message="| Usage
|"/>
+ <echo
message="================================================================"/>
+ <echo
message="----------------------------------------------------------------"/>
+ <echo message="| Standard Targets
|"/>
+ <echo
message="----------------------------------------------------------------"/>
+ <echo message="clean - Delete all generated files"/>
+ <echo message="build - build controls"/>
+ <echo
message="----------------------------------------------------------------"/>
+ </target>
+
+ <target name="clean" description="Deletes all generated files">
+ <delete dir="${build.dir}"/>
+ <delete file="velocity.log"/>
+ </target>
+
+ <target name="dirs">
+ <mkdir dir="${build.classes}" />
+ <mkdir dir="${build.beansrc}" />
+ </target>
+
+ <target name="build" depends="dirs" description="Builds controls sources">
+ <apt srcdir="${source.dir}" destdir="${build.classes}"
gendir="${build.beansrc}"
+ classpathref="build.classpath"
+ debug="on"
+ compileByExtension="true"
+ srcExtensions="*.java,*.jcx,*.jcs">
+ </apt>
+ <control-jar destfile="${build.dir}/${build.jar}"
basedir="${build.classes}" />
+ </target>
+
+</project>
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/DatabaseControl.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/DatabaseControl.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,64 @@
+package dbControl;
+
+import org.apache.beehive.controls.api.bean.AnnotationConstraints;
+import org.apache.beehive.controls.api.bean.AnnotationMemberTypes.*;
+import org.apache.beehive.controls.api.bean.AnnotationMemberTypes;
+import org.apache.beehive.controls.api.bean.ControlInterface;
+import org.apache.beehive.controls.api.bean.ControlInterface;
+import org.apache.beehive.controls.api.properties.PropertySet;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.sql.Connection;
+import java.util.Calendar;
+
[EMAIL PROTECTED]
+public interface DatabaseControl
+{
+
+ /**
+ * This constant can be used as the value for the maxRows member of the
SQL PropertySet.
+ * It indicates that all rows should be returned (i.e. no limit)
+ */
+ public final int MAXROWS_ALL = -1;
+
+ /**
+ * This class acts as a default value for the iteratorElementType member
of the
+ * SQL PropertySet. It signals that no type has been defined for the
method
+ * (common if the method return type isn't itself an iterator)
+ */
+ public interface UndefinedIteratorType {}
+
+
+ @PropertySet
+ @Inherited
+ @AnnotationConstraints.AllowExternalOverride
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target({ElementType.TYPE, ElementType.FIELD})
+ public @interface ConnectionDataSource
+ {
+ String jndiName(); // no default ... value is required
+ }
+
+ @PropertySet
+ @Inherited
+ @Retention(RetentionPolicy.RUNTIME)
+ @AnnotationConstraints.AllowExternalOverride // not sure we want to do this
+ @Target( { ElementType.METHOD } )
+ public @interface SQL
+ {
+ String statement() default "";
+ int maxRows() default MAXROWS_ALL;
+ @AnnotationMemberTypes.Optional
+ Class iteratorElementType() default UndefinedIteratorType.class;
+
+ }
+
+ public Calendar getDataSourceCalendar();
+
+ public void setDataSourceCalendar(Calendar cal);
+
+ public Connection getConnection();
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/DatabaseControlImpl.jcs
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/DatabaseControlImpl.jcs
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,238 @@
+package dbControl;
+
+import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.api.bean.ControlImplementation;
+import org.apache.beehive.controls.api.bean.Extensible;
+import org.apache.beehive.controls.api.context.ControlBeanContext;
+import org.apache.beehive.controls.api.context.ResourceContext;
+import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.api.context.ResourceContext.ResourceEvents;
+import org.apache.beehive.controls.api.events.EventHandler;
+import dbControl.util.JavaTypeHelper;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+import javax.naming.InitialContext;
+
[EMAIL PROTECTED]
+public class DatabaseControlImpl implements DatabaseControl, Extensible
+{
+ //Error messages
+ private static final String ERROR_GET_DATABASE_CONTROL = "Failed to obtain
database control.";
+ private static final String ERROR_MISSING_SQL_ATTRIBUTE = "SQL attribute
not defined.";
+ private static final String ERROR_MISSING_STATEMENT_MEMBER = "Statement
member not defined in SQL attribute";
+ private static final String ERROR_ITERATOR_ELEMENT_TYPE_NOT_SPECIFIED =
"Iterator element type is not specified.";
+ private static final String ERROR_RESULT_NOT_MATCH_RETURN_TYPE = "The
results of the SQL provided does not match return type of method";
+ private static final String ERROR_INVALID_ARGUMENT_NAME = "Invalid
argument name in SQL statement";
+ private static final String ERROR_PARAMETER_SUBSTITUTION_FAILED = "Failed
to substitute parameter by name";
+
+ @org.apache.beehive.controls.api.context.Context ControlBeanContext
context;
+ @org.apache.beehive.controls.api.context.Context ResourceContext
resourceContext;
+
+ transient Calendar calendar = null;
+ transient Connection connection = null;
+ Vector resources = new Vector();
+
+ public Calendar getDataSourceCalendar()
+ {
+ return calendar;
+ }
+
+ public void setDataSourceCalendar(Calendar cal)
+ {
+ this.calendar = (Calendar)cal.clone();
+ }
+
+ public Connection getConnection()
+ {
+ if (this.connection == null)
+ {
+ DatabaseControl.ConnectionDataSource ds =
+
(ConnectionDataSource)context.getControlPropertySet(ConnectionDataSource.class);
+ if (ds == null)
+ throw new ControlException("no @" +
ConnectionDataSource.class.getName() + "\' property found.");
+
+ //TODO: Need to change this code to use data source.
+ try {
+ Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
+ this.connection = DriverManager.getConnection(ds.jndiName());
+ } catch (Exception e) {
+ throw new ControlException(ERROR_GET_DATABASE_CONTROL, e);
+ }
+ }
+ return this.connection;
+ }
+
+ @EventHandler(field="resourceContext",eventSet=ResourceEvents.class,
eventName="onRelease")
+ public void onRelease()
+ {
+ for (int i = 0 ; i < this.resources.size() ; i++)
+ {
+ Object o = this.resources.get(i);
+ if (o instanceof PreparedStatement)
+ {
+ try {
+ ((PreparedStatement)o).close();
+ }
+ catch (SQLException sqe) {
+ //TODO: log error closing prepared statement.
+ }
+ }
+ else
+ {
+ //TODO: log unexpected resource type
+ }
+ }
+ resources.clear();
+
+ try {
+ if (this.connection != null)
+ this.connection.close();
+ } catch (SQLException sqe) {
+ //TODO: log error closing connection
+ }
+
+ this.connection = null;
+ }
+
+ @EventHandler(field="resourceContext",eventSet=ResourceEvents.class,
eventName="onAcquire")
+ public void onAcquire()
+ {
+ try {
+ getConnection();
+ }
+ catch (ControlException e) {
+ //TODO: log error
+ }
+ }
+
+ /**
+ * Extensible.invoke
+ * Handles all extended interface methods
+ */
+ public Object invoke(Method method, Object[] args) throws Throwable
+ {
+ //Retrieve the SQL statement from the STATEMENT member of the
SQL attribute.
+ SQL methodSQL = (SQL)context.getMethodPropertySet(method, SQL.class);
+ if (methodSQL == null)
+ throw new ControlException (ERROR_MISSING_SQL_ATTRIBUTE);
+ String statement = methodSQL.statement();
+ if (statement == null || statement.length() == 0)
+ throw new ControlException (ERROR_MISSING_STATEMENT_MEMBER);
+
+ //Parse the SQL statement
+ SQLParser parser = new SQLParser(statement);
+ SQLStatement sql = parser.parse();
+ //Set the parameters of the SQL statement based on the method arguments
+ //sql.setParameterValuesByPosition(args);
+ this.setParameterValues(sql.getParameters(), method, args);
+
+ PreparedStatement ps = sql.getPreparedStatement(this.getConnection());
+
+ //Set the max. rows returned
+ int maxRows = methodSQL.maxRows();
+ if (maxRows != MAXROWS_ALL && maxRows > 0)
+ ps.setMaxRows(maxRows);
+
+ boolean hasResults = ps.execute();
+
+ //
+ // process returned data
+ //
+ Class returnType = method.getReturnType();
+
+ Object returnObject = null;
+
+ if (hasResults)
+ {
+ // If a result must live beyond the lifetime of this
+ // 'invoke', the statement must be kept open and
+ // closed later.
+ ResultSet rs = ps.getResultSet();
+ if (returnType.equals(ResultSet.class))
+ {
+ this.resources.add(ps);
+ returnObject = rs;
+ }
+ else
+ {
+ ResultSetExtractor extractor = new ResultSetExtractor(rs,
this.calendar);
+ //return iterator
+ if (returnType.equals(Iterator.class))
+ {
+ this.resources.add(ps);
+ Class iteratorElement = methodSQL.iteratorElementType();
+ if (null == iteratorElement)
+ throw new
Exception(ERROR_ITERATOR_ELEMENT_TYPE_NOT_SPECIFIED);
+ returnObject = extractor.extractIterator(iteratorElement);
+ }
+ //return array
+ else if (returnType.isArray())
+ {
+ returnObject = extractor.extractArray(returnType);
+ }
+ //return HashMap
+ else if (returnType.equals(HashMap.class))
+ {
+ returnObject = extractor.extractHashMap();
+ }
+ //return an unmodifiable view of the HashMap
+ else if (returnType.equals(Map.class))
+ {
+ returnObject = extractor.extractUnmodifiableMap();
+ }
+
+ else
+ {
+ if (!rs.next())
+ //return null or if return type is a primitive, return the
primitive's default value.
+ returnObject =
JavaTypeHelper.getJaveTypeDefaultValue(returnType);
+ else
+ //return object
+ returnObject = extractor.extractObject(returnType);
+ }
+ }
+ }
+ else {
+ if (returnType.equals(Void.TYPE))
+ returnObject = null;
+ else if (!returnType.equals(Integer.TYPE))
+ throw new ControlException(ERROR_RESULT_NOT_MATCH_RETURN_TYPE);
+
+ returnObject = new Integer(ps.getUpdateCount());
+ }
+
+ return returnObject;
+ }
+
+ private void setParameterValues(SQLParameter[] params, Method method,
Object[] args)
+ {
+ for (int i = 0; i < params.length; i++)
+ {
+ SQLParameter param = params[i];
+ String firstNameComponent =
param.getFirstNameComponent();
+
+ try
+ {
+ Object value =
context.getParameterValue(method, firstNameComponent, args);
+ param.setValue(value);
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new
ControlException(ERROR_INVALID_ARGUMENT_NAME);
+ }
+ catch (Exception e)
+ {
+ throw new
ControlException(ERROR_PARAMETER_SUBSTITUTION_FAILED, e);
+ }
+ }
+ }
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/ResultSetExtractor.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/ResultSetExtractor.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,368 @@
+package dbControl;
+
+//import org.apache.beehive.controls.api.ControlException;
+import dbControl.util.JavaTypeHelper;
+import dbControl.util.ResultSetHelper;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Field;
+import java.sql.ResultSetMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.GregorianCalendar;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * This class extracts the the content of a ResultSet into various forms of
+ * object (e.g. an Iterator, HashMap, etc)
+ */
+public class ResultSetExtractor
+{
+ //Error messages
+ private static final String ERROR_SETTING_FIELD = "Error occurred while
setting a value from the database to class field.";
+ private static final String ERROR_SETTING_ARRAY = "Error occurred while
adding an elment to array.";
+ private static final String ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_OBJECT =
"Object type not specified when extracting object from ResultSet.";
+ private static final String ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_ITERATOR =
"Iterator element type not specified when extracting iterator from ResultSet.";
+
+ //ResultSet to extract data from
+ ResultSet rs;
+ //Meta data of the resultset.
+ ResultSetMetaData rsMetaData;
+ //Calendar used for working with dates.
+ protected GregorianCalendar cal;
+
+ //Column count of the resultset
+ int columnCount;
+
+ //Name of columns in the resultset
+ String[] columnNames = null;
+
+ // Field or Method
+ AccessibleObject[] fields = null;
+
+ /**
+ * Constructor
+ * @param rs the resultset to exrract data from
+ * @param cal the calendar to use when working with dates
+ */
+ public ResultSetExtractor(ResultSet rs, Calendar cal) throws SQLException
+ {
+ this.rs = rs;
+ this.columnCount = rs.getMetaData().getColumnCount();
+ this.rsMetaData = rs.getMetaData();
+ this.columnNames = new String[columnCount + 1];
+ for (int i = 1 ; i <= columnCount ; i++)
+ this.columnNames[i] =
this.rsMetaData.getColumnName(i).toUpperCase();
+
+ }
+
+ private Map<String, AccessibleObject> getColumnNameToFieldMap(Class
objectType) throws SQLException
+ {
+ HashMap<String, AccessibleObject> columnNameToFieldMap =
+ new HashMap<String, AccessibleObject>(columnCount * 2);
+
+ //Add names of all column from resultset to map.
+ for (int i = 1 ; i <= columnCount ; i++)
+ columnNameToFieldMap.put(columnNames[i], null);
+
+ //Map the class fields to column names in the map.
+ for (Class clazz = objectType ; null != clazz && Object.class != clazz
; clazz = clazz.getSuperclass())
+ {
+ Field[] classFields = clazz.getDeclaredFields();
+ if (null != classFields)
+ for (int i = 0 ; i < classFields.length ; i++)
+ {
+ Field f = classFields[i];
+ if (Modifier.isStatic(f.getModifiers()))
+ continue;
+ String fieldName = f.getName().toUpperCase();
+ if (!columnNameToFieldMap.containsKey(fieldName))
+ continue;
+ columnNameToFieldMap.put(fieldName, f);
+ }
+ }
+
+ //Map the class's attribute setter methods to column names in the map.
+ Method[] classMethods = objectType.getMethods();
+ if (null != classMethods)
+ for (int i = 0 ; i < classMethods.length ; i++)
+ {
+ Method m = classMethods[i];
+ String methodName = m.getName();
+ if (methodName.length() < 4 || !methodName.startsWith("set"))
+ continue;
+ if (!Character.isUpperCase(methodName.charAt(3)))
+ continue;
+ String fieldName = methodName.substring(3).toUpperCase();
+ if (!columnNameToFieldMap.containsKey(fieldName))
+ continue;
+ if (Modifier.isStatic(m.getModifiers()))
+ continue;
+ Class[] params = m.getParameterTypes();
+ if (1 != params.length)
+ continue;
+ if (Types.OTHER == JavaTypeHelper.getSqlType(params[0]))
+ continue;
+ if (!Void.TYPE.equals(m.getReturnType()))
+ continue;
+ // check for overloads
+ Object field = columnNameToFieldMap.get(fieldName);
+ if (null != field)
+ continue;
+ columnNameToFieldMap.put(fieldName, m);
+ }
+ return columnNameToFieldMap;
+ }
+
+ /**
+ * Extracts the data of the resultset into a array of a specified
+ * type.
+ * @param arrayClass array type
+ * @return array of the specified type
+ */
+ public Object extractArray(Class arrayClass) throws Exception{
+
+ Class componentType = arrayClass.getComponentType();
+
+ ArrayList list = new ArrayList();
+
+ while(rs.next())
+ {
+ list.add(extractObject(componentType));
+ }
+
+ Object array = java.lang.reflect.Array.newInstance(componentType,
list.size());
+
+ try
+ {
+ for (int i = 0 ; i < list.size() ; i++)
+ java.lang.reflect.Array.set(array, i, list.get(i));
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new Exception(ERROR_SETTING_ARRAY, iae);
+ }
+ return array;
+
+ }
+
+ /**
+ * Extracts the data of a resultset into an iterator of a specified type.
+ * @param iteratorElementType type of the elements in the iterator
+ * @return an iterator with elements of the specified type.
+ */
+ public Iterator extractIterator(Class iteratorElementType) throws Exception
+ {
+ return new ResultSetIterator(iteratorElementType);
+ }
+
+ /**
+ * Extracts one row of data from a resultset into a HashMap with
+ * the column names as keys.
+ * @return column name to value map of a row from the resultset.
+ */
+ public HashMap<String, Object> extractHashMap() throws Exception
+ {
+ return new ResultSetHashMap();
+ }
+
+ /**
+ * Extracts one row of data from a resultset into a unmodifiable
+ * map with the column names as keys.
+ * @return column name to value map of a row from the resultset.
+ */
+ public Map<String, Object> extractUnmodifiableMap() throws Exception
+ {
+ return Collections.unmodifiableMap(new ResultSetHashMap());
+ }
+
+ /**
+ * Extracts one row of data into an object of a specified type.
+ * @param returnClass type of object to extract the data to
+ * @return an object of the specified type
+ */
+ public Object extractObject(Class returnClass) throws Exception
+ {
+ if (returnClass == null)
+ {
+ throw new Exception(ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_OBJECT);
+ }
+
+ if (columnCount == 1)
+ {
+ Object val = ResultSetHelper.readValue(rs, columnNames[1],
returnClass.getClass(), cal);
+ if (returnClass.isAssignableFrom(val.getClass()))
+ {
+ return val;
+ }
+ }
+
+ // calculate reflection information
+ Map<String, AccessibleObject> columnNameToFieldMap =
getColumnNameToFieldMap(returnClass);
+
+ Object resultObject = returnClass.newInstance();
+
+ // array used for method.invoke()
+ Object[] args = new Object[1];
+
+ Set<String> columnNames = columnNameToFieldMap.keySet();
+
+ for (String columnName : columnNames)
+ {
+ AccessibleObject accessibleObj =
columnNameToFieldMap.get(columnName);
+
+ if (accessibleObj == null)
+ continue;
+
+ try
+ {
+ if (accessibleObj instanceof Field)
+ {
+ Object resultValue = ResultSetHelper.readValue(rs,
columnName, ((Field)accessibleObj).getType(), cal);
+ ((Field)accessibleObj).set(resultObject, resultValue);
+ }
+ else
+ {
+ Object resultValue = ResultSetHelper.readValue(rs,
columnName, ((Method)accessibleObj).getParameterTypes()[0], cal);
+ args[0] = resultValue;
+ ((Method)accessibleObj).invoke(resultObject, args);
+ }
+ }
+ catch (IllegalArgumentException iae)
+ {
+ throw new Exception(ERROR_SETTING_FIELD, iae);
+ }
+ }
+ return resultObject;
+ }
+
+ /**
+ * The ResultSetHashMap class extends a standard HashMap and
+ * populates it with data derived from a JDBC ResultSet.
+ * <p>
+ * Note: the keys are treated case-insensitively, and therefore requests
+ * made on the map are case-insensitive. Any direct access to the keys
+ * will yield uppercase keys.
+ * <p>
+ * Note: only the row associated with the current cursor position
+ * is used.
+ */
+ private class ResultSetHashMap extends HashMap<String, Object>
+ {
+ ResultSetHashMap() throws Exception
+ {
+ super();
+
+ ResultSetMetaData md = rs.getMetaData();
+ if (rs.next())
+ {
+ for (int i = 1 ; i <= md.getColumnCount() ; i++)
+ {
+
super.put(md.getColumnName(i).toUpperCase(), rs.getObject(i));
+ }
+ }
+ }
+
+
+ public boolean containsKey(Object key)
+ {
+ if (key instanceof String)
+ key = ((String)key).toUpperCase();
+ return super.containsKey(key);
+ }
+
+
+ public Object get(Object key)
+ {
+ if (key instanceof String)
+ key = ((String)key).toUpperCase();
+ return super.get(key);
+ }
+
+
+ public Object put(String key, Object value)
+ {
+ key = key.toUpperCase();
+ return super.put(key, value);
+ }
+
+
+ public Object remove(String key)
+ {
+ key = key.toUpperCase();
+ return super.remove(key);
+ }
+ }
+
+ private class ResultSetIterator implements Iterator {
+
+ Class iteratorElementType;
+ boolean primed = false;
+
+ ResultSetIterator(Class iteratorElementType) throws Exception
+ {
+ if (iteratorElementType == null)
+ throw new
Exception(ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_ITERATOR);
+
+ this.iteratorElementType = iteratorElementType;
+ }
+
+ public boolean hasNext()
+ {
+ if (primed)
+ return true;
+ try
+ {
+ primed = rs.next();
+ }
+ catch (SQLException sqle)
+ {
+ return false;
+ }
+
+ return primed;
+ }
+
+
+ public Object next()
+ {
+ try
+ {
+ if (!primed)
+ {
+ primed = rs.next();
+ if (!primed)
+ throw new NoSuchElementException();
+ }
+ // reset upon consumption
+ primed = false;
+ return extractObject(iteratorElementType);
+ }
+ catch (Exception e)
+ {
+ // Since Iterator interface is locked, all we can do
+ // is put the real exception inside an expected one.
+ NoSuchElementException xNoSuch = new
NoSuchElementException("ResultSet exception: " + e);
+ xNoSuch.initCause(e);
+ throw xNoSuch;
+ }
+ }
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException("remove not supported");
+ }
+ }
+
+
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLParameter.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLParameter.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,215 @@
+package dbControl;
+
+import java.sql.Types;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * A parameter in the SQLStatment.
+ */
+public class SQLParameter
+{
+ private static final String ERROR_INVOKING_GETTER_METHOD = "Failed to
invoke a getter method while setting parameter value";
+ private static final String ERROR_SET_PARAMETER_VALUE_FAILED = "Failed
to set parameter value";
+
+ /**
+ * Parameter name
+ */
+ private String name;
+
+ /**
+ * Parameter value
+ */
+ private Object value;
+
+ /**
+ * Constructor
+ * @param name of the parameter
+ */
+ public SQLParameter(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * Constructor
+ * @param name name of parameter
+ * @param value value of parameter
+ */
+ public SQLParameter(String name, Object value)
+ {
+ this.name = name;
+ try
+ {
+ this.setValue(value);
+ }
+ catch (Exception e)
+ {
+ //TODO log exception
+ }
+ }
+
+ /**
+ * @return a copy of this parameter
+ */
+ public Object clone()
+ {
+ return new SQLParameter(name, value);
+ }
+
+ /**
+ * Sets the name of this parameter
+ *
+ * @param name name of the parameter
+ */
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ /**
+ * Gets the name of this parameter
+ *
+ * @return name of the parameter
+ */
+ public String getName()
+ {
+ return this.name;
+ }
+
+ /**
+ * The parameter name can be made up of multiple components.
+ * e.g. "employee.address.street"
+ * This method returns each component in a String array.
+ * e.g. {"employee", "address", "street"}
+ *
+ * @return components of the parameter name
+ */
+ public String[] getNameComponents()
+ {
+ return this.name.split("\\.");
+ }
+
+ /**
+ * This method returns the first component in the parameter name.
+ * e.g. It returns "employee" when the name is
"employee.address.street"
+ *
+ * @return the first component in the parameter name
+ */
+ public String getFirstNameComponent()
+ {
+ String[] nameComponents = this.getNameComponents();
+ return nameComponents[0];
+ }
+
+ /**
+ * Returns the value of this parameter.
+ *
+ * @return the value of this parameter
+ */
+ public Object getValue()
+ {
+ return this.value;
+ }
+
+ /**
+ * Sets the value of this parameter
+ *
+ * @param aValue value of this parameter
+ */
+ public void setValue(Object aValue) throws Exception
+ {
+ String[] nameComponents = this.getNameComponents();
+ this.value = aValue;
+ for (int i = 1; i < nameComponents.length; i++)
+ {
+ this.value = extractValue(this.value,
nameComponents[i]);
+ }
+ }
+
+ /**
+ * Returns the value of a field in object where the name of the field
matches fieldName.
+ */
+ private Object extractValue(Object object, String fieldName) throws
Exception
+ {
+ Class objectClass = object.getClass();
+ Object value = null;
+
+ String fieldNameCapped =
Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
+ Method getMethod = null;
+ Method[] methods = objectClass.getMethods();
+
+ //Check if a is<fieldName>() method is available in object.
+ String methodName = "is" + fieldNameCapped;
+ for (int i = 0; i < methods.length; i++)
+ {
+ if (methods[i].getName().equals(methodName) &&
+ methods[i].getParameterTypes().length == 0 &&
+
(methods[i].getReturnType().equals(Boolean.class) ||
+
methods[i].getReturnType().equals(Boolean.TYPE)))
+ {
+ getMethod = methods[i];
+ break;
+ }
+ }
+
+ if (getMethod == null)
+ {
+ //Check if a get<fieldName>() method is available in
object.
+ methodName = "get" + fieldNameCapped;
+ for (int i = 0; i < methods.length; i++)
+ {
+ if (methods[i].getName().equals(methodName) &&
+ methods[i].getParameterTypes().length
== 0)
+ {
+ getMethod = methods[i];
+ break;
+ }
+ }
+ }
+
+ //If object contains a getter method for fieldName, invoke the
method
+ //to get the value of fieldName.
+ if (getMethod != null)
+ {
+ try
+ {
+ value = getMethod.invoke(object,
(Object[])null);
+ }
+ catch (Exception e)
+ {
+ throw new
Exception(ERROR_INVOKING_GETTER_METHOD, e);
+ }
+ return value;
+ }
+
+ //If a field named fieldName exists, return the value of this
field.
+ Field[] fields = objectClass.getFields();
+ for (int i = 0; i < fields.length; i++)
+ {
+ if (fields[i].getName().equals(fieldName))
+ {
+ try
+ {
+ return fields[i].get(object);
+ }
+ catch (Exception e)
+ {
+ throw new
Exception(ERROR_INVOKING_GETTER_METHOD, e);
+ }
+ }
+ }
+
+ //If object is a Map and it contains a key equals fieldName,
then return the value
+ //mapped to key.
+ if (object instanceof Map &&
((Map)object).containsKey(fieldName))
+ {
+ return ((Map)object).get(fieldName);
+ }
+
+ //Failed to get the value of fieldName from object.
+ throw new Exception(ERROR_SET_PARAMETER_VALUE_FAILED);
+ }
+
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLParser.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLParser.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,125 @@
+package dbControl;
+
+/**
+ * This class parses the statement member of the SQL annotation in the
+ * Database Control into a SQLStatement object.
+ */
+public class SQLParser
+{
+ //Error messages.
+ private static final String ERROR_MISSING_QUOTE = "A quote is missing from
SQL statement.";
+ private static final String ERROR_MISSING_BRACE = "A closing brace is
missing from SQL statement.";
+ private static final String ERROR_UNEXPECTED_BRACE = "An unexpected
closing brace found in SQL statement.";
+
+ //Points to a position in the SQL statement during parsing.
+ private int position = 0;
+
+ //The statement member in a SQL annotation.
+ private String statement;
+
+ /**
+ * Constructor
+ * @param stmt the statement member of a SQL annotation.
+ */
+ public SQLParser(String stmt)
+ {
+ this.statement = stmt;
+ }
+
+ /**
+ * Specifies the statement member of a SQL annotation to parse.
+ * @param stmt the statment member of a SQL annotation.
+ */
+ public void setStatement(String stmt) {
+ this.statement = stmt;
+ }
+
+ /**
+ * Parse a statement member of a SQL annotation into a SQLStatement
+ * object
+ * @return the SQLStatement representing of statement
+ */
+ public SQLStatement parse() throws Exception
+ {
+ SQLStatement sql = new SQLStatement();
+ parseStatement(sql);
+
+ if (-1 != position)
+ throw new Exception(ERROR_UNEXPECTED_BRACE);
+
+ return sql;
+ }
+
+
+ private void parseEscape(SQLStatement stmt) throws Exception
+ {
+ int i = findOneOf(statement, " :}", position);
+
+ int closeBrace = statement.indexOf('}', position);
+
+ if (closeBrace < 0)
+ throw new Exception(ERROR_MISSING_BRACE);
+
+ String paramName = statement.substring(position, closeBrace);
+ this.position = closeBrace;
+ stmt.addParameter(new SQLParameter(paramName));
+
+ if (-1 == position || statement.charAt(position) != '}')
+ throw new Exception(ERROR_MISSING_BRACE);
+
+ this.position++;
+ }
+
+ /**
+ * bascially just accept everything as-is, only looking for escapes
+ * only need to recognize SQL strings properly
+ */
+ private void parseStatement(SQLStatement stmt)
+ throws Exception
+ {
+ int index = position;
+ while ((index = findOneOf(statement, "{'}", index)) >= 0)
+ {
+ char ch = statement.charAt(index);
+
+ if (ch == '\'')
+ {
+ index = statement.indexOf('\'', index + 1);
+ if (-1 == index)
+ {
+ throw new Exception(ERROR_MISSING_QUOTE);
+ }
+ index++;
+ continue;
+ }
+
+ //Append to stmt text up-to, but not including { or }
+ stmt.append(statement.substring(position, index));
+ position = index;
+
+ if (ch == '}')
+ break;
+
+ this.position++;
+ parseEscape(stmt);
+ index = this.position;
+ }
+
+ if (-1 == index)
+ {
+ stmt.append(statement.substring(position));
+ this.position = -1;
+ }
+ }
+
+ static int findOneOf(String s, String chars, int i)
+ {
+ if (i == -1)
+ return -1;
+ for (; i < s.length() ; i++)
+ if (-1 != chars.indexOf(s.charAt(i)))
+ return i;
+ return -1;
+ }
+
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLStatement.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/SQLStatement.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,223 @@
+package dbControl;
+
+import dbControl.util.PreparedStatementHelper;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * This class holds a SQL statement and its parameters.
+ */
+public class SQLStatement
+{
+ transient Calendar calendar = null;
+ protected CharSequence sql;
+ protected List<SQLParameter> parameters;
+
+ /**
+ * Default constructor
+ */
+ public SQLStatement()
+ {
+ super();
+ sql = new StringBuffer();
+ parameters = new _ArrayList();
+ }
+
+ /**
+ * Constructor
+ * @param a SQL statement
+ */
+ public SQLStatement(String sql)
+ {
+ if (sql != null)
+ this.sql = sql;
+ else
+ this.sql = new StringBuffer();
+
+ this.parameters = new _ArrayList();
+ }
+
+ /**
+ * Constructor
+ * @param a SQL statement
+ * @param parameters parameters of the SQL statement
+ */
+ public SQLStatement(String sql, SQLParameter[] parameters)
+ {
+ if (sql != null)
+ this.sql = sql;
+ else
+ this.sql = new StringBuffer();
+
+ this.parameters = parameters != null ? Arrays.asList(parameters) : new
_ArrayList();
+ }
+
+ /**
+ * Constructor
+ * @param sql SQL statement
+ * @param parameters parameters of the SQL statement
+ * @param cal calendar for processing dates in the SQL statment.
+ */
+ public SQLStatement(String sql, SQLParameter[] parameters, Calendar cal)
+ {
+ if (sql != null)
+ this.sql = sql;
+ else
+ this.sql = new StringBuffer();
+
+ this.parameters = parameters != null ? Arrays.asList(parameters) : new
_ArrayList();
+ this.calendar = cal;
+ }
+
+ /**
+ * Returns the SQL statement of this class
+ * @return a sql statement
+ */
+ public String getSQL()
+ {
+ return sql.toString();
+ }
+
+ /**
+ * Returns the parameters of the SQL statement in this class
+ * @return parameters of the SQL statement in this class
+ */
+ public SQLParameter[] getParameters()
+ {
+ if (null == parameters)
+ return new SQLParameter[0];
+ return (SQLParameter[])parameters.toArray(new
SQLParameter[parameters.size()]);
+ }
+
+ /**
+ * Returns the SQL statement of this class
+ * @return a sql statement
+ */
+ public String toString()
+ {
+ return sql.toString();
+ }
+
+ /**
+ * Inserts a string into this SQL statement.
+ * @param offset the offset
+ * @param str the string
+ * @return a reference to this object
+ */
+ public SQLStatement insert(int offset, String str)
+ {
+ ((StringBuffer)sql).insert(offset, str);
+ return this;
+ }
+
+ /**
+ * Adds a parameter to this SQL statement
+ * @param param a SQL parameter
+ * @return a reference to this object.
+ */
+ protected SQLStatement addParameter(SQLParameter param)
+ {
+ try { ((StringBuffer)sql).append('?'); } catch (Exception ignore) {}
+ parameters.add(param);
+ return this;
+ }
+
+ /**
+ * Adds a collection of paramters to this sql statement
+ * @param params a collection of SQL parameters
+ */
+ protected void addAll(Collection<SQLParameter> params)
+ {
+ if (null == params)
+ return;
+ parameters.addAll(params);
+ }
+
+ /**
+ * Appends a seqence of characters to the SQL statement
+ */
+ public SQLStatement append(CharSequence sb)
+ {
+ try { ((StringBuffer)sql).append(sb); } catch (Exception ignore) {}
+ return this;
+ }
+
+ /**
+ * Appends a character to the SQL statement
+ */
+ public SQLStatement append(char c)
+ {
+ try { ((StringBuffer)sql).append(c); } catch (Exception ignore) {}
+ return this;
+ }
+
+ /*
+ * Assigns values to the parameters in the SQL parameter by order
+ * @param values values to be assigned to the SQL statement's parameters.
+ * @throws ControlException
+
+ public void setParameterValuesByPosition(Object[] values) throws Exception{
+ for (SQLParameter param : parameters)
+ {
+ int pos;
+ try
+ {
+ pos = Integer.parseInt(param.name);
+ //offset for zero base values array.
+ pos -= 1;
+ }
+ catch (NumberFormatException nfe)
+ {
+ throw new Exception("Parameter name is not an integer.", nfe);
+ }
+ if (pos < 0 || pos >= values.length)
+ {
+ throw new Exception("No argument provided for parameter: " +
pos);
+ }
+ param.value = values[pos];
+ }
+ }
+ */
+
+ /**
+ * This method returns a prepared statement constructed based on the
+ * attributes of the class.
+ * @ return a prepared statement with its SQL statement and parameters set.
+ */
+ public PreparedStatement getPreparedStatement(Connection connection)
throws SQLException
+ {
+ PreparedStatement ps = connection.prepareStatement(getSQL());
+ for (int i = 0; i < this.parameters.size(); i++)
+ {
+ //prepared statement index is 1-based not zero-based as the
parameters list.
+ int pos = i + 1;
+ SQLParameter param = this.parameters.get(i);
+ PreparedStatementHelper.setPreparedStatementParameter(ps, pos,
param.getValue(), calendar);
+ }
+ return ps;
+ }
+
+ private class _ArrayList extends ArrayList
+ {
+ public void setSize(int size)
+ {
+ ensureCapacity(size);
+ while (size() < size)
+ add(null);
+ }
+ public Object set(int i, Object o)
+ {
+ if (i >= size())
+ setSize(i+1);
+ return super.set(i,o);
+ }
+ }
+
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/JavaTypeHelper.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/JavaTypeHelper.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,85 @@
+package dbControl.util;
+
+import java.sql.Types;
+import java.util.HashMap;
+
+public class JavaTypeHelper
+{
+ private static final int TYPE_MAX = 29;
+ private static final int JAVA_PRIMITIVE_TYPES = 8;
+ private static HashMap javaSQLTypeMap = new HashMap(TYPE_MAX * 2);
+ private static HashMap primitiveDefaults = new
HashMap(JAVA_PRIMITIVE_TYPES);
+
+ static {
+ // Class to java.sql.Types
+ javaSQLTypeMap.put(Boolean.TYPE, Types.BOOLEAN);
+ javaSQLTypeMap.put(Integer.TYPE, Types.INTEGER);
+ javaSQLTypeMap.put(Long.TYPE, Types.BIGINT);
+ javaSQLTypeMap.put(Byte.TYPE, Types.TINYINT);
+ javaSQLTypeMap.put(Short.TYPE, Types.SMALLINT);
+ javaSQLTypeMap.put(Float.TYPE, Types.REAL);
+ javaSQLTypeMap.put(Double.TYPE, Types.DOUBLE);
+ javaSQLTypeMap.put(Boolean.class, Types.BOOLEAN);
+ javaSQLTypeMap.put(Integer.class, Types.INTEGER);
+ javaSQLTypeMap.put(Long.class, Types.BIGINT);
+ javaSQLTypeMap.put(Byte.class, Types.TINYINT);
+ javaSQLTypeMap.put(Short.class, Types.SMALLINT);
+ javaSQLTypeMap.put(Float.class, Types.REAL);
+ javaSQLTypeMap.put(Double.class, Types.DOUBLE);
+ javaSQLTypeMap.put(String.class, Types.VARCHAR);
+ javaSQLTypeMap.put(java.math.BigDecimal.class, Types.DECIMAL);
+ javaSQLTypeMap.put(byte[].class, Types.VARBINARY);
+ javaSQLTypeMap.put(java.sql.Timestamp.class, Types.TIMESTAMP);
+ javaSQLTypeMap.put(java.sql.Time.class, Types.TIME);
+ javaSQLTypeMap.put(java.sql.Date.class, Types.DATE);
+ javaSQLTypeMap.put(java.sql.Ref.class, Types.REF);
+ javaSQLTypeMap.put(java.sql.Blob.class, Types.BLOB);
+ javaSQLTypeMap.put(java.sql.Clob.class, Types.CLOB);
+ javaSQLTypeMap.put(java.sql.Array.class, Types.ARRAY);
+ javaSQLTypeMap.put(java.util.Date.class, Types.TIMESTAMP);
+ javaSQLTypeMap.put(java.util.Calendar.class, Types.TIMESTAMP);
+ javaSQLTypeMap.put(java.util.GregorianCalendar.class, Types.TIMESTAMP);
+ //javaSQLTypeMap.put(java.io.Reader.class, Types.READER);
+ //javaSQLTypeMap.put(java.io.InputStream.class, Types.STREAM);
+
+ //Java Primitive to Default values.
+ primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
+ primitiveDefaults.put(Integer.TYPE, new Integer(0));
+ primitiveDefaults.put(Long.TYPE, new Long(0));
+ primitiveDefaults.put(Byte.TYPE, new Byte((byte)0));
+ primitiveDefaults.put(Short.TYPE, new Short((short)0));
+ primitiveDefaults.put(Character.TYPE, new Character('\u0000'));
+ primitiveDefaults.put(Float.TYPE, new Float(0.0f));
+ primitiveDefaults.put(Double.TYPE, new Double(0.0d));
+
+ }
+
+
+
+ public static int getSqlType(Class classType)
+ {
+ while (null != classType)
+ {
+ Integer type = (Integer)javaSQLTypeMap.get(classType);
+ if (null != type)
+ return type.intValue();
+ classType = classType.getSuperclass();
+ }
+ return Types.OTHER;
+ }
+
+
+ public static int getSqlType(Object o)
+ {
+ if (null == o)
+ return Types.NULL;
+ return getSqlType(o.getClass());
+ }
+
+ public static Object getJaveTypeDefaultValue(Class primitiveType) {
+ if (primitiveType.isPrimitive())
+ return (primitiveDefaults.get(primitiveType));
+ else
+ return null;
+ }
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/PreparedStatementHelper.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/PreparedStatementHelper.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,163 @@
+package dbControl.util;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+public class PreparedStatementHelper
+{
+ private interface ParameterSetter {
+
+ public static final int NUM_OF_PARAMETER_SETTERS = 5;
+
+ public void setParameter(PreparedStatement ps, int index, Object
value, Calendar cal) throws SQLException;
+
+ static ParameterSetter VARCHAR = new ParameterSetter()
+ {
+ public void setParameter(PreparedStatement ps, int index, Object
value, Calendar cal) throws SQLException
+ {
+ String setValue = value instanceof String ? (String)value :
value.toString();
+ ps.setObject(index, setValue, Types.VARCHAR);
+ }
+ };
+
+ static ParameterSetter BOOLEAN = new ParameterSetter()
+ {
+ public void setParameter(PreparedStatement ps, int index, Object
value, Calendar cal) throws SQLException
+ {
+ if (value instanceof Boolean)
+ ps.setBoolean(index, ((Boolean)value).booleanValue());
+ }
+ };
+
+ static ParameterSetter TIMESTAMP = new ParameterSetter()
+ {
+ public void setParameter(PreparedStatement ps, int index, Object
value, Calendar cal) throws SQLException
+ {
+ if (value instanceof java.util.Calendar)
+ {
+ Calendar calValue = (Calendar)value;
+
+ if (null == cal)
+ {
+ /* NOTE: drivers are inconsistent in their handling of
setTimestamp(i,date,cal)
+ * so we won't use that, unless the user calls
setCalendar().
+ * I'm going with the theory that it makes sense to
store
+ * the time relative to the Calendar's timezone rather
than
+ * the system timezone otherwise, using a Calendar
would be a no-op.
+ */
+ value = new java.sql.Timestamp(
+ calValue.get(Calendar.YEAR) - 1900,
+ calValue.get(Calendar.MONTH),
+ calValue.get(Calendar.DATE),
+ calValue.get(Calendar.HOUR_OF_DAY),
+ calValue.get(Calendar.MINUTE),
+ calValue.get(Calendar.SECOND),
+ calValue.get(Calendar.MILLISECOND));
+ }
+ else
+ {
+ value = new
java.sql.Timestamp(calValue.getTimeInMillis());
+ }
+ }
+ else if (java.util.Date.class.equals(value.getClass()))
+ {
+ // some drivers don't like java.util.Date
+ value = new
java.sql.Timestamp(((java.util.Date)value).getTime());
+ }
+
+ if (value instanceof java.sql.Timestamp)
+ {
+ if (null == cal)
+ ps.setTimestamp(index, (java.sql.Timestamp)value);
+ else
+ ps.setTimestamp(index, (java.sql.Timestamp)value, cal);
+ return;
+ }
+ }
+ };
+
+ static ParameterSetter DATE = new ParameterSetter() {
+ public void setParameter(PreparedStatement ps, int index, Object
value, Calendar cal) throws SQLException
+ {
+ if (value instanceof java.util.Calendar)
+ {
+ /* NOTE: see note above
+ Calendar cal = (Calendar)value;
+ value = new java.sql.Date(cal.getTimeInMillis());
+ ps.setDate(i, (java.sql.Date)value, cal);
+ return;
+ */
+ Calendar calValue = (Calendar)value;
+
+ if (null == cal)
+ {
+ value = new java.sql.Date(
+ calValue.get(Calendar.YEAR - 1900),
+ calValue.get(Calendar.MONTH),
+ calValue.get(Calendar.DATE));
+ }
+ else
+ value = new java.sql.Date(calValue.getTimeInMillis());
+ }
+ else if (value.getClass() == java.util.Date.class)
+ {
+ // some drivers don't like java.util.Date
+ value = new
java.sql.Date(((java.util.Date)value).getTime());
+ }
+
+ if (value instanceof java.sql.Date)
+ {
+ if (null == cal)
+ ps.setDate(index, (java.sql.Date)value);
+ else
+ ps.setDate(index, (java.sql.Date)value, cal);
+ return;
+ }
+ }
+ };
+
+ static ParameterSetter TIME = new ParameterSetter()
+ {
+ public void setParameter(PreparedStatement ps, int index, Object
value, Calendar cal) throws SQLException
+ {
+ if (value instanceof java.sql.Time)
+ {
+ if (null == cal)
+ ps.setTime(index, (java.sql.Time)value);
+ else
+ ps.setTime(index, (java.sql.Time)value, cal);
+ return;
+ }
+ }
+ };
+ }
+
+ private static Map<Integer,ParameterSetter> typeToSetterMap = new
HashMap(ParameterSetter.NUM_OF_PARAMETER_SETTERS * 2);
+
+ static
+ {
+ typeToSetterMap.put(Types.BOOLEAN, ParameterSetter.BOOLEAN);
+ typeToSetterMap.put(Types.TIMESTAMP, ParameterSetter.TIMESTAMP);
+ typeToSetterMap.put(Types.DATE, ParameterSetter.DATE);
+ typeToSetterMap.put(Types.TIME, ParameterSetter.TIME);
+ typeToSetterMap.put(Types.VARCHAR, ParameterSetter.VARCHAR);
+ }
+
+ public static void setPreparedStatementParameter(PreparedStatement ps, int
index, Object value, Calendar calendar)
+ throws SQLException
+ {
+ int sqlType = JavaTypeHelper.getSqlType(value);
+ ParameterSetter setter = typeToSetterMap.get(sqlType);
+ if (null != setter)
+ setter.setParameter(ps, index, value, calendar);
+ else if (null == value)
+ ps.setNull(index, Types.NULL == sqlType ? Types.VARCHAR : sqlType);
+ else
+ ps.setObject(index, value, sqlType);
+
+ }
+}
Added:
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/ResultSetHelper.java
==============================================================================
--- (empty file)
+++
incubator/beehive/branches/v1/alpha/samples/controls-db/src/dbControl/util/ResultSetHelper.java
Thu Oct 28 18:21:48 2004
@@ -0,0 +1,320 @@
+package dbControl.util;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ResultSetHelper
+{
+ private static final int TYPE_MAX = 29;
+
+ private interface ColumnReader {
+
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException;
+
+ static ColumnReader UNKNOWN = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getObject(columnName);
+ }
+ };
+
+ static ColumnReader BYTE = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return new Byte(rs.getByte(columnName));
+ }
+ };
+
+ static ColumnReader SHORT = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return new Short(rs.getShort(columnName));
+ }
+ };
+
+ static ColumnReader INT = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return new Integer(rs.getInt(columnName));
+ }
+ };
+
+ static ColumnReader LONG = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return new Long(rs.getLong(columnName));
+ }
+ };
+
+ static ColumnReader FLOAT = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return new Float(rs.getFloat(columnName));
+ }
+ };
+
+ static ColumnReader DOUBLE = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return new Double(rs.getDouble(columnName));
+ }
+ };
+
+ static ColumnReader BOOLEAN = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getBoolean(columnName) ? Boolean.TRUE :
Boolean.FALSE;
+ }
+ };
+
+ static ColumnReader BYTE_OBJ = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ byte i = rs.getByte(columnName); return rs.wasNull() ? null :
new Byte(i);
+ }
+ };
+
+ static ColumnReader SHORT_OBJ = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ short i = rs.getShort(columnName); return rs.wasNull() ? null
: new Short(i);
+ }
+ };
+
+ static ColumnReader INT_OBJ = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ int i = rs.getInt(columnName); return rs.wasNull() ? null :
new Integer(i);
+ }
+ };
+
+ static ColumnReader LONG_OBJ = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ long i = rs.getLong(columnName); return rs.wasNull() ? null :
new Long(i);
+ }
+ };
+
+ static ColumnReader FLOAT_OBJ = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ float i = rs.getFloat(columnName); return rs.wasNull() ? null
: new Float(i);
+ }
+ };
+ static ColumnReader DOUBLE_OBJ = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ double i = rs.getDouble(columnName); return rs.wasNull() ?
null : new Double(i);
+ }
+ };
+
+ static ColumnReader BOOLEAN_OBJ = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ boolean i = rs.getBoolean(columnName); return rs.wasNull() ?
null : (i ? Boolean.TRUE : Boolean.FALSE);
+ }
+ };
+
+ static ColumnReader BIG_DECIMAL = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getBigDecimal(columnName);
+ }
+ };
+
+ static ColumnReader STRING = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getString(columnName);
+ }
+ };
+
+ static ColumnReader BYTES = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String
columnName, GregorianCalendar cal) throws SQLException
+ {
+ return rs.getBytes(columnName);
+ }
+ };
+
+ static ColumnReader SQLDATE = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ if (null == cal)
+ return rs.getDate(columnName);
+ else
+ return rs.getDate(columnName, cal);
+ }
+ };
+
+ static ColumnReader TIME = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ if (null == cal)
+ return rs.getTime(columnName);
+ else
+ return rs.getTime(columnName, cal);
+ }
+ };
+
+ static ColumnReader TIMESTAMP = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ if (null == cal)
+ return rs.getTimestamp(columnName);
+ else
+ return rs.getTimestamp(columnName, cal);
+ }
+ };
+
+ static ColumnReader STREAM = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ //not supported
+ return null;
+ }
+ };
+
+ static ColumnReader READER = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ //not supported
+ return null;
+ }
+ };
+
+ static ColumnReader CLOB = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getClob(columnName);
+ }
+ };
+
+ static ColumnReader BLOB = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getBlob(columnName);
+ }
+ };
+
+ static ColumnReader ARRAY = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getArray(columnName);
+ }
+ };
+
+ static ColumnReader REF = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ return rs.getRef(columnName);
+ }
+ };
+
+ static ColumnReader DATE = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ java.sql.Timestamp ts = (null == cal) ?
rs.getTimestamp(columnName) : rs.getTimestamp(columnName, cal);
+ if (null == ts)
+ return null;
+ return new java.util.Date(ts.getTime());
+ }
+ };
+
+ static ColumnReader CALENDAR = new ColumnReader()
+ {
+ public Object readValue(ResultSet rs, String columnName,
GregorianCalendar cal) throws SQLException
+ {
+ java.sql.Timestamp ts = (null == cal) ?
rs.getTimestamp(columnName) : rs.getTimestamp(columnName, cal);
+ if (null == ts)
+ return null;
+ Calendar c = (null == cal) ? Calendar.getInstance() :
(Calendar)cal.clone();
+ c.setTimeInMillis(ts.getTime());
+ return c;
+ }
+ };
+ }
+
+
+
+
+
+ private static Map<Class,ColumnReader> typeToReaderMap = new
HashMap(TYPE_MAX * 2);
+
+ static
+ {
+ typeToReaderMap.put(Boolean.TYPE, ColumnReader.BOOLEAN);
+ typeToReaderMap.put(Integer.TYPE, ColumnReader.INT);
+ typeToReaderMap.put(Long.TYPE, ColumnReader.LONG);
+ typeToReaderMap.put(Byte.TYPE, ColumnReader.BYTE);
+ typeToReaderMap.put(Short.TYPE, ColumnReader.SHORT);
+ typeToReaderMap.put(Float.TYPE, ColumnReader.FLOAT);
+ typeToReaderMap.put(Double.TYPE, ColumnReader.DOUBLE);
+ typeToReaderMap.put(Boolean.class, ColumnReader.BOOLEAN_OBJ);
+ typeToReaderMap.put(Integer.class, ColumnReader.INT_OBJ);
+ typeToReaderMap.put(Long.class, ColumnReader.LONG_OBJ);
+ typeToReaderMap.put(Byte.class, ColumnReader.BYTE_OBJ);
+ typeToReaderMap.put(Short.class, ColumnReader.SHORT_OBJ);
+ typeToReaderMap.put(Float.class, ColumnReader.FLOAT_OBJ);
+ typeToReaderMap.put(Double.class, ColumnReader.DOUBLE_OBJ);
+ typeToReaderMap.put(String.class, ColumnReader.STRING);
+ typeToReaderMap.put(java.math.BigDecimal.class,
ColumnReader.BIG_DECIMAL);
+ typeToReaderMap.put(byte[].class, ColumnReader.BYTES);
+ typeToReaderMap.put(java.sql.Timestamp.class, ColumnReader.TIMESTAMP);
+ typeToReaderMap.put(java.sql.Time.class, ColumnReader.TIME);
+ typeToReaderMap.put(java.sql.Date.class, ColumnReader.SQLDATE);
+ typeToReaderMap.put(java.sql.Ref.class, ColumnReader.REF);
+ typeToReaderMap.put(java.sql.Blob.class, ColumnReader.BLOB);
+ typeToReaderMap.put(java.sql.Clob.class, ColumnReader.CLOB);
+ typeToReaderMap.put(java.sql.Array.class, ColumnReader.ARRAY);
+ typeToReaderMap.put(java.io.Reader.class, ColumnReader.READER);
+ typeToReaderMap.put(java.io.InputStream.class, ColumnReader.STREAM);
+ typeToReaderMap.put(java.util.Date.class, ColumnReader.DATE);
+ typeToReaderMap.put(java.util.Calendar.class, ColumnReader.CALENDAR);
+ typeToReaderMap.put(java.util.GregorianCalendar.class,
ColumnReader.CALENDAR);
+ }
+
+ public static Object readValue(ResultSet rs, String columnName, Class
resultType) throws SQLException
+ {
+ return readValue(rs, columnName, resultType, null);
+ }
+
+ public static Object readValue(ResultSet rs, String columnName, Class
resultType, GregorianCalendar cal) throws SQLException
+ {
+ ColumnReader reader = typeToReaderMap.get(resultType);
+ if (reader == null)
+ reader = ColumnReader.UNKNOWN;
+ return reader.readValue(rs, columnName, cal);
+ }
+}