View Javadoc

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  import java.util.MissingResourceException;
24  import java.util.ResourceBundle;
25  
26  
27  /**
28  * Base class for commons-math checked exceptions.
29  * <p>
30  * Supports nesting, emulating JDK 1.4 behavior if necessary.</p>
31  * <p>
32  * Adapted from <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/FunctorException.html"/>.</p>
33  *
34  * @version $Revision: 822850 $ $Date: 2009-10-07 14:56:42 -0400 (Wed, 07 Oct 2009) $
35  */
36  public class MathException extends Exception {
37  
38      /** Serializable version identifier. */
39      private static final long serialVersionUID = -9004610152740737812L;
40  
41      /**
42       * Pattern used to build the message.
43       */
44      private final String pattern;
45  
46      /**
47       * Arguments used to build the message.
48       */
49      private final Object[] arguments;
50  
51      /**
52       * Constructs a new <code>MathException</code> with no
53       * detail message.
54       */
55      public MathException() {
56          this.pattern   = null;
57          this.arguments = new Object[0];
58      }
59  
60      /**
61       * Constructs a new <code>MathException</code> with specified
62       * formatted detail message.
63       * Message formatting is delegated to {@link java.text.MessageFormat}.
64       * @param pattern format specifier
65       * @param arguments format arguments
66       */
67      public MathException(String pattern, Object ... arguments) {
68        this.pattern   = pattern;
69        this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
70      }
71  
72      /**
73       * Constructs a new <code>MathException</code> with specified
74       * nested <code>Throwable</code> root cause.
75       *
76       * @param rootCause  the exception or error that caused this exception
77       *                   to be thrown.
78       */
79      public MathException(Throwable rootCause) {
80          super(rootCause);
81          this.pattern   = getMessage();
82          this.arguments = new Object[0];
83      }
84  
85      /**
86       * Constructs a new <code>MathException</code> with specified
87       * formatted detail message and nested <code>Throwable</code> root cause.
88       * Message formatting is delegated to {@link java.text.MessageFormat}.
89       * @param rootCause the exception or error that caused this exception
90       * to be thrown.
91       * @param pattern format specifier
92       * @param arguments format arguments
93       * @since 1.2
94       */
95      public MathException(Throwable rootCause, String pattern, Object ... arguments) {
96        super(rootCause);
97        this.pattern   = pattern;
98        this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
99      }
100 
101     /**
102      * Translate a string to a given locale.
103      * @param s string to translate
104      * @param locale locale into which to translate the string
105      * @return translated string or original string
106      * for unsupported locales or unknown strings
107      */
108     private static String translate(String s, Locale locale) {
109         try {
110             ResourceBundle bundle =
111                     ResourceBundle.getBundle("org.apache.commons.math.MessagesResources", locale);
112             if (bundle.getLocale().getLanguage().equals(locale.getLanguage())) {
113                 // the value of the resource is the translated string
114                 return bundle.getString(s);
115             }
116 
117         } catch (MissingResourceException mre) {
118             // do nothing here
119         }
120 
121         // the locale is not supported or the resource is unknown
122         // don't translate and fall back to using the string as is
123         return s;
124 
125     }
126 
127     /** Gets the pattern used to build the message of this throwable.
128      *
129      * @return the pattern used to build the message of this throwable
130      * @since 1.2
131      */
132     public String getPattern() {
133         return pattern;
134     }
135 
136     /** Gets the arguments used to build the message of this throwable.
137      *
138      * @return the arguments used to build the message of this throwable
139      * @since 1.2
140      */
141     public Object[] getArguments() {
142         return arguments.clone();
143     }
144 
145     /** Gets the message in a specified locale.
146      *
147      * @param locale Locale in which the message should be translated
148      *
149      * @return localized message
150      * @since 1.2
151      */
152     public String getMessage(final Locale locale) {
153         return (pattern == null) ? "" : new MessageFormat(translate(pattern, locale), locale).format(arguments);
154     }
155 
156     /** {@inheritDoc} */
157     @Override
158     public String getMessage() {
159         return getMessage(Locale.US);
160     }
161 
162     /** {@inheritDoc} */
163     @Override
164     public String getLocalizedMessage() {
165         return getMessage(Locale.getDefault());
166     }
167 
168     /**
169      * Prints the stack trace of this exception to the standard error stream.
170      */
171     @Override
172     public void printStackTrace() {
173         printStackTrace(System.err);
174     }
175 
176     /**
177      * Prints the stack trace of this exception to the specified stream.
178      *
179      * @param out  the <code>PrintStream</code> to use for output
180      */
181     @Override
182     public void printStackTrace(PrintStream out) {
183         synchronized (out) {
184             PrintWriter pw = new PrintWriter(out, false);
185             printStackTrace(pw);
186             // Flush the PrintWriter before it's GC'ed.
187             pw.flush();
188         }
189     }
190 
191 }