/*
 * Copyright 2003-2004 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.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.
 * <p>
 *
 * <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.
 * <P>
 *
 * <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>
 *     } 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:
 * <P>
 *    <LI>What operation was being attempted when a conflict occurred<BR>
 * 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>
 *     int operation = resolver.getStatus();
 * </PRE>
 * <P>
 *    <LI>The value in the data source that caused a conflict<BR>
 * 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.
 * </UL>
 * <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.
 * <P>
 *
 * <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>
 *     try {
 *
 *         crs.acceptChanges(con);
 *
 *     } catch (SyncProviderException spe) {
 *
 *         SyncResolver resolver = spe.getSyncResolver();
 *
 *         Object crsValue;  // value in the <code>RowSet</code> object
 *         Object resolverValue:  // value in the <code>SyncResolver</code> object
 *         Object resolvedValue:  // value to be persisted
 *
 *         while(resolver.nextConflict())  {
 *             if(resolver.getStatus() == SyncResolver.UPDATE_ROW_CONFLICT)  {
 *                 int row = resolver.getRow();
 *                 crs.absolute(row);
 *
 *                 int colCount = crs.getMetaData().getColumnCount();
 *                 for(int j = 1; j <= colCount; j++) {
 *                     if (resolver.getConflictValue(j) != null)  {
 *                         crsValue = crs.getObject(j);
 *                         resolverValue = resolver.getConflictValue(j);
 *                         . . .
 *                         // compare crsValue and resolverValue to determine
 *                         // which should be the resolved value (the value to persist)
 *                         resolvedValue = crsValue;
 *
 *                         resolver.setResolvedValue(j, resolvedValue);
 *                      }
 *                  }
 *              }
 *          }
 *      }
 * </PRE>
 * @author  Jonathan Bruce
 */

public interface SyncResolver extends RowSet {
    /**
     * Indicates that a conflict occurred while the <code>RowSet</code> object was
     * attempting to update a row in the data source.
     * The values in the data source row to be updated differ from the
     * <code>RowSet</code> object's original values for that row, which means that
     * the row in the data source has been updated or deleted since the last
     * synchronization.
     */
     public static int UPDATE_ROW_CONFLICT = 0;

    /**
     * Indicates that a conflict occurred while the <code>RowSet</code> object was
     * attempting to delete a row in the data source.
     * The values in the data source row to be updated differ from the
     * <code>RowSet</code> object's original values for that row, which means that
     * the row in the data source has been updated or deleted since the last
     * synchronization.
     */
    public static int DELETE_ROW_CONFLICT = 1;

   /**
    * Indicates that a conflict occurred while the <code>RowSet</code> object was
    * attempting to insert a row into the data source.  This means that a
    * row with the same primary key as the row to be inserted has been inserted
    * into the data source since the last synchronization.
    */
    public static int INSERT_ROW_CONFLICT = 2;

    /**
     * Indicates that <b>no</b> conflict occured 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 pertitent 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;

}
