/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.commons.beanutils2;


import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


/**
 * <p>Implementation of {@link DynaClass} that creates an in-memory collection
 * of {@link DynaBean}s representing the results of an SQL query.  Once the
 * {@link DynaClass} instance has been created, the JDBC {@code ResultSet}
 * and {@code Statement} on which it is based can be closed, and the
 * underlying {@code Connection} can be returned to its connection pool
 * (if you are using one).</p>
 *
 * <p>The normal usage pattern is something like:</p>
 * <pre>
 *   Connection conn = ...;  // Acquire connection from pool
 *   Statement stmt = conn.createStatement();
 *   ResultSet rs = stmt.executeQuery("SELECT ...");
 *   RowSetDynaClass rsdc = new RowSetDynaClass(rs);
 *   rs.close();
 *   stmt.close();
 *   ...;                    // Return connection to pool
 *   List rows = rsdc.getRows();
 *   ...;                   // Process the rows as desired
 * </pre>
 *
 * <p>Each column in the result set will be represented as a {@link DynaBean}
 * property of the corresponding name (optionally forced to lower case
 * for portability).  There will be one {@link DynaBean} in the
 * {@code List</code> returned by <code>getRows()} for each
 * row in the original {@code ResultSet}.</p>
 *
 * <p>In general, instances of {@link RowSetDynaClass} can be serialized
 * and deserialized, which will automatically include the list of
 * {@link DynaBean}s representing the data content.  The only exception
 * to this rule would be when the underlying property values that were
 * copied from the {@code ResultSet} originally cannot themselves
 * be serialized.  Therefore, a {@link RowSetDynaClass} makes a very
 * convenient mechanism for transporting data sets to remote Java-based
 * application components.</p>
 *
 */

public class RowSetDynaClass extends JDBCDynaClass {

    private static final long serialVersionUID = 1L;

    

    /**
     * <p>Limits the size of the returned list.  The call to
     * {@code getRows()} will return at most limit number of rows.
     * If less than or equal to 0, does not limit the size of the result.
     */
    protected int limit = -1;

    /**
     * <p>The list of {@link DynaBean}s representing the contents of
     * the original {@code ResultSet} on which this
     * {@link RowSetDynaClass} was based.</p>
     */
    protected List<DynaBean> rows = new ArrayList<>();

    


    /**
     * <p>Construct a new {@link RowSetDynaClass} for the specified
     * {@code ResultSet}.  The property names corresponding
     * to column names in the result set will be lower cased.</p>
     *
     * @param resultSet The result set to be wrapped
     *
     * @throws NullPointerException if {@code resultSet}
     *  is {@code null}
     * @throws SQLException if the metadata for this result set
     *  cannot be introspected
     */
    public RowSetDynaClass(final ResultSet resultSet) throws SQLException {

        this(resultSet, true, -1);

    }

    /**
     * <p>Construct a new {@link RowSetDynaClass} for the specified
     * {@code ResultSet}.  The property names corresponding
     * to column names in the result set will be lower cased.</p>
     *
     * If {@code limit</code> is not less than 0, max <code>limit}
     * number of rows will be copied into the list.
     *
     * @param resultSet The result set to be wrapped
     * @param limit The maximum for the size of the result.
     *
     * @throws NullPointerException if {@code resultSet}
     *  is {@code null}
     * @throws SQLException if the metadata for this result set
     *  cannot be introspected
     */
    public RowSetDynaClass(final ResultSet resultSet, final int limit) throws SQLException {

        this(resultSet, true, limit);

    }


    /**
     * <p>Construct a new {@link RowSetDynaClass} for the specified
     * {@code ResultSet}.  The property names corresponding
     * to the column names in the result set will be lower cased or not,
     * depending on the specified {@code lowerCase} value.</p>
     *
     * If {@code limit</code> is not less than 0, max <code>limit}
     * number of rows will be copied into the resultset.
     *
     *
     * @param resultSet The result set to be wrapped
     * @param lowerCase Should property names be lower cased?
     *
     * @throws NullPointerException if {@code resultSet}
     *  is {@code null}
     * @throws SQLException if the metadata for this result set
     *  cannot be introspected
     */
    public RowSetDynaClass(final ResultSet resultSet, final boolean lowerCase)
                                                    throws SQLException {
        this(resultSet, lowerCase, -1);

    }

    /**
     * <p>Construct a new {@link RowSetDynaClass} for the specified
     * {@code ResultSet}.  The property names corresponding
     * to the column names in the result set will be lower cased or not,
     * depending on the specified {@code lowerCase} value.</p>
     *
     * <p><strong>WARNING</strong> - If you specify {@code false}
     * for {@code lowerCase}, the returned property names will
     * exactly match the column names returned by your JDBC driver.
     * Because different drivers might return column names in different
     * cases, the property names seen by your application will vary
     * depending on which JDBC driver you are using.</p>
     *
     * @param resultSet The result set to be wrapped
     * @param lowerCase Should property names be lower cased?
     * @param limit Maximum limit for the {@code List} of {@link DynaBean}
     *
     * @throws NullPointerException if {@code resultSet}
     *  is {@code null}
     * @throws SQLException if the metadata for this result set
     *  cannot be introspected
     */
    public RowSetDynaClass(final ResultSet resultSet, final boolean lowerCase, final int limit)
                                                            throws SQLException {

        this(resultSet, lowerCase, limit, false);

    }

    /**
     * <p>Construct a new {@link RowSetDynaClass} for the specified
     * {@code ResultSet}.  The property names corresponding
     * to the column names in the result set will be lower cased or not,
     * depending on the specified {@code lowerCase} value.</p>
     *
     * <p><strong>WARNING</strong> - If you specify {@code false}
     * for {@code lowerCase}, the returned property names will
     * exactly match the column names returned by your JDBC driver.
     * Because different drivers might return column names in different
     * cases, the property names seen by your application will vary
     * depending on which JDBC driver you are using.</p>
     *
     * @param resultSet The result set to be wrapped
     * @param lowerCase Should property names be lower cased?
     * @param useColumnLabel true if the column label should be used, otherwise false
     *
     * @throws NullPointerException if {@code resultSet}
     *  is {@code null}
     * @throws SQLException if the metadata for this result set
     *  cannot be introspected
     * @since 1.8.3
     */
    public RowSetDynaClass(final ResultSet resultSet, final boolean lowerCase, final boolean useColumnLabel)
        throws SQLException {
        this(resultSet, lowerCase, -1, useColumnLabel);

    }

    /**
     * <p>Construct a new {@link RowSetDynaClass} for the specified
     * {@code ResultSet}.  The property names corresponding
     * to the column names in the result set will be lower cased or not,
     * depending on the specified {@code lowerCase} value.</p>
     *
     * <p><strong>WARNING</strong> - If you specify {@code false}
     * for {@code lowerCase}, the returned property names will
     * exactly match the column names returned by your JDBC driver.
     * Because different drivers might return column names in different
     * cases, the property names seen by your application will vary
     * depending on which JDBC driver you are using.</p>
     *
     * @param resultSet The result set to be wrapped
     * @param lowerCase Should property names be lower cased?
     * @param limit Maximum limit for the {@code List} of {@link DynaBean}
     * @param useColumnLabel true if the column label should be used, otherwise false
     *
     * @throws NullPointerException if {@code resultSet}
     *  is {@code null}
     * @throws SQLException if the metadata for this result set
     *  cannot be introspected
     * @since 1.8.3
     */
    public RowSetDynaClass(final ResultSet resultSet, final boolean lowerCase, final int limit, final boolean useColumnLabel)
                                                            throws SQLException {

        if (resultSet == null) {
            throw new NullPointerException();
        }
        this.lowerCase = lowerCase;
        this.limit = limit;
        setUseColumnLabel(useColumnLabel);
        introspect(resultSet);
        copy(resultSet);

    }

    /**
     * <p>Return a {@code List} containing the {@link DynaBean}s that
     * represent the contents of each {@code Row} from the
     * {@code ResultSet} that was the basis of this
     * {@link RowSetDynaClass} instance.  These {@link DynaBean}s are
     * disconnected from the database itself, so there is no problem with
     * modifying the contents of the list, or the values of the properties
     * of these {@link DynaBean}s.  However, it is the application's
     * responsibility to persist any such changes back to the database,
     * if it so desires.</p>
     *
     * @return A {@code List} of {@link DynaBean} instances
     */
    public List<DynaBean> getRows() {

        return this.rows;

    }


    


    /**
     * <p>Copy the column values for each row in the specified
     * {@code ResultSet} into a newly created {@link DynaBean}, and add
     * this bean to the list of {@link DynaBean}s that will later by
     * returned by a call to {@code getRows()}.</p>
     *
     * @param resultSet The {@code ResultSet} whose data is to be
     *  copied
     *
     * @throws SQLException if an error is encountered copying the data
     */
    protected void copy(final ResultSet resultSet) throws SQLException {

        int cnt = 0;
        while (resultSet.next() && (limit < 0  || cnt++ < limit) ) {
            final DynaBean bean = createDynaBean();
            for (final DynaProperty propertie : properties) {
                final String name = propertie.getName();
                final Object value = getObject(resultSet, name);
                bean.set(name, value);
            }
            rows.add(bean);
        }

    }


    /**
     * <p>Create and return a new {@link DynaBean} instance to be used for
     * representing a row in the underlying result set.</p>
     *
     * @return A new {@code DynaBean} instance
     */
    protected DynaBean createDynaBean() {

        return new BasicDynaBean(this);

    }


}
