changeset 57459:77d6e5cf5320

8235961: SyncResolverImpl does not throw SQLException as expected Reviewed-by: joehw, bpb
author lancea
date Mon, 23 Dec 2019 17:18:32 -0500
parents 97744abc4fde
children cf32454b65f0
files src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java src/java.sql.rowset/share/classes/com/sun/rowset/internal/SyncResolverImpl.java test/jdk/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java
diffstat 3 files changed, 92 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Mon Dec 23 09:17:00 2019 +0000
+++ b/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java	Mon Dec 23 17:18:32 2019 -0500
@@ -1601,7 +1601,7 @@
      * @throws SQLException if the given index is out of bounds
      */
     private void checkIndex(int idx) throws SQLException {
-        if (idx < 1 || idx > RowSetMD.getColumnCount()) {
+        if (idx < 1 ||  RowSetMD == null || idx > RowSetMD.getColumnCount()) {
             throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidcol").toString());
         }
     }
@@ -1638,14 +1638,15 @@
     private int getColIdxByName(String name) throws SQLException {
         RowSetMD = (RowSetMetaDataImpl)this.getMetaData();
         int cols = RowSetMD.getColumnCount();
-
-        for (int i=1; i <= cols; ++i) {
-            String colName = RowSetMD.getColumnName(i);
-            if (colName != null)
-                if (name.equalsIgnoreCase(colName))
-                    return (i);
-                else
-                    continue;
+        if (RowSetMD != null) {
+            for (int i = 1; i <= cols; ++i) {
+                String colName = RowSetMD.getColumnName(i);
+                if (colName != null)
+                    if (name.equalsIgnoreCase(colName))
+                        return (i);
+                    else
+                        continue;
+            }
         }
         throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalcolnm").toString());
 
--- a/src/java.sql.rowset/share/classes/com/sun/rowset/internal/SyncResolverImpl.java	Mon Dec 23 09:17:00 2019 +0000
+++ b/src/java.sql.rowset/share/classes/com/sun/rowset/internal/SyncResolverImpl.java	Mon Dec 23 17:18:32 2019 -0500
@@ -123,7 +123,7 @@
 
     /**
      * Retrieves the conflict status of the current row of this
-     * {@code SyncResolver}, which indicates the operationthe {@code RowSet}
+     * {@code SyncResolver}, which indicates the operation the {@code RowSet}
      * object was attempting when the conflict occurred.
      *
      * @return one of the following constants:
@@ -132,7 +132,8 @@
      *         {@code SyncResolver.INSERT_ROW_CONFLICT}
      */
     public int getStatus() {
-        return ((Integer)stats.get(rowStatus-1)).intValue();
+        return stats != null ? (Integer) stats.get(rowStatus - 1) :
+                SyncResolver.NO_ROW_CONFLICT;
     }
 
     /**
@@ -148,6 +149,8 @@
              return crsRes.getObject(index);
         } catch(SQLException sqle) {
             throw new SQLException(sqle.getMessage());
+        } catch (Exception e ) {
+            throw new SQLException("Problem obtaining conflicted value!", e);
         }
     }
 
@@ -164,6 +167,8 @@
              return crsRes.getObject(columnName);
         } catch(SQLException sqle) {
              throw new SQLException(sqle.getMessage());
+        } catch (Exception e ) {
+            throw new SQLException("Problem obtaining conflicted value!", e);
         }
     }
 
@@ -189,8 +194,9 @@
          * then sync back immediately.
          **/
         try {
+            ResultSetMetaData rsmd = crsSync.getMetaData();
             // check whether the index is in range
-            if(index<=0 || index > crsSync.getMetaData().getColumnCount() ) {
+            if(index<=0 || rsmd == null || index > rsmd.getColumnCount() ) {
                 throw new SQLException(resBundle.handleGetObject("syncrsimpl.indexval").toString()+ index);
             }
              // check whether index col is in conflict
@@ -393,8 +399,8 @@
      * @param obj an {@code Object} that is the value to be set in the data source
      */
     public void setResolvedValue(String columnName, Object obj) throws SQLException {
-       // modify method to throw SQLException in spec
-       // %%% Missing implementation!
+        // %%% Missing implementation!
+        throw new SQLException("Method not supported");
     }
 
     /**
@@ -503,7 +509,7 @@
      *     is TYPE_FORWARD_ONLY
      */
    public boolean previousConflict() throws SQLException {
-       throw new UnsupportedOperationException();
+       return false;
    }
 
     //-----------------------------------------------------------------------
--- a/test/jdk/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java	Mon Dec 23 09:17:00 2019 +0000
+++ b/test/jdk/javax/sql/testng/test/rowset/spi/SyncProviderExceptionTests.java	Mon Dec 23 17:18:32 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -25,14 +25,21 @@
 import com.sun.rowset.internal.SyncResolverImpl;
 import java.sql.SQLException;
 import javax.sql.rowset.spi.SyncProviderException;
+import javax.sql.rowset.spi.SyncResolver;
+
 import static org.testng.Assert.*;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 import util.BaseTest;
 import util.StubSyncResolver;
 
 public class SyncProviderExceptionTests extends BaseTest {
+
+    // Used by SyncProviderException::getSyncResolver tests
+    private SyncResolver resolver;
+
     @BeforeClass
     public static void setUpClass() throws Exception {
         System.out.println(System.getProperty("java.naming.factory.initial"));
@@ -41,6 +48,12 @@
     @AfterClass
     public static void tearDownClass() throws Exception {
     }
+
+    @BeforeMethod
+    public void setupTest() {
+        resolver = new SyncProviderException().getSyncResolver();
+    }
+
     /*
      * Create SyncProviderException with no-arg constructor
      */
@@ -184,4 +197,60 @@
                 && ex1.getErrorCode() == 0
                 && ex1.getSyncResolver() instanceof StubSyncResolver);
     }
+
+    /*
+     * Validate SyncResolver::getStatus() succeeds
+     */
+    @Test
+    public void testgetStatus() {
+        int status = resolver.getStatus();
+    }
+
+    /*
+     * Validate SyncResolver::nextConflict() succeeds
+     */
+    @Test
+    public void testnextConflict() throws SQLException {
+         boolean result = resolver.nextConflict();
+    }
+
+    /*
+     * Validate SyncResolver::previousConflict() succeeds
+     */
+    @Test
+    public void testPreviousConflict() throws SQLException {
+        boolean result =  resolver.previousConflict();
+    }
+
+    /*
+     * Validate SyncResolver::getConflictValue() throws a SQLException
+     */
+    @Test
+    public void testConflictedValueByInt() throws SQLException {
+        assertThrows(SQLException.class, () ->resolver.getConflictValue(1));
+    }
+
+    /*
+     * Validate SyncResolver::getConflictValue() throws a SQLException
+     */
+    @Test
+    public void testConflictedValueByName() throws SQLException {
+        assertThrows(SQLException.class, () -> resolver.getConflictValue("foo"));
+    }
+
+    /*
+     * Validate SyncResolver::setResolvedValue() throws a SQLException
+     */
+    @Test
+    public void testSetResolvedValueByInt() throws SQLException {
+        assertThrows(SQLException.class, () -> resolver.setResolvedValue(1, "foo"));
+    }
+
+    /*
+     * Validate SyncResolver::getConflictValue() throws a SQLException
+     */
+    @Test
+    public void testSetResolvedValueByName() throws SQLException {
+        assertThrows(SQLException.class, () -> resolver.setResolvedValue("foo", "bar"));
+    }
 }