--- /dev/null 2014-09-08 10:45:56.830930409 -0700 +++ new/test/javax/xml/jaxp/libs/org/apache/qetest/trax/CheckingErrorListener.java 2014-12-31 11:41:17.348144763 -0800 @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.qetest.trax; + +import javax.xml.transform.ErrorListener; +import javax.xml.transform.TransformerException; +import org.apache.qetest.CheckingHandler; +import static org.apache.qetest.CheckingHandler.Expectation.ITEM_CHECKPASS; +import static org.apache.qetest.CheckingHandler.Expectation.ITEM_DONT_CARE; +import static org.testng.Assert.fail; + +/** + * Cheap-o ErrorListener for use by API tests. + *

+ * Implements javax.xml.transform.ErrorListener and dumps everything to a + * Logger; is separately settable as to when it will throw an exception; also + * separately settable as to when we should validate specific events that we + * handle.

+ */ +public class CheckingErrorListener implements CheckingHandler, ErrorListener { + + /** + * Constants determining when we should throw exceptions. + * + */ + public static final int THROW_NEVER = 0; + + /** + * THROW_ON_WARNING - throw only on warnings. + */ + public static final int THROW_ON_WARNING = 1; + + /** + * THROW_ON_ERROR - throw only on errors. + */ + public static final int THROW_ON_ERROR = 2; + + /** + * THROW_ON_FATAL - throw only on fatalErrors - default. + */ + public static final int THROW_ON_FATAL = 4; + + /** + * THROW_ALWAYS - always throw exceptions. + */ + public static final int THROW_ALWAYS = THROW_ON_WARNING | THROW_ON_ERROR + | THROW_ON_FATAL; + + /** + * If we should throw an exception for each message type. + */ + protected final int throwWhen; + + /** + * Constructor set when we should re-throw exceptions. + * + * @param t THROW_WHEN_* constant as to when we should re-throw an exception + * when we are called. + */ + public CheckingErrorListener(int t) { + throwWhen = t; + } + + /** + * Default constructor will behave as default. Throw only when there is + * non-recoverable error. + */ + public CheckingErrorListener() { + this(THROW_ON_FATAL); + } + + /** + * Tells us when we should re-throw exceptions. + * + * @return THROW_WHEN_* constant as to when we should re-throw an exception + * when we are called + */ + public int getThrowWhen() { + return throwWhen; + } + + /** + * Constant for items returned in getCounters: messages. + */ + public static final int TYPE_WARNING = 0; + + /** + * Constant for items returned in getCounters: errors. + */ + public static final int TYPE_ERROR = 1; + + /** + * Constant for items returned in getCounters: fatalErrors. + */ + public static final int TYPE_FATALERROR = 2; + + /** + * Expected values for events we may handle, default=ITEM_DONT_CARE. + */ + private final Expectation[] expected = { + ITEM_DONT_CARE, /* warning */ + ITEM_DONT_CARE, /* error */ + ITEM_DONT_CARE /* fatalError */}; + + /** + * Ask us to report checkPass/Fail for certain events we handle. Since we + * may have to handle many events between when a test will be able to call + * us, testers can set this to have us automatically call checkPass when we + * see an item that matches, or to call checkFail when we get an unexpected + * item. Generally, we only call check* methods when: + * + * Note that any time we handle a particular event that was expected, we + * un-set the expected value for that item. This means that you can only ask + * us to validate one occurrence of any particular event; all events after + * that one will be treated as ITEM_DONT_CARE. Callers can of course call + * setExpected again, of course, but this covers the case where we handle + * multiple events in a single block, perhaps out of the caller's direct + * control. Note that we first store the event via setLast(), then we + * validate the event as above, and then we potentially re-throw the + * exception as by setThrowWhen(). + * + * @param itemType which of the various types of items we might handle; + * should be defined as a constant by subclasses + * @param expectation expectation if we need check or not. + */ + @Override + public void setExpected(int itemType, Expectation expectation) { + expected[itemType] = expectation; + } + + /** + * Reset all items or counters we've handled. + */ + @Override + public void reset() { + for (int j = 0; j < expected.length; j++) { + expected[j] = ITEM_DONT_CARE; + } + } + + /** + * Grab basic info out of a TransformerException. Worker method to hide + * implementation; currently just calls exception.getMessageAndLocation(). + * + * @param exception to get information from + * @return simple string describing the exception (getMessageAndLocation()) + */ + public String getTransformerExceptionInfo(TransformerException exception) { + if (exception == null) { + return ""; // Don't return null, just to make other code here simpler + } + return exception.getMessageAndLocation(); + } + + /** + * Implementation of warning; calls logMsg with info contained in exception. + * + * @param exception provided by Transformer + * @exception TransformerException thrown only if asked to or if loggers are + * bad + */ + @Override + public void warning(TransformerException exception) throws TransformerException { + // Log or validate the exception + if(expected[TYPE_WARNING] == ITEM_CHECKPASS) + fail("Unexpected error: ex " + exception); + + // Also re-throw the exception if asked to + if ((throwWhen & THROW_ON_WARNING) == THROW_ON_WARNING) { + // Note: re-throw the SAME exception, not a new one! + throw exception; + } + } + + /** + * Implementation of error; calls logMsg with info contained in exception. + * Only ever throws an exception itself if asked to or if loggers are bad. + * + * @param exception provided by Transformer + * @exception TransformerException thrown only if asked to. + */ + @Override + public void error(TransformerException exception) throws TransformerException { + // validate the exception + if(expected[TYPE_ERROR] == ITEM_CHECKPASS) + fail("Unexpected error: ex " + exception); + + // Also re-throw the exception if asked to + if ((throwWhen & THROW_ON_ERROR) == THROW_ON_ERROR) { + // Note: re-throw the SAME exception, not a new one! + throw exception; + } + } + + /** + * Implementation of error; calls logMsg with info contained in exception. + * Only ever throws an exception itself if asked to or if loggers are bad. + * Note that this may cause unusual behavior since we may not actually + * re-throw the exception, even though it was 'fatal'. + * + * @param exception provided by Transformer + * @exception TransformerException thrown only if asked to. + */ + @Override + public void fatalError(TransformerException exception) throws TransformerException { + // validate the exception + if(expected[TYPE_FATALERROR] == ITEM_CHECKPASS) + fail("Unexpected fatal error: ex " + exception); + + // Also re-throw the exception if asked to + if ((throwWhen & THROW_ON_FATAL) == THROW_ON_FATAL) { + // Note: re-throw the SAME exception, not a new one! + throw exception; + } + } +}