net.mlw.vlh.adapter.jdbc.AbstractJdbcAdapter.java Source code

Java tutorial

Introduction

Here is the source code for net.mlw.vlh.adapter.jdbc.AbstractJdbcAdapter.java

Source

/**
 * Copyright (c) 2003 held jointly by the individual authors.
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *  > http://www.gnu.org/copyleft/lesser.html >
 * http://www.opensource.org/licenses/lgpl-license.php
 */
package net.mlw.vlh.adapter.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import net.mlw.vlh.DefaultListBackedValueList;
import net.mlw.vlh.ValueList;
import net.mlw.vlh.ValueListInfo;
import net.mlw.vlh.adapter.AbstractValueListAdapter;
import net.mlw.vlh.adapter.jdbc.objectWrapper.ResultSetDecorator;
import net.mlw.vlh.adapter.jdbc.util.ConnectionCreator;
import net.mlw.vlh.adapter.jdbc.util.JdbcUtil;
import net.mlw.vlh.adapter.jdbc.util.SqlPagingSupport;
import net.mlw.vlh.adapter.jdbc.util.StandardConnectionCreator;
import net.mlw.vlh.adapter.jdbc.util.StandardStatementBuilder;
import net.mlw.vlh.adapter.jdbc.util.StatementBuilder;
import net.mlw.vlh.adapter.util.ObjectValidator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This adapter handles the standard functionality of creating a query and
 * execution it...
 *
 * If you set validator, it will use special ResultSetDecorator.
 *
 * @see net.mlw.vlh.adapter.jdbc.objectWrapper.ResultSetDecorator
 * @author Matthew L. Wilson, Andrej Zachar
 * @version $Revision: 1.27 $ $Date: 2006/04/18 17:15:05 $
 */
public abstract class AbstractJdbcAdapter extends AbstractValueListAdapter {
    /** Commons logger. */
    private static final Log LOGGER = LogFactory.getLog(AbstractJdbcAdapter.class);

    /** The sql to execute. */
    private String sql;

    /** Display generated sql on th standard output */
    private boolean showSql = false;

    /** The StatementBuilder to help generate a sql query. */
    private StatementBuilder statementBuilder = new StandardStatementBuilder();

    /** The ConnectionCreator to help SQL connection handling */
    private ConnectionCreator connectionCreator = new StandardConnectionCreator();

    /**
     * The validator for ResultSet's records.
     */
    private ObjectValidator _validator = null;

    /**
     * Helper to provide true in-database paging.
     */
    private SqlPagingSupport sqlPagingSupport;

    public AbstractJdbcAdapter() {
    }

    /**
     * @see net.mlw.vlh.ValueListAdapter#getValueList(java.lang.String,
     *      net.mlw.vlh.ValueListInfo)
     */
    public ValueList getValueList(String name, ValueListInfo info) {
        if (info.getSortingColumn() == null) {
            info.setPrimarySortColumn(getDefaultSortColumn());
            info.setPrimarySortDirection(getDefaultSortDirectionInteger());
        }

        int numberPerPage = info.getPagingNumberPer();

        if (numberPerPage == Integer.MAX_VALUE) {
            numberPerPage = getDefaultNumberPerPage();
            info.setPagingNumberPer(numberPerPage);
        }

        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet result = null;

        try {
            boolean doSqlPaging = ((getAdapterType() & DO_PAGE) == 0);

            connection = connectionCreator.createConnection();

            StringBuffer query = (sqlPagingSupport != null) ? sqlPagingSupport.getPagedQuery(sql)
                    : new StringBuffer(sql);
            statement = statementBuilder.generate(connection, query, info.getFilters(),
                    sqlPagingSupport == null && doSqlPaging);

            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(query.toString());
            }
            if (showSql) {
                System.out.println("sql: " + query.toString());
            }
            result = getResultSet(statement, info);

            if (sqlPagingSupport != null) {
                PreparedStatement countStatement = null;
                ResultSet countResult = null;

                try {
                    StringBuffer countQuery = sqlPagingSupport.getCountQuery(sql);
                    countStatement = statementBuilder.generate(connection, countQuery, info.getFilters(), false);
                    if (showSql) {
                        System.out.println("count sql: " + countQuery.toString());
                    }

                    countResult = countStatement.executeQuery();
                    if (countResult.next()) {
                        info.setTotalNumberOfEntries(countResult.getInt(1));
                    }
                } finally {
                    JdbcUtil.close(countResult, countStatement, null);
                }

            } else if (doSqlPaging) {
                result.last();
                int totalRows = result.getRow();
                info.setTotalNumberOfEntries(totalRows);

                if (numberPerPage == 0) {
                    numberPerPage = getDefaultNumberPerPage();
                }

                int pageNumber = info.getPagingPage();
                if (pageNumber > 1) {
                    if ((pageNumber - 1) * numberPerPage > totalRows) {
                        pageNumber = ((totalRows - 1) / numberPerPage) + 1;
                        info.setPagingPage(pageNumber);
                    }
                }

                if (pageNumber > 1) {
                    result.absolute((pageNumber - 1) * numberPerPage);
                } else {
                    result.beforeFirst();
                }
            }

            List list = processResultSet(name, result, (doSqlPaging) ? numberPerPage : Integer.MAX_VALUE, info);

            if (!doSqlPaging) {
                info.setTotalNumberOfEntries(list.size());
            }

            return new DefaultListBackedValueList(list, info);

        } catch (Exception e) {
            LOGGER.error(e);
            throw new RuntimeException(e);
        } finally {
            connectionCreator.close(result, statement, connection);
        }
    }

    /**
     * @param statement
     * @param info This info will be set to validator.
     * @return ResultSet (validator is null) or ResultSetDecorator (validator is
     *         not null)
     * @throws SQLException
     * @see net.mlw.vlh.adapter.util.ObjectValidator
     * @see net.mlw.vlh.adapter.jdbc.objectWrapper.ResultSetDecorator
     */
    private ResultSet getResultSet(PreparedStatement statement, ValueListInfo info) throws SQLException {
        if (_validator == null) {
            return statement.executeQuery();
        } else {
            _validator.setValueListInfo(info);
            return new ResultSetDecorator(statement.executeQuery(), _validator);
        }
    }

    /**
     * This method takes the result and puts the VOs in the List.
     *
     * @param result The ResultSet to interate through.
     * @param info is ussually constant during this process, you can use it for
     *            passing additional parameters from controler. (Like in
     *            DefaultWrapperAdapter)
     * @return The List of VOs.
     */
    public abstract List processResultSet(String name, ResultSet result, int numberPerPage, ValueListInfo info)
            throws SQLException;

    /**
     * @return Returns the dataSource.
     */
    public DataSource getDataSource() {
        return connectionCreator.getDataSource();
    }

    /**
     * @param dataSource The dataSource to set.
     */
    public void setDataSource(DataSource dataSource) {
        connectionCreator.setDataSource(dataSource);
    }

    /**
     * @return Returns the sql.
     */
    public String getSql() {
        return sql;
    }

    /**
     * @param sql The sql to set.
     */
    public void setSql(String sql) {
        this.sql = sql;
    }

    /**
     * @return Returns the statementBuilder.
     */
    public StatementBuilder getStatementBuilder() {
        return statementBuilder;
    }

    /**
     * @param statementBuilder The statementBuilder to set.
     */
    public void setStatementBuilder(StatementBuilder statementBuilder) {
        this.statementBuilder = statementBuilder;
    }

    /**
     * @return Returns the showSql.
     */
    public boolean isShowSql() {
        return showSql;
    }

    /**
     * @param showSql The showSql to set.
     */
    public void setShowSql(boolean showSql) {
        this.showSql = showSql;
    }

    /**
     * @return Returns the objectValidator.
     */
    public ObjectValidator getValidator() {
        return _validator;
    }

    /**
     * <p>
     * If is set to not null value, it uses a special
     * <code>ResultsSetDecorator<code>, that enable or
     * disable filtering objects in the final valuelist.
     * </p>
     * <h4>NOTE:</h4>
     * <p>
     * It respects the total count of entries that overlap your paged
     * list. Simply spoken it supports features such as paging.
     * </p>
     * @param objectValidator The objectValidator to set.
     * The null value means that validator is disabled.
     * @see net.mlw.vlh.adapter.util.ObjectValidator
     * @see net.mlw.vlh.adapter.jdbc.objectWrapper.ResultSetDecorator
     */
    public void setValidator(ObjectValidator objectValidator) {
        this._validator = objectValidator;
    }

    /**
     * @return Returns the connectionCreator.
     */
    public ConnectionCreator getConnectionCreator() {
        return connectionCreator;
    }

    /**
     * @param connectionCreator The connectionCreator to set.
     */
    public void setConnectionCreator(ConnectionCreator connectionCreator) {
        this.connectionCreator = connectionCreator;
    }

    public SqlPagingSupport getSqlPagingSupport() {
        return sqlPagingSupport;
    }

    public void setSqlPagingSupport(SqlPagingSupport sqlPagingSupport) {
        this.sqlPagingSupport = sqlPagingSupport;
    }
}