1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 */ 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one or more 6 * contributor license agreements. See the NOTICE file distributed with 7 * this work for additional information regarding copyright ownership. 8 * The ASF licenses this file to You under the Apache License, Version 2.0 9 * (the "License"); you may not use this file except in compliance with 10 * the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 package org.apache.qetest.xsl; 21 22 import org.apache.qetest.CheckingHandler; 23 import static org.apache.qetest.CheckingHandler.Expectation.ITEM_CHECKPASS; 24 import static org.apache.qetest.CheckingHandler.Expectation.ITEM_DONT_CARE; 25 import static org.testng.Assert.fail; 26 import org.xml.sax.ErrorHandler; 27 import org.xml.sax.SAXException; 28 import org.xml.sax.SAXParseException; 29 30 /** 31 * Cheap-o ErrorHandler for use by API tests. 32 */ 33 public class CheckingSAXErrorHandler implements CheckingHandler, ErrorHandler { 34 35 /** 36 * Constants determining when we should throw exceptions. 37 * <ul>Flags are combineable like a bitfield. 38 * <li>THROW_NEVER - never ever (always continue - note this may have 39 * unexpected effects when fatalErrors happen, see 40 * {@link javax.xml.transform.ErrorListener#fatalError(javax.xml.transform.TransformerException)}</li> 41 * <li>THROW_ON_WARNING - throw only on warnings</li> 42 * <li>THROW_ON_ERROR - throw only on errors</li> 43 * <li>THROW_ON_FATAL - throw only on fatalErrors - default</li> 44 * <li>THROW_ALWAYS - always throw exceptions</li> 45 * </ul> 46 */ 47 public static final int THROW_NEVER = 0; 48 49 /** 50 * THROW_ON_WARNING - throw only on warnings. 51 */ 52 public static final int THROW_ON_WARNING = 1; 53 54 /** 55 * THROW_ON_ERROR - throw only on errors. 56 */ 57 public static final int THROW_ON_ERROR = 2; 58 59 /** 60 * THROW_ON_FATAL - throw only on fatalErrors - default. 61 */ 62 public static final int THROW_ON_FATAL = 4; 63 64 /** 65 * THROW_ALWAYS - always throw exceptions. 66 */ 67 public static final int THROW_ALWAYS = THROW_ON_WARNING | THROW_ON_ERROR 68 | THROW_ON_FATAL; 69 70 /** 71 * If we should throw an exception for each message type. 72 */ 73 private final int throwWhen; 74 75 /** 76 * Constructor set when we should re-throw exceptions. 77 * 78 * @param t THROW_WHEN_* constant as to when we should re-throw an exception 79 * when we are called 80 */ 81 public CheckingSAXErrorHandler(int t) { 82 throwWhen = t; 83 } 84 85 /** 86 * Default constructor will behave as default. Throw only when there is 87 * non-recoverable error. 88 */ 89 public CheckingSAXErrorHandler() { 90 this.throwWhen = THROW_ON_FATAL; 91 } 92 93 /** 94 * Tells us when we should re-throw exceptions. 95 * 96 * @return THROW_WHEN_* constant as to when we should re-throw an exception 97 * when we are called 98 */ 99 public int getThrowWhen() { 100 return throwWhen; 101 } 102 103 /** 104 * Constant for items returned in getCounters: messages. 105 */ 106 public static final int TYPE_WARNING = 0; 107 108 /** 109 * Constant for items returned in getCounters: errors. 110 */ 111 public static final int TYPE_ERROR = 1; 112 113 /** 114 * Constant for items returned in getCounters: fatalErrors. 115 */ 116 public static final int TYPE_FATALERROR = 2; 117 118 /** 119 * Expected values for events we may handle, default=ITEM_DONT_CARE. 120 */ 121 private final Expectation[] expected = { 122 ITEM_DONT_CARE, /* warning */ 123 ITEM_DONT_CARE, /* error */ 124 ITEM_DONT_CARE /* fatalError */}; 125 126 /** 127 * Ask us to report checkPass/Fail for certain events we handle. Since we 128 * may have to handle many events between when a test will be able to call 129 * us, testers can set this to have us automatically call checkPass when we 130 * see an item that matches, or to call checkFail when we get an unexpected 131 * item. Generally, we only call check* methods when: 132 * <ul> 133 * <li>containsString is not set, reset, or is ITEM_DONT_CARE, we do nothing 134 * (i.e. never call check* for this item)</li> 135 * <li>containsString is ITEM_CHECKFAIL, we will always call checkFail with 136 * the contents of any item if it occurs</li> 137 * <li>containsString is anything else, we will grab a String representation 138 * of every item of that type that comes along, and if the containsString is 139 * found, case-sensitive, within the handled item's string, call checkPass, 140 * otherwise call checkFail</li> 141 * </ul> 142 * Note that any time we handle a particular event that was expected, we 143 * un-set the expected value for that item. This means that you can only ask 144 * us to validate one occurrence of any particular event; all events after 145 * that one will be treated as ITEM_DONT_CARE. Callers can of course call 146 * setExpected again, of course, but this covers the case where we handle 147 * multiple events in a single block, perhaps out of the caller's direct 148 * control. Note that we first store the event via setLast(), then we 149 * validate the event as above, and then we potentially re-throw the 150 * exception as by setThrowWhen(). 151 * 152 * @param itemType which of the various types of items we might handle; 153 * should be defined as a constant by subclasses 154 * @param expectation expectation if we need check or not. 155 */ 156 @Override 157 public void setExpected(int itemType, Expectation expectation) { 158 expected[itemType] = expectation; 159 } 160 161 /** 162 * Reset all items or counters we've handled. 163 */ 164 @Override 165 public void reset() { 166 for (int j = 0; j < expected.length; j++) { 167 expected[j] = ITEM_DONT_CARE; 168 } 169 } 170 171 /** 172 * Receive notification of a warning. fail the test if it expects pass. 173 * Re-throw the exception when re-throw flag is set. 174 * @param exception The error information encapsulated in a 175 * SAX parse exception. 176 * @exception org.xml.sax.SAXException Any SAX exception, possibly 177 * wrapping another exception. 178 */ 179 @Override 180 public void warning(SAXParseException exception) throws SAXException { 181 // Log or validate the exception 182 if (expected[TYPE_WARNING] == ITEM_CHECKPASS) { 183 fail("Unexpected error: ex " + exception); 184 } 185 186 // Also re-throw the exception if asked to 187 if ((throwWhen & THROW_ON_WARNING) == THROW_ON_WARNING) { 188 // Note: re-throw the SAME exception, not a new one! 189 throw exception; 190 } 191 } 192 193 /** 194 * Receive notification of a recoverable error. fail the test if it expects 195 * pass. Re-throw the exception when re-throw flag is set. 196 * @param exception The error information encapsulated in a 197 * SAX parse exception. 198 * @exception org.xml.sax.SAXException Any SAX exception, possibly 199 * wrapping another exception. 200 */ 201 @Override 202 public void error(SAXParseException exception) throws SAXException { 203 // validate the exception 204 if (expected[TYPE_FATALERROR] == ITEM_CHECKPASS) { 205 fail("Unexpected fatal error: ex " + exception); 206 } 207 208 // Also re-throw the exception if asked to 209 if ((throwWhen & THROW_ON_ERROR) == THROW_ON_ERROR) { 210 // Note: re-throw the SAME exception, not a new one! 211 throw exception; 212 } 213 } 214 215 /** 216 * Receive notification of a non-recoverable error. fail the test if it 217 * expects pass. Re-throw the exception when re-throw flag is set. 218 * @param exception The error information encapsulated in a 219 * SAX parse exception. 220 * @exception org.xml.sax.SAXException Any SAX exception, possibly 221 * wrapping another exception. 222 */ 223 @Override 224 public void fatalError(SAXParseException exception) throws SAXException { 225 // validate the exception 226 if (expected[TYPE_ERROR] == ITEM_CHECKPASS) { 227 fail("Unexpected fatal error: ex " + exception); 228 } 229 230 // Also re-throw the exception if asked to 231 if ((throwWhen & THROW_ON_FATAL) == THROW_ON_FATAL) { 232 // Note: re-throw the SAME exception, not a new one! 233 throw exception; 234 } 235 } 236 }