feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
4534
jdkSrc/jdk8/javax/sql/rowset/BaseRowSet.java
Normal file
4534
jdkSrc/jdk8/javax/sql/rowset/BaseRowSet.java
Normal file
File diff suppressed because it is too large
Load Diff
1624
jdkSrc/jdk8/javax/sql/rowset/CachedRowSet.java
Normal file
1624
jdkSrc/jdk8/javax/sql/rowset/CachedRowSet.java
Normal file
File diff suppressed because it is too large
Load Diff
160
jdkSrc/jdk8/javax/sql/rowset/FilteredRowSet.java
Normal file
160
jdkSrc/jdk8/javax/sql/rowset/FilteredRowSet.java
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import javax.naming.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* The standard interface that all standard implementations of
|
||||
* <code>FilteredRowSet</code> must implement. The <code>FilteredRowSetImpl</code> class
|
||||
* provides the reference implementation which may be extended if required.
|
||||
* Alternatively, a vendor is free to implement its own version
|
||||
* by implementing this interface.
|
||||
*
|
||||
* <h3>1.0 Background</h3>
|
||||
*
|
||||
* There are occasions when a <code>RowSet</code> object has a need to provide a degree
|
||||
* of filtering to its contents. One possible solution is to provide
|
||||
* a query language for all standard <code>RowSet</code> implementations; however,
|
||||
* this is an impractical approach for lightweight components such as disconnected
|
||||
* <code>RowSet</code>
|
||||
* objects. The <code>FilteredRowSet</code> interface seeks to address this need
|
||||
* without supplying a heavyweight query language along with the processing that
|
||||
* such a query language would require.
|
||||
* <p>
|
||||
* A JDBC <code>FilteredRowSet</code> standard implementation implements the
|
||||
* <code>RowSet</code> interfaces and extends the
|
||||
* <code>CachedRowSet</code>™ class. The
|
||||
* <code>CachedRowSet</code> class provides a set of protected cursor manipulation
|
||||
* methods, which a <code>FilteredRowSet</code> implementation can override
|
||||
* to supply filtering support.
|
||||
*
|
||||
* <h3>2.0 Predicate Sharing</h3>
|
||||
*
|
||||
* If a <code>FilteredRowSet</code> implementation is shared using the
|
||||
* inherited <code>createShared</code> method in parent interfaces, the
|
||||
* <code>Predicate</code> should be shared without modification by all
|
||||
* <code>FilteredRowSet</code> instance clones.
|
||||
*
|
||||
* <h3>3.0 Usage</h3>
|
||||
* <p>
|
||||
* By implementing a <code>Predicate</code> (see example in <a href="Predicate.html">Predicate</a>
|
||||
* class JavaDoc), a <code>FilteredRowSet</code> could then be used as described
|
||||
* below.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* FilteredRowSet frs = new FilteredRowSetImpl();
|
||||
* frs.populate(rs);
|
||||
*
|
||||
* Range name = new Range("Alpha", "Bravo", "columnName");
|
||||
* frs.setFilter(name);
|
||||
*
|
||||
* frs.next() // only names from "Alpha" to "Bravo" will be returned
|
||||
* }
|
||||
* </pre>
|
||||
* In the example above, we initialize a <code>Range</code> object which
|
||||
* implements the <code>Predicate</code> interface. This object expresses
|
||||
* the following constraints: All rows outputted or modified from this
|
||||
* <code>FilteredRowSet</code> object must fall between the values 'Alpha' and
|
||||
* 'Bravo' both values inclusive, in the column 'columnName'. If a filter is
|
||||
* applied to a <code>FilteredRowSet</code> object that contains no data that
|
||||
* falls within the range of the filter, no rows are returned.
|
||||
* <p>
|
||||
* This framework allows multiple classes implementing predicates to be
|
||||
* used in combination to achieved the required filtering result with
|
||||
* out the need for query language processing.
|
||||
*
|
||||
* <h3>4.0 Updating a <code>FilteredRowSet</code> Object</h3>
|
||||
* The predicate set on a <code>FilteredRowSet</code> object
|
||||
* applies a criterion on all rows in a
|
||||
* <code>RowSet</code> object to manage a subset of rows in a <code>RowSet</code>
|
||||
* object. This criterion governs the subset of rows that are visible and also
|
||||
* defines which rows can be modified, deleted or inserted.
|
||||
* <p>
|
||||
* Therefore, the predicate set on a <code>FilteredRowSet</code> object must be
|
||||
* considered as bi-directional and the set criterion as the gating mechanism
|
||||
* for all views and updates to the <code>FilteredRowSet</code> object. Any attempt
|
||||
* to update the <code>FilteredRowSet</code> that violates the criterion will
|
||||
* result in a <code>SQLException</code> object being thrown.
|
||||
* <p>
|
||||
* The <code>FilteredRowSet</code> range criterion can be modified by applying
|
||||
* a new <code>Predicate</code> object to the <code>FilteredRowSet</code>
|
||||
* instance at any time. This is possible if no additional references to the
|
||||
* <code>FilteredRowSet</code> object are detected. A new filter has has an
|
||||
* immediate effect on criterion enforcement within the
|
||||
* <code>FilteredRowSet</code> object, and all subsequent views and updates will be
|
||||
* subject to similar enforcement.
|
||||
*
|
||||
* <h3>5.0 Behavior of Rows Outside the Filter</h3>
|
||||
* Rows that fall outside of the filter set on a <code>FilteredRowSet</code>
|
||||
* object cannot be modified until the filter is removed or a
|
||||
* new filter is applied.
|
||||
* <p>
|
||||
* Furthermore, only rows that fall within the bounds of a filter will be
|
||||
* synchronized with the data source.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
*/
|
||||
|
||||
public interface FilteredRowSet extends WebRowSet {
|
||||
|
||||
/**
|
||||
* Applies the given <code>Predicate</code> object to this
|
||||
* <code>FilteredRowSet</code>
|
||||
* object. The filter applies controls both to inbound and outbound views,
|
||||
* constraining which rows are visible and which
|
||||
* rows can be manipulated.
|
||||
* <p>
|
||||
* A new <code>Predicate</code> object may be set at any time. This has the
|
||||
* effect of changing constraints on the <code>RowSet</code> object's data.
|
||||
* In addition, modifying the filter at runtime presents issues whereby
|
||||
* multiple components may be operating on one <code>FilteredRowSet</code> object.
|
||||
* Application developers must take responsibility for managing multiple handles
|
||||
* to <code>FilteredRowSet</code> objects when their underling <code>Predicate</code>
|
||||
* objects change.
|
||||
*
|
||||
* @param p a <code>Predicate</code> object defining the filter for this
|
||||
* <code>FilteredRowSet</code> object. Setting a <b>null</b> value
|
||||
* will clear the predicate, allowing all rows to become visible.
|
||||
*
|
||||
* @throws SQLException if an error occurs when setting the
|
||||
* <code>Predicate</code> object
|
||||
*/
|
||||
public void setFilter(Predicate p) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the active filter for this <code>FilteredRowSet</code> object.
|
||||
*
|
||||
* @return p the <code>Predicate</code> for this <code>FilteredRowSet</code>
|
||||
* object; <code>null</code> if no filter has been set.
|
||||
*/
|
||||
public Predicate getFilter() ;
|
||||
}
|
289
jdkSrc/jdk8/javax/sql/rowset/JdbcRowSet.java
Normal file
289
jdkSrc/jdk8/javax/sql/rowset/JdbcRowSet.java
Normal file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import javax.naming.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* The standard interface that all standard implementations of
|
||||
* <code>JdbcRowSet</code> must implement.
|
||||
*
|
||||
* <h3>1.0 Overview</h3>
|
||||
* A wrapper around a <code>ResultSet</code> object that makes it possible
|
||||
* to use the result set as a JavaBeans™
|
||||
* component. Thus, a <code>JdbcRowSet</code> object can be one of the Beans that
|
||||
* a tool makes available for composing an application. Because
|
||||
* a <code>JdbcRowSet</code> is a connected rowset, that is, it continually
|
||||
* maintains its connection to a database using a JDBC technology-enabled
|
||||
* driver, it also effectively makes the driver a JavaBeans component.
|
||||
* <P>
|
||||
* Because it is always connected to its database, an instance of
|
||||
* <code>JdbcRowSet</code>
|
||||
* can simply take calls invoked on it and in turn call them on its
|
||||
* <code>ResultSet</code> object. As a consequence, a result set can, for
|
||||
* example, be a component in a Swing application.
|
||||
* <P>
|
||||
* Another advantage of a <code>JdbcRowSet</code> object is that it can be
|
||||
* used to make a <code>ResultSet</code> object scrollable and updatable. All
|
||||
* <code>RowSet</code> objects are by default scrollable and updatable. If
|
||||
* the driver and database being used do not support scrolling and/or updating
|
||||
* of result sets, an application can populate a <code>JdbcRowSet</code> object
|
||||
* with the data of a <code>ResultSet</code> object and then operate on the
|
||||
* <code>JdbcRowSet</code> object as if it were the <code>ResultSet</code>
|
||||
* object.
|
||||
*
|
||||
* <h3>2.0 Creating a <code>JdbcRowSet</code> Object</h3>
|
||||
* The reference implementation of the <code>JdbcRowSet</code> interface,
|
||||
* <code>JdbcRowSetImpl</code>, provides an implementation of
|
||||
* the default constructor. A new instance is initialized with
|
||||
* default values, which can be set with new values as needed. A
|
||||
* new instance is not really functional until its <code>execute</code>
|
||||
* method is called. In general, this method does the following:
|
||||
* <UL>
|
||||
* <LI> establishes a connection with a database
|
||||
* <LI> creates a <code>PreparedStatement</code> object and sets any of its
|
||||
* placeholder parameters
|
||||
* <LI> executes the statement to create a <code>ResultSet</code> object
|
||||
* </UL>
|
||||
* If the <code>execute</code> method is successful, it will set the
|
||||
* appropriate private <code>JdbcRowSet</code> fields with the following:
|
||||
* <UL>
|
||||
* <LI> a <code>Connection</code> object -- the connection between the rowset
|
||||
* and the database
|
||||
* <LI> a <code>PreparedStatement</code> object -- the query that produces
|
||||
* the result set
|
||||
* <LI> a <code>ResultSet</code> object -- the result set that the rowset's
|
||||
* command produced and that is being made, in effect, a JavaBeans
|
||||
* component
|
||||
* </UL>
|
||||
* If these fields have not been set, meaning that the <code>execute</code>
|
||||
* method has not executed successfully, no methods other than
|
||||
* <code>execute</code> and <code>close</code> may be called on the
|
||||
* rowset. All other public methods will throw an exception.
|
||||
* <P>
|
||||
* Before calling the <code>execute</code> method, however, the command
|
||||
* and properties needed for establishing a connection must be set.
|
||||
* The following code fragment creates a <code>JdbcRowSetImpl</code> object,
|
||||
* sets the command and connection properties, sets the placeholder parameter,
|
||||
* and then invokes the method <code>execute</code>.
|
||||
* <PRE>
|
||||
* JdbcRowSetImpl jrs = new JdbcRowSetImpl();
|
||||
* jrs.setCommand("SELECT * FROM TITLES WHERE TYPE = ?");
|
||||
* jrs.setURL("jdbc:myDriver:myAttribute");
|
||||
* jrs.setUsername("cervantes");
|
||||
* jrs.setPassword("sancho");
|
||||
* jrs.setString(1, "BIOGRAPHY");
|
||||
* jrs.execute();
|
||||
* </PRE>
|
||||
* The variable <code>jrs</code> now represents an instance of
|
||||
* <code>JdbcRowSetImpl</code> that is a thin wrapper around the
|
||||
* <code>ResultSet</code> object containing all the rows in the
|
||||
* table <code>TITLES</code> where the type of book is biography.
|
||||
* At this point, operations called on <code>jrs</code> will
|
||||
* affect the rows in the result set, which is effectively a JavaBeans
|
||||
* component.
|
||||
* <P>
|
||||
* The implementation of the <code>RowSet</code> method <code>execute</code> in the
|
||||
* <code>JdbcRowSet</code> reference implementation differs from that in the
|
||||
* <code>CachedRowSet</code>™
|
||||
* reference implementation to account for the different
|
||||
* requirements of connected and disconnected <code>RowSet</code> objects.
|
||||
* <p>
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
*/
|
||||
|
||||
public interface JdbcRowSet extends RowSet, Joinable {
|
||||
|
||||
/**
|
||||
* Retrieves a <code>boolean</code> indicating whether rows marked
|
||||
* for deletion appear in the set of current rows. If <code>true</code> is
|
||||
* returned, deleted rows are visible with the current rows. If
|
||||
* <code>false</code> is returned, rows are not visible with the set of
|
||||
* current rows. The default value is <code>false</code>.
|
||||
* <P>
|
||||
* Standard rowset implementations may choose to restrict this behavior
|
||||
* for security considerations or for certain deployment
|
||||
* scenarios. The visibility of deleted rows is implementation-defined
|
||||
* and does not represent standard behavior.
|
||||
* <P>
|
||||
* Note: Allowing deleted rows to remain visible complicates the behavior
|
||||
* of some standard JDBC <code>RowSet</code> implementations methods.
|
||||
* However, most rowset users can simply ignore this extra detail because
|
||||
* only very specialized applications will likely want to take advantage of
|
||||
* this feature.
|
||||
*
|
||||
* @return <code>true</code> if deleted rows are visible;
|
||||
* <code>false</code> otherwise
|
||||
* @exception SQLException if a rowset implementation is unable to
|
||||
* to determine whether rows marked for deletion remain visible
|
||||
* @see #setShowDeleted
|
||||
*/
|
||||
public boolean getShowDeleted() throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets the property <code>showDeleted</code> to the given
|
||||
* <code>boolean</code> value. This property determines whether
|
||||
* rows marked for deletion continue to appear in the set of current rows.
|
||||
* If the value is set to <code>true</code>, deleted rows are immediately
|
||||
* visible with the set of current rows. If the value is set to
|
||||
* <code>false</code>, the deleted rows are set as invisible with the
|
||||
* current set of rows.
|
||||
* <P>
|
||||
* Standard rowset implementations may choose to restrict this behavior
|
||||
* for security considerations or for certain deployment
|
||||
* scenarios. This is left as implementation-defined and does not
|
||||
* represent standard behavior.
|
||||
*
|
||||
* @param b <code>true</code> if deleted rows should be shown;
|
||||
* <code>false</code> otherwise
|
||||
* @exception SQLException if a rowset implementation is unable to
|
||||
* to reset whether deleted rows should be visible
|
||||
* @see #getShowDeleted
|
||||
*/
|
||||
public void setShowDeleted(boolean b) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the first warning reported by calls on this <code>JdbcRowSet</code>
|
||||
* object.
|
||||
* If a second warning was reported on this <code>JdbcRowSet</code> object,
|
||||
* it will be chained to the first warning and can be retrieved by
|
||||
* calling the method <code>RowSetWarning.getNextWarning</code> on the
|
||||
* first warning. Subsequent warnings on this <code>JdbcRowSet</code>
|
||||
* object will be chained to the <code>RowSetWarning</code> objects
|
||||
* returned by the method <code>RowSetWarning.getNextWarning</code>.
|
||||
*
|
||||
* The warning chain is automatically cleared each time a new row is read.
|
||||
* This method may not be called on a <code>RowSet</code> object
|
||||
* that has been closed;
|
||||
* doing so will cause an <code>SQLException</code> to be thrown.
|
||||
* <P>
|
||||
* Because it is always connected to its data source, a <code>JdbcRowSet</code>
|
||||
* object can rely on the presence of active
|
||||
* <code>Statement</code>, <code>Connection</code>, and <code>ResultSet</code>
|
||||
* instances. This means that applications can obtain additional
|
||||
* <code>SQLWarning</code>
|
||||
* notifications by calling the <code>getNextWarning</code> methods that
|
||||
* they provide.
|
||||
* Disconnected <code>Rowset</code> objects, such as a
|
||||
* <code>CachedRowSet</code> object, do not have access to
|
||||
* these <code>getNextWarning</code> methods.
|
||||
*
|
||||
* @return the first <code>RowSetWarning</code>
|
||||
* object reported on this <code>JdbcRowSet</code> object
|
||||
* or <code>null</code> if there are none
|
||||
* @throws SQLException if this method is called on a closed
|
||||
* <code>JdbcRowSet</code> object
|
||||
* @see RowSetWarning
|
||||
*/
|
||||
public RowSetWarning getRowSetWarnings() throws SQLException;
|
||||
|
||||
/**
|
||||
* Each <code>JdbcRowSet</code> contains a <code>Connection</code> object from
|
||||
* the <code>ResultSet</code> or JDBC properties passed to it's constructors.
|
||||
* This method wraps the <code>Connection</code> commit method to allow flexible
|
||||
* auto commit or non auto commit transactional control support.
|
||||
* <p>
|
||||
* Makes all changes made since the previous commit/rollback permanent
|
||||
* and releases any database locks currently held by this Connection
|
||||
* object. This method should be used only when auto-commit mode has
|
||||
* been disabled.
|
||||
*
|
||||
* @throws SQLException if a database access error occurs or this
|
||||
* Connection object within this <code>JdbcRowSet</code> is in auto-commit mode
|
||||
* @see java.sql.Connection#setAutoCommit
|
||||
*/
|
||||
public void commit() throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* Each <code>JdbcRowSet</code> contains a <code>Connection</code> object from
|
||||
* the original <code>ResultSet</code> or JDBC properties passed to it. This
|
||||
* method wraps the <code>Connection</code>'s <code>getAutoCommit</code> method
|
||||
* to allow an application to determine the <code>JdbcRowSet</code> transaction
|
||||
* behavior.
|
||||
* <p>
|
||||
* Sets this connection's auto-commit mode to the given state. If a
|
||||
* connection is in auto-commit mode, then all its SQL statements will
|
||||
* be executed and committed as individual transactions. Otherwise, its
|
||||
* SQL statements are grouped into transactions that are terminated by a
|
||||
* call to either the method commit or the method rollback. By default,
|
||||
* new connections are in auto-commit mode.
|
||||
*
|
||||
* @return {@code true} if auto-commit is enabled; {@code false} otherwise
|
||||
* @throws SQLException if a database access error occurs
|
||||
* @see java.sql.Connection#getAutoCommit()
|
||||
*/
|
||||
public boolean getAutoCommit() throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* Each <code>JdbcRowSet</code> contains a <code>Connection</code> object from
|
||||
* the original <code>ResultSet</code> or JDBC properties passed to it. This
|
||||
* method wraps the <code>Connection</code>'s <code>getAutoCommit</code> method
|
||||
* to allow an application to set the <code>JdbcRowSet</code> transaction behavior.
|
||||
* <p>
|
||||
* Sets the current auto-commit mode for this <code>Connection</code> object.
|
||||
* @param autoCommit {@code true} to enable auto-commit; {@code false} to
|
||||
* disable auto-commit
|
||||
* @throws SQLException if a database access error occurs
|
||||
* @see java.sql.Connection#setAutoCommit(boolean)
|
||||
*/
|
||||
public void setAutoCommit(boolean autoCommit) throws SQLException;
|
||||
|
||||
/**
|
||||
* Each <code>JdbcRowSet</code> contains a <code>Connection</code> object from
|
||||
* the original <code>ResultSet</code> or JDBC properties passed to it.
|
||||
* Undoes all changes made in the current transaction and releases any
|
||||
* database locks currently held by this <code>Connection</code> object. This method
|
||||
* should be used only when auto-commit mode has been disabled.
|
||||
*
|
||||
* @throws SQLException if a database access error occurs or this <code>Connection</code>
|
||||
* object within this <code>JdbcRowSet</code> is in auto-commit mode.
|
||||
* @see #rollback(Savepoint)
|
||||
*/
|
||||
public void rollback() throws SQLException;
|
||||
|
||||
|
||||
/**
|
||||
* Each <code>JdbcRowSet</code> contains a <code>Connection</code> object from
|
||||
* the original <code>ResultSet</code> or JDBC properties passed to it.
|
||||
* Undoes all changes made in the current transaction to the last set savepoint
|
||||
* and releases any database locks currently held by this <code>Connection</code>
|
||||
* object. This method should be used only when auto-commit mode has been disabled.
|
||||
* @param s The {@code Savepoint} to rollback to
|
||||
* @throws SQLException if a database access error occurs or this <code>Connection</code>
|
||||
* object within this <code>JdbcRowSet</code> is in auto-commit mode.
|
||||
* @see #rollback
|
||||
*/
|
||||
public void rollback(Savepoint s) throws SQLException;
|
||||
|
||||
}
|
536
jdkSrc/jdk8/javax/sql/rowset/JoinRowSet.java
Normal file
536
jdkSrc/jdk8/javax/sql/rowset/JoinRowSet.java
Normal file
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import javax.naming.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.sql.rowset.*;
|
||||
|
||||
/**
|
||||
* The <code>JoinRowSet</code> interface provides a mechanism for combining related
|
||||
* data from different <code>RowSet</code> objects into one <code>JoinRowSet</code>
|
||||
* object, which represents an SQL <code>JOIN</code>.
|
||||
* In other words, a <code>JoinRowSet</code> object acts as a
|
||||
* container for the data from <code>RowSet</code> objects that form an SQL
|
||||
* <code>JOIN</code> relationship.
|
||||
* <P>
|
||||
* The <code>Joinable</code> interface provides the methods for setting,
|
||||
* retrieving, and unsetting a match column, the basis for
|
||||
* establishing an SQL <code>JOIN</code> relationship. The match column may
|
||||
* alternatively be set by supplying it to the appropriate version of the
|
||||
* <code>JointRowSet</code> method <code>addRowSet</code>.
|
||||
*
|
||||
* <h3>1.0 Overview</h3>
|
||||
* Disconnected <code>RowSet</code> objects (<code>CachedRowSet</code> objects
|
||||
* and implementations extending the <code>CachedRowSet</code> interface)
|
||||
* do not have a standard way to establish an SQL <code>JOIN</code> between
|
||||
* <code>RowSet</code> objects without the expensive operation of
|
||||
* reconnecting to the data source. The <code>JoinRowSet</code>
|
||||
* interface is specifically designed to address this need.
|
||||
* <P>
|
||||
* Any <code>RowSet</code> object
|
||||
* can be added to a <code>JoinRowSet</code> object to become
|
||||
* part of an SQL <code>JOIN</code> relationship. This means that both connected
|
||||
* and disconnected <code>RowSet</code> objects can be part of a <code>JOIN</code>.
|
||||
* <code>RowSet</code> objects operating in a connected environment
|
||||
* (<code>JdbcRowSet</code> objects) are
|
||||
* encouraged to use the database to which they are already
|
||||
* connected to establish SQL <code>JOIN</code> relationships between
|
||||
* tables directly. However, it is possible for a
|
||||
* <code>JdbcRowSet</code> object to be added to a <code>JoinRowSet</code> object
|
||||
* if necessary.
|
||||
* <P>
|
||||
* Any number of <code>RowSet</code> objects can be added to an
|
||||
* instance of <code>JoinRowSet</code> provided that they
|
||||
* can be related in an SQL <code>JOIN</code>.
|
||||
* By definition, the SQL <code>JOIN</code> statement is used to
|
||||
* combine the data contained in two or more relational database tables based
|
||||
* upon a common attribute. The <code>Joinable</code> interface provides the methods
|
||||
* for establishing a common attribute, which is done by setting a
|
||||
* <i>match column</i>. The match column commonly coincides with
|
||||
* the primary key, but there is
|
||||
* no requirement that the match column be the same as the primary key.
|
||||
* By establishing and then enforcing column matches,
|
||||
* a <code>JoinRowSet</code> object establishes <code>JOIN</code> relationships
|
||||
* between <code>RowSet</code> objects without the assistance of an available
|
||||
* relational database.
|
||||
* <P>
|
||||
* The type of <code>JOIN</code> to be established is determined by setting
|
||||
* one of the <code>JoinRowSet</code> constants using the method
|
||||
* <code>setJoinType</code>. The following SQL <code>JOIN</code> types can be set:
|
||||
* <UL>
|
||||
* <LI><code>CROSS_JOIN</code>
|
||||
* <LI><code>FULL_JOIN</code>
|
||||
* <LI><code>INNER_JOIN</code> - the default if no <code>JOIN</code> type has been set
|
||||
* <LI><code>LEFT_OUTER_JOIN</code>
|
||||
* <LI><code>RIGHT_OUTER_JOIN</code>
|
||||
* </UL>
|
||||
* Note that if no type is set, the <code>JOIN</code> will automatically be an
|
||||
* inner join. The comments for the fields in the
|
||||
* <code>JoinRowSet</code> interface explain these <code>JOIN</code> types, which are
|
||||
* standard SQL <code>JOIN</code> types.
|
||||
*
|
||||
* <h3>2.0 Using a <code>JoinRowSet</code> Object for Creating a <code>JOIN</code></h3>
|
||||
* When a <code>JoinRowSet</code> object is created, it is empty.
|
||||
* The first <code>RowSet</code> object to be added becomes the basis for the
|
||||
* <code>JOIN</code> relationship.
|
||||
* Applications must determine which column in each of the
|
||||
* <code>RowSet</code> objects to be added to the <code>JoinRowSet</code> object
|
||||
* should be the match column. All of the
|
||||
* <code>RowSet</code> objects must contain a match column, and the values in
|
||||
* each match column must be ones that can be compared to values in the other match
|
||||
* columns. The columns do not have to have the same name, though they often do,
|
||||
* and they do not have to store the exact same data type as long as the data types
|
||||
* can be compared.
|
||||
* <P>
|
||||
* A match column can be be set in two ways:
|
||||
* <ul>
|
||||
* <li>By calling the <code>Joinable</code> method <code>setMatchColumn</code><br>
|
||||
* This is the only method that can set the match column before a <code>RowSet</code>
|
||||
* object is added to a <code>JoinRowSet</code> object. The <code>RowSet</code> object
|
||||
* must have implemented the <code>Joinable</code> interface in order to use the method
|
||||
* <code>setMatchColumn</code>. Once the match column value
|
||||
* has been set, this method can be used to reset the match column at any time.
|
||||
* <li>By calling one of the versions of the <code>JoinRowSet</code> method
|
||||
* <code>addRowSet</code> that takes a column name or number (or an array of
|
||||
* column names or numbers)<BR>
|
||||
* Four of the five <code>addRowSet</code> methods take a match column as a parameter.
|
||||
* These four methods set or reset the match column at the time a <code>RowSet</code>
|
||||
* object is being added to a <code>JoinRowSet</code> object.
|
||||
* </ul>
|
||||
* <h3>3.0 Sample Usage</h3>
|
||||
* <p>
|
||||
* The following code fragment adds two <code>CachedRowSet</code>
|
||||
* objects to a <code>JoinRowSet</code> object. Note that in this example,
|
||||
* no SQL <code>JOIN</code> type is set, so the default <code>JOIN</code> type,
|
||||
* which is <i>INNER_JOIN</i>, is established.
|
||||
* <p>
|
||||
* In the following code fragment, the table <code>EMPLOYEES</code>, whose match
|
||||
* column is set to the first column (<code>EMP_ID</code>), is added to the
|
||||
* <code>JoinRowSet</code> object <i>jrs</i>. Then
|
||||
* the table <code>ESSP_BONUS_PLAN</code>, whose match column is likewise
|
||||
* the <code>EMP_ID</code> column, is added. When this second
|
||||
* table is added to <i>jrs</i>, only the rows in
|
||||
* <code>ESSP_BONUS_PLAN</code> whose <code>EMP_ID</code> value matches an
|
||||
* <code>EMP_ID</code> value in the <code>EMPLOYEES</code> table are added.
|
||||
* In this case, everyone in the bonus plan is an employee, so all of the rows
|
||||
* in the table <code>ESSP_BONUS_PLAN</code> are added to the <code>JoinRowSet</code>
|
||||
* object. In this example, both <code>CachedRowSet</code> objects being added
|
||||
* have implemented the <code>Joinable</code> interface and can therefore call
|
||||
* the <code>Joinable</code> method <code>setMatchColumn</code>.
|
||||
* <PRE>
|
||||
* JoinRowSet jrs = new JoinRowSetImpl();
|
||||
*
|
||||
* ResultSet rs1 = stmt.executeQuery("SELECT * FROM EMPLOYEES");
|
||||
* CachedRowSet empl = new CachedRowSetImpl();
|
||||
* empl.populate(rs1);
|
||||
* empl.setMatchColumn(1);
|
||||
* jrs.addRowSet(empl);
|
||||
*
|
||||
* ResultSet rs2 = stmt.executeQuery("SELECT * FROM ESSP_BONUS_PLAN");
|
||||
* CachedRowSet bonus = new CachedRowSetImpl();
|
||||
* bonus.populate(rs2);
|
||||
* bonus.setMatchColumn(1); // EMP_ID is the first column
|
||||
* jrs.addRowSet(bonus);
|
||||
* </PRE>
|
||||
* <P>
|
||||
* At this point, <i>jrs</i> is an inside JOIN of the two <code>RowSet</code> objects
|
||||
* based on their <code>EMP_ID</code> columns. The application can now browse the
|
||||
* combined data as if it were browsing one single <code>RowSet</code> object.
|
||||
* Because <i>jrs</i> is itself a <code>RowSet</code> object, an application can
|
||||
* navigate or modify it using <code>RowSet</code> methods.
|
||||
* <PRE>
|
||||
* jrs.first();
|
||||
* int employeeID = jrs.getInt(1);
|
||||
* String employeeName = jrs.getString(2);
|
||||
* </PRE>
|
||||
* <P>
|
||||
* Note that because the SQL <code>JOIN</code> must be enforced when an application
|
||||
* adds a second or subsequent <code>RowSet</code> object, there
|
||||
* may be an initial degradation in performance while the <code>JOIN</code> is
|
||||
* being performed.
|
||||
* <P>
|
||||
* The following code fragment adds an additional <code>CachedRowSet</code> object.
|
||||
* In this case, the match column (<code>EMP_ID</code>) is set when the
|
||||
* <code>CachedRowSet</code> object is added to the <code>JoinRowSet</code> object.
|
||||
* <PRE>
|
||||
* ResultSet rs3 = stmt.executeQuery("SELECT * FROM 401K_CONTRIB");
|
||||
* CachedRowSet fourO1k = new CachedRowSetImpl();
|
||||
* four01k.populate(rs3);
|
||||
* jrs.addRowSet(four01k, 1);
|
||||
* </PRE>
|
||||
* <P>
|
||||
* The <code>JoinRowSet</code> object <i>jrs</i> now contains values from all three
|
||||
* tables. The data in each row in <i>four01k</i> in which the value for the
|
||||
* <code>EMP_ID</code> column matches a value for the <code>EMP_ID</code> column
|
||||
* in <i>jrs</i> has been added to <i>jrs</i>.
|
||||
*
|
||||
* <h3>4.0 <code>JoinRowSet</code> Methods</h3>
|
||||
* The <code>JoinRowSet</code> interface supplies several methods for adding
|
||||
* <code>RowSet</code> objects and for getting information about the
|
||||
* <code>JoinRowSet</code> object.
|
||||
* <UL>
|
||||
* <LI>Methods for adding one or more <code>RowSet</code> objects<BR>
|
||||
* These methods allow an application to add one <code>RowSet</code> object
|
||||
* at a time or to add multiple <code>RowSet</code> objects at one time. In
|
||||
* either case, the methods may specify the match column for each
|
||||
* <code>RowSet</code> object being added.
|
||||
* <LI>Methods for getting information<BR>
|
||||
* One method retrieves the <code>RowSet</code> objects in the
|
||||
* <code>JoinRowSet</code> object, and another method retrieves the
|
||||
* <code>RowSet</code> names. A third method retrieves either the SQL
|
||||
* <code>WHERE</code> clause used behind the scenes to form the
|
||||
* <code>JOIN</code> or a text description of what the <code>WHERE</code>
|
||||
* clause does.
|
||||
* <LI>Methods related to the type of <code>JOIN</code><BR>
|
||||
* One method sets the <code>JOIN</code> type, and five methods find out whether
|
||||
* the <code>JoinRowSet</code> object supports a given type.
|
||||
* <LI>A method to make a separate copy of the <code>JoinRowSet</code> object<BR>
|
||||
* This method creates a copy that can be persisted to the data source.
|
||||
* </UL>
|
||||
*
|
||||
*/
|
||||
|
||||
public interface JoinRowSet extends WebRowSet {
|
||||
|
||||
/**
|
||||
* Adds the given <code>RowSet</code> object to this <code>JoinRowSet</code>
|
||||
* object. If the <code>RowSet</code> object
|
||||
* is the first to be added to this <code>JoinRowSet</code>
|
||||
* object, it forms the basis of the <code>JOIN</code> relationship to be
|
||||
* established.
|
||||
* <P>
|
||||
* This method should be used only when the given <code>RowSet</code>
|
||||
* object already has a match column that was set with the <code>Joinable</code>
|
||||
* method <code>setMatchColumn</code>.
|
||||
* <p>
|
||||
* Note: A <code>Joinable</code> object is any <code>RowSet</code> object
|
||||
* that has implemented the <code>Joinable</code> interface.
|
||||
*
|
||||
* @param rowset the <code>RowSet</code> object that is to be added to this
|
||||
* <code>JoinRowSet</code> object; it must implement the
|
||||
* <code>Joinable</code> interface and have a match column set
|
||||
* @throws SQLException if (1) an empty rowset is added to the to this
|
||||
* <code>JoinRowSet</code> object, (2) a match column has not been
|
||||
* set for <i>rowset</i>, or (3) <i>rowset</i>
|
||||
* violates the active <code>JOIN</code>
|
||||
* @see Joinable#setMatchColumn
|
||||
*/
|
||||
public void addRowSet(Joinable rowset) throws SQLException;
|
||||
|
||||
/**
|
||||
* Adds the given <code>RowSet</code> object to this <code>JoinRowSet</code>
|
||||
* object and sets the designated column as the match column for
|
||||
* the <code>RowSet</code> object. If the <code>RowSet</code> object
|
||||
* is the first to be added to this <code>JoinRowSet</code>
|
||||
* object, it forms the basis of the <code>JOIN</code> relationship to be
|
||||
* established.
|
||||
* <P>
|
||||
* This method should be used when <i>RowSet</i> does not already have a match
|
||||
* column set.
|
||||
*
|
||||
* @param rowset the <code>RowSet</code> object that is to be added to this
|
||||
* <code>JoinRowSet</code> object; it may implement the
|
||||
* <code>Joinable</code> interface
|
||||
* @param columnIdx an <code>int</code> that identifies the column to become the
|
||||
* match column
|
||||
* @throws SQLException if (1) <i>rowset</i> is an empty rowset or
|
||||
* (2) <i>rowset</i> violates the active <code>JOIN</code>
|
||||
* @see Joinable#unsetMatchColumn
|
||||
*/
|
||||
public void addRowSet(RowSet rowset, int columnIdx) throws SQLException;
|
||||
|
||||
/**
|
||||
* Adds <i>rowset</i> to this <code>JoinRowSet</code> object and
|
||||
* sets the designated column as the match column. If <i>rowset</i>
|
||||
* is the first to be added to this <code>JoinRowSet</code>
|
||||
* object, it forms the basis for the <code>JOIN</code> relationship to be
|
||||
* established.
|
||||
* <P>
|
||||
* This method should be used when the given <code>RowSet</code> object
|
||||
* does not already have a match column.
|
||||
*
|
||||
* @param rowset the <code>RowSet</code> object that is to be added to this
|
||||
* <code>JoinRowSet</code> object; it may implement the
|
||||
* <code>Joinable</code> interface
|
||||
* @param columnName the <code>String</code> object giving the name of the
|
||||
* column to be set as the match column
|
||||
* @throws SQLException if (1) <i>rowset</i> is an empty rowset or
|
||||
* (2) the match column for <i>rowset</i> does not satisfy the
|
||||
* conditions of the <code>JOIN</code>
|
||||
*/
|
||||
public void addRowSet(RowSet rowset,
|
||||
String columnName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Adds one or more <code>RowSet</code> objects contained in the given
|
||||
* array of <code>RowSet</code> objects to this <code>JoinRowSet</code>
|
||||
* object and sets the match column for
|
||||
* each of the <code>RowSet</code> objects to the match columns
|
||||
* in the given array of column indexes. The first element in
|
||||
* <i>columnIdx</i> is set as the match column for the first
|
||||
* <code>RowSet</code> object in <i>rowset</i>, the second element of
|
||||
* <i>columnIdx</i> is set as the match column for the second element
|
||||
* in <i>rowset</i>, and so on.
|
||||
* <P>
|
||||
* The first <code>RowSet</code> object added to this <code>JoinRowSet</code>
|
||||
* object forms the basis for the <code>JOIN</code> relationship.
|
||||
* <P>
|
||||
* This method should be used when the given <code>RowSet</code> object
|
||||
* does not already have a match column.
|
||||
*
|
||||
* @param rowset an array of one or more <code>RowSet</code> objects
|
||||
* to be added to the <code>JOIN</code>; it may implement the
|
||||
* <code>Joinable</code> interface
|
||||
* @param columnIdx an array of <code>int</code> values indicating the index(es)
|
||||
* of the columns to be set as the match columns for the <code>RowSet</code>
|
||||
* objects in <i>rowset</i>
|
||||
* @throws SQLException if (1) an empty rowset is added to this
|
||||
* <code>JoinRowSet</code> object, (2) a match column is not set
|
||||
* for a <code>RowSet</code> object in <i>rowset</i>, or (3)
|
||||
* a <code>RowSet</code> object being added violates the active
|
||||
* <code>JOIN</code>
|
||||
*/
|
||||
public void addRowSet(RowSet[] rowset,
|
||||
int[] columnIdx) throws SQLException;
|
||||
|
||||
/**
|
||||
* Adds one or more <code>RowSet</code> objects contained in the given
|
||||
* array of <code>RowSet</code> objects to this <code>JoinRowSet</code>
|
||||
* object and sets the match column for
|
||||
* each of the <code>RowSet</code> objects to the match columns
|
||||
* in the given array of column names. The first element in
|
||||
* <i>columnName</i> is set as the match column for the first
|
||||
* <code>RowSet</code> object in <i>rowset</i>, the second element of
|
||||
* <i>columnName</i> is set as the match column for the second element
|
||||
* in <i>rowset</i>, and so on.
|
||||
* <P>
|
||||
* The first <code>RowSet</code> object added to this <code>JoinRowSet</code>
|
||||
* object forms the basis for the <code>JOIN</code> relationship.
|
||||
* <P>
|
||||
* This method should be used when the given <code>RowSet</code> object(s)
|
||||
* does not already have a match column.
|
||||
*
|
||||
* @param rowset an array of one or more <code>RowSet</code> objects
|
||||
* to be added to the <code>JOIN</code>; it may implement the
|
||||
* <code>Joinable</code> interface
|
||||
* @param columnName an array of <code>String</code> values indicating the
|
||||
* names of the columns to be set as the match columns for the
|
||||
* <code>RowSet</code> objects in <i>rowset</i>
|
||||
* @throws SQLException if (1) an empty rowset is added to this
|
||||
* <code>JoinRowSet</code> object, (2) a match column is not set
|
||||
* for a <code>RowSet</code> object in <i>rowset</i>, or (3)
|
||||
* a <code>RowSet</code> object being added violates the active
|
||||
* <code>JOIN</code>
|
||||
*/
|
||||
public void addRowSet(RowSet[] rowset,
|
||||
String[] columnName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns a <code>Collection</code> object containing the
|
||||
* <code>RowSet</code> objects that have been added to this
|
||||
* <code>JoinRowSet</code> object.
|
||||
* This should return the 'n' number of RowSet contained
|
||||
* within the <code>JOIN</code> and maintain any updates that have occurred while in
|
||||
* this union.
|
||||
*
|
||||
* @return a <code>Collection</code> object consisting of the
|
||||
* <code>RowSet</code> objects added to this <code>JoinRowSet</code>
|
||||
* object
|
||||
* @throws SQLException if an error occurs generating the
|
||||
* <code>Collection</code> object to be returned
|
||||
*/
|
||||
public Collection<?> getRowSets() throws java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Returns a <code>String</code> array containing the names of the
|
||||
* <code>RowSet</code> objects added to this <code>JoinRowSet</code>
|
||||
* object.
|
||||
*
|
||||
* @return a <code>String</code> array of the names of the
|
||||
* <code>RowSet</code> objects in this <code>JoinRowSet</code>
|
||||
* object
|
||||
* @throws SQLException if an error occurs retrieving the names of
|
||||
* the <code>RowSet</code> objects
|
||||
* @see CachedRowSet#setTableName
|
||||
*/
|
||||
public String[] getRowSetNames() throws java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Creates a new <code>CachedRowSet</code> object containing the
|
||||
* data in this <code>JoinRowSet</code> object, which can be saved
|
||||
* to a data source using the <code>SyncProvider</code> object for
|
||||
* the <code>CachedRowSet</code> object.
|
||||
* <P>
|
||||
* If any updates or modifications have been applied to the JoinRowSet
|
||||
* the CachedRowSet returned by the method will not be able to persist
|
||||
* it's changes back to the originating rows and tables in the
|
||||
* in the datasource. The CachedRowSet instance returned should not
|
||||
* contain modification data and it should clear all properties of
|
||||
* it's originating SQL statement. An application should reset the
|
||||
* SQL statement using the <code>RowSet.setCommand</code> method.
|
||||
* <p>
|
||||
* In order to allow changes to be persisted back to the datasource
|
||||
* to the originating tables, the <code>acceptChanges</code> method
|
||||
* should be used and called on a JoinRowSet object instance. Implementations
|
||||
* can leverage the internal data and update tracking in their
|
||||
* implementations to interact with the SyncProvider to persist any
|
||||
* changes.
|
||||
*
|
||||
* @return a CachedRowSet containing the contents of the JoinRowSet
|
||||
* @throws SQLException if an error occurs assembling the CachedRowSet
|
||||
* object
|
||||
* @see javax.sql.RowSet
|
||||
* @see javax.sql.rowset.CachedRowSet
|
||||
* @see javax.sql.rowset.spi.SyncProvider
|
||||
*/
|
||||
public CachedRowSet toCachedRowSet() throws java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Indicates if CROSS_JOIN is supported by a JoinRowSet
|
||||
* implementation
|
||||
*
|
||||
* @return true if the CROSS_JOIN is supported; false otherwise
|
||||
*/
|
||||
public boolean supportsCrossJoin();
|
||||
|
||||
/**
|
||||
* Indicates if INNER_JOIN is supported by a JoinRowSet
|
||||
* implementation
|
||||
*
|
||||
* @return true is the INNER_JOIN is supported; false otherwise
|
||||
*/
|
||||
public boolean supportsInnerJoin();
|
||||
|
||||
/**
|
||||
* Indicates if LEFT_OUTER_JOIN is supported by a JoinRowSet
|
||||
* implementation
|
||||
*
|
||||
* @return true is the LEFT_OUTER_JOIN is supported; false otherwise
|
||||
*/
|
||||
public boolean supportsLeftOuterJoin();
|
||||
|
||||
/**
|
||||
* Indicates if RIGHT_OUTER_JOIN is supported by a JoinRowSet
|
||||
* implementation
|
||||
*
|
||||
* @return true is the RIGHT_OUTER_JOIN is supported; false otherwise
|
||||
*/
|
||||
public boolean supportsRightOuterJoin();
|
||||
|
||||
/**
|
||||
* Indicates if FULL_JOIN is supported by a JoinRowSet
|
||||
* implementation
|
||||
*
|
||||
* @return true is the FULL_JOIN is supported; false otherwise
|
||||
*/
|
||||
public boolean supportsFullJoin();
|
||||
|
||||
/**
|
||||
* Allow the application to adjust the type of <code>JOIN</code> imposed
|
||||
* on tables contained within the JoinRowSet object instance.
|
||||
* Implementations should throw a SQLException if they do
|
||||
* not support a given <code>JOIN</code> type.
|
||||
*
|
||||
* @param joinType the standard JoinRowSet.XXX static field definition
|
||||
* of a SQL <code>JOIN</code> to re-configure a JoinRowSet instance on
|
||||
* the fly.
|
||||
* @throws SQLException if an unsupported <code>JOIN</code> type is set
|
||||
* @see #getJoinType
|
||||
*/
|
||||
public void setJoinType(int joinType) throws SQLException;
|
||||
|
||||
/**
|
||||
* Return a SQL-like description of the WHERE clause being used
|
||||
* in a JoinRowSet object. An implementation can describe
|
||||
* the WHERE clause of the SQL <code>JOIN</code> by supplying a SQL
|
||||
* strings description of <code>JOIN</code> or provide a textual
|
||||
* description to assist applications using a <code>JoinRowSet</code>
|
||||
*
|
||||
* @return whereClause a textual or SQL description of the logical
|
||||
* WHERE clause used in the JoinRowSet instance
|
||||
* @throws SQLException if an error occurs in generating a representation
|
||||
* of the WHERE clause.
|
||||
*/
|
||||
public String getWhereClause() throws SQLException;
|
||||
|
||||
/**
|
||||
* Returns a <code>int</code> describing the set SQL <code>JOIN</code> type
|
||||
* governing this JoinRowSet instance. The returned type will be one of
|
||||
* standard JoinRowSet types: <code>CROSS_JOIN</code>, <code>INNER_JOIN</code>,
|
||||
* <code>LEFT_OUTER_JOIN</code>, <code>RIGHT_OUTER_JOIN</code> or
|
||||
* <code>FULL_JOIN</code>.
|
||||
*
|
||||
* @return joinType one of the standard JoinRowSet static field
|
||||
* definitions of a SQL <code>JOIN</code>. <code>JoinRowSet.INNER_JOIN</code>
|
||||
* is returned as the default <code>JOIN</code> type is no type has been
|
||||
* explicitly set.
|
||||
* @throws SQLException if an error occurs determining the SQL <code>JOIN</code>
|
||||
* type supported by the JoinRowSet instance.
|
||||
* @see #setJoinType
|
||||
*/
|
||||
public int getJoinType() throws SQLException;
|
||||
|
||||
/**
|
||||
* An ANSI-style <code>JOIN</code> providing a cross product of two tables
|
||||
*/
|
||||
public static int CROSS_JOIN = 0;
|
||||
|
||||
/**
|
||||
* An ANSI-style <code>JOIN</code> providing a inner join between two tables. Any
|
||||
* unmatched rows in either table of the join should be discarded.
|
||||
*/
|
||||
public static int INNER_JOIN = 1;
|
||||
|
||||
/**
|
||||
* An ANSI-style <code>JOIN</code> providing a left outer join between two
|
||||
* tables. In SQL, this is described where all records should be
|
||||
* returned from the left side of the JOIN statement.
|
||||
*/
|
||||
public static int LEFT_OUTER_JOIN = 2;
|
||||
|
||||
/**
|
||||
* An ANSI-style <code>JOIN</code> providing a right outer join between
|
||||
* two tables. In SQL, this is described where all records from the
|
||||
* table on the right side of the JOIN statement even if the table
|
||||
* on the left has no matching record.
|
||||
*/
|
||||
public static int RIGHT_OUTER_JOIN = 3;
|
||||
|
||||
/**
|
||||
* An ANSI-style <code>JOIN</code> providing a a full JOIN. Specifies that all
|
||||
* rows from either table be returned regardless of matching
|
||||
* records on the other table.
|
||||
*/
|
||||
public static int FULL_JOIN = 4;
|
||||
|
||||
|
||||
}
|
291
jdkSrc/jdk8/javax/sql/rowset/Joinable.java
Normal file
291
jdkSrc/jdk8/javax/sql/rowset/Joinable.java
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* <h3>1.0 Background</h3>
|
||||
* The <code>Joinable</code> interface provides the methods for getting and
|
||||
* setting a match column, which is the basis for forming the SQL <code>JOIN</code>
|
||||
* formed by adding <code>RowSet</code> objects to a <code>JoinRowSet</code>
|
||||
* object.
|
||||
* <P>
|
||||
* Any standard <code>RowSet</code> implementation <b>may</b> implement
|
||||
* the <code>Joinable</code> interface in order to be
|
||||
* added to a <code>JoinRowSet</code> object. Implementing this interface gives
|
||||
* a <code>RowSet</code> object the ability to use <code>Joinable</code> methods,
|
||||
* which set, retrieve, and get information about match columns. An
|
||||
* application may add a
|
||||
* <code>RowSet</code> object that has not implemented the <code>Joinable</code>
|
||||
* interface to a <code>JoinRowSet</code> object, but to do so it must use one
|
||||
* of the <code>JoinRowSet.addRowSet</code> methods that takes both a
|
||||
* <code>RowSet</code> object and a match column or an array of <code>RowSet</code>
|
||||
* objects and an array of match columns.
|
||||
* <P>
|
||||
* To get access to the methods in the <code>Joinable</code> interface, a
|
||||
* <code>RowSet</code> object implements at least one of the
|
||||
* five standard <code>RowSet</code> interfaces and also implements the
|
||||
* <code>Joinable</code> interface. In addition, most <code>RowSet</code>
|
||||
* objects extend the <code>BaseRowSet</code> class. For example:
|
||||
* <pre>
|
||||
* class MyRowSetImpl extends BaseRowSet implements CachedRowSet, Joinable {
|
||||
* :
|
||||
* :
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <h3>2.0 Usage Guidelines</h3>
|
||||
* <P>
|
||||
* The methods in the <code>Joinable</code> interface allow a <code>RowSet</code> object
|
||||
* to set a match column, retrieve a match column, or unset a match column, which is
|
||||
* the column upon which an SQL <code>JOIN</code> can be based.
|
||||
* An instance of a class that implements these methods can be added to a
|
||||
* <code>JoinRowSet</code> object to allow an SQL <code>JOIN</code> relationship to
|
||||
* be established.
|
||||
*
|
||||
* <pre>
|
||||
* CachedRowSet crs = new MyRowSetImpl();
|
||||
* crs.populate((ResultSet)rs);
|
||||
* (Joinable)crs.setMatchColumnIndex(1);
|
||||
*
|
||||
* JoinRowSet jrs = new JoinRowSetImpl();
|
||||
* jrs.addRowSet(crs);
|
||||
* </pre>
|
||||
* In the previous example, <i>crs</i> is a <code>CachedRowSet</code> object that
|
||||
* has implemented the <code>Joinable</code> interface. In the following example,
|
||||
* <i>crs2</i> has not, so it must supply the match column as an argument to the
|
||||
* <code>addRowSet</code> method. This example assumes that column 1 is the match
|
||||
* column.
|
||||
* <PRE>
|
||||
* CachedRowSet crs2 = new MyRowSetImpl();
|
||||
* crs2.populate((ResultSet)rs);
|
||||
*
|
||||
* JoinRowSet jrs2 = new JoinRowSetImpl();
|
||||
* jrs2.addRowSet(crs2, 1);
|
||||
* </PRE>
|
||||
* <p>
|
||||
* The <code>JoinRowSet</code> interface makes it possible to get data from one or
|
||||
* more <code>RowSet</code> objects consolidated into one table without having to incur
|
||||
* the expense of creating a connection to a database. It is therefore ideally suited
|
||||
* for use by disconnected <code>RowSet</code> objects. Nevertheless, any
|
||||
* <code>RowSet</code> object <b>may</b> implement this interface
|
||||
* regardless of whether it is connected or disconnected. Note that a
|
||||
* <code>JdbcRowSet</code> object, being always connected to its data source, can
|
||||
* become part of an SQL <code>JOIN</code> directly without having to become part
|
||||
* of a <code>JoinRowSet</code> object.
|
||||
*
|
||||
* <h3>3.0 Managing Multiple Match Columns</h3>
|
||||
* The index array passed into the <code>setMatchColumn</code> methods indicates
|
||||
* how many match columns are being set (the length of the array) in addition to
|
||||
* which columns will be used for the match. For example:
|
||||
* <pre>
|
||||
* int[] i = {1, 2, 4, 7}; // indicates four match columns, with column
|
||||
* // indexes 1, 2, 4, 7 participating in the JOIN.
|
||||
* Joinable.setMatchColumn(i);
|
||||
* </pre>
|
||||
* Subsequent match columns may be added as follows to a different <code>Joinable</code>
|
||||
* object (a <code>RowSet</code> object that has implemented the <code>Joinable</code>
|
||||
* interface).
|
||||
* <pre>
|
||||
* int[] w = {3, 2, 5, 3};
|
||||
* Joinable2.setMatchColumn(w);
|
||||
* </pre>
|
||||
* When an application adds two or more <code>RowSet</code> objects to a
|
||||
* <code>JoinRowSet</code> object, the order of the indexes in the array is
|
||||
* particularly important. Each index of
|
||||
* the array maps directly to the corresponding index of the previously added
|
||||
* <code>RowSet</code> object. If overlap or underlap occurs, the match column
|
||||
* data is maintained in the event an additional <code>Joinable</code> RowSet is
|
||||
* added and needs to relate to the match column data. Therefore, applications
|
||||
* can set multiple match columns in any order, but
|
||||
* this order has a direct effect on the outcome of the <code>SQL</code> JOIN.
|
||||
* <p>
|
||||
* This assertion applies in exactly the same manner when column names are used
|
||||
* rather than column indexes to indicate match columns.
|
||||
*
|
||||
* @see JoinRowSet
|
||||
* @author Jonathan Bruce
|
||||
*/
|
||||
public interface Joinable {
|
||||
|
||||
/**
|
||||
* Sets the designated column as the match column for this <code>RowSet</code>
|
||||
* object. A <code>JoinRowSet</code> object can now add this <code>RowSet</code>
|
||||
* object based on the match column.
|
||||
* <p>
|
||||
* Sub-interfaces such as the <code>CachedRowSet</code>™
|
||||
* interface define the method <code>CachedRowSet.setKeyColumns</code>, which allows
|
||||
* primary key semantics to be enforced on specific columns.
|
||||
* Implementations of the <code>setMatchColumn(int columnIdx)</code> method
|
||||
* should ensure that the constraints on the key columns are maintained when
|
||||
* a <code>CachedRowSet</code> object sets a primary key column as a match column.
|
||||
*
|
||||
* @param columnIdx an <code>int</code> identifying the index of the column to be
|
||||
* set as the match column
|
||||
* @throws SQLException if an invalid column index is set
|
||||
* @see #setMatchColumn(int[])
|
||||
* @see #unsetMatchColumn(int)
|
||||
*
|
||||
*/
|
||||
public void setMatchColumn(int columnIdx) throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets the designated columns as the match column for this <code>RowSet</code>
|
||||
* object. A <code>JoinRowSet</code> object can now add this <code>RowSet</code>
|
||||
* object based on the match column.
|
||||
*
|
||||
* @param columnIdxes an array of <code>int</code> identifying the indexes of the
|
||||
* columns to be set as the match columns
|
||||
* @throws SQLException if an invalid column index is set
|
||||
* @see #setMatchColumn(int[])
|
||||
* @see #unsetMatchColumn(int[])
|
||||
*/
|
||||
public void setMatchColumn(int[] columnIdxes) throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets the designated column as the match column for this <code>RowSet</code>
|
||||
* object. A <code>JoinRowSet</code> object can now add this <code>RowSet</code>
|
||||
* object based on the match column.
|
||||
* <p>
|
||||
* Subinterfaces such as the <code>CachedRowSet</code> interface define
|
||||
* the method <code>CachedRowSet.setKeyColumns</code>, which allows
|
||||
* primary key semantics to be enforced on specific columns.
|
||||
* Implementations of the <code>setMatchColumn(String columnIdx)</code> method
|
||||
* should ensure that the constraints on the key columns are maintained when
|
||||
* a <code>CachedRowSet</code> object sets a primary key column as a match column.
|
||||
*
|
||||
* @param columnName a <code>String</code> object giving the name of the column
|
||||
* to be set as the match column
|
||||
* @throws SQLException if an invalid column name is set, the column name
|
||||
* is a null, or the column name is an empty string
|
||||
* @see #unsetMatchColumn
|
||||
* @see #setMatchColumn(int[])
|
||||
*/
|
||||
public void setMatchColumn(String columnName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets the designated columns as the match column for this <code>RowSet</code>
|
||||
* object. A <code>JoinRowSet</code> object can now add this <code>RowSet</code>
|
||||
* object based on the match column.
|
||||
*
|
||||
* @param columnNames an array of <code>String</code> objects giving the names
|
||||
* of the column to be set as the match columns
|
||||
* @throws SQLException if an invalid column name is set, the column name
|
||||
* is a null, or the column name is an empty string
|
||||
* @see #unsetMatchColumn
|
||||
* @see #setMatchColumn(int[])
|
||||
*/
|
||||
public void setMatchColumn(String[] columnNames) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the indexes of the match columns that were set for this
|
||||
* <code>RowSet</code> object with the method
|
||||
* <code>setMatchColumn(int[] columnIdxes)</code>.
|
||||
*
|
||||
* @return an <code>int</code> array identifying the indexes of the columns
|
||||
* that were set as the match columns for this <code>RowSet</code> object
|
||||
* @throws SQLException if no match column has been set
|
||||
* @see #setMatchColumn
|
||||
* @see #unsetMatchColumn
|
||||
*/
|
||||
public int[] getMatchColumnIndexes() throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the names of the match columns that were set for this
|
||||
* <code>RowSet</code> object with the method
|
||||
* <code>setMatchColumn(String [] columnNames)</code>.
|
||||
*
|
||||
* @return an array of <code>String</code> objects giving the names of the columns
|
||||
* set as the match columns for this <code>RowSet</code> object
|
||||
* @throws SQLException if no match column has been set
|
||||
* @see #setMatchColumn
|
||||
* @see #unsetMatchColumn
|
||||
*
|
||||
*/
|
||||
public String[] getMatchColumnNames() throws SQLException;
|
||||
|
||||
/**
|
||||
* Unsets the designated column as the match column for this <code>RowSet</code>
|
||||
* object.
|
||||
* <P>
|
||||
* <code>RowSet</code> objects that implement the <code>Joinable</code> interface
|
||||
* must ensure that a key-like constraint continues to be enforced until the
|
||||
* method <code>CachedRowSet.unsetKeyColumns</code> has been called on the
|
||||
* designated column.
|
||||
*
|
||||
* @param columnIdx an <code>int</code> that identifies the index of the column
|
||||
* that is to be unset as a match column
|
||||
* @throws SQLException if an invalid column index is designated or if
|
||||
* the designated column was not previously set as a match
|
||||
* column
|
||||
* @see #setMatchColumn
|
||||
*/
|
||||
public void unsetMatchColumn(int columnIdx) throws SQLException;
|
||||
|
||||
/**
|
||||
* Unsets the designated columns as the match column for this <code>RowSet</code>
|
||||
* object.
|
||||
*
|
||||
* @param columnIdxes an array of <code>int</code> that identifies the indexes
|
||||
* of the columns that are to be unset as match columns
|
||||
* @throws SQLException if an invalid column index is designated or if
|
||||
* the designated column was not previously set as a match
|
||||
* column
|
||||
* @see #setMatchColumn
|
||||
*/
|
||||
public void unsetMatchColumn(int[] columnIdxes) throws SQLException;
|
||||
|
||||
/**
|
||||
* Unsets the designated column as the match column for this <code>RowSet</code>
|
||||
* object.
|
||||
* <P>
|
||||
* <code>RowSet</code> objects that implement the <code>Joinable</code> interface
|
||||
* must ensure that a key-like constraint continues to be enforced until the
|
||||
* method <code>CachedRowSet.unsetKeyColumns</code> has been called on the
|
||||
* designated column.
|
||||
*
|
||||
* @param columnName a <code>String</code> object giving the name of the column
|
||||
* that is to be unset as a match column
|
||||
* @throws SQLException if an invalid column name is designated or
|
||||
* the designated column was not previously set as a match
|
||||
* column
|
||||
* @see #setMatchColumn
|
||||
*/
|
||||
public void unsetMatchColumn(String columnName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Unsets the designated columns as the match columns for this <code>RowSet</code>
|
||||
* object.
|
||||
*
|
||||
* @param columnName an array of <code>String</code> objects giving the names of
|
||||
* the columns that are to be unset as the match columns
|
||||
* @throws SQLException if an invalid column name is designated or the
|
||||
* designated column was not previously set as a match column
|
||||
* @see #setMatchColumn
|
||||
*/
|
||||
public void unsetMatchColumn(String[] columnName) throws SQLException;
|
||||
}
|
162
jdkSrc/jdk8/javax/sql/rowset/Predicate.java
Normal file
162
jdkSrc/jdk8/javax/sql/rowset/Predicate.java
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import javax.sql.*;
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* The standard interface that provides the framework for all
|
||||
* <code>FilteredRowSet</code> objects to describe their filters.
|
||||
*
|
||||
* <h3>1.0 Background</h3>
|
||||
* The <code>Predicate</code> interface is a standard interface that
|
||||
* applications can implement to define the filter they wish to apply to a
|
||||
* a <code>FilteredRowSet</code> object. A <code>FilteredRowSet</code>
|
||||
* object consumes implementations of this interface and enforces the
|
||||
* constraints defined in the implementation of the method <code>evaluate</code>.
|
||||
* A <code>FilteredRowSet</code> object enforces the filter constraints in a
|
||||
* bi-directional manner: It outputs only rows that are within
|
||||
* the constraints of the filter; and conversely, it inserts, modifies, or updates
|
||||
* only rows that are within the constraints of the filter.
|
||||
*
|
||||
* <h3>2.0 Implementation Guidelines</h3>
|
||||
* In order to supply a predicate for the <code>FilteredRowSet</code>.
|
||||
* this interface must be implemented. At this time, the JDBC RowSet
|
||||
* Implementations (JSR-114) does not specify any standard filters definitions.
|
||||
* By specifying a standard means and mechanism for a range of filters to be
|
||||
* defined and deployed with both the reference and vendor implementations
|
||||
* of the <code>FilteredRowSet</code> interface, this allows for a flexible
|
||||
* and application motivated implementations of <code>Predicate</code> to emerge.
|
||||
* <p>
|
||||
* A sample implementation would look something like this:
|
||||
* <pre>{@code
|
||||
* public class Range implements Predicate {
|
||||
*
|
||||
* private int[] lo;
|
||||
* private int[] hi;
|
||||
* private int[] idx;
|
||||
*
|
||||
* public Range(int[] lo, int[] hi, int[] idx) {
|
||||
* this.lo = lo;
|
||||
* this.hi = hi;
|
||||
* this.idx = idx;
|
||||
* }
|
||||
*
|
||||
* public boolean evaluate(RowSet rs) {
|
||||
*
|
||||
* // Check the present row determine if it lies
|
||||
* // within the filtering criteria.
|
||||
*
|
||||
* for (int i = 0; i < idx.length; i++) {
|
||||
* int value;
|
||||
* try {
|
||||
* value = (Integer) rs.getObject(idx[i]);
|
||||
* } catch (SQLException ex) {
|
||||
* Logger.getLogger(Range.class.getName()).log(Level.SEVERE, null, ex);
|
||||
* return false;
|
||||
* }
|
||||
*
|
||||
* if (value < lo[i] && value > hi[i]) {
|
||||
* // outside of filter constraints
|
||||
* return false;
|
||||
* }
|
||||
* }
|
||||
* // Within filter constraints
|
||||
* return true;
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* <P>
|
||||
* The example above implements a simple range predicate. Note, that
|
||||
* implementations should but are not required to provide <code>String</code>
|
||||
* and integer index based constructors to provide for JDBC RowSet Implementation
|
||||
* applications that use both column identification conventions.
|
||||
*
|
||||
* @author Jonathan Bruce, Amit Handa
|
||||
*
|
||||
*/
|
||||
|
||||
// <h3>3.0 FilteredRowSet Internals</h3>
|
||||
// internalNext, Frist, Last. Discuss guidelines on how to approach this
|
||||
// and cite examples in reference implementations.
|
||||
public interface Predicate {
|
||||
/**
|
||||
* This method is typically called a <code>FilteredRowSet</code> object
|
||||
* internal methods (not public) that control the <code>RowSet</code> object's
|
||||
* cursor moving from row to the next. In addition, if this internal method
|
||||
* moves the cursor onto a row that has been deleted, the internal method will
|
||||
* continue to ove the cursor until a valid row is found.
|
||||
* @param rs The {@code RowSet} to be evaluated
|
||||
* @return <code>true</code> if there are more rows in the filter;
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean evaluate(RowSet rs);
|
||||
|
||||
|
||||
/**
|
||||
* This method is called by a <code>FilteredRowSet</code> object
|
||||
* to check whether the value lies between the filtering criterion (or criteria
|
||||
* if multiple constraints exist) set using the <code>setFilter()</code> method.
|
||||
* <P>
|
||||
* The <code>FilteredRowSet</code> object will use this method internally
|
||||
* while inserting new rows to a <code>FilteredRowSet</code> instance.
|
||||
*
|
||||
* @param value An <code>Object</code> value which needs to be checked,
|
||||
* whether it can be part of this <code>FilterRowSet</code> object.
|
||||
* @param column a <code>int</code> object that must match the
|
||||
* SQL index of a column in this <code>RowSet</code> object. This must
|
||||
* have been passed to <code>Predicate</code> as one of the columns
|
||||
* for filtering while initializing a <code>Predicate</code>
|
||||
* @return <code>true</code> if row value lies within the filter;
|
||||
* <code>false</code> otherwise
|
||||
* @throws SQLException if the column is not part of filtering criteria
|
||||
*/
|
||||
public boolean evaluate(Object value, int column) throws SQLException;
|
||||
|
||||
/**
|
||||
* This method is called by the <code>FilteredRowSet</code> object
|
||||
* to check whether the value lies between the filtering criteria set
|
||||
* using the setFilter method.
|
||||
* <P>
|
||||
* The <code>FilteredRowSet</code> object will use this method internally
|
||||
* while inserting new rows to a <code>FilteredRowSet</code> instance.
|
||||
*
|
||||
* @param value An <code>Object</code> value which needs to be checked,
|
||||
* whether it can be part of this <code>FilterRowSet</code>.
|
||||
*
|
||||
* @param columnName a <code>String</code> object that must match the
|
||||
* SQL name of a column in this <code>RowSet</code>, ignoring case. This must
|
||||
* have been passed to <code>Predicate</code> as one of the columns for filtering
|
||||
* while initializing a <code>Predicate</code>
|
||||
*
|
||||
* @return <code>true</code> if value lies within the filter; <code>false</code> otherwise
|
||||
*
|
||||
* @throws SQLException if the column is not part of filtering criteria
|
||||
*/
|
||||
public boolean evaluate(Object value, String columnName) throws SQLException;
|
||||
|
||||
}
|
99
jdkSrc/jdk8/javax/sql/rowset/RowSetFactory.java
Normal file
99
jdkSrc/jdk8/javax/sql/rowset/RowSetFactory.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* An interface that defines the implementation of a factory that is used
|
||||
* to obtain different types of {@code RowSet} implementations.
|
||||
*
|
||||
* @author Lance Andersen
|
||||
* @since 1.7
|
||||
*/
|
||||
public interface RowSetFactory{
|
||||
|
||||
/**
|
||||
* <p>Creates a new instance of a CachedRowSet.</p>
|
||||
*
|
||||
* @return A new instance of a CachedRowSet.
|
||||
*
|
||||
* @throws SQLException if a CachedRowSet cannot
|
||||
* be created.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public CachedRowSet createCachedRowSet() throws SQLException;
|
||||
|
||||
/**
|
||||
* <p>Creates a new instance of a FilteredRowSet.</p>
|
||||
*
|
||||
* @return A new instance of a FilteredRowSet.
|
||||
*
|
||||
* @throws SQLException if a FilteredRowSet cannot
|
||||
* be created.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public FilteredRowSet createFilteredRowSet() throws SQLException;
|
||||
|
||||
/**
|
||||
* <p>Creates a new instance of a JdbcRowSet.</p>
|
||||
*
|
||||
* @return A new instance of a JdbcRowSet.
|
||||
*
|
||||
* @throws SQLException if a JdbcRowSet cannot
|
||||
* be created.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public JdbcRowSet createJdbcRowSet() throws SQLException;
|
||||
|
||||
/**
|
||||
* <p>Creates a new instance of a JoinRowSet.</p>
|
||||
*
|
||||
* @return A new instance of a JoinRowSet.
|
||||
*
|
||||
* @throws SQLException if a JoinRowSet cannot
|
||||
* be created.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public JoinRowSet createJoinRowSet() throws SQLException;
|
||||
|
||||
/**
|
||||
* <p>Creates a new instance of a WebRowSet.</p>
|
||||
*
|
||||
* @return A new instance of a WebRowSet.
|
||||
*
|
||||
* @throws SQLException if a WebRowSet cannot
|
||||
* be created.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public WebRowSet createWebRowSet() throws SQLException;
|
||||
|
||||
}
|
1101
jdkSrc/jdk8/javax/sql/rowset/RowSetMetaDataImpl.java
Normal file
1101
jdkSrc/jdk8/javax/sql/rowset/RowSetMetaDataImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
323
jdkSrc/jdk8/javax/sql/rowset/RowSetProvider.java
Normal file
323
jdkSrc/jdk8/javax/sql/rowset/RowSetProvider.java
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.sql.SQLException;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.ServiceLoader;
|
||||
import javax.sql.rowset.spi.SyncFactoryException;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* A factory API that enables applications to obtain a
|
||||
* {@code RowSetFactory} implementation that can be used to create different
|
||||
* types of {@code RowSet} implementations.
|
||||
* <p>
|
||||
* Example:
|
||||
* </p>
|
||||
* <pre>
|
||||
* RowSetFactory aFactory = RowSetProvider.newFactory();
|
||||
* CachedRowSet crs = aFactory.createCachedRowSet();
|
||||
* ...
|
||||
* RowSetFactory rsf = RowSetProvider.newFactory("com.sun.rowset.RowSetFactoryImpl", null);
|
||||
* WebRowSet wrs = rsf.createWebRowSet();
|
||||
* </pre>
|
||||
*<p>
|
||||
* Tracing of this class may be enabled by setting the System property
|
||||
* {@code javax.sql.rowset.RowSetFactory.debug} to any value but {@code false}.
|
||||
* </p>
|
||||
*
|
||||
* @author Lance Andersen
|
||||
* @since 1.7
|
||||
*/
|
||||
public class RowSetProvider {
|
||||
|
||||
private static final String ROWSET_DEBUG_PROPERTY = "javax.sql.rowset.RowSetProvider.debug";
|
||||
private static final String ROWSET_FACTORY_IMPL = "com.sun.rowset.RowSetFactoryImpl";
|
||||
private static final String ROWSET_FACTORY_NAME = "javax.sql.rowset.RowSetFactory";
|
||||
/**
|
||||
* Internal debug flag.
|
||||
*/
|
||||
private static boolean debug = true;
|
||||
|
||||
|
||||
static {
|
||||
// Check to see if the debug property is set
|
||||
String val = getSystemProperty(ROWSET_DEBUG_PROPERTY);
|
||||
// Allow simply setting the prop to turn on debug
|
||||
debug = val != null && !"false".equals(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* RowSetProvider constructor
|
||||
*/
|
||||
protected RowSetProvider () {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new instance of a <code>RowSetFactory</code>
|
||||
* implementation. This method uses the following
|
||||
* look up order to determine
|
||||
* the <code>RowSetFactory</code> implementation class to load:</p>
|
||||
* <ul>
|
||||
* <li>
|
||||
* The System property {@code javax.sql.rowset.RowSetFactory}. For example:
|
||||
* <ul>
|
||||
* <li>
|
||||
* -Djavax.sql.rowset.RowSetFactory=com.sun.rowset.RowSetFactoryImpl
|
||||
* </li>
|
||||
* </ul>
|
||||
* <li>
|
||||
* The {@link ServiceLoader} API. The {@code ServiceLoader} API will look
|
||||
* for a class name in the file
|
||||
* {@code META-INF/services/javax.sql.rowset.RowSetFactory}
|
||||
* in jars available to the runtime. For example, to have the the RowSetFactory
|
||||
* implementation {@code com.sun.rowset.RowSetFactoryImpl } loaded, the
|
||||
* entry in {@code META-INF/services/javax.sql.rowset.RowSetFactory} would be:
|
||||
* <ul>
|
||||
* <li>
|
||||
* {@code com.sun.rowset.RowSetFactoryImpl }
|
||||
* </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>
|
||||
* Platform default <code>RowSetFactory</code> instance.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>Once an application has obtained a reference to a {@code RowSetFactory},
|
||||
* it can use the factory to obtain RowSet instances.</p>
|
||||
*
|
||||
* @return New instance of a <code>RowSetFactory</code>
|
||||
*
|
||||
* @throws SQLException if the default factory class cannot be loaded,
|
||||
* instantiated. The cause will be set to actual Exception
|
||||
*
|
||||
* @see ServiceLoader
|
||||
* @since 1.7
|
||||
*/
|
||||
public static RowSetFactory newFactory()
|
||||
throws SQLException {
|
||||
// Use the system property first
|
||||
RowSetFactory factory = null;
|
||||
String factoryClassName = null;
|
||||
try {
|
||||
trace("Checking for Rowset System Property...");
|
||||
factoryClassName = getSystemProperty(ROWSET_FACTORY_NAME);
|
||||
if (factoryClassName != null) {
|
||||
trace("Found system property, value=" + factoryClassName);
|
||||
factory = (RowSetFactory) ReflectUtil.newInstance(getFactoryClass(factoryClassName, null, true));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new SQLException( "RowSetFactory: " + factoryClassName +
|
||||
" could not be instantiated: ", e);
|
||||
}
|
||||
|
||||
// Check to see if we found the RowSetFactory via a System property
|
||||
if (factory == null) {
|
||||
// If the RowSetFactory is not found via a System Property, now
|
||||
// look it up via the ServiceLoader API and if not found, use the
|
||||
// Java SE default.
|
||||
factory = loadViaServiceLoader();
|
||||
factory =
|
||||
factory == null ? newFactory(ROWSET_FACTORY_IMPL, null) : factory;
|
||||
}
|
||||
return (factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new instance of a <code>RowSetFactory</code> from the
|
||||
* specified factory class name.
|
||||
* This function is useful when there are multiple providers in the classpath.
|
||||
* It gives more control to the application as it can specify which provider
|
||||
* should be loaded.</p>
|
||||
*
|
||||
* <p>Once an application has obtained a reference to a <code>RowSetFactory</code>
|
||||
* it can use the factory to obtain RowSet instances.</p>
|
||||
*
|
||||
* @param factoryClassName fully qualified factory class name that
|
||||
* provides an implementation of <code>javax.sql.rowset.RowSetFactory</code>.
|
||||
*
|
||||
* @param cl <code>ClassLoader</code> used to load the factory
|
||||
* class. If <code>null</code> current <code>Thread</code>'s context
|
||||
* classLoader is used to load the factory class.
|
||||
*
|
||||
* @return New instance of a <code>RowSetFactory</code>
|
||||
*
|
||||
* @throws SQLException if <code>factoryClassName</code> is
|
||||
* <code>null</code>, or the factory class cannot be loaded, instantiated.
|
||||
*
|
||||
* @see #newFactory()
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static RowSetFactory newFactory(String factoryClassName, ClassLoader cl)
|
||||
throws SQLException {
|
||||
|
||||
trace("***In newInstance()");
|
||||
|
||||
if(factoryClassName == null) {
|
||||
throw new SQLException("Error: factoryClassName cannot be null");
|
||||
}
|
||||
try {
|
||||
ReflectUtil.checkPackageAccess(factoryClassName);
|
||||
} catch (java.security.AccessControlException e) {
|
||||
throw new SQLException("Access Exception",e);
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> providerClass = getFactoryClass(factoryClassName, cl, false);
|
||||
RowSetFactory instance = (RowSetFactory) providerClass.newInstance();
|
||||
if (debug) {
|
||||
trace("Created new instance of " + providerClass +
|
||||
" using ClassLoader: " + cl);
|
||||
}
|
||||
return instance;
|
||||
} catch (ClassNotFoundException x) {
|
||||
throw new SQLException(
|
||||
"Provider " + factoryClassName + " not found", x);
|
||||
} catch (Exception x) {
|
||||
throw new SQLException(
|
||||
"Provider " + factoryClassName + " could not be instantiated: " + x,
|
||||
x);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the class loader to be used.
|
||||
* @return The ClassLoader to use.
|
||||
*
|
||||
*/
|
||||
static private ClassLoader getContextClassLoader() throws SecurityException {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
|
||||
public ClassLoader run() {
|
||||
ClassLoader cl = null;
|
||||
|
||||
cl = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
if (cl == null) {
|
||||
cl = ClassLoader.getSystemClassLoader();
|
||||
}
|
||||
|
||||
return cl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to load a class using the class loader supplied. If that fails
|
||||
* and fall back is enabled, the current (i.e. bootstrap) class loader is
|
||||
* tried.
|
||||
*
|
||||
* If the class loader supplied is <code>null</code>, first try using the
|
||||
* context class loader followed by the current class loader.
|
||||
* @return The class which was loaded
|
||||
*/
|
||||
static private Class<?> getFactoryClass(String factoryClassName, ClassLoader cl,
|
||||
boolean doFallback) throws ClassNotFoundException {
|
||||
try {
|
||||
if (cl == null) {
|
||||
cl = getContextClassLoader();
|
||||
if (cl == null) {
|
||||
throw new ClassNotFoundException();
|
||||
} else {
|
||||
return cl.loadClass(factoryClassName);
|
||||
}
|
||||
} else {
|
||||
return cl.loadClass(factoryClassName);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (doFallback) {
|
||||
// Use current class loader
|
||||
return Class.forName(factoryClassName, true, RowSetFactory.class.getClassLoader());
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the ServiceLoader mechanism to load the default RowSetFactory
|
||||
* @return default RowSetFactory Implementation
|
||||
*/
|
||||
static private RowSetFactory loadViaServiceLoader() throws SQLException {
|
||||
RowSetFactory theFactory = null;
|
||||
try {
|
||||
trace("***in loadViaServiceLoader():");
|
||||
for (RowSetFactory factory : ServiceLoader.load(javax.sql.rowset.RowSetFactory.class)) {
|
||||
trace(" Loading done by the java.util.ServiceLoader :" + factory.getClass().getName());
|
||||
theFactory = factory;
|
||||
break;
|
||||
}
|
||||
} catch (ServiceConfigurationError e) {
|
||||
throw new SQLException(
|
||||
"RowSetFactory: Error locating RowSetFactory using Service "
|
||||
+ "Loader API: " + e, e);
|
||||
}
|
||||
return theFactory;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested System Property. If a {@code SecurityException}
|
||||
* occurs, just return NULL
|
||||
* @param propName - System property to retrieve
|
||||
* @return The System property value or NULL if the property does not exist
|
||||
* or a {@code SecurityException} occurs.
|
||||
*/
|
||||
static private String getSystemProperty(final String propName) {
|
||||
String property = null;
|
||||
try {
|
||||
property = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
|
||||
public String run() {
|
||||
return System.getProperty(propName);
|
||||
}
|
||||
}, null, new PropertyPermission(propName, "read"));
|
||||
} catch (SecurityException se) {
|
||||
trace("error getting " + propName + ": "+ se);
|
||||
if (debug) {
|
||||
se.printStackTrace();
|
||||
}
|
||||
}
|
||||
return property;
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug routine which will output tracing if the System Property
|
||||
* -Djavax.sql.rowset.RowSetFactory.debug is set
|
||||
* @param msg - The debug message to display
|
||||
*/
|
||||
private static void trace(String msg) {
|
||||
if (debug) {
|
||||
System.err.println("###RowSets: " + msg);
|
||||
}
|
||||
}
|
||||
}
|
151
jdkSrc/jdk8/javax/sql/rowset/RowSetWarning.java
Normal file
151
jdkSrc/jdk8/javax/sql/rowset/RowSetWarning.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* An extension of <code>SQLException</code> that provides information
|
||||
* about database warnings set on <code>RowSet</code> objects.
|
||||
* Warnings are silently chained to the object whose method call
|
||||
* caused it to be reported.
|
||||
* This class complements the <code>SQLWarning</code> class.
|
||||
* <P>
|
||||
* Rowset warnings may be retrieved from <code>JdbcRowSet</code>,
|
||||
* <code>CachedRowSet</code>™,
|
||||
* <code>WebRowSet</code>, <code>FilteredRowSet</code>, or <code>JoinRowSet</code>
|
||||
* implementations. To retrieve the first warning reported on any
|
||||
* <code>RowSet</code>
|
||||
* implementation, use the method <code>getRowSetWarnings</code> defined
|
||||
* in the <code>JdbcRowSet</code> interface or the <code>CachedRowSet</code>
|
||||
* interface. To retrieve a warning chained to the first warning, use the
|
||||
* <code>RowSetWarning</code> method
|
||||
* <code>getNextWarning</code>. To retrieve subsequent warnings, call
|
||||
* <code>getNextWarning</code> on each <code>RowSetWarning</code> object that is
|
||||
* returned.
|
||||
* <P>
|
||||
* The inherited methods <code>getMessage</code>, <code>getSQLState</code>,
|
||||
* and <code>getErrorCode</code> retrieve information contained in a
|
||||
* <code>RowSetWarning</code> object.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class RowSetWarning extends SQLException {
|
||||
|
||||
/**
|
||||
* Constructs a <code>RowSetWarning</code> object
|
||||
* with the given value for the reason; SQLState defaults to null,
|
||||
* and vendorCode defaults to 0.
|
||||
*
|
||||
* @param reason a <code>String</code> object giving a description
|
||||
* of the warning; if the <code>String</code> is <code>null</code>,
|
||||
* this constructor behaves like the default (zero parameter)
|
||||
* <code>RowSetWarning</code> constructor
|
||||
*/
|
||||
public RowSetWarning(String reason) {
|
||||
super(reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a default <code>RowSetWarning</code> object. The reason
|
||||
* defaults to <code>null</code>, SQLState defaults to null and vendorCode
|
||||
* defaults to 0.
|
||||
*/
|
||||
public RowSetWarning() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>RowSetWarning</code> object initialized with the
|
||||
* given values for the reason and SQLState. The vendor code defaults to 0.
|
||||
*
|
||||
* If the <code>reason</code> or <code>SQLState</code> parameters are <code>null</code>,
|
||||
* this constructor behaves like the default (zero parameter)
|
||||
* <code>RowSetWarning</code> constructor.
|
||||
*
|
||||
* @param reason a <code>String</code> giving a description of the
|
||||
* warning;
|
||||
* @param SQLState an XOPEN code identifying the warning; if a non standard
|
||||
* XOPEN <i>SQLState</i> is supplied, no exception is thrown.
|
||||
*/
|
||||
public RowSetWarning(java.lang.String reason, java.lang.String SQLState) {
|
||||
super(reason, SQLState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a fully specified <code>RowSetWarning</code> object initialized
|
||||
* with the given values for the reason, SQLState and vendorCode.
|
||||
*
|
||||
* If the <code>reason</code>, or the <code>SQLState</code>
|
||||
* parameters are <code>null</code>, this constructor behaves like the default
|
||||
* (zero parameter) <code>RowSetWarning</code> constructor.
|
||||
*
|
||||
* @param reason a <code>String</code> giving a description of the
|
||||
* warning;
|
||||
* @param SQLState an XOPEN code identifying the warning; if a non standard
|
||||
* XOPEN <i>SQLState</i> is supplied, no exception is thrown.
|
||||
* @param vendorCode a database vendor-specific warning code
|
||||
*/
|
||||
public RowSetWarning(java.lang.String reason, java.lang.String SQLState, int vendorCode) {
|
||||
super(reason, SQLState, vendorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the warning chained to this <code>RowSetWarning</code>
|
||||
* object.
|
||||
*
|
||||
* @return the <code>RowSetWarning</code> object chained to this one; if no
|
||||
* <code>RowSetWarning</code> object is chained to this one,
|
||||
* <code>null</code> is returned (default value)
|
||||
* @see #setNextWarning
|
||||
*/
|
||||
public RowSetWarning getNextWarning() {
|
||||
SQLException warning = getNextException();
|
||||
if ( warning == null || warning instanceof RowSetWarning) {
|
||||
return (RowSetWarning)warning;
|
||||
} else {
|
||||
// The chained value isn't a RowSetWarning.
|
||||
// This is a programming error by whoever added it to
|
||||
// the RowSetWarning chain. We throw a Java "Error".
|
||||
throw new Error("RowSetWarning chain holds value that is not a RowSetWarning: ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets <i>warning</i> as the next warning, that is, the warning chained
|
||||
* to this <code>RowSetWarning</code> object.
|
||||
*
|
||||
* @param warning the <code>RowSetWarning</code> object to be set as the
|
||||
* next warning; if the <code>RowSetWarning</code> is null, this
|
||||
* represents the finish point in the warning chain
|
||||
* @see #getNextWarning
|
||||
*/
|
||||
public void setNextWarning(RowSetWarning warning) {
|
||||
setNextException(warning);
|
||||
}
|
||||
|
||||
static final long serialVersionUID = 6678332766434564774L;
|
||||
}
|
505
jdkSrc/jdk8/javax/sql/rowset/WebRowSet.java
Normal file
505
jdkSrc/jdk8/javax/sql/rowset/WebRowSet.java
Normal file
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import javax.naming.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import org.xml.sax.*;
|
||||
|
||||
/**
|
||||
* The standard interface that all implementations of a {@code WebRowSet}
|
||||
* must implement.
|
||||
*
|
||||
* <h3>1.0 Overview</h3>
|
||||
* The {@code WebRowSetImpl} provides the standard
|
||||
* reference implementation, which may be extended if required.
|
||||
* <P>
|
||||
* The standard WebRowSet XML Schema definition is available at the following
|
||||
* URI:
|
||||
* <ul>
|
||||
* <li>
|
||||
* <a href="http://java.sun.com/xml/ns/jdbc/webrowset.xsd">http://java.sun.com/xml/ns/jdbc/webrowset.xsd</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
* It describes the standard XML document format required when describing a
|
||||
* {@code RowSet} object in XML and must be used be all standard implementations
|
||||
* of the {@code WebRowSet} interface to ensure interoperability. In addition,
|
||||
* the {@code WebRowSet} schema uses specific SQL/XML Schema annotations,
|
||||
* thus ensuring greater cross
|
||||
* platform inter-operability. This is an effort currently under way at the ISO
|
||||
* organization. The SQL/XML definition is available at the following URI:
|
||||
* <ul>
|
||||
* <li>
|
||||
* <a href="http://standards.iso.org/iso/9075/2002/12/sqlxml">http://standards.iso.org/iso/9075/2002/12/sqlxml</a>
|
||||
* </li>
|
||||
* </ul>
|
||||
* The schema definition describes the internal data of a {@code RowSet} object
|
||||
* in three distinct areas:
|
||||
* <UL>
|
||||
* <li>properties - These properties describe the standard synchronization
|
||||
* provider properties in addition to the more general {@code RowSet} properties.
|
||||
* </li>
|
||||
* <li>metadata - This describes the metadata associated with the tabular structure governed by a
|
||||
* {@code WebRowSet} object. The metadata described is closely aligned with the
|
||||
* metadata accessible in the underlying {@code java.sql.ResultSet} interface.
|
||||
* </li>
|
||||
* <li>data - This describes the original data (the state of data since the
|
||||
* last population
|
||||
* or last synchronization of the {@code WebRowSet} object) and the current
|
||||
* data. By keeping track of the delta between the original data and the current data,
|
||||
* a {@code WebRowSet} maintains the ability to synchronize changes
|
||||
* in its data back to the originating data source.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>2.0 WebRowSet States</h3>
|
||||
* The following sections demonstrates how a {@code WebRowSet} implementation
|
||||
* should use the XML Schema to describe update, insert, and delete operations
|
||||
* and to describe the state of a {@code WebRowSet} object in XML.
|
||||
*
|
||||
* <h4>2.1 State 1 - Outputting a {@code WebRowSet} Object to XML</h4>
|
||||
* In this example, a {@code WebRowSet} object is created and populated with a simple 2 column,
|
||||
* 5 row table from a data source. Having the 5 rows in a {@code WebRowSet} object
|
||||
* makes it possible to describe them in XML. The
|
||||
* metadata describing the various standard JavaBeans properties as defined
|
||||
* in the RowSet interface plus the standard properties defined in
|
||||
* the {@code CachedRowSet}™ interface
|
||||
* provide key details that describe WebRowSet
|
||||
* properties. Outputting the WebRowSet object to XML using the standard
|
||||
* {@code writeXml} methods describes the internal properties as follows:
|
||||
* <PRE>
|
||||
* {@code
|
||||
* <properties>
|
||||
* <command>select co1, col2 from test_table</command>
|
||||
* <concurrency>1</concurrency>
|
||||
* <datasource/>
|
||||
* <escape-processing>true</escape-processing>
|
||||
* <fetch-direction>0</fetch-direction>
|
||||
* <fetch-size>0</fetch-size>
|
||||
* <isolation-level>1</isolation-level>
|
||||
* <key-columns/>
|
||||
* <map/>
|
||||
* <max-field-size>0</max-field-size>
|
||||
* <max-rows>0</max-rows>
|
||||
* <query-timeout>0</query-timeout>
|
||||
* <read-only>false</read-only>
|
||||
* <rowset-type>TRANSACTION_READ_UNCOMMITED</rowset-type>
|
||||
* <show-deleted>false</show-deleted>
|
||||
* <table-name/>
|
||||
* <url>jdbc:thin:oracle</url>
|
||||
* <sync-provider>
|
||||
* <sync-provider-name>.com.rowset.provider.RIOptimisticProvider</sync-provider-name>
|
||||
* <sync-provider-vendor>Oracle Corporation</sync-provider-vendor>
|
||||
* <sync-provider-version>1.0</sync-provider-name>
|
||||
* <sync-provider-grade>LOW</sync-provider-grade>
|
||||
* <data-source-lock>NONE</data-source-lock>
|
||||
* </sync-provider>
|
||||
* </properties>
|
||||
* } </PRE>
|
||||
* The meta-data describing the make up of the WebRowSet is described
|
||||
* in XML as detailed below. Note both columns are described between the
|
||||
* {@code column-definition} tags.
|
||||
* <PRE>
|
||||
* {@code
|
||||
* <metadata>
|
||||
* <column-count>2</column-count>
|
||||
* <column-definition>
|
||||
* <column-index>1</column-index>
|
||||
* <auto-increment>false</auto-increment>
|
||||
* <case-sensitive>true</case-sensitive>
|
||||
* <currency>false</currency>
|
||||
* <nullable>1</nullable>
|
||||
* <signed>false</signed>
|
||||
* <searchable>true</searchable>
|
||||
* <column-display-size>10</column-display-size>
|
||||
* <column-label>COL1</column-label>
|
||||
* <column-name>COL1</column-name>
|
||||
* <schema-name/>
|
||||
* <column-precision>10</column-precision>
|
||||
* <column-scale>0</column-scale>
|
||||
* <table-name/>
|
||||
* <catalog-name/>
|
||||
* <column-type>1</column-type>
|
||||
* <column-type-name>CHAR</column-type-name>
|
||||
* </column-definition>
|
||||
* <column-definition>
|
||||
* <column-index>2</column-index>
|
||||
* <auto-increment>false</auto-increment>
|
||||
* <case-sensitive>false</case-sensitive>
|
||||
* <currency>false</currency>
|
||||
* <nullable>1</nullable>
|
||||
* <signed>true</signed>
|
||||
* <searchable>true</searchable>
|
||||
* <column-display-size>39</column-display-size>
|
||||
* <column-label>COL2</column-label>
|
||||
* <column-name>COL2</column-name>
|
||||
* <schema-name/>
|
||||
* <column-precision>38</column-precision>
|
||||
* <column-scale>0</column-scale>
|
||||
* <table-name/>
|
||||
* <catalog-name/>
|
||||
* <column-type>3</column-type>
|
||||
* <column-type-name>NUMBER</column-type-name>
|
||||
* </column-definition>
|
||||
* </metadata>
|
||||
* }</PRE>
|
||||
* Having detailed how the properties and metadata are described, the following details
|
||||
* how the contents of a {@code WebRowSet} object is described in XML. Note, that
|
||||
* this describes a {@code WebRowSet} object that has not undergone any
|
||||
* modifications since its instantiation.
|
||||
* A {@code currentRow} tag is mapped to each row of the table structure that the
|
||||
* {@code WebRowSet} object provides. A {@code columnValue} tag may contain
|
||||
* either the {@code stringData} or {@code binaryData} tag, according to
|
||||
* the SQL type that
|
||||
* the XML value is mapping back to. The {@code binaryData} tag contains data in the
|
||||
* Base64 encoding and is typically used for {@code BLOB} and {@code CLOB} type data.
|
||||
* <PRE>
|
||||
* {@code
|
||||
* <data>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* firstrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 1
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* secondrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 2
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* thirdrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 3
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* fourthrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 4
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* </data>
|
||||
* }</PRE>
|
||||
* <h4>2.2 State 2 - Deleting a Row</h4>
|
||||
* Deleting a row in a {@code WebRowSet} object involves simply moving to the row
|
||||
* to be deleted and then calling the method {@code deleteRow}, as in any other
|
||||
* {@code RowSet} object. The following
|
||||
* two lines of code, in which <i>wrs</i> is a {@code WebRowSet} object, delete
|
||||
* the third row.
|
||||
* <PRE>
|
||||
* wrs.absolute(3);
|
||||
* wrs.deleteRow();
|
||||
* </PRE>
|
||||
* The XML description shows the third row is marked as a {@code deleteRow},
|
||||
* which eliminates the third row in the {@code WebRowSet} object.
|
||||
* <PRE>
|
||||
* {@code
|
||||
* <data>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* firstrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 1
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* secondrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 2
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <deleteRow>
|
||||
* <columnValue>
|
||||
* thirdrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 3
|
||||
* </columnValue>
|
||||
* </deleteRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* fourthrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 4
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* </data>
|
||||
*} </PRE>
|
||||
* <h4>2.3 State 3 - Inserting a Row</h4>
|
||||
* A {@code WebRowSet} object can insert a new row by moving to the insert row,
|
||||
* calling the appropriate updater methods for each column in the row, and then
|
||||
* calling the method {@code insertRow}.
|
||||
* <PRE>
|
||||
* {@code
|
||||
* wrs.moveToInsertRow();
|
||||
* wrs.updateString(1, "fifththrow");
|
||||
* wrs.updateString(2, "5");
|
||||
* wrs.insertRow();
|
||||
* }</PRE>
|
||||
* The following code fragment changes the second column value in the row just inserted.
|
||||
* Note that this code applies when new rows are inserted right after the current row,
|
||||
* which is why the method {@code next} moves the cursor to the correct row.
|
||||
* Calling the method {@code acceptChanges} writes the change to the data source.
|
||||
*
|
||||
* <PRE>
|
||||
* {@code wrs.moveToCurrentRow();
|
||||
* wrs.next();
|
||||
* wrs.updateString(2, "V");
|
||||
* wrs.acceptChanges();
|
||||
* }</PRE>
|
||||
* Describing this in XML demonstrates where the Java code inserts a new row and then
|
||||
* performs an update on the newly inserted row on an individual field.
|
||||
* <PRE>
|
||||
* {@code
|
||||
* <data>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* firstrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 1
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* secondrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 2
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* newthirdrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* III
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <insertRow>
|
||||
* <columnValue>
|
||||
* fifthrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 5
|
||||
* </columnValue>
|
||||
* <updateValue>
|
||||
* V
|
||||
* </updateValue>
|
||||
* </insertRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* fourthrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 4
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* </date>
|
||||
*} </PRE>
|
||||
* <h4>2.4 State 4 - Modifying a Row</h4>
|
||||
* Modifying a row produces specific XML that records both the new value and the
|
||||
* value that was replaced. The value that was replaced becomes the original value,
|
||||
* and the new value becomes the current value. The following
|
||||
* code moves the cursor to a specific row, performs some modifications, and updates
|
||||
* the row when complete.
|
||||
* <PRE>
|
||||
*{@code
|
||||
* wrs.absolute(5);
|
||||
* wrs.updateString(1, "new4thRow");
|
||||
* wrs.updateString(2, "IV");
|
||||
* wrs.updateRow();
|
||||
* }</PRE>
|
||||
* In XML, this is described by the {@code modifyRow} tag. Both the original and new
|
||||
* values are contained within the tag for original row tracking purposes.
|
||||
* <PRE>
|
||||
* {@code
|
||||
* <data>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* firstrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 1
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* secondrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 2
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* newthirdrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* III
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <currentRow>
|
||||
* <columnValue>
|
||||
* fifthrow
|
||||
* </columnValue>
|
||||
* <columnValue>
|
||||
* 5
|
||||
* </columnValue>
|
||||
* </currentRow>
|
||||
* <modifyRow>
|
||||
* <columnValue>
|
||||
* fourthrow
|
||||
* </columnValue>
|
||||
* <updateValue>
|
||||
* new4thRow
|
||||
* </updateValue>
|
||||
* <columnValue>
|
||||
* 4
|
||||
* </columnValue>
|
||||
* <updateValue>
|
||||
* IV
|
||||
* </updateValue>
|
||||
* </modifyRow>
|
||||
* </data>
|
||||
* }</PRE>
|
||||
*
|
||||
* @see javax.sql.rowset.JdbcRowSet
|
||||
* @see javax.sql.rowset.CachedRowSet
|
||||
* @see javax.sql.rowset.FilteredRowSet
|
||||
* @see javax.sql.rowset.JoinRowSet
|
||||
*/
|
||||
|
||||
public interface WebRowSet extends CachedRowSet {
|
||||
|
||||
/**
|
||||
* Reads a {@code WebRowSet} object in its XML format from the given
|
||||
* {@code Reader} object.
|
||||
*
|
||||
* @param reader the {@code java.io.Reader} stream from which this
|
||||
* {@code WebRowSet} object will be populated
|
||||
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public void readXml(java.io.Reader reader) throws SQLException;
|
||||
|
||||
/**
|
||||
* Reads a stream based XML input to populate this {@code WebRowSet}
|
||||
* object.
|
||||
*
|
||||
* @param iStream the {@code java.io.InputStream} from which this
|
||||
* {@code WebRowSet} object will be populated
|
||||
* @throws SQLException if a data source access error occurs
|
||||
* @throws IOException if an IO exception occurs
|
||||
*/
|
||||
public void readXml(java.io.InputStream iStream) throws SQLException, IOException;
|
||||
|
||||
/**
|
||||
* Populates this {@code WebRowSet} object with
|
||||
* the contents of the given {@code ResultSet} object and writes its
|
||||
* data, properties, and metadata
|
||||
* to the given {@code Writer} object in XML format.
|
||||
* <p>
|
||||
* NOTE: The {@code WebRowSet} cursor may be moved to write out the
|
||||
* contents to the XML data source. If implemented in this way, the cursor <b>must</b>
|
||||
* be returned to its position just prior to the {@code writeXml()} call.
|
||||
*
|
||||
* @param rs the {@code ResultSet} object with which to populate this
|
||||
* {@code WebRowSet} object
|
||||
* @param writer the {@code java.io.Writer} object to write to.
|
||||
* @throws SQLException if an error occurs writing out the rowset
|
||||
* contents in XML format
|
||||
*/
|
||||
public void writeXml(ResultSet rs, java.io.Writer writer) throws SQLException;
|
||||
|
||||
/**
|
||||
* Populates this {@code WebRowSet} object with
|
||||
* the contents of the given {@code ResultSet} object and writes its
|
||||
* data, properties, and metadata
|
||||
* to the given {@code OutputStream} object in XML format.
|
||||
* <p>
|
||||
* NOTE: The {@code WebRowSet} cursor may be moved to write out the
|
||||
* contents to the XML data source. If implemented in this way, the cursor <b>must</b>
|
||||
* be returned to its position just prior to the {@code writeXml()} call.
|
||||
*
|
||||
* @param rs the {@code ResultSet} object with which to populate this
|
||||
* {@code WebRowSet} object
|
||||
* @param oStream the {@code java.io.OutputStream} to write to
|
||||
* @throws SQLException if a data source access error occurs
|
||||
* @throws IOException if a IO exception occurs
|
||||
*/
|
||||
public void writeXml(ResultSet rs, java.io.OutputStream oStream) throws SQLException, IOException;
|
||||
|
||||
/**
|
||||
* Writes the data, properties, and metadata for this {@code WebRowSet} object
|
||||
* to the given {@code Writer} object in XML format.
|
||||
*
|
||||
* @param writer the {@code java.io.Writer} stream to write to
|
||||
* @throws SQLException if an error occurs writing out the rowset
|
||||
* contents to XML
|
||||
*/
|
||||
public void writeXml(java.io.Writer writer) throws SQLException;
|
||||
|
||||
/**
|
||||
* Writes the data, properties, and metadata for this {@code WebRowSet} object
|
||||
* to the given {@code OutputStream} object in XML format.
|
||||
*
|
||||
* @param oStream the {@code java.io.OutputStream} stream to write to
|
||||
* @throws SQLException if a data source access error occurs
|
||||
* @throws IOException if a IO exception occurs
|
||||
*/
|
||||
public void writeXml(java.io.OutputStream oStream) throws SQLException, IOException;
|
||||
|
||||
/**
|
||||
* The public identifier for the XML Schema definition that defines the XML
|
||||
* tags and their valid values for a {@code WebRowSet} implementation.
|
||||
*/
|
||||
public static String PUBLIC_XML_SCHEMA =
|
||||
"--//Oracle Corporation//XSD Schema//EN";
|
||||
|
||||
/**
|
||||
* The URL for the XML Schema definition file that defines the XML tags and
|
||||
* their valid values for a {@code WebRowSet} implementation.
|
||||
*/
|
||||
public static String SCHEMA_SYSTEM_ID = "http://java.sun.com/xml/ns/jdbc/webrowset.xsd";
|
||||
}
|
668
jdkSrc/jdk8/javax/sql/rowset/serial/SQLInputImpl.java
Normal file
668
jdkSrc/jdk8/javax/sql/rowset/serial/SQLInputImpl.java
Normal file
@@ -0,0 +1,668 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* An input stream used for custom mapping user-defined types (UDTs).
|
||||
* An <code>SQLInputImpl</code> object is an input stream that contains a
|
||||
* stream of values that are the attributes of a UDT.
|
||||
* <p>
|
||||
* This class is used by the driver behind the scenes when the method
|
||||
* <code>getObject</code> is called on an SQL structured or distinct type
|
||||
* that has a custom mapping; a programmer never invokes
|
||||
* <code>SQLInputImpl</code> methods directly. They are provided here as a
|
||||
* convenience for those who write <code>RowSet</code> implementations.
|
||||
* <P>
|
||||
* The <code>SQLInputImpl</code> class provides a set of
|
||||
* reader methods analogous to the <code>ResultSet</code> getter
|
||||
* methods. These methods make it possible to read the values in an
|
||||
* <code>SQLInputImpl</code> object.
|
||||
* <P>
|
||||
* The method <code>wasNull</code> is used to determine whether the
|
||||
* the last value read was SQL <code>NULL</code>.
|
||||
* <P>When the method <code>getObject</code> is called with an
|
||||
* object of a class implementing the interface <code>SQLData</code>,
|
||||
* the JDBC driver calls the method <code>SQLData.getSQLType</code>
|
||||
* to determine the SQL type of the UDT being custom mapped. The driver
|
||||
* creates an instance of <code>SQLInputImpl</code>, populating it with the
|
||||
* attributes of the UDT. The driver then passes the input
|
||||
* stream to the method <code>SQLData.readSQL</code>, which in turn
|
||||
* calls the <code>SQLInputImpl</code> reader methods
|
||||
* to read the attributes from the input stream.
|
||||
* @since 1.5
|
||||
* @see java.sql.SQLData
|
||||
*/
|
||||
public class SQLInputImpl implements SQLInput {
|
||||
|
||||
/**
|
||||
* <code>true</code> if the last value returned was <code>SQL NULL</code>;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
private boolean lastValueWasNull;
|
||||
|
||||
/**
|
||||
* The current index into the array of SQL structured type attributes
|
||||
* that will be read from this <code>SQLInputImpl</code> object and
|
||||
* mapped to the fields of a class in the Java programming language.
|
||||
*/
|
||||
private int idx;
|
||||
|
||||
/**
|
||||
* The array of attributes to be read from this stream. The order
|
||||
* of the attributes is the same as the order in which they were
|
||||
* listed in the SQL definition of the UDT.
|
||||
*/
|
||||
private Object attrib[];
|
||||
|
||||
/**
|
||||
* The type map to use when the method <code>readObject</code>
|
||||
* is invoked. This is a <code>java.util.Map</code> object in which
|
||||
* there may be zero or more entries. Each entry consists of the
|
||||
* fully qualified name of a UDT (the value to be mapped) and the
|
||||
* <code>Class</code> object for a class that implements
|
||||
* <code>SQLData</code> (the Java class that defines how the UDT
|
||||
* will be mapped).
|
||||
*/
|
||||
private Map<String,Class<?>> map;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an <code>SQLInputImpl</code> object initialized with the
|
||||
* given array of attributes and the given type map. If any of the
|
||||
* attributes is a UDT whose name is in an entry in the type map,
|
||||
* the attribute will be mapped according to the corresponding
|
||||
* <code>SQLData</code> implementation.
|
||||
*
|
||||
* @param attributes an array of <code>Object</code> instances in which
|
||||
* each element is an attribute of a UDT. The order of the
|
||||
* attributes in the array is the same order in which
|
||||
* the attributes were defined in the UDT definition.
|
||||
* @param map a <code>java.util.Map</code> object containing zero or more
|
||||
* entries, with each entry consisting of 1) a <code>String</code>
|
||||
* giving the fully
|
||||
* qualified name of the UDT and 2) the <code>Class</code> object
|
||||
* for the <code>SQLData</code> implementation that defines how
|
||||
* the UDT is to be mapped
|
||||
* @throws SQLException if the <code>attributes</code> or the <code>map</code>
|
||||
* is a <code>null</code> value
|
||||
*/
|
||||
|
||||
public SQLInputImpl(Object[] attributes, Map<String,Class<?>> map)
|
||||
throws SQLException
|
||||
{
|
||||
if ((attributes == null) || (map == null)) {
|
||||
throw new SQLException("Cannot instantiate a SQLInputImpl " +
|
||||
"object with null parameters");
|
||||
}
|
||||
// assign our local reference to the attribute stream
|
||||
attrib = Arrays.copyOf(attributes, attributes.length);
|
||||
// init the index point before the head of the stream
|
||||
idx = -1;
|
||||
// set the map
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as an <code>Object</code> in the Java programming language.
|
||||
*
|
||||
* @return the next value in the input stream
|
||||
* as an <code>Object</code> in the Java programming language
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream
|
||||
*/
|
||||
private Object getNextAttribute() throws SQLException {
|
||||
if (++idx >= attrib.length) {
|
||||
throw new SQLException("SQLInputImpl exception: Invalid read " +
|
||||
"position");
|
||||
} else {
|
||||
lastValueWasNull = attrib[idx] == null;
|
||||
return attrib[idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//================================================================
|
||||
// Methods for reading attributes from the stream of SQL data.
|
||||
// These methods correspond to the column-accessor methods of
|
||||
// java.sql.ResultSet.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>String</code> in the Java programming language.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code>
|
||||
* implementation.
|
||||
* <p>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream.
|
||||
*/
|
||||
public String readString() throws SQLException {
|
||||
return (String)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>boolean</code> in the Java programming language.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code>
|
||||
* implementation.
|
||||
* <p>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream.
|
||||
*/
|
||||
public boolean readBoolean() throws SQLException {
|
||||
Boolean attrib = (Boolean)getNextAttribute();
|
||||
return (attrib == null) ? false : attrib.booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>byte</code> in the Java programming language.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code>
|
||||
* implementation.
|
||||
* <p>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no further values in the stream
|
||||
*/
|
||||
public byte readByte() throws SQLException {
|
||||
Byte attrib = (Byte)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.byteValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>short</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public short readShort() throws SQLException {
|
||||
Short attrib = (Short)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.shortValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as an <code>int</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public int readInt() throws SQLException {
|
||||
Integer attrib = (Integer)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>long</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public long readLong() throws SQLException {
|
||||
Long attrib = (Long)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>float</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public float readFloat() throws SQLException {
|
||||
Float attrib = (Float)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.floatValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>double</code> in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public double readDouble() throws SQLException {
|
||||
Double attrib = (Double)getNextAttribute();
|
||||
return (attrib == null) ? 0 : attrib.doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a <code>java.math.BigDecimal</code>.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public java.math.BigDecimal readBigDecimal() throws SQLException {
|
||||
return (java.math.BigDecimal)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as an array of bytes.
|
||||
* <p>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public byte[] readBytes() throws SQLException {
|
||||
return (byte[])getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> as
|
||||
* a <code>java.sql.Date</code> object.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type; this responsibility is delegated
|
||||
* to the UDT mapping as defined by a <code>SQLData</code> implementation.
|
||||
* <P>
|
||||
* @return the next attribute in this <code>SQLInputImpl</code> object;
|
||||
* if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position or if there are no more values in the stream
|
||||
*/
|
||||
public java.sql.Date readDate() throws SQLException {
|
||||
return (java.sql.Date)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>java.sql.Time</code> object.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.sql.Time readTime() throws SQLException {
|
||||
return (java.sql.Time)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object as
|
||||
* a <code>java.sql.Timestamp</code> object.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.sql.Timestamp readTimestamp() throws SQLException {
|
||||
return (java.sql.Timestamp)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a stream of Unicode characters.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.io.Reader readCharacterStream() throws SQLException {
|
||||
return (java.io.Reader)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a stream of ASCII characters.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>,
|
||||
* return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.io.InputStream readAsciiStream() throws SQLException {
|
||||
return (java.io.InputStream)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next attribute in this <code>SQLInputImpl</code> object
|
||||
* as a stream of uninterpreted bytes.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return the attribute; if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.io.InputStream readBinaryStream() throws SQLException {
|
||||
return (java.io.InputStream)getNextAttribute();
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// Methods for reading items of SQL user-defined types from the stream.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Retrieves the value at the head of this <code>SQLInputImpl</code>
|
||||
* object as an <code>Object</code> in the Java programming language. The
|
||||
* actual type of the object returned is determined by the default
|
||||
* mapping of SQL types to types in the Java programming language unless
|
||||
* there is a custom mapping, in which case the type of the object
|
||||
* returned is determined by this stream's type map.
|
||||
* <P>
|
||||
* The JDBC technology-enabled driver registers a type map with the stream
|
||||
* before passing the stream to the application.
|
||||
* <P>
|
||||
* When the datum at the head of the stream is an SQL <code>NULL</code>,
|
||||
* this method returns <code>null</code>. If the datum is an SQL
|
||||
* structured or distinct type with a custom mapping, this method
|
||||
* determines the SQL type of the datum at the head of the stream,
|
||||
* constructs an object of the appropriate class, and calls the method
|
||||
* <code>SQLData.readSQL</code> on that object. The <code>readSQL</code>
|
||||
* method then calls the appropriate <code>SQLInputImpl.readXXX</code>
|
||||
* methods to retrieve the attribute values from the stream.
|
||||
*
|
||||
* @return the value at the head of the stream as an <code>Object</code>
|
||||
* in the Java programming language; <code>null</code> if
|
||||
* the value is SQL <code>NULL</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Object readObject() throws SQLException {
|
||||
Object attrib = getNextAttribute();
|
||||
if (attrib instanceof Struct) {
|
||||
Struct s = (Struct)attrib;
|
||||
// look up the class in the map
|
||||
Class<?> c = map.get(s.getSQLTypeName());
|
||||
if (c != null) {
|
||||
// create new instance of the class
|
||||
SQLData obj = null;
|
||||
try {
|
||||
obj = (SQLData)ReflectUtil.newInstance(c);
|
||||
} catch (Exception ex) {
|
||||
throw new SQLException("Unable to Instantiate: ", ex);
|
||||
}
|
||||
// get the attributes from the struct
|
||||
Object attribs[] = s.getAttributes(map);
|
||||
// create the SQLInput "stream"
|
||||
SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);
|
||||
// read the values...
|
||||
obj.readSQL(sqlInput, s.getSQLTypeName());
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
return attrib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value at the head of this <code>SQLInputImpl</code> object
|
||||
* as a <code>Ref</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>Ref</code> object representing the SQL
|
||||
* <code>REF</code> value at the head of the stream; if the value
|
||||
* is <code>SQL NULL</code> return <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Ref readRef() throws SQLException {
|
||||
return (Ref)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>BLOB</code> value at the head of this
|
||||
* <code>SQLInputImpl</code> object as a <code>Blob</code> object
|
||||
* in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return a <code>Blob</code> object representing the SQL
|
||||
* <code>BLOB</code> value at the head of this stream;
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Blob readBlob() throws SQLException {
|
||||
return (Blob)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>CLOB</code> value at the head of this
|
||||
* <code>SQLInputImpl</code> object as a <code>Clob</code> object
|
||||
* in the Java programming language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return a <code>Clob</code> object representing the SQL
|
||||
* <code>CLOB</code> value at the head of the stream;
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public Clob readClob() throws SQLException {
|
||||
return (Clob)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>ARRAY</code> value from the stream and
|
||||
* returns it as an <code>Array</code> object in the Java programming
|
||||
* language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return an <code>Array</code> object representing the SQL
|
||||
* <code>ARRAY</code> value at the head of the stream; *
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
|
||||
*/
|
||||
public Array readArray() throws SQLException {
|
||||
return (Array)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascertains whether the last value read from this
|
||||
* <code>SQLInputImpl</code> object was <code>null</code>.
|
||||
*
|
||||
* @return <code>true</code> if the SQL value read most recently was
|
||||
* <code>null</code>; otherwise, <code>false</code>; by default it
|
||||
* will return false
|
||||
* @throws SQLException if an error occurs determining the last value
|
||||
* read was a <code>null</code> value or not;
|
||||
*/
|
||||
public boolean wasNull() throws SQLException {
|
||||
return lastValueWasNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>DATALINK</code> value from the stream and
|
||||
* returns it as an <code>URL</code> object in the Java programming
|
||||
* language.
|
||||
* <P>
|
||||
* This method does not perform type-safe checking to determine if the
|
||||
* returned type is the expected type as this responsibility is delegated
|
||||
* to the UDT mapping as implemented by a <code>SQLData</code>
|
||||
* implementation.
|
||||
*
|
||||
* @return an <code>URL</code> object representing the SQL
|
||||
* <code>DATALINK</code> value at the head of the stream; *
|
||||
* if the value is <code>SQL NULL</code>, return
|
||||
* <code>null</code>
|
||||
* @throws SQLException if the read position is located at an invalid
|
||||
* position; or if there are no further values in the stream.
|
||||
*/
|
||||
public java.net.URL readURL() throws SQLException {
|
||||
return (java.net.URL)getNextAttribute();
|
||||
}
|
||||
|
||||
//---------------------------- JDBC 4.0 -------------------------
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>NCLOB</code> value from the stream and returns it as a
|
||||
* <code>Clob</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>NClob</code> object representing data of the SQL <code>NCLOB</code> value
|
||||
* at the head of the stream; <code>null</code> if the value read is
|
||||
* SQL <code>NULL</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public NClob readNClob() throws SQLException {
|
||||
return (NClob)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next attribute in the stream and returns it as a <code>String</code>
|
||||
* in the Java programming language. It is intended for use when
|
||||
* accessing <code>NCHAR</code>,<code>NVARCHAR</code>
|
||||
* and <code>LONGNVARCHAR</code> columns.
|
||||
*
|
||||
* @return the attribute; if the value is SQL <code>NULL</code>, returns <code>null</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public String readNString() throws SQLException {
|
||||
return (String)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>XML</code> value from the stream and returns it as a
|
||||
* <code>SQLXML</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>SQLXML</code> object representing data of the SQL <code>XML</code> value
|
||||
* at the head of the stream; <code>null</code> if the value read is
|
||||
* SQL <code>NULL</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public SQLXML readSQLXML() throws SQLException {
|
||||
return (SQLXML)getNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an SQL <code>ROWID</code> value from the stream and returns it as a
|
||||
* <code>RowId</code> object in the Java programming language.
|
||||
*
|
||||
* @return a <code>RowId</code> object representing data of the SQL <code>ROWID</code> value
|
||||
* at the head of the stream; <code>null</code> if the value read is
|
||||
* SQL <code>NULL</code>
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
public RowId readRowId() throws SQLException {
|
||||
return (RowId)getNextAttribute();
|
||||
}
|
||||
|
||||
|
||||
}
|
644
jdkSrc/jdk8/javax/sql/rowset/serial/SQLOutputImpl.java
Normal file
644
jdkSrc/jdk8/javax/sql/rowset/serial/SQLOutputImpl.java
Normal file
@@ -0,0 +1,644 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.sql.*;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* The output stream for writing the attributes of a
|
||||
* custom-mapped user-defined type (UDT) back to the database.
|
||||
* The driver uses this interface internally, and its
|
||||
* methods are never directly invoked by an application programmer.
|
||||
* <p>
|
||||
* When an application calls the
|
||||
* method <code>PreparedStatement.setObject</code>, the driver
|
||||
* checks to see whether the value to be written is a UDT with
|
||||
* a custom mapping. If it is, there will be an entry in a
|
||||
* type map containing the <code>Class</code> object for the
|
||||
* class that implements <code>SQLData</code> for this UDT.
|
||||
* If the value to be written is an instance of <code>SQLData</code>,
|
||||
* the driver will create an instance of <code>SQLOutputImpl</code>
|
||||
* and pass it to the method <code>SQLData.writeSQL</code>.
|
||||
* The method <code>writeSQL</code> in turn calls the
|
||||
* appropriate <code>SQLOutputImpl.writeXXX</code> methods
|
||||
* to write data from the <code>SQLData</code> object to
|
||||
* the <code>SQLOutputImpl</code> output stream as the
|
||||
* representation of an SQL user-defined type.
|
||||
*/
|
||||
public class SQLOutputImpl implements SQLOutput {
|
||||
|
||||
/**
|
||||
* A reference to an existing vector that
|
||||
* contains the attributes of a <code>Struct</code> object.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Vector attribs;
|
||||
|
||||
/**
|
||||
* The type map the driver supplies to a newly created
|
||||
* <code>SQLOutputImpl</code> object. This type map
|
||||
* indicates the <code>SQLData</code> class whose
|
||||
* <code>writeSQL</code> method will be called. This
|
||||
* method will in turn call the appropriate
|
||||
* <code>SQLOutputImpl</code> writer methods.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Map map;
|
||||
|
||||
/**
|
||||
* Creates a new <code>SQLOutputImpl</code> object
|
||||
* initialized with the given vector of attributes and
|
||||
* type map. The driver will use the type map to determine
|
||||
* which <code>SQLData.writeSQL</code> method to invoke.
|
||||
* This method will then call the appropriate
|
||||
* <code>SQLOutputImpl</code> writer methods in order and
|
||||
* thereby write the attributes to the new output stream.
|
||||
*
|
||||
* @param attributes a <code>Vector</code> object containing the attributes of
|
||||
* the UDT to be mapped to one or more objects in the Java
|
||||
* programming language
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object containing zero or
|
||||
* more entries, with each entry consisting of 1) a <code>String</code>
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @throws SQLException if the <code>attributes</code> or the <code>map</code>
|
||||
* is a <code>null</code> value
|
||||
*/
|
||||
public SQLOutputImpl(Vector<?> attributes, Map<String,?> map)
|
||||
throws SQLException
|
||||
{
|
||||
if ((attributes == null) || (map == null)) {
|
||||
throw new SQLException("Cannot instantiate a SQLOutputImpl " +
|
||||
"instance with null parameters");
|
||||
}
|
||||
this.attribs = attributes;
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// Methods for writing attributes to the stream of SQL data.
|
||||
// These methods correspond to the column-accessor methods of
|
||||
// java.sql.ResultSet.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Writes a <code>String</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>CHAR</code>, <code>VARCHAR</code>, or
|
||||
* <code>LONGVARCHAR</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeString(String x) throws SQLException {
|
||||
//System.out.println("Adding :"+x);
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>boolean</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>BIT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBoolean(boolean x) throws SQLException {
|
||||
attribs.add(Boolean.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>byte</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>BIT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeByte(byte x) throws SQLException {
|
||||
attribs.add(Byte.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>short</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>SMALLINT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeShort(short x) throws SQLException {
|
||||
attribs.add(Short.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an <code>int</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>INTEGER</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeInt(int x) throws SQLException {
|
||||
attribs.add(Integer.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>long</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>BIGINT</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeLong(long x) throws SQLException {
|
||||
attribs.add(Long.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>float</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>REAL</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeFloat(float x) throws SQLException {
|
||||
attribs.add(Float.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>double</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>DOUBLE</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeDouble(double x) throws SQLException{
|
||||
attribs.add(Double.valueOf(x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.math.BigDecimal</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>NUMERIC</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBigDecimal(java.math.BigDecimal x) throws SQLException{
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an array of <code>bytes</code> in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>VARBINARY</code> or <code>LONGVARBINARY</code>
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBytes(byte[] x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.sql.Date</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>DATE</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeDate(java.sql.Date x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.sql.Time</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>TIME</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTime(java.sql.Time x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>java.sql.Timestamp</code> object in the Java programming
|
||||
* language to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to an SQL <code>TIMESTAMP</code> before returning it to the database.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeTimestamp(java.sql.Timestamp x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a stream of Unicode characters to this
|
||||
* <code>SQLOutputImpl</code> object. The driver will do any necessary
|
||||
* conversion from Unicode to the database <code>CHAR</code> format.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeCharacterStream(java.io.Reader x) throws SQLException {
|
||||
BufferedReader bufReader = new BufferedReader(x);
|
||||
try {
|
||||
int i;
|
||||
while( (i = bufReader.read()) != -1 ) {
|
||||
char ch = (char)i;
|
||||
StringBuffer strBuf = new StringBuffer();
|
||||
strBuf.append(ch);
|
||||
|
||||
String str = new String(strBuf);
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(str.concat(strLine));
|
||||
}
|
||||
} catch(IOException ioe) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a stream of ASCII characters to this
|
||||
* <code>SQLOutputImpl</code> object. The driver will do any necessary
|
||||
* conversion from ASCII to the database <code>CHAR</code> format.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeAsciiStream(java.io.InputStream x) throws SQLException {
|
||||
BufferedReader bufReader = new BufferedReader(new InputStreamReader(x));
|
||||
try {
|
||||
int i;
|
||||
while( (i=bufReader.read()) != -1 ) {
|
||||
char ch = (char)i;
|
||||
|
||||
StringBuffer strBuf = new StringBuffer();
|
||||
strBuf.append(ch);
|
||||
|
||||
String str = new String(strBuf);
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(str.concat(strLine));
|
||||
}
|
||||
}catch(IOException ioe) {
|
||||
throw new SQLException(ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a stream of uninterpreted bytes to this <code>SQLOutputImpl</code>
|
||||
* object.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBinaryStream(java.io.InputStream x) throws SQLException {
|
||||
BufferedReader bufReader = new BufferedReader(new InputStreamReader(x));
|
||||
try {
|
||||
int i;
|
||||
while( (i=bufReader.read()) != -1 ) {
|
||||
char ch = (char)i;
|
||||
|
||||
StringBuffer strBuf = new StringBuffer();
|
||||
strBuf.append(ch);
|
||||
|
||||
String str = new String(strBuf);
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(str.concat(strLine));
|
||||
}
|
||||
} catch(IOException ioe) {
|
||||
throw new SQLException(ioe.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
//================================================================
|
||||
// Methods for writing items of SQL user-defined types to the stream.
|
||||
// These methods pass objects to the database as values of SQL
|
||||
// Structured Types, Distinct Types, Constructed Types, and Locator
|
||||
// Types. They decompose the Java object(s) and write leaf data
|
||||
// items using the methods above.
|
||||
//================================================================
|
||||
|
||||
/**
|
||||
* Writes to the stream the data contained in the given
|
||||
* <code>SQLData</code> object.
|
||||
* When the <code>SQLData</code> object is <code>null</code>, this
|
||||
* method writes an SQL <code>NULL</code> to the stream.
|
||||
* Otherwise, it calls the <code>SQLData.writeSQL</code>
|
||||
* method of the given object, which
|
||||
* writes the object's attributes to the stream.
|
||||
* <P>
|
||||
* The implementation of the method <code>SQLData.writeSQ</code>
|
||||
* calls the appropriate <code>SQLOutputImpl.writeXXX</code> method(s)
|
||||
* for writing each of the object's attributes in order.
|
||||
* The attributes must be read from an <code>SQLInput</code>
|
||||
* input stream and written to an <code>SQLOutputImpl</code>
|
||||
* output stream in the same order in which they were
|
||||
* listed in the SQL definition of the user-defined type.
|
||||
*
|
||||
* @param x the object representing data of an SQL structured or
|
||||
* distinct type
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeObject(SQLData x) throws SQLException {
|
||||
|
||||
/*
|
||||
* Except for the types that are passed as objects
|
||||
* this seems to be the only way for an object to
|
||||
* get a null value for a field in a structure.
|
||||
*
|
||||
* Note: this means that the class defining SQLData
|
||||
* will need to track if a field is SQL null for itself
|
||||
*/
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
/*
|
||||
* We have to write out a SerialStruct that contains
|
||||
* the name of this class otherwise we don't know
|
||||
* what to re-instantiate during readSQL()
|
||||
*/
|
||||
attribs.add(new SerialStruct(x, map));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Ref</code> object in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to a serializable <code>SerialRef</code> SQL <code>REF</code> value
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>REF</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeRef(Ref x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialRef(x));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Blob</code> object in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to a serializable <code>SerialBlob</code> SQL <code>BLOB</code> value
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>BLOB</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeBlob(Blob x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialBlob(x));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Clob</code> object in the Java programming language
|
||||
* to this <code>SQLOutputImpl</code> object. The driver converts
|
||||
* it to a serializable <code>SerialClob</code> SQL <code>CLOB</code> value
|
||||
* before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>CLOB</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeClob(Clob x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialClob(x));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a <code>Struct</code> object in the Java
|
||||
* programming language to this <code>SQLOutputImpl</code>
|
||||
* object. The driver converts this value to an SQL structured type
|
||||
* before returning it to the database.
|
||||
* <P>
|
||||
* This method should be used when an SQL structured type has been
|
||||
* mapped to a <code>Struct</code> object in the Java programming
|
||||
* language (the standard mapping). The method
|
||||
* <code>writeObject</code> should be used if an SQL structured type
|
||||
* has been custom mapped to a class in the Java programming language.
|
||||
*
|
||||
* @param x an object representing the attributes of an SQL structured type
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeStruct(Struct x) throws SQLException {
|
||||
SerialStruct s = new SerialStruct(x,map);;
|
||||
attribs.add(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an <code>Array</code> object in the Java
|
||||
* programming language to this <code>SQLOutputImpl</code>
|
||||
* object. The driver converts this value to a serializable
|
||||
* <code>SerialArray</code> SQL <code>ARRAY</code>
|
||||
* value before returning it to the database.
|
||||
*
|
||||
* @param x an object representing an SQL <code>ARRAY</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeArray(Array x) throws SQLException {
|
||||
if (x == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialArray(x, map));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an <code>java.sql.Type.DATALINK</code> object in the Java
|
||||
* programming language to this <code>SQLOutputImpl</code> object. The
|
||||
* driver converts this value to a serializable <code>SerialDatalink</code>
|
||||
* SQL <code>DATALINK</code> value before return it to the database.
|
||||
*
|
||||
* @param url an object representing a SQL <code>DATALINK</code> value
|
||||
* @throws SQLException if the <code>SQLOutputImpl</code> object is in
|
||||
* use by a <code>SQLData</code> object attempting to write the attribute
|
||||
* values of a UDT to the database.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeURL(java.net.URL url) throws SQLException {
|
||||
if (url == null) {
|
||||
attribs.add(null);
|
||||
} else {
|
||||
attribs.add(new SerialDatalink(url));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes the next attribute to the stream as a <code>String</code>
|
||||
* in the Java programming language. The driver converts this to a
|
||||
* SQL <code>NCHAR</code> or
|
||||
* <code>NVARCHAR</code> or <code>LONGNVARCHAR</code> value
|
||||
* (depending on the argument's
|
||||
* size relative to the driver's limits on <code>NVARCHAR</code> values)
|
||||
* when it sends it to the stream.
|
||||
*
|
||||
* @param x the value to pass to the database
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeNString(String x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an SQL <code>NCLOB</code> value to the stream.
|
||||
*
|
||||
* @param x a <code>NClob</code> object representing data of an SQL
|
||||
* <code>NCLOB</code> value
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeNClob(NClob x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes an SQL <code>ROWID</code> value to the stream.
|
||||
*
|
||||
* @param x a <code>RowId</code> object representing data of an SQL
|
||||
* <code>ROWID</code> value
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeRowId(RowId x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes an SQL <code>XML</code> value to the stream.
|
||||
*
|
||||
* @param x a <code>SQLXML</code> object representing data of an SQL
|
||||
* <code>XML</code> value
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
* @since 1.6
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void writeSQLXML(SQLXML x) throws SQLException {
|
||||
attribs.add(x);
|
||||
}
|
||||
|
||||
}
|
660
jdkSrc/jdk8/javax/sql/rowset/serial/SerialArray.java
Normal file
660
jdkSrc/jdk8/javax/sql/rowset/serial/SerialArray.java
Normal file
@@ -0,0 +1,660 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* A serialized version of an <code>Array</code>
|
||||
* object, which is the mapping in the Java programming language of an SQL
|
||||
* <code>ARRAY</code> value.
|
||||
* <P>
|
||||
* The <code>SerialArray</code> class provides a constructor for creating
|
||||
* a <code>SerialArray</code> instance from an <code>Array</code> object,
|
||||
* methods for getting the base type and the SQL name for the base type, and
|
||||
* methods for copying all or part of a <code>SerialArray</code> object.
|
||||
* <P>
|
||||
*
|
||||
* Note: In order for this class to function correctly, a connection to the
|
||||
* data source
|
||||
* must be available in order for the SQL <code>Array</code> object to be
|
||||
* materialized (have all of its elements brought to the client server)
|
||||
* if necessary. At this time, logical pointers to the data in the data source,
|
||||
* such as locators, are not currently supported.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* A SerialArray is not safe for use by multiple concurrent threads. If a
|
||||
* SerialArray is to be used by more than one thread then access to the
|
||||
* SerialArray should be controlled by appropriate synchronization.
|
||||
*
|
||||
*/
|
||||
public class SerialArray implements Array, Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* A serialized array in which each element is an <code>Object</code>
|
||||
* in the Java programming language that represents an element
|
||||
* in the SQL <code>ARRAY</code> value.
|
||||
* @serial
|
||||
*/
|
||||
private Object[] elements;
|
||||
|
||||
/**
|
||||
* The SQL type of the elements in this <code>SerialArray</code> object. The
|
||||
* type is expressed as one of the constants from the class
|
||||
* <code>java.sql.Types</code>.
|
||||
* @serial
|
||||
*/
|
||||
private int baseType;
|
||||
|
||||
/**
|
||||
* The type name used by the DBMS for the elements in the SQL <code>ARRAY</code>
|
||||
* value that this <code>SerialArray</code> object represents.
|
||||
* @serial
|
||||
*/
|
||||
private String baseTypeName;
|
||||
|
||||
/**
|
||||
* The number of elements in this <code>SerialArray</code> object, which
|
||||
* is also the number of elements in the SQL <code>ARRAY</code> value
|
||||
* that this <code>SerialArray</code> object represents.
|
||||
* @serial
|
||||
*/
|
||||
private int len;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SerialArray</code> object from the given
|
||||
* <code>Array</code> object, using the given type map for the custom
|
||||
* mapping of each element when the elements are SQL UDTs.
|
||||
* <P>
|
||||
* This method does custom mapping if the array elements are a UDT
|
||||
* and the given type map has an entry for that UDT.
|
||||
* Custom mapping is recursive,
|
||||
* meaning that if, for instance, an element of an SQL structured type
|
||||
* is an SQL structured type that itself has an element that is an SQL
|
||||
* structured type, each structured type that has a custom mapping will be
|
||||
* mapped according to the given type map.
|
||||
* <P>
|
||||
* The new <code>SerialArray</code>
|
||||
* object contains the same elements as the <code>Array</code> object
|
||||
* from which it is built, except when the base type is the SQL type
|
||||
* <code>STRUCT</code>, <code>ARRAY</code>, <code>BLOB</code>,
|
||||
* <code>CLOB</code>, <code>DATALINK</code> or <code>JAVA_OBJECT</code>.
|
||||
* In this case, each element in the new
|
||||
* <code>SerialArray</code> object is the appropriate serialized form,
|
||||
* that is, a <code>SerialStruct</code>, <code>SerialArray</code>,
|
||||
* <code>SerialBlob</code>, <code>SerialClob</code>,
|
||||
* <code>SerialDatalink</code>, or <code>SerialJavaObject</code> object.
|
||||
* <P>
|
||||
* Note: (1) The <code>Array</code> object from which a <code>SerialArray</code>
|
||||
* object is created must have materialized the SQL <code>ARRAY</code> value's
|
||||
* data on the client before it is passed to the constructor. Otherwise,
|
||||
* the new <code>SerialArray</code> object will contain no data.
|
||||
* <p>
|
||||
* Note: (2) If the <code>Array</code> contains <code>java.sql.Types.JAVA_OBJECT</code>
|
||||
* types, the <code>SerialJavaObject</code> constructor is called where checks
|
||||
* are made to ensure this object is serializable.
|
||||
* <p>
|
||||
* Note: (3) The <code>Array</code> object supplied to this constructor cannot
|
||||
* return <code>null</code> for any <code>Array.getArray()</code> methods.
|
||||
* <code>SerialArray</code> cannot serialize null array values.
|
||||
*
|
||||
*
|
||||
* @param array the <code>Array</code> object to be serialized
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT (an SQL structured type or
|
||||
* distinct type) and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped. The <i>map</i>
|
||||
* parameter does not have any effect for <code>Blob</code>,
|
||||
* <code>Clob</code>, <code>DATALINK</code>, or
|
||||
* <code>JAVA_OBJECT</code> types.
|
||||
* @throws SerialException if an error occurs serializing the
|
||||
* <code>Array</code> object
|
||||
* @throws SQLException if a database access error occurs or if the
|
||||
* <i>array</i> or the <i>map</i> values are <code>null</code>
|
||||
*/
|
||||
public SerialArray(Array array, Map<String,Class<?>> map)
|
||||
throws SerialException, SQLException
|
||||
{
|
||||
|
||||
if ((array == null) || (map == null)) {
|
||||
throw new SQLException("Cannot instantiate a SerialArray " +
|
||||
"object with null parameters");
|
||||
}
|
||||
|
||||
if ((elements = (Object[])array.getArray()) == null) {
|
||||
throw new SQLException("Invalid Array object. Calls to Array.getArray() " +
|
||||
"return null value which cannot be serialized");
|
||||
}
|
||||
|
||||
elements = (Object[])array.getArray(map);
|
||||
baseType = array.getBaseType();
|
||||
baseTypeName = array.getBaseTypeName();
|
||||
len = elements.length;
|
||||
|
||||
switch (baseType) {
|
||||
case java.sql.Types.STRUCT:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialStruct((Struct)elements[i], map);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.ARRAY:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialArray((Array)elements[i], map);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.BLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialBlob((Blob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.CLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialClob((Clob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.DATALINK:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialDatalink((URL)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.JAVA_OBJECT:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialJavaObject(elements[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method frees the {@code SeriableArray} object and releases the
|
||||
* resources that it holds. The object is invalid once the {@code free}
|
||||
* method is called. <p> If {@code free} is called multiple times, the
|
||||
* subsequent calls to {@code free} are treated as a no-op. </P>
|
||||
*
|
||||
* @throws SQLException if an error occurs releasing the SerialArray's resources
|
||||
* @since 1.6
|
||||
*/
|
||||
public void free() throws SQLException {
|
||||
if (elements != null) {
|
||||
elements = null;
|
||||
baseTypeName= null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SerialArray</code> object from the given
|
||||
* <code>Array</code> object.
|
||||
* <P>
|
||||
* This constructor does not do custom mapping. If the base type of the array
|
||||
* is an SQL structured type and custom mapping is desired, the constructor
|
||||
* <code>SerialArray(Array array, Map map)</code> should be used.
|
||||
* <P>
|
||||
* The new <code>SerialArray</code>
|
||||
* object contains the same elements as the <code>Array</code> object
|
||||
* from which it is built, except when the base type is the SQL type
|
||||
* <code>BLOB</code>,
|
||||
* <code>CLOB</code>, <code>DATALINK</code> or <code>JAVA_OBJECT</code>.
|
||||
* In this case, each element in the new
|
||||
* <code>SerialArray</code> object is the appropriate serialized form,
|
||||
* that is, a <code>SerialBlob</code>, <code>SerialClob</code>,
|
||||
* <code>SerialDatalink</code>, or <code>SerialJavaObject</code> object.
|
||||
* <P>
|
||||
* Note: (1) The <code>Array</code> object from which a <code>SerialArray</code>
|
||||
* object is created must have materialized the SQL <code>ARRAY</code> value's
|
||||
* data on the client before it is passed to the constructor. Otherwise,
|
||||
* the new <code>SerialArray</code> object will contain no data.
|
||||
* <p>
|
||||
* Note: (2) The <code>Array</code> object supplied to this constructor cannot
|
||||
* return <code>null</code> for any <code>Array.getArray()</code> methods.
|
||||
* <code>SerialArray</code> cannot serialize <code>null</code> array values.
|
||||
*
|
||||
* @param array the <code>Array</code> object to be serialized
|
||||
* @throws SerialException if an error occurs serializing the
|
||||
* <code>Array</code> object
|
||||
* @throws SQLException if a database access error occurs or the
|
||||
* <i>array</i> parameter is <code>null</code>.
|
||||
*/
|
||||
public SerialArray(Array array) throws SerialException, SQLException {
|
||||
if (array == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialArray " +
|
||||
"object with a null Array object");
|
||||
}
|
||||
|
||||
if ((elements = (Object[])array.getArray()) == null) {
|
||||
throw new SQLException("Invalid Array object. Calls to Array.getArray() " +
|
||||
"return null value which cannot be serialized");
|
||||
}
|
||||
|
||||
//elements = (Object[])array.getArray();
|
||||
baseType = array.getBaseType();
|
||||
baseTypeName = array.getBaseTypeName();
|
||||
len = elements.length;
|
||||
|
||||
switch (baseType) {
|
||||
|
||||
case java.sql.Types.BLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialBlob((Blob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.CLOB:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialClob((Clob)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.DATALINK:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialDatalink((URL)elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case java.sql.Types.JAVA_OBJECT:
|
||||
for (int i = 0; i < len; i++) {
|
||||
elements[i] = new SerialJavaObject(elements[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array that is a copy of this <code>SerialArray</code>
|
||||
* object.
|
||||
*
|
||||
* @return a copy of this <code>SerialArray</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public Object getArray() throws SerialException {
|
||||
isValid();
|
||||
Object dst = new Object[len];
|
||||
System.arraycopy((Object)elements, 0, dst, 0, len);
|
||||
return dst;
|
||||
}
|
||||
|
||||
//[if an error occurstype map used??]
|
||||
/**
|
||||
* Returns a new array that is a copy of this <code>SerialArray</code>
|
||||
* object, using the given type map for the custom
|
||||
* mapping of each element when the elements are SQL UDTs.
|
||||
* <P>
|
||||
* This method does custom mapping if the array elements are a UDT
|
||||
* and the given type map has an entry for that UDT.
|
||||
* Custom mapping is recursive,
|
||||
* meaning that if, for instance, an element of an SQL structured type
|
||||
* is an SQL structured type that itself has an element that is an SQL
|
||||
* structured type, each structured type that has a custom mapping will be
|
||||
* mapped according to the given type map.
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return a copy of this <code>SerialArray</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public Object getArray(Map<String, Class<?>> map) throws SerialException {
|
||||
isValid();
|
||||
Object dst[] = new Object[len];
|
||||
System.arraycopy((Object)elements, 0, dst, 0, len);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array that is a copy of a slice
|
||||
* of this <code>SerialArray</code> object, starting with the
|
||||
* element at the given index and containing the given number
|
||||
* of consecutive elements.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied;
|
||||
* the index of the first element is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* @return a copy of the designated elements in this <code>SerialArray</code>
|
||||
* object as an <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public Object getArray(long index, int count) throws SerialException {
|
||||
isValid();
|
||||
Object dst = new Object[count];
|
||||
System.arraycopy((Object)elements, (int)index, dst, 0, count);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new array that is a copy of a slice
|
||||
* of this <code>SerialArray</code> object, starting with the
|
||||
* element at the given index and containing the given number
|
||||
* of consecutive elements.
|
||||
* <P>
|
||||
* This method does custom mapping if the array elements are a UDT
|
||||
* and the given type map has an entry for that UDT.
|
||||
* Custom mapping is recursive,
|
||||
* meaning that if, for instance, an element of an SQL structured type
|
||||
* is an SQL structured type that itself has an element that is an SQL
|
||||
* structured type, each structured type that has a custom mapping will be
|
||||
* mapped according to the given type map.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied; the index of the
|
||||
* first element in the array is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return a copy of the designated elements in this <code>SerialArray</code>
|
||||
* object as an <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public Object getArray(long index, int count, Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
isValid();
|
||||
Object dst = new Object[count];
|
||||
System.arraycopy((Object)elements, (int)index, dst, 0, count);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the SQL type of the elements in this <code>SerialArray</code>
|
||||
* object. The <code>int</code> returned is one of the constants in the class
|
||||
* <code>java.sql.Types</code>.
|
||||
*
|
||||
* @return one of the constants in <code>java.sql.Types</code>, indicating
|
||||
* the SQL type of the elements in this <code>SerialArray</code> object
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public int getBaseType() throws SerialException {
|
||||
isValid();
|
||||
return baseType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the DBMS-specific type name for the elements in this
|
||||
* <code>SerialArray</code> object.
|
||||
*
|
||||
* @return the SQL type name used by the DBMS for the base type of this
|
||||
* <code>SerialArray</code> object
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public String getBaseTypeName() throws SerialException {
|
||||
isValid();
|
||||
return baseTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a <code>ResultSet</code> object holding the elements of
|
||||
* the subarray that starts at
|
||||
* index <i>index</i> and contains up to <i>count</i> successive elements.
|
||||
* This method uses the connection's type map to map the elements of
|
||||
* the array if the map contains
|
||||
* an entry for the base type. Otherwise, the standard mapping is used.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied; the index of the
|
||||
* first element in the array is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* @return a <code>ResultSet</code> object containing the designated
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(long index, int count) throws SerialException {
|
||||
SerialException se = new SerialException();
|
||||
se.initCause(new UnsupportedOperationException());
|
||||
throw se;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Retrieves a <code>ResultSet</code> object that contains all of
|
||||
* the elements of the SQL <code>ARRAY</code>
|
||||
* value represented by this <code>SerialArray</code> object. This method uses
|
||||
* the specified map for type map customizations unless the base type of the
|
||||
* array does not match a user-defined type (UDT) in <i>map</i>, in
|
||||
* which case it uses the
|
||||
* standard mapping. This version of the method <code>getResultSet</code>
|
||||
* uses either the given type map or the standard mapping; it never uses the
|
||||
* type map associated with the connection.
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return a <code>ResultSet</code> object containing all of the
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(Map<String, Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
SerialException se = new SerialException();
|
||||
se.initCause(new UnsupportedOperationException());
|
||||
throw se;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a <code>ResultSet</code> object that contains all of
|
||||
* the elements in the <code>ARRAY</code> value that this
|
||||
* <code>SerialArray</code> object represents.
|
||||
* If appropriate, the elements of the array are mapped using the connection's
|
||||
* type map; otherwise, the standard mapping is used.
|
||||
*
|
||||
* @return a <code>ResultSet</code> object containing all of the
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet() throws SerialException {
|
||||
SerialException se = new SerialException();
|
||||
se.initCause(new UnsupportedOperationException());
|
||||
throw se;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a result set holding the elements of the subarray that starts at
|
||||
* Retrieves a <code>ResultSet</code> object that contains a subarray of the
|
||||
* elements in this <code>SerialArray</code> object, starting at
|
||||
* index <i>index</i> and containing up to <i>count</i> successive
|
||||
* elements. This method uses
|
||||
* the specified map for type map customizations unless the base type of the
|
||||
* array does not match a user-defined type (UDT) in <i>map</i>, in
|
||||
* which case it uses the
|
||||
* standard mapping. This version of the method <code>getResultSet</code> uses
|
||||
* either the given type map or the standard mapping; it never uses the type
|
||||
* map associated with the connection.
|
||||
*
|
||||
* @param index the index into this <code>SerialArray</code> object
|
||||
* of the first element to be copied; the index of the
|
||||
* first element in the array is <code>0</code>
|
||||
* @param count the number of consecutive elements to be copied, starting
|
||||
* at the given index
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return a <code>ResultSet</code> object containing the designated
|
||||
* elements in this <code>SerialArray</code> object, with a
|
||||
* separate row for each element
|
||||
* @throws SerialException if called with the cause set to
|
||||
* {@code UnsupportedOperationException}
|
||||
*/
|
||||
public ResultSet getResultSet(long index, int count,
|
||||
Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
SerialException se = new SerialException();
|
||||
se.initCause(new UnsupportedOperationException());
|
||||
throw se;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares this SerialArray to the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
* SerialArray} object whose elements are identical to this object's elements
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialArray} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialArray}
|
||||
* equivalent to this SerialArray, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj instanceof SerialArray) {
|
||||
SerialArray sa = (SerialArray)obj;
|
||||
return baseType == sa.baseType &&
|
||||
baseTypeName.equals(sa.baseTypeName) &&
|
||||
Arrays.equals(elements, sa.elements);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this SerialArray. The hash code for a
|
||||
* {@code SerialArray} object is computed using the hash codes
|
||||
* of the elements of the {@code SerialArray} object
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (((31 + Arrays.hashCode(elements)) * 31 + len) * 31 +
|
||||
baseType) * 31 + baseTypeName.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialArray}. The copy will contain a
|
||||
* reference to a clone of the underlying objects array, not a reference
|
||||
* to the original underlying object array of this {@code SerialArray} object.
|
||||
*
|
||||
* @return a clone of this SerialArray
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialArray sa = (SerialArray) super.clone();
|
||||
sa.elements = (elements != null) ? Arrays.copyOf(elements, len) : null;
|
||||
return sa;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the {@code SerialArray} from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
Object[] tmp = (Object[])fields.get("elements", null);
|
||||
if (tmp == null)
|
||||
throw new InvalidObjectException("elements is null and should not be!");
|
||||
elements = tmp.clone();
|
||||
len = fields.get("len", 0);
|
||||
if(elements.length != len)
|
||||
throw new InvalidObjectException("elements is not the expected size");
|
||||
|
||||
baseType = fields.get("baseType", 0);
|
||||
baseTypeName = (String)fields.get("baseTypeName", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the {@code SerialArray}
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("elements", elements);
|
||||
fields.put("len", len);
|
||||
fields.put("baseType", baseType);
|
||||
fields.put("baseTypeName", baseTypeName);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this object had previously had its {@code free} method
|
||||
* called
|
||||
*
|
||||
* @throws SerialException
|
||||
*/
|
||||
private void isValid() throws SerialException {
|
||||
if (elements == null) {
|
||||
throw new SerialException("Error: You cannot call a method on a "
|
||||
+ "SerialArray instance once free() has been called.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this <code>SerialArray</code>
|
||||
* object.
|
||||
*/
|
||||
static final long serialVersionUID = -8466174297270688520L;
|
||||
}
|
602
jdkSrc/jdk8/javax/sql/rowset/serial/SerialBlob.java
Normal file
602
jdkSrc/jdk8/javax/sql/rowset/serial/SerialBlob.java
Normal file
@@ -0,0 +1,602 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* <code>BLOB</code> value.
|
||||
* <P>
|
||||
* The <code>SerialBlob</code> class provides a constructor for creating
|
||||
* an instance from a <code>Blob</code> object. Note that the
|
||||
* <code>Blob</code>
|
||||
* object should have brought the SQL <code>BLOB</code> value's data over
|
||||
* to the client before a <code>SerialBlob</code> object
|
||||
* is constructed from it. The data of an SQL <code>BLOB</code> value can
|
||||
* be materialized on the client as an array of bytes (using the method
|
||||
* <code>Blob.getBytes</code>) or as a stream of uninterpreted bytes
|
||||
* (using the method <code>Blob.getBinaryStream</code>).
|
||||
* <P>
|
||||
* <code>SerialBlob</code> methods make it possible to make a copy of a
|
||||
* <code>SerialBlob</code> object as an array of bytes or as a stream.
|
||||
* They also make it possible to locate a given pattern of bytes or a
|
||||
* <code>Blob</code> object within a <code>SerialBlob</code> object
|
||||
* and to update or truncate a <code>Blob</code> object.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* <p> A SerialBlob is not safe for use by multiple concurrent threads. If a
|
||||
* SerialBlob is to be used by more than one thread then access to the SerialBlob
|
||||
* should be controlled by appropriate synchronization.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
*/
|
||||
public class SerialBlob implements Blob, Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* A serialized array of uninterpreted bytes representing the
|
||||
* value of this <code>SerialBlob</code> object.
|
||||
* @serial
|
||||
*/
|
||||
private byte[] buf;
|
||||
|
||||
/**
|
||||
* The internal representation of the <code>Blob</code> object on which this
|
||||
* <code>SerialBlob</code> object is based.
|
||||
*/
|
||||
private Blob blob;
|
||||
|
||||
/**
|
||||
* The number of bytes in this <code>SerialBlob</code> object's
|
||||
* array of bytes.
|
||||
* @serial
|
||||
*/
|
||||
private long len;
|
||||
|
||||
/**
|
||||
* The original number of bytes in this <code>SerialBlob</code> object's
|
||||
* array of bytes when it was first established.
|
||||
* @serial
|
||||
*/
|
||||
private long origLen;
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialBlob</code> object that is a serialized version of
|
||||
* the given <code>byte</code> array.
|
||||
* <p>
|
||||
* The new <code>SerialBlob</code> object is initialized with the data from the
|
||||
* <code>byte</code> array, thus allowing disconnected <code>RowSet</code>
|
||||
* objects to establish serialized <code>Blob</code> objects without
|
||||
* touching the data source.
|
||||
*
|
||||
* @param b the <code>byte</code> array containing the data for the
|
||||
* <code>Blob</code> object to be serialized
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if a SQL errors occurs
|
||||
*/
|
||||
public SerialBlob(byte[] b)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
len = b.length;
|
||||
buf = new byte[(int)len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
buf[i] = b[i];
|
||||
}
|
||||
origLen = len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialBlob</code> object that is a serialized
|
||||
* version of the given <code>Blob</code> object.
|
||||
* <P>
|
||||
* The new <code>SerialBlob</code> object is initialized with the
|
||||
* data from the <code>Blob</code> object; therefore, the
|
||||
* <code>Blob</code> object should have previously brought the
|
||||
* SQL <code>BLOB</code> value's data over to the client from
|
||||
* the database. Otherwise, the new <code>SerialBlob</code> object
|
||||
* will contain no data.
|
||||
*
|
||||
* @param blob the <code>Blob</code> object from which this
|
||||
* <code>SerialBlob</code> object is to be constructed;
|
||||
* cannot be null.
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if the <code>Blob</code> passed to this
|
||||
* to this constructor is a <code>null</code>.
|
||||
* @see java.sql.Blob
|
||||
*/
|
||||
public SerialBlob (Blob blob)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
if (blob == null) {
|
||||
throw new SQLException(
|
||||
"Cannot instantiate a SerialBlob object with a null Blob object");
|
||||
}
|
||||
|
||||
len = blob.length();
|
||||
buf = blob.getBytes(1, (int)len );
|
||||
this.blob = blob;
|
||||
origLen = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the specified number of bytes, starting at the given
|
||||
* position, from this <code>SerialBlob</code> object to
|
||||
* another array of bytes.
|
||||
* <P>
|
||||
* Note that if the given number of bytes to be copied is larger than
|
||||
* the length of this <code>SerialBlob</code> object's array of
|
||||
* bytes, the given number will be shortened to the array's length.
|
||||
*
|
||||
* @param pos the ordinal position of the first byte in this
|
||||
* <code>SerialBlob</code> object to be copied;
|
||||
* numbering starts at <code>1</code>; must not be less
|
||||
* than <code>1</code> and must be less than or equal
|
||||
* to the length of this <code>SerialBlob</code> object
|
||||
* @param length the number of bytes to be copied
|
||||
* @return an array of bytes that is a copy of a region of this
|
||||
* <code>SerialBlob</code> object, starting at the given
|
||||
* position and containing the given number of consecutive bytes
|
||||
* @throws SerialException if the given starting position is out of bounds;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public byte[] getBytes(long pos, int length) throws SerialException {
|
||||
isValid();
|
||||
if (length > len) {
|
||||
length = (int)len;
|
||||
}
|
||||
|
||||
if (pos < 1 || len - pos < 0 ) {
|
||||
throw new SerialException("Invalid arguments: position cannot be "
|
||||
+ "less than 1 or greater than the length of the SerialBlob");
|
||||
}
|
||||
|
||||
pos--; // correct pos to array index
|
||||
|
||||
byte[] b = new byte[length];
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
b[i] = this.buf[(int)pos];
|
||||
pos++;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the number of bytes in this <code>SerialBlob</code>
|
||||
* object's array of bytes.
|
||||
*
|
||||
* @return a <code>long</code> indicating the length in bytes of this
|
||||
* <code>SerialBlob</code> object's array of bytes
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public long length() throws SerialException {
|
||||
isValid();
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this <code>SerialBlob</code> object as an input stream.
|
||||
* Unlike the related method, <code>setBinaryStream</code>,
|
||||
* a stream is produced regardless of whether the <code>SerialBlob</code>
|
||||
* was created with a <code>Blob</code> object or a <code>byte</code> array.
|
||||
*
|
||||
* @return a <code>java.io.InputStream</code> object that contains
|
||||
* this <code>SerialBlob</code> object's array of bytes
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @see #setBinaryStream
|
||||
*/
|
||||
public java.io.InputStream getBinaryStream() throws SerialException {
|
||||
isValid();
|
||||
InputStream stream = new ByteArrayInputStream(buf);
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialBlob</code> object where
|
||||
* the given pattern of bytes begins, starting the search at the
|
||||
* specified position.
|
||||
*
|
||||
* @param pattern the pattern of bytes for which to search
|
||||
* @param start the position of the byte in this
|
||||
* <code>SerialBlob</code> object from which to begin
|
||||
* the search; the first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object
|
||||
* @return the position in this <code>SerialBlob</code> object
|
||||
* where the given pattern begins, starting at the specified
|
||||
* position; <code>-1</code> if the pattern is not found
|
||||
* or the given starting position is out of bounds; position
|
||||
* numbering for the return value starts at <code>1</code>
|
||||
* @throws SerialException if an error occurs when serializing the blob;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @throws SQLException if there is an error accessing the <code>BLOB</code>
|
||||
* value from the database
|
||||
*/
|
||||
public long position(byte[] pattern, long start)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
isValid();
|
||||
if (start < 1 || start > len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pos = (int)start-1; // internally Blobs are stored as arrays.
|
||||
int i = 0;
|
||||
long patlen = pattern.length;
|
||||
|
||||
while (pos < len) {
|
||||
if (pattern[i] == buf[pos]) {
|
||||
if (i + 1 == patlen) {
|
||||
return (pos + 1) - (patlen - 1);
|
||||
}
|
||||
i++; pos++; // increment pos, and i
|
||||
} else if (pattern[i] != buf[pos]) {
|
||||
pos++; // increment pos only
|
||||
}
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialBlob</code> object where
|
||||
* the given <code>Blob</code> object begins, starting the search at the
|
||||
* specified position.
|
||||
*
|
||||
* @param pattern the <code>Blob</code> object for which to search;
|
||||
* @param start the position of the byte in this
|
||||
* <code>SerialBlob</code> object from which to begin
|
||||
* the search; the first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object
|
||||
* @return the position in this <code>SerialBlob</code> object
|
||||
* where the given <code>Blob</code> object begins, starting
|
||||
* at the specified position; <code>-1</code> if the pattern is
|
||||
* not found or the given starting position is out of bounds;
|
||||
* position numbering for the return value starts at <code>1</code>
|
||||
* @throws SerialException if an error occurs when serializing the blob;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @throws SQLException if there is an error accessing the <code>BLOB</code>
|
||||
* value from the database
|
||||
*/
|
||||
public long position(Blob pattern, long start)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
return position(pattern.getBytes(1, (int)(pattern.length())), start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given array of bytes to the <code>BLOB</code> value that
|
||||
* this <code>Blob</code> object represents, starting at position
|
||||
* <code>pos</code>, and returns the number of bytes written.
|
||||
*
|
||||
* @param pos the position in the SQL <code>BLOB</code> value at which
|
||||
* to start writing. The first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object.
|
||||
* @param bytes the array of bytes to be written to the <code>BLOB</code>
|
||||
* value that this <code>Blob</code> object represents
|
||||
* @return the number of bytes written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <code>BLOB</code> value; or if an invalid position is set; if an
|
||||
* invalid offset value is set;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @throws SQLException if there is an error accessing the <code>BLOB</code>
|
||||
* value from the database
|
||||
* @see #getBytes
|
||||
*/
|
||||
public int setBytes(long pos, byte[] bytes)
|
||||
throws SerialException, SQLException {
|
||||
return setBytes(pos, bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes all or part of the given <code>byte</code> array to the
|
||||
* <code>BLOB</code> value that this <code>Blob</code> object represents
|
||||
* and returns the number of bytes written.
|
||||
* Writing starts at position <code>pos</code> in the <code>BLOB</code>
|
||||
* value; <i>len</i> bytes from the given byte array are written.
|
||||
*
|
||||
* @param pos the position in the <code>BLOB</code> object at which
|
||||
* to start writing. The first position is <code>1</code>;
|
||||
* must not be less than <code>1</code> nor greater than
|
||||
* the length of this <code>SerialBlob</code> object.
|
||||
* @param bytes the array of bytes to be written to the <code>BLOB</code>
|
||||
* value
|
||||
* @param offset the offset in the <code>byte</code> array at which
|
||||
* to start reading the bytes. The first offset position is
|
||||
* <code>0</code>; must not be less than <code>0</code> nor greater
|
||||
* than the length of the <code>byte</code> array
|
||||
* @param length the number of bytes to be written to the
|
||||
* <code>BLOB</code> value from the array of bytes <i>bytes</i>.
|
||||
*
|
||||
* @return the number of bytes written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <code>BLOB</code> value; if an invalid position is set; if an
|
||||
* invalid offset value is set; if number of bytes to be written
|
||||
* is greater than the <code>SerialBlob</code> length; or the combined
|
||||
* values of the length and offset is greater than the Blob buffer;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @throws SQLException if there is an error accessing the <code>BLOB</code>
|
||||
* value from the database.
|
||||
* @see #getBytes
|
||||
*/
|
||||
public int setBytes(long pos, byte[] bytes, int offset, int length)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
isValid();
|
||||
if (offset < 0 || offset > bytes.length) {
|
||||
throw new SerialException("Invalid offset in byte array set");
|
||||
}
|
||||
|
||||
if (pos < 1 || pos > this.length()) {
|
||||
throw new SerialException("Invalid position in BLOB object set");
|
||||
}
|
||||
|
||||
if ((long)(length) > origLen) {
|
||||
throw new SerialException("Buffer is not sufficient to hold the value");
|
||||
}
|
||||
|
||||
if ((length + offset) > bytes.length) {
|
||||
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
|
||||
"and length that is greater that the Blob buffer");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
pos--; // correct to array indexing
|
||||
while ( i < length || (offset + i +1) < (bytes.length-offset) ) {
|
||||
this.buf[(int)pos + i] = bytes[offset + i ];
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stream that can be used to write to the <code>BLOB</code>
|
||||
* value that this <code>Blob</code> object represents. The stream begins
|
||||
* at position <code>pos</code>. This method forwards the
|
||||
* <code>setBinaryStream()</code> call to the underlying <code>Blob</code> in
|
||||
* the event that this <code>SerialBlob</code> object is instantiated with a
|
||||
* <code>Blob</code>. If this <code>SerialBlob</code> is instantiated with
|
||||
* a <code>byte</code> array, a <code>SerialException</code> is thrown.
|
||||
*
|
||||
* @param pos the position in the <code>BLOB</code> value at which
|
||||
* to start writing
|
||||
* @return a <code>java.io.OutputStream</code> object to which data can
|
||||
* be written
|
||||
* @throws SQLException if there is an error accessing the
|
||||
* <code>BLOB</code> value
|
||||
* @throws SerialException if the SerialBlob in not instantiated with a
|
||||
* <code>Blob</code> object that supports <code>setBinaryStream()</code>;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @see #getBinaryStream
|
||||
*/
|
||||
public java.io.OutputStream setBinaryStream(long pos)
|
||||
throws SerialException, SQLException {
|
||||
|
||||
isValid();
|
||||
if (this.blob != null) {
|
||||
return this.blob.setBinaryStream(pos);
|
||||
} else {
|
||||
throw new SerialException("Unsupported operation. SerialBlob cannot " +
|
||||
"return a writable binary stream, unless instantiated with a Blob object " +
|
||||
"that provides a setBinaryStream() implementation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the <code>BLOB</code> value that this <code>Blob</code>
|
||||
* object represents to be <code>len</code> bytes in length.
|
||||
*
|
||||
* @param length the length, in bytes, to which the <code>BLOB</code>
|
||||
* value that this <code>Blob</code> object represents should be
|
||||
* truncated
|
||||
* @throws SerialException if there is an error accessing the Blob value;
|
||||
* or the length to truncate is greater that the SerialBlob length;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public void truncate(long length) throws SerialException {
|
||||
isValid();
|
||||
if (length > len) {
|
||||
throw new SerialException(
|
||||
"Length more than what can be truncated");
|
||||
} else if((int)length == 0) {
|
||||
buf = new byte[0];
|
||||
len = length;
|
||||
} else {
|
||||
len = length;
|
||||
buf = this.getBytes(1, (int)len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an
|
||||
* <code>InputStream</code> object that contains a partial
|
||||
* {@code Blob} value, starting with the byte specified by pos, which is
|
||||
* length bytes in length.
|
||||
*
|
||||
* @param pos the offset to the first byte of the partial value to be
|
||||
* retrieved. The first byte in the {@code Blob} is at position 1
|
||||
* @param length the length in bytes of the partial value to be retrieved
|
||||
* @return
|
||||
* <code>InputStream</code> through which the partial {@code Blob} value can
|
||||
* be read.
|
||||
* @throws SQLException if pos is less than 1 or if pos is greater than the
|
||||
* number of bytes in the {@code Blob} or if pos + length is greater than
|
||||
* the number of bytes in the {@code Blob}
|
||||
* @throws SerialException if the {@code free} method had been previously
|
||||
* called on this object
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public InputStream getBinaryStream(long pos, long length) throws SQLException {
|
||||
isValid();
|
||||
if (pos < 1 || pos > this.length()) {
|
||||
throw new SerialException("Invalid position in BLOB object set");
|
||||
}
|
||||
if (length < 1 || length > len - pos + 1) {
|
||||
throw new SerialException(
|
||||
"length is < 1 or pos + length > total number of bytes");
|
||||
}
|
||||
return new ByteArrayInputStream(buf, (int) pos - 1, (int) length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method frees the {@code SeriableBlob} object and releases the
|
||||
* resources that it holds. The object is invalid once the {@code free}
|
||||
* method is called. <p> If {@code free} is called multiple times, the
|
||||
* subsequent calls to {@code free} are treated as a no-op. </P>
|
||||
*
|
||||
* @throws SQLException if an error occurs releasing the Blob's resources
|
||||
* @since 1.6
|
||||
*/
|
||||
public void free() throws SQLException {
|
||||
if (buf != null) {
|
||||
buf = null;
|
||||
if (blob != null) {
|
||||
blob.free();
|
||||
}
|
||||
blob = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialBlob to the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
* SerialBlob} object that represents the same sequence of bytes as this
|
||||
* object.
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialBlob} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialBlob}
|
||||
* equivalent to this SerialBlob, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialBlob) {
|
||||
SerialBlob sb = (SerialBlob)obj;
|
||||
if (this.len == sb.len) {
|
||||
return Arrays.equals(buf, sb.buf);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialBlob}.
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((31 + Arrays.hashCode(buf)) * 31 + (int)len) * 31 + (int)origLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialBlob}. The copy will contain a
|
||||
* reference to a clone of the internal byte array, not a reference
|
||||
* to the original internal byte array of this {@code SerialBlob} object.
|
||||
* The underlying {@code Blob} object will be set to null.
|
||||
*
|
||||
* @return a clone of this SerialBlob
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialBlob sb = (SerialBlob) super.clone();
|
||||
sb.buf = (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
|
||||
sb.blob = null;
|
||||
return sb;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the SerialBlob from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
byte[] tmp = (byte[])fields.get("buf", null);
|
||||
if (tmp == null)
|
||||
throw new InvalidObjectException("buf is null and should not be!");
|
||||
buf = tmp.clone();
|
||||
len = fields.get("len", 0L);
|
||||
if (buf.length != len)
|
||||
throw new InvalidObjectException("buf is not the expected size");
|
||||
origLen = fields.get("origLen", 0L);
|
||||
blob = (Blob) fields.get("blob", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the SerialBlob
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("buf", buf);
|
||||
fields.put("len", len);
|
||||
fields.put("origLen", origLen);
|
||||
// Note: this check to see if it is an instance of Serializable
|
||||
// is for backwards compatibiity
|
||||
fields.put("blob", blob instanceof Serializable ? blob : null);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this object had previously had its {@code free} method
|
||||
* called
|
||||
*
|
||||
* @throws SerialException
|
||||
*/
|
||||
private void isValid() throws SerialException {
|
||||
if (buf == null) {
|
||||
throw new SerialException("Error: You cannot call a method on a " +
|
||||
"SerialBlob instance once free() has been called.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* {@code SerialBlob} object.
|
||||
*/
|
||||
static final long serialVersionUID = -8144641928112860441L;
|
||||
}
|
694
jdkSrc/jdk8/javax/sql/rowset/serial/SerialClob.java
Normal file
694
jdkSrc/jdk8/javax/sql/rowset/serial/SerialClob.java
Normal file
@@ -0,0 +1,694 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* <code>CLOB</code> value.
|
||||
* <P>
|
||||
* The <code>SerialClob</code> class provides a constructor for creating
|
||||
* an instance from a <code>Clob</code> object. Note that the <code>Clob</code>
|
||||
* object should have brought the SQL <code>CLOB</code> value's data over
|
||||
* to the client before a <code>SerialClob</code> object
|
||||
* is constructed from it. The data of an SQL <code>CLOB</code> value can
|
||||
* be materialized on the client as a stream of Unicode characters.
|
||||
* <P>
|
||||
* <code>SerialClob</code> methods make it possible to get a substring
|
||||
* from a <code>SerialClob</code> object or to locate the start of
|
||||
* a pattern of characters.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* <p> A SerialClob is not safe for use by multiple concurrent threads. If a
|
||||
* SerialClob is to be used by more than one thread then access to the SerialClob
|
||||
* should be controlled by appropriate synchronization.
|
||||
* @author Jonathan Bruce
|
||||
*/
|
||||
public class SerialClob implements Clob, Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* A serialized array of characters containing the data of the SQL
|
||||
* <code>CLOB</code> value that this <code>SerialClob</code> object
|
||||
* represents.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private char buf[];
|
||||
|
||||
/**
|
||||
* Internal Clob representation if SerialClob is initialized with a
|
||||
* Clob. Null if SerialClob is initialized with a char[].
|
||||
*/
|
||||
private Clob clob;
|
||||
|
||||
/**
|
||||
* The length in characters of this <code>SerialClob</code> object's
|
||||
* internal array of characters.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private long len;
|
||||
|
||||
/**
|
||||
* The original length in characters of this <code>SerialClob</code>
|
||||
* object's internal array of characters.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private long origLen;
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialClob</code> object that is a serialized version of
|
||||
* the given <code>char</code> array.
|
||||
* <p>
|
||||
* The new <code>SerialClob</code> object is initialized with the data from the
|
||||
* <code>char</code> array, thus allowing disconnected <code>RowSet</code>
|
||||
* objects to establish a serialized <code>Clob</code> object without touching
|
||||
* the data source.
|
||||
*
|
||||
* @param ch the char array representing the <code>Clob</code> object to be
|
||||
* serialized
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if a SQL error occurs
|
||||
*/
|
||||
public SerialClob(char ch[]) throws SerialException, SQLException {
|
||||
|
||||
// %%% JMB. Agreed. Add code here to throw a SQLException if no
|
||||
// support is available for locatorsUpdateCopy=false
|
||||
// Serializing locators is not supported.
|
||||
|
||||
len = ch.length;
|
||||
buf = new char[(int)len];
|
||||
for (int i = 0; i < len ; i++){
|
||||
buf[i] = ch[i];
|
||||
}
|
||||
origLen = len;
|
||||
clob = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialClob</code> object that is a serialized
|
||||
* version of the given <code>Clob</code> object.
|
||||
* <P>
|
||||
* The new <code>SerialClob</code> object is initialized with the
|
||||
* data from the <code>Clob</code> object; therefore, the
|
||||
* <code>Clob</code> object should have previously brought the
|
||||
* SQL <code>CLOB</code> value's data over to the client from
|
||||
* the database. Otherwise, the new <code>SerialClob</code> object
|
||||
* object will contain no data.
|
||||
* <p>
|
||||
* Note: The <code>Clob</code> object supplied to this constructor must
|
||||
* return non-null for both the <code>Clob.getCharacterStream()</code>
|
||||
* and <code>Clob.getAsciiStream</code> methods. This <code>SerialClob</code>
|
||||
* constructor cannot serialize a <code>Clob</code> object in this instance
|
||||
* and will throw an <code>SQLException</code> object.
|
||||
*
|
||||
* @param clob the <code>Clob</code> object from which this
|
||||
* <code>SerialClob</code> object is to be constructed; cannot be null
|
||||
* @throws SerialException if an error occurs during serialization
|
||||
* @throws SQLException if a SQL error occurs in capturing the CLOB;
|
||||
* if the <code>Clob</code> object is a null; or if either of the
|
||||
* <code>Clob.getCharacterStream()</code> and <code>Clob.getAsciiStream()</code>
|
||||
* methods on the <code>Clob</code> returns a null
|
||||
* @see java.sql.Clob
|
||||
*/
|
||||
public SerialClob(Clob clob) throws SerialException, SQLException {
|
||||
|
||||
if (clob == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialClob " +
|
||||
"object with a null Clob object");
|
||||
}
|
||||
len = clob.length();
|
||||
this.clob = clob;
|
||||
buf = new char[(int)len];
|
||||
int read = 0;
|
||||
int offset = 0;
|
||||
|
||||
try (Reader charStream = clob.getCharacterStream()) {
|
||||
if (charStream == null) {
|
||||
throw new SQLException("Invalid Clob object. The call to getCharacterStream " +
|
||||
"returned null which cannot be serialized.");
|
||||
}
|
||||
|
||||
// Note: get an ASCII stream in order to null-check it,
|
||||
// even though we don't do anything with it.
|
||||
try (InputStream asciiStream = clob.getAsciiStream()) {
|
||||
if (asciiStream == null) {
|
||||
throw new SQLException("Invalid Clob object. The call to getAsciiStream " +
|
||||
"returned null which cannot be serialized.");
|
||||
}
|
||||
}
|
||||
|
||||
try (Reader reader = new BufferedReader(charStream)) {
|
||||
do {
|
||||
read = reader.read(buf, offset, (int)(len - offset));
|
||||
offset += read;
|
||||
} while (read > 0);
|
||||
}
|
||||
} catch (java.io.IOException ex) {
|
||||
throw new SerialException("SerialClob: " + ex.getMessage());
|
||||
}
|
||||
|
||||
origLen = len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the number of characters in this <code>SerialClob</code>
|
||||
* object's array of characters.
|
||||
*
|
||||
* @return a <code>long</code> indicating the length in characters of this
|
||||
* <code>SerialClob</code> object's array of character
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public long length() throws SerialException {
|
||||
isValid();
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this <code>SerialClob</code> object's data as a stream
|
||||
* of Unicode characters. Unlike the related method, <code>getAsciiStream</code>,
|
||||
* a stream is produced regardless of whether the <code>SerialClob</code> object
|
||||
* was created with a <code>Clob</code> object or a <code>char</code> array.
|
||||
*
|
||||
* @return a <code>java.io.Reader</code> object containing this
|
||||
* <code>SerialClob</code> object's data
|
||||
* @throws SerialException if an error occurs;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public java.io.Reader getCharacterStream() throws SerialException {
|
||||
isValid();
|
||||
return (java.io.Reader) new CharArrayReader(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>CLOB</code> value designated by this <code>SerialClob</code>
|
||||
* object as an ascii stream. This method forwards the <code>getAsciiStream</code>
|
||||
* call to the underlying <code>Clob</code> object in the event that this
|
||||
* <code>SerialClob</code> object is instantiated with a <code>Clob</code>
|
||||
* object. If this <code>SerialClob</code> object is instantiated with
|
||||
* a <code>char</code> array, a <code>SerialException</code> object is thrown.
|
||||
*
|
||||
* @return a <code>java.io.InputStream</code> object containing
|
||||
* this <code>SerialClob</code> object's data
|
||||
* @throws SerialException if this {@code SerialClob} object was not
|
||||
* instantiated with a <code>Clob</code> object;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @throws SQLException if there is an error accessing the
|
||||
* <code>CLOB</code> value represented by the <code>Clob</code> object
|
||||
* that was used to create this <code>SerialClob</code> object
|
||||
*/
|
||||
public java.io.InputStream getAsciiStream() throws SerialException, SQLException {
|
||||
isValid();
|
||||
if (this.clob != null) {
|
||||
return this.clob.getAsciiStream();
|
||||
} else {
|
||||
throw new SerialException("Unsupported operation. SerialClob cannot " +
|
||||
"return a the CLOB value as an ascii stream, unless instantiated " +
|
||||
"with a fully implemented Clob object.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the substring contained in this
|
||||
* <code>SerialClob</code> object, starting at the given position
|
||||
* and continuing for the specified number or characters.
|
||||
*
|
||||
* @param pos the position of the first character in the substring
|
||||
* to be copied; the first character of the
|
||||
* <code>SerialClob</code> object is at position
|
||||
* <code>1</code>; must not be less than <code>1</code>,
|
||||
* and the sum of the starting position and the length
|
||||
* of the substring must be less than the length of this
|
||||
* <code>SerialClob</code> object
|
||||
* @param length the number of characters in the substring to be
|
||||
* returned; must not be greater than the length of
|
||||
* this <code>SerialClob</code> object, and the
|
||||
* sum of the starting position and the length
|
||||
* of the substring must be less than the length of this
|
||||
* <code>SerialClob</code> object
|
||||
* @return a <code>String</code> object containing a substring of
|
||||
* this <code>SerialClob</code> object beginning at the
|
||||
* given position and containing the specified number of
|
||||
* consecutive characters
|
||||
* @throws SerialException if either of the arguments is out of bounds;
|
||||
* if {@code free} had previously been called on this object
|
||||
*/
|
||||
public String getSubString(long pos, int length) throws SerialException {
|
||||
|
||||
isValid();
|
||||
if (pos < 1 || pos > this.length()) {
|
||||
throw new SerialException("Invalid position in SerialClob object set");
|
||||
}
|
||||
|
||||
if ((pos-1) + length > this.length()) {
|
||||
throw new SerialException("Invalid position and substring length");
|
||||
}
|
||||
|
||||
try {
|
||||
return new String(buf, (int)pos - 1, length);
|
||||
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
throw new SerialException("StringIndexOutOfBoundsException: " +
|
||||
e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialClob</code> object
|
||||
* where the given <code>String</code> object begins, starting
|
||||
* the search at the specified position. This method returns
|
||||
* <code>-1</code> if the pattern is not found.
|
||||
*
|
||||
* @param searchStr the <code>String</code> object for which to
|
||||
* search
|
||||
* @param start the position in this <code>SerialClob</code> object
|
||||
* at which to start the search; the first position is
|
||||
* <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @return the position at which the given <code>String</code> object
|
||||
* begins, starting the search at the specified position;
|
||||
* <code>-1</code> if the given <code>String</code> object is
|
||||
* not found or the starting position is out of bounds; position
|
||||
* numbering for the return value starts at <code>1</code>
|
||||
* @throws SerialException if the {@code free} method had been
|
||||
* previously called on this object
|
||||
* @throws SQLException if there is an error accessing the Clob value
|
||||
* from the database.
|
||||
*/
|
||||
public long position(String searchStr, long start)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
if (start < 1 || start > len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char pattern[] = searchStr.toCharArray();
|
||||
|
||||
int pos = (int)start-1;
|
||||
int i = 0;
|
||||
long patlen = pattern.length;
|
||||
|
||||
while (pos < len) {
|
||||
if (pattern[i] == buf[pos]) {
|
||||
if (i + 1 == patlen) {
|
||||
return (pos + 1) - (patlen - 1);
|
||||
}
|
||||
i++; pos++; // increment pos, and i
|
||||
|
||||
} else if (pattern[i] != buf[pos]) {
|
||||
pos++; // increment pos only
|
||||
}
|
||||
}
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the position in this <code>SerialClob</code> object
|
||||
* where the given <code>Clob</code> signature begins, starting
|
||||
* the search at the specified position. This method returns
|
||||
* <code>-1</code> if the pattern is not found.
|
||||
*
|
||||
* @param searchStr the <code>Clob</code> object for which to search
|
||||
* @param start the position in this <code>SerialClob</code> object
|
||||
* at which to begin the search; the first position is
|
||||
* <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @return the position at which the given <code>Clob</code>
|
||||
* object begins in this <code>SerialClob</code> object,
|
||||
* at or after the specified starting position
|
||||
* @throws SerialException if an error occurs locating the Clob signature;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
* @throws SQLException if there is an error accessing the Clob value
|
||||
* from the database
|
||||
*/
|
||||
public long position(Clob searchStr, long start)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
return position(searchStr.getSubString(1,(int)searchStr.length()), start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given Java <code>String</code> to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents, at the position
|
||||
* <code>pos</code>.
|
||||
*
|
||||
* @param pos the position at which to start writing to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents; the first
|
||||
* position is <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @param str the string to be written to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents
|
||||
* @return the number of characters written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <code>CLOB</code> value; if an invalid position is set; if an
|
||||
* invalid offset value is set; if number of bytes to be written
|
||||
* is greater than the <code>SerialClob</code> length; or the combined
|
||||
* values of the length and offset is greater than the Clob buffer;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
*/
|
||||
public int setString(long pos, String str) throws SerialException {
|
||||
return (setString(pos, str, 0, str.length()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes <code>len</code> characters of <code>str</code>, starting
|
||||
* at character <code>offset</code>, to the <code>CLOB</code> value
|
||||
* that this <code>Clob</code> represents.
|
||||
*
|
||||
* @param pos the position at which to start writing to the <code>CLOB</code>
|
||||
* value that this <code>SerialClob</code> object represents; the first
|
||||
* position is <code>1</code>; must not be less than <code>1</code> nor
|
||||
* greater than the length of this <code>SerialClob</code> object
|
||||
* @param str the string to be written to the <code>CLOB</code>
|
||||
* value that this <code>Clob</code> object represents
|
||||
* @param offset the offset into <code>str</code> to start reading
|
||||
* the characters to be written
|
||||
* @param length the number of characters to be written
|
||||
* @return the number of characters written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <code>CLOB</code> value; if an invalid position is set; if an
|
||||
* invalid offset value is set; if number of bytes to be written
|
||||
* is greater than the <code>SerialClob</code> length; or the combined
|
||||
* values of the length and offset is greater than the Clob buffer;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
*/
|
||||
public int setString(long pos, String str, int offset, int length)
|
||||
throws SerialException {
|
||||
isValid();
|
||||
String temp = str.substring(offset);
|
||||
char cPattern[] = temp.toCharArray();
|
||||
|
||||
if (offset < 0 || offset > str.length()) {
|
||||
throw new SerialException("Invalid offset in byte array set");
|
||||
}
|
||||
|
||||
if (pos < 1 || pos > this.length()) {
|
||||
throw new SerialException("Invalid position in Clob object set");
|
||||
}
|
||||
|
||||
if ((long)(length) > origLen) {
|
||||
throw new SerialException("Buffer is not sufficient to hold the value");
|
||||
}
|
||||
|
||||
if ((length + offset) > str.length()) {
|
||||
// need check to ensure length + offset !> bytes.length
|
||||
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
|
||||
" and length that is greater that the Blob buffer");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
pos--; //values in the array are at position one less
|
||||
while ( i < length || (offset + i +1) < (str.length() - offset ) ) {
|
||||
this.buf[(int)pos + i ] = cPattern[offset + i ];
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stream to be used to write Ascii characters to the
|
||||
* <code>CLOB</code> value that this <code>SerialClob</code> object represents,
|
||||
* starting at position <code>pos</code>. This method forwards the
|
||||
* <code>setAsciiStream()</code> call to the underlying <code>Clob</code> object in
|
||||
* the event that this <code>SerialClob</code> object is instantiated with a
|
||||
* <code>Clob</code> object. If this <code>SerialClob</code> object is instantiated
|
||||
* with a <code>char</code> array, a <code>SerialException</code> object is thrown.
|
||||
*
|
||||
* @param pos the position at which to start writing to the
|
||||
* <code>CLOB</code> object
|
||||
* @return the stream to which ASCII encoded characters can be written
|
||||
* @throws SerialException if SerialClob is not instantiated with a
|
||||
* Clob object;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
* @throws SQLException if there is an error accessing the
|
||||
* <code>CLOB</code> value
|
||||
* @see #getAsciiStream
|
||||
*/
|
||||
public java.io.OutputStream setAsciiStream(long pos)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
if (this.clob != null) {
|
||||
return this.clob.setAsciiStream(pos);
|
||||
} else {
|
||||
throw new SerialException("Unsupported operation. SerialClob cannot " +
|
||||
"return a writable ascii stream\n unless instantiated with a Clob object " +
|
||||
"that has a setAsciiStream() implementation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a stream to be used to write a stream of Unicode characters
|
||||
* to the <code>CLOB</code> value that this <code>SerialClob</code> object
|
||||
* represents, at position <code>pos</code>. This method forwards the
|
||||
* <code>setCharacterStream()</code> call to the underlying <code>Clob</code>
|
||||
* object in the event that this <code>SerialClob</code> object is instantiated with a
|
||||
* <code>Clob</code> object. If this <code>SerialClob</code> object is instantiated with
|
||||
* a <code>char</code> array, a <code>SerialException</code> is thrown.
|
||||
*
|
||||
* @param pos the position at which to start writing to the
|
||||
* <code>CLOB</code> value
|
||||
*
|
||||
* @return a stream to which Unicode encoded characters can be written
|
||||
* @throws SerialException if the SerialClob is not instantiated with
|
||||
* a Clob object;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
* @throws SQLException if there is an error accessing the
|
||||
* <code>CLOB</code> value
|
||||
* @see #getCharacterStream
|
||||
*/
|
||||
public java.io.Writer setCharacterStream(long pos)
|
||||
throws SerialException, SQLException {
|
||||
isValid();
|
||||
if (this.clob != null) {
|
||||
return this.clob.setCharacterStream(pos);
|
||||
} else {
|
||||
throw new SerialException("Unsupported operation. SerialClob cannot " +
|
||||
"return a writable character stream\n unless instantiated with a Clob object " +
|
||||
"that has a setCharacterStream implementation");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncates the <code>CLOB</code> value that this <code>SerialClob</code>
|
||||
* object represents so that it has a length of <code>len</code>
|
||||
* characters.
|
||||
* <p>
|
||||
* Truncating a <code>SerialClob</code> object to length 0 has the effect of
|
||||
* clearing its contents.
|
||||
*
|
||||
* @param length the length, in bytes, to which the <code>CLOB</code>
|
||||
* value should be truncated
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* <code>CLOB</code> value;
|
||||
* if the {@code free} method had been previously called on this object
|
||||
*/
|
||||
public void truncate(long length) throws SerialException {
|
||||
isValid();
|
||||
if (length > len) {
|
||||
throw new SerialException
|
||||
("Length more than what can be truncated");
|
||||
} else {
|
||||
len = length;
|
||||
// re-size the buffer
|
||||
|
||||
if (len == 0) {
|
||||
buf = new char[] {};
|
||||
} else {
|
||||
buf = (this.getSubString(1, (int)len)).toCharArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a {@code Reader} object that contains a partial
|
||||
* {@code SerialClob} value, starting
|
||||
* with the character specified by pos, which is length characters in length.
|
||||
*
|
||||
* @param pos the offset to the first character of the partial value to
|
||||
* be retrieved. The first character in the {@code SerialClob} is at position 1.
|
||||
* @param length the length in characters of the partial value to be retrieved.
|
||||
* @return {@code Reader} through which the partial {@code SerialClob}
|
||||
* value can be read.
|
||||
* @throws SQLException if pos is less than 1 or if pos is greater than the
|
||||
* number of characters in the {@code SerialClob} or if pos + length
|
||||
* is greater than the number of characters in the {@code SerialClob};
|
||||
* @throws SerialException if the {@code free} method had been previously
|
||||
* called on this object
|
||||
* @since 1.6
|
||||
*/
|
||||
public Reader getCharacterStream(long pos, long length) throws SQLException {
|
||||
isValid();
|
||||
if (pos < 1 || pos > len) {
|
||||
throw new SerialException("Invalid position in Clob object set");
|
||||
}
|
||||
|
||||
if ((pos-1) + length > len) {
|
||||
throw new SerialException("Invalid position and substring length");
|
||||
}
|
||||
if (length <= 0) {
|
||||
throw new SerialException("Invalid length specified");
|
||||
}
|
||||
return new CharArrayReader(buf, (int)pos, (int)length);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method frees the {@code SeriableClob} object and releases the
|
||||
* resources that it holds.
|
||||
* The object is invalid once the {@code free} method is called.
|
||||
* <p>
|
||||
* If {@code free} is called multiple times, the subsequent
|
||||
* calls to {@code free} are treated as a no-op.
|
||||
* </P>
|
||||
* @throws SQLException if an error occurs releasing
|
||||
* the Clob's resources
|
||||
* @since 1.6
|
||||
*/
|
||||
public void free() throws SQLException {
|
||||
if (buf != null) {
|
||||
buf = null;
|
||||
if (clob != null) {
|
||||
clob.free();
|
||||
}
|
||||
clob = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialClob to the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
* SerialClob} object that represents the same sequence of characters as this
|
||||
* object.
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialClob} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialClob}
|
||||
* equivalent to this SerialClob, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialClob) {
|
||||
SerialClob sc = (SerialClob)obj;
|
||||
if (this.len == sc.len) {
|
||||
return Arrays.equals(buf, sc.buf);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialClob}.
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((31 + Arrays.hashCode(buf)) * 31 + (int)len) * 31 + (int)origLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialClob}. The copy will contain a
|
||||
* reference to a clone of the internal character array, not a reference
|
||||
* to the original internal character array of this {@code SerialClob} object.
|
||||
* The underlying {@code Clob} object will be set to null.
|
||||
*
|
||||
* @return a clone of this SerialClob
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialClob sc = (SerialClob) super.clone();
|
||||
sc.buf = (buf != null) ? Arrays.copyOf(buf, (int)len) : null;
|
||||
sc.clob = null;
|
||||
return sc;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the SerialClob from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
char[] tmp = (char[])fields.get("buf", null);
|
||||
if (tmp == null)
|
||||
throw new InvalidObjectException("buf is null and should not be!");
|
||||
buf = tmp.clone();
|
||||
len = fields.get("len", 0L);
|
||||
if (buf.length != len)
|
||||
throw new InvalidObjectException("buf is not the expected size");
|
||||
origLen = fields.get("origLen", 0L);
|
||||
clob = (Clob) fields.get("clob", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the SerialClob
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("buf", buf);
|
||||
fields.put("len", len);
|
||||
fields.put("origLen", origLen);
|
||||
// Note: this check to see if it is an instance of Serializable
|
||||
// is for backwards compatibiity
|
||||
fields.put("clob", clob instanceof Serializable ? clob : null);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this object had previously had its {@code free} method
|
||||
* called
|
||||
*
|
||||
* @throws SerialException
|
||||
*/
|
||||
private void isValid() throws SerialException {
|
||||
if (buf == null) {
|
||||
throw new SerialException("Error: You cannot call a method on a "
|
||||
+ "SerialClob instance once free() has been called.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this {@code SerialClob}
|
||||
* object.
|
||||
*/
|
||||
static final long serialVersionUID = -1662519690087375313L;
|
||||
}
|
170
jdkSrc/jdk8/javax/sql/rowset/serial/SerialDatalink.java
Normal file
170
jdkSrc/jdk8/javax/sql/rowset/serial/SerialDatalink.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* <code>DATALINK</code> value. A <code>DATALINK</code> value
|
||||
* references a file outside of the underlying data source that the
|
||||
* data source manages.
|
||||
* <P>
|
||||
* <code>RowSet</code> implementations can use the method <code>RowSet.getURL</code>
|
||||
* to retrieve a <code>java.net.URL</code> object, which can be used
|
||||
* to manipulate the external data.
|
||||
* <pre>
|
||||
* java.net.URL url = rowset.getURL(1);
|
||||
* </pre>
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* A SerialDatalink is not safe for use by multiple concurrent threads. If a
|
||||
* SerialDatalink is to be used by more than one thread then access to the
|
||||
* SerialDatalink should be controlled by appropriate synchronization.
|
||||
*/
|
||||
public class SerialDatalink implements Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* The extracted URL field retrieved from the DATALINK field.
|
||||
* @serial
|
||||
*/
|
||||
private URL url;
|
||||
|
||||
/**
|
||||
* The SQL type of the elements in this <code>SerialDatalink</code>
|
||||
* object. The type is expressed as one of the contants from the
|
||||
* class <code>java.sql.Types</code>.
|
||||
* @serial
|
||||
*/
|
||||
private int baseType;
|
||||
|
||||
/**
|
||||
* The type name used by the DBMS for the elements in the SQL
|
||||
* <code>DATALINK</code> value that this SerialDatalink object
|
||||
* represents.
|
||||
* @serial
|
||||
*/
|
||||
private String baseTypeName;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>SerialDatalink</code> object from the given
|
||||
* <code>java.net.URL</code> object.
|
||||
* <P>
|
||||
* @param url the {@code URL} to create the {@code SerialDataLink} from
|
||||
* @throws SerialException if url parameter is a null
|
||||
*/
|
||||
public SerialDatalink(URL url) throws SerialException {
|
||||
if (url == null) {
|
||||
throw new SerialException("Cannot serialize empty URL instance");
|
||||
}
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new URL that is a copy of this <code>SerialDatalink</code>
|
||||
* object.
|
||||
*
|
||||
* @return a copy of this <code>SerialDatalink</code> object as a
|
||||
* <code>URL</code> object in the Java programming language.
|
||||
* @throws SerialException if the <code>URL</code> object cannot be de-serialized
|
||||
*/
|
||||
public URL getDatalink() throws SerialException {
|
||||
|
||||
URL aURL = null;
|
||||
|
||||
try {
|
||||
aURL = new URL((this.url).toString());
|
||||
} catch (java.net.MalformedURLException e) {
|
||||
throw new SerialException("MalformedURLException: " + e.getMessage());
|
||||
}
|
||||
return aURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code SerialDatalink} to the specified object.
|
||||
* The result is {@code true} if and only if the argument is not
|
||||
* {@code null} and is a {@code SerialDatalink} object whose URL is
|
||||
* identical to this object's URL
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialDatalink} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialDatalink}
|
||||
* equivalent to this SerialDatalink, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialDatalink) {
|
||||
SerialDatalink sdl = (SerialDatalink) obj;
|
||||
return url.equals(sdl.url);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialDatalink}. The hash code for a
|
||||
* {@code SerialDatalink} object is taken as the hash code of
|
||||
* the {@code URL} it stores
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 31 + url.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialDatalink}.
|
||||
*
|
||||
* @return a clone of this SerialDatalink
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialDatalink sdl = (SerialDatalink) super.clone();
|
||||
return sdl;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject and writeObject are called to restore the state
|
||||
* of the {@code SerialDatalink}
|
||||
* from a stream. Note: we leverage the default Serialized form
|
||||
*/
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* {@code SerialDatalink} object.
|
||||
*/
|
||||
static final long serialVersionUID = 2826907821828733626L;
|
||||
}
|
56
jdkSrc/jdk8/javax/sql/rowset/serial/SerialException.java
Normal file
56
jdkSrc/jdk8/javax/sql/rowset/serial/SerialException.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Indicates and an error with the serialization or de-serialization of
|
||||
* SQL types such as <code>BLOB, CLOB, STRUCT or ARRAY</code> in
|
||||
* addition to SQL types such as <code>DATALINK and JAVAOBJECT</code>
|
||||
*
|
||||
*/
|
||||
public class SerialException extends java.sql.SQLException {
|
||||
|
||||
/**
|
||||
* Creates a new <code>SerialException</code> without a
|
||||
* message.
|
||||
*/
|
||||
public SerialException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>SerialException</code> with the
|
||||
* specified message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public SerialException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
static final long serialVersionUID = -489794565168592690L;
|
||||
}
|
281
jdkSrc/jdk8/javax/sql/rowset/serial/SerialJavaObject.java
Normal file
281
jdkSrc/jdk8/javax/sql/rowset/serial/SerialJavaObject.java
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Vector;
|
||||
import javax.sql.rowset.RowSetWarning;
|
||||
import sun.reflect.CallerSensitive;
|
||||
import sun.reflect.Reflection;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* A serializable mapping in the Java programming language of an SQL
|
||||
* <code>JAVA_OBJECT</code> value. Assuming the Java object
|
||||
* implements the <code>Serializable</code> interface, this class simply wraps the
|
||||
* serialization process.
|
||||
* <P>
|
||||
* If however, the serialization is not possible because
|
||||
* the Java object is not immediately serializable, this class will
|
||||
* attempt to serialize all non-static members to permit the object
|
||||
* state to be serialized.
|
||||
* Static or transient fields cannot be serialized; an attempt to serialize
|
||||
* them will result in a <code>SerialException</code> object being thrown.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* A SerialJavaObject is not safe for use by multiple concurrent threads. If a
|
||||
* SerialJavaObject is to be used by more than one thread then access to the
|
||||
* SerialJavaObject should be controlled by appropriate synchronization.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
*/
|
||||
public class SerialJavaObject implements Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* Placeholder for object to be serialized.
|
||||
*/
|
||||
private Object obj;
|
||||
|
||||
|
||||
/**
|
||||
* Placeholder for all fields in the <code>JavaObject</code> being serialized.
|
||||
*/
|
||||
private transient Field[] fields;
|
||||
|
||||
/**
|
||||
* Constructor for <code>SerialJavaObject</code> helper class.
|
||||
* <p>
|
||||
*
|
||||
* @param obj the Java <code>Object</code> to be serialized
|
||||
* @throws SerialException if the object is found not to be serializable
|
||||
*/
|
||||
public SerialJavaObject(Object obj) throws SerialException {
|
||||
|
||||
// if any static fields are found, an exception
|
||||
// should be thrown
|
||||
|
||||
|
||||
// get Class. Object instance should always be available
|
||||
Class<?> c = obj.getClass();
|
||||
|
||||
// determine if object implements Serializable i/f
|
||||
if (!(obj instanceof java.io.Serializable)) {
|
||||
setWarning(new RowSetWarning("Warning, the object passed to the constructor does not implement Serializable"));
|
||||
}
|
||||
|
||||
// can only determine public fields (obviously). If
|
||||
// any of these are static, this should invalidate
|
||||
// the action of attempting to persist these fields
|
||||
// in a serialized form
|
||||
fields = c.getFields();
|
||||
|
||||
if (hasStaticFields(fields)) {
|
||||
throw new SerialException("Located static fields in " +
|
||||
"object instance. Cannot serialize");
|
||||
}
|
||||
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Object</code> that is a copy of this <code>SerialJavaObject</code>
|
||||
* object.
|
||||
*
|
||||
* @return a copy of this <code>SerialJavaObject</code> object as an
|
||||
* <code>Object</code> in the Java programming language
|
||||
* @throws SerialException if the instance is corrupt
|
||||
*/
|
||||
public Object getObject() throws SerialException {
|
||||
return this.obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>Field</code> objects that contains each
|
||||
* field of the object that this helper class is serializing.
|
||||
*
|
||||
* @return an array of <code>Field</code> objects
|
||||
* @throws SerialException if an error is encountered accessing
|
||||
* the serialized object
|
||||
* @throws SecurityException If a security manager, <i>s</i>, is present
|
||||
* and the caller's class loader is not the same as or an
|
||||
* ancestor of the class loader for the class of the
|
||||
* {@linkplain #getObject object} being serialized
|
||||
* and invocation of {@link SecurityManager#checkPackageAccess
|
||||
* s.checkPackageAccess()} denies access to the package
|
||||
* of that class.
|
||||
* @see Class#getFields
|
||||
*/
|
||||
@CallerSensitive
|
||||
public Field[] getFields() throws SerialException {
|
||||
if (fields != null) {
|
||||
Class<?> c = this.obj.getClass();
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
/*
|
||||
* Check if the caller is allowed to access the specified class's package.
|
||||
* If access is denied, throw a SecurityException.
|
||||
*/
|
||||
Class<?> caller = sun.reflect.Reflection.getCallerClass();
|
||||
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
|
||||
c.getClassLoader())) {
|
||||
ReflectUtil.checkPackageAccess(c);
|
||||
}
|
||||
}
|
||||
return c.getFields();
|
||||
} else {
|
||||
throw new SerialException("SerialJavaObject does not contain" +
|
||||
" a serialized object instance");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* <code>SerialJavaObject</code> object.
|
||||
*/
|
||||
static final long serialVersionUID = -1465795139032831023L;
|
||||
|
||||
/**
|
||||
* A container for the warnings issued on this <code>SerialJavaObject</code>
|
||||
* object. When there are multiple warnings, each warning is chained to the
|
||||
* previous warning.
|
||||
*/
|
||||
Vector<RowSetWarning> chain;
|
||||
|
||||
/**
|
||||
* Compares this SerialJavaObject to the specified object.
|
||||
* The result is {@code true} if and only if the argument
|
||||
* is not {@code null} and is a {@code SerialJavaObject}
|
||||
* object that is identical to this object
|
||||
*
|
||||
* @param o The object to compare this {@code SerialJavaObject} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialJavaObject}
|
||||
* equivalent to this SerialJavaObject, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof SerialJavaObject) {
|
||||
SerialJavaObject sjo = (SerialJavaObject) o;
|
||||
return obj.equals(sjo.obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this SerialJavaObject. The hash code for a
|
||||
* {@code SerialJavaObject} object is taken as the hash code of
|
||||
* the {@code Object} it stores
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return 31 + obj.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialJavaObject}.
|
||||
*
|
||||
* @return a clone of this SerialJavaObject
|
||||
*/
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialJavaObject sjo = (SerialJavaObject) super.clone();
|
||||
sjo.fields = Arrays.copyOf(fields, fields.length);
|
||||
if (chain != null)
|
||||
sjo.chain = new Vector<>(chain);
|
||||
return sjo;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given warning.
|
||||
*/
|
||||
private void setWarning(RowSetWarning e) {
|
||||
if (chain == null) {
|
||||
chain = new Vector<>();
|
||||
}
|
||||
chain.add(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the {@code SerialJavaObject}
|
||||
* from a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields1 = s.readFields();
|
||||
@SuppressWarnings("unchecked")
|
||||
Vector<RowSetWarning> tmp = (Vector<RowSetWarning>)fields1.get("chain", null);
|
||||
if (tmp != null)
|
||||
chain = new Vector<>(tmp);
|
||||
|
||||
obj = fields1.get("obj", null);
|
||||
if (obj != null) {
|
||||
fields = obj.getClass().getFields();
|
||||
if(hasStaticFields(fields))
|
||||
throw new IOException("Located static fields in " +
|
||||
"object instance. Cannot serialize");
|
||||
} else {
|
||||
throw new IOException("Object cannot be null!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the {@code SerialJavaObject}
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException {
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("obj", obj);
|
||||
fields.put("chain", chain);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if there are any Static Fields in this object
|
||||
*/
|
||||
private static boolean hasStaticFields(Field[] fields) {
|
||||
for (Field field : fields) {
|
||||
if ( field.getModifiers() == Modifier.STATIC) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
257
jdkSrc/jdk8/javax/sql/rowset/serial/SerialRef.java
Normal file
257
jdkSrc/jdk8/javax/sql/rowset/serial/SerialRef.java
Normal file
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A serialized mapping of a <code>Ref</code> object, which is the mapping in the
|
||||
* Java programming language of an SQL <code>REF</code> value.
|
||||
* <p>
|
||||
* The <code>SerialRef</code> class provides a constructor for
|
||||
* creating a <code>SerialRef</code> instance from a <code>Ref</code>
|
||||
* object and provides methods for getting and setting the <code>Ref</code> object.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* A SerialRef is not safe for use by multiple concurrent threads. If a
|
||||
* SerialRef is to be used by more than one thread then access to the SerialRef
|
||||
* should be controlled by appropriate synchronization.
|
||||
*
|
||||
*/
|
||||
public class SerialRef implements Ref, Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* String containing the base type name.
|
||||
* @serial
|
||||
*/
|
||||
private String baseTypeName;
|
||||
|
||||
/**
|
||||
* This will store the type <code>Ref</code> as an <code>Object</code>.
|
||||
*/
|
||||
private Object object;
|
||||
|
||||
/**
|
||||
* Private copy of the Ref reference.
|
||||
*/
|
||||
private Ref reference;
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialRef</code> object from the given <code>Ref</code>
|
||||
* object.
|
||||
*
|
||||
* @param ref a Ref object; cannot be <code>null</code>
|
||||
* @throws SQLException if a database access occurs; if <code>ref</code>
|
||||
* is <code>null</code>; or if the <code>Ref</code> object returns a
|
||||
* <code>null</code> value base type name.
|
||||
* @throws SerialException if an error occurs serializing the <code>Ref</code>
|
||||
* object
|
||||
*/
|
||||
public SerialRef(Ref ref) throws SerialException, SQLException {
|
||||
if (ref == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialRef object " +
|
||||
"with a null Ref object");
|
||||
}
|
||||
reference = ref;
|
||||
object = ref;
|
||||
if (ref.getBaseTypeName() == null) {
|
||||
throw new SQLException("Cannot instantiate a SerialRef object " +
|
||||
"that returns a null base type name");
|
||||
} else {
|
||||
baseTypeName = ref.getBaseTypeName();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing the base type name of the <code>Ref</code>.
|
||||
*
|
||||
* @return a string of the base type name of the Ref
|
||||
* @throws SerialException in no Ref object has been set
|
||||
*/
|
||||
public String getBaseTypeName() throws SerialException {
|
||||
return baseTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Object</code> representing the SQL structured type
|
||||
* to which this <code>SerialRef</code> object refers. The attributes
|
||||
* of the structured type are mapped according to the given type map.
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object containing zero or
|
||||
* more entries, with each entry consisting of 1) a <code>String</code>
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return an object instance resolved from the Ref reference and mapped
|
||||
* according to the supplied type map
|
||||
* @throws SerialException if an error is encountered in the reference
|
||||
* resolution
|
||||
*/
|
||||
public Object getObject(java.util.Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
map = new Hashtable<String, Class<?>>(map);
|
||||
if (object != null) {
|
||||
return map.get(object);
|
||||
} else {
|
||||
throw new SerialException("The object is not set");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Object</code> representing the SQL structured type
|
||||
* to which this <code>SerialRef</code> object refers.
|
||||
*
|
||||
* @return an object instance resolved from the Ref reference
|
||||
* @throws SerialException if an error is encountered in the reference
|
||||
* resolution
|
||||
*/
|
||||
public Object getObject() throws SerialException {
|
||||
|
||||
if (reference != null) {
|
||||
try {
|
||||
return reference.getObject();
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException("SQLException: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (object != null) {
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
throw new SerialException("The object is not set");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SQL structured type that this <code>SerialRef</code> object
|
||||
* references to the given <code>Object</code> object.
|
||||
*
|
||||
* @param obj an <code>Object</code> representing the SQL structured type
|
||||
* to be referenced
|
||||
* @throws SerialException if an error is encountered generating the
|
||||
* the structured type referenced by this <code>SerialRef</code> object
|
||||
*/
|
||||
public void setObject(Object obj) throws SerialException {
|
||||
try {
|
||||
reference.setObject(obj);
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException("SQLException: " + e.getMessage());
|
||||
}
|
||||
object = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialRef to the specified object. The result is {@code
|
||||
* true} if and only if the argument is not {@code null} and is a {@code
|
||||
* SerialRef} object that represents the same object as this
|
||||
* object.
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialRef} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialRef}
|
||||
* equivalent to this SerialRef, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if(obj instanceof SerialRef) {
|
||||
SerialRef ref = (SerialRef)obj;
|
||||
return baseTypeName.equals(ref.baseTypeName) &&
|
||||
object.equals(ref.object);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialRef}.
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (31 + object.hashCode()) * 31 + baseTypeName.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialRef}.
|
||||
* The underlying {@code Ref} object will be set to null.
|
||||
*
|
||||
* @return a clone of this SerialRef
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialRef ref = (SerialRef) super.clone();
|
||||
ref.reference = null;
|
||||
return ref;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the SerialRef from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
object = fields.get("object", null);
|
||||
baseTypeName = (String) fields.get("baseTypeName", null);
|
||||
reference = (Ref) fields.get("reference", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the SerialRef
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("baseTypeName", baseTypeName);
|
||||
fields.put("object", object);
|
||||
// Note: this check to see if it is an instance of Serializable
|
||||
// is for backwards compatibiity
|
||||
fields.put("reference", reference instanceof Serializable ? reference : null);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this <code>SerialRef</code>
|
||||
* object.
|
||||
*/
|
||||
static final long serialVersionUID = -4727123500609662274L;
|
||||
|
||||
|
||||
}
|
347
jdkSrc/jdk8/javax/sql/rowset/serial/SerialStruct.java
Normal file
347
jdkSrc/jdk8/javax/sql/rowset/serial/SerialStruct.java
Normal file
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.serial;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.sql.rowset.*;
|
||||
|
||||
/**
|
||||
* A serialized mapping in the Java programming language of an SQL
|
||||
* structured type. Each attribute that is not already serialized
|
||||
* is mapped to a serialized form, and if an attribute is itself
|
||||
* a structured type, each of its attributes that is not already
|
||||
* serialized is mapped to a serialized form.
|
||||
* <P>
|
||||
* In addition, the structured type is custom mapped to a class in the
|
||||
* Java programming language if there is such a mapping, as are
|
||||
* its attributes, if appropriate.
|
||||
* <P>
|
||||
* The <code>SerialStruct</code> class provides a constructor for creating
|
||||
* an instance from a <code>Struct</code> object, a method for retrieving
|
||||
* the SQL type name of the SQL structured type in the database, and methods
|
||||
* for retrieving its attribute values.
|
||||
*
|
||||
* <h3> Thread safety </h3>
|
||||
*
|
||||
* A SerialStruct is not safe for use by multiple concurrent threads. If a
|
||||
* SerialStruct is to be used by more than one thread then access to the
|
||||
* SerialStruct should be controlled by appropriate synchronization.
|
||||
*
|
||||
*/
|
||||
public class SerialStruct implements Struct, Serializable, Cloneable {
|
||||
|
||||
|
||||
/**
|
||||
* The SQL type name for the structured type that this
|
||||
* <code>SerialStruct</code> object represents. This is the name
|
||||
* used in the SQL definition of the SQL structured type.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private String SQLTypeName;
|
||||
|
||||
/**
|
||||
* An array of <code>Object</code> instances in which each
|
||||
* element is an attribute of the SQL structured type that this
|
||||
* <code>SerialStruct</code> object represents. The attributes are
|
||||
* ordered according to their order in the definition of the
|
||||
* SQL structured type.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private Object attribs[];
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialStruct</code> object from the given
|
||||
* <code>Struct</code> object, using the given <code>java.util.Map</code>
|
||||
* object for custom mapping the SQL structured type or any of its
|
||||
* attributes that are SQL structured types.
|
||||
*
|
||||
* @param in an instance of {@code Struct}
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @throws SerialException if an error occurs
|
||||
* @see java.sql.Struct
|
||||
*/
|
||||
public SerialStruct(Struct in, Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
// get the type name
|
||||
SQLTypeName = in.getSQLTypeName();
|
||||
System.out.println("SQLTypeName: " + SQLTypeName);
|
||||
|
||||
// get the attributes of the struct
|
||||
attribs = in.getAttributes(map);
|
||||
|
||||
/*
|
||||
* the array may contain further Structs
|
||||
* and/or classes that have been mapped,
|
||||
* other types that we have to serialize
|
||||
*/
|
||||
mapToSerial(map);
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>SerialStruct</code> object from the
|
||||
* given <code>SQLData</code> object, using the given type
|
||||
* map to custom map it to a class in the Java programming
|
||||
* language. The type map gives the SQL type and the class
|
||||
* to which it is mapped. The <code>SQLData</code> object
|
||||
* defines the class to which the SQL type will be mapped.
|
||||
*
|
||||
* @param in an instance of the <code>SQLData</code> class
|
||||
* that defines the mapping of the SQL structured
|
||||
* type to one or more objects in the Java programming language
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public SerialStruct(SQLData in, Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
|
||||
try {
|
||||
|
||||
//set the type name
|
||||
SQLTypeName = in.getSQLTypeName();
|
||||
|
||||
Vector<Object> tmp = new Vector<>();
|
||||
in.writeSQL(new SQLOutputImpl(tmp, map));
|
||||
attribs = tmp.toArray();
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the SQL type name for this <code>SerialStruct</code>
|
||||
* object. This is the name used in the SQL definition of the
|
||||
* structured type
|
||||
*
|
||||
* @return a <code>String</code> object representing the SQL
|
||||
* type name for the SQL structured type that this
|
||||
* <code>SerialStruct</code> object represents
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public String getSQLTypeName() throws SerialException {
|
||||
return SQLTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an array of <code>Object</code> values containing the
|
||||
* attributes of the SQL structured type that this
|
||||
* <code>SerialStruct</code> object represents.
|
||||
*
|
||||
* @return an array of <code>Object</code> values, with each
|
||||
* element being an attribute of the SQL structured type
|
||||
* that this <code>SerialStruct</code> object represents
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public Object[] getAttributes() throws SerialException {
|
||||
Object[] val = this.attribs;
|
||||
return (val == null) ? null : Arrays.copyOf(val, val.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the attributes for the SQL structured type that
|
||||
* this <code>SerialStruct</code> represents as an array of
|
||||
* <code>Object</code> values, using the given type map for
|
||||
* custom mapping if appropriate.
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @return an array of <code>Object</code> values, with each
|
||||
* element being an attribute of the SQL structured
|
||||
* type that this <code>SerialStruct</code> object
|
||||
* represents
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
public Object[] getAttributes(Map<String,Class<?>> map)
|
||||
throws SerialException
|
||||
{
|
||||
Object[] val = this.attribs;
|
||||
return (val == null) ? null : Arrays.copyOf(val, val.length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Maps attributes of an SQL structured type that are not
|
||||
* serialized to a serialized form, using the given type map
|
||||
* for custom mapping when appropriate. The following types
|
||||
* in the Java programming language are mapped to their
|
||||
* serialized forms: <code>Struct</code>, <code>SQLData</code>,
|
||||
* <code>Ref</code>, <code>Blob</code>, <code>Clob</code>, and
|
||||
* <code>Array</code>.
|
||||
* <P>
|
||||
* This method is called internally and is not used by an
|
||||
* application programmer.
|
||||
*
|
||||
* @param map a <code>java.util.Map</code> object in which
|
||||
* each entry consists of 1) a <code>String</code> object
|
||||
* giving the fully qualified name of a UDT and 2) the
|
||||
* <code>Class</code> object for the <code>SQLData</code> implementation
|
||||
* that defines how the UDT is to be mapped
|
||||
* @throws SerialException if an error occurs
|
||||
*/
|
||||
private void mapToSerial(Map<String,Class<?>> map) throws SerialException {
|
||||
|
||||
try {
|
||||
|
||||
for (int i = 0; i < attribs.length; i++) {
|
||||
if (attribs[i] instanceof Struct) {
|
||||
attribs[i] = new SerialStruct((Struct)attribs[i], map);
|
||||
} else if (attribs[i] instanceof SQLData) {
|
||||
attribs[i] = new SerialStruct((SQLData)attribs[i], map);
|
||||
} else if (attribs[i] instanceof Blob) {
|
||||
attribs[i] = new SerialBlob((Blob)attribs[i]);
|
||||
} else if (attribs[i] instanceof Clob) {
|
||||
attribs[i] = new SerialClob((Clob)attribs[i]);
|
||||
} else if (attribs[i] instanceof Ref) {
|
||||
attribs[i] = new SerialRef((Ref)attribs[i]);
|
||||
} else if (attribs[i] instanceof java.sql.Array) {
|
||||
attribs[i] = new SerialArray((java.sql.Array)attribs[i], map);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new SerialException(e.getMessage());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this SerialStruct to the specified object. The result is
|
||||
* {@code true} if and only if the argument is not {@code null} and is a
|
||||
* {@code SerialStruct} object whose attributes are identical to this
|
||||
* object's attributes
|
||||
*
|
||||
* @param obj The object to compare this {@code SerialStruct} against
|
||||
*
|
||||
* @return {@code true} if the given object represents a {@code SerialStruct}
|
||||
* equivalent to this SerialStruct, {@code false} otherwise
|
||||
*
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof SerialStruct) {
|
||||
SerialStruct ss = (SerialStruct)obj;
|
||||
return SQLTypeName.equals(ss.SQLTypeName) &&
|
||||
Arrays.equals(attribs, ss.attribs);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this {@code SerialStruct}. The hash code for a
|
||||
* {@code SerialStruct} object is computed using the hash codes
|
||||
* of the attributes of the {@code SerialStruct} object and its
|
||||
* {@code SQLTypeName}
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((31 + Arrays.hashCode(attribs)) * 31) * 31
|
||||
+ SQLTypeName.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this {@code SerialStruct}. The copy will contain a
|
||||
* reference to a clone of the underlying attribs array, not a reference
|
||||
* to the original underlying attribs array of this {@code SerialStruct} object.
|
||||
*
|
||||
* @return a clone of this SerialStruct
|
||||
*/
|
||||
public Object clone() {
|
||||
try {
|
||||
SerialStruct ss = (SerialStruct) super.clone();
|
||||
ss.attribs = Arrays.copyOf(attribs, attribs.length);
|
||||
return ss;
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
// this shouldn't happen, since we are Cloneable
|
||||
throw new InternalError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* readObject is called to restore the state of the {@code SerialStruct} from
|
||||
* a stream.
|
||||
*/
|
||||
private void readObject(ObjectInputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectInputStream.GetField fields = s.readFields();
|
||||
Object[] tmp = (Object[])fields.get("attribs", null);
|
||||
attribs = tmp == null ? null : tmp.clone();
|
||||
SQLTypeName = (String)fields.get("SQLTypeName", null);
|
||||
}
|
||||
|
||||
/**
|
||||
* writeObject is called to save the state of the {@code SerialStruct}
|
||||
* to a stream.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ObjectOutputStream.PutField fields = s.putFields();
|
||||
fields.put("attribs", attribs);
|
||||
fields.put("SQLTypeName", SQLTypeName);
|
||||
s.writeFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* The identifier that assists in the serialization of this
|
||||
* <code>SerialStruct</code> object.
|
||||
*/
|
||||
static final long serialVersionUID = -8322445504027483372L;
|
||||
}
|
967
jdkSrc/jdk8/javax/sql/rowset/spi/SyncFactory.java
Normal file
967
jdkSrc/jdk8/javax/sql/rowset/spi/SyncFactory.java
Normal file
@@ -0,0 +1,967 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import java.util.logging.*;
|
||||
import java.util.*;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
import javax.naming.*;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
/**
|
||||
* The Service Provider Interface (SPI) mechanism that generates <code>SyncProvider</code>
|
||||
* instances to be used by disconnected <code>RowSet</code> objects.
|
||||
* The <code>SyncProvider</code> instances in turn provide the
|
||||
* <code>javax.sql.RowSetReader</code> object the <code>RowSet</code> object
|
||||
* needs to populate itself with data and the
|
||||
* <code>javax.sql.RowSetWriter</code> object it needs to
|
||||
* propagate changes to its
|
||||
* data back to the underlying data source.
|
||||
* <P>
|
||||
* Because the methods in the <code>SyncFactory</code> class are all static,
|
||||
* there is only one <code>SyncFactory</code> object
|
||||
* per Java VM at any one time. This ensures that there is a single source from which a
|
||||
* <code>RowSet</code> implementation can obtain its <code>SyncProvider</code>
|
||||
* implementation.
|
||||
*
|
||||
* <h3>1.0 Overview</h3>
|
||||
* The <code>SyncFactory</code> class provides an internal registry of available
|
||||
* synchronization provider implementations (<code>SyncProvider</code> objects).
|
||||
* This registry may be queried to determine which
|
||||
* synchronization providers are available.
|
||||
* The following line of code gets an enumeration of the providers currently registered.
|
||||
* <PRE>
|
||||
* java.util.Enumeration e = SyncFactory.getRegisteredProviders();
|
||||
* </PRE>
|
||||
* All standard <code>RowSet</code> implementations must provide at least two providers:
|
||||
* <UL>
|
||||
* <LI>an optimistic provider for use with a <code>CachedRowSet</code> implementation
|
||||
* or an implementation derived from it
|
||||
* <LI>an XML provider, which is used for reading and writing XML, such as with
|
||||
* <code>WebRowSet</code> objects
|
||||
* </UL>
|
||||
* Note that the JDBC RowSet Implementations include the <code>SyncProvider</code>
|
||||
* implementations <code>RIOptimisticProvider</code> and <code>RIXmlProvider</code>,
|
||||
* which satisfy this requirement.
|
||||
* <P>
|
||||
* The <code>SyncFactory</code> class provides accessor methods to assist
|
||||
* applications in determining which synchronization providers are currently
|
||||
* registered with the <code>SyncFactory</code>.
|
||||
* <p>
|
||||
* Other methods let <code>RowSet</code> persistence providers be
|
||||
* registered or de-registered with the factory mechanism. This
|
||||
* allows additional synchronization provider implementations to be made
|
||||
* available to <code>RowSet</code> objects at run time.
|
||||
* <p>
|
||||
* Applications can apply a degree of filtering to determine the level of
|
||||
* synchronization that a <code>SyncProvider</code> implementation offers.
|
||||
* The following criteria determine whether a provider is
|
||||
* made available to a <code>RowSet</code> object:
|
||||
* <ol>
|
||||
* <li>If a particular provider is specified by a <code>RowSet</code> object, and
|
||||
* the <code>SyncFactory</code> does not contain a reference to this provider,
|
||||
* a <code>SyncFactoryException</code> is thrown stating that the synchronization
|
||||
* provider could not be found.
|
||||
*
|
||||
* <li>If a <code>RowSet</code> implementation is instantiated with a specified
|
||||
* provider and the specified provider has been properly registered, the
|
||||
* requested provider is supplied. Otherwise a <code>SyncFactoryException</code>
|
||||
* is thrown.
|
||||
*
|
||||
* <li>If a <code>RowSet</code> object does not specify a
|
||||
* <code>SyncProvider</code> implementation and no additional
|
||||
* <code>SyncProvider</code> implementations are available, the reference
|
||||
* implementation providers are supplied.
|
||||
* </ol>
|
||||
* <h3>2.0 Registering <code>SyncProvider</code> Implementations</h3>
|
||||
* <p>
|
||||
* Both vendors and developers can register <code>SyncProvider</code>
|
||||
* implementations using one of the following mechanisms.
|
||||
* <ul>
|
||||
* <LI><B>Using the command line</B><BR>
|
||||
* The name of the provider is supplied on the command line, which will add
|
||||
* the provider to the system properties.
|
||||
* For example:
|
||||
* <PRE>
|
||||
* -Drowset.provider.classname=com.fred.providers.HighAvailabilityProvider
|
||||
* </PRE>
|
||||
* <li><b>Using the Standard Properties File</b><BR>
|
||||
* The reference implementation is targeted
|
||||
* to ship with J2SE 1.5, which will include an additional resource file
|
||||
* that may be edited by hand. Here is an example of the properties file
|
||||
* included in the reference implementation:
|
||||
* <PRE>
|
||||
* #Default JDBC RowSet sync providers listing
|
||||
* #
|
||||
*
|
||||
* # Optimistic synchronization provider
|
||||
* rowset.provider.classname.0=com.sun.rowset.providers.RIOptimisticProvider
|
||||
* rowset.provider.vendor.0=Oracle Corporation
|
||||
* rowset.provider.version.0=1.0
|
||||
*
|
||||
* # XML Provider using standard XML schema
|
||||
* rowset.provider.classname.1=com.sun.rowset.providers.RIXMLProvider
|
||||
* rowset.provider.vendor.1=Oracle Corporation
|
||||
* rowset.provider.version.1=1.0
|
||||
* </PRE>
|
||||
* The <code>SyncFactory</code> checks this file and registers the
|
||||
* <code>SyncProvider</code> implementations that it contains. A
|
||||
* developer or vendor can add other implementations to this file.
|
||||
* For example, here is a possible addition:
|
||||
* <PRE>
|
||||
* rowset.provider.classname.2=com.fred.providers.HighAvailabilityProvider
|
||||
* rowset.provider.vendor.2=Fred, Inc.
|
||||
* rowset.provider.version.2=1.0
|
||||
* </PRE>
|
||||
*
|
||||
* <li><b>Using a JNDI Context</b><BR>
|
||||
* Available providers can be registered on a JNDI
|
||||
* context, and the <code>SyncFactory</code> will attempt to load
|
||||
* <code>SyncProvider</code> implementations from that JNDI context.
|
||||
* For example, the following code fragment registers a provider implementation
|
||||
* on a JNDI context. This is something a deployer would normally do. In this
|
||||
* example, <code>MyProvider</code> is being registered on a CosNaming
|
||||
* namespace, which is the namespace used by J2EE resources.
|
||||
* <PRE>
|
||||
* import javax.naming.*;
|
||||
*
|
||||
* Hashtable svrEnv = new Hashtable();
|
||||
* srvEnv.put(Context.INITIAL_CONTEXT_FACTORY, "CosNaming");
|
||||
*
|
||||
* Context ctx = new InitialContext(svrEnv);
|
||||
* com.fred.providers.MyProvider = new MyProvider();
|
||||
* ctx.rebind("providers/MyProvider", syncProvider);
|
||||
* </PRE>
|
||||
* </ul>
|
||||
* Next, an application will register the JNDI context with the
|
||||
* <code>SyncFactory</code> instance. This allows the <code>SyncFactory</code>
|
||||
* to browse within the JNDI context looking for <code>SyncProvider</code>
|
||||
* implementations.
|
||||
* <PRE>
|
||||
* Hashtable appEnv = new Hashtable();
|
||||
* appEnv.put(Context.INITIAL_CONTEXT_FACTORY, "CosNaming");
|
||||
* appEnv.put(Context.PROVIDER_URL, "iiop://hostname/providers");
|
||||
* Context ctx = new InitialContext(appEnv);
|
||||
*
|
||||
* SyncFactory.registerJNDIContext(ctx);
|
||||
* </PRE>
|
||||
* If a <code>RowSet</code> object attempts to obtain a <code>MyProvider</code>
|
||||
* object, the <code>SyncFactory</code> will try to locate it. First it searches
|
||||
* for it in the system properties, then it looks in the resource files, and
|
||||
* finally it checks the JNDI context that has been set. The <code>SyncFactory</code>
|
||||
* instance verifies that the requested provider is a valid extension of the
|
||||
* <code>SyncProvider</code> abstract class and then gives it to the
|
||||
* <code>RowSet</code> object. In the following code fragment, a new
|
||||
* <code>CachedRowSet</code> object is created and initialized with
|
||||
* <i>env</i>, which contains the binding to <code>MyProvider</code>.
|
||||
* <PRE>
|
||||
* Hashtable env = new Hashtable();
|
||||
* env.put(SyncFactory.ROWSET_SYNC_PROVIDER, "com.fred.providers.MyProvider");
|
||||
* CachedRowSet crs = new com.sun.rowset.CachedRowSetImpl(env);
|
||||
* </PRE>
|
||||
* Further details on these mechanisms are available in the
|
||||
* <code>javax.sql.rowset.spi</code> package specification.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @see javax.sql.rowset.spi.SyncProvider
|
||||
* @see javax.sql.rowset.spi.SyncFactoryException
|
||||
*/
|
||||
public class SyncFactory {
|
||||
|
||||
/**
|
||||
* Creates a new <code>SyncFactory</code> object, which is the singleton
|
||||
* instance.
|
||||
* Having a private constructor guarantees that no more than
|
||||
* one <code>SyncProvider</code> object can exist at a time.
|
||||
*/
|
||||
private SyncFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard property-id for a synchronization provider implementation
|
||||
* name.
|
||||
*/
|
||||
public static final String ROWSET_SYNC_PROVIDER =
|
||||
"rowset.provider.classname";
|
||||
/**
|
||||
* The standard property-id for a synchronization provider implementation
|
||||
* vendor name.
|
||||
*/
|
||||
public static final String ROWSET_SYNC_VENDOR =
|
||||
"rowset.provider.vendor";
|
||||
/**
|
||||
* The standard property-id for a synchronization provider implementation
|
||||
* version tag.
|
||||
*/
|
||||
public static final String ROWSET_SYNC_PROVIDER_VERSION =
|
||||
"rowset.provider.version";
|
||||
/**
|
||||
* The standard resource file name.
|
||||
*/
|
||||
private static String ROWSET_PROPERTIES = "rowset.properties";
|
||||
|
||||
/**
|
||||
* Permission required to invoke setJNDIContext and setLogger
|
||||
*/
|
||||
private static final SQLPermission SET_SYNCFACTORY_PERMISSION =
|
||||
new SQLPermission("setSyncFactory");
|
||||
/**
|
||||
* The initial JNDI context where <code>SyncProvider</code> implementations can
|
||||
* be stored and from which they can be invoked.
|
||||
*/
|
||||
private static Context ic;
|
||||
/**
|
||||
* The <code>Logger</code> object to be used by the <code>SyncFactory</code>.
|
||||
*/
|
||||
private static volatile Logger rsLogger;
|
||||
|
||||
/**
|
||||
* The registry of available <code>SyncProvider</code> implementations.
|
||||
* See section 2.0 of the class comment for <code>SyncFactory</code> for an
|
||||
* explanation of how a provider can be added to this registry.
|
||||
*/
|
||||
private static Hashtable<String, SyncProvider> implementations;
|
||||
|
||||
/**
|
||||
* Adds the the given synchronization provider to the factory register. Guidelines
|
||||
* are provided in the <code>SyncProvider</code> specification for the
|
||||
* required naming conventions for <code>SyncProvider</code>
|
||||
* implementations.
|
||||
* <p>
|
||||
* Synchronization providers bound to a JNDI context can be
|
||||
* registered by binding a SyncProvider instance to a JNDI namespace.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* SyncProvider p = new MySyncProvider();
|
||||
* InitialContext ic = new InitialContext();
|
||||
* ic.bind ("jdbc/rowset/MySyncProvider", p);
|
||||
* } </pre>
|
||||
*
|
||||
* Furthermore, an initial JNDI context should be set with the
|
||||
* <code>SyncFactory</code> using the <code>setJNDIContext</code> method.
|
||||
* The <code>SyncFactory</code> leverages this context to search for
|
||||
* available <code>SyncProvider</code> objects bound to the JNDI
|
||||
* context and its child nodes.
|
||||
*
|
||||
* @param providerID A <code>String</code> object with the unique ID of the
|
||||
* synchronization provider being registered
|
||||
* @throws SyncFactoryException if an attempt is made to supply an empty
|
||||
* or null provider name
|
||||
* @see #setJNDIContext
|
||||
*/
|
||||
public static synchronized void registerProvider(String providerID)
|
||||
throws SyncFactoryException {
|
||||
|
||||
ProviderImpl impl = new ProviderImpl();
|
||||
impl.setClassname(providerID);
|
||||
initMapIfNecessary();
|
||||
implementations.put(providerID, impl);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>SyncFactory</code> singleton.
|
||||
*
|
||||
* @return the <code>SyncFactory</code> instance
|
||||
*/
|
||||
public static SyncFactory getSyncFactory() {
|
||||
/*
|
||||
* Using Initialization on Demand Holder idiom as
|
||||
* Effective Java 2nd Edition,ITEM 71, indicates it is more performant
|
||||
* than the Double-Check Locking idiom.
|
||||
*/
|
||||
return SyncFactoryHolder.factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the designated currently registered synchronization provider from the
|
||||
* Factory SPI register.
|
||||
*
|
||||
* @param providerID The unique-id of the synchronization provider
|
||||
* @throws SyncFactoryException If an attempt is made to
|
||||
* unregister a SyncProvider implementation that was not registered.
|
||||
*/
|
||||
public static synchronized void unregisterProvider(String providerID)
|
||||
throws SyncFactoryException {
|
||||
initMapIfNecessary();
|
||||
if (implementations.containsKey(providerID)) {
|
||||
implementations.remove(providerID);
|
||||
}
|
||||
}
|
||||
private static String colon = ":";
|
||||
private static String strFileSep = "/";
|
||||
|
||||
private static synchronized void initMapIfNecessary() throws SyncFactoryException {
|
||||
|
||||
// Local implementation class names and keys from Properties
|
||||
// file, translate names into Class objects using Class.forName
|
||||
// and store mappings
|
||||
final Properties properties = new Properties();
|
||||
|
||||
if (implementations == null) {
|
||||
implementations = new Hashtable<>();
|
||||
|
||||
try {
|
||||
|
||||
// check if user is supplying his Synchronisation Provider
|
||||
// Implementation if not using Oracle's implementation.
|
||||
// properties.load(new FileInputStream(ROWSET_PROPERTIES));
|
||||
|
||||
// The rowset.properties needs to be in jdk/jre/lib when
|
||||
// integrated with jdk.
|
||||
// else it should be picked from -D option from command line.
|
||||
|
||||
// -Drowset.properties will add to standard properties. Similar
|
||||
// keys will over-write
|
||||
|
||||
/*
|
||||
* Dependent on application
|
||||
*/
|
||||
String strRowsetProperties;
|
||||
try {
|
||||
strRowsetProperties = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty("rowset.properties");
|
||||
}
|
||||
}, null, new PropertyPermission("rowset.properties", "read"));
|
||||
} catch (Exception ex) {
|
||||
System.out.println("errorget rowset.properties: " + ex);
|
||||
strRowsetProperties = null;
|
||||
};
|
||||
|
||||
if (strRowsetProperties != null) {
|
||||
// Load user's implementation of SyncProvider
|
||||
// here. -Drowset.properties=/abc/def/pqr.txt
|
||||
ROWSET_PROPERTIES = strRowsetProperties;
|
||||
try (FileInputStream fis = new FileInputStream(ROWSET_PROPERTIES)) {
|
||||
properties.load(fis);
|
||||
}
|
||||
parseProperties(properties);
|
||||
}
|
||||
|
||||
/*
|
||||
* Always available
|
||||
*/
|
||||
ROWSET_PROPERTIES = "javax" + strFileSep + "sql" +
|
||||
strFileSep + "rowset" + strFileSep +
|
||||
"rowset.properties";
|
||||
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
||||
try (InputStream stream = (cl == null) ?
|
||||
ClassLoader.getSystemResourceAsStream(ROWSET_PROPERTIES)
|
||||
: cl.getResourceAsStream(ROWSET_PROPERTIES)) {
|
||||
if (stream == null) {
|
||||
throw new SyncFactoryException("Resource " + ROWSET_PROPERTIES + " not found");
|
||||
}
|
||||
properties.load(stream);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
} catch (PrivilegedActionException ex) {
|
||||
Throwable e = ex.getException();
|
||||
if (e instanceof SyncFactoryException) {
|
||||
throw (SyncFactoryException) e;
|
||||
} else {
|
||||
SyncFactoryException sfe = new SyncFactoryException();
|
||||
sfe.initCause(ex.getException());
|
||||
throw sfe;
|
||||
}
|
||||
}
|
||||
|
||||
parseProperties(properties);
|
||||
|
||||
// removed else, has properties should sum together
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new SyncFactoryException("Cannot locate properties file: " + e);
|
||||
} catch (IOException e) {
|
||||
throw new SyncFactoryException("IOException: " + e);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now deal with -Drowset.provider.classname
|
||||
* load additional properties from -D command line
|
||||
*/
|
||||
properties.clear();
|
||||
String providerImpls;
|
||||
try {
|
||||
providerImpls = AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty(ROWSET_SYNC_PROVIDER);
|
||||
}
|
||||
}, null, new PropertyPermission(ROWSET_SYNC_PROVIDER, "read"));
|
||||
} catch (Exception ex) {
|
||||
providerImpls = null;
|
||||
}
|
||||
|
||||
if (providerImpls != null) {
|
||||
int i = 0;
|
||||
if (providerImpls.indexOf(colon) > 0) {
|
||||
StringTokenizer tokenizer = new StringTokenizer(providerImpls, colon);
|
||||
while (tokenizer.hasMoreElements()) {
|
||||
properties.put(ROWSET_SYNC_PROVIDER + "." + i, tokenizer.nextToken());
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
properties.put(ROWSET_SYNC_PROVIDER, providerImpls);
|
||||
}
|
||||
parseProperties(properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The internal debug switch.
|
||||
*/
|
||||
private static boolean debug = false;
|
||||
/**
|
||||
* Internal registry count for the number of providers contained in the
|
||||
* registry.
|
||||
*/
|
||||
private static int providerImplIndex = 0;
|
||||
|
||||
/**
|
||||
* Internal handler for all standard property parsing. Parses standard
|
||||
* ROWSET properties and stores lazy references into the the internal registry.
|
||||
*/
|
||||
private static void parseProperties(Properties p) {
|
||||
|
||||
ProviderImpl impl = null;
|
||||
String key = null;
|
||||
String[] propertyNames = null;
|
||||
|
||||
for (Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) {
|
||||
|
||||
String str = (String) e.nextElement();
|
||||
|
||||
int w = str.length();
|
||||
|
||||
if (str.startsWith(SyncFactory.ROWSET_SYNC_PROVIDER)) {
|
||||
|
||||
impl = new ProviderImpl();
|
||||
impl.setIndex(providerImplIndex++);
|
||||
|
||||
if (w == (SyncFactory.ROWSET_SYNC_PROVIDER).length()) {
|
||||
// no property index has been set.
|
||||
propertyNames = getPropertyNames(false);
|
||||
} else {
|
||||
// property index has been set.
|
||||
propertyNames = getPropertyNames(true, str.substring(w - 1));
|
||||
}
|
||||
|
||||
key = p.getProperty(propertyNames[0]);
|
||||
impl.setClassname(key);
|
||||
impl.setVendor(p.getProperty(propertyNames[1]));
|
||||
impl.setVersion(p.getProperty(propertyNames[2]));
|
||||
implementations.put(key, impl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the parseProperties methods to disassemble each property tuple.
|
||||
*/
|
||||
private static String[] getPropertyNames(boolean append) {
|
||||
return getPropertyNames(append, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disassembles each property and its associated value. Also handles
|
||||
* overloaded property names that contain indexes.
|
||||
*/
|
||||
private static String[] getPropertyNames(boolean append,
|
||||
String propertyIndex) {
|
||||
String dot = ".";
|
||||
String[] propertyNames =
|
||||
new String[]{SyncFactory.ROWSET_SYNC_PROVIDER,
|
||||
SyncFactory.ROWSET_SYNC_VENDOR,
|
||||
SyncFactory.ROWSET_SYNC_PROVIDER_VERSION};
|
||||
if (append) {
|
||||
for (int i = 0; i < propertyNames.length; i++) {
|
||||
propertyNames[i] = propertyNames[i] +
|
||||
dot +
|
||||
propertyIndex;
|
||||
}
|
||||
return propertyNames;
|
||||
} else {
|
||||
return propertyNames;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal debug method that outputs the registry contents.
|
||||
*/
|
||||
private static void showImpl(ProviderImpl impl) {
|
||||
System.out.println("Provider implementation:");
|
||||
System.out.println("Classname: " + impl.getClassname());
|
||||
System.out.println("Vendor: " + impl.getVendor());
|
||||
System.out.println("Version: " + impl.getVersion());
|
||||
System.out.println("Impl index: " + impl.getIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>SyncProvider</code> instance identified by <i>providerID</i>.
|
||||
*
|
||||
* @param providerID the unique identifier of the provider
|
||||
* @return a <code>SyncProvider</code> implementation
|
||||
* @throws SyncFactoryException If the SyncProvider cannot be found,
|
||||
* the providerID is {@code null}, or
|
||||
* some error was encountered when trying to invoke this provider.
|
||||
*/
|
||||
public static SyncProvider getInstance(String providerID)
|
||||
throws SyncFactoryException {
|
||||
|
||||
if(providerID == null) {
|
||||
throw new SyncFactoryException("The providerID cannot be null");
|
||||
}
|
||||
|
||||
initMapIfNecessary(); // populate HashTable
|
||||
initJNDIContext(); // check JNDI context for any additional bindings
|
||||
|
||||
ProviderImpl impl = (ProviderImpl) implementations.get(providerID);
|
||||
|
||||
if (impl == null) {
|
||||
// Requested SyncProvider is unavailable. Return default provider.
|
||||
return new com.sun.rowset.providers.RIOptimisticProvider();
|
||||
}
|
||||
|
||||
try {
|
||||
ReflectUtil.checkPackageAccess(providerID);
|
||||
} catch (java.security.AccessControlException e) {
|
||||
SyncFactoryException sfe = new SyncFactoryException();
|
||||
sfe.initCause(e);
|
||||
throw sfe;
|
||||
}
|
||||
|
||||
// Attempt to invoke classname from registered SyncProvider list
|
||||
Class<?> c = null;
|
||||
try {
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
/**
|
||||
* The SyncProvider implementation of the user will be in
|
||||
* the classpath. We need to find the ClassLoader which loads
|
||||
* this SyncFactory and try to load the SyncProvider class from
|
||||
* there.
|
||||
**/
|
||||
c = Class.forName(providerID, true, cl);
|
||||
|
||||
if (c != null) {
|
||||
return (SyncProvider) c.newInstance();
|
||||
} else {
|
||||
return new com.sun.rowset.providers.RIOptimisticProvider();
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new SyncFactoryException("IllegalAccessException: " + e.getMessage());
|
||||
} catch (InstantiationException e) {
|
||||
throw new SyncFactoryException("InstantiationException: " + e.getMessage());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new SyncFactoryException("ClassNotFoundException: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Enumeration of currently registered synchronization
|
||||
* providers. A <code>RowSet</code> implementation may use any provider in
|
||||
* the enumeration as its <code>SyncProvider</code> object.
|
||||
* <p>
|
||||
* At a minimum, the reference synchronization provider allowing
|
||||
* RowSet content data to be stored using a JDBC driver should be
|
||||
* possible.
|
||||
*
|
||||
* @return Enumeration A enumeration of available synchronization
|
||||
* providers that are registered with this Factory
|
||||
* @throws SyncFactoryException If an error occurs obtaining the registered
|
||||
* providers
|
||||
*/
|
||||
public static Enumeration<SyncProvider> getRegisteredProviders()
|
||||
throws SyncFactoryException {
|
||||
initMapIfNecessary();
|
||||
// return a collection of classnames
|
||||
// of type SyncProvider
|
||||
return implementations.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logging object to be used by the <code>SyncProvider</code>
|
||||
* implementation provided by the <code>SyncFactory</code>. All
|
||||
* <code>SyncProvider</code> implementations can log their events to
|
||||
* this object and the application can retrieve a handle to this
|
||||
* object using the <code>getLogger</code> method.
|
||||
* <p>
|
||||
* This method checks to see that there is an {@code SQLPermission}
|
||||
* object which grants the permission {@code setSyncFactory}
|
||||
* before allowing the method to succeed. If a
|
||||
* {@code SecurityManager} exists and its
|
||||
* {@code checkPermission} method denies calling {@code setLogger},
|
||||
* this method throws a
|
||||
* {@code java.lang.SecurityException}.
|
||||
*
|
||||
* @param logger A Logger object instance
|
||||
* @throws java.lang.SecurityException if a security manager exists and its
|
||||
* {@code checkPermission} method denies calling {@code setLogger}
|
||||
* @throws NullPointerException if the logger is null
|
||||
* @see SecurityManager#checkPermission
|
||||
*/
|
||||
public static void setLogger(Logger logger) {
|
||||
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
if (sec != null) {
|
||||
sec.checkPermission(SET_SYNCFACTORY_PERMISSION);
|
||||
}
|
||||
|
||||
if(logger == null){
|
||||
throw new NullPointerException("You must provide a Logger");
|
||||
}
|
||||
rsLogger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logging object that is used by <code>SyncProvider</code>
|
||||
* implementations provided by the <code>SyncFactory</code> SPI. All
|
||||
* <code>SyncProvider</code> implementations can log their events
|
||||
* to this object and the application can retrieve a handle to this
|
||||
* object using the <code>getLogger</code> method.
|
||||
* <p>
|
||||
* This method checks to see that there is an {@code SQLPermission}
|
||||
* object which grants the permission {@code setSyncFactory}
|
||||
* before allowing the method to succeed. If a
|
||||
* {@code SecurityManager} exists and its
|
||||
* {@code checkPermission} method denies calling {@code setLogger},
|
||||
* this method throws a
|
||||
* {@code java.lang.SecurityException}.
|
||||
*
|
||||
* @param logger a Logger object instance
|
||||
* @param level a Level object instance indicating the degree of logging
|
||||
* required
|
||||
* @throws java.lang.SecurityException if a security manager exists and its
|
||||
* {@code checkPermission} method denies calling {@code setLogger}
|
||||
* @throws NullPointerException if the logger is null
|
||||
* @see SecurityManager#checkPermission
|
||||
* @see LoggingPermission
|
||||
*/
|
||||
public static void setLogger(Logger logger, Level level) {
|
||||
// singleton
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
if (sec != null) {
|
||||
sec.checkPermission(SET_SYNCFACTORY_PERMISSION);
|
||||
}
|
||||
|
||||
if(logger == null){
|
||||
throw new NullPointerException("You must provide a Logger");
|
||||
}
|
||||
logger.setLevel(level);
|
||||
rsLogger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the logging object for applications to retrieve
|
||||
* synchronization events posted by SyncProvider implementations.
|
||||
* @return The {@code Logger} that has been specified for use by
|
||||
* {@code SyncProvider} implementations
|
||||
* @throws SyncFactoryException if no logging object has been set.
|
||||
*/
|
||||
public static Logger getLogger() throws SyncFactoryException {
|
||||
|
||||
Logger result = rsLogger;
|
||||
// only one logger per session
|
||||
if (result == null) {
|
||||
throw new SyncFactoryException("(SyncFactory) : No logger has been set");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initial JNDI context from which SyncProvider implementations
|
||||
* can be retrieved from a JNDI namespace
|
||||
* <p>
|
||||
* This method checks to see that there is an {@code SQLPermission}
|
||||
* object which grants the permission {@code setSyncFactory}
|
||||
* before allowing the method to succeed. If a
|
||||
* {@code SecurityManager} exists and its
|
||||
* {@code checkPermission} method denies calling {@code setJNDIContext},
|
||||
* this method throws a
|
||||
* {@code java.lang.SecurityException}.
|
||||
*
|
||||
* @param ctx a valid JNDI context
|
||||
* @throws SyncFactoryException if the supplied JNDI context is null
|
||||
* @throws java.lang.SecurityException if a security manager exists and its
|
||||
* {@code checkPermission} method denies calling {@code setJNDIContext}
|
||||
* @see SecurityManager#checkPermission
|
||||
*/
|
||||
public static synchronized void setJNDIContext(javax.naming.Context ctx)
|
||||
throws SyncFactoryException {
|
||||
SecurityManager sec = System.getSecurityManager();
|
||||
if (sec != null) {
|
||||
sec.checkPermission(SET_SYNCFACTORY_PERMISSION);
|
||||
}
|
||||
if (ctx == null) {
|
||||
throw new SyncFactoryException("Invalid JNDI context supplied");
|
||||
}
|
||||
ic = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls JNDI context initialization.
|
||||
*
|
||||
* @throws SyncFactoryException if an error occurs parsing the JNDI context
|
||||
*/
|
||||
private static synchronized void initJNDIContext() throws SyncFactoryException {
|
||||
|
||||
if ((ic != null) && (lazyJNDICtxRefresh == false)) {
|
||||
try {
|
||||
parseProperties(parseJNDIContext());
|
||||
lazyJNDICtxRefresh = true; // touch JNDI namespace once.
|
||||
} catch (NamingException e) {
|
||||
e.printStackTrace();
|
||||
throw new SyncFactoryException("SPI: NamingException: " + e.getExplanation());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new SyncFactoryException("SPI: Exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Internal switch indicating whether the JNDI namespace should be re-read.
|
||||
*/
|
||||
private static boolean lazyJNDICtxRefresh = false;
|
||||
|
||||
/**
|
||||
* Parses the set JNDI Context and passes bindings to the enumerateBindings
|
||||
* method when complete.
|
||||
*/
|
||||
private static Properties parseJNDIContext() throws NamingException {
|
||||
|
||||
NamingEnumeration<?> bindings = ic.listBindings("");
|
||||
Properties properties = new Properties();
|
||||
|
||||
// Hunt one level below context for available SyncProvider objects
|
||||
enumerateBindings(bindings, properties);
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans each binding on JNDI context and determines if any binding is an
|
||||
* instance of SyncProvider, if so, add this to the registry and continue to
|
||||
* scan the current context using a re-entrant call to this method until all
|
||||
* bindings have been enumerated.
|
||||
*/
|
||||
private static void enumerateBindings(NamingEnumeration<?> bindings,
|
||||
Properties properties) throws NamingException {
|
||||
|
||||
boolean syncProviderObj = false; // move to parameters ?
|
||||
|
||||
try {
|
||||
Binding bd = null;
|
||||
Object elementObj = null;
|
||||
String element = null;
|
||||
while (bindings.hasMore()) {
|
||||
bd = (Binding) bindings.next();
|
||||
element = bd.getName();
|
||||
elementObj = bd.getObject();
|
||||
|
||||
if (!(ic.lookup(element) instanceof Context)) {
|
||||
// skip directories/sub-contexts
|
||||
if (ic.lookup(element) instanceof SyncProvider) {
|
||||
syncProviderObj = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (syncProviderObj) {
|
||||
SyncProvider sync = (SyncProvider) elementObj;
|
||||
properties.put(SyncFactory.ROWSET_SYNC_PROVIDER,
|
||||
sync.getProviderID());
|
||||
syncProviderObj = false; // reset
|
||||
}
|
||||
|
||||
}
|
||||
} catch (javax.naming.NotContextException e) {
|
||||
bindings.next();
|
||||
// Re-entrant call into method
|
||||
enumerateBindings(bindings, properties);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy initialization Holder class used by {@code getSyncFactory}
|
||||
*/
|
||||
private static class SyncFactoryHolder {
|
||||
static final SyncFactory factory = new SyncFactory();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal class that defines the lazy reference construct for each registered
|
||||
* SyncProvider implementation.
|
||||
*/
|
||||
class ProviderImpl extends SyncProvider {
|
||||
|
||||
private String className = null;
|
||||
private String vendorName = null;
|
||||
private String ver = null;
|
||||
private int index;
|
||||
|
||||
public void setClassname(String classname) {
|
||||
className = classname;
|
||||
}
|
||||
|
||||
public String getClassname() {
|
||||
return className;
|
||||
}
|
||||
|
||||
public void setVendor(String vendor) {
|
||||
vendorName = vendor;
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return vendorName;
|
||||
}
|
||||
|
||||
public void setVersion(String providerVer) {
|
||||
ver = providerVer;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return ver;
|
||||
}
|
||||
|
||||
public void setIndex(int i) {
|
||||
index = i;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public int getDataSourceLock() throws SyncProviderException {
|
||||
|
||||
int dsLock = 0;
|
||||
try {
|
||||
dsLock = SyncFactory.getInstance(className).getDataSourceLock();
|
||||
} catch (SyncFactoryException sfEx) {
|
||||
|
||||
throw new SyncProviderException(sfEx.getMessage());
|
||||
}
|
||||
|
||||
return dsLock;
|
||||
}
|
||||
|
||||
public int getProviderGrade() {
|
||||
|
||||
int grade = 0;
|
||||
|
||||
try {
|
||||
grade = SyncFactory.getInstance(className).getProviderGrade();
|
||||
} catch (SyncFactoryException sfEx) {
|
||||
//
|
||||
}
|
||||
|
||||
return grade;
|
||||
}
|
||||
|
||||
public String getProviderID() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/*
|
||||
public javax.sql.RowSetInternal getRowSetInternal() {
|
||||
try
|
||||
{
|
||||
return SyncFactory.getInstance(className).getRowSetInternal();
|
||||
} catch(SyncFactoryException sfEx) {
|
||||
//
|
||||
}
|
||||
}
|
||||
*/
|
||||
public javax.sql.RowSetReader getRowSetReader() {
|
||||
|
||||
RowSetReader rsReader = null;
|
||||
|
||||
try {
|
||||
rsReader = SyncFactory.getInstance(className).getRowSetReader();
|
||||
} catch (SyncFactoryException sfEx) {
|
||||
//
|
||||
}
|
||||
|
||||
return rsReader;
|
||||
|
||||
}
|
||||
|
||||
public javax.sql.RowSetWriter getRowSetWriter() {
|
||||
|
||||
RowSetWriter rsWriter = null;
|
||||
try {
|
||||
rsWriter = SyncFactory.getInstance(className).getRowSetWriter();
|
||||
} catch (SyncFactoryException sfEx) {
|
||||
//
|
||||
}
|
||||
|
||||
return rsWriter;
|
||||
}
|
||||
|
||||
public void setDataSourceLock(int param)
|
||||
throws SyncProviderException {
|
||||
|
||||
try {
|
||||
SyncFactory.getInstance(className).setDataSourceLock(param);
|
||||
} catch (SyncFactoryException sfEx) {
|
||||
|
||||
throw new SyncProviderException(sfEx.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public int supportsUpdatableView() {
|
||||
|
||||
int view = 0;
|
||||
|
||||
try {
|
||||
view = SyncFactory.getInstance(className).supportsUpdatableView();
|
||||
} catch (SyncFactoryException sfEx) {
|
||||
//
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
}
|
58
jdkSrc/jdk8/javax/sql/rowset/spi/SyncFactoryException.java
Normal file
58
jdkSrc/jdk8/javax/sql/rowset/spi/SyncFactoryException.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Indicates an error with <code>SyncFactory</code> mechanism. A disconnected
|
||||
* RowSet implementation cannot be used without a <code>SyncProvider</code>
|
||||
* being successfully instantiated
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @see javax.sql.rowset.spi.SyncFactory
|
||||
* @see javax.sql.rowset.spi.SyncFactoryException
|
||||
*/
|
||||
public class SyncFactoryException extends java.sql.SQLException {
|
||||
|
||||
/**
|
||||
* Creates new <code>SyncFactoryException</code> without detail message.
|
||||
*/
|
||||
public SyncFactoryException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>SyncFactoryException</code> with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message.
|
||||
*/
|
||||
public SyncFactoryException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
static final long serialVersionUID = -4354595476433200352L;
|
||||
}
|
430
jdkSrc/jdk8/javax/sql/rowset/spi/SyncProvider.java
Normal file
430
jdkSrc/jdk8/javax/sql/rowset/spi/SyncProvider.java
Normal file
@@ -0,0 +1,430 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import javax.sql.*;
|
||||
|
||||
/**
|
||||
* The synchronization mechanism that provides reader/writer capabilities for
|
||||
* disconnected <code>RowSet</code> objects.
|
||||
* A <code>SyncProvider</code> implementation is a class that extends the
|
||||
* <code>SyncProvider</code> abstract class.
|
||||
* <P>
|
||||
* A <code>SyncProvider</code> implementation is
|
||||
* identified by a unique ID, which is its fully qualified class name.
|
||||
* This name must be registered with the
|
||||
* <code>SyncFactory</code> SPI, thus making the implementation available to
|
||||
* all <code>RowSet</code> implementations.
|
||||
* The factory mechanism in the reference implementation uses this name to instantiate
|
||||
* the implementation, which can then provide a <code>RowSet</code> object with its
|
||||
* reader (a <code>javax.sql.RowSetReader</code> object) and its writer (a
|
||||
* <code>javax.sql.RowSetWriter</code> object).
|
||||
* <P>
|
||||
* The Jdbc <code>RowSet</code> Implementations specification provides two
|
||||
* reference implementations of the <code>SyncProvider</code> abstract class:
|
||||
* <code>RIOptimisticProvider</code> and <code>RIXMLProvider</code>.
|
||||
* The <code>RIOptimisticProvider</code> can set any <code>RowSet</code>
|
||||
* implementation with a <code>RowSetReader</code> object and a
|
||||
* <code>RowSetWriter</code> object. However, only the <code>RIXMLProvider</code>
|
||||
* implementation can set an <code>XmlReader</code> object and an
|
||||
* <code>XmlWriter</code> object. A <code>WebRowSet</code> object uses the
|
||||
* <code>XmlReader</code> object to read data in XML format to populate itself with that
|
||||
* data. It uses the <code>XmlWriter</code> object to write itself to a stream or
|
||||
* <code>java.io.Writer</code> object in XML format.
|
||||
*
|
||||
* <h3>1.0 Naming Convention for Implementations</h3>
|
||||
* As a guide to naming <code>SyncProvider</code>
|
||||
* implementations, the following should be noted:
|
||||
* <UL>
|
||||
* <li>The name for a <code>SyncProvider</code> implementation
|
||||
* is its fully qualified class name.
|
||||
* <li>It is recommended that vendors supply a
|
||||
* <code>SyncProvider</code> implementation in a package named <code>providers</code>.
|
||||
* </UL>
|
||||
* <p>
|
||||
* For instance, if a vendor named Fred, Inc. offered a
|
||||
* <code>SyncProvider</code> implementation, you could have the following:
|
||||
* <PRE>
|
||||
* Vendor name: Fred, Inc.
|
||||
* Domain name of vendor: com.fred
|
||||
* Package name: com.fred.providers
|
||||
* SyncProvider implementation class name: HighAvailabilityProvider
|
||||
*
|
||||
* Fully qualified class name of SyncProvider implementation:
|
||||
* com.fred.providers.HighAvailabilityProvider
|
||||
* </PRE>
|
||||
* <P>
|
||||
* The following line of code uses the fully qualified name to register
|
||||
* this implementation with the <code>SyncFactory</code> static instance.
|
||||
* <PRE>
|
||||
* SyncFactory.registerProvider(
|
||||
* "com.fred.providers.HighAvailabilityProvider");
|
||||
* </PRE>
|
||||
* <P>
|
||||
* The default <code>SyncProvider</code> object provided with the reference
|
||||
* implementation uses the following name:
|
||||
* <pre>
|
||||
* com.sun.rowset.providers.RIOptimisticProvider
|
||||
* </pre>
|
||||
* <p>
|
||||
* A vendor can register a <code>SyncProvider</code> implementation class name
|
||||
* with Oracle Corporation by sending email to jdbc@sun.com.
|
||||
* Oracle will maintain a database listing the
|
||||
* available <code>SyncProvider</code> implementations for use with compliant
|
||||
* <code>RowSet</code> implementations. This database will be similar to the
|
||||
* one already maintained to list available JDBC drivers.
|
||||
* <P>
|
||||
* Vendors should refer to the reference implementation synchronization
|
||||
* providers for additional guidance on how to implement a new
|
||||
* <code>SyncProvider</code> implementation.
|
||||
*
|
||||
* <h3>2.0 How a <code>RowSet</code> Object Gets Its Provider</h3>
|
||||
*
|
||||
* A disconnected <code>Rowset</code> object may get access to a
|
||||
* <code>SyncProvider</code> object in one of the following two ways:
|
||||
* <UL>
|
||||
* <LI>Using a constructor<BR>
|
||||
* <PRE>
|
||||
* CachedRowSet crs = new CachedRowSet(
|
||||
* "com.fred.providers.HighAvailabilitySyncProvider");
|
||||
* </PRE>
|
||||
* <LI>Using the <code>setSyncProvider</code> method
|
||||
* <PRE>
|
||||
* CachedRowSet crs = new CachedRowSet();
|
||||
* crs.setSyncProvider("com.fred.providers.HighAvailabilitySyncProvider");
|
||||
* </PRE>
|
||||
|
||||
* </UL>
|
||||
* <p>
|
||||
* By default, the reference implementations of the <code>RowSet</code> synchronization
|
||||
* providers are always available to the Java platform.
|
||||
* If no other pluggable synchronization providers have been correctly
|
||||
* registered, the <code>SyncFactory</code> will automatically generate
|
||||
* an instance of the default <code>SyncProvider</code> reference implementation.
|
||||
* Thus, in the preceding code fragment, if no implementation named
|
||||
* <code>com.fred.providers.HighAvailabilitySyncProvider</code> has been
|
||||
* registered with the <code>SyncFactory</code> instance, <i>crs</i> will be
|
||||
* assigned the default provider in the reference implementation, which is
|
||||
* <code>com.sun.rowset.providers.RIOptimisticProvider</code>.
|
||||
*
|
||||
* <h3>3.0 Violations and Synchronization Issues</h3>
|
||||
* If an update between a disconnected <code>RowSet</code> object
|
||||
* and a data source violates
|
||||
* the original query or the underlying data source constraints, this will
|
||||
* result in undefined behavior for all disconnected <code>RowSet</code> implementations
|
||||
* and their designated <code>SyncProvider</code> implementations.
|
||||
* Not defining the behavior when such violations occur offers greater flexibility
|
||||
* for a <code>SyncProvider</code>
|
||||
* implementation to determine its own best course of action.
|
||||
* <p>
|
||||
* A <code>SyncProvider</code> implementation
|
||||
* may choose to implement a specific handler to
|
||||
* handle a subset of query violations.
|
||||
* However if an original query violation or a more general data source constraint
|
||||
* violation is not handled by the <code>SyncProvider</code> implementation,
|
||||
* all <code>SyncProvider</code>
|
||||
* objects must throw a <code>SyncProviderException</code>.
|
||||
*
|
||||
* <h3>4.0 Updatable SQL VIEWs</h3>
|
||||
* It is possible for any disconnected or connected <code>RowSet</code> object to be populated
|
||||
* from an SQL query that is formulated originally from an SQL <code>VIEW</code>.
|
||||
* While in many cases it is possible for an update to be performed to an
|
||||
* underlying view, such an update requires additional metadata, which may vary.
|
||||
* The <code>SyncProvider</code> class provides two constants to indicate whether
|
||||
* an implementation supports updating an SQL <code>VIEW</code>.
|
||||
* <ul>
|
||||
* <li><code><b>NONUPDATABLE_VIEW_SYNC</b></code> - Indicates that a <code>SyncProvider</code>
|
||||
* implementation does not support synchronization with an SQL <code>VIEW</code> as the
|
||||
* underlying source of data for the <code>RowSet</code> object.
|
||||
* <li><code><b>UPDATABLE_VIEW_SYNC</b></code> - Indicates that a
|
||||
* <code>SyncProvider</code> implementation
|
||||
* supports synchronization with an SQL <code>VIEW</code> as the underlying source
|
||||
* of data.
|
||||
* </ul>
|
||||
* <P>
|
||||
* The default is for a <code>RowSet</code> object not to be updatable if it was
|
||||
* populated with data from an SQL <code>VIEW</code>.
|
||||
*
|
||||
* <h3>5.0 <code>SyncProvider</code> Constants</h3>
|
||||
* The <code>SyncProvider</code> class provides three sets of constants that
|
||||
* are used as return values or parameters for <code>SyncProvider</code> methods.
|
||||
* <code>SyncProvider</code> objects may be implemented to perform synchronization
|
||||
* between a <code>RowSet</code> object and its underlying data source with varying
|
||||
* degrees of of care. The first group of constants indicate how synchronization
|
||||
* is handled. For example, <code>GRADE_NONE</code> indicates that a
|
||||
* <code>SyncProvider</code> object will not take any care to see what data is
|
||||
* valid and will simply write the <code>RowSet</code> data to the data source.
|
||||
* <code>GRADE_MODIFIED_AT_COMMIT</code> indicates that the provider will check
|
||||
* only modified data for validity. Other grades check all data for validity
|
||||
* or set locks when data is modified or loaded.
|
||||
* <OL>
|
||||
* <LI>Constants to indicate the synchronization grade of a
|
||||
* <code>SyncProvider</code> object
|
||||
* <UL>
|
||||
* <LI>SyncProvider.GRADE_NONE
|
||||
* <LI>SyncProvider.GRADE_MODIFIED_AT_COMMIT
|
||||
* <LI>SyncProvider.GRADE_CHECK_ALL_AT_COMMIT
|
||||
* <LI>SyncProvider.GRADE_LOCK_WHEN_MODIFIED
|
||||
* <LI>SyncProvider.GRADE_LOCK_WHEN_LOADED
|
||||
* </UL>
|
||||
* <LI>Constants to indicate what locks are set on the data source
|
||||
* <UL>
|
||||
* <LI>SyncProvider.DATASOURCE_NO_LOCK
|
||||
* <LI>SyncProvider.DATASOURCE_ROW_LOCK
|
||||
* <LI>SyncProvider.DATASOURCE_TABLE_LOCK
|
||||
* <LI>SyncProvider.DATASOURCE_DB_LOCK
|
||||
* </UL>
|
||||
* <LI>Constants to indicate whether a <code>SyncProvider</code> object can
|
||||
* perform updates to an SQL <code>VIEW</code> <BR>
|
||||
* These constants are explained in the preceding section (4.0).
|
||||
* <UL>
|
||||
* <LI>SyncProvider.UPDATABLE_VIEW_SYNC
|
||||
* <LI>SyncProvider.NONUPDATABLE_VIEW_SYNC
|
||||
* </UL>
|
||||
* </OL>
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @see javax.sql.rowset.spi.SyncFactory
|
||||
* @see javax.sql.rowset.spi.SyncFactoryException
|
||||
*/
|
||||
public abstract class SyncProvider {
|
||||
|
||||
/**
|
||||
* Creates a default <code>SyncProvider</code> object.
|
||||
*/
|
||||
public SyncProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique identifier for this <code>SyncProvider</code> object.
|
||||
*
|
||||
* @return a <code>String</code> object with the fully qualified class name of
|
||||
* this <code>SyncProvider</code> object
|
||||
*/
|
||||
public abstract String getProviderID();
|
||||
|
||||
/**
|
||||
* Returns a <code>javax.sql.RowSetReader</code> object, which can be used to
|
||||
* populate a <code>RowSet</code> object with data.
|
||||
*
|
||||
* @return a <code>javax.sql.RowSetReader</code> object
|
||||
*/
|
||||
public abstract RowSetReader getRowSetReader();
|
||||
|
||||
/**
|
||||
* Returns a <code>javax.sql.RowSetWriter</code> object, which can be
|
||||
* used to write a <code>RowSet</code> object's data back to the
|
||||
* underlying data source.
|
||||
*
|
||||
* @return a <code>javax.sql.RowSetWriter</code> object
|
||||
*/
|
||||
public abstract RowSetWriter getRowSetWriter();
|
||||
|
||||
/**
|
||||
* Returns a constant indicating the
|
||||
* grade of synchronization a <code>RowSet</code> object can expect from
|
||||
* this <code>SyncProvider</code> object.
|
||||
*
|
||||
* @return an int that is one of the following constants:
|
||||
* SyncProvider.GRADE_NONE,
|
||||
* SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT,
|
||||
* SyncProvider.GRADE_CHECK_ALL_AT_COMMIT,
|
||||
* SyncProvider.GRADE_LOCK_WHEN_MODIFIED,
|
||||
* SyncProvider.GRADE_LOCK_WHEN_LOADED
|
||||
*/
|
||||
public abstract int getProviderGrade();
|
||||
|
||||
|
||||
/**
|
||||
* Sets a lock on the underlying data source at the level indicated by
|
||||
* <i>datasource_lock</i>. This should cause the
|
||||
* <code>SyncProvider</code> to adjust its behavior by increasing or
|
||||
* decreasing the level of optimism it provides for a successful
|
||||
* synchronization.
|
||||
*
|
||||
* @param datasource_lock one of the following constants indicating the severity
|
||||
* level of data source lock required:
|
||||
* <pre>
|
||||
* SyncProvider.DATASOURCE_NO_LOCK,
|
||||
* SyncProvider.DATASOURCE_ROW_LOCK,
|
||||
* SyncProvider.DATASOURCE_TABLE_LOCK,
|
||||
* SyncProvider.DATASOURCE_DB_LOCK,
|
||||
* </pre>
|
||||
* @throws SyncProviderException if an unsupported data source locking level
|
||||
* is set.
|
||||
* @see #getDataSourceLock
|
||||
*/
|
||||
public abstract void setDataSourceLock(int datasource_lock)
|
||||
throws SyncProviderException;
|
||||
|
||||
/**
|
||||
* Returns the current data source lock severity level active in this
|
||||
* <code>SyncProvider</code> implementation.
|
||||
*
|
||||
* @return a constant indicating the current level of data source lock
|
||||
* active in this <code>SyncProvider</code> object;
|
||||
* one of the following:
|
||||
* <pre>
|
||||
* SyncProvider.DATASOURCE_NO_LOCK,
|
||||
* SyncProvider.DATASOURCE_ROW_LOCK,
|
||||
* SyncProvider.DATASOURCE_TABLE_LOCK,
|
||||
* SyncProvider.DATASOURCE_DB_LOCK
|
||||
* </pre>
|
||||
* @throws SyncProviderException if an error occurs determining the data
|
||||
* source locking level.
|
||||
* @see #setDataSourceLock
|
||||
|
||||
*/
|
||||
public abstract int getDataSourceLock()
|
||||
throws SyncProviderException;
|
||||
|
||||
/**
|
||||
* Returns whether this <code>SyncProvider</code> implementation
|
||||
* can perform synchronization between a <code>RowSet</code> object
|
||||
* and the SQL <code>VIEW</code> in the data source from which
|
||||
* the <code>RowSet</code> object got its data.
|
||||
*
|
||||
* @return an <code>int</code> saying whether this <code>SyncProvider</code>
|
||||
* object supports updating an SQL <code>VIEW</code>; one of the
|
||||
* following:
|
||||
* SyncProvider.UPDATABLE_VIEW_SYNC,
|
||||
* SyncProvider.NONUPDATABLE_VIEW_SYNC
|
||||
*/
|
||||
public abstract int supportsUpdatableView();
|
||||
|
||||
/**
|
||||
* Returns the release version of this <code>SyncProvider</code> instance.
|
||||
*
|
||||
* @return a <code>String</code> detailing the release version of the
|
||||
* <code>SyncProvider</code> implementation
|
||||
*/
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* Returns the vendor name of this <code>SyncProvider</code> instance
|
||||
*
|
||||
* @return a <code>String</code> detailing the vendor name of this
|
||||
* <code>SyncProvider</code> implementation
|
||||
*/
|
||||
public abstract String getVendor();
|
||||
|
||||
/*
|
||||
* Standard description of synchronization grades that a SyncProvider
|
||||
* could provide.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that no synchronization with the originating data source is
|
||||
* provided. A <code>SyncProvider</code>
|
||||
* implementation returning this grade will simply attempt to write
|
||||
* updates in the <code>RowSet</code> object to the underlying data
|
||||
* source without checking the validity of any data.
|
||||
*
|
||||
*/
|
||||
public static final int GRADE_NONE = 1;
|
||||
|
||||
/**
|
||||
* Indicates a low level optimistic synchronization grade with
|
||||
* respect to the originating data source.
|
||||
*
|
||||
* A <code>SyncProvider</code> implementation
|
||||
* returning this grade will check only rows that have changed.
|
||||
*
|
||||
*/
|
||||
public static final int GRADE_CHECK_MODIFIED_AT_COMMIT = 2;
|
||||
|
||||
/**
|
||||
* Indicates a high level optimistic synchronization grade with
|
||||
* respect to the originating data source.
|
||||
*
|
||||
* A <code>SyncProvider</code> implementation
|
||||
* returning this grade will check all rows, including rows that have not
|
||||
* changed.
|
||||
*/
|
||||
public static final int GRADE_CHECK_ALL_AT_COMMIT = 3;
|
||||
|
||||
/**
|
||||
* Indicates a pessimistic synchronization grade with
|
||||
* respect to the originating data source.
|
||||
*
|
||||
* A <code>SyncProvider</code>
|
||||
* implementation returning this grade will lock the row in the originating
|
||||
* data source.
|
||||
*/
|
||||
public static final int GRADE_LOCK_WHEN_MODIFIED = 4;
|
||||
|
||||
/**
|
||||
* Indicates the most pessimistic synchronization grade with
|
||||
* respect to the originating
|
||||
* data source. A <code>SyncProvider</code>
|
||||
* implementation returning this grade will lock the entire view and/or
|
||||
* table affected by the original statement used to populate a
|
||||
* <code>RowSet</code> object.
|
||||
*/
|
||||
public static final int GRADE_LOCK_WHEN_LOADED = 5;
|
||||
|
||||
/**
|
||||
* Indicates that no locks remain on the originating data source. This is the default
|
||||
* lock setting for all <code>SyncProvider</code> implementations unless
|
||||
* otherwise directed by a <code>RowSet</code> object.
|
||||
*/
|
||||
public static final int DATASOURCE_NO_LOCK = 1;
|
||||
|
||||
/**
|
||||
* Indicates that a lock is placed on the rows that are touched by the original
|
||||
* SQL statement used to populate the <code>RowSet</code> object
|
||||
* that is using this <code>SyncProvider</code> object.
|
||||
*/
|
||||
public static final int DATASOURCE_ROW_LOCK = 2;
|
||||
|
||||
/**
|
||||
* Indicates that a lock is placed on all tables that are touched by the original
|
||||
* SQL statement used to populate the <code>RowSet</code> object
|
||||
* that is using this <code>SyncProvider</code> object.
|
||||
*/
|
||||
public static final int DATASOURCE_TABLE_LOCK = 3;
|
||||
|
||||
/**
|
||||
* Indicates that a lock is placed on the entire data source that is the source of
|
||||
* data for the <code>RowSet</code> object
|
||||
* that is using this <code>SyncProvider</code> object.
|
||||
*/
|
||||
public static final int DATASOURCE_DB_LOCK = 4;
|
||||
|
||||
/**
|
||||
* Indicates that a <code>SyncProvider</code> implementation
|
||||
* supports synchronization between a <code>RowSet</code> object and
|
||||
* the SQL <code>VIEW</code> used to populate it.
|
||||
*/
|
||||
public static final int UPDATABLE_VIEW_SYNC = 5;
|
||||
|
||||
/**
|
||||
* Indicates that a <code>SyncProvider</code> implementation
|
||||
* does <B>not</B> support synchronization between a <code>RowSet</code>
|
||||
* object and the SQL <code>VIEW</code> used to populate it.
|
||||
*/
|
||||
public static final int NONUPDATABLE_VIEW_SYNC = 6;
|
||||
}
|
164
jdkSrc/jdk8/javax/sql/rowset/spi/SyncProviderException.java
Normal file
164
jdkSrc/jdk8/javax/sql/rowset/spi/SyncProviderException.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import javax.sql.rowset.*;
|
||||
|
||||
/**
|
||||
* Indicates an error with the <code>SyncProvider</code> mechanism. This exception
|
||||
* is created by a <code>SyncProvider</code> abstract class extension if it
|
||||
* encounters violations in reading from or writing to the originating data source.
|
||||
* <P>
|
||||
* If it is implemented to do so, the <code>SyncProvider</code> object may also create a
|
||||
* <code>SyncResolver</code> object and either initialize the <code>SyncProviderException</code>
|
||||
* object with it at construction time or set it with the <code>SyncProvider</code> object at
|
||||
* a later time.
|
||||
* <P>
|
||||
* The method <code>acceptChanges</code> will throw this exception after the writer
|
||||
* has finished checking for conflicts and has found one or more conflicts. An
|
||||
* application may catch a <code>SyncProviderException</code> object and call its
|
||||
* <code>getSyncResolver</code> method to get its <code>SyncResolver</code> object.
|
||||
* See the code fragment in the interface comment for
|
||||
* <a href="SyncResolver.html"><code>SyncResolver</code></a> for an example.
|
||||
* This <code>SyncResolver</code> object will mirror the <code>RowSet</code>
|
||||
* object that generated the exception, except that it will contain only the values
|
||||
* from the data source that are in conflict. All other values in the <code>SyncResolver</code>
|
||||
* object will be <code>null</code>.
|
||||
* <P>
|
||||
* The <code>SyncResolver</code> object may be used to examine and resolve
|
||||
* each conflict in a row and then go to the next row with a conflict to
|
||||
* repeat the procedure.
|
||||
* <P>
|
||||
* A <code>SyncProviderException</code> object may or may not contain a description of the
|
||||
* condition causing the exception. The inherited method <code>getMessage</code> may be
|
||||
* called to retrieve the description if there is one.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @see javax.sql.rowset.spi.SyncFactory
|
||||
* @see javax.sql.rowset.spi.SyncResolver
|
||||
* @see javax.sql.rowset.spi.SyncFactoryException
|
||||
*/
|
||||
public class SyncProviderException extends java.sql.SQLException {
|
||||
|
||||
/**
|
||||
* The instance of <code>javax.sql.rowset.spi.SyncResolver</code> that
|
||||
* this <code>SyncProviderException</code> object will return when its
|
||||
* <code>getSyncResolver</code> method is called.
|
||||
*/
|
||||
private SyncResolver syncResolver = null;
|
||||
|
||||
/**
|
||||
* Creates a new <code>SyncProviderException</code> object without a detail message.
|
||||
*/
|
||||
public SyncProviderException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>SyncProviderException</code> object with the specified
|
||||
* detail message.
|
||||
*
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public SyncProviderException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>SyncProviderException</code> object with the specified
|
||||
* <code>SyncResolver</code> instance.
|
||||
*
|
||||
* @param syncResolver the <code>SyncResolver</code> instance used to
|
||||
* to process the synchronization conflicts
|
||||
* @throws IllegalArgumentException if the <code>SyncResolver</code> object
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public SyncProviderException(SyncResolver syncResolver) {
|
||||
if (syncResolver == null) {
|
||||
throw new IllegalArgumentException("Cannot instantiate a SyncProviderException " +
|
||||
"with a null SyncResolver object");
|
||||
} else {
|
||||
this.syncResolver = syncResolver;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the <code>SyncResolver</code> object that has been set for
|
||||
* this <code>SyncProviderException</code> object, or
|
||||
* if none has been set, an instance of the default <code>SyncResolver</code>
|
||||
* implementation included in the reference implementation.
|
||||
* <P>
|
||||
* If a <code>SyncProviderException</code> object is thrown, an application
|
||||
* may use this method to generate a <code>SyncResolver</code> object
|
||||
* with which to resolve the conflict or conflicts that caused the
|
||||
* exception to be thrown.
|
||||
*
|
||||
* @return the <code>SyncResolver</code> object set for this
|
||||
* <code>SyncProviderException</code> object or, if none has
|
||||
* been set, an instance of the default <code>SyncResolver</code>
|
||||
* implementation. In addition, the default <code>SyncResolver</code>
|
||||
* implementation is also returned if the <code>SyncResolver()</code> or
|
||||
* <code>SyncResolver(String)</code> constructors are used to instantiate
|
||||
* the <code>SyncResolver</code> instance.
|
||||
*/
|
||||
public SyncResolver getSyncResolver() {
|
||||
if (syncResolver != null) {
|
||||
return syncResolver;
|
||||
} else {
|
||||
try {
|
||||
syncResolver = new com.sun.rowset.internal.SyncResolverImpl();
|
||||
} catch (SQLException sqle) {
|
||||
}
|
||||
return syncResolver;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>SyncResolver</code> object for this
|
||||
* <code>SyncProviderException</code> object to the one supplied.
|
||||
* If the argument supplied is <code>null</code>, a call to the method
|
||||
* <code>getSyncResolver</code> will return the default reference
|
||||
* implementation of the <code>SyncResolver</code> interface.
|
||||
*
|
||||
* @param syncResolver the <code>SyncResolver</code> object to be set;
|
||||
* cannot be <code>null</code>
|
||||
* @throws IllegalArgumentException if the <code>SyncResolver</code> object
|
||||
* is <code>null</code>.
|
||||
* @see #getSyncResolver
|
||||
*/
|
||||
public void setSyncResolver(SyncResolver syncResolver) {
|
||||
if (syncResolver == null) {
|
||||
throw new IllegalArgumentException("Cannot set a null SyncResolver " +
|
||||
"object");
|
||||
} else {
|
||||
this.syncResolver = syncResolver;
|
||||
}
|
||||
}
|
||||
|
||||
static final long serialVersionUID = -939908523620640692L;
|
||||
|
||||
}
|
375
jdkSrc/jdk8/javax/sql/rowset/spi/SyncResolver.java
Normal file
375
jdkSrc/jdk8/javax/sql/rowset/spi/SyncResolver.java
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import javax.sql.RowSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Defines a framework that allows applications to use a manual decision tree
|
||||
* to decide what should be done when a synchronization conflict occurs.
|
||||
* Although it is not mandatory for
|
||||
* applications to resolve synchronization conflicts manually, this
|
||||
* framework provides the means to delegate to the application when conflicts
|
||||
* arise.
|
||||
* <p>
|
||||
* Note that a conflict is a situation where the <code>RowSet</code> object's original
|
||||
* values for a row do not match the values in the data source, which indicates that
|
||||
* the data source row has been modified since the last synchronization. Note also that
|
||||
* a <code>RowSet</code> object's original values are the values it had just prior to the
|
||||
* the last synchronization, which are not necessarily its initial values.
|
||||
*
|
||||
*
|
||||
* <H2>Description of a <code>SyncResolver</code> Object</H2>
|
||||
*
|
||||
* A <code>SyncResolver</code> object is a specialized <code>RowSet</code> object
|
||||
* that implements the <code>SyncResolver</code> interface.
|
||||
* It <b>may</b> operate as either a connected <code>RowSet</code> object (an
|
||||
* implementation of the <code>JdbcRowSet</code> interface) or a connected
|
||||
* <code>RowSet</code> object (an implementation of the
|
||||
* <code>CachedRowSet</code> interface or one of its subinterfaces). For information
|
||||
* on the subinterfaces, see the
|
||||
* <a href="../package-summary.html"><code>javax.sql.rowset</code></a> package
|
||||
* description. The reference implementation for <code>SyncResolver</code> implements
|
||||
* the <code>CachedRowSet</code> interface, but other implementations
|
||||
* may choose to implement the <code>JdbcRowSet</code> interface to satisfy
|
||||
* particular needs.
|
||||
* <P>
|
||||
* After an application has attempted to synchronize a <code>RowSet</code> object with
|
||||
* the data source (by calling the <code>CachedRowSet</code>
|
||||
* method <code>acceptChanges</code>), and one or more conflicts have been found,
|
||||
* a rowset's <code>SyncProvider</code> object creates an instance of
|
||||
* <code>SyncResolver</code>. This new <code>SyncResolver</code> object has
|
||||
* the same number of rows and columns as the
|
||||
* <code>RowSet</code> object that was attempting the synchronization. The
|
||||
* <code>SyncResolver</code> object contains the values from the data source that caused
|
||||
* the conflict(s) and <code>null</code> for all other values.
|
||||
* In addition, it contains information about each conflict.
|
||||
*
|
||||
*
|
||||
* <H2>Getting and Using a <code>SyncResolver</code> Object</H2>
|
||||
*
|
||||
* When the method <code>acceptChanges</code> encounters conflicts, the
|
||||
* <code>SyncProvider</code> object creates a <code>SyncProviderException</code>
|
||||
* object and sets it with the new <code>SyncResolver</code> object. The method
|
||||
* <code>acceptChanges</code> will throw this exception, which
|
||||
* the application can then catch and use to retrieve the
|
||||
* <code>SyncResolver</code> object it contains. The following code snippet uses the
|
||||
* <code>SyncProviderException</code> method <code>getSyncResolver</code> to get
|
||||
* the <code>SyncResolver</code> object <i>resolver</i>.
|
||||
* <PRE>
|
||||
* {@code
|
||||
* } catch (SyncProviderException spe) {
|
||||
* SyncResolver resolver = spe.getSyncResolver();
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </PRE>
|
||||
* <P>
|
||||
* With <i>resolver</i> in hand, an application can use it to get the information
|
||||
* it contains about the conflict or conflicts. A <code>SyncResolver</code> object
|
||||
* such as <i>resolver</i> keeps
|
||||
* track of the conflicts for each row in which there is a conflict. It also places a
|
||||
* lock on the table or tables affected by the rowset's command so that no more
|
||||
* conflicts can occur while the current conflicts are being resolved.
|
||||
* <P>
|
||||
* The following kinds of information can be obtained from a <code>SyncResolver</code>
|
||||
* object:
|
||||
*
|
||||
* <h3>What operation was being attempted when a conflict occurred</h3>
|
||||
* The <code>SyncProvider</code> interface defines four constants
|
||||
* describing states that may occur. Three
|
||||
* constants describe the type of operation (update, delete, or insert) that a
|
||||
* <code>RowSet</code> object was attempting to perform when a conflict was discovered,
|
||||
* and the fourth indicates that there is no conflict.
|
||||
* These constants are the possible return values when a <code>SyncResolver</code> object
|
||||
* calls the method <code>getStatus</code>.
|
||||
* <PRE>
|
||||
* {@code int operation = resolver.getStatus(); }
|
||||
* </PRE>
|
||||
*
|
||||
* <h3>The value in the data source that caused a conflict</h3>
|
||||
* A conflict exists when a value that a <code>RowSet</code> object has changed
|
||||
* and is attempting to write to the data source
|
||||
* has also been changed in the data source since the last synchronization. An
|
||||
* application can call the <code>SyncResolver</code> method
|
||||
* <code>getConflictValue</code > to retrieve the
|
||||
* value in the data source that is the cause of the conflict because the values in a
|
||||
* <code>SyncResolver</code> object are the conflict values from the data source.
|
||||
* <PRE>
|
||||
* java.lang.Object conflictValue = resolver.getConflictValue(2);
|
||||
* </PRE>
|
||||
* Note that the column in <i>resolver</i> can be designated by the column number,
|
||||
* as is done in the preceding line of code, or by the column name.
|
||||
* <P>
|
||||
* With the information retrieved from the methods <code>getStatus</code> and
|
||||
* <code>getConflictValue</code>, the application may make a determination as to
|
||||
* which value should be persisted in the data source. The application then calls the
|
||||
* <code>SyncResolver</code> method <code>setResolvedValue</code>, which sets the value
|
||||
* to be persisted in the <code>RowSet</code> object and also in the data source.
|
||||
* <PRE>
|
||||
* resolver.setResolvedValue("DEPT", 8390426);
|
||||
* </PRE>
|
||||
* In the preceding line of code,
|
||||
* the column name designates the column in the <code>RowSet</code> object
|
||||
* that is to be set with the given value. The column number can also be used to
|
||||
* designate the column.
|
||||
* <P>
|
||||
* An application calls the method <code>setResolvedValue</code> after it has
|
||||
* resolved all of the conflicts in the current conflict row and repeats this process
|
||||
* for each conflict row in the <code>SyncResolver</code> object.
|
||||
*
|
||||
*
|
||||
* <H2>Navigating a <code>SyncResolver</code> Object</H2>
|
||||
*
|
||||
* Because a <code>SyncResolver</code> object is a <code>RowSet</code> object, an
|
||||
* application can use all of the <code>RowSet</code> methods for moving the cursor
|
||||
* to navigate a <code>SyncResolver</code> object. For example, an application can
|
||||
* use the <code>RowSet</code> method <code>next</code> to get to each row and then
|
||||
* call the <code>SyncResolver</code> method <code>getStatus</code> to see if the row
|
||||
* contains a conflict. In a row with one or more conflicts, the application can
|
||||
* iterate through the columns to find any non-null values, which will be the values
|
||||
* from the data source that are in conflict.
|
||||
* <P>
|
||||
* To make it easier to navigate a <code>SyncResolver</code> object, especially when
|
||||
* there are large numbers of rows with no conflicts, the <code>SyncResolver</code>
|
||||
* interface defines the methods <code>nextConflict</code> and
|
||||
* <code>previousConflict</code>, which move only to rows
|
||||
* that contain at least one conflict value. Then an application can call the
|
||||
* <code>SyncResolver</code> method <code>getConflictValue</code>, supplying it
|
||||
* with the column number, to get the conflict value itself. The code fragment in the
|
||||
* next section gives an example.
|
||||
*
|
||||
* <H2>Code Example</H2>
|
||||
*
|
||||
* The following code fragment demonstrates how a disconnected <code>RowSet</code>
|
||||
* object <i>crs</i> might attempt to synchronize itself with the
|
||||
* underlying data source and then resolve the conflicts. In the <code>try</code>
|
||||
* block, <i>crs</i> calls the method <code>acceptChanges</code>, passing it the
|
||||
* <code>Connection</code> object <i>con</i>. If there are no conflicts, the
|
||||
* changes in <i>crs</i> are simply written to the data source. However, if there
|
||||
* is a conflict, the method <code>acceptChanges</code> throws a
|
||||
* <code>SyncProviderException</code> object, and the
|
||||
* <code>catch</code> block takes effect. In this example, which
|
||||
* illustrates one of the many ways a <code>SyncResolver</code> object can be used,
|
||||
* the <code>SyncResolver</code> method <code>nextConflict</code> is used in a
|
||||
* <code>while</code> loop. The loop will end when <code>nextConflict</code> returns
|
||||
* <code>false</code>, which will occur when there are no more conflict rows in the
|
||||
* <code>SyncResolver</code> object <i>resolver</i>. In This particular code fragment,
|
||||
* <i>resolver</i> looks for rows that have update conflicts (rows with the status
|
||||
* <code>SyncResolver.UPDATE_ROW_CONFLICT</code>), and the rest of this code fragment
|
||||
* executes only for rows where conflicts occurred because <i>crs</i> was attempting an
|
||||
* update.
|
||||
* <P>
|
||||
* After the cursor for <i>resolver</i> has moved to the next conflict row that
|
||||
* has an update conflict, the method <code>getRow</code> indicates the number of the
|
||||
* current row, and
|
||||
* the cursor for the <code>CachedRowSet</code> object <i>crs</i> is moved to
|
||||
* the comparable row in <i>crs</i>. By iterating
|
||||
* through the columns of that row in both <i>resolver</i> and <i>crs</i>, the conflicting
|
||||
* values can be retrieved and compared to decide which one should be persisted. In this
|
||||
* code fragment, the value in <i>crs</i> is the one set as the resolved value, which means
|
||||
* that it will be used to overwrite the conflict value in the data source.
|
||||
*
|
||||
* <PRE>
|
||||
* {@code
|
||||
* try {
|
||||
*
|
||||
* crs.acceptChanges(con);
|
||||
*
|
||||
* } catch (SyncProviderException spe) {
|
||||
*
|
||||
* SyncResolver resolver = spe.getSyncResolver();
|
||||
*
|
||||
* Object crsValue; // value in the RowSet object
|
||||
* Object resolverValue: // value in the SyncResolver object
|
||||
* Object resolvedValue: // value to be persisted
|
||||
*
|
||||
* while(resolver.nextConflict()) {
|
||||
* if(resolver.getStatus() == SyncResolver.UPDATE_ROW_CONFLICT) {
|
||||
* int row = resolver.getRow();
|
||||
* crs.absolute(row);
|
||||
*
|
||||
* int colCount = crs.getMetaData().getColumnCount();
|
||||
* for(int j = 1; j <= colCount; j++) {
|
||||
* if (resolver.getConflictValue(j) != null) {
|
||||
* crsValue = crs.getObject(j);
|
||||
* resolverValue = resolver.getConflictValue(j);
|
||||
* . . .
|
||||
* // compare crsValue and resolverValue to determine
|
||||
* // which should be the resolved value (the value to persist)
|
||||
* resolvedValue = crsValue;
|
||||
*
|
||||
* resolver.setResolvedValue(j, resolvedValue);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }</PRE>
|
||||
* @author Jonathan Bruce
|
||||
*/
|
||||
|
||||
public interface SyncResolver extends RowSet {
|
||||
/**
|
||||
* Indicates that a conflict occurred while the <code>RowSet</code> object was
|
||||
* attempting to update a row in the data source.
|
||||
* The values in the data source row to be updated differ from the
|
||||
* <code>RowSet</code> object's original values for that row, which means that
|
||||
* the row in the data source has been updated or deleted since the last
|
||||
* synchronization.
|
||||
*/
|
||||
public static int UPDATE_ROW_CONFLICT = 0;
|
||||
|
||||
/**
|
||||
* Indicates that a conflict occurred while the <code>RowSet</code> object was
|
||||
* attempting to delete a row in the data source.
|
||||
* The values in the data source row to be updated differ from the
|
||||
* <code>RowSet</code> object's original values for that row, which means that
|
||||
* the row in the data source has been updated or deleted since the last
|
||||
* synchronization.
|
||||
*/
|
||||
public static int DELETE_ROW_CONFLICT = 1;
|
||||
|
||||
/**
|
||||
* Indicates that a conflict occurred while the <code>RowSet</code> object was
|
||||
* attempting to insert a row into the data source. This means that a
|
||||
* row with the same primary key as the row to be inserted has been inserted
|
||||
* into the data source since the last synchronization.
|
||||
*/
|
||||
public static int INSERT_ROW_CONFLICT = 2;
|
||||
|
||||
/**
|
||||
* Indicates that <b>no</b> conflict occurred while the <code>RowSet</code> object
|
||||
* was attempting to update, delete or insert a row in the data source. The values in
|
||||
* the <code>SyncResolver</code> will contain <code>null</code> values only as an indication
|
||||
* that no information in pertinent to the conflict resolution in this row.
|
||||
*/
|
||||
public static int NO_ROW_CONFLICT = 3;
|
||||
|
||||
/**
|
||||
* Retrieves the conflict status of the current row of this <code>SyncResolver</code>,
|
||||
* which indicates the operation
|
||||
* the <code>RowSet</code> object was attempting when the conflict occurred.
|
||||
*
|
||||
* @return one of the following constants:
|
||||
* <code>SyncResolver.UPDATE_ROW_CONFLICT</code>,
|
||||
* <code>SyncResolver.DELETE_ROW_CONFLICT</code>,
|
||||
* <code>SyncResolver.INSERT_ROW_CONFLICT</code>, or
|
||||
* <code>SyncResolver.NO_ROW_CONFLICT</code>
|
||||
*/
|
||||
public int getStatus();
|
||||
|
||||
/**
|
||||
* Retrieves the value in the designated column in the current row of this
|
||||
* <code>SyncResolver</code> object, which is the value in the data source
|
||||
* that caused a conflict.
|
||||
*
|
||||
* @param index an <code>int</code> designating the column in this row of this
|
||||
* <code>SyncResolver</code> object from which to retrieve the value
|
||||
* causing a conflict
|
||||
* @return the value of the designated column in the current row of this
|
||||
* <code>SyncResolver</code> object
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public Object getConflictValue(int index) throws SQLException;
|
||||
|
||||
/**
|
||||
* Retrieves the value in the designated column in the current row of this
|
||||
* <code>SyncResolver</code> object, which is the value in the data source
|
||||
* that caused a conflict.
|
||||
*
|
||||
* @param columnName a <code>String</code> object designating the column in this row of this
|
||||
* <code>SyncResolver</code> object from which to retrieve the value
|
||||
* causing a conflict
|
||||
* @return the value of the designated column in the current row of this
|
||||
* <code>SyncResolver</code> object
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public Object getConflictValue(String columnName) throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets <i>obj</i> as the value in column <i>index</i> in the current row of the
|
||||
* <code>RowSet</code> object that is being synchronized. <i>obj</i>
|
||||
* is set as the value in the data source internally.
|
||||
*
|
||||
* @param index an <code>int</code> giving the number of the column into which to
|
||||
* set the value to be persisted
|
||||
* @param obj an <code>Object</code> that is the value to be set in the
|
||||
* <code>RowSet</code> object and persisted in the data source
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public void setResolvedValue(int index, Object obj) throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets <i>obj</i> as the value in column <i>columnName</i> in the current row of the
|
||||
* <code>RowSet</code> object that is being synchronized. <i>obj</i>
|
||||
* is set as the value in the data source internally.
|
||||
*
|
||||
* @param columnName a <code>String</code> object giving the name of the column
|
||||
* into which to set the value to be persisted
|
||||
* @param obj an <code>Object</code> that is the value to be set in the
|
||||
* <code>RowSet</code> object and persisted in the data source
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public void setResolvedValue(String columnName, Object obj) throws SQLException;
|
||||
|
||||
/**
|
||||
* Moves the cursor down from its current position to the next row that contains
|
||||
* a conflict value. A <code>SyncResolver</code> object's
|
||||
* cursor is initially positioned before the first conflict row; the first call to the
|
||||
* method <code>nextConflict</code> makes the first conflict row the current row;
|
||||
* the second call makes the second conflict row the current row, and so on.
|
||||
* <p>
|
||||
* A call to the method <code>nextConflict</code> will implicitly close
|
||||
* an input stream if one is open and will clear the <code>SyncResolver</code>
|
||||
* object's warning chain.
|
||||
*
|
||||
* @return <code>true</code> if the new current row is valid; <code>false</code>
|
||||
* if there are no more rows
|
||||
* @throws SQLException if a database access error occurs or the result set type
|
||||
* is <code>TYPE_FORWARD_ONLY</code>
|
||||
*
|
||||
*/
|
||||
public boolean nextConflict() throws SQLException;
|
||||
|
||||
/**
|
||||
* Moves the cursor up from its current position to the previous conflict
|
||||
* row in this <code>SyncResolver</code> object.
|
||||
* <p>
|
||||
* A call to the method <code>previousConflict</code> will implicitly close
|
||||
* an input stream if one is open and will clear the <code>SyncResolver</code>
|
||||
* object's warning chain.
|
||||
*
|
||||
* @return <code>true</code> if the cursor is on a valid row; <code>false</code>
|
||||
* if it is off the result set
|
||||
* @throws SQLException if a database access error occurs or the result set type
|
||||
* is <code>TYPE_FORWARD_ONLY</code>
|
||||
*/
|
||||
public boolean previousConflict() throws SQLException;
|
||||
|
||||
}
|
83
jdkSrc/jdk8/javax/sql/rowset/spi/TransactionalWriter.java
Normal file
83
jdkSrc/jdk8/javax/sql/rowset/spi/TransactionalWriter.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.io.Reader;
|
||||
|
||||
import javax.sql.RowSetWriter;
|
||||
import javax.sql.rowset.*;
|
||||
import java.sql.Savepoint;
|
||||
|
||||
/**
|
||||
* A specialized interface that facilitates an extension of the standard
|
||||
* <code>SyncProvider</code> abstract class so that it has finer grained
|
||||
* transaction control.
|
||||
* <p>
|
||||
* If one or more disconnected <code>RowSet</code> objects are participating
|
||||
* in a global transaction, they may wish to coordinate their synchronization
|
||||
* commits to preserve data integrity and reduce the number of
|
||||
* synchronization exceptions. If this is the case, an application should set
|
||||
* the <code>CachedRowSet</code> constant <code>COMMIT_ON_ACCEPT_CHANGES</code>
|
||||
* to <code>false</code> and use the <code>commit</code> and <code>rollback</code>
|
||||
* methods defined in this interface to manage transaction boundaries.
|
||||
*/
|
||||
public interface TransactionalWriter extends RowSetWriter {
|
||||
|
||||
/**
|
||||
* Makes permanent all changes that have been performed by the
|
||||
* <code>acceptChanges</code> method since the last call to either the
|
||||
* <code>commit</code> or <code>rollback</code> methods.
|
||||
* This method should be used only when auto-commit mode has been disabled.
|
||||
*
|
||||
* @throws SQLException if a database access error occurs or the
|
||||
* <code>Connection</code> object within this <code>CachedRowSet</code>
|
||||
* object is in auto-commit mode
|
||||
*/
|
||||
public void commit() throws SQLException;
|
||||
|
||||
/**
|
||||
* Undoes all changes made in the current transaction. This method should be
|
||||
* used only when auto-commit mode has been disabled.
|
||||
*
|
||||
* @throws SQLException if a database access error occurs or the <code>Connection</code>
|
||||
* object within this <code>CachedRowSet</code> object is in auto-commit mode
|
||||
*/
|
||||
public void rollback() throws SQLException;
|
||||
|
||||
/**
|
||||
* Undoes all changes made in the current transaction made prior to the given
|
||||
* <code>Savepoint</code> object. This method should be used only when auto-commit
|
||||
* mode has been disabled.
|
||||
*
|
||||
* @param s a <code>Savepoint</code> object marking a savepoint in the current
|
||||
* transaction. All changes made before <i>s</i> was set will be undone.
|
||||
* All changes made after <i>s</i> was set will be made permanent.
|
||||
* @throws SQLException if a database access error occurs or the <code>Connection</code>
|
||||
* object within this <code>CachedRowSet</code> object is in auto-commit mode
|
||||
*/
|
||||
public void rollback(Savepoint s) throws SQLException;
|
||||
}
|
74
jdkSrc/jdk8/javax/sql/rowset/spi/XmlReader.java
Normal file
74
jdkSrc/jdk8/javax/sql/rowset/spi/XmlReader.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.io.Reader;
|
||||
|
||||
import javax.sql.RowSetReader;
|
||||
import javax.sql.rowset.*;
|
||||
|
||||
/**
|
||||
* A specialized interface that facilitates an extension of the
|
||||
* <code>SyncProvider</code> abstract class for XML orientated
|
||||
* synchronization providers.
|
||||
* <P>
|
||||
* <code>SyncProvider</code> implementations that supply XML data reader
|
||||
* capabilities such as output XML stream capabilities can implement this
|
||||
* interface to provide standard <code>XmlReader</code> objects to
|
||||
* <code>WebRowSet</code> implementations.
|
||||
* <p>
|
||||
* An <code>XmlReader</code> object is registered as the
|
||||
* XML reader for a <code>WebRowSet</code> by being assigned to the
|
||||
* rowset's <code>xmlReader</code> field. When the <code>WebRowSet</code>
|
||||
* object's <code>readXml</code> method is invoked, it in turn invokes
|
||||
* its XML reader's <code>readXML</code> method.
|
||||
*/
|
||||
public interface XmlReader extends RowSetReader {
|
||||
|
||||
/**
|
||||
* Reads and parses the given <code>WebRowSet</code> object from the given
|
||||
* input stream in XML format. The <code>xmlReader</code> field of the
|
||||
* given <code>WebRowSet</code> object must contain this
|
||||
* <code>XmlReader</code> object.
|
||||
* <P>
|
||||
* If a parsing error occurs, the exception that is thrown will
|
||||
* include information about the location of the error in the
|
||||
* original XML document.
|
||||
*
|
||||
* @param caller the <code>WebRowSet</code> object to be parsed, whose
|
||||
* <code>xmlReader</code> field must contain a reference to
|
||||
* this <code>XmlReader</code> object
|
||||
* @param reader the <code>java.io.Reader</code> object from which
|
||||
* <code>caller</code> will be read
|
||||
* @throws SQLException if a database access error occurs or
|
||||
* this <code>XmlReader</code> object is not the reader
|
||||
* for the given rowset
|
||||
*/
|
||||
public void readXML(WebRowSet caller, java.io.Reader reader)
|
||||
throws SQLException;
|
||||
|
||||
}
|
74
jdkSrc/jdk8/javax/sql/rowset/spi/XmlWriter.java
Normal file
74
jdkSrc/jdk8/javax/sql/rowset/spi/XmlWriter.java
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.sql.rowset.spi;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.io.Writer;
|
||||
|
||||
import javax.sql.RowSetWriter;
|
||||
import javax.sql.rowset.*;
|
||||
|
||||
/**
|
||||
* A specialized interface that facilitates an extension of the
|
||||
* <code>SyncProvider</code> abstract class for XML orientated
|
||||
* synchronization providers.
|
||||
* <p>
|
||||
* <code>SyncProvider</code> implementations that supply XML data writer
|
||||
* capabilities such as output XML stream capabilities can implement this
|
||||
* interface to provide standard <code>XmlWriter</code> objects to
|
||||
* <code>WebRowSet</code> implementations.
|
||||
* <P>
|
||||
* Writing a <code>WebRowSet</code> object includes printing the
|
||||
* rowset's data, metadata, and properties, all with the
|
||||
* appropriate XML tags.
|
||||
*/
|
||||
public interface XmlWriter extends RowSetWriter {
|
||||
|
||||
/**
|
||||
* Writes the given <code>WebRowSet</code> object to the specified
|
||||
* <code>java.io.Writer</code> output stream as an XML document.
|
||||
* This document includes the rowset's data, metadata, and properties
|
||||
* plus the appropriate XML tags.
|
||||
* <P>
|
||||
* The <code>caller</code> parameter must be a <code>WebRowSet</code>
|
||||
* object whose <code>XmlWriter</code> field contains a reference to
|
||||
* this <code>XmlWriter</code> object.
|
||||
*
|
||||
* @param caller the <code>WebRowSet</code> instance to be written,
|
||||
* for which this <code>XmlWriter</code> object is the writer
|
||||
* @param writer the <code>java.io.Writer</code> object that serves
|
||||
* as the output stream for writing <code>caller</code> as
|
||||
* an XML document
|
||||
* @throws SQLException if a database access error occurs or
|
||||
* this <code>XmlWriter</code> object is not the writer
|
||||
* for the given <code>WebRowSet</code> object
|
||||
*/
|
||||
public void writeXML(WebRowSet caller, java.io.Writer writer)
|
||||
throws SQLException;
|
||||
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user