001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.jdbc.core;
018
019import java.sql.ResultSet;
020import java.sql.SQLException;
021
022import javax.sql.rowset.CachedRowSet;
023import javax.sql.rowset.RowSetFactory;
024import javax.sql.rowset.RowSetProvider;
025
026import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
027import org.springframework.jdbc.support.rowset.SqlRowSet;
028
029/**
030 * {@link ResultSetExtractor} implementation that returns a Spring {@link SqlRowSet}
031 * representation for each given {@link ResultSet}.
032 *
033 * <p>The default implementation uses a standard JDBC CachedRowSet underneath.
034 *
035 * @author Juergen Hoeller
036 * @since 1.2
037 * @see #newCachedRowSet
038 * @see org.springframework.jdbc.support.rowset.SqlRowSet
039 * @see JdbcTemplate#queryForRowSet(String)
040 * @see javax.sql.rowset.CachedRowSet
041 */
042public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet> {
043
044        private static final RowSetFactory rowSetFactory;
045
046        static {
047                try {
048                        rowSetFactory = RowSetProvider.newFactory();
049                }
050                catch (SQLException ex) {
051                        throw new IllegalStateException("Cannot create RowSetFactory through RowSetProvider", ex);
052                }
053        }
054
055
056        @Override
057        public SqlRowSet extractData(ResultSet rs) throws SQLException {
058                return createSqlRowSet(rs);
059        }
060
061        /**
062         * Create a {@link SqlRowSet} that wraps the given {@link ResultSet},
063         * representing its data in a disconnected fashion.
064         * <p>This implementation creates a Spring {@link ResultSetWrappingSqlRowSet}
065         * instance that wraps a standard JDBC {@link CachedRowSet} instance.
066         * Can be overridden to use a different implementation.
067         * @param rs the original ResultSet (connected)
068         * @return the disconnected SqlRowSet
069         * @throws SQLException if thrown by JDBC methods
070         * @see #newCachedRowSet()
071         * @see org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet
072         */
073        protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException {
074                CachedRowSet rowSet = newCachedRowSet();
075                rowSet.populate(rs);
076                return new ResultSetWrappingSqlRowSet(rowSet);
077        }
078
079        /**
080         * Create a new {@link CachedRowSet} instance, to be populated by
081         * the {@code createSqlRowSet} implementation.
082         * <p>The default implementation uses JDBC 4.1's {@link RowSetFactory}.
083         * @return a new CachedRowSet instance
084         * @throws SQLException if thrown by JDBC methods
085         * @see #createSqlRowSet
086         * @see RowSetProvider#newFactory()
087         * @see RowSetFactory#createCachedRowSet()
088         */
089        protected CachedRowSet newCachedRowSet() throws SQLException {
090                return rowSetFactory.createCachedRowSet();
091        }
092
093}