Author: kentam
Date: Tue Oct  5 16:12:30 2004
New Revision: 53833

Added:
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControl.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControlImpl.jcs
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/ResultSetExtractor.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParameter.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParser.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLStatement.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/Employee.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/TestDBControl.jcx
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/JavaTypeHelper.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/PreparedStatementHelper.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/ResultSetHelper.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/
   
incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/DriveDatabaseControl.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/Car.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/ParserTest.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/ResultSetExtractorTest.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/SQLStatementTest.java
   (contents, props changed)
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/jpf/database/
   
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/jpf/database/TestDatabaseControl.java
   (contents, props changed)
   incubator/beehive/trunk/controls/test/webapps/controlsWeb/database/
   
incubator/beehive/trunk/controls/test/webapps/controlsWeb/database/Controller.jpf
   (contents, props changed)
Modified:
   incubator/beehive/trunk/controls/test/build.xml
   incubator/beehive/trunk/controls/test/webapps/build.xml
   incubator/beehive/trunk/controls/test/webapps/controlsWeb/app.properties
Log:
Integration of Derby database and initial implementation/tests for a database 
(JDBC) control.

Contributed by: Hoi Lam ([EMAIL PROTECTED])



Modified: incubator/beehive/trunk/controls/test/build.xml
==============================================================================
--- incubator/beehive/trunk/controls/test/build.xml     (original)
+++ incubator/beehive/trunk/controls/test/build.xml     Tue Oct  5 16:12:30 2004
@@ -55,6 +55,7 @@
         <pathelement location="${velocity14.jar}"/>
         <pathelement location="${velocitydep14.jar}"/>
         <pathelement location="${servlet24.jar}"/>
+        <pathelement location="${derby.jar}"/>
         <pathelement path="../build/jars/controls.jar"/>
         <pathelement path="${build.beans}"/>
     </path>
@@ -72,6 +73,7 @@
         <pathelement location="${velocity14.jar}"/>
         <pathelement location="${velocitydep14.jar}"/>
         <pathelement location="${servlet24.jar}"/>
+        <pathelement location="${derby.jar}"/>
         <pathelement location="../build/jars/controls.jar"/>
         <pathelement path="${build.beans}"/>
        

Added: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControl.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControl.java
  Tue Oct  5 16:12:30 2004
@@ -0,0 +1,64 @@
+package org.apache.beehive.controls.test.controls.database;
+
+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/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControlImpl.jcs
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/DatabaseControlImpl.jcs
       Tue Oct  5 16:12:30 2004
@@ -0,0 +1,212 @@
+package org.apache.beehive.controls.test.controls.database;
+
+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;
+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 org.apache.beehive.controls.test.controls.database.util.JavaTypeHelper;
+
[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";
+
+    @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.setParameterValues(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;
+    }
+
+}

Added: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/ResultSetExtractor.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/ResultSetExtractor.java
       Tue Oct  5 16:12:30 2004
@@ -0,0 +1,368 @@
+package org.apache.beehive.controls.test.controls.database;
+
+//import org.apache.beehive.controls.api.ControlException;
+import org.apache.beehive.controls.test.controls.database.util.JavaTypeHelper;
+import org.apache.beehive.controls.test.controls.database.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/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParameter.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParameter.java
     Tue Oct  5 16:12:30 2004
@@ -0,0 +1,44 @@
+package org.apache.beehive.controls.test.controls.database;
+
+import java.sql.Types;
+
+/**
+ * A parameter in the SQLStatment.
+ */
+public class SQLParameter
+{
+    /**
+     * Parameter name
+     */
+    public String name;
+    
+    /**
+     * Parameter value
+     */
+    public 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;
+        this.value = value;
+    }
+
+    public Object clone()
+    {
+        return new SQLParameter(name, value);
+    }
+}

Added: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParser.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLParser.java
        Tue Oct  5 16:12:30 2004
@@ -0,0 +1,125 @@
+package org.apache.beehive.controls.test.controls.database;
+
+/**
+ * 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/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLStatement.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/SQLStatement.java
     Tue Oct  5 16:12:30 2004
@@ -0,0 +1,216 @@
+package org.apache.beehive.controls.test.controls.database;
+
+import 
org.apache.beehive.controls.test.controls.database.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 setParameterValues(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.value, 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/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/Employee.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/Employee.java
    Tue Oct  5 16:12:30 2004
@@ -0,0 +1,49 @@
+package org.apache.beehive.controls.test.controls.database.test;
+
+public class Employee
+{
+       public int id;
+       public String fName;
+       public String lName;
+       public String title;
+
+       public Employee() {
+               super();
+       }
+
+       public Employee(int id, String fName, String lName, String title) {
+               this.id = id;
+               this.fName = fName;
+               this.lName = lName;
+               this.title = title;
+       }
+
+       public String toString()
+       {
+               return "[" + id + "," + fName + "," + lName + "," + title + "] 
";
+       }
+
+       public boolean equals(Object obj) {
+               if (obj == null || !(obj instanceof Employee))
+                       return false;
+
+               Employee emp = (Employee)obj;
+
+               if (this.id != emp.id)
+                       return false;
+               else if (this.fName == null && emp.fName != null)
+                       return false;
+               else if (!this.fName.equals(emp.fName))
+                       return false;
+               else if (this.lName == null && emp.lName != null)
+                       return false;
+               else if (!this.lName.equals(emp.lName))
+                       return false;
+               else if (this.title == null && emp.title != null)
+                       return false;
+               else if (!this.title.equals(emp.title))
+                       return false;
+
+               return true;
+       }
+}

Added: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/TestDBControl.jcx
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/test/TestDBControl.jcx
        Tue Oct  5 16:12:30 2004
@@ -0,0 +1,49 @@
+package org.apache.beehive.controls.test.controls.database.test;
+
+import java.sql.SQLException;
+import java.io.Serializable;
+import java.util.Iterator;
+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;
+
[EMAIL PROTECTED]
[EMAIL PROTECTED](jndiName="jdbc:derby:build/databaseControlTestDB;create=true")
+public interface TestDBControl extends DatabaseControl
+{
+    @SQL(statement="CREATE TABLE EMPLOYEE ( id INT PRIMARY KEY NOT NULL, " +
+                   "fName VARCHAR(20), lName VARCHAR(20), title VARCHAR(15))")
+    public void createTable() throws SQLException;
+
+    @SQL(statement="DROP TABLE EMPLOYEE")
+    public void dropTable() throws SQLException;
+
+    @SQL(statement="INSERT INTO EMPLOYEE " +
+                   "(id, fName, lName, title) " +
+                   "VALUES ({1}, {2}, {3}, {4})")
+    public void insertEmployee(int p_id, String p_fName, String p_lName,
+                               String p_title) throws SQLException;
+
+    @SQL(statement="SELECT * FROM EMPLOYEE WHERE id={1}")
+    public Employee selectEmployee(int p_id) throws SQLException;
+
+    @SQL(statement="SELECT * FROM EMPLOYEE ORDER BY id")
+    public Employee[] selectEmployees() throws SQLException;
+
+    @SQL(statement="SELECT * FROM EMPLOYEE ORDER BY id", 
iteratorElementType=Employee.class)
+    public Iterator selectEmployeesWithIterator() throws SQLException;
+
+    @SQL(statement="SELECT * FROM EMPLOYEE ORDER BY id")
+    public HashMap selectEmployeeWithHashMap() throws SQLException;
+
+    @SQL(statement="SELECT * FROM EMPLOYEE ORDER BY id", maxRows=1)
+    public Employee[] selectOneEmployee() throws SQLException;
+
+    @SQL(statement="UPDATE EMPLOYEE SET title = {2} WHERE id = {1}")
+    public void changeTitle(int p_id, String p_title) throws SQLException;
+
+    @SQL(statement="DELETE FROM EMPLOYEE WHERE id = {1}")
+    public void deleteEmployee(int p_id) throws SQLException;
+}

Added: 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/JavaTypeHelper.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/JavaTypeHelper.java
      Tue Oct  5 16:12:30 2004
@@ -0,0 +1,85 @@
+package org.apache.beehive.controls.test.controls.database.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/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/PreparedStatementHelper.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/PreparedStatementHelper.java
     Tue Oct  5 16:12:30 2004
@@ -0,0 +1,163 @@
+package org.apache.beehive.controls.test.controls.database.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/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/ResultSetHelper.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/controls/org/apache/beehive/controls/test/controls/database/util/ResultSetHelper.java
     Tue Oct  5 16:12:30 2004
@@ -0,0 +1,320 @@
+package org.apache.beehive.controls.test.controls.database.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);
+    }
+}

Added: 
incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/DriveDatabaseControl.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/drivers/org/apache/beehive/controls/test/driver/database/DriveDatabaseControl.java
        Tue Oct  5 16:12:30 2004
@@ -0,0 +1,320 @@
+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 java.util.Iterator;
+import java.util.HashMap;
+
+/* This class contains the logic to test control extensibility.
+ * By invoking methods on a SubControlBean, features of control extensibility 
are verified.
+ */
+
+public class DriveDatabaseControl
+{
+
+       //Error messages
+       private static final String INSERTED_EMPLOYEE_NOT_FOUND = "Inserted 
employee not found ";
+       private static final String EMPLOYEE_ARRAY_IS_EMPTY = "Employee array 
is empty";
+       private static final String BAD_DATA_IN_EMPLOYEE_ARRAY = "Data in 
employee array does not match expectation.";
+       private static final String EMPLOYEE_ITERATOR_IS_NULL = "Employee 
iterator is null";
+       private static final String BAD_DATA_IN_EMPLOYEE_ITERATOR = "Data in 
employee iterator does not match expectation.";
+       private static final String EMPLOYEE_HASHMAP_IS_NULL = "Employee 
HashMap is null";
+       private static final String BAD_DATA_IN_EMPLOYEE_HASHMAP = "Data in 
employee HashMap does not match expectation.";
+       private static final String SELECT_ONE_EMPLOYEE_FAILED = "Select one 
employee did not return one employee";
+       private static final String UPDATE_EMPLOYEE_FAILED = "Failed to update 
employee";
+       private static final String DELETE_EMPLOYEE_FAILED = "Failed to delete 
employee";
+
+       //Test data
+       private static Employee[] emps = { new Employee(1, "John", "Doe", 
"CEO"), new Employee(2, "Jane", "Doe", "CFO") };
+
+
+       private TestDBControlBean testDBControl;
+
+       public DriveDatabaseControl (TestDBControlBean aControl)
+       {
+               this.testDBControl = aControl;
+       }
+
+       public void setControl(TestDBControlBean aControl)
+       {
+
+               this.testDBControl = aControl;
+       }
+
+       public Report doCreateTable()
+       {
+               Report report=new Report();
+               try
+               {
+                       testDBControl.createTable();
+                       report.setStatus(Report.PASS);
+               }
+               catch(Exception e)
+               {
+                       report.setStatus(Report.FAIL);
+                       report.setExceptionStack(e);
+               }
+               return report;
+       }
+
+       public Report doDropTable()
+       {
+
+               Report report=new Report();
+               try
+               {
+                       testDBControl.dropTable();
+                       report.setStatus(Report.PASS);
+        }
+        catch(Exception e)
+        {
+                       report.setStatus(Report.FAIL);
+                       report.setExceptionStack(e);
+        }
+               return report;
+       }
+
+       public Report doInsertEmployees()
+       {
+               Report report=new Report();
+               try
+               {
+                       //Insert test employees
+                       for (int i = 0; i < emps.length; i++)
+                       {
+                               testDBControl.insertEmployee(emps[i].id, 
emps[i].fName, emps[i].lName, emps[i].title);
+                       }
+
+                       //Retrieve the two employees just inserted, and verify 
they match those
+                       //inserted.
+                       for (int i = 0; i < emps.length; i++)
+                       {
+                               Employee emp = 
testDBControl.selectEmployee(emps[i].id);
+                               if (emp == null || !emp.equals(emps[i]))
+                               {
+                                       
report.setMessage(INSERTED_EMPLOYEE_NOT_FOUND + emps[i] + emp);
+                                       break;
+                               }
+                               report.setStatus(Report.PASS);
+                       }
+
+        }
+        catch(Exception e)
+        {
+                       report.setExceptionStack(e);
+        }
+               return report;
+       }
+
+       public Report doSelectEmployeesWithArray()
+       {
+               Report report=new Report();
+               try
+               {
+
+                       //Select employees into array
+                       Employee[] employees = testDBControl.selectEmployees();
+
+                       //Ensure the array is not empty
+                       if (employees == null || employees.length == 0)
+                       {
+                                report.setMessage(EMPLOYEE_ARRAY_IS_EMPTY + 
employees);
+                       }
+                       //Ensure correct number of employees in the array
+                       else if (employees.length != emps.length)
+                       {
+                                report.setMessage(BAD_DATA_IN_EMPLOYEE_ARRAY);
+                       }
+                       else {
+                               //Ensure employee in array matches those 
inserted
+                               for (int i = 0; i < emps.length; i++)
+                               {
+                                       if (employees[i] == null || 
!employees[i].equals(emps[i]))
+                                       {
+                                               
report.setMessage(BAD_DATA_IN_EMPLOYEE_ARRAY + employees[i] + emps[i]);
+                                               break;
+                                       }
+                                       report.setStatus(Report.PASS);
+                               }
+                       }
+
+               }
+        catch(Exception e)
+        {
+                       report.setExceptionStack(e);
+        }
+               return report;
+       }
+
+       public Report doSelectEmployeesWithIterator()
+       {
+               Report report=new Report();
+               try
+               {
+                       //Select employees into iterator
+                       Iterator employees = 
testDBControl.selectEmployeesWithIterator();
+                       //Ensure iterator is not null
+                       if (employees == null)
+                       {
+                                report.setMessage(EMPLOYEE_ITERATOR_IS_NULL);
+                                return report;
+                       }
+
+                       //Tracks number of employees in the iterator
+                       int count = -1;
+
+                       //Ensure employees in the iterator matches those 
inserted
+                       while (employees.hasNext())
+                       {
+                               count++;
+                               Employee emp = (Employee)employees.next();
+                               if (emp == null || !emp.equals(emps[count]))
+                               {
+                                        
report.setMessage(BAD_DATA_IN_EMPLOYEE_ITERATOR + emps[count] + emp);
+                                        return report;
+                               }
+                       }
+
+                       //Ensure the number of employees in the iterator 
matches that inserted.
+                       if (count != emps.length-1)
+                       {
+                                
report.setMessage(BAD_DATA_IN_EMPLOYEE_ITERATOR + emps.length + " " + count);
+                                return report;
+                       }
+                       report.setStatus(Report.PASS);
+               }
+               catch(Exception e)
+               {
+                       report.setExceptionStack(e);
+               }
+               return report;
+       }
+
+       public Report doSelectEmployeesWithHashMap()
+       {
+               Report report=new Report();
+               try
+               {
+                       //Select employees into iterator
+                       HashMap<String, Object> map = 
testDBControl.selectEmployeeWithHashMap();
+                       //Ensure HashMap is not null
+                       if (map == null)
+                       {
+                               report.setMessage(EMPLOYEE_HASHMAP_IS_NULL);
+                       }
+                       //Ensure employee id matches
+                       else if (map.get("ID") == null || 
((Integer)map.get("ID")).intValue() != emps[0].id)
+                       {
+                               report.setMessage(BAD_DATA_IN_EMPLOYEE_HASHMAP 
+ "ID");
+                       }
+                       //Ensure employee fName matches
+                       else if (map.get("FNAME") == null || 
!emps[0].fName.equals(map.get("FNAME")))
+                       {
+                               report.setMessage(BAD_DATA_IN_EMPLOYEE_HASHMAP 
+ "FNAME");
+                       }
+                       //Ensure employee lName matches
+                       else if (map.get("LNAME") == null || 
!emps[0].lName.equals(map.get("LNAME")))
+                       {
+                               report.setMessage(BAD_DATA_IN_EMPLOYEE_HASHMAP 
+ "LNAME");
+                       }
+                       //Ensure employee title matches
+                       else if (map.get("TITLE") == null || 
!emps[0].title.equals(map.get("TITLE")))
+                       {
+                               report.setMessage(BAD_DATA_IN_EMPLOYEE_HASHMAP 
+ "TITLE");
+                       }
+                       else
+                       {
+                               report.setStatus(Report.PASS);
+                       }
+               }
+               catch(Exception e)
+               {
+                       report.setExceptionStack(e);
+               }
+               return report;
+       }
+
+       public Report doSelectOneEmployeeWithMaxRow()
+       {
+               Report report=new Report();
+               try
+               {
+                       //Select employees into iterator
+                       Employee[] employees = 
testDBControl.selectOneEmployee();
+
+                       //Ensure only one employee is returned
+                       if (employees == null || employees.length != 1)
+                       {
+                               report.setMessage(SELECT_ONE_EMPLOYEE_FAILED);
+                       }
+                       else
+                       {
+                               report.setStatus(Report.PASS);
+                       }
+               }
+               catch(Exception e)
+               {
+                       report.setExceptionStack(e);
+               }
+               return report;
+       }
+
+       public Report doUpdateEmployee()
+       {
+               Report report=new Report();
+               try
+               {
+                       String newTitle = "President";
+
+                       //Change title of an employee
+                       testDBControl.changeTitle(emps[0].id, newTitle);
+
+                       //Ensure title is changed
+                       Employee emp = testDBControl.selectEmployee(emps[0].id);
+
+                       if (emp == null || !emp.title.equals(newTitle))
+                       {
+                               report.setMessage(UPDATE_EMPLOYEE_FAILED);
+                       }
+                       else
+                       {
+                               report.setStatus(Report.PASS);
+                       }
+               }
+               catch(Exception e)
+               {
+                       report.setExceptionStack(e);
+               }
+               return report;
+       }
+
+       public Report doDeleteEmployee()
+       {
+               Report report=new Report();
+               try
+               {
+                       //delete an employee
+                       testDBControl.deleteEmployee(emps[0].id);
+
+                       //Ensure employee is deleted
+                       Employee emp = testDBControl.selectEmployee(emps[0].id);
+
+                       if (emp != null)
+                       {
+                               report.setMessage(DELETE_EMPLOYEE_FAILED);
+                       }
+                       else
+                       {
+                               report.setStatus(Report.PASS);
+                       }
+               }
+               catch(Exception e)
+               {
+                       report.setExceptionStack(e);
+               }
+               return report;
+       }
+
+}

Added: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/Car.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/Car.java
     Tue Oct  5 16:12:30 2004
@@ -0,0 +1,8 @@
+package org.apache.beehive.controls.test.java.database;
+
+public class Car
+{
+    public String make;
+    public String model;
+    public int cycl;
+}

Added: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/ParserTest.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/ParserTest.java
      Tue Oct  5 16:12:30 2004
@@ -0,0 +1,74 @@
+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 org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
+import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+public class ParserTest extends TestCase
+{
+       public ParserTest(String name)
+       {
+               super(name);
+       }
+
+    public static void main (String[] args)
+    {
+               junit.textui.TestRunner.run (suite());
+       }
+
+       public static Test suite()
+       {
+               return new TestSuite(ParserTest.class);
+       }
+
+       @Freq("checkin")
+    public void testParseStatementWithSimpleParameters()
+    {
+               SQLStatement stmt = parse("SELECT * FROM EMPLOYEE WHERE 
FNAME={1} AND LNAME={2}");
+               assertNotNull(stmt);
+               String sql = stmt.getSQL();
+               assertEquals("SELECT * FROM EMPLOYEE WHERE FNAME=? AND 
LNAME=?", sql);
+               SQLParameter[] params = stmt.getParameters();
+               assertNotNull(params);
+               assertEquals(2, params.length);
+               assertEquals("1", params[0].name);
+               assertEquals("2", params[1].name);
+       }
+
+       @Freq("checkin")
+    public void testParseStatementWithNoParameters()
+    {
+               String inputStatement = "DELETE * FROM EMPLOYEE";
+               SQLStatement stmt = parse(inputStatement);
+               assertNotNull(stmt);
+               String sql = stmt.getSQL();
+               assertEquals(inputStatement, sql);
+               SQLParameter[] params = stmt.getParameters();
+               assertNotNull(params);
+               assertEquals(0, params.length);
+       }
+
+
+    private static SQLStatement parse (String sql)
+    {
+        try
+        {
+            SQLParser parser = new SQLParser(sql);
+            SQLStatement stmt = parser.parse();
+                       return stmt;
+        }
+        catch (Exception e)
+        {
+            assertTrue("The following error occurred in parse(): " + e, false);
+            return null;
+        }
+    }
+}

Added: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/ResultSetExtractorTest.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/ResultSetExtractorTest.java
  Tue Oct  5 16:12:30 2004
@@ -0,0 +1,243 @@
+package org.apache.beehive.controls.test.java.database;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.beehive.controls.test.controls.database.ResultSetExtractor;
+import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
+import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
+
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import java.sql.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class ResultSetExtractorTest extends TestCase
+{
+    private static final String DROP_TABLE = "DROP TABLE CAR";
+    private static final String CREATE_TABLE = "CREATE TABLE CAR ( ID INT 
PRIMARY KEY NOT NULL, " +
+        "MAKE VARCHAR(20), MODEL VARCHAR(20), CYCL INT)";
+    private static final String INSERT_HONDA = "INSERT INTO CAR VALUES (1, 
'HONDA', 'CIVIC', 4)";
+    private static final String INSERT_TOYOTA = "INSERT INTO CAR VALUES (2, 
'TOYOTA', 'CAMRY', 6)";
+    private static final String SELECT_HONDA = "SELECT * FROM CAR WHERE MAKE = 
'HONDA'";
+    private static final String SELECT_ALL = "SELECT * FROM CAR ORDER BY MAKE";
+
+    private Connection con;
+
+    public ResultSetExtractorTest(String name)
+    {
+               super(name);
+       }
+
+    public static void main (String[] args)
+    {
+               junit.textui.TestRunner.run (suite());
+       }
+
+       public static Test suite()
+       {
+               return new TestSuite(ResultSetExtractorTest.class);
+       }
+
+    protected void setUp()
+    {
+        this.con = getConnection();
+               this.dropTable();
+        try
+        {
+            executeSQL(CREATE_TABLE);
+            executeSQL(INSERT_HONDA);
+            executeSQL(INSERT_TOYOTA);
+        }
+        catch (Exception e)
+        {
+            assertTrue("The following error occurred in setup(): " + e, false);
+        }
+
+    }
+
+    protected void tearDown()
+    {
+               this.dropTable();
+        try { con.close(); } catch (Throwable t) {}
+
+       }
+
+       private void dropTable()
+       {
+        try
+        {
+            executeSQL(DROP_TABLE);
+        }
+        catch (Exception e)
+        {
+            //ignore exception
+        }
+       }
+
+       @Freq("checkin")
+    public void testExtractObject()
+    {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        try
+        {
+            ps = this.con.prepareStatement(SELECT_HONDA);
+            rs = ps.executeQuery();
+            ResultSetExtractor extractor = new ResultSetExtractor(rs, null);
+
+            assertTrue(rs.next());
+            Car car = (Car)extractor.extractObject(Car.class);
+            assertNotNull(car);
+            assertEquals("HONDA", car.make);
+            assertEquals("CIVIC", car.model);
+            assertEquals(4, car.cycl);
+        }
+        catch (Exception e)
+        {
+            assertTrue("The following error occurred in testExtractObject(): " 
+ e, false);
+        }
+        finally
+        {
+            try { rs.close(); } catch (Throwable t) {}
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+       @Freq("checkin")
+    public void testExtractArray()
+    {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        try
+        {
+            ps = this.con.prepareStatement(SELECT_ALL);
+            rs = ps.executeQuery();
+            ResultSetExtractor extractor = new ResultSetExtractor(rs, null);
+
+            Car[] cars = (Car[])extractor.extractArray(Car[].class);
+
+            assertNotNull(cars);
+            assertEquals(2, cars.length);
+            assertEquals("HONDA", cars[0].make);
+            assertEquals("TOYOTA", cars[1].make);
+            assertEquals(4, cars[0].cycl);
+            assertEquals(6, cars[1].cycl);
+
+        }
+        catch (Exception e)
+        {
+            assertTrue("The following error occurred in testExtractArray(): " 
+ e, false);
+        }
+        finally
+        {
+            try { rs.close(); } catch (Throwable t) {}
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+       @Freq("checkin")
+    public void testExtractIterator()
+    {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        try
+        {
+            ps = this.con.prepareStatement(SELECT_ALL);
+            rs = ps.executeQuery();
+            ResultSetExtractor extractor = new ResultSetExtractor(rs, null);
+
+            Iterator<Car> i = extractor.extractIterator(Car.class);
+
+            assertNotNull(i);
+            Car[] cars = new Car[2];
+            for (int cnt = 0; i.hasNext(); cnt++)
+            {
+                cars[cnt] = i.next();
+            }
+            assertEquals(2, cars.length);
+            assertEquals("HONDA", cars[0].make);
+            assertEquals("TOYOTA", cars[1].make);
+            assertEquals(4, cars[0].cycl);
+            assertEquals(6, cars[1].cycl);
+        }
+        catch (Exception e)
+        {
+            assertTrue("The following error occurred in testExtractIterator(): 
" + e, false);
+        }
+        finally
+        {
+            try { rs.close(); } catch (Throwable t) {}
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+
+       @Freq("checkin")
+    public void testExtractHashMap()
+    {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        try
+        {
+            ps = this.con.prepareStatement(SELECT_HONDA);
+            rs = ps.executeQuery();
+            ResultSetExtractor extractor = new ResultSetExtractor(rs, null);
+
+            HashMap<String, Object> map = extractor.extractHashMap();
+            assertNotNull(map);
+
+            assertEquals("HONDA", map.get("MAKE"));
+            assertEquals("CIVIC", map.get("MODEL"));
+            assertEquals(4, map.get("CYCL"));
+        }
+        catch (Exception e)
+        {
+            assertTrue("The following error occurred in testExtractHashMap(): 
" + e, false);
+        }
+        finally
+        {
+            try { rs.close(); } catch (Throwable t) {}
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+    private void executeSQL(String sql) throws Exception
+    {
+        PreparedStatement ps = null;
+
+        try
+        {
+            ps = this.con.prepareStatement(sql);
+            ps.execute();
+        }
+        finally
+        {
+            try { ps.close(); } catch (Throwable t) {}
+        }
+
+    }
+
+    private Connection getConnection()
+    {
+        Connection con = null;
+        try
+        {
+            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
+            con = 
DriverManager.getConnection("jdbc:derby:build/databaseControlTestDB;create=true");
+        }
+        catch (Exception e)
+        {
+            assertTrue("The following error occurred in getConnection(): " + 
e, false);
+        }
+        return con;
+    }
+}

Added: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/SQLStatementTest.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/java/database/SQLStatementTest.java
        Tue Oct  5 16:12:30 2004
@@ -0,0 +1,256 @@
+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 org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
+import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import java.sql.*;
+
+public class SQLStatementTest extends TestCase
+{
+    private Connection con;
+    private int id;
+
+    //Test data
+    private String firstName = "Tom";
+    private String newFirstName = "Tommy";
+    private String lastName = "Hilfiger";
+    private String title = "Designer";
+
+       public SQLStatementTest(String name) {
+               super(name);
+       }
+
+    public static void main (String[] args) {
+               junit.textui.TestRunner.run (suite());
+       }
+
+       public static Test suite() {
+               return new TestSuite(SQLStatementTest.class);
+       }
+
+    public void setUp() {
+               this.con = getConnection();
+        dropTable();
+        createTable();
+       }
+
+       protected void tearDown() {
+               try { this.con.close(); } catch (Throwable t) {}
+        dropTable();
+       }
+
+
+       @Freq("checkin")
+    public void testInsert() {
+               //Test data
+               String fName = "Tom";
+               String lName = "Clancy";
+               String title = "Writer";
+               try {
+                       int rowsInserted = insertRow(fName, lName, title);
+            assertEquals(1, rowsInserted);
+                       Employee emp = selectByName(fName, lName);
+                       assertNotNull(emp);
+                       assertEquals(fName, emp.fName);
+                       assertEquals(lName, emp.lName);
+                       assertEquals(title, emp.title);
+               } catch (Exception e) {
+            assertTrue("The following error occurred in testInsert(): " + e, 
false);
+               }
+
+       }
+
+       @Freq("checkin")
+    public void testDelete() {
+               PreparedStatement ps = null;
+               ResultSet rs = null;
+
+               try {
+            int rowsInserted = insertRow(this.firstName, this.lastName, 
this.title);
+            assertEquals(1, rowsInserted);
+               String sql = "DELETE FROM EMPLOYEE WHERE ID=?";
+               Object[] values = {this.id};
+               SQLParameter[] params = {new SQLParameter("1")};
+            SQLStatement stmt = new SQLStatement(sql, params);
+            stmt.setParameterValues(values);
+            ps = stmt.getPreparedStatement(con);
+            int rowsDeleted = ps.executeUpdate();
+                       assertEquals(1, rowsDeleted);
+                       Employee emp = selectById();
+                       assertNull(emp);
+        } catch (Exception e) {
+            assertTrue("The following error occurred in testDelete(): " + e, 
false);
+        } finally {
+            try { rs.close(); } catch (Throwable t) {}
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+       @Freq("checkin")
+    public void testUpdate() {
+        PreparedStatement ps = null;
+
+        try {
+            int rowsInserted = insertRow(this.firstName, this.lastName, 
this.title);
+            assertEquals(1, rowsInserted);
+
+            String sql = "UPDATE EMPLOYEE SET FNAME=? WHERE ID=?";
+            Object[] values = {this.id, this.newFirstName};
+            SQLParameter[] params = { new SQLParameter("2"), new 
SQLParameter("1")};
+            SQLStatement stmt = new SQLStatement(sql, params);
+            stmt.setParameterValues(values);
+            ps = stmt.getPreparedStatement(this.con);
+            int rowsUpdated = ps.executeUpdate();
+            assertEquals(1, rowsUpdated);
+
+            Employee emp = selectById();
+            assertNotNull(emp);
+            assertEquals(this.newFirstName, emp.fName);
+
+        } catch (Exception e) {
+            assertTrue("The following error occurred in testUpdate(): " + e, 
false);
+        } finally {
+            try { ps.close(); } catch (Throwable t) {}
+        }
+
+    }
+
+    private int insertRow(String fName, String lName, String title) throws 
Exception
+    {
+        String sql = "INSERT INTO EMPLOYEE (ID, FNAME, LNAME, TITLE) VALUES 
(?,?,?,?)";
+        Object[] values = {++this.id, fName, lName, title};
+        SQLParameter[] params = { new SQLParameter("1"), new SQLParameter("2"),
+            new SQLParameter("3"), new SQLParameter("4")};
+        PreparedStatement ps = null;
+        try {
+            SQLStatement stmt = new SQLStatement(sql, params);
+            stmt.setParameterValues(values);
+            ps = stmt.getPreparedStatement(con);
+            return ps.executeUpdate();
+        } finally {
+            try { ps.close(); } catch (Throwable t) {}
+        }
+
+    }
+
+    private Employee selectByName(String fName, String lName) throws Exception 
{
+
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        try {
+            String sql = "SELECT * FROM EMPLOYEE WHERE fName=? and lName=?";
+            String[] values = {fName, lName};
+            SQLParameter[] params = { new SQLParameter("1"), new 
SQLParameter("2")};
+
+            SQLStatement stmt = new SQLStatement(sql, params);
+            stmt.setParameterValues(values);
+            ps = stmt.getPreparedStatement(con);
+            rs = ps.executeQuery();
+
+            if (rs.next())
+                return new Employee(rs.getString(2), rs.getString(3), 
rs.getString(4));
+            else
+                return null;
+
+        } finally {
+            try { rs.close(); } catch (Throwable t) {}
+            try { ps.close(); } catch (Throwable t) {}
+        }
+
+    }
+
+    private Employee selectById() throws Exception {
+
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        try {
+            String sql = "SELECT * FROM EMPLOYEE WHERE ID=?";
+            Object[] values = {new Integer(this.id)};
+            SQLParameter[] params = { new SQLParameter("1")};
+
+            SQLStatement stmt = new SQLStatement(sql, params);
+            stmt.setParameterValues(values);
+            ps = stmt.getPreparedStatement(con);
+            rs = ps.executeQuery();
+
+            if (rs.next())
+                return new Employee(rs.getString(2), rs.getString(3), 
rs.getString(4));
+            else
+                return null;
+
+        } finally {
+            try { rs.close(); } catch (Throwable t) {}
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+
+    private static Connection getConnection() {
+
+        Connection con = null;
+        try {
+            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
+            con = DriverManager.getConnection("jdbc:derby:test;create=true");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return con;
+
+    }
+
+    private void createTable() {
+        //Test data
+        String sql = "CREATE TABLE EMPLOYEE ( ID INT PRIMARY KEY NOT NULL, " +
+                   "FNAME VARCHAR(20), LNAME VARCHAR(20), TITLE VARCHAR(15))";
+
+        PreparedStatement ps = null;
+        try {
+            SQLStatement stmt = new SQLStatement(sql);
+            ps = stmt.getPreparedStatement(con);
+            ps.execute();
+        } catch (Exception e) {
+            assertTrue("The following error occurred in createTable(): " + e, 
false);
+        } finally {
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+    private void dropTable() {
+        //Test data
+        String sql = "DROP TABLE EMPLOYEE";
+        PreparedStatement ps = null;
+        try {
+            SQLStatement stmt = new SQLStatement(sql);
+            ps = stmt.getPreparedStatement(con);
+            ps.execute();
+        } catch (Exception e) {
+            //ignore
+        } finally {
+            try { ps.close(); } catch (Throwable t) {}
+        }
+    }
+
+    private class Employee {
+
+        public String fName;
+        public String lName;
+        public String title;
+
+        public Employee(String fName, String lName, String title) {
+                       this.fName = fName;
+                       this.lName = lName;
+                       this.title = title;
+               }
+
+    }
+
+}

Added: 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/jpf/database/TestDatabaseControl.java
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/src/units/org/apache/beehive/controls/test/jpf/database/TestDatabaseControl.java
      Tue Oct  5 16:12:30 2004
@@ -0,0 +1,119 @@
+package org.apache.beehive.controls.test.jpf.database;
+
+import org.apache.beehive.test.tools.milton.junit.HtmlReportTestCase;
+import org.apache.beehive.test.tools.mantis.annotations.tch.Freq;
+import org.apache.beehive.test.tools.mantis.annotations.tch.Status;
+
+
+/**
+ * Tests controls inheritance by invoking a sub control on a pageflow.
+ */
+public class TestDatabaseControl extends HtmlReportTestCase
+{
+       public TestDatabaseControl(String s)
+       {
+               super(s);
+       }
+
+       protected void setUp()
+       {
+               try
+               {
+                       createTable();
+                       insertEmployees();
+               }
+               catch (Exception e)
+               {
+                       assertTrue("The following error occurred in setUp(): " 
+ e, false);
+               }
+
+       }
+
+       protected void tearDown()
+       {
+               try
+               {
+                       dropTable();
+        }
+        catch (Exception e)
+        {
+            //ignore
+        }
+       }
+
+    private void createTable() throws Exception
+    {
+               assertReport("/controlsWeb/database/testCreateTable.do");
+    }
+
+    private void dropTable() throws Exception
+    {
+               assertReport("/controlsWeb/database/testDropTable.do");
+    }
+
+    private void insertEmployees() throws Exception
+    {
+               assertReport("/controlsWeb/database/testInsertEmployees.do");
+    }
+
+    /**
+     * Tests invoking a method inherited from the super control
+     * The sub control is instantiated programmatically
+     */
+       @Freq("checkin")
+    public void testSelectEmployeesWithArray() throws Exception
+    {
+               
assertReport("/controlsWeb/database/testSelectEmployeesWithArray.do");
+    }
+
+    /**
+     * Tests invoking a method inherited from the super control
+     * The sub control is instantiated programmatically
+     */
+       @Freq("checkin")
+    public void testSelectEmployeesWithIterator() throws Exception
+    {
+               
assertReport("/controlsWeb/database/testSelectEmployeesWithIterator.do");
+    }
+
+    /**
+     * Tests invoking a method inherited from the super control
+     * The sub control is instantiated programmatically
+     */
+       @Freq("checkin")
+    public void testSelectEmployeeWithHashMap() throws Exception
+    {
+               
assertReport("/controlsWeb/database/testSelectEmployeeWithHashMap.do");
+    }
+
+    /**
+     * Tests invoking a method inherited from the super control
+     * The sub control is instantiated programmatically
+     */
+       @Freq("checkin")
+    public void testSelectOneEmployeeWithMaxRow() throws Exception
+    {
+               
assertReport("/controlsWeb/database/testSelectOneEmployeeWithMaxRow.do");
+    }
+
+    /**
+     * Tests invoking a method inherited from the super control
+     * The sub control is instantiated programmatically
+     */
+       @Freq("checkin")
+    public void testUpdateEmployee() throws Exception
+    {
+               assertReport("/controlsWeb/database/testUpdateEmployee.do");
+    }
+
+    /**
+     * Tests invoking a method inherited from the super control
+     * The sub control is instantiated programmatically
+     */
+       @Freq("checkin")
+    public void testDeleteEmployee() throws Exception
+    {
+               assertReport("/controlsWeb/database/testDeleteEmployee.do");
+    }
+
+}

Modified: incubator/beehive/trunk/controls/test/webapps/build.xml
==============================================================================
--- incubator/beehive/trunk/controls/test/webapps/build.xml     (original)
+++ incubator/beehive/trunk/controls/test/webapps/build.xml     Tue Oct  5 
16:12:30 2004
@@ -58,6 +58,9 @@
         <condition property="do.inject.milton">
            <istrue value="${app.inject.milton}"/>
         </condition>
+        <condition property="do.inject.derby">
+           <istrue value="${app.inject.derby}"/>
+        </condition>        
         <condition property="do.inject.test.controls">
            <isset property="app.inject.test.controls"/>
         </condition>
@@ -96,6 +99,7 @@
 
         <antcall target="-inject.netui"/>
         <antcall target="-inject.milton"/>
+        <antcall target="-inject.derby"/>
         <antcall target="-inject.test.controls"/>
         <antcall target="-inject.test.drivers"/>
         <antcall target="-build.webapp"/>
@@ -142,6 +146,13 @@
         </copy>
     </target>
  
+    <target name="-inject.derby" if="do.inject.derby">
+        <echo message="Injecting ${derby.jar} to ${webapp.name}"/>
+        <copy todir="${webapp.dir}/WEB-INF/lib" 
+              file="${derby.jar}" verbose="true" 
+              overwrite="true"/>
+    </target>
+
     <target name="-inject.test.controls" if="do.inject.test.controls">
         <antcall target="-inject.test.controls.src"/>
         <antcall target="-inject.test.controls.jar"/>

Modified: 
incubator/beehive/trunk/controls/test/webapps/controlsWeb/app.properties
==============================================================================
--- incubator/beehive/trunk/controls/test/webapps/controlsWeb/app.properties    
(original)
+++ incubator/beehive/trunk/controls/test/webapps/controlsWeb/app.properties    
Tue Oct  5 16:12:30 2004
@@ -1,5 +1,6 @@
 app.inject.netui: true
 app.inject.milton: true
+app.inject.derby: true
 ### these two can be set to 'jar' or 'src' ###
 app.inject.test.drivers: jar
 app.inject.test.controls: jar

Added: 
incubator/beehive/trunk/controls/test/webapps/controlsWeb/database/Controller.jpf
==============================================================================
--- (empty file)
+++ 
incubator/beehive/trunk/controls/test/webapps/controlsWeb/database/Controller.jpf
   Tue Oct  5 16:12:30 2004
@@ -0,0 +1,167 @@
+/*
+ *
+ * N E T U I
+ *
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * All Rights Reserved. Unpublished rights reserved under the copyright laws
+ * of the United States. The software contained on this media is proprietary
+ * to and embodies the confidential technology of BEA Systems, Inc. The
+ * possession or receipt of this information does not convey any right to
+ * disclose its contents, reproduce it, or use,  or license the use,
+ * for manufacture or sale, the information or anything described
+ * therein. Any use, disclosure, or reproduction without BEA System's
+ * prior written permission is strictly prohibited.
+ *
+ * $Header:$
+ */
+package database;
+
+import org.apache.beehive.netui.pageflow.PageFlowController;
+import org.apache.beehive.netui.pageflow.Forward;
+import org.apache.beehive.netui.pageflow.FormData;
+import org.apache.beehive.netui.pageflow.annotations.Jpf;
+
+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.driver.database.DriveDatabaseControl;
+import org.apache.beehive.test.tools.milton.common.Report;
+
+/* Test control inheritance by invoking methods on a sub control instance*/
+
[EMAIL PROTECTED](
+    forwards = {
+        @Jpf.Forward(name=Report.RESULTS,path = Report.RESULTSJSP)
+    })
+public class Controller extends PageFlowController
+{
+
+    @Control
+    private TestDBControlBean testDBControl;
+
+    transient private DriveDatabaseControl driver = new 
DriveDatabaseControl(this.testDBControl);
+
+    @Jpf.Action(
+        )
+    protected Forward begin(){
+               Report report =new Report();
+               report.setStatus(Report.PASS);
+               report.setMessage("This is a bogus test.");
+
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+    /*
+     * Invokes create table
+     */
+    @Jpf.Action(
+        )
+    protected Forward testCreateTable()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doCreateTable();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+    /*
+     * Invokes drop table
+     */
+    @Jpf.Action(
+        )
+    protected Forward testDropTable()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doDropTable();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+
+    /*
+     * Invokes insert employee
+     */
+    @Jpf.Action(
+        )
+    protected Forward testInsertEmployees()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doInsertEmployees();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+    /*
+     * Invokes select employees with array
+     */
+    @Jpf.Action(
+        )
+    protected Forward testSelectEmployeesWithArray()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doSelectEmployeesWithArray();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+    /*
+     * Invokes select employees with Iterator
+     */
+    @Jpf.Action(
+        )
+    protected Forward testSelectEmployeesWithIterator()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doSelectEmployeesWithIterator();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+    /*
+     * Invokes select employee with HashMap
+     */
+    @Jpf.Action(
+        )
+    protected Forward testSelectEmployeeWithHashMap()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doSelectEmployeesWithHashMap();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+    /*
+     * Invokes select employees with max row
+     */
+    @Jpf.Action(
+        )
+    protected Forward testSelectOneEmployeeWithMaxRow()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doSelectOneEmployeeWithMaxRow();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+
+    /*
+     * Invokes update employee
+     */
+    @Jpf.Action(
+        )
+    protected Forward testUpdateEmployee()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doUpdateEmployee();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+    /*
+     * Invokes delete employee
+     */
+    @Jpf.Action(
+        )
+    protected Forward testDeleteEmployee()
+    {
+               driver.setControl(testDBControl);
+               Report report = this.driver.doDeleteEmployee();
+        return new Forward(Report.RESULTS, Report.KEY, report);
+    }
+
+}
+
+

Reply via email to