History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/sql/rowset/RowSetProvider.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/sql/rowset/RowSetProvider.java+311−0
@@ -0,0 +1,311 @@
1+/*
2+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package javax.sql.rowset;
27+
28+import java.security.AccessController;
29+import java.security.PrivilegedAction;
30+import java.sql.SQLException;
31+import java.util.ServiceConfigurationError;
32+import java.util.ServiceLoader;
33+
34+/**
35+ * A factory API that enables applications to obtain a
36+ * {@code RowSetFactory} implementation that can be used to create different
37+ * types of {@code RowSet} implementations.
38+ * <p>
39+ * Example:
40+ * </p>
41+ * <pre>
42+ * RowSetFactory aFactory = RowSetProvider.newFactory();
43+ * CachedRowSet crs = aFactory.createCachedRowSet();
44+ * ...
45+ * RowSetFactory rsf = RowSetProvider.newFactory("com.sun.rowset.RowSetFactoryImpl", null);
46+ * WebRowSet wrs = rsf.createWebRowSet();
47+ * </pre>
48+ *<p>
49+ * Tracing of this class may be enabled by setting the System property
50+ * {@code javax.sql.rowset.RowSetFactory.debug} to any value but {@code false}.
51+ * </p>
52+ *
53+ * @author Lance Andersen
54+ * @since 1.7
55+ */
56+public class RowSetProvider {
57+
58+ private static final String ROWSET_DEBUG_PROPERTY = "javax.sql.rowset.RowSetProvider.debug";
59+ private static final String ROWSET_FACTORY_IMPL = "com.sun.rowset.RowSetFactoryImpl";
60+ private static final String ROWSET_FACTORY_NAME = "javax.sql.rowset.RowSetFactory";
61+ /**
62+ * Internal debug flag.
63+ */
64+ private static boolean debug = true;
65+
66+
67+ static {
68+ // Check to see if the debug property is set
69+ String val = getSystemProperty(ROWSET_DEBUG_PROPERTY);
70+ // Allow simply setting the prop to turn on debug
71+ debug = val != null && !"false".equals(val);
72+ }
73+
74+
75+ protected RowSetProvider () {
76+ }
77+
78+ /**
79+ * <p>Creates a new instance of a <code>RowSetFactory</code>
80+ * implementation. This method uses the following
81+ * look up order to determine
82+ * the <code>RowSetFactory</code> implementation class to load:</p>
83+ * <ul>
84+ * <li>
85+ * The System property {@code javax.sql.rowset.RowSetFactory}. For example:
86+ * <ul>
87+ * <li>
88+ * -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl
89+ * </li>
90+ * </ul>
91+ * <li>
92+ * The {@link ServiceLoader} API. The {@code ServiceLoader} API will look
93+ * for a class name in the file
94+ * {@code META-INF/services/javax.sql.rowset.RowSetFactory}
95+ * in jars available to the runtime. For example, to have the the RowSetFactory
96+ * implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the
97+ * entry in {@code META-INF/services/javax.sql.rowset.RowSetFactory} would be:
98+ * <ul>
99+ * <li>
100+ * {@code com.sun.rowset.RowSetFactoryImpl }
101+ * </li>
102+ * </ul>
103+ * </li>
104+ * <li>
105+ * Platform default <code>RowSetFactory</code> instance.
106+ * </li>
107+ * </ul>
108+ *
109+ * <p>Once an application has obtained a reference to a {@code RowSetFactory},
110+ * it can use the factory to obtain RowSet instances.</p>
111+ *
112+ * @return New instance of a <code>RowSetFactory</code>
113+ *
114+ * @throws SQLException if the default factory class cannot be loaded,
115+ * instantiated. The cause will be set to actual Exception
116+ *
117+ * @see ServiceLoader
118+ * @since 1.7
119+ */
120+ public static RowSetFactory newFactory()
121+ throws SQLException {
122+ // Use the system property first
123+ RowSetFactory factory = null;
124+ String factoryClassName = null;
125+ try {
126+ trace("Checking for Rowset System Property...");
127+ factoryClassName = getSystemProperty(ROWSET_FACTORY_NAME);
128+ if (factoryClassName != null) {
129+ trace("Found system property, value=" + factoryClassName);
130+ factory = (RowSetFactory) getFactoryClass(factoryClassName, null, true).newInstance();
131+ }
132+ } catch (ClassNotFoundException e) {
133+ throw new SQLException(
134+ "RowSetFactory: " + factoryClassName + " not found", e);
135+ } catch (Exception e) {
136+ throw new SQLException(
137+ "RowSetFactory: " + factoryClassName + " could not be instantiated: " + e,
138+ e);
139+ }
140+
141+ // Check to see if we found the RowSetFactory via a System property
142+ if (factory == null) {
143+ // If the RowSetFactory is not found via a System Property, now
144+ // look it up via the ServiceLoader API and if not found, use the
145+ // Java SE default.
146+ factory = loadViaServiceLoader();
147+ factory =
148+ factory == null ? newFactory(ROWSET_FACTORY_IMPL, null) : factory;
149+ }
150+ return (factory);
151+ }
152+
153+ /**
154+ * <p>Creates a new instance of a <code>RowSetFactory</code> from the
155+ * specified factory class name.
156+ * This function is useful when there are multiple providers in the classpath.
157+ * It gives more control to the application as it can specify which provider
158+ * should be loaded.</p>
159+ *
160+ * <p>Once an application has obtained a reference to a <code>RowSetFactory</code>
161+ * it can use the factory to obtain RowSet instances.</p>
162+ *
163+ * @param factoryClassName fully qualified factory class name that
164+ * provides an implementation of <code>javax.sql.rowset.RowSetFactory</code>.
165+ *
166+ * @param cl <code>ClassLoader</code> used to load the factory
167+ * class. If <code>null</code> current <code>Thread</code>'s context
168+ * classLoader is used to load the factory class.
169+ *
170+ * @return New instance of a <code>RowSetFactory</code>
171+ *
172+ * @throws SQLException if <code>factoryClassName</code> is
173+ * <code>null</code>, or the factory class cannot be loaded, instantiated.
174+ *
175+ * @see #newFactory()
176+ *
177+ * @since 1.7
178+ */
179+ public static RowSetFactory newFactory(String factoryClassName, ClassLoader cl)
180+ throws SQLException {
181+
182+ trace("***In newInstance()");
183+ try {
184+ Class providerClass = getFactoryClass(factoryClassName, cl, false);
185+ RowSetFactory instance = (RowSetFactory) providerClass.newInstance();
186+ if (debug) {
187+ trace("Created new instance of " + providerClass +
188+ " using ClassLoader: " + cl);
189+ }
190+ return instance;
191+ } catch (ClassNotFoundException x) {
192+ throw new SQLException(
193+ "Provider " + factoryClassName + " not found", x);
194+ } catch (Exception x) {
195+ throw new SQLException(
196+ "Provider " + factoryClassName + " could not be instantiated: " + x,
197+ x);
198+ }
199+ }
200+
201+ /*
202+ * Returns the class loader to be used.
203+ * @return The ClassLoader to use.
204+ *
205+ */
206+ static private ClassLoader getContextClassLoader() throws SecurityException {
207+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
208+
209+ public ClassLoader run() {
210+ ClassLoader cl = null;
211+
212+ cl = Thread.currentThread().getContextClassLoader();
213+
214+ if (cl == null) {
215+ cl = ClassLoader.getSystemClassLoader();
216+ }
217+
218+ return cl;
219+ }
220+ });
221+ }
222+
223+ /**
224+ * Attempt to load a class using the class loader supplied. If that fails
225+ * and fall back is enabled, the current (i.e. bootstrap) class loader is
226+ * tried.
227+ *
228+ * If the class loader supplied is <code>null</code>, first try using the
229+ * context class loader followed by the current class loader.
230+ * @return The class which was loaded
231+ */
232+ static private Class getFactoryClass(String factoryClassName, ClassLoader cl,
233+ boolean doFallback) throws ClassNotFoundException {
234+ try {
235+ if (cl == null) {
236+ cl = getContextClassLoader();
237+ if (cl == null) {
238+ throw new ClassNotFoundException();
239+ } else {
240+ return cl.loadClass(factoryClassName);
241+ }
242+ } else {
243+ return cl.loadClass(factoryClassName);
244+ }
245+ } catch (ClassNotFoundException e) {
246+ if (doFallback) {
247+ // Use current class loader
248+ return Class.forName(factoryClassName, true, RowSetFactory.class.getClassLoader());
249+ } else {
250+ throw e;
251+ }
252+ }
253+ }
254+
255+ /**
256+ * Use the ServiceLoader mechanism to load the default RowSetFactory
257+ * @return default RowSetFactory Implementation
258+ */
259+ static private RowSetFactory loadViaServiceLoader() throws SQLException {
260+ RowSetFactory theFactory = null;
261+ try {
262+ trace("***in loadViaServiceLoader():");
263+ for (RowSetFactory factory : ServiceLoader.load(javax.sql.rowset.RowSetFactory.class)) {
264+ trace(" Loading done by the java.util.ServiceLoader :" + factory.getClass().getName());
265+ theFactory = factory;
266+ break;
267+ }
268+ } catch (ServiceConfigurationError e) {
269+ throw new SQLException(
270+ "RowSetFactory: Error locating RowSetFactory using Service "
271+ + "Loader API: " + e, e);
272+ }
273+ return theFactory;
274+
275+ }
276+
277+ /**
278+ * Returns the requested System Property. If a {@code SecurityException}
279+ * occurs, just return NULL
280+ * @param propName - System property to retrieve
281+ * @return The System property value or NULL if the property does not exist
282+ * or a {@code SecurityException} occurs.
283+ */
284+ static private String getSystemProperty(final String propName) {
285+ String property = null;
286+ try {
287+ property = AccessController.doPrivileged(new PrivilegedAction<String>() {
288+
289+ public String run() {
290+ return System.getProperty(propName);
291+ }
292+ });
293+ } catch (SecurityException se) {
294+ if (debug) {
295+ se.printStackTrace();
296+ }
297+ }
298+ return property;
299+ }
300+
301+ /**
302+ * Debug routine which will output tracing if the System Property
303+ * -Djavax.sql.rowset.RowSetFactory.debug is set
304+ * @param msg - The debug message to display
305+ */
306+ private static void trace(String msg) {
307+ if (debug) {
308+ System.err.println("###RowSets: " + msg);
309+ }
310+ }
311+}