blob: 1e8192e576dfa67d5e21e1d6fa9ec762ef45a3bf [file] [log] [blame]
/*
* 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 that uses indexed records.
* Builds the input and output records from the arguments.
*
* @author James
* @since OracleAS TopLink 10<i>g</i> (10.0.3)
*/
public class IndexedInteraction extends EISInteraction {
/**
* Default constructor.
*/
public IndexedInteraction() {
super();
}
/**
* PUBLIC:
* Define the argument to the interaction for the index argument.
* This must be called in the order of the arguments in the input indexed record.
* The argumentFieldName is the field or argument name in the descriptor that maps to the indexed value.
*/
public void addArgument(String argumentFieldName) {
getArguments().addElement(new DatabaseField(argumentFieldName));
}
/**
* PUBLIC:
* Define the argument to the interaction for the index argument.
* This must be called in the order of the arguments in the input indexed record.
* The argumentValue is the value of the argument to be used to pass to the interaction.
*/
public void addArgumentValue(Object argumentValue) {
getArguments().addElement(argumentValue);
}
/**
* PUBLIC:
* Define the field/argument name to be substitute for the index output argument.
* This must be called in the order of the output arguments in the result indexed record.
* The argumentFieldName is the field or argument name in the descriptor that maps to the indexed value.
*/
@Override
public void addOutputArgument(String argumentFieldName) {
getOutputArguments().addElement(new DatabaseField(argumentFieldName));
}
/**
* The arguments are the values in order of occurance in the record.
*/
@Override
public Vector getArguments() {
return super.getArguments();
}
/**
* The output arguments in order of occurance in the record.
*/
@Override
public Vector<DatabaseField> getOutputArguments() {
return super.getOutputArguments();
}
/**
* The arguments are the values in order of occurance in the record.
*/
@Override
public void setArguments(Vector arguments) {
super.setArguments(arguments);
}
/**
* The output arguments in order of occurance in the record.
*/
@Override
public void setOutputArguments(Vector<DatabaseField> outputArguments) {
super.setOutputArguments(outputArguments);
}
/**
* Create an indexed 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 {
IndexedRecord record = accessor.getRecordFactory().createIndexedRecord(getInputRecordName());
for (int index = 0; index < getParameters().size(); index++) {
Object parameter = getParameters().get(index);
// Allow conversion of nested rows and collections.
record.add(createRecordElement("", parameter, accessor));
}
return record;
} catch (ResourceException exception) {
throw EISException.resourceException(exception, accessor, null);
}
}
/**
* Build a database row from the record returned from the interaction.
* Also handles MappedRecords for case of input being indexed but mapped ouput.
*/
@Override
public AbstractRecord buildRow(jakarta.resource.cci.Record record, EISAccessor accessor) {
AbstractRecord row = null;
if (record instanceof IndexedRecord) {
IndexedRecord indexedRecord = (IndexedRecord)record;
row = new DatabaseRecord(indexedRecord.size());
for (int index = 0; index < indexedRecord.size(); index++) {
DatabaseField field = getOutputArguments().get(index);
row.put(field, indexedRecord.get(index));
}
} else if (record instanceof MappedRecord) {
MappedRecord mappedRecord = (MappedRecord)record;
// Handle the case of a single output argument of the entire row contained within the return record.
if (getOutputArgumentNames().size() == 1) {
mappedRecord = (MappedRecord)mappedRecord.get(getOutputArgumentNames().get(0));
// Handle the case were the output row is mapped into a database row of values.
} else if (getOutputArgumentNames().size() > 1) {
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;
}
// Wrapped the record in a database to avoid loosing any information in conversion to database row,
// also gets around problem of some adatpers not supporting keySet or entrySet.
row = new EISMappedRecord(mappedRecord, accessor);
} else {
row = new DatabaseRecord(1);
row.put(getOutputResultPath(), record);
}
return row;
}
}