All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.eis.EISAccessor Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.eis;

import javax.resource.ResourceException;
import javax.resource.cci.Connection;
import javax.resource.cci.ConnectionMetaData;
import javax.resource.cci.Interaction;
import javax.resource.cci.InteractionSpec;
import javax.resource.cci.Record;
import javax.resource.cci.RecordFactory;

import org.eclipse.persistence.eis.interactions.EISInteraction;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.internal.databaseaccess.DatasourceAccessor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.queries.Call;
import org.eclipse.persistence.sessions.SessionProfiler;

/**
 * 

EISAccessor is an implementation of the Accessor * interface. It is responsible for: *

    *
  • Connecting via connection factory *
  • Local transactions *
  • Interaction execution *
  • Record translation *
* * @see EISInteraction * @see EISLogin * * @author James * @since OracleAS TopLink 10g (10.0.3) */ public class EISAccessor extends DatasourceAccessor { protected Connection cciConnection; protected RecordFactory recordFactory; /** * Default Constructor. */ public EISAccessor() { super(); } /** * Begin a local transaction. */ @Override protected void basicBeginTransaction(AbstractSession session) throws EISException { try { if (getEISPlatform().supportsLocalTransactions()) { getCCIConnection().getLocalTransaction().begin(); } } catch (ResourceException exception) { throw EISException.resourceException(exception, this, session); } } /** * Close the connection. */ @Override protected void closeDatasourceConnection() { try { getCCIConnection().close(); } catch (ResourceException exception) { throw EISException.resourceException(exception, this, null); } } /** * Commit the local transaction. */ @Override protected void basicCommitTransaction(AbstractSession session) throws EISException { try { if (getEISPlatform().supportsLocalTransactions()) { getCCIConnection().getLocalTransaction().commit(); } } catch (ResourceException exception) { throw EISException.resourceException(exception, this, session); } } /** * If logging is turned on and the CCI implementation supports meta data then display connection info. */ @Override protected void buildConnectLog(AbstractSession session) { try { // Log connection information. if (session.shouldLog(SessionLog.CONFIG, SessionLog.CONNECTION)) {// Avoid printing if no logging required. ConnectionMetaData metaData = getCCIConnection().getMetaData(); Object[] args = { metaData.getUserName(), metaData.getEISProductName(), metaData.getEISProductVersion(), Helper.cr(), "\t" }; session.log(SessionLog.CONFIG, SessionLog.CONNECTION, "connected_user_database", args, this); } } catch (ResourceException exception) { // Some databases do not support metadata, ignore exception. session.warning("JDBC_driver_does_not_support_meta_data", SessionLog.CONNECTION); } } /** * Avoid super to have logging occur after possible manual auto-commit. */ @Override public Object executeCall(Call call, AbstractRecord translationRow, AbstractSession session) throws DatabaseException { return basicExecuteCall(call, translationRow, session); } /** * Execute the interaction. * The execution can differ slightly depending on the type of interaction. * The call may be parameterized where the arguments are in the translation row. * The row will be empty if there are no parameters. * @return depending of the type either the row count, row or vector of rows. */ @Override public Object basicExecuteCall(Call call, AbstractRecord translationRow, AbstractSession session) throws DatabaseException { // If the login is null, then this accessor has never been connected. if (getLogin() == null) { throw DatabaseException.databaseAccessorNotConnected(); } Interaction interaction = null; Object result = null; EISInteraction eisCall = null; try { eisCall = (EISInteraction)call; } catch (ClassCastException e) { throw QueryException.invalidDatabaseCall(call); } // Record and check if auto-commit is required. // Some platforms may require this (AQ). boolean autoCommit = (!isInTransaction()) && getEISPlatform().requiresAutoCommit(); if (autoCommit) { beginTransaction(session); } try { if (session.shouldLog(SessionLog.FINE, SessionLog.SQL)) {// pre-check to improve performance session.log(SessionLog.FINE, SessionLog.SQL, call.getLogString(this), (Object[])null, this, false); } incrementCallCount(session); session.startOperationProfile(SessionProfiler.SqlPrepare, eisCall.getQuery(), SessionProfiler.ALL); javax.resource.cci.Record input = null; javax.resource.cci.Record output = null; try { interaction = getCCIConnection().createInteraction(); input = getEISPlatform().createInputRecord(eisCall, this); output = getEISPlatform().createOutputRecord(eisCall, translationRow, this); } finally { session.endOperationProfile(SessionProfiler.SqlPrepare, eisCall.getQuery(), SessionProfiler.ALL); } session.startOperationProfile(SessionProfiler.StatementExecute, eisCall.getQuery(), SessionProfiler.ALL); try { boolean success = true; InteractionSpec interactionSpec = getEISPlatform().buildInteractionSpec(eisCall); if (output == null) { output = interaction.execute(interactionSpec, input); } else { success = interaction.execute(interactionSpec, input, output); } session.log(SessionLog.FINEST, SessionLog.QUERY, "adapter_result", output); if (eisCall.isNothingReturned()) { if (success) { result = Integer.valueOf(1); } else { result = Integer.valueOf(0); } // Fire the output parameter row to allow app to handle return value. if (output != null) { AbstractRecord outputRow = getEISPlatform().buildRow(output, eisCall, this); if (outputRow != null) { eisCall.getQuery().setProperty("output", outputRow); if (session.hasEventManager()) { session.getEventManager().outputParametersDetected(outputRow, eisCall); } } } } else if (eisCall.isOneRowReturned()) { result = getEISPlatform().buildRow(output, eisCall, this); } else { result = getEISPlatform().buildRows(output, eisCall, this); } session.log(SessionLog.FINEST, SessionLog.QUERY, "data_access_result", output); } finally { session.endOperationProfile(SessionProfiler.StatementExecute, eisCall.getQuery(), SessionProfiler.ALL); } } catch (ResourceException exception) { // Ensure each resource is released, but still ensure that the real exception is thrown. if (interaction != null) { try { interaction.close(); } catch (Exception closeException) { // Ignore error to avoid masking real exception. } } try { decrementCallCount(); } catch (Exception closeException) { // Ignore error to avoid masking real exception. } try { if (autoCommit) { commitTransaction(session); } } catch (Exception closeException) { // Ignore error to avoid masking real exception. } throw EISException.resourceException(exception, call, this, session); } catch (RuntimeException exception) { try {// Ensure that the statement is closed, but still ensure that the real exception is thrown. try { if (interaction != null) { interaction.close(); } } finally { if (autoCommit) { commitTransaction(session); } } } catch (Exception closeException) { } throw exception; } boolean transactionCommitted = false; boolean countDecremented = false; // This is in separate try block to ensure that the real exception is not masked by the close exception. try { interaction.close(); if (autoCommit) { commitTransaction(session); } transactionCommitted = true; decrementCallCount(); countDecremented = true; } catch (ResourceException exception) { try { if (!transactionCommitted) { if (autoCommit) { commitTransaction(session); } } } catch (Exception ignore) { // Ignore error to avoid masking real exception. } try { if (!countDecremented) { decrementCallCount(); } } catch (Exception ignore) { // Ignore error to avoid masking real exception. } throw EISException.resourceException(exception, this, session); } return result; } /** * Return the CCI connection to the EIS resource adapter. */ public Connection getCCIConnection() { return (Connection)getDatasourceConnection(); } /** * Return and cast the platform. */ public EISPlatform getEISPlatform() { return (EISPlatform)getDatasourcePlatform(); } /** * Return the RecordFactory. * The record factory is acquired from the ConnectionManager, * and used to create record to pass to interactions. */ public RecordFactory getRecordFactory() { return recordFactory; } /** * Set the RecordFactory. * The record factory is acquired from the ConnectionManager, * and used to create record to pass to interactions. */ public void setRecordFactory(RecordFactory recordFactory) { this.recordFactory = recordFactory; } /** * Rollback the local transaction on the datasource. */ @Override public void basicRollbackTransaction(AbstractSession session) throws DatabaseException { try { if (getEISPlatform().supportsLocalTransactions()) { getCCIConnection().getLocalTransaction().rollback(); } } catch (ResourceException exception) { throw EISException.resourceException(exception, this, session); } } /** * Return if the connection to the "data source" is connected. */ @Override protected boolean isDatasourceConnected() { return isConnected; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy