001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     * 
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.lang;
018    
019    /**
020     * <p>Thrown when an object is an instance of an unexpected type (a class or interface).
021     * This exception supplements the standard <code>IllegalArgumentException</code>
022     * by providing a more semantically rich description of the problem.</p>
023     * 
024     * <p><code>IllegalClassException</code> represents the case where a method takes
025     * in a genericly typed parameter like Object (typically because it has to due to some
026     * other interface it implements), but this implementation only actually accepts a specific
027     * type, for example String. This exception would be used in place of
028     * <code>IllegalArgumentException</code>, yet it still extends it.</p>
029     * 
030     * <pre>
031     * public void foo(Object obj) {
032     *   if (obj instanceof String == false) {
033     *     throw new IllegalClassException(String.class, obj);
034     *   }
035     *   // do something with the string
036     * }
037     * </pre>
038     * 
039     * @author Apache Software Foundation
040     * @author Matthew Hawthorne
041     * @author Gary Gregory
042     * @since 2.0
043     * @version $Id: IllegalClassException.java 905636 2010-02-02 14:03:32Z niallp $
044     */
045    public class IllegalClassException extends IllegalArgumentException {
046    
047        /**
048         * Required for serialization support.
049         * 
050         * @see java.io.Serializable
051         */
052        private static final long serialVersionUID = 8063272569377254819L;
053    
054        /**
055         * <p>Instantiates with the expected type, and actual object.</p>
056         * 
057         * @param expected  the expected type
058         * @param actual  the actual object
059         * @since 2.1
060         */
061        public IllegalClassException(Class expected, Object actual) {
062            super(
063                "Expected: "
064                    + safeGetClassName(expected)
065                    + ", actual: "
066                    + (actual == null ? "null" : actual.getClass().getName()));
067        }
068    
069        /**
070         * <p>Instantiates with the expected and actual types.</p>
071         * 
072         * @param expected  the expected type
073         * @param actual  the actual type
074         */
075        public IllegalClassException(Class expected, Class actual) {
076            super(
077                "Expected: "
078                    + safeGetClassName(expected)
079                    + ", actual: "
080                    + safeGetClassName(actual));
081        }
082    
083        /**
084         * <p>Instantiates with the specified message.</p>
085         * 
086         * @param message  the exception message
087         */
088        public IllegalClassException(String message) {
089            super(message);
090        }
091    
092        /**
093         * <p>Returns the class name or <code>null</code> if the class is
094         * <code>null</code>.</p>
095         * 
096         * @param cls  a <code>Class</code>
097         * @return the name of <code>cls</code>, or <code>null</code> if if <code>cls</code> is <code>null</code>.
098         */
099        private static final String safeGetClassName(Class cls) {
100            return cls == null ? null : cls.getName();
101        }
102    
103    }