sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1567407 - in /sis/branches/JDK7/core: sis-metadata/src/main/java/org/apache/sis/internal/metadata/ sis-metadata/src/main/java/org/apache/sis/io/wkt/ sis-metadata/src/main/java/org/apache/sis/metadata/iso/ sis-referencing/src/main/java/org/...
Date Tue, 11 Feb 2014 21:48:55 GMT
Author: desruisseaux
Date: Tue Feb 11 21:48:54 2014
New Revision: 1567407

URL: http://svn.apache.org/r1567407
Log:
WKT2 formatting:
- Completed ID[...] with the URI[...] inner element.
- Formatter provides information about the enclosing element (necessary for the above URI[...]).
- Consolidation of Formatter.getLinearUnit()/getAngularUnit() in a single getContextualUnit(...).
- Explicit requests for new lines instead of trying to guess automatically - the later was too convolved.
- Javadoc.

Modified:
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingUtilities.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.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/metadata/iso/ImmutableIdentifier.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRSTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
    sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.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
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestStep.java
    sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingUtilities.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingUtilities.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingUtilities.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -83,6 +83,18 @@ public final class ReferencingUtilities 
     }
 
     /**
+     * Returns {@code true} if codes in the given code space are often represented using the URN syntax.
+     * Current implementation conservatively returns {@code true} only for {@code "EPSG"}.
+     * The list of accepted code spaces may be expanded in any future SIS version.
+     *
+     * @param  codeSpace The code space (can be {@code null}).
+     * @return {@code true} if the given code space is known to use the URN syntax.
+     */
+    public static boolean usesURN(final String codeSpace) {
+        return (codeSpace != null) && codeSpace.equalsIgnoreCase("EPSG");
+    }
+
+    /**
      * Returns the URN type for the given class, or {@code null} if unknown.
      * See {@link org.apache.sis.internal.util.DefinitionURI} javadoc for a list of URN types.
      *

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -72,12 +72,15 @@ public enum Convention {
      * <ul>
      *   <li>{@code ANGLEUNIT}, {@code LENGTHUNIT}, {@code SCALEUNIT}, {@code PARAMETRICUNIT} and
      *       {@code TIMEUNIT} are formatted as plain {@code UNIT} elements.</li>
-     *   <li>In {@code AXIS} elements, the {@code ORDER} elements are omitted.</li>
-     *   <li>In {@code VERTICALEXTENT} elements, the {@code UNIT} element is omitted
+     *   <li>In {@code AXIS} elements, the {@code ORDER} sub-element is omitted.</li>
+     *   <li>In {@code VERTICALEXTENT} elements, the {@code UNIT} sub-element is omitted
      *       if the unit is {@link javax.measure.unit.SI#METRE}.</li>
+     *   <li>{@code ID[…]} elements are formatted for child elements in addition to the root one.
+     *       This <em>addition</em> apparently goes against the simplification goal, but is often
+     *       a helpful information when using Apache SIS.</li>
      * </ul>
      *
-     * Those simplifications are allowed by the ISO 19162 standard and do not cause any information lost.
+     * Those modifications are allowed by the ISO 19162 standard and do not cause any information lost.
      * The omitted elements are not needed by Apache SIS WKT parser and often distractive for the human reader.
      *
      * <p>This is the default convention used by {@link FormattableObject#toString()}.</p>
@@ -128,11 +131,17 @@ public enum Convention {
 
     /**
      * A special convention for formatting objects as stored internally by Apache SIS.
-     * In the majority of cases, the result will be identical to the one we would get using the {@link #WKT2} convention.
-     * However in the particular case of map projections, the result may be quite different because of the way
-     * SIS separates the linear from the non-linear parameters.
+     * The result is similar to the one produced using the {@link #WKT2_SIMPLIFIED} convention,
+     * with the following differences:
      *
-     * <p>This convention is used only for debugging purpose.</p>
+     * <ul>
+     *   <li>In {@code ID[…]} elements, the {@code URI[…]} sub-element is omitted if the sub-element
+     *       was derived by Apache SIS from the other {@code ID[…]} properties.</li>
+     *   <li>Map projections are shown as SIS stores them internally, i.e. with the separation between
+     *       linear and non-linear steps, rather than as a single operation.</li>
+     * </ul>
+     *
+     * This convention is used only for debugging purpose.
      */
     @Debug
     INTERNAL(false);
@@ -173,6 +182,13 @@ public enum Convention {
     }
 
     /**
+     * {@code true} if the identifiers should be formatted for all elements instead of only the last one.
+     */
+    final boolean showIdentifiers() {
+        return this == WKT2_SIMPLIFIED || this == INTERNAL;
+    }
+
+    /**
      * {@code true} for a frequently-used convention about units instead than the standard one.
      * <ul>
      *   <li>If {@code true}, forces {@code PRIMEM} and {@code PARAMETER} angular units to degrees

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -175,10 +175,10 @@ public abstract class FormattableObject 
             if (strict) {
                 final String message = formatter.getErrorMessage();
                 if (message != null) {
-                    throw new UnformattableObjectException(message, formatter.errorCause);
+                    throw new UnformattableObjectException(message, formatter.getErrorCause());
                 }
             }
-            wkt = formatter.toString();
+            wkt = formatter.toWKT();
         } finally {
             formatter.clear();
         }

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=1567407&r1=1567406&r2=1567407&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] Tue Feb 11 21:48:54 2014
@@ -16,12 +16,16 @@
  */
 package org.apache.sis.io.wkt;
 
-import java.util.Date;
-import java.util.Locale;
+import java.util.Map;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.ArrayList;
 import java.util.Collection;
-import java.text.NumberFormat;
+import java.util.Locale;
+import java.util.Date;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.text.NumberFormat;
 import java.text.FieldPosition;
 import java.lang.reflect.Array;
 import java.math.RoundingMode;
@@ -31,6 +35,7 @@ import javax.measure.unit.Unit;
 import javax.measure.unit.UnitFormat;
 import javax.measure.quantity.Angle;
 import javax.measure.quantity.Length;
+import javax.measure.quantity.Quantity;
 
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.citation.Citation;
@@ -40,7 +45,6 @@ import org.opengis.referencing.Identifie
 import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.ReferenceSystem;
 import org.opengis.referencing.datum.Datum;
-import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.operation.CoordinateOperation;
 import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.Matrix;
@@ -48,6 +52,7 @@ import org.opengis.util.CodeList;
 
 import org.apache.sis.measure.Units;
 import org.apache.sis.math.DecimalFunctions;
+import org.apache.sis.util.Debug;
 import org.apache.sis.util.Classes;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.Localized;
@@ -71,8 +76,8 @@ import org.apache.sis.metadata.iso.exten
  *
  * <ul>
  *   <li>A series of {@code append(…)} methods to be invoked by the {@code formatTo(Formatter)} implementations.</li>
- *   <li>Contextual information. In particular, the {@linkplain #getLinearUnit() linear unit} and the
- *       {@linkplain #getAngularUnit() angular unit} depend on the enclosing WKT element.</li>
+ *   <li>Contextual information. In particular, the {@linkplain #getContextualUnit(Class) contextual units} depend on
+ *       the {@linkplain #getEnclosingElement(int) enclosing WKT element}.</li>
  *   <li>A flag for declaring the object unformattable.</li>
  * </ul>
  *
@@ -83,11 +88,6 @@ import org.apache.sis.metadata.iso.exten
  */
 public class Formatter implements Localized {
     /**
-     * Do not format an {@code ID[…]} element for instance of this class.
-     */
-    private static final Class<? extends IdentifiedObject> ID_EXCLUDE = CoordinateSystemAxis.class;
-
-    /**
      * Accuracy of geographic bounding boxes, in number of fraction digits.
      * We use the accuracy recommended by ISO 19162.
      */
@@ -150,20 +150,22 @@ public class Formatter implements Locali
     private Citation authority;
 
     /**
-     * The unit for writing length, or {@code null} for the "natural" unit of each WKT element.
+     * The enclosing WKT element being formatted.
      *
-     * @see #setLinearUnit(Unit)
+     * @see #getEnclosingElement(int)
      */
-    private Unit<Length> linearUnit;
+    private final List<FormattableObject> enclosingElements = new ArrayList<>();
 
     /**
-     * The unit for writing angles, or {@code null} for the "natural" unit of each WKT element.
+     * The units for writing lengths, angles or other type of measurements.
+     * A unit not present in this map means that the "natural" unit of the WKT element shall be used.
      * This value is set for example by {@code "GEOGCS"}, which force its enclosing {@code "PRIMEM"}
      * to take the same units than itself.
      *
-     * @see #setAngularUnit(Unit)
+     * @see #getContextualUnit(Class)
+     * @see #setContextualUnit(Class, Unit)
      */
-    private Unit<Angle> angularUnit;
+    private final Map<Class<? extends Quantity>, Unit<?>> units = new IdentityHashMap<>(4);
 
     /**
      * The object to use for formatting numbers.
@@ -229,6 +231,16 @@ public class Formatter implements Locali
     private boolean requestNewLine;
 
     /**
+     * {@code true} if we are in the process of formatting the optional complementary attributes.
+     * Those attributes are {@code SCOPE}, {@code AREA}, {@code BBOX}, {@code VERTICALEXTENT}, {@code TIMEEXTENT},
+     * {@code ID} (previously known as {@code AUTHORITY}) and {@code REMARKS}, and have a special treatment: they
+     * are written by {@link #append(FormattableObject))} after the {@code formatTo(Formatter)} method returned.
+     *
+     * @see #appendComplement(IdentifiedObject, boolean)
+     */
+    private boolean isComplement;
+
+    /**
      * {@code true} if the last formatted element was invalid WKT and shall be highlighted with syntactic coloration.
      * This field has no effect if {@link #colors} is null. This field is reset to {@code false} after the invalid
      * part has been processed by {@link #append(FormattableObject)}, in order to highlight only the first erroneous
@@ -248,9 +260,9 @@ public class Formatter implements Locali
     /**
      * Error that occurred during WKT formatting, or {@code null} if none.
      *
-     * @see #getErrorMessage()
+     * @see #getErrorCause()
      */
-    Exception errorCause;
+    private Exception errorCause;
 
     /**
      * Creates a new formatter instance with the default configuration.
@@ -423,6 +435,23 @@ public class Formatter implements Locali
     }
 
     /**
+     * Request a line separator before the next element to format. Invoking this method before any
+     * {@code append(…)} method call will cause the next element to appear on the next line.
+     *
+     * <p>This method has no effect in any of the following cases:</p>
+     * <ul>
+     *   <li>WKT formatting has not yet started.</li>
+     *   <li>This method has already been invoked before the next {@code append(…)}.</li>
+     *   <li>The indentation is {@link WKTFormat#SINGLE_LINE}.</li>
+     * </ul>
+     */
+    public void newLine() {
+        if (indentation > WKTFormat.SINGLE_LINE) {
+            requestNewLine = true;
+        }
+    }
+
+    /**
      * Increase or reduce the indentation. A value of {@code +1} increase
      * the indentation by the amount of spaces specified at construction time,
      * and a value of {@code -1} reduce it.
@@ -434,44 +463,54 @@ public class Formatter implements Locali
     /**
      * Conditionally appends a separator to the {@linkplain #buffer}, if needed.
      * This method does nothing if there is currently no element at the buffer end.
-     *
-     * @param newLine If {@code true}, add a line separator too.
      */
-    private void appendSeparator(final boolean newLine) {
+    private void appendSeparator() {
         final StringBuffer buffer = this.buffer;
         int length = buffer.length();
         int c;
         do {
             if (length <= bufferBase) {
+                requestNewLine = false;
                 return; // We are at the buffer beginning.
             }
             c = buffer.codePointBefore(length);
             if (symbols.matchingBracket(c) >= 0 || c == symbols.getOpenSequence()) {
+                requestNewLine = false;
                 return; // We are the first item inside a new keyword.
             }
             length -= Character.charCount(c);
         } while (Character.isSpaceChar(c) || c < 32); // c < 32 is for ignoring all control characters.
         buffer.append(symbols.getSeparator());
-        if (newLine && indentation > WKTFormat.SINGLE_LINE) {
+        if (requestNewLine) {
             buffer.append(System.lineSeparator()).append(CharSequences.spaces(margin));
+            requestNewLine = false;
         }
     }
 
     /**
      * Appends a separator if needed, then opens a new element.
      *
+     * @param newLine {@code true} for invoking {@link #newLine()} first.
      * @param keyword The element keyword (e.g. {@code "DATUM"}, {@code "AXIS"}, <i>etc</i>).
      */
-    private void openElement(final String keyword) {
-        appendSeparator(requestNewLine);
+    private void openElement(final boolean newLine, final String keyword) {
+        if (newLine) {
+            newLine();
+        }
+        appendSeparator();
         buffer.append(keyword).appendCodePoint(symbols.getOpeningBracket(0));
     }
 
     /**
      * Closes the element opened by {@link #openElement(String)}.
+     *
+     * @param newLine {@code true} for invoking {@link #newLine()} last.
      */
-    private void closeElement() {
+    private void closeElement(final boolean newLine) {
         buffer.appendCodePoint(symbols.getClosingBracket(0));
+        if (newLine) {
+            newLine();
+        }
     }
 
     /**
@@ -496,11 +535,26 @@ public class Formatter implements Locali
         if (object == null) {
             return;
         }
-        final StringBuffer buffer = this.buffer;
-        appendSeparator(requestNewLine || !(object instanceof ReferenceIdentifier));
+        /*
+         * Safety check: ensure that we do not have circular dependencies (e.g. a ProjectedCRS contains
+         * a Conversion which may contain the ProjectedCRS as its target CRS). Without this protection,
+         * a circular dependency would cause an OutOfMemoryError.
+         */
+        final int stackDepth = enclosingElements.size();
+        for (int i=stackDepth; --i >= 0;) {
+            if (enclosingElements.get(i) == object) {
+                throw new IllegalStateException(Errors.getResources(locale).getString(Errors.Keys.CircularReference));
+            }
+        }
+        enclosingElements.add(object);
+        /*
+         * Add a new line if it was requested, open the bracket and increase indentation in case the
+         * element to format contains other FormattableObject elements.
+         */
+        appendSeparator();
         int base = buffer.length();
         buffer.appendCodePoint(symbols.getOpeningBracket(0));
-        final IdentifiedObject info = (object instanceof IdentifiedObject) ? (IdentifiedObject) object : null;
+        indent(+1);
         /*
          * Formats the inner part, then prepend the WKT keyword.
          * The result looks like the following:
@@ -510,8 +564,7 @@ public class Formatter implements Locali
          *             GEOGCS[...etc...],
          *             ...etc...
          */
-        indent(+1);
-        requestNewLine = false;
+        final IdentifiedObject info = (object instanceof IdentifiedObject) ? (IdentifiedObject) object : null;
         String keyword = object.formatTo(this);
         if (keyword == null) {
             if (info != null) {
@@ -532,46 +585,58 @@ public class Formatter implements Locali
         }
         buffer.insert(base, keyword);
         /*
-         * Format the SCOPE["…"] and AREA["…"] elements (WKT 2 only). Those information
+         * Format the SCOPE["…"], AREA["…"] and other elements. Some of those information
          * are available only for Datum, CoordinateOperation and ReferenceSystem objects.
          */
+        if (info != null) {
+            appendComplement(info, stackDepth == 0);
+        }
+        buffer.appendCodePoint(symbols.getClosingBracket(0));
+        indent(-1);
+        enclosingElements.remove(stackDepth);
+    }
+
+    /**
+     * Appends the optional complementary attributes common to all {@link IdentifiedObject}s.
+     * Those attributes are {@code SCOPE}, {@code AREA}, {@code BBOX}, {@code VERTICALEXTENT}, {@code TIMEEXTENT},
+     * {@code ID} (previously known as {@code AUTHORITY}) and {@code REMARKS}, 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:
+     *
+     * {@preformat text
+     *   PROJCS["NAD27 / Idaho Central",
+     *     GEOGCS[...etc...],
+     *     ...etc...
+     *     ID["EPSG", 26769]]
+     * }
+     */
+    private void appendComplement(final IdentifiedObject object, final boolean isRoot) {
+        isComplement = true;
         final boolean isWKT1 = convention.isWKT1();
         if (!isWKT1) {
             appendScopeAndArea(object);
         }
-        /*
-         * Formats the ID[<name>,<code>,…] element. The 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:
-         *
-         *           PROJCS["NAD27 / Idaho Central",
-         *             GEOGCS[...etc...],
-         *             ...etc...
-         *             ID["EPSG", 26769]]
-         */
-        if (!ID_EXCLUDE.isInstance(info)) {
-            ReferenceIdentifier id = getIdentifier(info);
+        if (isRoot || convention.showIdentifiers()) {
+            ReferenceIdentifier id = getIdentifier(object);
             if (!(id instanceof FormattableObject)) {
                 id = ImmutableIdentifier.castOrCopy(id);
             }
             append((FormattableObject) id);
         }
-        /*
-         * Format remarks if any, and close the element.
-         */
-        if (!isWKT1 && info != null) {
-            append("REMARKS", info.getRemarks(), ElementKind.REMARKS);
+        if (!isWKT1) {
+            appendOnNewLine("REMARKS", object.getRemarks(), ElementKind.REMARKS);
         }
-        buffer.appendCodePoint(symbols.getClosingBracket(0));
-        requestNewLine = true;
-        indent(-1);
+        isComplement = false;
     }
 
     /**
      * Appends the scope and domain of validity of the given object. Those information are available
      * only for {@link ReferenceSystem}, {@link Datum} and {@link CoordinateOperation} objects.
      */
-    private void appendScopeAndArea(final Object object) {
+    private void appendScopeAndArea(final IdentifiedObject object) {
         final InternationalString scope;
         final Extent area;
         if (object instanceof ReferenceSystem) {
@@ -586,13 +651,13 @@ public class Formatter implements Locali
         } else {
             return;
         }
-        append("SCOPE", scope, ElementKind.SCOPE);
+        appendOnNewLine("SCOPE", scope, ElementKind.SCOPE);
         if (area != null) {
-            append("AREA", area.getDescription(), ElementKind.EXTENT);
+            appendOnNewLine("AREA", area.getDescription(), ElementKind.EXTENT);
             append(Extents.getGeographicBoundingBox(area), BBOX_ACCURACY);
             final MeasurementRange<Double> range = Extents.getVerticalRange(area);
             if (range != null) {
-                openElement("VERTICALEXTENT");
+                openElement(true, "VERTICALEXTENT");
                 setColor(ElementKind.EXTENT);
                 numberFormat.setMinimumFractionDigits(0);
                 numberFormat.setMaximumFractionDigits(VERTICAL_ACCURACY);
@@ -602,22 +667,19 @@ public class Formatter implements Locali
                 appendPreset(range.getMaxDouble());
                 final Unit<?> unit = range.unit();
                 if (!convention.isSimple() || !SI.METRE.equals(unit)) {
-                    requestNewLine = false;
                     append(unit); // Unit are optional if they are metres.
                 }
                 resetColor();
-                closeElement();
-                requestNewLine = true;
+                closeElement(true);
             }
             final Range<Date> timeRange = Extents.getTimeRange(area);
             if (timeRange != null) {
-                openElement("TIMEEXTENT");
+                openElement(true, "TIMEEXTENT");
                 setColor(ElementKind.EXTENT);
                 append(timeRange.getMinValue());
                 append(timeRange.getMaxValue());
                 resetColor();
-                closeElement();
-                requestNewLine = true;
+                closeElement(true);
             }
         }
     }
@@ -655,7 +717,7 @@ public class Formatter implements Locali
      */
     public void append(final GeographicBoundingBox bbox, final int fractionDigits) {
         if (bbox != null) {
-            openElement("BBOX");
+            openElement(isComplement, "BBOX");
             setColor(ElementKind.EXTENT);
             numberFormat.setMinimumFractionDigits(fractionDigits);
             numberFormat.setMaximumFractionDigits(fractionDigits);
@@ -666,7 +728,7 @@ public class Formatter implements Locali
             appendPreset(bbox.getNorthBoundLatitude());
             appendPreset(bbox.getEastBoundLongitude());
             resetColor();
-            closeElement();
+            closeElement(isComplement);
         }
     }
 
@@ -682,7 +744,7 @@ public class Formatter implements Locali
             } else {
                 final Matrix matrix = ReferencingServices.getInstance().getMatrix(transform);
                 if (matrix != null) {
-                    appendSeparator(true);
+                    appendSeparator();
                     buffer.append("PARAM_MT").appendCodePoint(symbols.getOpeningBracket(0));
                     quote("Affine");
                     indent(+1);
@@ -713,24 +775,23 @@ public class Formatter implements Locali
         final int openQuote  = symbols.getOpeningQuote(0);
         final int closeQuote = symbols.getClosingQuote(0);
         boolean columns = false;
-        requestNewLine = true;
         do {
-            openElement("PARAMETER");
+            openElement(true, "PARAMETER");
             quote(columns ? "num_col" : "num_row");
             append(columns ? numCol : numRow);
-            closeElement();
+            closeElement(false);
         } while ((columns = !columns) == true);
         for (int j=0; j<numRow; j++) {
             for (int i=0; i<numCol; i++) {
                 final double element = matrix.getElement(j, i);
                 if (element != (i == j ? 1 : 0)) {
-                    openElement("PARAMETER");
+                    openElement(true, "PARAMETER");
                     setColor(ElementKind.PARAMETER);
                     buffer.appendCodePoint(openQuote).append("elt_").append(j)
                             .append('_').append(i).appendCodePoint(closeQuote);
                     resetColor();
                     append(element);
-                    closeElement();
+                    closeElement(false);
                 }
             }
         }
@@ -748,7 +809,7 @@ public class Formatter implements Locali
      */
     public void append(final CodeList<?> code) {
         if (code != null) {
-            appendSeparator(false);
+            appendSeparator();
             setColor(ElementKind.CODE_LIST);
             buffer.append(code.name());
             resetColor();
@@ -769,7 +830,7 @@ public class Formatter implements Locali
      */
     public void append(final String text, final ElementKind type) {
         if (text != null) {
-            appendSeparator(false);
+            appendSeparator();
             setColor(type);
             quote(text);
             resetColor();
@@ -790,16 +851,15 @@ public class Formatter implements Locali
      * @param keyword The keyword. Example: {@code "SCOPE"}, {@code "AREA"} or {@code "REMARKS"}.
      * @param text The text, or {@code null} if none.
      */
-    private void append(final String keyword, final InternationalString text, final ElementKind type) {
+    private void appendOnNewLine(final String keyword, final InternationalString text, final ElementKind type) {
         if (text != null) {
             final String localized = CharSequences.trimWhitespaces(text.toString(locale));
             if (localized != null && !localized.isEmpty()) {
-                requestNewLine = true;
-                openElement(keyword);
+                openElement(true, keyword);
                 setColor(type);
                 quote(localized);
                 resetColor();
-                closeElement();
+                closeElement(true);
             }
         }
     }
@@ -852,7 +912,7 @@ public class Formatter implements Locali
      */
     public void append(final Date date) {
         if (date != null) {
-            appendSeparator(false);
+            appendSeparator();
             dateFormat.format(date, buffer, dummy);
         }
     }
@@ -869,7 +929,7 @@ public class Formatter implements Locali
      * @param value The boolean to append to the WKT.
      */
     public void append(final boolean value) {
-        appendSeparator(false);
+        appendSeparator();
         buffer.append(value ? "TRUE" : "FALSE");
     }
 
@@ -885,7 +945,7 @@ public class Formatter implements Locali
      * @param number The integer to append to the WKT.
      */
     public void append(final long number) {
-        appendSeparator(false);
+        appendSeparator();
         setColor(ElementKind.INTEGER);
         numberFormat.setMaximumFractionDigits(0);
         numberFormat.format(number, buffer, dummy);
@@ -904,7 +964,7 @@ public class Formatter implements Locali
      * @param number The floating point value to append to the WKT.
      */
     public void append(final double number) {
-        appendSeparator(false);
+        appendSeparator();
         setColor(ElementKind.NUMBER);
         /*
          * The 2 below is for using two less fraction digits than the expected number accuracy.
@@ -931,7 +991,7 @@ public class Formatter implements Locali
      * </ul>
      */
     private void appendPreset(final double number) {
-        appendSeparator(false);
+        appendSeparator();
         setColor(ElementKind.NUMBER);
         numberFormat.format(number, buffer, dummy);
         resetColor();
@@ -954,7 +1014,7 @@ public class Formatter implements Locali
     public void append(final Unit<?> unit) {
         if (unit != null) {
             final StringBuffer buffer = this.buffer;
-            appendSeparator(requestNewLine);
+            appendSeparator();
             String keyword = "UNIT";
             if (!convention.isSimple()) {
                 if (Units.isLinear(unit)) {
@@ -980,7 +1040,7 @@ public class Formatter implements Locali
             closeQuote(fromIndex);
             resetColor();
             append(Units.toStandardUnit(unit));
-            closeElement();
+            closeElement(false);
         }
     }
 
@@ -1001,10 +1061,10 @@ public class Formatter implements Locali
      */
     public void appendAny(final Object value) {
         if (value == null) {
-            appendSeparator(false);
+            appendSeparator();
             buffer.append("null");
         } else if (value.getClass().isArray()) {
-            appendSeparator(false);
+            appendSeparator();
             buffer.appendCodePoint(symbols.getOpenSequence());
             final int length = Array.getLength(value);
             for (int i=0; i<length; i++) {
@@ -1033,63 +1093,79 @@ public class Formatter implements Locali
     }
 
     /**
-     * Returns the linear unit for expressing lengths, or {@code null} for the default unit of each WKT element.
-     * If {@code null}, then the default value depends on the object to format.
+     * Returns the enclosing WKT element, or {@code null} if element being formatted is the root.
+     * This method can be invoked by child elements having some aspects that depend on the enclosing element.
      *
-     * <p>This method may return a non-null value if the next WKT elements to format are enclosed in a larger WKT
-     * element, and the child elements shall inherit the linear unit of the enclosing element. The most typical
-     * cases are the {@code PARAMETER[…]} elements enclosed in a {@code PROJCS[…]} element.</p>
-     *
-     * <p>The value returned by this method can be ignored if the WKT element to format contains an explicit
-     * {@code UNIT[…]} element.</p>
-     *
-     * @return The unit for linear measurements, or {@code null} for the default unit.
+     * @param  depth 1 for the immediate parent, 2 for the parent of the parent, <i>etc.</i>
+     * @return The parent element at the given depth, or {@code null}.
      */
-    public Unit<Length> getLinearUnit() {
-        return linearUnit;
+    public FormattableObject getEnclosingElement(int depth) {
+        ArgumentChecks.ensurePositive("depth", depth);
+        depth = (enclosingElements.size() - 1) - depth;
+        return (depth >= 0) ? enclosingElements.get(depth) : null;
     }
 
     /**
-     * Sets the unit to use for the next lengths to format. If non-null, the given unit will apply to all WKT elements
-     * that do not define their own {@code UNIT[…]}, until this {@code setLinearUnit(…)} method is invoked again.
+     * Sets the unit to use for the next measurements of the given quantity. If non-null, the given unit will apply
+     * to all WKT elements that do not define their own {@code UNIT[…]}, until this {@code setUnit(…)} method is
+     * invoked again for the same quantity.
+     *
+     * {@section Special case}
+     * If the WKT conventions are {@code WKT1_COMMON_UNITS}, then this method ignores the given unit.
+     * See {@link Convention#WKT1_COMMON_UNITS} javadoc for more information.
      *
+     * @param  <Q> The compile-time type of the {@code quantity} argument.
+     * @param  quantity The quantity, typically as <code>{@linkplain Angle}.class</code> or
+     *         <code>{@linkplain Length}.class</code>.
      * @param unit The new unit, or {@code null} for letting element uses their own default.
      */
-    public void setLinearUnit(final Unit<Length> unit) {
-        linearUnit = unit;
+    public <Q extends Quantity> void setContextualUnit(final Class<Q> quantity, final Unit<Q> unit) {
+        if (!convention.usesCommonUnits()) {
+            units.put(quantity, unit);
+        }
     }
 
     /**
-     * Returns the angular unit for expressing angles, or {@code null} for the default unit of each WKT element.
-     * If {@code null}, then the default value depends on the object to format.
+     * Returns the unit for expressing measurements of the given quantity, or {@code null} for the default unit
+     * of each WKT element. If {@code null}, then the default value depends on the object to format.
      *
      * <p>This method may return a non-null value if the next WKT elements to format are enclosed in a larger WKT
      * element, and the child elements shall inherit the linear unit of the enclosing element. A typical case is
-     * the {@code PRIMEM[…]} element enclosed in a {@code GEOGCS[…]} element.</p>
+     * the angular unit of the {@code PRIMEM[…]} element enclosed in a {@code GEOGCS[…]} element.</p>
      *
      * <p>The value returned by this method can be ignored if the WKT element to format contains an explicit
      * {@code UNIT[…]} element.</p>
      *
-     * @return The unit for angular measurement, or {@code null} for the default unit.
+     * @param  <Q> The compile-time type of the {@code quantity} argument.
+     * @param  quantity The quantity, typically as <code>{@linkplain Angle}.class</code> or
+     *         <code>{@linkplain Length}.class</code>.
+     * @return The unit for measurements of the given quantity, or {@code null} for the default unit.
      */
-    public Unit<Angle> getAngularUnit() {
-        return angularUnit;
+    @SuppressWarnings("unchecked")
+    public <Q extends Quantity> Unit<Q> getContextualUnit(final Class<Q> quantity) {
+        return (Unit<Q>) units.get(quantity);
     }
 
     /**
-     * Sets the unit to use for the next angles to format. If non-null, the given unit will apply to all WKT elements
-     * that do not define their own {@code UNIT[…]}, until this {@code setAngularUnit(…)} method is invoked again.
-     *
-     * {@section Special case}
-     * If the WKT conventions are {@code WKT1_COMMON_UNITS}, then this method ignores the given unit.
-     * See {@link Convention#WKT1_COMMON_UNITS} javadoc for more information.
+     * Returns the unit to use instead than the given one, or the given unit if there is no replacement for it.
+     * This method searches for a unit specified by {@link #setContextualUnit(Class, Unit)} which
+     * {@linkplain Unit#isCompatible(Unit) is compatible} with the given unit.
      *
-     * @param unit The new unit, or {@code null} for letting element uses their own default.
+     * @param  <Q>  The quantity of the unit.
+     * @param  unit The unit to replace by the contextual unit, or {@code null}.
+     * @return A contextual unit compatible with the given unit, or {@code unit}
+     *         if not contextual unit has been found.
      */
-    public void setAngularUnit(final Unit<Angle> unit) {
-        if (!convention.usesCommonUnits()) {
-            angularUnit = unit;
+    @SuppressWarnings("unchecked")
+    public <Q extends Quantity> Unit<Q> toContextualUnit(final Unit<Q> unit) {
+        if (unit != null) {
+            for (final Unit<?> c : units.values()) {
+                if (unit.isCompatible(c)) {
+                    return (Unit<Q>) c;
+                }
+            }
         }
+        return unit;
     }
 
     /**
@@ -1174,25 +1250,48 @@ public class Formatter implements Locali
 
     /**
      * Returns the error message {@link #isInvalidWKT()} is set, or {@code null} otherwise.
-     * If non-null, a cause may be available in the {@link #errorCause} field.
+     * If non-null, a cause may be available in the {@link #getErrorCause()} method.
      */
     final String getErrorMessage() {
         return isInvalidWKT() ? Errors.format(Errors.Keys.CanNotRepresentInFormat_2, "WKT", invalidElement) : null;
     }
 
     /**
+     * Returns the cause of the error, or {@code null} if the cause is not an exception.
+     */
+    final Exception getErrorCause() {
+        return errorCause;
+    }
+
+    /**
      * Returns the WKT formatted by this object.
      *
-     * @return The WKT formatted by this instance.
+     * @return The WKT formatted by this formatter.
      */
+    public String toWKT() {
+        return buffer.toString();
+    }
+
+    /**
+     * Returns a string representation of this formatter for debugging purpose.
+     *
+     * @return A string representation of this formatter.
+     */
+    @Debug
     @Override
     public String toString() {
-        return buffer.toString();
+        final StringBuilder b = new StringBuilder(Classes.getShortClassName(this)).append('[');
+        String separator = "";
+        for (final FormattableObject element : enclosingElements) {
+            b.append(separator).append(Classes.getShortClassName(element));
+            separator = " 〉 ";
+        }
+        return b.append(']').toString();
     }
 
     /**
-     * Clears this formatter before formatting a new object. This method clears the
-     * {@linkplain #getLinearUnit() linear unit} and {@linkplain #isInvalidWKT() WKT validity flag}.
+     * Clears this formatter before formatting a new object.
+     * This method clears also the {@linkplain #isInvalidWKT() WKT validity flag}.
      */
     final void clear() {
         /*
@@ -1203,13 +1302,14 @@ public class Formatter implements Locali
         if (buffer != null) {
             buffer.setLength(0);
         }
-        linearUnit     = null;
-        angularUnit    = null;
+        enclosingElements.clear();
+        units.clear();
+        colorApplied   = 0;
+        margin         = 0;
+        requestNewLine = false;
+        isComplement   = false;
+        highlightError = false;
         invalidElement = null;
         errorCause     = null;
-        highlightError = false;
-        requestNewLine = false;
-        margin         = 0;
-        colorApplied   = 0;
     }
 }

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -29,8 +29,11 @@ import org.apache.sis.util.Deprecable;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.internal.metadata.ReferencingUtilities;
+import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
+import org.apache.sis.io.wkt.Convention;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.util.CharSequences.trimWhitespaces;
@@ -544,7 +547,7 @@ public class ImmutableIdentifier extends
      * @return The WKT keyword: {@code "ID"} (WKT 2) or {@code "AUTHORITY"} (WKT 1).
      */
     @Override
-    protected String formatTo(Formatter formatter) {
+    protected String formatTo(final Formatter formatter) {
         String keyword = null;
         final String code = getCode();
         if (code != null) {
@@ -555,19 +558,40 @@ public class ImmutableIdentifier extends
                 citation  = null;
             }
             if (codeSpace != null) {
-                if (formatter.getConvention().isWKT1()) {
+                final Convention convention = formatter.getConvention();
+                if (convention.isWKT1()) {
                     keyword = "AUTHORITY";
                     formatter.append(codeSpace, null);
                     formatter.append(code, null);
                 } else {
                     keyword = "ID";
                     formatter.append(codeSpace, null);
-                    append(formatter, code);
+                    appendCode(formatter, code);
                     final String version = getVersion();
                     if (version != null) {
-                        append(formatter, version);
+                        appendCode(formatter, version);
                         formatter.append(citation, null);
                     }
+                    /*
+                     * Do not format the optional URI element for internal convention,
+                     * because this property is currently computed rather than stored.
+                     * Simplified convention formats only for the ID of root element.
+                     */
+                    final boolean shownURI;
+                    switch (convention) {
+                        default:              shownURI = true;  break;
+                        case INTERNAL:        shownURI = false; break;
+                        case WKT2_SIMPLIFIED: shownURI = formatter.getEnclosingElement(2) == null; break;
+                    }
+                    if (shownURI) {
+                        final FormattableObject parent = formatter.getEnclosingElement(1);
+                        if (parent != null && ReferencingUtilities.usesURN(codeSpace)) {
+                            final String type = ReferencingUtilities.toURNType(parent.getClass());
+                            if (type != null) {
+                                formatter.append(new URI(type, codeSpace, version, code));
+                            }
+                        }
+                    }
                 }
             }
         }
@@ -575,12 +599,12 @@ public class ImmutableIdentifier extends
     }
 
     /**
-     * Appends the given text as an integer if possible, or as a text otherwise.
+     * Appends the given code or version number as an integer if possible, or as a text otherwise.
      *
      * {@note ISO 19162 specifies "number or text". In Apache SIS, we restrict the numbers to integers
      *        because handling version numbers like "8.2" as floating point numbers can be confusing.}
      */
-    private static void append(final Formatter formatter, final String text) {
+    private static void appendCode(final Formatter formatter, final String text) {
         if (text != null) {
             final long n;
             try {
@@ -592,4 +616,35 @@ public class ImmutableIdentifier extends
             formatter.append(n);
         }
     }
+
+    /**
+     * The {@code URI[…]} element inside an {@code ID[…]}.
+     */
+    private static final class URI extends FormattableObject {
+        /** The components of the URI to format. */
+        private final String type, codeSpace, version, code;
+
+        /** Creates a new URI with the given components. */
+        URI(final String type, final String codeSpace, final String version, final String code) {
+            this.type      = type;
+            this.codeSpace = codeSpace;
+            this.version   = version;
+            this.code      = code;
+        }
+
+        /** Formats the URI. */
+        @Override
+        protected String formatTo(final Formatter formatter) {
+            final StringBuilder buffer = new StringBuilder(DefinitionURI.PREFIX)
+                    .append(DefinitionURI.SEPARATOR).append(type)
+                    .append(DefinitionURI.SEPARATOR).append(codeSpace)
+                    .append(DefinitionURI.SEPARATOR);
+            if (version != null) {
+                buffer.append(version);
+            }
+            buffer.append(DefinitionURI.SEPARATOR).append(code);
+            formatter.append(buffer.toString(), null);
+            return "URI";
+        }
+    }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -148,7 +148,7 @@ public final class Code {
                 }
             }
             /*
-             * If no "urn:" or "http:" form has been found, try to create a "urn:" form from the first identifier.
+             * If no "urn:" or "http:" form has been found, try to create a "urn:" form the first identifier.
              * For example "EPSG:4326" may be converted to "urn:ogc:def:crs:EPSG:8.2:4326". If the first identifier
              * can not be converted to a "urn:" form, then it will be returned as-is.
              */

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValue.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -695,19 +695,8 @@ public class DefaultParameterValue<T> ex
      */
     @Override
     protected String formatTo(final Formatter formatter) {
-        Unit<?> unit = descriptor.getUnit();
-        if (unit != null && !Unit.ONE.equals(unit)) {
-            final Unit<?> linearUnit = formatter.getLinearUnit();
-            if (linearUnit != null && unit.isCompatible(linearUnit)) {
-                unit = linearUnit;
-            } else {
-                final Unit<?> angularUnit = formatter.getAngularUnit();
-                if (angularUnit != null && unit.isCompatible(angularUnit)) {
-                    unit = angularUnit;
-                }
-            }
-        }
         WKTUtilities.appendName(descriptor, formatter, ElementKind.PARAMETER);
+        final Unit<?> unit = formatter.toContextualUnit(descriptor.getUnit());
         if (unit != null) {
             double value;
             try {

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -414,17 +414,21 @@ public class AbstractCRS extends Abstrac
     @Override
     protected String formatTo(final Formatter formatter) {
         final String keyword = super.formatTo(formatter);
+        formatter.newLine();
         formatter.append(getDatum());
         final Unit<?> unit = getUnit();
+        formatter.newLine();
         formatter.append(unit);
         final CoordinateSystem cs = coordinateSystem;
         final int dimension = cs.getDimension();
         for (int i=0; i<dimension; i++) {
+            formatter.newLine();
             formatter.append(cs.getAxis(i));
         }
         if (unit == null) {
             formatter.setInvalidWKT(cs, null);
         }
+        formatter.newLine(); // For writing the ID[…] element on its own line.
         return keyword;
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultCompoundCRS.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -391,8 +391,10 @@ public class DefaultCompoundCRS extends 
     protected String formatTo(final Formatter formatter) {
         WKTUtilities.appendName(this, formatter, null);
         for (final CoordinateReferenceSystem element : components) {
+            formatter.newLine();
             formatter.append(element);
         }
+        formatter.newLine(); // For writing the ID[…] element on its own line.
         return "COMPD_CS";
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeocentricCRS.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -222,8 +222,11 @@ public class DefaultGeocentricCRS extend
         WKTUtilities.appendName(this, formatter, null);
         final Unit<?> unit = getUnit();
         final GeodeticDatum datum = getDatum();
+        formatter.newLine();
         formatter.append(datum);
+        formatter.newLine();
         formatter.append(datum.getPrimeMeridian());
+        formatter.newLine();
         formatter.append(unit);
         CoordinateSystem cs = getCoordinateSystem();
         if (formatter.getConvention().isWKT1()) {
@@ -235,11 +238,13 @@ public class DefaultGeocentricCRS extend
         }
         final int dimension = cs.getDimension();
         for (int i=0; i<dimension; i++) {
+            formatter.newLine();
             formatter.append(cs.getAxis(i));
         }
         if (unit == null) {
             formatter.setInvalidWKT(this, null);
         }
+        formatter.newLine(); // For writing the ID[…] element on its own line.
         return "GEOCCS";
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -225,22 +225,27 @@ public class DefaultGeographicCRS extend
     @Override
     protected String formatTo(final Formatter formatter) {
         WKTUtilities.appendName(this, formatter, null);
-        final Unit<Angle> oldUnit = formatter.getAngularUnit();
+        final Unit<Angle> oldUnit = formatter.getContextualUnit(Angle.class);
         final Unit<Angle> unit = getAngularUnit(getCoordinateSystem());
         final GeodeticDatum datum = getDatum();
-        formatter.setAngularUnit(unit);
+        formatter.setContextualUnit(Angle.class, unit);
+        formatter.newLine();
         formatter.append(datum);
+        formatter.newLine();
         formatter.append(datum.getPrimeMeridian());
+        formatter.newLine();
         formatter.append(unit);
         final EllipsoidalCS cs = getCoordinateSystem();
         final int dimension = cs.getDimension();
         for (int i=0; i<dimension; i++) {
+            formatter.newLine();
             formatter.append(cs.getAxis(i));
         }
         if (!unit.equals(getUnit())) {
             formatter.setInvalidWKT(this, null);
         }
-        formatter.setAngularUnit(oldUnit);
+        formatter.setContextualUnit(Angle.class, oldUnit);
+        formatter.newLine(); // For writing the ID[…] element on its own line.
         return "GEOGCS";
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/AbstractCS.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -423,6 +423,7 @@ public class AbstractCS extends Abstract
     protected String formatTo(final Formatter formatter) {
         final String keyword = super.formatTo(formatter);
         for (final CoordinateSystemAxis axe : axes) {
+            formatter.newLine();
             formatter.append(axe);
         }
         return keyword;

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -509,16 +509,19 @@ public class DefaultGeodeticDatum extend
         // Do NOT invokes the super-class method, because
         // horizontal datum do not write the datum type.
         WKTUtilities.appendName(this, formatter, ElementKind.DATUM);
+        formatter.newLine();
         formatter.append(ellipsoid instanceof FormattableObject ? (FormattableObject) ellipsoid :
                          DefaultEllipsoid.castOrCopy(ellipsoid));
         if (bursaWolf != null) {
             for (final BursaWolfParameters candidate : bursaWolf) {
                 if (candidate.isToWGS84()) {
+                    formatter.newLine();
                     formatter.append(candidate);
                     break;
                 }
             }
         }
+        formatter.newLine(); // For writing the ID[…] element on its own line.
         return "DATUM";
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -339,7 +339,7 @@ public class DefaultPrimeMeridian extend
     @Override
     protected String formatTo(final Formatter formatter) {
         super.formatTo(formatter);
-        Unit<Angle> unit = formatter.getAngularUnit();
+        Unit<Angle> unit = formatter.getContextualUnit(Angle.class);
         if (unit == null) {
             unit = NonSI.DEGREE_ANGLE;
         }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractReferenceSystemTest.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -120,7 +120,7 @@ public final strictfp class AbstractRefe
                 "  AREA[“Netherlands offshore.”],\n" +
                 "  BBOX[51.43, 2.54, 55.77, 6.40],\n" +
                 "  VERTICALEXTENT[-1000, -10, LENGTHUNIT[“metre”, 1.0]],\n" +
-                "  ID[“EPSG”, 4326, “8.2”, “OGP”],\n" +
+                "  ID[“EPSG”, 4326, “8.2”, “OGP”, URI[“urn:ogc:def:referenceSystem:EPSG:8.2:4326”]],\n" +
                 "  REMARKS[“注です。”]]",
                 object);
 
@@ -130,7 +130,7 @@ public final strictfp class AbstractRefe
                 "  AREA[“Netherlands offshore.”],\n" +
                 "  BBOX[51.43, 2.54, 55.77, 6.40],\n" +
                 "  VERTICALEXTENT[-1000, -10],\n" +
-                "  ID[“EPSG”, 4326, “8.2”, “OGP”],\n" +
+                "  ID[“EPSG”, 4326, “8.2”, “OGP”, URI[“urn:ogc:def:referenceSystem:EPSG:8.2:4326”]],\n" +
                 "  REMARKS[“注です。”]]",
                 object);
     }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRSTest.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRSTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/crs/HardCodedCRSTest.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -17,6 +17,7 @@
 package org.apache.sis.referencing.crs;
 
 import org.opengis.test.ValidatorContainer;
+import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.test.TestCase;
 import org.apache.sis.test.DependsOn;
 import org.junit.Test;
@@ -72,13 +73,48 @@ public final strictfp class HardCodedCRS
      */
     @Test
     public void testWKT() {
-        assertWktEquals(
+        assertWktEquals(Convention.WKT1,
+                "GEOGCS[“WGS 84”,\n" +
+                "  DATUM[“World Geodetic System 1984”,\n" +
+                "    SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
+                "  PRIMEM[“Greenwich”, 0.0],\n" +
+                "  UNIT[“degree”, 0.017453292519943295],\n" +
+                "  AXIS[“Geodetic longitude”, EAST],\n" +
+                "  AXIS[“Geodetic latitude”, NORTH]]",
+                WGS84);
+
+        assertWktEquals(Convention.WKT2,
+                "GEOGCS[“WGS 84”,\n" +
+                "  DATUM[“World Geodetic System 1984”,\n" +
+                "    SPHEROID[“WGS84”, 6378137.0, 298.257223563]],\n" +
+                "  PRIMEM[“Greenwich”, 0.0],\n" +
+                "  ANGLEUNIT[“degree”, 0.017453292519943295],\n" +
+                "  AXIS[“Geodetic longitude”, EAST],\n" +
+                "  AXIS[“Geodetic latitude”, NORTH],\n" +
+                "  AREA[“World”],\n" +
+                "  BBOX[-90.00, -180.00, 90.00, 180.00]]",
+                WGS84);
+
+        assertWktEquals(Convention.WKT2_SIMPLIFIED,
                 "GEOGCS[“WGS 84”,\n" +
                 "  DATUM[“World Geodetic System 1984”,\n" +
                 "    SPHEROID[“WGS84”, 6378137.0, 298.257223563],\n" +
                 "    ID[“EPSG”, 6326]],\n" +
                 "  PRIMEM[“Greenwich”, 0.0, ID[“EPSG”, 8901]],\n" +
-                "  ANGLEUNIT[“degree”, 0.017453292519943295],\n" +
+                "  UNIT[“degree”, 0.017453292519943295],\n" +
+                "  AXIS[“Geodetic longitude”, EAST],\n" +
+                "  AXIS[“Geodetic latitude”, NORTH],\n" +
+                "  AREA[“World”],\n" +
+                "  BBOX[-90.00, -180.00, 90.00, 180.00]]",
+                WGS84);
+
+        assertWktEquals(Convention.INTERNAL,
+                "GEOGCS[“WGS 84”,\n" +
+                "  DATUM[“World Geodetic System 1984”,\n" +
+                "    SPHEROID[“WGS84”, 6378137.0, 298.257223563],\n" +
+                "    ID[“EPSG”, 6326]],\n" +
+                "  PRIMEM[“Greenwich”, 0.0, ID[“EPSG”, 8901]],\n" +
+                "  UNIT[“degree”, 0.017453292519943295],\n" +
                 "  AXIS[“Geodetic longitude”, EAST],\n" +
                 "  AXIS[“Geodetic latitude”, NORTH],\n" +
                 "  AREA[“World”],\n" +

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -27,11 +27,13 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.test.Validators;
 import org.apache.sis.xml.Namespaces;
+import org.apache.sis.io.wkt.Convention;
 import org.apache.sis.metadata.iso.extent.DefaultExtent;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.test.XMLTestCase;
 import org.apache.sis.test.DependsOnMethod;
 import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.TestStep;
 import org.junit.Test;
 
 import static org.apache.sis.test.MetadataAssert.*;
@@ -221,10 +223,14 @@ public final strictfp class DefaultGeode
     /**
      * Tests unmarshalling.
      *
+     * <p>This method is part of a chain.
+     * The next method is {@link #testWKT()}.</p>
+     *
+     * @return The unmarshalled datum.
      * @throws JAXBException If an error occurred during unmarshalling.
      */
-    @Test
-    public void testUnmarshalling() throws JAXBException {
+    @TestStep
+    public DefaultGeodeticDatum testUnmarshalling() throws JAXBException {
         final DefaultGeodeticDatum datum = unmarshalFile(DefaultGeodeticDatum.class, XML_FILE);
         assertIsWGS84(datum, true);
         /*
@@ -241,5 +247,43 @@ public final strictfp class DefaultGeode
                 datum.getRealizationEpoch());
         assertEquals("remarks", "Defining parameters cited in EPSG database.",
                 datum.getEllipsoid().getRemarks().toString());
+        return datum;
+    }
+
+    /**
+     * Tests the WKT formatting of the datum created by {@link #testUnmarshalling()}.
+     *
+     * @throws JAXBException If an error occurred during unmarshalling.
+     */
+    @Test
+    public void testWKT() throws JAXBException {
+        final DefaultGeodeticDatum datum = testUnmarshalling();
+        assertWktEquals(Convention.WKT1,
+                "DATUM[“World Geodetic System 1984”,\n" +
+                "  SPHEROID[“WGS 84”, 6378137.0, 298.257223563],\n" +
+                "  AUTHORITY[“EPSG”, “6326”]]",
+                datum);
+
+        assertWktEquals(Convention.WKT2,
+                "DATUM[“World Geodetic System 1984”,\n" +
+                "  SPHEROID[“WGS 84”, 6378137.0, 298.257223563,\n" +
+                "    REMARKS[“Defining parameters cited in EPSG database.”]],\n" +
+                "  SCOPE[“Satellite navigation.”],\n" +
+                "  AREA[“World.”],\n" +
+                "  BBOX[-90.00, -180.00, 90.00, 180.00],\n" +
+                "  ID[“EPSG”, 6326, URI[“urn:ogc:def:datum:EPSG::6326”]],\n" +
+                "  REMARKS[“No distinction between the original and subsequent WGS 84 frames.”]]",
+                datum);
+
+        assertWktEquals(Convention.INTERNAL,
+                "DATUM[“World Geodetic System 1984”,\n" +
+                "  SPHEROID[“WGS 84”, 6378137.0, 298.257223563, ID[“EPSG”, 7030],\n" +
+                "    REMARKS[“Defining parameters cited in EPSG database.”]],\n" +
+                "  SCOPE[“Satellite navigation.”],\n" +
+                "  AREA[“World.”],\n" +
+                "  BBOX[-90.00, -180.00, 90.00, 180.00],\n" +
+                "  ID[“EPSG”, 6326],\n" +
+                "  REMARKS[“No distinction between the original and subsequent WGS 84 frames.”]]",
+                datum);
     }
 }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultPrimeMeridianTest.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -147,8 +147,8 @@ public final strictfp class DefaultPrime
         assertEquals("Equivalent to 2°20′14.025″.", pm.getRemarks().toString());
         assertNull("name.codeSpace", pm.getName().getCodeSpace());
         assertWktEquals(
-                "PRIMEM[“Paris”, 2.33722917, ID[“EPSG”, 8903],\n" +
-                "REMARKS[“Equivalent to 2°20′14.025″.”]]", pm);
+                "PRIMEM[“Paris”, 2.33722917, ID[“EPSG”, 8903, URI[“urn:ogc:def:meridian:EPSG::8903”]],\n" +
+                "  REMARKS[“Equivalent to 2°20′14.025″.”]]", pm);
         assertXmlEquals(
                 "<gml:PrimeMeridian xmlns:gml=\"" + Namespaces.GML + "\">\n" +
                 "  <gml:identifier codeSpace=\"OGP\">urn:ogc:def:meridian:EPSG::8903</gml:identifier>\n" +

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -24,6 +24,7 @@ import javax.xml.bind.annotation.XmlValu
 import javax.xml.bind.annotation.XmlAttribute;
 import org.apache.sis.internal.jaxb.Context;
 import org.apache.sis.internal.jaxb.Schemas;
+import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.measure.Units;
 
@@ -142,7 +143,7 @@ public final class Measure {
         if (!asXPointer) {
             final Integer code = Units.getEpsgCode(unit, inAxis);
             if (code != null) {
-                return "urn:ogc:def:uom:EPSG::" + code;
+                return DefinitionURI.PREFIX + ":uom:EPSG::" + code;
             }
         }
         if (unit == null || unit.equals(Unit.ONE)) {

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -101,6 +101,11 @@ import static org.apache.sis.internal.ut
  */
 public final class DefinitionURI {
     /**
+     * The {@value} prefix used in all URI supported by this class.
+     */
+    public static final String PREFIX = "urn:ogc:def";
+
+    /**
      * The URN separator.
      */
     public static final char SEPARATOR = ':';
@@ -442,7 +447,7 @@ public final class DefinitionURI {
      * @return An identifier using the URN syntax, or {@code null} if an information is missing.
      */
     public static String format(final String type, final ReferenceIdentifier identifier) {
-        final StringBuilder buffer = new StringBuilder("urn:ogc:def");
+        final StringBuilder buffer = new StringBuilder(PREFIX);
         for (int p=0; p<4; p++) {
             final String component;
             switch (p) {
@@ -469,7 +474,7 @@ public final class DefinitionURI {
      * @return A URN representation of this URI.
      */
     public String toURN() {
-        final StringBuilder buffer = new StringBuilder("urn:ogc:def");
+        final StringBuilder buffer = new StringBuilder(PREFIX);
         int n = 4;
         if (parameters != null) {
             n += parameters.length;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/AbstractName.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -426,7 +426,7 @@ public abstract class AbstractName imple
             final LocalName thatNext = thatNames.next();
             if (thisNext == this && thatNext == name) {
                 // Never-ending loop: usually an implementation error
-                throw new IllegalStateException(Errors.format(Errors.Keys.InfiniteRecursivity));
+                throw new IllegalStateException(Errors.format(Errors.Keys.CircularReference));
             }
             final int compare = thisNext.compareTo(thatNext);
             if (compare != 0) {

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=1567407&r1=1567406&r2=1567407&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] Tue Feb 11 21:48:54 2014
@@ -125,6 +125,11 @@ public final class Errors extends Indexe
         public static final short CanNotSetPropertyValue_1 = 11;
 
         /**
+         * Circular reference.
+         */
+        public static final short CircularReference = 52;
+
+        /**
          * Class ‘{0}’ is not final.
          */
         public static final short ClassNotFinal_1 = 12;
@@ -353,11 +358,6 @@ public final class Errors extends Indexe
         public static final short InfiniteArgumentValue_1 = 51;
 
         /**
-         * Infinite recursivity.
-         */
-        public static final short InfiniteRecursivity = 52;
-
-        /**
          * Argument ‘{0}’ shall contain at least {1} elements. A number of {2} is insufficient.
          */
         public static final short InsufficientArgumentSize_3 = 53;

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=1567407&r1=1567406&r2=1567407&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] Tue Feb 11 21:48:54 2014
@@ -36,6 +36,7 @@ CanNotParseFile_2                 = Can 
 CanNotRead_1                      = Can not read \u201c{0}\u201d.
 CanNotRepresentInFormat_2         = Can not represent \u201c{1}\u201d in the {0} format.
 CanNotSetPropertyValue_1          = Can not set a value for property \u201c{0}\u201d.
+CircularReference                 = Circular reference.
 ClassNotFinal_1                   = Class \u2018{0}\u2019 is not final.
 CloneNotSupported_1               = Can not clone an object of type \u2018{0}\u2019.
 ColinearAxisDirections_2          = Axis directions {0} and {1} are colinear.
@@ -81,7 +82,6 @@ IdentifierAlreadyBound_1          = Iden
 IndexOutOfBounds_1                = Index {0} is out of bounds.
 IndicesOutOfBounds_2              = Indices ({0}, {1}) are out of bounds.
 InfiniteArgumentValue_1           = Argument \u2018{0}\u2019 can not take an infinite value.
-InfiniteRecursivity               = Infinite recursivity.
 InsufficientArgumentSize_3        = Argument \u2018{0}\u2019 shall contain at least {1} elements. A number of {2} is insufficient.
 KeyCollision_1                    = A different value is already associated to the \u201c{0}\u201d key.
 MandatoryAttribute_2              = Attribute \u201c{0}\u201d is mandatory for an object of type \u2018{1}\u2019.

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=1567407&r1=1567406&r2=1567407&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] Tue Feb 11 21:48:54 2014
@@ -26,6 +26,7 @@ CanNotParseFile_2                 = Ne p
 CanNotRead_1                      = Ne peut pas lire \u00ab\u202f{0}\u202f\u00bb.
 CanNotRepresentInFormat_2         = Ne peut pas repr\u00e9senter \u00ab\u202f{1}\u202f\u00bb dans le format {0}.
 CanNotSetPropertyValue_1          = Ne peut pas d\u00e9finir une valeur pour la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb.
+CircularReference                 = R\u00e9f\u00e9rence circulaire.
 ClassNotFinal_1                   = La classe \u2018{0}\u2019 n\u2019est pas finale.
 CloneNotSupported_1               = Un objet de type \u2018{0}\u2019 ne peut pas \u00eatre clon\u00e9.
 ColinearAxisDirections_2          = Les directions d\u2019axes {0} et {1} sont colin\u00e9aires.
@@ -71,7 +72,6 @@ IdentifierAlreadyBound_1          = L\u2
 IndexOutOfBounds_1                = L\u2019index {0} est en dehors des limites permises.
 IndicesOutOfBounds_2              = Les index ({0}, {1}) sont en dehors des limites permises.
 InfiniteArgumentValue_1           = L\u2019argument \u2018{0}\u2019 ne peut pas prendre une valeur infinie.
-InfiniteRecursivity               = R\u00e9cursivit\u00e9 infinie.
 InsufficientArgumentSize_3        = L\u2019argument \u2018{0}\u2019 doit contenir au moins {1} \u00e9l\u00e9ments. Un nombre de {2} est insuffisant.
 KeyCollision_1                    = Une valeur diff\u00e9rente est d\u00e9j\u00e0 associ\u00e9e \u00e0 la cl\u00e9 \u00ab\u202f{0}\u202f\u00bb.
 MandatoryAttribute_2              = L\u2019attribut \u00ab\u202f{0}\u202f\u00bb est obligatoire pour un objet de type \u2018{1}\u2019.

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestStep.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestStep.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestStep.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/TestStep.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -25,11 +25,12 @@ import java.lang.annotation.RetentionPol
 
 /**
  * A test method producing an object to be used by another test method.
- * Such methods are annotated with this {@code TestStep} annotation instead than the
- * JUnit {@link org.junit.Test} one. However in current implementation, those methods
- * must be explicitely invoked from another method. This is because JUnit 4 does not
- * support tests chaining, so this annotation is currently used only for documentation
- * purpose.
+ *
+ * <p>If this annotation was supported, we would annotate some methods with the {@code TestStep} annotation
+ * instead than the JUnit {@link org.junit.Test} one. However in current implementation, this functionality
+ * is not supported and the test step methods must be explicitely invoked from another method. Consequently
+ * this annotation is currently used only for documentation purpose, in case a future JUnit version would
+ * support tests chaining.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3

Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java?rev=1567407&r1=1567406&r2=1567407&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/collection/DefaultTreeTableTest.java [UTF-8] Tue Feb 11 21:48:54 2014
@@ -50,7 +50,7 @@ public final strictfp class DefaultTreeT
      *         after this one.
      */
     @TestStep
-    private static DefaultTreeTable testTableCreation() {
+    public static DefaultTreeTable testTableCreation() {
         final DefaultTreeTable table = new DefaultTreeTable(NAME, TYPE);
         assertEquals("Number of columns:",      2,                  table.columnIndices.size());
         assertEquals("Index of first column:",  Integer.valueOf(0), table.columnIndices.get(NAME));
@@ -71,7 +71,7 @@ public final strictfp class DefaultTreeT
      * @return The root node produced by this method.
      */
     @TestStep
-    private static DefaultTreeTable.Node testNodeCreation(final DefaultTreeTable table) {
+    public static DefaultTreeTable.Node testNodeCreation(final DefaultTreeTable table) {
         /*
          * Create a root node with an initially empty list of children.
          */
@@ -114,7 +114,7 @@ public final strictfp class DefaultTreeT
      * @param root The root node where to move children.
      */
     @TestStep
-    private static void testNodeDisplacement(final TreeTable.Node root) {
+    public static void testNodeDisplacement(final TreeTable.Node root) {
         final Collection<TreeTable.Node> rootChildren, nodeChildren;
         final TreeTable.Node node1 = getSingleton(rootChildren = root .getChildren());
         final TreeTable.Node node2 = getSingleton(nodeChildren = node1.getChildren());
@@ -142,10 +142,11 @@ public final strictfp class DefaultTreeT
      * <p>This method is part of a chain.
      * The previous method is {@link #testNodeDisplacement(TreeTable.Node)}.</p>
      *
+     * @param  table The table to clone.
      * @throws CloneNotSupportedException Should never happen.
      */
     @TestStep
-    private void testClone(final DefaultTreeTable table) throws CloneNotSupportedException {
+    public static void testClone(final DefaultTreeTable table) throws CloneNotSupportedException {
         final TreeTable newTable = table.clone();
         assertNotSame("clone", table, newTable);
         assertEquals("newTable.equals(table)", table, newTable);
@@ -159,9 +160,11 @@ public final strictfp class DefaultTreeT
      *
      * <p>This method is part of a chain.
      * The previous method is {@link #testNodeDisplacement(TreeTable.Node)}.</p>
+     *
+     * @param table The table to serialize.
      */
     @TestStep
-    private void testSerialization(final TreeTable table) {
+    public static void testSerialization(final TreeTable table) {
         final TreeTable newTable = assertSerializedEquals(table);
         getChildrenList(newTable).get(1).setValue(NAME, "New name");
         assertFalse("newTable.equals(table)", newTable.equals(table));



Mime
View raw message