Author: desruisseaux
Date: Sun Dec 8 04:35:04 2013
New Revision: 1548994
URL: http://svn.apache.org/r1548994
Log:
More intelligent parsing of <gml:identifier> elements.
Added:
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierTest.java
(with props)
Removed:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierCode.java
Modified:
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/RS_Identifier.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.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/test/suite/ReferencingTestSuite.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/URIParser.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/URIParserTest.java
sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -58,6 +58,17 @@ public final class Citations extends Sta
public static final Citation OGC = new SimpleCitation("OGC");
/**
+ * The <a href="http://www.ogp.org.uk">International Association of Oil & Gas
Producers</a> organization.
+ * This organization is responsible for maintainance of {@link #EPSG} database.
+ *
+ * @see #EPSG
+ * @category Organization
+ *
+ * @since 0.4
+ */
+ public static final Citation OGP = new SimpleCitation("OGP");
+
+ /**
* The <a href="http://sis.apache.org">Apache SIS</a> project.
*
* @since 0.4
@@ -121,6 +132,7 @@ public final class Citations extends Sta
* {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference
system}
* identifiers.
*
+ * @see #OGP
* @see #AUTO
* @see #AUTO2
* @see #CRS
@@ -157,7 +169,7 @@ public final class Citations extends Sta
* List of citations declared in this class.
*/
private static final Citation[] AUTHORITIES = {
- ISO, OGC, SIS, ESRI, ORACLE, NETCDF, GEOTIFF, PROJ4, EPSG, ISBN, ISSN
+ ISO, OGC, OGP, SIS, ESRI, ORACLE, NETCDF, GEOTIFF, PROJ4, EPSG, ISBN, ISSN
};
/**
Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/HardCodedCitations.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -87,6 +87,21 @@ public final strictfp class HardCodedCit
}
/**
+ * The <a href="http://www.ogp.org.uk">International Association of Oil & Gas
Producers</a> organization.
+ * This organization is responsible for maintainance of {@link #EPSG} database.
+ * An {@linkplain Citation#getAlternateTitles() alternate title} for this citation is
"OGP"
+ * (according ISO 19115, alternate titles often contain abbreviations).
+ */
+ public static final DefaultCitation OGP;
+ static {
+ final DefaultCitation c = new DefaultCitation("International Association of Oil &
Gas Producers");
+ c.setAlternateTitles(singleton(new SimpleInternationalString("OGP")));
+ c.getIdentifiers().add(new DefaultIdentifier("OGP"));
+ c.freeze();
+ OGP = c;
+ }
+
+ /**
* The <a href="http://www.epsg.org">European Petroleum Survey Group</a>
authority.
* An {@linkplain Citation#getAlternateTitles() alternate title} for this citation is
* "EPSG" (according ISO 19115, alternate titles often contain abbreviations). In
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/RS_Identifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/RS_Identifier.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/RS_Identifier.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/RS_Identifier.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -23,21 +23,43 @@ import org.opengis.metadata.citation.Cit
import org.opengis.referencing.ReferenceIdentifier;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.metadata.iso.ImmutableIdentifier;
-import org.apache.sis.util.StringBuilders;
+import org.apache.sis.internal.util.URIParser;
/**
* JAXB adapter mapping the GeoAPI {@link ReferenceIdentifier} to an implementation class
that can
* be marshalled. See the package documentation for more information about JAXB and interfaces.
*
- * <p>The XML produced by this adapter uses the GML syntax. The {@link RS_IdentifierCode}
class
- * performs a similar mapping, but in which only the code (without codespace) is marshalled.</p>
- *
* <p>Note that a class of the same name is defined in the {@link org.apache.sis.internal.jaxb.metadata}
* package, which serve the same purpose (wrapping exactly the same interface) but using
the ISO 19139
* syntax instead. The ISO 19139 syntax represents the code and codespace as XML elements,
while in this
* GML representation the code is a XML value and the codespace is a XML attribute.</p>
*
+ * {@section Marshalling}
+ * Identifiers are typically marshalled as below:
+ *
+ * {@preformat xml
+ * <gml:identifier codeSpace="EPSG">4326</gml:identifier>
+ * }
+ *
+ * If the {@code ReferenceIdentifier} to marshal contains a {@linkplain ReferenceIdentifier#getVersion()
version},
+ * then this adapter concatenates the version to the codespace in a "URI-like" way like below:
+ *
+ * {@preformat xml
+ * <gml:identifier codeSpace="EPSG:8.3">4326</gml:identifier>
+ * }
+ *
+ * {@section Unmarshalling}
+ * Some data producers put a URN instead than a simple code value, as in the example below:
+ *
+ * {@preformat xml
+ * <gml:identifier codeSpace="OGP">urn:ogc:def:crs:EPSG::4326</gml:identifier>
+ * }
+ *
+ * In such case this class takes the codespace as the {@linkplain ReferenceIdentifier#getAuthority()
authority}
+ * ("OGP" in above example), and the 3 last URI elements are parsed as the codespace, version
(optional) and
+ * code values respectively.
+ *
* @author Guilhem Legal (Geomatys)
* @author Cédric Briançon (Geomatys)
* @author Martin Desruisseaux (Geomatys)
@@ -59,7 +81,7 @@ public final class RS_Identifier extends
* {@link org.apache.sis.metadata.iso.ImmutableIdentifier} represents it as an XML
element.</p>
*/
@XmlValue
- private String code;
+ String code;
/**
* The code space, which is often {@code "EPSG"} with the version in use.
@@ -68,7 +90,7 @@ public final class RS_Identifier extends
* {@link org.apache.sis.metadata.iso.ImmutableIdentifier} represents it as an XML
element.</p>
*/
@XmlAttribute
- private String codeSpace;
+ String codeSpace;
/**
* Empty constructor for JAXB only.
@@ -78,6 +100,9 @@ public final class RS_Identifier extends
/**
* Creates a wrapper initialized to the values of the given identifier.
+ * Version number, if presents, will be appended after the codespace with a semicolon
separator.
+ * The {@link #getIdentifier()} method shall be able to perform the opposite operation
(split the
+ * above in separated codespace and version attributes).
*
* @param identifier The identifier from which to get the values.
*/
@@ -86,21 +111,42 @@ public final class RS_Identifier extends
codeSpace = identifier.getCodeSpace();
String version = identifier.getVersion();
if (version != null) {
- final StringBuilder buffer = new StringBuilder(codeSpace);
- if (buffer.length() != 0) {
- buffer.append('_');
+ final StringBuilder buffer = new StringBuilder();
+ if (codeSpace != null) {
+ buffer.append(codeSpace);
}
- StringBuilders.remove(buffer.append('v').append(version), ".");
- codeSpace = buffer.toString();
+ codeSpace = buffer.append(URIParser.SEPARATOR).append(version).toString();
}
}
/**
* Returns the identifier for this value. This method is the converse of the constructor.
+ * If the {@link #codeSpace} contains a semicolon, then the part after the last semicolon
+ * will be taken as the authority version number. This is for consistency with what
the
+ * constructor does.
*/
ReferenceIdentifier getIdentifier() {
- final Citation authority = Citations.fromName(codeSpace); // May be null.
- return new ImmutableIdentifier(authority, Citations.getIdentifier(authority),
code);
+ String c = code;
+ if (c == null) {
+ return null;
+ }
+ Citation authority = null;
+ String version = null, cs = codeSpace;
+ final URIParser parsed = URIParser.parse(c);
+ if (parsed != null) {
+ authority = Citations.fromName(cs); // May be null.
+ cs = parsed.authority;
+ version = parsed.version;
+ c = parsed.code;
+ } else if (cs != null) {
+ final int s = cs.lastIndexOf(URIParser.SEPARATOR);
+ if (s >= 0) {
+ version = cs.substring(s+1);
+ cs = cs.substring(0, s);
+ }
+ authority = Citations.fromName(cs);
+ }
+ return new ImmutableIdentifier(authority, cs, c, version, null);
}
}
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=1548994&r1=1548993&r2=1548994&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] Sun Dec 8 04:35:04 2013
@@ -34,6 +34,7 @@ import org.opengis.parameter.ParameterDe
import org.opengis.parameter.ParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.util.CodeList;
@@ -463,20 +464,26 @@ public class Formatter {
*/
final Identifier identifier = getIdentifier(info);
if (identifier != null && !AUTHORITY_EXCLUDE.isInstance(info)) {
- final Citation authority = identifier.getAuthority();
- if (authority != null) {
- final String title = Citations.getIdentifier(authority);
- if (title != null) {
- appendSeparator(requestNewLine);
- buffer.append("AUTHORITY").appendCodePoint(open);
- quote(title);
- final String code = identifier.getCode();
- if (code != null) {
- buffer.append(symbols.getSeparator());
- quote(code);
- }
- buffer.appendCodePoint(close);
+ String codeSpace = null;
+ if (identifier instanceof ReferenceIdentifier) {
+ codeSpace = ((ReferenceIdentifier) identifier).getCodeSpace();
+ }
+ if (codeSpace == null) {
+ final Citation authority = identifier.getAuthority();
+ if (authority != null) {
+ codeSpace = Citations.getIdentifier(authority);
+ }
+ }
+ if (codeSpace != null) {
+ appendSeparator(requestNewLine);
+ buffer.append("AUTHORITY").appendCodePoint(open);
+ quote(codeSpace);
+ final String code = identifier.getCode();
+ if (code != null) {
+ buffer.append(symbols.getSeparator());
+ quote(code);
}
+ buffer.appendCodePoint(close);
}
}
buffer.appendCodePoint(close);
Added: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierTest.java?rev=1548994&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierTest.java
(added)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierTest.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -0,0 +1,97 @@
+/*
+ * 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.jaxb.referencing;
+
+import org.opengis.referencing.ReferenceIdentifier;
+import org.apache.sis.metadata.iso.ImmutableIdentifier;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.metadata.iso.citation.HardCodedCitations;
+import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests {@link RS_Identifier}.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.4
+ * @version 0.4
+ * @module
+ */
+public final strictfp class RS_IdentifierTest extends TestCase {
+ /**
+ * Tests {@link RS_Identifier.Value} with {@code "EPSG:4326"}.
+ */
+ @Test
+ public void testSimple() {
+ final ReferenceIdentifier id = new ImmutableIdentifier(HardCodedCitations.OGP, "EPSG",
"4326");
+ final RS_Identifier.Value value = new RS_Identifier.Value(id);
+ assertEquals("codeSpace", "EPSG", value.codeSpace);
+ assertEquals("code", "4326", value.code);
+ /*
+ * Reverse operation. Note that the authority is lost since there is no room for
that in a
+ * <gml:identifier> element. Current implementation sets the authority to the
code space.
+ */
+ final ReferenceIdentifier actual = value.getIdentifier();
+ assertSame ("authority", Citations.EPSG, actual.getAuthority());
+ assertEquals("codeSpace", "EPSG", actual.getCodeSpace());
+ assertNull ("version", actual.getVersion());
+ assertEquals("code", "4326", actual.getCode());
+ }
+
+ /**
+ * Tests {@link RS_Identifier.Value} with {@code "EPSG:8.3:4326"}.
+ */
+ @Test
+ @DependsOnMethod("testSimple")
+ public void testWithVersion() {
+ final ReferenceIdentifier id = new ImmutableIdentifier(HardCodedCitations.OGP, "EPSG",
"4326", "8.2", null);
+ final RS_Identifier.Value value = new RS_Identifier.Value(id);
+ assertEquals("codeSpace", "EPSG:8.2", value.codeSpace);
+ assertEquals("code", "4326", value.code);
+ /*
+ * Reverse operation. Note that the authority is lost since there is no room for
that in a
+ * <gml:identifier> element. Current implementation sets the authority to the
code space.
+ */
+ final ReferenceIdentifier actual = value.getIdentifier();
+ assertSame ("authority", Citations.EPSG, actual.getAuthority());
+ assertEquals("codeSpace", "EPSG", actual.getCodeSpace());
+ assertEquals("version", "8.2", actual.getVersion());
+ assertEquals("code", "4326", actual.getCode());
+ }
+
+ /**
+ * Tests {@link RS_Identifier.Value} with {@code "urn:ogc:def:crs:EPSG:8.2:4326"}.
+ * This test simulate the {@code RS_Identifier.Value} object state that we get after
+ * XML unmarshalling of an object from the EPSG registry.
+ */
+ @Test
+ @DependsOnMethod("testWithVersion")
+ public void testURN() {
+ final RS_Identifier.Value value = new RS_Identifier.Value();
+ value.codeSpace = "OGP";
+ value.code = "urn:ogc:def:crs:EPSG:8.2:4326";
+ final ReferenceIdentifier actual = value.getIdentifier();
+ assertSame ("authority", Citations.OGP, actual.getAuthority());
+ assertEquals("codeSpace", "EPSG", actual.getCodeSpace());
+ assertEquals("version", "8.2", actual.getVersion());
+ assertEquals("code", "4326", actual.getCode());
+ }
+}
Propchange: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/jaxb/referencing/RS_IdentifierTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/AbstractIdentifiedObjectTest.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -37,7 +37,10 @@ import static org.apache.sis.metadata.is
* @version 0.4
* @module
*/
-@DependsOn({IdentifiedObjectsTest.class, NamedIdentifierTest.class})
+@DependsOn({
+ IdentifiedObjectsTest.class, NamedIdentifierTest.class,
+ org.apache.sis.internal.jaxb.referencing.RS_IdentifierTest.class
+})
public final strictfp class AbstractIdentifiedObjectTest extends TestCase {
/**
* Tests the {@link AbstractIdentifiedObject#AbstractIdentifiedObject(Map)} constructor.
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=1548994&r1=1548993&r2=1548994&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] Sun Dec 8 04:35:04 2013
@@ -139,10 +139,10 @@ 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[“OGP”, “urn:ogc:def:meridian:EPSG::8903”]]");
+ assertWktEquals(pm, "PRIMEM[“Paris”, 2.33722917, AUTHORITY[“EPSG”, “8903”]]");
assertXmlEquals(
"<gml:PrimeMeridian xmlns:gml=\"" + Namespaces.GML + "\">\n" +
- " <gml:identifier codeSpace=\"OGP\">urn:ogc:def:meridian:EPSG::8903</gml:identifier>"
+
+ " <gml:identifier codeSpace=\"EPSG\">8903</gml:identifier>"
+
" <gml:name>Paris</gml:name>\n" +
" <gml:remarks>Equivalent to 2°20′14.025″.</gml:remarks>\n"
+
" <gml:greenwichLongitude uom=\"urn:ogc:def:uom:EPSG::9105\">2.5969213</gml:greenwichLongitude>\n"
+
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -47,6 +47,7 @@ import org.junit.BeforeClass;
org.apache.sis.io.wkt.ConventionTest.class,
org.apache.sis.io.wkt.SymbolsTest.class,
org.apache.sis.io.wkt.FormatterTest.class,
+ org.apache.sis.internal.jaxb.referencing.RS_IdentifierTest.class,
org.apache.sis.referencing.IdentifiedObjectsTest.class,
org.apache.sis.referencing.NamedIdentifierTest.class,
org.apache.sis.referencing.AbstractIdentifiedObjectTest.class,
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -26,6 +26,7 @@ import org.opengis.metadata.citation.Cit
import org.opengis.metadata.extent.Extent;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.ReferenceIdentifier;
+import org.apache.sis.internal.util.Citations;
import org.apache.sis.util.iso.DefaultNameSpace;
import org.apache.sis.util.LenientComparable;
import org.apache.sis.util.ComparisonMode;
@@ -243,7 +244,7 @@ public class SimpleIdentifiedObject impl
}
buffer.append(code).append('"');
if (authority != null) {
- buffer.append(", AUTHORITY[\"").append(authority.getTitle()).append("\"]");
+ buffer.append(", AUTHORITY[\"").append(Citations.getIdentifier(authority)).append("\"]");
}
if (deprecated) {
buffer.append(", DEPRECATED");
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/URIParser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/URIParser.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/URIParser.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/URIParser.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -16,7 +16,11 @@
*/
package org.apache.sis.internal.util;
+import java.util.Map;
+import java.util.Collections;
+
import static org.apache.sis.util.CharSequences.*;
+import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
/**
@@ -36,11 +40,11 @@ import static org.apache.sis.util.CharSe
* {@section Components or URN}
* URN begins with {@code "urn:ogc:def:"} (formerly {@code "urn:x-ogc:def:"}) followed by:
* <ul>
- * <li>an <cite>object type</cite></li>
- * <li>an <cite>authority</cite></li>
- * <li>an optional version number (often omitted)</li>
- * <li>the code</li>
- * <li>an arbitrary amount of parameters</li>
+ * <li>an object {@linkplain #type}</li>
+ * <li>an {@linkplain #authority}</li>
+ * <li>an optional {@linkplain #version} number (often omitted)</li>
+ * <li>the {@linkplain #code}</li>
+ * <li>an arbitrary amount of {@linkplain #parameters}</li>
* </ul>
*
* The <cite>object type</cite> can be:
@@ -97,26 +101,133 @@ public final class URIParser {
/**
* The URN separator.
*/
- private static final char SEPARATOR = ':';
+ public static final char SEPARATOR = ':';
+
+ /**
+ * Server and path portions of HTTP URL for various types (currently {@code "crs"}).
+ * For each URL, value starts after the protocol part and finishes before the authority
filename.
+ *
+ * <p>As of Apache SIS 0.4, this map has a single entry. However more entries may
be added in future SIS versions.
+ * If new entries are added, then see the TODO comment in the {@link #codeForHTTP(String,
String, String, int)}
+ * method.</p>
+ */
+ private static final Map<String,String> PATHS = Collections.singletonMap("crs",
"//www.opengis.net/gml/srs/");
+
+ /**
+ * {@code true} if the URI is a {@code "http://www.opengis.net/gml/…"} URL, or
+ * {@code false} if the URI is a {@code "urn:ogc:def:…"} URN.
+ */
+ public boolean isHTTP;
+
+ /**
+ * The type part of a URI, or {@code null} if none (empty).
+ *
+ * {@example In the <code>"urn:ogc:def:crs:EPSG:8.2:4326"</code> URN, this
is <code>"crs"</code>}.
+ */
+ public String type;
+
+ /**
+ * The authority part of a URI, or {@code null} if none (empty).
+ *
+ * {@example In the <code>"urn:ogc:def:crs:EPSG:8.2:4326"</code> URN, this
is <code>"EPSG"</code>}.
+ */
+ public String authority;
+
+ /**
+ * The version part of a URI, or {@code null} if none (empty).
+ *
+ * {@example In the <code>"urn:ogc:def:crs:EPSG:8.2:4326"</code> URN, this
is <code>"8.2"</code>}.
+ */
+ public String version;
/**
- * A URL portion of HTTP URL for Coordinate Reference System identifiers.
- * Portion starts after the protocol part, and finishes before the authority
+ * The code part of a URI, or {@code null} if none (empty).
+ *
+ * {@example In the <code>"urn:ogc:def:crs:EPSG:8.2:4326"</code> URN, this
is <code>"4326"</code>}.
*/
- private static final String SRS_PATH = "//www.opengis.net/gml/srs/";
+ public String code;
- /*
- * Current version contains only static methods. However a future version may contain
- * some fields like 'type', 'version' and 'authority' for storing the parsing result.
+ /**
+ * The parameters, or {@code null} if none.
+ *
+ * {@example In the <code>"urn:ogc:def:crs:OGC:1.3:AUTO42003:1:-100:45"</code>
URN,
+ * this is <code>{"1", "-100", "45"}</code>}.
*/
+ public String[] parameters;
/**
- * Do not allow instantiation of this class.
+ * For {@link #parse(String)} usage only.
*/
private URIParser() {
}
/**
+ * Parses the given URI.
+ *
+ * @param uri The URI to parse.
+ * @return The parse result, or {@code null} if the given URI is not recognized.
+ */
+ public static URIParser parse(final String uri) {
+ ensureNonNull("uri", uri);
+ URIParser result = null;
+ int upper = -1;
+ for (int p=0; p<=6; p++) {
+ final int lower = upper + 1;
+ upper = uri.indexOf(SEPARATOR, lower);
+ if (upper < 0) {
+ if (p != 6) {
+ return null; // No more components.
+ }
+ upper = uri.length();
+ }
+ final String require;
+ switch (p) {
+ /*
+ * Verifies that the 3 first components are ""urn:ogc:def:" without storing
them.
+ * In the particular case of second component, we also accept "x-ogc" in
addition
+ * to "ogc". The actual verification is performed after the 'switch' case.
+ */
+ case 0: if (regionMatches("http", uri, lower, upper)) {
+ result = new URIParser();
+ return codeForHTTP(null, null, uri, upper+1, result) != null
? result : null;
+ }
+ require = "urn"; break;
+ case 1: if (regionMatches("ogc", uri, lower, upper)) continue;
+ require = "x-ogc"; break;
+ case 2: require = "def"; break;
+ default: {
+ /*
+ * For all components after the first 3 ones, trim whitespaces and store
non-empty values.
+ */
+ String value = trimWhitespaces(uri, lower, upper).toString();
+ if (value.isEmpty()) {
+ value = null;
+ }
+ switch (p) {
+ case 3: result = new URIParser();
+ result.type = value; break;
+ case 4: result.authority = value; break;
+ case 5: result.version = value; break;
+ case 6: result.code = value; break;
+ default: throw new AssertionError(p);
+ }
+ continue;
+ }
+ }
+ if (!regionMatches(require, uri, lower, upper)) {
+ return null;
+ }
+ }
+ /*
+ * Take every remaining components as parameters.
+ */
+ if (++upper < uri.length()) {
+ result.parameters = (String[]) split(uri.substring(upper), SEPARATOR);
+ }
+ return result;
+ }
+
+ /**
* Returns {@code true} if a sub-region of {@code urn} matches the given {@code component},
* ignoring case, leading and trailing whitespaces.
*
@@ -184,13 +295,16 @@ public final class URIParser {
* <li>The HTTP form (e.g. {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"}).</li>
* </ul>
*
- * @param type The expected object type (e.g. {@code "crs"}). See class javadoc
for a list of types.
+ * @param type The expected object type (e.g. {@code "crs"}) in lower cases. See
class javadoc for a list of types.
* @param authority The expected authority, typically {@code "epsg"}. See class javadoc
for a list of authorities.
* @param uri The URI to parse.
* @return The code part of the given URI, or {@code null} if the codespace does not
match the given type
* and authority, the code is empty, or the code is followed by parameters.
*/
public static String codeOf(final String type, final String authority, final String uri)
{
+ ensureNonNull("type", type);
+ ensureNonNull("authority", authority);
+ ensureNonNull("uri", uri);
/*
* Get the part before the first ':' character. If none, assume that the given URI
is already the code.
* Otherwise the part may be either "http" or "urn" protocol, or the given authority
(typically "EPSG").
@@ -219,7 +333,7 @@ public final class URIParser {
return null;
}
if (length == 4) {
- return codeForHTTP(type, authority, uri, upper+1);
+ return codeForHTTP(type, authority, uri, upper+1, null);
}
/*
* At this point we have determined that the protocol is URN. The next components
after "urn"
@@ -256,23 +370,47 @@ public final class URIParser {
* <li>{@code crs} for Coordinate Reference System objects
* (example: {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"})</li>
* </ul>
+ *
+ * @param type The expected type in lower cases, or {@code null} for any.
+ * @param authority The expected authority, or {@code null} for any.
+ * @param url The URL to parse.
+ * @param result If non-null, store the type, authority and code in that object.
*/
- private static String codeForHTTP(final String type, final String authority, final String
url, int lower) {
- if (type.equals("crs")) {
- if (url.regionMatches(true, lower, SRS_PATH, 0, SRS_PATH.length())) {
- lower += SRS_PATH.length();
- if (url.regionMatches(true, lower, authority, 0, authority.length())) {
- lower += authority.length();
- int upper = url.length();
- if (lower < upper && url.charAt(lower) == '.') {
- // Ignore the extension (typically ".xml", but we accept anything).
- if ((lower = url.indexOf('#', lower+1)) >= 0) {
- lower = skipLeadingWhitespaces(url, lower+1, upper);
- upper = skipTrailingWhitespaces(url, lower, upper);
- if (lower < upper) {
- return url.substring(lower, upper);
- }
+ private static String codeForHTTP(final String type, String authority, final String url,
int lower,
+ final URIParser result)
+ {
+ Map<String, String> paths = PATHS;
+ if (type != null) {
+ final String path = paths.get(type);
+ if (path == null) {
+ return null;
+ }
+ // TODO: For now do nothing since PATHS is a singleton. However if a future SIS
version
+ // defines more PATHS entries, then we should replace here the 'paths'
reference by
+ // a new Collection.singletonMap containing only the entry of interest.
+ }
+ for (final Map.Entry<String,String> entry : paths.entrySet()) {
+ final String path = entry.getValue();
+ if (url.regionMatches(true, lower, path, 0, path.length())) {
+ lower += path.length();
+ if (authority == null) {
+ authority = url.substring(lower, skipIdentifierPart(url, lower));
+ } else if (!url.regionMatches(true, lower, authority, 0, authority.length()))
{
+ continue;
+ }
+ lower += authority.length();
+ int upper = url.length();
+ if (lower < upper && url.charAt(lower) == '.') {
+ // Ignore the extension (typically ".xml", but we accept anything).
+ if ((lower = url.indexOf('#', lower+1)) >= 0) {
+ final String code = trimWhitespaces(url, lower+1, upper).toString();
+ if (result != null) {
+ result.isHTTP = true;
+ result.type = entry.getKey();
+ result.authority = authority;
+ result.code = code;
}
+ return code;
}
}
}
@@ -281,6 +419,18 @@ public final class URIParser {
}
/**
+ * Returns the index after the last identifier character.
+ */
+ private static int skipIdentifierPart(final String text, int i) {
+ while (i < text.length()) {
+ final int c = text.codePointAt(i);
+ if (!Character.isUnicodeIdentifierPart(c)) break;
+ i += Character.charCount(c);
+ }
+ return i;
+ }
+
+ /**
* Parses a URL which contains a pointer to a XML fragment.
* The current implementation recognizes the following types:
*
@@ -319,16 +469,61 @@ public final class URIParser {
if (c == '\'' || c == '"') {
final int s = url.indexOf(c, ++i);
if (s >= 0) {
- return (String) trimWhitespaces(url, i, s);
+ return trimWhitespaces(url, i, s).toString();
}
}
}
} else {
- return (String) trimWhitespaces(url, f+1, url.length());
+ return trimWhitespaces(url, f+1, url.length()).toString();
}
}
}
}
return null;
}
+
+ /**
+ * Returns a URN representation of this URI.
+ *
+ * @return A URN representation of this URI.
+ */
+ public String toURN() {
+ final StringBuilder buffer = new StringBuilder("urn:ogc:def");
+ int n = 4;
+ if (parameters != null) {
+ n += parameters.length;
+ }
+ for (int p=0; p<n; p++) {
+ String component;
+ switch (p) {
+ case 0: component = type; break;
+ case 1: component = authority; break;
+ case 2: component = version; break;
+ case 3: component = code; break;
+ default: component = parameters[p-4]; break;
+ }
+ buffer.append(SEPARATOR);
+ if (component != null) {
+ buffer.append(component);
+ }
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Returns a string representation of this URI. If the URI were originally a HTTP URL,
+ * then this method format the URI as such. Otherwise this method returns {@link #toURN()}.
+ *
+ * @return The string representation of this URI.
+ */
+ @Override
+ public String toString() {
+ if (isHTTP) {
+ final String path = PATHS.get(type);
+ if (path != null) {
+ return "http:" + path + authority + ".xml#" + code;
+ }
+ }
+ return toURN();
+ }
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/CharSequences.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -639,7 +639,7 @@ search: for (; fromIndex <= toIndex;
}
// 'excludeEmpty' must use the same criterion than trimWhitespaces(…).
final boolean excludeEmpty = isWhitespace(separator);
- CharSequence[] strings = new CharSequence[4];
+ CharSequence[] strings = (text instanceof String) ? new String[4] : new CharSequence[4];
final int length = text.length();
int count = 0, last = 0, i = 0;
while ((i = indexOf(text, separator, i, length)) >= 0) {
Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/URIParserTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/URIParserTest.java?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/URIParserTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/URIParserTest.java
[UTF-8] Sun Dec 8 04:35:04 2013
@@ -16,6 +16,7 @@
*/
package org.apache.sis.internal.util;
+import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -32,6 +33,71 @@ import static org.junit.Assert.*;
*/
public final strictfp class URIParserTest extends TestCase {
/**
+ * Tests {@link URIParser#parse(String)} on {@code "urn:ogc:def:crs:EPSG:8.2:4326"}.
+ * This is a URN without parameters defined by EPSG.
+ */
+ @Test
+ public void testParse() {
+ assertNull(URIParser.parse("EPSG:4326"));
+
+ URIParser parsed = URIParser.parse(" urn:ogc:def: crs : EPSG: 8.2 :4326 ");
+ assertNotNull("URIParser", parsed);
+ assertEquals ("isHTTP", false, parsed.isHTTP);
+ assertEquals ("type", "crs", parsed.type);
+ assertEquals ("authority", "EPSG", parsed.authority);
+ assertEquals ("version", "8.2", parsed.version);
+ assertEquals ("code", "4326", parsed.code);
+ assertNull ("parameters", parsed.parameters);
+ assertEquals ("toString()", "urn:ogc:def:crs:EPSG:8.2:4326", parsed.toString());
+
+ parsed = URIParser.parse("URN :X-OGC: Def:crs:EPSG::4326");
+ assertNotNull("URIParser", parsed);
+ assertEquals ("isHTTP", false, parsed.isHTTP);
+ assertEquals ("type", "crs", parsed.type);
+ assertEquals ("authority", "EPSG", parsed.authority);
+ assertNull ("version", parsed.version);
+ assertEquals ("code", "4326", parsed.code);
+ assertNull ("parameters", parsed.parameters);
+ assertEquals ("toString()", "urn:ogc:def:crs:EPSG::4326", parsed.toString());
+ }
+
+ /**
+ * Tests {@link URIParser#parse(String)} on {@code "urn:ogc:def:crs:OGC:1.3:AUTO42003:1:-100:45"}.
+ * This is a URN with parameters defined in WMS specification.
+ */
+ @Test
+ @DependsOnMethod("testParse")
+ public void testParseWithParameters() {
+ final URIParser parsed = URIParser.parse("urn:ogc:def:crs:OGC:1.3:AUTO42003:1:-100:45");
+ assertNotNull("URIParser", parsed);
+ assertEquals ("isHTTP", false, parsed.isHTTP);
+ assertEquals ("type", "crs", parsed.type);
+ assertEquals ("authority", "OGC", parsed.authority);
+ assertEquals ("version", "1.3", parsed.version);
+ assertEquals ("code", "AUTO42003", parsed.code);
+ assertNotNull("parameters", parsed.parameters);
+ assertArrayEquals("parameters", new String[] {"1", "-100", "45"}, parsed.parameters);
+ assertEquals("toString()", "urn:ogc:def:crs:OGC:1.3:AUTO42003:1:-100:45", parsed.toString());
+ }
+
+ /**
+ * Tests {@link URIParser#parse(String)} on {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"}.
+ */
+ @Test
+ @DependsOnMethod("testParse")
+ public void testParseHTTP() {
+ final URIParser parsed = URIParser.parse("http://www.opengis.net/gml/srs/epsg.xml#4326");
+ assertNotNull("URIParser", parsed);
+ assertEquals ("isHTTP", true, parsed.isHTTP);
+ assertEquals ("type", "crs", parsed.type);
+ assertEquals ("authority", "epsg", parsed.authority);
+ assertNull ("version", parsed.version);
+ assertEquals ("code", "4326", parsed.code);
+ assertNull ("parameters", parsed.parameters);
+ assertEquals ("toString()", "http://www.opengis.net/gml/srs/epsg.xml#4326", parsed.toString());
+ }
+
+ /**
* Tests {@link URIParser#codeOf(String, String, String)} with URI like {@code "EPSG:4326"}.
*/
@Test
Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml?rev=1548994&r1=1548993&r2=1548994&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml (original)
+++ sis/branches/JDK7/ide-project/NetBeans/nbproject/project.xml Sun Dec 8 04:35:04 2013
@@ -59,6 +59,7 @@
<word>initially</word>
<word>javadoc</word>
<word>loggings</word>
+ <word>maintainance</word>
<word>marshallable</word>
<word>marshalled</word>
<word>marshaller</word>
|