sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1732232 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-referencing/src/main/java/org/apache/sis/referencing/cs/ sis-referencing/src/test/java/org/apache/sis/test/integration/ sis-referencing/src/test/ja...
Date Wed, 24 Feb 2016 22:29:42 GMT
Author: desruisseaux
Date: Wed Feb 24 22:29:41 2016
New Revision: 1732232

URL: http://svn.apache.org/viewvc?rev=1732232&view=rev
Log:
Bug fix in WKT parser and formatter: SIS-311, SIS-312, SIS-313.

Added:
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java?rev=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -316,28 +316,17 @@ abstract class AbstractParser implements
     /**
      * Reports a non-fatal warning that occurred while parsing a WKT.
      *
-     * @param parent  The parent element.
-     * @param element The element that we can not parse.
-     * @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 (warnings == null) {
-            warnings = new Warnings(errorLocale, true, ignoredElements);
-        }
-        warnings.add(null, ex, new String[] {parent.keyword, element.keyword});
-    }
-
-    /**
-     * Reports a non-fatal warning that occurred while parsing a WKT.
-     *
-     * @param message The message. Can not be {@code null}.
+     * @param parent  The parent element, or {@code null} if unknown.
+     * @param element The element that we can not parse, or {@code null} if unknown.
+     * @param message The message. Can be {@code null} only if {@code ex} is non-null.
      * @param ex      The non-fatal exception that occurred while parsing the element, or
{@code null}.
      */
-    final void warning(final InternationalString message, final Exception ex) {
+    final void warning(final Element parent, final Element element, final InternationalString
message, final Exception ex) {
         if (warnings == null) {
             warnings = new Warnings(errorLocale, true, ignoredElements);
         }
-        warnings.add(message, ex, null);
+        warnings.add(message, ex, (parent != null && element != null)
+                ? new String[] {parent.keyword, element.keyword} : null);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -299,7 +299,7 @@ final class GeodeticObjectParser extends
                     else ex.addSuppressed(e);
                 }
                 if (verticalElements != null) {
-                    warning(Errors.formatInternational(Errors.Keys.CanNotAssignUnitToDimension_2,
+                    warning(null, null, Errors.formatInternational(Errors.Keys.CanNotAssignUnitToDimension_2,
                             WKTKeywords.VerticalExtent, verticalElements.unit), ex);
                 }
             }
@@ -411,7 +411,7 @@ final class GeodeticObjectParser extends
      * This include elements like {@code "SCOPE"}, {@code "ID"} (WKT 2) or {@code "AUTHORITY"}
(WKT 1).
      * This WKT 1 element has the following pattern:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     AUTHORITY["<name>", "<code>"]
      * }
      *
@@ -505,8 +505,11 @@ final class GeodeticObjectParser extends
             while ((element = parent.pullElement(OPTIONAL, WKTKeywords.Area)) != null) {
                 final String area = element.pullString("area");
                 element.close(ignoredElements);
-                if (extent == null) extent = new DefaultExtent();
-                extent.getGeographicElements().add(new DefaultGeographicDescription(area));
+                if (extent == null) {
+                    extent = new DefaultExtent(area, null, null, null);
+                } else {
+                    extent.getGeographicElements().add(new DefaultGeographicDescription(area));
+                }
             }
             /*
              * Example: BBOX[51.43, 2.54, 55.77, 6.40]
@@ -549,7 +552,7 @@ final class GeodeticObjectParser extends
                     element.pullString("startTime");
                     element.pullString("endTime");
                     element.close(ignoredElements);
-                    warning(Errors.formatInternational(Errors.Keys.UnsupportedType_1, "TimeExtent[String,String]"),
null);
+                    warning(parent, element, Errors.formatInternational(Errors.Keys.UnsupportedType_1,
"TimeExtent[String,String]"), null);
                 } else {
                     final Date startTime = element.pullDate("startTime");
                     final Date endTime   = element.pullDate("endTime");
@@ -560,10 +563,13 @@ final class GeodeticObjectParser extends
                         if (extent == null) extent = new DefaultExtent();
                         extent.getTemporalElements().add(t);
                     } catch (UnsupportedOperationException e) {
-                        warning(parent, element, e);
+                        warning(parent, element, null, e);
                     }
                 }
             }
+            if (extent != null) {
+                properties.put(ReferenceSystem.DOMAIN_OF_VALIDITY_KEY, extent);
+            }
             /*
              * Example: REMARK["Замечание на русском языке"]
              */
@@ -595,7 +601,7 @@ final class GeodeticObjectParser extends
      * Parses an optional {@code "UNIT"} element of a known dimension.
      * This element has the following pattern:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     UNIT["<name>", <conversion factor> {,<authority>}]
      * }
      *
@@ -627,7 +633,7 @@ final class GeodeticObjectParser extends
             if (baseUnit.toSI().equals(unit.toSI())) {
                 return (Unit<Q>) unit;
             } else {
-                warning(Errors.formatInternational(Errors.Keys.IllegalUnitFor_2, keyword,
unit), null);
+                warning(parent, element, Errors.formatInternational(Errors.Keys.IllegalUnitFor_2,
keyword, unit), null);
             }
         }
         return Units.multiply(baseUnit, factor);
@@ -637,7 +643,7 @@ final class GeodeticObjectParser extends
      * Parses a {@code "CS"} element followed by all {@code "AXIS"} elements.
      * This element has the following pattern (simplified):
      *
-     * {@preformat text
+     * {@preformat wkt
      *     CS["<type>", dimension],
      *     AXIS["<name>", NORTH | SOUTH | EAST | WEST | UP | DOWN | OTHER],
      *     UNIT["<name>", <conversion factor>],
@@ -934,7 +940,7 @@ final class GeodeticObjectParser extends
                 return referencing.createAbstractCS(csProperties, axes);
             }
             default: {
-                warning(Errors.formatInternational(Errors.Keys.UnknownType_1, type), null);
+                warning(parent, null, Errors.formatInternational(Errors.Keys.UnknownType_1,
type), null);
                 return referencing.createAbstractCS(csProperties, axes);
             }
         }
@@ -947,10 +953,16 @@ final class GeodeticObjectParser extends
      * Parses an {@code "AXIS"} element.
      * This element has the following pattern (simplified):
      *
-     * {@preformat text
+     * {@preformat wkt
      *     AXIS["<name (abbr.)>", NORTH | SOUTH | EAST | WEST | UP | DOWN | OTHER,
ORDER[n], UNIT[…], ID[…]]
      * }
      *
+     * Abbreviation may be specified between parenthesis. Nested parenthesis are possible,
as for example:
+     *
+     * {@preformat wkt
+     *     AXIS["Easting (E(X))", EAST]
+     * }
+     *
      * @param  mode        {@link #FIRST}, {@link #OPTIONAL} or {@link #MANDATORY}.
      * @param  parent      The parent element.
      * @param  csType      The coordinate system type (Cartesian | ellipsoidal | vertical
| etc…), or null if unknown.
@@ -999,8 +1011,18 @@ final class GeodeticObjectParser extends
          * have to guess one since abbreviation is a mandatory part of axis.
          */
         String abbreviation;
-        final int start, end = name.length() - 1;
+        int start, end = name.length() - 1;
         if (end > 1 && name.charAt(end) == ')' && (start = name.lastIndexOf('(',
end-1)) >= 0) {
+            // Abbreviation may have nested parenthesis (e.g. "Easting (E(X))").
+            for (int np = end; (--np >= 0) && name.charAt(np) == ')';) {
+                final int c = name.lastIndexOf('(', start - 1);
+                if (c < 0) {
+                    warning(parent, element, Errors.formatInternational(
+                            Errors.Keys.NonEquilibratedParenthesis_2, '(', name), null);
+                    break;
+                }
+                start = c;
+            }
             abbreviation = CharSequences.trimWhitespaces(name.substring(start + 1, end));
             name = CharSequences.trimWhitespaces(name.substring(0, start));
             if (name.isEmpty()) {
@@ -1074,7 +1096,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 pattern was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     PRIMEM["<name>", <longitude> {,<authority>}]
      * }
      *
@@ -1116,7 +1138,7 @@ final class GeodeticObjectParser extends
      * Parses an <strong>optional</strong> {@code "TOWGS84"} element.
      * This element is specific to WKT 1 and has the following pattern:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     TOWGS84[<dx>, <dy>, <dz>, <ex>, <ey>, <ez>,
<ppm>]
      * }
      *
@@ -1148,7 +1170,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 pattern was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     SPHEROID["<name>", <semi-major axis>, <inverse flattening> {,<authority>}]
      * }
      *
@@ -1239,7 +1261,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 specification was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     PROJECTION["<name>" {,<authority>}]
      * }
      *
@@ -1313,7 +1335,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 pattern was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     DATUM["<name>", <spheroid> {,<to wgs84>} {,<authority>}]
      * }
      *
@@ -1353,7 +1375,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 pattern was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     VERT_DATUM["<name>", <datum type> {,<authority>}]
      * }
      *
@@ -1391,7 +1413,7 @@ final class GeodeticObjectParser extends
     /**
      * Parses a {@code "TimeDatum"} element. This element has the following pattern:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     TimeDatum["<name>", TimeOrigin[<time origin>] {,<authority>}]
      * }
      *
@@ -1422,7 +1444,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 pattern was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     LOCAL_DATUM["<name>", <datum type> {,<authority>}]
      * }
      *
@@ -1483,7 +1505,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 pattern was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     LOCAL_CS["<name>", <local datum>, <unit>, <axis>, {,<axis>}*
{,<authority>}]
      * }
      *
@@ -1577,8 +1599,8 @@ final class GeodeticObjectParser extends
         try {
             cs = parseCoordinateSystem(element, WKTKeywords.Cartesian, 2, false, unit, datum);
             final Map<String,?> properties = parseMetadataAndClose(element, name, datum);
-            if (cs instanceof CartesianCS) {
-                return crsFactory.createImageCRS(properties, datum, (CartesianCS) cs);
+            if (cs instanceof AffineCS) {
+                return crsFactory.createImageCRS(properties, datum, (AffineCS) cs);
             }
         } catch (FactoryException exception) {
             throw element.parseFailed(exception);
@@ -1592,13 +1614,13 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 specification had two elements for this:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     GEOGCS["<name>", <datum>, <prime meridian>, <angular unit>
 {,<twin axes>} {,<authority>}]
      * }
      *
      * and
      *
-     * {@preformat text
+     * {@preformat wkt
      *     GEOCCS["<name>", <datum>, <prime meridian>, <linear unit>
{,<axis> ,<axis> ,<axis>} {,<authority>}]
      * }
      *
@@ -1761,7 +1783,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 pattern was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     VERT_CS["<name>", <vert datum>, <linear unit>, {<axis>,}
{,<authority>}]
      * }
      *
@@ -1808,7 +1830,7 @@ final class GeodeticObjectParser extends
                 baseCRS = parseVerticalCRS(MANDATORY, element, true);
             }
         }
-        if (baseCRS == null) {  // The most usual case.
+        if (baseCRS == null) {                                                          
   // The most usual case.
             datum = parseVerticalDatum(MANDATORY, element, isWKT1);
         }
         final CoordinateSystem cs;
@@ -1912,7 +1934,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 specification was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     PROJCS["<name>", <geographic cs>, <projection>, {<parameter>,}*,
      *            <linear unit> {,<twin axes>}{,<authority>}]
      * }
@@ -1994,7 +2016,7 @@ final class GeodeticObjectParser extends
      *
      * The legacy WKT 1 specification was:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     COMPD_CS["<name>", <head cs>, <tail cs> {,<authority>}]
      * }
      *
@@ -2026,7 +2048,7 @@ final class GeodeticObjectParser extends
      * Parses a {@code "FITTED_CS"} element.
      * This element has the following pattern:
      *
-     * {@preformat text
+     * {@preformat wkt
      *     FITTED_CS["<name>", <to base>, <base cs>]
      * }
      *

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java?rev=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -214,7 +214,7 @@ class MathTransformParser extends Abstra
                 }
                 return Units.valueOfEPSG(n);
             } catch (NumberFormatException e) {
-                warning(parent, element, e);
+                warning(parent, element, null, e);
             }
         }
         return null;

Modified: 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=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Warnings.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -185,13 +185,13 @@ public final class Warnings implements L
     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 = 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 = new LinkedHashMap<>(4);          // We expect few
items.
             }
             exceptionSources.put(cause, source);
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -54,6 +54,7 @@ import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.io.wkt.ElementKind;
 import org.apache.sis.io.wkt.Transliterator;
 import org.apache.sis.io.wkt.FormattableObject;
+import org.apache.sis.io.wkt.UnformattableObjectException;
 
 import static java.lang.Double.doubleToLongBits;
 import static java.lang.Double.NEGATIVE_INFINITY;
@@ -92,7 +93,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4
- * @version 0.6
+ * @version 0.7
  * @module
  *
  * @see AbstractCS
@@ -772,9 +773,13 @@ public class DefaultCoordinateSystemAxis
          * if the direction is of the kind "South along 90°N" for instance.
          */
         DirectionAlongMeridian meridian = null;
-        if (!isWKT1 && AxisDirections.isUserDefined(dir)) {
+        if (AxisDirections.isUserDefined(dir)) {
             meridian = DirectionAlongMeridian.parse(dir);
             if (meridian != null) {
+                if (isWKT1) {
+                    throw new UnformattableObjectException(Errors.format(
+                            Errors.Keys.CanNotRepresentInFormat_2, "WKT 1", meridian));
+                }
                 dir = meridian.baseDirection;
             }
         }

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java?rev=1732232&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -0,0 +1,203 @@
+/*
+ * 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.test.integration;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TimeZone;
+import java.text.ParseException;
+import org.opengis.util.FactoryException;
+import org.opengis.util.NoSuchIdentifierException;
+import org.opengis.referencing.crs.GeographicCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.apache.sis.referencing.factory.FactoryDataException;
+import org.apache.sis.referencing.CRS;
+import org.apache.sis.io.wkt.Convention;
+import org.apache.sis.io.wkt.Warnings;
+import org.apache.sis.io.wkt.WKTFormat;
+import org.apache.sis.io.TableAppender;
+import org.apache.sis.io.wkt.UnformattableObjectException;
+import org.apache.sis.util.CharSequences;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assume.*;
+import static org.junit.Assert.*;
+
+
+/**
+ * Performs consistency checks on all CRS given by {@link CRS#getAuthorityFactory(String)}.
+ * The consistency checks include:
+ *
+ * <ul>
+ *   <li>Format in WKT, parse, reformat again and verify that we get the same WKT string.</li>
+ * </ul>
+ *
+ * This test is executed only of {@link #RUN_EXTENSIVE_TESTS} is {@code true}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public final strictfp class ConsistencyTest extends TestCase {
+    /**
+     * Codes to exclude for now.
+     */
+    private static final Set<String> EXCLUDES = new HashSet<>(Arrays.asList(
+            "CRS:1",            // Computer display
+            "EPSG:5819"         // EPSG topocentric example A
+    ));
+
+    /**
+     * Verifies the WKT consistency of all CRS instances.
+     *
+     * @throws FactoryException if an error other than "unsupported operation method" occurred.
+     */
+    @Test
+    public void testCoordinateReferenceSystems() throws FactoryException {
+        assumeTrue("Extensive tests not enabled.", RUN_EXTENSIVE_TESTS);
+        final WKTFormat v1 = new WKTFormat(Locale.US, TimeZone.getTimeZone("UTC"));
+        final WKTFormat v2 = new WKTFormat(Locale.US, TimeZone.getTimeZone("UTC"));
+        v1.setConvention(Convention.WKT1);
+        v2.setConvention(Convention.WKT2);
+        for (final String code : CRS.getAuthorityFactory(null).getAuthorityCodes(CoordinateReferenceSystem.class))
{
+            if (!EXCLUDES.contains(code)) {
+                final CoordinateReferenceSystem crs;
+                try {
+                    crs = CRS.forCode(code);
+                } catch (NoSuchIdentifierException | FactoryDataException e) {
+                    print(code, "WARNING", e.getLocalizedMessage());
+                    continue;
+                }
+                parseAndFormat(v2, code, crs);
+                /*
+                 * There is more information lost in WKT 1 than in WKT 2, so we can not test
everything.
+                 * For example we can not format fully three-dimensional geographic CRS because
the unit
+                 * is not the same for all axes. We can not format neither some axis directions.
+                 */
+                if (crs.getCoordinateSystem().getDimension() == 3 && (crs instanceof
GeographicCRS)) {
+                    continue;
+                }
+                try {
+                    parseAndFormat(v1, code, crs);
+                } catch (UnformattableObjectException e) {
+                    print(code, "WARNING", e.getLocalizedMessage());
+                }
+            }
+        }
+    }
+
+    /**
+     * Prints the given code followed by spaces and the given {@code "ERROR"} or {@code "WARNING"}
word,
+     * then the given message.
+     */
+    private static void print(final String code, final String word, final Object message)
{
+        out.print(code);
+        out.print(CharSequences.spaces(15 - code.length()));
+        out.print(word);
+        out.print(": ");
+        out.println(message);
+    }
+
+    /**
+     * Format the given CRS using the given formatter, parses it and reformat again.
+     * Then the two WKT are compared.
+     *
+     * @param f    The formatter to use.
+     * @param code The authority code, used only in case of errors.
+     * @param crs  The CRS to test.
+     */
+    private static void parseAndFormat(final WKTFormat f, final String code, final CoordinateReferenceSystem
crs) {
+        String wkt = f.format(crs);
+        final Warnings warnings = f.getWarnings();
+        if (warnings != null && !warnings.getExceptions().isEmpty()) {
+            print(code, "WARNING", warnings.getException(0));
+        }
+        final CoordinateReferenceSystem parsed;
+        try {
+            parsed = (CoordinateReferenceSystem) f.parseObject(wkt);
+        } catch (ParseException e) {
+            print(code, "ERROR", "Can not parse the WKT below.");
+            out.println(wkt);
+            out.println();
+            e.printStackTrace(out);
+            fail(e.getLocalizedMessage());
+            return;
+        }
+        final String again = f.format(parsed);
+        final CharSequence[] expectedLines = CharSequences.splitOnEOL(wkt);
+        final CharSequence[] actualLines   = CharSequences.splitOnEOL(again);
+        /*
+         * WKT 2 contains a line like below:
+         *
+         *   METHOD["Transverse Mercator", ID["EPSG", 9807, "8.9"]]
+         *
+         * But after parsing, the version number disaspear:
+         *
+         *   METHOD["Transverse Mercator", ID["EPSG", 9807]]
+         *
+         * This is a side effect of the fact that operation method are hard-coded in Java
code.
+         * This is normal for our implementation, so remove the version number from the expected
lines.
+         */
+        if (f.getConvention().majorVersion() >= 2) {
+            for (int i=0; i < expectedLines.length; i++) {
+                final CharSequence line = expectedLines[i];
+                int p = line.length();
+                int s = CharSequences.skipLeadingWhitespaces(line, 0, p);
+                if (CharSequences.regionMatches(line, s, "METHOD[\"")) {
+                    assertEquals(code, ',', line.charAt(--p));
+                    assertEquals(code, ']', line.charAt(--p));
+                    assertEquals(code, ']', line.charAt(--p));
+                    if (line.charAt(--p) == '"') {
+                        p = CharSequences.lastIndexOf(line, ',', 0, p);
+                        expectedLines[i] = line.subSequence(0, p) + "]],";
+                    }
+                }
+            }
+        }
+        /*
+         * Now compare the WKT line-by-line.
+         */
+        final int length = StrictMath.min(expectedLines.length, actualLines.length);
+        try {
+            for (int i=0; i<length; i++) {
+                assertEquals(code, expectedLines[i], actualLines[i]);
+            }
+        } catch (AssertionError e) {
+            print(code, "ERROR", "WKT are not equal.");
+            final TableAppender table = new TableAppender();
+            table.nextLine('═');
+            table.setMultiLinesCells(true);
+            table.append("Original WKT:");
+            table.nextColumn();
+            table.append("CRS parsed from the WKT:");
+            table.nextLine();
+            table.appendHorizontalSeparator();
+            table.append(wkt);
+            table.nextColumn();
+            table.append(again);
+            table.nextLine();
+            table.nextLine('═');
+            out.println(table);
+            throw e;
+        }
+        assertEquals("Unexpected number of lines.", expectedLines.length, actualLines.length);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -224,7 +224,8 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
     org.apache.sis.internal.referencing.ServicesForMetadataTest.class,
     org.apache.sis.test.integration.DatumShiftTest.class,
-    org.apache.sis.test.integration.MetadataTest.class
+    org.apache.sis.test.integration.MetadataTest.class,
+    org.apache.sis.test.integration.ConsistencyTest.class
 })
 public final strictfp class ReferencingTestSuite extends TestSuite {
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java?rev=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/TableAppender.java
[UTF-8] Wed Feb 24 22:29:41 2016
@@ -588,8 +588,8 @@ public class TableAppender extends Appen
      * row with the specified character. The subsequent writing operations will occur on
a new
      * row.
      *
-     * <p>Calling {@code nextLine('-')} from the first column of a row is a convenient
way
-     * to fill this row with a line separator.</p>
+     * <p>Calling {@code nextLine('-')} or {@code nextLine('═')} from the first column
of a row
+     * is a convenient way to fill this row with a line separator.</p>
      *
      * @param fill Character filling the rest of the line (default to whitespace).
      *             This character may be use as a row separator.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java?rev=1732232&r1=1732231&r2=1732232&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8]
(original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java [UTF-8]
Wed Feb 24 22:29:41 2016
@@ -415,21 +415,22 @@ public final class Units extends Static
              */
             if (uom.equals("°")                      || equalsIgnorePlural(uom, "decimal_degree"))
return NonSI.DEGREE_ANGLE;
             if (uom.equalsIgnoreCase("arcsec"))                                         
          return NonSI.SECOND_ANGLE;
-            if (equalsIgnorePlural(uom, "grade"))                                       
          return NonSI.GRADE;
             if (uom.equalsIgnoreCase("rad")          || equalsIgnorePlural(uom, "radian"))
        return SI.RADIAN;
-            if (equalsIgnorePlural(uom, "kilometer") || equalsIgnorePlural(uom, "kilometre"))
     return SI.KILOMETRE;
             if (equalsIgnorePlural(uom, "meter")     || equalsIgnorePlural(uom, "metre"))
         return SI.METRE;
-            if (equalsIgnorePlural(uom, "week"))   return NonSI.WEEK;
-            if (equalsIgnorePlural(uom, "day"))    return NonSI.DAY;
-            if (equalsIgnorePlural(uom, "hour"))   return NonSI.HOUR;
-            if (equalsIgnorePlural(uom, "minute")) return NonSI.MINUTE;
-            if (equalsIgnorePlural(uom, "second")) return SI   .SECOND;
-            if (equalsIgnorePlural(uom, "pixel"))  return NonSI.PIXEL;
-            if (isCelsius(uom))                    return SI.CELSIUS;
-            if (uom.isEmpty())                     return Unit.ONE;
-            if (uom.equalsIgnoreCase("ppm"))       return PPM;
-            if (uom.equalsIgnoreCase("psu"))       return PSU;
-            if (uom.equalsIgnoreCase("sigma"))     return SIGMA;
+            if (equalsIgnorePlural(uom, "kilometer") || equalsIgnorePlural(uom, "kilometre"))
     return SI.KILOMETRE;
+            if (equalsIgnorePlural(uom, "week"))        return NonSI.WEEK;
+            if (equalsIgnorePlural(uom, "day"))         return NonSI.DAY;
+            if (equalsIgnorePlural(uom, "hour"))        return NonSI.HOUR;
+            if (equalsIgnorePlural(uom, "minute"))      return NonSI.MINUTE;
+            if (equalsIgnorePlural(uom, "second"))      return SI   .SECOND;
+            if (equalsIgnorePlural(uom, "pixel"))       return NonSI.PIXEL;
+            if (equalsIgnorePlural(uom, "grade"))       return NonSI.GRADE;
+            if (isCelsius(uom))                         return SI.CELSIUS;
+            if (uom.isEmpty())                          return Unit.ONE;
+            if (uom.equalsIgnoreCase("US survey foot")) return NonSI.FOOT_SURVEY_US;
+            if (uom.equalsIgnoreCase("ppm"))            return PPM;
+            if (uom.equalsIgnoreCase("psu"))            return PSU;
+            if (uom.equalsIgnoreCase("sigma"))          return SIGMA;
         }
         final Unit<?> unit;
         try {



Mime
View raw message