Package dbControl

Source Code of dbControl.ResultSetExtractor$ResultSetIterator

package dbControl;

//import org.apache.beehive.controls.api.ControlException;
import dbControl.util.JavaTypeHelper;
import dbControl.util.ResultSetHelper;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Field;
import java.sql.ResultSetMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.util.GregorianCalendar;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.logging.Logger;

/**
* This class extracts the the content of a ResultSet into various forms of
* object (e.g. an Iterator, HashMap, etc)
*/
public class ResultSetExtractor
{
    //Error messages
    private static final String ERROR_SETTING_FIELD = "Error occurred while setting a value from the database to class field.";
    private static final String ERROR_SETTING_ARRAY = "Error occurred while adding an elment to array.";
    private static final String ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_OBJECT = "Object type not specified when extracting object from ResultSet.";
    private static final String ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_ITERATOR = "Iterator element type not specified when extracting iterator from ResultSet.";

    //ResultSet to extract data from
    ResultSet rs;
    //Meta data of the resultset.
    ResultSetMetaData rsMetaData;
    //Calendar used for working with dates.
    protected GregorianCalendar cal;

    //Column count of the resultset
    int columnCount;

    //Name of columns in the resultset
    String[] columnNames = null;

    // Field or Method
    AccessibleObject[] fields = null;

    /**
     * Constructor
     * @param rs the resultset to exrract data from
     * @param cal the calendar to use when working with dates
     */
    public ResultSetExtractor(ResultSet rs, Calendar cal) throws SQLException
    {
        this.rs = rs;
        this.columnCount = rs.getMetaData().getColumnCount();
        this.rsMetaData = rs.getMetaData();
        this.columnNames = new String[columnCount + 1];
        for (int i = 1 ; i <= columnCount ; i++)
            this.columnNames[i] = this.rsMetaData.getColumnName(i).toUpperCase();

    }

    private Map<String, AccessibleObject> getColumnNameToFieldMap(Class objectType) throws SQLException
    {
        HashMap<String, AccessibleObject> columnNameToFieldMap =
            new HashMap<String, AccessibleObject>(columnCount * 2);

        //Add names of all column from resultset to map.
        for (int i = 1 ; i <= columnCount ; i++)
            columnNameToFieldMap.put(columnNames[i], null);

        //Map the class fields to column names in the map.
        for (Class clazz = objectType ; null != clazz && Object.class != clazz ; clazz = clazz.getSuperclass())
        {
            Field[] classFields = clazz.getDeclaredFields();
            if (null != classFields)
                for (int i = 0 ; i < classFields.length ; i++)
                {
                    Field f = classFields[i];
                    if (Modifier.isStatic(f.getModifiers()))
                        continue;
                    String fieldName = f.getName().toUpperCase();
                    if (!columnNameToFieldMap.containsKey(fieldName))
                        continue;
                    columnNameToFieldMap.put(fieldName, f);
                }
        }

        //Map the class's attribute setter methods to column names in the map.
        Method[] classMethods = objectType.getMethods();
        if (null != classMethods)
            for (int i = 0 ; i < classMethods.length ; i++)
            {
                Method m = classMethods[i];
                String methodName = m.getName();
                if (methodName.length() < 4 || !methodName.startsWith("set"))
                    continue;
                if (!Character.isUpperCase(methodName.charAt(3)))
                    continue;
                String fieldName = methodName.substring(3).toUpperCase();
                if (!columnNameToFieldMap.containsKey(fieldName))
                    continue;
                if (Modifier.isStatic(m.getModifiers()))
                    continue;
                Class[] params = m.getParameterTypes();
                if (1 != params.length)
                    continue;
                if (Types.OTHER == JavaTypeHelper.getSqlType(params[0]))
                    continue;
                if (!Void.TYPE.equals(m.getReturnType()))
                    continue;
                // check for overloads
                Object field = columnNameToFieldMap.get(fieldName);
                if (null != field)
                    continue;
                columnNameToFieldMap.put(fieldName, m);
            }
        return columnNameToFieldMap;
    }

    /**
     * Extracts the data of the resultset into a array of a specified
     * type.
     * @param arrayClass array type
     * @return array of the specified type
     */
    public Object extractArray(Class arrayClass) throws Exception{

        Class componentType = arrayClass.getComponentType();

        ArrayList list = new ArrayList();

        while(rs.next())
        {
            list.add(extractObject(componentType));
        }

        Object array = java.lang.reflect.Array.newInstance(componentType, list.size());

        try
        {
            for (int i = 0 ; i < list.size() ; i++)
                java.lang.reflect.Array.set(array, i, list.get(i));
        }
        catch (IllegalArgumentException iae)
        {
            throw new Exception(ERROR_SETTING_ARRAY, iae);
        }
        return array;

    }

    /**
     * Extracts the data of a resultset into an iterator of a specified type.
     * @param iteratorElementType type of the elements in the iterator
     * @return an iterator with elements of the specified type.
     */
    public Iterator extractIterator(Class iteratorElementType) throws Exception
    {
        return new ResultSetIterator(iteratorElementType);
    }

    /**
     * Extracts one row of data from a resultset into a HashMap with
     * the column names as keys.
     * @return column name to value map of a row from the resultset.
     */
    public HashMap<String, Object> extractHashMap() throws Exception
    {
        return new ResultSetHashMap();
    }

    /**
     * Extracts one row of data from a resultset into a unmodifiable
     * map with the column names as keys.
     * @return column name to value map of a row from the resultset.
     */
    public Map<String, Object> extractUnmodifiableMap() throws Exception
    {
      return Collections.unmodifiableMap(new ResultSetHashMap());
  }

    /**
     * Extracts one row of data into an object of a specified type.
     * @param returnClass type of object to extract the data to
     * @return an object of the specified type
     */
    public Object extractObject(Class returnClass) throws Exception
    {
        if (returnClass == null)
        {
            throw new Exception(ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_OBJECT);
        }

        if (columnCount == 1)
        {
            Object val = ResultSetHelper.readValue(rs, columnNames[1], returnClass.getClass(), cal);
            if (returnClass.isAssignableFrom(val.getClass()))
            {
                return val;
            }
        }

        // calculate reflection information
        Map<String, AccessibleObject> columnNameToFieldMap = getColumnNameToFieldMap(returnClass);

        Object resultObject = returnClass.newInstance();

        // array used for method.invoke()
        Object[] args = new Object[1];

        Set<String> columnNames = columnNameToFieldMap.keySet();

        for (String columnName : columnNames)
        {
            AccessibleObject accessibleObj = columnNameToFieldMap.get(columnName);

            if (accessibleObj == null)
                continue;

            try
            {
                if (accessibleObj instanceof Field)
                {
                    Object resultValue = ResultSetHelper.readValue(rs, columnName, ((Field)accessibleObj).getType(), cal);
                    ((Field)accessibleObj).set(resultObject, resultValue);
                }
                else
                {
                    Object resultValue = ResultSetHelper.readValue(rs, columnName, ((Method)accessibleObj).getParameterTypes()[0], cal);
                    args[0] = resultValue;
                    ((Method)accessibleObj).invoke(resultObject, args);
                }
            }
            catch (IllegalArgumentException iae)
            {
                throw new Exception(ERROR_SETTING_FIELD, iae);
            }
        }
        return resultObject;
    }

    /**
     * The ResultSetHashMap class extends a standard HashMap and
     * populates it with data derived from a JDBC ResultSet.
     * <p>
     * Note: the keys are treated case-insensitively, and therefore requests
     * made on the map are case-insensitive.  Any direct access to the keys
     * will yield uppercase keys.
     * <p>
     * Note: only the row associated with the current cursor position
     * is used.
     */
    private class ResultSetHashMap extends HashMap<String, Object>
    {
        ResultSetHashMap() throws Exception
        {
            super();

            ResultSetMetaData md = rs.getMetaData();
             if (rs.next())
             {
        for (int i = 1 ; i <= md.getColumnCount() ; i++)
        {
          super.put(md.getColumnName(i).toUpperCase(), rs.getObject(i));
        }
      }
        }


        public boolean containsKey(Object key)
        {
            if (key instanceof String)
                key = ((String)key).toUpperCase();
            return super.containsKey(key);
        }


        public Object get(Object key)
        {
            if (key instanceof String)
                key = ((String)key).toUpperCase();
            return super.get(key);
        }


        public Object put(String key, Object value)
        {
            key = key.toUpperCase();
            return super.put(key, value);
        }


        public Object remove(String key)
        {
                key = key.toUpperCase();
            return super.remove(key);
        }
    }

    private class ResultSetIterator implements Iterator {

        Class iteratorElementType;
        boolean primed = false;

        ResultSetIterator(Class iteratorElementType) throws Exception
        {
            if (iteratorElementType == null)
                throw new Exception(ERROR_NO_TYPE_SPECIFIED_FOR_EXTRACT_ITERATOR);

            this.iteratorElementType = iteratorElementType;
        }

        public boolean hasNext()
        {
            if (primed)
                return true;
            try
            {
                primed = rs.next();
            }
            catch (SQLException sqle)
            {
                return false;
            }

            return primed;
        }


        public Object next()
        {
            try
            {
                if (!primed)
                {
                    primed = rs.next();
                    if (!primed)
                        throw new NoSuchElementException();
                }
                // reset upon consumption
                primed = false;
                return extractObject(iteratorElementType);
            }
            catch (Exception e)
            {
                // Since Iterator interface is locked, all we can do
                // is put the real exception inside an expected one.
                NoSuchElementException xNoSuch = new NoSuchElementException("ResultSet exception: " + e);
                xNoSuch.initCause(e);
                throw xNoSuch;
            }
        }

        public void remove()
        {
            throw new UnsupportedOperationException("remove not supported");
        }
    }


}
TOP

Related Classes of dbControl.ResultSetExtractor$ResultSetIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.