undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
10129
src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java
Normal file
10129
src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
6938
src/java.sql.rowset/share/classes/com/sun/rowset/JdbcRowSetImpl.java
Normal file
6938
src/java.sql.rowset/share/classes/com/sun/rowset/JdbcRowSetImpl.java
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 2005, 2022, 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 com.sun.rowset;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class is used to help in localization of resources,
|
||||
* especially the exception strings.
|
||||
*
|
||||
* @author Amit Handa
|
||||
*/
|
||||
|
||||
public class JdbcRowSetResourceBundle implements Serializable {
|
||||
|
||||
/**
|
||||
* This <code>String</code> variable stores the location
|
||||
* of the resource bundle location.
|
||||
*/
|
||||
private static String fileName;
|
||||
|
||||
/**
|
||||
* This variable will hold the <code>PropertyResourceBundle</code>
|
||||
* of the text to be internationalized.
|
||||
*/
|
||||
private transient PropertyResourceBundle propResBundle;
|
||||
|
||||
/**
|
||||
* The constructor initializes to this object
|
||||
*
|
||||
*/
|
||||
private static volatile JdbcRowSetResourceBundle jpResBundle;
|
||||
|
||||
/**
|
||||
* The variable which will represent the properties
|
||||
* the suffix or extension of the resource bundle.
|
||||
**/
|
||||
private static final String PROPERTIES = "properties";
|
||||
|
||||
/**
|
||||
* The variable to represent underscore
|
||||
**/
|
||||
private static final String UNDERSCORE = "_";
|
||||
|
||||
/**
|
||||
* The variable which will represent dot
|
||||
**/
|
||||
private static final String DOT = ".";
|
||||
|
||||
/**
|
||||
* The variable which will represent the slash.
|
||||
**/
|
||||
private static final String SLASH = "/";
|
||||
|
||||
/**
|
||||
* The variable where the default resource bundle will
|
||||
* be placed.
|
||||
**/
|
||||
private static final String PATH = "com.sun.rowset.RowSetResourceBundle";
|
||||
|
||||
/**
|
||||
* The constructor which initializes the resource bundle.
|
||||
* Note this is a private constructor and follows Singleton
|
||||
* Design Pattern.
|
||||
*
|
||||
* @throws IOException if unable to load the ResourceBundle
|
||||
* according to locale or the default one.
|
||||
*/
|
||||
private JdbcRowSetResourceBundle () throws IOException {
|
||||
// Try to load the resource bundle according
|
||||
// to the locale. Else if no bundle found according
|
||||
// to the locale load the default.
|
||||
|
||||
// In default case the default locale resource bundle
|
||||
// should always be loaded else it
|
||||
// will be difficult to throw appropriate
|
||||
// exception string messages.
|
||||
Locale locale = Locale.getDefault();
|
||||
|
||||
// Load appropriate bundle according to locale
|
||||
propResBundle = (PropertyResourceBundle) ResourceBundle.getBundle(PATH,
|
||||
locale, JdbcRowSetResourceBundle.class.getModule());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to get a handle to the
|
||||
* initialized instance of this class. Note that
|
||||
* at any time there is only one instance of this
|
||||
* class initialized which will be returned.
|
||||
*
|
||||
* @throws IOException if unable to find the RowSetResourceBundle.properties
|
||||
*/
|
||||
public static JdbcRowSetResourceBundle getJdbcRowSetResourceBundle()
|
||||
throws IOException {
|
||||
|
||||
if(jpResBundle == null){
|
||||
synchronized(JdbcRowSetResourceBundle.class) {
|
||||
if(jpResBundle == null){
|
||||
jpResBundle = new JdbcRowSetResourceBundle();
|
||||
} //end if
|
||||
} //end synchronized block
|
||||
} //end if
|
||||
return jpResBundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an enumerated handle of the keys
|
||||
* which correspond to values translated to various locales.
|
||||
*
|
||||
* @return an enumeration of keys which have messages translated to
|
||||
* corresponding locales.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Enumeration getKeys() {
|
||||
return propResBundle.getKeys();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method takes the key as an argument and
|
||||
* returns the corresponding value reading it
|
||||
* from the Resource Bundle loaded earlier.
|
||||
*
|
||||
* @return value in locale specific language
|
||||
* according to the key passed.
|
||||
*/
|
||||
public Object handleGetObject(String key) {
|
||||
return propResBundle.handleGetObject(key);
|
||||
}
|
||||
|
||||
static final long serialVersionUID = 436199386225359954L;
|
||||
}
|
||||
4355
src/java.sql.rowset/share/classes/com/sun/rowset/JoinRowSetImpl.java
Normal file
4355
src/java.sql.rowset/share/classes/com/sun/rowset/JoinRowSetImpl.java
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 com.sun.rowset;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import javax.sql.rowset.CachedRowSet;
|
||||
import javax.sql.rowset.FilteredRowSet;
|
||||
import javax.sql.rowset.JdbcRowSet;
|
||||
import javax.sql.rowset.JoinRowSet;
|
||||
import javax.sql.rowset.WebRowSet;
|
||||
import javax.sql.rowset.RowSetFactory;
|
||||
|
||||
/**
|
||||
* This is the implementation specific class for the
|
||||
* <code>javax.sql.rowset.spi.RowSetFactory</code>. This is the platform
|
||||
* default implementation for the Java SE platform.
|
||||
*
|
||||
* @author Lance Andersen
|
||||
*
|
||||
*
|
||||
* @version 1.7
|
||||
*/
|
||||
public final class RowSetFactoryImpl implements RowSetFactory {
|
||||
|
||||
public CachedRowSet createCachedRowSet() throws SQLException {
|
||||
return new com.sun.rowset.CachedRowSetImpl();
|
||||
}
|
||||
|
||||
public FilteredRowSet createFilteredRowSet() throws SQLException {
|
||||
return new com.sun.rowset.FilteredRowSetImpl();
|
||||
}
|
||||
|
||||
|
||||
public JdbcRowSet createJdbcRowSet() throws SQLException {
|
||||
return new com.sun.rowset.JdbcRowSetImpl();
|
||||
}
|
||||
|
||||
public JoinRowSet createJoinRowSet() throws SQLException {
|
||||
return new com.sun.rowset.JoinRowSetImpl();
|
||||
}
|
||||
|
||||
public WebRowSet createWebRowSet() throws SQLException {
|
||||
return new com.sun.rowset.WebRowSetImpl();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = Invalid ResultSet object supplied to populate method
|
||||
cachedrowsetimpl.invalidp = Invalid persistence provider generated
|
||||
cachedrowsetimpl.nullhash = Cannot instantiate CachedRowSetImpl instance. Null Hashtable supplied to constructor
|
||||
cachedrowsetimpl.invalidop = Invalid operation while on insert row
|
||||
cachedrowsetimpl.accfailed = acceptChanges Failed
|
||||
cachedrowsetimpl.invalidcp = Invalid cursor position
|
||||
cachedrowsetimpl.illegalop = Illegal operation on non-inserted row
|
||||
cachedrowsetimpl.clonefail = Clone failed: {0}
|
||||
cachedrowsetimpl.invalidcol = Invalid column index
|
||||
cachedrowsetimpl.invalcolnm = Invalid column name
|
||||
cachedrowsetimpl.boolfail = getBoolen Failed on value ( {0} ) in column {1}
|
||||
cachedrowsetimpl.bytefail = getByte Failed on value ( {0} ) in column {1}
|
||||
cachedrowsetimpl.shortfail = getShort Failed on value ( {0} ) in column {1}
|
||||
cachedrowsetimpl.intfail = getInt Failed on value ( {0} ) in column {1}
|
||||
cachedrowsetimpl.longfail = getLong Failed on value ( {0} ) in column {1}
|
||||
cachedrowsetimpl.floatfail = getFloat failed on value ( {0} ) in column {1}
|
||||
cachedrowsetimpl.doublefail = getDouble failed on value ( {0} ) in column {1}
|
||||
cachedrowsetimpl.dtypemismt = Data Type Mismatch
|
||||
cachedrowsetimpl.datefail = getDate Failed on value ( {0} ) in column {1} no conversion available
|
||||
cachedrowsetimpl.timefail = getTime failed on value ( {0} ) in column {1} no conversion available
|
||||
cachedrowsetimpl.posupdate = Positioned updates not supported
|
||||
cachedrowsetimpl.unableins = Unable to instantiate : {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst : Invalid cursor operation
|
||||
cachedrowsetimpl.first = First : Invalid cursor operation
|
||||
cachedrowsetimpl.last = last : TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute : Invalid cursor position
|
||||
cachedrowsetimpl.relative = relative : Invalid cursor position
|
||||
cachedrowsetimpl.asciistream = read failed for ascii stream
|
||||
cachedrowsetimpl.binstream = read failed on binary stream
|
||||
cachedrowsetimpl.failedins = Failed on insert row
|
||||
cachedrowsetimpl.updateins = updateRow called while on insert row
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow : CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow : no meta data
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow : invalid number of columns
|
||||
cachedrowsetimpl.tablename = Table name cannot be null
|
||||
cachedrowsetimpl.keycols = Invalid key columns
|
||||
cachedrowsetimpl.opnotsupp = Operation not supported by Database
|
||||
cachedrowsetimpl.matchcols = Match columns are not the same as those set
|
||||
cachedrowsetimpl.setmatchcols = Set Match columns before getting them
|
||||
cachedrowsetimpl.matchcols1 = Match columns should be greater than 0
|
||||
cachedrowsetimpl.matchcols2 = Match columns should be empty or null string
|
||||
cachedrowsetimpl.unsetmatch = Columns being unset are not the same as set
|
||||
cachedrowsetimpl.unsetmatch1 = Use column name as argument to unsetMatchColumn
|
||||
cachedrowsetimpl.unsetmatch2 = Use column ID as argument to unsetMatchColumn
|
||||
cachedrowsetimpl.numrows = Number of rows is less than zero or less than fetch size
|
||||
cachedrowsetimpl.startpos = Start position cannot be negative
|
||||
cachedrowsetimpl.nextpage = Populate data before calling
|
||||
cachedrowsetimpl.pagesize = Page size cannot be less than zero
|
||||
cachedrowsetimpl.pagesize1 = Page size cannot be greater than maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet is forward only
|
||||
cachedrowsetimpl.type = Type is : {0}
|
||||
cachedrowsetimpl.opnotysupp = Operation not yet supported
|
||||
cachedrowsetimpl.featnotsupp = Feature not supported
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = Cannot instantiate WebRowSetImpl instance. Null Hashtable supplied to constructor
|
||||
webrowsetimpl.invalidwr = Invalid writer
|
||||
webrowsetimpl.invalidrd = Invalid reader
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative : Invalid cursor operation
|
||||
filteredrowsetimpl.absolute = absolute : Invalid cursor operation
|
||||
filteredrowsetimpl.notallowed = This value is not allowed through the filter
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = Not an instance of rowset
|
||||
joinrowsetimpl.matchnotset = Match Column not set for join
|
||||
joinrowsetimpl.numnotequal = Number of elements in rowset not equal to match column
|
||||
joinrowsetimpl.notdefined = This is not a defined type of join
|
||||
joinrowsetimpl.notsupported = This type of join is not supported
|
||||
joinrowsetimpl.initerror = JoinRowSet initialization error
|
||||
joinrowsetimpl.genericerr = Generic joinrowset initial error
|
||||
joinrowsetimpl.emptyrowset = Empty rowset cannot be added to this JoinRowSet
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = Invalid state
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (connect) JNDI unable to connect
|
||||
jdbcrowsetimpl.paramtype = Unable to deduce param type
|
||||
jdbcrowsetimpl.matchcols = Match Columns are not the same as those set
|
||||
jdbcrowsetimpl.setmatchcols = Set the match columns before getting them
|
||||
jdbcrowsetimpl.matchcols1 = Match columns should be greater than 0
|
||||
jdbcrowsetimpl.matchcols2 = Match columns cannot be null or empty string
|
||||
jdbcrowsetimpl.unsetmatch = Columns being unset are not the same as those set
|
||||
jdbcrowsetimpl.usecolname = Use column name as argument to unsetMatchColumn
|
||||
jdbcrowsetimpl.usecolid = Use column ID as argument to unsetMatchColumn
|
||||
jdbcrowsetimpl.resnotupd = ResultSet is not updatable
|
||||
jdbcrowsetimpl.opnotysupp = Operation not yet supported
|
||||
jdbcrowsetimpl.featnotsupp = Feature not supported
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) Unable to connect
|
||||
crsreader.paramtype = Unable to deduce param type
|
||||
crsreader.connecterr = Internal Error in RowSetReader: no connection or command
|
||||
crsreader.datedetected = Detected a Date
|
||||
crsreader.caldetected = Detected a Calendar
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = Unable to get connection
|
||||
crswriter.tname = writeData cannot determine table name
|
||||
crswriter.params1 = Value of params1 : {0}
|
||||
crswriter.params2 = Value of params2 : {0}
|
||||
crswriter.conflictsno = conflicts while synchronizing
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = No value has been inserted
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = Index value out of range
|
||||
syncrsimpl.noconflict = This column not in conflict
|
||||
syncrsimpl.syncnotpos = Synchronization is not possible
|
||||
syncrsimpl.valtores = Value to be resolved can either be in the database or in cachedrowset
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = End of RowSet reached. Invalid cursor position
|
||||
wrsxmlreader.readxml = readXML : {0}
|
||||
wrsxmlreader.parseerr = ** Parsing Error : {0} , line : {1} , uri : {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException : {0}
|
||||
wrsxmlwriter.sqlex = SQLException : {0}
|
||||
wrsxmlwriter.failedwrite = Failed to write value
|
||||
wsrxmlwriter.notproper = Not a proper type
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Error setting Map : {0}
|
||||
xmlrch.errmetadata = Error setting metadata : {0}
|
||||
xmlrch.errinsertval = Error inserting values : {0}
|
||||
xmlrch.errconstr = Error constructing row : {0}
|
||||
xmlrch.errdel = Error deleting row : {0}
|
||||
xmlrch.errinsert = Error constructing insert row : {0}
|
||||
xmlrch.errinsdel = Error constructing insdel row : {0}
|
||||
xmlrch.errupdate = Error constructing update row : {0}
|
||||
xmlrch.errupdrow = Error updating row : {0}
|
||||
xmlrch.chars = characters :
|
||||
xmlrch.badvalue = Bad value ; non-nullable property
|
||||
xmlrch.badvalue1 = Bad value ; non-nullable metadata
|
||||
xmlrch.warning = ** Warning : {0} , line : {1} , uri : {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = Locking classification is not supported
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = Unsupported with RIXMLProvider
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = Ungültiges ResultSet-Objekt zum Auffüllen der Methode angegeben
|
||||
cachedrowsetimpl.invalidp = Ungültiger Persistence-Provider generiert
|
||||
cachedrowsetimpl.nullhash = CachedRowSetImpl-Instanz kann nicht instanziiert werden. Null-Hashtabelle für Constructor angegeben
|
||||
cachedrowsetimpl.invalidop = Ungültiger Vorgang beim Zeileneinfügen
|
||||
cachedrowsetimpl.accfailed = acceptChanges nicht erfolgreich
|
||||
cachedrowsetimpl.invalidcp = Ungültige Cursorposition
|
||||
cachedrowsetimpl.illegalop = Unzulässiger Vorgang bei nicht eingefügter Zeile
|
||||
cachedrowsetimpl.clonefail = Klonen nicht erfolgreich: {0}
|
||||
cachedrowsetimpl.invalidcol = Ungültiger Spaltenindex
|
||||
cachedrowsetimpl.invalcolnm = Ungültiger Spaltenname
|
||||
cachedrowsetimpl.boolfail = getBoolen bei Wert ( {0} ) in Spalte {1} nicht erfolgreich
|
||||
cachedrowsetimpl.bytefail = getByte bei Wert ( {0} ) in Spalte {1} nicht erfolgreich
|
||||
cachedrowsetimpl.shortfail = getShort bei Wert ( {0} ) in Spalte {1} nicht erfolgreich
|
||||
cachedrowsetimpl.intfail = getInt bei Wert ( {0} ) in Spalte {1} nicht erfolgreich
|
||||
cachedrowsetimpl.longfail = getLong bei Wert ( {0} ) in Spalte {1} nicht erfolgreich
|
||||
cachedrowsetimpl.floatfail = getFloat bei Wert ( {0} ) in Spalte {1} nicht erfolgreich
|
||||
cachedrowsetimpl.doublefail = getDouble bei Wert ( {0} ) in Spalte {1} nicht erfolgreich
|
||||
cachedrowsetimpl.dtypemismt = Keine Datentypübereinstimmung
|
||||
cachedrowsetimpl.datefail = getDate bei Wert ( {0} ) in Spalte {1} nicht erfolgreich. Keine Konvertierung möglich
|
||||
cachedrowsetimpl.timefail = getTime bei Wert ( {0} ) in Spalte {1} nicht erfolgreich. Keine Konvertierung möglich
|
||||
cachedrowsetimpl.posupdate = Positionierte Updates werden nicht unterstützt
|
||||
cachedrowsetimpl.unableins = Keine Instanziierung möglich: {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: Ungültiger Cursorvorgang
|
||||
cachedrowsetimpl.first = First: Ungültiger Cursorvorgang
|
||||
cachedrowsetimpl.last = last: TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute: Ungültige Cursorposition
|
||||
cachedrowsetimpl.relative = relative: Ungültige Cursorposition
|
||||
cachedrowsetimpl.asciistream = Lesen von ASCII-Stream nicht erfolgreich
|
||||
cachedrowsetimpl.binstream = Lesen von Binär-Stream nicht erfolgreich
|
||||
cachedrowsetimpl.failedins = Fehler beim Zeileneinfügen
|
||||
cachedrowsetimpl.updateins = updateRow beim Zeileneinfügen aufgerufen
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow: CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: keine Metadaten
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: ungültige Spaltenanzahl
|
||||
cachedrowsetimpl.tablename = Tabellenname darf nicht null sein
|
||||
cachedrowsetimpl.keycols = Ungültige Schlüsselspalten
|
||||
cachedrowsetimpl.opnotsupp = Vorgang nicht von Datenbank unterstützt
|
||||
cachedrowsetimpl.matchcols = Übereinstimmungsspalten entsprechen nicht den festgelegten Spalten
|
||||
cachedrowsetimpl.setmatchcols = Übereinstimmungsspalten müssen vor dem Abrufen festgelegt werden
|
||||
cachedrowsetimpl.matchcols1 = Wert für Übereinstimmungsspalten muss größer als 0 sein
|
||||
cachedrowsetimpl.matchcols2 = Übereinstimmungsspalten müssen leer sein oder eine Nullzeichenfolge aufweisen
|
||||
cachedrowsetimpl.unsetmatch = Spalten, deren Wert aufgehoben wird, entsprechen nicht den festgelegten Spalten
|
||||
cachedrowsetimpl.unsetmatch1 = Spaltenname als Argument für unsetMatchColumn verwenden
|
||||
cachedrowsetimpl.unsetmatch2 = Spalten-ID als Argument für unsetMatchColumn verwenden
|
||||
cachedrowsetimpl.numrows = Zeilenanzahl ist kleiner als null oder kleiner als Abrufgröße
|
||||
cachedrowsetimpl.startpos = Startposition darf keinen Negativwert aufweisen
|
||||
cachedrowsetimpl.nextpage = Daten müssen vor dem Aufruf ausgefüllt werden
|
||||
cachedrowsetimpl.pagesize = Seitengröße darf nicht kleiner als null sein
|
||||
cachedrowsetimpl.pagesize1 = Seitengröße darf nicht größer als maxRows sein
|
||||
cachedrowsetimpl.fwdonly = ResultSet kann nur vorwärts gerichtet sein
|
||||
cachedrowsetimpl.type = Typ ist: {0}
|
||||
cachedrowsetimpl.opnotysupp = Vorgang noch nicht unterstützt
|
||||
cachedrowsetimpl.featnotsupp = Feature nicht unterstützt
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = WebRowSetImpl-Instanz kann nicht instanziiert werden. Null-Hashtabelle für Constructor angegeben
|
||||
webrowsetimpl.invalidwr = Ungültiger Writer
|
||||
webrowsetimpl.invalidrd = Ungültiger Reader
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative: Ungültiger Cursorvorgang
|
||||
filteredrowsetimpl.absolute = absolute: Ungültiger Cursorvorgang
|
||||
filteredrowsetimpl.notallowed = Kein zulässiger Wert im Filter
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = Keine Instanz von rowset
|
||||
joinrowsetimpl.matchnotset = Übereinstimmungsspalte wurde nicht für Join festgelegt
|
||||
joinrowsetimpl.numnotequal = Elementanzahl in rowset nicht gleich Übereinstimmungsspalte
|
||||
joinrowsetimpl.notdefined = Kein definierter Join-Typ
|
||||
joinrowsetimpl.notsupported = Join-Typ wird nicht unterstützt
|
||||
joinrowsetimpl.initerror = JoinRowSet-Initialisierungsfehler
|
||||
joinrowsetimpl.genericerr = Generischer JoinRowSet-Initialisierungsfehler
|
||||
joinrowsetimpl.emptyrowset = Leeres rowset kann nicht zu diesem JoinRowSet hinzugefügt werden
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = Ungültiger Status
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (verbinden), keine JNDI-Verbindung möglich
|
||||
jdbcrowsetimpl.paramtype = Parametertyp kann nicht abgeleitet werden
|
||||
jdbcrowsetimpl.matchcols = Übereinstimmungsspalten entsprechen nicht den festgelegten Spalten
|
||||
jdbcrowsetimpl.setmatchcols = Übereinstimmungsspalten müssen vor dem Abrufen festgelegt werden
|
||||
jdbcrowsetimpl.matchcols1 = Wert für Übereinstimmungsspalten muss größer als 0 sein
|
||||
jdbcrowsetimpl.matchcols2 = Übereinstimmungsspalten können keine Null- oder leere Zeichenfolge aufweisen
|
||||
jdbcrowsetimpl.unsetmatch = Spalten, deren Wert aufgehoben wird, entsprechen nicht den festgelegten Spalten
|
||||
jdbcrowsetimpl.usecolname = Spaltenname als Argument für unsetMatchColumn verwenden
|
||||
jdbcrowsetimpl.usecolid = Spalten-ID als Argument für unsetMatchColumn verwenden
|
||||
jdbcrowsetimpl.resnotupd = ResultSet kann nicht aktualisiert werden
|
||||
jdbcrowsetimpl.opnotysupp = Vorgang noch nicht unterstützt
|
||||
jdbcrowsetimpl.featnotsupp = Feature nicht unterstützt
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) Verbindung nicht möglich
|
||||
crsreader.paramtype = Parametertyp kann nicht abgeleitet werden
|
||||
crsreader.connecterr = Interner Fehler in RowSetReader: Keine Verbindung oder kein Befehl
|
||||
crsreader.datedetected = Datum festgestellt
|
||||
crsreader.caldetected = Kalender festgestellt
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = Verbindung kann nicht hergestellt werden
|
||||
crswriter.tname = writeData kann Tabellennamen nicht bestimmen
|
||||
crswriter.params1 = Wert für params1: {0}
|
||||
crswriter.params2 = Wert für params2: {0}
|
||||
crswriter.conflictsno = Konflikte beim Synchronisieren
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = Es wurde kein Wert eingefügt
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = Indexwert liegt außerhalb des Bereichs
|
||||
syncrsimpl.noconflict = Kein Konflikt bei dieser Spalte
|
||||
syncrsimpl.syncnotpos = Keine Synchronisierung möglich
|
||||
syncrsimpl.valtores = Aufzulösender Wert kann sich entweder in der Datenbank oder in cachedrowset befinden
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = Ende von RowSet wurde erreicht. Ungültige Cursorposition
|
||||
wrsxmlreader.readxml = readXML: {0}
|
||||
wrsxmlreader.parseerr = ** Parsingfehler: {0}, Zeile: {1} , URI: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException: {0}
|
||||
wrsxmlwriter.sqlex = SQLException: {0}
|
||||
wrsxmlwriter.failedwrite = Schreiben des Wertes nicht erfolgreich
|
||||
wsrxmlwriter.notproper = Kein zulässiger Typ
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Fehler beim Festlegen der Zuordnung: {0}
|
||||
xmlrch.errmetadata = Fehler beim Festlegen der Metadaten: {0}
|
||||
xmlrch.errinsertval = Fehler beim Einfügen der Werte: {0}
|
||||
xmlrch.errconstr = Fehler beim Erstellen der Zeile: {0}
|
||||
xmlrch.errdel = Fehler beim Löschen der Zeile: {0}
|
||||
xmlrch.errinsert = Fehler beim Erstellen der Einfügezeile: {0}
|
||||
xmlrch.errinsdel = Fehler beim Erstellen der Einfüge- oder Löschzeile: {0}
|
||||
xmlrch.errupdate = Fehler beim Erstellen der Updatezeile: {0}
|
||||
xmlrch.errupdrow = Fehler beim Aktualisieren der Zeile: {0}
|
||||
xmlrch.chars = Zeichen:
|
||||
xmlrch.badvalue = Ungültiger Wert. Eigenschaft kann nicht auf null gesetzt werden
|
||||
xmlrch.badvalue1 = Ungültiger Wert. Metadaten können nicht auf null gesetzt werden
|
||||
xmlrch.warning = ** Warnung: {0}, Zeile: {1} , URI: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = Sperren der Klassifizierung wird nicht unterstützt
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = Keine Unterstützung bei RIXMLProvider
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = Se ha proporcionado un objeto ResultSet no válido para el método de relleno
|
||||
cachedrowsetimpl.invalidp = El proveedor de persistencia generado no es válido
|
||||
cachedrowsetimpl.nullhash = La instancia CachedRowSetImpl no se puede crear. Se ha proporcionado una tabla hash nula al constructor
|
||||
cachedrowsetimpl.invalidop = Operación no válida al insertar fila
|
||||
cachedrowsetimpl.accfailed = Fallo de acceptChanges
|
||||
cachedrowsetimpl.invalidcp = Posición de cursor no válida
|
||||
cachedrowsetimpl.illegalop = Operación no permitida en fila no insertada
|
||||
cachedrowsetimpl.clonefail = Fallo en la clonación: {0}
|
||||
cachedrowsetimpl.invalidcol = Índice de columnas no válido
|
||||
cachedrowsetimpl.invalcolnm = Nombre de columna no válido
|
||||
cachedrowsetimpl.boolfail = Fallo de getBoolen en valor ( {0} ) de columna {1}
|
||||
cachedrowsetimpl.bytefail = Fallo de getByte en valor ( {0} ) de columna {1}
|
||||
cachedrowsetimpl.shortfail = Fallo de getShort en valor ( {0} ) de columna {1}
|
||||
cachedrowsetimpl.intfail = Fallo de getInt en valor ( {0} ) de columna {1}
|
||||
cachedrowsetimpl.longfail = Fallo de getLong en valor ( {0} ) de columna {1}
|
||||
cachedrowsetimpl.floatfail = Fallo de getFloat en valor ( {0} ) de columna {1}
|
||||
cachedrowsetimpl.doublefail = Fallo de getDouble en valor ( {0} ) de columna {1}
|
||||
cachedrowsetimpl.dtypemismt = Discordancia entre Tipos de Datos
|
||||
cachedrowsetimpl.datefail = Fallo de getDate en valor ( {0} ) de columna {1}. No es posible convertir
|
||||
cachedrowsetimpl.timefail = Fallo de getTime en valor ( {0} ) de columna {1}. No es posible convertir
|
||||
cachedrowsetimpl.posupdate = Actualizaciones posicionadas no soportadas
|
||||
cachedrowsetimpl.unableins = No se ha podido crear la instancia: {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: Operación de cursor no válida
|
||||
cachedrowsetimpl.first = First: Operación de cursor no válida
|
||||
cachedrowsetimpl.last = last : TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute: Posición de cursor no válida
|
||||
cachedrowsetimpl.relative = relative: Posición de cursor no válida
|
||||
cachedrowsetimpl.asciistream = fallo en lectura de flujo de caracteres ascii
|
||||
cachedrowsetimpl.binstream = fallo de lectura de flujo binario
|
||||
cachedrowsetimpl.failedins = Fallo en inserción de fila
|
||||
cachedrowsetimpl.updateins = llamada a updateRow mientras se insertaba fila
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow : CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: no hay metadatos
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: número de columnas no válido
|
||||
cachedrowsetimpl.tablename = El nombre de la tabla no puede ser nulo
|
||||
cachedrowsetimpl.keycols = Columnas clave no válidas
|
||||
cachedrowsetimpl.opnotsupp = La base de datos no admite esta operación
|
||||
cachedrowsetimpl.matchcols = Las columnas coincidentes no concuerdan con las definidas
|
||||
cachedrowsetimpl.setmatchcols = Defina las columnas coincidentes antes de obtenerlas
|
||||
cachedrowsetimpl.matchcols1 = Las columnas coincidentes deben ser mayores que 0
|
||||
cachedrowsetimpl.matchcols2 = Las columnas coincidentes deben estar vacías o ser una cadena nula
|
||||
cachedrowsetimpl.unsetmatch = Las columnas cuya definición se está anulando no concuerdan con las definidas
|
||||
cachedrowsetimpl.unsetmatch1 = Use el nombre de columna como argumento en unsetMatchColumn
|
||||
cachedrowsetimpl.unsetmatch2 = Use el identificador de columna como argumento en unsetMatchColumn
|
||||
cachedrowsetimpl.numrows = El número de filas es menor que cero o menor que el tamaño recuperado
|
||||
cachedrowsetimpl.startpos = La posición de inicio no puede ser negativa
|
||||
cachedrowsetimpl.nextpage = Rellene los datos antes de realizar la llamada
|
||||
cachedrowsetimpl.pagesize = El tamaño de página no puede ser menor que cero
|
||||
cachedrowsetimpl.pagesize1 = El tamaño de página no puede ser mayor que maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet sólo se reenvía
|
||||
cachedrowsetimpl.type = El tipo es: {0}
|
||||
cachedrowsetimpl.opnotysupp = Operación no soportada todavía
|
||||
cachedrowsetimpl.featnotsupp = Función no soportada
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = La instancia WebRowSetImpl no se puede crear. Se ha proporcionado una tabla hash nula al constructor
|
||||
webrowsetimpl.invalidwr = Escritor no válido
|
||||
webrowsetimpl.invalidrd = Lector no válido
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative: Operación de cursor no válida
|
||||
filteredrowsetimpl.absolute = absolute: Operación de cursor no válida
|
||||
filteredrowsetimpl.notallowed = El filtro no admite este valor
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = No es una instancia de rowset
|
||||
joinrowsetimpl.matchnotset = Las columnas coincidentes no están definidas para la unión
|
||||
joinrowsetimpl.numnotequal = El número de elementos de rowset y el de columnas coincidentes no es el mismo
|
||||
joinrowsetimpl.notdefined = No es un tipo de unión definido
|
||||
joinrowsetimpl.notsupported = Este tipo de unión no está soportado
|
||||
joinrowsetimpl.initerror = Error de inicialización de JoinRowSet
|
||||
joinrowsetimpl.genericerr = Error de inicialización genérico de joinrowset
|
||||
joinrowsetimpl.emptyrowset = No se puede agregar un juego de filas vacío a este JoinRowSet
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = Estado no válido
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (connect): JNDI no se puede conectar
|
||||
jdbcrowsetimpl.paramtype = No se puede deducir el tipo de parámetro
|
||||
jdbcrowsetimpl.matchcols = Las columnas coincidentes no concuerdan con las definidas
|
||||
jdbcrowsetimpl.setmatchcols = Defina las columnas coincidentes antes de obtenerlas
|
||||
jdbcrowsetimpl.matchcols1 = Las columnas coincidentes deben ser mayores que 0
|
||||
jdbcrowsetimpl.matchcols2 = Las columnas coincidentes no pueden estar vacías ni ser una cadena nula
|
||||
jdbcrowsetimpl.unsetmatch = Las columnas cuya definición se está anulando no concuerdan con las definidas
|
||||
jdbcrowsetimpl.usecolname = Use el nombre de columna como argumento en unsetMatchColumn
|
||||
jdbcrowsetimpl.usecolid = Use el identificador de columna como argumento en unsetMatchColumn
|
||||
jdbcrowsetimpl.resnotupd = ResultSet no se puede actualizar
|
||||
jdbcrowsetimpl.opnotysupp = Operación no soportada todavía
|
||||
jdbcrowsetimpl.featnotsupp = Función no soportada
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) No se ha podido conectar
|
||||
crsreader.paramtype = No se ha podido deducir el tipo de parámetro
|
||||
crsreader.connecterr = Error interno en RowSetReader: no hay conexión o comando
|
||||
crsreader.datedetected = Fecha Detectada
|
||||
crsreader.caldetected = Calendario Detectado
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = No se ha podido obtener una conexión
|
||||
crswriter.tname = writeData no puede determinar el nombre de tabla
|
||||
crswriter.params1 = Valor de params1: {0}
|
||||
crswriter.params2 = Valor de params2: {0}
|
||||
crswriter.conflictsno = conflictos en la sincronización
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = No se ha insertado ningún valor
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = El valor de índice está fuera de rango
|
||||
syncrsimpl.noconflict = Esta columna no está en conflicto
|
||||
syncrsimpl.syncnotpos = No se puede sincronizar
|
||||
syncrsimpl.valtores = El valor que se debe resolver puede estar en la base de datos o en cachedrowset
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = Se ha llegado al final de RowSet. Posición de cursor no válida
|
||||
wrsxmlreader.readxml = readXML : {0}
|
||||
wrsxmlreader.parseerr = ** Error de análisis: {0} , línea: {1} , uri: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException : {0}
|
||||
wrsxmlwriter.sqlex = SQLException : {0}
|
||||
wrsxmlwriter.failedwrite = Error al escribir el valor
|
||||
wsrxmlwriter.notproper = Tipo incorrecto
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Error al definir la asignación: {0}
|
||||
xmlrch.errmetadata = Error al definir metadatos: {0}
|
||||
xmlrch.errinsertval = Error al insertar los valores: {0}
|
||||
xmlrch.errconstr = Error al construir la fila: {0}
|
||||
xmlrch.errdel = Error al suprimir la fila: {0}
|
||||
xmlrch.errinsert = Error al construir la fila de inserción: {0}
|
||||
xmlrch.errinsdel = Error al construir la fila de inserción o supresión: {0}
|
||||
xmlrch.errupdate = Error al construir la fila de actualización: {0}
|
||||
xmlrch.errupdrow = Error al actualizar la fila: {0}
|
||||
xmlrch.chars = caracteres:
|
||||
xmlrch.badvalue = Valor incorrecto; la propiedad no puede ser nula
|
||||
xmlrch.badvalue1 = Valor incorrecto; los metadatos no pueden ser nulos
|
||||
xmlrch.warning = ** Advertencia: {0} , línea: {1} , uri: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = No se permite bloquear la clasificación
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = No soportado con RIXMLProvider
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = L'objet ResultSet fourni en entrée de la méthode n'est pas valide
|
||||
cachedrowsetimpl.invalidp = Le fournisseur de persistance généré n'est pas valide
|
||||
cachedrowsetimpl.nullhash = Impossible de créer une instance de CachedRowSetImpl. Table de hachage NULL fournie au constructeur
|
||||
cachedrowsetimpl.invalidop = Opération non valide lors de l'insertion de ligne
|
||||
cachedrowsetimpl.accfailed = Echec de acceptChanges
|
||||
cachedrowsetimpl.invalidcp = Position du curseur non valide
|
||||
cachedrowsetimpl.illegalop = Opération non admise sur une ligne non insérée
|
||||
cachedrowsetimpl.clonefail = Echec du clonage : {0}
|
||||
cachedrowsetimpl.invalidcol = Index de colonne non valide
|
||||
cachedrowsetimpl.invalcolnm = Nom de colonne non valide
|
||||
cachedrowsetimpl.boolfail = Echec de getBoolen pour la valeur ({0}) de la colonne {1}
|
||||
cachedrowsetimpl.bytefail = Echec de getByte pour la valeur ({0}) de la colonne {1}
|
||||
cachedrowsetimpl.shortfail = Echec de getShort pour la valeur ({0}) de la colonne {1}
|
||||
cachedrowsetimpl.intfail = Echec de getInt pour la valeur ({0}) de la colonne {1}
|
||||
cachedrowsetimpl.longfail = Echec de getLong pour la valeur ({0}) de la colonne {1}
|
||||
cachedrowsetimpl.floatfail = Echec de getFloat pour la valeur ({0}) de la colonne {1}
|
||||
cachedrowsetimpl.doublefail = Echec de getDouble pour la valeur ({0}) de la colonne {1}
|
||||
cachedrowsetimpl.dtypemismt = Le type de données ne correspond pas
|
||||
cachedrowsetimpl.datefail = Echec de getDate pour la valeur ({0}) de la colonne {1} - Aucune conversion possible
|
||||
cachedrowsetimpl.timefail = Echec de getTime pour la valeur ({0}) de la colonne {1} - Aucune conversion possible
|
||||
cachedrowsetimpl.posupdate = Mises à jour choisies non prises en charge
|
||||
cachedrowsetimpl.unableins = Instanciation impossible : {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst : opération de curseur non valide
|
||||
cachedrowsetimpl.first = First : opération de curseur non valide
|
||||
cachedrowsetimpl.last = last : TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute : position de curseur non valide
|
||||
cachedrowsetimpl.relative = relative : position de curseur non valide
|
||||
cachedrowsetimpl.asciistream = échec de la lecture pour le flux ASCII
|
||||
cachedrowsetimpl.binstream = échec de la lecture pour le flux binaire
|
||||
cachedrowsetimpl.failedins = Echec de l'insertion de ligne
|
||||
cachedrowsetimpl.updateins = appel de updateRow lors de l'insertion de ligne
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow : CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow : aucune métadonnée
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow : nombre de colonnes non valide
|
||||
cachedrowsetimpl.tablename = Le nom de la table ne peut pas être NULL
|
||||
cachedrowsetimpl.keycols = Colonnes de clé non valides
|
||||
cachedrowsetimpl.opnotsupp = Opération non prise en charge par la base de données
|
||||
cachedrowsetimpl.matchcols = Les colonnes correspondantes ne sont pas les mêmes que les colonnes définies
|
||||
cachedrowsetimpl.setmatchcols = Définir les colonnes correspondantes avant de les prendre
|
||||
cachedrowsetimpl.matchcols1 = Les colonnes correspondantes doivent être supérieures à zéro
|
||||
cachedrowsetimpl.matchcols2 = Les colonnes correspondantes doivent êtres vides ou ne contenir que des chaînes NULL
|
||||
cachedrowsetimpl.unsetmatch = Les colonnes définies et non définies sont différentes
|
||||
cachedrowsetimpl.unsetmatch1 = Utiliser le nom de colonne comme argument pour unsetMatchColumn
|
||||
cachedrowsetimpl.unsetmatch2 = Utiliser l'ID de colonne comme argument pour unsetMatchColumn
|
||||
cachedrowsetimpl.numrows = Le nombre de lignes est inférieur à zéro ou à la taille d'extraction
|
||||
cachedrowsetimpl.startpos = La position de départ ne peut pas être négative
|
||||
cachedrowsetimpl.nextpage = Entrer les données avant l'appel
|
||||
cachedrowsetimpl.pagesize = La taille de la page ne peut pas être négative
|
||||
cachedrowsetimpl.pagesize1 = La taille de la page ne peut pas être supérieure à maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet va en avant seulement
|
||||
cachedrowsetimpl.type = Le type est : {0}
|
||||
cachedrowsetimpl.opnotysupp = Opération non encore prise en charge
|
||||
cachedrowsetimpl.featnotsupp = Fonctionnalité non prise en charge
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = Impossible de créer une instance de WebRowSetImpl. Table de hachage NULL fournie au constructeur
|
||||
webrowsetimpl.invalidwr = Processus d'écriture non valide
|
||||
webrowsetimpl.invalidrd = Processus de lecture non valide
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative : opération de curseur non valide
|
||||
filteredrowsetimpl.absolute = absolute : opération de curseur non valide
|
||||
filteredrowsetimpl.notallowed = Cette valeur n'est pas autorisée via le filtre
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = N'est pas une instance de RowSet
|
||||
joinrowsetimpl.matchnotset = Les colonnes correspondantes ne sont pas définies pour la jointure
|
||||
joinrowsetimpl.numnotequal = Le nombre d'éléments dans RowSet est différent du nombre de colonnes correspondantes
|
||||
joinrowsetimpl.notdefined = Ce n'est pas un type de jointure défini
|
||||
joinrowsetimpl.notsupported = Ce type de jointure n'est pas pris en charge
|
||||
joinrowsetimpl.initerror = Erreur d'initialisation de JoinRowSet
|
||||
joinrowsetimpl.genericerr = Erreur initiale générique de JoinRowSet
|
||||
joinrowsetimpl.emptyrowset = Impossible d'ajouter un objet RowSet vide à ce JoinRowSet
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = Etat non valide
|
||||
jdbcrowsetimpl.connect = Impossible de connecter JNDI JdbcRowSet (connexion)
|
||||
jdbcrowsetimpl.paramtype = Impossible de déduire le type de paramètre
|
||||
jdbcrowsetimpl.matchcols = Les colonnes correspondantes ne sont pas les mêmes que les colonnes définies
|
||||
jdbcrowsetimpl.setmatchcols = Définir les colonnes correspondantes avant de les prendre
|
||||
jdbcrowsetimpl.matchcols1 = Les colonnes correspondantes doivent être supérieures à zéro
|
||||
jdbcrowsetimpl.matchcols2 = Les colonnes correspondantes ne doivent pas êtres NULL ni contenir des chaînes vides
|
||||
jdbcrowsetimpl.unsetmatch = Les colonnes non définies ne sont pas les mêmes que les colonnes définies
|
||||
jdbcrowsetimpl.usecolname = Utiliser le nom de colonne comme argument pour unsetMatchColumn
|
||||
jdbcrowsetimpl.usecolid = Utiliser l'ID de colonne comme argument pour unsetMatchColumn
|
||||
jdbcrowsetimpl.resnotupd = La mise à jour de ResultSet est interdite
|
||||
jdbcrowsetimpl.opnotysupp = Opération non encore prise en charge
|
||||
jdbcrowsetimpl.featnotsupp = Fonctionnalité non prise en charge
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = Impossible de connecter (JNDI)
|
||||
crsreader.paramtype = Impossible de déduire le type de paramètre
|
||||
crsreader.connecterr = Erreur interne dans RowSetReader : pas de connexion ni de commande
|
||||
crsreader.datedetected = Une date a été détectée
|
||||
crsreader.caldetected = Un calendrier a été détecté
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = Impossible d'obtenir la connexion
|
||||
crswriter.tname = writeData ne peut pas déterminer le nom de la table
|
||||
crswriter.params1 = Valeur de params1 : {0}
|
||||
crswriter.params2 = Valeur de params2 : {0}
|
||||
crswriter.conflictsno = conflits lors de la synchronisation
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = Aucune valeur n'a été insérée
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = Valeur d'index hors plage
|
||||
syncrsimpl.noconflict = Cette colonne n'est pas en conflit
|
||||
syncrsimpl.syncnotpos = La synchronisation est impossible
|
||||
syncrsimpl.valtores = La valeur à résoudre peut être soit dans la base de données, soit dans CachedrowSet
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = Fin de RowSet atteinte. Position de curseur non valide
|
||||
wrsxmlreader.readxml = readXML : {0}
|
||||
wrsxmlreader.parseerr = ** Erreur d''analyse : {0} , ligne : {1} , URI : {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = Exception d''E/S : {0}
|
||||
wrsxmlwriter.sqlex = Exception SQL : {0}
|
||||
wrsxmlwriter.failedwrite = Echec d'écriture de la valeur
|
||||
wsrxmlwriter.notproper = N'est pas un type correct
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Erreur lors de la définition du mappage : {0}
|
||||
xmlrch.errmetadata = Erreur lors de la définition des métadonnées : {0}
|
||||
xmlrch.errinsertval = Erreur lors de l''insertion des valeurs : {0}
|
||||
xmlrch.errconstr = Erreur lors de la construction de la ligne : {0}
|
||||
xmlrch.errdel = Erreur lors de la suppression de la ligne : {0}
|
||||
xmlrch.errinsert = Erreur lors de la construction de la ligne à insérer : {0}
|
||||
xmlrch.errinsdel = Erreur lors de la construction de la ligne insdel : {0}
|
||||
xmlrch.errupdate = Erreur lors de la construction de la ligne à mettre à jour : {0}
|
||||
xmlrch.errupdrow = Erreur lors de la mise à jour de la ligne : {0}
|
||||
xmlrch.chars = caractères :
|
||||
xmlrch.badvalue = Valeur incorrecte ; cette propriété ne peut pas être NULL
|
||||
xmlrch.badvalue1 = Valeur incorrecte ; ces métadonnées ne peuvent pas être NULL
|
||||
xmlrch.warning = ** Avertissement : {0} , ligne : {1} , URI : {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = Le verrouillage de la classification n'est pas pris en charge
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = Non pris en charge avec RIXMLProvider
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = Oggetto ResultSet non valido fornito per l'inserimento dati nel metodo
|
||||
cachedrowsetimpl.invalidp = Generato provider di persistenza non valido
|
||||
cachedrowsetimpl.nullhash = Impossibile creare istanza CachedRowSetImpl. Tabella hash nulla fornita al costruttore
|
||||
cachedrowsetimpl.invalidop = Operazione non valida nella riga di inserimento
|
||||
cachedrowsetimpl.accfailed = acceptChanges non riuscito
|
||||
cachedrowsetimpl.invalidcp = Posizione cursore non valida
|
||||
cachedrowsetimpl.illegalop = Operazione non valida nella riga non inserita
|
||||
cachedrowsetimpl.clonefail = Copia non riuscita: {0}
|
||||
cachedrowsetimpl.invalidcol = Indice di colonna non valido
|
||||
cachedrowsetimpl.invalcolnm = Nome di colonna non valido
|
||||
cachedrowsetimpl.boolfail = getBoolen non riuscito per il valore ( {0} ) nella colonna {1}
|
||||
cachedrowsetimpl.bytefail = getByte non riuscito per il valore ( {0} ) nella colonna {1}
|
||||
cachedrowsetimpl.shortfail = getShort non riuscito per il valore ( {0} ) nella colonna {1}
|
||||
cachedrowsetimpl.intfail = getInt non riuscito per il valore ( {0} ) nella colonna {1}
|
||||
cachedrowsetimpl.longfail = getLong non riuscito per il valore ( {0} ) nella colonna {1}
|
||||
cachedrowsetimpl.floatfail = getFloat non riuscito per il valore ( {0} ) nella colonna {1}
|
||||
cachedrowsetimpl.doublefail = getDouble non riuscito per il valore ( {0} ) nella colonna {1}
|
||||
cachedrowsetimpl.dtypemismt = Mancata corrispondenza tipo di dati
|
||||
cachedrowsetimpl.datefail = getDate non riuscito per il valore ( {0} ) nella colonna {1}. Nessuna conversione disponibile.
|
||||
cachedrowsetimpl.timefail = getTime non riuscito per il valore ( {0} ) nella colonna {1}. Nessuna conversione disponibile.
|
||||
cachedrowsetimpl.posupdate = Aggiornamenti posizionati non supportati
|
||||
cachedrowsetimpl.unableins = Impossibile creare istanza: {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: operazione cursore non valida
|
||||
cachedrowsetimpl.first = First: operazione cursore non valida
|
||||
cachedrowsetimpl.last = last: TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute: posizione cursore non valida
|
||||
cachedrowsetimpl.relative = relative: posizione cursore non valida
|
||||
cachedrowsetimpl.asciistream = lettura non riuscita per il flusso ascii
|
||||
cachedrowsetimpl.binstream = lettura non riuscita per il flusso binario
|
||||
cachedrowsetimpl.failedins = operazione non riuscita nella riga di inserimento
|
||||
cachedrowsetimpl.updateins = updateRow chiamato nella riga di inserimento
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow: CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: nessun metadato
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: numero di colonne non valido
|
||||
cachedrowsetimpl.tablename = Il nome di tabella non può essere nullo
|
||||
cachedrowsetimpl.keycols = Colonne chiave non valide
|
||||
cachedrowsetimpl.opnotsupp = Operazione non supportata dal database
|
||||
cachedrowsetimpl.matchcols = Le colonne di corrispondenza non coincidono con le colonne impostate
|
||||
cachedrowsetimpl.setmatchcols = Impostare le colonne di corrispondenza prima di recuperarle
|
||||
cachedrowsetimpl.matchcols1 = Le colonne di corrispondenza devono essere superiori a 0
|
||||
cachedrowsetimpl.matchcols2 = Le colonne di corrispondenza devono essere una stringa vuota o nulla
|
||||
cachedrowsetimpl.unsetmatch = Le colonne rimosse non coincidono con le colonne impostate
|
||||
cachedrowsetimpl.unsetmatch1 = Utilizzare il nome di colonna come argomento per unsetMatchColumn
|
||||
cachedrowsetimpl.unsetmatch2 = Utilizzare l'ID di colonna come argomento per unsetMatchColumn
|
||||
cachedrowsetimpl.numrows = Il numero di righe è inferiore a zero o alla dimensione di recupero
|
||||
cachedrowsetimpl.startpos = La posizione iniziale non può essere negativa
|
||||
cachedrowsetimpl.nextpage = Inserire i dati prima di chiamare
|
||||
cachedrowsetimpl.pagesize = La dimensione della pagina non può essere inferiore a zero
|
||||
cachedrowsetimpl.pagesize1 = La dimensione della pagina non può essere superiore a maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet è a solo inoltro
|
||||
cachedrowsetimpl.type = Il tipo è: {0}
|
||||
cachedrowsetimpl.opnotysupp = Operazione attualmente non supportata
|
||||
cachedrowsetimpl.featnotsupp = Funzione non supportata
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = Impossibile creare istanza WebRowSetImpl. Tabella hash nulla fornita al costruttore
|
||||
webrowsetimpl.invalidwr = Processo di scrittura non valido
|
||||
webrowsetimpl.invalidrd = Processo di lettura non valido
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative: operazione cursore non valida
|
||||
filteredrowsetimpl.absolute = absolute: operazione cursore non valida
|
||||
filteredrowsetimpl.notallowed = Questo valore non è consentito nel filtro
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = Non è un'istanza di rowset
|
||||
joinrowsetimpl.matchnotset = Colonna di corrispondenza non impostata per l'unione
|
||||
joinrowsetimpl.numnotequal = Numero di elementi in rowset diverso dalla colonna di corrispondenza
|
||||
joinrowsetimpl.notdefined = Non è un tipo di unione definito
|
||||
joinrowsetimpl.notsupported = Questo tipo di unione non è supportato
|
||||
joinrowsetimpl.initerror = Errore di inizializzazione di JoinRowSet
|
||||
joinrowsetimpl.genericerr = Errore iniziale di joinrowset generico
|
||||
joinrowsetimpl.emptyrowset = Impossibile aggiungere un set di righe vuoto al JoinRowSet corrente
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = Stato non valido
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (connessione): impossibile stabilire una connessione con JNDI
|
||||
jdbcrowsetimpl.paramtype = Impossibile dedurre il tipo di parametro
|
||||
jdbcrowsetimpl.matchcols = Le colonne di corrispondenza non coincidono con le colonne impostate
|
||||
jdbcrowsetimpl.setmatchcols = Impostare le colonne di corrispondenza prima di recuperarle
|
||||
jdbcrowsetimpl.matchcols1 = Le colonne di corrispondenza devono essere superiori a 0
|
||||
jdbcrowsetimpl.matchcols2 = Le colonne di corrispondenza non possono essere una stringa vuota o nulla
|
||||
jdbcrowsetimpl.unsetmatch = Le colonne rimosse non coincidono con le colonne impostate
|
||||
jdbcrowsetimpl.usecolname = Utilizzare il nome di colonna come argomento per unsetMatchColumn
|
||||
jdbcrowsetimpl.usecolid = Utilizzare l'ID di colonna come argomento per unsetMatchColumn
|
||||
jdbcrowsetimpl.resnotupd = ResultSet non è aggiornabile
|
||||
jdbcrowsetimpl.opnotysupp = Operazione attualmente non supportata
|
||||
jdbcrowsetimpl.featnotsupp = Funzione non supportata
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) Impossibile stabilire una connessione
|
||||
crsreader.paramtype = Impossibile dedurre il tipo di parametro
|
||||
crsreader.connecterr = Errore interno in RowSetReader: nessuna connessione o comando
|
||||
crsreader.datedetected = È stata rilevata una data
|
||||
crsreader.caldetected = È stato rilevato un calendario
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = Impossibile stabilire una connessione
|
||||
crswriter.tname = writeData non riesce a determinare il nome di tabella
|
||||
crswriter.params1 = Valore dei parametri 1: {0}
|
||||
crswriter.params2 = Valore dei parametri 2: {0}
|
||||
crswriter.conflictsno = Conflitti durante la sincronizzazione
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = Non è stato inserito alcun valore
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = Valore indice non compreso nell'intervallo
|
||||
syncrsimpl.noconflict = Questa colonna non è in conflitto
|
||||
syncrsimpl.syncnotpos = Impossibile eseguire la sincronizzazione
|
||||
syncrsimpl.valtores = Il valore da risolvere può essere nel database o in cachedrowset
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = Raggiunta la fine di RowSet. Posizione cursore non valida
|
||||
wrsxmlreader.readxml = readXML: {0}
|
||||
wrsxmlreader.parseerr = **Errore di analisi: {0}, riga: {1}, URI: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException: {0}
|
||||
wrsxmlwriter.sqlex = SQLException: {0}
|
||||
wrsxmlwriter.failedwrite = Impossibile scrivere il valore
|
||||
wsrxmlwriter.notproper = Non un tipo corretto
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Errore durante l''impostazione della mappa: {0}
|
||||
xmlrch.errmetadata = Errore durante l''impostazione dei metadati: {0}
|
||||
xmlrch.errinsertval = Errore durante l''inserimento dei valori: {0}
|
||||
xmlrch.errconstr = Errore durante la costruzione della riga: {0}
|
||||
xmlrch.errdel = Errore durante l''eliminazione della riga: {0}
|
||||
xmlrch.errinsert = Errore durante la costruzione della riga di inserimento: {0}
|
||||
xmlrch.errinsdel = Errore durante la costruzione della riga insdel: {0}
|
||||
xmlrch.errupdate = Errore durante la costruzione della riga di aggiornamento: {0}
|
||||
xmlrch.errupdrow = Errore durante l''aggiornamento della riga: {0}
|
||||
xmlrch.chars = caratteri:
|
||||
xmlrch.badvalue = valore non valido; proprietà non annullabile
|
||||
xmlrch.badvalue1 = valore non valido; metadati non annullabili
|
||||
xmlrch.warning = **Avvertenza: {0}, riga: {1}, URI: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = La classificazione di blocco non è supportata
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = Non supportato con RIXMLProvider
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = populateメソッドに無効なResultSetオブジェクトが使用されました
|
||||
cachedrowsetimpl.invalidp = 無効な永続性プロバイダが生成されました
|
||||
cachedrowsetimpl.nullhash = CachedRowSetImplインスタンスをインスタンス化できません。コンストラクタにnullのHashtableが使用されました
|
||||
cachedrowsetimpl.invalidop = 挿入行での無効な操作
|
||||
cachedrowsetimpl.accfailed = acceptChangesの失敗
|
||||
cachedrowsetimpl.invalidcp = 無効なカーソル位置
|
||||
cachedrowsetimpl.illegalop = 挿入されなかった行の不正な操作
|
||||
cachedrowsetimpl.clonefail = クローンの失敗: {0}
|
||||
cachedrowsetimpl.invalidcol = 無効な列索引
|
||||
cachedrowsetimpl.invalcolnm = 無効な列名
|
||||
cachedrowsetimpl.boolfail = 列{1}の値({0})でgetBooleanが失敗しました
|
||||
cachedrowsetimpl.bytefail = 列{1}の値({0})でgetByteが失敗しました
|
||||
cachedrowsetimpl.shortfail = 列{1}の値({0})でgetShortが失敗しました
|
||||
cachedrowsetimpl.intfail = 列{1}の値({0})でgetIntが失敗しました
|
||||
cachedrowsetimpl.longfail = 列{1}の値({0})でgetLongが失敗しました
|
||||
cachedrowsetimpl.floatfail = 列{1}の値({0})でgetFloatが失敗しました
|
||||
cachedrowsetimpl.doublefail = 列{1}の値({0})でgetDoubleが失敗しました
|
||||
cachedrowsetimpl.dtypemismt = データ型の不一致
|
||||
cachedrowsetimpl.datefail = 列{1}の値({0})でgetDateが失敗。変換できません
|
||||
cachedrowsetimpl.timefail = 列{1}の値({0})でgetTimeが失敗。変換できません
|
||||
cachedrowsetimpl.posupdate = 位置決めされた更新がサポートされません
|
||||
cachedrowsetimpl.unableins = インスタンス化できない: {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: 無効なカーソル操作
|
||||
cachedrowsetimpl.first = First: 無効なカーソル操作
|
||||
cachedrowsetimpl.last = last: TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute: 無効なカーソル位置
|
||||
cachedrowsetimpl.relative = relative: 無効なカーソル位置
|
||||
cachedrowsetimpl.asciistream = asciiストリームの読込みが失敗しました
|
||||
cachedrowsetimpl.binstream = バイナリ・ストリームの読込みが失敗しました
|
||||
cachedrowsetimpl.failedins = 行の挿入に失敗
|
||||
cachedrowsetimpl.updateins = 挿入行においてupdateRowが呼び出されました
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow: CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: メタデータなし
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: 無効な列数
|
||||
cachedrowsetimpl.tablename = 表名にnullは使用できません
|
||||
cachedrowsetimpl.keycols = 無効なキー列
|
||||
cachedrowsetimpl.opnotsupp = データベースでサポートされない操作
|
||||
cachedrowsetimpl.matchcols = 一致列が列のセットと同じではありません
|
||||
cachedrowsetimpl.setmatchcols = 一致列を取得する前に設定してください
|
||||
cachedrowsetimpl.matchcols1 = 一致列は0より大きい必要があります
|
||||
cachedrowsetimpl.matchcols2 = 一致列は空かnull文字列である必要があります
|
||||
cachedrowsetimpl.unsetmatch = 設定解除されている列はセットと同じではありません
|
||||
cachedrowsetimpl.unsetmatch1 = unsetMatchColumnへの引数として列名を使用してください
|
||||
cachedrowsetimpl.unsetmatch2 = unsetMatchColumnへの引数として列IDを使用してください
|
||||
cachedrowsetimpl.numrows = 行数がゼロまたはフェッチ・サイズより小さいです
|
||||
cachedrowsetimpl.startpos = 開始位置を負にすることはできません
|
||||
cachedrowsetimpl.nextpage = 呼出し前にデータを移入します
|
||||
cachedrowsetimpl.pagesize = ページ・サイズをゼロより小さくすることはできません
|
||||
cachedrowsetimpl.pagesize1 = ページ・サイズをmaxRowsより大きくすることができません
|
||||
cachedrowsetimpl.fwdonly = ResultSetは順方向のみです
|
||||
cachedrowsetimpl.type = タイプ: {0}
|
||||
cachedrowsetimpl.opnotysupp = まだサポートされていない操作
|
||||
cachedrowsetimpl.featnotsupp = サポートされていない機能
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = WebRowSetImplインスタンスをインスタンス化できません。コンストラクタにnullのHashtableが使用されました
|
||||
webrowsetimpl.invalidwr = 無効なライター
|
||||
webrowsetimpl.invalidrd = 無効なリーダー
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative: 無効なカーソル操作
|
||||
filteredrowsetimpl.absolute = absolute: 無効なカーソル操作
|
||||
filteredrowsetimpl.notallowed = この値はフィルタで許容されません
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = 行セットのインスタンスではありません
|
||||
joinrowsetimpl.matchnotset = 一致列が結合用に設定されていません
|
||||
joinrowsetimpl.numnotequal = 行セットの要素数が一致列と等しくありません
|
||||
joinrowsetimpl.notdefined = 定義された結合のタイプではありません
|
||||
joinrowsetimpl.notsupported = このタイプの結合はサポートされていません
|
||||
joinrowsetimpl.initerror = JoinRowSet初期化エラー
|
||||
joinrowsetimpl.genericerr = 一般的なjoinrowset初期エラー
|
||||
joinrowsetimpl.emptyrowset = このJoinRowSetに空の行セットを追加することはできません
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = 無効な状態
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (connect): JNDIが接続できません
|
||||
jdbcrowsetimpl.paramtype = パラメータ・タイプを推定できません
|
||||
jdbcrowsetimpl.matchcols = 一致列が列のセットと同じではありません
|
||||
jdbcrowsetimpl.setmatchcols = 一致列を取得する前に設定してください
|
||||
jdbcrowsetimpl.matchcols1 = 一致列は0より大きい必要があります
|
||||
jdbcrowsetimpl.matchcols2 = 一致列を空またはnull文字列にすることはできません
|
||||
jdbcrowsetimpl.unsetmatch = 設定解除されている列はセットと同じではありません
|
||||
jdbcrowsetimpl.usecolname = unsetMatchColumnへの引数として列名を使用してください
|
||||
jdbcrowsetimpl.usecolid = unsetMatchColumnへの引数として列IDを使用してください
|
||||
jdbcrowsetimpl.resnotupd = ResultSetは更新できません
|
||||
jdbcrowsetimpl.opnotysupp = まだサポートされていない操作
|
||||
jdbcrowsetimpl.featnotsupp = サポートされていない機能
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI)接続できません
|
||||
crsreader.paramtype = パラメータ・タイプを推定できません
|
||||
crsreader.connecterr = RowSetReaderの内部エラー: 接続またはコマンドなし
|
||||
crsreader.datedetected = 日付を検出しました
|
||||
crsreader.caldetected = カレンダを検出しました
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = 接続を取得できません
|
||||
crswriter.tname = writeDataが表名を判別できません
|
||||
crswriter.params1 = params1の値: {0}
|
||||
crswriter.params2 = params2の値: {0}
|
||||
crswriter.conflictsno = 同期中に競合が発生します
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = 値は挿入されていません
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = 範囲外の索引値
|
||||
syncrsimpl.noconflict = この列は競合していません
|
||||
syncrsimpl.syncnotpos = 同期できません
|
||||
syncrsimpl.valtores = 解決される値はデータベースまたはcachedrowsetにある可能性があります
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = RowSetの最後に到達しました。無効なカーソル位置
|
||||
wrsxmlreader.readxml = readXML: {0}
|
||||
wrsxmlreader.parseerr = **解析エラー: {0}、行: {1}、URI: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException: {0}
|
||||
wrsxmlwriter.sqlex = SQLException: {0}
|
||||
wrsxmlwriter.failedwrite = 値の書込みに失敗しました
|
||||
wsrxmlwriter.notproper = 適切なタイプではありません
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Map設定エラー: {0}
|
||||
xmlrch.errmetadata = メタデータ設定エラー: {0}
|
||||
xmlrch.errinsertval = 値の挿入エラー: {0}
|
||||
xmlrch.errconstr = 行の生成エラー: {0}
|
||||
xmlrch.errdel = 行の削除エラー: {0}
|
||||
xmlrch.errinsert = 挿入行の生成エラー: {0}
|
||||
xmlrch.errinsdel = insdel行の生成エラー: {0}
|
||||
xmlrch.errupdate = 更新行の生成エラー: {0}
|
||||
xmlrch.errupdrow = 行の更新エラー: {0}
|
||||
xmlrch.chars = 文字:
|
||||
xmlrch.badvalue = 不正な値: nullにできないプロパティ
|
||||
xmlrch.badvalue1 = 不正な値: nullにできないメタデータ
|
||||
xmlrch.warning = **警告: {0}、行: {1}、URI: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = ロックの分類はサポートされていません
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = RIXMLProviderでは未サポート
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = 부적합한 ResultSet 객체가 제공되어 메소드를 채울 수 없습니다.
|
||||
cachedrowsetimpl.invalidp = 부적합한 지속성 제공자가 생성되었습니다.
|
||||
cachedrowsetimpl.nullhash = CachedRowSetImpl 인스턴스를 인스턴스화할 수 없습니다. 생성자에 널 Hashtable이 제공되었습니다.
|
||||
cachedrowsetimpl.invalidop = 행을 삽입하는 중 부적합한 작업이 수행되었습니다.
|
||||
cachedrowsetimpl.accfailed = acceptChanges를 실패했습니다.
|
||||
cachedrowsetimpl.invalidcp = 커서 위치가 부적합합니다.
|
||||
cachedrowsetimpl.illegalop = 삽입된 행이 아닌 행에서 잘못된 작업이 수행되었습니다.
|
||||
cachedrowsetimpl.clonefail = 복제 실패: {0}
|
||||
cachedrowsetimpl.invalidcol = 열 인덱스가 부적합합니다.
|
||||
cachedrowsetimpl.invalcolnm = 열 이름이 부적합합니다.
|
||||
cachedrowsetimpl.boolfail = {1} 열의 값({0})에서 getBoolen을 실패했습니다.
|
||||
cachedrowsetimpl.bytefail = {1} 열의 값({0})에서 getByte를 실패했습니다.
|
||||
cachedrowsetimpl.shortfail = {1} 열의 값({0})에서 getShort를 실패했습니다.
|
||||
cachedrowsetimpl.intfail = {1} 열의 값({0})에서 getInt를 실패했습니다.
|
||||
cachedrowsetimpl.longfail = {1} 열의 값({0})에서 getLong을 실패했습니다.
|
||||
cachedrowsetimpl.floatfail = {1} 열의 값({0})에서 getFloat를 실패했습니다.
|
||||
cachedrowsetimpl.doublefail = {1} 열의 값({0})에서 getDouble을 실패했습니다.
|
||||
cachedrowsetimpl.dtypemismt = 데이터 유형이 일치하지 않습니다.
|
||||
cachedrowsetimpl.datefail = {1} 열의 값({0})에서 getDate를 실패했습니다. 변환할 수 없습니다.
|
||||
cachedrowsetimpl.timefail = {1} 열의 값({0})에서 getTime을 실패했습니다. 변환할 수 없습니다.
|
||||
cachedrowsetimpl.posupdate = 위치가 지정된 업데이트가 지원되지 않습니다.
|
||||
cachedrowsetimpl.unableins = 인스턴스화할 수 없음: {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: 커서 작업이 부적합합니다.
|
||||
cachedrowsetimpl.first = 처음: 커서 작업이 부적합합니다.
|
||||
cachedrowsetimpl.last = 마지막: TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = 절대: 커서 위치가 부적합합니다.
|
||||
cachedrowsetimpl.relative = 상대: 커서 위치가 부적합합니다.
|
||||
cachedrowsetimpl.asciistream = ASCII 스트림에 대한 읽기를 실패했습니다.
|
||||
cachedrowsetimpl.binstream = 바이너리 스트림에서 읽기를 실패했습니다.
|
||||
cachedrowsetimpl.failedins = 행 삽입을 실패했습니다.
|
||||
cachedrowsetimpl.updateins = 행을 삽입하는 중 updateRow가 호출되었습니다.
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow: CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: 메타데이터가 없습니다.
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: 열 수가 부적합합니다.
|
||||
cachedrowsetimpl.tablename = 테이블 이름은 널일 수 없습니다.
|
||||
cachedrowsetimpl.keycols = 키 열이 부적합합니다.
|
||||
cachedrowsetimpl.opnotsupp = 데이터베이스에서 지원하지 않는 작업입니다.
|
||||
cachedrowsetimpl.matchcols = 일치 열이 설정된 열과 동일하지 않습니다.
|
||||
cachedrowsetimpl.setmatchcols = 일치 열을 설정한 후 가져오십시오.
|
||||
cachedrowsetimpl.matchcols1 = 일치 열은 0개 이상이어야 합니다.
|
||||
cachedrowsetimpl.matchcols2 = 일치 열은 비어 있거나 널 문자열이어야 합니다.
|
||||
cachedrowsetimpl.unsetmatch = 설정을 해제하려는 열이 설정된 열과 다릅니다.
|
||||
cachedrowsetimpl.unsetmatch1 = 열 이름을 unsetMatchColumn의 인수로 사용하십시오.
|
||||
cachedrowsetimpl.unsetmatch2 = 열 ID를 unsetMatchColumn의 인수로 사용하십시오.
|
||||
cachedrowsetimpl.numrows = 행 수가 0보다 작거나 인출 크기보다 작습니다.
|
||||
cachedrowsetimpl.startpos = 시작 위치는 음수일 수 없습니다.
|
||||
cachedrowsetimpl.nextpage = 호출하기 전에 데이터를 채우십시오.
|
||||
cachedrowsetimpl.pagesize = 페이지 크기는 0보다 작을 수 없습니다.
|
||||
cachedrowsetimpl.pagesize1 = 페이지 크기는 maxRows보다 클 수 없습니다.
|
||||
cachedrowsetimpl.fwdonly = ResultSet는 전달 전용입니다.
|
||||
cachedrowsetimpl.type = 유형: {0}
|
||||
cachedrowsetimpl.opnotysupp = 작업이 아직 지원되지 않습니다.
|
||||
cachedrowsetimpl.featnotsupp = 기능이 지원되지 않습니다.
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = WebRowSetImpl 인스턴스를 인스턴스화할 수 없습니다. 생성자에 널 Hashtable이 제공되었습니다.
|
||||
webrowsetimpl.invalidwr = 기록 장치가 부적합합니다.
|
||||
webrowsetimpl.invalidrd = 읽기 프로그램이 부적합합니다.
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = 상대: 커서 작업이 부적합합니다.
|
||||
filteredrowsetimpl.absolute = 절대: 커서 작업이 부적합합니다.
|
||||
filteredrowsetimpl.notallowed = 이 값은 필터를 통과할 수 없습니다.
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = Rowset의 인스턴스가 아닙니다.
|
||||
joinrowsetimpl.matchnotset = 조인할 일치 열이 설정되지 않았습니다.
|
||||
joinrowsetimpl.numnotequal = Rowset의 요소 수가 일치 열과 같지 않습니다.
|
||||
joinrowsetimpl.notdefined = 정의된 조인 유형이 아닙니다.
|
||||
joinrowsetimpl.notsupported = 이 조인 유형은 지원되지 않습니다.
|
||||
joinrowsetimpl.initerror = JoinRowSet 초기화 오류
|
||||
joinrowsetimpl.genericerr = 일반 joinrowset 초기 오류
|
||||
joinrowsetimpl.emptyrowset = 빈 rowset를 이 JoinRowSet에 추가할 수 없습니다.
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = 상태가 부적합합니다.
|
||||
jdbcrowsetimpl.connect = JdbcRowSet(접속) JNDI가 접속할 수 없습니다.
|
||||
jdbcrowsetimpl.paramtype = 매개변수 유형을 추론할 수 없습니다.
|
||||
jdbcrowsetimpl.matchcols = 일치 열이 설정된 열과 동일하지 않습니다.
|
||||
jdbcrowsetimpl.setmatchcols = 일치 열을 설정한 후 가져오십시오.
|
||||
jdbcrowsetimpl.matchcols1 = 일치 열은 0개 이상이어야 합니다.
|
||||
jdbcrowsetimpl.matchcols2 = 일치 열은 널 또는 빈 문자열일 수 없습니다.
|
||||
jdbcrowsetimpl.unsetmatch = 설정을 해제하려는 열이 설정된 열과 다릅니다.
|
||||
jdbcrowsetimpl.usecolname = 열 이름을 unsetMatchColumn의 인수로 사용하십시오.
|
||||
jdbcrowsetimpl.usecolid = 열 ID를 unsetMatchColumn의 인수로 사용하십시오.
|
||||
jdbcrowsetimpl.resnotupd = ResultSet를 업데이트할 수 없습니다.
|
||||
jdbcrowsetimpl.opnotysupp = 작업이 아직 지원되지 않습니다.
|
||||
jdbcrowsetimpl.featnotsupp = 기능이 지원되지 않습니다.
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) 접속할 수 없습니다.
|
||||
crsreader.paramtype = 매개변수 유형을 추론할 수 없습니다.
|
||||
crsreader.connecterr = RowSetReader에 내부 오류 발생: 접속 또는 명령이 없습니다.
|
||||
crsreader.datedetected = 날짜를 감지함
|
||||
crsreader.caldetected = 달력을 감지함
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = 접속할 수 없습니다.
|
||||
crswriter.tname = writeData에서 테이블 이름을 확인할 수 없습니다.
|
||||
crswriter.params1 = params1의 값: {0}
|
||||
crswriter.params2 = params2의 값: {0}
|
||||
crswriter.conflictsno = 동기화하는 중 충돌함
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = 값이 삽입되지 않았습니다.
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = 인덱스 값이 범위를 벗어났습니다.
|
||||
syncrsimpl.noconflict = 이 열은 충돌하지 않습니다.
|
||||
syncrsimpl.syncnotpos = 동기화할 수 없습니다.
|
||||
syncrsimpl.valtores = 분석할 값이 데이터베이스 또는 cachedrowset에 있을 수 있습니다.
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = RowSet의 끝에 도달했습니다. 커서 위치가 부적합합니다.
|
||||
wrsxmlreader.readxml = readXML: {0}
|
||||
wrsxmlreader.parseerr = ** 구문분석 오류: {0}, 행: {1}, URI: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException : {0}
|
||||
wrsxmlwriter.sqlex = SQLException : {0}
|
||||
wrsxmlwriter.failedwrite = 값 쓰기를 실패했습니다.
|
||||
wsrxmlwriter.notproper = 적절한 유형이 아닙니다.
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = 맵을 설정하는 중 오류 발생: {0}
|
||||
xmlrch.errmetadata = 메타데이터를 설정하는 중 오류 발생: {0}
|
||||
xmlrch.errinsertval = 값을 삽입하는 중 오류 발생: {0}
|
||||
xmlrch.errconstr = 행을 생성하는 중 오류 발생: {0}
|
||||
xmlrch.errdel = 행을 삭제하는 중 오류 발생: {0}
|
||||
xmlrch.errinsert = insert 행을 생성하는 중 오류 발생: {0}
|
||||
xmlrch.errinsdel = insdel 행을 생성하는 중 오류 발생: {0}
|
||||
xmlrch.errupdate = update 행을 생성하는 중 오류 발생: {0}
|
||||
xmlrch.errupdrow = 행을 업데이트하는 중 오류 발생: {0}
|
||||
xmlrch.chars = 문자:
|
||||
xmlrch.badvalue = 잘못된 값: 널일 수 없는 속성입니다.
|
||||
xmlrch.badvalue1 = 잘못된 값: 널일 수 없는 메타데이터입니다.
|
||||
xmlrch.warning = ** 경고: {0}, 행: {1}, URI: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = 분류 잠금이 지원되지 않습니다.
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = RIXMLProvider에서 지원되지 않습니다.
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = Objeto ResultSet inválido fornecido para preencher o método
|
||||
cachedrowsetimpl.invalidp = Fornecedor de persistências inválido gerado
|
||||
cachedrowsetimpl.nullhash = Não é possível instanciar a instância CachedRowSetImpl. Hashtable Nulo fornecido ao construtor
|
||||
cachedrowsetimpl.invalidop = Operação inválida durante a inserção de linha
|
||||
cachedrowsetimpl.accfailed = Falha em acceptChanges
|
||||
cachedrowsetimpl.invalidcp = Posição inválida do cursor
|
||||
cachedrowsetimpl.illegalop = Operação inválida em linha não inserida
|
||||
cachedrowsetimpl.clonefail = Falha ao clonar: {0}
|
||||
cachedrowsetimpl.invalidcol = Índice de coluna inválido
|
||||
cachedrowsetimpl.invalcolnm = Nome de coluna inválido
|
||||
cachedrowsetimpl.boolfail = Falha em getBoolen no valor ( {0} ) na coluna {1}
|
||||
cachedrowsetimpl.bytefail = Falha em getByte no valor ( {0} ) na coluna {1}
|
||||
cachedrowsetimpl.shortfail = Falha em getShort no valor ( {0} ) na coluna {1}
|
||||
cachedrowsetimpl.intfail = Falha em getInt no valor ( {0} ) na coluna {1}
|
||||
cachedrowsetimpl.longfail = Falha em getLong no valor ( {0} ) na coluna {1}
|
||||
cachedrowsetimpl.floatfail = Falha em getFloat no valor ( {0} ) na coluna {1}
|
||||
cachedrowsetimpl.doublefail = Falha em getDouble no valor ( {0} ) na coluna {1}
|
||||
cachedrowsetimpl.dtypemismt = Tipo de Dados Incompatível
|
||||
cachedrowsetimpl.datefail = Falha em getDate no valor ( {0} ) na coluna {1} sem conversão disponível
|
||||
cachedrowsetimpl.timefail = Falha em getTime no valor ( {0} ) na coluna {1} sem conversão disponível
|
||||
cachedrowsetimpl.posupdate = Atualizações posicionadas não suportadas
|
||||
cachedrowsetimpl.unableins = Não é possível instanciar : {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst : Operação do cursor inválida
|
||||
cachedrowsetimpl.first = First : Operação inválida do cursor
|
||||
cachedrowsetimpl.last = last : TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute : Posição inválida do cursor
|
||||
cachedrowsetimpl.relative = relative : Posição inválida do cursor
|
||||
cachedrowsetimpl.asciistream = falha na leitura do fluxo ascii
|
||||
cachedrowsetimpl.binstream = falha na leitura do fluxo binário
|
||||
cachedrowsetimpl.failedins = Falha ao inserir a linha
|
||||
cachedrowsetimpl.updateins = updateRow chamado durante a inserção de linha
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow : CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow : sem metadados
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow : número de colunas inválido
|
||||
cachedrowsetimpl.tablename = O nome da tabela não pode ser nulo
|
||||
cachedrowsetimpl.keycols = Colunas de chaves inválidas
|
||||
cachedrowsetimpl.opnotsupp = Operação não suportada pelo Banco de Dados
|
||||
cachedrowsetimpl.matchcols = As colunas correspondentes não são iguais às colunas definidas
|
||||
cachedrowsetimpl.setmatchcols = Definir Colunas correspondentes antes de obtê-las
|
||||
cachedrowsetimpl.matchcols1 = As colunas correspondentes devem ser maior do que 0
|
||||
cachedrowsetimpl.matchcols2 = As colunas correspondentes devem ser strings vazias ou nulas
|
||||
cachedrowsetimpl.unsetmatch = As colunas não definidas não são iguais às colunas definidas
|
||||
cachedrowsetimpl.unsetmatch1 = Usar o nome da coluna como argumento para unsetMatchColumn
|
||||
cachedrowsetimpl.unsetmatch2 = Usar o ID da coluna como argumento para unsetMatchColumn
|
||||
cachedrowsetimpl.numrows = O número de linhas é menor do que zero ou menor do que o tamanho obtido
|
||||
cachedrowsetimpl.startpos = A posição de início não pode ser negativa
|
||||
cachedrowsetimpl.nextpage = Preencher dados antes de chamar
|
||||
cachedrowsetimpl.pagesize = O tamanho da página não pode ser menor do que zero
|
||||
cachedrowsetimpl.pagesize1 = O tamanho da página não pode ser maior do que maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet é somente para frente
|
||||
cachedrowsetimpl.type = O tipo é : {0}
|
||||
cachedrowsetimpl.opnotysupp = Operação ainda não suportada
|
||||
cachedrowsetimpl.featnotsupp = Recurso não suportado
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = Não é possível instanciar a instância WebRowSetImpl. Hashtable nulo fornecido ao construtor
|
||||
webrowsetimpl.invalidwr = Gravador inválido
|
||||
webrowsetimpl.invalidrd = Leitor inválido
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative : Operação inválida do cursor
|
||||
filteredrowsetimpl.absolute = absolute : Operação inválida do cursor
|
||||
filteredrowsetimpl.notallowed = Este valor não é permitido no filtro
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = Não é uma instância do conjunto de linhas
|
||||
joinrowsetimpl.matchnotset = Coluna Correspondente não definida para junção
|
||||
joinrowsetimpl.numnotequal = Número de elementos no conjunto de linhas diferente da coluna correspondente
|
||||
joinrowsetimpl.notdefined = Não é um tipo definido de junção
|
||||
joinrowsetimpl.notsupported = Este tipo de junção não é suportada
|
||||
joinrowsetimpl.initerror = Erro de inicialização do JoinRowSet
|
||||
joinrowsetimpl.genericerr = Erro inicial de joinrowset genérico
|
||||
joinrowsetimpl.emptyrowset = O conjunto de linha vazio não pode ser adicionado a este JoinRowSet
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = Estado inválido
|
||||
jdbcrowsetimpl.connect = Não é possível conectar JdbcRowSet (connect) a JNDI
|
||||
jdbcrowsetimpl.paramtype = Não é possível deduzir o tipo de parâmetro
|
||||
jdbcrowsetimpl.matchcols = As Colunas Correspondentes não são iguais às colunas definidas
|
||||
jdbcrowsetimpl.setmatchcols = Definir as colunas correspondentes antes de obtê-las
|
||||
jdbcrowsetimpl.matchcols1 = As colunas correspondentes devem ser maior do que 0
|
||||
jdbcrowsetimpl.matchcols2 = As colunas correspondentes não podem ser strings vazias ou nulas
|
||||
jdbcrowsetimpl.unsetmatch = As colunas não definidas não são iguais às colunas definidas
|
||||
jdbcrowsetimpl.usecolname = Usar o nome da coluna como argumento para unsetMatchColumn
|
||||
jdbcrowsetimpl.usecolid = Usar o ID da coluna como argumento para unsetMatchColumn
|
||||
jdbcrowsetimpl.resnotupd = ResultSet não é atualizável
|
||||
jdbcrowsetimpl.opnotysupp = Operação ainda não suportada
|
||||
jdbcrowsetimpl.featnotsupp = Recurso não suportado
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) Não é possível conectar
|
||||
crsreader.paramtype = Não é possível deduzir o tipo de parâmetro
|
||||
crsreader.connecterr = Erro Interno no RowSetReader: sem conexão ou comando
|
||||
crsreader.datedetected = Data Detectada
|
||||
crsreader.caldetected = Calendário Detectado
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = Não é possível obter a conexão
|
||||
crswriter.tname = writeData não pode determinar o nome da tabela
|
||||
crswriter.params1 = Valor de params1 : {0}
|
||||
crswriter.params2 = Valor de params2 : {0}
|
||||
crswriter.conflictsno = conflitos durante a sincronização
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = Nenhum valor foi inserido
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = Valor de índice fora da faixa
|
||||
syncrsimpl.noconflict = Está coluna não está em conflito
|
||||
syncrsimpl.syncnotpos = A sincronização não é possível
|
||||
syncrsimpl.valtores = O valor a ser decidido pode estar no banco de dados ou no conjunto de linhas armazenado no cache
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = Fim de RowSet atingido. Posição inválida do cursor
|
||||
wrsxmlreader.readxml = readXML : {0}
|
||||
wrsxmlreader.parseerr = ** Erro de Parsing : {0} , linha : {1} , uri : {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException : {0}
|
||||
wrsxmlwriter.sqlex = SQLException : {0}
|
||||
wrsxmlwriter.failedwrite = Falha ao gravar o valor
|
||||
wsrxmlwriter.notproper = Não é um tipo adequado
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Erro ao definir o Mapa : {0}
|
||||
xmlrch.errmetadata = Erro ao definir metadados : {0}
|
||||
xmlrch.errinsertval = Erro ao inserir valores : {0}
|
||||
xmlrch.errconstr = Erro ao construir a linha : {0}
|
||||
xmlrch.errdel = Erro ao excluir a linha : {0}
|
||||
xmlrch.errinsert = Erro ao construir a linha de inserção : {0}
|
||||
xmlrch.errinsdel = Erro ao construir a linha insdel : {0}
|
||||
xmlrch.errupdate = Erro ao construir a linha de atualização : {0}
|
||||
xmlrch.errupdrow = Erro ao atualizar a linha : {0}
|
||||
xmlrch.chars = caracteres :
|
||||
xmlrch.badvalue = Valor incorreto ; propriedade não anulável
|
||||
xmlrch.badvalue1 = Valor incorreto ; metadado não anulável
|
||||
xmlrch.warning = ** Advertência : {0} , linha : {1} , uri : {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = O bloqueio de classificação não é suportado
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = Não suportado com RIXMLProvider
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = Ifyllningsmetoden fick ett ogiltigt ResultSet-objekt
|
||||
cachedrowsetimpl.invalidp = En ogiltig beständig leverantör genererades
|
||||
cachedrowsetimpl.nullhash = Kan inte instansiera CachedRowSetImpl. Null-hashtabell skickades till konstruktor
|
||||
cachedrowsetimpl.invalidop = En ogiltig åtgärd utfördes på infogad rad
|
||||
cachedrowsetimpl.accfailed = acceptChanges utfördes inte
|
||||
cachedrowsetimpl.invalidcp = Ogiltigt markörläge
|
||||
cachedrowsetimpl.illegalop = En otillåten åtgärd utfördes på en icke infogad rad
|
||||
cachedrowsetimpl.clonefail = Kloningen utfördes inte: {0}
|
||||
cachedrowsetimpl.invalidcol = Ogiltigt kolumnindex
|
||||
cachedrowsetimpl.invalcolnm = Ogiltigt kolumnnamn
|
||||
cachedrowsetimpl.boolfail = getBoolen utfördes inte för värdet ({0}) i kolumnen {1}
|
||||
cachedrowsetimpl.bytefail = getByte utfördes inte för värdet ({0}) i kolumnen {1}
|
||||
cachedrowsetimpl.shortfail = getShort utfördes inte för värdet ({0}) i kolumnen {1}
|
||||
cachedrowsetimpl.intfail = getInt utfördes inte för värdet ({0}) i kolumnen {1}
|
||||
cachedrowsetimpl.longfail = getLong utfördes inte för värdet ({0}) i kolumnen {1}
|
||||
cachedrowsetimpl.floatfail = getFloat utfördes inte för värdet ({0}) i kolumnen {1}
|
||||
cachedrowsetimpl.doublefail = getDouble utfördes inte för värdet ({0}) i kolumnen {1}
|
||||
cachedrowsetimpl.dtypemismt = Felmatchad datatyp
|
||||
cachedrowsetimpl.datefail = getDate utfördes inte för värdet ({0}) i kolumnen {1}, ingen konvertering tillgänglig
|
||||
cachedrowsetimpl.timefail = getTime utfördes inte för värdet ({0}) i kolumnen {1}, ingen konvertering tillgänglig
|
||||
cachedrowsetimpl.posupdate = Det finns inte stöd för positionerad uppdatering
|
||||
cachedrowsetimpl.unableins = Kan inte instansiera {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: Ogiltig marköråtgärd
|
||||
cachedrowsetimpl.first = First: Ogiltig marköråtgärd
|
||||
cachedrowsetimpl.last = last: TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute: Markörpositionen är ogiltig
|
||||
cachedrowsetimpl.relative = relative: Markörpositionen är ogiltig
|
||||
cachedrowsetimpl.asciistream = kunde inte läsa ASCII-strömmen
|
||||
cachedrowsetimpl.binstream = kunde inte läsa den binära strömmen
|
||||
cachedrowsetimpl.failedins = Kunde inte infoga rad
|
||||
cachedrowsetimpl.updateins = updateRow anropades från infogad rad
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow : CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: inga metadata
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: ogiltigt antal kolumner
|
||||
cachedrowsetimpl.tablename = Tabellnamnet kan inte vara null
|
||||
cachedrowsetimpl.keycols = Ogiltiga nyckelkolumner
|
||||
cachedrowsetimpl.opnotsupp = Databasen har inte stöd för denna åtgärd
|
||||
cachedrowsetimpl.matchcols = Matchningskolumnerna är inte samma som de som ställts in
|
||||
cachedrowsetimpl.setmatchcols = Ställ in matchningskolumnerna innan du hämtar dem
|
||||
cachedrowsetimpl.matchcols1 = Matchningskolumnerna måste vara större än 0
|
||||
cachedrowsetimpl.matchcols2 = Matchningskolumnerna måste vara tomma eller en null-sträng
|
||||
cachedrowsetimpl.unsetmatch = Kolumnerna som återställs är inte samma som de som ställts in
|
||||
cachedrowsetimpl.unsetmatch1 = Använd kolumnnamn som argument för unsetMatchColumn
|
||||
cachedrowsetimpl.unsetmatch2 = Använd kolumn-id som argument för unsetMatchColumn
|
||||
cachedrowsetimpl.numrows = Antalet rader understiger noll eller är mindre än hämtningsstorleken
|
||||
cachedrowsetimpl.startpos = Startpositionen får inte vara negativ
|
||||
cachedrowsetimpl.nextpage = Fyll i data innan anrop
|
||||
cachedrowsetimpl.pagesize = Sidstorleken får inte understiga noll
|
||||
cachedrowsetimpl.pagesize1 = Sidstorleken får inte överstiga maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet kan endast gå framåt
|
||||
cachedrowsetimpl.type = Typ: {0}
|
||||
cachedrowsetimpl.opnotysupp = Det finns ännu inget stöd för denna åtgärd
|
||||
cachedrowsetimpl.featnotsupp = Funktionen stöds inte
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = Kan inte instansiera WebRowSetImpl. Null-hashtabell skickades till konstruktor.
|
||||
webrowsetimpl.invalidwr = Ogiltig skrivfunktion
|
||||
webrowsetimpl.invalidrd = Ogiltig läsare
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative: Ogiltig marköråtgärd
|
||||
filteredrowsetimpl.absolute = absolute: Ogiltig marköråtgärd
|
||||
filteredrowsetimpl.notallowed = Detta värde kommer att filtreras bort
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = Detta är inte en instans av raduppsättning
|
||||
joinrowsetimpl.matchnotset = Matchningskolumnen är inte inställd på koppling
|
||||
joinrowsetimpl.numnotequal = Antal objekt i raduppsättning stämmer inte med matchningskolumnens
|
||||
joinrowsetimpl.notdefined = Detta är inte någon definierad kopplingstyp
|
||||
joinrowsetimpl.notsupported = Det finns inget stöd för denna kopplingstyp
|
||||
joinrowsetimpl.initerror = Initieringsfel för JoinRowSet
|
||||
joinrowsetimpl.genericerr = Allmänt initieringsfel för JoinRowSet
|
||||
joinrowsetimpl.emptyrowset = Tomma raduppsättningar kan inte läggas till i denna JoinRowSet
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = Ogiltigt tillstånd
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (anslut) JNDI kan inte anslutas
|
||||
jdbcrowsetimpl.paramtype = Kan inte härleda parametertypen
|
||||
jdbcrowsetimpl.matchcols = Matchningskolumnerna är inte samma som de som ställts in
|
||||
jdbcrowsetimpl.setmatchcols = Ställ in matchningskolumnerna innan du hämtar dem
|
||||
jdbcrowsetimpl.matchcols1 = Matchningskolumnerna måste vara större än 0
|
||||
jdbcrowsetimpl.matchcols2 = Matchningskolumnerna kan inte vara en null-sträng eller tomma
|
||||
jdbcrowsetimpl.unsetmatch = Kolumnerna som återställs är inte samma som de som ställts in
|
||||
jdbcrowsetimpl.usecolname = Använd kolumnnamn som argument för unsetMatchColumn
|
||||
jdbcrowsetimpl.usecolid = Använd kolumn-id som argument för unsetMatchColumn
|
||||
jdbcrowsetimpl.resnotupd = ResultSet är inte uppdateringsbart
|
||||
jdbcrowsetimpl.opnotysupp = Det finns ännu inget stöd för denna åtgärd
|
||||
jdbcrowsetimpl.featnotsupp = Funktionen stöds inte
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) kan inte anslutas
|
||||
crsreader.paramtype = Kan inte härleda parametertypen
|
||||
crsreader.connecterr = Internt fel i RowSetReader: ingen anslutning eller inget kommando
|
||||
crsreader.datedetected = Ett datum har identifierats
|
||||
crsreader.caldetected = En kalender har identifierats
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = Kan inte upprätta anslutning
|
||||
crswriter.tname = writeData kan inte fastställa tabellnamnet
|
||||
crswriter.params1 = Parametervärde1: {0}
|
||||
crswriter.params2 = Parametervärde2: {0}
|
||||
crswriter.conflictsno = orsakar konflikt vid synkronisering
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = Inget värde har infogats
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = Indexvärdet ligger utanför intervallet
|
||||
syncrsimpl.noconflict = Kolumnen orsakar ingen konflikt
|
||||
syncrsimpl.syncnotpos = Synkronisering är inte möjlig
|
||||
syncrsimpl.valtores = Värdet som ska fastställas kan antingen finnas i databasen eller i cachedrowset
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = Slutet på RowSet har nåtts. Markörpositionen är ogiltig.
|
||||
wrsxmlreader.readxml = readXML: {0}
|
||||
wrsxmlreader.parseerr = ** Tolkningsfel: {0}, rad: {1}, URI: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException: {0}
|
||||
wrsxmlwriter.sqlex = SQLException: {0}
|
||||
wrsxmlwriter.failedwrite = Kunde inte skriva värdet
|
||||
wsrxmlwriter.notproper = Ingen riktig typ
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = Ett fel inträffade vid inställning av mappning: {0}
|
||||
xmlrch.errmetadata = Ett fel inträffade vid inställning av metadata: {0}
|
||||
xmlrch.errinsertval = Ett fel inträffade vid infogning av värden: {0}
|
||||
xmlrch.errconstr = Ett fel inträffade vid konstruktion av rad: {0}
|
||||
xmlrch.errdel = Ett fel inträffade vid borttagning av rad: {0}
|
||||
xmlrch.errinsert = Ett fel inträffade vid konstruktion av infogad rad: {0}
|
||||
xmlrch.errinsdel = Ett fel inträffade vid konstruktion av insdel-rad: {0}
|
||||
xmlrch.errupdate = Ett fel inträffade vid konstruktion av uppdateringsrad: {0}
|
||||
xmlrch.errupdrow = Ett fel inträffade vid uppdatering av rad: {0}
|
||||
xmlrch.chars = tecken:
|
||||
xmlrch.badvalue = Felaktigt värde; egenskapen får inte ha värdet null
|
||||
xmlrch.badvalue1 = Felaktigt värde; metadata får inte ha värdet null
|
||||
xmlrch.warning = ** Varning! {0}, rad: {1}, URI: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = Det finns inte stöd för denna låsningsklassificering
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = RIXMLProvider har inte stöd för detta
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = 提供给填充方法的 ResultSet 对象无效
|
||||
cachedrowsetimpl.invalidp = 生成的持久性提供方无效
|
||||
cachedrowsetimpl.nullhash = 无法实例化 CachedRowSetImpl 实例。提供给构造器的 Hashtable 为空值
|
||||
cachedrowsetimpl.invalidop = 对插入行执行的操作无效
|
||||
cachedrowsetimpl.accfailed = acceptChanges 失败
|
||||
cachedrowsetimpl.invalidcp = 光标位置无效
|
||||
cachedrowsetimpl.illegalop = 对非插入行执行的操作非法
|
||||
cachedrowsetimpl.clonefail = 克隆失败: {0}
|
||||
cachedrowsetimpl.invalidcol = 列索引无效
|
||||
cachedrowsetimpl.invalcolnm = 列名无效
|
||||
cachedrowsetimpl.boolfail = 对列 {1} 中的值 ({0}) 执行 getBoolen 失败
|
||||
cachedrowsetimpl.bytefail = 对列 {1} 中的值 ({0}) 执行 getByte 失败
|
||||
cachedrowsetimpl.shortfail = 对列 {1} 中的值 ({0}) 执行 getShort 失败
|
||||
cachedrowsetimpl.intfail = 对列 {1} 中的值 ({0}) 执行 getInt 失败
|
||||
cachedrowsetimpl.longfail = 对列 {1} 中的值 ({0}) 执行 getLong 失败
|
||||
cachedrowsetimpl.floatfail = 对列 {1} 中的值 ({0}) 执行 getFloat 失败
|
||||
cachedrowsetimpl.doublefail = 对列 {1} 中的值 ({0}) 执行 getDouble 失败
|
||||
cachedrowsetimpl.dtypemismt = 数据类型不匹配
|
||||
cachedrowsetimpl.datefail = 对列 {1} 中的值 ({0}) 执行 getDate 失败, 无可用转换
|
||||
cachedrowsetimpl.timefail = 对列 {1} 中的值 ({0}) 执行 getTime 失败, 无可用转换
|
||||
cachedrowsetimpl.posupdate = 不支持定位更新
|
||||
cachedrowsetimpl.unableins = 无法实例化: {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: 光标操作无效
|
||||
cachedrowsetimpl.first = First: 光标操作无效
|
||||
cachedrowsetimpl.last = last: TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute: 光标位置无效
|
||||
cachedrowsetimpl.relative = relative: 光标位置无效
|
||||
cachedrowsetimpl.asciistream = 未能读取 ASCII 流
|
||||
cachedrowsetimpl.binstream = 未能读取二进制流
|
||||
cachedrowsetimpl.failedins = 对插入行执行操作失败
|
||||
cachedrowsetimpl.updateins = 为插入行调用 updateRow
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow: CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: 无元数据
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: 列数无效
|
||||
cachedrowsetimpl.tablename = 表名不能为空值
|
||||
cachedrowsetimpl.keycols = 关键字列无效
|
||||
cachedrowsetimpl.opnotsupp = 操作不受数据库支持
|
||||
cachedrowsetimpl.matchcols = 匹配列与设置的那些匹配列不同
|
||||
cachedrowsetimpl.setmatchcols = 在获取匹配列之前先设置匹配列
|
||||
cachedrowsetimpl.matchcols1 = 匹配列数应当大于 0
|
||||
cachedrowsetimpl.matchcols2 = 匹配列数应当为空或空值字符串
|
||||
cachedrowsetimpl.unsetmatch = 要取消设置的列与设置的列不同
|
||||
cachedrowsetimpl.unsetmatch1 = 使用列名作为 unsetMatchColumn 的参数
|
||||
cachedrowsetimpl.unsetmatch2 = 使用列 ID 作为 unsetMatchColumn 的参数
|
||||
cachedrowsetimpl.numrows = 行数小于零或小于要提取的行数
|
||||
cachedrowsetimpl.startpos = 起始位置不能为负数
|
||||
cachedrowsetimpl.nextpage = 在调用之前先填充数据
|
||||
cachedrowsetimpl.pagesize = 页面大小不能小于零
|
||||
cachedrowsetimpl.pagesize1 = 页面大小不能大于 maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet 的类型为仅向前类型
|
||||
cachedrowsetimpl.type = 类型为: {0}
|
||||
cachedrowsetimpl.opnotysupp = 尚不支持该操作
|
||||
cachedrowsetimpl.featnotsupp = 尚不支持该功能
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = 无法实例化 WebRowSetImpl 实例。提供给构造器的 Hashtable 为空值
|
||||
webrowsetimpl.invalidwr = 写进程无效
|
||||
webrowsetimpl.invalidrd = 读进程无效
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative: 光标操作无效
|
||||
filteredrowsetimpl.absolute = absolute: 光标操作无效
|
||||
filteredrowsetimpl.notallowed = 不允许此值通过筛选器
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = 不是 RowSet 的实例
|
||||
joinrowsetimpl.matchnotset = 未设置匹配列以进行联接
|
||||
joinrowsetimpl.numnotequal = RowSet 中的元素个数不等于匹配列数
|
||||
joinrowsetimpl.notdefined = 这不是定义的联接类型
|
||||
joinrowsetimpl.notsupported = 不支持此联接类型
|
||||
joinrowsetimpl.initerror = JoinRowSet 初始化错误
|
||||
joinrowsetimpl.genericerr = 一般 joinrowset 初始错误
|
||||
joinrowsetimpl.emptyrowset = 无法将空 RowSet 添加到此 JoinRowSet
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = 状态无效
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (连接) JNDI 无法连接
|
||||
jdbcrowsetimpl.paramtype = 无法推断参数类型
|
||||
jdbcrowsetimpl.matchcols = 匹配列与设置的那些匹配列不同
|
||||
jdbcrowsetimpl.setmatchcols = 在获取匹配列之前先设置匹配列
|
||||
jdbcrowsetimpl.matchcols1 = 匹配列数应当大于 0
|
||||
jdbcrowsetimpl.matchcols2 = 匹配列不能为空值或空字符串
|
||||
jdbcrowsetimpl.unsetmatch = 要取消设置的列与设置的列不同
|
||||
jdbcrowsetimpl.usecolname = 使用列名作为 unsetMatchColumn 的参数
|
||||
jdbcrowsetimpl.usecolid = 使用列 ID 作为 unsetMatchColumn 的参数
|
||||
jdbcrowsetimpl.resnotupd = ResultSet 不可更新
|
||||
jdbcrowsetimpl.opnotysupp = 尚不支持该操作
|
||||
jdbcrowsetimpl.featnotsupp = 尚不支持该功能
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) 无法连接
|
||||
crsreader.paramtype = 无法推断参数类型
|
||||
crsreader.connecterr = RowSetReader 中出现内部错误: 无连接或命令
|
||||
crsreader.datedetected = 检测到日期
|
||||
crsreader.caldetected = 检测到日历
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = 无法获取连接
|
||||
crswriter.tname = writeData 无法确定表名
|
||||
crswriter.params1 = params1 的值: {0}
|
||||
crswriter.params2 = params2 的值: {0}
|
||||
crswriter.conflictsno = 同步时发生冲突
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = 尚未插入任何值
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = 索引值超出范围
|
||||
syncrsimpl.noconflict = 此列不冲突
|
||||
syncrsimpl.syncnotpos = 不能同步
|
||||
syncrsimpl.valtores = 要解析的值可以在数据库中, 也可以在 CachedRowSet 中
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = 已到达 RowSet 的结尾。光标位置无效
|
||||
wrsxmlreader.readxml = readXML: {0}
|
||||
wrsxmlreader.parseerr = ** 解析错误: {0}, 行: {1}, URI: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException: {0}
|
||||
wrsxmlwriter.sqlex = SQLException: {0}
|
||||
wrsxmlwriter.failedwrite = 无法写入值
|
||||
wsrxmlwriter.notproper = 类型不正确
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = 设置映射时出错: {0}
|
||||
xmlrch.errmetadata = 设置元数据时出错: {0}
|
||||
xmlrch.errinsertval = 插入值时出错: {0}
|
||||
xmlrch.errconstr = 构造行时出错: {0}
|
||||
xmlrch.errdel = 删除行时出错: {0}
|
||||
xmlrch.errinsert = 构造插入行时出错: {0}
|
||||
xmlrch.errinsdel = 构造 insdel 行时出错: {0}
|
||||
xmlrch.errupdate = 构造更新行时出错: {0}
|
||||
xmlrch.errupdrow = 更新行时出错: {0}
|
||||
xmlrch.chars = 字符:
|
||||
xmlrch.badvalue = 值错误; 属性不可为空值
|
||||
xmlrch.badvalue1 = 值错误; 元数据不可为空值
|
||||
xmlrch.warning = ** 警告: {0}, 行: {1}, URI: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = 不支持锁定分类
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = 不支持 RIXMLProvider
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2024, 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.
|
||||
#
|
||||
|
||||
# CacheRowSetImpl exceptions
|
||||
cachedrowsetimpl.populate = 為植入方法提供的 ResultSet 物件無效
|
||||
cachedrowsetimpl.invalidp = 產生的持續性提供者無效
|
||||
cachedrowsetimpl.nullhash = 無法建立 CachedRowSetImpl 執行處理。為建構子提供的 Hashtable 為空值
|
||||
cachedrowsetimpl.invalidop = 插入列時的作業無效
|
||||
cachedrowsetimpl.accfailed = acceptChanges 失敗
|
||||
cachedrowsetimpl.invalidcp = 游標位置無效
|
||||
cachedrowsetimpl.illegalop = 非插入列上存在無效作業
|
||||
cachedrowsetimpl.clonefail = 複製失敗: {0}
|
||||
cachedrowsetimpl.invalidcol = 欄索引無效
|
||||
cachedrowsetimpl.invalcolnm = 欄名無效
|
||||
cachedrowsetimpl.boolfail = 對欄 {1} 中的值 ( {0} ) 執行 getBoolen 失敗
|
||||
cachedrowsetimpl.bytefail = 對欄 {1} 中的值 ( {0} ) 執行 getByte 失敗
|
||||
cachedrowsetimpl.shortfail = 對欄 {1} 中的值 ( {0} ) 執行 getShort 失敗
|
||||
cachedrowsetimpl.intfail = 對欄 {1} 中的值 ( {0} ) 執行 getInt 失敗
|
||||
cachedrowsetimpl.longfail = 對欄 {1} 中的值 ( {0} ) 執行 getLong 失敗
|
||||
cachedrowsetimpl.floatfail = 對欄 {1} 中的值 ( {0} ) 執行 getFloat 失敗
|
||||
cachedrowsetimpl.doublefail = 對欄 {1} 中的值 ( {0} ) 執行 getDouble 失敗
|
||||
cachedrowsetimpl.dtypemismt = 資料類型不相符
|
||||
cachedrowsetimpl.datefail = 對欄 {1} 中的值 ( {0} ) 執行 getDate 失敗,未進行轉換
|
||||
cachedrowsetimpl.timefail = 對欄 {1} 中的值 ( {0} ) 執行 getTime 失敗,未進行轉換
|
||||
cachedrowsetimpl.posupdate = 不支援定位的更新
|
||||
cachedrowsetimpl.unableins = 無法建立: {0}
|
||||
cachedrowsetimpl.beforefirst = beforeFirst: 游標作業無效
|
||||
cachedrowsetimpl.first = First: 游標作業無效
|
||||
cachedrowsetimpl.last = last : TYPE_FORWARD_ONLY
|
||||
cachedrowsetimpl.absolute = absolute: 游標位置無效
|
||||
cachedrowsetimpl.relative = relative: 游標位置無效
|
||||
cachedrowsetimpl.asciistream = 讀取 ascii 串流失敗
|
||||
cachedrowsetimpl.binstream = 讀取二進位串流失敗
|
||||
cachedrowsetimpl.failedins = 插入列失敗
|
||||
cachedrowsetimpl.updateins = 插入列時呼叫 updateRow
|
||||
cachedrowsetimpl.movetoins = moveToInsertRow: CONCUR_READ_ONLY
|
||||
cachedrowsetimpl.movetoins1 = moveToInsertRow: 沒有描述資料
|
||||
cachedrowsetimpl.movetoins2 = moveToInsertRow: 欄數無效
|
||||
cachedrowsetimpl.tablename = 表格名稱不能為空值
|
||||
cachedrowsetimpl.keycols = 關鍵欄無效
|
||||
cachedrowsetimpl.opnotsupp = 資料庫不支援作業
|
||||
cachedrowsetimpl.matchcols = 匹配欄和設定的欄不同
|
||||
cachedrowsetimpl.setmatchcols = 在取得匹配欄之前設定它們
|
||||
cachedrowsetimpl.matchcols1 = 匹配欄應大於 0
|
||||
cachedrowsetimpl.matchcols2 = 匹配欄應為空白字串或空值字串
|
||||
cachedrowsetimpl.unsetmatch = 取消設定的欄和設定的欄不同
|
||||
cachedrowsetimpl.unsetmatch1 = 使用欄名作為 unsetMatchColumn 的引數
|
||||
cachedrowsetimpl.unsetmatch2 = 使用欄 ID 作為 unsetMatchColumn 的引數
|
||||
cachedrowsetimpl.numrows = 列數小於零或小於擷取大小
|
||||
cachedrowsetimpl.startpos = 起始位置不能為負數
|
||||
cachedrowsetimpl.nextpage = 在呼叫之前植入資料
|
||||
cachedrowsetimpl.pagesize = 頁面大小不能小於零
|
||||
cachedrowsetimpl.pagesize1 = 頁面大小不能大於 maxRows
|
||||
cachedrowsetimpl.fwdonly = ResultSet 只能向前進行
|
||||
cachedrowsetimpl.type = 類型是: {0}
|
||||
cachedrowsetimpl.opnotysupp = 尚不支援該作業
|
||||
cachedrowsetimpl.featnotsupp = 不支援該功能
|
||||
|
||||
# WebRowSetImpl exceptions
|
||||
webrowsetimpl.nullhash = 無法建立 WebRowSetImpl 執行處理。為建構子提供的 Hashtable 為空值
|
||||
webrowsetimpl.invalidwr = 寫入器無效
|
||||
webrowsetimpl.invalidrd = 讀取器無效
|
||||
|
||||
#FilteredRowSetImpl exceptions
|
||||
filteredrowsetimpl.relative = relative: 游標作業無效
|
||||
filteredrowsetimpl.absolute = absolute: 游標作業無效
|
||||
filteredrowsetimpl.notallowed = 不允許此值通過篩選
|
||||
|
||||
#JoinRowSetImpl exceptions
|
||||
joinrowsetimpl.notinstance = 不是 rowset 的執行處理
|
||||
joinrowsetimpl.matchnotset = 未設定用於連結的匹配欄
|
||||
joinrowsetimpl.numnotequal = rowset 中的元素數不等於匹配欄
|
||||
joinrowsetimpl.notdefined = 這不是連結的已定義類型
|
||||
joinrowsetimpl.notsupported = 不支援此類連結
|
||||
joinrowsetimpl.initerror = JoinRowSet 初始化錯誤
|
||||
joinrowsetimpl.genericerr = 一般的 joinrowset 初始化錯誤
|
||||
joinrowsetimpl.emptyrowset = 無法將空 rowset 新增至此 JoinRowSet
|
||||
|
||||
#JdbcRowSetImpl exceptions
|
||||
jdbcrowsetimpl.invalstate = 狀態無效
|
||||
jdbcrowsetimpl.connect = JdbcRowSet (連線) JNDI 無法連線
|
||||
jdbcrowsetimpl.paramtype = 無法推斷參數類型
|
||||
jdbcrowsetimpl.matchcols = 匹配欄和設定的欄不同
|
||||
jdbcrowsetimpl.setmatchcols = 要先設定匹配欄,才能取得它們
|
||||
jdbcrowsetimpl.matchcols1 = 匹配欄應大於 0
|
||||
jdbcrowsetimpl.matchcols2 = 匹配欄不能為空白字串或空值字串
|
||||
jdbcrowsetimpl.unsetmatch = 取消設定的欄和設定的欄不同
|
||||
jdbcrowsetimpl.usecolname = 使用欄名作為 unsetMatchColumn 的引數
|
||||
jdbcrowsetimpl.usecolid = 使用欄 ID 作為 unsetMatchColumn 的引數
|
||||
jdbcrowsetimpl.resnotupd = ResultSet 不可更新
|
||||
jdbcrowsetimpl.opnotysupp = 尚不支援該作業
|
||||
jdbcrowsetimpl.featnotsupp = 不支援該功能
|
||||
|
||||
#CachedRowSetReader exceptions
|
||||
crsreader.connect = (JNDI) 無法連線
|
||||
crsreader.paramtype = 無法推斷參數類型
|
||||
crsreader.connecterr = RowSetReader 中出現內部錯誤: 無連線或命令
|
||||
crsreader.datedetected = 偵測到日期
|
||||
crsreader.caldetected = 偵測到行事曆
|
||||
|
||||
#CachedRowSetWriter exceptions
|
||||
crswriter.connect = 無法取得連線
|
||||
crswriter.tname = writeData 不能決定表格名稱
|
||||
crswriter.params1 = params1 的值: {0}
|
||||
crswriter.params2 = params2 的值: {0}
|
||||
crswriter.conflictsno = 同步化時發生衝突
|
||||
|
||||
#InsertRow exceptions
|
||||
insertrow.novalue = 尚未插入值
|
||||
|
||||
#SyncResolverImpl exceptions
|
||||
syncrsimpl.indexval = 索引值超出範圍
|
||||
syncrsimpl.noconflict = 此欄不衝突
|
||||
syncrsimpl.syncnotpos = 不可能同步化
|
||||
syncrsimpl.valtores = 要解析的值可位於資料庫或 cachedrowset 中
|
||||
|
||||
#WebRowSetXmlReader exception
|
||||
wrsxmlreader.invalidcp = 已到達 RowSet 結尾。游標位置無效
|
||||
wrsxmlreader.readxml = readXML: {0}
|
||||
wrsxmlreader.parseerr = ** 剖析錯誤: {0},行: {1},uri: {2}
|
||||
|
||||
#WebRowSetXmlWriter exceptions
|
||||
wrsxmlwriter.ioex = IOException : {0}
|
||||
wrsxmlwriter.sqlex = SQLException : {0}
|
||||
wrsxmlwriter.failedwrite = 寫入值失敗
|
||||
wsrxmlwriter.notproper = 不是正確類型
|
||||
|
||||
#XmlReaderContentHandler exceptions
|
||||
xmlrch.errmap = 設定對映時發生錯誤: {0}
|
||||
xmlrch.errmetadata = 設定描述資料時發生錯誤: {0}
|
||||
xmlrch.errinsertval = 插入值時發生錯誤: {0}
|
||||
xmlrch.errconstr = 建構列時發生錯誤: {0}
|
||||
xmlrch.errdel = 刪除列時發生錯誤: {0}
|
||||
xmlrch.errinsert = 建構插入列時發生錯誤 : {0}
|
||||
xmlrch.errinsdel = 建構 insdel 列時發生錯誤: {0}
|
||||
xmlrch.errupdate = 建構更新列時發生錯誤: {0}
|
||||
xmlrch.errupdrow = 更新列時發生錯誤: {0}
|
||||
xmlrch.chars = 字元:
|
||||
xmlrch.badvalue = 錯誤的值; 屬性不能為空值
|
||||
xmlrch.badvalue1 = 錯誤的值; 描述資料不能為空值
|
||||
xmlrch.warning = ** 警告: {0},行: {1},uri: {2}
|
||||
|
||||
#RIOptimisticProvider Exceptions
|
||||
riop.locking = 不支援鎖定分類
|
||||
|
||||
#RIXMLProvider exceptions
|
||||
rixml.unsupp = RIXMLProvider 不支援
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2021, 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 com.sun.rowset;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.util.*;
|
||||
import java.text.*;
|
||||
|
||||
import org.xml.sax.*;
|
||||
|
||||
import javax.sql.rowset.*;
|
||||
import javax.sql.rowset.spi.*;
|
||||
|
||||
import com.sun.rowset.providers.*;
|
||||
import com.sun.rowset.internal.*;
|
||||
|
||||
/**
|
||||
* The standard implementation of the <code>WebRowSet</code> interface. See the interface
|
||||
* definition for full behavior and implementation requirements.
|
||||
*
|
||||
* @author Jonathan Bruce, Amit Handa
|
||||
*/
|
||||
public class WebRowSetImpl extends CachedRowSetImpl implements WebRowSet {
|
||||
|
||||
/**
|
||||
* The <code>WebRowSetXmlReader</code> object that this
|
||||
* <code>WebRowSet</code> object will call when the method
|
||||
* <code>WebRowSet.readXml</code> is invoked.
|
||||
*/
|
||||
private WebRowSetXmlReader xmlReader;
|
||||
|
||||
/**
|
||||
* The <code>WebRowSetXmlWriter</code> object that this
|
||||
* <code>WebRowSet</code> object will call when the method
|
||||
* <code>WebRowSet.writeXml</code> is invoked.
|
||||
*/
|
||||
private WebRowSetXmlWriter xmlWriter;
|
||||
|
||||
/* This stores the cursor position prior to calling the writeXML.
|
||||
* This variable is used after the write to restore the position
|
||||
* to the point where the writeXml was called.
|
||||
*/
|
||||
private int curPosBfrWrite;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private SyncProvider provider;
|
||||
|
||||
/**
|
||||
* Constructs a new <code>WebRowSet</code> object initialized with the
|
||||
* default values for a <code>CachedRowSet</code> object instance. This
|
||||
* provides the <code>RIOptimistic</code> provider to deliver
|
||||
* synchronization capabilities to relational datastores and a default
|
||||
* <code>WebRowSetXmlReader</code> object and a default
|
||||
* <code>WebRowSetXmlWriter</code> object to enable XML output
|
||||
* capabilities.
|
||||
*
|
||||
* @throws SQLException if an error occurs in configuring the default
|
||||
* synchronization providers for relational and XML providers.
|
||||
*/
|
||||
public WebRowSetImpl() throws SQLException {
|
||||
super();
|
||||
|
||||
// %%%
|
||||
// Needs to use to SPI XmlReader,XmlWriters
|
||||
//
|
||||
xmlReader = new WebRowSetXmlReader();
|
||||
xmlWriter = new WebRowSetXmlWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>WebRowSet</code> object initialized with the
|
||||
* synchronization SPI provider properties as specified in the <code>Hashtable</code>. If
|
||||
* this hashtable is empty or is <code>null</code> the default constructor is invoked.
|
||||
*
|
||||
* @throws SQLException if an error occurs in configuring the specified
|
||||
* synchronization providers for the relational and XML providers; or
|
||||
* if the Hashtanle is null
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public WebRowSetImpl(Hashtable env) throws SQLException {
|
||||
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
|
||||
if ( env == null) {
|
||||
throw new SQLException(resBundle.handleGetObject("webrowsetimpl.nullhash").toString());
|
||||
}
|
||||
|
||||
String providerName =
|
||||
(String)env.get(javax.sql.rowset.spi.SyncFactory.ROWSET_SYNC_PROVIDER);
|
||||
|
||||
// set the Reader, this maybe overridden latter
|
||||
provider = SyncFactory.getInstance(providerName);
|
||||
|
||||
// xmlReader = provider.getRowSetReader();
|
||||
// xmlWriter = provider.getRowSetWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates this <code>WebRowSet</code> object with the
|
||||
* data in the given <code>ResultSet</code> object and writes itself
|
||||
* to the given <code>java.io.Writer</code> object in XML format.
|
||||
* This includes the rowset's data, properties, and metadata.
|
||||
*
|
||||
* @throws SQLException if an error occurs writing out the rowset
|
||||
* contents to XML
|
||||
*/
|
||||
public void writeXml(ResultSet rs, java.io.Writer writer)
|
||||
throws SQLException {
|
||||
// WebRowSetImpl wrs = new WebRowSetImpl();
|
||||
this.populate(rs);
|
||||
|
||||
// Store the cursor position before writing
|
||||
curPosBfrWrite = this.getRow();
|
||||
|
||||
this.writeXml(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes this <code>WebRowSet</code> object to the given
|
||||
* <code>java.io.Writer</code> object in XML format. This
|
||||
* includes the rowset's data, properties, and metadata.
|
||||
*
|
||||
* @throws SQLException if an error occurs writing out the rowset
|
||||
* contents to XML
|
||||
*/
|
||||
public void writeXml(java.io.Writer writer) throws SQLException {
|
||||
// %%%
|
||||
// This will change to a XmlReader, which over-rides the default
|
||||
// Xml that is used when a WRS is instantiated.
|
||||
// WebRowSetXmlWriter xmlWriter = getXmlWriter();
|
||||
if (xmlWriter != null) {
|
||||
|
||||
// Store the cursor position before writing
|
||||
curPosBfrWrite = this.getRow();
|
||||
|
||||
xmlWriter.writeXML(this, writer);
|
||||
} else {
|
||||
throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidwr").toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this <code>WebRowSet</code> object in its XML format.
|
||||
*
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public void readXml(java.io.Reader reader) throws SQLException {
|
||||
// %%%
|
||||
// This will change to a XmlReader, which over-rides the default
|
||||
// Xml that is used when a WRS is instantiated.
|
||||
//WebRowSetXmlReader xmlReader = getXmlReader();
|
||||
try {
|
||||
if (reader != null) {
|
||||
xmlReader.readXML(this, reader);
|
||||
|
||||
// Position is before the first row
|
||||
// The cursor position is to be stored while serializng
|
||||
// and deserializing the WebRowSet Object.
|
||||
if(curPosBfrWrite == 0) {
|
||||
this.beforeFirst();
|
||||
}
|
||||
|
||||
// Return the position back to place prior to callin writeXml
|
||||
else {
|
||||
this.absolute(curPosBfrWrite);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidrd").toString());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new SQLException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Stream based methods
|
||||
/**
|
||||
* Reads a stream based XML input to populate this <code>WebRowSet</code>
|
||||
* object.
|
||||
*
|
||||
* @throws SQLException if a data source access error occurs
|
||||
* @throws IOException if a IO exception occurs
|
||||
*/
|
||||
public void readXml(java.io.InputStream iStream) throws SQLException, IOException {
|
||||
if (iStream != null) {
|
||||
xmlReader.readXML(this, iStream);
|
||||
|
||||
// Position is before the first row
|
||||
// The cursor position is to be stored while serializng
|
||||
// and deserializing the WebRowSet Object.
|
||||
if(curPosBfrWrite == 0) {
|
||||
this.beforeFirst();
|
||||
}
|
||||
|
||||
// Return the position back to place prior to callin writeXml
|
||||
else {
|
||||
this.absolute(curPosBfrWrite);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidrd").toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes this <code>WebRowSet</code> object to the given <code> OutputStream</code>
|
||||
* object in XML format.
|
||||
* Creates an output stream of the internal state and contents of a
|
||||
* <code>WebRowSet</code> for XML proceessing
|
||||
*
|
||||
* @throws SQLException if a datasource access error occurs
|
||||
* @throws IOException if an IO exception occurs
|
||||
*/
|
||||
public void writeXml(java.io.OutputStream oStream) throws SQLException, IOException {
|
||||
if (xmlWriter != null) {
|
||||
|
||||
// Store the cursor position before writing
|
||||
curPosBfrWrite = this.getRow();
|
||||
|
||||
xmlWriter.writeXML(this, oStream);
|
||||
} else {
|
||||
throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidwr").toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates this <code>WebRowSet</code> object with the
|
||||
* data in the given <code>ResultSet</code> object and writes itself
|
||||
* to the given <code>java.io.OutputStream</code> object in XML format.
|
||||
* This includes the rowset's data, properties, and metadata.
|
||||
*
|
||||
* @throws SQLException if a datasource access error occurs
|
||||
* @throws IOException if an IO exception occurs
|
||||
*/
|
||||
public void writeXml(ResultSet rs, java.io.OutputStream oStream) throws SQLException, IOException {
|
||||
this.populate(rs);
|
||||
|
||||
// Store the cursor position before writing
|
||||
curPosBfrWrite = this.getRow();
|
||||
|
||||
this.writeXml(oStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method re populates the resBundle
|
||||
* during the deserialization process
|
||||
*
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Default state initialization happens here
|
||||
ois.defaultReadObject();
|
||||
// Initialization of transient Res Bundle happens here .
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final long serialVersionUID = -8771775154092422943L;
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2021, 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 com.sun.rowset.internal;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The abstract base class from which the classes <code>Row</code>
|
||||
* The class <code>BaseRow</code> stores
|
||||
* a row's original values as an array of <code>Object</code>
|
||||
* values, which can be retrieved with the method <code>getOrigRow</code>.
|
||||
* This class also provides methods for getting and setting individual
|
||||
* values in the row.
|
||||
* <P>
|
||||
* A row's original values are the values it contained before it was last
|
||||
* modified. For example, when the <code>CachedRowSet</code>method
|
||||
* <code>acceptChanges</code> is called, it will reset a row's original
|
||||
* values to be the row's current values. Then, when the row is modified,
|
||||
* the values that were previously the current values will become the row's
|
||||
* original values (the values the row had immediately before it was modified).
|
||||
* If a row has not been modified, its original values are its initial values.
|
||||
* <P>
|
||||
* Subclasses of this class contain more specific details, such as
|
||||
* the conditions under which an exception is thrown or the bounds for
|
||||
* index parameters.
|
||||
*/
|
||||
public abstract class BaseRow implements Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* Specify the serialVersionUID
|
||||
*/
|
||||
private static final long serialVersionUID = 4152013523511412238L;
|
||||
|
||||
/**
|
||||
* The array containing the original values for this <code>BaseRow</code>
|
||||
* object.
|
||||
* @serial
|
||||
*/
|
||||
@SuppressWarnings("serial") // Array component type is not Serializable
|
||||
protected Object[] origVals;
|
||||
|
||||
/**
|
||||
* Retrieves the values that this row contained immediately
|
||||
* prior to its last modification.
|
||||
*
|
||||
* @return an array of <code>Object</code> values containing this row's
|
||||
* original values
|
||||
*/
|
||||
public Object[] getOrigRow() {
|
||||
Object[] origRow = this.origVals;
|
||||
return (origRow == null) ? null: Arrays.copyOf(origRow, origRow.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the array element at the given index, which is
|
||||
* the original value of column number <i>idx</i> in this row.
|
||||
*
|
||||
* @param idx the index of the element to return
|
||||
* @return the <code>Object</code> value at the given index into this
|
||||
* row's array of original values
|
||||
* @throws SQLException if there is an error
|
||||
*/
|
||||
public abstract Object getColumnObject(int idx) throws SQLException;
|
||||
|
||||
/**
|
||||
* Sets the element at the given index into this row's array of
|
||||
* original values to the given value. Implementations of the classes
|
||||
* <code>Row</code> and determine what happens
|
||||
* when the cursor is on the insert row and when it is on any other row.
|
||||
*
|
||||
* @param idx the index of the element to be set
|
||||
* @param obj the <code>Object</code> to which the element at index
|
||||
* <code>idx</code> to be set
|
||||
* @throws SQLException if there is an error
|
||||
*/
|
||||
public abstract void setColumnObject(int idx, Object obj) throws SQLException;
|
||||
}
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2011, 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 com.sun.rowset.internal;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import javax.naming.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import com.sun.rowset.*;
|
||||
import javax.sql.rowset.*;
|
||||
import javax.sql.rowset.spi.*;
|
||||
|
||||
/**
|
||||
* The facility called by the <code>RIOptimisticProvider</code> object
|
||||
* internally to read data into it. The calling <code>RowSet</code> object
|
||||
* must have implemented the <code>RowSetInternal</code> interface
|
||||
* and have the standard <code>CachedRowSetReader</code> object set as its
|
||||
* reader.
|
||||
* <P>
|
||||
* This implementation always reads all rows of the data source,
|
||||
* and it assumes that the <code>command</code> property for the caller
|
||||
* is set with a query that is appropriate for execution by a
|
||||
* <code>PreparedStatement</code> object.
|
||||
* <P>
|
||||
* Typically the <code>SyncFactory</code> manages the <code>RowSetReader</code> and
|
||||
* the <code>RowSetWriter</code> implementations using <code>SyncProvider</code> objects.
|
||||
* Standard JDBC RowSet implementations provide an object instance of this
|
||||
* reader by invoking the <code>SyncProvider.getRowSetReader()</code> method.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @see javax.sql.rowset.spi.SyncProvider
|
||||
* @see javax.sql.rowset.spi.SyncFactory
|
||||
* @see javax.sql.rowset.spi.SyncFactoryException
|
||||
*/
|
||||
public class CachedRowSetReader implements RowSetReader, Serializable {
|
||||
|
||||
/**
|
||||
* The field that keeps track of whether the writer associated with
|
||||
* this <code>CachedRowSetReader</code> object's rowset has been called since
|
||||
* the rowset was populated.
|
||||
* <P>
|
||||
* When this <code>CachedRowSetReader</code> object reads data into
|
||||
* its rowset, it sets the field <code>writerCalls</code> to 0.
|
||||
* When the writer associated with the rowset is called to write
|
||||
* data back to the underlying data source, its <code>writeData</code>
|
||||
* method calls the method <code>CachedRowSetReader.reset</code>,
|
||||
* which increments <code>writerCalls</code> and returns <code>true</code>
|
||||
* if <code>writerCalls</code> is 1. Thus, <code>writerCalls</code> equals
|
||||
* 1 after the first call to <code>writeData</code> that occurs
|
||||
* after the rowset has had data read into it.
|
||||
*
|
||||
* @serial
|
||||
*/
|
||||
private int writerCalls = 0;
|
||||
|
||||
private boolean userCon = false;
|
||||
|
||||
private int startPosition;
|
||||
|
||||
private JdbcRowSetResourceBundle resBundle;
|
||||
|
||||
public CachedRowSetReader() {
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads data from a data source and populates the given
|
||||
* <code>RowSet</code> object with that data.
|
||||
* This method is called by the rowset internally when
|
||||
* the application invokes the method <code>execute</code>
|
||||
* to read a new set of rows.
|
||||
* <P>
|
||||
* After clearing the rowset of its contents, if any, and setting
|
||||
* the number of writer calls to <code>0</code>, this reader calls
|
||||
* its <code>connect</code> method to make
|
||||
* a connection to the rowset's data source. Depending on which
|
||||
* of the rowset's properties have been set, the <code>connect</code>
|
||||
* method will use a <code>DataSource</code> object or the
|
||||
* <code>DriverManager</code> facility to make a connection to the
|
||||
* data source.
|
||||
* <P>
|
||||
* Once the connection to the data source is made, this reader
|
||||
* executes the query in the calling <code>CachedRowSet</code> object's
|
||||
* <code>command</code> property. Then it calls the rowset's
|
||||
* <code>populate</code> method, which reads data from the
|
||||
* <code>ResultSet</code> object produced by executing the rowset's
|
||||
* command. The rowset is then populated with this data.
|
||||
* <P>
|
||||
* This method's final act is to close the connection it made, thus
|
||||
* leaving the rowset disconnected from its data source.
|
||||
*
|
||||
* @param caller a <code>RowSet</code> object that has implemented
|
||||
* the <code>RowSetInternal</code> interface and had
|
||||
* this <code>CachedRowSetReader</code> object set as
|
||||
* its reader
|
||||
* @throws SQLException if there is a database access error, there is a
|
||||
* problem making the connection, or the command property has not
|
||||
* been set
|
||||
*/
|
||||
public void readData(RowSetInternal caller) throws SQLException
|
||||
{
|
||||
Connection con = null;
|
||||
try {
|
||||
CachedRowSet crs = (CachedRowSet)caller;
|
||||
|
||||
// Get rid of the current contents of the rowset.
|
||||
|
||||
/**
|
||||
* Checking added to verify whether page size has been set or not.
|
||||
* If set then do not close the object as certain parameters need
|
||||
* to be maintained.
|
||||
*/
|
||||
|
||||
if(crs.getPageSize() == 0 && crs.size() >0 ) {
|
||||
// When page size is not set,
|
||||
// crs.size() will show the total no of rows.
|
||||
crs.close();
|
||||
}
|
||||
|
||||
writerCalls = 0;
|
||||
|
||||
// Get a connection. This reader assumes that the necessary
|
||||
// properties have been set on the caller to let it supply a
|
||||
// connection.
|
||||
userCon = false;
|
||||
|
||||
con = this.connect(caller);
|
||||
|
||||
// Check our assumptions.
|
||||
if (con == null || crs.getCommand() == null)
|
||||
throw new SQLException(resBundle.handleGetObject("crsreader.connecterr").toString());
|
||||
|
||||
try {
|
||||
con.setTransactionIsolation(crs.getTransactionIsolation());
|
||||
} catch (Exception ex) {
|
||||
;
|
||||
}
|
||||
// Use JDBC to read the data.
|
||||
PreparedStatement pstmt = con.prepareStatement(crs.getCommand());
|
||||
// Pass any input parameters to JDBC.
|
||||
|
||||
decodeParams(caller.getParams(), pstmt);
|
||||
try {
|
||||
pstmt.setMaxRows(crs.getMaxRows());
|
||||
pstmt.setMaxFieldSize(crs.getMaxFieldSize());
|
||||
pstmt.setEscapeProcessing(crs.getEscapeProcessing());
|
||||
pstmt.setQueryTimeout(crs.getQueryTimeout());
|
||||
} catch (Exception ex) {
|
||||
/*
|
||||
* drivers may not support the above - esp. older
|
||||
* drivers being used by the bridge..
|
||||
*/
|
||||
throw new SQLException(ex.getMessage());
|
||||
}
|
||||
|
||||
if(crs.getCommand().toLowerCase().indexOf("select") != -1) {
|
||||
// can be (crs.getCommand()).indexOf("select")) == 0
|
||||
// because we will be getting resultset when
|
||||
// it may be the case that some false select query with
|
||||
// select coming in between instead of first.
|
||||
|
||||
// if ((crs.getCommand()).indexOf("?")) does not return -1
|
||||
// implies a Prepared Statement like query exists.
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
if(crs.getPageSize() == 0){
|
||||
crs.populate(rs);
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* If page size has been set then create a ResultSet object that is scrollable using a
|
||||
* PreparedStatement handle.Also call the populate(ResultSet,int) function to populate
|
||||
* a page of data as specified by the page size.
|
||||
*/
|
||||
pstmt = con.prepareStatement(crs.getCommand(),ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
|
||||
decodeParams(caller.getParams(), pstmt);
|
||||
try {
|
||||
pstmt.setMaxRows(crs.getMaxRows());
|
||||
pstmt.setMaxFieldSize(crs.getMaxFieldSize());
|
||||
pstmt.setEscapeProcessing(crs.getEscapeProcessing());
|
||||
pstmt.setQueryTimeout(crs.getQueryTimeout());
|
||||
} catch (Exception ex) {
|
||||
/*
|
||||
* drivers may not support the above - esp. older
|
||||
* drivers being used by the bridge..
|
||||
*/
|
||||
throw new SQLException(ex.getMessage());
|
||||
}
|
||||
rs = pstmt.executeQuery();
|
||||
crs.populate(rs,startPosition);
|
||||
}
|
||||
rs.close();
|
||||
} else {
|
||||
pstmt.executeUpdate();
|
||||
}
|
||||
|
||||
// Get the data.
|
||||
pstmt.close();
|
||||
try {
|
||||
con.commit();
|
||||
} catch (SQLException ex) {
|
||||
;
|
||||
}
|
||||
// only close connections we created...
|
||||
if (getCloseConnection() == true)
|
||||
con.close();
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
// Throw an exception if reading fails for any reason.
|
||||
throw ex;
|
||||
} finally {
|
||||
try {
|
||||
// only close connections we created...
|
||||
if (con != null && getCloseConnection() == true) {
|
||||
try {
|
||||
if (!con.getAutoCommit()) {
|
||||
con.rollback();
|
||||
}
|
||||
} catch (Exception dummy) {
|
||||
/*
|
||||
* not an error condition, we're closing anyway, but
|
||||
* we'd like to clean up any locks if we can since
|
||||
* it is not clear the connection pool will clean
|
||||
* these connections in a timely manner
|
||||
*/
|
||||
}
|
||||
con.close();
|
||||
con = null;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
// will get exception if something already went wrong, but don't
|
||||
// override that exception with this one
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the writer associated with this reader needs
|
||||
* to reset its state. The writer will need to initialize its state
|
||||
* if new contents have been read since the writer was last called.
|
||||
* This method is called by the writer that was registered with
|
||||
* this reader when components were being wired together.
|
||||
*
|
||||
* @return <code>true</code> if writer associated with this reader needs
|
||||
* to reset the values of its fields; <code>false</code> otherwise
|
||||
* @throws SQLException if an access error occurs
|
||||
*/
|
||||
public boolean reset() throws SQLException {
|
||||
writerCalls++;
|
||||
return writerCalls == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Establishes a connection with the data source for the given
|
||||
* <code>RowSet</code> object. If the rowset's <code>dataSourceName</code>
|
||||
* property has been set, this method uses the JNDI API to retrieve the
|
||||
* <code>DataSource</code> object that it can use to make the connection.
|
||||
* If the url, username, and password properties have been set, this
|
||||
* method uses the <code>DriverManager.getConnection</code> method to
|
||||
* make the connection.
|
||||
* <P>
|
||||
* This method is used internally by the reader and writer associated with
|
||||
* the calling <code>RowSet</code> object; an application never calls it
|
||||
* directly.
|
||||
*
|
||||
* @param caller a <code>RowSet</code> object that has implemented
|
||||
* the <code>RowSetInternal</code> interface and had
|
||||
* this <code>CachedRowSetReader</code> object set as
|
||||
* its reader
|
||||
* @return a <code>Connection</code> object that represents a connection
|
||||
* to the caller's data source
|
||||
* @throws SQLException if an access error occurs
|
||||
*/
|
||||
public Connection connect(RowSetInternal caller) throws SQLException {
|
||||
|
||||
// Get a JDBC connection.
|
||||
if (caller.getConnection() != null) {
|
||||
// A connection was passed to execute(), so use it.
|
||||
// As we are using a connection the user gave us we
|
||||
// won't close it.
|
||||
userCon = true;
|
||||
return caller.getConnection();
|
||||
}
|
||||
else if (((RowSet)caller).getDataSourceName() != null) {
|
||||
// Connect using JNDI.
|
||||
try {
|
||||
Context ctx = new InitialContext();
|
||||
DataSource ds = (DataSource)ctx.lookup
|
||||
(((RowSet)caller).getDataSourceName());
|
||||
|
||||
// Check for username, password,
|
||||
// if it exists try getting a Connection handle through them
|
||||
// else try without these
|
||||
// else throw SQLException
|
||||
|
||||
if(((RowSet)caller).getUsername() != null) {
|
||||
return ds.getConnection(((RowSet)caller).getUsername(),
|
||||
((RowSet)caller).getPassword());
|
||||
} else {
|
||||
return ds.getConnection();
|
||||
}
|
||||
}
|
||||
catch (javax.naming.NamingException ex) {
|
||||
SQLException sqlEx = new SQLException(resBundle.handleGetObject("crsreader.connect").toString());
|
||||
sqlEx.initCause(ex);
|
||||
throw sqlEx;
|
||||
}
|
||||
} else if (((RowSet)caller).getUrl() != null) {
|
||||
// Connect using the driver manager.
|
||||
return DriverManager.getConnection(((RowSet)caller).getUrl(),
|
||||
((RowSet)caller).getUsername(),
|
||||
((RowSet)caller).getPassword());
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameter placeholders
|
||||
* in the rowset's command (the given <code>PreparedStatement</code>
|
||||
* object) with the parameters in the given array.
|
||||
* This method, called internally by the method
|
||||
* <code>CachedRowSetReader.readData</code>, reads each parameter, and
|
||||
* based on its type, determines the correct
|
||||
* <code>PreparedStatement.setXXX</code> method to use for setting
|
||||
* that parameter.
|
||||
*
|
||||
* @param params an array of parameters to be used with the given
|
||||
* <code>PreparedStatement</code> object
|
||||
* @param pstmt the <code>PreparedStatement</code> object that is the
|
||||
* command for the calling rowset and into which
|
||||
* the given parameters are to be set
|
||||
* @throws SQLException if an access error occurs
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private void decodeParams(Object[] params,
|
||||
PreparedStatement pstmt) throws SQLException {
|
||||
// There is a corresponding decodeParams in JdbcRowSetImpl
|
||||
// which does the same as this method. This is a design flaw.
|
||||
// Update the JdbcRowSetImpl.decodeParams when you update
|
||||
// this method.
|
||||
|
||||
// Adding the same comments to JdbcRowSetImpl.decodeParams.
|
||||
|
||||
int arraySize;
|
||||
Object[] param = null;
|
||||
|
||||
for (int i=0; i < params.length; i++) {
|
||||
if (params[i] instanceof Object[]) {
|
||||
param = (Object[])params[i];
|
||||
|
||||
if (param.length == 2) {
|
||||
if (param[0] == null) {
|
||||
pstmt.setNull(i + 1, ((Integer)param[1]).intValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param[0] instanceof java.sql.Date ||
|
||||
param[0] instanceof java.sql.Time ||
|
||||
param[0] instanceof java.sql.Timestamp) {
|
||||
System.err.println(resBundle.handleGetObject("crsreader.datedetected").toString());
|
||||
if (param[1] instanceof java.util.Calendar) {
|
||||
System.err.println(resBundle.handleGetObject("crsreader.caldetected").toString());
|
||||
pstmt.setDate(i + 1, (java.sql.Date)param[0],
|
||||
(java.util.Calendar)param[1]);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
throw new SQLException(resBundle.handleGetObject("crsreader.paramtype").toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (param[0] instanceof Reader) {
|
||||
pstmt.setCharacterStream(i + 1, (Reader)param[0],
|
||||
((Integer)param[1]).intValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* What's left should be setObject(int, Object, scale)
|
||||
*/
|
||||
if (param[1] instanceof Integer) {
|
||||
pstmt.setObject(i + 1, param[0], ((Integer)param[1]).intValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (param.length == 3) {
|
||||
|
||||
if (param[0] == null) {
|
||||
pstmt.setNull(i + 1, ((Integer)param[1]).intValue(),
|
||||
(String)param[2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (param[0] instanceof java.io.InputStream) {
|
||||
switch (((Integer)param[2]).intValue()) {
|
||||
case CachedRowSetImpl.UNICODE_STREAM_PARAM:
|
||||
pstmt.setUnicodeStream(i + 1,
|
||||
(java.io.InputStream)param[0],
|
||||
((Integer)param[1]).intValue());
|
||||
break;
|
||||
case CachedRowSetImpl.BINARY_STREAM_PARAM:
|
||||
pstmt.setBinaryStream(i + 1,
|
||||
(java.io.InputStream)param[0],
|
||||
((Integer)param[1]).intValue());
|
||||
break;
|
||||
case CachedRowSetImpl.ASCII_STREAM_PARAM:
|
||||
pstmt.setAsciiStream(i + 1,
|
||||
(java.io.InputStream)param[0],
|
||||
((Integer)param[1]).intValue());
|
||||
break;
|
||||
default:
|
||||
throw new SQLException(resBundle.handleGetObject("crsreader.paramtype").toString());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* no point at looking at the first element now;
|
||||
* what's left must be the setObject() cases.
|
||||
*/
|
||||
if (param[1] instanceof Integer && param[2] instanceof Integer) {
|
||||
pstmt.setObject(i + 1, param[0], ((Integer)param[1]).intValue(),
|
||||
((Integer)param[2]).intValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new SQLException(resBundle.handleGetObject("crsreader.paramtype").toString());
|
||||
|
||||
} else {
|
||||
// common case - this catches all SQL92 types
|
||||
pstmt.setObject(i + 1, params[i]);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Try to get all the params to be set here
|
||||
pstmt.setObject(i + 1, params[i]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assists in determining whether the current connection was created by this
|
||||
* CachedRowSet to ensure incorrect connections are not prematurely terminated.
|
||||
*
|
||||
* @return a boolean giving the status of whether the connection has been closed.
|
||||
*/
|
||||
protected boolean getCloseConnection() {
|
||||
if (userCon == true)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets the start position in the ResultSet from where to begin. This is
|
||||
* called by the Reader in the CachedRowSetImpl to set the position on the page
|
||||
* to begin populating from.
|
||||
* @param pos integer indicating the position in the <code>ResultSet</code> to begin
|
||||
* populating from.
|
||||
*/
|
||||
public void setStartPosition(int pos){
|
||||
startPosition = pos;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Default state initialization happens here
|
||||
ois.defaultReadObject();
|
||||
// Initialization of Res Bundle happens here .
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final long serialVersionUID =5049738185801363801L;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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 com.sun.rowset.internal;
|
||||
|
||||
import com.sun.rowset.JdbcRowSetResourceBundle;
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A class used internally to manage a <code>CachedRowSet</code> object's
|
||||
* insert row. This class keeps track of the number of columns in the
|
||||
* insert row and which columns have had a value inserted. It provides
|
||||
* methods for retrieving a column value, setting a column value, and finding
|
||||
* out whether the insert row is complete.
|
||||
*/
|
||||
public class InsertRow extends BaseRow implements Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* An internal <code>BitSet</code> object used to keep track of the
|
||||
* columns in this <code>InsertRow</code> object that have had a value
|
||||
* inserted.
|
||||
*/
|
||||
private BitSet colsInserted;
|
||||
|
||||
/**
|
||||
* The number of columns in this <code>InsertRow</code> object.
|
||||
*/
|
||||
private int cols;
|
||||
|
||||
private JdbcRowSetResourceBundle resBundle;
|
||||
|
||||
/**
|
||||
* Creates an <code>InsertRow</code> object initialized with the
|
||||
* given number of columns, an array for keeping track of the
|
||||
* original values in this insert row, and a
|
||||
* <code>BitSet</code> object with the same number of bits as
|
||||
* there are columns.
|
||||
*
|
||||
* @param numCols an <code>int</code> indicating the number of columns
|
||||
* in this <code>InsertRow</code> object
|
||||
*/
|
||||
public InsertRow(int numCols) {
|
||||
origVals = new Object[numCols];
|
||||
colsInserted = new BitSet(numCols);
|
||||
cols = numCols;
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bit in this <code>InsertRow</code> object's internal
|
||||
* <code>BitSet</code> object that corresponds to the specified column
|
||||
* in this <code>InsertRow</code> object. Setting a bit indicates
|
||||
* that a value has been set.
|
||||
*
|
||||
* @param col the number of the column to be marked as inserted;
|
||||
* the first column is <code>1</code>
|
||||
*/
|
||||
protected void markColInserted(int col) {
|
||||
colsInserted.set(col);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this <code>InsertRow</code> object has a value
|
||||
* for every column that cannot be null.
|
||||
* @param RowSetMD the <code>RowSetMetaData</code> object for the
|
||||
* <code>CachedRowSet</code> object that maintains this
|
||||
* <code>InsertRow</code> object
|
||||
* @return <code>true</code> if this <code>InsertRow</code> object is
|
||||
* complete; <code>false</code> otherwise
|
||||
* @throws SQLException if there is an error accessing data
|
||||
*/
|
||||
public boolean isCompleteRow(RowSetMetaData RowSetMD) throws SQLException {
|
||||
for (int i = 0; i < cols; i++) {
|
||||
if (colsInserted.get(i) == false &&
|
||||
RowSetMD.isNullable(i + 1) ==
|
||||
ResultSetMetaData.columnNoNulls) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all the bits in the internal <code>BitSet</code> object
|
||||
* maintained by this <code>InsertRow</code> object. Clearing all the bits
|
||||
* indicates that none of the columns have had a value inserted.
|
||||
*/
|
||||
public void initInsertRow() {
|
||||
for (int i = 0; i < cols; i++) {
|
||||
colsInserted.clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of the designated column in this
|
||||
* <code>InsertRow</code> object. If no value has been inserted
|
||||
* into the designated column, this method throws an
|
||||
* <code>SQLException</code>.
|
||||
*
|
||||
* @param idx the column number of the value to be retrieved;
|
||||
* the first column is <code>1</code>
|
||||
* @throws SQLException if no value has been inserted into
|
||||
* the designated column
|
||||
*/
|
||||
public Object getColumnObject(int idx) throws SQLException {
|
||||
if (colsInserted.get(idx - 1) == false) {
|
||||
throw new SQLException(resBundle.handleGetObject("insertrow.novalue").toString());
|
||||
}
|
||||
return (origVals[idx - 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the element in this <code>InsertRow</code> object's
|
||||
* internal array of original values that corresponds to the
|
||||
* designated column with the given value. If the third
|
||||
* argument is <code>true</code>,
|
||||
* which means that the cursor is on the insert row, this
|
||||
* <code>InsertRow</code> object's internal <code>BitSet</code> object
|
||||
* is set so that the bit corresponding to the column being set is
|
||||
* turned on.
|
||||
*
|
||||
* @param idx the number of the column in the insert row to be set;
|
||||
* the first column is <code>1</code>
|
||||
* @param val the value to be set
|
||||
*/
|
||||
public void setColumnObject(int idx, Object val) {
|
||||
origVals[idx - 1] = val;
|
||||
markColInserted(idx - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method re populates the resBundle
|
||||
* during the deserialization process
|
||||
*
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Default state initialization happens here
|
||||
ois.defaultReadObject();
|
||||
// Initialization of transient Res Bundle happens here .
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final long serialVersionUID = 1066099658102869344L;
|
||||
}
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2021, 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 com.sun.rowset.internal;
|
||||
|
||||
import java.sql.*;
|
||||
import java.io.*;
|
||||
import java.lang.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A class that keeps track of a row's values. A <code>Row</code> object
|
||||
* maintains an array of current column values and an array of original
|
||||
* column values, and it provides methods for getting and setting the
|
||||
* value of a column. It also keeps track of which columns have
|
||||
* changed and whether the change was a delete, insert, or update.
|
||||
* <P>
|
||||
* Note that column numbers for rowsets start at <code>1</code>,
|
||||
* whereas the first element of an array or bitset is <code>0</code>.
|
||||
* The argument for the method <code>getColumnUpdated</code> refers to
|
||||
* the column number in the rowset (the first column is <code>1</code>);
|
||||
* the argument for <code>setColumnUpdated</code> refers to the index
|
||||
* into the rowset's internal bitset (the first bit is <code>0</code>).
|
||||
*/
|
||||
public class Row extends BaseRow implements Serializable, Cloneable {
|
||||
|
||||
static final long serialVersionUID = 5047859032611314762L;
|
||||
|
||||
/**
|
||||
* An array containing the current column values for this <code>Row</code>
|
||||
* object.
|
||||
* @serial
|
||||
*/
|
||||
@SuppressWarnings("serial") // Array component type is not Serializable
|
||||
private Object[] currentVals;
|
||||
|
||||
/**
|
||||
* A <code>BitSet</code> object containing a flag for each column in
|
||||
* this <code>Row</code> object, with each flag indicating whether or
|
||||
* not the value in the column has been changed.
|
||||
* @serial
|
||||
*/
|
||||
private BitSet colsChanged;
|
||||
|
||||
/**
|
||||
* A <code>boolean</code> indicating whether or not this <code>Row</code>
|
||||
* object has been deleted. <code>true</code> indicates that it has
|
||||
* been deleted; <code>false</code> indicates that it has not.
|
||||
* @serial
|
||||
*/
|
||||
private boolean deleted;
|
||||
|
||||
/**
|
||||
* A <code>boolean</code> indicating whether or not this <code>Row</code>
|
||||
* object has been updated. <code>true</code> indicates that it has
|
||||
* been updated; <code>false</code> indicates that it has not.
|
||||
* @serial
|
||||
*/
|
||||
private boolean updated;
|
||||
|
||||
/**
|
||||
* A <code>boolean</code> indicating whether or not this <code>Row</code>
|
||||
* object has been inserted. <code>true</code> indicates that it has
|
||||
* been inserted; <code>false</code> indicates that it has not.
|
||||
* @serial
|
||||
*/
|
||||
private boolean inserted;
|
||||
|
||||
/**
|
||||
* The number of columns in this <code>Row</code> object.
|
||||
* @serial
|
||||
*/
|
||||
private int numCols;
|
||||
|
||||
/**
|
||||
* Creates a new <code>Row</code> object with the given number of columns.
|
||||
* The newly-created row includes an array of original values,
|
||||
* an array for storing its current values, and a <code>BitSet</code>
|
||||
* object for keeping track of which column values have been changed.
|
||||
*/
|
||||
public Row(int numCols) {
|
||||
origVals = new Object[numCols];
|
||||
currentVals = new Object[numCols];
|
||||
colsChanged = new BitSet(numCols);
|
||||
this.numCols = numCols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>Row</code> object with the given number of columns
|
||||
* and with its array of original values initialized to the given array.
|
||||
* The new <code>Row</code> object also has an array for storing its
|
||||
* current values and a <code>BitSet</code> object for keeping track
|
||||
* of which column values have been changed.
|
||||
*/
|
||||
public Row(int numCols, Object[] vals) {
|
||||
origVals = new Object[numCols];
|
||||
System.arraycopy(vals, 0, origVals, 0, numCols);
|
||||
currentVals = new Object[numCols];
|
||||
colsChanged = new BitSet(numCols);
|
||||
this.numCols = numCols;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* This method is called internally by the <code>CachedRowSet.populate</code>
|
||||
* methods.
|
||||
*
|
||||
* @param idx the number of the column in this <code>Row</code> object
|
||||
* that is to be set; the index of the first column is
|
||||
* <code>1</code>
|
||||
* @param val the new value to be set
|
||||
*/
|
||||
public void initColumnObject(int idx, Object val) {
|
||||
origVals[idx - 1] = val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* This method is called internally by the <code>CachedRowSet.updateXXX</code>
|
||||
* methods.
|
||||
*
|
||||
* @param idx the number of the column in this <code>Row</code> object
|
||||
* that is to be set; the index of the first column is
|
||||
* <code>1</code>
|
||||
* @param val the new value to be set
|
||||
*/
|
||||
public void setColumnObject(int idx, Object val) {
|
||||
currentVals[idx - 1] = val;
|
||||
setColUpdated(idx - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the column value stored in the designated column of this
|
||||
* <code>Row</code> object.
|
||||
*
|
||||
* @param columnIndex the index of the column value to be retrieved;
|
||||
* the index of the first column is <code>1</code>
|
||||
* @return an <code>Object</code> in the Java programming language that
|
||||
* represents the value stored in the designated column
|
||||
* @throws SQLException if there is a database access error
|
||||
*/
|
||||
public Object getColumnObject(int columnIndex) throws SQLException {
|
||||
if (getColUpdated(columnIndex - 1)) {
|
||||
return(currentVals[columnIndex - 1]); // maps to array!!
|
||||
} else {
|
||||
return(origVals[columnIndex - 1]); // maps to array!!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the designated column of this <code>Row</code> object
|
||||
* has been changed.
|
||||
* @param idx the index into the <code>BitSet</code> object maintained by
|
||||
* this <code>Row</code> object to keep track of which column
|
||||
* values have been modified; the index of the first bit is
|
||||
* <code>0</code>
|
||||
* @return <code>true</code> if the designated column value has been changed;
|
||||
* <code>false</code> otherwise
|
||||
*
|
||||
*/
|
||||
public boolean getColUpdated(int idx) {
|
||||
return colsChanged.get(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this <code>Row</code> object's <code>deleted</code> field
|
||||
* to <code>true</code>.
|
||||
*
|
||||
* @see #getDeleted
|
||||
*/
|
||||
public void setDeleted() { // %%% was public
|
||||
deleted = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the value of this <code>Row</code> object's <code>deleted</code> field,
|
||||
* which will be <code>true</code> if one or more of its columns has been
|
||||
* deleted.
|
||||
* @return <code>true</code> if a column value has been deleted; <code>false</code>
|
||||
* otherwise
|
||||
*
|
||||
* @see #setDeleted
|
||||
*/
|
||||
public boolean getDeleted() {
|
||||
return(deleted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>deleted</code> field for this <code>Row</code> object to
|
||||
* <code>false</code>.
|
||||
*/
|
||||
public void clearDeleted() {
|
||||
deleted = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the value of this <code>Row</code> object's <code>inserted</code> field
|
||||
* to <code>true</code>.
|
||||
*
|
||||
* @see #getInserted
|
||||
*/
|
||||
public void setInserted() {
|
||||
inserted = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the value of this <code>Row</code> object's <code>inserted</code> field,
|
||||
* which will be <code>true</code> if this row has been inserted.
|
||||
* @return <code>true</code> if this row has been inserted; <code>false</code>
|
||||
* otherwise
|
||||
*
|
||||
* @see #setInserted
|
||||
*/
|
||||
public boolean getInserted() {
|
||||
return(inserted);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the <code>inserted</code> field for this <code>Row</code> object to
|
||||
* <code>false</code>.
|
||||
*/
|
||||
public void clearInserted() { // %%% was public
|
||||
inserted = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of this <code>Row</code> object's
|
||||
* <code>updated</code> field.
|
||||
* @return <code>true</code> if this <code>Row</code> object has been
|
||||
* updated; <code>false</code> if it has not
|
||||
*
|
||||
* @see #setUpdated
|
||||
*/
|
||||
public boolean getUpdated() {
|
||||
return(updated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>updated</code> field for this <code>Row</code> object to
|
||||
* <code>true</code> if one or more of its column values has been changed.
|
||||
*
|
||||
* @see #getUpdated
|
||||
*/
|
||||
public void setUpdated() {
|
||||
// only mark something as updated if one or
|
||||
// more of the columns has been changed.
|
||||
for (int i = 0; i < numCols; i++) {
|
||||
if (getColUpdated(i) == true) {
|
||||
updated = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bit at the given index into this <code>Row</code> object's internal
|
||||
* <code>BitSet</code> object, indicating that the corresponding column value
|
||||
* (column <code>idx</code> + 1) has been changed.
|
||||
*
|
||||
* @param idx the index into the <code>BitSet</code> object maintained by
|
||||
* this <code>Row</code> object; the first bit is at index
|
||||
* <code>0</code>
|
||||
*
|
||||
*/
|
||||
private void setColUpdated(int idx) {
|
||||
colsChanged.set(idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>updated</code> field for this <code>Row</code> object to
|
||||
* <code>false</code>, sets all the column values in this <code>Row</code>
|
||||
* object's internal array of current values to <code>null</code>, and clears
|
||||
* all of the bits in the <code>BitSet</code> object maintained by this
|
||||
* <code>Row</code> object.
|
||||
*/
|
||||
public void clearUpdated() {
|
||||
updated = false;
|
||||
for (int i = 0; i < numCols; i++) {
|
||||
currentVals[i] = null;
|
||||
colsChanged.clear(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the column values in this <code>Row</code> object's internal
|
||||
* array of original values with the values in its internal array of
|
||||
* current values, sets all the values in this <code>Row</code>
|
||||
* object's internal array of current values to <code>null</code>,
|
||||
* clears all the bits in this <code>Row</code> object's internal bitset,
|
||||
* and sets its <code>updated</code> field to <code>false</code>.
|
||||
* <P>
|
||||
* This method is called internally by the <code>CachedRowSet</code>
|
||||
* method <code>makeRowOriginal</code>.
|
||||
*/
|
||||
public void moveCurrentToOrig() {
|
||||
for (int i = 0; i < numCols; i++) {
|
||||
if (getColUpdated(i) == true) {
|
||||
origVals[i] = currentVals[i];
|
||||
currentVals[i] = null;
|
||||
colsChanged.clear(i);
|
||||
}
|
||||
}
|
||||
updated = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the row on which the cursor is positioned.
|
||||
*
|
||||
* @return the <code>Row</code> object on which the <code>CachedRowSet</code>
|
||||
* implementation objects's cursor is positioned
|
||||
*/
|
||||
public BaseRow getCurrentRow() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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 com.sun.rowset.internal;
|
||||
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import java.io.*;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import com.sun.rowset.*;
|
||||
import java.text.MessageFormat;
|
||||
import javax.sql.rowset.*;
|
||||
import javax.sql.rowset.spi.*;
|
||||
|
||||
/**
|
||||
* An implementation of the <code>XmlReader</code> interface, which
|
||||
* reads and parses an XML formatted <code>WebRowSet</code> object.
|
||||
* This implementation uses an <code>org.xml.sax.Parser</code> object
|
||||
* as its parser.
|
||||
*/
|
||||
public class WebRowSetXmlReader implements XmlReader, Serializable {
|
||||
|
||||
|
||||
private JdbcRowSetResourceBundle resBundle;
|
||||
|
||||
public WebRowSetXmlReader(){
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given <code>WebRowSet</code> object, getting its input from
|
||||
* the given <code>java.io.Reader</code> object. The parser will send
|
||||
* notifications of parse events to the rowset's
|
||||
* <code>XmlReaderDocHandler</code>, which will build the rowset as
|
||||
* an XML document.
|
||||
* <P>
|
||||
* This method is called internally by the method
|
||||
* <code>WebRowSet.readXml</code>.
|
||||
* <P>
|
||||
* If a parsing error occurs, the exception thrown will include
|
||||
* information for locating 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
|
||||
* the parser will get its input
|
||||
* @exception SQLException if a database access error occurs or
|
||||
* this <code>WebRowSetXmlReader</code> object is not the
|
||||
* reader for the given rowset
|
||||
* @see XmlReaderContentHandler
|
||||
*/
|
||||
public void readXML(WebRowSet caller, java.io.Reader reader) throws SQLException {
|
||||
try {
|
||||
// Crimson Parser(as in J2SE 1.4.1 is NOT able to handle
|
||||
// Reader(s)(FileReader).
|
||||
//
|
||||
// But getting the file as a Stream works fine. So we are going to take
|
||||
// the reader but send it as a InputStream to the parser. Note that this
|
||||
// functionality needs to work against any parser
|
||||
// Crimson(J2SE 1.4.x) / Xerces(J2SE 1.5.x).
|
||||
InputSource is = new InputSource(reader);
|
||||
DefaultHandler dh = new XmlErrorHandler();
|
||||
XmlReaderContentHandler hndr = new XmlReaderContentHandler((RowSet)caller);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
factory.setValidating(true);
|
||||
SAXParser parser = factory.newSAXParser() ;
|
||||
|
||||
parser.setProperty(
|
||||
"http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
|
||||
|
||||
XMLReader reader1 = parser.getXMLReader() ;
|
||||
reader1.setEntityResolver(new XmlResolver());
|
||||
reader1.setContentHandler(hndr);
|
||||
|
||||
reader1.setErrorHandler(dh);
|
||||
|
||||
reader1.parse(is);
|
||||
|
||||
} catch (SAXParseException err) {
|
||||
System.out.println (MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.parseerr").toString(), new Object[]{ err.getMessage (), err.getLineNumber(), err.getSystemId()}));
|
||||
err.printStackTrace();
|
||||
throw new SQLException(err.getMessage());
|
||||
|
||||
} catch (SAXException e) {
|
||||
Exception x = e;
|
||||
if (e.getException () != null)
|
||||
x = e.getException();
|
||||
x.printStackTrace ();
|
||||
throw new SQLException(x.getMessage());
|
||||
|
||||
}
|
||||
|
||||
// Will be here if trying to write beyond the RowSet limits
|
||||
|
||||
catch (ArrayIndexOutOfBoundsException aie) {
|
||||
throw new SQLException(resBundle.handleGetObject("wrsxmlreader.invalidcp").toString());
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.readxml").toString() , e.getMessage()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses the given <code>WebRowSet</code> object, getting its input from
|
||||
* the given <code>java.io.InputStream</code> object. The parser will send
|
||||
* notifications of parse events to the rowset's
|
||||
* <code>XmlReaderDocHandler</code>, which will build the rowset as
|
||||
* an XML document.
|
||||
* <P>
|
||||
* Using streams is a much faster way than using <code>java.io.Reader</code>
|
||||
* <P>
|
||||
* This method is called internally by the method
|
||||
* <code>WebRowSet.readXml</code>.
|
||||
* <P>
|
||||
* If a parsing error occurs, the exception thrown will include
|
||||
* information for locating 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 iStream the <code>java.io.InputStream</code> object from which
|
||||
* the parser will get its input
|
||||
* @throws SQLException if a database access error occurs or
|
||||
* this <code>WebRowSetXmlReader</code> object is not the
|
||||
* reader for the given rowset
|
||||
* @see XmlReaderContentHandler
|
||||
*/
|
||||
public void readXML(WebRowSet caller, java.io.InputStream iStream) throws SQLException {
|
||||
try {
|
||||
InputSource is = new InputSource(iStream);
|
||||
DefaultHandler dh = new XmlErrorHandler();
|
||||
|
||||
XmlReaderContentHandler hndr = new XmlReaderContentHandler((RowSet)caller);
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
factory.setValidating(true);
|
||||
|
||||
SAXParser parser = factory.newSAXParser() ;
|
||||
|
||||
parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
|
||||
"http://www.w3.org/2001/XMLSchema");
|
||||
|
||||
XMLReader reader1 = parser.getXMLReader() ;
|
||||
reader1.setEntityResolver(new XmlResolver());
|
||||
reader1.setContentHandler(hndr);
|
||||
|
||||
reader1.setErrorHandler(dh);
|
||||
|
||||
reader1.parse(is);
|
||||
|
||||
} catch (SAXParseException err) {
|
||||
System.out.println (MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.parseerr").toString(), new Object[]{err.getLineNumber(), err.getSystemId() }));
|
||||
System.out.println(" " + err.getMessage ());
|
||||
err.printStackTrace();
|
||||
throw new SQLException(err.getMessage());
|
||||
|
||||
} catch (SAXException e) {
|
||||
Exception x = e;
|
||||
if (e.getException () != null)
|
||||
x = e.getException();
|
||||
x.printStackTrace ();
|
||||
throw new SQLException(x.getMessage());
|
||||
|
||||
}
|
||||
|
||||
// Will be here if trying to write beyond the RowSet limits
|
||||
|
||||
catch (ArrayIndexOutOfBoundsException aie) {
|
||||
throw new SQLException(resBundle.handleGetObject("wrsxmlreader.invalidcp").toString());
|
||||
}
|
||||
|
||||
catch (Throwable e) {
|
||||
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.readxml").toString() , e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For code coverage purposes only right now
|
||||
*
|
||||
*/
|
||||
|
||||
public void readData(RowSetInternal caller) {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method re populates the resBundle
|
||||
* during the deserialization process
|
||||
*
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Default state initialization happens here
|
||||
ois.defaultReadObject();
|
||||
// Initialization of transient Res Bundle happens here .
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final long serialVersionUID = -9127058392819008014L;
|
||||
}
|
||||
|
|
@ -0,0 +1,680 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2022, 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 com.sun.rowset.internal;
|
||||
|
||||
import com.sun.rowset.JdbcRowSetResourceBundle;
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
import java.io.*;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
|
||||
import javax.sql.rowset.*;
|
||||
import javax.sql.rowset.spi.*;
|
||||
|
||||
/**
|
||||
* An implementation of the {@code XmlWriter} interface, which writes a
|
||||
* {@code WebRowSet} object to an output stream as an XML document.
|
||||
*/
|
||||
|
||||
public class WebRowSetXmlWriter implements XmlWriter, Serializable {
|
||||
|
||||
/**
|
||||
* The {@code java.io.Writer} object to which this {@code WebRowSetXmlWriter}
|
||||
* object will write when its {@code writeXML} method is called. The value
|
||||
* for this field is set with the {@code java.io.Writer} object given
|
||||
* as the second argument to the {@code writeXML} method.
|
||||
*/
|
||||
private transient java.io.Writer writer;
|
||||
|
||||
/**
|
||||
* The {@code java.util.Stack} object that this {@code WebRowSetXmlWriter}
|
||||
* object will use for storing the tags to be used for writing the calling
|
||||
* {@code WebRowSet} object as an XML document.
|
||||
*/
|
||||
private java.util.Stack<String> stack;
|
||||
|
||||
private JdbcRowSetResourceBundle resBundle;
|
||||
|
||||
public WebRowSetXmlWriter() {
|
||||
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given {@code WebRowSet} object as an XML document
|
||||
* using the given {@code java.io.Writer} object. The XML document
|
||||
* will include the {@code WebRowSet} object's data, metadata, and
|
||||
* properties. If a data value has been updated, that information is also
|
||||
* included.
|
||||
* <P>
|
||||
* This method is called by the {@code XmlWriter} object that is
|
||||
* referenced in the calling {@code WebRowSet} object's
|
||||
* {@code xmlWriter} field. The {@code XmlWriter.writeXML}
|
||||
* method passes to this method the arguments that were supplied to it.
|
||||
*
|
||||
* @param caller the {@code WebRowSet} object to be written; must
|
||||
* be a rowset for which this {@code WebRowSetXmlWriter} object
|
||||
* is the writer
|
||||
* @param wrt the {@code java.io.Writer} object to which
|
||||
* {@code caller} will be written
|
||||
* @exception SQLException if a database access error occurs or
|
||||
* this {@code WebRowSetXmlWriter} object is not the writer
|
||||
* for the given rowset
|
||||
* @see XmlWriter#writeXML
|
||||
*/
|
||||
public void writeXML(WebRowSet caller, java.io.Writer wrt)
|
||||
throws SQLException {
|
||||
|
||||
// create a new stack for tag checking.
|
||||
stack = new java.util.Stack<>();
|
||||
writer = wrt;
|
||||
writeRowSet(caller);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given {@code WebRowSet} object as an XML document
|
||||
* using the given {@code java.io.OutputStream} object. The XML document
|
||||
* will include the {@code WebRowSet} object's data, metadata, and
|
||||
* properties. If a data value has been updated, that information is also
|
||||
* included.
|
||||
* <P>
|
||||
* Using stream is a faster way than using {@code java.io.Writer}
|
||||
*
|
||||
* This method is called by the {@code XmlWriter} object that is
|
||||
* referenced in the calling {@code WebRowSet} object's
|
||||
* {@code xmlWriter} field. The {@code XmlWriter.writeXML}
|
||||
* method passes to this method the arguments that were supplied to it.
|
||||
*
|
||||
* @param caller the {@code WebRowSet} object to be written; must
|
||||
* be a rowset for which this {@code WebRowSetXmlWriter} object
|
||||
* is the writer
|
||||
* @param oStream the {@code java.io.OutputStream} object to which
|
||||
* {@code caller} will be written
|
||||
* @throws SQLException if a database access error occurs or
|
||||
* this {@code WebRowSetXmlWriter} object is not the writer
|
||||
* for the given rowset
|
||||
* @see XmlWriter#writeXML
|
||||
*/
|
||||
public void writeXML(WebRowSet caller, java.io.OutputStream oStream)
|
||||
throws SQLException {
|
||||
|
||||
// create a new stack for tag checking.
|
||||
stack = new java.util.Stack<>();
|
||||
writer = new OutputStreamWriter(oStream);
|
||||
writeRowSet(caller);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
private void writeRowSet(WebRowSet caller) throws SQLException {
|
||||
|
||||
try {
|
||||
|
||||
startHeader();
|
||||
|
||||
writeProperties(caller);
|
||||
writeMetaData(caller);
|
||||
writeData(caller);
|
||||
|
||||
endHeader();
|
||||
|
||||
} catch (java.io.IOException ex) {
|
||||
throw new SQLException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.ioex").toString(), ex.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private void startHeader() throws java.io.IOException {
|
||||
|
||||
setTag("webRowSet");
|
||||
writer.write("<?xml version=\"1.0\"?>\n");
|
||||
writer.write("<webRowSet xmlns=\"http://java.sun.com/xml/ns/jdbc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
|
||||
writer.write("xsi:schemaLocation=\"http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd\">\n");
|
||||
}
|
||||
|
||||
private void endHeader() throws java.io.IOException {
|
||||
endTag("webRowSet");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
private void writeProperties(WebRowSet caller) throws java.io.IOException {
|
||||
|
||||
beginSection("properties");
|
||||
|
||||
try {
|
||||
propString("command", processSpecialCharacters(caller.getCommand()));
|
||||
propInteger("concurrency", caller.getConcurrency());
|
||||
propString("datasource", caller.getDataSourceName());
|
||||
propBoolean("escape-processing",
|
||||
caller.getEscapeProcessing());
|
||||
|
||||
try {
|
||||
propInteger("fetch-direction", caller.getFetchDirection());
|
||||
} catch(SQLException sqle) {
|
||||
// it may be the case that fetch direction has not been set
|
||||
// fetchDir == 0
|
||||
// in that case it will throw a SQLException.
|
||||
// To avoid that catch it here
|
||||
}
|
||||
|
||||
propInteger("fetch-size", caller.getFetchSize());
|
||||
propInteger("isolation-level",
|
||||
caller.getTransactionIsolation());
|
||||
|
||||
beginSection("key-columns");
|
||||
|
||||
int[] kc = caller.getKeyColumns();
|
||||
for (int i = 0; kc != null && i < kc.length; i++)
|
||||
propInteger("column", kc[i]);
|
||||
|
||||
endSection("key-columns");
|
||||
|
||||
//Changed to beginSection and endSection for maps for proper indentation
|
||||
beginSection("map");
|
||||
Map<String, Class<?>> typeMap = caller.getTypeMap();
|
||||
if(typeMap != null) {
|
||||
for(Map.Entry<String, Class<?>> mm : typeMap.entrySet()) {
|
||||
propString("type", mm.getKey());
|
||||
propString("class", mm.getValue().getName());
|
||||
}
|
||||
}
|
||||
endSection("map");
|
||||
|
||||
propInteger("max-field-size", caller.getMaxFieldSize());
|
||||
propInteger("max-rows", caller.getMaxRows());
|
||||
propInteger("query-timeout", caller.getQueryTimeout());
|
||||
propBoolean("read-only", caller.isReadOnly());
|
||||
|
||||
int itype = caller.getType();
|
||||
String strType = "";
|
||||
|
||||
if(itype == 1003) {
|
||||
strType = "ResultSet.TYPE_FORWARD_ONLY";
|
||||
} else if(itype == 1004) {
|
||||
strType = "ResultSet.TYPE_SCROLL_INSENSITIVE";
|
||||
} else if(itype == 1005) {
|
||||
strType = "ResultSet.TYPE_SCROLL_SENSITIVE";
|
||||
}
|
||||
|
||||
propString("rowset-type", strType);
|
||||
|
||||
propBoolean("show-deleted", caller.getShowDeleted());
|
||||
propString("table-name", caller.getTableName());
|
||||
propString("url", caller.getUrl());
|
||||
|
||||
beginSection("sync-provider");
|
||||
// Remove the string after "@xxxx"
|
||||
// before writing it to the xml file.
|
||||
String strProviderInstance = (caller.getSyncProvider()).toString();
|
||||
String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf('@'));
|
||||
|
||||
propString("sync-provider-name", strProvider);
|
||||
propString("sync-provider-vendor", "Oracle Corporation");
|
||||
propString("sync-provider-version", "1.0");
|
||||
propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
|
||||
propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
|
||||
|
||||
endSection("sync-provider");
|
||||
|
||||
} catch (SQLException ex) {
|
||||
throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
|
||||
}
|
||||
|
||||
endSection("properties");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
private void writeMetaData(WebRowSet caller) throws java.io.IOException {
|
||||
int columnCount;
|
||||
|
||||
beginSection("metadata");
|
||||
|
||||
try {
|
||||
|
||||
ResultSetMetaData rsmd = caller.getMetaData();
|
||||
columnCount = rsmd.getColumnCount();
|
||||
propInteger("column-count", columnCount);
|
||||
|
||||
for (int colIndex = 1; colIndex <= columnCount; colIndex++) {
|
||||
beginSection("column-definition");
|
||||
|
||||
propInteger("column-index", colIndex);
|
||||
propBoolean("auto-increment", rsmd.isAutoIncrement(colIndex));
|
||||
propBoolean("case-sensitive", rsmd.isCaseSensitive(colIndex));
|
||||
propBoolean("currency", rsmd.isCurrency(colIndex));
|
||||
propInteger("nullable", rsmd.isNullable(colIndex));
|
||||
propBoolean("signed", rsmd.isSigned(colIndex));
|
||||
propBoolean("searchable", rsmd.isSearchable(colIndex));
|
||||
propInteger("column-display-size",rsmd.getColumnDisplaySize(colIndex));
|
||||
propString("column-label", rsmd.getColumnLabel(colIndex));
|
||||
propString("column-name", rsmd.getColumnName(colIndex));
|
||||
propString("schema-name", rsmd.getSchemaName(colIndex));
|
||||
propInteger("column-precision", rsmd.getPrecision(colIndex));
|
||||
propInteger("column-scale", rsmd.getScale(colIndex));
|
||||
propString("table-name", rsmd.getTableName(colIndex));
|
||||
propString("catalog-name", rsmd.getCatalogName(colIndex));
|
||||
propInteger("column-type", rsmd.getColumnType(colIndex));
|
||||
propString("column-type-name", rsmd.getColumnTypeName(colIndex));
|
||||
|
||||
endSection("column-definition");
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
|
||||
}
|
||||
|
||||
endSection("metadata");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @exception SQLException if a database access error occurs
|
||||
*/
|
||||
private void writeData(WebRowSet caller) throws java.io.IOException {
|
||||
ResultSet rs;
|
||||
|
||||
try {
|
||||
ResultSetMetaData rsmd = caller.getMetaData();
|
||||
int columnCount = rsmd.getColumnCount();
|
||||
int i;
|
||||
|
||||
beginSection("data");
|
||||
|
||||
caller.beforeFirst();
|
||||
caller.setShowDeleted(true);
|
||||
while (caller.next()) {
|
||||
if (caller.rowDeleted() && caller.rowInserted()) {
|
||||
beginSection("modifyRow");
|
||||
} else if (caller.rowDeleted()) {
|
||||
beginSection("deleteRow");
|
||||
} else if (caller.rowInserted()) {
|
||||
beginSection("insertRow");
|
||||
} else {
|
||||
beginSection("currentRow");
|
||||
}
|
||||
|
||||
for (i = 1; i <= columnCount; i++) {
|
||||
if (caller.columnUpdated(i)) {
|
||||
rs = caller.getOriginalRow();
|
||||
rs.next();
|
||||
beginTag("columnValue");
|
||||
writeValue(i, (RowSet)rs);
|
||||
endTag("columnValue");
|
||||
beginTag("updateRow");
|
||||
writeValue(i, caller);
|
||||
endTag("updateRow");
|
||||
} else {
|
||||
beginTag("columnValue");
|
||||
writeValue(i, caller);
|
||||
endTag("columnValue");
|
||||
}
|
||||
}
|
||||
|
||||
endSection(); // this is unchecked
|
||||
}
|
||||
endSection("data");
|
||||
} catch (SQLException ex) {
|
||||
throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeValue(int idx, RowSet caller) throws java.io.IOException {
|
||||
try {
|
||||
int type = caller.getMetaData().getColumnType(idx);
|
||||
|
||||
switch (type) {
|
||||
case java.sql.Types.BIT:
|
||||
case java.sql.Types.BOOLEAN:
|
||||
boolean b = caller.getBoolean(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeBoolean(b);
|
||||
break;
|
||||
case java.sql.Types.TINYINT:
|
||||
case java.sql.Types.SMALLINT:
|
||||
short s = caller.getShort(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeShort(s);
|
||||
break;
|
||||
case java.sql.Types.INTEGER:
|
||||
int i = caller.getInt(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeInteger(i);
|
||||
break;
|
||||
case java.sql.Types.BIGINT:
|
||||
long l = caller.getLong(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeLong(l);
|
||||
break;
|
||||
case java.sql.Types.REAL:
|
||||
case java.sql.Types.FLOAT:
|
||||
float f = caller.getFloat(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeFloat(f);
|
||||
break;
|
||||
case java.sql.Types.DOUBLE:
|
||||
double d = caller.getDouble(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeDouble(d);
|
||||
break;
|
||||
case java.sql.Types.NUMERIC:
|
||||
case java.sql.Types.DECIMAL:
|
||||
writeBigDecimal(caller.getBigDecimal(idx));
|
||||
break;
|
||||
case java.sql.Types.BINARY:
|
||||
case java.sql.Types.VARBINARY:
|
||||
case java.sql.Types.LONGVARBINARY:
|
||||
break;
|
||||
case java.sql.Types.DATE:
|
||||
java.sql.Date date = caller.getDate(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeLong(date.getTime());
|
||||
break;
|
||||
case java.sql.Types.TIME:
|
||||
java.sql.Time time = caller.getTime(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeLong(time.getTime());
|
||||
break;
|
||||
case java.sql.Types.TIMESTAMP:
|
||||
java.sql.Timestamp ts = caller.getTimestamp(idx);
|
||||
if (caller.wasNull())
|
||||
writeNull();
|
||||
else
|
||||
writeLong(ts.getTime());
|
||||
break;
|
||||
case java.sql.Types.CHAR:
|
||||
case java.sql.Types.VARCHAR:
|
||||
case java.sql.Types.LONGVARCHAR:
|
||||
writeStringData(caller.getString(idx));
|
||||
break;
|
||||
default:
|
||||
System.out.println(resBundle.handleGetObject("wsrxmlwriter.notproper").toString());
|
||||
//Need to take care of BLOB, CLOB, Array, Ref here
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
throw new java.io.IOException(resBundle.handleGetObject("wrsxmlwriter.failedwrite").toString()+ ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This begins a new tag with a indent
|
||||
*
|
||||
*/
|
||||
private void beginSection(String tag) throws java.io.IOException {
|
||||
// store the current tag
|
||||
setTag(tag);
|
||||
|
||||
writeIndent(stack.size());
|
||||
|
||||
// write it out
|
||||
writer.write("<" + tag + ">\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This closes a tag started by beginTag with a indent
|
||||
*
|
||||
*/
|
||||
private void endSection(String tag) throws java.io.IOException {
|
||||
writeIndent(stack.size());
|
||||
|
||||
String beginTag = getTag();
|
||||
|
||||
if(beginTag.indexOf("webRowSet") != -1) {
|
||||
beginTag ="webRowSet";
|
||||
}
|
||||
|
||||
if (tag.equals(beginTag) ) {
|
||||
// get the current tag and write it out
|
||||
writer.write("</" + beginTag + ">\n");
|
||||
} else {
|
||||
;
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
private void endSection() throws java.io.IOException {
|
||||
writeIndent(stack.size());
|
||||
|
||||
// get the current tag and write it out
|
||||
String beginTag = getTag();
|
||||
writer.write("</" + beginTag + ">\n");
|
||||
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
private void beginTag(String tag) throws java.io.IOException {
|
||||
// store the current tag
|
||||
setTag(tag);
|
||||
|
||||
writeIndent(stack.size());
|
||||
|
||||
// write tag out
|
||||
writer.write("<" + tag + ">");
|
||||
}
|
||||
|
||||
private void endTag(String tag) throws java.io.IOException {
|
||||
String beginTag = getTag();
|
||||
if (tag.equals(beginTag)) {
|
||||
// get the current tag and write it out
|
||||
writer.write("</" + beginTag + ">\n");
|
||||
} else {
|
||||
;
|
||||
}
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
private void emptyTag(String tag) throws java.io.IOException {
|
||||
// write an emptyTag
|
||||
writer.write("<" + tag + "/>");
|
||||
}
|
||||
|
||||
private void setTag(String tag) {
|
||||
// add the tag to stack
|
||||
stack.push(tag);
|
||||
}
|
||||
|
||||
private String getTag() {
|
||||
return stack.pop();
|
||||
}
|
||||
|
||||
private void writeNull() throws java.io.IOException {
|
||||
emptyTag("null");
|
||||
}
|
||||
|
||||
private void writeStringData(String s) throws java.io.IOException {
|
||||
if (s == null) {
|
||||
writeNull();
|
||||
} else if (s.isEmpty()) {
|
||||
writeEmptyString();
|
||||
} else {
|
||||
|
||||
s = processSpecialCharacters(s);
|
||||
|
||||
writer.write(s);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeString(String s) throws java.io.IOException {
|
||||
if (s != null) {
|
||||
writer.write(s);
|
||||
} else {
|
||||
writeNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void writeShort(short s) throws java.io.IOException {
|
||||
writer.write(Short.toString(s));
|
||||
}
|
||||
|
||||
private void writeLong(long l) throws java.io.IOException {
|
||||
writer.write(Long.toString(l));
|
||||
}
|
||||
|
||||
private void writeInteger(int i) throws java.io.IOException {
|
||||
writer.write(Integer.toString(i));
|
||||
}
|
||||
|
||||
private void writeBoolean(boolean b) throws java.io.IOException {
|
||||
writer.write(Boolean.toString(b));
|
||||
}
|
||||
|
||||
private void writeFloat(float f) throws java.io.IOException {
|
||||
writer.write(Float.toString(f));
|
||||
}
|
||||
|
||||
private void writeDouble(double d) throws java.io.IOException {
|
||||
writer.write(Double.toString(d));
|
||||
}
|
||||
|
||||
private void writeBigDecimal(java.math.BigDecimal bd) throws java.io.IOException {
|
||||
if (bd != null)
|
||||
writer.write(bd.toString());
|
||||
else
|
||||
emptyTag("null");
|
||||
}
|
||||
|
||||
private void writeIndent(int tabs) throws java.io.IOException {
|
||||
// indent...
|
||||
for (int i = 1; i < tabs; i++) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void propString(String tag, String s) throws java.io.IOException {
|
||||
beginTag(tag);
|
||||
writeString(s);
|
||||
endTag(tag);
|
||||
}
|
||||
|
||||
private void propInteger(String tag, int i) throws java.io.IOException {
|
||||
beginTag(tag);
|
||||
writeInteger(i);
|
||||
endTag(tag);
|
||||
}
|
||||
|
||||
private void propBoolean(String tag, boolean b) throws java.io.IOException {
|
||||
beginTag(tag);
|
||||
writeBoolean(b);
|
||||
endTag(tag);
|
||||
}
|
||||
|
||||
private void writeEmptyString() throws java.io.IOException {
|
||||
emptyTag("emptyString");
|
||||
}
|
||||
/**
|
||||
* Purely for code coverage purposes..
|
||||
*/
|
||||
public boolean writeData(RowSetInternal caller) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function has been added for the processing of special characters
|
||||
* like <,>,'," and & in the data to be serialized. These have to be taken
|
||||
* of specifically or else there will be parsing error while trying to read
|
||||
* the contents of the XML file.
|
||||
**/
|
||||
|
||||
private String processSpecialCharacters(String s) {
|
||||
|
||||
if(s == null) {
|
||||
return null;
|
||||
}
|
||||
char []charStr = s.toCharArray();
|
||||
String specialStr = "";
|
||||
|
||||
for(int i = 0; i < charStr.length; i++) {
|
||||
if(charStr[i] == '&') {
|
||||
specialStr = specialStr.concat("&");
|
||||
} else if(charStr[i] == '<') {
|
||||
specialStr = specialStr.concat("<");
|
||||
} else if(charStr[i] == '>') {
|
||||
specialStr = specialStr.concat(">");
|
||||
} else if(charStr[i] == '\'') {
|
||||
specialStr = specialStr.concat("'");
|
||||
} else if(charStr[i] == '\"') {
|
||||
specialStr = specialStr.concat(""");
|
||||
} else {
|
||||
specialStr = specialStr.concat(String.valueOf(charStr[i]));
|
||||
}
|
||||
}
|
||||
|
||||
s = specialStr;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method re populates the resBundle
|
||||
* during the deserialization process
|
||||
*
|
||||
*/
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Default state initialization happens here
|
||||
ois.defaultReadObject();
|
||||
// Initialization of transient Res Bundle happens here .
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static final long serialVersionUID = 7163134986189677641L;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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 com.sun.rowset.internal;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import com.sun.rowset.*;
|
||||
import javax.sql.rowset.*;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of the <code>DefaultHandler</code> interface, which
|
||||
* handles all the errors, fatalerrors and warnings while reading the xml file.
|
||||
* This is the ErrorHandler which helps <code>WebRowSetXmlReader</code>
|
||||
* to handle any errors while reading the xml data.
|
||||
*/
|
||||
|
||||
|
||||
public class XmlErrorHandler extends DefaultHandler {
|
||||
public int errorCounter = 0;
|
||||
|
||||
public void error(SAXParseException e) throws SAXException {
|
||||
errorCounter++;
|
||||
|
||||
}
|
||||
|
||||
public void fatalError(SAXParseException e) throws SAXException {
|
||||
errorCounter++;
|
||||
|
||||
}
|
||||
|
||||
public void warning(SAXParseException exception) throws SAXException {
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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 com.sun.rowset.internal;
|
||||
|
||||
import org.xml.sax.*;
|
||||
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* An implementation of the <code>EntityResolver</code> interface, which
|
||||
* reads and parses an XML formatted <code>WebRowSet</code> object.
|
||||
* This is an implementation of org.xml.sax
|
||||
*
|
||||
*/
|
||||
public class XmlResolver implements EntityResolver {
|
||||
|
||||
public InputSource resolveEntity(String publicId, String systemId) {
|
||||
String schemaName = systemId.substring(systemId.lastIndexOf('/'));
|
||||
|
||||
if(systemId.startsWith("http://java.sun.com/xml/ns/jdbc")) {
|
||||
return new InputSource(this.getClass().getResourceAsStream(schemaName));
|
||||
|
||||
} else {
|
||||
// use the default behaviour
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2023, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides five standard implementations of the standard JDBC {@code RowSet} implementation
|
||||
* interface definitions. These reference implementations are included with the J2SE version
|
||||
* 1.5 platform and represent the benchmark standard {@code RowSet} implementations as verified
|
||||
* by the Test Compatibility Kit (TCK) as mandated by the Java Community Process.
|
||||
* <br>
|
||||
*
|
||||
* <h2>1.0 Available JDBC RowSet Reference Implementations </h2>
|
||||
* The following implementations are provided:<br>
|
||||
*
|
||||
* <blockquote><b>{@code JdbcRowSetImpl}</b> - The {@code javax.sql.rowset.JdbcRowSet}
|
||||
* interface reference implementation. <br>
|
||||
* <br>
|
||||
* <b>{@code CachedRowSetImpl}</b> - The {@code javax.sql.rowset.CachedRowSet} interface
|
||||
* reference implementation.<br>
|
||||
* <br>
|
||||
* <b>{@code WebRowSetImpl}</b> - The {@code javax.sql.rowset.WebRowSet} interface
|
||||
* reference implementation.<br>
|
||||
* <br>
|
||||
* <b>{@code FilteredRowSetImpl}</b> - The {@code javax.sql.rowset.FilteredRowSet}
|
||||
* interface reference implementation.<br>
|
||||
* <br>
|
||||
* <b>{@code JoinRowSetImpl}</b> - The {@code javax.sql.rowset.JoinRowSet} interface
|
||||
* reference implementation.<br>
|
||||
* </blockquote>
|
||||
*
|
||||
* All details on their expected behavior, including their interactions with the {@code SyncProvider}
|
||||
* SPI and helper classes are provided in the interface definitions in the {@code javax.sql.rowset}
|
||||
* package specification.<br>
|
||||
*
|
||||
* <h2>2.0 Usage</h2>
|
||||
* The reference implementations represent robust implementations of the standard
|
||||
* {@code RowSet} interfaces defined in the {@code javax.sql.rowset} package.
|
||||
* All disconnected {@code RowSet} implementations, such as the {@code CachedRowSetImpl}
|
||||
* and {@code WebRowSetImpl}, are flexible enough to use the {@code SyncFactory} SPIs to
|
||||
* leverage non-reference implementation {@code SyncProvider} implementations to obtain
|
||||
* differing synchronization semantics. Furthermore, developers and vendors alike are free
|
||||
* to use these implementations and integrate them into their products just as they
|
||||
* can with to other components of the Java platform.<br>
|
||||
*
|
||||
* <h2>3.0 Extending the JDBC RowSet Implementations</h2>
|
||||
*
|
||||
* The JDBC {@code RowSet} reference implementations are provided as non-final
|
||||
* classes so that any developer can extend them to provide additional features
|
||||
* while maintaining the core required standard functionality and compatibility. It
|
||||
* is anticipated that many vendors and developers will extend the standard feature
|
||||
* set to their particular needs. The website for JDBC Technology will
|
||||
* provider a portal where implementations can be listed, similar to the way it
|
||||
* provides a site for JDBC drivers.
|
||||
* @since 1.5
|
||||
*/
|
||||
package com.sun.rowset;
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2022, 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 com.sun.rowset.providers;
|
||||
|
||||
import com.sun.rowset.JdbcRowSetResourceBundle;
|
||||
import javax.sql.*;
|
||||
import java.io.*;
|
||||
|
||||
import javax.sql.rowset.spi.*;
|
||||
import com.sun.rowset.internal.*;
|
||||
|
||||
/**
|
||||
* The reference implementation of a JDBC Rowset synchronization provider
|
||||
* providing optimistic synchronization with a relational datastore
|
||||
* using any JDBC technology-enabled driver.
|
||||
*
|
||||
* <h2>1.0 Background</h2>
|
||||
* This synchronization provider is registered with the
|
||||
* <code>SyncFactory</code> by default as the
|
||||
* <code>com.sun.rowset.providers.RIOptimisticProvider</code>.
|
||||
* As an extension of the <code>SyncProvider</code> abstract
|
||||
* class, it provides the reader and writer classes required by disconnected
|
||||
* rowsets as <code>javax.sql.RowSetReader</code> and <code>javax.sql.RowSetWriter</code>
|
||||
* interface implementations. As a reference implementation,
|
||||
* <code>RIOptimisticProvider</code> provides a
|
||||
* fully functional implementation offering a medium grade classification of
|
||||
* synchronization, namely GRADE_CHECK_MODIFIED_AT_COMMIT. A
|
||||
* disconnected <code>RowSet</code> implementation using the
|
||||
* <code>RIOptimisticProvider</code> can expect the writer to
|
||||
* check only rows that have been modified in the <code>RowSet</code> against
|
||||
* the values in the data source. If there is a conflict, that is, if a value
|
||||
* in the data source has been changed by another party, the
|
||||
* <code>RIOptimisticProvider</code> will not write any of the changes to the data
|
||||
* source and will throw a <code>SyncProviderException</code> object.
|
||||
*
|
||||
* <h2>2.0 Usage</h2>
|
||||
* Standard disconnected <code>RowSet</code> implementations may opt to use this
|
||||
* <code>SyncProvider</code> implementation in one of two ways:
|
||||
* <OL>
|
||||
* <LI>By specifically calling the <code>setSyncProvider</code> method
|
||||
defined in the <code>CachedRowSet</code> interface
|
||||
* <pre>
|
||||
* CachedRowset crs = new FooCachedRowSetImpl();
|
||||
* crs.setSyncProvider("com.sun.rowset.providers.RIOptimisticProvider");
|
||||
* </pre>
|
||||
* <LI>By specifying it in the constructor of the <code>RowSet</code>
|
||||
* implementation
|
||||
* <pre>
|
||||
* CachedRowset crs = new FooCachedRowSetImpl(
|
||||
* "com.sun.rowset.providers.RIOptimisticProvider");
|
||||
* </pre>
|
||||
* </OL>
|
||||
* Note that because the <code>RIOptimisticProvider</code> implementation is
|
||||
* the default provider, it will always be the provider when no provider ID is
|
||||
* specified to the constructor.
|
||||
* <P>
|
||||
* See the standard <code>RowSet</code> reference implementations in the
|
||||
* <code>com.sun.rowset</code> package for more details.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @see javax.sql.rowset.spi.SyncProvider
|
||||
* @see javax.sql.rowset.spi.SyncProviderException
|
||||
* @see javax.sql.rowset.spi.SyncFactory
|
||||
* @see javax.sql.rowset.spi.SyncFactoryException
|
||||
*
|
||||
*/
|
||||
public final class RIOptimisticProvider extends SyncProvider implements Serializable {
|
||||
|
||||
private CachedRowSetReader reader;
|
||||
private CachedRowSetWriter writer;
|
||||
|
||||
/**
|
||||
* The unique provider identifier.
|
||||
*/
|
||||
private String providerID = "com.sun.rowset.providers.RIOptimisticProvider";
|
||||
|
||||
/**
|
||||
* The vendor name of this SyncProvider implementation
|
||||
*/
|
||||
private String vendorName = "Oracle Corporation";
|
||||
|
||||
/**
|
||||
* The version number of this SyncProvider implementation
|
||||
*/
|
||||
private String versionNumber = "1.0";
|
||||
|
||||
/**
|
||||
* ResourceBundle
|
||||
*/
|
||||
private JdbcRowSetResourceBundle resBundle;
|
||||
|
||||
/**
|
||||
* Creates an <code>RIOptimisticProvider</code> object initialized with the
|
||||
* fully qualified class name of this <code>SyncProvider</code> implementation
|
||||
* and a default reader and writer.
|
||||
* <P>
|
||||
* This provider is available to all disconnected <code>RowSet</code> implementations
|
||||
* as the default persistence provider.
|
||||
*/
|
||||
public RIOptimisticProvider() {
|
||||
providerID = this.getClass().getName();
|
||||
reader = new CachedRowSetReader();
|
||||
writer = new CachedRowSetWriter();
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>'javax.sql.rowset.providers.RIOptimisticProvider'</code>
|
||||
* provider identification string.
|
||||
*
|
||||
* @return String Provider ID of this persistence provider
|
||||
*/
|
||||
public String getProviderID() {
|
||||
return providerID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>javax.sql.RowSetWriter</code> object for this
|
||||
* <code>RIOptimisticProvider</code> object. This is the writer that will
|
||||
* write changes made to the <code>Rowset</code> object back to the data source.
|
||||
*
|
||||
* @return the <code>javax.sql.RowSetWriter</code> object for this
|
||||
* <code>RIOptimisticProvider</code> object
|
||||
*/
|
||||
public RowSetWriter getRowSetWriter() {
|
||||
try {
|
||||
writer.setReader(reader);
|
||||
} catch (java.sql.SQLException e) {}
|
||||
return writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>javax.sql.RowSetReader</code> object for this
|
||||
* <code>RIOptimisticProvider</code> object. This is the reader that will
|
||||
* populate a <code>RowSet</code> object using this <code>RIOptimisticProvider</code>.
|
||||
*
|
||||
* @return the <code>javax.sql.RowSetReader</code> object for this
|
||||
* <code>RIOptimisticProvider</code> object
|
||||
*/
|
||||
public RowSetReader getRowSetReader() {
|
||||
return reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>SyncProvider</code> grade of synchronization that
|
||||
* <code>RowSet</code> objects can expect when using this
|
||||
* implementation. As an optimistic synchronization provider, the writer
|
||||
* will only check rows that have been modified in the <code>RowSet</code>
|
||||
* object.
|
||||
*/
|
||||
public int getProviderGrade() {
|
||||
return SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the data source lock severity according to the standard
|
||||
* <code>SyncProvider</code> classifications.
|
||||
*
|
||||
* @param datasource_lock An <code>int</code> indicating the level of locking to be
|
||||
* set; must be one of the following constants:
|
||||
* <PRE>
|
||||
* SyncProvider.DATASOURCE_NO_LOCK,
|
||||
* SyncProvider.DATASOURCE_ROW_LOCK,
|
||||
* SyncProvider.DATASOURCE_TABLE_LOCK,
|
||||
* SyncProvider.DATASOURCE_DB_LOCk
|
||||
* </PRE>
|
||||
* @throws SyncProviderException if the parameter specified is not
|
||||
* <code>SyncProvider.DATASOURCE_NO_LOCK</code>
|
||||
*/
|
||||
public void setDataSourceLock(int datasource_lock) throws SyncProviderException {
|
||||
if(datasource_lock != SyncProvider.DATASOURCE_NO_LOCK ) {
|
||||
throw new SyncProviderException(resBundle.handleGetObject("riop.locking").toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active data source lock severity in this
|
||||
* reference implementation of the <code>SyncProvider</code>
|
||||
* abstract class.
|
||||
*
|
||||
* @return <code>SyncProvider.DATASOURCE_NO_LOCK</code>.
|
||||
* The reference implementation does not support data source locks.
|
||||
*/
|
||||
public int getDataSourceLock() throws SyncProviderException {
|
||||
return SyncProvider.DATASOURCE_NO_LOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the supported updatable view abilities of the
|
||||
* reference implementation of the <code>SyncProvider</code>
|
||||
* abstract class.
|
||||
*
|
||||
* @return <code>SyncProvider.NONUPDATABLE_VIEW_SYNC</code>. The
|
||||
* the reference implementation does not support updating tables
|
||||
* that are the source of a view.
|
||||
*/
|
||||
public int supportsUpdatableView() {
|
||||
return SyncProvider.NONUPDATABLE_VIEW_SYNC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the release version ID of the Reference Implementation Optimistic
|
||||
* Synchronization Provider.
|
||||
*
|
||||
* @return the <code>String</code> detailing the version number of this SyncProvider
|
||||
*/
|
||||
public String getVersion() {
|
||||
return this.versionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vendor name of the Reference Implementation Optimistic
|
||||
* Synchronization Provider
|
||||
*
|
||||
* @return the <code>String</code> detailing the vendor name of this
|
||||
* SyncProvider
|
||||
*/
|
||||
public String getVendor() {
|
||||
return this.vendorName;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
// Default state initialization happens here
|
||||
ois.defaultReadObject();
|
||||
// Initialization of transient Res Bundle happens here .
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
|
||||
}
|
||||
static final long serialVersionUID =-3143367176751761936L;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2022, 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 com.sun.rowset.providers;
|
||||
|
||||
import com.sun.rowset.JdbcRowSetResourceBundle;
|
||||
import java.io.IOException;
|
||||
import java.sql.*;
|
||||
import javax.sql.*;
|
||||
|
||||
import javax.sql.rowset.spi.*;
|
||||
|
||||
/**
|
||||
* A reference implementation of a JDBC RowSet synchronization provider
|
||||
* with the ability to read and write rowsets in well formed XML using the
|
||||
* standard WebRowSet schema.
|
||||
*
|
||||
* <h2>1.0 Background</h2>
|
||||
* This synchronization provider is registered with the
|
||||
* <code>SyncFactory</code> by default as the
|
||||
* <code>com.sun.rowset.providers.RIXMLProvider</code>.
|
||||
* <P>
|
||||
* A <code>WebRowSet</code> object uses an <code>RIXMLProvider</code> implementation
|
||||
* to read an XML data source or to write itself in XML format using the
|
||||
* <code>WebRowSet</code> XML schema definition available at
|
||||
* <pre>
|
||||
* <a href="http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd">http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd</a>
|
||||
* </pre>
|
||||
* The <code>RIXMLProvider</code> implementation has a synchronization level of
|
||||
* GRADE_NONE, which means that it does no checking at all for conflicts. It
|
||||
* simply writes a <code>WebRowSet</code> object to a file.
|
||||
* <h2>2.0 Usage</h2>
|
||||
* A <code>WebRowSet</code> implementation is created with an <code>RIXMLProvider</code>
|
||||
* by default.
|
||||
* <pre>
|
||||
* WebRowSet wrs = new FooWebRowSetImpl();
|
||||
* </pre>
|
||||
* The <code>SyncFactory</code> always provides an instance of
|
||||
* <code>RIOptimisticProvider</code> when no provider is specified,
|
||||
* but the implementation of the default constructor for <code>WebRowSet</code> sets the
|
||||
* provider to be the <code>RIXMLProvider</code> implementation. Therefore,
|
||||
* the following line of code is executed behind the scenes as part of the
|
||||
* implementation of the default constructor.
|
||||
* <pre>
|
||||
* wrs.setSyncProvider("com.sun.rowset.providers.RIXMLProvider");
|
||||
* </pre>
|
||||
* See the standard <code>RowSet</code> reference implementations in the
|
||||
* <code>com.sun.rowset</code> package for more details.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @see javax.sql.rowset.spi.SyncProvider
|
||||
* @see javax.sql.rowset.spi.SyncProviderException
|
||||
* @see javax.sql.rowset.spi.SyncFactory
|
||||
* @see javax.sql.rowset.spi.SyncFactoryException
|
||||
*/
|
||||
public final class RIXMLProvider extends SyncProvider {
|
||||
|
||||
/**
|
||||
* The unique provider identifier.
|
||||
*/
|
||||
private String providerID = "com.sun.rowset.providers.RIXMLProvider";
|
||||
|
||||
/**
|
||||
* The vendor name of this SyncProvider implementation.
|
||||
*/
|
||||
private String vendorName = "Oracle Corporation";
|
||||
|
||||
/**
|
||||
* The version number of this SyncProvider implementation.
|
||||
*/
|
||||
private String versionNumber = "1.0";
|
||||
|
||||
private JdbcRowSetResourceBundle resBundle;
|
||||
|
||||
private XmlReader xmlReader;
|
||||
private XmlWriter xmlWriter;
|
||||
|
||||
/**
|
||||
* This provider is available to all JDBC <code>RowSet</code> implementations as the
|
||||
* default persistence provider.
|
||||
*/
|
||||
public RIXMLProvider() {
|
||||
providerID = this.getClass().getName();
|
||||
try {
|
||||
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
|
||||
} catch(IOException ioe) {
|
||||
throw new RuntimeException(ioe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>"javax.sql.rowset.providers.RIXMLProvider"</code>, which is
|
||||
* the fully qualified class name of this provider implementation.
|
||||
*
|
||||
* @return a <code>String</code> object with the fully specified class name of
|
||||
* this <code>RIOptimisticProvider</code> implementation
|
||||
*/
|
||||
public String getProviderID() {
|
||||
return providerID;
|
||||
}
|
||||
|
||||
// additional methods that sit on top of reader/writer methods back to
|
||||
// original datasource. Allow XML state to be written out and in
|
||||
|
||||
/**
|
||||
* Sets this <code>WebRowSet</code> object's reader to the given
|
||||
* <code>XmlReader</code> object.
|
||||
*
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public void setXmlReader(XmlReader reader) throws SQLException {
|
||||
xmlReader = reader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this <code>WebRowSet</code> object's writer to the given
|
||||
* <code>XmlWriter</code> object.
|
||||
*
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public void setXmlWriter(XmlWriter writer) throws SQLException {
|
||||
xmlWriter = writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the reader that this <code>WebRowSet</code> object
|
||||
* will call when its <code>readXml</code> method is called.
|
||||
*
|
||||
* @return the <code>XmlReader</code> object for this SyncProvider
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public XmlReader getXmlReader() throws SQLException {
|
||||
return xmlReader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the writer that this <code>WebRowSet</code> object
|
||||
* will call when its <code>writeXml</code> method is called.
|
||||
*
|
||||
* @return the <code>XmlWriter</code> for this SyncProvider
|
||||
* @throws SQLException if a database access error occurs
|
||||
*/
|
||||
public XmlWriter getXmlWriter() throws SQLException {
|
||||
return xmlWriter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>SyncProvider</code> grade of syncrhonization that
|
||||
* <code>RowSet</code> object instances can expect when using this
|
||||
* implementation. As this implementation provides no synchronization
|
||||
* facilities to the XML data source, the lowest grade is returned.
|
||||
*
|
||||
* @return the <code>SyncProvider</code> synchronization grade of this
|
||||
* provider; must be one of the following constants:
|
||||
* <PRE>
|
||||
* SyncProvider.GRADE_NONE,
|
||||
* SyncProvider.GRADE_MODIFIED_AT_COMMIT,
|
||||
* SyncProvider.GRADE_CHECK_ALL_AT_COMMIT,
|
||||
* SyncProvider.GRADE_LOCK_WHEN_MODIFIED,
|
||||
* SyncProvider.GRADE_LOCK_WHEN_LOADED
|
||||
* </PRE>
|
||||
*
|
||||
*/
|
||||
public int getProviderGrade() {
|
||||
return SyncProvider.GRADE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default UPDATABLE_VIEW behavior of this reader
|
||||
*
|
||||
*/
|
||||
public int supportsUpdatableView() {
|
||||
return SyncProvider.NONUPDATABLE_VIEW_SYNC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default DATASOURCE_LOCK behavior of this reader
|
||||
*/
|
||||
public int getDataSourceLock() throws SyncProviderException {
|
||||
return SyncProvider.DATASOURCE_NO_LOCK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an unsupported operation exception as this method does
|
||||
* function with non-locking XML data sources.
|
||||
*/
|
||||
public void setDataSourceLock(int lock) throws SyncProviderException {
|
||||
throw new UnsupportedOperationException(resBundle.handleGetObject("rixml.unsupp").toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a null object as RowSetWriters are not returned by this SyncProvider
|
||||
*/
|
||||
public RowSetWriter getRowSetWriter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a null object as RowSetWriter objects are not returned by this
|
||||
* SyncProvider
|
||||
*/
|
||||
public RowSetReader getRowSetReader() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the release version ID of the Reference Implementation Optimistic
|
||||
* Synchronization Provider.
|
||||
*
|
||||
* @return the <code>String</code> detailing the version number of this SyncProvider
|
||||
*/
|
||||
public String getVersion() {
|
||||
return this.versionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vendor name of the Reference Implementation Optimistic
|
||||
* Synchronization Provider
|
||||
*
|
||||
* @return the <code>String</code> detailing the vendor name of this
|
||||
* SyncProvider
|
||||
*/
|
||||
public String getVendor() {
|
||||
return this.vendorName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2023, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Repository for the {@code RowSet} reference implementations of the
|
||||
* {@code SyncProvider} abstract class. These implementations provide a
|
||||
* disconnected {@code RowSet}
|
||||
* object with the ability to synchronize the data in the underlying data
|
||||
* source with its data. These implementations are provided as
|
||||
* the default {@code SyncProvider} implementations and are accessible via the
|
||||
* {@code SyncProvider} SPI managed by the {@code SyncFactory}.
|
||||
*
|
||||
* <h2>1.0 {@code SyncProvider} Reference Implementations</h2>
|
||||
* The main job of a {@code SyncProvider} implementation is to manage
|
||||
* the reader and writer mechanisms.
|
||||
* The {@code SyncProvider} SPI, as specified in the {@code javax.sql.rowset.spi}
|
||||
* package, provides a pluggable mechanism by which {@code javax.sql.RowSetReader}
|
||||
* and {@code javax.sql.RowSetWriter} implementations can be supplied to a disconnected
|
||||
* {@code RowSet} object.
|
||||
* <P>
|
||||
* A reader, a {@code javax.sql.RowSetReader}
|
||||
* object, does the work necessary to populate a {@code RowSet} object with data.
|
||||
* A writer, a {@code javax.sql.RowSetWriter} object, does the work necessary for
|
||||
* synchronizing a {@code RowSet} object's data with the data in the originating
|
||||
* source of data. Put another way, a writer writes a {@code RowSet}
|
||||
* object's data back to the data source.
|
||||
* <P>
|
||||
* Generally speaking, the course of events is this. The reader makes a connection to
|
||||
* the data source and reads the data from a {@code ResultSet} object into its
|
||||
* {@code RowSet} object. Then it closes the connection. While
|
||||
* the {@code RowSet} object is disconnected, an application makes some modifications
|
||||
* to the data and calls the method {@code acceptChanges}. At this point, the
|
||||
* writer is called to write the changes back to the database table or view
|
||||
* from which the original data came. This is called <i>synchronization</i>.
|
||||
* <P>
|
||||
* If the data in the originating data source has not changed, there is no problem
|
||||
* with just writing the {@code RowSet} object's new data to the data source.
|
||||
* If it has changed, however, there is a conflict that needs to be resolved. One
|
||||
* way to solve the problem is not to let the data in the data source be changed in
|
||||
* the first place, which can be done by setting locks on a row, a table, or the
|
||||
* whole data source. Setting locks is a way to avoid conflicts, but it can be
|
||||
* very expensive. Another approach, which is at the other end of the spectrum,
|
||||
* is simply to assume that no conflicts will occur and thus do nothing to avoid
|
||||
* conflicts.
|
||||
* Different {@code SyncProvider} implementations may handle synchronization in
|
||||
* any of these ways, varying from doing no checking for
|
||||
* conflicts, to doing various levels of checking, to guaranteeing that there are no
|
||||
* conflicts.
|
||||
* <P>
|
||||
* The {@code SyncProvider} class offers methods to help a {@code RowSet}
|
||||
* object discover and manage how a provider handles synchronization.
|
||||
* The method {@code getProviderGrade} returns the
|
||||
* grade of synchronization a provider offers. An application can
|
||||
* direct the provider to use a particular level of locking by calling
|
||||
* the method {@code setDataSourceLock} and specifying the level of locking desired.
|
||||
* If a {@code RowSet} object's data came from an SQL {@code VIEW}, an
|
||||
* application may call the method {@code supportsUpdatableView} to
|
||||
* find out whether the {@code VIEW} can be updated.
|
||||
* <P>
|
||||
* Synchronization is done completely behind the scenes, so it is third party vendors of
|
||||
* synchronization provider implementations who have to take care of this complex task.
|
||||
* Application programmers can decide which provider to use and the level of locking to
|
||||
* be done, but they are free from having to worry about the implementation details.
|
||||
* <P>
|
||||
* The JDBC {@code RowSet} Implementations reference implementation provides two
|
||||
* implementations of the {@code SyncProvider} class:
|
||||
*
|
||||
* <UL>
|
||||
* <LI>
|
||||
* <b>{@code RIOptimisticProvider}</b> - provides the {@code javax.sql.RowSetReader}
|
||||
* and {@code javax.sql.RowSetWriter} interface implementations and provides
|
||||
* an optimistic concurrency model for synchronization. This model assumes that there
|
||||
* will be few conflicts and therefore uses a relatively low grade of synchronization.
|
||||
* If no other provider is available, this is the default provider that the
|
||||
* {@code SyncFactory} will supply to a {@code RowSet} object.
|
||||
* <br>
|
||||
* <LI>
|
||||
* <b>{@code RIXMLProvider}</b> - provides the {@code XmlReader} (an extension
|
||||
* of the {@code javax.sql.RowSetReader} interface) and the {@code XmlWriter}
|
||||
* (an extension of the {@code javax.sql.RowSetWriter} interface) to enable
|
||||
* {@code WebRowSet} objects to write their state to a
|
||||
* well formed XML document according to the {@code WebRowSet} XML schema
|
||||
* definition.<br>
|
||||
* </UL>
|
||||
*
|
||||
* <h2>2.0 Basics in RowSet Population & Synchronization</h2>
|
||||
* A rowset's first task is to populate itself with rows of column values.
|
||||
* Generally, these rows will come from a relational database, so a rowset
|
||||
* has properties that supply what is necessary for making a connection to
|
||||
* a database and executing a query. A rowset that does not need to establish
|
||||
* a connection and execute a command, such as one that gets its data from
|
||||
* a tabular file instead of a relational database, does not need to have these
|
||||
* properties set. The vast majority of RowSets, however, do need to set these
|
||||
* properties. The general rule is that a RowSet is required to set only the
|
||||
* properties that it uses.<br>
|
||||
* <br>
|
||||
* The {@code command} property contains the query that determines what
|
||||
* data a {@code RowSet} will contain. Rowsets have methods for setting a query's
|
||||
* parameter(s), which means that a query can be executed multiple times with
|
||||
* different parameters to produce different result sets. Or the query can be
|
||||
* changed to something completely new to get a new result set.
|
||||
* <p>Once a rowset contains the rows from a {@code ResultSet} object or some
|
||||
* other data source, its column values can be updated, and its rows can be
|
||||
* inserted or deleted. Any method that causes a change in the rowset's values
|
||||
* or cursor position also notifies any object that has been registered as
|
||||
* a listener with the rowset. So, for example, a table that displays the rowset's
|
||||
* data in an applet can be notified of changes and make updates as they
|
||||
* occur.<br>
|
||||
* <br>
|
||||
* The changes made to a rowset can be propagated back to the original data
|
||||
* source to keep the rowset and its data source synchronized. Although this
|
||||
* involves many operations behind the scenes, it is completely transparent
|
||||
* to the application programmer and remains the concern of the RowSet provider
|
||||
* developer. All an application has to do is invoke the method {@code acceptChanges},
|
||||
* and the data source backing the rowset will be updated to match the current
|
||||
* values in the rowset. </p>
|
||||
*
|
||||
* <p>A disconnected rowset, such as a {@code CachedRowSet} or {@code WebRowSet}
|
||||
* object, establishes a connection to populate itself with data from a database
|
||||
* and then closes the connection. The {@code RowSet} object will remain
|
||||
* disconnected until it wants to propagate changes back to its database table,
|
||||
* which is optional. To write its changes back to the database (synchronize with
|
||||
* the database), the rowset establishes a connection, write the changes, and then
|
||||
* once again disconnects itself.<br>
|
||||
* </p>
|
||||
*
|
||||
* <h2> 3.0 Other Possible Implementations</h2>
|
||||
* There are many other possible implementations of the {@code SyncProvider} abstract
|
||||
* class. One possibility is to employ a more robust synchronization model, which
|
||||
* would give a {@code RowSet} object increased trust in the provider's
|
||||
* ability to get any updates back to the original data source. Another possibility
|
||||
* is a more formal synchronization mechanism such as SyncML
|
||||
* (<a href="http://www.syncml.org/">http://www.syncml.org/</a>) <br>
|
||||
* @since 1.5
|
||||
*/
|
||||
package com.sun.rowset.providers;
|
||||
4450
src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java
Normal file
4450
src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java
Normal file
File diff suppressed because it is too large
Load diff
1624
src/java.sql.rowset/share/classes/javax/sql/rowset/CachedRowSet.java
Normal file
1624
src/java.sql.rowset/share/classes/javax/sql/rowset/CachedRowSet.java
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2019, 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.
|
||||
*
|
||||
* <h2>1.0 Background</h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* <h2>2.0 Predicate Sharing</h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* <h2>3.0 Usage</h2>
|
||||
* <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.
|
||||
*
|
||||
* <h2>4.0 Updating a <code>FilteredRowSet</code> Object</h2>
|
||||
* 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 an
|
||||
* immediate effect on criterion enforcement within the
|
||||
* <code>FilteredRowSet</code> object, and all subsequent views and updates will be
|
||||
* subject to similar enforcement.
|
||||
*
|
||||
* <h2>5.0 Behavior of Rows Outside the Filter</h2>
|
||||
* 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
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
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() ;
|
||||
}
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2019, 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.
|
||||
*
|
||||
* <h2>1.0 Overview</h2>
|
||||
* 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.
|
||||
*
|
||||
* <h2>2.0 Creating a <code>JdbcRowSet</code> Object</h2>
|
||||
* 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.
|
||||
*
|
||||
* @author Jonathan Bruce
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2019, 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>.
|
||||
*
|
||||
* <h2>1.0 Overview</h2>
|
||||
* 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.
|
||||
*
|
||||
* <h2>2.0 Using a <code>JoinRowSet</code> Object for Creating a <code>JOIN</code></h2>
|
||||
* 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 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>
|
||||
* <h2>3.0 Sample Usage</h2>
|
||||
* <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>.
|
||||
*
|
||||
* <h2>4.0 <code>JoinRowSet</code> Methods</h2>
|
||||
* 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>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
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 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;
|
||||
|
||||
|
||||
}
|
||||
292
src/java.sql.rowset/share/classes/javax/sql/rowset/Joinable.java
Normal file
292
src/java.sql.rowset/share/classes/javax/sql/rowset/Joinable.java
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2019, 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;
|
||||
|
||||
/**
|
||||
* <h2>1.0 Background</h2>
|
||||
* 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>
|
||||
*
|
||||
* <h2>2.0 Usage Guidelines</h2>
|
||||
* <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.
|
||||
*
|
||||
* <h2>3.0 Managing Multiple Match Columns</h2>
|
||||
* 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
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2019, 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.
|
||||
*
|
||||
* <h2>1.0 Background</h2>
|
||||
* 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.
|
||||
*
|
||||
* <h2>2.0 Implementation Guidelines</h2>
|
||||
* 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
|
||||
* @since 1.5
|
||||
*
|
||||
*/
|
||||
|
||||
// <h2>3.0 FilteredRowSet Internals</h2>
|
||||
// internalNext, First, 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;
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 2024, 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;
|
||||
import java.util.ServiceConfigurationError;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* 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 = System.getProperty(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 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 = System.getProperty(ROWSET_FACTORY_NAME);
|
||||
if (factoryClassName != null) {
|
||||
trace("Found system property, value=" + factoryClassName);
|
||||
if (factoryClassName.equals(ROWSET_FACTORY_IMPL)) {
|
||||
return defaultRowSetFactory();
|
||||
}
|
||||
// getFactoryClass takes care of adding the read edge if
|
||||
// necessary
|
||||
@SuppressWarnings("deprecation")
|
||||
Object o = getFactoryClass(factoryClassName, null, false).newInstance();
|
||||
factory = (RowSetFactory) o;
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
return factory == null ? defaultRowSetFactory() : factory;
|
||||
}
|
||||
|
||||
private static RowSetFactory defaultRowSetFactory() {
|
||||
return new com.sun.rowset.RowSetFactoryImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* <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 {
|
||||
// getFactoryClass takes care of adding the read edge if
|
||||
// necessary
|
||||
Class<?> providerClass = getFactoryClass(factoryClassName, cl, false);
|
||||
@SuppressWarnings("deprecation")
|
||||
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.
|
||||
*
|
||||
*/
|
||||
private static ClassLoader getContextClassLoader() {
|
||||
ClassLoader 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
|
||||
*/
|
||||
private static Class<?> getFactoryClass(String factoryClassName, ClassLoader cl,
|
||||
boolean doFallback) throws ClassNotFoundException {
|
||||
Class<?> factoryClass = null;
|
||||
|
||||
try {
|
||||
if (cl == null) {
|
||||
cl = getContextClassLoader();
|
||||
if (cl == null) {
|
||||
throw new ClassNotFoundException();
|
||||
} else {
|
||||
factoryClass = cl.loadClass(factoryClassName);
|
||||
}
|
||||
} else {
|
||||
factoryClass = cl.loadClass(factoryClassName);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (doFallback) {
|
||||
// Use current class loader
|
||||
factoryClass = Class.forName(factoryClassName, true, RowSetFactory.class.getClassLoader());
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return factoryClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the ServiceLoader mechanism to load the default RowSetFactory
|
||||
* @return default RowSetFactory Implementation
|
||||
*/
|
||||
private static 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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2019, 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.
|
||||
*
|
||||
* <h2>1.0 Overview</h2>
|
||||
* 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://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd">http://xmlns.jcp.org/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 interoperability. 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.xsd">http://standards.iso.org/iso/9075/2002/12/sqlxml.xsd</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>
|
||||
*
|
||||
* <h2>2.0 WebRowSet States</h2>
|
||||
* 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.
|
||||
*
|
||||
* <h2>2.1 State 1 - Outputting a {@code WebRowSet} Object to XML</h2>
|
||||
* 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_UNCOMMITTED</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>
|
||||
* <h2>2.2 State 2 - Deleting a Row</h2>
|
||||
* 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>
|
||||
* <h2>2.3 State 3 - Inserting a Row</h2>
|
||||
* 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>
|
||||
* <h2>2.4 State 4 - Modifying a Row</h2>
|
||||
* 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
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
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";
|
||||
}
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 2023, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Standard interfaces and base classes for JDBC {@code RowSet}
|
||||
* implementations. This package contains interfaces and classes
|
||||
* that a standard {@code RowSet} implementation either implements or extends.
|
||||
*
|
||||
* <h2>Table of Contents</h2>
|
||||
* <ul>
|
||||
* <li><a href="#pkgspec">1.0 Package Specification</a>
|
||||
* <li><a href="#stdrowset">2.0 Standard RowSet Definitions</a>
|
||||
* <li><a href="#impl">3.0 Implementer's Guide</a>
|
||||
* <li><a href="#relspec">4.0 Related Specifications</a>
|
||||
* <li><a href="#reldocs">5.0 Related Documentation</a>
|
||||
* </ul>
|
||||
*
|
||||
* <h3><a id="pkgspec">1.0 Package Specification</a></h3>
|
||||
* This package specifies five standard JDBC {@code RowSet} interfaces.
|
||||
* All five extend the
|
||||
* {@link java.sql/javax.sql.RowSet} interface described in the JDBC 3.0
|
||||
* specification. It is anticipated that additional definitions
|
||||
* of more specialized JDBC {@code RowSet} types will emerge as this technology
|
||||
* matures. Future definitions <i>should</i> be specified as subinterfaces using
|
||||
* inheritance similar to the way it is used in this specification.
|
||||
* <p>
|
||||
* <i>Note:</i> The interface definitions provided in this package form the basis for
|
||||
* all compliant JDBC {@code RowSet} implementations. Vendors and more advanced
|
||||
* developers who intend to provide their own compliant {@code RowSet} implementations
|
||||
* should pay particular attention to the assertions detailed in specification
|
||||
* interfaces.
|
||||
*
|
||||
* <h3><a id="stdrowset">2.0 Standard RowSet Definitions</a></h3>
|
||||
* <ul>
|
||||
* <li><a href="JdbcRowSet.html"><b>{@code JdbcRowSet}</b></a> - A wrapper around
|
||||
* a {@code ResultSet} object that makes it possible to use the result set as a
|
||||
* JavaBeans component. Thus,
|
||||
* a {@code JdbcRowSet} object can be a Bean that any tool
|
||||
* makes available for assembling an application as part of a component based
|
||||
* architecture. A {@code JdbcRowSet} object is a connected {@code RowSet}
|
||||
* object, that is, it
|
||||
* <b>must</b> continually maintain its connection to its data source using a JDBC
|
||||
* technology-enabled driver ("JDBC driver"). In addition, a {@code JdbcRowSet}
|
||||
* object provides a fully updatable and scrollable tabular
|
||||
* data structure as defined in the JDBC 3.0 specification.
|
||||
*
|
||||
* <li><a href="CachedRowSet.html">
|
||||
* <b>{@code CachedRowSet}</b></a>
|
||||
* - A {@code CachedRowSet} object is a JavaBeans
|
||||
* component that is scrollable, updatable, serializable, and generally disconnected from
|
||||
* the source of its data. A {@code CachedRowSet} object
|
||||
* typically contains rows from a result set, but it can also contain rows from any
|
||||
* file with a tabular format, such as a spreadsheet. {@code CachedRowSet} implementations
|
||||
* <b>must</b> use the {@code SyncFactory} to manage and obtain pluggable
|
||||
* {@code SyncProvider} objects to provide synchronization between the
|
||||
* disconnected {@code RowSet} object and the originating data source.
|
||||
* Typically a {@code SyncProvider} implementation relies upon a JDBC
|
||||
* driver to obtain connectivity to a particular data source.
|
||||
* Further details on this mechanism are discussed in the <a
|
||||
* href="spi/package-summary.html">{@code javax.sql.rowset.spi}</a> package
|
||||
* specification.
|
||||
*
|
||||
* <li><a href="WebRowSet.html"><b>{@code WebRowSet}</b></a> - A
|
||||
* {@code WebRowSet} object is an extension of {@code CachedRowSet}
|
||||
* that can read and write a {@code RowSet} object in a well formed XML format.
|
||||
* This class calls an <a href="spi/XmlReader.html">{@code XmlReader}</a> object
|
||||
* (an extension of the {@link java.sql/javax.sql.RowSetReader RowSetReader}
|
||||
* interface) to read a rowset in XML format. It calls an
|
||||
* <a href="spi/XmlWriter.html">{@code XmlWriter}</a> object (an extension of the
|
||||
* {@link java.sql/javax.sql.RowSetWriter RowSetWriter} interface)
|
||||
* to write a rowset in XML format. The reader and writer required by
|
||||
* {@code WebRowSet} objects are provided by the
|
||||
* {@code SyncFactory} in the form of {@code SyncProvider}
|
||||
* implementations. In order to ensure well formed XML usage, a standard generic XML
|
||||
* Schema is defined and published at
|
||||
* <a href="http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd">
|
||||
* {@code http://xmlns.jcp.org/xml/ns//jdbc/webrowset.xsd}</a>.
|
||||
*
|
||||
* <li><a href="FilteredRowSet.html"><b>{@code FilteredRowSet}</b></a> - A
|
||||
* {@code FilteredRowSet} object provides filtering functionality in a programmatic
|
||||
* and extensible way. There are many instances when a {@code RowSet} {@code object}
|
||||
* has a need to provide filtering in its contents without sacrificing the disconnected
|
||||
* environment, thus saving the expense of having to create a connection to the data source.
|
||||
* Solutions to this need vary from providing heavyweight full scale
|
||||
* SQL query abilities, to portable components, to more lightweight
|
||||
* approaches. A {@code FilteredRowSet} object consumes
|
||||
* an implementation of the {@link Predicate}
|
||||
* interface, which <b>may</b> define a filter at run time. In turn, a
|
||||
* {@code FilteredRowSet} object is tasked with enforcing the set filter for both
|
||||
* inbound and outbound read and write operations. That is, all filters can be
|
||||
* considered as bi-directional. No standard filters are defined;
|
||||
* however, sufficient mechanics are specified to permit any required filter to be
|
||||
* implemented.
|
||||
*
|
||||
* <li><a href="JoinRowSet.html"><b>{@code JoinRowSet}</b></a> - The {@code JoinRowSet}
|
||||
* interface describes a mechanism by which relationships can be established between
|
||||
* two or more standard {@code RowSet} implementations. Any number of {@code RowSet}
|
||||
* objects can be added to a {@code JoinRowSet} object provided the {@code RowSet}objects
|
||||
* can be related in a SQL {@code JOIN} like fashion. By definition, the SQL {@code JOIN}
|
||||
* statement is used to combine the data contained in two (<i>or more</i>) relational
|
||||
* database tables based upon a common attribute. By establishing and then enforcing
|
||||
* column matches, a {@code JoinRowSet} object establishes relationships between
|
||||
* {@code RowSet} instances without the need to touch the originating data source.
|
||||
* </ul>
|
||||
*
|
||||
* <h3><a id="impl">3.0 Implementer's Guide</a></h3>
|
||||
* Compliant implementations of JDBC {@code RowSet} Implementations
|
||||
* <b>must</b> follow the assertions described in this specification. In accordance
|
||||
* with the terms of the <a href="http://www.jcp.org">Java Community Process</a>, a
|
||||
* Test Compatibility Kit (TCK) can be licensed to ensure compatibility with the
|
||||
* specification. The following paragraphs outline a number of starting points for
|
||||
* implementers of the standard JDBC {@code RowSet} definitions. Implementers
|
||||
* should also consult the <i>Implementer's Guide</i> in the <a
|
||||
* href="spi/package-summary.html">javax.sql.rowset.spi</a> package for guidelines
|
||||
* on <a href="spi/SyncProvider.html">{@code SyncProvider}</a> implementations.
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>3.1 Constructor</b>
|
||||
* <p>
|
||||
* All {@code RowSet} implementations <strong>must</strong> provide a
|
||||
* no-argument constructor.
|
||||
* </li>
|
||||
* <li><b>3.2 Role of the {@code BaseRowSet} Class</b>
|
||||
* <p>
|
||||
* A compliant JDBC {@code RowSet} implementation <b>must</b> implement one or more
|
||||
* standard interfaces specified in this package and <b>may</b> extend the
|
||||
* {@link javax.sql.rowset.BaseRowSet} abstract class. For example, a
|
||||
* {@code CachedRowSet} implementation must implement the {@code CachedRowSet}
|
||||
* interface and extend the {@code BaseRowSet} abstract class. The
|
||||
* {@code BaseRowSet} class provides the standard architecture on which all
|
||||
* {@code RowSet} implementations should be built, regardless of whether the
|
||||
* {@code RowSet} objects exist in a connected or disconnected environment.
|
||||
* The {@code BaseRowSet} abstract class provides any {@code RowSet} implementation
|
||||
* with its base functionality, including property manipulation and event notification
|
||||
* that is fully compliant with
|
||||
* <a href="https://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">JavaBeans</a>
|
||||
* component requirements. As an example, all implementations provided in the
|
||||
* reference implementations (contained in the {@code com.sun.rowset} package) use
|
||||
* the {@code BaseRowSet} class as a basis for their implementations.
|
||||
* <P>
|
||||
* The following table illustrates the features that the {@code BaseRowSet}
|
||||
* abstract class provides.
|
||||
* <blockquote>
|
||||
* <table class="striped" style="vertical-align:top; width:75%">
|
||||
* <caption>Features in {@code BaseRowSet}</caption>
|
||||
* <thead>
|
||||
* <tr>
|
||||
* <th scope="col">Feature</th>
|
||||
* <th scope="col">Details</th>
|
||||
* </tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <th scope="row">Properties</th>
|
||||
* <td>Provides standard JavaBeans property manipulation
|
||||
* mechanisms to allow applications to get and set {@code RowSet} command and
|
||||
* property values. Refer to the documentation of the {@code javax.sql.RowSet}
|
||||
* interface (available in the JDBC 3.0 specification) for more details on
|
||||
* the standard {@code RowSet} properties.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">Event notification</th>
|
||||
* <td>Provides standard JavaBeans event notifications
|
||||
* to registered event listeners. Refer to the documentation of {@code javax.sql.RowSetEvent}
|
||||
* interface (available in the JDBC 3.0 specification) for
|
||||
* more details on how to register and handle standard RowSet events generated
|
||||
* by compliant implementations.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">Setters for a RowSet object's command</th>
|
||||
* <td>Provides a complete set of setter methods
|
||||
* for setting RowSet command parameters.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <th scope="row">Streams</th>
|
||||
* <td>Provides fields for storing of stream instances
|
||||
* in addition to providing a set of constants for stream type designation.</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* </blockquote>
|
||||
*
|
||||
* <li><b>3.3 Connected RowSet Requirements</b>
|
||||
* <p>
|
||||
* The {@code JdbcRowSet} describes a {@code RowSet} object that <b>must</b> always
|
||||
* be connected to the originating data source. Implementations of the {@code JdbcRowSet}
|
||||
* should ensure that this connection is provided solely by a JDBC driver.
|
||||
* Furthermore, {@code RowSet} objects that are implementations of the
|
||||
* {@code JdbcRowSet} interface and are therefore operating in a connected environment
|
||||
* do not use the {@code SyncFactory} to obtain a {@code RowSetReader} object
|
||||
* or a {@code RowSetWriter} object. They can safely rely on the JDBC driver to
|
||||
* supply their needs by virtue of the presence of an underlying updatable and scrollable
|
||||
* {@code ResultSet} implementation.
|
||||
*
|
||||
* <li>
|
||||
* <b>3.4 Disconnected RowSet Requirements</b>
|
||||
* <p>
|
||||
* A disconnected {@code RowSet} object, such as a {@code CachedRowSet} object,
|
||||
* <b>should</b> delegate
|
||||
* connection management to a {@code SyncProvider} object provided by the
|
||||
* {@code SyncFactory}. To ensure fully disconnected semantics, all
|
||||
* disconnected {@code RowSet} objects <b>must</b> ensure
|
||||
* that the original connection made to the data source to populate the {@code RowSet}
|
||||
* object is closed to permit the garbage collector to recover and release resources. The
|
||||
* {@code SyncProvider} object ensures that the critical JDBC properties are
|
||||
* maintained in order to re-establish a connection to the data source when a
|
||||
* synchronization is required. A disconnected {@code RowSet} object should
|
||||
* therefore ensure that no
|
||||
* extraneous references remain on the {@code Connection} object.
|
||||
*
|
||||
* <li><b>3.5 Role of RowSetMetaDataImpl</b>
|
||||
* <p>
|
||||
* The {@code RowsetMetaDataImpl} class is a utility class that provides an implementation of the
|
||||
* {@link java.sql/javax.sql.RowSetMetaData RowSetMetaData} interface, supplying standard setter
|
||||
* method implementations for metadata for both connected and disconnected
|
||||
* {@code RowSet} objects. All implementations are free to use this standard
|
||||
* implementation but are not required to do so.
|
||||
*
|
||||
* <li><b>3.6 RowSetWarning Class</b>
|
||||
* <p>
|
||||
* The {@code RowSetWarning} class provides warnings that can be set
|
||||
* on {@code RowSet} implementations.
|
||||
* Similar to {@link java.sql/java.sql.SQLWarning SQLWarning} objects,
|
||||
* {@code RowSetWarning} objects are silently chained to the object whose method
|
||||
* caused the warning to be thrown. All {@code RowSet} implementations <b>should</b>
|
||||
* ensure that this chaining occurs if a warning is generated and also ensure that the
|
||||
* warnings are available via the {@code getRowSetWarnings} method defined in either
|
||||
* the {@code JdbcRowSet} interface or the {@code CachedRowSet} interface.
|
||||
* After a warning has been retrieved with one of the
|
||||
* {@code getRowSetWarnings} methods, the {@code RowSetWarning} method
|
||||
* {@code getNextWarning} can be called on it to retrieve any warnings that might
|
||||
* be chained on it. If a warning is returned, {@code getNextWarning} can be called
|
||||
* on it, and so on until there are no more warnings.
|
||||
*
|
||||
* <li><b>3.7 The Joinable Interface</b>
|
||||
* <P>
|
||||
* The {@code Joinable} interface provides both connected and disconnected
|
||||
* {@code RowSet} objects with the capability to be added to a
|
||||
* {@code JoinRowSet} object in an SQL {@code JOIN} operation.
|
||||
* A {@code RowSet} object that has implemented the {@code Joinable}
|
||||
* interface can set a match column, retrieve a match column, or unset a match column.
|
||||
* A {@code JoinRowSet} object can then use the {@code RowSet} object's
|
||||
* match column as a basis for adding the {@code RowSet} object.
|
||||
* </li>
|
||||
*
|
||||
* <li><b>3.8 The RowSetFactory Interface</b>
|
||||
* <p>
|
||||
* A {@code RowSetFactory} implementation <strong>must</strong>
|
||||
* be provided.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3><a id="relspec">4.0 Related Specifications</a></h3>
|
||||
* <ul>
|
||||
* <li><a href="https://jcp.org/en/jsr/detail?id=221">JDBC 4.3 Specification</a>
|
||||
* <li><a href="http://www.w3.org/XML/Schema">XML Schema</a>
|
||||
* </ul>
|
||||
*
|
||||
* <h3><a id="reldocs">5.0 Related Documentation</a></h3>
|
||||
* <ul>
|
||||
* <li><a href="http://docs.oracle.com/javase/tutorial/jdbc/basics/rowset.html">
|
||||
* JDBC RowSet Tutorial</a>
|
||||
*</ul>
|
||||
* @since 1.5
|
||||
*/
|
||||
package javax.sql.rowset;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#Default JDBC RowSet sync providers listing
|
||||
#
|
||||
|
||||
# Optimistic synchonriztaion 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
|
||||
|
|
@ -0,0 +1,669 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2024, 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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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 {
|
||||
@SuppressWarnings("deprecation")
|
||||
Object tmp = c.newInstance();
|
||||
obj = (SQLData)tmp;
|
||||
} 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,631 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(ch + 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
String strLine = bufReader.readLine();
|
||||
writeString(ch + 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
String strLine = bufReader.readLine();
|
||||
|
||||
writeString(ch + 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,668 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2020, 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.
|
||||
*
|
||||
* <h2> Thread safety </h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
||||
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 SerialArray} 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param s the {@code ObjectInputStream} to read from.
|
||||
*
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
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.
|
||||
* @param s the {@code ObjectOutputStream} to write to.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException {
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,618 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, 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.
|
||||
*
|
||||
* <h2> Thread safety </h2>
|
||||
*
|
||||
* <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
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @serial The internal representation of the <code>Blob</code> object on which this
|
||||
* <code>SerialBlob</code> object is based.
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable; checked in writeObject
|
||||
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} value that
|
||||
* this {@code Blob} object represents, starting at position
|
||||
* {@code pos}, and returns the number of bytes written.
|
||||
*
|
||||
* @param pos the position in the SQL {@code BLOB} value at which
|
||||
* to start writing. The first position is {@code 1};
|
||||
* must not be less than {@code 1} nor greater than
|
||||
* the length+1 of this {@code SerialBlob} object.
|
||||
* @param bytes the array of bytes to be written to the {@code BLOB}
|
||||
* value that this {@code Blob} object represents
|
||||
* @return the number of bytes written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* {@code BLOB} value; or if an invalid position is set;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @throws SQLException if there is an error accessing the {@code BLOB}
|
||||
* 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} array to the
|
||||
* {@code BLOB} value that this {@code Blob} object represents
|
||||
* and returns the number of bytes written.
|
||||
* Writing starts at position {@code pos} in the {@code BLOB}
|
||||
* value; {@code length} bytes from the given byte array are written.
|
||||
*
|
||||
* @param pos the position in the {@code BLOB} object at which
|
||||
* to start writing. The first position is {@code 1};
|
||||
* must not be less than {@code 1} nor greater than
|
||||
* the length+1 of this {@code SerialBlob} object.
|
||||
* @param bytes the array of bytes to be written to the {@code BLOB}
|
||||
* value
|
||||
* @param offset the offset into the array {@code byte}s at which
|
||||
* to start reading the bytes to be set. The first offset position is
|
||||
* {@code 0}; must not be less than {@code 0} nor greater
|
||||
* than the length of the array {@code byte}s
|
||||
* @param length the number of bytes to be written to the
|
||||
* {@code BLOB} value from the array of bytes {@code byte}s
|
||||
*
|
||||
* @return the number of bytes written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* {@code BLOB} value; if an invalid position is set; if an
|
||||
* invalid offset value is set; or the combined values of the
|
||||
* {@code length} and {@code offset} is greater than the length of
|
||||
* {@code byte}s;
|
||||
* if {@code free} had previously been called on this object
|
||||
* @throws SQLException if there is an error accessing the {@code BLOB}
|
||||
* 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 (length < 0) {
|
||||
throw new SerialException("Invalid arguments: length cannot be "
|
||||
+ "negative");
|
||||
}
|
||||
|
||||
if (pos < 1 || pos > len + 1) {
|
||||
throw new SerialException("Invalid position in BLOB object set");
|
||||
}
|
||||
|
||||
if (length > bytes.length - offset) {
|
||||
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
|
||||
"and length that is greater than the length of bytes");
|
||||
}
|
||||
|
||||
if (pos - 1 + length > Integer.MAX_VALUE) {
|
||||
throw new SerialException("Invalid length. Cannot have combined pos " +
|
||||
"and length that is greater than Integer.MAX_VALUE");
|
||||
}
|
||||
|
||||
pos--; // correct to array indexing
|
||||
if (pos + length > len) {
|
||||
len = pos + length;
|
||||
byte[] newbuf = new byte[(int)len];
|
||||
System.arraycopy(buf, 0, newbuf, 0, (int)pos);
|
||||
buf = newbuf;
|
||||
}
|
||||
System.arraycopy(bytes, offset, buf, (int)pos, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 SerialBlob} 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.
|
||||
* @param s the {@code ObjectInputStream} to read from.
|
||||
*
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
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.
|
||||
* @param s the {@code ObjectOutputStream} to write to.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException {
|
||||
|
||||
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 compatibility
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,709 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, 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.
|
||||
*
|
||||
* <h2> Thread safety </h2>
|
||||
*
|
||||
* <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
|
||||
* @since 1.5
|
||||
*/
|
||||
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[];
|
||||
|
||||
/**
|
||||
* @serial Internal Clob representation if SerialClob is initialized with a
|
||||
* Clob. Null if SerialClob is initialized with a char[].
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable; checked in writeObject
|
||||
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 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} to the {@code CLOB}
|
||||
* value that this {@code SerialClob} object represents, at the position
|
||||
* {@code pos}.
|
||||
*
|
||||
* @param pos the position at which to start writing to the {@code CLOB}
|
||||
* value that this {@code SerialClob} object represents; the first
|
||||
* position is {@code 1}; must not be less than {@code 1} nor
|
||||
* greater than the length+1 of this {@code SerialClob} object
|
||||
* @param str the string to be written to the {@code CLOB}
|
||||
* value that this {@code SerialClob} object represents
|
||||
* @return the number of characters written
|
||||
* @throws SerialException if there is an error accessing the
|
||||
* {@code CLOB} value; if an invalid position is set;
|
||||
* 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} characters of {@code str}, starting
|
||||
* at character {@code offset}, to the {@code CLOB} value
|
||||
* that this {@code Clob} represents.
|
||||
*
|
||||
* @param pos the position at which to start writing to the {@code CLOB}
|
||||
* value that this {@code SerialClob} object represents; the first
|
||||
* position is {@code 1}; must not be less than {@code 1} nor
|
||||
* greater than the length+1 of this {@code SerialClob} object
|
||||
* @param str the string to be written to the {@code CLOB}
|
||||
* value that this {@code Clob} object represents
|
||||
* @param offset the offset into {@code str} 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} value; if an invalid position is set; if an
|
||||
* invalid offset value is set; or the combined values of the
|
||||
* {@code length} and {@code offset} is greater than the length of
|
||||
* {@code str};
|
||||
* 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();
|
||||
if (offset < 0 || offset > str.length()) {
|
||||
throw new SerialException("Invalid offset in String object set");
|
||||
}
|
||||
|
||||
if (length < 0) {
|
||||
throw new SerialException("Invalid arguments: length cannot be "
|
||||
+ "negative");
|
||||
}
|
||||
|
||||
if (pos < 1 || pos > len + 1) {
|
||||
throw new SerialException("Invalid position in Clob object set");
|
||||
}
|
||||
|
||||
if (length > str.length() - offset) {
|
||||
// need check to ensure length + offset !> str.length
|
||||
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
|
||||
" and length that is greater than the length of str");
|
||||
}
|
||||
|
||||
if (pos - 1 + length > Integer.MAX_VALUE) {
|
||||
throw new SerialException("Invalid length. Cannot have combined pos " +
|
||||
"and length that is greater than Integer.MAX_VALUE");
|
||||
}
|
||||
|
||||
pos--; //values in the array are at position one less
|
||||
if (pos + length > len) {
|
||||
len = pos + length;
|
||||
char[] newbuf = new char[(int)len];
|
||||
System.arraycopy(buf, 0, newbuf, 0, (int)pos);
|
||||
buf = newbuf;
|
||||
}
|
||||
|
||||
String temp = str.substring(offset, offset + length);
|
||||
char cPattern[] = temp.toCharArray();
|
||||
System.arraycopy(cPattern, 0, buf, (int)pos, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 SerialClob} 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.
|
||||
* @param s the {@code ObjectInputStream} to read from.
|
||||
*
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
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.
|
||||
* @param s the {@code ObjectOutputStream} to write to.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException {
|
||||
|
||||
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 compatibility
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2022, 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>
|
||||
*
|
||||
* <h2> Thread safety </h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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 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>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.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* 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>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, 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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <h2> Thread safety </h2>
|
||||
*
|
||||
* 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
|
||||
* @since 1.5
|
||||
*/
|
||||
public class SerialJavaObject implements Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* @serial Placeholder for object to be serialized.
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
||||
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.
|
||||
*
|
||||
* @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
|
||||
* @see Class#getFields
|
||||
*/
|
||||
public Field[] getFields() throws SerialException {
|
||||
if (fields != null) {
|
||||
Class<?> c = this.obj.getClass();
|
||||
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;
|
||||
|
||||
/**
|
||||
* @serial 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.
|
||||
* @param s the {@code ObjectInputStream} to read from.
|
||||
*
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
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.
|
||||
* @param s the {@code ObjectOutputStream} to write to.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, 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.
|
||||
*
|
||||
* <h2> Thread safety </h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class SerialRef implements Ref, Serializable, Cloneable {
|
||||
|
||||
/**
|
||||
* String containing the base type name.
|
||||
* @serial
|
||||
*/
|
||||
private String baseTypeName;
|
||||
|
||||
/**
|
||||
* @serial This will store the type <code>Ref</code> as an <code>Object</code>.
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
||||
private Object object;
|
||||
|
||||
/**
|
||||
* @serial Private copy of the Ref reference.
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable; checked in writeObject
|
||||
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.
|
||||
* @param s the {@code ObjectInputStream} to read from.
|
||||
*
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
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.
|
||||
* @param s the {@code ObjectOutputStream} to write to.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException {
|
||||
|
||||
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 compatibility
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2020, 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.
|
||||
*
|
||||
* <h2> Thread safety </h2>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
||||
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.
|
||||
* @param s the {@code ObjectInputStream} to read from.
|
||||
*
|
||||
* @throws ClassNotFoundException if the class of a serialized object
|
||||
* could not be found.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
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.
|
||||
* @param s the {@code ObjectOutputStream} to write to.
|
||||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream s)
|
||||
throws IOException {
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2023, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides utility classes to allow serializable mappings between SQL types
|
||||
* and data types in the Java programming language.
|
||||
* <p> Standard JDBC {@code RowSet} implementations may use these utility
|
||||
* classes to
|
||||
* assist in the serialization of disconnected {@code RowSet} objects.
|
||||
* This is useful
|
||||
* when transmitting a disconnected {@code RowSet} object over the wire to
|
||||
* a different VM or across layers within an application.<br>
|
||||
* </p>
|
||||
*
|
||||
* <h2>1.0 SerialArray</h2>
|
||||
* A serializable mapping in the Java programming language of an SQL ARRAY
|
||||
* value. <br>
|
||||
* <br>
|
||||
* The {@code SerialArray} class provides a constructor for creating a {@code SerialArray}
|
||||
* instance from an Array 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} object. <br>
|
||||
*
|
||||
* <h2>2.0 SerialBlob</h2>
|
||||
* A serializable mapping in the Java programming language of an SQL BLOB
|
||||
* value. <br>
|
||||
* <br>
|
||||
* The {@code SerialBlob} class provides a constructor for creating an instance
|
||||
* from a Blob object. Note that the Blob object should have brought the SQL
|
||||
* BLOB value's data over to the client before a {@code SerialBlob} object
|
||||
* is constructed from it. The data of an SQL BLOB value can be materialized
|
||||
* on the client as an array of bytes (using the method {@code Blob.getBytes})
|
||||
* or as a stream of uninterpreted bytes (using the method {@code Blob.getBinaryStream}).
|
||||
* <br>
|
||||
* <br>
|
||||
* {@code SerialBlob} methods make it possible to make a copy of a {@code SerialBlob}
|
||||
* 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} object within a {@code SerialBlob}
|
||||
* object. <br>
|
||||
*
|
||||
* <h2>3.0 SerialClob</h2>
|
||||
* A serializable mapping in the Java programming language of an SQL CLOB
|
||||
* value. <br>
|
||||
* <br>
|
||||
* The {@code SerialClob} class provides a constructor for creating an instance
|
||||
* from a {@code Clob} object. Note that the {@code Clob} object should have
|
||||
* brought the SQL CLOB value's data over to the client before a {@code SerialClob}
|
||||
* object is constructed from it. The data of an SQL CLOB value can be
|
||||
* materialized on the client as a stream of Unicode characters. <br>
|
||||
* <br>
|
||||
* {@code SerialClob} methods make it possible to get a substring from a
|
||||
* {@code SerialClob} object or to locate the start of a pattern of characters.
|
||||
* <br>
|
||||
*
|
||||
* <h2>5.0 SerialDatalink</h2>
|
||||
* A serializable mapping in the Java programming language of an SQL DATALINK
|
||||
* value. A DATALINK value references a file outside of the underlying data source
|
||||
* that the originating data source manages. <br>
|
||||
* <br>
|
||||
* {@code RowSet} implementations can use the method {@code RowSet.getURL()} to retrieve
|
||||
* a {@code java.net.URL} object, which can be used to manipulate the external data.
|
||||
* <br>
|
||||
* <PRE>
|
||||
* java.net.URL url = rowset.getURL(1);
|
||||
* </PRE>
|
||||
*
|
||||
* <h2>6.0 SerialJavaObject</h2>
|
||||
* A serializable mapping in the Java programming language of an SQL JAVA_OBJECT
|
||||
* value. Assuming the Java object instance implements the Serializable interface,
|
||||
* this simply wraps the serialization process. <br>
|
||||
* <br>
|
||||
* If however, the serialization is not possible in the case where the Java
|
||||
* object is not immediately serializable, this class will attempt to serialize
|
||||
* all non static members to permit the object instance state to be serialized.
|
||||
* Static or transient fields cannot be serialized and attempting to do so
|
||||
* will result in a {@code SerialException} being thrown. <br>
|
||||
*
|
||||
* <h2>7.0 SerialRef</h2>
|
||||
* A serializable mapping between the SQL REF type and the Java programming
|
||||
* language. <br>
|
||||
* <br>
|
||||
* The {@code SerialRef} class provides a constructor for creating a {@code SerialRef}
|
||||
* instance from a {@code Ref} type and provides methods for getting
|
||||
* and setting the {@code Ref} object type. <br>
|
||||
*
|
||||
* <h2>8.0 SerialStruct</h2>
|
||||
* A serializable mapping in the Java programming language of an SQL structured
|
||||
* type. Each attribute that is not already serializable is mapped to a serializable
|
||||
* form, and if an attribute is itself a structured type, each of its attributes
|
||||
* that is not already serializable is mapped to a serializable form. <br>
|
||||
* <br>
|
||||
* In addition, if a {@code Map} object is passed to one of the constructors or
|
||||
* to the method {@code getAttributes}, the structured type is custom mapped
|
||||
* according to the mapping specified in the {@code Map} object.
|
||||
* <br>
|
||||
* The {@code SerialStruct} class provides a constructor for creating an
|
||||
* instance from a {@code Struct} object, a method for retrieving the SQL
|
||||
* type name of the SQL structured type in the database, and methods for retrieving
|
||||
* its attribute values. <br>
|
||||
*
|
||||
* <h2>9.0 SQLInputImpl</h2>
|
||||
* An input stream used for custom mapping user-defined types (UDTs). An
|
||||
* {@code SQLInputImpl} object is an input stream that contains a stream of
|
||||
* values that are
|
||||
* the attributes of a UDT. This class is used by the driver behind the scenes
|
||||
* when the method {@code getObject} is called on an SQL structured or distinct
|
||||
* type that has a custom mapping; a programmer never invokes {@code SQLInputImpl}
|
||||
* methods directly. <br>
|
||||
* <br>
|
||||
* The {@code SQLInputImpl} class provides a set of reader methods
|
||||
* analogous to the {@code ResultSet} getter methods. These methods make it
|
||||
* possible to read the values in an {@code SQLInputImpl} object. The method
|
||||
* {@code wasNull} is used to determine whether the last value read was SQL NULL.
|
||||
* <br>
|
||||
* <br>
|
||||
* When a constructor or getter method that takes a {@code Map} object is called,
|
||||
* the JDBC driver calls the method
|
||||
* {@code SQLData.getSQLType} to determine the SQL type of the UDT being custom
|
||||
* mapped. The driver creates an instance of {@code SQLInputImpl}, populating it with
|
||||
* the attributes of the UDT. The driver then passes the input stream to the
|
||||
* method {@code SQLData.readSQL}, which in turn calls the {@code SQLInputImpl}
|
||||
* methods to read the attributes from the input stream. <br>
|
||||
*
|
||||
* <h2>10.0 SQLOutputImpl</h2>
|
||||
* 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.
|
||||
* <br>
|
||||
* <br>
|
||||
* When an application calls the method {@code PreparedStatement.setObject}, 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 Class
|
||||
* object for the class that implements {@code SQLData} for this UDT. If the
|
||||
* value to be written is an instance of {@code SQLData}, the driver will
|
||||
* create an instance of {@code SQLOutputImpl} and pass it to the method
|
||||
* {@code SQLData.writeSQL}.
|
||||
* The method {@code writeSQL} in turn calls the appropriate {@code SQLOutputImpl}
|
||||
* writer methods to write data from the {@code SQLData} object to the
|
||||
* {@code SQLOutputImpl}
|
||||
* output stream as the representation of an SQL user-defined type.
|
||||
*
|
||||
* <h2>Custom Mapping</h2>
|
||||
* The JDBC API provides mechanisms for mapping an SQL structured type or DISTINCT
|
||||
* type to the Java programming language. Typically, a structured type is mapped
|
||||
* to a class, and its attributes are mapped to fields in the class.
|
||||
* (A DISTINCT type can thought of as having one attribute.) However, there are
|
||||
* many other possibilities, and there may be any number of different mappings.
|
||||
* <P>
|
||||
* A programmer defines the mapping by implementing the interface {@code SQLData}.
|
||||
* For example, if an SQL structured type named AUTHORS has the attributes NAME,
|
||||
* TITLE, and PUBLISHER, it could be mapped to a Java class named Authors. The
|
||||
* Authors class could have the fields name, title, and publisher, to which the
|
||||
* attributes of AUTHORS are mapped. In such a case, the implementation of
|
||||
* {@code SQLData} could look like the following:
|
||||
* <PRE>
|
||||
* public class Authors implements SQLData {
|
||||
* public String name;
|
||||
* public String title;
|
||||
* public String publisher;
|
||||
*
|
||||
* private String sql_type;
|
||||
* public String getSQLTypeName() {
|
||||
* return sql_type;
|
||||
* }
|
||||
*
|
||||
* public void readSQL(SQLInput stream, String type)
|
||||
* throws SQLException {
|
||||
* sql_type = type;
|
||||
* name = stream.readString();
|
||||
* title = stream.readString();
|
||||
* publisher = stream.readString();
|
||||
* }
|
||||
*
|
||||
* public void writeSQL(SQLOutput stream) throws SQLException {
|
||||
* stream.writeString(name);
|
||||
* stream.writeString(title);
|
||||
* stream.writeString(publisher);
|
||||
* }
|
||||
* }
|
||||
* </PRE>
|
||||
*
|
||||
* A {@code java.util.Map} object is used to associate the SQL structured
|
||||
* type with its mapping to the class {@code Authors}. The following code fragment shows
|
||||
* how a {@code Map} object might be created and given an entry associating
|
||||
* {@code AUTHORS} and {@code Authors}.
|
||||
* <PRE>
|
||||
* java.util.Map map = new java.util.HashMap();
|
||||
* map.put("SCHEMA_NAME.AUTHORS", Class.forName("Authors");
|
||||
* </PRE>
|
||||
*
|
||||
* The {@code Map} object <i>map</i> now contains an entry with the
|
||||
* fully qualified name of the SQL structured type and the {@code Class}
|
||||
* object for the class {@code Authors}. It can be passed to a method
|
||||
* to tell the driver how to map {@code AUTHORS} to {@code Authors}.
|
||||
* <P>
|
||||
* For a disconnected {@code RowSet} object, custom mapping can be done
|
||||
* only when a {@code Map} object is passed to the method or constructor
|
||||
* that will be doing the custom mapping. The situation is different for
|
||||
* connected {@code RowSet} objects because they maintain a connection
|
||||
* with the data source. A method that does custom mapping and is called by
|
||||
* a disconnected {@code RowSet} object may use the {@code Map}
|
||||
* object that is associated with the {@code Connection} object being
|
||||
* used. So, in other words, if no map is specified, the connection's type
|
||||
* map can be used by default.
|
||||
* @since 1.5
|
||||
*/
|
||||
package javax.sql.rowset.serial;
|
||||
|
|
@ -0,0 +1,865 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, 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 javax.naming.*;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <h2>1.0 Overview</h2>
|
||||
* 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>
|
||||
* <h2>2.0 Registering <code>SyncProvider</code> Implementations</h2>
|
||||
* <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
|
||||
* @since 1.5
|
||||
*/
|
||||
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";
|
||||
|
||||
/**
|
||||
* 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 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 = System.getProperty("rowset.properties");
|
||||
|
||||
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";
|
||||
|
||||
try {
|
||||
InputStream in = SyncFactory.class.getModule().getResourceAsStream(ROWSET_PROPERTIES);
|
||||
if (in == null) {
|
||||
throw new SyncFactoryException("Resource " + ROWSET_PROPERTIES + " not found");
|
||||
}
|
||||
try (in) {
|
||||
properties.load(in);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
SyncFactoryException sfe = new SyncFactoryException();
|
||||
sfe.initCause(e);
|
||||
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 = System.getProperty(ROWSET_SYNC_PROVIDER);
|
||||
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 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();
|
||||
}
|
||||
|
||||
// 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);
|
||||
@SuppressWarnings("deprecation")
|
||||
Object result = c.newInstance();
|
||||
return (SyncProvider)result;
|
||||
|
||||
} catch (IllegalAccessException | InstantiationException | ClassNotFoundException e) {
|
||||
throw new SyncFactoryException("IllegalAccessException: " + 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.
|
||||
*
|
||||
* @param logger A Logger object instance
|
||||
* @throws NullPointerException if the logger is null
|
||||
*/
|
||||
public static void setLogger(Logger logger) {
|
||||
|
||||
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.
|
||||
*
|
||||
* @param logger a Logger object instance
|
||||
* @param level a Level object instance indicating the degree of logging
|
||||
* required
|
||||
* @throws NullPointerException if the logger is null
|
||||
*/
|
||||
public static void setLogger(Logger logger, Level level) {
|
||||
// singleton
|
||||
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
|
||||
*
|
||||
* @param ctx a valid JNDI context
|
||||
* @throws SyncFactoryException if the supplied JNDI context is null
|
||||
*/
|
||||
public static synchronized void setJNDIContext(javax.naming.Context ctx)
|
||||
throws SyncFactoryException {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2019, 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.
|
||||
*
|
||||
* <h2>1.0 Naming Convention for Implementations</h2>
|
||||
* 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>
|
||||
* Vendors should refer to the reference implementation synchronization
|
||||
* providers for additional guidance on how to implement a new
|
||||
* <code>SyncProvider</code> implementation.
|
||||
*
|
||||
* <h2>2.0 How a <code>RowSet</code> Object Gets Its Provider</h2>
|
||||
*
|
||||
* 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>.
|
||||
*
|
||||
* <h2>3.0 Violations and Synchronization Issues</h2>
|
||||
* 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>.
|
||||
*
|
||||
* <h2>4.0 Updatable SQL VIEWs</h2>
|
||||
* 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>.
|
||||
*
|
||||
* <h2>5.0 <code>SyncProvider</code> Constants</h2>
|
||||
* 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 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
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, 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
|
||||
* @since 1.5
|
||||
*/
|
||||
public class SyncProviderException extends java.sql.SQLException {
|
||||
|
||||
/**
|
||||
* @serial 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.
|
||||
*/
|
||||
@SuppressWarnings("serial") // Not statically typed as Serializable
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* 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
|
||||
* @since 1.5
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2023, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The standard classes and interfaces that a third party vendor has to
|
||||
* use in its implementation of a synchronization provider. These classes and
|
||||
* interfaces are referred to as the Service Provider Interface (SPI). To make it possible
|
||||
* for a {@code RowSet} object to use an implementation, the vendor must register
|
||||
* it with the {@code SyncFactory} singleton. (See the class comment for
|
||||
* {@code SyncProvider} for a full explanation of the registration process and
|
||||
* the naming convention to be used.)
|
||||
*
|
||||
* <h2>Table of Contents</h2>
|
||||
* <ul>
|
||||
* <li><a href="#pkgspec">1.0 Package Specification</a>
|
||||
* <li><a href="#arch">2.0 Service Provider Architecture</a>
|
||||
* <li><a href="#impl">3.0 Implementer's Guide</a>
|
||||
* <li><a href="#resolving">4.0 Resolving Synchronization Conflicts</a>
|
||||
* <li><a href="#relspec">5.0 Related Specifications</a>
|
||||
* <li><a href="#reldocs">6.0 Related Documentation</a>
|
||||
* </ul>
|
||||
*
|
||||
* <h3><a id="pkgspec">1.0 Package Specification</a></h3>
|
||||
* <P>
|
||||
* The following classes and interfaces make up the {@code javax.sql.rowset.spi}
|
||||
* package:
|
||||
* <UL>
|
||||
* <LI>{@code SyncFactory}
|
||||
* <LI>{@code SyncProvider}
|
||||
* <LI>{@code SyncFactoryException}
|
||||
* <LI>{@code SyncProviderException}
|
||||
* <LI>{@code SyncResolver}
|
||||
* <LI>{@code XmlReader}
|
||||
* <LI>{@code XmlWriter}
|
||||
* <LI>{@code TransactionalWriter}
|
||||
* </UL>
|
||||
* The following interfaces, in the {@code javax.sql} package, are also part of the SPI:
|
||||
* <UL>
|
||||
* <LI>{@code RowSetReader}
|
||||
* <LI>{@code RowSetWriter}
|
||||
* </UL>
|
||||
* <P>
|
||||
* A {@code SyncProvider} implementation provides a disconnected {@code RowSet}
|
||||
* object with the mechanisms for reading data into it and for writing data that has been
|
||||
* modified in it
|
||||
* back to the underlying data source. A <i>reader</i>, a {@code RowSetReader} or
|
||||
* {@code XMLReader} object, reads data into a {@code RowSet} object when the
|
||||
* {@code CachedRowSet} methods {@code execute} or {@code populate}
|
||||
* are called. A <i>writer</i>, a {@code RowSetWriter} or {@code XMLWriter}
|
||||
* object, writes changes back to the underlying data source when the
|
||||
* {@code CachedRowSet} method {@code acceptChanges} is called.
|
||||
* <P>
|
||||
* The process of writing changes in a {@code RowSet} object to its data source
|
||||
* is known as <i>synchronization</i>. The {@code SyncProvider} implementation that a
|
||||
* {@code RowSet} object is using determines the level of synchronization that the
|
||||
* {@code RowSet} object's writer uses. The various levels of synchronization are
|
||||
* referred to as <i>grades</i>.
|
||||
* <P>
|
||||
* The lower grades of synchronization are
|
||||
* known as <i>optimistic</i> concurrency levels because they optimistically
|
||||
* assume that there will be no conflicts or very few conflicts. A conflict exists when
|
||||
* the same data modified in the {@code RowSet} object has also been modified
|
||||
* in the data source. Using the optimistic concurrency model means that if there
|
||||
* is a conflict, modifications to either the data source or the {@code RowSet}
|
||||
* object will be lost.
|
||||
* <P>
|
||||
* Higher grades of synchronization are called <i>pessimistic</i> because they assume
|
||||
* that others will be accessing the data source and making modifications. These
|
||||
* grades set varying levels of locks to increase the chances that no conflicts
|
||||
* occur.
|
||||
* <P>
|
||||
* The lowest level of synchronization is simply writing any changes made to the
|
||||
* {@code RowSet} object to its underlying data source. The writer does
|
||||
* nothing to check for conflicts.
|
||||
* If there is a conflict and the data
|
||||
* source values are overwritten, the changes other parties have made by to the data
|
||||
* source are lost.
|
||||
* <P>
|
||||
* The {@code RIXMLProvider} implementation uses the lowest level
|
||||
* of synchronization and just writes {@code RowSet} changes to the data source.
|
||||
*
|
||||
* <P>
|
||||
* For the next level up, the
|
||||
* writer checks to see if there are any conflicts, and if there are,
|
||||
* it does not write anything to the data source. The problem with this concurrency
|
||||
* level is that if another party has modified the corresponding data in the data source
|
||||
* since the {@code RowSet} object got its data,
|
||||
* the changes made to the {@code RowSet} object are lost. The
|
||||
* {@code RIOptimisticProvider} implementation uses this level of synchronization.
|
||||
* <P>
|
||||
* At higher levels of synchronization, referred to as pessimistic concurrency,
|
||||
* the writer take steps to avoid conflicts by setting locks. Setting locks
|
||||
* can vary from setting a lock on a single row to setting a lock on a table
|
||||
* or the entire data source. The level of synchronization is therefore a tradeoff
|
||||
* between the ability of users to access the data source concurrently and the ability
|
||||
* of the writer to keep the data in the {@code RowSet} object and its data source
|
||||
* synchronized.
|
||||
* <P>
|
||||
* It is a requirement that all disconnected {@code RowSet} objects
|
||||
* ({@code CachedRowSet}, {@code FilteredRowSet}, {@code JoinRowSet},
|
||||
* and {@code WebRowSet} objects) obtain their {@code SyncProvider} objects
|
||||
* from the {@code SyncFactory} mechanism.
|
||||
* <P>
|
||||
* The reference implementation (RI) provides two synchronization providers.
|
||||
* <UL>
|
||||
* <LI><b>{@code RIOptimisticProvider}</b> <br>
|
||||
* The default provider that the {@code SyncFactory} instance will
|
||||
* supply to a disconnected {@code RowSet} object when no provider
|
||||
* implementation is specified.<BR>
|
||||
* This synchronization provider uses an optimistic concurrency model,
|
||||
* assuming that there will be few conflicts among users
|
||||
* who are accessing the same data in a database. It avoids
|
||||
* using locks; rather, it checks to see if there is a conflict
|
||||
* before trying to synchronize the {@code RowSet} object and the
|
||||
* data source. If there is a conflict, it does nothing, meaning that
|
||||
* changes to the {@code RowSet} object are not persisted to the data
|
||||
* source.
|
||||
* <LI><B>{@code RIXMLProvider}</B> <BR>
|
||||
* A synchronization provider that can be used with a
|
||||
* {@code WebRowSet} object, which is a rowset that can be written
|
||||
* in XML format or read from XML format. The
|
||||
* {@code RIXMLProvider} implementation does no checking at all for
|
||||
* conflicts and simply writes any updated data in the
|
||||
* {@code WebRowSet} object to the underlying data source.
|
||||
* {@code WebRowSet} objects use this provider when they are
|
||||
* dealing with XML data.
|
||||
* </UL>
|
||||
*
|
||||
* These {@code SyncProvider} implementations
|
||||
* are bundled with the reference implementation, which makes them always available to
|
||||
* {@code RowSet} implementations.
|
||||
* {@code SyncProvider} implementations make themselves available by being
|
||||
* registered with the {@code SyncFactory} singleton. When a {@code RowSet}
|
||||
* object requests a provider, by specifying it in the constructor or as an argument to the
|
||||
* {@code CachedRowSet} method {@code setSyncProvider},
|
||||
* the {@code SyncFactory} singleton
|
||||
* checks to see if the requested provider has been registered with it.
|
||||
* If it has, the {@code SyncFactory} creates an instance of it and passes it to the
|
||||
* requesting {@code RowSet} object.
|
||||
* If the {@code SyncProvider} implementation that is specified has not been registered,
|
||||
* the {@code SyncFactory} singleton causes a {@code SyncFactoryException} object
|
||||
* to be thrown. If no provider is specified,
|
||||
* the {@code SyncFactory} singleton will create an instance of the default
|
||||
* provider implementation, {@code RIOptimisticProvider},
|
||||
* and pass it to the requesting {@code RowSet} object.
|
||||
*
|
||||
* <P>
|
||||
* If a {@code WebRowSet} object does not specify a provider in its constructor, the
|
||||
* {@code SyncFactory} will give it an instance of {@code RIOptimisticProvider}.
|
||||
* However, the constructor for {@code WebRowSet} is implemented to set the provider
|
||||
* to the {@code RIXMLProvider}, which reads and writes a {@code RowSet} object
|
||||
* in XML format.
|
||||
* <P>
|
||||
* See the <a href="SyncProvider.html">SyncProvider</a> class
|
||||
* specification for further details.
|
||||
* <p>
|
||||
* Vendors may develop a {@code SyncProvider} implementation with any one of the possible
|
||||
* levels of synchronization, thus giving {@code RowSet} objects a choice of
|
||||
* synchronization mechanisms.
|
||||
*
|
||||
* <h3><a id="arch">2.0 Service Provider Interface Architecture</a></h3>
|
||||
* <b>2.1 Overview</b>
|
||||
* <p>
|
||||
* The Service Provider Interface provides a pluggable mechanism by which
|
||||
* {@code SyncProvider} implementations can be registered and then generated when
|
||||
* required. The lazy reference mechanism employed by the {@code SyncFactory} limits
|
||||
* unnecessary resource consumption by not creating an instance until it is
|
||||
* required by a disconnected
|
||||
* {@code RowSet} object. The {@code SyncFactory} class also provides
|
||||
* a standard API to configure logging options and streams that <b>may</b> be provided
|
||||
* by a particular {@code SyncProvider} implementation.
|
||||
* <p>
|
||||
* <b>2.2 Registering with the {@code SyncFactory}</b>
|
||||
* <p>
|
||||
* A third party {@code SyncProvider} implementation must be registered with the
|
||||
* {@code SyncFactory} in order for a disconnected {@code RowSet} object
|
||||
* to obtain it and thereby use its {@code javax.sql.RowSetReader} and
|
||||
* {@code javax.sql.RowSetWriter}
|
||||
* implementations. The following registration mechanisms are available to all
|
||||
* {@code SyncProvider} implementations:
|
||||
* <ul>
|
||||
* <li><b>System properties</b> - Properties set at the command line. These
|
||||
* properties are set at run time and apply system-wide per invocation of the Java
|
||||
* application. See the section <a href="#reldocs">"Related Documentation"</a>
|
||||
* further related information.
|
||||
*
|
||||
* <li><b>Property Files</b> - Properties specified in a standard property file.
|
||||
* This can be specified using a System Property or by modifying a standard
|
||||
* property file located in the platform run-time. The
|
||||
* reference implementation of this technology includes a standard property
|
||||
* file than can be edited to add additional {@code SyncProvider} objects.
|
||||
*
|
||||
* <li><b>JNDI Context</b> - Available providers can be registered on a JNDI
|
||||
* context. The {@code SyncFactory} will attempt to load {@code SyncProvider}
|
||||
* objects bound to the context and register them with the factory. This
|
||||
* context must be supplied to the {@code SyncFactory} for the mechanism to
|
||||
* function correctly.
|
||||
* </ul>
|
||||
* <p>
|
||||
* Details on how to specify the system properties or properties in a property file
|
||||
* and how to configure the JNDI Context are explained in detail in the
|
||||
* <a href="SyncFactory.html">{@code SyncFactory}</a> class description.
|
||||
* <p>
|
||||
* <b>2.3 SyncFactory Provider Instance Generation Policies</b>
|
||||
* <p>
|
||||
* The {@code SyncFactory} generates a requested {@code SyncProvider}
|
||||
* object if the provider has been correctly registered. The
|
||||
* following policies are adhered to when either a disconnected {@code RowSet} object
|
||||
* is instantiated with a specified {@code SyncProvider} implementation or is
|
||||
* reconfigured at runtime with an alternative {@code SyncProvider} object.
|
||||
* <ul>
|
||||
* <li> If a {@code SyncProvider} object is specified and the {@code SyncFactory}
|
||||
* contains <i>no</i> reference to the provider, a {@code SyncFactoryException} is
|
||||
* thrown.
|
||||
*
|
||||
* <li> If a {@code SyncProvider} object is specified and the {@code SyncFactory}
|
||||
* contains a reference to the provider, the requested provider is supplied.
|
||||
*
|
||||
* <li> If no {@code SyncProvider} object is specified, the reference
|
||||
* implementation provider {@code RIOptimisticProvider} is supplied.
|
||||
* </ul>
|
||||
* <p>
|
||||
* These policies are explored in more detail in the <a href="SyncFactory.html">
|
||||
* {@code SyncFactory}</a> class.
|
||||
*
|
||||
* <h3><a id="impl">3.0 SyncProvider Implementer's Guide</a></h3>
|
||||
*
|
||||
* <b>3.1 Requirements</b>
|
||||
* <p>
|
||||
* A compliant {@code SyncProvider} implementation that is fully pluggable
|
||||
* into the {@code SyncFactory} <b>must</b> extend and implement all
|
||||
* abstract methods in the <a href="SyncProvider.html">{@code SyncProvider}</a>
|
||||
* class. In addition, an implementation <b>must</b> determine the
|
||||
* grade, locking and updatable view capabilities defined in the
|
||||
* {@code SyncProvider} class definition. One or more of the
|
||||
* {@code SyncProvider} description criteria <b>must</b> be supported. It
|
||||
* is expected that vendor implementations will offer a range of grade, locking, and
|
||||
* updatable view capabilities.
|
||||
* <p>
|
||||
* Furthermore, the {@code SyncProvider} naming convention <b>must</b> be followed as
|
||||
* detailed in the <a href="SyncProvider.html">{@code SyncProvider}</a> class
|
||||
* description.
|
||||
* <p>
|
||||
* <b>3.2 Grades</b>
|
||||
* <p>
|
||||
* JSR 114 defines a set of grades to describe the quality of synchronization
|
||||
* a {@code SyncProvider} object can offer a disconnected {@code RowSet}
|
||||
* object. These grades are listed from the lowest quality of service to the highest.
|
||||
* <ul>
|
||||
* <li><b>GRADE_NONE</b> - No synchronization with the originating data source is
|
||||
* provided. A {@code SyncProvider} implementation returning this grade will simply
|
||||
* attempt to write any data that has changed in the {@code RowSet} object to the
|
||||
*underlying data source, overwriting whatever is there. No attempt is made to compare
|
||||
* original values with current values to see if there is a conflict. The
|
||||
* {@code RIXMLProvider} is implemented with this grade.
|
||||
*
|
||||
* <li><b>GRADE_CHECK_MODIFIED_AT_COMMIT</b> - A low grade of optimistic synchronization.
|
||||
* A {@code SyncProvider} implementation returning this grade
|
||||
* will check for conflicts in rows that have changed between the last synchronization
|
||||
* and the current synchronization under way. Any changes in the originating data source
|
||||
* that have been modified will not be reflected in the disconnected {@code RowSet}
|
||||
* object. If there are no conflicts, changes in the {@code RowSet} object will be
|
||||
* written to the data source. If there are conflicts, no changes are written.
|
||||
* The {@code RIOptimisticProvider} implementation uses this grade.
|
||||
*
|
||||
* <li><b>GRADE_CHECK_ALL_AT_COMMIT</b> - A high grade of optimistic synchronization.
|
||||
* A {@code SyncProvider} implementation returning this grade
|
||||
* will check all rows, including rows that have not changed in the disconnected
|
||||
* {@code RowSet} object. In this way, any changes to rows in the underlying
|
||||
* data source will be reflected in the disconnected {@code RowSet} object
|
||||
* when the synchronization finishes successfully.
|
||||
*
|
||||
* <li><b>GRADE_LOCK_WHEN_MODIFIED</b> - A pessimistic grade of synchronization.
|
||||
* {@code SyncProvider} implementations returning this grade will lock
|
||||
* the row in the originating data source that corresponds to the row being changed
|
||||
* in the {@code RowSet} object to reduce the possibility of other
|
||||
* processes modifying the same data in the data source.
|
||||
*
|
||||
* <li><b>GRADE_LOCK_WHEN_LOADED</b> - A higher pessimistic synchronization grade.
|
||||
* A {@code SyncProvider} implementation returning this grade will lock
|
||||
* the entire view and/or table affected by the original query used to
|
||||
* populate a {@code RowSet} object.
|
||||
* </ul>
|
||||
* <p>
|
||||
* <b>3.3 Locks</b>
|
||||
* <p>
|
||||
* JSR 114 defines a set of constants that specify whether any locks have been
|
||||
* placed on a {@code RowSet} object's underlying data source and, if so,
|
||||
* on which constructs the locks are placed. These locks will remain on the data
|
||||
* source while the {@code RowSet} object is disconnected from the data source.
|
||||
* <P>
|
||||
* These constants <b>should</b> be considered complementary to the
|
||||
* grade constants. The default setting for the majority of grade settings requires
|
||||
* that no data source locks remain when a {@code RowSet} object is disconnected
|
||||
* from its data source.
|
||||
* The grades {@code GRADE_LOCK_WHEN_MODIFIED} and
|
||||
* {@code GRADE_LOCK_WHEN_LOADED} allow a disconnected {@code RowSet} object
|
||||
* to have a fine-grained control over the degree of locking.
|
||||
* <ul>
|
||||
* <li><b>DATASOURCE_NO_LOCK</b> - No locks remain on the originating data source.
|
||||
* This is the default lock setting for all {@code SyncProvider} implementations
|
||||
* unless otherwise directed by a {@code RowSet} object.
|
||||
*
|
||||
* <li><b>DATASOURCE_ROW_LOCK</b> - A lock is placed on the rows that are touched by
|
||||
* the original SQL query used to populate the {@code RowSet} object.
|
||||
*
|
||||
* <li><b>DATASOURCE_TABLE_LOCK</b> - A lock is placed on all tables that are touched
|
||||
* by the query that was used to populate the {@code RowSet} object.
|
||||
*
|
||||
* <li><b>DATASOURCE_DB_LOCK</b>
|
||||
* A lock is placed on the entire data source that is used by the {@code RowSet}
|
||||
* object.
|
||||
* </ul>
|
||||
* <p>
|
||||
* <b>3.4 Updatable Views</b>
|
||||
* <p>
|
||||
* A {@code RowSet} object may be populated with data from an SQL {@code VIEW}.
|
||||
* The following constants indicate whether a {@code SyncProvider} object can
|
||||
* update data in the table or tables from which the {@code VIEW} was derived.
|
||||
* <ul>
|
||||
* <li><b>UPDATABLE_VIEW_SYNC</b>
|
||||
* Indicates that a {@code SyncProvider} implementation supports synchronization
|
||||
* to the table or tables from which the SQL {@code VIEW} used to populate
|
||||
* a {@code RowSet} object is derived.
|
||||
*
|
||||
* <li><b>NONUPDATABLE_VIEW_SYNC</b>
|
||||
* Indicates that a {@code SyncProvider} implementation does <b>not</b> support
|
||||
* synchronization to the table or tables from which the SQL {@code VIEW}
|
||||
* used to populate a {@code RowSet} object is derived.
|
||||
* </ul>
|
||||
* <p>
|
||||
* <b>3.5 Usage of {@code SyncProvider} Grading and Locking</b>
|
||||
* <p>
|
||||
* In the example below, the reference {@code CachedRowSetImpl} implementation
|
||||
* reconfigures its current {@code SyncProvider} object by calling the
|
||||
* {@code setSyncProvider} method.<br>
|
||||
*
|
||||
* <PRE>
|
||||
* CachedRowSetImpl crs = new CachedRowSetImpl();
|
||||
* crs.setSyncProvider("com.foo.bar.HASyncProvider");
|
||||
* </PRE>
|
||||
* An application can retrieve the {@code SyncProvider} object currently in use
|
||||
* by a disconnected {@code RowSet} object. It can also retrieve the
|
||||
* grade of synchronization with which the provider was implemented and the degree of
|
||||
* locking currently in use. In addition, an application has the flexibility to set
|
||||
* the degree of locking to be used, which can increase the possibilities for successful
|
||||
* synchronization. These operation are shown in the following code fragment.
|
||||
* <PRE>
|
||||
* SyncProvider sync = crs.getSyncProvider();
|
||||
*
|
||||
* switch (sync.getProviderGrade()) {
|
||||
* case: SyncProvider.GRADE_CHECK_ALL_AT_COMMIT
|
||||
* //A high grade of optimistic synchronization
|
||||
* break;
|
||||
* case: SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT
|
||||
* //A low grade of optimistic synchronization
|
||||
* break;
|
||||
* case: SyncProvider.GRADE_LOCK_WHEN_LOADED
|
||||
* // A pessimistic synchronization grade
|
||||
* break;
|
||||
* case: SyncProvider.GRADE_LOCK_WHEN_MODIFIED
|
||||
* // A pessimistic synchronization grade
|
||||
* break;
|
||||
* case: SyncProvider.GRADE_NONE
|
||||
* // No synchronization with the originating data source provided
|
||||
* break;
|
||||
* }
|
||||
*
|
||||
* switch (sync.getDataSourceLock() {
|
||||
* case: SyncProvider.DATASOURCE_DB_LOCK
|
||||
* // A lock is placed on the entire datasource that is used by the
|
||||
* // {@code RowSet} object
|
||||
* break;
|
||||
*
|
||||
* case: SyncProvider.DATASOURCE_NO_LOCK
|
||||
* // No locks remain on the originating data source.
|
||||
* break;
|
||||
*
|
||||
* case: SyncProvider.DATASOURCE_ROW_LOCK
|
||||
* // A lock is placed on the rows that are touched by the original
|
||||
* // SQL statement used to populate
|
||||
* // the RowSet object that is using the SyncProvider
|
||||
* break;
|
||||
*
|
||||
* case: DATASOURCE_TABLE_LOCK
|
||||
* // A lock is placed on all tables that are touched by the original
|
||||
* // SQL statement used to populated
|
||||
* // the RowSet object that is using the SyncProvider
|
||||
* break;
|
||||
*
|
||||
* </PRE>
|
||||
* It is also possible using the static utility method in the
|
||||
* {@code SyncFactory} class to determine the list of {@code SyncProvider}
|
||||
* implementations currently registered with the {@code SyncFactory}.
|
||||
*
|
||||
* <pre>
|
||||
* Enumeration e = SyncFactory.getRegisteredProviders();
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* <h3><a id="resolving">4.0 Resolving Synchronization Conflicts</a></h3>
|
||||
*
|
||||
* The interface {@code SyncResolver} provides a way for an application to
|
||||
* decide manually what to do when a conflict occurs. When the {@code CachedRowSet}
|
||||
* method {@code acceptChanges} finishes and has detected one or more conflicts,
|
||||
* it throws a {@code SyncProviderException} object. An application can
|
||||
* catch the exception and
|
||||
* have it retrieve a {@code SyncResolver} object by calling the method
|
||||
* {@code SyncProviderException.getSyncResolver()}.
|
||||
* <P>
|
||||
* A {@code SyncResolver} object, which is a special kind of
|
||||
* {@code CachedRowSet} object or
|
||||
* a {@code JdbcRowSet} object that has implemented the {@code SyncResolver}
|
||||
* interface, examines the conflicts row by row. It is a duplicate of the
|
||||
* {@code RowSet} object being synchronized except that it contains only the data
|
||||
* from the data source this is causing a conflict. All of the other column values are
|
||||
* set to {@code null}. To navigate from one conflict value to another, a
|
||||
* {@code SyncResolver} object provides the methods {@code nextConflict} and
|
||||
* {@code previousConflict}.
|
||||
* <P>
|
||||
* The {@code SyncResolver} interface also
|
||||
* provides methods for doing the following:
|
||||
* <UL>
|
||||
* <LI>finding out whether the conflict involved an update, a delete, or an insert
|
||||
* <LI>getting the value in the data source that caused the conflict
|
||||
* <LI>setting the value that should be in the data source if it needs to be changed
|
||||
* or setting the value that should be in the {@code RowSet} object if it needs
|
||||
* to be changed
|
||||
* </UL>
|
||||
* <P>
|
||||
* When the {@code CachedRowSet} method {@code acceptChanges} is called, it
|
||||
* delegates to the {@code RowSet} object's {@code SyncProvider} object.
|
||||
* How the writer provided by that {@code SyncProvider} object is implemented
|
||||
* determines what level (grade) of checking for conflicts will be done. After all
|
||||
* checking for conflicts is completed and one or more conflicts has been found, the method
|
||||
* {@code acceptChanges} throws a {@code SyncProviderException} object. The
|
||||
* application can catch the exception and use it to obtain a {@code SyncResolver} object.
|
||||
* <P>
|
||||
* The application can then use {@code SyncResolver} methods to get information
|
||||
* about each conflict and decide what to do. If the application logic or the user
|
||||
* decides that a value in the {@code RowSet} object should be the one to
|
||||
* persist, the application or user can overwrite the data source value with it.
|
||||
* <P>
|
||||
* The comment for the {@code SyncResolver} interface has more detail.
|
||||
*
|
||||
* <h3><a id="relspec">5.0 Related Specifications</a></h3>
|
||||
* <ul>
|
||||
* <li><a href="http://docs.oracle.com/javase/jndi/tutorial/index.html">JNDI</a>
|
||||
* <li><a href="{@docRoot}/java.logging/java/util/logging/package-summary.html">Java Logging
|
||||
* APIs</a>
|
||||
* </ul>
|
||||
* <h3><a id="reldocs">6.0 Related Documentation</a></h3>
|
||||
* <ul>
|
||||
* <li><a href="http://docs.oracle.com/javase/tutorial/jdbc/">DataSource for JDBC
|
||||
* Connections</a>
|
||||
* </ul>
|
||||
* @since 1.5
|
||||
*/
|
||||
package javax.sql.rowset.spi;
|
||||
162
src/java.sql.rowset/share/classes/javax/sql/rowset/sqlxml.xsd
Normal file
162
src/java.sql.rowset/share/classes/javax/sql/rowset/sqlxml.xsd
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
Copyright (c) 2003, 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.
|
||||
-->
|
||||
|
||||
<xsd:schema
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://standards.iso.org/iso/9075/2002/12/sqlxml"
|
||||
xmlns:sqlxml="http://standards.iso.org/iso/9075/2002/12/sqlxml">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
ISO/IEC 9075-14:2003 (SQL/XML)
|
||||
This document contains definitions of types and
|
||||
annotations as specified in ISO/IEC 9075-14:2003.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:simpleType name="kindKeyword">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="PREDEFINED"/>
|
||||
<xsd:enumeration value="DOMAIN"/>
|
||||
<xsd:enumeration value="ROW"/>
|
||||
<xsd:enumeration value="DISTINCT"/>
|
||||
<xsd:enumeration value="ARRAY"/>
|
||||
<xsd:enumeration value="MULTISET"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="typeKeyword">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="CHAR"/>
|
||||
<xsd:enumeration value="VARCHAR"/>
|
||||
<xsd:enumeration value="CLOB"/>
|
||||
<xsd:enumeration value="BLOB"/>
|
||||
<xsd:enumeration value="NUMERIC"/>
|
||||
<xsd:enumeration value="DECIMAL"/>
|
||||
<xsd:enumeration value="INTEGER"/>
|
||||
<xsd:enumeration value="SMALLINT"/>
|
||||
<xsd:enumeration value="BIGINT"/>
|
||||
<xsd:enumeration value="FLOAT"/>
|
||||
<xsd:enumeration value="REAL"/>
|
||||
<xsd:enumeration value="DOUBLE PRECISION"/>
|
||||
<xsd:enumeration value="BOOLEAN"/>
|
||||
<xsd:enumeration value="DATE"/>
|
||||
<xsd:enumeration value="TIME"/>
|
||||
<xsd:enumeration value="TIME WITH TIME ZONE"/>
|
||||
<xsd:enumeration value="TIMESTAMP"/>
|
||||
<xsd:enumeration value="TIMESTAMP WITH TIME ZONE"/>
|
||||
<xsd:enumeration value="INTERVAL YEAR"/>
|
||||
<xsd:enumeration value="INTERVAL YEAR TO MONTH"/>
|
||||
<xsd:enumeration value="INTERVAL MONTH"/>
|
||||
<xsd:enumeration value="INTERVAL DAY"/>
|
||||
<xsd:enumeration value="INTERVAL DAY TO HOUR"/>
|
||||
<xsd:enumeration value="INTERVAL DAY TO MINUTE"/>
|
||||
<xsd:enumeration value="INTERVAL DAY TO SECOND"/>
|
||||
<xsd:enumeration value="INTERVAL HOUR"/>
|
||||
<xsd:enumeration value="INTERVAL HOUR TO MINUTE"/>
|
||||
<xsd:enumeration value="INTERVAL HOUR TO SECOND"/>
|
||||
<xsd:enumeration value="INTERVAL MINUTE"/>
|
||||
<xsd:enumeration value="INTERVAL MINUTE TO SECOND"/>
|
||||
<xsd:enumeration value="INTERVAL SECOND"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="fieldType">
|
||||
<xsd:attribute name="name" type="xsd:string"/>
|
||||
<xsd:attribute name="mappedType" type="xsd:string"/>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="sqltype">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="field" type="sqlxml:fieldType"
|
||||
minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="kind"
|
||||
type="sqlxml:kindKeyword"/>
|
||||
<xsd:attribute name="name"
|
||||
type="sqlxml:typeKeyword" use="optional"/>
|
||||
<xsd:attribute name="length" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="maxLength" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="characterSetName" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="collation" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="precision" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="scale" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="maxExponent" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="minExponent" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="userPrecision" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="leadingPrecision" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="maxElements" type="xsd:integer"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="catalogName" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="schemaName" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="domainName" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="typeName" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="mappedType" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="mappedElementType" type="xsd:string"
|
||||
use="optional"/>
|
||||
<xsd:attribute name="final" type="xsd:boolean"
|
||||
use="optional"/>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:simpleType name="objectType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="CATALOG" />
|
||||
<xsd:enumeration value="SCHEMA" />
|
||||
<xsd:enumeration value="BASE TABLE" />
|
||||
<xsd:enumeration value="VIEWED TABLE" />
|
||||
<xsd:enumeration value="CHARACTER SET" />
|
||||
<xsd:enumeration value="COLLATION" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:element name="sqlname">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="type" type="sqlxml:objectType"
|
||||
use="required" />
|
||||
<xsd:attribute name="catalogName" type="xsd:string" />
|
||||
<xsd:attribute name="schemaName" type="xsd:string" />
|
||||
<xsd:attribute name="localName" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
</xsd:schema>
|
||||
160
src/java.sql.rowset/share/classes/javax/sql/rowset/webrowset.xsd
Normal file
160
src/java.sql.rowset/share/classes/javax/sql/rowset/webrowset.xsd
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
Copyright (c) 2003, 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.
|
||||
-->
|
||||
|
||||
<!-- WebRowSet XML Schema by Jonathan Bruce (Sun Microsystems Inc.) -->
|
||||
<xs:schema targetNamespace="http://java.sun.com/xml/ns/jdbc" xmlns:wrs="http://java.sun.com/xml/ns/jdbc" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
|
||||
|
||||
<xs:element name="webRowSet">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="wrs:properties"/>
|
||||
<xs:element ref="wrs:metadata"/>
|
||||
<xs:element ref="wrs:data"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
||||
<xs:element name="columnValue" type="xs:anyType"/>
|
||||
<xs:element name="updateValue" type="xs:anyType"/>
|
||||
|
||||
<xs:element name="properties">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="command" type="xs:string"/>
|
||||
<xs:element name="concurrency" type="xs:string"/>
|
||||
<xs:element name="datasource" type="xs:string"/>
|
||||
<xs:element name="escape-processing" type="xs:string"/>
|
||||
<xs:element name="fetch-direction" type="xs:string"/>
|
||||
<xs:element name="fetch-size" type="xs:string"/>
|
||||
<xs:element name="isolation-level" type="xs:string"/>
|
||||
<xs:element name="key-columns">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="column" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="map">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="type" type="xs:string"/>
|
||||
<xs:element name="class" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="max-field-size" type="xs:string"/>
|
||||
<xs:element name="max-rows" type="xs:string"/>
|
||||
<xs:element name="query-timeout" type="xs:string"/>
|
||||
<xs:element name="read-only" type="xs:string"/>
|
||||
<xs:element name="rowset-type" type="xs:string"/>
|
||||
<xs:element name="show-deleted" type="xs:string"/>
|
||||
<xs:element name="table-name" type="xs:string"/>
|
||||
<xs:element name="url" type="xs:string"/>
|
||||
<xs:element name="sync-provider">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="sync-provider-name" type="xs:string"/>
|
||||
<xs:element name="sync-provider-vendor" type="xs:string"/>
|
||||
<xs:element name="sync-provider-version" type="xs:string"/>
|
||||
<xs:element name="sync-provider-grade" type="xs:string"/>
|
||||
<xs:element name="data-source-lock" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="metadata">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="column-count" type="xs:string"/>
|
||||
<xs:choice>
|
||||
<xs:element name="column-definition" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="column-index" type="xs:string"/>
|
||||
<xs:element name="auto-increment" type="xs:string"/>
|
||||
<xs:element name="case-sensitive" type="xs:string"/>
|
||||
<xs:element name="currency" type="xs:string"/>
|
||||
<xs:element name="nullable" type="xs:string"/>
|
||||
<xs:element name="signed" type="xs:string"/>
|
||||
<xs:element name="searchable" type="xs:string"/>
|
||||
<xs:element name="column-display-size" type="xs:string"/>
|
||||
<xs:element name="column-label" type="xs:string"/>
|
||||
<xs:element name="column-name" type="xs:string"/>
|
||||
<xs:element name="schema-name" type="xs:string"/>
|
||||
<xs:element name="column-precision" type="xs:string"/>
|
||||
<xs:element name="column-scale" type="xs:string"/>
|
||||
<xs:element name="table-name" type="xs:string"/>
|
||||
<xs:element name="catalog-name" type="xs:string"/>
|
||||
<xs:element name="column-type" type="xs:string"/>
|
||||
<xs:element name="column-type-name" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="data">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element name="currentRow" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="wrs:columnValue"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="insertRow" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="wrs:columnValue"/>
|
||||
<xs:element ref="wrs:updateValue"/>
|
||||
</xs:choice>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="deleteRow" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="wrs:columnValue"/>
|
||||
<xs:element ref="wrs:updateValue"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="modifyRow" minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:complexType>
|
||||
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||
<xs:element ref="wrs:columnValue"/>
|
||||
<xs:element ref="wrs:updateValue"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
44
src/java.sql.rowset/share/classes/module-info.java
Normal file
44
src/java.sql.rowset/share/classes/module-info.java
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines the JDBC RowSet API.
|
||||
*
|
||||
* @uses javax.sql.rowset.RowSetFactory
|
||||
*
|
||||
* @moduleGraph
|
||||
* @since 9
|
||||
*/
|
||||
module java.sql.rowset {
|
||||
requires transitive java.logging;
|
||||
requires transitive java.naming;
|
||||
requires transitive java.sql;
|
||||
|
||||
exports javax.sql.rowset;
|
||||
exports javax.sql.rowset.serial;
|
||||
exports javax.sql.rowset.spi;
|
||||
|
||||
uses javax.sql.rowset.RowSetFactory;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue