Avoid a hard dependency on Sun's CachedRowSetImpl class

Also using the JDBC 4.1 RowSetProvider API directly instead of going through reflection, since we're building on JDK 7 now.
master
Juergen Hoeller 12 years ago
parent e2f418ab4c
commit 9e337d2705
  1. 76
      spring-jdbc/src/main/java/org/springframework/jdbc/core/SqlRowSetResultSetExtractor.java

@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,20 +16,21 @@
package org.springframework.jdbc.core;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
import com.sun.rowset.CachedRowSetImpl;
import org.springframework.core.JdkVersion;
import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.util.ReflectionUtils;
/**
* ResultSetExtractor implementation that returns a Spring SqlRowSet
* representation for each given ResultSet.
* {@link ResultSetExtractor} implementation that returns a Spring {@link SqlRowSet}
* representation for each given {@link ResultSet}.
*
* <p>The default implementation uses a standard JDBC CachedRowSet underneath.
* This means that JDBC RowSet support needs to be available at runtime:
@ -45,20 +46,16 @@ import org.springframework.util.ReflectionUtils;
*/
public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet> {
private static Object rowSetFactory = null;
private static Method createCachedRowSet = null;
private static final CachedRowSetFactory cachedRowSetFactory;
static {
ClassLoader cl = SqlRowSetResultSetExtractor.class.getClassLoader();
try {
Class rowSetProviderClass = cl.loadClass("javax.sql.rowset.RowSetProvider");
Method newFactory = rowSetProviderClass.getMethod("newFactory");
rowSetFactory = ReflectionUtils.invokeMethod(newFactory, null);
createCachedRowSet = rowSetFactory.getClass().getMethod("createCachedRowSet");
if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_17) {
// using JDBC 4.1 RowSetProvider
cachedRowSetFactory = new StandardCachedRowSetFactory();
}
catch (Exception ex) {
else {
// JDBC 4.1 API not available - fall back to Sun CachedRowSetImpl
cachedRowSetFactory = new SunCachedRowSetFactory();
}
}
@ -88,19 +85,56 @@ public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet
/**
* Create a new CachedRowSet instance, to be populated by
* the <code>createSqlRowSet</code> implementation.
* <p>The default implementation creates a new instance of
* Sun's <code>com.sun.rowset.CachedRowSetImpl</code> class.
* <p>The default implementation uses JDBC 4.1's RowSetProvider
* when running on JDK 7 or higher, falling back to Sun's
* <code>com.sun.rowset.CachedRowSetImpl</code> class on older JDKs.
* @return a new CachedRowSet instance
* @throws SQLException if thrown by JDBC methods
* @see #createSqlRowSet
* @see com.sun.rowset.CachedRowSetImpl
*/
protected CachedRowSet newCachedRowSet() throws SQLException {
if (createCachedRowSet != null) {
// RowSetProvider.newFactory().createCachedRowSet();
return (CachedRowSet) ReflectionUtils.invokeJdbcMethod(createCachedRowSet, rowSetFactory);
return cachedRowSetFactory.createCachedRowSet();
}
/**
* Internal strategy interface for the creation of CachedRowSet instances.
*/
private interface CachedRowSetFactory {
CachedRowSet createCachedRowSet() throws SQLException;
}
/**
* Inner class to avoid a hard dependency on JDBC 4.1 RowSetProvider class.
*/
private static class StandardCachedRowSetFactory implements CachedRowSetFactory {
private final RowSetFactory rowSetFactory;
public StandardCachedRowSetFactory() {
try {
this.rowSetFactory = RowSetProvider.newFactory();
}
catch (SQLException ex) {
throw new IllegalStateException("Cannot create RowSetFactory through RowSetProvider", ex);
}
}
else {
public CachedRowSet createCachedRowSet() throws SQLException {
return this.rowSetFactory.createCachedRowSet();
}
}
/**
* Inner class to avoid a hard dependency on Sun's CachedRowSetImpl class.
*/
private static class SunCachedRowSetFactory implements CachedRowSetFactory {
public CachedRowSet createCachedRowSet() throws SQLException {
return new CachedRowSetImpl();
}
}

Loading…
Cancel
Save