private void copy(OAssign.Copy ocopy) throws FaultException, ExternalVariableModuleException {
if (__log.isDebugEnabled())
__log.debug("Assign.copy(" + ocopy + ")");
ScopeEvent se;
// Check for message to message - copy, we can do this efficiently in
// the database.
if ((ocopy.to instanceof VariableRef && ((VariableRef) ocopy.to)
.isMessageRef())
|| (ocopy.from instanceof VariableRef && ((VariableRef) ocopy.from)
.isMessageRef())) {
if ((ocopy.to instanceof VariableRef && ((VariableRef) ocopy.to)
.isMessageRef())
&& ocopy.from instanceof VariableRef
&& ((VariableRef) ocopy.from).isMessageRef()) {
final VariableInstance lval = _scopeFrame.resolve(ocopy.to
.getVariable());
final VariableInstance rval = _scopeFrame
.resolve(((VariableRef) ocopy.from).getVariable());
Element lvalue = (Element) fetchVariableData(rval, false);
initializeVariable(lval, lvalue);
se = new VariableModificationEvent(lval.declaration.name);
((VariableModificationEvent)se).setNewValue(lvalue);
} else {
// This really should have been caught by the compiler.
__log
.fatal("Message/Non-Message Assignment, should be caught by compiler:"
+ ocopy);
throw new FaultException(
ocopy.getOwner().constants.qnSelectionFailure,
"Message/Non-Message Assignment: " + ocopy);
}
} else {
// Conventional Assignment logic.
Node rvalue = evalRValue(ocopy.from);
Node lvalue = evalLValue(ocopy.to);
if (__log.isDebugEnabled()) {
__log.debug("lvalue after eval " + lvalue);
if (lvalue != null) __log.debug("content " + DOMUtils.domToString(lvalue));
}
// Get a pointer within the lvalue.
Node lvaluePtr = lvalue;
boolean headerAssign = false;
if (ocopy.to instanceof OAssign.DirectRef) {
DirectRef dref = ((DirectRef) ocopy.to);
Element el = DOMUtils.findChildByName((Element)lvalue, dref.elName);
if (el == null) {
el = (Element) ((Element)lvalue).appendChild(lvalue.getOwnerDocument()
.createElementNS(dref.elName.getNamespaceURI(), dref.elName.getLocalPart()));
}
lvaluePtr = el;
} else if (ocopy.to instanceof OAssign.VariableRef) {
VariableRef varRef = ((VariableRef) ocopy.to);
if (varRef.headerPart != null) headerAssign = true;
lvaluePtr = evalQuery(lvalue, varRef.part != null ? varRef.part : varRef.headerPart, varRef.location,
new EvaluationContextProxy(varRef.getVariable(), lvalue));
} else if (ocopy.to instanceof OAssign.PropertyRef) {
PropertyRef propRef = ((PropertyRef) ocopy.to);
lvaluePtr = evalQuery(lvalue, propRef.propertyAlias.part,
propRef.propertyAlias.location,
new EvaluationContextProxy(propRef.getVariable(),
lvalue));
} else if (ocopy.to instanceof OAssign.LValueExpression) {
LValueExpression lexpr = (LValueExpression) ocopy.to;
lexpr.setInsertMissingToData(ocopy.insertMissingToData);
lvaluePtr = evalQuery(lvalue, null, lexpr.expression,
new EvaluationContextProxy(lexpr.getVariable(), lvalue));
if (__log.isDebugEnabled())
__log.debug("lvaluePtr expr res " + lvaluePtr);
}
// For partner link assignmenent, the whole content is assigned.
if (ocopy.to instanceof OAssign.PartnerLinkRef) {
OAssign.PartnerLinkRef pLinkRef = ((OAssign.PartnerLinkRef) ocopy.to);
PartnerLinkInstance plval = _scopeFrame
.resolve(pLinkRef.partnerLink);
replaceEndpointRefence(plval, rvalue);
se = new PartnerLinkModificationEvent(((OAssign.PartnerLinkRef) ocopy.to).partnerLink.getName());
} else {
// Sneakily converting the EPR if it's not the format expected by the lvalue
if (ocopy.from instanceof OAssign.PartnerLinkRef) {
rvalue = getBpelRuntimeContext().convertEndpointReference((Element)rvalue, lvaluePtr);
if (rvalue.getNodeType() == Node.DOCUMENT_NODE)
rvalue = ((Document)rvalue).getDocumentElement();
}
Node parentNode = lvaluePtr.getParentNode();
if (headerAssign && parentNode != null && "message".equals(parentNode.getNodeName()) && rvalue.getNodeType()==Node.ELEMENT_NODE ) {
lvalue = copyInto((Element)lvalue, (Element) lvaluePtr, (Element) rvalue);
} else if (rvalue.getNodeType() == Node.ELEMENT_NODE && lvaluePtr.getNodeType() == Node.ELEMENT_NODE) {
lvalue = replaceElement((Element)lvalue, (Element) lvaluePtr, (Element) rvalue,
ocopy.keepSrcElementName);
} else {
// This try block which handles RuntimeException is added to fix issue when using process properties
// in BPEL processes. Due to some DOM related thing Node#getTextContent() throws a runtime exception.
// If getTextContent throws a exception we can try getNodeValue method to get the text content of this DOM
// Text Node. AFAIK this runtime exception is due to some incompatibility in DOM 3 and 2.
// ~ Milinda
// Refer : https://issues.apache.org/jira/browse/XMLBEANS-100
String rValueTextContent;
try{
rValueTextContent = rvalue.getTextContent();
} catch (RuntimeException re){
rValueTextContent = rvalue.getNodeValue();
}
lvalue = replaceContent(lvalue, lvaluePtr, rValueTextContent);
}
final VariableInstance lval = _scopeFrame.resolve(ocopy.to.getVariable());
if (__log.isDebugEnabled())
__log.debug("ASSIGN Writing variable '" + lval.declaration.name +
"' value '" + DOMUtils.domToString(lvalue) +"'");
commitChanges(lval, lvalue);
se = new VariableModificationEvent(lval.declaration.name);
((VariableModificationEvent)se).setNewValue(lvalue);
}
}
if (ocopy.debugInfo != null)
se.setLineNo(ocopy.debugInfo.startLine);
sendEvent(se);
}