/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
<<<<<<< Updated upstream
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
=======
 * 
 *     https://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
>>>>>>> Stashed changes
 * limitations under the License.
 */

package org.apache.jdo.tck.api.persistencemanager;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import javax.jdo.datastore.JDOConnection;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.util.BatchTestRunner;

/**
 * <B>Title:</B> DataStoreConnectionThrows <br>
 * <B>Keywords:</B> <br>
 * <B>Assertion ID:</B> A12.16-2 <br>
 * <B>Assertion Description: </B> For portability, a JDBC-based JDO implementation will return an
 * instance that implements java.sql.Connection. The instance will throw an exception for any of the
 * following method calls: commit, getMetaData, releaseSavepoint, rollback, setAutoCommit,
 * setCatalog, setHoldability, setReadOnly, setSavepoint, setTransactionIsolation, and setTypeMap.
 */
public class DataStoreConnectionThrows extends PersistenceManagerTest {

  /** */
  private static final String ASSERTION_FAILED =
      "Assertion A12.16-2 (DataStoreConnectionThrows) failed: ";

  protected PCPoint goldenPoint;

  /**
   * The <code>main</code> is called when the class is directly executed from the command line.
   *
   * @param args The arguments passed to the program.
   */
  public static void main(String[] args) {
    BatchTestRunner.run(DataStoreConnectionThrows.class);
  }

  /**
   * @param conn connection
   * @param call call
   */
  protected void checkThrow(Connection conn, Call call) {
    try {
      call.execute(conn);
      appendMessage(ASSERTION_FAILED + "Failed to throw an exception for " + call.getName());
    } catch (SQLException ex) {
      appendMessage(ASSERTION_FAILED + "Threw a SQLException for " + call.getName() + NL + ex);
      return;
    } catch (Exception ex) {
      return;
    }
  }

  /** */
  interface Call {
    String getName();

    void execute(Connection conn) throws SQLException;
  }

  /** */
  public void testDataStoreConnectionThrows() {
    if (!(isDataStoreConnectionSupported() && isSQLSupported())) {
      printUnsupportedOptionalFeatureNotTested(
          this.getClass().getName(), "getDataStoreConnection AND SQLSupported.");
      return;
    }
    JDOConnection jconn = getPM().getDataStoreConnection();
    Connection conn = (Connection) jconn;
    check13Methods(conn);
    if (isJRE14orBetter()) {
      check14Methods(conn);
    }
    jconn.close();
    failOnError();
  }

  /**
   * These methods are defined in Java 1.3 Connection.
   *
   * @param conn connection
   */
  protected void check13Methods(Connection conn) {
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "commit";
          }

          public void execute(Connection conn) throws SQLException {
            conn.commit();
          }
        });
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "rollback";
          }

          public void execute(Connection conn) throws SQLException {
            conn.rollback();
          }
        });
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "setTransactionIsolation";
          }

          public void execute(Connection conn) throws SQLException {
            conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
          }
        });
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "setAutoCommit";
          }

          public void execute(Connection conn) throws SQLException {
            conn.setAutoCommit(true);
          }
        });
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "setCatalog";
          }

          public void execute(Connection conn) throws SQLException {
            conn.setCatalog("NONE");
          }
        });
  }

  /**
   * These methods are defined in Java 1.4 Connection.
   *
   * @param conn connection
   */
  protected void check14Methods(Connection conn) {
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "setSavepoint";
          }

          public void execute(Connection conn) throws SQLException {
            conn.setSavepoint();
          }
        });
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "releaseSavepoint";
          }

          public void execute(Connection conn) throws SQLException {
            conn.releaseSavepoint(null);
          }
        });
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "setHoldability";
          }

          public void execute(Connection conn) throws SQLException {
            conn.setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT);
          }
        });
    checkThrow(
        conn,
        new Call() {
          public String getName() {
            return "setTypeMap";
          }

          public void execute(Connection conn) throws SQLException {
            conn.setTypeMap(Collections.emptyMap());
          }
        });
  }
}
