1 /* Copyright 2004 The Apache Software Foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 package org.apache.xmlbeans.samples.validation;
17
18 import org.apache.xmlbeans;
19 import org.apache.xmlbeans.samples.validation.todolist;
20 import org.apache.xmlbeans.samples.validation.todolist.TodolistDocument.Todolist;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26
27 /**
28 * A sample to illustrate two means for validating XML against schema
29 * using features of the XMLBeans API. The features illustrated are:
30 *
31 * - Validating after changes by using the XmlObject.validate method.
32 * This method is exposed by types generated by compiling schema. The
33 * validate method validates instances against all aspects of schema.
34 * Also, with this method you can specify a Collection instance to
35 * capture errors that occur during validation.
36 *
37 * - Validating "on the fly" using the XmlOptions.VALIDATE_ON_SET constant.
38 * This option prompts XMLBeans to validate XML against simple schema types
39 * <em>as you set them</em>, rather than by expressly calling for validation.
40 * You can set this option by calling XmlOptions.setValidateOnSet, then
41 * specifying the XmlOptions instance as a parameter when creating
42 * a new instance from schema or parsing an existing one.
43 *
44 * Note that it is also possible to validate instances from the
45 * command line by using tools you'll find in the bin directory of the
46 * XMLBeans distribution.
47 */
48 public class Validation
49 {
50 private static XmlOptions m_validationOptions;
51
52 /**
53 * Receives a todo list XML instance, twice rendering it invalid
54 * and validating it using the XMLBeans API.
55 *
56 * @param args An array in which the first item is a
57 * path to the XML instance file.
58 */
59 public static void main(String[] args)
60 {
61 Validation thisSample = new Validation();
62
63 // Use the validate method to validate an instance after
64 // updates.
65 boolean isValidAfterChanges = thisSample.isValidAfterChanges(args[0]);
66
67 // Use the VALIDATE_ON_SET option to validate an instance
68 // as updates are made.
69 boolean isValidOnTheFly = thisSample.isValidOnTheFly(args[0]);
70 }
71
72 /**
73 * Illustrates use of the validate method by making changes to incoming
74 * XML that invalidate the XML, then validating the instance and
75 * printing resulting error messages.
76 *
77 * Because this code is designed to generate invalid XML, it
78 * returns false when successful.
79 *
80 * @param xmlPath A path to the XML instance file.
81 * @return <code>true if the XML is valid after changes;
82 * otherwise, <code>false</code>.
83 */
84 public boolean isValidAfterChanges(String xmlPath)
85 {
86 System.out.println("Validating after changes: \n");
87 // Set up the validation error listener.
88 ArrayList validationErrors = new ArrayList();
89 m_validationOptions = new XmlOptions();
90 m_validationOptions.setErrorListener(validationErrors);
91
92 TodolistDocument todoList = (TodolistDocument)parseXml(xmlPath, null);
93
94 // Schema defines the <name> element as required (minOccurs = '1').
95 // So this statement renders the XML invalid because it sets the
96 // <name> element to nil.
97 todoList.getTodolist().getItemArray(0).setName(null);
98
99 // During validation, errors are added to the ArrayList for
100 // retrieval and printing by the printErrors method.
101 boolean isValid = todoList.validate(m_validationOptions);
102
103 if (!isValid)
104 {
105 printErrors(validationErrors);
106 }
107 return isValid;
108 }
109
110 /**
111 * Illustrates the "validate on set" feature, which validates XML
112 * for simple types on the fly. As XML for those types is "set" through
113 * accessors generated by compiling schema, XMLBeans checks the XML's
114 * validity. The code here uses generated types to retrieve the first
115 * <item> in a <todolist>, then update the <item>'s id attribute. The code
116 * throws an exception when it tries to set an id attribute value that
117 * is too high.
118 *
119 * Because this code is designed to generate invalid XML, it
120 * returns false when successful.
121 *
122 * @param xmlPath A path to the XML instance file.
123 * @return <code>true</code> if valid XML is successfully created;
124 * otherwise, <code>false</code>.
125 */
126 public boolean isValidOnTheFly(String xmlPath)
127 {
128 System.out.println("Validating on-the-fly: \n");
129 m_validationOptions = new XmlOptions();
130 m_validationOptions.setValidateOnSet();
131
132 TodolistDocument todoList = (TodolistDocument)parseXml(xmlPath, m_validationOptions);
133 Todolist list = todoList.getTodolist();
134 ItemType firstItem = list.getItemArray(0);
135
136 // Schema defines the <id> element as allowing values up to 100. So
137 // this line throws an exception because it invalidates the XML the
138 // code is updating.
139 firstItem.setId(8587);
140
141 // This line will not be reached.
142 return todoList.validate();
143 }
144
145 /**
146 * Receives the collection containing errors found during
147 * validation and print the errors to the console.
148 *
149 * @param validationErrors The validation errors.
150 */
151 public void printErrors(ArrayList validationErrors)
152 {
153 System.out.println("Errors discovered during validation: \n");
154 Iterator iter = validationErrors.iterator();
155 while (iter.hasNext())
156 {
157 System.out.println(">> " + iter.next() + "\n");
158 }
159 }
160
161 /**
162 * <p>Creates a File from the XML path provided in main arguments, then
163 * parses the file's contents into a type generated from schema.</p>
164 * <p/>
165 * <p>Note that this work might have been done in main. Isolating it here
166 * makes the code separately available from outside this class.</p>
167 *
168 * @param xmlFilePath A path to XML based on the schema in inventory.xsd.
169 * @return An instance of a generated schema type that contains the parsed
170 * XML.
171 */
172 public XmlObject parseXml(String xmlFilePath, XmlOptions validationOptions)
173 {
174 File xmlFile = new File(xmlFilePath);
175 XmlObject xml = null;
176 try
177 {
178 xml = XmlObject.Factory.parse(xmlFile, validationOptions);
179 } catch (XmlException e)
180 {
181 e.printStackTrace();
182 } catch (IOException e)
183 {
184 e.printStackTrace();
185 }
186 return xml;
187 }
188 }