private void performQuery()

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);
        }
    }