Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2007.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2007.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2007.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2007.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -52,7 +52,7 @@ public final strictfp class GIGS2007 ext * Creates a new test using the default authority factory. */ public GIGS2007() { - super(GIGS2001.factory); + super(TestFactorySource.factory); } /** @@ -62,16 +62,16 @@ public final strictfp class GIGS2007 ext */ @BeforeClass public static void createFactory() throws FactoryException { - GIGS2001.createFactory(); + TestFactorySource.createFactory(); } /** - * Force releases of JDBC connections after the tests in this class. + * Forces release of JDBC connections after the tests in this class. * * @throws FactoryException if an error occurred while closing the connections. */ @AfterClass public static void close() throws FactoryException { - GIGS2001.close(); + TestFactorySource.close(); } }
Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2008.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2008.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2008.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2008.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -52,7 +52,7 @@ public final strictfp class GIGS2008 ext * Creates a new test using the default authority factory. */ public GIGS2008() { - super(GIGS2001.factory, GIGS2001.factory); + super(TestFactorySource.factory, TestFactorySource.factory); } /** @@ -62,16 +62,16 @@ public final strictfp class GIGS2008 ext */ @BeforeClass public static void createFactory() throws FactoryException { - GIGS2001.createFactory(); + TestFactorySource.createFactory(); } /** - * Force releases of JDBC connections after the tests in this class. + * Forces release of JDBC connections after the tests in this class. * * @throws FactoryException if an error occurred while closing the connections. */ @AfterClass public static void close() throws FactoryException { - GIGS2001.close(); + TestFactorySource.close(); } } Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2009.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2009.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2009.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2009.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -52,7 +52,7 @@ public final strictfp class GIGS2009 ext * Creates a new test using the default authority factory. */ public GIGS2009() { - super(GIGS2001.factory); + super(TestFactorySource.factory); } /** @@ -62,16 +62,16 @@ public final strictfp class GIGS2009 ext */ @BeforeClass public static void createFactory() throws FactoryException { - GIGS2001.createFactory(); + TestFactorySource.createFactory(); } /** - * Force releases of JDBC connections after the tests in this class. + * Forces release of JDBC connections after the tests in this class. * * @throws FactoryException if an error occurred while closing the connections. */ @AfterClass public static void close() throws FactoryException { - GIGS2001.close(); + TestFactorySource.close(); } } Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -28,6 +28,8 @@ import org.opengis.referencing.crs.Geoce import org.opengis.referencing.crs.GeodeticCRS; import org.opengis.referencing.crs.GeographicCRS; import org.opengis.referencing.crs.VerticalCRS; +import org.opengis.referencing.crs.CompoundCRS; +import org.opengis.referencing.crs.SingleCRS; import org.opengis.referencing.datum.Datum; import org.opengis.referencing.datum.DatumAuthorityFactory; import org.opengis.referencing.datum.GeodeticDatum; @@ -36,6 +38,7 @@ import org.opengis.referencing.datum.Ver import org.opengis.util.FactoryException; import org.apache.sis.internal.system.Loggers; import org.apache.sis.metadata.iso.extent.Extents; +import org.apache.sis.referencing.cs.HardCodedCS; import org.apache.sis.referencing.crs.HardCodedCRS; import org.apache.sis.referencing.datum.HardCodedDatum; import org.apache.sis.measure.Units; @@ -274,6 +277,89 @@ public final strictfp class MultiAuthori } /** + * Tests {@code MultiAuthoritiesFactory.createFoo(String)} from codes in the + * {@code "urn:ogc:def:type, type₁:authority₁:version₁:code₁, type₂:authority₂:version₂:code₂"} form. + * + * @throws FactoryException if an authority or a code is not recognized. + * + * @since 0.8 + */ + @Test + @DependsOnMethod("testCreateFromURNs") + public void testCreateFromCombinedURNs() throws FactoryException { + final Set<AuthorityFactoryMock> mock = Collections.singleton(new AuthorityFactoryMock("MOCK", "2.3")); + final MultiAuthoritiesFactory factory = new MultiAuthoritiesFactory(mock, mock, mock, null); + testCreateFromCombinedURIs(factory, "urn:ogc:def:crs, crs:MOCK::4326, crs:MOCK::5714"); + /* + * Following are more unusual combinations described in OGC 07-092r1 (2007) + * "Definition identifier URNs in OGC namespace". + */ + SingleCRS crs = factory.createGeographicCRS("urn:ogc:def:crs, datum:MOCK::6326, cs:MOCK::6424"); + assertSame("datum", HardCodedDatum.WGS84, crs.getDatum()); + assertSame("cs", HardCodedCS.GEODETIC_2D, crs.getCoordinateSystem()); + /* + * Verify that invalid combined URIs are rejected. + */ + try { + factory.createObject("urn:ogc:def:cs, crs:MOCK::4326, crs:MOCK::5714"); + fail("Shall not accept to create CoordinateSystem from combined URI."); + } catch (FactoryException e) { + String message = e.getMessage(); + assertTrue(message, message.contains("CoordinateSystem")); + } + try { + factory.createObject("urn:ogc:def:crs, datum:MOCK::6326, cs:MOCK::6424, cs:MOCK::6422"); + fail("Shall not accept to create combined URI with unexpected objects."); + } catch (FactoryException e) { + assertNotNull(e.getMessage()); + } + } + + /** + * Tests {@code MultiAuthoritiesFactory.createFoo(String)} from codes in the + * {@code "http://www.opengis.net/def/crs-compound?1=(…)/code₁&2=(…)/code₂"} form. + * + * @throws FactoryException if an authority or a code is not recognized. + * + * @since 0.8 + */ + @Test + @DependsOnMethod("testCreateFromHTTPs") + public void testCreateFromCombinedHTTPs() throws FactoryException { + final Set<AuthorityFactoryMock> mock = Collections.singleton(new AuthorityFactoryMock("MOCK", "2.3")); + final MultiAuthoritiesFactory factory = new MultiAuthoritiesFactory(mock, mock, mock, null); + testCreateFromCombinedURIs(factory, "http://www.opengis.net/def/crs-compound?" + + "1=http://www.opengis.net/def/crs/MOCK/0/4326&" + + "2=http://www.opengis.net/def/crs/MOCK/0/5714"); + testCreateFromCombinedURIs(factory, "http://www.opengis.net/def/crs-compound?" + + "2=http://www.opengis.net/def/crs/MOCK/0/5714&" + + "1=http://www.opengis.net/def/crs/MOCK/0/4326"); + /* + * Contrarily to URN, the HTTP form shall not accept Datum + CoordinateSystem combination. + */ + try { + factory.createObject("http://www.opengis.net/def/crs-compound?" + + "1=http://www.opengis.net/def/datum/MOCK/0/6326&" + + "2=http://www.opengis.net/def/cs/MOCK/0/6424"); + fail("Shall not accept Datum + CoordinateSystem combination."); + } catch (FactoryException e) { + assertNotNull(e.getMessage()); + } + } + + /** + * Implementation of {@link #testCreateFromCombinedURNs()} and {@link #testCreateFromCombinedHTTPs()}. + */ + private static void testCreateFromCombinedURIs(final MultiAuthoritiesFactory factory, final String heightOnWGS84) + throws FactoryException + { + CompoundCRS crs = factory.createCompoundCRS(heightOnWGS84); + assertArrayEquals("WGS 84 + MSL height", new SingleCRS[] { + HardCodedCRS.WGS84_φλ, HardCodedCRS.GRAVITY_RELATED_HEIGHT + }, crs.getComponents().toArray()); + } + + /** * Tests {@link MultiAuthoritiesFactory#getAuthorityCodes(Class)}. * * @throws FactoryException if an error occurred while fetching the set of codes. Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -66,7 +66,7 @@ import org.apache.sis.test.TestCase; import org.apache.sis.test.LoggingWatcher; import org.apache.sis.test.DependsOnMethod; import org.apache.sis.test.DependsOn; -import org.apache.sis.referencing.factory.GIGS2001; +import org.apache.sis.referencing.factory.TestFactorySource; import static org.junit.Assume.assumeNotNull; import static org.apache.sis.test.ReferencingAssert.*; @@ -96,7 +96,7 @@ public final strictfp class EPSGFactoryT */ @BeforeClass public static void createFactory() throws FactoryException { - GIGS2001.createFactory(); + TestFactorySource.createFactory(); } /** @@ -106,7 +106,7 @@ public final strictfp class EPSGFactoryT */ @AfterClass public static void close() throws FactoryException { - GIGS2001.close(); + TestFactorySource.close(); } /** @@ -140,7 +140,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testWGS84() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final GeographicCRS crs = factory.createGeographicCRS("EPSG:4326"); assertEpsgNameAndIdentifierEqual("WGS 84", 4326, crs); @@ -162,7 +162,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testWGS84") public void testGeographic2D() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final GeographicCRS crs = factory.createGeographicCRS("4274"); assertEpsgNameAndIdentifierEqual("Datum 73", 4274, crs); @@ -183,7 +183,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testGeographic2D") public void testGeographic3D() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final GeographicCRS crs = factory.createGeographicCRS("EPSG::4993"); assertEpsgNameAndIdentifierEqual("Lao 1997", 4993, crs); @@ -201,7 +201,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testGeocentric() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final GeocentricCRS crs = factory.createGeocentricCRS("epsg:4915"); assertEpsgNameAndIdentifierEqual("ITRF93", 4915, crs); @@ -220,7 +220,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testGeographic2D") public void testProjected() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final ProjectedCRS crs = factory.createProjectedCRS("2027"); assertEpsgNameAndIdentifierEqual("NAD27(76) / UTM zone 15N", 2027, crs); @@ -258,7 +258,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testProjected") public void testProjectedNorthEast() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final ProjectedCRS crs = factory.createProjectedCRS(" EPSG : 2442 "); assertEpsgNameAndIdentifierEqual("Beijing 1954 / 3-degree Gauss-Kruger CM 135E", 2442, crs); @@ -291,7 +291,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testProjected") public void testProjectedWithSharedConversion() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final ProjectedCRS crs = factory.createProjectedCRS("32210"); assertEpsgNameAndIdentifierEqual("WGS 72 / UTM zone 10N", 32210, crs); @@ -330,7 +330,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testCreateByName") public void testProjectedByName() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final ProjectedCRS crs = factory.createProjectedCRS("NTF (Paris) / Lambert zone I"); assertEpsgNameAndIdentifierEqual("NTF (Paris) / Lambert zone I", 27571, crs); @@ -358,7 +358,7 @@ public final strictfp class EPSGFactoryT @Test @Ignore("“Lambert Azimuthal Equal Area (Spherical)” projection is not yet implemented.") public void testProjectedOnPole() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final ProjectedCRS crs = factory.createProjectedCRS("3408"); assertEpsgNameAndIdentifierEqual("NSIDC EASE-Grid North", 3408, crs); @@ -378,7 +378,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testGoogleProjection() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final ProjectedCRS crs = factory.createProjectedCRS("3857"); assertEpsgNameAndIdentifierEqual("WGS 84 / Pseudo-Mercator", 3857, crs); @@ -397,7 +397,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testEngineering() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final EngineeringCRS crs = factory.createEngineeringCRS("EPSG:5801"); assertEpsgNameAndIdentifierEqual("Barcelona Grid B1", 5801, crs); @@ -413,7 +413,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testVertical() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final VerticalCRS crs = factory.createVerticalCRS("EPSG:5735"); assertEpsgNameAndIdentifierEqual("Black Sea height", 5735, crs); @@ -431,7 +431,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod({"testGeographic2D", "testVertical"}) public void testCompound() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final CompoundCRS crs = factory.createCompoundCRS("EPSG:7400"); assertEpsgNameAndIdentifierEqual("NTF (Paris) + NGF IGN69 height", 7400, crs); @@ -461,7 +461,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testDeprecatedCoordinateSystems() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); for (final Map.Entry<Integer,Integer> entry : EPSGDataAccess.deprecatedCS().entrySet()) { final CoordinateSystem expected = factory.createEllipsoidalCS(entry.getValue().toString()); @@ -504,7 +504,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod({"testGeographic2D", "testDeprecatedCoordinateSystems"}) public void testDeprecatedGeographic() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final GeographicCRS crs = factory.createGeographicCRS("63266405"); @@ -526,7 +526,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod({"testDeprecatedGeographic", "testDeprecatedCoordinateSystems"}) public void testDeprecatedProjected() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final ProjectedCRS crs = factory.createProjectedCRS("3786"); @@ -559,7 +559,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testCreateByName() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); assertSame (factory.createUnit("9002"), factory.createUnit("foot")); assertNotSame(factory.createUnit("9001"), factory.createUnit("foot")); @@ -591,7 +591,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testAuthorityCodes() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); /* * Most basic objects. @@ -758,7 +758,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testDescriptionText() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); assertEquals("World Geodetic System 1984", factory.getDescriptionText( "6326").toString(Locale.US)); @@ -776,7 +776,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testProjectedWithSharedConversion") public void testConversion() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); /* * Fetch directly the "UTM zone 10N" operation. Because this operation was not obtained in @@ -833,7 +833,7 @@ public final strictfp class EPSGFactoryT */ @Test public void testSimpleTransformation() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final CoordinateOperation operation = factory.createCoordinateOperation("1764"); assertEpsgNameAndIdentifierEqual("NTF (Paris) to NTF (2)", 1764, operation); @@ -851,7 +851,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testSimpleTransformation") public void testTransformation() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final CoordinateOperation operation = factory.createCoordinateOperation("1609"); assertEpsgNameAndIdentifierEqual("BD72 to WGS 84 (1)", 1609, operation); @@ -868,7 +868,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testTransformation") public void testCreateFromCoordinateReferenceSystemCodes() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); /* * ED50 (4230) to WGS 84 (4326) using @@ -942,7 +942,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testWGS84") public void testFindGeographic() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final IdentifiedObjectFinder finder = factory.newIdentifiedObjectFinder(); final DefaultGeographicCRS crs = (DefaultGeographicCRS) CRS.fromWKT( @@ -990,7 +990,7 @@ public final strictfp class EPSGFactoryT @Test @DependsOnMethod("testFindGeographic") public void testFindProjected() throws FactoryException { - final EPSGFactory factory = GIGS2001.factory; + final EPSGFactory factory = TestFactorySource.factory; assumeNotNull(factory); final IdentifiedObjectFinder finder = factory.newIdentifiedObjectFinder(); /* Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -49,7 +49,7 @@ import org.junit.Rule; import org.junit.Test; import static org.junit.Assert.*; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeTrue; /** Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -864,7 +864,7 @@ public final strictfp class CoordinateOp assertSame ("sourceCRS", sourceCRS, operation.getSourceCRS()); assertSame ("targetCRS", targetCRS, operation.getTargetCRS()); assertInstanceOf("operation", ConcatenatedOperation.class, operation); - assertEquals ("name", "CompoundCRS[“Test3D”] → CompoundCRS[“Test4D”]", operation.getName().getCode()); + assertEquals ("name", "CompoundCRS[“Test3D”] ⟶ CompoundCRS[“Test4D”]", operation.getName().getCode()); transform = operation.getMathTransform(); assertInstanceOf("transform", LinearTransform.class, transform); Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -45,7 +45,7 @@ import org.junit.AfterClass; import org.junit.Test; import static org.apache.sis.test.ReferencingAssert.*; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeTrue; /** Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -39,8 +39,8 @@ import org.apache.sis.test.DependsOn; import org.apache.sis.test.TestCase; import org.junit.Test; -import static org.junit.Assume.*; import static org.junit.Assert.*; +import static org.junit.Assume.assumeTrue; /** 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=1812269&r1=1812268&r2=1812269&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] Mon Oct 16 10:01:46 2017 @@ -249,6 +249,7 @@ import org.junit.BeforeClass; org.apache.sis.distance.LatLonPointRadiusTest.class, // Pending refactoring in a geometry package. + org.apache.sis.test.integration.CoordinateReferenceSystemTest.class, org.apache.sis.test.integration.CoordinateOperationTest.class, org.apache.sis.test.integration.DatumShiftTest.class, org.apache.sis.test.integration.MetadataTest.class, Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/PrimitiveTypeProperties.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/PrimitiveTypeProperties.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/PrimitiveTypeProperties.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/PrimitiveTypeProperties.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -89,7 +89,7 @@ public final class PrimitiveTypeProperti assert isValidKey(primitive) : primitive; synchronized (SENTINEL_VALUES) { final Object old = SENTINEL_VALUES.put(primitive, property); - if (old != null) { // Should never happen - this is rather debugging check. + if (old != null) { // Should never happen - this is rather debugging check. SENTINEL_VALUES.put(primitive, old); throw new AssertionError(primitive); } @@ -103,8 +103,10 @@ public final class PrimitiveTypeProperti * @return the property associated to the given instance, or {@code null} if none. */ public static Object property(final Object primitive) { - // No 'assert isValidKey(primitive)' because this method is sometime invoked - // only after a brief inspection (e.g. 'NilReason.mayBeNil(Object)' method). + /* + * No 'assert isValidKey(primitive)' because this method is sometime invoked + * only after a brief inspection (e.g. 'NilReason.mayBeNil(Object)' method). + */ synchronized (SENTINEL_VALUES) { return SENTINEL_VALUES.get(primitive); } Added: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/BinaryOperator.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/BinaryOperator.java?rev=1812269&view=auto ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/BinaryOperator.java (added) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/BinaryOperator.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -0,0 +1,26 @@ +/* + * 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.jdk8; + + +/** + * Placeholder for the {@link java.util.function.BinaryOperator} interface. + * + * @param <T> The type of parameters and return values. + */ +public interface BinaryOperator<T> extends BiFunction<T,T,T> { +} Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/BinaryOperator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/BinaryOperator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain;charset=UTF-8 Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -67,14 +67,15 @@ public final class DefaultFactories exte /** * Returns {@code true} if the default factory of the given type is the given instance. + * A {@code null} factory is interpreted as the default one. * * @param <T> the interface type. * @param type the interface type. - * @param factory the factory implementation to test. + * @param factory the factory implementation to test, or {@code null}. * @return {@code true} if the given factory implementation is the default instance. */ public static synchronized <T> boolean isDefaultInstance(final Class<T> type, final T factory) { - return FACTORIES.get(type) == factory; + return (factory == null) || FACTORIES.get(type) == factory; } /** Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -17,12 +17,14 @@ package org.apache.sis.internal.util; import java.util.Map; +import java.util.TreeMap; import java.util.Collections; import org.apache.sis.util.CharSequences; +import org.apache.sis.util.logging.Logging; +import org.apache.sis.internal.system.Loggers; import static org.apache.sis.util.CharSequences.*; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; -import static org.apache.sis.internal.util.Utilities.appendUnicodeIdentifier; /** @@ -46,7 +48,7 @@ import static org.apache.sis.internal.ut * <li>{@code http://www.opengis.net/def/uom/SI/0/m%2Fs}</li> * </ul> * - * <div class="section">Components or URN</div> + * <div class="section">Parts of URN</div> * URN begins with {@code "urn:ogc:def:"} (formerly {@code "urn:x-ogc:def:"}) followed by: * <ul> * <li>an object {@linkplain #type}</li> @@ -103,7 +105,7 @@ import static org.apache.sis.internal.ut * {@code "urn:ogc:def:crs,crs:EPSG:6.3:27700,crs:EPSG:6.3:5701"}. * * @author Martin Desruisseaux (Geomatys) - * @version 0.7 + * @version 0.8 * * @see org.apache.sis.internal.metadata.NameMeaning * @see <a href="http://portal.opengeospatial.org/files/?artifact_id=24045">Definition identifier URNs in OGC namespace</a> @@ -124,6 +126,43 @@ public final class DefinitionURI { public static final char SEPARATOR = ':'; /** + * The separator between {@linkplain #components} in a URN. + * + * <div class="note"><b>Example:</b> + * in {@code "urn:ogc:def:crs,crs:EPSG:9.1:27700,crs:EPSG:9.1:5701"}, the components are + * {@code "crs:EPSG:9.1:27700"} and {@code "crs:EPSG:9.1:5701"}.</div> + */ + public static final char COMPONENT_SEPARATOR = ','; + + /** + * The separator between a URL and its first {@linkplain #components}. + * In URL syntax, this is the separator between URL path and the query. + * + * <div class="note"><b>Example:</b><code> + * http://www.opengis.net/def/crs-compound<u>?</u>1=…&2=… + * </code></div> + */ + private static final char COMPONENT_SEPARATOR_1 = '?'; + + /** + * The separator between {@linkplain #components} in a URL after the first component. + * + * <div class="note"><b>Example:</b><code> + * http://www.opengis.net/def/crs-compound?1=…<u>&</u>2=… + * </code></div> + */ + private static final char COMPONENT_SEPARATOR_2 = '&'; + + /** + * Separator between keys and values in the query part of a URL. + * + * <div class="note"><b>Example:</b><code> + * http://www.opengis.net/def/crs-compound?1<u>=</u>…&2<u>=</u>… + * </code></div> + */ + private static final char KEY_VALUE_SEPARATOR = '='; + + /** * The domain of URLs in the OGC namespace. */ public static final String DOMAIN = "www.opengis.net"; @@ -204,6 +243,30 @@ public final class DefinitionURI { public String[] parameters; /** + * If the URI contains sub-components, those sub-components. Otherwise {@code null}. + * + * <div class="note"><b>URN example:</b> + * if the URI is {@code "urn:ogc:def:crs,crs:EPSG:9.1:27700,crs:EPSG:9.1:5701"}, then this + * {@code DefinitionURI} will contain the {@code "urn:ogc:def:crs"} header with two components: + * <ol> + * <li>{@code "urn:ogc:def:crs:EPSG:9.1:27700"}</li> + * <li>{@code "urn:ogc:def:crs:EPSG:9.1:5701"}</li> + * </ol></div> + * + * <div class="note"><b>HTTP example:</b> if the URI is + * {@code "http://www.opengis.net/def/crs-compound?1=(…)/crs/EPSG/9.1/27700&2=(…)/crs/EPSG/9.1/5701"}, + * then this {@code DefinitionURI} will contain the {@code "http://www.opengis.net/def/crs-compound"} + * header with two components: + * <ol> + * <li>{@code "http://http://www.opengis.net/def/crs/EPSG/9.1/27700"}</li> + * <li>{@code "http://http://www.opengis.net/def/crs/EPSG/9.1/5701"}</li> + * </ol></div> + * + * Note that this array may contain {@code null} elements if we failed to parse the corresponding component. + */ + public DefinitionURI[] components; + + /** * For {@link #parse(String)} usage only. */ private DefinitionURI() { @@ -219,9 +282,26 @@ public final class DefinitionURI { */ public static DefinitionURI parse(final String uri) { ensureNonNull("uri", uri); - DefinitionURI result = null; - char separator = SEPARATOR; - int upper = -1; + return parse(uri, false, -1, uri.length()); + } + + /** + * Parses a sub-region of the given URI. This method can start parsing for an arbitrary URI part, + * no necessarily the root. The first URI part is identified by an ordinal number: + * + * This method may invoke itself recursively if the URI contains sub-components. + * + * @param uri the URI to parse. + * @param prefixIsOptional {@code true} if {@value #PREFIX} may not be present. + * @param upper upper index of the previous URI part, or -1 if none. + * @param stopAt index (exclusive) where to stop parsing. + * @return the parse result, or {@code null} if the URI is not recognized. + */ + @SuppressWarnings("fallthrough") + private static DefinitionURI parse(final String uri, boolean prefixIsOptional, int upper, int stopAt) { + DefinitionURI result = null; + char separator = SEPARATOR; // Separator character of URI parts. + char componentSeparator = COMPONENT_SEPARATOR; // Separator character of components. /* * Loop on all parts that we expect in the URI. Those parts are: * @@ -234,19 +314,19 @@ public final class DefinitionURI { * 6: code * 7: parameters, or null if none. */ - for (int p=0; p<=6; p++) { + for (int part = 0; part <= 6; part++) { final int lower = upper + 1; upper = uri.indexOf(separator, lower); - if (upper < 0) { - upper = uri.length(); + if (upper < 0 || upper >= stopAt) { + upper = stopAt; if (lower > upper) { - return result; // Happen if a component is missing. + return result; // Happen if a part is missing. } } - switch (p) { + switch (part) { /* - * Verifies that the 3 first components are "urn:ogc:def:" or "http://www.opengis.net/def/" - * without storing them. In the particular case of second component, we also accept "x-ogc" + * Verifies that the 3 first parts are "urn:ogc:def:" or "http://www.opengis.net/def/" + * without storing them. In the particular case of second part, we also accept "x-ogc" * in addition to "ogc" in URN. */ case 0: { @@ -257,74 +337,158 @@ public final class DefinitionURI { return result; } if (!uri.regionMatches(upper, "//", 0, 2)) { - return null; + return null; // Prefix is never optional for HTTP. } upper++; - separator = '/'; // Separator for the HTTP namespace. - } else if (!regionMatches("urn", uri, lower, upper)) { + separator = '/'; // Separator for the HTTP namespace. + componentSeparator = COMPONENT_SEPARATOR_1; // Separator for the query part in URL. + prefixIsOptional = false; + break; + } else if (regionMatches("urn", uri, lower, upper)) { + prefixIsOptional = false; + break; + } else if (!prefixIsOptional) { return null; } - break; + part++; + // Part is not "urn" but its presence was optional. Maybe it is "ogc". Fall through for checking. } case 1: { final boolean isHTTP = (separator != SEPARATOR); - if (!regionMatches(isHTTP ? DOMAIN : "ogc", uri, lower, upper)) { - if (isHTTP || !regionMatches("x-ogc", uri, lower, upper)) { - return null; - } + if (regionMatches(isHTTP ? DOMAIN : "ogc", uri, lower, upper) || + (!isHTTP && regionMatches("x-ogc", uri, lower, upper))) + { + prefixIsOptional = false; + break; + } else if (!prefixIsOptional) { + return null; } - break; + part++; + // Part is not "ogc" but its presence was optional. Maybe it is "def". Fall through for checking. } case 2: { - if (!regionMatches("def", uri, lower, upper)) { + if (regionMatches("def", uri, lower, upper)) { + prefixIsOptional = false; + break; + } else if (!prefixIsOptional) { return null; } - break; + part++; + // Part is not "def" but its presence was optional. Maybe it is "crs". Fall through for checking. + } + /* + * The forth part is the first one that we want to remember; all cases before this one were + * only verification. This case is also the first part where component separator may appear, + * for example as in "urn:ogc:def:crs,crs:EPSG:9.1:27700,crs:EPSG:9.1:5701". We verify here + * if such components exist, and if so we parse them recursively. + */ + case 3: { + int splitAt = uri.indexOf(componentSeparator, lower); + if (splitAt >= 0 && splitAt < stopAt) { + final int componentsEnd = stopAt; + stopAt = splitAt; // Upper limit of the DefinitionURI created in this method call. + if (stopAt < upper) { + upper = stopAt; + } + if (componentSeparator == COMPONENT_SEPARATOR_1) { + componentSeparator = COMPONENT_SEPARATOR_2; // E.g. http://(…)/crs-compound?1=(…)&2=(…) + } + if (result == null) { + result = new DefinitionURI(); + } + final boolean isURN = !result.isHTTP; + final Map<Integer,DefinitionURI> orderedComponents = new TreeMap<>(); + boolean hasMore; + do { + /* + * Find indices of URI sub-component to parse. The sub-component will + * go from 'splitAt' to 'next' exclusive ('splitAt' is exclusive too). + */ + int next = uri.indexOf(componentSeparator, splitAt+1); + hasMore = next >= 0 && next < componentsEnd; + if (!hasMore) next = componentsEnd; + /* + * HTTP uses key-value pairs as in "http://something?1=...&2=... + * URN uses a comma-separated value list without number. + * We support both forms, regardless if HTTP or URN. + */ + int sequenceNumber = orderedComponents.size() + 1; // Default value if no explicit key. + final int s = splitKeyValue(uri, splitAt+1, next); + if (s >= 0) try { + sequenceNumber = Integer.parseInt(trimWhitespaces(uri, splitAt+1, s).toString()); + splitAt = s; // Set only on success. + } catch (NumberFormatException e) { + // Ignore. The URN is likely to be invalid, but we let parse(…) determines that. + Logging.recoverableException(Logging.getLogger(Loggers.CRS_FACTORY), DefinitionURI.class, "parse", e); + } + orderedComponents.put(sequenceNumber, parse(uri, isURN, splitAt, next)); + splitAt = next; + } while (hasMore); + result.components = orderedComponents.values().toArray(new DefinitionURI[orderedComponents.size()]); + } + // Fall through } /* - * For all components after the first 3 ones, trim whitespaces and store non-empty values. + * For all parts after the first 3 ones, trim whitespaces and store non-empty values. */ default: { final String value = trimWhitespaces(uri, lower, upper).toString(); - if (!value.isEmpty() && (p != 5 || !NO_VERSION.equals(value))) { + if (!value.isEmpty() && (part != 5 || !NO_VERSION.equals(value))) { if (result == null) { result = new DefinitionURI(); } - switch (p) { + switch (part) { case 3: 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); + default: throw new AssertionError(part); } } } } } /* - * Take every remaining components as parameters. + * Take every remaining parts as parameters. */ - if (result != null && ++upper < uri.length()) { + if (result != null && ++upper < stopAt) { 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}, + * Returns {@code true} if a sub-region of {@code urn} matches the given {@code part}, * ignoring case, leading and trailing whitespaces. * - * @param component the expected component ({@code "urn"}, {@code "ogc"}, {@code "def"}, <i>etc.</i>) + * @param part the expected part ({@code "urn"}, {@code "ogc"}, {@code "def"}, <i>etc.</i>) * @param urn the URN for which to test a subregion. * @param lower index of the first character in {@code urn} to compare, after skipping whitespaces. * @param upper index after the last character in {@code urn} to compare, ignoring whitespaces. - * @return {@code true} if the given sub-region of {@code urn} match the given component. + * @return {@code true} if the given sub-region of {@code urn} match the given part. */ - static boolean regionMatches(final String component, final String urn, int lower, int upper) { + static boolean regionMatches(final String part, final String urn, int lower, int upper) { lower = skipLeadingWhitespaces (urn, lower, upper); upper = skipTrailingWhitespaces(urn, lower, upper); final int length = upper - lower; - return (length == component.length()) && urn.regionMatches(true, lower, component, 0, length); + return (length == part.length()) && urn.regionMatches(true, lower, part, 0, length); + } + + /** + * Returns the index of the {@code '='} character in the given sub-string, provided that all characters + * before it are spaces or decimal digits. Returns -1 if the key-value separator character is not found. + * Note that a positive return value does not guarantee that the number is parsable. + */ + private static int splitKeyValue(final String uri, int lower, final int upper) { + while (lower < upper) { + int c = uri.codePointAt(lower); + if ((c < '0' || c > '9') && !Character.isWhitespace(c)) { + if (c == KEY_VALUE_SEPARATOR) return lower; + break; + } + lower += Character.charCount(c); + } + return -1; } /** @@ -406,38 +570,38 @@ public final class DefinitionURI { * Check for supported protocols: only "urn" and "http" at this time. * All other protocols are rejected as unrecognized. */ - String component; + String part; switch (length) { - case 3: component = "urn"; break; - case 4: component = "http"; break; + case 3: part = "urn"; break; + case 4: part = "http"; break; default: return null; } - if (!uri.regionMatches(true, lower, component, 0, length)) { + if (!uri.regionMatches(true, lower, part, 0, length)) { return null; } if (length == 4) { return codeForGML(type, authority, uri, upper+1, null); } /* - * At this point we have determined that the protocol is URN. The next components after "urn" + * At this point we have determined that the protocol is URN. The next parts after "urn" * shall be "ogc" or "x-ogc", then "def", then the type and authority given in arguments. */ for (int p=0; p!=4; p++) { lower = upper + 1; upper = uri.indexOf(SEPARATOR, lower); if (upper < 0) { - return null; // No more components. + return null; // No more parts. } switch (p) { // "ogc" is tested before "x-ogc" because more common. case 0: if (regionMatches("ogc", uri, lower, upper)) continue; - component = "x-ogc"; break; // Fallback if the component is not "ogc". - case 1: component = "def"; break; - case 2: component = type; break; - case 3: component = authority; break; + part = "x-ogc"; break; // Fallback if the part is not "ogc". + case 1: part = "def"; break; + case 2: part = type; break; + case 3: part = authority; break; default: throw new AssertionError(p); } - if (!regionMatches(component, uri, lower, upper)) { + if (!regionMatches(part, uri, lower, upper)) { return null; } } @@ -519,43 +683,6 @@ public final class DefinitionURI { } /** - * Formats the given identifier using the {@code "ogc:urn:def:"} syntax. The identifier code space, - * version and code are appended omitting any characters that are not valid for a Unicode identifier. - * If some information are missing in the given identifier, then this method returns {@code null}. - * - * @param type the object type as one of the types documented in class javadoc, or {@code null}. - * @param authority the authority as one of the values documented in class javadoc, or {@code null}. - * @param version the code version, or {@code null}. This is the only optional information. - * @param code the code, or {@code null}. - * @return an identifier using the URN syntax, or {@code null} if a mandatory information is missing. - * - * @see org.apache.sis.internal.metadata.NameMeaning#toURN(Class, String, String, String) - */ - public static String format(final String type, final String authority, final String version, final String code) { - final StringBuilder buffer = new StringBuilder(PREFIX); -loop: for (int p=0; ; p++) { - final 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: break loop; - } - if (!appendUnicodeIdentifier(buffer.append(SEPARATOR), '\u0000', component, ".-", false)) { - /* - * Only the version (p = 2) is optional. All other fields are mandatory. - * If no character has been added for a mandatory field, we can not build a URN. - */ - if (p != 2) { - return null; - } - } - } - return buffer.toString(); - } - - /** * Returns a string representation of this URI. If the URI were originally a GML's URL, then this method formats * the URI in the {@code "http://www.opengis.net/gml/srs/"} namespace. Otherwise the URI were originally a URL, * then this method formats the URI in the {@code "http://www.opengis.net/"} namespace. @@ -571,10 +698,23 @@ loop: for (int p=0; ; p++) { return "http:" + path + authority + ".xml#" + code; } } - final StringBuilder buffer = new StringBuilder(PREFIX); - char separator = SEPARATOR; + final StringBuilder buffer = new StringBuilder(40); + if (!isHTTP) { + buffer.append(PREFIX); + } + toString(buffer, SEPARATOR); + return buffer.toString(); + } + + /** + * Formats the string representation of this URI into the given buffer. This method invoke itself recursively + * if this URI has {@linkplain #components}. The {@value #PREFIX} must be appended by the caller, if applicable. + * + * @param buffer where to format the string representation. + * @param separator first separator to append. Ignored if the URI is actually a URL. + */ + private void toString(final StringBuilder buffer, char separator) { if (isHTTP) { - buffer.setLength(0); buffer.append("http://").append(DOMAIN).append("/def"); separator = '/'; } @@ -583,21 +723,53 @@ loop: for (int p=0; ; p++) { n += parameters.length; } for (int p=0; p<n; p++) { - String component; + String part; 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; + case 0: part = type; break; + case 1: part = authority; break; + case 2: part = version; break; + case 3: part = code; break; + default: part = parameters[p-4]; break; } buffer.append(separator); - if (component == null) { - if (!isHTTP) continue; - component = NO_VERSION; + if (isHTTP) { + if (part == null) { + part = NO_VERSION; + } + } else { + separator = SEPARATOR; + if (part == null) { + continue; + } + } + buffer.append(part); + } + /* + * Before to return the URI, trim trailing separators. For example if the URN has only a type + * (no authority, version, code, etc.), then we want to return only "urn:ogc:def:crs" instead + * of "urn:ogc:def:crs:::"). This happen with URN defining compound CRS for instance. + */ + int length = buffer.length(); + n = isHTTP ? 2 : 1; + while ((length -= n) >= 0 && buffer.charAt(length) == separator) { + if (isHTTP && buffer.charAt(length + 1) != NO_VERSION.charAt(0)) break; + buffer.setLength(length); + } + /* + * If there is components, format them recursively. Note that the format is different depending if + * we are formatting URN or HTTP. Example: "urn:ogc:def:crs,crs:EPSG:9.1:27700,crs:EPSG:9.1:5701" + * and "http://www.opengis.net/def/crs-compound?1=(…)/crs/EPSG/9.1/27700&2=(…)/crs/EPSG/9.1/5701". + */ + if (components != null) { + for (int i=0; i<components.length;) { + final DefinitionURI c = components[i++]; + if (isHTTP) { + buffer.append(i == 1 ? COMPONENT_SEPARATOR_1 + : COMPONENT_SEPARATOR_2) + .append(i).append(KEY_VALUE_SEPARATOR); + } + c.toString(buffer, COMPONENT_SEPARATOR); } - buffer.append(component); } - return buffer.toString(); } } Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -67,7 +67,7 @@ import java.lang.reflect.Array; * objects. * * @author Martin Desruisseaux (IRD, Geomatys) - * @version 0.4 + * @version 0.8 * * @see Arrays * @@ -1684,6 +1684,33 @@ public final class ArraysExt extends Sta } /** + * Returns {@code true} if all values in the specified array are equal to the specified value, + * which may be {@code null}. + * + * @param array the array to check. + * @param value the expected value. + * @return {@code true} if all elements in the given array are equal to the given value. + * + * @since 0.8 + */ + public static boolean allEquals(final Object[] array, final Object value) { + if (value == null) { + for (int i=0; i<array.length; i++) { + if (array[i] != null) { + return false; + } + } + } else { + for (int i=0; i<array.length; i++) { + if (!value.equals(array[i])) { + return false; + } + } + } + return true; + } + + /** * Returns {@code true} if all values in the specified array are equal to the specified value, * which may be {@link Double#NaN}. * Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -253,7 +253,7 @@ public final class NilReason implements } String result = buffer.toString(); if (result.equals(reason)) { - result = reason; // Use the existing instance. + result = reason; // Use the existing instance. } return POOL.unique(new NilReason(result)); } @@ -422,7 +422,7 @@ public final class NilReason implements PrimitiveTypeProperties.associate(object, this); } if (nilObjects.put(type, object) != null) { - throw new AssertionError(type); // Should never happen. + throw new AssertionError(type); // Should never happen. } } return type.cast(object); Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -30,7 +30,7 @@ import org.apache.sis.test.DependsOn; import org.apache.sis.test.TestCase; import org.junit.Test; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeTrue; import static org.apache.sis.test.Assert.*; @@ -49,7 +49,7 @@ public final strictfp class PathConverte * Windows platform has driver letters instead, like "C:\\", * which are not correctly tested by this class. */ - static void assumeUnixRoot() { + private static void assumeUnixRoot() { assumeTrue(ArraysExt.contains(File.listRoots(), new File("/"))); } Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -27,7 +27,7 @@ import static org.junit.Assert.*; * Tests {@link DefinitionURI}. * * @author Martin Desruisseaux (Geomatys) - * @version 0.7 + * @version 0.8 * @since 0.4 * @module */ @@ -143,6 +143,51 @@ public final strictfp class DefinitionUR } /** + * Tests comma-separated URNs in the {@code "urn:ogc:def"} namespace. + * Example: {@code "urn:ogc:def:crs,crs:EPSG:6.3:27700,crs:EPSG:6.3:5701"}. + */ + @Test + @DependsOnMethod("testParse") + public void testCompoundURN() { + DefinitionURI parsed = DefinitionURI.parse("urn:ogc:def:crs, crs :EPSG:9.1:27700, crs:EPSG: 9.1 :5701"); + assertNotNull("components", parsed.components); + assertEquals("components.length", 2, parsed.components.length); + assertEquals("urn:ogc:def:crs:EPSG:9.1:27700", parsed.components[0].toString()); + assertEquals("urn:ogc:def:crs:EPSG:9.1:5701", parsed.components[1].toString()); + assertEquals("urn:ogc:def:crs,crs:EPSG:9.1:27700,crs:EPSG:9.1:5701", parsed.toString()); + /* + * The following URN is malformed, but Apache SIS should be tolerant to some errors. + * + * - the "urn:ogc:def" prefix should be omitted in components, but SIS should be able to skip them. + * - the "ogc:crs" parts should not be accepted because "def" is missing between "ogc" and "crs". + */ + parsed = DefinitionURI.parse("urn:ogc:def:crs,urn:ogc:def:crs:EPSG:9.1:27700,ogc:crs:EPSG:9.1:5701,def:crs:OGC::AnsiDate"); + assertNotNull("components", parsed.components); + assertEquals("components.length", 3, parsed.components.length); + assertEquals("urn:ogc:def:crs:EPSG:9.1:27700", parsed.components[0].toString()); + assertNull ("urn:ogc:def:crs:EPSG:9.1:5701", parsed.components[1]); + assertEquals("urn:ogc:def:crs:OGC::AnsiDate", parsed.components[2].toString()); + } + + /** + * Tests compound CRS in HTTP URL. + */ + @Test + @DependsOnMethod("testParseHTTP") + public void testCompoundHTTP() { + DefinitionURI parsed = DefinitionURI.parse("http://www.opengis.net/def/crs-compound?" + + "1=http://www.opengis.net/def/crs/EPSG/9.1/27700&" + + "2=http://www.opengis.net/def/crs/EPSG/9.1/5701"); + assertEquals("type", "crs-compound", parsed.type); + assertEquals("components.length", 2, parsed.components.length); + assertEquals("http://www.opengis.net/def/crs/EPSG/9.1/27700", parsed.components[0].toString()); + assertEquals("http://www.opengis.net/def/crs/EPSG/9.1/5701", parsed.components[1].toString()); + assertEquals("http://www.opengis.net/def/crs-compound?" + + "1=http://www.opengis.net/def/crs/EPSG/9.1/27700&" + + "2=http://www.opengis.net/def/crs/EPSG/9.1/5701", parsed.toString()); + } + + /** * Tests {@link DefinitionURI#codeOf(String, String, String)} with URI like {@code "EPSG:4326"}. */ @Test @@ -187,13 +232,4 @@ public final strictfp class DefinitionUR assertNull ( DefinitionURI.codeOf("uom", "EPSG", "http://www.opengis.net/gml/srs/epsg.xml#4326")); assertNull ( DefinitionURI.codeOf("uom", "EPSG", "http://schemas.opengis.net/iso/19139/20070417/resources/uom/gmxUom.xml#xpointer(//*[@gml:id='m'])")); } - - /** - * Tests {@link DefinitionURI#format(String, String, String, String)}. - */ - @Test - public void testToURN() { - assertEquals("urn:ogc:def:crs:EPSG::4326", DefinitionURI.format("crs", "EPSG", null, "4326")); - assertNull ("Authority is not optional.", DefinitionURI.format("crs", null, null, "4326")); - } } Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/RangeTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/RangeTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/RangeTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/RangeTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -20,7 +20,7 @@ import java.util.Locale; import org.apache.sis.test.TestCase; import org.junit.Test; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeTrue; import static org.apache.sis.test.Assert.*; Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -50,11 +50,12 @@ public final strictfp class Assume exten * @return the path to the given file. */ public static Path assumeDataExists(final DataDirectory type, final String file) { - assumeNotNull(System.getenv(DataDirectory.ENV)); + assumeNotNull("$SIS_DATA environment variable not set.", System.getenv(DataDirectory.ENV)); Path path = type.getDirectory(); - assumeNotNull(path); + assumeNotNull("$SIS_DATA/" + type + " directory not found.", path); path = path.resolve(file); - assumeTrue(Files.isReadable(path)); + assumeTrue("Specified directory not found.", Files.isDirectory(path)); + assumeTrue("Specified directory not readable.", Files.isReadable(path)); return path; } } Modified: sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -22,8 +22,8 @@ import org.apache.sis.util.Numbers; import org.apache.sis.test.TestCase; import org.junit.Test; -import static org.junit.Assume.*; import static org.junit.Assert.*; +import static org.junit.Assume.assumeTrue; /** Modified: sis/branches/JDK7/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java [UTF-8] (original) +++ sis/branches/JDK7/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -23,7 +23,7 @@ import org.apache.sis.test.TestCase; import org.junit.BeforeClass; import org.junit.Test; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeTrue; import static org.apache.sis.test.Assert.*; Modified: sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java [UTF-8] (original) +++ sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -34,7 +34,7 @@ import org.apache.sis.test.TestCase; import org.junit.Test; import static org.junit.Assert.*; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeTrue; /** Modified: sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java [UTF-8] (original) +++ sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -37,7 +37,7 @@ import org.apache.sis.test.DependsOn; import org.apache.sis.test.TestCase; import org.junit.Test; -import static org.junit.Assume.*; +import static org.junit.Assume.assumeTrue; import static org.opengis.test.Assert.*;
