|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2011 the original author or authors. |
| 2 | + * Copyright 2002-2012 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
|
16 | 16 |
|
17 | 17 | package org.springframework.jdbc.core;
|
18 | 18 |
|
19 |
| -import java.lang.reflect.Method; |
20 | 19 | import java.sql.ResultSet;
|
21 | 20 | import java.sql.SQLException;
|
22 | 21 | import javax.sql.rowset.CachedRowSet;
|
| 22 | +import javax.sql.rowset.RowSetFactory; |
| 23 | +import javax.sql.rowset.RowSetProvider; |
23 | 24 |
|
24 | 25 | import com.sun.rowset.CachedRowSetImpl;
|
25 | 26 |
|
| 27 | +import org.springframework.core.JdkVersion; |
26 | 28 | import org.springframework.jdbc.support.rowset.ResultSetWrappingSqlRowSet;
|
27 | 29 | import org.springframework.jdbc.support.rowset.SqlRowSet;
|
28 |
| -import org.springframework.util.ReflectionUtils; |
29 | 30 |
|
30 | 31 | /**
|
31 |
| - * ResultSetExtractor implementation that returns a Spring SqlRowSet |
32 |
| - * representation for each given ResultSet. |
| 32 | + * {@link ResultSetExtractor} implementation that returns a Spring {@link SqlRowSet} |
| 33 | + * representation for each given {@link ResultSet}. |
33 | 34 | *
|
34 | 35 | * <p>The default implementation uses a standard JDBC CachedRowSet underneath.
|
35 | 36 | * This means that JDBC RowSet support needs to be available at runtime:
|
|
45 | 46 | */
|
46 | 47 | public class SqlRowSetResultSetExtractor implements ResultSetExtractor<SqlRowSet> {
|
47 | 48 |
|
48 |
| - private static Object rowSetFactory = null; |
49 |
| - |
50 |
| - private static Method createCachedRowSet = null; |
| 49 | + private static final CachedRowSetFactory cachedRowSetFactory; |
51 | 50 |
|
52 | 51 | static {
|
53 |
| - ClassLoader cl = SqlRowSetResultSetExtractor.class.getClassLoader(); |
54 |
| - try { |
55 |
| - Class rowSetProviderClass = cl.loadClass("javax.sql.rowset.RowSetProvider"); |
56 |
| - Method newFactory = rowSetProviderClass.getMethod("newFactory"); |
57 |
| - rowSetFactory = ReflectionUtils.invokeMethod(newFactory, null); |
58 |
| - createCachedRowSet = rowSetFactory.getClass().getMethod("createCachedRowSet"); |
| 52 | + if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_17) { |
| 53 | + // using JDBC 4.1 RowSetProvider |
| 54 | + cachedRowSetFactory = new StandardCachedRowSetFactory(); |
59 | 55 | }
|
60 |
| - catch (Exception ex) { |
| 56 | + else { |
61 | 57 | // JDBC 4.1 API not available - fall back to Sun CachedRowSetImpl
|
| 58 | + cachedRowSetFactory = new SunCachedRowSetFactory(); |
62 | 59 | }
|
63 | 60 | }
|
64 | 61 |
|
@@ -88,19 +85,56 @@ protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException {
|
88 | 85 | /**
|
89 | 86 | * Create a new CachedRowSet instance, to be populated by
|
90 | 87 | * the <code>createSqlRowSet</code> implementation.
|
91 |
| - * <p>The default implementation creates a new instance of |
92 |
| - * Sun's <code>com.sun.rowset.CachedRowSetImpl</code> class. |
| 88 | + * <p>The default implementation uses JDBC 4.1's RowSetProvider |
| 89 | + * when running on JDK 7 or higher, falling back to Sun's |
| 90 | + * <code>com.sun.rowset.CachedRowSetImpl</code> class on older JDKs. |
93 | 91 | * @return a new CachedRowSet instance
|
94 | 92 | * @throws SQLException if thrown by JDBC methods
|
95 | 93 | * @see #createSqlRowSet
|
96 | 94 | * @see com.sun.rowset.CachedRowSetImpl
|
97 | 95 | */
|
98 | 96 | protected CachedRowSet newCachedRowSet() throws SQLException {
|
99 |
| - if (createCachedRowSet != null) { |
100 |
| - // RowSetProvider.newFactory().createCachedRowSet(); |
101 |
| - return (CachedRowSet) ReflectionUtils.invokeJdbcMethod(createCachedRowSet, rowSetFactory); |
| 97 | + return cachedRowSetFactory.createCachedRowSet(); |
| 98 | + } |
| 99 | + |
| 100 | + |
| 101 | + /** |
| 102 | + * Internal strategy interface for the creation of CachedRowSet instances. |
| 103 | + */ |
| 104 | + private interface CachedRowSetFactory { |
| 105 | + |
| 106 | + CachedRowSet createCachedRowSet() throws SQLException; |
| 107 | + } |
| 108 | + |
| 109 | + |
| 110 | + /** |
| 111 | + * Inner class to avoid a hard dependency on JDBC 4.1 RowSetProvider class. |
| 112 | + */ |
| 113 | + private static class StandardCachedRowSetFactory implements CachedRowSetFactory { |
| 114 | + |
| 115 | + private final RowSetFactory rowSetFactory; |
| 116 | + |
| 117 | + public StandardCachedRowSetFactory() { |
| 118 | + try { |
| 119 | + this.rowSetFactory = RowSetProvider.newFactory(); |
| 120 | + } |
| 121 | + catch (SQLException ex) { |
| 122 | + throw new IllegalStateException("Cannot create RowSetFactory through RowSetProvider", ex); |
| 123 | + } |
102 | 124 | }
|
103 |
| - else { |
| 125 | + |
| 126 | + public CachedRowSet createCachedRowSet() throws SQLException { |
| 127 | + return this.rowSetFactory.createCachedRowSet(); |
| 128 | + } |
| 129 | + } |
| 130 | + |
| 131 | + |
| 132 | + /** |
| 133 | + * Inner class to avoid a hard dependency on Sun's CachedRowSetImpl class. |
| 134 | + */ |
| 135 | + private static class SunCachedRowSetFactory implements CachedRowSetFactory { |
| 136 | + |
| 137 | + public CachedRowSet createCachedRowSet() throws SQLException { |
104 | 138 | return new CachedRowSetImpl();
|
105 | 139 | }
|
106 | 140 | }
|
|
0 commit comments