1 /******************************************************************************* 2 * Copyright 2013 André Rouél and Dominik Seichter 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 package net.sf.qualitycheck.exception; 17 18 import javax.annotation.Nullable; 19 20 /** 21 * Thrown to indicate that a method has been passed with a reference of an unexpected type. 22 * 23 * @author André Rouél 24 * @author Dominik Seichter 25 */ 26 public class IllegalInstanceOfArgumentException extends RuntimeException { 27 28 private static final long serialVersionUID = -1886931952915327794L; 29 30 /** 31 * Default message to indicate that a given argument must is a member of an unexpected type 32 */ 33 protected static final String DEFAULT_MESSAGE = "The passed argument is a member of an unexpected type."; 34 35 /** 36 * Message to indicate that a given argument with must is a member of an unexpected type (with current and expected 37 * type information) 38 */ 39 protected static final String MESSAGE_WITH_TYPES = "The passed argument is a member of an unexpected type (expected type: %s, actual: %s)."; 40 41 /** 42 * Message to indicate that a given argument with <em>name</em> must is a member of an unexpected type (with current 43 * and expected type information) 44 */ 45 protected static final String MESSAGE_WITH_NAME_AND_TYPES = "The passed argument '%s' is a member of an unexpected type (expected type: %s, actual: %s)."; 46 47 /** 48 * Placeholder for not set types to format a message human readable 49 */ 50 protected static final String NO_TYPE_PLACEHOLDER = "(not set)"; 51 52 /** 53 * Determines the message to be used, depending on the passed argument name. If if the given argument name is 54 * {@code null} or empty {@code DEFAULT_MESSAGE} will be returned, otherwise a formatted {@code MESSAGE_WITH_NAME} 55 * with the passed name. 56 * 57 * @param argumentName 58 * the name of the passed argument 59 * @param expectedType 60 * the expected class of the given argument 61 * @param actualType 62 * the actual class of the given argument 63 * @return {@code MESSAGE_WITH_TYPES} if the given argument name is {@code null} or empty, otherwise a formatted 64 * {@code MESSAGE_WITH_NAME} 65 */ 66 private static String determineMessage(@Nullable final String argumentName, @Nullable final Class<?> expectedType, 67 @Nullable final Class<?> actualType) { 68 return argumentName != null && !argumentName.isEmpty() ? format(argumentName, expectedType, actualType) : format(expectedType, 69 actualType); 70 } 71 72 /** 73 * Returns the formatted string {@link IllegalInstanceOfArgumentException#MESSAGE_WITH_TYPES} with the given types. 74 * 75 * @param expectedType 76 * the expected class of the given argument 77 * @param actualType 78 * the actual class of the given argument 79 * @return a formatted string of message with the given argument name 80 */ 81 private static String format(@Nullable final Class<?> expectedType, @Nullable final Class<?> actualType) { 82 final String expected = expectedType != null ? expectedType.getName() : NO_TYPE_PLACEHOLDER; 83 final String actual = actualType != null ? actualType.getName() : NO_TYPE_PLACEHOLDER; 84 return String.format(MESSAGE_WITH_TYPES, expected, actual); 85 } 86 87 /** 88 * Returns the formatted string {@link IllegalInstanceOfArgumentException#MESSAGE_WITH_NAME_AND_TYPES} with the 89 * given {@code argumentName}. 90 * 91 * @param argumentName 92 * the name of the passed argument 93 * @param expectedType 94 * the expected class of the given argument 95 * @param actualType 96 * the actual class of the given argument 97 * @return a formatted string of message with the given argument name 98 */ 99 private static String format(@Nullable final String argumentName, @Nullable final Class<?> expectedType, 100 @Nullable final Class<?> actualType) { 101 final String expected = expectedType != null ? expectedType.getName() : NO_TYPE_PLACEHOLDER; 102 final String actual = actualType != null ? actualType.getName() : NO_TYPE_PLACEHOLDER; 103 return String.format(MESSAGE_WITH_NAME_AND_TYPES, argumentName, expected, actual); 104 } 105 106 /** 107 * Constructs an {@code IllegalInstanceOfArgumentException} with the default message 108 * {@link IllegalInstanceOfArgumentException#DEFAULT_MESSAGE}. 109 */ 110 public IllegalInstanceOfArgumentException() { 111 super(DEFAULT_MESSAGE); 112 } 113 114 /** 115 * Constructs an {@code IllegalInstanceOfArgumentException} with the message 116 * {@link IllegalInstanceOfArgumentException#MESSAGE_WITH_NAME_AND_TYPES} including the given name of the argument 117 * as string representation. 118 * 119 * @param argumentName 120 * the name of the passed argument 121 * @param expectedType 122 * the expected class of the given argument 123 * @param actualType 124 * the actual class of the given argument 125 */ 126 public IllegalInstanceOfArgumentException(@Nullable final String argumentName, @Nullable final Class<?> expectedType, 127 @Nullable final Class<?> actualType) { 128 super(determineMessage(argumentName, expectedType, actualType)); 129 } 130 131 /** 132 * Constructs a new exception with the default message {@link IllegalInstanceOfArgumentException#DEFAULT_MESSAGE}. 133 * 134 * @param cause 135 * the cause (which is saved for later retrieval by the {@link Throwable#getCause()} method). (A 136 * {@code null} value is permitted, and indicates that the cause is nonexistent or unknown.) 137 */ 138 public IllegalInstanceOfArgumentException(@Nullable final Throwable cause) { 139 super(DEFAULT_MESSAGE, cause); 140 } 141 142 }