| /* |
| * Copyright (c) 1998, 2021 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.interactions; |
| |
| import java.util.*; |
| import jakarta.resource.*; |
| import jakarta.resource.cci.*; |
| |
| import org.eclipse.persistence.internal.helper.DatabaseField; |
| import org.eclipse.persistence.internal.sessions.AbstractRecord; |
| import org.eclipse.persistence.sessions.DatabaseRecord; |
| import org.eclipse.persistence.eis.*; |
| |
| /** |
| * Defines the specification for a call to a JCA interaction using Mapped records. |
| * Builds the input and output records from the arguments. |
| * |
| * @author James |
| * @since OracleAS TopLink 10<i>g</i> (10.0.3) |
| */ |
| public class MappedInteraction extends EISInteraction { |
| protected String inputResultPath; |
| protected Vector<String> argumentNames; |
| |
| /** |
| * Default constructor. |
| */ |
| public MappedInteraction() { |
| super(); |
| this.inputResultPath = ""; |
| } |
| |
| /** |
| * PUBLIC: |
| * Define the argument to the interaction and the field/argument name to be substitute for it. |
| * This is only required if an input row is not used. |
| * The parameterAndArgumentFieldName is the name of the input record argument, |
| * and is the field or argument name to be used to pass to the interaction. |
| * These names are assumed to be the same, if not this method can be called with two arguments. |
| */ |
| public void addArgument(String parameterAndArgumentFieldName) { |
| addArgument(parameterAndArgumentFieldName, parameterAndArgumentFieldName); |
| } |
| |
| /** |
| * PUBLIC: |
| * Define the argument to the interaction and the field/argument name to be substitute for it. |
| * This is only required if an input row is not used. |
| * The parameterName is the name of the input record argument. |
| * The argumentFieldName is the field or argument name to be used to pass to the interaction. |
| * If these names are the same (as they normally are) this method can be called with a single argument. |
| */ |
| public void addArgument(String parameterName, String argumentFieldName) { |
| getArgumentNames().addElement(parameterName); |
| getArguments().addElement(new DatabaseField(argumentFieldName)); |
| } |
| |
| /** |
| * PUBLIC: |
| * Define the argument to the interaction and the value name to be input for it. |
| * This is only required if an input row is not used. |
| * The parameterName is the name of the input record argument. |
| * The argumentValue is the value of the input record argument. |
| */ |
| public void addArgumentValue(String parameterName, Object argumentValue) { |
| getArgumentNames().addElement(parameterName); |
| getArguments().addElement(argumentValue); |
| } |
| |
| /** |
| * PUBLIC: |
| * The input result path defines the root key for the MappedRecord that |
| * the interaction argument is nested into. |
| * This is required for write interaction that take the row build from the mapped object |
| * and need the input to contain that row record as part of the input, instead of the entire input. |
| */ |
| public String getInputResultPath() { |
| return inputResultPath; |
| } |
| |
| /** |
| * PUBLIC: |
| * The input result path defines the root key for the MappedRecord that |
| * the interaction argument is nested into. |
| * This is required for write interaction that take the row build from the mapped object |
| * and need the input to contain that row record as part of the input, instead of the entire input. |
| */ |
| public void setInputResultPath(String inputResultPath) { |
| this.inputResultPath = inputResultPath; |
| } |
| |
| /** |
| * The argument names for the input record. |
| */ |
| public Vector<String> getArgumentNames() { |
| // This is lazy initialized to conserv space on calls that have no parameters. |
| if (argumentNames == null) { |
| argumentNames = new Vector<>(); |
| } |
| return argumentNames; |
| } |
| |
| /** |
| * INTERNAL: |
| * The argument names for the input record. |
| */ |
| public void setArgumentNames(Vector<String> argumentNames) { |
| this.argumentNames = argumentNames; |
| } |
| |
| /** |
| * Create a mapped input record for this interaction. |
| * Populate the data into the record from this interaction's arguments. |
| */ |
| @Override |
| public jakarta.resource.cci.Record createInputRecord(EISAccessor accessor) { |
| try { |
| MappedRecord record = null; |
| |
| // The input record can either be build from the interaction arguments, |
| // or the modify row. |
| if ((getInputRow() != null) && (!hasArguments())) { |
| if (getInputResultPath().length() == 0) { |
| record = (MappedRecord)createRecordElement(getInputRecordName(), getInputRow(), accessor); |
| } else { |
| record = accessor.getRecordFactory().createMappedRecord(getInputRecordName()); |
| Object nestedRecord = createRecordElement(getInputResultPath(), getInputRow(), accessor); |
| accessor.getEISPlatform().setValueInRecord(getInputResultPath(), nestedRecord, record, accessor); |
| } |
| } else { |
| record = accessor.getRecordFactory().createMappedRecord(getInputRecordName()); |
| for (int index = 0; index < getArgumentNames().size(); index++) { |
| String parameterName = getArgumentNames().get(index); |
| Object parameter = getParameters().get(index); |
| |
| // If no arguments were passed to the call execution find the parameter from the row. |
| if ((parameter == null) && (getInputRow() != null)) { |
| parameter = getInputRow().get(parameterName); |
| } |
| |
| // Allow for conversion of nested rows into nested records. |
| parameter = createRecordElement(parameterName, parameter, accessor); |
| // Allow for the platform to perform any platform specific record access. |
| accessor.getEISPlatform().setValueInRecord(parameterName, parameter, record, accessor); |
| } |
| } |
| return record; |
| } catch (ResourceException exception) { |
| throw EISException.resourceException(exception, accessor, null); |
| } |
| } |
| |
| /** |
| * Create a mapped input record for this interaction. |
| * Populate the data into the record from this interaction's translation row. |
| */ |
| public jakarta.resource.cci.Record createTranslationRecord(AbstractRecord transaltionRow, EISAccessor accessor) { |
| return (MappedRecord)createRecordElement(getInputRecordName(), transaltionRow, accessor); |
| } |
| |
| /** |
| * Build a database row from the record returned from the interaction. |
| */ |
| @Override |
| public AbstractRecord buildRow(jakarta.resource.cci.Record record, EISAccessor accessor) { |
| if (record == null) { |
| return null; |
| } |
| AbstractRecord row = null; |
| |
| if (record instanceof IndexedRecord) { |
| IndexedRecord indexedRecord = (IndexedRecord)record; |
| if (indexedRecord.isEmpty()) { |
| return null; |
| } |
| if (indexedRecord.get(0) instanceof jakarta.resource.cci.Record) { |
| return buildRow((jakarta.resource.cci.Record)indexedRecord.get(0), accessor); |
| } |
| } |
| // If not a mapped record then just put it as a result value in the row. |
| if (!(record instanceof MappedRecord)) { |
| row = new DatabaseRecord(1); |
| row.put(getOutputResultPath(), record); |
| return row; |
| } |
| MappedRecord mappedRecord = (MappedRecord)record; |
| |
| // The desired result is either the entire output record, |
| // or a translation of the output with the output arguments. |
| if (hasOutputArguments()) { |
| row = new DatabaseRecord(getOutputArgumentNames().size()); |
| for (int index = 0; index < getOutputArgumentNames().size(); index++) { |
| DatabaseField field = getOutputArguments().get(index); |
| row.put(field, mappedRecord.get(getOutputArgumentNames().get(index))); |
| } |
| return row; |
| } else if (getOutputResultPath().length() > 0) { |
| // Extract the desired nested record from the output. |
| mappedRecord = (MappedRecord)mappedRecord.get(getOutputResultPath()); |
| } |
| |
| // Wrapped the record in a database to avoid lossing any information in conversion to database row, |
| // also gets around problem of some adatpers not supporting keySet or entrySet. |
| row = new EISMappedRecord(mappedRecord, accessor); |
| return row; |
| } |
| } |