From 173735d2df7894572018c15e45a0839059f5fa4c Mon Sep 17 00:00:00 2001 From: Gilles Sadowski Date: Thu, 5 Aug 2010 09:51:48 +0000 Subject: [PATCH] Moved exception utilities to package "exception.util". Created "MathUnsupportedOperationException". Replaced factory method "createUnsupportedOperationException" occurences by an explicit construction of a "MathUnsupportedOperationException". Corrected a bug (in "AbstractRealVector") where a "dimension" was stored in a "double". Replaced a "createIllegalArgumentException" by a "DimensionMismatchException". Removed checks for "null" in "BigFraction". git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@982526 13f79535-47bb-0310-9956-ffa450edef68 --- .../commons/math/MathRuntimeException.java | 3 + .../math/exception/LocalizedFormats.java | 2 +- .../MathIllegalArgumentException.java | 56 +++--------- .../MathUnsupportedOperationException.java | 90 +++++++++++++++++++ .../commons/math/exception/util/ArgUtils.java | 45 ++++++++++ .../exception/{ => util}/MessageFactory.java | 39 ++++++-- .../commons/math/fraction/BigFraction.java | 8 -- .../math/linear/AbstractRealVector.java | 16 ++-- .../LocalizedFormats_fr.properties | 25 +++--- src/site/xdoc/changes.xml | 2 + .../math/exception/util/ArgUtilsTest.java | 76 ++++++++++++++++ 11 files changed, 286 insertions(+), 76 deletions(-) create mode 100644 src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.java create mode 100644 src/main/java/org/apache/commons/math/exception/util/ArgUtils.java rename src/main/java/org/apache/commons/math/exception/{ => util}/MessageFactory.java (51%) create mode 100644 src/test/java/org/apache/commons/math/exception/util/ArgUtilsTest.java diff --git a/src/main/java/org/apache/commons/math/MathRuntimeException.java b/src/main/java/org/apache/commons/math/MathRuntimeException.java index b2135de56..1afb8881a 100644 --- a/src/main/java/org/apache/commons/math/MathRuntimeException.java +++ b/src/main/java/org/apache/commons/math/MathRuntimeException.java @@ -556,6 +556,8 @@ public class MathRuntimeException extends RuntimeException { * @param arguments format arguments * @return built exception * @since 2.2 + * @deprecated in 2.2. Please use {@link org.apache.commons.math.exception.MathUnsupportedOperationException} + * instead. */ public static UnsupportedOperationException createUnsupportedOperationException(final Localizable pattern, final Object ... arguments) { @@ -600,6 +602,7 @@ public class MathRuntimeException extends RuntimeException { * @param arguments format arguments * @return built exception * @since 2.2 + * @deprecated in 2.2. Checks for "null" must not be performed in Commons-Math. */ public static NullPointerException createNullPointerException(final Localizable pattern, final Object ... arguments) { diff --git a/src/main/java/org/apache/commons/math/exception/LocalizedFormats.java b/src/main/java/org/apache/commons/math/exception/LocalizedFormats.java index af9f522d7..c14db2dd8 100644 --- a/src/main/java/org/apache/commons/math/exception/LocalizedFormats.java +++ b/src/main/java/org/apache/commons/math/exception/LocalizedFormats.java @@ -281,7 +281,7 @@ public enum LocalizedFormats implements Localizable { UNPARSEABLE_FRACTION_NUMBER("unparseable fraction number: \"{0}\""), UNPARSEABLE_REAL_VECTOR("unparseable real vector: \"{0}\""), UNSUPPORTED_EXPANSION_MODE("unsupported expansion mode {0}, supported modes are {1} ({2}) and {3} ({4})"), - UNSUPPORTED_OPERATION("unsupported operation"), + UNSUPPORTED_OPERATION("unsupported operation"), /* keep */ URL_CONTAINS_NO_DATA("URL {0} contains no data"), VALUES_ADDED_BEFORE_CONFIGURING_STATISTIC("{0} values have been added before statistic is configured"), VECTOR_LENGTH_MISMATCH("vector length mismatch: got {0} but expected {1}"), diff --git a/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.java b/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.java index 738d82c4d..f7a7250ec 100644 --- a/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.java +++ b/src/main/java/org/apache/commons/math/exception/MathIllegalArgumentException.java @@ -17,8 +17,9 @@ package org.apache.commons.math.exception; import java.util.Locale; -import java.util.List; -import java.util.ArrayList; + +import org.apache.commons.math.exception.util.ArgUtils; +import org.apache.commons.math.exception.util.MessageFactory; /** * Base class for all preconditions violation exceptions. @@ -59,7 +60,7 @@ public class MathIllegalArgumentException extends IllegalArgumentException { Object ... args) { this.specific = specific; this.general = general; - arguments = flatten(args).toArray(); + arguments = ArgUtils.flatten(args); } /** * @param general Message pattern explaining the cause of the error. @@ -70,24 +71,16 @@ public class MathIllegalArgumentException extends IllegalArgumentException { this(null, general, args); } - /** Gets the message in a specified locale. - * - * @param locale Locale in which the message should be translated - * - * @return localized message - * @since 2.2 - */ - public String getMessage(final Locale locale) { - final StringBuilder sb = new StringBuilder(); - - if (specific != null) { - sb.append(MessageFactory.buildMessage(locale, specific, arguments)); - sb.append(": "); - } - sb.append(MessageFactory.buildMessage(locale, general, arguments)); - - return sb.toString(); - } + /** + * Get the message in a specified locale. + * + * @param locale Locale in which the message should be translated. + * + * @return the localized message. + */ + public String getMessage(final Locale locale) { + return MessageFactory.buildMessage(locale, specific, general, arguments); + } /** {@inheritDoc} */ @Override @@ -100,25 +93,4 @@ public class MathIllegalArgumentException extends IllegalArgumentException { public String getLocalizedMessage() { return getMessage(Locale.getDefault()); } - - /** - * Transform a multidimensional array into a one-dimensional list. - * - * @param array Array (possibly multidimensional). - * @return a list of all the {@code Object} instances contained in - * {@code array}. - */ - private List flatten(Object[] array) { - final List list = new ArrayList(); - if (array != null) { - for (Object o : array) { - if (o instanceof Object[]) { - list.addAll(flatten((Object[]) o)); - } else { - list.add(o); - } - } - } - return list; - } } diff --git a/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.java b/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.java new file mode 100644 index 000000000..876af8620 --- /dev/null +++ b/src/main/java/org/apache/commons/math/exception/MathUnsupportedOperationException.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.exception; + +import java.util.Locale; + +import org.apache.commons.math.exception.util.ArgUtils; +import org.apache.commons.math.exception.util.MessageFactory; +import org.apache.commons.math.exception.LocalizedFormats; + +/** + * Base class for all unsupported features. + * It is used for all the exceptions that share the semantics of the standard + * {@link UnsupportedOperationException}, but must also provide a localized + * message. + * + * @since 2.2 + * @version $Revision$ $Date$ + */ +public class MathUnsupportedOperationException extends UnsupportedOperationException { + + /** Serializable version Id. */ + private static final long serialVersionUID = -6024911025449780478L; + + /** + * Pattern used to build the message (specific context). + */ + private final Localizable specific; + /** + * Arguments used to build the message. + */ + private final Object[] arguments; + + /** + * @param args Arguments. + */ + public MathUnsupportedOperationException(Object ... args) { + this(null, args); + } + /** + * @param specific Message pattern providing the specific context of + * the error. + * @param args Arguments. + */ + public MathUnsupportedOperationException(Localizable specific, + Object ... args) { + this.specific = specific; + arguments = ArgUtils.flatten(args); + } + + /** + * Get the message in a specified locale. + * + * @param locale Locale in which the message should be translated. + * + * @return the localized message. + */ + public String getMessage(final Locale locale) { + return MessageFactory.buildMessage(locale, + specific, + LocalizedFormats.UNSUPPORTED_OPERATION, + arguments); + } + + /** {@inheritDoc} */ + @Override + public String getMessage() { + return getMessage(Locale.US); + } + + /** {@inheritDoc} */ + @Override + public String getLocalizedMessage() { + return getMessage(Locale.getDefault()); + } +} diff --git a/src/main/java/org/apache/commons/math/exception/util/ArgUtils.java b/src/main/java/org/apache/commons/math/exception/util/ArgUtils.java new file mode 100644 index 000000000..be21c6c30 --- /dev/null +++ b/src/main/java/org/apache/commons/math/exception/util/ArgUtils.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.exception.util; + +import java.util.List; +import java.util.ArrayList; + +public class ArgUtils { + /** + * Transform a multidimensional array into a one-dimensional list. + * + * @param array Array (possibly multidimensional). + * @return a list of all the {@code Object} instances contained in + * {@code array}. + */ + public static Object[] flatten(Object[] array) { + final List list = new ArrayList(); + if (array != null) { + for (Object o : array) { + if (o instanceof Object[]) { + for (Object oR : flatten((Object[]) o)) { + list.add(oR); + } + } else { + list.add(o); + } + } + } + return list.toArray(); + } +} diff --git a/src/main/java/org/apache/commons/math/exception/MessageFactory.java b/src/main/java/org/apache/commons/math/exception/util/MessageFactory.java similarity index 51% rename from src/main/java/org/apache/commons/math/exception/MessageFactory.java rename to src/main/java/org/apache/commons/math/exception/util/MessageFactory.java index 2d371c7c8..fd05419a8 100644 --- a/src/main/java/org/apache/commons/math/exception/MessageFactory.java +++ b/src/main/java/org/apache/commons/math/exception/util/MessageFactory.java @@ -14,11 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.math.exception; +package org.apache.commons.math.exception.util; import java.text.MessageFormat; import java.util.Locale; +import org.apache.commons.math.exception.Localizable; + /** * Class for constructing localized messages. * @@ -37,13 +39,40 @@ public class MessageFactory { * @param locale Locale in which the message should be translated. * @param pattern Format specifier. * @param arguments Format arguments. - * @return a message string. - * @since 2.2 + * @return a localized message string. */ public static String buildMessage(Locale locale, Localizable pattern, Object ... arguments) { - final String locPattern = pattern.getLocalizedString(locale); - return (new MessageFormat(locPattern, locale)).format(arguments); + return buildMessage(locale, null, pattern, arguments); + } + + /** + * Builds a message string by from two patterns (specific and general) and + * an argument list. + * + * @param locale Locale in which the message should be translated. + * @param specific Format specifier. + * @param general Format specifier. + * @param arguments Format arguments. They will be substituted first in + * the {@code specific} format specifier, then the remaining arguments + * will be substituted in the {@code general} format specifier. + * @return a localized message string. + */ + public static String buildMessage(Locale locale, + Localizable specific, + Localizable general, + Object ... arguments) { + final StringBuilder sb = new StringBuilder(); + MessageFormat fmt = null; + if (specific != null) { + fmt = new MessageFormat(specific.getLocalizedString(locale), locale); + sb.append(fmt.format(arguments)); + sb.append(": "); + } + fmt = new MessageFormat(general.getLocalizedString(locale), locale); + sb.append(fmt.format(arguments)); + + return sb.toString(); } } diff --git a/src/main/java/org/apache/commons/math/fraction/BigFraction.java b/src/main/java/org/apache/commons/math/fraction/BigFraction.java index 941d09e2c..70fb64448 100644 --- a/src/main/java/org/apache/commons/math/fraction/BigFraction.java +++ b/src/main/java/org/apache/commons/math/fraction/BigFraction.java @@ -115,16 +115,8 @@ public class BigFraction * the denominator, must not be null. * @throws ArithmeticException * if the denominator is zero. - * @throws NullPointerException - * if the numerator or the denominator is zero. */ public BigFraction(BigInteger num, BigInteger den) { - if (num == null) { - throw MathRuntimeException.createNullPointerException(LocalizedFormats.NULL_NUMERATOR); - } - if (den == null) { - throw MathRuntimeException.createNullPointerException(LocalizedFormats.NULL_DENOMINATOR); - } if (BigInteger.ZERO.equals(den)) { throw MathRuntimeException.createArithmeticException(LocalizedFormats.ZERO_DENOMINATOR); } diff --git a/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java index 7f94e7e9a..f2cd89bc6 100644 --- a/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java +++ b/src/main/java/org/apache/commons/math/linear/AbstractRealVector.java @@ -21,7 +21,8 @@ import java.util.Iterator; import java.util.NoSuchElementException; import org.apache.commons.math.FunctionEvaluationException; -import org.apache.commons.math.MathRuntimeException; +import org.apache.commons.math.exception.MathUnsupportedOperationException; +import org.apache.commons.math.exception.DimensionMismatchException; import org.apache.commons.math.analysis.BinaryFunction; import org.apache.commons.math.analysis.ComposableFunction; import org.apache.commons.math.analysis.UnivariateRealFunction; @@ -29,7 +30,7 @@ import org.apache.commons.math.exception.LocalizedFormats; /** * This class provides default basic implementations for many methods in the - * {@link RealVector} interface with. + * {@link RealVector} interface. * @version $Revision$ $Date$ * @since 2.1 */ @@ -53,11 +54,10 @@ public abstract class AbstractRealVector implements RealVector { * inconsistent with vector size */ protected void checkVectorDimensions(int n) - throws IllegalArgumentException { - double d = getDimension(); + throws DimensionMismatchException { + int d = getDimension(); if (d != n) { - throw MathRuntimeException.createIllegalArgumentException( - LocalizedFormats.VECTOR_LENGTH_MISMATCH, d, n); + throw new DimensionMismatchException(d, n); } } @@ -816,7 +816,7 @@ public abstract class AbstractRealVector implements RealVector { /** {@inheritDoc} */ public void remove() { - throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.UNSUPPORTED_OPERATION); + throw new MathUnsupportedOperationException(); } }; } @@ -924,7 +924,7 @@ public abstract class AbstractRealVector implements RealVector { /** {@inheritDoc} */ public void remove() { - throw MathRuntimeException.createUnsupportedOperationException(LocalizedFormats.UNSUPPORTED_OPERATION); + throw new MathUnsupportedOperationException(); } } diff --git a/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties b/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties index 67d5624f7..18afba968 100644 --- a/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties +++ b/src/main/resources/META-INF/localization/LocalizedFormats_fr.properties @@ -183,18 +183,19 @@ NO_FEASIBLE_SOLUTION = aucune solution r\u00e9alisable NO_OPTIMUM_COMPUTED_YET = aucun optimum n''a encore \u00e9t\u00e9 calcul\u00e9 NO_RESULT_AVAILABLE = aucun r\u00e9sultat n''est disponible NO_SUCH_MATRIX_ENTRY = pas d''\u00e9l\u00e9ment ({0}, {1}) dans une matrice {2}x{3} -NULL_COVARIANCE_MATRIX = la matrice de covariance est nulle -NULL_DENOMINATOR = le d\u00e9nominateur est null -NULL_DENOMINATOR_FORMAT = le format du d\u00e9nominateur ne doit pas \u00eatre nul -NULL_FRACTION = fraction nulle -NULL_FUNCTION = la fonction est nulle -NULL_IMAGINARY_FORMAT = format imaginaire nul -NULL_INPUT_ARRAY = tableau d''entr\u00e9e nul -NULL_NUMERATOR = le num\u00e9rateur est null -NULL_NUMERATOR_FORMAT = le format du num\u00e9rateur ne doit pas \u00eatre nul -NULL_OBJECT_TRANSFORMATION = Exception de conversion dans une transformation, l''objet est nul -NULL_REAL_FORMAT = format r\u00e9el nul -NULL_WHOLE_FORMAT = le format complet ne doit pas \u00eatre nul +NULL_NOT_ALLOWED = "null" n''est pas permis +COVARIANCE_MATRIX = matrice de covariance +DENOMINATOR = d\u00e9nominateur +DENOMINATOR_FORMAT = format du d\u00e9nominateur +FRACTION = fraction +FUNCTION = fonction +IMAGINARY_FORMAT = format imaginaire +INPUT_ARRAY = tableau d''entr\u00e9e +NUMERATOR = num\u00e9rateur +NUMERATOR_FORMAT = format du num\u00e9rateur +OBJECT_TRANSFORMATION = exception de conversion dans une transformation +REAL_FORMAT = format r\u00e9el +WHOLE_FORMAT = format complet NUMBER_TOO_LARGE = {0} est plus grand que le maximum ({1}) NUMBER_TOO_SMALL = {0} est plus petit que le minimum ({1}) NUMBER_TOO_LARGE_BOUND_EXCLUDED = {0} n''est pas strictement plus grand que le maximum ({1}) diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml index 5d5a42b93..7d8200b9a 100644 --- a/src/site/xdoc/changes.xml +++ b/src/site/xdoc/changes.xml @@ -94,6 +94,8 @@ The type attribute can be add,update,fix,remove. Created package "exception" to contain the new exceptions hierarchy. + Created package "exception.util": utilities for the exception classes + (e.g. managing the localization of error messages). Implementation of linear interpolation. diff --git a/src/test/java/org/apache/commons/math/exception/util/ArgUtilsTest.java b/src/test/java/org/apache/commons/math/exception/util/ArgUtilsTest.java new file mode 100644 index 000000000..34c4d8523 --- /dev/null +++ b/src/test/java/org/apache/commons/math/exception/util/ArgUtilsTest.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.math.exception.util; + +import java.util.List; +import java.util.ArrayList; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for {@link ArgUtils}. + * + * @version $Revision$ $Date$ + */ +public class ArgUtilsTest { + @Test + public void testFlatten() { + final List orig = new ArrayList(); + + final Object[] struct = new Object[] { + new Object[] { + new Object[] { + create(orig), + create(orig), + }, + create(orig), + new Object[] { + create(orig), + } + }, + create(orig), + new Object[] { + create(orig), + new Object[] { + create(orig), + create(orig), + } + }, + create(orig), + }; + + Object[] flat = ArgUtils.flatten(struct); + Assert.assertEquals(flat.length, orig.size()); + + for (int i = 0, max = orig.size(); i < max; i++) { + Assert.assertEquals(orig.get(i), flat[i]); + } + } + + /** + * Create and store an {@code Object}. + * + * @param list List to store to. + * @return the stored object. + */ + private Object create(List list) { + final Object o = new Object(); + list.add(o); + return o; + } +}