| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.sis.internal.jaxb.cat; |
| |
| import java.util.Arrays; |
| import java.util.Locale; |
| import java.util.Collections; |
| import javax.xml.bind.Marshaller; |
| import javax.xml.bind.JAXBException; |
| import org.opengis.metadata.citation.Role; |
| import org.opengis.metadata.citation.DateType; |
| import org.opengis.metadata.citation.CitationDate; |
| import org.opengis.metadata.citation.ResponsibleParty; |
| import org.opengis.metadata.citation.PresentationForm; |
| import org.apache.sis.metadata.iso.citation.DefaultCitation; |
| import org.apache.sis.internal.xml.LegacyNamespaces; |
| import org.apache.sis.internal.xml.Schemas; |
| import org.apache.sis.xml.XML; |
| import org.apache.sis.xml.Namespaces; |
| import org.apache.sis.xml.MarshallerPool; |
| import org.apache.sis.test.DependsOnMethod; |
| import org.apache.sis.test.xml.TestCase; |
| import org.junit.Test; |
| |
| import static org.apache.sis.test.MetadataAssert.*; |
| |
| |
| /** |
| * Tests the XML marshalling of {@code CodeList}. |
| * |
| * @author Martin Desruisseaux (Geomatys) |
| * @author Guilhem Legal (Geomatys) |
| * @version 1.0 |
| * @since 0.3 |
| * @module |
| */ |
| public final strictfp class CodeListMarshallingTest extends TestCase { |
| /** |
| * Returns a XML string to use for testing purpose. |
| * Note that responsible party exists only in legacy ISO 19115:2003 model. |
| * |
| * @param baseURL the base URL of XML schemas. |
| */ |
| private static String getResponsiblePartyXML(final String baseURL) { |
| return "<gmd:CI_ResponsibleParty xmlns:gmd=\"" + LegacyNamespaces.GMD + "\">\n" + |
| " <gmd:role>\n" + |
| " <gmd:CI_RoleCode codeList=\"" + baseURL + Schemas.CODELISTS_PATH_LEGACY + "#CI_RoleCode\"" + |
| " codeListValue=\"principalInvestigator\">" + "Principal investigator</gmd:CI_RoleCode>\n" + |
| " </gmd:role>\n" + |
| "</gmd:CI_ResponsibleParty>"; |
| } |
| |
| /** |
| * Returns a XML string to use for testing purpose. |
| * |
| * @param language three-letter ISO code. |
| * @param dateType date type code list in the language identified by {@code language}. |
| * @param legacy {@code true} for ISO 19139:2007 format, {@code false} for ISO 19115-3 format. |
| */ |
| private static String getCitationXML(final String language, final String dateType, final boolean legacy) { |
| final Object[] args = new Object[] { |
| "cit", // Prefix |
| Namespaces.CIT, // Namespace |
| Schemas.METADATA_ROOT, // Base URL of code list path |
| Schemas.CODELISTS_PATH, // Relative code list path in base URL |
| language, dateType |
| }; |
| if (legacy) { |
| args[0] = "gmd"; // Prefix |
| args[1] = LegacyNamespaces.GMD; // Namespace |
| args[2] = Schemas.METADATA_ROOT_LEGACY; // Base URL of code list path |
| args[3] = Schemas.CODELISTS_PATH_LEGACY; // Relative code list path in base URL |
| } |
| return String.format( |
| "<%1$s:CI_Date xmlns:%1$s=\"%2$s\">\n" + |
| " <%1$s:dateType>\n" + |
| " <%1$s:CI_DateTypeCode codeList=\"%3$s%4$s#CI_DateTypeCode\"" + |
| " codeListValue=\"creation\" codeSpace=\"%5$s\">%6$s</%1$s:CI_DateTypeCode>\n" + |
| " </%1$s:dateType>\n" + |
| "</%1$s:CI_Date>", args); |
| } |
| |
| /** |
| * Tests marshalling using the default URL. |
| * |
| * @throws JAXBException if an error occurred while marshalling the XML. |
| */ |
| @Test |
| public void testDefaultURL() throws JAXBException { |
| final String expected = getResponsiblePartyXML(Schemas.METADATA_ROOT_LEGACY); |
| final ResponsibleParty rp = unmarshal(ResponsibleParty.class, expected); |
| assertEquals(Role.PRINCIPAL_INVESTIGATOR, rp.getRole()); |
| /* |
| * Use the convenience method in order to avoid the effort of creating |
| * our own MarshallerPool. |
| */ |
| final String actual = marshal(rp, VERSION_2007); |
| assertXmlEquals(expected, actual, "xmlns:*"); |
| } |
| |
| /** |
| * Tests marshalling using legacy ISO URLs. |
| * |
| * @throws JAXBException if an error occurred while marshalling the XML. |
| * |
| * @see <a href="https://standards.iso.org/iso/19115/-3/">ISO schemas</a> |
| */ |
| @Test |
| public void testLegacyISO_URL() throws JAXBException { |
| final String expected = getResponsiblePartyXML("http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/"); |
| final ResponsibleParty rp = unmarshal(ResponsibleParty.class, expected); |
| assertEquals(Role.PRINCIPAL_INVESTIGATOR, rp.getRole()); |
| |
| final MarshallerPool pool = getMarshallerPool(); |
| final Marshaller marshaller = pool.acquireMarshaller(); |
| marshaller.setProperty(XML.METADATA_VERSION, VERSION_2007); |
| marshaller.setProperty(XML.SCHEMAS, Collections.singletonMap("gmd", |
| "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas")); // Intentionally omit trailing '/'. |
| final String actual = marshal(marshaller, rp); |
| pool.recycle(marshaller); |
| assertXmlEquals(expected, actual, "xmlns:*"); |
| } |
| |
| /** |
| * Tests a code list localization. |
| * |
| * @throws JAXBException if an error occurred while marshalling the XML. |
| */ |
| @Test |
| public void testLocalization() throws JAXBException { |
| testLocalization(false); |
| } |
| |
| /** |
| * Tests a code list localization in ISO 19139:2007. |
| * |
| * @throws JAXBException if an error occurred while marshalling the XML. |
| * |
| * @since 1.0 |
| */ |
| @Test |
| @DependsOnMethod("testLocalization") |
| public void testLocalizationLegacyXML() throws JAXBException { |
| testLocalization(true); |
| } |
| |
| /** |
| * Implementation of {@link #testLocalization()} and {@link #testLocalizationLegacyXML()}. |
| */ |
| private void testLocalization(final boolean legacy) throws JAXBException { |
| final MarshallerPool pool = getMarshallerPool(); |
| final Marshaller marshaller = pool.acquireMarshaller(); |
| if (legacy) { |
| marshaller.setProperty(XML.METADATA_VERSION, VERSION_2007); |
| } |
| /* |
| * First, test using the French locale. |
| */ |
| marshaller.setProperty(XML.LOCALE, Locale.FRENCH); |
| String expected = getCitationXML("fra", "Création", legacy); |
| CitationDate ci = unmarshal(CitationDate.class, expected); |
| assertEquals(DateType.CREATION, ci.getDateType()); |
| String actual = marshal(marshaller, ci); |
| assertXmlEquals(expected, actual, "xmlns:*"); |
| /* |
| * Tests again using the English locale. |
| */ |
| marshaller.setProperty(XML.LOCALE, Locale.ENGLISH); |
| expected = getCitationXML("eng", "Creation", legacy); |
| ci = unmarshal(CitationDate.class, expected); |
| assertEquals(DateType.CREATION, ci.getDateType()); |
| actual = marshal(marshaller, ci); |
| assertXmlEquals(expected, actual, "xmlns:*"); |
| |
| pool.recycle(marshaller); |
| } |
| |
| /** |
| * Tests marshalling of a code list which is not in the list of standard codes. |
| * |
| * @throws JAXBException if an error occurred while marshalling the XML. |
| */ |
| @Test |
| public void testExtraCodes() throws JAXBException { |
| final DefaultCitation id = new DefaultCitation(); |
| id.setPresentationForms(Arrays.asList( |
| PresentationForm.valueOf("IMAGE_DIGITAL"), // Existing code with UML id="imageDigital" |
| PresentationForm.valueOf("test"))); // New code |
| |
| final String xml = marshal(id); |
| /* |
| * "IMAGE_DIGITAL" is marshalled as "imageDigital" because is contains a UML id, which is lower-case. |
| */ |
| assertXmlEquals( |
| "<cit:CI_Citation xmlns:cit=\"" + Namespaces.CIT + "\">\n" + |
| " <cit:presentationForm>\n" + |
| " <cit:CI_PresentationFormCode codeListValue=\"imageDigital\">Image digital</cit:CI_PresentationFormCode>\n" + |
| " </cit:presentationForm>\n" + |
| " <cit:presentationForm>\n" + |
| " <cit:CI_PresentationFormCode codeListValue=\"test\">Test</cit:CI_PresentationFormCode>\n" + |
| " </cit:presentationForm>\n" + |
| "</cit:CI_Citation>\n", |
| xml, "xmlns:*", "codeList", "codeSpace"); |
| } |
| } |