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 84001f14e4e32649114612a68aadc7ee4367c08f Author: Martin Desruisseaux <[email protected]> AuthorDate: Thu Nov 19 12:29:14 2020 +0100 Log warnings during WKT parsing by `WKTDictionary`. --- .../java/org/apache/sis/io/wkt/AbstractParser.java | 9 +++++ .../java/org/apache/sis/io/wkt/WKTDictionary.java | 3 ++ .../main/java/org/apache/sis/io/wkt/WKTFormat.java | 42 +++++++++++++++++----- .../main/java/org/apache/sis/io/wkt/Warnings.java | 3 +- 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java index 74196b9..b0ce14f 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/AbstractParser.java @@ -268,12 +268,18 @@ abstract class AbstractParser implements Parser { * Caller should invoke {@link #getAndClearWarnings(Object)} in a {@code finally} block * after this method and should decide what to do with remaining character at the end of the string. * + * <p>If this method is invoked from {@link WKTFormat}, then {@link WKTFormat#clear()} + * should be invoked before this method for making sure that no {@link Warnings} instance + * is referencing {@link #ignoredElements}.</p> + * * @param text the Well-Known Text (WKT) to parse. * @param position index of the first character to parse (on input) or after last parsed character (on output). * @return the parsed object. * @throws ParseException if the string can not be parsed. */ Object createFromWKT(final String text, final ParsePosition position) throws ParseException { + warnings = null; + ignoredElements.clear(); final Element root = new Element(textToTree(text, position)); final Object result = buildFromTree(root); root.close(ignoredElements); @@ -335,6 +341,9 @@ abstract class AbstractParser implements Parser { * Subclasses will typically get the name of the first element and delegate to a specialized method * such as {@code parseAxis(…)}, {@code parseEllipsoid(…)}, {@code parseTimeDatum(…)}, <i>etc</i>. * + * <p>Callers should clear {@link #ignoredElements} before to invoke this method. + * Cleaning {@link #warnings} can be done for safety but should not be necessary.</p> + * * @param element the element to be parsed. * @return the parsed object. * @throws ParseException if the element can not be parsed. diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java index 854ed10..7ddff94 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/WKTDictionary.java @@ -572,6 +572,7 @@ public class WKTDictionary extends GeodeticAuthorityFactory { } } addAliasOrDefinition(); + parser.logWarnings(WKTDictionary.class, "load"); } /** @@ -687,6 +688,7 @@ public class WKTDictionary extends GeodeticAuthorityFactory { pos.setIndex(0); lineNumber++; } + parser.logWarnings(WKTDictionary.class, "addDefinitions"); } catch (ParseException | IllegalArgumentException e) { throw new FactoryDataException(resources().getString( Resources.Keys.CanNotParseWKT_2, lineNumber, e.getLocalizedMessage())); @@ -984,6 +986,7 @@ public class WKTDictionary extends GeodeticAuthorityFactory { ParseException cause = null; try { value = parser.buildFromTree((StoredTree) value); + parser.logWarnings(WKTDictionary.class, "createObject"); // `createObject` is the public facade. } catch (ParseException e) { cause = e; value = e.getLocalizedMessage(); 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 a8d5f7c..7d87093 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 @@ -26,6 +26,8 @@ import java.util.TreeMap; import java.util.List; import java.util.ArrayList; import java.util.Collections; +import java.util.logging.Level; +import java.util.logging.LogRecord; import java.io.IOException; import java.text.Format; import java.text.NumberFormat; @@ -47,6 +49,8 @@ import org.apache.sis.measure.UnitFormat; import org.apache.sis.util.CharSequences; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.resources.Errors; +import org.apache.sis.util.logging.Logging; +import org.apache.sis.internal.system.Loggers; import org.apache.sis.internal.util.Constants; import org.apache.sis.internal.util.StandardDateFormat; import org.apache.sis.internal.referencing.ReferencingFactoryContainer; @@ -771,6 +775,7 @@ public class WKTFormat extends CompoundFormat<Object> { new Object[] {name + " = " + definition.keyword() + "[…]", CharSequences.token(wkt, index)}, index); } addFragment(name, definition); + logWarnings(WKTFormat.class, "addFragment"); } /** @@ -805,7 +810,7 @@ public class WKTFormat extends CompoundFormat<Object> { final StoredTree textToTree(final String wkt, final ParsePosition pos, final String aliasKey) throws ParseException { final AbstractParser parser = parser(true); final List<Element> results = new ArrayList<>(4); - warnings = null; + warnings = null; // Do not invoke `clear()` because we do not want to clear `sharedValues` map. try { for (;;) { results.add(parser.textToTree(wkt, pos)); @@ -821,6 +826,7 @@ public class WKTFormat extends CompoundFormat<Object> { pos.setIndex(p + separator.length()); } } finally { + // Invoked as a matter of principle, but no warning is expected at this stage. warnings = parser.getAndClearWarnings(results.isEmpty() ? null : results.get(0)); } if (sharedValues == null) { @@ -879,6 +885,7 @@ public class WKTFormat extends CompoundFormat<Object> { final Object buildFromTree(StoredTree tree) throws ParseException { clear(); final AbstractParser parser = parser(false); + parser.ignoredElements.clear(); final SingletonElement singleton = new SingletonElement(); tree.toElements(parser, singleton, 0); final Element root = new Element(singleton.value); @@ -1041,11 +1048,28 @@ public class WKTFormat extends CompoundFormat<Object> { * @since 0.6 */ public Warnings getWarnings() { - final Warnings w = warnings; - if (w != null) { - w.publish(); + if (warnings != null) { + warnings.publish(); + } + return warnings; + } + + /** + * If a warning occurred, logs it. + * + * @param classe the class to report as the source of the logging message. + * @param method the method to report as the source of the logging message. + */ + final void logWarnings(final Class<?> classe, final String method) { + if (warnings != null) { + /* + * We can avoid the call to `Warnings.publish()` because we know that we are not keeping a + * reference for long, so we do not need to copy the `AbstractParser.ignoredElements` map. + */ + final LogRecord record = new LogRecord(Level.WARNING, warnings.toString()); + record.setLoggerName(Loggers.WKT); + Logging.log(classe, method, record); } - return w; } /** @@ -1065,10 +1089,10 @@ public class WKTFormat extends CompoundFormat<Object> { public WKTFormat clone() { final WKTFormat clone = (WKTFormat) super.clone(); clone.clear(); - clone.factories = null; // Not thread-safe; clone needs its own. - clone.formatter = null; // Do not share the formatter. - clone.parser = null; - clone.isCloned = isCloned = true; + clone.factories = null; // Not thread-safe; clone needs its own. + clone.formatter = null; // Do not share the formatter. + clone.parser = null; + clone.isCloned = isCloned = true; // Symbols and Colors do not need to be cloned because they are flagged as immutable. return clone; } diff --git a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Warnings.java b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Warnings.java index f7ab6f9..937a009 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Warnings.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Warnings.java @@ -327,9 +327,8 @@ public final class Warnings implements Localized, Serializable { } /** - * Returns a string representation of the warning messages in the default locale. + * Returns a string representation of the warning messages in the formatter 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. */
