| /* |
| * 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.xml.bind.referencing; |
| |
| import java.util.Map; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import jakarta.xml.bind.JAXBException; |
| import org.opengis.parameter.ParameterDescriptor; |
| import org.opengis.parameter.ParameterDescriptorGroup; |
| import org.opengis.parameter.GeneralParameterDescriptor; |
| import org.apache.sis.parameter.DefaultParameterDescriptor; |
| import org.apache.sis.parameter.DefaultParameterDescriptorGroup; |
| import org.apache.sis.system.Loggers; |
| import org.apache.sis.xml.Namespaces; |
| |
| // Test dependencies |
| import org.junit.jupiter.api.Test; |
| import static org.junit.jupiter.api.Assertions.*; |
| import static org.apache.sis.referencing.Assertions.assertRemarksEquals; |
| import org.apache.sis.xml.test.TestCase; |
| |
| |
| /** |
| * Tests {@link CC_GeneralOperationParameter} static methods. |
| * |
| * @author Martin Desruisseaux (Geomatys) |
| * |
| * @see <a href="http://issues.apache.org/jira/browse/SIS-290">SIS-290</a> |
| */ |
| public final class CC_GeneralOperationParameterTest extends TestCase.WithLogs { |
| /** |
| * Creates a new test case. |
| */ |
| public CC_GeneralOperationParameterTest() { |
| super(Loggers.XML); |
| } |
| |
| /** |
| * Creates a parameter descriptor as unmarshalled by JAXB, without {@code valueClass}. |
| * |
| * @throws JAXBException if this method failed to create test data. |
| */ |
| private DefaultParameterDescriptor<?> unmarshal(final String name, final String remarks) throws JAXBException { |
| final StringBuilder buffer = new StringBuilder(256); |
| buffer.append("<gml:OperationParameter xmlns:gml=\"" + Namespaces.GML + "\">\n" |
| + " <gml:name>").append(name).append("</gml:name>\n"); |
| if (remarks != null) { |
| buffer.append(" <gml:remarks>").append(remarks).append("</gml:remarks>\n"); |
| } |
| buffer.append(" <gml:minimumOccurs>0</gml:minimumOccurs>\n" |
| + "</gml:OperationParameter>"); |
| final DefaultParameterDescriptor<?> p = unmarshal(DefaultParameterDescriptor.class, buffer.toString()); |
| /* |
| * Following assertions are not really the purpose of this class, but are done on an opportunist way. |
| * We need the unmarshalled descriptor to have those property values for the remaining of this test. |
| * The most noticeable assertion is the 'valueClass', which is required to be null (despite being an |
| * illegal value) for this test. |
| */ |
| assertEquals(name, p.getName().getCode()); |
| assertEquals(remarks, (remarks == null) ? null : p.getRemarks().orElseThrow().toString()); |
| assertTrue(p.getDescription().isEmpty()); |
| assertNull(p.getValueClass()); |
| assertEquals(0, p.getMinimumOccurs()); |
| assertEquals(1, p.getMaximumOccurs()); |
| return p; |
| } |
| |
| /** |
| * Creates a parameter descriptor from the given properties. |
| * All properties except {@code defaultValue} can be part of GML documents. |
| * |
| * @param name the parameter descriptor name. |
| * @param remarks the remarks, or {@code null} if none. |
| * @param mandatory {@code true} for a mandatory parameter, or {@code false} for an optional one. |
| * @param defaultValue the default value, or {@code null} if none. |
| * @return the parameter descriptor. |
| */ |
| private static DefaultParameterDescriptor<Integer> create(final String name, final String remarks, |
| final boolean mandatory, final Integer defaultValue) |
| { |
| final var properties = new HashMap<String,String>(4); |
| assertNull(properties.put(DefaultParameterDescriptor.NAME_KEY, name)); |
| assertNull(properties.put(DefaultParameterDescriptor.REMARKS_KEY, remarks)); |
| return new DefaultParameterDescriptor<>(properties, mandatory ? 1 : 0, 1, Integer.class, null, null, defaultValue); |
| } |
| |
| /** |
| * Tests cases where the unmarshalled parameter can be substituted by the complete parameter. |
| * The cases tested in this method should not create any new {@code ParameterDescriptor} instance. |
| * |
| * @throws JAXBException if this method failed to create test data. |
| */ |
| @Test |
| public void testParameterSubstitution() throws JAXBException { |
| ParameterDescriptor<?> provided = unmarshal("Optional parameter", null); |
| ParameterDescriptor<?> complete = create("Optional parameter", null, false, null); |
| assertSame(complete, CC_GeneralOperationParameter.merge(complete, complete)); |
| assertSame(complete, CC_GeneralOperationParameter.merge(provided, complete)); |
| |
| complete = create("OptionalParameter", null, false, null); |
| assertSame(complete, CC_GeneralOperationParameter.merge(provided, complete)); |
| |
| complete = create("Optional parameter", null, false, 3); |
| assertSame(complete, CC_GeneralOperationParameter.merge(provided, complete)); |
| |
| complete = create("Optional parameter", "More details here.", false, null); |
| assertSame(complete, CC_GeneralOperationParameter.merge(provided, complete)); |
| |
| provided = unmarshal("Optional parameter", "More details here."); |
| assertSame(complete, CC_GeneralOperationParameter.merge(provided, complete)); |
| |
| loggings.assertNoUnexpectedLog(); |
| } |
| |
| /** |
| * Tests cases where the unmarshalled parameter needs to be merged with the complete parameter. |
| * All cases tested in this method should create a new {@link ParameterDescriptor} instance. |
| * |
| * @throws JAXBException if this method failed to create test data. |
| */ |
| @Test |
| public void testParameterMerge() throws JAXBException { |
| ParameterDescriptor<?> provided = unmarshal("Test parameter", null); |
| ParameterDescriptor<?> complete = create("Test parameter", null, true, null); |
| ParameterDescriptor<?> merged = (ParameterDescriptor<?>) CC_GeneralOperationParameter.merge(provided, complete); |
| assertNotSame(complete, merged); |
| assertSame (complete.getName(), merged.getName()); |
| assertEquals (0, merged.getMinimumOccurs()); // From provided descriptor. |
| assertEquals (1, merged.getMaximumOccurs()); |
| assertEquals (Integer.class, merged.getValueClass()); // From complete descriptor. |
| assertTrue ( merged.getRemarks().isEmpty()); |
| |
| complete = create("Test parameter", null, false, null); |
| assertSame(complete, CC_GeneralOperationParameter.merge(provided, complete)); |
| // Above assertion was tested by testParameterSubstitutions(), but was verified again here |
| // for making sure that the following assertion verifies the effect of the remarks alone. |
| provided = unmarshal("Test parameter", "More details here."); |
| merged = (ParameterDescriptor<?>) CC_GeneralOperationParameter.merge(provided, complete); |
| assertNotSame(complete, merged); |
| assertSame (complete.getName(), merged.getName()); |
| assertEquals (0, merged.getMinimumOccurs()); |
| assertEquals (1, merged.getMaximumOccurs()); |
| assertEquals (Integer.class, merged.getValueClass()); |
| assertEquals (provided.getRemarks(), merged.getRemarks()); |
| loggings.assertNoUnexpectedLog(); |
| } |
| |
| /** |
| * Tests case where the unmarshalled parameter group can be substituted by the complete parameter group. |
| * The cases tested in this method should not create any new {@link ParameterDescriptorGroup} instance. |
| * |
| * @throws JAXBException if this method failed to create test data. |
| */ |
| @Test |
| public void testGroupSubstitution() throws JAXBException { |
| final Map<String,String> properties = new HashMap<>(4); |
| assertNull(properties.put(DefaultParameterDescriptor.NAME_KEY, "Group")); |
| final var provided = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| unmarshal("Parameter A", null), |
| unmarshal("Parameter B", "Remarks B."), |
| unmarshal("Parameter C", null)); |
| |
| assertNull(properties.put(DefaultParameterDescriptor.REMARKS_KEY, "More details here.")); |
| final var complete = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| create("Parameter A", "Remarks A.", false, 3), |
| create("Parameter B", "Remarks B.", false, 4), |
| create("Parameter C", "Remarks C.", false, 5), |
| create("Parameter D", "Remarks D.", false, 6)); |
| |
| assertSame(complete, CC_GeneralOperationParameter.merge(provided, complete)); |
| loggings.assertNoUnexpectedLog(); |
| } |
| |
| /** |
| * Tests case where the unmarshalled parameter group needs to be merged with the complete parameter group. |
| * The reason for the group merge in this test is because the unmarshalled parameters have different remarks |
| * or different obligation. |
| * |
| * @throws JAXBException if this method failed to create test data. |
| */ |
| @Test |
| public void testGroupMergeBecauseDifferentProperties() throws JAXBException { |
| final Map<String,String> properties = new HashMap<>(4); |
| assertNull(properties.put(DefaultParameterDescriptor.NAME_KEY, "Group")); |
| final var provided = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| unmarshal("Parameter A", "Remarks A."), |
| unmarshal("Parameter B", "Remarks B."), |
| unmarshal("Parameter C", "Remarks C.")); |
| |
| assertNull(properties.put(DefaultParameterDescriptor.REMARKS_KEY, "More details here.")); |
| final var complete = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| create("Parameter A", "Remarks A.", true, 3), |
| create("Parameter B", "Remarks B.", false, 4), |
| create("Parameter C", "Different.", false, 5), |
| create("Parameter D", "Remarks D.", false, 6)); |
| |
| final var merged = (ParameterDescriptorGroup) CC_GeneralOperationParameter.merge(provided, complete); |
| assertNotSame(complete, provided); |
| assertSame (complete.getName(), merged.getName()); |
| assertEquals (complete.getRemarks(), merged.getRemarks()); |
| assertEquals (1, merged.getMinimumOccurs()); |
| assertEquals (2, merged.getMaximumOccurs()); |
| |
| final Iterator<GeneralParameterDescriptor> itc = complete.descriptors().iterator(); |
| final Iterator<GeneralParameterDescriptor> itm = merged .descriptors().iterator(); |
| verifyParameter(itc.next(), itm.next(), false, "Remarks A."); // Not same because different obligation. |
| verifyParameter(itc.next(), itm.next(), true, "Remarks B."); // Same ParameterDescriptor instance. |
| verifyParameter(itc.next(), itm.next(), false, "Remarks C."); // Not same because different remarks. |
| assertTrue (itc.hasNext()); |
| assertFalse(itm.hasNext()); |
| loggings.assertNoUnexpectedLog(); |
| } |
| |
| /** |
| * Tests case where the unmarshalled parameter group needs to be merged with the complete parameter group. |
| * The reason for the group merge in this test is because the unmarshalled parameters is missing a mandatory |
| * parameter. |
| * |
| * @throws JAXBException if this method failed to create test data. |
| */ |
| @Test |
| public void testGroupMergeBecauseMissingParameter() throws JAXBException { |
| final Map<String,String> properties = new HashMap<>(4); |
| assertNull(properties.put(DefaultParameterDescriptor.NAME_KEY, "Group")); |
| final var provided = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| unmarshal("Parameter A", null), |
| unmarshal("Parameter C", null)); |
| |
| assertNull(properties.put(DefaultParameterDescriptor.REMARKS_KEY, "More details here.")); |
| final var complete = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| create("Parameter A", null, false, 3), |
| create("Parameter B", null, true, 4), |
| create("Parameter C", null, false, 5)); |
| |
| final var merged = (ParameterDescriptorGroup) CC_GeneralOperationParameter.merge(provided, complete); |
| assertNotSame(complete, provided); |
| assertSame (complete.getName(), merged.getName()); |
| assertEquals (complete.getRemarks(), merged.getRemarks()); |
| assertEquals (1, merged.getMinimumOccurs()); |
| assertEquals (2, merged.getMaximumOccurs()); |
| |
| final Iterator<GeneralParameterDescriptor> itc = complete.descriptors().iterator(); |
| final Iterator<GeneralParameterDescriptor> itm = merged .descriptors().iterator(); |
| verifyParameter(itc.next(), itm.next(), true, null); |
| |
| // Skip the parameter which is missing in the unmarshalled descriptor group. |
| assertEquals("Parameter B", itc.next().getName().getCode()); |
| |
| verifyParameter(itc.next(), itm.next(), true, null); |
| assertFalse(itc.hasNext()); |
| assertFalse(itm.hasNext()); |
| loggings.assertNoUnexpectedLog(); |
| } |
| |
| /** |
| * Tests case where the unmarshalled parameter group needs to be merged with the complete parameter group. |
| * The reason for the group merge in this test is because the unmarshalled parameters have a parameter not |
| * present in the "complete" group. |
| * |
| * @throws JAXBException if this method failed to create test data. |
| */ |
| @Test |
| public void testGroupMergeBecauseExtraParameter() throws JAXBException { |
| final Map<String,String> properties = new HashMap<>(4); |
| assertNull(properties.put(DefaultParameterDescriptor.NAME_KEY, "Group")); |
| final var provided = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| unmarshal("Parameter A", "Remarks A."), |
| unmarshal("Parameter B", "Remarks B."), |
| unmarshal("Parameter C", "Remarks C.")); |
| |
| assertNull(properties.put(DefaultParameterDescriptor.REMARKS_KEY, "More details here.")); |
| final var complete = new DefaultParameterDescriptorGroup(properties, 1, 2, |
| create("Parameter A", "Remarks A.", false, 3), |
| create("Parameter C", "Remarks C.", false, 4)); |
| |
| loggings.assertNoUnexpectedLog(); |
| final var merged = (ParameterDescriptorGroup) CC_GeneralOperationParameter.merge(provided, complete); |
| assertNotSame(complete, provided); |
| assertSame (complete.getName(), merged.getName()); |
| assertEquals (complete.getRemarks(), merged.getRemarks()); |
| assertEquals (1, merged.getMinimumOccurs()); |
| assertEquals (2, merged.getMaximumOccurs()); |
| loggings.assertNextLogContains("Parameter B", "Group"); |
| loggings.assertNoUnexpectedLog(); |
| |
| final Iterator<GeneralParameterDescriptor> itc = complete.descriptors().iterator(); |
| final Iterator<GeneralParameterDescriptor> itm = merged .descriptors().iterator(); |
| verifyParameter(itc.next(), itm.next(), true, "Remarks A."); |
| |
| final GeneralParameterDescriptor extra = itm.next(); |
| assertEquals("Parameter B", extra.getName().getCode()); |
| assertRemarksEquals("Remarks B.", extra, null); |
| |
| verifyParameter(itc.next(), itm.next(), true, "Remarks C."); |
| assertFalse(itc.hasNext()); |
| assertFalse(itm.hasNext()); |
| loggings.assertNoUnexpectedLog(); |
| } |
| |
| /** |
| * Verifies the properties of the given member of a {@link DefaultParameterDescriptorGroup}. |
| */ |
| private static void verifyParameter(final GeneralParameterDescriptor complete, |
| final GeneralParameterDescriptor merged, |
| final boolean same, final String remarks) |
| { |
| assertEquals(same, merged == complete); |
| assertSame (complete.getName(), merged.getName()); |
| assertEquals(0, merged.getMinimumOccurs()); |
| assertEquals(1, merged.getMaximumOccurs()); |
| assertEquals(Integer.class, ((ParameterDescriptor<?>) merged).getValueClass()); |
| assertRemarksEquals(remarks, merged, null); |
| } |
| } |