sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1685064 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-referencing/src/test/java/org/apache/sis/io/wkt/
Date Fri, 12 Jun 2015 11:14:29 GMT
Author: desruisseaux
Date: Fri Jun 12 11:14:29 2015
New Revision: 1685064

URL: http://svn.apache.org/r1685064
Log:
WKT: provide information about WKT problems in a dedicated 'Warnings' class instead than a
plain String.
The intend is to allow users to have programmatic access to the issues during WKT parsing
or formatting.

Added:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Parser.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1685064&r1=1685063&r2=1685064&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
[UTF-8] Fri Jun 12 11:14:29 2015
@@ -1424,7 +1424,7 @@ public class Formatter implements Locali
     }
 
     /**
-     * Marks the current WKT representation of the given object as not strictly compliant
to the WKT specification.
+     * Marks the current WKT representation of the given object as not strictly compliant
with the WKT specification.
      * This method can be invoked by implementations of {@link FormattableObject#formatTo(Formatter)}
when the object
      * to format is more complex than what the WKT specification allows.
      * Applications can test {@link #isInvalidWKT()} later for checking WKT validity.
@@ -1449,7 +1449,7 @@ public class Formatter implements Locali
     }
 
     /**
-     * Marks the current WKT representation of the given class as not strictly compliant
to the WKT specification.
+     * Marks the current WKT representation of the given class as not strictly compliant
with the WKT specification.
      * This method can be used as an alternative to {@link #setInvalidWKT(IdentifiedObject,
Exception)} when the
      * problematic object is not an instance of {@code IdentifiedObject}.
      *

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Parser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Parser.java?rev=1685064&r1=1685063&r2=1685064&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Parser.java [UTF-8]
(original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Parser.java [UTF-8]
Fri Jun 12 11:14:29 2015
@@ -28,13 +28,8 @@ import java.text.ParsePosition;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import org.opengis.util.FactoryException;
-import org.opengis.util.InternationalString;
 import org.apache.sis.util.Workaround;
-import org.apache.sis.util.Exceptions;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.resources.Vocabulary;
 import org.apache.sis.internal.metadata.WKTParser;
-import org.apache.sis.util.iso.AbstractInternationalString;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 
@@ -105,11 +100,10 @@ abstract class Parser implements WKTPars
     final Map<String, List<String>> ignoredElements;
 
     /**
-     * The first warning (other than {@link #ignoredElements}) that occurred during the parsing.
-     * Stored as an {@link InternationalString} in order to defer the actual message formatting
until needed.
-     * This is reset to {@code null} when a new parsing start.
+     * The warning (other than {@link #ignoredElements}) that occurred during the parsing.
+     * Created when first needed and reset to {@code null} when a new parsing start.
      */
-    private InternationalString warning;
+    private Warnings warnings;
 
     /**
      * Constructs a parser using the specified set of symbols.
@@ -180,7 +174,7 @@ abstract class Parser implements WKTPars
      * @throws ParseException if the string can not be parsed.
      */
     public Object parseObject(final String text, final ParsePosition position) throws ParseException
{
-        warning = null;
+        warnings = null;
         ignoredElements.clear();
         final Element element = new Element(new Element(this, text, position));
         final Object object = parseObject(element);
@@ -235,70 +229,28 @@ abstract class Parser implements WKTPars
      *
      * @param parent  The parent element.
      * @param keyword The element that we can not parse.
-     * @param ex      The non-fatal exception that occurred while parsing the element, or
{@code null} if none.
+     * @param ex      The non-fatal exception that occurred while parsing the element.
      */
     final void warning(final Element parent, final Element element, final Exception ex) {
-        if (warning == null) {
-            warning = new AbstractInternationalString() {
-                /**
-                 * Formats the error message only when requested.
-                 * In many cases, this method is never invoked.
-                 */
-                @Override
-                public String toString(final Locale locale) {
-                    CharSequence  text   = null;
-                    StringBuilder buffer = null;
-                    final Errors resources = Errors.getResources(locale);
-                    if (element != null) {  // Should be null only if 'warning' has been
invoked by 'getAndClearWarning'.
-                        text = resources.getString(Errors.Keys.UnparsableStringInElement_2,
parent.keyword, element.keyword);
-                        final String message = Exceptions.getLocalizedMessage(ex, locale);
-                        if (message != null) {
-                            text = buffer = new StringBuilder(text).append(' ').append(message);
-                        }
-                    }
-                    /*
-                     * If the parser has found some unknown elements, formats a bullet list
for them.
-                     */
-                    if (!ignoredElements.isEmpty()) {
-                        final String lineSeparator = System.lineSeparator();
-                        if (buffer == null) {
-                            buffer = new StringBuilder(250);
-                            if (text != null) {
-                                buffer.append(text).append(lineSeparator);
-                            }
-                            text = buffer;
-                        } else {
-                            buffer.append(lineSeparator);
-                        }
-                        final Vocabulary vocabulary = Vocabulary.getResources(locale);
-                        buffer.append(resources.getString(Errors.Keys.UnknownElementsInText));
-                        for (final Map.Entry<String, List<String>> entry : ignoredElements.entrySet())
{
-                            buffer.append(lineSeparator).append("  • ")
-                                    .append(vocabulary.getString(Vocabulary.Keys.Quoted_1,
entry.getKey()));
-                            String separator = vocabulary.getString(Vocabulary.Keys.InBetweenWords);
-                            for (final String p : entry.getValue()) {
-                                buffer.append(separator).append(p);
-                                separator = ", ";
-                            }
-                            buffer.append('.');
-                        }
-                    }
-                    return String.valueOf(text);
-                }
-            };
+        if (warnings == null) {
+            warnings = new Warnings(errorLocale, ignoredElements);
         }
+        warnings.add(null, ex, new String[] {parent.keyword, element.keyword});
     }
 
     /**
-     * Returns the warning, or {@code null} if none.
-     * This method clears the warning message after the call.
+     * Returns the warnings, or {@code null} if none.
+     * This method clears the warnings after the call.
+     *
+     * <p>The returned object is valid only until a new parsing starts. If a longer
lifetime is desired,
+     * then the callers <strong>must</strong> invoke {@link Warnings#publish()}.</p>
      */
-    final InternationalString getAndClearWarning() {
-        if (warning == null && !ignoredElements.isEmpty()) {
-            warning(null, null, null);  // Force the creation of the warning object.
+    final Warnings getAndClearWarnings() {
+        Warnings w = warnings;
+        warnings = null;
+        if (w == null && !ignoredElements.isEmpty()) {
+            w = new Warnings(errorLocale, ignoredElements);
         }
-        InternationalString m = warning;
-        warning = null;
-        return m;
+        return w;
     }
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1685064&r1=1685063&r2=1685064&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
[UTF-8] Fri Jun 12 11:14:29 2015
@@ -21,6 +21,7 @@ import java.util.Locale;
 import java.util.TimeZone;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.Collections;
 import java.io.IOException;
 import java.text.Format;
 import java.text.NumberFormat;
@@ -77,9 +78,15 @@ import org.apache.sis.util.resources.Err
  * PROJECTION[</code> <i>…etc…</i> <code>]]");</code></blockquote>
  * </div>
  *
- * <div class="section">Thread safety</div>
- * {@code WKTFormat}s are not synchronized. It is recommended to create separated format
instances for each thread.
- * If multiple threads access a {@code WKTFormat} concurrently, it must be synchronized externally.
+ * <div class="section">Limitations</div>
+ * <ul>
+ *   <li>Instances of this class are not synchronized for multi-threading.
+ *       It is recommended to create separated format instances for each thread.
+ *       If multiple threads access a {@code WKTFormat} concurrently, it must be synchronized
externally.</li>
+ *   <li>Serialized objects of this class are not guaranteed to be compatible with
future Apache SIS releases.
+ *       Serialization support is appropriate for short term storage or RMI between applications
running the
+ *       same version of Apache SIS.</li>
+ * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Rémi Eve (IRD)
@@ -188,16 +195,14 @@ public class WKTFormat extends CompoundF
 
     /**
      * The warning produced by the last parsing or formatting operation, or {@code null}
if none.
-     * Stored as an {@link InternationalString} in order to defer the actual message formatting
until needed.
      *
-     * @see #getWarning()
+     * @see #getWarnings()
      */
-    private transient InternationalString warning;
+    private transient Warnings warnings;
 
     /**
      * Creates a format for the given locale and timezone. The given locale will be used
for
-     * {@link org.opengis.util.InternationalString} localization; this is <strong>not</strong>
-     * the locale for number format.
+     * {@link InternationalString} localization; this is <strong>not</strong>
the locale for number format.
      *
      * @param locale   The locale for the new {@code Format}, or {@code null} for {@code
Locale.ROOT}.
      * @param timezone The timezone, or {@code null} for UTC.
@@ -217,7 +222,7 @@ public class WKTFormat extends CompoundF
      *   <li>{@link java.util.Locale.Category#FORMAT}: the value of {@link Symbols#getLocale()},
      *       normally fixed to {@link Locale#ROOT}, used for number formatting.</li>
      *   <li>{@link java.util.Locale.Category#DISPLAY}: the {@code locale} given at
construction time,
-     *       used for {@link org.opengis.util.InternationalString} localization.</li>
+     *       used for {@link InternationalString} localization.</li>
      * </ul>
      *
      * @param  category The category for which a locale is desired.
@@ -508,6 +513,7 @@ public class WKTFormat extends CompoundF
      */
     @Override
     public Object parse(final CharSequence text, final ParsePosition pos) throws ParseException
{
+        warnings = null;
         ArgumentChecks.ensureNonNull("text", text);
         ArgumentChecks.ensureNonNull("pos",  pos);
         Parser parser = this.parser;
@@ -523,7 +529,7 @@ public class WKTFormat extends CompoundF
         try {
             return parser.parseObject(text.toString(), pos);
         } finally {
-            warning = parser.getAndClearWarning();
+            warnings = parser.getAndClearWarnings();
         }
     }
 
@@ -544,6 +550,7 @@ public class WKTFormat extends CompoundF
      */
     @Override
     public void format(final Object object, final Appendable toAppendTo) throws IOException
{
+        warnings = null;
         ArgumentChecks.ensureNonNull("object",     object);
         ArgumentChecks.ensureNonNull("toAppendTo", toAppendTo);
         /*
@@ -571,6 +578,7 @@ public class WKTFormat extends CompoundF
             this.formatter = formatter;
         }
         final boolean valid;
+        final InternationalString warning;
         try {
             formatter.setBuffer(buffer);
             valid = formatter.appendElement(object) || formatter.appendValue(object);
@@ -579,6 +587,10 @@ public class WKTFormat extends CompoundF
             formatter.setBuffer(null);
             formatter.clear();
         }
+        if (warning != null) {
+            warnings = new Warnings(getLocale(), Collections.emptyMap());
+            warnings.add(warning, formatter.getErrorCause(), null);
+        }
         if (!valid) {
             throw new ClassCastException(Errors.format(
                     Errors.Keys.IllegalArgumentClass_2, "object", object.getClass()));
@@ -611,14 +623,34 @@ public class WKTFormat extends CompoundF
     }
 
     /**
+     * If warnings occurred during the last WKT {@linkplain #parse(CharSequence, ParsePosition)
parsing} or
+     * {@linkplain #format(Object, Appendable) formatting}, returns the warnings. Otherwise
returns {@code null}.
+     * The warnings are cleared every time a new object is parsed or formatted.
+     *
+     * @return The warnings of the last parsing of formatting operation, or {@code null}
if none.
+     *
+     * @since 0.6
+     */
+    public Warnings getWarnings() {
+        final Warnings w = warnings;
+        if (w != null) {
+            w.publish();
+        }
+        return w;
+    }
+
+    /**
      * If a warning occurred during the last WKT {@linkplain #parse(CharSequence, ParsePosition)
parsing} or
      * {@linkplain #format(Object, Appendable) formatting}, returns the warning. Otherwise
returns {@code null}.
      * The warning is cleared every time a new object is parsed or formatted.
      *
      * @return The last warning, or {@code null} if none.
+     *
+     * @deprecated Replaced by {@link #getWarnings()}.
      */
+    @Deprecated
     public String getWarning() {
-        return (warning != null) ? warning.toString(getLocale()) : null;
+        return (warnings != null) ? warnings.toString() : null;
     }
 
     /**
@@ -630,7 +662,8 @@ public class WKTFormat extends CompoundF
     public WKTFormat clone() {
         final WKTFormat clone = (WKTFormat) super.clone();
         clone.formatter = null; // Do not share the formatter.
-        clone.parser = null;
+        clone.parser    = null;
+        clone.warnings  = null;
         return clone;
     }
 }

Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java?rev=1685064&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
(added)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
[UTF-8] Fri Jun 12 11:14:29 2015
@@ -0,0 +1,288 @@
+/*
+ * 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.sis.io.wkt;
+
+import java.util.Locale;
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Iterator;
+import java.io.Serializable;
+import org.opengis.util.InternationalString;
+import org.apache.sis.util.Exceptions;
+import org.apache.sis.util.Localized;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.resources.Vocabulary;
+
+
+/**
+ * Warnings that occurred during a <cite>Well Known Text</cite> (WKT) parsing
or formatting.
+ * Some example of information provided by this object are:
+ *
+ * <ul>
+ *   <li>Recoverable exceptions.</li>
+ *   <li>At formatting time, object that can not be formatted in a standard-compliant
WKT.</li>
+ *   <li>At parsing time, unknown keywords.</li>
+ * </ul>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ *
+ * @see WKTFormat#getWarnings()
+ */
+public final class Warnings implements Localized, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -1825161781642905329L;
+
+    /**
+     * The locale in which warning messages are reported.
+     * Not necessarily the same than the locale for number and date parsing or formating.
+     *
+     * @see #getLocale()
+     */
+    private final Locale errorLocale;
+
+    /**
+     * Warning messages or exceptions emitted during parsing or formatting.
+     * Initially {@code null} and created when first needed.
+     *
+     * <p>Objects in this list must be a sequence of the following tupple:</p>
+     *
+     * <ul>
+     *   <li>An optional message as an {@link InternationalString}.</li>
+     *   <li>An optional warning cause as an {@link Exception}.</li>
+     * </ul>
+     *
+     * Any element of the above tupple can be null, but at least one element must be non-null.
+     *
+     * @see #add(InternationalString, Exception, String[])
+     */
+    private List<Object> messages;
+
+    /**
+     * The keywords of elements in which exception occurred.
+     * Initially {@code null} and created when first needed.
+     *
+     * <p>For each {@code String[]} value, the first array element shall be the keyword
of the WKT element
+     * in which the exception occurred. The second array element shall be the parent of above-cited
first
+     * element. Other array elements can optionally be present for declaring the parents
of the parent,
+     * but they will be ignored by this {@code Warnings} implementation.</p>
+     */
+    private Map<Exception, String[]> exceptionSources;
+
+    /**
+     * Keyword of unknown elements. This is initially a direct reference to the {@link Parser#ignoredElements}
map,
+     * which is okay only until a new parsing start. If this {@code Warnings} instance is
given to the user, then
+     * the {@link #publish()} method must be invoked in order to copy this map.
+     *
+     * @see Parser#ignoredElements
+     */
+    private Map<String, List<String>> ignoredElements;
+
+    /**
+     * {@code true} if {@link #publish()} has been invoked.
+     */
+    private boolean published;
+
+    /**
+     * Creates a new object for declaring warnings.
+     *
+     * @param locale The locale for reporting warning messages.
+     * @param ignoredElements The {@link Parser#ignoredElements} map, or an empty map (can
not be null).
+     */
+    Warnings(final Locale locale, final Map<String, List<String>> ignoredElements)
{
+        this.errorLocale     = locale;
+        this.ignoredElements = ignoredElements;
+    }
+
+    /**
+     * Must be invoked before this {@code Warnings} instance is given to the user,
+     * in order to protect this instance from changes caused by the next parsing operation.
+     */
+    final void publish() {
+        if (!published) {
+            ignoredElements = ignoredElements.isEmpty() ? Collections.emptyMap() : new LinkedHashMap<>(ignoredElements);
+            published = true;
+        }
+    }
+
+    /**
+     * Returns the locale in which warning messages are reported by the default {@link #toString()}
method.
+     * This is not necessarily the same locale than the one used for parsing and formatting
dates and numbers
+     * in the WKT.
+     *
+     * @return The locale or warning messages are reported.
+     */
+    @Override
+    public Locale getLocale() {
+        return errorLocale;
+    }
+
+    /**
+     * Adds a warning. At least one of {@code message} or {@code cause} shall be non-null.
+     *
+     * @param message The message, or {@code null}.
+     * @param cause   The exception that caused the warning, or {@code null}
+     * @param source  The location of the exception, or {@code null}. If non-null, then {@code
source[0]} shall be
+     *                the keyword of the WKT element where the exception occurred, and {@code
source[1]} the keyword
+     *                of the parent of {@code source[0]}.
+     */
+    final void add(final InternationalString message, final Exception cause, final String[]
source) {
+        assert (message != null) || (cause != null);
+        if (messages == null) {
+            messages = new ArrayList<>(4);  // We expect few items.
+        }
+        messages.add(message);
+        messages.add(cause);
+        if (cause != null) {
+            if (exceptionSources == null) {
+                exceptionSources = new LinkedHashMap<>(4);  // We expect few items.
+            }
+            exceptionSources.put(cause, source);
+        }
+    }
+
+    /**
+     * Returns the non-fatal exceptions that occurred during the parsing or formatting.
+     * If no exception occurred, then returns an empty set.
+     *
+     * @return The non-fatal exceptions that occurred.
+     */
+    public Set<Exception> getExceptions() {
+        return (exceptionSources != null) ? exceptionSources.keySet() : Collections.emptySet();
+    }
+
+    /**
+     * Returns the keywords of the WKT element where the given exception occurred, or {@code
null} if unknown.
+     * If this method returns a non-null array, then {@code source[0]} is the keyword of
the WKT element where
+     * the exception occurred and {@code source[1]} is the keyword of the parent of {@code
source[0]}.
+     *
+     * <div class="note"><b>Note:</b>
+     * in other words, this method returns the tail of the path to the WKT element where
the exception occurred,
+     * but with path elements stored in reverse order.
+     * </div>
+     *
+     * @param  ex The exception for which to get the source.
+     * @return The keywords of the WKT element where the given exception occurred, or {@code
null} if unknown.
+     */
+    public String[] getExceptionSource(final Exception ex) {
+        return (exceptionSources != null) ? exceptionSources.get(ex) : null;
+    }
+
+    /**
+     * Returns the keywords of all unknown elements found during the WKT parsing.
+     *
+     * @return The keywords of unknown WKT elements, or an empty set if none.
+     */
+    public Set<String> getUnknownElements() {
+        return ignoredElements.keySet();
+    }
+
+    /**
+     * Returns the keyword of WKT elements that contains the given unknown element.
+     * If the given element is not one of the value returned by {@link #getUnknownElements()},
+     * then this method returns {@code null}.
+     *
+     * <p>The returned collection elements are in no particular order.</p>
+     *
+     * @param element The keyword of the unknown element.
+     * @return The keywords of elements where the given unknown element was found.
+     */
+    public Collection<String> getUnknownElementLocations(final String element) {
+        return ignoredElements.get(element);
+    }
+
+    /**
+     * Returns a string representation of the warning messages if the default locale.
+     * The locale used by this method is given by {@link #getLocale()}.
+     * This is usually the locale given to the {@link WKTFormat} constructor.
+     *
+     * @return A string representation of the warning messages.
+     */
+    @Override
+    public String toString() {
+        return toString(errorLocale);
+    }
+
+    /**
+     * Returns a string representation of the warning messages in the given locale.
+     * This method formats the warnings in a bullet list.
+     *
+     * @param  locale The locale to use for formatting warning messages.
+     * @return A string representation of the warning messages.
+     */
+    public String toString(final Locale locale) {
+        final StringBuilder buffer = new StringBuilder(250);
+        final String lineSeparator = System.lineSeparator();
+        final Errors resources = Errors.getResources(locale);
+        if (messages != null) {
+            for (final Iterator<?> it = messages.iterator(); it.hasNext();) {
+                InternationalString i18n = (InternationalString) it.next();
+                Exception cause = (Exception) it.next();
+                final String message;
+                if (i18n != null) {
+                    message = i18n.toString(locale);
+                } else {
+                    /*
+                     * If there is no message, then we must have at least one exception.
+                     * Consequently a NullPointerException below would be a bug.
+                     */
+                    final String[] sources = exceptionSources.get(cause);
+                    if (sources != null) {
+                        message = resources.getString(Errors.Keys.UnparsableStringInElement_2,
sources);
+                    } else {
+                        message = cause.toString();
+                        cause = null;
+                    }
+                }
+                buffer.append(" • ").append(message).append(lineSeparator);
+                if (cause != null) {
+                    String details = Exceptions.getLocalizedMessage(cause, locale);
+                    if (details == null) {
+                        details = cause.toString();
+                    }
+                    buffer.append("   ").append(details).append(lineSeparator);
+                }
+            }
+        }
+        /*
+         * If the parser found some unknown elements, formats an enclosed bullet list for
them.
+         */
+        if (!ignoredElements.isEmpty()) {
+            final Vocabulary vocabulary = Vocabulary.getResources(locale);
+            buffer.append(" • ").append(resources.getString(Errors.Keys.UnknownElementsInText)).append(lineSeparator);
+            for (final Map.Entry<String, List<String>> entry : ignoredElements.entrySet())
{
+                buffer.append("    ‣ ").append(vocabulary.getString(Vocabulary.Keys.Quoted_1,
entry.getKey()));
+                String separator = vocabulary.getString(Vocabulary.Keys.InBetweenWords);
+                for (final String p : entry.getValue()) {
+                    buffer.append(separator).append(p);
+                    separator = ", ";
+                }
+                buffer.append('.').append(lineSeparator);
+            }
+        }
+        return buffer.toString();
+    }
+}

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1685064&r1=1685063&r2=1685064&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
[UTF-8] Fri Jun 12 11:14:29 2015
@@ -25,7 +25,6 @@ import javax.measure.unit.SI;
 import javax.measure.unit.NonSI;
 import javax.measure.unit.Unit;
 import javax.measure.quantity.Length;
-import org.opengis.util.InternationalString;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
@@ -80,7 +79,7 @@ public final strictfp class GeodeticObje
         final Object obj = parser.parseObject(text, position);
         assertEquals("errorIndex", -1, position.getErrorIndex());
         assertEquals("index", text.length(), position.getIndex());
-        assertNull("warning", parser.getAndClearWarning());
+        assertNull("warnings", parser.getAndClearWarnings());
         assertTrue("ignoredElements", parser.ignoredElements.isEmpty());
         assertInstanceOf("GeodeticObjectParser.parseObject", type, obj);
         return type.cast(obj);
@@ -626,13 +625,13 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Tests the production of a warning message when the WKT contains unknown elements.
+     * Tests the production of a warning messages when the WKT contains unknown elements.
      *
      * @throws ParseException if the parsing failed.
      */
     @Test
     @DependsOnMethod("testWithImplicitAxes")
-    public void testWarningMessage() throws ParseException {
+    public void testWarnings() throws ParseException {
         parser = new GeodeticObjectParser();
         final ParsePosition position = new ParsePosition(0);
         verifyGeographicCRS(0, (GeographicCRS) parser.parseObject(
@@ -643,11 +642,36 @@ public final strictfp class GeodeticObje
                "    UNIT[“degree”, 0.017453292519943295], Intruder[“foo”]]", position));
 
         assertEquals("errorIndex", -1, position.getErrorIndex());
-        final InternationalString warning = parser.getAndClearWarning();
-        assertNotNull("warning", warning);
-        assertMultilinesEquals("The text contains unknown elements:\n" +
-                               "  • “Intruder” in PRIMEM, GEOGCS.\n" +
-                               "  • “Ext1” in SPHEROID.\n" +
-                               "  • “Ext2” in SPHEROID.", warning.toString(Locale.ENGLISH));
+        final Warnings warnings = parser.getAndClearWarnings();
+        assertNotNull("warnings", warnings);
+
+        assertTrue("warnings.getExceptions()",
+                warnings.getExceptions().isEmpty());
+
+        assertArrayEquals("warnings.getUnknownElements()",
+                new String[] {"Intruder", "Ext1", "Ext2"},
+                warnings.getUnknownElements().toArray());
+
+        assertArrayEquals("warnings.getUnknownElementLocations(…)",
+                new String[] {"PRIMEM", "GEOGCS"},
+                warnings.getUnknownElementLocations("Intruder").toArray());
+
+        assertArrayEquals("warnings.getUnknownElementLocations(…)",
+                new String[] {"SPHEROID"},
+                warnings.getUnknownElementLocations("Ext1").toArray());
+
+        assertArrayEquals("warnings.getUnknownElementLocations(…)",
+                new String[] {"SPHEROID"},
+                warnings.getUnknownElementLocations("Ext2").toArray());
+
+        assertMultilinesEquals(" • The text contains unknown elements:\n" +
+                               "    ‣ “Intruder” in PRIMEM, GEOGCS.\n" +
+                               "    ‣ “Ext1” in SPHEROID.\n" +
+                               "    ‣ “Ext2” in SPHEROID.\n", warnings.toString(Locale.US));
+
+        assertMultilinesEquals(" • Le texte contient des éléments inconnus :\n" +
+                               "    ‣ « Intruder » dans PRIMEM, GEOGCS.\n"
+
+                               "    ‣ « Ext1 » dans SPHEROID.\n" +
+                               "    ‣ « Ext2 » dans SPHEROID.\n", warnings.toString(Locale.FRANCE));
     }
 }



Mime
View raw message