Author: desruisseaux
Date: Mon Jan 27 15:06:18 2014
New Revision: 1561702

URL: http://svn.apache.org/r1561702
Log:
Tuned the API for setting paired brackets and code symbols,
and use it in tests for more redeable String constants.

Modified:
    
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
    
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
    
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Symbols.java
    
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java
    
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/FormatterTest.java
    
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/SymbolsTest.java
    
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/Assert.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/cs/DefaultCoordinateSystemAxisTest.java
    
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.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-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java

Modified: 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -32,6 +32,12 @@ import static javax.measure.unit.NonSI.D
  * This enumeration specifies whether to use the <cite>Well Known Text</cite> 
format defined by ISO 19162
  * (also known as “WKT 2”), or whether to use the format previously defined in 
OGC 01-009 (referenced as “WKT 1”).
  *
+ * {@section Apache SIS extensions to WKT 2}
+ * The WKT 2 format does not define any syntax for {@link 
org.opengis.referencing.operation.MathTransform} instances,
+ * and consequently does not provide {@link 
org.opengis.referencing.crs.DerivedCRS} representations. Apache SIS uses
+ * the WKT 1 format for {@code MathTransform} and extends the WKT 2 format 
with a {@code DerivedCRS} representation
+ * that contains those math transforms.
+ *
  * {@section WKT 1 variants}
  * The WKT 2 format should be parsed and formatted consistently by all 
softwares.
  * But the WKT 1 format has been interpreted differently by various 
implementors.
@@ -63,11 +69,8 @@ public enum Convention {
      * This is the default convention for all WKT formatting in the Apache SIS 
library.
      *
      * <p>Unless otherwise specified by {@link 
WKTFormat#setNameAuthority(Citation)}, when using
-     * this convention SIS will favor <a href="http://www.epsg.org";>EPSG</a> 
definitions of
-     * projection and parameter names.</p>
-     *
-     * @see Citations#ISO
-     * @see Citations#EPSG
+     * this convention SIS will favor {@linkplain Citations#EPSG EPSG} 
definitions of projection
+     * and parameter names.</p>
      */
     WKT2(Citations.EPSG, false, false),
 
@@ -77,19 +80,22 @@ public enum Convention {
      * <a 
href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html";>on
 GeoAPI</a>.
      *
      * <p>Unless otherwise specified by {@link 
WKTFormat#setNameAuthority(Citation)}, when using
-     * this convention SIS will favor OGC definitions of projection and 
parameter names.</p>
+     * this convention SIS will favor {@linkplain Citations#OGC OGC} 
definitions of projection
+     * and parameter names.</p>
      *
-     * <p>For {@link GeocentricCRS}, this convention uses the legacy set of 
Cartesian axes. Those axes were
-     * defined in OGC 01-009 as <var>Other</var>, <var>Easting</var> and 
<var>Northing</var> in metres:</p>
+     * {@section Differences compared to WKT 2}
+     * WKT 1 and WKT 2 differ in their keywords and syntax, but also in more 
subtle ways regarding parameter
+     * and code list values. For {@link GeocentricCRS}, WKT 1 uses a legacy 
set of Cartesian axes which were
+     * defined in OGC 01-009. Those axes use the <var>Other</var>, 
<var>Easting</var> and <var>Northing</var>
+     * {@linkplain org.opengis.referencing.cs.AxisDirection axis directions} 
instead than the geocentric ones,
+     * as shown in the following table:
      *
      * <table class="sis">
-     *   <tr><th>ISO 19111</th>    <th>OGC 01-009</th> <th>Direction</th></tr>
+     *   <tr><th>ISO 19111</th>    <th>OGC 01-009</th> 
<th>Description</th></tr>
      *   <tr><td>Geocentric X</td> <td>Other</td>      <td>Toward prime 
meridian</td></tr>
      *   <tr><td>Geocentric Y</td> <td>Easting</td>    <td>Toward 90°E 
longitude</td></tr>
      *   <tr><td>Geocentric Z</td> <td>Northing</td>   <td>Toward north 
pole</td></tr>
      * </table>
-     *
-     * @see Citations#OGC
      */
     WKT1(Citations.OGC, true, false),
 

Modified: 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -539,8 +539,8 @@ public class Formatter {
         final int numCol = matrix.getNumCol();
         final int openingBracket  = symbols.getOpeningBracket(0);
         final int closingBracket  = symbols.getClosingBracket(0);
-        final int openQuote       = symbols.getOpenQuote();
-        final int closeQuote      = symbols.getCloseQuote();
+        final int openQuote       = symbols.getOpeningQuote(0);
+        final int closeQuote      = symbols.getClosingQuote(0);
         final String separator    = symbols.getSeparator();
         final StringBuffer buffer = this.buffer;
         boolean columns = false;
@@ -701,7 +701,8 @@ public class Formatter {
      * Appends the given string as a quoted text.
      */
     private void quote(final String text) {
-        
buffer.appendCodePoint(symbols.getOpenQuote()).append(text).appendCodePoint(symbols.getCloseQuote());
+        buffer.appendCodePoint(symbols.getOpeningQuote(0)).append(text)
+              .appendCodePoint(symbols.getClosingQuote(0));
     }
 
     /**
@@ -766,7 +767,7 @@ public class Formatter {
             appendSeparator(requestNewLine);
             
buffer.append("UNIT").appendCodePoint(symbols.getOpeningBracket(0));
             setColor(ElementKind.UNIT);
-            buffer.appendCodePoint(symbols.getOpenQuote());
+            buffer.appendCodePoint(symbols.getOpeningQuote(0));
             if (NonSI.DEGREE_ANGLE.equals(unit)) {
                 buffer.append("degree");
             } else if (SI.METRE.equals(unit)) {
@@ -774,7 +775,7 @@ public class Formatter {
             } else {
                 unitFormat.format(unit, buffer, dummy);
             }
-            buffer.appendCodePoint(symbols.getCloseQuote());
+            buffer.appendCodePoint(symbols.getClosingQuote(0));
             resetColor();
             append(Units.toStandardUnit(unit));
             buffer.appendCodePoint(symbols.getClosingBracket(0));

Modified: 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Symbols.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Symbols.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Symbols.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Symbols.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -34,7 +34,8 @@ import static org.apache.sis.util.Argume
  *   <li>An English locale for {@linkplain java.text.DecimalFormatSymbols 
decimal format symbols}.</li>
  *   <li>Square brackets, as in {@code DATUM["WGS84"]}. An alternative allowed 
by the WKT
  *       specification is curly brackets as in {@code DATUM("WGS84")}.</li>
- *   <li>English quotation mark ({@code '"'}).</li>
+ *   <li>English quotation mark ({@code '"'}). SIS also accepts {@code “…”} 
quotation marks
+ *       for more readable {@link String} constants in Java code.</li>
  *   <li>Coma separator followed by a space ({@code ", "}).</li>
  * </ul>
  *
@@ -62,13 +63,15 @@ public class Symbols implements Localize
      * A set of symbols with values between square brackets, like {@code 
DATUM["WGS84"]}.
      * This is the most frequently used WKT format.
      */
-    public static final Symbols SQUARE_BRACKETS = new Immutable('[', ']', '(', 
')');
+    public static final Symbols SQUARE_BRACKETS = new Immutable(
+            new int[] {'[', ']', '(', ')'}, new int[] {'"', '"', '“', '”'});
 
     /**
      * A set of symbols with values between parentheses, like {@code 
DATUM("WGS84")}.
      * This is a less frequently used but legal WKT format.
      */
-    public static final Symbols CURLY_BRACKETS = new Immutable('(', ')', '[', 
']');
+    public static final Symbols CURLY_BRACKETS = new Immutable(
+            new int[] {'(', ')', '[', ']'}, SQUARE_BRACKETS.quotes);
 
     /**
      * The default set of symbols, as documented in the class javadoc.
@@ -98,16 +101,23 @@ public class Symbols implements Localize
     private int[] brackets;
 
     /**
-     * The character (as Unicode code point) used for opening ({@code 
openSequence})
-     * or closing ({@code closeSequence}) an array or enumeration.
+     * List of characters (as Unicode code point) used for opening or closing 
a quoted text.
+     * The array shall comply to the following restrictions:
+     *
+     * <ul>
+     *   <li>The characters at index 0 and 1 are the preferred opening and 
closing quotes respectively.</li>
+     *   <li>For each even index <var>i</var>, {@code quotes[i+1]} is the 
closing quote matching {@code quotes[i]}.</li>
+     * </ul>
+     *
+     * Both opening and closing quotes are usually {@code '"'}.
      */
-    private int openSequence, closeSequence;
+    private int[] quotes;
 
     /**
-     * The character (as Unicode code point) used for opening ({@code 
openQuote}) or
-     * closing ({@code closeQuote}) a quoted text. This is usually {@code '"'}.
+     * The character (as Unicode code point) used for opening ({@code 
openSequence})
+     * or closing ({@code closeSequence}) an array or enumeration.
      */
-    private int openQuote, closeQuote;
+    private int openSequence, closeSequence;
 
     /**
      * The string used as a separator in a list of values. This is usually 
{@code ", "},
@@ -130,10 +140,9 @@ public class Symbols implements Localize
     public Symbols(final Symbols symbols) {
         locale        = symbols.locale;
         brackets      = symbols.brackets;
+        quotes        = symbols.quotes;
         openSequence  = symbols.openSequence;
         closeSequence = symbols.closeSequence;
-        openQuote     = symbols.openQuote;
-        closeQuote    = symbols.closeQuote;
         separator     = symbols.separator;
     }
 
@@ -141,13 +150,12 @@ public class Symbols implements Localize
      * Constructor reserved to {@link #SQUARE_BRACKETS} and {@link 
#CURLY_BRACKETS} constants.
      * The given array is stored by reference - it is not cloned.
      */
-    private Symbols(final int[] brackets) {
+    private Symbols(final int[] brackets, final int[] quotes) {
         this.locale        = Locale.US;
         this.brackets      = brackets;
+        this.quotes        = quotes;
         this.openSequence  = '{';
         this.closeSequence = '}';
-        this.openQuote     = '"';
-        this.closeQuote    = '"';
         this.separator     = ", ";
     }
 
@@ -162,10 +170,10 @@ public class Symbols implements Localize
 
         /**
          * Constructor reserved to {@link Symbols#SQUARE_BRACKETS} and {@link 
Symbols#CURLY_BRACKETS} constants.
-         * The given array is stored by reference - it is not cloned.
+         * The given arrays are stored by reference - they are not cloned.
          */
-        Immutable(final int... brackets) {
-            super(brackets);
+        Immutable(final int[] brackets, final int[] quotes) {
+            super(brackets, quotes);
         }
 
         /**
@@ -244,12 +252,15 @@ public class Symbols implements Localize
 
     /**
      * Returns the number of paired brackets. For example if the WKT parser 
accepts both the
-     * {@code [ ]} and {@code ( )} paired brackets, then this method returns 2.
+     * {@code […]} and {@code (…)} bracket pairs, then this method returns 2.
      *
      * @return The number of bracket pairs.
+     *
+     * @see #getOpeningBracket(int)
+     * @see #getClosingBracket(int)
      */
-    public final int getNumPairedBracket() {
-        return brackets.length / 2;
+    public final int getNumPairedBrackets() {
+        return brackets.length >>> 1;
     }
 
     /**
@@ -257,12 +268,12 @@ public class Symbols implements Localize
      * Index 0 stands for the default bracket used at formatting time.
      * All other index are for optional brackets accepted at parsing time.
      *
-     * @param  index Index of the opening bracket to get, from 0 to {@link 
#getNumPairedBracket()} exclusive.
+     * @param  index Index of the opening bracket to get, from 0 to {@link 
#getNumPairedBrackets()} exclusive.
      * @return The opening bracket at the given index, as a Unicode code point.
      * @throws IndexOutOfBoundsException if the given index is out of bounds.
      */
     public final int getOpeningBracket(final int index) {
-        return brackets[index*2];
+        return brackets[index << 1];
     }
 
     /**
@@ -270,47 +281,116 @@ public class Symbols implements Localize
      * Index 0 stands for the default bracket used at formatting time.
      * All other index are for optional brackets accepted at parsing time.
      *
-     * @param  index Index of the closing bracket to get, from 0 to {@link 
#getNumPairedBracket()} exclusive.
+     * @param  index Index of the closing bracket to get, from 0 to {@link 
#getNumPairedBrackets()} exclusive.
      * @return The closing bracket at the given index, as a Unicode code point.
      * @throws IndexOutOfBoundsException if the given index is out of bounds.
      */
     public final int getClosingBracket(final int index) {
-        return brackets[index*2 + 1];
+        return brackets[(index << 1) | 1];
     }
 
     /**
-     * Sets the opening and closing brackets to the given characters.
-     * The given arrays shall comply to the following constraints:
+     * Sets the opening and closing brackets to the given pairs.
+     * Each string shall contain exactly two code points (usually two 
characters).
+     * The first code point is taken as the opening bracket, and the second 
code point as the closing bracket.
      *
-     * <ul>
-     *   <li>The two arrays shall be non-empty and have the same length.</li>
-     *   <li>The characters at index 0 are the preferred opening and closing 
brackets.</li>
-     *   <li>For each index <var>i</var>, {@code closingBrackets[i]} is the 
closing bracket
-     *       matching {@code openingBrackets[i]}.</li>
-     * </ul>
+     * {@example The following code will instruct the WKT formatter to use the 
<code>(…)</code> pair of brackets
+     *           at formatting time, but still accept the more common 
<code>[…]</code> pair of brackets at parsing
+     *           time:
      *
-     * @param openingBrackets The opening brackets, as a Unicode code point.
-     * @param closingBrackets The closing brackets matching the opening ones.
+     *           <pre>setPairedBrackets("()", "[]");</pre>}
+     *
+     * @param preferred The preferred pair of opening and closing quotes, used 
at formatting time.
+     * @param alternatives Alternative pairs of opening and closing quotes 
accepted at parsing time.
      */
-    public void setBrackets(final int[] openingBrackets, final int[] 
closingBrackets) {
+    public void setPairedBrackets(final String preferred, final String... 
alternatives) {
         checkWritePermission();
-        ensureNonNull("openingBrackets", openingBrackets);
-        ensureNonNull("closingBrackets", closingBrackets);
-        final int length = openingBrackets.length;
-        if (closingBrackets.length != length) {
-            throw new 
IllegalArgumentException(Errors.format(Errors.Keys.MismatchedArrayLengths));
-        }
-        if (length == 0) {
-            throw new 
IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, 
"openingBrackets"));
-        }
-        final int[] brackets = new int[length * 2];
-        for (int i=0,j=0; i<length; i++) {
-            ensureValidUnicodeCodePoint("openingBrackets", openingBrackets[i]);
-            ensureValidUnicodeCodePoint("closingBrackets", closingBrackets[i]);
-            brackets[j++] = openingBrackets[i];
-            brackets[j++] = closingBrackets[i];
+        brackets = toCodePoints(preferred, alternatives);
+    }
+
+    /**
+     * Returns the number of paired quotes. For example if the WKT parser 
accepts both the
+     * {@code "…"} and {@code “…”} quote pairs, then this method returns 2.
+     *
+     * @return The number of quote pairs.
+     *
+     * @see #getOpeningQuote(int)
+     * @see #getClosingQuote(int)
+     */
+    public final int getNumPairedQuotes() {
+        return quotes.length >>> 1;
+    }
+
+    /**
+     * Returns the opening quote character at the given index.
+     * Index 0 stands for the default quote used at formatting time, which is 
usually {@code '"'}.
+     * All other index are for optional quotes accepted at parsing time.
+     *
+     * @param  index Index of the opening quote to get, from 0 to {@link 
#getNumPairedQuotes()} exclusive.
+     * @return The opening quote at the given index, as a Unicode code point.
+     * @throws IndexOutOfBoundsException if the given index is out of bounds.
+     */
+    public final int getOpeningQuote(final int index) {
+        return quotes[index << 1];
+    }
+
+    /**
+     * Returns the closing quote character at the given index.
+     * Index 0 stands for the default quote used at formatting time, which is 
usually {@code '"'}.
+     * All other index are for optional quotes accepted at parsing time.
+     *
+     * @param  index Index of the closing quote to get, from 0 to {@link 
#getNumPairedQuotes()} exclusive.
+     * @return The closing quote at the given index, as a Unicode code point.
+     * @throws IndexOutOfBoundsException if the given index is out of bounds.
+     */
+    public final int getClosingQuote(final int index) {
+        return quotes[(index << 1) | 1];
+    }
+
+    /**
+     * Sets the opening and closing quotes to the given pairs.
+     * Each string shall contain exactly two code points (usually two 
characters).
+     * The first code point is taken as the opening quote, and the second code 
point as the closing quote.
+     *
+     * {@example The following code will instruct the WKT formatter to use the 
prettier <code>“…”</code>
+     *           quotation marks at formatting time (especially useful for 
<code>String</code> constants
+     *           in Java code), but still accept the standard <code>"…"</code> 
quotation marks at parsing
+     *           time:
+     *
+     *           <pre>setPairedQuotes("“”", "\"\"");</pre>}
+     *
+     * @param preferred The preferred pair of opening and closing quotes, used 
at formatting time.
+     * @param alternatives Alternative pairs of opening and closing quotes 
accepted at parsing time.
+     */
+    public void setPairedQuotes(final String preferred, final String... 
alternatives) {
+        checkWritePermission();
+        quotes = toCodePoints(preferred, alternatives);
+    }
+
+    /**
+     * Packs the given pairs of bracket or quotes in a single array of code 
points.
+     * This method also verifies arguments validity.
+     */
+    private static int[] toCodePoints(final String preferred, final String[] 
alternatives) {
+        ensureNonNull("preferred", preferred);
+        final int n = (alternatives != null) ? alternatives.length : 0;
+        final int[] array = new int[(n+1) * 2];
+        String name = "preferred";
+        String pair = preferred;
+        int i=0, j=0;
+        while (true) {
+            if (pair.codePointCount(0, pair.length()) != 2) {
+                throw new 
IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, 
name, pair));
+            }
+            final int c = pair.codePointAt(0);
+            ensureValidUnicodeCodePoint(name, array[j++] = c);
+            ensureValidUnicodeCodePoint(name, array[j++] = 
pair.codePointAt(Character.charCount(c)));
+            if (i >= n) {
+                break;
+            }
+            ensureNonNullElement(name = "alternatives", i, pair = 
alternatives[i++]);
         }
-        this.brackets = brackets; // Store only on success.
+        return array;
     }
 
     /**
@@ -348,38 +428,6 @@ public class Symbols implements Localize
     }
 
     /**
-     * Returns the character used for opening a quoted text. This is usually 
{@code '"'}.
-     *
-     * @return The character used for opening a quoted text, as a Unicode code 
point.
-     */
-    public final int getOpenQuote() {
-        return openQuote;
-    }
-
-    /**
-     * Returns the character used for closing a quoted text. This is usually 
{@code '"'}.
-     *
-     * @return The character used for closing a quoted text, as a Unicode code 
point.
-     */
-    public final int getCloseQuote() {
-        return closeQuote;
-    }
-
-    /**
-     * Sets the characters used for opening and closing a quoted text.
-     *
-     * @param openQuote  The character for opening a quoted text, as a Unicode 
code point.
-     * @param closeQuote The character for closing a quoted text, as a Unicode 
code point.
-     */
-    public void setQuotes(final int openQuote, final int closeQuote) {
-        checkWritePermission();
-        ensureValidUnicodeCodePoint("openQuote",  openQuote);
-        ensureValidUnicodeCodePoint("closeQuote", closeQuote);
-        this.openQuote  = openQuote;
-        this.closeQuote = closeQuote;
-    }
-
-    /**
      * Returns the string used as a separator in a list of values. This is 
usually {@code ", "},
      * but may be different if a non-English locale is used for formatting 
numbers.
      *
@@ -426,8 +474,8 @@ public class Symbols implements Localize
      *
      * <ul>
      *   <li>The search is case-insensitive.</li>
-     *   <li>Characters between the {@linkplain #getOpenQuote() open quote} 
and the
-     *       {@linkplain #getCloseQuote() close quote} are ignored.</li>
+     *   <li>Characters between {@linkplain #getOpeningQuote(int) opening 
quotes} and
+     *       {@linkplain #getClosingQuote(int) closing quotes} are 
ignored.</li>
      *   <li>The element found in the given WKT can not be preceded by other
      *       {@linkplain Character#isUnicodeIdentifierPart(int) Unicode 
identifier characters}.</li>
      *   <li>The element found in the given WKT must be followed, ignoring 
space, by an
@@ -455,12 +503,12 @@ public class Symbols implements Localize
      * Invoking this method is equivalent to invoking
      * <code>{@linkplain #containsElement(CharSequence, String) 
containsElement}(wkt, "AXIS")</code>.
      *
-     * <p>The check for axis elements is of particular interest because the 
axis order is a frequent cause
+     * {@section Use case}
+     * The check for axis elements is of particular interest because the axis 
order is a frequent cause
      * of confusion when processing geographic data. Some applications just 
ignore any declared axis order
      * in favor of their own hard-coded (<var>longitude</var>, 
<var>latitude</var>) axis order.
      * Consequently, the presence of {@code AXIS[…]} elements in a WKT is an 
indication that the encoded
      * object may not be understood as intended by some external softwares.
-     * See for example {@link Convention#ESRI}.</p>
      *
      * @param  wkt The WKT to inspect.
      * @return {@code true} if the given WKT contains at least one instance of 
the {@code AXIS[…]} element.
@@ -478,12 +526,22 @@ public class Symbols implements Localize
      * @param  offset  The index to start the search from.
      */
     private boolean containsElement(final CharSequence wkt, final String 
element, int offset) {
+        final int[] quotes = this.quotes;
         final int length = wkt.length();
         boolean isQuoting = false;
+        int closeQuote = 0;
         while (offset < length) {
             int c = Character.codePointAt(wkt, offset);
-            if (c == (isQuoting ? closeQuote : openQuote)) {
-                isQuoting = !isQuoting;
+            if (closeQuote != 0) {
+                if (c == closeQuote) {
+                    isQuoting = false;
+                }
+            } else for (int i=0; i<quotes.length; i+=2) {
+                if (c == quotes[i]) {
+                    closeQuote = quotes[i | 1];
+                    isQuoting = true;
+                    break;
+                }
             }
             if (!isQuoting && Character.isUnicodeIdentifierStart(c)) {
                 /*

Modified: 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -35,11 +35,11 @@
  * </ul>
  *
  * {@section Referencing WKT}
- * Referencing WKT is defined in two versions:
+ * Referencing WKT is defined using Extended Backus Naur Form (EBNF) in two 
versions:
  * <ul>
  *   <li>ISO 19162 defines the current format, also known as “WKT 2”.</li>
  *   <li>The previous format — “WKT 1” — was defined in the <a 
href="http://www.opengeospatial.org/standards/ct";>OGC
- *       document 01-009</a> using Extended Backus Naur Form (EBNF). This 
definition is
+ *       document 01-009</a>. This definition is
  *       <a 
href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html";>shown
 on GeoAPI</a>.</li>
  * </ul>
  *
@@ -50,6 +50,13 @@
  * the WKT syntax require knowledge of the WKT variant used by that software. 
This variant can be specified by the
  * {@link org.apache.sis.io.wkt.Convention} enumeration.
  *
+ * <p>The WKT 2 format provides more complete CRS descriptions than WKT 1 with 
one exception:
+ * to retain simplicity, WKT 2 does not define {@link 
org.opengis.referencing.crs.DerivedCRS} representations.
+ * This is because WKT 2 does not define {@link 
org.opengis.referencing.operation.MathTransform} representations
+ * neither, while the later were used to be contained inside {@code 
DerivedCRS} representations in WKT 1.
+ * Apache SIS workarounds this limitation by using the WKT 1 format for {@code 
MathTransform} instances,
+ * and extending the WKT 2 format with a {@code DerivedCRS} representation 
that contains those math transforms.</p>
+ *
  * {@section Geometry WKT}
  * The {@link org.apache.sis.geometry.GeneralEnvelope} and {@link 
org.apache.sis.geometry.GeneralDirectPosition} classes
  * provide their own, limited, WKT parsing and formatting services for the 
{@code BOX} and {@code POINT} elements.

Modified: 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/FormatterTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/FormatterTest.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/FormatterTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/FormatterTest.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -50,16 +50,16 @@ public final strictfp class FormatterTes
      */
     @Test
     public void testAppendMatrix() {
-        final Formatter formatter = new Formatter();
-        formatter.append(new Matrix4(1, 0, 4, 0,
-                                    -2, 1, 0, 0,
-                                     0, 0, 1, 7,
-                                     0, 0, 0, 1));
+        final Matrix m = new Matrix4(
+                1, 0, 4, 0,
+               -2, 1, 0, 0,
+                0, 0, 1, 7,
+                0, 0, 0, 1);
         assertWktEquals(
                 "PARAMETER[“num_row”, 4],\n"    +
                 "PARAMETER[“num_col”, 4],\n"    +
                 "PARAMETER[“elt_0_2”, 4.0],\n"  +
                 "PARAMETER[“elt_1_0”, -2.0],\n"  +
-                "PARAMETER[“elt_2_3”, 7.0]", formatter.toString());
+                "PARAMETER[“elt_2_3”, 7.0]", m);
     }
 }

Modified: 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/SymbolsTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/SymbolsTest.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/SymbolsTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/io/wkt/SymbolsTest.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -17,6 +17,7 @@
 package org.apache.sis.io.wkt;
 
 import org.apache.sis.test.TestCase;
+import org.apache.sis.util.StringBuilders;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
@@ -36,13 +37,26 @@ public final strictfp class SymbolsTest 
      */
     @Test
     public void testContainsAxis() {
-        final Symbols s = Symbols.DEFAULT;
-        assertTrue("At beginning of a line.",   s.containsAxis(                
  "AXIS[\"Long\", EAST]"));
-        assertTrue("Embeded in GEOGCS.",        
s.containsAxis("GEOGCS[\"WGS84\", AXIS[\"Long\", EAST]]"));
-        assertTrue("Using different brackets.", 
s.containsAxis("GEOGCS[\"WGS84\", AXIS (\"Long\", EAST)]"));
-        assertTrue("Mixed cases.",              
s.containsAxis("GEOGCS[\"WGS84\", aXis[\"Long\", EAST]]"));
-        assertFalse("AXIS in quoted text.",     
s.containsAxis("GEOGCS[\"AXIS\"]"));
-        assertFalse("Without opening bracket.", 
s.containsAxis("GEOGCS[\"WGS84\", AXIS]"));
-        assertFalse("No AXIS.",                 
s.containsAxis("GEOGCS[\"WGS84\"]"));
+        assertContainsAxis("At beginning of a line.",   true,                  
"AXIS[“Long”, EAST]");
+        assertContainsAxis("Embeded in GEOGCS.",        true,  
"GEOGCS[“WGS84”, AXIS[“Long”, EAST]]");
+        assertContainsAxis("Using different brackets.", true,  
"GEOGCS[“WGS84”, AXIS (“Long”, EAST)]");
+        assertContainsAxis("Mixed cases.",              true,  
"GEOGCS[“WGS84”, aXis[“Long”, EAST]]");
+        assertContainsAxis("AXIS in quoted text.",      false, 
"GEOGCS[“AXIS”]");
+        assertContainsAxis("Without opening bracket.",  false, 
"GEOGCS[“WGS84”, AXIS]");
+        assertContainsAxis("No AXIS.",                  false, 
"GEOGCS[“WGS84”]");
+    }
+
+    /**
+     * Asserts that the call to {@link Symbols#containsAxis(CharSequence)} 
produce the given result.
+     * This method expects an array using the {@code “…”} quotation marks, 
which will be replaced by
+     * the standard {@code '"'} quotation mark after we tested the given 
string.
+     */
+    private static void assertContainsAxis(final String message, final boolean 
expected, final String wkt) {
+        assertEquals(message, expected, Symbols.DEFAULT.containsAxis(wkt));
+        final StringBuilder buffer = new StringBuilder(wkt);
+        StringBuilders.replace(buffer, '“', '"');
+        StringBuilders.replace(buffer, '”', '"');
+        assertFalse(wkt.contentEquals(buffer));
+        assertEquals(message, expected, Symbols.DEFAULT.containsAxis(buffer));
     }
 }

Modified: 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/Assert.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/Assert.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/Assert.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/Assert.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -30,6 +30,8 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.cs.RangeMeaning;
+import org.apache.sis.io.wkt.Symbols;
+import org.apache.sis.io.wkt.WKTFormat;
 import org.apache.sis.geometry.AbstractEnvelope;
 import org.apache.sis.geometry.GeneralDirectPosition;
 
@@ -52,6 +54,18 @@ public strictfp class Assert extends org
     private static final double STRICT = 0;
 
     /**
+     * The formatter to be used by {@link #assertWktEquals(Object, String)}.
+     * This formatter uses the {@code “…”} quotation marks instead of {@code 
"…"}
+     * for easier readability of {@link String} constants in Java code.
+     */
+    private static final WKTFormat WKT_FORMAT = new WKTFormat();
+    static {
+        final Symbols s = new Symbols();
+        s.setPairedQuotes("“”", "\"\"");
+        WKT_FORMAT.setSymbols(s);
+    }
+
+    /**
      * For subclass constructor only.
      */
     protected Assert() {
@@ -318,38 +332,24 @@ public strictfp class Assert extends org
     }
 
     /**
-     * Asserts that the WKT of the given object is equal to the expected one. 
If the given string contains
-     * {@code '“'} and {@code '”'} characters (for easier reading), then those 
characters will be replaced
-     * by "ordinary" quote characters ({@code '"'}).
+     * Asserts that the WKT of the given object is equal to the expected one.
+     * This method expected the {@code “…”} quotation marks instead of {@code 
"…"}
+     * for easier readability of {@link String} constants in Java code.
      *
-     * @param object The object to format in <cite>Well Known Text</cite> 
format.
      * @param expected The expected text, or {@code null} if {@code object} is 
expected to be null.
+     * @param object The object to format in <cite>Well Known Text</cite> 
format, or {@code null}.
      */
-    public static void assertWktEquals(final IdentifiedObject object, String 
expected) {
+    public static void assertWktEquals(final String expected, final Object 
object) {
         if (expected == null) {
             assertNull(object);
         } else {
             assertNotNull(object);
-            expected = expected.replace('“', '"').replace('”', '"');
-            assertMultilinesEquals(object.getName().getCode(), expected, 
object.toWKT());
-        }
-    }
-
-    /**
-     * Asserts that the given WKT is equal to the expected one. If the given 
expected string contains
-     * {@code '“'} and {@code '”'} characters (for easier reading), then those 
characters will be replaced
-     * by "ordinary" quote characters ({@code '"'}).
-     *
-     * @param expected The expected text, or {@code null} if {@code actual} is 
expected to be null.
-     * @param actual   The actual <cite>Well Known Text</cite> to compare.
-     */
-    public static void assertWktEquals(String expected, final String actual) {
-        if (expected == null) {
-            assertNull(actual);
-        } else {
-            assertNotNull(actual);
-            expected = expected.replace('“', '"').replace('”', '"');
-            assertMultilinesEquals(expected, actual);
+            final String wkt;
+            synchronized (WKT_FORMAT) {
+                wkt = WKT_FORMAT.format(object);
+            }
+            assertMultilinesEquals((object instanceof IdentifiedObject) ?
+                    ((IdentifiedObject) object).getName().getCode() : 
object.getClass().getSimpleName(), expected, wkt);
         }
     }
 }

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=1561702&r1=1561701&r2=1561702&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] Mon Jan 27 15:06:18 2014
@@ -72,7 +72,7 @@ public final strictfp class HardCodedCRS
      */
     @Test
     public void testWKT() {
-        assertWktEquals(WGS84,
+        assertWktEquals(
                 "GEOGCS[“WGS 84”,\n" +
                 "  DATUM[“World Geodetic System 1984”,\n" +
                 "    SPHEROID[“WGS84”, 6378137.0, 298.257223563],\n" +
@@ -80,7 +80,8 @@ public final strictfp class HardCodedCRS
                 "  PRIMEM[“Greenwich”, 0.0, AUTHORITY[“EPSG”, “8901”]],\n" +
                 "  UNIT[“degree”, 0.017453292519943295],\n" +
                 "  AXIS[“Geodetic longitude”, EAST],\n" +
-                "  AXIS[“Geodetic latitude”, NORTH]]");
+                "  AXIS[“Geodetic latitude”, NORTH]]",
+                WGS84);
     }
 
     /**

Modified: 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxisTest.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -82,17 +82,17 @@ public final strictfp class DefaultCoord
      */
     @Test
     public void testWKT() {
-        assertWktEquals(X,                   "AXIS[“x”, EAST]");
-        assertWktEquals(Y,                   "AXIS[“y”, NORTH]");
-        assertWktEquals(Z,                   "AXIS[“z”, UP]");
-        assertWktEquals(LONGITUDE_gon,       "AXIS[“Longitude”, EAST]");
-        assertWktEquals(LATITUDE_gon,        "AXIS[“Latitude”, NORTH]");
-        assertWktEquals(ALTITUDE,            "AXIS[“Altitude”, UP]");
-        assertWktEquals(TIME,                "AXIS[“Time”, FUTURE]");
-        assertWktEquals(GEODETIC_LONGITUDE,  "AXIS[“Geodetic longitude”, 
EAST]");
-        assertWktEquals(SPHERICAL_LONGITUDE, "AXIS[“Spherical longitude”, 
EAST]");
-        assertWktEquals(GEODETIC_LATITUDE,   "AXIS[“Geodetic latitude”, 
NORTH]");
-        assertWktEquals(SPHERICAL_LATITUDE,  "AXIS[“Spherical latitude”, 
NORTH]");
+        assertWktEquals("AXIS[“x”, EAST]",                   X);
+        assertWktEquals("AXIS[“y”, NORTH]",                  Y);
+        assertWktEquals("AXIS[“z”, UP]",                     Z);
+        assertWktEquals("AXIS[“Longitude”, EAST]",           LONGITUDE_gon);
+        assertWktEquals("AXIS[“Latitude”, NORTH]",           LATITUDE_gon);
+        assertWktEquals("AXIS[“Altitude”, UP]",              ALTITUDE);
+        assertWktEquals("AXIS[“Time”, FUTURE]",              TIME);
+        assertWktEquals("AXIS[“Geodetic longitude”, EAST]",  
GEODETIC_LONGITUDE);
+        assertWktEquals("AXIS[“Spherical longitude”, EAST]", 
SPHERICAL_LONGITUDE);
+        assertWktEquals("AXIS[“Geodetic latitude”, NORTH]",  
GEODETIC_LATITUDE);
+        assertWktEquals("AXIS[“Spherical latitude”, NORTH]", 
SPHERICAL_LATITUDE);
     }
 
     /**

Modified: 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -166,7 +166,7 @@ public final strictfp class DefaultEllip
     @Test
     public void testToWKT() {
         final DefaultEllipsoid e = new 
DefaultEllipsoid(GeodeticDatumMock.WGS84.getEllipsoid());
-        assertWktEquals(e, "SPHEROID[“WGS84”, 6378137.0, 298.257223563]");
+        assertWktEquals("SPHEROID[“WGS84”, 6378137.0, 298.257223563]", e);
     }
 
     /**

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=1561702&r1=1561701&r2=1561702&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] Mon Jan 27 15:06:18 2014
@@ -181,9 +181,10 @@ public final strictfp class DefaultGeode
     @Test
     public void testToWKT() {
         final DefaultGeodeticDatum datum = new DefaultGeodeticDatum(WGS84);
-        assertWktEquals(datum,
+        assertWktEquals(
                 "DATUM[“WGS84”,\n" +
-                "  SPHEROID[“WGS84”, 6378137.0, 298.257223563]]");
+                "  SPHEROID[“WGS84”, 6378137.0, 298.257223563]]",
+                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=1561702&r1=1561701&r2=1561702&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] Mon Jan 27 15:06:18 2014
@@ -57,7 +57,7 @@ public final strictfp class DefaultPrime
     public void testToWKT() {
         final DefaultPrimeMeridian pm = new DefaultPrimeMeridian(GREENWICH);
         assertIsGreenwich(pm);
-        assertWktEquals(pm, "PRIMEM[“Greenwich”, 0.0]");
+        assertWktEquals("PRIMEM[“Greenwich”, 0.0]", pm);
     }
 
     /**
@@ -146,7 +146,7 @@ public final strictfp class DefaultPrime
         assertEquals("greenwichLongitude", 2.33722917, 
pm.getGreenwichLongitude(NonSI.DEGREE_ANGLE), 1E-12);
         assertEquals("Equivalent to 2°20′14.025″.", 
pm.getRemarks().toString());
         assertNull("name.codeSpace", pm.getName().getCodeSpace());
-        assertWktEquals(pm, "PRIMEM[“Paris”, 2.33722917, AUTHORITY[“EPSG”, 
“8903”]]");
+        assertWktEquals("PRIMEM[“Paris”, 2.33722917, AUTHORITY[“EPSG”, 
“8903”]]", pm);
         assertXmlEquals(
                 "<gml:PrimeMeridian xmlns:gml=\"" + Namespaces.GML + "\">\n" +
                 "  <gml:identifier 
codeSpace=\"OGP\">urn:ogc:def:meridian:EPSG::8903</gml:identifier>" +

Modified: 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java?rev=1561702&r1=1561701&r2=1561702&view=diff
==============================================================================
--- 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
 [UTF-8] (original)
+++ 
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
 [UTF-8] Mon Jan 27 15:06:18 2014
@@ -89,10 +89,10 @@ public final strictfp class DefaultVerti
     public void testToWKT() {
         DefaultVerticalDatum datum;
         datum = new 
DefaultVerticalDatum(singletonMap(DefaultVerticalDatum.NAME_KEY, "Geoidal"), 
VerticalDatumType.GEOIDAL);
-        assertWktEquals(datum, "VERT_DATUM[“Geoidal”, 2005]");
+        assertWktEquals("VERT_DATUM[“Geoidal”, 2005]", datum);
 
         datum = new 
DefaultVerticalDatum(singletonMap(DefaultVerticalDatum.NAME_KEY, 
"Ellipsoidal"), VerticalDatumTypes.ELLIPSOIDAL);
-        assertWktEquals(datum, "VERT_DATUM[“Ellipsoidal”, 2002]");
+        assertWktEquals("VERT_DATUM[“Ellipsoidal”, 2002]", datum);
     }
 
     /**


Reply via email to