| /* |
| * 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.io.*; |
| import java.util.*; |
| |
| import org.eclipse.persistence.internal.oxm.XMLObjectBuilder; |
| import org.eclipse.persistence.internal.sessions.AbstractRecord; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.oxm.XMLField; |
| import org.w3c.dom.Element; |
| import org.eclipse.persistence.internal.databaseaccess.Accessor; |
| import org.eclipse.persistence.oxm.record.XMLRecord; |
| import org.eclipse.persistence.internal.helper.*; |
| import org.eclipse.persistence.eis.*; |
| |
| /** |
| * Defines the specification for a call to a JCA interaction that uses XML. |
| * Builds the input and output XML records from the arguments. |
| * This extends MappedInteraction to allow for mapped style of argument input and output. |
| * |
| * @author James |
| * @since OracleAS TopLink 10<i>g</i> (10.0.3) |
| */ |
| public class XMLInteraction extends MappedInteraction { |
| |
| /** The root element name to use for the input DOM. */ |
| protected String inputRootElementName; |
| |
| /** The root element name to use for the output DOM. */ |
| protected String outputRootElementName; |
| |
| /** |
| * Default constructor. |
| */ |
| public XMLInteraction() { |
| super(); |
| this.inputRootElementName = ""; |
| this.outputRootElementName = ""; |
| } |
| |
| /** |
| * PUBLIC: |
| * Return the root element name to use for the input DOM. |
| */ |
| public String getInputRootElementName() { |
| return inputRootElementName; |
| } |
| |
| /** |
| * PUBLIC: |
| * Set the root element name to use for the input DOM. |
| */ |
| public void setInputRootElementName(String inputRootElementName) { |
| this.inputRootElementName = inputRootElementName; |
| } |
| |
| /** |
| * PUBLIC: |
| * Return the root element name to use for the output DOM. |
| */ |
| public String getOutputRootElementName() { |
| return outputRootElementName; |
| } |
| |
| /** |
| * PUBLIC: |
| * Set the root element name to use for the output DOM. |
| */ |
| public void setOutputRootElementName(String outputRootElementName) { |
| this.outputRootElementName = outputRootElementName; |
| } |
| |
| /** |
| * Set the default record name from the descriptor. |
| */ |
| @Override |
| public void prepare(AbstractSession session) { |
| if (getInputRootElementName().length() == 0) { |
| if ((getQuery() != null) && (getQuery().getDescriptor() instanceof EISDescriptor)) { |
| EISDescriptor descriptor = (EISDescriptor)getQuery().getDescriptor(); |
| setInputRootElementName(descriptor.getDataTypeName()); |
| } else { |
| setInputRootElementName("input"); |
| } |
| } |
| if (getOutputRootElementName().length() == 0) { |
| if ((getQuery() != null) && (getQuery().getDescriptor() instanceof EISDescriptor)) { |
| EISDescriptor descriptor = (EISDescriptor)getQuery().getDescriptor(); |
| setOutputRootElementName(descriptor.getDataTypeName()); |
| } else { |
| setInputRootElementName("output"); |
| } |
| } |
| super.prepare(session); |
| } |
| |
| /** |
| * Create a DOM input record for this interaction. |
| * Convert the database row or arguments into an XML DOM tree. |
| */ |
| @Override |
| public jakarta.resource.cci.Record createInputRecord(EISAccessor accessor) { |
| jakarta.resource.cci.Record record = accessor.getEISPlatform().createDOMRecord(getInputRecordName(), accessor); |
| Element dom = createInputDOM(accessor); |
| accessor.getEISPlatform().setDOMInRecord(dom, record, this, accessor); |
| if (record instanceof XMLRecord) { |
| ((XMLRecord) record).setSession(this.getQuery().getSession()); |
| } |
| return record; |
| } |
| |
| /** |
| * Create a DOM for this interaction. |
| * Convert the database row or arguments into an XML DOM tree. |
| */ |
| public Element createInputDOM(EISAccessor accessor) { |
| Element dom = null; |
| |
| // The input record can either be build from the interaction arguments, |
| // or the modify row. |
| if ((getInputRow() != null) && (!hasArguments())) { |
| if (getInputResultPath().length() == 0) { |
| if (getInputRow() instanceof XMLRecord) { |
| dom = (Element)((XMLRecord)getInputRow()).getDOM(); |
| // Rename the root element if specified to be different. |
| if (!dom.getTagName().equals(getInputRootElementName())) { |
| XMLRecord parameterRow = createXMLRecord(getInputRootElementName()); |
| parameterRow.put("/" + getInputRootElementName(), getInputRow()); |
| dom = (Element)parameterRow.getDOM(); |
| } |
| } else { |
| XMLRecord parameterRow = createXMLRecord(getInputRootElementName()); |
| for (int index = 0; index < getInputRow().size(); index++) { |
| parameterRow.put(getInputRow().getFields().elementAt(index), getInputRow().getValues().elementAt(index)); |
| } |
| dom = (Element)parameterRow.getDOM(); |
| } |
| } else { |
| XMLRecord parameterRow = createXMLRecord(getInputRootElementName()); |
| parameterRow.put(getInputResultPath(), getInputRow()); |
| dom = (Element)parameterRow.getDOM(); |
| } |
| } else { |
| XMLRecord parameterRow = createXMLRecord(getInputRootElementName()); |
| 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 paramter from the row. |
| if ((parameter == null) && (getInputRow() != null)) { |
| parameter = getInputRow().get(parameterName); |
| } |
| parameterRow.put(parameterName, parameter); |
| } |
| dom = (Element)parameterRow.getDOM(); |
| } |
| return dom; |
| } |
| |
| /** |
| * 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 = accessor.getEISPlatform().createDatabaseRowFromDOMRecord(record, this, accessor); |
| if (row == null) { |
| return null; |
| } |
| if (getOutputResultPath().length() > 0) { |
| row = (AbstractRecord)row.get(getOutputResultPath()); |
| // Handle the case were the output row is mapped into a database row of values. |
| } else if (hasOutputArguments()) { |
| row = createXMLRecord(getOutputRootElementName()); |
| for (int index = 0; index < getOutputArgumentNames().size(); index++) { |
| DatabaseField field = getOutputArguments().get(index); |
| row.put(field, row.get(getOutputArgumentNames().get(index))); |
| } |
| } |
| return row; |
| } |
| |
| /** |
| * Build a collection of database rows from the Record returned from the interaction. |
| */ |
| @Override |
| public Vector<AbstractRecord> buildRows(jakarta.resource.cci.Record record, EISAccessor accessor) { |
| Vector<AbstractRecord> rows = null; |
| if (record == null) { |
| return new Vector<>(0); |
| } |
| AbstractRecord row = accessor.getEISPlatform().createDatabaseRowFromDOMRecord(record, this, accessor); |
| if (getOutputResultPath().length() > 0) { |
| @SuppressWarnings({"unchecked"}) |
| Vector<AbstractRecord> values = (Vector<AbstractRecord>)row.getValues(getOutputResultPath()); |
| if (values == null) { |
| values = new Vector<>(0); |
| } |
| rows = values; |
| } else { |
| rows = new Vector<>(1); |
| rows.add(row); |
| } |
| return rows; |
| } |
| |
| /** |
| * Return the string for logging purposes. |
| */ |
| @Override |
| public String getLogString(Accessor accessor) { |
| StringWriter writer = new StringWriter(); |
| writer.write("Executing "); |
| writer.write(toString()); |
| writer.write(Helper.cr()); |
| writer.write("\tspec => "); |
| writer.write(String.valueOf(getInteractionSpec())); |
| writer.write(Helper.cr()); |
| writer.write("\tproperties => "); |
| writer.write(String.valueOf(getProperties())); |
| writer.write(Helper.cr()); |
| writer.write("\txml => "); |
| Element dom = createInputDOM((EISAccessor)accessor); |
| EISDOMRecord record = new EISDOMRecord(dom); |
| record.transformToWriter(writer); |
| return writer.toString(); |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| @Override |
| protected DatabaseField createField(String fieldName) { |
| if (getQuery().getDescriptor() != null) { |
| return getQuery().getDescriptor().buildField(fieldName); |
| } |
| return new XMLField(fieldName); |
| } |
| |
| /** |
| * INTERNAL: |
| * Use the createRecord method on ObjectBuilder in case the root element is namespace qualified |
| */ |
| protected XMLRecord createXMLRecord(String rootName) { |
| XMLRecord xmlRec; |
| if (getQuery().getDescriptor() != null && getQuery().getDescriptor() instanceof EISDescriptor) { |
| xmlRec = (XMLRecord)((XMLObjectBuilder)this.getQuery().getDescriptor().getObjectBuilder()).createRecord(getInputRootElementName(), getQuery().getSession()); |
| } else { |
| xmlRec = new org.eclipse.persistence.oxm.record.DOMRecord(getInputRootElementName()); |
| xmlRec.setSession(getQuery().getSession()); |
| } |
| return xmlRec; |
| } |
| } |