/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.ode.bpel.runtime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.ode.bpel.common.FaultException; import org.apache.ode.bpel.evt.PartnerLinkModificationEvent; import org.apache.ode.bpel.evt.ScopeEvent; import org.apache.ode.bpel.evt.VariableModificationEvent; import org.apache.ode.bpel.explang.EvaluationContext; import org.apache.ode.bpel.explang.EvaluationException; import org.apache.ode.bpel.obj.OAssign; import org.apache.ode.bpel.obj.OAssign.DirectRef; import org.apache.ode.bpel.obj.OAssign.LValueExpression; import org.apache.ode.bpel.obj.OAssign.PropertyRef; import org.apache.ode.bpel.obj.OAssign.VariableRef; import org.apache.ode.bpel.obj.OElementVarType; import org.apache.ode.bpel.obj.OExpression; import org.apache.ode.bpel.obj.OLink; import org.apache.ode.bpel.obj.OMessageVarType; import org.apache.ode.bpel.obj.OMessageVarType.Part; import org.apache.ode.bpel.obj.OProcess.OProperty; import org.apache.ode.bpel.obj.OScope; import org.apache.ode.bpel.obj.OScope.Variable; import org.apache.ode.bpel.runtime.channels.FaultData; import org.apache.ode.utils.DOMUtils; import org.apache.ode.utils.Namespaces; import org.apache.ode.utils.msg.MessageBundle; import org.apache.ode.bpel.evar.ExternalVariableModuleException; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.SAXException; import javax.xml.namespace.QName; import java.io.IOException; import java.net.URI; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Map; /** * Assign activity run-time template. */ class ASSIGN extends ACTIVITY { private static final long serialVersionUID = 1L; private static final Logger __log = LoggerFactory.getLogger(ASSIGN.class); private static final ASSIGNMessages __msgs = MessageBundle .getMessages(ASSIGNMessages.class); public ASSIGN(ActivityInfo self, ScopeFrame scopeFrame, LinkFrame linkFrame) { super(self, scopeFrame, linkFrame); } public void run() { OAssign oassign = getOAsssign(); FaultData faultData = null; for (OAssign.Copy aCopy : oassign.getCopy()) { try { copy(aCopy); } catch (FaultException fault) { if (aCopy.isIgnoreMissingFromData()) { if (fault.getQName().equals(getOAsssign().getOwner().getConstants().getQnSelectionFailure()) && (fault.getCause() != null && "ignoreMissingFromData".equals(fault.getCause().getMessage()))) { continue; } } if (aCopy.isIgnoreUninitializedFromVariable()) { if (fault.getQName().equals(getOAsssign().getOwner().getConstants().getQnUninitializedVariable()) && (fault.getCause() == null || !"throwUninitializedToVariable".equals(fault.getCause().getMessage()))) { continue; } } faultData = createFault(fault.getQName(), aCopy, fault .getMessage()); break; } catch (ExternalVariableModuleException e) { __log.error("Exception while initializing external variable", e); _self.parent.failure(e.toString(), null); return; } } if (faultData != null) { __log.info("Assignment Fault: " + faultData.getFaultName() + ",lineNo=" + faultData.getFaultLineNo() + ",faultExplanation=" + faultData.getExplanation()); _self.parent.completed(faultData, CompensationHandler.emptySet()); } else { _self.parent.completed(null, CompensationHandler.emptySet()); } } protected Logger log() { return __log; } private OAssign getOAsssign() { return (OAssign) _self.o; } private Node evalLValue(OAssign.LValue to) throws FaultException, ExternalVariableModuleException { final BpelRuntimeContext napi = getBpelRuntimeContext(); Node lval = null; if (!(to instanceof OAssign.PartnerLinkRef)) { VariableInstance lvar; try { lvar = _scopeFrame.resolve(to.getVariable()); } catch (RuntimeException e) { __log.error("iid: " + getBpelRuntimeContext().getPid() + " error evaluating lvalue"); throw new FaultException(getOAsssign().getOwner().getConstants().getQnSelectionFailure(), e.getMessage()); } if (lvar == null) { String msg = __msgs.msgEvalException(to.toString(), "Could not resolve variable in current scope"); if (__log.isDebugEnabled()) __log.debug(to + ": " + msg); throw new FaultException(getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } if (!napi.isVariableInitialized(lvar)) { Document doc = DOMUtils.newDocument(); Node val = to.getVariable().getType().newInstance(doc); if (val.getNodeType() == Node.TEXT_NODE) { Element tempwrapper = doc.createElementNS(null, "temporary-simple-type-wrapper"); doc.appendChild(tempwrapper); tempwrapper.appendChild(val); val = tempwrapper; } else doc.appendChild(val); // Only external variables need to be initialized, others are new and going to be overwtitten if (lvar.declaration.getExtVar() != null) lval = initializeVariable(lvar, val); else lval = val; } else lval = fetchVariableData(lvar, true); } return lval; } /** * Get the r-value. There are several possibilities: * <ul> * <li>a message is selected - an element representing the whole message is * returned.</li> * <li>a (element) message part is selected - the element is returned. * </li> * <li>a (typed) message part is select - a wrapper element is returned. * </li> * <li>an attribute is selected - an attribute node is returned. </li> * <li>a text node/string expression is selected - a text node is returned. * </li> * </ul> * * @param from * * @return Either {@link Element}, {@link org.w3c.dom.Text}, or * {@link org.w3c.dom.Attr} node representing the r-value. * * @throws FaultException * DOCUMENTME * @throws UnsupportedOperationException * DOCUMENTME * @throws IllegalStateException * DOCUMENTME */ private Node evalRValue(OAssign.RValue from) throws FaultException, ExternalVariableModuleException { if (__log.isDebugEnabled()) __log.debug("Evaluating FROM expression \"" + from + "\"."); Node retVal; if (from instanceof DirectRef) { OAssign.DirectRef dref = (OAssign.DirectRef) from; sendVariableReadEvent(_scopeFrame.resolve(dref.getVariable())); Node data = fetchVariableData( _scopeFrame.resolve(dref.getVariable()), false); retVal = DOMUtils.findChildByName((Element)data, dref.getElName()); } else if (from instanceof OAssign.VariableRef) { OAssign.VariableRef varRef = (OAssign.VariableRef) from; sendVariableReadEvent(_scopeFrame.resolve(varRef.getVariable())); Node data = fetchVariableData(_scopeFrame.resolve(varRef.getVariable()), false); retVal = evalQuery(data, varRef.getPart() != null ? varRef.getPart() : varRef.getHeaderPart(), varRef.getLocation(), getEvaluationContext()); } else if (from instanceof OAssign.PropertyRef) { OAssign.PropertyRef propRef = (OAssign.PropertyRef) from; sendVariableReadEvent(_scopeFrame.resolve(propRef.getVariable())); Node data = fetchVariableData(_scopeFrame.resolve(propRef.getVariable()), false); retVal = evalQuery(data, propRef.getPropertyAlias().getPart(), propRef.getPropertyAlias().getLocation(), getEvaluationContext()); } else if (from instanceof OAssign.PartnerLinkRef) { OAssign.PartnerLinkRef pLinkRef = (OAssign.PartnerLinkRef) from; PartnerLinkInstance pLink = _scopeFrame.resolve(pLinkRef.getPartnerLink()); Node tempVal =pLinkRef.isIsMyEndpointReference() ? getBpelRuntimeContext().fetchMyRoleEndpointReferenceData(pLink) : getBpelRuntimeContext().fetchPartnerRoleEndpointReferenceData(pLink); if (__log.isDebugEnabled()) __log.debug("RValue is a partner link, corresponding endpoint " + tempVal.getClass().getName() + " has value " + DOMUtils.domToString(tempVal)); retVal = tempVal; } else if (from instanceof OAssign.Expression) { List<Node> l; OExpression expr = ((OAssign.Expression) from).getExpression(); try { l = getBpelRuntimeContext().getExpLangRuntime().evaluate(expr, getEvaluationContext()); if (l.size() == 0 || l.get(0) == null || !(l.get(0) instanceof Element)) { if (__log.isTraceEnabled()) { __log.trace("evalRValue: OAssign.Expression: eval reult not Element or node=null"); } } else { Element element = (Element)l.get(0); for (Map.Entry<String, String> entry : DOMUtils.getMyNSContext(element).toMap().entrySet()) { String key = entry.getKey(); String value = entry.getValue(); if (entry.getKey() == null || entry.getKey().length() == 0) { element.setAttributeNS(DOMUtils.NS_URI_XMLNS, "xmlns", value); } else { element.setAttributeNS(DOMUtils.NS_URI_XMLNS, "xmlns:" + key, value); } } } } catch (EvaluationException e) { String msg = __msgs.msgEvalException(from.toString(), e.getMessage()); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); if (e.getCause() instanceof FaultException) throw (FaultException)e.getCause(); throw new FaultException(getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } if (l.size() == 0) { String msg = __msgs.msgRValueNoNodesSelected(expr.toString()); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); throw new FaultException(getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg, new Throwable("ignoreMissingFromData")); } else if (l.size() > 1) { String msg = __msgs.msgRValueMultipleNodesSelected(expr.toString()); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); throw new FaultException(getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } retVal = (Node) l.get(0); } else if (from instanceof OAssign.Literal) { String literal = ((OAssign.Literal) from).getXmlLiteral(); Element literalRoot; try { literalRoot = DOMUtils.stringToDOM(literal); } catch (Exception e) { throw new RuntimeException("XML literal parsing failed " + literal, e); } assert literalRoot.getLocalName().equals("literal"); // We'd like a single text node... literalRoot.normalize(); retVal = literalRoot.getFirstChild(); // Adjust for whitespace before an element. if (retVal != null && retVal.getNodeType() == Node.TEXT_NODE && retVal.getTextContent().trim().length() == 0 && retVal.getNextSibling() != null) { retVal = retVal.getNextSibling(); } if (retVal == null) { // Special case, no children --> empty TII retVal = literalRoot.getOwnerDocument().createTextNode(""); } else if (retVal.getNodeType() == Node.ELEMENT_NODE) { // Make sure there is no more elements. Node x = retVal.getNextSibling(); while (x != null) { if (x.getNodeType() == Node.ELEMENT_NODE) { String msg = __msgs.msgLiteralContainsMultipleEIIs(); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); throw new FaultException( getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } x = x.getNextSibling(); } } else if (retVal.getNodeType() == Node.TEXT_NODE) { // Make sure there are no elements following this text node. Node x = retVal.getNextSibling(); while (x != null) { if (x.getNodeType() == Node.ELEMENT_NODE) { String msg = __msgs.msgLiteralContainsMixedContent(); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); throw new FaultException( getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } x = x.getNextSibling(); } } if (retVal == null) { String msg = __msgs.msgLiteralMustContainTIIorEII(); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); throw new FaultException( getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } } else { String msg = __msgs .msgInternalError("Unknown RVALUE type: " + from); if (__log.isErrorEnabled()) __log.error(from + ": " + msg); throw new FaultException( getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } // Now verify we got something. if (retVal == null) { String msg = __msgs.msgEmptyRValue(); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); throw new FaultException( getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } // Now check that we got the right thing. switch (retVal.getNodeType()) { case Node.TEXT_NODE: case Node.ATTRIBUTE_NODE: case Node.ELEMENT_NODE: case Node.CDATA_SECTION_NODE: break; default: String msg = __msgs.msgInvalidRValue(); if (__log.isDebugEnabled()) __log.debug(from + ": " + msg); throw new FaultException( getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } return retVal; } 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.getTo() instanceof VariableRef && ((VariableRef) ocopy.getTo()) .isMessageRef()) || (ocopy.getFrom() instanceof VariableRef && ((VariableRef) ocopy.getFrom()) .isMessageRef())) { if ((ocopy.getTo() instanceof VariableRef && ((VariableRef) ocopy.getTo()) .isMessageRef()) && ocopy.getFrom() instanceof VariableRef && ((VariableRef) ocopy.getFrom()).isMessageRef()) { final VariableInstance lval = _scopeFrame.resolve(ocopy.getTo() .getVariable()); final VariableInstance rval = _scopeFrame .resolve(((VariableRef) ocopy.getFrom()).getVariable()); Element lvalue = (Element) fetchVariableData(rval, false); initializeVariable(lval, lvalue); se = new VariableModificationEvent(lval.declaration.getName()); ((VariableModificationEvent)se).setNewValue(lvalue); } else { // This really should have been caught by the compiler. __log.error("Message/Non-Message Assignment, should be caught by compiler:" + ocopy); throw new FaultException( ocopy.getOwner().getConstants().getQnSelectionFailure(), "Message/Non-Message Assignment: " + ocopy); } } else { // Conventional Assignment logic. Node rvalue = evalRValue(ocopy.getFrom()); Node lvalue = evalLValue(ocopy.getTo()); 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.getTo() instanceof OAssign.DirectRef) { DirectRef dref = ((DirectRef) ocopy.getTo()); Element el = DOMUtils.findChildByName((Element)lvalue, dref.getElName()); if (el == null) { el = (Element) ((Element)lvalue).appendChild(lvalue.getOwnerDocument() .createElementNS(dref.getElName().getNamespaceURI(), dref.getElName().getLocalPart())); } lvaluePtr = el; } else if (ocopy.getTo() instanceof OAssign.VariableRef) { VariableRef varRef = ((VariableRef) ocopy.getTo()); if (varRef.getHeaderPart() != null) headerAssign = true; lvaluePtr = evalQuery(lvalue, varRef.getPart() != null ? varRef.getPart() : varRef.getHeaderPart(), varRef.getLocation(), new EvaluationContextProxy(varRef.getVariable(), lvalue)); } else if (ocopy.getTo() instanceof OAssign.PropertyRef) { PropertyRef propRef = ((PropertyRef) ocopy.getTo()); lvaluePtr = evalQuery(lvalue, propRef.getPropertyAlias().getPart(), propRef.getPropertyAlias().getLocation(), new EvaluationContextProxy(propRef.getVariable(), lvalue)); } else if (ocopy.getTo() instanceof OAssign.LValueExpression) { LValueExpression lexpr = (LValueExpression) ocopy.getTo(); lexpr.setInsertMissingToData(ocopy.isInsertMissingToData()); lvaluePtr = evalQuery(lvalue, null, lexpr.getExpression(), 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.getTo() instanceof OAssign.PartnerLinkRef) { OAssign.PartnerLinkRef pLinkRef = ((OAssign.PartnerLinkRef) ocopy.getTo()); PartnerLinkInstance plval = _scopeFrame .resolve(pLinkRef.getPartnerLink()); replaceEndpointRefence(plval, rvalue); se = new PartnerLinkModificationEvent(((OAssign.PartnerLinkRef) ocopy.getTo()).getPartnerLink().getName()); } else { // Sneakily converting the EPR if it's not the format expected by the lvalue if (ocopy.getFrom() 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.isKeepSrcElementName()); } else { lvalue = replaceContent(lvalue, lvaluePtr, rvalue.getTextContent()); } final VariableInstance lval = _scopeFrame.resolve(ocopy.getTo().getVariable()); if (__log.isDebugEnabled()) __log.debug("ASSIGN Writing variable '" + lval.declaration.getName() + "' value '" + DOMUtils.domToString(lvalue) +"'"); commitChanges(lval, lvalue); se = new VariableModificationEvent(lval.declaration.getName()); ((VariableModificationEvent)se).setNewValue(lvalue); } } if (ocopy.getDebugInfo() != null) se.setLineNo(ocopy.getDebugInfo().getStartLine()); sendEvent(se); } @Override Node fetchVariableData(VariableInstance variable, boolean forWriting) throws FaultException { try { return super.fetchVariableData(variable, forWriting); } catch (FaultException fe) { if (forWriting) { fe = new FaultException(fe.getQName(), fe.getMessage(), new Throwable("throwUninitializedToVariable")); } throw fe; } } private void replaceEndpointRefence(PartnerLinkInstance plval, Node rvalue) throws FaultException { if (rvalue.getNodeType() == Node.ATTRIBUTE_NODE){ rvalue = rvalue.getOwnerDocument().createTextNode(((Attr) rvalue).getValue()); } // Eventually wrapping with service-ref element if we've been directly assigned some // value that isn't wrapped. if (rvalue.getNodeType() == Node.TEXT_NODE || (rvalue.getNodeType() == Node.ELEMENT_NODE && !rvalue.getLocalName().equals("service-ref"))) { Document doc = DOMUtils.newDocument(); Element serviceRef = doc.createElementNS(Namespaces.WSBPEL2_0_FINAL_SERVREF, "service-ref"); doc.appendChild(serviceRef); serviceRef.appendChild(doc.importNode(rvalue, true)); rvalue = serviceRef; } getBpelRuntimeContext().writeEndpointReference(plval, (Element)rvalue); } private Element replaceElement(Element lval, Element ptr, Element src, boolean keepSrcElement) { Document doc = ptr.getOwnerDocument(); Node parent = ptr.getParentNode(); if (keepSrcElement) { Element replacement = (Element)doc.importNode(src, true); parent.replaceChild(replacement, ptr); return (lval == ptr) ? replacement : lval; } Element replacement = doc.createElementNS(ptr.getNamespaceURI(), ptr.getTagName()); NodeList nl = src.getChildNodes(); for (int i = 0; i < nl.getLength(); ++i) replacement.appendChild(doc.importNode(nl.item(i), true)); copyAttributes(doc, ptr, replacement); copyAttributes(doc, src, replacement); parent.replaceChild(replacement, ptr); DOMUtils.copyNSContext(ptr, replacement); return (lval == ptr) ? replacement : lval; } private void copyAttributes(Document doc, Element original, Element replacement) { NamedNodeMap attrs = original.getAttributes(); for (int i = 0; i < attrs.getLength(); ++i) { Attr attr = (Attr)attrs.item(i); replacement.setAttributeNodeNS((Attr)doc.importNode(attr, true)); } } private Element copyInto(Element lval, Element ptr, Element src) { ptr.appendChild(ptr.getOwnerDocument().importNode(src, true)); return lval; } /** * isInsert flag desginates this as an 'element' type insertion, which * requires insert the actual element value, rather than it's children * * @return * @throws FaultException */ private Node replaceContent(Node lvalue, Node lvaluePtr, String rvalue) throws FaultException { Document d = lvaluePtr.getOwnerDocument(); if (__log.isDebugEnabled()) { __log.debug("lvaluePtr type " + lvaluePtr.getNodeType()); __log.debug("lvaluePtr " + DOMUtils.domToString(lvaluePtr)); __log.debug("lvalue " + lvalue); __log.debug("rvalue " + rvalue); } switch (lvaluePtr.getNodeType()) { case Node.ELEMENT_NODE: // Remove all the children. while (lvaluePtr.hasChildNodes()) lvaluePtr.removeChild(lvaluePtr.getFirstChild()); // Append a new text node. lvaluePtr.appendChild(d.createTextNode(rvalue)); // If lvalue is a text, removing all lvaluePtr children had just removed it // so we need to rebuild it as a child of lvaluePtr if (lvalue instanceof Text) lvalue = lvaluePtr.getFirstChild(); break; case Node.TEXT_NODE: Node newval = d.createTextNode(rvalue); // Replace ourselves . lvaluePtr.getParentNode().replaceChild(newval, lvaluePtr); // A little kludge, let our caller know that the root element has changed. // (used for assignment to a simple typed variable) if (lvalue.getNodeType() == Node.ELEMENT_NODE) { // No children, adding an empty text children to point to if (lvalue.getFirstChild() == null) { Text txt = lvalue.getOwnerDocument().createTextNode(""); lvalue.appendChild(txt); } if (lvalue.getFirstChild().getNodeType() == Node.TEXT_NODE) lvalue = lvalue.getFirstChild(); } if (lvalue.getNodeType() == Node.TEXT_NODE && ((Text) lvalue).getWholeText().equals( ((Text) lvaluePtr).getWholeText())) lvalue = lvaluePtr = newval; break; case Node.ATTRIBUTE_NODE: ((Attr) lvaluePtr).setValue(rvalue); break; default: // This could occur if the expression language selects something // like // a PI or a CDATA. String msg = __msgs.msgInvalidLValue(); if (__log.isDebugEnabled()) __log.debug(lvaluePtr + ": " + msg); throw new FaultException( getOAsssign().getOwner().getConstants().getQnSelectionFailure(), msg); } return lvalue; } private Node evalQuery(Node data, OMessageVarType.Part part, OExpression expression, EvaluationContext ec) throws FaultException { assert data != null; if (part != null) { QName partName = new QName(null, part.getName()); Node qualLVal = DOMUtils.findChildByName((Element) data, partName); if (part.getType() instanceof OElementVarType) { QName elName = ((OElementVarType) part.getType()).getElementType(); qualLVal = DOMUtils.findChildByName((Element) qualLVal, elName); } else if (part.getType() == null) { // Special case of header parts never referenced in the WSDL def if (qualLVal != null && qualLVal.getNodeType() == Node.ELEMENT_NODE && ((Element)qualLVal).getAttribute("headerPart") != null && DOMUtils.getTextContent(qualLVal) == null) qualLVal = DOMUtils.getFirstChildElement((Element) qualLVal); // The needed part isn't there, dynamically creating it if (qualLVal == null) { qualLVal = data.getOwnerDocument().createElementNS(null, part.getName()); ((Element)qualLVal).setAttribute("headerPart", "true"); data.appendChild(qualLVal); } } data = qualLVal; } if (expression != null) { // Neat little trick.... try { data = ec.evaluateQuery(data, expression); } catch (EvaluationException e) { String msg = __msgs.msgEvalException(expression.toString(), e.getMessage()); if (__log.isDebugEnabled()) __log.debug(expression + ": " + msg); if (e.getCause() instanceof FaultException) throw (FaultException)e.getCause(); throw new FaultException(getOAsssign().getOwner().getConstants().getQnSubLanguageExecutionFault(), msg); } } return data; } private class EvaluationContextProxy implements EvaluationContext { private Variable _var; private Node _varNode; private Node _rootNode; private EvaluationContext _ctx; private EvaluationContextProxy(Variable var, Node varNode) { _var = var; _varNode = varNode; _ctx = getEvaluationContext(); } public Node readVariable(OScope.Variable variable, OMessageVarType.Part part) throws FaultException { if (variable.getName().equals(_var.getName())) { if (part == null) return _varNode; return _ctx.getPartData((Element)_varNode, part); } else return _ctx.readVariable(variable, part); } /** * @see org.apache.ode.bpel.explang.EvaluationContext#readMessageProperty(org.apache.ode.bpel.obj.OScope.Variable, * org.apache.ode.bpel.obj.OProcess.OProperty) */ public String readMessageProperty(Variable variable, OProperty property) throws FaultException { return _ctx.readMessageProperty(variable, property); } /** * @see org.apache.ode.bpel.explang.EvaluationContext#isLinkActive(org.apache.ode.bpel.obj.OLink) */ public boolean isLinkActive(OLink olink) throws FaultException { return _ctx.isLinkActive(olink); } /** * @see org.apache.ode.bpel.explang.EvaluationContext#getRootNode() */ public Node getRootNode() { return _rootNode; } /** * @see org.apache.ode.bpel.explang.EvaluationContext#evaluateQuery(org.w3c.dom.Node, * org.apache.ode.bpel.obj.OExpression) */ public Node evaluateQuery(Node root, OExpression expr) throws FaultException { _rootNode = root; try { return getBpelRuntimeContext().getExpLangRuntime() .evaluateNode(expr, this); } catch (org.apache.ode.bpel.explang.EvaluationException e) { throw new FaultException(expr.getOwner().getConstants().getQnSubLanguageExecutionFault(), e); } } public Node getPartData(Element message, Part part) throws FaultException { return _ctx.getPartData(message,part); } public Long getProcessId() { return _ctx.getProcessId(); } public boolean narrowTypes() { return false; } public URI getBaseResourceURI() { return _ctx.getBaseResourceURI(); } public Node getPropertyValue(QName propertyName) { return _ctx.getPropertyValue(propertyName); } public QName getProcessQName() { return _ctx.getProcessQName(); } public Date getCurrentEventDateTime() { return Calendar.getInstance().getTime(); } } }