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 }