View Javadoc

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 }