From commits-return-3247-apmail-sis-commits-archive=sis.apache.org@sis.apache.org Sun Dec 8 04:35:42 2013 Return-Path: X-Original-To: apmail-sis-commits-archive@www.apache.org Delivered-To: apmail-sis-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8F94D10240 for ; Sun, 8 Dec 2013 04:35:42 +0000 (UTC) Received: (qmail 63308 invoked by uid 500); 8 Dec 2013 04:35:41 -0000 Delivered-To: apmail-sis-commits-archive@sis.apache.org Received: (qmail 63272 invoked by uid 500); 8 Dec 2013 04:35:36 -0000 Mailing-List: contact commits-help@sis.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sis-dev@sis.apache.org Delivered-To: mailing list commits@sis.apache.org Received: (qmail 63255 invoked by uid 99); 8 Dec 2013 04:35:34 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 08 Dec 2013 04:35:34 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 08 Dec 2013 04:35:28 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id CBA752388831; Sun, 8 Dec 2013 04:35:05 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r1548994 - in /sis/branches/JDK7: core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/ core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/ core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/re... Date: Sun, 08 Dec 2013 04:35:05 -0000 To: commits@sis.apache.org From: desruisseaux@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20131208043505.CBA752388831@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: desruisseaux Date: Sun Dec 8 04:35:04 2013 New Revision: 1548994 URL: http://svn.apache.org/r1548994 Log: More intelligent parsing of 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 International Association of Oil & Gas Producers 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 Apache SIS 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 International Association of Oil & Gas Producers 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 European Petroleum Survey Group 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. * - *

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.

- * *

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.

* + * {@section Marshalling} + * Identifiers are typically marshalled as below: + * + * {@preformat xml + * 4326 + * } + * + * 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 + * 4326 + * } + * + * {@section Unmarshalling} + * Some data producers put a URN instead than a simple code value, as in the example below: + * + * {@preformat xml + * urn:ogc:def:crs:EPSG::4326 + * } + * + * 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.

*/ @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.

*/ @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 + * 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 + * 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( "\n" + - " urn:ogc:def:meridian:EPSG::8903" + + " 8903" + " Paris\n" + " Equivalent to 2°20′14.025″.\n" + " 2.5969213\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: *
    - *
  • an object type
  • - *
  • an authority
  • - *
  • an optional version number (often omitted)
  • - *
  • the code
  • - *
  • an arbitrary amount of parameters
  • + *
  • an object {@linkplain #type}
  • + *
  • an {@linkplain #authority}
  • + *
  • an optional {@linkplain #version} number (often omitted)
  • + *
  • the {@linkplain #code}
  • + *
  • an arbitrary amount of {@linkplain #parameters}
  • *
* * The object type 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. + * + *

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.

+ */ + private static final Map 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 "urn:ogc:def:crs:EPSG:8.2:4326" URN, this is "crs"}. + */ + public String type; + + /** + * The authority part of a URI, or {@code null} if none (empty). + * + * {@example In the "urn:ogc:def:crs:EPSG:8.2:4326" URN, this is "EPSG"}. + */ + public String authority; + + /** + * The version part of a URI, or {@code null} if none (empty). + * + * {@example In the "urn:ogc:def:crs:EPSG:8.2:4326" URN, this is "8.2"}. + */ + 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 "urn:ogc:def:crs:EPSG:8.2:4326" URN, this is "4326"}. */ - 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 "urn:ogc:def:crs:OGC:1.3:AUTO42003:1:-100:45" URN, + * this is {"1", "-100", "45"}}. */ + 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 { *
  • The HTTP form (e.g. {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"}).
  • * * - * @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 { *
  • {@code crs} for Coordinate Reference System objects * (example: {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"})
  • * + * + * @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 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 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= 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 @@ initially javadoc loggings + maintainance marshallable marshalled marshaller