in modules/extensions/src/main/java/org/apache/synapse/mediators/xquery/XQueryMediator.java [142:415]
private void performQuery(MessageContext synCtx, SynapseLog synLog) {
boolean reLoad = false;
boolean needBind = false;
XQResultSequence resultSequence;
String generatedQueryKey = null;
boolean isQueryKeyGenerated = false;
if (queryKey != null) {
// Derive actual key from xpath or get static key
generatedQueryKey = queryKey.evaluateValue(synCtx);
}
if (generatedQueryKey != null) {
isQueryKeyGenerated = true;
}
// get expression from generatedQueryKey
XQPreparedExpression cachedPreparedExpression = null;
if (generatedQueryKey != null && !"".equals(generatedQueryKey)) {
Entry dp = synCtx.getConfiguration().getEntryDefinition(generatedQueryKey);
// if the queryKey refers to a dynamic resource
if (dp != null && dp.isDynamic()) {
if (!dp.isCached() || dp.isExpired()) {
reLoad = true;
}
}
}
try {
synchronized (resourceLock) {
//creating data source
if (cachedXQDataSource == null) {
// A factory for XQConnection objects
cachedXQDataSource = new SaxonXQDataSource();
//setting up the properties to the XQDataSource
if (dataSourceProperties != null && !dataSourceProperties.isEmpty()) {
synLog.traceOrDebug("Setting up properties to the XQDataSource");
for (MediatorProperty dataSourceProperty : dataSourceProperties) {
if (dataSourceProperty != null) {
cachedXQDataSource.setProperty(dataSourceProperty.getName(),
dataSourceProperty.getValue());
}
}
}
}
//creating connection
if (cachedConnection == null
|| (cachedConnection != null && cachedConnection.isClosed())) {
//get the Connection to XML DataBase
synLog.traceOrDebug("Creating a connection from the XQDataSource ");
cachedConnection = cachedXQDataSource.getConnection();
}
//If already cached expression then load it from cachedPreparedExpressionMap
if (isQueryKeyGenerated) {
cachedPreparedExpression = cachedPreparedExpressionMap.get(generatedQueryKey);
}
// prepare the expression to execute query
if (reLoad || cachedPreparedExpression == null
|| (cachedPreparedExpression != null
&& cachedPreparedExpression.isClosed())) {
if (querySource != null && !"".equals(querySource)) {
if (cachedPreparedExpression == null) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Using in-lined query source - " + querySource);
synLog.traceOrDebug("Prepare an expression for the query ");
}
//create an XQPreparedExpression using the query source
cachedPreparedExpression =
cachedConnection.prepareExpression(querySource);
// if cachedPreparedExpression is created then put it in to cachedPreparedExpressionMap
if (isQueryKeyGenerated) {
cachedPreparedExpressionMap.put(generatedQueryKey, cachedPreparedExpression);
}
// need binding because the expression just has recreated
needBind = true;
}
} else {
Object o = synCtx.getEntry(generatedQueryKey);
if (o == null) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Couldn't find the xquery source with a key "
+ queryKey);
}
return;
}
String sourceCode = null;
InputStream inputStream = null;
if (o instanceof OMElement) {
sourceCode = ((OMElement) (o)).getText();
} else if (o instanceof String) {
sourceCode = (String) o;
} else if (o instanceof OMText) {
DataHandler dataHandler = (DataHandler) ((OMText) o).getDataHandler();
if (dataHandler != null) {
try {
inputStream = dataHandler.getInputStream();
if (inputStream == null) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Couldn't get" +
" the stream from the xquery source with a key "
+ queryKey);
}
return;
}
} catch (IOException e) {
handleException("Error in reading content as a stream ");
}
}
}
if ((sourceCode == null || "".equals(sourceCode)) && inputStream == null) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Couldn't find the xquery source with a key "
+ queryKey);
}
return;
}
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("Picked up the xquery source from the " +
"key " + queryKey);
synLog.traceOrDebug("Prepare an expression for the query ");
}
if (sourceCode != null) {
//create an XQPreparedExpression using the query source
cachedPreparedExpression =
cachedConnection.prepareExpression(sourceCode);
} else {
//create an XQPreparedExpression using the query source stream
cachedPreparedExpression =
cachedConnection.prepareExpression(inputStream);
}
// if cachedPreparedExpression is created then put it in to cachedPreparedExpressionMap
if (isQueryKeyGenerated) {
cachedPreparedExpressionMap.put(generatedQueryKey, cachedPreparedExpression);
}
// need binding because the expression just has recreated
needBind = true;
}
}
//Bind the external variables to the DynamicContext
if (variables != null && !variables.isEmpty()) {
synLog.traceOrDebug("Binding external variables to the DynamicContext");
for (MediatorVariable variable : variables) {
if (variable != null) {
boolean hasValueChanged = variable.evaluateValue(synCtx);
//if the value has changed or need binding because the expression has recreated
if (hasValueChanged || needBind) {
//Binds the external variable to the DynamicContext
bindVariable(cachedPreparedExpression, variable, synLog);
}
}
}
}
//executing the query
resultSequence = cachedPreparedExpression.executeQuery();
}
if (resultSequence == null) {
synLog.traceOrDebug("Result Sequence is null");
return;
}
//processing the result
while (resultSequence.next()) {
XQItem xqItem = resultSequence.getItem();
if (xqItem == null) {
return;
}
XQItemType itemType = xqItem.getItemType();
if (itemType == null) {
return;
}
int itemKind = itemType.getItemKind();
int baseType = itemType.getBaseType();
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("The XQuery Result " + xqItem.getItemAsString());
}
//The target node that is going to modify
OMNode destination = target.selectOMNode(synCtx, synLog);
if (destination != null) {
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("The target node " + destination);
}
//If the result is XML
if (XQItemType.XQITEMKIND_DOCUMENT_ELEMENT == itemKind ||
XQItemType.XQITEMKIND_ELEMENT == itemKind ||
XQItemType.XQITEMKIND_DOCUMENT == itemKind) {
OMXMLParserWrapper builder = OMXMLBuilderFactory.createOMBuilder(
new StringReader(xqItem.getItemAsString()));
OMElement resultOM = builder.getDocumentElement();
if (resultOM != null) {
//replace the target node from the result
destination.insertSiblingAfter(resultOM);
destination.detach();
}
} else if (XQItemType.XQBASETYPE_INTEGER == baseType ||
XQItemType.XQBASETYPE_INT == baseType) {
//replace the text value of the target node by the result ,If the result is
// a basic type
((OMElement) destination).setText(String.valueOf(xqItem.getInt()));
} else if (XQItemType.XQBASETYPE_BOOLEAN == baseType) {
((OMElement) destination).setText(String.valueOf(xqItem.getBoolean()));
} else if (XQItemType.XQBASETYPE_DOUBLE == baseType) {
((OMElement) destination).setText(String.valueOf(xqItem.getDouble()));
} else if (XQItemType.XQBASETYPE_FLOAT == baseType) {
((OMElement) destination).setText(String.valueOf(xqItem.getFloat()));
} else if (XQItemType.XQBASETYPE_LONG == baseType) {
((OMElement) destination).setText(String.valueOf(xqItem.getLong()));
} else if (XQItemType.XQBASETYPE_SHORT == baseType) {
((OMElement) destination).setText(String.valueOf(xqItem.getShort()));
} else if (XQItemType.XQBASETYPE_BYTE == baseType) {
((OMElement) destination).setText(String.valueOf(xqItem.getByte()));
} else if (XQItemType.XQBASETYPE_STRING == baseType) {
((OMElement) destination).setText(
String.valueOf(xqItem.getItemAsString()));
}
} else if (target.getXPath() == null) {
//In the case soap body doesn't have the first element --> Empty soap body
destination = synCtx.getEnvelope().getBody();
if (synLog.isTraceOrDebugEnabled()) {
synLog.traceOrDebug("The target node " + destination);
}
//If the result is XML
if (XQItemType.XQITEMKIND_DOCUMENT_ELEMENT == itemKind ||
XQItemType.XQITEMKIND_ELEMENT == itemKind ||
XQItemType.XQITEMKIND_DOCUMENT == itemKind) {
OMXMLParserWrapper builder = OMXMLBuilderFactory.createOMBuilder(
new StringReader(xqItem.getItemAsString()));
OMElement resultOM = builder.getDocumentElement();
if (resultOM != null) {
((OMElement) destination).addChild(resultOM);
}
}
//No else part since soap body could have only XML part not text values
}
break; // Only take the *first* value of the result sequence
}
resultSequence.close(); // closing the result sequence
} catch (XQException e) {
handleException("Error during the querying " + e.getMessage(), e);
} catch (OMException e) {
handleException("Error during retrieving the Doument Node as the result "
+ e.getMessage(), e);
}
}