001: /* Copyright 2004 The Apache Software Foundation
002: *
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: *
007: * http://www.apache.org/licenses/LICENSE-2.0
008: *
009: * Unless required by applicable law or agreed to in writing, software
010: * distributed under the License is distributed on an "AS IS" BASIS,
011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: * See the License for the specific language governing permissions and
013: * limitations under the License.
014: */
015:
016: package org.apache.xmlbeans.samples.validation;
017:
018: import org.apache.xmlbeans.*;
019: import org.apache.xmlbeans.samples.validation.todolist.*;
020: import org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist;
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.util.ArrayList;
025: import java.util.Iterator;
026:
027: /**
028: * A sample to illustrate two means for validating XML against schema
029: * using features of the XMLBeans API. The features illustrated are:
030: *
031: * - Validating after changes by using the XmlObject.validate method.
032: * This method is exposed by types generated by compiling schema. The
033: * validate method validates instances against all aspects of schema.
034: * Also, with this method you can specify a Collection instance to
035: * capture errors that occur during validation.
036: *
037: * - Validating "on the fly" using the XmlOptions.VALIDATE_ON_SET constant.
038: * This option prompts XMLBeans to validate XML against simple schema types
039: * <em>as you set them</em>, rather than by expressly calling for validation.
040: * You can set this option by calling XmlOptions.setValidateOnSet, then
041: * specifying the XmlOptions instance as a parameter when creating
042: * a new instance from schema or parsing an existing one.
043: *
044: * Note that it is also possible to validate instances from the
045: * command line by using tools you'll find in the bin directory of the
046: * XMLBeans distribution.
047: */
048: public class Validation {
049: private static XmlOptions m_validationOptions;
050:
051: /**
052: * Receives a todo list XML instance, twice rendering it invalid
053: * and validating it using the XMLBeans API.
054: *
055: * @param args An array in which the first item is a
056: * path to the XML instance file.
057: */
058: public static void main(String[] args) {
059: Validation this Sample = new Validation();
060:
061: // Use the validate method to validate an instance after
062: // updates.
063: boolean isValidAfterChanges = this Sample
064: .isValidAfterChanges(args[0]);
065:
066: // Use the VALIDATE_ON_SET option to validate an instance
067: // as updates are made.
068: boolean isValidOnTheFly = this Sample.isValidOnTheFly(args[0]);
069: }
070:
071: /**
072: * Illustrates use of the validate method by making changes to incoming
073: * XML that invalidate the XML, then validating the instance and
074: * printing resulting error messages.
075: *
076: * Because this code is designed to generate invalid XML, it
077: * returns false when successful.
078: *
079: * @param xmlPath A path to the XML instance file.
080: * @return <code>true if the XML is valid after changes;
081: * otherwise, <code>false</code>.
082: */
083: public boolean isValidAfterChanges(String xmlPath) {
084: System.out.println("Validating after changes: \n");
085: // Set up the validation error listener.
086: ArrayList validationErrors = new ArrayList();
087: m_validationOptions = new XmlOptions();
088: m_validationOptions.setErrorListener(validationErrors);
089:
090: TodolistDocument todoList = (TodolistDocument) parseXml(
091: xmlPath, null);
092:
093: // Schema defines the <name> element as required (minOccurs = '1').
094: // So this statement renders the XML invalid because it sets the
095: // <name> element to nil.
096: todoList.getTodolist().getItemArray(0).setName(null);
097:
098: // During validation, errors are added to the ArrayList for
099: // retrieval and printing by the printErrors method.
100: boolean isValid = todoList.validate(m_validationOptions);
101:
102: if (!isValid) {
103: printErrors(validationErrors);
104: }
105: return isValid;
106: }
107:
108: /**
109: * Illustrates the "validate on set" feature, which validates XML
110: * for simple types on the fly. As XML for those types is "set" through
111: * accessors generated by compiling schema, XMLBeans checks the XML's
112: * validity. The code here uses generated types to retrieve the first
113: * <item> in a <todolist>, then update the <item>'s id attribute. The code
114: * throws an exception when it tries to set an id attribute value that
115: * is too high.
116: *
117: * Because this code is designed to generate invalid XML, it
118: * returns false when successful.
119: *
120: * @param xmlPath A path to the XML instance file.
121: * @return <code>true</code> if valid XML is successfully created;
122: * otherwise, <code>false</code>.
123: */
124: public boolean isValidOnTheFly(String xmlPath) {
125: System.out.println("Validating on-the-fly: \n");
126: m_validationOptions = new XmlOptions();
127: m_validationOptions.setValidateOnSet();
128:
129: TodolistDocument todoList = (TodolistDocument) parseXml(
130: xmlPath, m_validationOptions);
131: Todolist list = todoList.getTodolist();
132: ItemType firstItem = list.getItemArray(0);
133:
134: // Schema defines the <id> element as allowing values up to 100. So
135: // this line throws an exception because it invalidates the XML the
136: // code is updating.
137: firstItem.setId(8587);
138:
139: // This line will not be reached.
140: return todoList.validate();
141: }
142:
143: /**
144: * Receives the collection containing errors found during
145: * validation and print the errors to the console.
146: *
147: * @param validationErrors The validation errors.
148: */
149: public void printErrors(ArrayList validationErrors) {
150: System.out.println("Errors discovered during validation: \n");
151: Iterator iter = validationErrors.iterator();
152: while (iter.hasNext()) {
153: System.out.println(">> " + iter.next() + "\n");
154: }
155: }
156:
157: /**
158: * <p>Creates a File from the XML path provided in main arguments, then
159: * parses the file's contents into a type generated from schema.</p>
160: * <p/>
161: * <p>Note that this work might have been done in main. Isolating it here
162: * makes the code separately available from outside this class.</p>
163: *
164: * @param xmlFilePath A path to XML based on the schema in inventory.xsd.
165: * @return An instance of a generated schema type that contains the parsed
166: * XML.
167: */
168: public XmlObject parseXml(String xmlFilePath,
169: XmlOptions validationOptions) {
170: File xmlFile = new File(xmlFilePath);
171: XmlObject xml = null;
172: try {
173: xml = XmlObject.Factory.parse(xmlFile, validationOptions);
174: } catch (XmlException e) {
175: e.printStackTrace();
176: } catch (IOException e) {
177: e.printStackTrace();
178: }
179: return xml;
180: }
181: }
|