    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    import java.io.PrintStream;
    020    import java.io.PrintWriter;
    021
    022    import org.apache.commons.lang.exception.Nestable;
    023    import org.apache.commons.lang.exception.NestableDelegate;
    024
    025    /**
    026     * <p>Thrown to indicate that a block of code has not been implemented.
    027     * This exception supplements <code>UnsupportedOperationException</code>
    028     * by providing a more semantically rich description of the problem.</p>
    029     *
    030     * <p><code>NotImplementedException</code> represents the case where the
    031     * author has yet to implement the logic at this point in the program.
    032     * This can act as an exception based TODO tag.
    033     * Because this logic might be within a catch block, this exception
    034     * suports exception chaining.</p>
    035     *
    036     * <pre>
    037     * public void foo() {
    038     *   try {
    039     *     // do something that throws an Exception
    040     *   } catch (Exception ex) {
    041     *     // don't know what to do here yet
    042     *     throw new NotImplementedException("TODO", ex);
    043     *   }
    044     * }
    045     * </pre>
    046     *
    047     * @author Apache Software Foundation
    048     * @author Matthew Hawthorne
    049     * @since 2.0
    050     * @version $Id: NotImplementedException.java 905636 2010-02-02 14:03:32Z niallp $
    051     */
    052    public class NotImplementedException
    053            extends UnsupportedOperationException implements Nestable {
    054
    055        private static final String DEFAULT_MESSAGE = "Code is not implemented";
    056
    057        /**
    058         * Required for serialization support.
    059         *
    060         * @see java.io.Serializable
    061         */
    062        private static final long serialVersionUID = -6894122266938754088L;
    063
    064        /**
    065         * The exception helper to delegate nested exception handling to.
    066         */
    067        private NestableDelegate delegate = new NestableDelegate(this);
    068
    069        /**
    070         * Holds the reference to the exception or error that caused
    071         * this exception to be thrown.
    072         */
    073        private Throwable cause;
    074
    075        //-----------------------------------------------------------------------
    076        /**
    077         * Constructs a new <code>NotImplementedException</code> with default message.
    078         *
    079         * @since 2.1
    080         */
    081        public NotImplementedException() {
    082            super(DEFAULT_MESSAGE);
    083        }
    084
    085        /**
    086         * Constructs a new <code>NotImplementedException</code> with specified
    087         * detail message.
    088         *
    089         * @param msg  the error message.
    090         */
    091        public NotImplementedException(String msg) {
    092            super(msg == null ? DEFAULT_MESSAGE : msg);
    093        }
    094
    095        /**
    096         * Constructs a new <code>NotImplementedException</code> with specified
    097         * nested <code>Throwable</code> and default message.
    098         *
    099         * @param cause  the exception that caused this exception to be thrown
    100         * @since 2.1
    101         */
    102        public NotImplementedException(Throwable cause) {
    103            super(DEFAULT_MESSAGE);
    104            this.cause = cause;
    105        }
    106
    107        /**
    108         * Constructs a new <code>NotImplementedException</code> with specified
    109         * detail message and nested <code>Throwable</code>.
    110         *
    111         * @param msg  the error message
    112         * @param cause  the exception that caused this exception to be thrown
    113         * @since 2.1
    114         */
    115        public NotImplementedException(String msg, Throwable cause) {
    116            super(msg == null ? DEFAULT_MESSAGE : msg);
    117            this.cause = cause;
    118        }
    119
    120        /**
    121         * Constructs a new <code>NotImplementedException</code> referencing the specified class.
    122         *
    123         * @param clazz
    124         *            the <code>Class</code> that has not implemented the method
    125         */
    126        public NotImplementedException(Class clazz) {
    127            super(clazz == null ? DEFAULT_MESSAGE : DEFAULT_MESSAGE + " in " + clazz);
    128        }
    129
    130        // -----------------------------------------------------------------------
    131        /**
    132         * Gets the root cause of this exception.
    133         * @return the root cause of this exception.
    134         *
    135         * @since 2.1
    136         */
    137        public Throwable getCause() {
    138            return cause;
    139        }
    140
    141        /**
    142         * Gets the combined the error message of this and any nested errors.
    143         *
    144         * @return the error message
    145         * @since 2.1
    146         */
    147        public String getMessage() {
    148            if (super.getMessage() != null) {
    149                return super.getMessage();
    150            } else if (cause != null) {
    151                return cause.toString();
    152            } else {
    153                return null;
    154            }
    155        }
    156
    157        /**
    158         * Returns the error message of the <code>Throwable</code> in the chain
    159         * of <code>Throwable</code>s at the specified index, numbered from 0.
    160         *
    161         * @param index  the index of the <code>Throwable</code> in the chain
    162         * @return the error message, or null if the <code>Throwable</code> at the
    163         *  specified index in the chain does not contain a message
    164         * @throws IndexOutOfBoundsException if the <code>index</code> argument is
    165         *  negative or not less than the count of <code>Throwable</code>s in the chain
    166         * @since 2.1
    167         */
    168        public String getMessage(int index) {
    169            if (index == 0) {
    170                return super.getMessage();
    171            }
    172            return delegate.getMessage(index);
    173        }
    174
    175        /**
    176         * Returns the error message of this and any nested <code>Throwable</code> objects.
    177         * Each throwable returns a message, a null string is included in the array if
    178         * there is no message for a particular <code>Throwable</code>.
    179         *
    180         * @return the error messages
    181         * @since 2.1
    182         */
    183        public String[] getMessages() {
    184            return delegate.getMessages();
    185        }
    186
    187        /**
    188         * Returns the <code>Throwable</code> in the chain by index.
    189         *
    190         * @param index  the index to retrieve
    191         * @return the <code>Throwable</code>
    192         * @throws IndexOutOfBoundsException if the <code>index</code> argument is
    193         *  negative or not less than the count of <code>Throwable</code>s in the chain
    194         * @since 2.1
    195         */
    196        public Throwable getThrowable(int index) {
    197            return delegate.getThrowable(index);
    198        }
    199
    200        /**
    201         * Returns the number of nested <code>Throwable</code>s represented by
    202         * this <code>Nestable</code>, including this <code>Nestable</code>.
    203         *
    204         * @return the throwable count
    205         * @since 2.1
    206         */
    207        public int getThrowableCount() {
    208            return delegate.getThrowableCount();
    209        }
    210
    211        /**
    212         * Returns this <code>Nestable</code> and any nested <code>Throwable</code>s
    213         * in an array of <code>Throwable</code>s, one element for each
    214         * <code>Throwable</code>.
    215         *
    216         * @return the <code>Throwable</code>s
    217         * @since 2.1
    218         */
    219        public Throwable[] getThrowables() {
    220            return delegate.getThrowables();
    221        }
    222
    223        /**
    224         * Returns the index of the first occurrence of the specified type.
    225         * If there is no match, <code>-1</code> is returned.
    226         *
    227         * @param type  the type to search for
    228         * @return index of the first occurrence of the type in the chain, or -1 if
    229         *  the type is not found
    230         * @since 2.1
    231         */
    232        public int indexOfThrowable(Class type) {
    233            return delegate.indexOfThrowable(type, 0);
    234        }
    235
    236        /**
    237         * Returns the index of the first occurrence of the specified type starting
    238         * from the specified index. If there is no match, <code>-1</code> is returned.
    239         *
    240         * @param type  the type to search for
    241         * @param fromIndex  the index of the starting position in the chain to be searched
    242         * @return index of the first occurrence of the type in the chain, or -1 if
    243         *  the type is not found
    244         * @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
    245         *  is negative or not less than the count of <code>Throwable</code>s in the chain
    246         * @since 2.1
    247         */
    248        public int indexOfThrowable(Class type, int fromIndex) {
    249            return delegate.indexOfThrowable(type, fromIndex);
    250        }
    251
    252        /**
    253         * Prints the stack trace of this exception.
    254         * Includes information from the exception, if any, which caused this exception.
    255         *
    256         * @since 2.1
    257         */
    258        public void printStackTrace() {
    259            delegate.printStackTrace();
    260        }
    261
    262        /**
    263         * Prints the stack trace of this exception to the specified stream.
    264         * Includes information from the exception, if any, which caused this exception.
    265         *
    266         * @param out  the stream to write to
    267         * @since 2.1
    268         */
    269        public void printStackTrace(PrintStream out) {
    270            delegate.printStackTrace(out);
    271        }
    272
    273        /**
    274         * Prints the stack trace of this exception to the specified writer.
    275         * Includes information from the exception, if any, which caused this exception.
    276         *
    277         * @param out  the writer to write to
    278         * @since 2.1
    279         */
    280        public void printStackTrace(PrintWriter out) {
    281            delegate.printStackTrace(out);
    282        }
    283
    284        /**
    285         * Prints the stack trace for this exception only (root cause not included)
    286         * using the specified writer.
    287         *
    288         * @param out  the writer to write to
    289         * @since 2.1
    290         */
    291        public final void printPartialStackTrace(PrintWriter out) {
    292            super.printStackTrace(out);
    293        }
    294
    295    }