    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
    024    import org.apache.commons.math.exception.MathThrowable;
    025    import org.apache.commons.math.exception.util.DummyLocalizable;
    026    import org.apache.commons.math.exception.util.Localizable;
    027    import org.apache.commons.math.exception.util.LocalizedFormats;
    028
    029
    030    /**
    031     * Base class for commons-math checked exceptions.
    032     * <p>
    033     * Supports nesting, emulating JDK 1.4 behavior if necessary.</p>
    034     * <p>
    035     * Adapted from <a href="http://commons.apache.org/collections/api-release/org/apache/commons/collections/FunctorException.html"/>.</p>
    036     *
    037     * @version $Revision: 1070725 $ $Date: 2011-02-15 02:31:12 +0100 (mar. 15 f??vr. 2011) $
    038     */
    039    public class MathException extends Exception implements MathThrowable {
    040
    041        /** Serializable version identifier. */
    042        private static final long serialVersionUID = 7428019509644517071L;
    043
    044        /**
    045         * Pattern used to build the message.
    046         */
    047        private final Localizable pattern;
    048
    049        /**
    050         * Arguments used to build the message.
    051         */
    052        private final Object[] arguments;
    053
    054        /**
    055         * Constructs a new <code>MathException</code> with no
    056         * detail message.
    057         */
    058        public MathException() {
    059            this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
    060            this.arguments = new Object[] { "" };
    061        }
    062
    063        /**
    064         * Constructs a new <code>MathException</code> with specified
    065         * formatted detail message.
    066         * Message formatting is delegated to {@link java.text.MessageFormat}.
    067         * @param pattern format specifier
    068         * @param arguments format arguments
    069         * @deprecated as of 2.2 replaced by {@link #MathException(Localizable, Object...)}
    070         */
    071        @Deprecated
    072        public MathException(String pattern, Object ... arguments) {
    073          this(new DummyLocalizable(pattern), arguments);
    074        }
    075
    076        /**
    077         * Constructs a new <code>MathException</code> with specified
    078         * formatted detail message.
    079         * Message formatting is delegated to {@link java.text.MessageFormat}.
    080         * @param pattern format specifier
    081         * @param arguments format arguments
    082         * @since 2.2
    083         */
    084        public MathException(Localizable pattern, Object ... arguments) {
    085          this.pattern   = pattern;
    086          this.arguments = (arguments == null) ? new Object[0] : arguments.clone();
    087        }
    088
    089        /**
    090         * Constructs a new <code>MathException</code> with specified
    091         * nested <code>Throwable</code> root cause.
    092         *
    093         * @param rootCause  the exception or error that caused this exception
    094         *                   to be thrown.
    095         */
    096        public MathException(Throwable rootCause) {
    097            super(rootCause);
    098            this.pattern   = LocalizedFormats.SIMPLE_MESSAGE;
    099            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
    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         */
    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
    141        public String getPattern() {
    142            return pattern.getSourceString();
    143        }
    144
    145        /**
    146         * {@inheritDoc}
    147         *
    148         * @since 2.2
    149         */
    150        public Localizable getSpecificPattern() {
    151            return null;
    152        }
    153
    154        /**
    155         * {@inheritDoc}
    156         *
    157         * @since 2.2
    158         */
    159        public Localizable getGeneralPattern() {
    160            return pattern;
    161        }
    162
    163        /** {@inheritDoc} */
    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         */
    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
    184        public String getMessage() {
    185            return getMessage(Locale.US);
    186        }
    187
    188        /** {@inheritDoc} */
    189        @Override
    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
    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
    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    }