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    }