sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1660761 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/metadata/ sis-metadata/src/main/java/org/apache/sis/metadata/iso/ sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/ sis-metadata/src/test/java/o...
Date Wed, 18 Feb 2015 23:12:18 GMT
Author: desruisseaux
Date: Wed Feb 18 23:12:17 2015
New Revision: 1660761

URL: http://svn.apache.org/r1660761
Log:
Clarified the way codeSpace are inferred from Citation objects:
- Added a getUnicodeIdentifier(Citation) method which guarantee that the returned String is
a valid Unicode identifier
- Remove ignorable identifier character for better compatibility with XML identifier
- Documented the relationship between Unicode identifier and XML identifier
- Make use of the above-cited getUnicodeIdentifier(Citation) in most places where we need
to infer a scope or codeSpace,
  except when it is mostly for information purpose in which case we use the more tolerant
getIdentifier(Citation) method.

Added:
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifier.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/IdentifiedObjectFormat.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/simple/SimpleIdentifierTest.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -1231,6 +1231,6 @@ class PropertyAccessor {
         if (type != implementation) {
             buffer.append(':').append(Classes.getShortName(type));
         }
-        return buffer.append(" from “").append(Citations.getIdentifier(standard)).append("”]").toString();
+        return buffer.append(" from “").append(Citations.getIdentifier(standard, false)).append("”]").toString();
     }
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ImmutableIdentifier.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -39,6 +39,7 @@ import org.apache.sis.io.wkt.ElementKind
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.util.CharSequences.trimWhitespaces;
 import static org.apache.sis.util.collection.Containers.property;
+import static org.apache.sis.internal.util.Citations.getUnicodeIdentifier;
 import static org.opengis.referencing.IdentifiedObject.REMARKS_KEY;
 
 // Branch-dependent imports
@@ -356,7 +357,7 @@ public class ImmutableIdentifier extends
          */
         value = properties.get(CODESPACE_KEY);
         if (value == null && !properties.containsKey(CODESPACE_KEY)) {
-            codeSpace = getCodeSpace(authority);
+            codeSpace = getUnicodeIdentifier(authority);
         } else if (value instanceof String) {
             codeSpace = trimWhitespaces((String) value);
         } else {
@@ -441,37 +442,6 @@ public class ImmutableIdentifier extends
     }
 
     /**
-     * Infers a code space from the given authority. First, this method takes a short identifier
or title with
-     * preference for Unicode identifier - see {@link Citations#getIdentifier(Citation)}
for more information.
-     * Next this method applies additional restrictions in order to reduce the risk of undesired
code space.
-     * Those restrictions are arbitrary and may change in any future SIS version. Currently,
the restriction
-     * is to accept only letters or digits.
-     *
-     * @param  authority The authority for which to get a code space.
-     * @return The code space, or {@code null} if none.
-     *
-     * @see Citations#getIdentifier(Citation)
-     */
-    private static String getCodeSpace(final Citation authority) {
-        final String codeSpace = Citations.getIdentifier(authority); // Whitespaces trimed
by Citations.
-        if (codeSpace != null) {
-            final int length = codeSpace.length();
-            if (length != 0) {
-                int i = 0;
-                do {
-                    final int c = codeSpace.charAt(i);
-                    if (!Character.isLetterOrDigit(c)) {
-                        return null;
-                    }
-                    i += Character.charCount(c);
-                } while (i < length);
-                return codeSpace;
-            }
-        }
-        return null;
-    }
-
-    /**
      * Organization or party responsible for definition and maintenance of the
      * {@linkplain #getCode() code}.
      *
@@ -589,12 +559,7 @@ public class ImmutableIdentifier extends
     protected String formatTo(final Formatter formatter) {
         String keyword = null;
         if (code != null) {
-            String citation = Citations.getIdentifier(authority);
-            String cs = codeSpace;
-            if (cs == null) {
-                cs = citation;
-                citation  = null;
-            }
+            final String cs = (codeSpace != null) ? codeSpace : getUnicodeIdentifier(authority);
             if (cs != null) {
                 final Convention convention = formatter.getConvention();
                 if (convention.majorVersion() == 1) {
@@ -608,6 +573,7 @@ public class ImmutableIdentifier extends
                     if (version != null) {
                         appendCode(formatter, version);
                     }
+                    final String citation = org.apache.sis.internal.util.Citations.getIdentifier(authority,
false);
                     if (citation != null && !citation.equals(cs)) {
                         formatter.append(new Cite(citation));
                     }

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -17,11 +17,12 @@
 package org.apache.sis.metadata.iso.citation;
 
 import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.IdentifiedObject;        // For javadoc
 import org.apache.sis.util.Static;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.xml.IdentifierSpace;
 import org.apache.sis.internal.simple.SimpleCitation;
-import org.apache.sis.metadata.iso.DefaultIdentifier; // For javadoc
+import org.apache.sis.metadata.iso.DefaultIdentifier;   // For javadoc
 
 
 /**
@@ -38,7 +39,7 @@ import org.apache.sis.metadata.iso.Defau
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.6
  * @module
  */
 public final class Citations extends Static {
@@ -322,6 +323,42 @@ public final class Citations extends Sta
      *         or {@code null} if the given citation is null or does not declare any identifier
or title.
      */
     public static String getIdentifier(final Citation citation) {
-        return org.apache.sis.internal.util.Citations.getIdentifier(citation);
+        return org.apache.sis.internal.util.Citations.getIdentifier(citation, false);
+    }
+
+    /**
+     * Infers a valid Unicode identifier from the given citation, or returns {@code null}
if none.
+     * This method performs the following actions:
+     *
+     * <ul>
+     *   <li>First, invoke {@link #getIdentifier(Citation)}.</li>
+     *   <li>If the result of above method call is {@code null} or is not a
+     *       {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier valid Unicode
identifier},
+     *       then return {@code null}.</li>
+     *   <li>Otherwise remove the {@linkplain Character#isIdentifierIgnorable(int)
ignorable identifier characters},
+     *       if any. Then:
+     *       <ul>
+     *         <li>If the result is an empty string, returns {@code null}.</li>
+     *         <li>Otherwise returns the result.</li>
+     *       </ul>
+     *   </li>
+     * </ul>
+     *
+     * If non-null, the result is suitable for use as a XML identifier except for rarely
used characters
+     * (‘{@code µ}’, ‘{@code ª}’ (feminine ordinal indicator), ‘{@code º}’
(masculine ordinal indicator)
+     * and ‘{@code ⁔}’).
+     *
+     * @param  citation The citation for which to get the Unicode identifier, or {@code null}.
+     * @return A non-empty Unicode identifier for the given citation without leading or trailing
whitespaces,
+     *         or {@code null} if the given citation is null or does not have any Unicode
identifier or title.
+     *
+     * @see org.apache.sis.metadata.iso.ImmutableIdentifier
+     * @see org.apache.sis.referencing.IdentifiedObjects#getUnicodeIdentifier(IdentifiedObject)
+     * @see org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence)
+     *
+     * @since 0.6
+     */
+    public static String getUnicodeIdentifier(final Citation citation) {
+        return org.apache.sis.internal.util.Citations.getUnicodeIdentifier(citation);
     }
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -22,7 +22,9 @@ import org.opengis.referencing.Identifie
 import org.apache.sis.io.wkt.Symbols;
 import org.apache.sis.io.wkt.WKTFormat;
 import org.apache.sis.io.wkt.Convention;
-import org.apache.sis.internal.util.Citations;
+import org.apache.sis.metadata.iso.citation.Citations;
+
+import static org.apache.sis.internal.util.Citations.EPSG;
 
 
 /**
@@ -65,8 +67,8 @@ public strictfp class MetadataAssert ext
     public static void assertEpsgIdentifierEquals(final String expected, final Identifier
identifier) {
         assertNotNull(identifier);
         assertEquals("code",      expected, identifier.getCode());
-        assertEquals("codeSpace", Citations.EPSG, identifier.getCodeSpace());
-        assertEquals("authority", "OGP",  Citations.getIdentifier(identifier.getAuthority()));
+        assertEquals("codeSpace", EPSG,  identifier.getCodeSpace());
+        assertEquals("authority", "OGP", Citations.getIdentifier(identifier.getAuthority()));
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -26,6 +26,8 @@ import org.apache.sis.internal.metadata.
 import org.apache.sis.referencing.NamedIdentifier;
 import org.apache.sis.metadata.iso.citation.Citations;
 
+import static org.apache.sis.internal.util.Citations.getUnicodeIdentifier;
+
 
 /**
  * The {@code gml:CodeType}, which is made of a code space and a code value.
@@ -156,7 +158,7 @@ public final class Code {
                     final String urn = DefinitionURI.format(NameMeaning.toObjectType(type),
fallback);
                     if (urn != null) {
                         final Code code = new Code();
-                        code.codeSpace = Citations.getIdentifier(fallback.getAuthority());
+                        code.codeSpace = getUnicodeIdentifier(fallback.getAuthority());
                         code.code = urn;
                         return code;
                     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/Builder.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -29,7 +29,7 @@ import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.referencing.IdentifiedObject;
 import org.apache.sis.metadata.iso.ImmutableIdentifier;
-import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.internal.util.Citations;
 import org.apache.sis.util.resources.Errors;
 
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -464,7 +464,7 @@ public abstract class Builder<B extends
      */
     public B addIdentifier(final Citation authority, final String identifier) {
         ensureNonNull("identifier", identifier);
-        identifiers.add(new ImmutableIdentifier(authority, Citations.getIdentifier(authority),
identifier));
+        identifiers.add(new ImmutableIdentifier(authority, Citations.getUnicodeIdentifier(authority),
identifier));
         return self();
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -318,6 +318,10 @@ public final class IdentifiedObjects ext
      *
      * @param  object The identified object, or {@code null}.
      * @return The first name, alias or identifier which is a valid Unicode identifier, or
{@code null} if none.
+     *
+     * @see org.apache.sis.metadata.iso.ImmutableIdentifier
+     * @see org.apache.sis.metadata.iso.citation.Citations#getUnicodeIdentifier(Citation)
+     * @see org.apache.sis.util.CharSequences#isUnicodeIdentifier(CharSequence)
      */
     public static String getUnicodeIdentifier(final IdentifiedObject object) {
         if (object != null) {
@@ -474,10 +478,10 @@ public final class IdentifiedObjects ext
         }
         final String code = identifier.getCode();
         String cs = identifier.getCodeSpace();
-        if (cs == null) {
-            cs = org.apache.sis.internal.util.Citations.getIdentifier(identifier.getAuthority());
+        if (cs == null || cs.isEmpty()) {
+            cs = org.apache.sis.internal.util.Citations.getUnicodeIdentifier(identifier.getAuthority());
         }
-        if (cs != null && !cs.isEmpty()) {
+        if (cs != null) {
             return cs + DefaultNameSpace.DEFAULT_SEPARATOR + code;
         }
         return code;

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/NamedIdentifier.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -33,10 +33,12 @@ import org.opengis.metadata.Identifier;
 import org.opengis.parameter.InvalidParameterValueException;
 import org.apache.sis.internal.metadata.NameToIdentifier;
 import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.metadata.iso.citation.Citations;  // For javadoc
 import org.apache.sis.metadata.iso.ImmutableIdentifier;
 import org.apache.sis.util.collection.WeakValueHashMap;
 
+import static org.apache.sis.internal.util.Citations.getUnicodeIdentifier;
+
 // Branch-dependent imports
 import java.util.Objects;
 
@@ -182,7 +184,7 @@ public class NamedIdentifier extends Imm
      * @param code      The code. This parameter is mandatory.
      */
     public NamedIdentifier(final Citation authority, final String code) {
-        super(authority, Citations.getIdentifier(authority), code);
+        super(authority, getUnicodeIdentifier(authority), code);
     }
 
     /**
@@ -238,14 +240,14 @@ public class NamedIdentifier extends Imm
      */
     private GenericName createName(final Citation authority, final CharSequence code) {
         final NameFactory factory = DefaultFactories.NAMES;
-        final String title = Citations.getIdentifier(authority); // Whitespaces trimed by
Citations.
+        final String identifier = getUnicodeIdentifier(authority);      // Whitespaces trimed
by Citations.
         NameSpace scope = null;
-        if (title != null) {
+        if (identifier != null) {
             synchronized (SCOPES) {
-                scope = SCOPES.get(title);
+                scope = SCOPES.get(identifier);
                 if (scope == null) {
-                    scope = factory.createNameSpace(factory.createLocalName(null, title),
null);
-                    SCOPES.put(title, scope);
+                    scope = factory.createNameSpace(factory.createLocalName(null, identifier),
null);
+                    SCOPES.put(identifier, scope);
                 }
             }
         }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/IdentifierMapEntry.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -73,7 +73,7 @@ final class IdentifierMapEntry extends A
      */
     @Override
     public String getCodeSpace() {
-        return Citations.getIdentifier(getAuthority());
+        return Citations.getUnicodeIdentifier(getAuthority());
     }
 
     /**
@@ -110,7 +110,7 @@ final class IdentifierMapEntry extends A
         Immutable(Citation authority, String code) {super(authority, code);}
         @Override public Citation            getAuthority()   {return getKey();}
         @Override public String              getCode()        {return getValue();}
-        @Override public String              getCodeSpace()   {return Citations.getIdentifier(getAuthority());}
+        @Override public String              getCodeSpace()   {return Citations.getUnicodeIdentifier(getAuthority());}
         @Override public String              getVersion()     {return null;}
         @Override public InternationalString getDescription() {return null;}
     }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/SpecializedIdentifier.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -196,7 +196,7 @@ public final class SpecializedIdentifier
      */
     @Override
     public String getCodeSpace() {
-        return Citations.getIdentifier(authority);
+        return Citations.getUnicodeIdentifier(authority);
     }
 
     /**
@@ -264,7 +264,7 @@ public final class SpecializedIdentifier
      * Formats the given (authority, code) par value in the given buffer.
      */
     static void format(final StringBuilder buffer, final Citation authority, final String
code) {
-        buffer.append(Citations.getIdentifier(authority)).append('=');
+        buffer.append(Citations.getIdentifier(authority, false)).append('=');
         final boolean quote = (code != null) && (code.indexOf('[') < 0);
         if (quote) buffer.append('“');
         buffer.append(code);

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -249,8 +249,9 @@ public class SimpleIdentifiedObject impl
             buffer.append(codespace).append(DefaultNameSpace.DEFAULT_SEPARATOR);
         }
         buffer.append(code).append('"');
-        if (authority != null) {
-            buffer.append(", ID[\"").append(Citations.getIdentifier(authority)).append("\"]");
+        final String identifier = Citations.getUnicodeIdentifier(authority);
+        if (identifier != null) {
+            buffer.append(", ID[\"").append(identifier).append("\"]");
         }
         return buffer.append(']').toString();
     }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifier.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifier.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifier.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -102,7 +102,7 @@ public class SimpleIdentifier implements
      */
     @Override
     public String getCodeSpace() {
-        return Citations.getIdentifier(authority);
+        return Citations.getUnicodeIdentifier(authority);
     }
 
     /**
@@ -220,7 +220,7 @@ public class SimpleIdentifier implements
      */
     public String toWKT() {
         final StringBuilder buffer = new StringBuilder(40).append("ID[");
-        append(buffer, Citations.getIdentifier(authority)); // Do not invoke getCodeSpace().
+        append(buffer, Citations.getUnicodeIdentifier(authority)); // Do not invoke getCodeSpace().
         append(buffer.append(", "), code);
         return buffer.append(']').toString();
     }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Citations.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -79,7 +79,7 @@ public final class Citations extends Sta
 
     /**
      * Returns a "unlocalized" string representation of the given international string,
-     * or {@code null} if none. This method is used by {@link #getIdentifier(Citation)},
+     * or {@code null} if none. This method is used by {@link #getIdentifier(Citation, boolean)},
      * which is why we don't want the localized string.
      */
     private static String toString(final InternationalString title) {
@@ -291,10 +291,11 @@ public final class Citations extends Sta
      * Null references, empty character sequences and sequences of whitespaces only are ignored.
      *
      * @param  citation The citation for which to get the identifier, or {@code null}.
+     * @param  strict {@code true} for returning a non-null value only if the identifier
is a valid Unicode identifier.
      * @return A non-empty identifier for the given citation without leading or trailing
whitespaces,
      *         or {@code null} if the given citation is null or does not declare any identifier
or title.
      */
-    public static String getIdentifier(final Citation citation) {
+    public static String getIdentifier(final Citation citation, final boolean strict) {
         boolean isUnicode = false; // Whether 'identifier' is a Unicode identifier.
         String identifier = null;
         if (citation != null) {
@@ -345,6 +346,73 @@ public final class Citations extends Sta
                 }
             }
         }
+        return (isUnicode || !strict) ? identifier : null;
+    }
+
+    /**
+     * Infers a valid Unicode identifier from the given citation, or returns {@code null}
if none.
+     * This method performs the following actions:
+     *
+     * <ul>
+     *   <li>First, invoke {@link #getIdentifier(Citation, boolean)}.</li>
+     *   <li>If the result of above method call is {@code null} or is not a
+     *       {@linkplain org.apache.sis.util.CharSequences#isUnicodeIdentifier valid Unicode
identifier},
+     *       then return {@code null}.</li>
+     *   <li>Otherwise remove the {@linkplain Character#isIdentifierIgnorable(int)
ignorable identifier characters},
+     *       if any. Then:
+     *       <ul>
+     *         <li>If the result is an empty string, returns {@code null}.</li>
+     *         <li>Otherwise returns the result.</li>
+     *       </ul>
+     *   </li>
+     * </ul>
+     *
+     * If non-null, the result is suitable for use as a XML identifier except for rarely
used characters
+     * (‘{@code µ}’, ‘{@code ª}’ (feminine ordinal indicator), ‘{@code º}’
(masculine ordinal indicator)
+     * and ‘{@code ⁔}’).
+     *
+     * @param  citation The citation for which to get the Unicode identifier, or {@code null}.
+     * @return A non-empty Unicode identifier for the given citation without leading or trailing
whitespaces,
+     *         or {@code null} if the given citation is null or does not have any Unicode
identifier or title.
+     *
+     * @since 0.6
+     */
+    public static String getUnicodeIdentifier(final Citation citation) {
+        final String identifier = getIdentifier(citation, true);
+        if (identifier != null) {
+            /*
+             * First perform a quick check to see if there is any ignorable characters.
+             * We make this check because those characters are valid according Unicode
+             * but not according XML. However there is usually no such characters, so
+             * we will avoid the StringBuilder creation in the vast majority of times.
+             *
+             * Note that 'µ' and its friends are not ignorable, so we do not remove them.
+             * This method is "getUnicodeIdentifier", not "getXmlIdentifier".
+             */
+            final int length = identifier.length();
+            for (int i=0; i<length;) {
+                int c = identifier.codePointAt(i);
+                int n = Character.charCount(c);
+                if (Character.isIdentifierIgnorable(c)) {
+                    /*
+                     * Found an ignorable character. Create the buffer and copy non-ignorable
characters.
+                     * Following algorithm is inefficient, since we fill the buffer character-by-character
+                     * (a more efficient approach would be to perform bulk appends). However
we presume
+                     * that this block will be rarely executed, so it is not worth to optimize
it.
+                     */
+                    final StringBuilder buffer = new StringBuilder(length - n).append(identifier,
0, i);
+                    while ((i += n) < length) {
+                        c = identifier.codePointAt(i);
+                        n = Character.charCount(c);
+                        if (!Character.isIdentifierIgnorable(c)) {
+                            buffer.appendCodePoint(c);
+                        }
+                    }
+                    return (buffer.length() != 0) ? buffer.toString() : null;
+                }
+                i += n;
+            }
+        }
         return identifier;
     }
 }

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/IdentifiedObjectFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/IdentifiedObjectFormat.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/IdentifiedObjectFormat.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/io/IdentifiedObjectFormat.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -70,7 +70,7 @@ final class IdentifiedObjectFormat exten
         final String code = identifier.getCode();
         String cs = identifier.getCodeSpace();
         if (cs == null || cs.isEmpty()) {
-            cs = Citations.getIdentifier(identifier.getAuthority());
+            cs = Citations.getUnicodeIdentifier(identifier.getAuthority());
         }
         if (cs != null) {
             toAppendTo.append(cs).append(DefaultNameSpace.DEFAULT_SEPARATOR);

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -19,6 +19,8 @@ package org.apache.sis.util;
 import java.util.Arrays;
 import java.nio.CharBuffer;
 import java.util.StringJoiner;
+import org.opengis.metadata.citation.Citation;      // For javadoc
+import org.opengis.referencing.IdentifiedObject;    // For javadoc
 
 import static java.lang.Character.*;
 
@@ -1539,8 +1541,42 @@ cmp:    while (ia < lga) {
      * Unicode identifier start} and all remaining characters (if any) are
      * {@linkplain Character#isUnicodeIdentifierPart(int) Unicode identifier parts}.
      *
+     * {@section Relationship with legal XML identifiers}
+     * Most legal Unicode identifiers are also legal XML identifiers, but the converse is
not true.
+     * The most noticeable differences are the ‘{@code :}’, ‘{@code -}’ and ‘{@code
.}’ characters,
+     * which are legal in XML identifiers but not in Unicode.
+     *
+     * <table class="sis">
+     *   <caption>Characters legal in one set but not in the other</caption>
+     *   <tr><th colspan="2">Not legal in Unicode</th>    <th class="sep"
colspan="2">Not legal in XML</th></tr>
+     *   <tr><td>{@code :}</td><td>(colon)</td>           <td
class="sep">{@code µ}</td><td>(micro sign)</td></tr>
+     *   <tr><td>{@code -}</td><td>(hyphen or minus)</td> <td
class="sep">{@code ª}</td><td>(feminine ordinal indicator)</td></tr>
+     *   <tr><td>{@code .}</td><td>(dot)</td>             <td
class="sep">{@code º}</td><td>(masculine ordinal indicator)</td></tr>
+     *   <tr><td>{@code ·}</td><td>(middle dot)</td>     
<td class="sep">{@code ⁔}</td><td>(inverted undertie)</td></tr>
+     *   <tr>
+     *     <td colspan="2">Many punctuation, symbols, <i>etc</i>.</td>
+     *     <td colspan="2" class="sep">{@linkplain Character#isIdentifierIgnorable(int)
Identifier ignorable} characters.</td>
+     *   </tr>
+     * </table>
+     *
+     * Note that the ‘{@code _}’ (underscore) character is legal according both Unicode
and XML, while spaces,
+     * ‘{@code !}’, ‘{@code #}’, ‘{@code *}’, ‘{@code /}’, ‘{@code ?}’
and most other punctuation characters are not.
+     *
+     * {@section Usage in Apache SIS}
+     * In its handling of {@linkplain org.apache.sis.metadata.iso.ImmutableIdentifier identifiers},
Apache SIS favors
+     * Unicode identifiers without {@linkplain Character#isIdentifierIgnorable(int) ignorable}
characters since those
+     * identifiers are legal XML identifiers except for the above-cited rarely used characters.
As a side effect,
+     * this policy excludes ‘{@code :}’, ‘{@code -}’ and ‘{@code .}’ which would
normally be legal XML identifiers.
+     * But since those characters could easily be confused with
+     * {@linkplain org.apache.sis.util.iso.DefaultNameSpace#DEFAULT_SEPARATOR namespace separators},
+     * this exclusion is considered desirable.
+     *
      * @param  identifier The character sequence to test, or {@code null}.
      * @return {@code true} if the given character sequence is a legal Unicode identifier.
+     *
+     * @see org.apache.sis.metadata.iso.ImmutableIdentifier
+     * @see org.apache.sis.metadata.iso.citation.Citations#getUnicodeIdentifier(Citation)
+     * @see org.apache.sis.referencing.IdentifiedObjects#getUnicodeIdentifier(IdentifiedObject)
      */
     public static boolean isUnicodeIdentifier(final CharSequence identifier) {
         final int length = length(identifier);

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/simple/SimpleIdentifierTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/simple/SimpleIdentifierTest.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/simple/SimpleIdentifierTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/simple/SimpleIdentifierTest.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.simple;
 
+import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
@@ -30,6 +31,7 @@ import static org.junit.Assert.*;
  * @version 0.3
  * @module
  */
+@DependsOn(org.apache.sis.internal.util.CitationsTest.class)
 public final strictfp class SimpleIdentifierTest extends TestCase {
     /**
      * Tests {@link SimpleIdentifier#toString()}.

Added: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java?rev=1660761&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java
(added)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.util;
+
+import org.opengis.metadata.citation.Citation;
+import org.apache.sis.internal.simple.SimpleCitation;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests the {@link Citations} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ */
+public final strictfp class CitationsTest extends TestCase {
+    /**
+     * Tests {@link Citations#getIdentifier(Citation, boolean)}.
+     */
+    @Test
+    public void testGetIdentifier() {
+        SimpleCitation citation = new SimpleCitation(" Not an identifier ");
+        assertEquals("Not an identifier", Citations.getIdentifier(citation, false));
+        assertNull(Citations.getIdentifier(citation, true));
+
+        citation = new SimpleCitation(" ValidIdentifier ");
+        assertEquals("ValidIdentifier", Citations.getIdentifier(citation, false));
+        assertEquals("ValidIdentifier", Citations.getIdentifier(citation, true));
+    }
+
+    /**
+     * Tests {@link Citations#getUnicodeIdentifier(Citation)} with some ignorable characters.
+     * Ignorable character used in this test are:
+     *
+     * <ul>
+     *   <li>200B: zero width space</li>
+     *   <li>2060: word joiner</li>
+     * </ul>
+     */
+    @Test
+    @DependsOnMethod("testGetIdentifier")
+    public void testGetUnicodeIdentifier() {
+        final SimpleCitation citation = new SimpleCitation(" Valid\u2060Id\u200Bentifier
");
+        assertEquals("ValidIdentifier", Citations.getUnicodeIdentifier(citation));
+    }
+}

Propchange: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/CitationsTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -82,6 +82,7 @@ import org.junit.BeforeClass;
     // GeoAPI most basic types.
     org.apache.sis.internal.util.DefinitionURITest.class,
     org.apache.sis.internal.util.XPathsTest.class,
+    org.apache.sis.internal.util.CitationsTest.class,
     org.apache.sis.util.iso.TypesTest.class,
     org.apache.sis.util.iso.SimpleInternationalStringTest.class,
     org.apache.sis.util.iso.DefaultInternationalStringTest.class,

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java?rev=1660761&r1=1660760&r2=1660761&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/CharSequencesTest.java
[UTF-8] Wed Feb 18 23:12:17 2015
@@ -34,7 +34,7 @@ import static org.apache.sis.util.CharSe
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Johann Sorel (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.6
  * @module
  */
 @DependsOn({
@@ -394,9 +394,28 @@ public final strictfp class CharSequence
      */
     @Test
     public void testIsUnicodeIdentifier() {
+        assertFalse(        isUnicodeIdentifier(null));
         assertTrue ("A123", isUnicodeIdentifier("A123"));
         assertFalse("123A", isUnicodeIdentifier("123A"));
-        assertFalse(        isUnicodeIdentifier(null));
+        assertTrue ("A_1",  isUnicodeIdentifier("A_1"));
+        assertFalse("A-1",  isUnicodeIdentifier("A-1"));
+        assertFalse("A+1",  isUnicodeIdentifier("A+1"));
+        assertFalse("A/1",  isUnicodeIdentifier("A/1"));
+        assertFalse("A\\1", isUnicodeIdentifier("A\\1"));
+        assertFalse("A*1",  isUnicodeIdentifier("A*1"));
+        assertFalse("A.1",  isUnicodeIdentifier("A.1"));
+        assertFalse("A,1",  isUnicodeIdentifier("A,1"));
+        assertFalse("A:1",  isUnicodeIdentifier("A:1"));
+        assertFalse("A;1",  isUnicodeIdentifier("A;1"));
+        assertFalse("A#1",  isUnicodeIdentifier("A#1"));
+        assertFalse("A?1",  isUnicodeIdentifier("A?1"));
+        assertFalse("A!1",  isUnicodeIdentifier("A!1"));
+        assertFalse("A°1",  isUnicodeIdentifier("A°1"));  // Degree
+        assertTrue ("Aº1",  isUnicodeIdentifier("Aº1"));  // Masculine ordinal
+        assertFalse("A 1",  isUnicodeIdentifier("A 1"));  // Ordinary space
+        assertFalse("A 1",  isUnicodeIdentifier("A" + Characters.NO_BREAK_SPACE + "1"));
+        assertFalse("A‐1",  isUnicodeIdentifier("A" + Characters.HYPHEN         + "1"));
+        assertTrue ("A­1",  isUnicodeIdentifier("A" + Characters.SOFT_HYPHEN    + "1"));
     }
 
     /**



Mime
View raw message