001: /*
002: * Copyright 2003-2006 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 com.sun.rowset.providers;
027:
028: import com.sun.rowset.JdbcRowSetResourceBundle;
029: import javax.sql.*;
030: import java.io.*;
031:
032: import javax.sql.rowset.spi.*;
033: import com.sun.rowset.internal.*;
034:
035: /**
036: * The reference implementation of a JDBC Rowset synchronization provider
037: * providing optimistic synchronization with a relational datastore
038: * using any JDBC technology-enabled driver.
039: * <p>
040: * <h3>1.0 Backgroud</h3>
041: * This synchronization provider is registered with the
042: * <code>SyncFactory</code> by default as the
043: * <code>com.sun.rowset.providers.RIOptimisticProvider</code>.
044: * As an extension of the <code>SyncProvider</code> abstract
045: * class, it provides the reader and writer classes required by disconnected
046: * rowsets as <code>javax.sql.RowSetReader</code> and <code>javax.sql.RowSetWriter</code>
047: * interface implementations. As a reference implementation,
048: * <code>RIOptimisticProvider</code> provides a
049: * fully functional implementation offering a medium grade classification of
050: * syncrhonization, namely GRADE_CHECK_MODIFIED_AT_COMMIT. A
051: * disconnected <code>RowSet</code> implementation using the
052: * <code>RIOptimisticProvider</code> can expect the writer to
053: * check only rows that have been modified in the <code>RowSet</code> against
054: * the values in the data source. If there is a conflict, that is, if a value
055: * in the data source has been changed by another party, the
056: * <code>RIOptimisticProvider</code> will not write any of the changes to the data
057: * source and will throw a <code>SyncProviderException</code> object.
058: *
059: * <h3>2.0 Usage</h3>
060: * Standard disconnected <code>RowSet</code> implementations may opt to use this
061: * <code>SyncProvider</code> implementation in one of two ways:
062: * <OL>
063: * <LI>By specifically calling the <code>setSyncProvider</code> method
064: defined in the <code>CachedRowSet</code> interface
065: * <pre>
066: * CachedRowset crs = new FooCachedRowSetImpl();
067: * crs.setSyncProvider("com.sun.rowset.providers.RIOptimisticProvider");
068: * </pre>
069: * <LI>By specifying it in the constructor of the <code>RowSet</code>
070: * implementation
071: * <pre>
072: * CachedRowset crs = new FooCachedRowSetImpl(
073: * "com.sun.rowset.providers.RIOptimisticProvider");
074: * </pre>
075: * </OL>
076: * Note that because the <code>RIOptimisticProvider</code> implementation is
077: * the default provider, it will always be the provider when no provider ID is
078: * specified to the constructor.
079: * <P>
080: * See the standard <code>RowSet</code> reference implementations in the
081: * <code>com.sun.rowset</code> package for more details.
082: *
083: * @author Jonathan Bruce
084: * @see javax.sql.rowset.spi.SyncProvider
085: * @see javax.sql.rowset.spi.SyncProviderException
086: * @see javax.sql.rowset.spi.SyncFactory
087: * @see javax.sql.rowset.spi.SyncFactoryException
088: *
089: */
090: public final class RIOptimisticProvider extends SyncProvider implements
091: Serializable {
092:
093: private CachedRowSetReader reader;
094: private CachedRowSetWriter writer;
095:
096: /**
097: * The unique provider indentifier.
098: */
099: private String providerID = "com.sun.rowset.providers.RIOptimisticProvider";
100:
101: /**
102: * The vendor name of this SyncProvider implementation
103: */
104: private String vendorName = "Sun Microsystems Inc.";
105:
106: /**
107: * The version number of this SyncProvider implementation
108: */
109: private String versionNumber = "1.0";
110:
111: /**
112: * ResourceBundle
113: */
114: private JdbcRowSetResourceBundle resBundle;
115:
116: /**
117: * Creates an <code>RIOptimisticProvider</code> object initialized with the
118: * fully qualified class name of this <code>SyncProvider</code> implementation
119: * and a default reader and writer.
120: * <P>
121: * This provider is available to all disconnected <code>RowSet</code> implementations
122: * as the default persistence provider.
123: */
124: public RIOptimisticProvider() {
125: providerID = this .getClass().getName();
126: reader = new CachedRowSetReader();
127: writer = new CachedRowSetWriter();
128: try {
129: resBundle = JdbcRowSetResourceBundle
130: .getJdbcRowSetResourceBundle();
131: } catch (IOException ioe) {
132: throw new RuntimeException(ioe);
133: }
134: }
135:
136: /**
137: * Returns the <code>'javax.sql.rowset.providers.RIOptimisticProvider'</code>
138: * provider identification string.
139: *
140: * @return String Provider ID of this persistence provider
141: */
142: public String getProviderID() {
143: return providerID;
144: }
145:
146: /**
147: * Returns the <code>javax.sql.RowSetWriter</code> object for this
148: * <code>RIOptimisticProvider</code> object. This is the writer that will
149: * write changes made to the <code>Rowset</code> object back to the data source.
150: *
151: * @return the <code>javax.sql.RowSetWriter</code> object for this
152: * <code>RIOptimisticProvider</code> object
153: */
154: public RowSetWriter getRowSetWriter() {
155: try {
156: writer.setReader(reader);
157: } catch (java.sql.SQLException e) {
158: }
159: return writer;
160: }
161:
162: /**
163: * Returns the <code>javax.sql.RowSetReader</code> object for this
164: * <code>RIOptimisticProvider</code> object. This is the reader that will
165: * populate a <code>RowSet</code> object using this <code>RIOptimisticProvider</code>.
166: *
167: * @return the <code>javax.sql.RowSetReader</code> object for this
168: * <code>RIOptimisticProvider</code> object
169: */
170: public RowSetReader getRowSetReader() {
171: return reader;
172: }
173:
174: /**
175: * Returns the <code>SyncProvider</code> grade of synchronization that
176: * <code>RowSet</code> objects can expect when using this
177: * implementation. As an optimisic synchonization provider, the writer
178: * will only check rows that have been modified in the <code>RowSet</code>
179: * object.
180: */
181: public int getProviderGrade() {
182: return SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT;
183: }
184:
185: /**
186: * Modifies the data source lock severity according to the standard
187: * <code>SyncProvider</code> classifications.
188: *
189: * @param datasource_lock An <code>int</code> indicating the level of locking to be
190: * set; must be one of the following constants:
191: * <PRE>
192: * SyncProvider.DATASOURCE_NO_LOCK,
193: * SyncProvider.DATASOURCE_ROW_LOCK,
194: * SyncProvider.DATASOURCE_TABLE_LOCK,
195: * SyncProvider.DATASOURCE_DB_LOCk
196: * </PRE>
197: * @throws SyncProviderException if the parameter specified is not
198: * <code>SyncProvider.DATASOURCE_NO_LOCK</code>
199: */
200: public void setDataSourceLock(int datasource_lock)
201: throws SyncProviderException {
202: if (datasource_lock != SyncProvider.DATASOURCE_NO_LOCK) {
203: throw new SyncProviderException(resBundle.handleGetObject(
204: "riop.locking").toString());
205: }
206: }
207:
208: /**
209: * Returns the active data source lock severity in this
210: * reference implementation of the <code>SyncProvider</code>
211: * abstract class.
212: *
213: * @return <code>SyncProvider.DATASOURCE_NO_LOCK</code>.
214: * The reference implementation does not support data source locks.
215: */
216: public int getDataSourceLock() throws SyncProviderException {
217: return SyncProvider.DATASOURCE_NO_LOCK;
218: }
219:
220: /**
221: * Returns the supported updatable view abilities of the
222: * reference implementation of the <code>SyncProvider</code>
223: * abstract class.
224: *
225: * @return <code>SyncProvider.NONUPDATABLE_VIEW_SYNC</code>. The
226: * the reference implementation does not support updating tables
227: * that are the source of a view.
228: */
229: public int supportsUpdatableView() {
230: return SyncProvider.NONUPDATABLE_VIEW_SYNC;
231: }
232:
233: /**
234: * Returns the release version ID of the Reference Implementation Optimistic
235: * Synchronization Provider.
236: *
237: * @return the <code>String</code> detailing the version number of this SyncProvider
238: */
239: public String getVersion() {
240: return this .versionNumber;
241: }
242:
243: /**
244: * Returns the vendor name of the Reference Implemntation Optimistic
245: * Syncchronication Provider
246: *
247: * @return the <code>String</code> detailing the vendor name of this
248: * SyncProvider
249: */
250: public String getVendor() {
251: return this.vendorName;
252: }
253: }
|