src/java.sql.rowset/share/classes/javax/sql/rowset/spi/package-info.java
changeset 50444 db65921e9a9b
parent 47216 71c04702a3d5
child 54057 687e10fefa11
equal deleted inserted replaced
50443:8e56de95ce10 50444:db65921e9a9b
       
     1 /*
       
     2  * Copyright (c)  2003, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 /**
       
    27  * The standard classes and interfaces that a third party vendor has to
       
    28  * use in its implementation of a synchronization provider. These classes and
       
    29  * interfaces are referred to as the Service Provider Interface (SPI).  To make it possible
       
    30  * for a <code>RowSet</code> object to use an implementation, the vendor must register
       
    31  * it with the <code>SyncFactory</code> singleton. (See the class comment for
       
    32  * <code>SyncProvider</code> for a full explanation of the registration process and
       
    33  * the naming convention to be used.)
       
    34  *
       
    35  * <h2>Table of Contents</h2>
       
    36  * <ul>
       
    37  * <li><a href="#pkgspec">1.0 Package Specification</a>
       
    38  * <li><a href="#arch">2.0 Service Provider Architecture</a>
       
    39  * <li><a href="#impl">3.0 Implementer's Guide</a>
       
    40  * <li><a href="#resolving">4.0 Resolving Synchronization Conflicts</a>
       
    41  * <li><a href="#relspec">5.0 Related Specifications</a>
       
    42  * <li><a href="#reldocs">6.0 Related Documentation</a>
       
    43  * </ul>
       
    44  *
       
    45  * <h3><a id="pkgspec">1.0 Package Specification</a></h3>
       
    46  * <P>
       
    47  * The following classes and interfaces make up the <code>javax.sql.rowset.spi</code>
       
    48  * package:
       
    49  * <UL>
       
    50  *  <LI><code>SyncFactory</code>
       
    51  *  <LI><code>SyncProvider</code>
       
    52  *  <LI><code>SyncFactoryException</code>
       
    53  *  <LI><code>SyncProviderException</code>
       
    54  *  <LI><code>SyncResolver</code>
       
    55  *  <LI><code>XmlReader</code>
       
    56  *  <LI><code>XmlWriter</code>
       
    57  *  <LI><code>TransactionalWriter</code>
       
    58  * </UL>
       
    59  * The following interfaces, in the <code>javax.sql</code> package, are also part of the SPI:
       
    60  * <UL>
       
    61  *  <LI><code>RowSetReader</code>
       
    62  *  <LI><code>RowSetWriter</code>
       
    63  * </UL>
       
    64  * <P>
       
    65  * A <code>SyncProvider</code> implementation provides a disconnected <code>RowSet</code>
       
    66  * object with the mechanisms for reading data into it and for writing data that has been
       
    67  * modified in it
       
    68  * back to the underlying data source.  A <i>reader</i>, a <code>RowSetReader</code> or
       
    69  * <code>XMLReader</code> object, reads data into a <code>RowSet</code> object when the
       
    70  * <code>CachedRowSet</code> methods <code>execute</code> or <code>populate</code>
       
    71  * are called.  A <i>writer</i>, a <code>RowSetWriter</code> or <code>XMLWriter</code>
       
    72  * object, writes changes back to the underlying data source when the
       
    73  * <code>CachedRowSet</code> method <code>acceptChanges</code> is called.
       
    74  * <P>
       
    75  * The process of writing changes in a <code>RowSet</code> object to its data source
       
    76  * is known as <i>synchronization</i>.  The <code>SyncProvider</code> implementation that a
       
    77  * <code>RowSet</code> object is using determines the level of synchronization that the
       
    78  * <code>RowSet</code> object's writer uses. The various levels of synchronization are
       
    79  * referred to as <i>grades</i>.
       
    80  * <P>
       
    81  * The lower grades of synchronization are
       
    82  * known as <i>optimistic</i> concurrency levels because they optimistically
       
    83  * assume that there will be no conflicts or very few conflicts.  A conflict exists when
       
    84  * the same data modified in the <code>RowSet</code> object has also been modified
       
    85  * in the data source. Using the optimistic concurrency model means that if there
       
    86  * is a conflict, modifications to either the data source or the <code>RowSet</code>
       
    87  * object will be lost.
       
    88  * <P>
       
    89  * Higher grades of synchronization are called <i>pessimistic</i> because they assume
       
    90  * that others will be accessing the data source and making modifications.  These
       
    91  * grades set varying levels of locks to increase the chances that no conflicts
       
    92  * occur.
       
    93  * <P>
       
    94  * The lowest level of synchronization is simply writing any changes made to the
       
    95  * <code>RowSet</code> object to its underlying data source.  The writer does
       
    96  * nothing to check for conflicts.
       
    97  * If there is a conflict and the data
       
    98  * source values are overwritten, the changes other parties have made by to the data
       
    99  * source are lost.
       
   100  * <P>
       
   101  * The <code>RIXMLProvider</code> implementation uses the lowest level
       
   102  * of synchronization and just writes <code>RowSet</code> changes to the data source.
       
   103  *
       
   104  * <P>
       
   105  * For the next level up, the
       
   106  * writer checks to see if there are any conflicts, and if there are,
       
   107  * it does not write anything to the data source.  The problem with this concurrency
       
   108  * level is that if another party has modified the corresponding data in the data source
       
   109  * since the <code>RowSet</code> object got its data,
       
   110  * the changes made to the <code>RowSet</code> object are lost. The
       
   111  * <code>RIOptimisticProvider</code> implementation uses this level of synchronization.
       
   112  * <P>
       
   113  * At higher levels of synchronization, referred to as pessimistic concurrency,
       
   114  * the writer take steps to avoid conflicts by setting locks. Setting locks
       
   115  * can vary from setting a lock on a single row to setting a lock on a table
       
   116  * or the entire data source. The level of synchronization is therefore a tradeoff
       
   117  * between the ability of users to access the data source concurrently and the  ability
       
   118  * of the writer to keep the data in the <code>RowSet</code> object and its data source
       
   119  * synchronized.
       
   120  * <P>
       
   121  * It is a requirement that all disconnected <code>RowSet</code> objects
       
   122  * (<code>CachedRowSet</code>, <code>FilteredRowSet</code>, <code>JoinRowSet</code>,
       
   123  * and <code>WebRowSet</code> objects) obtain their <code>SyncProvider</code> objects
       
   124  * from the <code>SyncFactory</code> mechanism.
       
   125  * <P>
       
   126  * The reference implementation (RI) provides two synchronization providers.
       
   127  *    <UL>
       
   128  *       <LI><b><code>RIOptimisticProvider</code></b> <br>
       
   129  *            The default provider that the <code>SyncFactory</code> instance will
       
   130  *            supply to a disconnected <code>RowSet</code> object when no provider
       
   131  *            implementation is specified.<BR>
       
   132  *            This synchronization provider uses an optimistic concurrency model,
       
   133  *            assuming that there will be few conflicts among users
       
   134  *            who are accessing the same data in a database.  It avoids
       
   135  *            using locks; rather, it checks to see if there is a conflict
       
   136  *            before trying to synchronize the <code>RowSet</code> object and the
       
   137  *            data source. If there is a conflict, it does nothing, meaning that
       
   138  *            changes to the <code>RowSet</code> object are not persisted to the data
       
   139  *            source.
       
   140  *        <LI><B><code>RIXMLProvider</code></B> <BR>
       
   141  *             A synchronization provider that can be used with a
       
   142  *             <code>WebRowSet</code> object, which is a rowset that can be written
       
   143  *             in XML format or read from XML format. The
       
   144  *             <code>RIXMLProvider</code> implementation does no checking at all for
       
   145  *             conflicts and simply writes any updated data in the
       
   146  *             <code>WebRowSet</code> object to the underlying data source.
       
   147  *             <code>WebRowSet</code> objects use this provider when they are
       
   148  *             dealing with XML data.
       
   149  *     </UL>
       
   150  *
       
   151  *  These <code>SyncProvider</code> implementations
       
   152  *  are bundled with the reference implementation, which makes them always available to
       
   153  *  <code>RowSet</code> implementations.
       
   154  *  <code>SyncProvider</code> implementations make themselves available by being
       
   155  *  registered with the <code>SyncFactory</code> singleton.  When a <code>RowSet</code>
       
   156  *  object requests a provider, by specifying it in the constructor or as an argument to the
       
   157  *  <code>CachedRowSet</code> method <code>setSyncProvider</code>,
       
   158  *  the <code>SyncFactory</code> singleton
       
   159  *  checks to see if the requested provider has been registered with it.
       
   160  *  If it has, the <code>SyncFactory</code> creates an instance of it and passes it to the
       
   161  *  requesting <code>RowSet</code> object.
       
   162  *  If the <code>SyncProvider</code> implementation that is specified has not been registered,
       
   163  *  the <code>SyncFactory</code> singleton causes a <code>SyncFactoryException</code> object
       
   164  *  to be thrown.  If no provider is specified,
       
   165  *  the <code>SyncFactory</code> singleton will create an instance of the default
       
   166  *  provider implementation, <code>RIOptimisticProvider</code>,
       
   167  *  and pass it to the requesting <code>RowSet</code> object.
       
   168  *
       
   169  * <P>
       
   170  * If a <code>WebRowSet</code> object does not specify a provider in its constructor, the
       
   171  * <code>SyncFactory</code> will give it an instance of <code>RIOptimisticProvider</code>.
       
   172  * However, the constructor for <code>WebRowSet</code> is implemented to set the provider
       
   173  * to the <code>RIXMLProvider</code>, which reads and writes a <code>RowSet</code> object
       
   174  *  in XML format.
       
   175  *  <P>
       
   176  * See the <a href="SyncProvider.html">SyncProvider</a> class
       
   177  *  specification for further details.
       
   178  * <p>
       
   179  * Vendors may develop a <code>SyncProvider</code> implementation with any one of the possible
       
   180  * levels of synchronization, thus giving <code>RowSet</code> objects a choice of
       
   181  * synchronization mechanisms.
       
   182  *
       
   183  * <h3><a id="arch">2.0 Service Provider Interface Architecture</a></h3>
       
   184  * <b>2.1 Overview</b>
       
   185  * <p>
       
   186  * The Service Provider Interface provides a pluggable mechanism by which
       
   187  * <code>SyncProvider</code> implementations can be registered and then generated when
       
   188  * required. The lazy reference mechanism employed by the <code>SyncFactory</code> limits
       
   189  * unnecessary resource consumption by not creating an instance until it is
       
   190  * required by a disconnected
       
   191  * <code>RowSet</code> object. The <code>SyncFactory</code> class also provides
       
   192  * a standard API to configure logging options and streams that <b>may</b> be provided
       
   193  * by a particular <code>SyncProvider</code> implementation.
       
   194  * <p>
       
   195  * <b>2.2 Registering with the <code>SyncFactory</code></b>
       
   196  * <p>
       
   197  * A third party <code>SyncProvider</code> implementation must be registered with the
       
   198  * <code>SyncFactory</code> in order for a disconnected <code>RowSet</code> object
       
   199  * to obtain it and thereby use its <code>javax.sql.RowSetReader</code> and
       
   200  * <code>javax.sql.RowSetWriter</code>
       
   201  * implementations. The following registration mechanisms are available to all
       
   202  * <code>SyncProvider</code> implementations:
       
   203  * <ul>
       
   204  * <li><b>System properties</b> - Properties set at the command line. These
       
   205  * properties are set at run time and apply system-wide per invocation of the Java
       
   206  * application. See the section <a href="#reldocs">"Related Documentation"</a>
       
   207  * further related information.
       
   208  *
       
   209  * <li><b>Property Files</b> - Properties specified in a standard property file.
       
   210  * This can be specified using a System Property or by modifying a standard
       
   211  * property file located in the platform run-time. The
       
   212  * reference implementation of this technology includes a standard property
       
   213  * file than can be edited to add additional <code>SyncProvider</code> objects.
       
   214  *
       
   215  * <li><b>JNDI Context</b> - Available providers can be registered on a JNDI
       
   216  * context. The <code>SyncFactory</code> will attempt to load <code>SyncProvider</code>
       
   217  * objects bound to the context and register them with the factory. This
       
   218  * context must be supplied to the <code>SyncFactory</code> for the mechanism to
       
   219  * function correctly.
       
   220  * </ul>
       
   221  * <p>
       
   222  * Details on how to specify the system properties or properties in a property file
       
   223  * and how to configure the JNDI Context are explained in detail in the
       
   224  * <a href="SyncFactory.html"><code>SyncFactory</code></a> class description.
       
   225  * <p>
       
   226  * <b>2.3 SyncFactory Provider Instance Generation Policies</b>
       
   227  * <p>
       
   228  * The <code>SyncFactory</code> generates a requested <code>SyncProvider</code>
       
   229  * object if the provider has been correctly registered.  The
       
   230  * following policies are adhered to when either a disconnected <code>RowSet</code> object
       
   231  * is instantiated with a specified <code>SyncProvider</code> implementation or is
       
   232  * reconfigured at runtime with an alternative <code>SyncProvider</code> object.
       
   233  * <ul>
       
   234  * <li> If a <code>SyncProvider</code> object is specified and the <code>SyncFactory</code>
       
   235  * contains <i>no</i> reference to the provider, a <code>SyncFactoryException</code> is
       
   236  * thrown.
       
   237  *
       
   238  * <li> If a <code>SyncProvider</code> object is specified and the <code>SyncFactory</code>
       
   239  * contains a reference to the provider, the requested provider is supplied.
       
   240  *
       
   241  * <li> If no <code>SyncProvider</code> object is specified, the reference
       
   242  * implementation provider <code>RIOptimisticProvider</code> is supplied.
       
   243  * </ul>
       
   244  * <p>
       
   245  * These policies are explored in more detail in the <a href="SyncFactory.html">
       
   246  * <code>SyncFactory</code></a> class.
       
   247  *
       
   248  * <h3><a id="impl">3.0 SyncProvider Implementer's Guide</a></h3>
       
   249  *
       
   250  * <b>3.1 Requirements</b>
       
   251  * <p>
       
   252  * A compliant <code>SyncProvider</code> implementation that is fully pluggable
       
   253  * into the <code>SyncFactory</code> <b>must</b> extend and implement all
       
   254  * abstract methods in the <a href="SyncProvider.html"><code>SyncProvider</code></a>
       
   255  * class. In addition, an implementation <b>must</b> determine the
       
   256  * grade, locking and updatable view capabilities defined in the
       
   257  * <code>SyncProvider</code> class definition. One or more of the
       
   258  * <code>SyncProvider</code> description criteria <b>must</b> be supported. It
       
   259  * is expected that vendor implementations will offer a range of grade, locking, and
       
   260  * updatable view capabilities.
       
   261  * <p>
       
   262  * Furthermore, the <code>SyncProvider</code> naming convention <b>must</b> be followed as
       
   263  * detailed in the <a href="SyncProvider.html"><code>SyncProvider</code></a> class
       
   264  * description.
       
   265  * <p>
       
   266  * <b>3.2 Grades</b>
       
   267  * <p>
       
   268  * JSR 114 defines a set of grades to describe the quality of synchronization
       
   269  * a <code>SyncProvider</code> object can offer a disconnected <code>RowSet</code>
       
   270  * object. These grades are listed from the lowest quality of service to the highest.
       
   271  * <ul>
       
   272  * <li><b>GRADE_NONE</b> - No synchronization with the originating data source is
       
   273  * provided. A <code>SyncProvider</code> implementation returning this grade will simply
       
   274  * attempt to write any data that has changed in the <code>RowSet</code> object to the
       
   275  *underlying data source, overwriting whatever is there. No attempt is made to compare
       
   276  * original values with current values to see if there is a conflict. The
       
   277  * <code>RIXMLProvider</code> is implemented with this grade.
       
   278  *
       
   279  * <li><b>GRADE_CHECK_MODIFIED_AT_COMMIT</b> - A low grade of optimistic synchronization.
       
   280  * A <code>SyncProvider</code> implementation returning this grade
       
   281  * will check for conflicts in rows that have changed between the last synchronization
       
   282  * and the current synchronization under way. Any changes in the originating data source
       
   283  * that have been modified will not be reflected in the disconnected <code>RowSet</code>
       
   284  * object. If there are no conflicts, changes in the <code>RowSet</code> object will be
       
   285  * written to the data source. If there are conflicts, no changes are written.
       
   286  * The <code>RIOptimisticProvider</code> implementation uses this grade.
       
   287  *
       
   288  * <li><b>GRADE_CHECK_ALL_AT_COMMIT</b> - A high grade of optimistic synchronization.
       
   289  * A <code>SyncProvider</code> implementation   returning this grade
       
   290  * will check all rows, including rows that have not changed in the disconnected
       
   291  * <code>RowSet</code> object. In this way, any changes to rows in the underlying
       
   292  * data source will be reflected in the disconnected <code>RowSet</code> object
       
   293  * when the synchronization finishes successfully.
       
   294  *
       
   295  * <li><b>GRADE_LOCK_WHEN_MODIFIED</b> - A pessimistic grade of synchronization.
       
   296  * <code>SyncProvider</code> implementations returning this grade will lock
       
   297  * the row in the originating  data source that corresponds to the row being changed
       
   298  * in the <code>RowSet</code> object to reduce the possibility of other
       
   299  * processes modifying the same data in the data source.
       
   300  *
       
   301  * <li><b>GRADE_LOCK_WHEN_LOADED</b> - A higher pessimistic synchronization grade.
       
   302  * A <code>SyncProvider</code> implementation returning this grade will lock
       
   303  * the entire view and/or  table affected by the original query used to
       
   304  * populate a <code>RowSet</code> object.
       
   305  * </ul>
       
   306  * <p>
       
   307  * <b>3.3 Locks</b>
       
   308  * <p>
       
   309  * JSR 114 defines a set of constants that specify whether any locks have been
       
   310  * placed on a <code>RowSet</code> object's underlying data source and, if so,
       
   311  * on which constructs the locks are placed.  These locks will remain on the data
       
   312  * source while the <code>RowSet</code> object is disconnected from the data source.
       
   313  * <P>
       
   314  * These constants <b>should</b> be considered complementary to the
       
   315  * grade constants. The default setting for the majority of grade settings requires
       
   316  * that no data source locks remain when a <code>RowSet</code> object is disconnected
       
   317  * from its data source.
       
   318  * The grades <code>GRADE_LOCK_WHEN_MODIFIED</code> and
       
   319  * <code>GRADE_LOCK_WHEN_LOADED</code> allow a disconnected <code>RowSet</code> object
       
   320  * to have a fine-grained control over the degree of locking.
       
   321  * <ul>
       
   322  * <li><b>DATASOURCE_NO_LOCK</b> - No locks remain on the originating data source.
       
   323  * This is the default lock setting for all <code>SyncProvider</code> implementations
       
   324  * unless otherwise directed by a <code>RowSet</code> object.
       
   325  *
       
   326  * <li><b>DATASOURCE_ROW_LOCK</b> - A lock is placed on the rows that are touched by
       
   327  * the original SQL query used to populate the <code>RowSet</code> object.
       
   328  *
       
   329  * <li><b>DATASOURCE_TABLE_LOCK</b> - A lock is placed on all tables that are touched
       
   330  * by the query that was used to populate the <code>RowSet</code> object.
       
   331  *
       
   332  * <li><b>DATASOURCE_DB_LOCK</b>
       
   333  * A lock is placed on the entire data source that is used by the <code>RowSet</code>
       
   334  * object.
       
   335  * </ul>
       
   336  * <p>
       
   337  * <b>3.4 Updatable Views</b>
       
   338  * <p>
       
   339  * A <code>RowSet</code> object may be populated with data from an SQL <code>VIEW</code>.
       
   340  * The following constants indicate whether a <code>SyncProvider</code> object can
       
   341  * update data in the table or tables from which the <code>VIEW</code> was derived.
       
   342  * <ul>
       
   343  * <li><b>UPDATABLE_VIEW_SYNC</b>
       
   344  * Indicates that a <code>SyncProvider</code> implementation  supports synchronization
       
   345  * to the table or tables from which the SQL <code>VIEW</code> used to populate
       
   346  * a <code>RowSet</code> object is derived.
       
   347  *
       
   348  * <li><b>NONUPDATABLE_VIEW_SYNC</b>
       
   349  * Indicates that a <code>SyncProvider</code> implementation  does <b>not</b> support
       
   350  * synchronization to the table or tables from which the SQL <code>VIEW</code>
       
   351  * used to populate  a <code>RowSet</code> object is derived.
       
   352  * </ul>
       
   353  * <p>
       
   354  * <b>3.5 Usage of <code>SyncProvider</code> Grading and Locking</b>
       
   355  * <p>
       
   356  * In the example below, the reference <code>CachedRowSetImpl</code> implementation
       
   357  * reconfigures its current <code>SyncProvider</code> object by calling the
       
   358  * <code>setSyncProvider</code> method.<br>
       
   359  *
       
   360  * <PRE>
       
   361  *   CachedRowSetImpl crs = new CachedRowSetImpl();
       
   362  *   crs.setSyncProvider("com.foo.bar.HASyncProvider");
       
   363  * </PRE>
       
   364  *   An application can retrieve the <code>SyncProvider</code> object currently in use
       
   365  * by a disconnected <code>RowSet</code> object. It can also retrieve the
       
   366  * grade of synchronization with which the provider was implemented and the degree of
       
   367  * locking currently in use.  In addition, an application has the flexibility to set
       
   368  * the degree of locking to be used, which can increase the possibilities for successful
       
   369  * synchronization.  These operation are shown in the following code fragment.
       
   370  * <PRE>
       
   371  *   SyncProvider sync = crs.getSyncProvider();
       
   372  *
       
   373  *   switch (sync.getProviderGrade()) {
       
   374  *   case: SyncProvider.GRADE_CHECK_ALL_AT_COMMIT
       
   375  *         //A high grade of optimistic synchronization
       
   376  *    break;
       
   377  *    case: SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT
       
   378  *         //A low grade of optimistic synchronization
       
   379  *    break;
       
   380  *    case: SyncProvider.GRADE_LOCK_WHEN_LOADED
       
   381  *         // A pessimistic synchronization grade
       
   382  *    break;
       
   383  *    case: SyncProvider.GRADE_LOCK_WHEN_MODIFIED
       
   384  *         // A pessimistic synchronization grade
       
   385  *    break;
       
   386  *    case: SyncProvider.GRADE_NONE
       
   387  *      // No synchronization with the originating data source provided
       
   388  *    break;
       
   389  *    }
       
   390  *
       
   391  *    switch (sync.getDataSourcLock() {
       
   392  *      case: SyncProvider.DATASOURCE_DB_LOCK
       
   393  *       // A lock is placed on the entire datasource that is used by the
       
   394  *       // <code>RowSet</code> object
       
   395  *       break;
       
   396  *
       
   397  *      case: SyncProvider.DATASOURCE_NO_LOCK
       
   398  *       // No locks remain on the  originating data source.
       
   399  *      break;
       
   400  *
       
   401  *      case: SyncProvider.DATASOURCE_ROW_LOCK
       
   402  *       // A lock is placed on the rows that are  touched by the original
       
   403  *       // SQL statement used to populate
       
   404  *       // the RowSet object that is using the SyncProvider
       
   405  *       break;
       
   406  *
       
   407  *      case: DATASOURCE_TABLE_LOCK
       
   408  *       // A lock is placed on  all tables that are touched by the original
       
   409  *       // SQL statement used to populated
       
   410  *       // the RowSet object that is using the SyncProvider
       
   411  *      break;
       
   412  *
       
   413  * </PRE>
       
   414  *    It is also possible using the static utility method in the
       
   415  * <code>SyncFactory</code> class to determine the list of <code>SyncProvider</code>
       
   416  * implementations currently registered with the <code>SyncFactory</code>.
       
   417  *
       
   418  * <pre>
       
   419  *       Enumeration e = SyncFactory.getRegisteredProviders();
       
   420  * </pre>
       
   421  *
       
   422  *
       
   423  * <h3><a id="resolving">4.0 Resolving Synchronization Conflicts</a></h3>
       
   424  *
       
   425  * The interface <code>SyncResolver</code> provides a way for an application to
       
   426  * decide manually what to do when a conflict occurs. When the <code>CachedRowSet</code>
       
   427  * method <code>acceptChanges</code> finishes and has detected one or more conflicts,
       
   428  * it throws a <code>SyncProviderException</code> object.  An application can
       
   429  * catch the exception and
       
   430  * have it retrieve a <code>SyncResolver</code> object by calling the method
       
   431  * <code>SyncProviderException.getSyncResolver()</code>.
       
   432  * <P>
       
   433  * A <code>SyncResolver</code> object, which is a special kind of
       
   434  * <code>CachedRowSet</code> object or
       
   435  * a <code>JdbcRowSet</code> object that has implemented the <code>SyncResolver</code>
       
   436  * interface,  examines the conflicts row by row. It is a duplicate of the
       
   437  * <code>RowSet</code> object being synchronized except that it contains only the data
       
   438  * from the data source this is causing a conflict. All of the other column values are
       
   439  * set to <code>null</code>. To navigate from one conflict value to another, a
       
   440  * <code>SyncResolver</code> object provides the methods <code>nextConflict</code> and
       
   441  * <code>previousConflict</code>.
       
   442  * <P>
       
   443  * The <code>SyncResolver</code> interface also
       
   444  * provides methods for doing the following:
       
   445  * <UL>
       
   446  *  <LI>finding out whether the conflict involved an update, a delete, or an insert
       
   447  *  <LI>getting the value in the data source that caused the conflict
       
   448  *  <LI>setting the value that should be in the data source if it needs to be changed
       
   449  *      or setting the value that should be in the <code>RowSet</code> object if it needs
       
   450  *      to be changed
       
   451  * </UL>
       
   452  * <P>
       
   453  * When the <code>CachedRowSet</code> method <code>acceptChanges</code> is called, it
       
   454  * delegates to the <code>RowSet</code> object's  <code>SyncProvider</code> object.
       
   455  * How the writer provided by that <code>SyncProvider</code> object is implemented
       
   456  * determines what level (grade) of checking for conflicts will be done.  After all
       
   457  * checking for conflicts is completed and one or more conflicts has been found, the method
       
   458  * <code>acceptChanges</code> throws a <code>SyncProviderException</code> object. The
       
   459  * application can catch the exception and use it to obtain a <code>SyncResolver</code> object.
       
   460  * <P>
       
   461  * The application can then use <code>SyncResolver</code> methods to get information
       
   462  * about each conflict and decide what to do.  If the application logic or the user
       
   463  * decides that a value in the <code>RowSet</code> object should be the one to
       
   464  * persist, the application or user can overwrite the data source value with it.
       
   465  * <P>
       
   466  * The comment for the <code>SyncResolver</code> interface has more detail.
       
   467  *
       
   468  * <h3><a id="relspec">5.0 Related Specifications</a></h3>
       
   469  * <ul>
       
   470  * <li><a href="http://docs.oracle.com/javase/jndi/tutorial/index.html">JNDI</a>
       
   471  * <li><a href="{@docRoot}/java.logging/java/util/logging/package-summary.html">Java Logging
       
   472  * APIs</a>
       
   473  * </ul>
       
   474  * <h3><a id="reldocs">6.0 Related Documentation</a></h3>
       
   475  * <ul>
       
   476  * <li><a href="http://docs.oracle.com/javase/tutorial/jdbc/">DataSource for JDBC
       
   477  * Connections</a>
       
   478  * </ul>
       
   479  */
       
   480 package javax.sql.rowset.spi;