Source Code Cross Referenced for SyncResolver.java in  » 6.0-JDK-Core » sql » javax » sql » rowset » spi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » sql » javax.sql.rowset.spi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 2003-2004 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025
026        package javax.sql.rowset.spi;
027
028        import javax.sql.RowSet;
029        import java.sql.SQLException;
030
031        /**
032         * Defines a framework that allows applications to use a manual decision tree
033         * to decide what should be done when a synchronization conflict occurs.
034         * Although it is not mandatory for 
035         * applications to resolve synchronization conflicts manually, this
036         * framework provides the means to delegate to the application when conflicts 
037         * arise.
038         * <p>
039         * Note that a conflict is a situation where the <code>RowSet</code> object's original
040         * values for a row do not match the values in the data source, which indicates that 
041         * the data source row has been modified since the last synchronization. Note also that
042         * a <code>RowSet</code> object's original values are the values it had just prior to the
043         * the last synchronization, which are not necessarily its initial values.
044         * <p>
045         *
046         * <H2>Description of a <code>SyncResolver</code> Object</H2>
047         * 
048         * A <code>SyncResolver</code> object is a specialized <code>RowSet</code> object
049         * that implements the <code>SyncResolver</code> interface. 
050         * It <b>may</b> operate as either a connected <code>RowSet</code> object (an
051         * implementation of the <code>JdbcRowSet</code> interface) or a connected
052         * <code>RowSet</code> object (an implementation of the
053         * <code>CachedRowSet</code> interface or one of its subinterfaces). For information
054         * on the subinterfaces, see the 
055         * <a href="../package-summary.html"><code>javax.sql.rowset</code></a> package
056         * description. The reference implementation for <code>SyncResolver</code> implements
057         * the <code>CachedRowSet</code> interface, but other implementations
058         * may choose to implement the <code>JdbcRowSet</code> interface to satisfy 
059         * particular needs.
060         * <P> 
061         * After an application has attempted to synchronize a <code>RowSet</code> object with
062         * the data source (by calling the <code>CachedRowSet</code>
063         * method <code>acceptChanges</code>), and one or more conflicts have been found,
064         * a rowset's <code>SyncProvider</code> object creates an instance of 
065         * <code>SyncResolver</code>. This new <code>SyncResolver</code> object has
066         * the same number of rows and columns as the
067         * <code>RowSet</code> object that was attempting the synchronization. The
068         * <code>SyncResolver</code> object contains the values from the data source that caused
069         * the conflict(s) and <code>null</code> for all other values.
070         * In addition, it contains information about each conflict.
071         * <P>
072         *
073         * <H2>Getting and Using a <code>SyncResolver</code> Object</H2>
074         * 
075         * When the method <code>acceptChanges</code> encounters conflicts, the 
076         * <code>SyncProvider</code> object creates a <code>SyncProviderException</code> 
077         * object and sets it with the new <code>SyncResolver</code> object. The method
078         * <code>acceptChanges</code> will throw this exception, which
079         * the application can then catch and use to retrieve the 
080         * <code>SyncResolver</code> object it contains. The following code snippet uses the
081         * <code>SyncProviderException</code> method <code>getSyncResolver</code> to get
082         * the <code>SyncResolver</code> object <i>resolver</i>.  
083         * <PRE>
084         *     } catch (SyncProviderException spe) {
085         *         SyncResolver resolver = spe.getSyncResolver();
086         *     ...
087         *     }
088         * </PRE>
089         * <P>
090         * With <i>resolver</i> in hand, an application can use it to get the information
091         * it contains about the conflict or conflicts.  A <code>SyncResolver</code> object
092         * such as <i>resolver</i> keeps
093         * track of the conflicts for each row in which there is a conflict.  It also places a
094         * lock on the table or tables affected by the rowset's command so that no more
095         * conflicts can occur while the current conflicts are being resolved.
096         * <P>
097         * The following kinds of information can be obtained from a <code>SyncResolver</code>
098         * object: 
099         * <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>
146         *
147         * Because a <code>SyncResolver</code> object is a <code>RowSet</code> object, an
148         * application can use all of the <code>RowSet</code> methods for moving the cursor
149         * to navigate a <code>SyncResolver</code> object. For example, an application can
150         * use the <code>RowSet</code> method <code>next</code> to get to each row and then 
151         * call the <code>SyncResolver</code> method <code>getStatus</code> to see if the row
152         * contains a conflict.  In a row with one or more conflicts, the application can 
153         * iterate through the columns to find any non-null values, which will be the values
154         * from the data source that are in conflict.
155         * <P> 
156         * To make it easier to navigate a <code>SyncResolver</code> object, especially when 
157         * there are large numbers of rows with no conflicts, the <code>SyncResolver</code>
158         * interface defines the methods <code>nextConflict</code> and
159         * <code>previousConflict</code>, which move only to rows
160         * that contain at least one conflict value. Then an application can call the 
161         * <code>SyncResolver</code> method <code>getConflictValue</code>, supplying it
162         * with the column number, to get the conflict value itself. The code fragment in the
163         * next section gives an example.
164         *
165         * <H2>Code Example</H2>
166         * 
167         * The following code fragment demonstrates how a disconnected <code>RowSet</code>
168         * object <i>crs</i> might attempt to synchronize itself with the
169         * underlying data source and then resolve the conflicts. In the <code>try</code>
170         * block, <i>crs</i> calls the method <code>acceptChanges</code>, passing it the
171         * <code>Connection</code> object <i>con</i>.  If there are no conflicts, the
172         * changes in <i>crs</i> are simply written to the data source.  However, if there
173         * is a conflict, the method <code>acceptChanges</code> throws a
174         * <code>SyncProviderException</code> object, and the 
175         * <code>catch</code> block takes effect.  In this example, which
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>
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 <code>RowSet</code> object 
206         *         Object resolverValue:  // value in the <code>SyncResolver</code> 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)  {
217         *                         crsValue = crs.getObject(j);
218         *                         resolverValue = resolver.getConflictValue(j);
219         *                         . . . 
220         *                         // compare crsValue and resolverValue to determine
221         *                         // which should be the resolved value (the value to persist)
222         *                         resolvedValue = crsValue;
223         *
224         *                         resolver.setResolvedValue(j, resolvedValue);
225         *                      } 
226         *                  } 
227         *              }
228         *          }
229         *      }
230         * </PRE>
231         * @author  Jonathan Bruce
232         */
233
234        public interface SyncResolver extends RowSet {
235            /**
236             * Indicates that a conflict occurred while the <code>RowSet</code> object was
237             * attempting to update a row in the data source. 
238             * The values in the data source row to be updated differ from the
239             * <code>RowSet</code> object's original values for that row, which means that
240             * the row in the data source has been updated or deleted since the last 
241             * synchronization. 
242             */
243            public static int UPDATE_ROW_CONFLICT = 0;
244
245            /** 
246             * Indicates that a conflict occurred while the <code>RowSet</code> object was
247             * attempting to delete a row in the data source.
248             * The values in the data source row to be updated differ from the
249             * <code>RowSet</code> object's original values for that row, which means that 
250             * the row in the data source has been updated or deleted since the last 
251             * synchronization. 
252             */
253            public static int DELETE_ROW_CONFLICT = 1;
254
255            /**
256             * Indicates that a conflict occurred while the <code>RowSet</code> object was
257             * attempting to insert a row into the data source.  This means that a
258             * row with the same primary key as the row to be inserted has been inserted
259             * into the data source since the last synchronization.
260             */
261            public static int INSERT_ROW_CONFLICT = 2;
262
263            /**
264             * Indicates that <b>no</b> conflict occured while the <code>RowSet</code> object
265             * was attempting to update, delete or insert a row in the data source. The values in
266             * the <code>SyncResolver</code> will contain <code>null</code> values only as an indication
267             * that no information in pertitent to the conflict resolution in this row.
268             */
269            public static int NO_ROW_CONFLICT = 3;
270
271            /**
272             * Retrieves the conflict status of the current row of this <code>SyncResolver</code>,
273             * which indicates the operation
274             * the <code>RowSet</code> object was attempting when the conflict occurred.
275             *
276             * @return one of the following constants:
277             *         <code>SyncResolver.UPDATE_ROW_CONFLICT</code>,
278             *         <code>SyncResolver.DELETE_ROW_CONFLICT</code>, 
279             *         <code>SyncResolver.INSERT_ROW_CONFLICT</code>, or
280             *         <code>SyncResolver.NO_ROW_CONFLICT</code>
281             */
282            public int getStatus();
283
284            /**
285             * Retrieves the value in the designated column in the current row of this
286             * <code>SyncResolver</code> object, which is the value in the data source
287             * that caused a conflict.
288             *
289             * @param index an <code>int</code> designating the column in this row of this
290             *        <code>SyncResolver</code> object from which to retrieve the value 
291             *        causing a conflict
292             * @return the value of the designated column in the current row of this
293             *         <code>SyncResolver</code> object 
294             * @throws SQLException if a database access error occurs     
295             */
296            public Object getConflictValue(int index) throws SQLException;
297
298            /**
299             * Retrieves the value in the designated column in the current row of this
300             * <code>SyncResolver</code> object, which is the value in the data source
301             * that caused a conflict.
302             *
303             * @param columnName a <code>String</code> object designating the column in this row of this
304             *        <code>SyncResolver</code> object from which to retrieve the value 
305             *        causing a conflict
306             * @return the value of the designated column in the current row of this
307             *         <code>SyncResolver</code> object 
308             * @throws SQLException if a database access error occurs     
309             */
310            public Object getConflictValue(String columnName)
311                    throws SQLException;
312
313            /**
314             * Sets <i>obj</i> as the value in column <i>index</i> in the current row of the
315             * <code>RowSet</code> object that is being synchronized. <i>obj</i>
316             * is set as the value in the data source internally.
317             *
318             * @param index an <code>int</code> giving the number of the column into which to
319             *        set the value to be persisted
320             * @param obj an <code>Object</code> that is the value to be set in the 
321             *        <code>RowSet</code> object and persisted in the data source
322             * @throws SQLException if a database access error occurs
323             */
324            public void setResolvedValue(int index, Object obj)
325                    throws SQLException;
326
327            /**
328             * Sets <i>obj</i> as the value in column <i>columnName</i> in the current row of the
329             * <code>RowSet</code> object that is being synchronized. <i>obj</i>
330             * is set as the value in the data source internally.
331             *
332             * @param columnName a <code>String</code> object giving the name of the column 
333             *        into which to set the value to be persisted
334             * @param obj an <code>Object</code> that is the value to be set in the 
335             *        <code>RowSet</code> object and persisted in the data source
336             * @throws SQLException if a database access error occurs
337             */
338            public void setResolvedValue(String columnName, Object obj)
339                    throws SQLException;
340
341            /**
342             * Moves the cursor down from its current position to the next row that contains
343             * a conflict value. A <code>SyncResolver</code> object's
344             * cursor is initially positioned before the first conflict row; the first call to the 
345             * method <code>nextConflict</code> makes the first conflict row the current row; 
346             * the second call makes the second conflict row the current row, and so on.
347             * <p>
348             * A call to the method <code>nextConflict</code> will implicitly close 
349             * an input stream if one is open and will clear the <code>SyncResolver</code> 
350             * object's warning chain.
351             *
352             * @return <code>true</code> if the new current row is valid; <code>false</code>
353             *         if there are no more rows
354             * @throws SQLException if a database access error occurs or the result set type
355             *     is <code>TYPE_FORWARD_ONLY</code>
356             *
357             */
358            public boolean nextConflict() throws SQLException;
359
360            /**
361             * Moves the cursor up from its current position to the previous conflict 
362             * row in this <code>SyncResolver</code> object.
363             * <p>
364             * A call to the method <code>previousConflict</code> will implicitly close 
365             * an input stream if one is open and will clear the <code>SyncResolver</code> 
366             * object's warning chain.
367             *
368             * @return <code>true</code> if the cursor is on a valid row; <code>false</code>
369             *     if it is off the result set 
370             * @throws SQLException if a database access error occurs or the result set type
371             *     is <code>TYPE_FORWARD_ONLY</code>
372             */
373            public boolean previousConflict() throws SQLException;
374
375        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.