/******************************************************************************* | |
* Copyright (c) 1998, 2013 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 v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Oracle - initial API and implementation from Oracle TopLink | |
******************************************************************************/ | |
package org.eclipse.persistence.eis.interactions; | |
import java.io.*; | |
import java.util.*; | |
import javax.resource.cci.*; | |
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.internal.helper.DatabaseField; | |
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. | |
*/ | |
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. | |
*/ | |
public Record createInputRecord(EISAccessor accessor) { | |
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 = (String)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. | |
*/ | |
public AbstractRecord buildRow(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 = (DatabaseField)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. | |
*/ | |
public Vector buildRows(Record record, EISAccessor accessor) { | |
Vector rows = null; | |
if (record == null) { | |
return new Vector(0); | |
} | |
AbstractRecord row = accessor.getEISPlatform().createDatabaseRowFromDOMRecord(record, this, accessor); | |
if (getOutputResultPath().length() > 0) { | |
Vector values = (Vector)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. | |
*/ | |
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: | |
*/ | |
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; | |
} | |
} |