/*   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;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.samples.xquery.employees.PhoneType;

/**
 * This class demonstrates how to use the selectPath method to execute XPath
 * expressions. Compare the code here with the code in the ExecQuery class. 
 * That class uses the execQuery method to execute XQuery expressions.
 * <p/>
 * You can call the selectPath method from either an XmlObject or XmlCursor 
 * instance. Calling from XmlObject returns an XmlObject array. Calling 
 * from XmlCursor returns void, and you use methods of the cursor to 
 * navigate among returned "selections".
 */
public class SelectPath
{
    // Declare a namespace corresponding to the namespace declared in the XML
    // instance. The string here will be used as part of the XPath expression to
    // ensure that the query finds namespace-qualified elements in the XML.
    final static String m_namespaceDeclaration = 
        "declare namespace xq='http://xmlbeans.apache.org/samples/xquery/employees';";

    /**
     * Prints the XML bound to <em>empDoc</em>, uses XPath to 
     * retrieve elements containing work phone numbers, changes the numbers 
     * to another number, then prints the XML again to display the changes.
     * 
     * This method demonstrates the following characteristics of the selectPath method: 
     * 
     * - it supports expressions that include predicates 
     * - the XML it returns is the XML queried against -- not a copy, as with results
     * returned via execQuery methods and XQuery. Changes to this XML update 
     * the XML queried against. 
     * - selectPath called from an XMLBean type (instead of a cursor) returns an 
     * array of results (if any). These results can be cast to a matching type 
     * generated from schema.
     * 
     * @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;

        // Print the XML received.
        System.out.println("XML as received by updateWorkPhone method: \n\n"
                + empDoc.toString());
 
        // Create a variable with the query expression.
        String pathExpression = 
            "$this/xq:employees/xq:employee/xq:phone[@location='work']";

        // Execute the query.
        XmlObject[] results = empDoc.selectPath(m_namespaceDeclaration
                + pathExpression);
        if (results.length > 0)
        {
            hasResults = true;

            // <phone> elements returned from the expression will conform to the
            // schema, so bind them to the appropriate XMLBeans type generated
            // from the schema.
            PhoneType[] phones = (PhoneType[]) results;

            // Change all the work phone numbers to the same number.
            for (int i = 0; i < phones.length; i++)
            {
                phones[i].setStringValue("(206)555-1234");
            }
            // Print the XML with updates.
            System.out.println("\nXML as updated by updateWorkPhone method (each work \n" +
                    "phone number has been changed to the same number): \n\n"
                    + empDoc.toString() + "\n");
        }
        return hasResults;
    }

    /**
     * Uses the XPath text() function to get values from <name>
     * elements in received XML, then collects those values as the value of a
     * <names> element created here.
     * <p/>
     * Demonstrates the following characteristics of the selectPath method: 
     * <p/>
     * - It supports expressions that include XPath function calls.
     * - selectPath called from an XmlCursor instance (instead of an XMLBeans 
     * type) places results (if any) into the cursor's selection set.
     * 
     * @param empDoc The incoming XML.
     * @return <code>true</code> if the XPath expression returned results;
     * otherwise, <code>false</code>.
     */
    public boolean collectNames(XmlObject empDoc)
    {
        boolean hasResults = false;

        // Create a cursor with which to execute query expressions. The cursor
        // is inserted at the very beginning of the incoming XML, then moved to
        // the first element's START token.
        XmlCursor pathCursor = empDoc.newCursor();
        pathCursor.toFirstChild();

        // Execute the path expression, qualifying it with the namespace
        // declaration.
        pathCursor.selectPath(m_namespaceDeclaration
                + "$this//xq:employee/xq:name/text()");

        // If there are results, then go ahead and do stuff.
        if (pathCursor.getSelectionCount() > 0)
        {
            hasResults = true;

            // Create a new <names> element into which names from the XML
            // will be copied. Note that this element is in the default
            // namespace; it's not part of the schema.
            XmlObject namesElement = null;
            try
            {
                namesElement = XmlObject.Factory.parse("<names/>");
            } catch (XmlException e)
            {
                e.printStackTrace();
            }

            // Add a cursor the new element and put it between its START and END
            // tokens, where new values can be inserted.
            XmlCursor namesCursor = namesElement.newCursor();
            namesCursor.toFirstContentToken();
            namesCursor.toEndToken();

            // Loop through the selections, appending the incoming <name> element's 
            // value to the new <name> element's value. (Of course, this could have
            // been done with a StringBuffer, but that wouldn't show the cursor in
            // use.)
            while (pathCursor.toNextSelection())
            {
                namesCursor.insertChars(pathCursor.getTextValue());
                if (pathCursor.hasNextSelection())
                {
                    namesCursor.insertChars(", ");
                }
            }
            // Dispose of the cursors now that they're not needed.
            pathCursor.dispose();
            namesCursor.dispose();

            // Print the new element.
            System.out.println("\nNames collected by collectNames method: \n\n"
                    + namesElement + "\n");
        }
        return hasResults;
    }
}
