You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2016/04/22 18:51:23 UTC

svn commit: r1740563 - in /sis/branches/JDK7: ./ core/sis-metadata/src/main/java/org/apache/sis/io/wkt/ core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/ core...

Author: desruisseaux
Date: Fri Apr 22 16:51:23 2016
New Revision: 1740563

URL: http://svn.apache.org/viewvc?rev=1740563&view=rev
Log:
Merge from JDK8 branch.

Modified:
    sis/branches/JDK7/   (props changed)
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
    sis/branches/JDK7/core/sis-referencing/src/main/resources/org/apache/sis/referencing/factory/sql/EPSG_Finish.sql
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/IdentifiedObjectsTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GeodeticObjectFactoryTest.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties

Propchange: sis/branches/JDK7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Apr 22 16:51:23 2016
@@ -1,4 +1,4 @@
 /sis/branches/Android:1430670-1480699
 /sis/branches/JDK6:1394913-1508480
-/sis/branches/JDK8:1584960-1740419
+/sis/branches/JDK8:1584960-1740562
 /sis/trunk:1394364-1508466,1519089-1519674

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/AbstractParser.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -83,13 +83,6 @@ abstract class AbstractParser implements
     static final int MANDATORY = 2;
 
     /**
-     * The logger to use for reporting warnings when this parser is used through the {@link #createFromWKT(String)}.
-     * This happen most often when the user invoke the {@link org.apache.sis.referencing.CRS#fromWKT(String)}
-     * convenience method.
-     */
-    private static final Logger LOGGER = Logging.getLogger(Loggers.WKT);
-
-    /**
      * The locale for error messages (not for number parsing), or {@code null} for the system default.
      */
     final Locale errorLocale;
@@ -196,6 +189,14 @@ abstract class AbstractParser implements
     abstract String getPublicFacade();
 
     /**
+     * Returns the name of the method invoked from {@link #getPublicFacade()}.
+     * This information is used for logging purpose only.
+     */
+    String getFacadeMethod() {
+        return "createFromWKT";
+    }
+
+    /**
      * Creates the object from a string. This method is for implementation of {@code createFromWKT(String)}
      * method is SIS factories only.
      *
@@ -220,16 +221,24 @@ abstract class AbstractParser implements
         }
         final Warnings warnings = getAndClearWarnings(value);
         if (warnings != null) {
-            final LogRecord record = new LogRecord(Level.WARNING, warnings.toString());
-            record.setSourceClassName(getPublicFacade());
-            record.setSourceMethodName("createFromWKT");
-            record.setLoggerName(LOGGER.getName());
-            LOGGER.log(record);
+            log(new LogRecord(Level.WARNING, warnings.toString()));
         }
         return value;
     }
 
     /**
+     * Logs the given record. This is used only when we can not use the {@link #warning warning methods},
+     * or when the information is not worth to report as a warning.
+     */
+    final void log(final LogRecord record) {
+        Logger logger = Logging.getLogger(Loggers.WKT);
+        record.setSourceClassName(getPublicFacade());
+        record.setSourceMethodName(getFacadeMethod());
+        record.setLoggerName(logger.getName());
+        logger.log(record);
+    }
+
+    /**
      * Returns the index after the end of the fragment name starting at the given index.
      * Current implementation assumes that the fragment name is a Unicode identifier.
      */
@@ -323,7 +332,7 @@ abstract class AbstractParser implements
     /**
      * Parses the given unit symbol.
      */
-    final Unit<?> parseUnit(final String text) throws ParseException {
+    final Unit<?> parseUnit(final String text) throws ParseException, IllegalArgumentException {
         if (unitFormat == null) {
             if (symbols.getLocale() == Locale.ROOT) {
                 return Units.valueOf(text);             // Most common case, avoid the convolved code below.

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -692,7 +692,8 @@ public class Formatter implements Locali
             info = ((GeneralParameterValue) object).getDescriptor();
         }
         if (info != null) {
-            appendComplement(info, (stackDepth != 0) ? enclosingElements.get(stackDepth - 1) : null);
+            appendComplement(info, (stackDepth >= 1) ? enclosingElements.get(stackDepth - 1) : null,
+                                   (stackDepth >= 2) ? enclosingElements.get(stackDepth - 2) : null);
         }
         buffer.appendCodePoint(symbols.getClosingBracket(0));
         indent(-1);
@@ -707,9 +708,10 @@ public class Formatter implements Locali
      * and have a special treatment: they are written by {@link #append(FormattableObject)}
      * after the {@code formatTo(Formatter)} method returned.
      *
-     * <p>The {@code ID[<name>,<code>,…]} element is written only for the root element, unless the convention are
-     * INTERNAL. If formatted, the ID element will be on the same line than the enclosing one if no line separator
-     * were requested (e.g. SPHEROID["Clarke 1866", …, ID["EPSG", 7008]]), or on a new line otherwise. Example:</p>
+     * <p>The {@code ID[<name>,<code>,…]} element is normally written only for the root element
+     * (unless the convention is {@code INTERNAL}), but there is various exceptions to this rule.
+     * If formatted, the {@code ID} element will be by default on the same line than the enclosing
+     * element (e.g. {@code SPHEROID["Clarke 1866", …, ID["EPSG", 7008]]}). Other example:</p>
      *
      * {@preformat text
      *   PROJCS["NAD27 / Idaho Central",
@@ -730,7 +732,7 @@ public class Formatter implements Locali
      * A {@code <remark>} can be included within the descriptions of source and target CRS embedded within
      * a coordinate transformation as well as within the coordinate transformation itself.</blockquote>
      */
-    private void appendComplement(final IdentifiedObject object, final FormattableObject parent) {
+    private void appendComplement(final IdentifiedObject object, final FormattableObject parent, final FormattableObject gp) {
         isComplement = true;
         final boolean showIDs;      // Whether to format ID[…] elements.
         final boolean filterID;     // Whether we shall limit to a single ID[…] element.
@@ -753,6 +755,9 @@ public class Formatter implements Locali
              */
             if (parent == null || parent instanceof CompoundCRS) {
                 showIDs = true;
+            } else if (gp instanceof CoordinateOperation && !(parent instanceof IdentifiedObject)) {
+                // "SourceCRS[…]" and "TargetCRS[…]" sub-elements in CoordinateOperation.
+                showIDs = true;
             } else if (convention == Convention.WKT2_SIMPLIFIED) {
                 showIDs = false;
             } else {
@@ -769,7 +774,7 @@ public class Formatter implements Locali
                     showRemarks = showOthers;
                 } else if (object instanceof ReferenceSystem) {
                     showOthers  = (parent == null);
-                    showRemarks = (parent == null) || (getEnclosingElement(2) instanceof CoordinateOperation);
+                    showRemarks = (parent == null) || (gp instanceof CoordinateOperation);
                 } else {
                     showOthers  = false;    // Mandated by ISO 19162.
                     showRemarks = false;

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/GeodeticObjectParser.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -26,6 +26,8 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
 import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.text.ParsePosition;
@@ -38,6 +40,7 @@ import javax.measure.quantity.Angle;
 import javax.measure.quantity.Length;
 import javax.measure.quantity.Quantity;
 import javax.measure.quantity.Duration;
+import javax.measure.converter.ConversionException;
 
 import org.opengis.util.Factory;
 import org.opengis.metadata.Identifier;
@@ -70,6 +73,7 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.internal.metadata.TransformationAccuracy;
 import org.apache.sis.internal.util.LocalizedParseException;
 import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.iso.DefaultNameSpace;
@@ -91,7 +95,7 @@ import static java.util.Collections.sing
  * @version 0.7
  * @module
  */
-final class GeodeticObjectParser extends MathTransformParser implements Comparator<CoordinateSystemAxis> {
+class GeodeticObjectParser extends MathTransformParser implements Comparator<CoordinateSystemAxis> {
     /**
      * The names of the 7 parameters in a {@code TOWGS84[…]} element.
      * Those names are derived from the <cite>Well Known Text</cite> (WKT) version 1 specification.
@@ -276,7 +280,7 @@ final class GeodeticObjectParser extends
      * @throws ParseException if the string can not be parsed.
      */
     @Override
-    public Object parseObject(final String text, final ParsePosition position) throws ParseException {
+    public final Object parseObject(final String text, final ParsePosition position) throws ParseException {
         final Object object;
         try {
             object = super.parseObject(text, position);
@@ -321,7 +325,7 @@ final class GeodeticObjectParser extends
      * @throws ParseException if the element can not be parsed.
      */
     @Override
-    Object parseObject(final Element element) throws ParseException {
+    final Object parseObject(final Element element) throws ParseException {
         Object value = parseCoordinateReferenceSystem(element, false);
         if (value != null) {
             return value;
@@ -617,7 +621,7 @@ final class GeodeticObjectParser extends
      * @return The {@code "UNIT"} element as an {@link Unit} object, or {@code null} if none.
      * @throws ParseException if the {@code "UNIT"} can not be parsed.
      *
-     * @todo Authority code is currently ignored. We may consider to create a subclass of
+     * @todo Authority code is currently discarded after parsing. We may consider to create a subclass of
      *       {@link Unit} which implements {@link IdentifiedObject} in a future version.
      */
     @SuppressWarnings("unchecked")
@@ -630,16 +634,46 @@ final class GeodeticObjectParser extends
         }
         final String name   = element.pullString("name");
         final double factor = element.pullDouble("factor");
-        final Unit<?> unit  = parseUnitID(element);
+        Unit<Q> unit   = Units.multiply(baseUnit, factor);
+        Unit<?> verify = parseUnitID(element);
         element.close(ignoredElements);
-        if (unit != null) {
-            if (baseUnit.toSI().equals(unit.toSI())) {
-                return (Unit<Q>) unit;
+        /*
+         * Consider the following element: UNIT[“km”, 1000, ID[“EPSG”, “9036”]]
+         *
+         *  - if the authority code (“9036”) refers to a unit incompatible with 'baseUnit' (“metre”), log a warning.
+         *  - otherwise: 1) unconditionally replace the parsed unit (“km”) by the unit referenced by the authority code.
+         *               2) if the new unit is not equivalent to the old one (i.e. different scale factor), log a warning.
+         */
+        if (verify != null) {
+            if (!baseUnit.toSI().equals(verify.toSI())) {
+                warning(parent, element, Errors.formatInternational(Errors.Keys.InconsistentUnitsForCS_1, verify), null);
+            } else if (Math.abs(unit.getConverterTo(unit = (Unit<Q>) verify).convert(1) - 1) > Numerics.COMPARISON_THRESHOLD) {
+                warning(parent, element, Errors.formatInternational(Errors.Keys.UnexpectedScaleFactorForUnit_2, verify, factor), null);
             } else {
-                warning(parent, element, Errors.formatInternational(Errors.Keys.IllegalUnitFor_2, keyword, unit), null);
+                verify = null;                                          // Means to perform additional verifications.
+            }
+        }
+        /*
+         * Above block verified the ID[“EPSG”, “9036”] authority code. Now verify the unit parsed from the “km” symbol.
+         * This is only a verification; we will not replace the unit by the parsed one (i.e. authority code or scale
+         * factor have precedence over the unit symbol).
+         */
+        if (verify == null) {
+            try {
+                verify = parseUnit(name);
+            } catch (IllegalArgumentException | ParseException e) {
+                log(new LogRecord(Level.FINE, e.toString()));
+            }
+            if (verify != null) try {
+                if (Math.abs(verify.getConverterToAny(unit).convert(1) - 1) > Numerics.COMPARISON_THRESHOLD) {
+                    warning(parent, element, Errors.formatInternational(Errors.Keys.UnexpectedScaleFactorForUnit_2, verify, factor), null);
+                }
+            } catch (ConversionException e) {
+                throw (ParseException) new LocalizedParseException(errorLocale,
+                        Errors.Keys.InconsistentUnitsForCS_1, new Object[] {verify}, element.offset).initCause(e);
             }
         }
-        return Units.multiply(baseUnit, factor);
+        return unit;
     }
 
     /**
@@ -1092,7 +1126,7 @@ final class GeodeticObjectParser extends
      *          0 if undetermined (no axis order change).
      */
     @Override
-    public int compare(final CoordinateSystemAxis o1, final CoordinateSystemAxis o2) {
+    public final int compare(final CoordinateSystemAxis o1, final CoordinateSystemAxis o2) {
         final Integer n1 = axisOrder.get(o1);
         final Integer n2 = axisOrder.get(o2);
         if (n1 != null) {

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/MathTransformParser.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -245,7 +245,12 @@ class MathTransformParser extends Abstra
             return Units.multiply(BASE_UNITS[index], factor);
         }
         // If we can not infer the base type, we have to rely on the name.
-        return parseUnit(name);
+        try {
+            return parseUnit(name);
+        } catch (IllegalArgumentException e) {
+            throw (ParseException) new LocalizedParseException(errorLocale,
+                    Errors.Keys.UnknownUnit_1, new Object[] {name}, element.offset).initCause(e);
+        }
     }
 
     /**

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -729,7 +729,7 @@ public class WKTFormat extends CompoundF
     private AbstractParser parser() {
         AbstractParser parser = this.parser;
         if (parser == null) {
-            this.parser = parser = new GeodeticObjectParser(symbols, fragments(),
+            this.parser = parser = new Parser(symbols, fragments(),
                     (NumberFormat) getFormat(Number.class),
                     (DateFormat)   getFormat(Date.class),
                     (UnitFormat)   getFormat(Unit.class),
@@ -742,6 +742,23 @@ public class WKTFormat extends CompoundF
     }
 
     /**
+     * The parser created by {@link #parser()}, identical to {@link GeodeticObjectParser} except for
+     * the source of logging messages which is the enclosing {@code WKTParser} instead than a factory.
+     */
+    private static final class Parser extends GeodeticObjectParser {
+        Parser(final Symbols symbols, final Map<String,Element> fragments,
+                final NumberFormat numberFormat, final DateFormat dateFormat, final UnitFormat unitFormat,
+                final Convention convention, final Transliterator transliterator, final Locale errorLocale,
+                final Map<Class<?>,Factory> factories)
+        {
+            super(symbols, fragments, numberFormat, dateFormat, unitFormat, convention, transliterator, errorLocale, factories);
+        }
+
+        @Override String getPublicFacade() {return WKTFormat.class.getName();}
+        @Override String getFacadeMethod() {return "parse";}
+    }
+
+    /**
      * Formats the specified object as a Well Know Text. The formatter accepts at least the following types:
      * {@link FormattableObject}, {@link IdentifiedObject},
      * {@link org.opengis.referencing.operation.MathTransform},

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -42,6 +42,7 @@ import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
 import org.opengis.referencing.datum.*;
 import org.opengis.referencing.operation.*;
+import org.opengis.parameter.ParameterNotFoundException;
 import org.apache.sis.referencing.cs.*;
 import org.apache.sis.referencing.crs.*;
 import org.apache.sis.referencing.datum.*;
@@ -1631,7 +1632,25 @@ public class GeodeticObjectFactory exten
         } catch (ReflectiveOperationException e) {
             throw new FactoryException(e);
         }
-        final Object object = p.createFromWKT(text);
+        final Object object;
+        try {
+            object = p.createFromWKT(text);
+        } catch (FactoryException e) {
+            /*
+             * In the case of map projection, the parsing may fail because a projection parameter is not known to SIS.
+             * If this happen, replace the generic exception thrown be the parser (which is FactoryException) by a
+             * more specific one. Note that InvalidGeodeticParameterException is defined only in this sis-referencing
+             * module, so we could not throw it from the sis-metadata module that contain the parser.
+             */
+            Throwable cause = e.getCause();
+            while (cause != null) {
+                if (cause instanceof ParameterNotFoundException) {
+                    throw new InvalidGeodeticParameterException(e.getMessage(), cause);     // More accurate exception.
+                }
+                cause = cause.getCause();
+            }
+            throw e;
+        }
         parser.set(p);
         if (object instanceof CoordinateReferenceSystem) {
             return (CoordinateReferenceSystem) object;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -930,6 +930,7 @@ check:      for (int isTarget=0; ; isTar
                     return type;
                 }
             });
+            formatter.newLine();
         }
     }
 

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DefaultMathTransformFactory.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -1376,7 +1376,25 @@ public class DefaultMathTransformFactory
          * No need to check the type of the parsed object, because MathTransformParser
          * should return only instance of MathTransform.
          */
-        final Object object = p.createFromWKT(text);
+        final Object object;
+        try {
+            object = p.createFromWKT(text);
+        } catch (FactoryException e) {
+            /*
+             * The parsing may fail because a operation parameter is not known to SIS. If this happen, replace
+             * the generic exception thrown be the parser (which is FactoryException) by a more specific one.
+             * Note that InvalidGeodeticParameterException is defined only in this sis-referencing module,
+             * so we could not throw it from the sis-metadata module that contain the parser.
+             */
+            Throwable cause = e.getCause();
+            while (cause != null) {
+                if (cause instanceof ParameterNotFoundException) {
+                    throw new InvalidGeodeticParameterException(e.getMessage(), cause);     // More accurate exception.
+                }
+                cause = cause.getCause();
+            }
+            throw e;
+        }
         parser.set(p);
         return (MathTransform) object;
     }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -163,10 +163,14 @@ public final class MathTransforms extend
      * Furthermore the returned transform is affine (i.e. implement the {@link LinearTransform} interface)
      * if the interval between each {@code preimage} and {@code values} element is constant.
      *
+     * <p>The current implementation uses linear interpolation. This may be changed in a future SIS version.</p>
+     *
      * @param preimage the input values (<var>x</var>) in the function domain, or {@code null}.
      * @param values the output values (<var>y</var>) in the function range, or {@code null}.
      * @return the <i>y=f(x)</i> function.
      *
+     * @see org.opengis.coverage.InterpolationMethod
+     *
      * @since 0.7
      */
     public static MathTransform1D interpolate(final double[] preimage, final double[] values) {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/resources/org/apache/sis/referencing/factory/sql/EPSG_Finish.sql
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/resources/org/apache/sis/referencing/factory/sql/EPSG_Finish.sql?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/resources/org/apache/sis/referencing/factory/sql/EPSG_Finish.sql [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/resources/org/apache/sis/referencing/factory/sql/EPSG_Finish.sql [UTF-8] Fri Apr 22 16:51:23 2016
@@ -19,6 +19,19 @@ UPDATE epsg_coordoperationparamvalue SET
 
 
 
+---
+--- Extensions to EPSG dataset 8.9 for helping Apache SIS to find some coordinate operation paths.
+---
+---     NTF Paris (EPSG:4807)  →  NTF (EPSG:4275)  →  RGF93 (EPSG:4171)
+---
+INSERT INTO epsg_coordoperation VALUES (48094, 'NTF (Paris) to RGF93 (1)', 'concatenated operation',
+ 4807, 4171, NULL, 1, 3694, '?', 1, NULL, NULL, NULL, NULL, NULL, 'Apache SIS', '2016-04-22', NULL, FALSE, FALSE);
+INSERT INTO epsg_coordoperationpath VALUES
+ (48094, 1763, 1),
+ (48094, 1053, 2);
+
+
+
 --
 -- Additional indexes for the EPSG database. Those indexes are not declared
 -- in the SQL scripts distributed by EPSG. They are not required for proper

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/GeodeticObjectParserTest.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -1090,6 +1090,25 @@ public final strictfp class GeodeticObje
     }
 
     /**
+     * Ensures that parsing a WKT with wrong units throws an exception.
+     */
+    @Test
+    public void testIncompatibleUnits() {
+        try {
+            parse(GeographicCRS.class,
+                    "GEOGCS[“NAD83”,\n" +
+                    "  DATUM[“North American Datum 1983”,\n" +
+                    "    SPHEROID[“GRS 1980”, 6378137.0, 298.257222]],\n" +
+                    "  PRIMEM[“Greenwich”, 0],\n" +
+                    "  UNIT[“km”, 1000]]");                                             // Wrong unit
+            fail("Should not have parsed a CRS with wrong unit of measurement.");
+        } catch (ParseException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("km"));
+        }
+    }
+
+    /**
      * Tests the production of a warning messages when the WKT contains unknown elements.
      *
      * @throws ParseException if the parsing failed.
@@ -1101,7 +1120,7 @@ public final strictfp class GeodeticObje
                "GEOGCS[“WGS 84”,\n" +
                "  DATUM[“World Geodetic System 1984”,\n" +
                "    SPHEROID[“WGS84”, 6378137.0, 298.257223563, Ext1[“foo”], Ext2[“bla”]]],\n" +
-               "    PRIMEM[“Greenwich”, 0.0, Intruder[“unknown”]],\n" +
+               "    PRIMEM[“Greenwich”, 0.0, Intruder[“unknown”], UNIT[“degree”, 0.01745]],\n" +    // Truncated scale factor.
                "  UNIT[“degree”, 0.017453292519943295], Intruder[“foo”]]");
 
         verifyGeographicCRS(0, crs);
@@ -1131,12 +1150,14 @@ public final strictfp class GeodeticObje
                 warnings.getUnknownElementLocations("Ext2").toArray());
 
         assertMultilinesEquals("Parsing of “WGS 84” done, but some elements were ignored.\n" +
+                               " • Unexpected scale factor 0.017 for unit of measurement “°”.\n" +
                                " • The text contains unknown elements:\n" +
                                "    ‣ “Intruder” in PRIMEM, GEOGCS.\n" +
                                "    ‣ “Ext1” in SPHEROID.\n" +
                                "    ‣ “Ext2” in SPHEROID.", warnings.toString(Locale.US));
 
         assertMultilinesEquals("La lecture de « WGS 84 » a été faite, mais en ignorant certains éléments.\n" +
+                               " • Le facteur d’échelle 0,017 est inattendu pour l’unité de mesure « ° ».\n" +
                                " • Le texte contient des éléments inconnus :\n" +
                                "    ‣ « Intruder » dans PRIMEM, GEOGCS.\n" +
                                "    ‣ « Ext1 » dans SPHEROID.\n" +

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -21,6 +21,7 @@ import org.opengis.referencing.crs.Geode
 import org.opengis.referencing.crs.SingleCRS;
 import org.opengis.util.FactoryException;
 import org.apache.sis.referencing.crs.DefaultCompoundCRS;
+import org.apache.sis.referencing.crs.DefaultGeographicCRS;
 import org.apache.sis.referencing.crs.HardCodedCRS;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Utilities;
@@ -105,6 +106,23 @@ public final strictfp class CRSTest exte
     }
 
     /**
+     * Tests simple WKT parsing. It is not the purpose of this class to test extensively the WKT parser;
+     * those tests are rather done by {@link org.apache.sis.io.wkt.GeodeticObjectParserTest}.
+     * Here we merely test that {@link CRS#fromWKT(String)} is connected to the parser.
+     *
+     * @throws FactoryException if an error occurred while parsing the WKT.
+     */
+    @Test
+    public void testFromWKT() throws FactoryException {
+        final CoordinateReferenceSystem crs = CRS.fromWKT(
+                "GEOGCS[\"GCS WGS 1984\","
+                + "DATUM[\"WGS 1984\",SPHEROID[\"WGS 1984\",6378137,298.257223563]],"
+                + "PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433]]");
+        assertInstanceOf("GEOGCS", DefaultGeographicCRS.class, crs);
+        assertEquals("GCS WGS 1984", crs.getName().getCode());
+    }
+
+    /**
      * Tests {@link CRS#isHorizontalCRS(CoordinateReferenceSystem)}.
      */
     @Test

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/IdentifiedObjectsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/IdentifiedObjectsTest.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/IdentifiedObjectsTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/IdentifiedObjectsTest.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -33,9 +33,10 @@ import static org.apache.sis.referencing
 
 /**
  * Tests the {@link IdentifiedObjects} static methods.
- * This test class intentionally declares {@code testLookup()} method without {@link Test} annotation
- * because those tests should not be executed only after the EPSG tests. Those tests will be executed
- * by {@link CRSTest} instead.
+ *
+ * <p><b>Note:</b> this test class intentionally declares {@link #testLookupEPSG()} and {@link #testLookupWMS()}
+ * methods without {@link Test} annotation because those tests should be executed only after the EPSG tests in
+ * {@link org.apache.sis.test.suite.ReferencingTestSuite}. Those tests will be executed by {@link CRSTest} instead.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GeodeticObjectFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GeodeticObjectFactoryTest.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GeodeticObjectFactoryTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GeodeticObjectFactoryTest.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -91,7 +91,7 @@ public final strictfp class GeodeticObje
     }
 
     /**
-     * Test {@link GeodeticObjectFactory#createFromWKT(String)}. We test only a very small WKT here because
+     * Tests {@link GeodeticObjectFactory#createFromWKT(String)}. We test only a very small WKT here because
      * it is not the purpose of this class to test the parser. The main purpose of this test is to verify
      * that {@link GeodeticObjectFactory} has been able to instantiate the parser.
      *
@@ -111,6 +111,35 @@ public final strictfp class GeodeticObje
     }
 
     /**
+     * Tests {@link GeodeticObjectFactory#createFromWKT(String)} with an erroneous projection parameter name.
+     * The intend is to verify that the expected exception is thrown.
+     *
+     * @throws FactoryException if the parsing failed for another reason than the expected one.
+     */
+    @Test
+    public void testInvalidParameterInWKT() throws FactoryException {
+        try {
+            crsFactory.createFromWKT(
+                "PROJCRS[“Custom”,\n" +
+                "  BASEGEODCRS[“North American 1983”,\n" +
+                "    DATUM[“North American 1983”,\n" +
+                "      ELLIPSOID[“GRS 1980”, 6378137, 298.257222101]]],\n" +
+                "  CONVERSION[“Custom”,\n" +
+                "    METHOD[“Lambert Conformal Conic”],\n" +
+                "    PARAMETER[“Standard parallel 1”, 43.0],\n" +
+                "    PARAMETER[“Standard parallel 2”, 45.5],\n" +
+                "    PARAMETER[“Central parallel”, 41.75]],\n" +       // Wrong parameter.
+                "  CS[Cartesian, 2],\n" +
+                "    AXIS[“(Y)”, north],\n" +
+                "    AXIS[“(X)”, east]]");
+            fail("Should not have parsed a WKT with wrong projection parameter.");
+        } catch (InvalidGeodeticParameterException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("Central parallel"));
+        }
+    }
+
+    /**
      * Convenience method creating a map with only the "{@code name"} property.
      * This is the only mandatory property for object creation.
      */

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Fri Apr 22 16:51:23 2016
@@ -1036,6 +1036,11 @@ public final class Errors extends Indexe
         public static final short UnexpectedParameter_1 = 152;
 
         /**
+         * Unexpected scale factor {1} for unit of measurement “{0}”.
+         */
+        public static final short UnexpectedScaleFactorForUnit_2 = 227;
+
+        /**
          * Expected “{0}” to reference an instance of ‘{1}’, but found an instance of ‘{2}’.
          */
         public static final short UnexpectedTypeForReference_3 = 200;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Fri Apr 22 16:51:23 2016
@@ -218,6 +218,7 @@ UnexpectedEndOfString_1           = More
 UnexpectedFileFormat_2            = File \u201c{1}\u201d seems to be encoded in an other format than {0}.
 UnexpectedNumberOfComponents_3    = Expected {1} components in \u201c{0}\u201d but found {2}.
 UnexpectedParameter_1             = Parameter \u201c{0}\u201d was not expected.
+UnexpectedScaleFactorForUnit_2    = Unexpected scale factor {1} for unit of measurement \u201c{0}\u201d.
 UnexpectedTypeForReference_3      = Expected \u201c{0}\u201d to reference an instance of \u2018{1}\u2019, but found an instance of \u2018{2}\u2019.
 UnexpectedValueInElement_2        = Unexpected value \u201c{1}\u201d in \u201c{0}\u201d element.
 UnitlessParameter_1               = Parameter \u201c{0}\u201d has no unit.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1740563&r1=1740562&r2=1740563&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Fri Apr 22 16:51:23 2016
@@ -214,6 +214,7 @@ UnexpectedEndOfString_1           = D\u2
 UnexpectedNumberOfComponents_3    = Il y a {2} composantes dans \u00ab\u202f{0}\u202f\u00bb alors qu\u2019on en attendait {1}.
 UnexpectedFileFormat_2            = Le fichier \u00ab\u202f{1}\u202f\u00bb semble \u00eatre encod\u00e9 dans un autre format que {0}.
 UnexpectedParameter_1             = Le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb est inattendu.
+UnexpectedScaleFactorForUnit_2    = Le facteur d\u2019\u00e9chelle {1} est inattendu pour l\u2019unit\u00e9 de mesure \u00ab\u202f{0}\u202f\u00bb.
 UnexpectedTypeForReference_3      = L\u2019identifiant \u201c{0}\u201d r\u00e9f\u00e9rence une instance de \u2018{2}\u2019 alors qu\u2019on attendait une instance de \u2018{1}\u2019.
 UnexpectedValueInElement_2        = La valeur \u00ab\u202f{1}\u202f\u00bb dans  l\u2019\u00e9l\u00e9ment \u00ab\u202f{0}\u202f\u00bb est inattendue.
 UnitlessParameter_1               = Le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb n\u2019a pas d\u2019unit\u00e9.