/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2009-2012, Open Source Geospatial Foundation (OSGeo)
* (C) 2009-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.image.io.metadata;
import java.util.List;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Collection;
import java.util.logging.Level;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.content.RangeDimension;
import org.opengis.metadata.content.ImageDescription;
import org.opengis.metadata.content.ImagingCondition;
import org.opengis.metadata.identification.Keywords;
import org.opengis.metadata.identification.Resolution;
import org.opengis.metadata.identification.DataIdentification;
import org.opengis.coverage.grid.RectifiedGrid;
import org.apache.sis.test.DependsOn;
import org.apache.sis.measure.NumberRange;
import org.apache.sis.util.iso.SimpleInternationalString;
import org.geotoolkit.metadata.Citations;
import org.junit.*;
import static org.geotoolkit.test.Assert.*;
import static org.geotoolkit.test.Commons.*;
import static org.geotoolkit.image.io.metadata.SpatialMetadataFormat.GEOTK_FORMAT_NAME;
/**
* Tests {@link MetadataProxy}.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.16
*
* @since 3.06
*/
@DependsOn(MetadataNodeAccessorTest.class)
public final strictfp class MetadataProxyTest extends org.geotoolkit.test.TestBase {
/**
* Tests the proxy with some properties defined under the {@code "ImageDescription"} node
* without children.
*/
@Test
public void testImageDescription() {
final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(GEOTK_FORMAT_NAME));
final MetadataNodeAccessor accessor = new MetadataNodeAccessor(metadata, null, "ImageDescription", null);
final ImageDescription proxy = accessor.newProxyInstance(ImageDescription.class);
/*
* Test the properties before they are defined.
*/
assertNull(proxy.getImagingCondition());
assertNull(proxy.getCloudCoverPercentage());
/*
* Now define the properties and test again.
*/
accessor.setAttribute("imagingCondition", "cloud");
accessor.setAttribute("cloudCoverPercentage", 20.0);
assertEquals(20.0, proxy.getCloudCoverPercentage(), 0.0);
assertEquals(ImagingCondition.CLOUD, proxy.getImagingCondition());
/*
* Ask for an element which was excluded from the metadata format.
* The intend is to ensure that no exception is thrown.
*/
final Level originalLevel = accessor.setWarningLevel(Level.OFF);
assertNull(proxy.getAttributeDescription());
accessor.setWarningLevel(originalLevel);
/*
* Check the methods defined in java.lang.Object.
*/
assertEquals("hashCode consistency.", proxy.hashCode(), proxy.hashCode());
assertEquals(proxy, proxy);
assertFalse(proxy.equals(accessor));
assertMultilinesEquals(decodeQuotes(
"ImageDescription[“ImageDescription”]\n" +
"├───imagingCondition=“cloud”\n" +
"└───cloudCoverPercentage=“20.0”\n"), proxy.toString());
}
/**
* Tests the proxy with a property which is an other metadata object.
* In this test, the child metadata is an {@link Identifier}.
*/
@Test
public void testImageQualityCode() {
final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(GEOTK_FORMAT_NAME));
final MetadataNodeAccessor accessor = new MetadataNodeAccessor(metadata, null, "ImageDescription", null);
final MetadataNodeAccessor qualityA = new MetadataNodeAccessor(metadata, null, "ImageDescription/ImageQualityCode", null);
qualityA.setAttribute("code", "okay");
qualityA.setAttribute("authority", "Geotoolkit.org");
accessor.setAttribute("cloudCoverPercentage", 20); // Test mixing attributes with elements.
final ImageDescription proxy = accessor.newProxyInstance(ImageDescription.class);
assertEquals("Safety check against regression.", 20.0, proxy.getCloudCoverPercentage(), 0.0);
final Identifier identifier = proxy.getImageQualityCode();
assertSame(Citations.GEOTOOLKIT, identifier.getAuthority());
assertEquals("okay", identifier.getCode());
assertSame(identifier, proxy.getImageQualityCode());
assertNull(proxy.getProcessingLevelCode());
}
/**
* Test the {@code "DiscoveryMetadata/DescriptiveKeywords/.../keywords"} metadata.
* This attribute is of kind {@code Collection<String>}.
*/
@Test
public void testKeywords() {
final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getStreamInstance(GEOTK_FORMAT_NAME));
final MetadataNodeAccessor accessor = new MetadataNodeAccessor(metadata, null,
"DiscoveryMetadata/DescriptiveKeywords", "DescriptiveKeywordsEntry");
accessor.selectChild(accessor.appendChild());
accessor.setAttribute("keywords", "red", "yellow or green", "blue");
accessor.selectChild(accessor.appendChild());
accessor.setAttribute("keywords", "rouge", "jaune ou vert", "bleu");
/*
* Build the metadata objects.
*/
final MetadataNodeAccessor rootAccessor = new MetadataNodeAccessor(metadata, null, "DiscoveryMetadata", null);
final DataIdentification identification = rootAccessor.newProxyInstance(DataIdentification.class);
assertMultilinesEquals(decodeQuotes(
"DataIdentification[“DiscoveryMetadata”]\n" +
"└───DescriptiveKeywords\n" +
" ├───DescriptiveKeywordsEntry\n" +
" │ └───keywords=“red yellow\u00A0or\u00A0green blue”\n" +
" └───DescriptiveKeywordsEntry\n" +
" └───keywords=“rouge jaune\u00A0ou\u00A0vert bleu”\n"), identification.toString());
final Iterator<? extends Keywords> it = identification.getDescriptiveKeywords().iterator();
assertTrue(it.hasNext());
assertEquals(Arrays.asList(
new SimpleInternationalString("red"),
new SimpleInternationalString("yellow or green"),
new SimpleInternationalString("blue")), it.next().getKeywords());
assertTrue(it.hasNext());
assertEquals(Arrays.asList(
new SimpleInternationalString("rouge"),
new SimpleInternationalString("jaune ou vert"),
new SimpleInternationalString("bleu")), it.next().getKeywords());
assertFalse(it.hasNext());
}
/**
* Tests the list of {@code "ImageDescription/Dimensions/Dimension"} elements.
* This method is actually a test of the {@link MetadataProxyList} class.
*/
@Test
public void testDimensionList() {
final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(GEOTK_FORMAT_NAME));
final MetadataNodeAccessor accessor = new MetadataNodeAccessor(metadata, null, "ImageDescription/Dimensions", "Dimension");
final List<SampleDimension> dimensions = accessor.newProxyList(SampleDimension.class);
for (int i=1; i<=4; i++) {
accessor.selectChild(accessor.appendChild());
assertNull(accessor.getAttributeAsDouble("minValue"));
assertNull(accessor.getAttributeAsDouble("maxValue"));
accessor.setAttribute("minValue", -i);
accessor.setAttribute("maxValue", i);
accessor.setAttribute("validSampleValues", NumberRange.create(-i, true, i, true));
assertEquals(i, dimensions.size());
}
int index = 0;
for (final RangeDimension dim : dimensions) {
assertSame(dim, dimensions.get(index++));
assertTrue(dim instanceof SampleDimension);
final SampleDimension sd = (SampleDimension) dim;
assertEquals(Double.valueOf(-index), sd.getMinValue());
assertEquals(Double.valueOf( index), sd.getMaxValue());
assertEquals(NumberRange.create((byte) -index, true, (byte) index, true), sd.getValidSampleValues());
/*
* Check the methods defined in java.lang.Object.
*/
assertEquals("hashCode consistency.", dim.hashCode(), dim.hashCode());
assertEquals(dim, dim);
assertFalse(dim.equals(accessor));
}
}
/**
* Tests the proxy with the children defined under the {@code "ImageDescription/Dimensions"}
* node. This is also an indirect test of {@link MetadataProxyList}, except that this time
* the list is created implicitly.
*/
@Test
public void testDimensions() {
final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(GEOTK_FORMAT_NAME));
final MetadataNodeAccessor accessor = new MetadataNodeAccessor(metadata, null, "ImageDescription/Dimensions", "Dimension");
for (int i=1; i<=4; i++) {
accessor.selectChild(accessor.appendChild());
accessor.setAttribute("minValue", -i);
accessor.setAttribute("maxValue", i);
}
/*
* We need to create the list only after the elements have been added, because the
* current implementation does not detect element additions when they are not performed
* by the same accessor.
*/
final MetadataNodeAccessor rootAccessor = new MetadataNodeAccessor(metadata, null, "ImageDescription", null);
final ImageDescription proxy = rootAccessor.newProxyInstance(ImageDescription.class);
final Collection<? extends RangeDimension> dimensions = proxy.getDimensions();
assertEquals(4, dimensions.size());
/*
* Check the content.
*/
int index = 0;
for (final RangeDimension dim : dimensions) {
index++;
assertTrue(dim instanceof SampleDimension);
final SampleDimension sd = (SampleDimension) dim;
assertEquals(Double.valueOf(-index), sd.getMinValue());
assertEquals(Double.valueOf( index), sd.getMaxValue());
}
/*
* Check the methods defined in java.lang.Object.
*/
assertEquals("hashCode consistency.", proxy.hashCode(), proxy.hashCode());
assertEquals(proxy, proxy);
assertFalse(proxy.equals(accessor));
assertTrue(proxy.toString().startsWith("ImageDescription[\"ImageDescription\"]"));
}
/**
* Test the {@code "DiscoveryMetadata/SpatialResolution"} metadata. This is a collection
* in metadata interface, but declared as a singleton in {@link SpatialMetadataFormat}.
* The proxy should be able to handle that.
*/
@Test
public void testSpatialResolution() {
final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getStreamInstance(GEOTK_FORMAT_NAME));
final MetadataNodeAccessor accessor = new MetadataNodeAccessor(metadata, null, "DiscoveryMetadata/SpatialResolution", null);
accessor.setAttribute("distance", 40);
/*
* Build the metadata objects.
*/
final MetadataNodeAccessor rootAccessor = new MetadataNodeAccessor(metadata, null, "DiscoveryMetadata", null);
final DataIdentification identification = rootAccessor.newProxyInstance(DataIdentification.class);
assertMultilinesEquals(decodeQuotes(
"DataIdentification[“DiscoveryMetadata”]\n" +
"└───SpatialResolution\n" +
" └───distance=“40”\n"), identification.toString());
final Iterator<? extends Resolution> it = identification.getSpatialResolutions().iterator();
assertTrue(it.hasNext());
assertEquals(Double.valueOf(40), it.next().getDistance());
assertFalse(it.hasNext());
}
/**
* Tests the {@code RectifiedGridDomain} node.
*
* @since 3.16
*/
@Test
public void testRectifiedGrid() {
final SpatialMetadata metadata = new SpatialMetadata(SpatialMetadataFormat.getImageInstance(GEOTK_FORMAT_NAME));
final MetadataNodeAccessor rootAccessor = new MetadataNodeAccessor(metadata, null, "RectifiedGridDomain", null);
rootAccessor.setAttribute("origin", -180.0, 90.0);
MetadataNodeAccessor accessor = new MetadataNodeAccessor(rootAccessor, "Limits", null);
accessor.setAttribute("low", new int[] { 0, 0});
accessor.setAttribute("high", new int[] {719, 359});
accessor = new MetadataNodeAccessor(rootAccessor, "OffsetVectors", "OffsetVector");
accessor.selectChild(accessor.appendChild()); accessor.setAttribute("values", 0.5, 0);
accessor.selectChild(accessor.appendChild()); accessor.setAttribute("values", 0, -0.5);
/*
* Build the metadata proxy.
*/
final RectifiedGrid grid = rootAccessor.newProxyInstance(RectifiedGrid.class);
assertNull(grid.getCells());
assertEquals(2, grid.getExtent().getDimension());
assertEquals(2, grid.getOffsetVectors().size());
assertTrue(Arrays.equals(new double[] { 0.5, 0}, grid.getOffsetVectors().get(0)));
assertTrue(Arrays.equals(new double[] { 0.0, -0.5}, grid.getOffsetVectors().get(1)));
assertTrue(Arrays.equals(new double[] {-180, 90}, grid.getOrigin().getCoordinate()));
assertArrayEquals(new int[] {0, 0}, grid.getExtent().getLow ().getCoordinateValues());
assertArrayEquals(new int[] {719, 359}, grid.getExtent().getHigh().getCoordinateValues());
assertEquals(0, grid.getExtent().getLow (1));
assertEquals(359, grid.getExtent().getHigh(1));
assertEquals(360, grid.getExtent().getSpan(1));
}
}