001 /*
002 * $Id: ExceptionThrower.java,v 1.5 2011/07/09 21:43:22 oboehm Exp $
003 *
004 * Copyright (c) 2010 by Oliver Boehm
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 *
018 * (c)reated 30.01.2010 by oliver (ob@oasd.de)
019 */
020
021 package patterntesting.runtime.util;
022
023 import java.lang.reflect.Constructor;
024
025 import org.junit.Test;
026 import org.slf4j.*;
027
028 /**
029 * Because we need the functionality of throwing any exception not only in
030 * PatternTesting Exception but also here this functionality was shifted to
031 * PatternTesting Runtime.
032 * <br/>
033 * This class is not intended for public use. If you do so use it on your own
034 * risk!
035 *
036 * @author oliver
037 * @since 1.0 (30.01.2010)
038 */
039 public final class ExceptionThrower {
040
041 private static Logger log = LoggerFactory.getLogger(ExceptionThrower.class);
042
043 /** only a utility class - no need to instantiate it. */
044 private ExceptionThrower() {}
045
046 /**
047 * Be careful - you can provoke any Exception with the method without the
048 * need to declare it with a throws statement. For example
049 * <pre>provoke(IOException.class)</pre>
050 * would throw an IOException.
051 * <br/>
052 * WARNING: If the desired exception can't be instantiated an
053 * InstantiationException or IllegalAccessException may be thrown.
054 * <br/>
055 * WARNING(2): This method is not synchronized.
056 *
057 * @param type e.g. IOException.class
058 */
059 public static void provoke(final Class<? extends Throwable> type) {
060 Throwable t;
061 try {
062 t = create(type);
063 } catch (Exception ex) {
064 log.debug("can't create " + type, ex);
065 t = ex;
066 }
067 Thrower.provoke(t);
068 }
069
070 /**
071 * This method throws the expected exception wrapped into the
072 * {@link Test} annotation.
073 *
074 * @param test with the expected exception
075 */
076 public static void provoke(final Test test) {
077 Class<? extends Throwable> expected = test.expected();
078 if ((expected != Test.None.class) && (expected != null)) {
079 ExceptionThrower.provoke(expected);
080 }
081 }
082
083 /**
084 * Creates any desired exception you want.
085 * If the desired exception can't be instantiated an
086 * InstantiationException or IllegalAccessException may be thrown.
087 *
088 * @param type the exception class you want to be created
089 *
090 * @return the instantiated exception or the caught exception
091 *
092 * @throws IllegalAccessException the illegal access exception
093 * @throws InstantiationException the instantiation exception
094 */
095 public static Throwable create(final Class<? extends Throwable> type)
096 throws InstantiationException, IllegalAccessException {
097 try {
098 Constructor<? extends Throwable> ctor = type
099 .getConstructor(String.class);
100 return ctor.newInstance("created by ExceptionThrower");
101 } catch (Exception e) {
102 if (log.isTraceEnabled()) {
103 log.trace("can't call 'new " + type + "(String)'", e);
104 }
105 return type.newInstance();
106 }
107 }
108
109 /**
110 * The trick here is to use the constructor to throw any desired exception.
111 * So you can throw any exception without the need to have it as throws
112 * clause.
113 *
114 * @author <a href="boehm@javatux.de">oliver</a>
115 */
116 static final class Thrower {
117 private static Throwable throwable;
118
119 private Thrower() throws Throwable {
120 throw throwable;
121 }
122
123 /**
124 * Provoke an exception.
125 *
126 * @param t the Throwable which should be used as provoked exception.
127 */
128 public static void provoke(final Throwable t) {
129 throwable = t;
130 try {
131 Thrower.class.newInstance();
132 } catch (InstantiationException unexpected) {
133 log.debug("can't instantiate Thrower class", unexpected);
134 } catch (IllegalAccessException unexpected) {
135 log.debug("can't access Thrower constructor", unexpected);
136 }
137 }
138 }
139
140 }
141