src/share/classes/javax/sql/rowset/spi/SyncResolver.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 2004, 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


  64  * a rowset's <code>SyncProvider</code> object creates an instance of
  65  * <code>SyncResolver</code>. This new <code>SyncResolver</code> object has
  66  * the same number of rows and columns as the
  67  * <code>RowSet</code> object that was attempting the synchronization. The
  68  * <code>SyncResolver</code> object contains the values from the data source that caused
  69  * the conflict(s) and <code>null</code> for all other values.
  70  * In addition, it contains information about each conflict.
  71  * <P>
  72  *
  73  * <H2>Getting and Using a <code>SyncResolver</code> Object</H2>
  74  *
  75  * When the method <code>acceptChanges</code> encounters conflicts, the
  76  * <code>SyncProvider</code> object creates a <code>SyncProviderException</code>
  77  * object and sets it with the new <code>SyncResolver</code> object. The method
  78  * <code>acceptChanges</code> will throw this exception, which
  79  * the application can then catch and use to retrieve the
  80  * <code>SyncResolver</code> object it contains. The following code snippet uses the
  81  * <code>SyncProviderException</code> method <code>getSyncResolver</code> to get
  82  * the <code>SyncResolver</code> object <i>resolver</i>.
  83  * <PRE>

  84  *     } catch (SyncProviderException spe) {
  85  *         SyncResolver resolver = spe.getSyncResolver();
  86  *     ...
  87  *     }


  88  * </PRE>
  89  * <P>
  90  * With <i>resolver</i> in hand, an application can use it to get the information
  91  * it contains about the conflict or conflicts.  A <code>SyncResolver</code> object
  92  * such as <i>resolver</i> keeps
  93  * track of the conflicts for each row in which there is a conflict.  It also places a
  94  * lock on the table or tables affected by the rowset's command so that no more
  95  * conflicts can occur while the current conflicts are being resolved.
  96  * <P>
  97  * The following kinds of information can be obtained from a <code>SyncResolver</code>
  98  * object:
  99  * <P>
 100  *    <LI>What operation was being attempted when a conflict occurred<BR>
 101  * The <code>SyncProvider</code> interface defines four constants
 102  * describing states that may occur. Three
 103  * constants describe the type of operation (update, delete, or insert) that a
 104  * <code>RowSet</code> object was attempting to perform when a conflict was discovered,
 105  * and the fourth indicates that there is no conflict.
 106  * These constants are the possible return values when a <code>SyncResolver</code> object
 107  * calls the method <code>getStatus</code>.
 108  * <PRE>
 109  *     int operation = resolver.getStatus();
 110  * </PRE>
 111  * <P>
 112  *    <LI>The value in the data source that caused a conflict<BR>
 113  * A conflict exists when a value that a <code>RowSet</code> object has changed
 114  * and is attempting to write to the data source
 115  * has also been changed in the data source since the last synchronization.  An
 116  * application can call the <code>SyncResolver</code> method
 117  * <code>getConflictValue</code > to retrieve the
 118  * value in the data source that is the cause of the conflict because the values in a
 119  * <code>SyncResolver</code> object are the conflict values from the data source.
 120  * <PRE>
 121  *     java.lang.Object conflictValue = resolver.getConflictValue(2);
 122  * </PRE>
 123  * Note that the column in <i>resolver</i> can be designated by the column number,
 124  * as is done in the preceding line of code, or by the column name.
 125  * </UL>
 126  * <P>
 127  * With the information retrieved from the methods <code>getStatus</code> and
 128  * <code>getConflictValue</code>, the application may make a determination as to
 129  * which value should be persisted in the data source. The application then calls the
 130  * <code>SyncResolver</code> method <code>setResolvedValue</code>, which sets the value
 131  * to be persisted in the <code>RowSet</code> object and also in the data source.
 132  * <PRE>
 133  *     resolver.setResolvedValue("DEPT", 8390426);
 134  * </PRE>
 135  * In the preceding line of code,
 136  * the column name designates the column in the <code>RowSet</code> object
 137  * that is to be set with the given value. The column number can also be used to
 138  * designate the column.
 139  * <P>
 140  * An application calls the method <code>setResolvedValue</code> after it has
 141  * resolved all of the conflicts in the current conflict row and repeats this process
 142  * for each conflict row in the <code>SyncResolver</code> object.
 143  * <P>
 144  *
 145  * <H2>Navigating a <code>SyncResolver</code> Object</H2>


 176  * illustrates one of the many ways a <code>SyncResolver</code> object can be used,
 177  * the <code>SyncResolver</code> method <code>nextConflict</code> is used in a
 178  * <code>while</code> loop. The loop will end when <code>nextConflict</code> returns
 179  * <code>false</code>, which will occur when there are no more conflict rows in the
 180  * <code>SyncResolver</code> object <i>resolver</i>. In This particular code fragment,
 181  * <i>resolver</i> looks for rows that have update conflicts (rows with the status
 182  * <code>SyncResolver.UPDATE_ROW_CONFLICT</code>), and the rest of this code fragment
 183  * executes only for rows where conflicts occurred because <i>crs</i> was attempting an
 184  * update.
 185  * <P>
 186  * After the cursor for <i>resolver</i> has moved to the next conflict row that
 187  * has an update conflict, the method <code>getRow</code> indicates the number of the
 188  * current row, and
 189  * the cursor for the <code>CachedRowSet</code> object <i>crs</i> is moved to
 190  * the comparable row in <i>crs</i>. By iterating
 191  * through the columns of that row in both <i>resolver</i> and <i>crs</i>, the conflicting
 192  * values can be retrieved and compared to decide which one should be persisted. In this
 193  * code fragment, the value in <i>crs</i> is the one set as the resolved value, which means
 194  * that it will be used to overwrite the conflict value in the data source.
 195  *
 196  * <PRE>{@code

 197  *     try {
 198  *
 199  *         crs.acceptChanges(con);
 200  *
 201  *     } catch (SyncProviderException spe) {
 202  *
 203  *         SyncResolver resolver = spe.getSyncResolver();
 204  *
 205  *         Object crsValue;  // value in the RowSet object
 206  *         Object resolverValue:  // value in the SyncResolver object
 207  *         Object resolvedValue:  // value to be persisted
 208  *
 209  *         while(resolver.nextConflict())  {
 210  *             if(resolver.getStatus() == SyncResolver.UPDATE_ROW_CONFLICT)  {
 211  *                 int row = resolver.getRow();
 212  *                 crs.absolute(row);
 213  *
 214  *                 int colCount = crs.getMetaData().getColumnCount();
 215  *                 for(int j = 1; j <= colCount; j++) {
 216  *                     if (resolver.getConflictValue(j) != null)  {


   1 /*
   2  * Copyright (c) 2003, 2013, 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


  64  * a rowset's <code>SyncProvider</code> object creates an instance of
  65  * <code>SyncResolver</code>. This new <code>SyncResolver</code> object has
  66  * the same number of rows and columns as the
  67  * <code>RowSet</code> object that was attempting the synchronization. The
  68  * <code>SyncResolver</code> object contains the values from the data source that caused
  69  * the conflict(s) and <code>null</code> for all other values.
  70  * In addition, it contains information about each conflict.
  71  * <P>
  72  *
  73  * <H2>Getting and Using a <code>SyncResolver</code> Object</H2>
  74  *
  75  * When the method <code>acceptChanges</code> encounters conflicts, the
  76  * <code>SyncProvider</code> object creates a <code>SyncProviderException</code>
  77  * object and sets it with the new <code>SyncResolver</code> object. The method
  78  * <code>acceptChanges</code> will throw this exception, which
  79  * the application can then catch and use to retrieve the
  80  * <code>SyncResolver</code> object it contains. The following code snippet uses the
  81  * <code>SyncProviderException</code> method <code>getSyncResolver</code> to get
  82  * the <code>SyncResolver</code> object <i>resolver</i>.
  83  * <PRE>
  84  * {@code 
  85  *     } catch (SyncProviderException spe) {
  86  *         SyncResolver resolver = spe.getSyncResolver();
  87  *     ...
  88  *     }
  89  * 
  90  * }
  91  * </PRE>
  92  * <P>
  93  * With <i>resolver</i> in hand, an application can use it to get the information
  94  * it contains about the conflict or conflicts.  A <code>SyncResolver</code> object
  95  * such as <i>resolver</i> keeps
  96  * track of the conflicts for each row in which there is a conflict.  It also places a
  97  * lock on the table or tables affected by the rowset's command so that no more
  98  * conflicts can occur while the current conflicts are being resolved.
  99  * <P>
 100  * The following kinds of information can be obtained from a <code>SyncResolver</code>
 101  * object:
 102  * <P>
 103  *    <h3>What operation was being attempted when a conflict occurred</h3>
 104  * The <code>SyncProvider</code> interface defines four constants
 105  * describing states that may occur. Three
 106  * constants describe the type of operation (update, delete, or insert) that a
 107  * <code>RowSet</code> object was attempting to perform when a conflict was discovered,
 108  * and the fourth indicates that there is no conflict.
 109  * These constants are the possible return values when a <code>SyncResolver</code> object
 110  * calls the method <code>getStatus</code>.
 111  * <PRE>
 112  *     {@code int operation = resolver.getStatus(); }
 113  * </PRE>
 114  * <P>
 115  *    <h3>The value in the data source that caused a conflict</h3>
 116  * A conflict exists when a value that a <code>RowSet</code> object has changed
 117  * and is attempting to write to the data source
 118  * has also been changed in the data source since the last synchronization.  An
 119  * application can call the <code>SyncResolver</code> method
 120  * <code>getConflictValue</code > to retrieve the
 121  * value in the data source that is the cause of the conflict because the values in a
 122  * <code>SyncResolver</code> object are the conflict values from the data source.
 123  * <PRE>
 124  *     java.lang.Object conflictValue = resolver.getConflictValue(2);
 125  * </PRE>
 126  * Note that the column in <i>resolver</i> can be designated by the column number,
 127  * as is done in the preceding line of code, or by the column name.

 128  * <P>
 129  * With the information retrieved from the methods <code>getStatus</code> and
 130  * <code>getConflictValue</code>, the application may make a determination as to
 131  * which value should be persisted in the data source. The application then calls the
 132  * <code>SyncResolver</code> method <code>setResolvedValue</code>, which sets the value
 133  * to be persisted in the <code>RowSet</code> object and also in the data source.
 134  * <PRE>
 135  *     resolver.setResolvedValue("DEPT", 8390426);
 136  * </PRE>
 137  * In the preceding line of code,
 138  * the column name designates the column in the <code>RowSet</code> object
 139  * that is to be set with the given value. The column number can also be used to
 140  * designate the column.
 141  * <P>
 142  * An application calls the method <code>setResolvedValue</code> after it has
 143  * resolved all of the conflicts in the current conflict row and repeats this process
 144  * for each conflict row in the <code>SyncResolver</code> object.
 145  * <P>
 146  *
 147  * <H2>Navigating a <code>SyncResolver</code> Object</H2>


 178  * illustrates one of the many ways a <code>SyncResolver</code> object can be used,
 179  * the <code>SyncResolver</code> method <code>nextConflict</code> is used in a
 180  * <code>while</code> loop. The loop will end when <code>nextConflict</code> returns
 181  * <code>false</code>, which will occur when there are no more conflict rows in the
 182  * <code>SyncResolver</code> object <i>resolver</i>. In This particular code fragment,
 183  * <i>resolver</i> looks for rows that have update conflicts (rows with the status
 184  * <code>SyncResolver.UPDATE_ROW_CONFLICT</code>), and the rest of this code fragment
 185  * executes only for rows where conflicts occurred because <i>crs</i> was attempting an
 186  * update.
 187  * <P>
 188  * After the cursor for <i>resolver</i> has moved to the next conflict row that
 189  * has an update conflict, the method <code>getRow</code> indicates the number of the
 190  * current row, and
 191  * the cursor for the <code>CachedRowSet</code> object <i>crs</i> is moved to
 192  * the comparable row in <i>crs</i>. By iterating
 193  * through the columns of that row in both <i>resolver</i> and <i>crs</i>, the conflicting
 194  * values can be retrieved and compared to decide which one should be persisted. In this
 195  * code fragment, the value in <i>crs</i> is the one set as the resolved value, which means
 196  * that it will be used to overwrite the conflict value in the data source.
 197  *
 198  * <PRE>
 199  * {@code
 200  *     try {
 201  *
 202  *         crs.acceptChanges(con);
 203  *
 204  *     } catch (SyncProviderException spe) {
 205  *
 206  *         SyncResolver resolver = spe.getSyncResolver();
 207  *
 208  *         Object crsValue;  // value in the RowSet object
 209  *         Object resolverValue:  // value in the SyncResolver object
 210  *         Object resolvedValue:  // value to be persisted
 211  *
 212  *         while(resolver.nextConflict())  {
 213  *             if(resolver.getStatus() == SyncResolver.UPDATE_ROW_CONFLICT)  {
 214  *                 int row = resolver.getRow();
 215  *                 crs.absolute(row);
 216  *
 217  *                 int colCount = crs.getMetaData().getColumnCount();
 218  *                 for(int j = 1; j <= colCount; j++) {
 219  *                     if (resolver.getConflictValue(j) != null)  {