/* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. 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. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.rowset.providers; import com.sun.rowset.JdbcRowSetResourceBundle; import javax.sql.*; import java.io.*; import javax.sql.rowset.spi.*; import com.sun.rowset.internal.*; /** * The reference implementation of a JDBC Rowset synchronization provider * providing optimistic synchronization with a relational datastore * using any JDBC technology-enabled driver. * *

1.0 Backgroud

* This synchronization provider is registered with the * SyncFactory by default as the * com.sun.rowset.providers.RIOptimisticProvider. * As an extension of the SyncProvider abstract * class, it provides the reader and writer classes required by disconnected * rowsets as javax.sql.RowSetReader and javax.sql.RowSetWriter * interface implementations. As a reference implementation, * RIOptimisticProvider provides a * fully functional implementation offering a medium grade classification of * syncrhonization, namely GRADE_CHECK_MODIFIED_AT_COMMIT. A * disconnected RowSet implementation using the * RIOptimisticProvider can expect the writer to * check only rows that have been modified in the RowSet against * the values in the data source. If there is a conflict, that is, if a value * in the data source has been changed by another party, the * RIOptimisticProvider will not write any of the changes to the data * source and will throw a SyncProviderException object. * *

2.0 Usage

* Standard disconnected RowSet implementations may opt to use this * SyncProvider implementation in one of two ways: *
    *
  1. By specifically calling the setSyncProvider method defined in the CachedRowSet interface *
     *     CachedRowset crs = new FooCachedRowSetImpl();
     *     crs.setSyncProvider("com.sun.rowset.providers.RIOptimisticProvider");
     * 
    *
  2. By specifying it in the constructor of the RowSet * implementation *
     *     CachedRowset crs = new FooCachedRowSetImpl(
     *                         "com.sun.rowset.providers.RIOptimisticProvider");
     * 
    *
* Note that because the RIOptimisticProvider implementation is * the default provider, it will always be the provider when no provider ID is * specified to the constructor. *

* See the standard RowSet reference implementations in the * com.sun.rowset package for more details. * * @author Jonathan Bruce * @see javax.sql.rowset.spi.SyncProvider * @see javax.sql.rowset.spi.SyncProviderException * @see javax.sql.rowset.spi.SyncFactory * @see javax.sql.rowset.spi.SyncFactoryException * */ public final class RIOptimisticProvider extends SyncProvider implements Serializable { private CachedRowSetReader reader; private CachedRowSetWriter writer; /** * The unique provider identifier. */ private String providerID = "com.sun.rowset.providers.RIOptimisticProvider"; /** * The vendor name of this SyncProvider implementation */ private String vendorName = "Oracle Corporation"; /** * The version number of this SyncProvider implementation */ private String versionNumber = "1.0"; /** * ResourceBundle */ private JdbcRowSetResourceBundle resBundle; /** * Creates an RIOptimisticProvider object initialized with the * fully qualified class name of this SyncProvider implementation * and a default reader and writer. *

* This provider is available to all disconnected RowSet implementations * as the default persistence provider. */ public RIOptimisticProvider() { providerID = this.getClass().getName(); reader = new CachedRowSetReader(); writer = new CachedRowSetWriter(); try { resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); } catch(IOException ioe) { throw new RuntimeException(ioe); } } /** * Returns the 'javax.sql.rowset.providers.RIOptimisticProvider' * provider identification string. * * @return String Provider ID of this persistence provider */ public String getProviderID() { return providerID; } /** * Returns the javax.sql.RowSetWriter object for this * RIOptimisticProvider object. This is the writer that will * write changes made to the Rowset object back to the data source. * * @return the javax.sql.RowSetWriter object for this * RIOptimisticProvider object */ public RowSetWriter getRowSetWriter() { try { writer.setReader(reader); } catch (java.sql.SQLException e) {} return writer; } /** * Returns the javax.sql.RowSetReader object for this * RIOptimisticProvider object. This is the reader that will * populate a RowSet object using this RIOptimisticProvider. * * @return the javax.sql.RowSetReader object for this * RIOptimisticProvider object */ public RowSetReader getRowSetReader() { return reader; } /** * Returns the SyncProvider grade of synchronization that * RowSet objects can expect when using this * implementation. As an optimisic synchonization provider, the writer * will only check rows that have been modified in the RowSet * object. */ public int getProviderGrade() { return SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT; } /** * Modifies the data source lock severity according to the standard * SyncProvider classifications. * * @param datasource_lock An int indicating the level of locking to be * set; must be one of the following constants: *

     *       SyncProvider.DATASOURCE_NO_LOCK,
     *       SyncProvider.DATASOURCE_ROW_LOCK,
     *       SyncProvider.DATASOURCE_TABLE_LOCK,
     *       SyncProvider.DATASOURCE_DB_LOCk
     * 
* @throws SyncProviderException if the parameter specified is not * SyncProvider.DATASOURCE_NO_LOCK */ public void setDataSourceLock(int datasource_lock) throws SyncProviderException { if(datasource_lock != SyncProvider.DATASOURCE_NO_LOCK ) { throw new SyncProviderException(resBundle.handleGetObject("riop.locking").toString()); } } /** * Returns the active data source lock severity in this * reference implementation of the SyncProvider * abstract class. * * @return SyncProvider.DATASOURCE_NO_LOCK. * The reference implementation does not support data source locks. */ public int getDataSourceLock() throws SyncProviderException { return SyncProvider.DATASOURCE_NO_LOCK; } /** * Returns the supported updatable view abilities of the * reference implementation of the SyncProvider * abstract class. * * @return SyncProvider.NONUPDATABLE_VIEW_SYNC. The * the reference implementation does not support updating tables * that are the source of a view. */ public int supportsUpdatableView() { return SyncProvider.NONUPDATABLE_VIEW_SYNC; } /** * Returns the release version ID of the Reference Implementation Optimistic * Synchronization Provider. * * @return the String detailing the version number of this SyncProvider */ public String getVersion() { return this.versionNumber; } /** * Returns the vendor name of the Reference Implementation Optimistic * Synchronization Provider * * @return the String detailing the vendor name of this * SyncProvider */ public String getVendor() { return this.vendorName; } private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { // Default state initialization happens here ois.defaultReadObject(); // Initialization of transient Res Bundle happens here . try { resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); } catch(IOException ioe) { throw new RuntimeException(ioe); } } static final long serialVersionUID =-3143367176751761936L; }