sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/03: Clarify which locale is used in error messages.
Date Mon, 09 Nov 2020 23:16:13 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 847ab7ed972ce1cc0a1f765d4583fa19aa04dcc7
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Fri Nov 6 11:09:59 2020 +0100

    Clarify which locale is used in error messages.
---
 .../main/java/org/apache/sis/io/wkt/Element.java   | 34 ++++++++++----------
 .../main/java/org/apache/sis/io/wkt/Formatter.java | 36 +++++++++++++++++-----
 .../main/java/org/apache/sis/io/wkt/WKTFormat.java | 33 +++++++++++++++-----
 .../java/org/apache/sis/io/wkt/WKTFormatTest.java  |  3 +-
 .../java/org/apache/sis/math/StatisticsFormat.java |  3 +-
 .../sis/util/collection/TreeTableFormat.java       |  4 +--
 6 files changed, 76 insertions(+), 37 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java
index a1e66d1..137203e 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Element.java
@@ -111,7 +111,7 @@ final class Element implements Serializable {
      * The locale to be used for formatting an error message if the parsing fails, or {@code
null} for
      * the system default. This is <strong>not</strong> the locale for parting
number or date values.
      */
-    private final Locale locale;
+    private final Locale errorLocale;
 
     /**
      * Constructs a root element.
@@ -120,10 +120,10 @@ final class Element implements Serializable {
      * @param singleton  the only child for this root.
      */
     Element(final String name, final Element singleton) {
-        keyword  = name;
-        offset   = singleton.offset;
-        locale   = singleton.locale;
-        children = new LinkedList<>();                          // Needs to be a modifiable
collection.
+        keyword     = name;
+        offset      = singleton.offset;
+        errorLocale = singleton.errorLocale;
+        children    = new LinkedList<>();                       // Needs to be a modifiable
collection.
         children.add(singleton);
         isEnumeration = false;
     }
@@ -135,7 +135,7 @@ final class Element implements Serializable {
         offset        = toCopy.offset;
         keyword       = toCopy.keyword;
         isEnumeration = toCopy.isEnumeration;
-        locale        = toCopy.locale;
+        errorLocale   = toCopy.errorLocale;
         children      = new LinkedList<>(toCopy.children);      // Needs to be a modifiable
collection.
         final ListIterator<Object> it = children.listIterator();
         while (it.hasNext()) {
@@ -175,7 +175,7 @@ final class Element implements Serializable {
          * Find the first keyword in the specified string. If a keyword is found, then
          * the position is set to the index of the first character after the keyword.
          */
-        locale = parser.errorLocale;
+        errorLocale = parser.errorLocale;
         offset = position.getIndex();
         final int length = text.length();
         int lower = skipLeadingWhitespaces(text, offset, length);
@@ -238,7 +238,7 @@ final class Element implements Serializable {
                 if (fragment == null) {
                     position.setIndex(offset);
                     position.setErrorIndex(lower);
-                    throw new UnparsableObjectException(locale, Errors.Keys.NoSuchValue_1,
new Object[] {id}, lower);
+                    throw new UnparsableObjectException(errorLocale, Errors.Keys.NoSuchValue_1,
new Object[] {id}, lower);
                 }
                 if (!fragment.isEnumeration) {
                     fragment = new Element(fragment);
@@ -388,8 +388,8 @@ final class Element implements Serializable {
      * @return the exception to be thrown.
      */
     final ParseException parseFailed(final Exception cause) {
-        return new UnparsableObjectException(locale, Errors.Keys.ErrorIn_2,
-                new String[] {keyword, Exceptions.getLocalizedMessage(cause, locale)}, offset).initCause(cause);
+        return new UnparsableObjectException(errorLocale, Errors.Keys.ErrorIn_2,
+                new String[] {keyword, Exceptions.getLocalizedMessage(cause, errorLocale)},
offset).initCause(cause);
     }
 
     /**
@@ -415,7 +415,7 @@ final class Element implements Serializable {
             arguments = new CharSequence[] {keyword, CharSequences.token(text, errorIndex)};
         }
         position.setIndex(offset);
-        return new UnparsableObjectException(locale, errorKey, arguments, errorIndex);
+        return new UnparsableObjectException(errorLocale, errorKey, arguments, errorIndex);
     }
 
     /**
@@ -429,7 +429,7 @@ final class Element implements Serializable {
         position.setIndex(offset);
         position.setErrorIndex(errorIndex);
         final StringBuilder buffer = new StringBuilder(2).appendCodePoint(c);
-        return new UnparsableObjectException(locale, Errors.Keys.MissingCharacterInElement_2,
+        return new UnparsableObjectException(errorLocale, Errors.Keys.MissingCharacterInElement_2,
                 new CharSequence[] {keyword, buffer}, errorIndex);
     }
 
@@ -443,7 +443,7 @@ final class Element implements Serializable {
         if (keyword != null) {
             error += keyword.length();
         }
-        return new UnparsableObjectException(locale, Errors.Keys.MissingComponentInElement_2,
+        return new UnparsableObjectException(errorLocale, Errors.Keys.MissingComponentInElement_2,
                 new String[] {keyword, key}, error);
     }
 
@@ -472,7 +472,7 @@ final class Element implements Serializable {
             res  = Errors.Keys.MissingComponentInElement_2;
             args = new String[] {keyword, expected};
         }
-        return new UnparsableObjectException(locale, res, args, offset);
+        return new UnparsableObjectException(errorLocale, res, args, offset);
     }
 
     /**
@@ -496,7 +496,7 @@ final class Element implements Serializable {
             key   = Errors.Keys.IllegalCoordinateSystem_1;
             value = cs.getName().getCode();
         }
-        return new UnparsableObjectException(locale, key, new String[] {value}, offset);
+        return new UnparsableObjectException(errorLocale, key, new String[] {value}, offset);
     }
 
 
@@ -577,7 +577,7 @@ final class Element implements Serializable {
                 iterator.remove();
                 final Number number = (Number) object;
                 if (number instanceof Float || number instanceof Double) {
-                    throw new UnparsableObjectException(locale, Errors.Keys.UnparsableStringForClass_2,
+                    throw new UnparsableObjectException(errorLocale, Errors.Keys.UnparsableStringForClass_2,
                             new Object[] {Integer.class, number}, offset);
                 }
                 return number.intValue();
@@ -764,7 +764,7 @@ final class Element implements Serializable {
             if (value instanceof Element) {
                 CollectionsExt.addToMultiValuesMap(ignoredElements, ((Element) value).keyword,
keyword);
             } else {
-                throw new UnparsableObjectException(locale, Errors.Keys.UnexpectedValueInElement_2,
+                throw new UnparsableObjectException(errorLocale, Errors.Keys.UnexpectedValueInElement_2,
                         new Object[] {keyword, value}, offset + keyword.length());
             }
         }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
index 5f28fbd..11a1d0c 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
@@ -105,7 +105,7 @@ import org.apache.sis.math.Vector;
  * </ul>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.0
+ * @version 1.1
  *
  * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html">WKT 2 specification</a>
  * @see <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Legacy
WKT 1</a>
@@ -141,6 +141,8 @@ public class Formatter implements Localized {
     /**
      * The locale for the localization of international strings.
      * This is not the same than {@link Symbols#getLocale()}.
+     *
+     * @see #errorLocale
      */
     private final Locale locale;
 
@@ -345,6 +347,13 @@ public class Formatter implements Localized {
     private Warnings warnings;
 
     /**
+     * The locale for error messages (not for formatting).
+     *
+     * @see #locale
+     */
+    private final Locale errorLocale;
+
+    /**
      * Creates a new formatter instance with the default configuration.
      */
     public Formatter() {
@@ -364,6 +373,7 @@ public class Formatter implements Localized {
         ArgumentChecks.ensureNonNull("symbols",     symbols);
         ArgumentChecks.ensureBetween("indentation", WKTFormat.SINGLE_LINE, Byte.MAX_VALUE,
indentation);
         this.locale           = Locale.getDefault(Locale.Category.DISPLAY);
+        this.errorLocale      = locale;
         this.convention       = convention;
         this.authority        = convention.getNameAuthority();
         this.symbols          = symbols.immutable();
@@ -383,11 +393,19 @@ public class Formatter implements Localized {
     /**
      * Constructor for private use by {@link WKTFormat} only. This allows to use the number
format
      * created by {@link WKTFormat#createFormat(Class)}, which may be overridden by the user.
+     *
+     * @param  locale        the locale for the localization of international strings.
+     * @param  errorLocale   the locale for error messages (not for parsing), or {@code null}
for the system default.
+     * @param  symbols       the symbols to use for this formatter.
+     * @param  numberFormat  the object to use for formatting numbers.
+     * @param  dateFormat    the object to use for formatting dates.
+     * @param  unitFormat    the object to use for formatting unit symbols.
      */
-    Formatter(final Locale locale, final Symbols symbols, final NumberFormat numberFormat,
-            final DateFormat dateFormat, final UnitFormat unitFormat)
+    Formatter(final Locale locale, final Locale errorLocale, final Symbols symbols,
+              final NumberFormat numberFormat, final DateFormat dateFormat, final UnitFormat
unitFormat)
     {
         this.locale           = locale;
+        this.errorLocale      = errorLocale;
         this.convention       = Convention.DEFAULT;
         this.authority        = Convention.DEFAULT.getNameAuthority();
         this.symbols          = symbols;
@@ -662,12 +680,14 @@ public class Formatter implements Localized {
         final int stackDepth = enclosingElements.size();
         for (int i=stackDepth; --i >= 0;) {
             if (enclosingElements.get(i) == object) {
-                throw new IllegalStateException(Errors.getResources(locale).getString(Errors.Keys.CircularReference));
+                throw new IllegalStateException(Errors.getResources(errorLocale)
+                            .getString(Errors.Keys.CircularReference));
             }
         }
         enclosingElements.add(object);
         if (hasContextualUnit < 0) {                            // Test if leftmost bit
is set to 1.
-            throw new IllegalStateException(Errors.getResources(locale).getString(Errors.Keys.TreeDepthExceedsMaximum));
+            throw new IllegalStateException(Errors.getResources(errorLocale)
+                        .getString(Errors.Keys.TreeDepthExceedsMaximum));
         }
         hasContextualUnit <<= 1;
         /*
@@ -1741,7 +1761,7 @@ public class Formatter implements Localized {
      */
     private Warnings warnings() {
         if (warnings == null) {
-            warnings = new Warnings(locale, false, Collections.emptyMap());
+            warnings = new Warnings(errorLocale, false, Collections.emptyMap());
         }
         return warnings;
     }
@@ -1825,7 +1845,7 @@ public class Formatter implements Localized {
             if (colors != null) {
                 buffer.append(X364.BACKGROUND_RED.sequence()).append(X364.BOLD.sequence()).append('
');
             }
-            Vocabulary.getResources(locale).appendLabel(Vocabulary.Keys.Warnings, buffer);
+            Vocabulary.getResources(errorLocale).appendLabel(Vocabulary.Keys.Warnings, buffer);
             if (colors != null) {
                 buffer.append(' ').append(X364.RESET.sequence()).append(X364.FOREGROUND_RED.sequence());
             }
@@ -1833,7 +1853,7 @@ public class Formatter implements Localized {
             final int n = warnings.getNumMessages();
             final Set<String> done = new HashSet<>();
             for (int i=0; i<n; i++) {
-                String message = Exceptions.getLocalizedMessage(warnings.getException(i),
locale);
+                String message = Exceptions.getLocalizedMessage(warnings.getException(i),
errorLocale);
                 if (message == null) {
                     message = warnings.getMessage(i);
                 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
index 9c53c96..f9ab3e9 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
@@ -333,6 +333,19 @@ public class WKTFormat extends CompoundFormat<Object> {
     }
 
     /**
+     * Returns the locale to use for error messages. Other {@link CompoundFormat} classes
use the system default.
+     * But this class uses a compromise: not exactly the locale used for {@link InternationalString}
because that
+     * locale is often fixed to English, and not exactly the system default neither because
this "error locale"
+     * is also used for warnings. The compromise implemented in this method may change in
any future version.
+     *
+     * @see #errors()
+     */
+    private Locale getErrorLocale() {
+        final Locale locale = getLocale(Locale.Category.DISPLAY);
+        return (locale != null && locale != Locale.ROOT) ? locale : Locale.getDefault(Locale.Category.DISPLAY);
+    }
+
+    /**
      * Returns the symbols used for parsing and formatting WKT. This method returns an unmodifiable
instance.
      * Modifications, if desired, should be applied on a {@linkplain Symbols#clone() clone}
of the returned object.
      *
@@ -634,8 +647,7 @@ public class WKTFormat extends CompoundFormat<Object> {
             type != MathTransformFactory.class  &&
             type != CoordinateOperationFactory.class)
         {
-            throw new IllegalArgumentException(Errors.getResources(getLocale())
-                    .getString(Errors.Keys.IllegalArgumentValue_2, "type", type));
+            throw new IllegalArgumentException(errors().getString(Errors.Keys.IllegalArgumentValue_2,
"type", type));
         }
     }
 
@@ -751,7 +763,7 @@ public class WKTFormat extends CompoundFormat<Object> {
             final Element element = parseFragment(wkt, pos);
             final int index = CharSequences.skipLeadingWhitespaces(wkt, pos.getIndex(), wkt.length());
             if (index < wkt.length()) {
-                throw new UnparsableObjectException(getLocale(), Errors.Keys.UnexpectedCharactersAfter_2,
+                throw new UnparsableObjectException(getErrorLocale(), Errors.Keys.UnexpectedCharactersAfter_2,
                         new Object[] {name + " = " + element.keyword + "[…]", CharSequences.token(wkt,
index)}, index);
             }
             // `fragments` map has been created by `parser(true)`.
@@ -760,7 +772,7 @@ public class WKTFormat extends CompoundFormat<Object> {
             }
             error = Errors.Keys.ElementAlreadyPresent_1;
         }
-        throw new IllegalArgumentException(Errors.getResources(getLocale()).getString(error,
name));
+        throw new IllegalArgumentException(errors().getString(error, name));
     }
 
     /**
@@ -817,7 +829,7 @@ public class WKTFormat extends CompoundFormat<Object> {
                     (UnitFormat)   getFormat(Unit.class),
                     convention,
                     (transliterator != null) ? transliterator : Transliterator.DEFAULT,
-                    getLocale(),
+                    getErrorLocale(),
                     factories());
         }
         return parser;
@@ -879,7 +891,7 @@ public class WKTFormat extends CompoundFormat<Object> {
          */
         Formatter formatter = this.formatter;
         if (formatter == null) {
-            formatter = new Formatter(getLocale(), symbols,
+            formatter = new Formatter(getLocale(), getErrorLocale(), symbols,
                     (NumberFormat) getFormat(Number.class),
                     (DateFormat)   getFormat(Date.class),
                     (UnitFormat)   getFormat(Unit.class));
@@ -905,7 +917,7 @@ public class WKTFormat extends CompoundFormat<Object> {
                 warnings.setRoot(object);
             }
             if (!valid) {
-                throw new ClassCastException(Errors.getResources(getLocale()).getString(
+                throw new ClassCastException(errors().getString(
                         Errors.Keys.IllegalArgumentClass_2, "object", object.getClass()));
             }
             if (buffer != toAppendTo) {
@@ -956,6 +968,13 @@ public class WKTFormat extends CompoundFormat<Object> {
     }
 
     /**
+     * Convenience methods for resources for error message in the locale given by {@link
#getLocale()}.
+     */
+    private Errors errors() {
+        return Errors.getResources(getErrorLocale());
+    }
+
+    /**
      * Returns a clone of this format. The clone has the same configuration (including any
added
      * {@linkplain #addFragment fragments}), except the {@linkplain #getWarnings() warnings}.
      *
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
index 8af1cff..e81ed67 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/WKTFormatTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.io.wkt;
 
+import java.util.Locale;
 import java.util.Collections;
 import java.text.ParseException;
 import org.opengis.referencing.crs.VerticalCRS;
@@ -381,7 +382,7 @@ public final strictfp class WKTFormatTest extends TestCase {
     public void testWarnings() throws ParseException {
         DefaultPrimeMeridian pm = new DefaultPrimeMeridian(Collections.singletonMap(
                 DefaultPrimeMeridian.NAME_KEY, "Invalid “$name” here"), -10, Units.DEGREE);
-        format = new WKTFormat(null, null);
+        format = new WKTFormat(Locale.US, null);
         final String   wkt      = format.format(pm);
         final Warnings warnings = format.getWarnings();
         assertNotNull("warnings", warnings);
diff --git a/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java b/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
index 99f2bfe..e785fc4 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
@@ -226,8 +226,7 @@ public class StatisticsFormat extends TabularFormat<Statistics>
{
      */
     @Override
     public Statistics parse(CharSequence text, ParsePosition pos) throws ParseException {
-        throw new ParseException(Errors.getResources(getLocale())
-                .getString(Errors.Keys.UnsupportedOperation_1, "parse"), pos.getIndex());
+        throw new ParseException(Errors.format(Errors.Keys.UnsupportedOperation_1, "parse"),
pos.getIndex());
     }
 
     /**
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
b/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
index c00e883..d06e8af 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/collection/TreeTableFormat.java
@@ -340,9 +340,9 @@ public class TreeTableFormat extends TabularFormat<TreeTable> {
     }
 
     /**
-     * Returns the locale to use for code lists, international strings and exception messages.
+     * Returns the locale to use for code lists, international strings and localized messages
of exceptions.
      */
-    final Locale getDisplayLocale() {
+    private Locale getDisplayLocale() {
         return getLocale(Locale.Category.DISPLAY);
     }
 


Mime
View raw message