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 ("A1", isUnicodeIdentifier("A" + Characters.SOFT_HYPHEN
+ "1"));
}
/**