blob: 02f71e38e8c3261d08bc539b2d4a6652b39c67c8 [file] [log] [blame]
/*
* 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;
import java.lang.reflect.Proxy;
import jakarta.xml.bind.JAXBException;
import org.opengis.metadata.citation.Series;
import org.opengis.metadata.citation.Citation;
// Test dependencies
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import org.apache.sis.xml.test.TestCase;
import static org.apache.sis.metadata.Assertions.assertTitleEquals;
import static org.apache.sis.metadata.Assertions.assertXmlEquals;
/**
* Tests the XML marshalling of object having {@code uuid} or {@code uuidref} attributes.
*
* @author Martin Desruisseaux (Geomatys)
*/
public final class UUIDMarshallingTest extends TestCase {
/**
* A random UUID for the tests in this class.
*/
private static final String UUID_VALUE = "f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf";
/**
* A XML with a {@code uuid} identifier in the {@code <cit:CI_Series>} element.
*/
private static final String IDENTIFIED_XML =
"<cit:CI_Citation xmlns:cit=\"" + Namespaces.CIT + '"' +
" xmlns:gco=\"" + Namespaces.GCO + "\">\n" +
" <cit:title>\n" +
" <gco:CharacterString>My data</gco:CharacterString>\n" +
" </cit:title>\n" +
" <cit:series>\n" +
" <cit:CI_Series uuid=\"" + UUID_VALUE + "\">\n" +
" <cit:name>\n" +
" <gco:CharacterString>My aggregate dataset</gco:CharacterString>\n" +
" </cit:name>\n" +
" </cit:CI_Series>\n" +
" </cit:series>\n" +
"</cit:CI_Citation>";
/**
* A XML with a {@code uuidref} identifier in the {@code <cit:series>} element.
* This XML declares the method body anyway, which is kind of contradictory with usage of reference.
*/
private static final String REFERENCED_XML_WITH_BODY =
"<cit:CI_Citation xmlns:cit=\"" + Namespaces.CIT + '"' +
" xmlns:gco=\"" + Namespaces.GCO + "\">\n" +
" <cit:title>\n" +
" <gco:CharacterString>My data</gco:CharacterString>\n" +
" </cit:title>\n" +
" <cit:series uuidref=\"" + UUID_VALUE + "\">\n" +
" <cit:CI_Series>\n" +
" <cit:name>\n" +
" <gco:CharacterString>My aggregate dataset</gco:CharacterString>\n" +
" </cit:name>\n" +
" </cit:CI_Series>\n" +
" </cit:series>\n" +
"</cit:CI_Citation>";
/**
* A XML with a {@code uuidref} identifier in the {@code <cit:series>} element.
*/
private static final String REFERENCED_XML =
"<cit:CI_Citation xmlns:cit=\"" + Namespaces.CIT + '"' +
" xmlns:gco=\"" + Namespaces.GCO + "\">\n" +
" <cit:title>\n" +
" <gco:CharacterString>My data</gco:CharacterString>\n" +
" </cit:title>\n" +
" <cit:series uuidref=\"" + UUID_VALUE + "\"/>\n" +
"</cit:CI_Citation>";
/**
* Creates a new test case.
*/
public UUIDMarshallingTest() {
}
/**
* Tests (un)marshalling of an object identified by the {@code uuid} attribute.
* The element of interest for this test is the {@code "uuid"} attribute value
* in the {@code <cit:CI_Series>} element of the following XML fragment:
*
* {@snippet lang="xml" :
* <cit:CI_Citation>
* <cit:title>
* <gco:CharacterString>My data</gco:CharacterString>
* </cit:title>
* <cit:series>
* <cit:CI_Series uuid="f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf">
* <cit:name>
* <gco:CharacterString>My aggregate dataset</gco:CharacterString>
* </cit:name>
* </cit:CI_Series>
* </cit:series>
* </cit:CI_Citation>
* }
*
* On an implementation note, the {@code uuid} and other attributes of the {@code <cit:CI_Series>}
* elements are handled by {@link org.apache.sis.xml.bind.gco.PropertyType}.
*
* @throws JAXBException if an error occurred during (un)marshalling.
*/
@Test
public void testIdentification() throws JAXBException {
final var citation = assertInstanceOf(Citation.class, XML.unmarshal(IDENTIFIED_XML));
assertTitleEquals("My data", citation, "citation");
/*
* Programmatic verification of the Series properties,
* which is the main object of interest in this test.
*/
final Series series = citation.getSeries();
assertFalse(Proxy.isProxyClass(series.getClass()), "Citation.series.isProxy");
assertInstanceOf(IdentifiedObject.class, series, "Citation.series");
final IdentifierMap map = ((IdentifiedObject) series).getIdentifierMap();
assertEquals("My aggregate dataset", series.getName().toString(), "series");
assertNull(map.get(IdentifierSpace.HREF), "href");
assertEquals(UUID_VALUE, String.valueOf(map.get(IdentifierSpace.UUID)));
/*
* Marshal the object back to XML and compare with the original string
* supplied to this method.
*/
final String actual = XML.marshal(citation);
assertXmlEquals(IDENTIFIED_XML, actual, "xmlns:*");
assertEquals(citation, XML.unmarshal(actual));
}
/**
* Tests (un)marshalling of an object referenced by a {@code uuidref} attribute.
* This test does not try to resolve the reference, but only check that the identifier is properly saved.
*
* <p>The element of interest for this test is the {@code "uuidref"} part
* in the {@code <cit:series>} property of the following XML fragment:</p>
*
* {@snippet lang="xml" :
* <cit:CI_Citation>
* <cit:title>
* <gco:CharacterString>My data</gco:CharacterString>
* </cit:title>
* <cit:series uuidref="f8f5fcb1-d57b-4013-b3a4-4eaa40df6dcf">
* <cit:CI_Series>
* <cit:name>
* <gco:CharacterString>My aggregate dataset</gco:CharacterString>
* </cit:name>
* </cit:CI_Series>
* </cit:series>
* </cit:CI_Citation>
* }
*
* On an implementation note, the {@code uuidref}, {@code xlink:href} and other attributes of the
* {@code <cit:series>} element are handled by {@link org.apache.sis.xml.bind.gco.PropertyType}.
*
* @throws JAXBException if an error occurred during (un)marshalling.
*/
@Test
public void testReference() throws JAXBException {
final var citation = assertInstanceOf(Citation.class, XML.unmarshal(REFERENCED_XML_WITH_BODY));
assertTitleEquals("My data", citation, "citation");
/*
* Programmatic verification of the Series properties,
* which is the main object of interest in this test.
*/
final Series series = citation.getSeries();
assertInstanceOf(IdentifiedObject.class, series, "Citation.series");
assertFalse(Proxy.isProxyClass(series.getClass()), "Citation.series.isProxy");
assertEquals("My aggregate dataset", series.getName().toString(), "Citation.series.name");
final IdentifierMap map = ((IdentifiedObject) series).getIdentifierMap();
assertNull(map.get(IdentifierSpace.HREF), "href");
assertEquals(UUID_VALUE, map.get(IdentifierSpace.UUID), "uuid");
/*
* Marshal the object back to XML and compare with the expected result. The result shall be
* slightly different than the original XML, since the UUID in the <cit:series> element shall
* move to the <cit:CI_Series> element. This is the expected behavior because we have a fully
* constructed object, not a reference to an object defined elsewhere.
*/
final String actual = XML.marshal(citation);
assertXmlEquals(IDENTIFIED_XML, actual, "xmlns:*");
assertEquals(citation, XML.unmarshal(actual));
}
/**
* The same test as {@link #testReference()}, except that the {@code <cit:CI_Series>} element is empty.
* This situation shall force the creation of a new, empty, element for storing the {@code uuidref} information.
*
* @throws JAXBException if an error occurred during (un)marshalling.
*/
@Test
public void testReferenceInEmptyObject() throws JAXBException {
final var citation = assertInstanceOf(Citation.class, XML.unmarshal(REFERENCED_XML));
assertTitleEquals("My data", citation, "citation");
/*
* Programmatic verification of the Series properties,
* which is the main object of interest in this test.
*/
final Series series = citation.getSeries();
assertInstanceOf(IdentifiedObject.class, series, "Citation.series");
assertNull(series.getName(), "Citation.series.name");
assertTrue(Proxy.isProxyClass(series.getClass()), "Citation.series.isProxy");
assertInstanceOf(NilObject.class, series, "Citation.series");
assertEquals("Series[{gco:uuid=“" + UUID_VALUE + "”}]", series.toString());
final IdentifierMap map = ((IdentifiedObject) series).getIdentifierMap();
assertNull(map.get(IdentifierSpace.HREF), "href");
assertEquals(UUID_VALUE, map.get(IdentifierSpace.UUID), "uuid");
/*
* Marshal the object back to XML and compare with the expected result.
*/
final String actual = XML.marshal(citation);
assertXmlEquals(REFERENCED_XML, actual, "xmlns:*");
assertEquals(citation, XML.unmarshal(actual));
}
}