/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2011-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2011-2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.metadata.netcdf; import java.util.Map; import java.util.Arrays; import java.util.HashSet; import java.io.IOException; import javax.imageio.IIOException; import ucar.nc2.NetcdfFile; import org.opengis.metadata.Metadata; import org.opengis.metadata.citation.Role; import org.opengis.metadata.identification.DataIdentification; import org.opengis.metadata.extent.TemporalExtent; import org.opengis.metadata.maintenance.ScopeCode; import org.opengis.temporal.Instant; import org.opengis.wrapper.netcdf.NetcdfMetadataTest; import org.geotoolkit.factory.Hints; import org.geotoolkit.coverage.io.ImageCoverageReader; import org.geotoolkit.coverage.io.CoverageStoreException; import org.geotoolkit.image.io.plugin.NetcdfImageReader; import org.junit.*; import static org.opengis.test.Assert.*; /** * Tests using the {@link NetcdfMetadataReader} class. This class inherits the tests from the * {@code geoapi-netcdf} module, and adds a some additional assertions for attributes not * parsed by the GeoAPI demo code. * * @author Martin Desruisseaux (Geomatys) * @version 3.20 * * @since 3.20 */ public final strictfp class NetcdfMetadataReaderTest extends NetcdfMetadataTest { /** * Necessary for testCIP() for now, because GeographicBoundingBox.setBounds(Envelope) * does not have the possibility to specify whether it wants a lenient or non-lenient * factory. */ static { Hints.putSystemDefault(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE); } /** * {@code true} if this instance is running an integration test. * <p> * <ul> * <li>If {@code false} (the usual value), the metadata will be constructed directly by a * {@link NetcdfMetadata} instance.</li> * <li>If {@code true}, the metadata will be constructed by an {@link ImageCoverageReader}, * which will itself use a {@link NetcdfMetadata} under the hood and will add more * information.</li> * </ul> */ private boolean integrationTest; /** * Wraps the given NetCDF file into the Metadata object to be tested. * This method is invoked by the tests inherited from the {@code geoapi-test} module. * * @param file The NetCDF file to wrap. * @return A metadata implementation created from the attributes found in the given file. * @throws IOException If an error occurred while wrapping the given NetCDF file. */ @Override protected Metadata wrap(final NetcdfFile file) throws IOException { if (integrationTest) try { final NetcdfImageReader imageReader = new NetcdfImageReader(null); imageReader.setInput(file); final ImageCoverageReader coverageReader = new ImageCoverageReader(); coverageReader.setInput(imageReader); final Metadata metadata = coverageReader.getMetadata(); coverageReader.dispose(); return metadata; } catch (CoverageStoreException e) { throw new IIOException(e.getLocalizedMessage(), e); } // Bellow is the "normal" test. final NetcdfMetadataReader ncISO = new NetcdfMetadataReader(file, null); return ncISO.read(); } /** * Adds a set of common property values expected by every tests in this class. */ private static void addCommonProperties(final Map<String,Object> expected, final boolean contact) { assertNull(expected.put("metadataStandardName", "ISO 19115-2 Geographic Information - Metadata Part 2 Extensions for imagery and gridded data")); assertNull(expected.put("metadataStandardVersion", "ISO 19115-2:2009(E)")); if (contact) { assertNull(expected.put("identificationInfo.pointOfContact.role", Role.POINT_OF_CONTACT)); assertNull(expected.put("contact.role", Role.POINT_OF_CONTACT)); } } /** * Tests a file that contains THREDDS metadata. This method inherits the tests defined in * GeoAPI, and adds some additional tests for attributes parsed by Geotk but not GeoAPI. * * @throws IOException If the test file can not be read. */ @Test @Override public void testTHREDDS() throws IOException { final Map<String,Object> expected = expectedProperties; addCommonProperties(expected, true); assertNull(expected.put("identificationInfo.citation.title", "crm_v1.grd")); assertNull(expected.put("identificationInfo.citation.identifier.code", "crm_v1")); assertNull(expected.put("contentInfo.dimension.sequenceIdentifier", "z")); super.testTHREDDS(); assertEquals("hierarchyLevel", new HashSet<>(Arrays.asList(ScopeCode.DATASET, ScopeCode.SERVICE)), new HashSet<>(metadata.getHierarchyLevels())); /* * In the Geotk case, the Metadata/Contact and Metadata/Identification/PointOfContact * proprties are not just equals - they are expected to be the exact same instance. */ assertSame("identificationInfo.pointOfContact", getSingleton(metadata.getContacts()), getSingleton(getSingleton(metadata.getIdentificationInfo()).getPointOfContacts())); /* * We expect every properties to have been processed. */ assertTrue(expectedProperties.toString(), expectedProperties.isEmpty()); assertTrue(actualProperties .toString(), actualProperties .isEmpty()); } /** * Tests a NetCDF binary file. This method inherits the tests defined in GeoAPI, * and adds some additional tests for attributes parsed by Geotk but not GeoAPI. * * @throws IOException If the test file can not be read. */ @Test @Override @Ignore("Conflict in version of UCAR library used by Geotk and GeoAPI.") public void testNCEP() throws IOException { org.junit.Assume.assumeTrue(false); // TODO addCommonProperties(expectedProperties, true); super.testNCEP(); assertSame("hierarchyLevel", ScopeCode.DATASET, getSingleton(metadata.getHierarchyLevels())); /* * In the Geotk case, the Metadata/Contact and Metadata/Identification/PointOfContact * proprties are not just equals - they are expected to be the exact same instance. */ assertSame("identificationInfo.pointOfContact", getSingleton(metadata.getContacts()), getSingleton(getSingleton(metadata.getIdentificationInfo()).getPointOfContacts())); /* * Metadata / Data Identification / Temporal Extent. */ final DataIdentification identification = (DataIdentification) getSingleton(metadata.getIdentificationInfo()); final TemporalExtent text = getSingleton(getSingleton(identification.getExtents()).getTemporalElements()); final Instant instant = (Instant) text.getExtent(); // Can not test at this time, since it requires the geotk-temporal module. /* * Every properties found in the metadata should have been verified by this test case. * However the set of expected values may contains more entries than what we found in * the metadata object, because some values are found only in the "integrated" tests. * Consequently the set of expected values will be tested for emptiness only in the * "integrated" test case. */ assertTrue(actualProperties.toString(), actualProperties.isEmpty()); } /** * Same test than {@link #testNCEP()}, but now reading through a {@link ImageCoverageReader}. * This is an integration test, with some additional metadata which were added by the coverage * reader. * * @throws IOException If the test file can not be read. * @throws CoverageStoreException Should never happen. */ @Test @Ignore("Conflict in version of UCAR library used by Geotk and GeoAPI.") public void testIntegratedNCEP() throws IOException, CoverageStoreException { integrationTest = true; testNCEP(); // See the comment in testNCEP() assertTrue(expectedProperties.toString(), expectedProperties.isEmpty()); } /** * Tests the Landsat file (binary format). * * @throws IOException If the test file can not be read. */ @Test @Override public void testLandsat() throws IOException { addCommonProperties(expectedProperties, false); super.testLandsat(); assertSame("hierarchyLevel", ScopeCode.DATASET, getSingleton(metadata.getHierarchyLevels())); /* * We expect every properties to have been processed. */ assertTrue(expectedProperties.toString(), expectedProperties.isEmpty()); assertTrue(actualProperties .toString(), actualProperties .isEmpty()); } /** * Tests the "Current Icing Product" file (binary format). * * @throws IOException If the test file can not be read. */ @Test @Override public void testCIP() throws IOException { final Map<String,Object> expected = expectedProperties; addCommonProperties(expected, true); super.testCIP(); assertSame("hierarchyLevel", ScopeCode.DATASET, getSingleton(metadata.getHierarchyLevels())); /* * In the Geotk case, the Metadata/Contact and Metadata/Identification/PointOfContact * proprties are not just equals - they are expected to be the exact same instance. */ assertSame("identificationInfo.pointOfContact", getSingleton(metadata.getContacts()), getSingleton(getSingleton(metadata.getIdentificationInfo()).getPointOfContacts())); /* * Every properties found in the metadata should have been verified by this test case. * However the set of expected values may contains more entries than what we found in * the metadata object, because some values are found only in the "integrated" tests. * Consequently the set of expected values will be tested for emptiness only in the * "integrated" test case. */ assertTrue(actualProperties.toString(), actualProperties.isEmpty()); } /** * Same test than {@link #testCIP()}, but now reading through a {@link ImageCoverageReader}. * This is an integration test. * * @throws IOException If the test file can not be read. * @throws CoverageStoreException Should never happen. */ @Test @Ignore("Requires GeographicBoundingBox.setBounds(Envelope) to use a lenient coordinate transformation factory.") public void testIntegratedCIP() throws IOException, CoverageStoreException { integrationTest = true; testCIP(); // See the comment in testCIP() assertTrue(expectedProperties.toString(), expectedProperties.isEmpty()); } }