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.math;
018    
019    import java.io.PrintStream;
020    import java.io.PrintWriter;
021    import java.text.MessageFormat;
022    import java.util.Locale;
023    import java.util.Set;
024    
025    import org.apache.commons.math.exception.util.Localizable;
026    import org.apache.commons.math.exception.util.LocalizedFormats;
027    
028    
029    /**
030    * Base class for commons-math checked exceptions.
031    * <p>
032    * Supports nesting, emulating JDK 1.4 behavior if necessary.</p>
033    * <p>
034    * Adapted from <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/FunctorException.html"/>.</p>
035    *
036    * @version $Id: MathException.java 1178040 2011-10-01 16:23:48Z erans $
037    * @deprecated To be removed before 3.0.  Please do not use in any new code.
038    */
039    public class MathException extends Exception {
040    
041        /** Serializable version identifier. */
042        private static final long serialVersionUID = 7428019509644517071L;
043    
044        /** Deprecation message. */
045        private static final String DEPRECATION_MESSAGE = "This class is deprecated; calling this method is a bug.";
046    
047        /**
048         * Pattern used to build the message.
049         */
050        private final Localizable pattern;
051    
052        /**
053         * Arguments used to build the message.
054         */
055        private final Object[] arguments;
056    
057        /**
058         * Constructs a new <code>MathException</code> with no
059         * detail message.
060         */
061        public MathException() {
062            this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
063            this.arguments = new Object[] { "" };
064        }
065    
066        /**
067         * Constructs a new <code>MathException</code> with specified
068         * formatted detail message.
069         * Message formatting is delegated to {@link java.text.MessageFormat}.
070         * @param pattern format specifier
071         * @param arguments format arguments
072         * @since 2.2
073         */
074        public MathException(Localizable pattern, Object ... arguments) {
075          this.pattern   = pattern;
076          this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
077        }
078    
079        /**
080         * Constructs a new <code>MathException</code> with specified
081         * nested <code>Throwable</code> root cause.
082         *
083         * @param rootCause  the exception or error that caused this exception
084         *                   to be thrown.
085         */
086        public MathException(Throwable rootCause) {
087            super(rootCause);
088            this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
089            this.arguments = new Object[] { (rootCause == null) ? "" : rootCause.getMessage() };
090        }
091    
092        /**
093         * Constructs a new <code>MathException</code> with specified
094         * formatted detail message and nested <code>Throwable</code> root cause.
095         * Message formatting is delegated to {@link java.text.MessageFormat}.
096         * @param rootCause the exception or error that caused this exception
097         * to be thrown.
098         * @param pattern format specifier
099         * @param arguments format arguments
100         * @since 2.2
101         */
102        public MathException(Throwable rootCause, Localizable pattern, Object ... arguments) {
103          super(rootCause);
104          this.pattern   = pattern;
105          this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
106        }
107    
108        /**
109         * Sets a message.
110         *
111         * @param pat Message pattern.
112         * @param args Values for replacing the placeholders in the message
113         * pattern.
114         */
115        public void addMessage(Localizable pat,
116                               Object ... args) {
117            throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
118        }
119    
120        /**
121         * Sets the context (key, value) pair.
122         * Keys are assumed to be unique within an instance. If the same key is
123         * assigned a new value, the previous one will be lost.
124         *
125         * @param key Context key (not null).
126         * @param value Context value.
127         */
128        public void setContext(String key, Object value) {
129            throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
130        }
131    
132        /**
133         * Gets the value associated to the given context key.
134         *
135         * @param key Context key.
136         * @return the context value or {@code null} if the key does not exist.
137         */
138        public Object getContext(String key) {
139            throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
140        }
141    
142        /**
143         * Gets all the keys stored in the exception
144         *
145         * @return the set of keys.
146         */
147        public Set<String> getContextKeys() {
148            throw new UnsupportedOperationException(DEPRECATION_MESSAGE);
149        }
150    
151        /** Gets the message in a specified locale.
152         *
153         * @param locale Locale in which the message should be translated
154         *
155         * @return localized message
156         * @since 1.2
157         */
158        public String getMessage(final Locale locale) {
159            if (pattern != null) {
160                return new MessageFormat(pattern.getLocalizedString(locale), locale).format(arguments);
161            }
162            return "";
163        }
164    
165        /**
166         * Gets the message in a conventional US locale.
167         *
168         * @return localized message
169         */
170        @Override
171        public String getMessage() {
172            return getMessage(Locale.US);
173        }
174    
175        /**
176         * Gets the message in the system default locale.
177         *
178         * @return localized message
179         */
180        @Override
181        public String getLocalizedMessage() {
182            return getMessage(Locale.getDefault());
183        }
184    
185        /**
186         * Prints the stack trace of this exception to the standard error stream.
187         */
188        @Override
189        public void printStackTrace() {
190            printStackTrace(System.err);
191        }
192    
193        /**
194         * Prints the stack trace of this exception to the specified stream.
195         *
196         * @param out  the <code>PrintStream</code> to use for output
197         */
198        @Override
199        public void printStackTrace(PrintStream out) {
200            synchronized (out) {
201                PrintWriter pw = new PrintWriter(out, false);
202                printStackTrace(pw);
203                // Flush the PrintWriter before it's GC'ed.
204                pw.flush();
205            }
206        }
207    
208    }