1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.commons.math;
18 
19 import java.io.PrintStream;
20 import java.io.PrintWriter;
21 import java.text.MessageFormat;
22 import java.util.Locale;
23 
24 import org.apache.commons.math.exception.MathThrowable;
25 import org.apache.commons.math.exception.util.DummyLocalizable;
26 import org.apache.commons.math.exception.util.Localizable;
27 import org.apache.commons.math.exception.util.LocalizedFormats;
28 
29 
30 /**
31  * Base class for commons-math checked exceptions.
32  * <p>
33  * Supports nesting, emulating JDK 1.4 behavior if necessary.</p>
34  * <p>
35  * Adapted from <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/FunctorException.html"/>.</p>
36  *
37  * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 févr. 2011) $
38  */
39 public class MathException extends Exception implements MathThrowable {
40 
41     /** Serializable version identifier. */
42     private static final long serialVersionUID = 7428019509644517071L;
43 
44     /**
45      * Pattern used to build the message.
46      */
47     private final Localizable pattern;
48 
49     /**
50      * Arguments used to build the message.
51      */
52     private final Object[] arguments;
53 
54     /**
55      * Constructs a new <code>MathException</code> with no
56      * detail message.
57      */
MathException()58     public MathException() {
59         this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
60         this.arguments = new Object[] { "" };
61     }
62 
63     /**
64      * Constructs a new <code>MathException</code> with specified
65      * formatted detail message.
66      * Message formatting is delegated to {@link java.text.MessageFormat}.
67      * @param pattern format specifier
68      * @param arguments format arguments
69      * @deprecated as of 2.2 replaced by {@link #MathException(Localizable, Object...)}
70      */
71     @Deprecated
MathException(String pattern, Object ... arguments)72     public MathException(String pattern, Object ... arguments) {
73       this(new DummyLocalizable(pattern), arguments);
74     }
75 
76     /**
77      * Constructs a new <code>MathException</code> with specified
78      * formatted detail message.
79      * Message formatting is delegated to {@link java.text.MessageFormat}.
80      * @param pattern format specifier
81      * @param arguments format arguments
82      * @since 2.2
83      */
MathException(Localizable pattern, Object ... arguments)84     public MathException(Localizable pattern, Object ... arguments) {
85       this.pattern   = pattern;
86       this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
87     }
88 
89     /**
90      * Constructs a new <code>MathException</code> with specified
91      * nested <code>Throwable</code> root cause.
92      *
93      * @param rootCause  the exception or error that caused this exception
94      *                   to be thrown.
95      */
MathException(Throwable rootCause)96     public MathException(Throwable rootCause) {
97         super(rootCause);
98         this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
99         this.arguments = new Object[] { (rootCause == null) ? "" : rootCause.getMessage() };
100     }
101 
102     /**
103      * Constructs a new <code>MathException</code> with specified
104      * formatted detail message and nested <code>Throwable</code> root cause.
105      * Message formatting is delegated to {@link java.text.MessageFormat}.
106      * @param rootCause the exception or error that caused this exception
107      * to be thrown.
108      * @param pattern format specifier
109      * @param arguments format arguments
110      * @since 1.2
111      * @deprecated as of 2.2 replaced by {@link #MathException(Throwable, Localizable, Object...)}
112      */
113     @Deprecated
MathException(Throwable rootCause, String pattern, Object ... arguments)114     public MathException(Throwable rootCause, String pattern, Object ... arguments) {
115         this(rootCause, new DummyLocalizable(pattern), arguments);
116     }
117 
118     /**
119      * Constructs a new <code>MathException</code> with specified
120      * formatted detail message and nested <code>Throwable</code> root cause.
121      * Message formatting is delegated to {@link java.text.MessageFormat}.
122      * @param rootCause the exception or error that caused this exception
123      * to be thrown.
124      * @param pattern format specifier
125      * @param arguments format arguments
126      * @since 2.2
127      */
MathException(Throwable rootCause, Localizable pattern, Object ... arguments)128     public MathException(Throwable rootCause, Localizable pattern, Object ... arguments) {
129       super(rootCause);
130       this.pattern   = pattern;
131       this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
132     }
133 
134     /** Gets the pattern used to build the message of this throwable.
135      *
136      * @return the pattern used to build the message of this throwable
137      * @since 1.2
138      * @deprecated as of 2.2 replaced by {@link #getSpecificPattern()} and {@link #getGeneralPattern()}
139      */
140     @Deprecated
getPattern()141     public String getPattern() {
142         return pattern.getSourceString();
143     }
144 
145     /**
146      * {@inheritDoc}
147      *
148      * @since 2.2
149      */
getSpecificPattern()150     public Localizable getSpecificPattern() {
151         return null;
152     }
153 
154     /**
155      * {@inheritDoc}
156      *
157      * @since 2.2
158      */
getGeneralPattern()159     public Localizable getGeneralPattern() {
160         return pattern;
161     }
162 
163     /** {@inheritDoc} */
getArguments()164     public Object[] getArguments() {
165         return arguments.clone();
166     }
167 
168     /** Gets the message in a specified locale.
169      *
170      * @param locale Locale in which the message should be translated
171      *
172      * @return localized message
173      * @since 1.2
174      */
getMessage(final Locale locale)175     public String getMessage(final Locale locale) {
176         if (pattern != null) {
177             return new MessageFormat(pattern.getLocalizedString(locale), locale).format(arguments);
178         }
179         return "";
180     }
181 
182     /** {@inheritDoc} */
183     @Override
getMessage()184     public String getMessage() {
185         return getMessage(Locale.US);
186     }
187 
188     /** {@inheritDoc} */
189     @Override
getLocalizedMessage()190     public String getLocalizedMessage() {
191         return getMessage(Locale.getDefault());
192     }
193 
194     /**
195      * Prints the stack trace of this exception to the standard error stream.
196      */
197     @Override
printStackTrace()198     public void printStackTrace() {
199         printStackTrace(System.err);
200     }
201 
202     /**
203      * Prints the stack trace of this exception to the specified stream.
204      *
205      * @param out  the <code>PrintStream</code> to use for output
206      */
207     @Override
printStackTrace(PrintStream out)208     public void printStackTrace(PrintStream out) {
209         synchronized (out) {
210             PrintWriter pw = new PrintWriter(out, false);
211             printStackTrace(pw);
212             // Flush the PrintWriter before it's GC'ed.
213             pw.flush();
214         }
215     }
216 
217 }
218