/*
 * 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);

    }

}
