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
The following commit(s) were added to refs/heads/geoapi-4.0 by this push: new 09203d6078 Fix broken error highlighting in WKT formatter. The problem was when an axis direction has illegal characters. 09203d6078 is described below commit 09203d60781a6810d38e3c7024e64c027f0587d4 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Thu Dec 14 12:33:19 2023 +0100 Fix broken error highlighting in WKT formatter. The problem was when an axis direction has illegal characters. --- .../apache/sis/console/FormattedOutputCommand.java | 7 ++++ .../main/org/apache/sis/io/wkt/Formatter.java | 37 ++++++++++------------ .../main/org/apache/sis/io/wkt/WKTFormat.java | 12 ++++++- .../main/org/apache/sis/io/wkt/package-info.java | 2 +- .../sis/parameter/DefaultParameterValue.java | 1 + .../sis/referencing/crs/DefaultGeodeticCRS.java | 1 + .../cs/DefaultCoordinateSystemAxis.java | 6 ++-- .../sis/referencing/datum/DefaultEllipsoid.java | 1 + .../test/org/apache/sis/io/wkt/FormatterTest.java | 11 ------- 9 files changed, 41 insertions(+), 37 deletions(-) diff --git a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/FormattedOutputCommand.java b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/FormattedOutputCommand.java index e65fd49cce..3f15750b64 100644 --- a/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/FormattedOutputCommand.java +++ b/endorsed/src/org.apache.sis.console/main/org/apache/sis/console/FormattedOutputCommand.java @@ -29,6 +29,7 @@ import org.opengis.util.FactoryException; import org.apache.sis.io.wkt.WKTFormat; import org.apache.sis.io.wkt.Convention; import org.apache.sis.io.wkt.Colors; +import org.apache.sis.io.wkt.Warnings; import org.apache.sis.metadata.MetadataStandard; import org.apache.sis.metadata.ValueExistencePolicy; import org.apache.sis.referencing.CRS; @@ -236,6 +237,12 @@ abstract class FormattedOutputCommand extends CommandRunner { } f.format(object, out); out.println(); + final Warnings warnings = f.getWarnings(); + if (warnings != null) { + out.flush(); + err.println(); + err.println(warnings.toString(locale)); + } break; } diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java index 331581d591..7d897f820d 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/Formatter.java @@ -129,18 +129,6 @@ public class Formatter implements Localized { @Configuration private static final int VERTICAL_ACCURACY = 9; - /** - * The value of {@code X364.FOREGROUND_DEFAULT.sequence()}, hard-coded for avoiding - * {@link org.apache.sis.util.internal.X364} class loading. - */ - static final String FOREGROUND_DEFAULT = "\u001B[39m"; - - /** - * The value of {@code X364.BACKGROUND_DEFAULT.sequence()}, hard-coded for avoiding - * {@link org.apache.sis.util.internal.X364} class loading. - */ - static final String BACKGROUND_DEFAULT = "\u001B[49m"; - /** * The locale for the localization of international strings. * This is not the same than {@link Symbols#getLocale()}. @@ -543,11 +531,16 @@ public class Formatter implements Localized { /** * Appends in the {@linkplain #buffer} the ANSI escape sequence for resetting the color to the default. * This method does nothing unless syntax coloring has been explicitly enabled. + * + * <h4>Implementation note</h4> + * This method needs to reset not only the foreground, but also the background if the + * {@link #highlightError} flag is {@code true}. It is simpler to just use the "reset" + * sequence unconditionally for the current implementation. */ private void resetColor() { if (colors != null && --colorApplied <= 0) { colorApplied = 0; - buffer.append(FOREGROUND_DEFAULT); + buffer.append(X364.RESET.sequence()); } } @@ -627,8 +620,8 @@ public class Formatter implements Localized { } appendSeparator(); if (toUpperCase != 0) { - final Locale locale = symbols.getLocale(); - keyword = (toUpperCase >= 0) ? keyword.toUpperCase(locale) : keyword.toLowerCase(locale); + final Locale syntax = symbols.getLocale(); // Not the same purpose as `this.locale`. + keyword = (toUpperCase >= 0) ? keyword.toUpperCase(syntax) : keyword.toLowerCase(syntax); } elementStart = buffer.append(keyword).appendCodePoint(symbols.getOpeningBracket(0)).length(); } @@ -719,13 +712,13 @@ public class Formatter implements Localized { } keyword = getName(object.getClass()); } else if (toUpperCase != 0) { - final Locale locale = symbols.getLocale(); - keyword = (toUpperCase >= 0) ? keyword.toUpperCase(locale) : keyword.toLowerCase(locale); + final Locale syntax = symbols.getLocale(); // Not the same purpose as `this.locale`. + keyword = (toUpperCase >= 0) ? keyword.toUpperCase(syntax) : keyword.toLowerCase(syntax); } if (highlightError && colors != null) { final String color = colors.getAnsiSequence(ElementKind.ERROR); if (color != null) { - buffer.insert(base, color + BACKGROUND_DEFAULT); + buffer.insert(base, color + X364.BACKGROUND_DEFAULT.sequence()); base += color.length(); } } @@ -1174,8 +1167,9 @@ public class Formatter implements Localized { buffer.append(name); resetColor(); } else { - quote(name, ElementKind.CODE_LIST); + quote(name, ElementKind.ERROR); setInvalidWKT(code.getClass(), null); + highlightError = false; // Because already highlighted. } } } @@ -1413,7 +1407,7 @@ public class Formatter implements Localized { private void appendExact(final double number) { if (Locale.ROOT.equals(symbols.getLocale())) { appendSeparator(); - setColor(highlightError ? ElementKind.ERROR : ElementKind.NUMBER); + setColor(ElementKind.NUMBER); final int i = (int) number; if (i == number) { buffer.append(i); @@ -1424,7 +1418,6 @@ public class Formatter implements Localized { } else { append(number); } - highlightError = false; } /** @@ -1854,8 +1847,10 @@ public class Formatter implements Localized { * If this method is invoked, then it shall be the last method before {@link #toWKT()}. */ final void appendWarnings() throws IOException { + @SuppressWarnings("LocalVariableHidesMemberVariable") final Warnings warnings = this.warnings; // Protect against accidental changes. if (warnings != null) { + @SuppressWarnings("LocalVariableHidesMemberVariable") final StringBuffer buffer = this.buffer; final String ln = System.lineSeparator(); buffer.append(ln).append(ln); diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java index 880b64f08a..cc7047cc0f 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/WKTFormat.java @@ -49,6 +49,7 @@ import org.apache.sis.io.CompoundFormat; import org.apache.sis.measure.UnitFormat; import org.apache.sis.util.CharSequences; import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.OptionalCandidate; import org.apache.sis.util.logging.Logging; import org.apache.sis.util.resources.Errors; import org.apache.sis.system.Loggers; @@ -845,6 +846,7 @@ public class WKTFormat extends CompoundFormat<Object> { * @return root of the tree of elements. */ final StoredTree textToTree(final String wkt, final ParsePosition pos, final String aliasKey) throws ParseException { + @SuppressWarnings("LocalVariableHidesMemberVariable") final AbstractParser parser = parser(true); final List<Element> results = new ArrayList<>(4); warnings = null; // Do not invoke `clear()` because we do not want to clear `sharedValues` map. @@ -900,6 +902,8 @@ public class WKTFormat extends CompoundFormat<Object> { clear(); ArgumentChecks.ensureNonEmpty("wkt", wkt); ArgumentChecks.ensureNonNull ("pos", pos); + + @SuppressWarnings("LocalVariableHidesMemberVariable") final AbstractParser parser = parser(false); Object result = null; try { @@ -921,6 +925,7 @@ public class WKTFormat extends CompoundFormat<Object> { */ final Object buildFromTree(StoredTree tree) throws ParseException { clear(); + @SuppressWarnings("LocalVariableHidesMemberVariable") final AbstractParser parser = parser(false); parser.ignoredElements.clear(); final SingletonElement singleton = new SingletonElement(); @@ -942,6 +947,7 @@ public class WKTFormat extends CompoundFormat<Object> { * @param modifiable whether the caller intents to modify the {@link #fragments} map. */ private AbstractParser parser(final boolean modifiable) { + @SuppressWarnings("LocalVariableHidesMemberVariable") AbstractParser parser = this.parser; /* * `parser` is always null on a fresh clone. However, the `fragments` @@ -1027,6 +1033,7 @@ public class WKTFormat extends CompoundFormat<Object> { /* * Creates the Formatter when first needed. */ + @SuppressWarnings("LocalVariableHidesMemberVariable") Formatter formatter = this.formatter; if (formatter == null) { formatter = new Formatter(getLocale(), getErrorLocale(), symbols, @@ -1097,6 +1104,7 @@ public class WKTFormat extends CompoundFormat<Object> { * * @since 0.6 */ + @OptionalCandidate public Warnings getWarnings() { if (warnings != null) { warnings.publish(); @@ -1105,7 +1113,9 @@ public class WKTFormat extends CompoundFormat<Object> { } /** - * If a warning occurred, logs it. + * If a warning occurred, logs it. This method is invoked when a WKT was parsed or formatted + * in another context than a call to a {@code parse(…)} or {@code format(…)} method. + * For example it may be during the build of {@link WKTDictionary}. * * @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. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/package-info.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/package-info.java index 61d05c15c5..107b6d4044 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/package-info.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/io/wkt/package-info.java @@ -83,7 +83,7 @@ * @author Martin Desruisseaux (IRD, Geomatys) * @author Rémi Eve (IRD) * @author Rueben Schulz (UBC) - * @version 1.4 + * @version 1.5 * * @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> diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java index d7242c6d1c..d9817c7107 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/parameter/DefaultParameterValue.java @@ -993,6 +993,7 @@ convert: if (componentType != null) { * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#119">WKT 2 specification §17.2.4</a> */ @Override + @SuppressWarnings("LocalVariableHidesMemberVariable") protected String formatTo(final Formatter formatter) { final ParameterDescriptor<T> descriptor = getDescriptor(); // Gives to users a chance to override this property. WKTUtilities.appendName(descriptor, formatter, ElementKind.PARAMETER); diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java index 1dede43059..7aa712d54f 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/crs/DefaultGeodeticCRS.java @@ -194,6 +194,7 @@ class DefaultGeodeticCRS extends AbstractCRS implements GeodeticCRS { // If made * The prime meridian is part of datum according ISO 19111, but is formatted * as a sibling (rather than a child) element in WKT for historical reasons. */ + @SuppressWarnings("LocalVariableHidesMemberVariable") final GeodeticDatum datum = getDatum(); // Gives subclasses a chance to override. formatter.newLine(); formatter.append(WKTUtilities.toFormattable(datum)); diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java index 7e5d52d66f..ca69d62b7c 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java @@ -741,7 +741,7 @@ public class DefaultCoordinateSystemAxis extends AbstractIdentifiedObject implem final String old = name; name = formatter.getTransliterator().toShortAxisName(cs, dir, name); if (name == null && isWKT1) { - name = old; // WKT 1 does not allow omission of name. + name = old; // WKT 1 does not allow omission of name. } } /* @@ -809,11 +809,11 @@ public class DefaultCoordinateSystemAxis extends AbstractIdentifiedObject implem /** * Creates a new {@code ORDER[…]} element for the given axis in the given coordinate system. - * If this method does not found exactly one instance of the given axis in the given coordinate system, + * If this method does not find exactly one instance of the given axis in the given coordinate system, * then returns {@code null}. In the latter case, it is caller's responsibility to declare the WKT as invalid. * * <p>This method is a little bit inefficient since the enclosing {@link AbstractCS#formatTo(Formatter)} - * method already know this axis index. But there is currently no API in {@link Formatter} for carrying + * method already knows this axis index. But there is currently no API in {@link Formatter} for carrying * this information, and we are a little bit reluctant to introduce such API since it would force us to * introduce lists in a model which is, for everything else, purely based on trees.</p> * diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultEllipsoid.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultEllipsoid.java index 9474ade786..29516e47b7 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultEllipsoid.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/datum/DefaultEllipsoid.java @@ -656,6 +656,7 @@ public class DefaultEllipsoid extends AbstractIdentifiedObject implements Ellips * @see <a href="http://docs.opengeospatial.org/is/12-063r5/12-063r5.html#52">WKT 2 specification §8.2.1</a> */ @Override + @SuppressWarnings("LocalVariableHidesMemberVariable") protected String formatTo(final Formatter formatter) { super.formatTo(formatter); final Convention convention = formatter.getConvention(); diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/FormatterTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/FormatterTest.java index 1d77f7783a..ab758d69c7 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/FormatterTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/io/wkt/FormatterTest.java @@ -21,11 +21,9 @@ import org.opengis.metadata.extent.GeographicBoundingBox; import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox; import org.apache.sis.metadata.iso.extent.DefaultVerticalExtent; import org.apache.sis.measure.Units; -import org.apache.sis.util.internal.X364; // Test dependencies import org.junit.Test; -import static org.junit.Assert.*; import org.apache.sis.test.DependsOn; import org.apache.sis.test.TestCase; import org.apache.sis.test.mock.VerticalCRSMock; @@ -45,15 +43,6 @@ public final class FormatterTest extends TestCase { public FormatterTest() { } - /** - * Verifies the ANSI escape sequences hard-coded in {@link Formatter}. - */ - @Test - public void testAnsiEscapeSequences() { - assertEquals("FOREGROUND_DEFAULT", X364.FOREGROUND_DEFAULT.sequence(), Formatter.FOREGROUND_DEFAULT); - assertEquals("BACKGROUND_DEFAULT", X364.BACKGROUND_DEFAULT.sequence(), Formatter.BACKGROUND_DEFAULT); - } - /** * Tests (indirectly) {@link Formatter#quote(String, ElementKind)}. */