/*   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.validation;

import org.apache.xmlbeans.*;
import org.apache.xmlbeans.samples.validation.todolist.*;
import org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * A sample to illustrate two means for validating XML against schema
 * using features of the XMLBeans API. The features illustrated are:
 * 
 * - Validating after changes by using the XmlObject.validate method.
 * This method is exposed by types generated by compiling schema. The 
 * validate method validates instances against all aspects of schema.
 * Also, with this method you can specify a Collection instance to 
 * capture errors that occur during validation.
 * 
 * - Validating "on the fly" using the XmlOptions.VALIDATE_ON_SET constant.
 * This option prompts XMLBeans to validate XML against simple schema types
 * <em>as you set them</em>, rather than by expressly calling for validation.
 * You can set this option by calling XmlOptions.setValidateOnSet, then
 * specifying the XmlOptions instance as a parameter when creating
 * a new instance from schema or parsing an existing one.
 * 
 * Note that it is also possible to validate instances from the
 * command line by using tools you'll find in the bin directory of the 
 * XMLBeans distribution.
 */
public class Validation
{
    private static XmlOptions m_validationOptions;

    /**
     * Receives a todo list XML instance, twice rendering it invalid
     * and validating it using the XMLBeans API.
     * 
     * @param args An array in which the first item is a
     * path to the XML instance file.
     */
    public static void main(String[] args)
    {
        Validation thisSample = new Validation();
        
        // Use the validate method to validate an instance after
        // updates.
        boolean isValidAfterChanges = thisSample.isValidAfterChanges(args[0]);
        
        // Use the VALIDATE_ON_SET option to validate an instance
        // as updates are made.
        boolean isValidOnTheFly = thisSample.isValidOnTheFly(args[0]);
    }

    /**
     * Illustrates use of the validate method by making changes to incoming
     * XML that invalidate the XML, then validating the instance and 
     * printing resulting error messages.
     * 
     * Because this code is designed to generate invalid XML, it
     * returns false when successful.
     * 
     * @param xmlPath A path to the XML instance file.
     * @return <code>true if the XML is valid after changes; 
     * otherwise, <code>false</code>.
     */
    public boolean isValidAfterChanges(String xmlPath)
    {
        System.out.println("Validating after changes: \n");
        // Set up the validation error listener.
        ArrayList validationErrors = new ArrayList();
        m_validationOptions = new XmlOptions();
        m_validationOptions.setErrorListener(validationErrors);

        TodolistDocument todoList = (TodolistDocument)parseXml(xmlPath, null);

        // Schema defines the <name> element as required (minOccurs = '1').
        // So this statement renders the XML invalid because it sets the
        // <name> element to nil.
        todoList.getTodolist().getItemArray(0).setName(null);

        // During validation, errors are added to the ArrayList for
        // retrieval and printing by the printErrors method.
        boolean isValid = todoList.validate(m_validationOptions);

        if (!isValid)
        {
            printErrors(validationErrors);
        }
        return isValid;
    }

    /**
     * Illustrates the "validate on set" feature, which validates XML
     * for simple types on the fly. As XML for those types is "set" through
     * accessors generated by compiling schema, XMLBeans checks the XML's 
     * validity. The code here uses generated types to retrieve the first
     * <item> in a <todolist>, then update the <item>'s id attribute. The code 
     * throws an exception when it tries to set an id attribute value that
     * is too high.
     * 
     * Because this code is designed to generate invalid XML, it
     * returns false when successful.
     * 
     * @param xmlPath A path to the XML instance file.
     * @return <code>true</code> if valid XML is successfully created; 
     * otherwise, <code>false</code>.
     */
    public boolean isValidOnTheFly(String xmlPath)
    {
        System.out.println("Validating on-the-fly: \n");
        m_validationOptions = new XmlOptions();
        m_validationOptions.setValidateOnSet();
        
        TodolistDocument todoList = (TodolistDocument)parseXml(xmlPath, m_validationOptions);
        Todolist list = todoList.getTodolist();
        ItemType firstItem = list.getItemArray(0);

        // Schema defines the <id> element as allowing values up to 100. So
        // this line throws an exception because it invalidates the XML the
        // code is updating.
        firstItem.setId(8587);
        
        // This line will not be reached.
        return todoList.validate();
    }

    /**
     * Receives the collection containing errors found during
     * validation and print the errors to the console.
     * 
     * @param validationErrors The validation errors.
     */
    public void printErrors(ArrayList validationErrors)
    {
        System.out.println("Errors discovered during validation: \n");
        Iterator iter = validationErrors.iterator();
        while (iter.hasNext())
        {
            System.out.println(">> " + iter.next() + "\n");
        }
    }

    /**
     * <p>Creates a File from the XML path provided in main arguments, then
     * parses the file's contents into a type generated from schema.</p>
     * <p/>
     * <p>Note that this work might have been done in main. Isolating it here
     * makes the code separately available from outside this class.</p>
     *
     * @param xmlFilePath A path to XML based on the schema in inventory.xsd.
     * @return An instance of a generated schema type that contains the parsed
     *         XML.
     */
    public XmlObject parseXml(String xmlFilePath, XmlOptions validationOptions)
    {
        File xmlFile = new File(xmlFilePath);
        XmlObject xml = null;
        try
        {
            xml = XmlObject.Factory.parse(xmlFile, validationOptions);
        } catch (XmlException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
        return xml;
    }
}
