/* * 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.synapse.mediators.xquery; import net.sf.saxon.s9api.XdmNodeKind; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNode; import org.apache.axiom.om.OMText; import org.apache.axiom.soap.SOAP11Constants; import org.apache.axiom.soap.SOAP12Constants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.MessageContext; import org.apache.synapse.SynapseException; import org.apache.synapse.config.Entry; import org.apache.synapse.util.xpath.SynapseXPath; import org.apache.synapse.util.xpath.SourceXPathSupport; import org.jaxen.JaxenException; import javax.xml.namespace.QName; import java.util.List; /** * The value of the custom variable will be evaluated dynamically. * The value is computed by extracting the data from the XML document which will lookup through the * key or the current SOAP message. */ public class MediatorCustomVariable extends MediatorVariable { private static final Log log = LogFactory.getLog(MediatorCustomVariable.class); /* The key to lookup the xml document from registry */ private String regKey; /* The XPath expression*/ private SynapseXPath expression; /*Lock used to ensure thread-safe lookup of the object from the registry */ private final Object resourceLock = new Object(); public MediatorCustomVariable(QName name) { super(name); // create the default XPath try { this.expression = new SynapseXPath(SourceXPathSupport.DEFAULT_XPATH); this.expression.addNamespace("s11", SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI); this.expression.addNamespace("s12", SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI); } catch (JaxenException e) { handleException("Error creating source XPath expression", e); } } /** * To assign a value to variable dynamically * * @param synCtx The current message context */ public boolean evaluateValue(MessageContext synCtx) { if (this.regKey == null) { // get the node from the current message payload this.value = evaluate(synCtx); return true; } else { //Load the XML document from the registry boolean reLoad = false; boolean hasValueChanged = false; Entry dp = synCtx.getConfiguration().getEntryDefinition(this.regKey); // if the key refers to a dynamic resource if (dp != null && dp.isDynamic()) { if (!dp.isCached() || dp.isExpired()) { reLoad = true; } } synchronized (resourceLock) { if (reLoad || this.value == null) { hasValueChanged = true; Object o = synCtx.getEntry(this.regKey); if (o != null) { if (!SourceXPathSupport.DEFAULT_XPATH.equals(expression.toString())) { this.value = evaluate(o); } else { this.value = o; } } } } return hasValueChanged; } } /** * Return the object to be used for the variable value * * @param source The source on which will be evaluated the XPath expression * @return Return the OMNode to be used for the variable value */ private Object evaluate(Object source) { try { Object result = expression.evaluate(source); if (result instanceof List && !((List) result).isEmpty()) { result = ((List) result).get(0); // Always fetches *only* the first } if (result instanceof OMNode) { //if the type is not document-node(), then get the text value of the node if (this.getNodeKind() != XdmNodeKind.DOCUMENT && this.getNodeKind() != XdmNodeKind.ELEMENT) { int nodeType = ((OMNode) result).getType(); if (nodeType == OMNode.TEXT_NODE) { return ((OMText) result).getText(); } else if (nodeType == OMNode.ELEMENT_NODE) { return ((OMElement) result).getText(); } } return result; } else { return result; } } catch (JaxenException e) { handleException("Error evaluating XPath " + expression + " on message" + source); } return null; } private void handleException(String msg, Exception e) { log.error(msg, e); throw new SynapseException(msg, e); } private void handleException(String msg) { log.error(msg); throw new SynapseException(msg); } public void setExpression(SynapseXPath expression) { this.expression = expression; } public void setRegKey(String regKey) { this.regKey = regKey; } public String getRegKey() { return regKey; } public SynapseXPath getExpression() { return expression; } }