/*   Copyright 2004 The Apache Software Foundation
*
*   Licensed 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.xmlbeans.samples.xquery;

import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;

/**
 * This class demonstrates how to use the execQuery method to execute XQuery
 * expressions. Compare the code here with the code in the SelectPath class. 
 * That class uses the selectPath method to execute XPath expressions.
 * <p/>
 * You can call the execQuery method from either an XmlObject or XmlCursor 
 * instance. Calling from XmlObject returns an XmlObject array. Calling 
 * from XmlCursor returns a new XmlCursor instance positioned at the root
 * of a fragment containing copies of the XML queried against. Results of the
 * query (if any) are sibling children of the fragment's root.
 */
public class ExecQuery
{
    final static String m_namespaceDeclaration =
                "declare namespace xq='http://xmlbeans.apache.org/samples/xquery/employees';";
    
    /**
     * Uses XQuery to retrieve work <phone> elements from the incoming XML, then
     * changes the number in the results.
     * 
     * This method demonstrates the following characteristics of the execQuery method: 
     * 
     * - it supports XQuery.
     * - the XML it returns is a copy of the XML queried against; contrast this with
     * the selectPath method, which returns a portion of the original document.
     * Changes to returned XML do not impact the XML queried against. 
     * - execQuery called from an XmlCursor returns a cursor positioned at
     * the STARTDOC token of a new XML fragment. Contrast this with the 
     * XmlCursor.selectPath method, which stores results as "selections" in 
     * the cursor used to execute the query.
     * 
     * @param empDoc The incoming XML.
     * @return <code>true</code> if the XPath expression returned results;
     * otherwise, <code>false</code>.
     */
    public boolean updateWorkPhone(XmlObject empDoc)
    {
        boolean hasResults = false;
        
        // A cursor instance to query with.
        XmlCursor empCursor = empDoc.newCursor();

        // The expression: Get the <employee> elements with <state> elements whose
        // value is "WA".
        String queryExpression =
                "for $e in $this/xq:employees/xq:employee " +
                "let $s := $e/xq:address/xq:state " +
                "where $s = 'WA' " +
                "return $e//xq:phone[@location='work']";

        // Execute the query. Results, if any, will be available at 
        // the position of the resultCursor in a new XML document.
        XmlCursor resultCursor = 
            empCursor.execQuery(m_namespaceDeclaration + queryExpression);
        
        System.out.println("The query results, <phone> element copies made " +
        		"from the received document: \n");
        System.out.println(resultCursor.getObject().toString() + "\n");
        
        // If there are results, the results will be children of the fragment root
        // where the new cursor is positioned. This statement tests for children
        // and moves the cursor if to the first if it exists.
        if (resultCursor.toFirstChild())
        {
            hasResults = true;
	        // Use the cursor to loop through the results, printing each sibling
	        // <employee> element returned by the query.
	        int i = 0;
	        do 
	        {
	            // Change the phone numbers.
	            XmlCursor editCursor = resultCursor.newCursor();
	            editCursor.toLastAttribute();
	            editCursor.toNextToken();
	            editCursor.removeXml();
	            editCursor.insertChars("(206)555-1234");
	        } while (resultCursor.toNextSibling());

	        resultCursor.toStartDoc();
	        System.out.println("The query results after changes: \n");
	        System.out.println(resultCursor.getObject().toString() + "\n");

    			System.out.println("The received document -- note that it is unchanged. " +
            		"Changes were made to the copy created by the execQuery method. \n");
    			System.out.println(empDoc + "\n");
        }
        return hasResults;
    }

    /**
     * Uses XQuery to retrieve work <zip> elements from the incoming XML, adding the
     * elements as children to a <zip-list> element.
     * 
     * This method demonstrates the following characteristics of the execQuery method: 
     * 
     * - it supports XQuery.
     * - execQuery called from an XmlObject returns an array of XmlObject instances.
     * These are bound to copies of the received XML.
     * 
     * @param empDoc The incoming XML.
     * @return <code>true</code> if the XPath expression returned results;
     * otherwise, <code>false</code>.
     */
    public boolean collectZips(XmlObject empDoc)
    {
        // The query is designed to return results, so return
        // true if it does.
        boolean hasResults = false;

        // The expression: Get the <zip> elements and return them as children 
        // of a new <zip-list> element.
        String queryExpression =
                "let $e := $this/xq:employees " +
                "return " +
                "<zip-list> " +
                    "{for $z in $e/xq:employee/xq:address/xq:zip " +
                    "return $z} " +
                "</zip-list>";

        // Execute the query. Results will be copies of the XML queried against,
        // stored as members of an XmlObject array.
        XmlObject[] results = 
            empDoc.execQuery(m_namespaceDeclaration + queryExpression);

        // Print the results.
        if (results.length > 0)
        {
            hasResults = true;
            System.out.println("The query results: \n");
            System.out.println(results[0].toString() + "\n");
        }
        return hasResults;
    }
}
