| /* |
| * 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.referencing; |
| |
| import java.util.Map; |
| import java.util.HashMap; |
| import org.opengis.util.NameSpace; |
| import org.opengis.util.LocalName; |
| import org.opengis.util.GenericName; |
| import org.opengis.util.NameFactory; |
| import org.opengis.metadata.Identifier; |
| import org.opengis.metadata.citation.Citation; |
| import org.apache.sis.metadata.simple.SimpleCitation; |
| import org.apache.sis.metadata.simple.SimpleIdentifier; |
| import org.apache.sis.metadata.iso.citation.Citations; |
| import org.apache.sis.util.iso.DefaultNameFactory; |
| |
| // Test dependencies |
| import org.junit.jupiter.api.Test; |
| import static org.junit.jupiter.api.Assertions.*; |
| import static org.apache.sis.test.Assertions.assertMessageContains; |
| import org.apache.sis.test.TestCase; |
| |
| // Specific to the main branch: |
| import org.opengis.referencing.ReferenceIdentifier; |
| |
| |
| /** |
| * Tests {@link Builder}. |
| * |
| * @author Martin Desruisseaux (Geomatys) |
| */ |
| public final class BuilderTest extends TestCase { |
| /** |
| * Creates a new test case. |
| */ |
| public BuilderTest() { |
| } |
| |
| /** |
| * Tests {@link Builder#verifyParameterizedType(Class)}. |
| */ |
| @Test |
| @SuppressWarnings("ResultOfObjectAllocationIgnored") |
| public void testVerifyParameterizedType() { |
| final class Invalid extends Builder<BuilderMock> { |
| } |
| var exception = assertThrows(AssertionError.class, () -> new Invalid()); |
| assertMessageContains(exception, BuilderMock.class.getName()); |
| } |
| |
| /** |
| * Tests {@link Builder#setCodeSpace(Citation, String)}. |
| */ |
| @Test |
| public void testSetCodeSpace() { |
| final var builder = new BuilderMock(); |
| builder.setCodeSpace(Citations.EPSG, "EPSG"); |
| builder.addName("Mercator (variant A)"); |
| /* |
| * Setting the same codespace should have no effect, while attempt to |
| * set a new codespace after we added a name shall not be allowed. |
| */ |
| final SimpleCitation IOGP = new SimpleCitation("IOGP"); |
| builder.setCodeSpace(Citations.EPSG, "EPSG"); |
| var exception = assertThrows(IllegalStateException.class, () -> builder.setCodeSpace(IOGP, "EPSG")); |
| assertMessageContains(exception, Identifier.AUTHORITY_KEY); |
| /* |
| * The failed attempt to set a new codespace shall not have modified builder state. |
| */ |
| assertEquals("EPSG", builder.properties.get(ReferenceIdentifier.CODESPACE_KEY)); |
| assertSame (Citations.EPSG, builder.properties.get(Identifier.AUTHORITY_KEY)); |
| /* |
| * After a cleanup (normally after a createXXX(…) method call), user shall be allowed to |
| * set a new codespace again. Note that the cleanup operation shall not clear the codespace. |
| */ |
| builder.onCreate(true); |
| assertEquals("EPSG", builder.properties.get(ReferenceIdentifier.CODESPACE_KEY)); |
| assertSame (Citations.EPSG, builder.properties.get(Identifier.AUTHORITY_KEY)); |
| builder.setCodeSpace(IOGP, "EPSG"); |
| assertEquals("EPSG", builder.properties.get(ReferenceIdentifier.CODESPACE_KEY)); |
| assertSame ( IOGP, builder.properties.get(Identifier.AUTHORITY_KEY)); |
| } |
| |
| /** |
| * Tests {@link Builder#addName(CharSequence)} without codespace. |
| */ |
| @Test |
| public void testAddName() { |
| final NameFactory factory = DefaultNameFactory.provider(); |
| |
| // Expected values to be used later in the test. |
| final String name = "Mercator (variant A)"; |
| final LocalName alias1 = factory.createLocalName(null, "Mercator (1SP)"); |
| final LocalName alias2 = factory.createLocalName(null, "Mercator_1SP"); |
| final LocalName alias3 = factory.createLocalName(null, "CT_Mercator"); |
| assertTrue(alias1.scope().isGlobal()); |
| assertTrue(alias2.scope().isGlobal()); |
| assertTrue(alias3.scope().isGlobal()); |
| assertEquals("Mercator (1SP)", alias1.toString()); |
| assertEquals("Mercator_1SP", alias2.toString()); |
| assertEquals("CT_Mercator", alias3.toString()); |
| |
| // The test. |
| final BuilderMock builder = new BuilderMock(); |
| assertSame(builder, builder.addName("Mercator (variant A)")); // EPSG version 7.6 and later. |
| assertSame(builder, builder.addName("Mercator (1SP)")); // EPSG before version 7.6. |
| assertSame(builder, builder.addName("Mercator_1SP")); // OGC |
| assertSame(builder, builder.addName("CT_Mercator")); // GeoTIFF |
| builder.onCreate(false); |
| assertEquals(name, builder.getName()); |
| assertArrayEquals(new GenericName[] {alias1, alias2, alias3}, builder.getAliases()); |
| } |
| |
| /** |
| * Creates a {@link Builder} with <q>Mercator (variant A)</q> projection (EPSG:9804) names and identifiers. |
| * This method uses scopes for differentiating the EPSG names from the OGC and GeoTIFF ones. |
| * |
| * @param withNames {@code true} for adding the names in the builder. |
| * @param withIdentifiers {@code true} for adding the identifiers in the builder. |
| * @return the builder with Mercator names and/or identifiers. |
| */ |
| private static BuilderMock createMercator(final boolean withNames, final boolean withIdentifiers) { |
| final var builder = new BuilderMock(); |
| assertSame(builder, builder.setCodeSpace(Citations.EPSG, "EPSG")); |
| if (withNames) { |
| assertSame(builder, builder.addName( "Mercator (variant A)")); // EPSG version 7.6 and later. |
| assertSame(builder, builder.addName( "Mercator (1SP)")); // EPSG before version 7.6. |
| assertSame(builder, builder.addName(Citations.OGC, "Mercator_1SP")); |
| assertSame(builder, builder.addName(Citations.GEOTIFF, "CT_Mercator")); |
| } |
| if (withIdentifiers) { |
| assertSame(builder, builder.addIdentifier( "9804")); |
| assertSame(builder, builder.addIdentifier(Citations.GEOTIFF, "7")); |
| } |
| builder.onCreate(false); |
| return builder; |
| } |
| |
| /** |
| * Tests {@link Builder#addName(Citation, CharSequence)} and {@link Builder#addName(CharSequence)} with codespace. |
| */ |
| @Test |
| public void testAddNameWithScope() { |
| final NameFactory factory = DefaultNameFactory.provider(); |
| |
| // Expected values to be used later in the test. |
| final String name = "Mercator (variant A)"; |
| final GenericName alias1 = factory.createLocalName(scope(factory, "EPSG"), "Mercator (1SP)"); |
| final GenericName alias2 = new NamedIdentifier(Citations.OGC, "Mercator_1SP"); |
| final GenericName alias3 = new NamedIdentifier(Citations.GEOTIFF, "CT_Mercator"); |
| assertTrue (alias3.scope().isGlobal()); |
| assertTrue (alias2.scope().isGlobal()); |
| assertFalse(alias1.scope().isGlobal()); |
| assertEquals("EPSG", alias1.scope().name().toString()); |
| assertEquals("Mercator (1SP)", alias1.toString()); |
| assertEquals("OGC:Mercator_1SP", alias2.toString()); |
| assertEquals("GeoTIFF:CT_Mercator", alias3.toString()); |
| |
| // The test. |
| final BuilderMock builder = createMercator(true, false); |
| assertEquals(name, builder.getName()); |
| assertArrayEquals(new GenericName[] {alias1, alias2, alias3}, builder.getAliases()); |
| } |
| |
| /** |
| * Convenience method creating a namespace for {@link #testAddNameWithScope()} purpose. |
| */ |
| private static NameSpace scope(final NameFactory factory, final String codespace) { |
| return factory.createNameSpace(factory.createLocalName(null, codespace), null); |
| } |
| |
| /** |
| * Tests {@link Builder#addIdentifier(Citation, String)} and {@link Builder#addIdentifier(String)} with code space. |
| */ |
| @Test |
| public void testAddIdentifiers() { |
| // Expected values to be used later in the test. |
| final var id1 = new ImmutableIdentifier(Citations.EPSG, "EPSG", "9804"); |
| final var id2 = new ImmutableIdentifier(Citations.GEOTIFF, "GeoTIFF", "7"); |
| assertEquals("EPSG:9804", IdentifiedObjects.toString(id1)); |
| assertEquals("GeoTIFF:7", IdentifiedObjects.toString(id2)); |
| |
| // The test. |
| final BuilderMock builder = createMercator(false, true); |
| assertArrayEquals(new Identifier[] {id1, id2}, builder.getIdentifiers()); |
| } |
| |
| /** |
| * Tests {@link Builder#addNamesAndIdentifiers(IdentifiedObject)}. |
| */ |
| @Test |
| public void testAddNamesAndIdentifiers() { |
| final BuilderMock builder = createMercator(true, true); |
| final var object = new AbstractIdentifiedObject(builder.properties); |
| builder.onCreate(true); |
| for (final Map.Entry<String,?> entry : builder.properties.entrySet()) { |
| final Object value = entry.getValue(); |
| switch (entry.getKey()) { |
| case Identifier.AUTHORITY_KEY: { |
| assertSame(Citations.EPSG, value); // Authority and codespace shall be unchanged. |
| break; |
| } |
| case ReferenceIdentifier.CODESPACE_KEY: { |
| assertEquals("EPSG", value); // Authority and codespace shall be unchanged. |
| break; |
| } |
| default: { |
| assertNull(value); // Should not contain any non-null value except the authority. |
| break; |
| } |
| } |
| } |
| assertSame(builder, builder.addNamesAndIdentifiers(object)); |
| builder.onCreate(false); |
| assertSame (object.getName(), builder.getName()); |
| assertArrayEquals(object.getAlias().toArray(), builder.getAliases()); |
| assertArrayEquals(object.getIdentifiers().toArray(), builder.getIdentifiers()); |
| } |
| |
| /** |
| * Tests {@link Builder#rename(Citation, CharSequence[])}. |
| */ |
| @Test |
| public void testRename() { |
| final BuilderMock builder = createMercator(true, false); |
| |
| // Replace "OGC:Mercator_1SP" and insert a new OGC code before the GeoTIFF one. |
| assertSame(builder, builder.rename(Citations.OGC, "Replacement 1", "Replacement 2")); |
| builder.onCreate(false); |
| assertArrayEquals(new String[] { |
| "Mercator (variant A)", |
| "Mercator (1SP)", |
| "OGC:Replacement 1", |
| "OGC:Replacement 2", |
| "GeoTIFF:CT_Mercator" |
| }, builder.getAsStrings(1)); |
| |
| // Replace "EPSG:Mercator (variant A)" and "(1SP)", and insert a new EPSG code as an alias. |
| assertSame(builder, builder.rename(Citations.EPSG, "Replacement 3", "Replacement 4", "Replacement 5")); |
| builder.onCreate(false); |
| assertArrayEquals(new String[] { |
| "Replacement 3", |
| "Replacement 4", |
| "Replacement 5", |
| "OGC:Replacement 1", |
| "OGC:Replacement 2", |
| "GeoTIFF:CT_Mercator" |
| }, builder.getAsStrings(1)); |
| |
| // Remove all EPSG codes. |
| assertSame(builder, builder.rename(Citations.EPSG, (String[]) null)); |
| builder.onCreate(false); |
| assertArrayEquals(new String[] { |
| "OGC:Replacement 1", |
| "OGC:Replacement 2", |
| "GeoTIFF:CT_Mercator" |
| }, builder.getAsStrings(1)); |
| } |
| |
| /** |
| * Tests the {@link Builder#Builder(IdentifiedObject)} constructor. |
| */ |
| @Test |
| public void testCreationFromObject() { |
| final Map<String,Object> properties = new HashMap<>(); |
| final Identifier id = new SimpleIdentifier(null, "An identifier", false); |
| assertNull(properties.put(AbstractIdentifiedObject.IDENTIFIERS_KEY, id)); |
| assertNull(properties.put(AbstractIdentifiedObject.ALIAS_KEY, "An alias")); |
| assertNull(properties.put(AbstractIdentifiedObject.NAME_KEY, "Dummy object")); |
| assertNull(properties.put(AbstractIdentifiedObject.REMARKS_KEY, "Some remarks")); |
| final var builder = new BuilderMock(new AbstractIdentifiedObject(properties)); |
| |
| assertEquals(3, builder.properties.size()); // Expect only name, remarks and deprecated status. |
| builder.onCreate(false); |
| assertEquals(5, builder.properties.size()); // Expect name, aliases, identifiers and remarks. |
| |
| assertEquals("Dummy object", builder.properties.get(AbstractIdentifiedObject.NAME_KEY).toString()); |
| assertEquals("Some remarks", builder.properties.get(AbstractIdentifiedObject.REMARKS_KEY).toString()); |
| assertEquals("An alias", ((Object[]) builder.properties.get(AbstractIdentifiedObject.ALIAS_KEY))[0].toString()); |
| assertSame(id, ((Object[]) builder.properties.get(AbstractIdentifiedObject.IDENTIFIERS_KEY))[0]); |
| } |
| } |