/**
* Copyright (c) Codice Foundation
*
* This 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, either version 3 of the
* License, or any later version.
*
* This program 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. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*
**/
package org.codice.ddf.spatial.ogc.wfs.v2_0_0.catalog.converter.impl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.DatatypeConverter;
import javax.xml.namespace.QName;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.apache.ws.commons.schema.constants.Constants;
import org.codice.ddf.spatial.ogc.wfs.catalog.common.FeatureMetacardType;
import org.codice.ddf.spatial.ogc.wfs.catalog.common.WfsConstants;
import org.codice.ddf.spatial.ogc.wfs.catalog.converter.FeatureConverter;
import org.codice.ddf.spatial.ogc.wfs.catalog.converter.impl.EnhancedStaxDriver;
import org.codice.ddf.spatial.ogc.wfs.catalog.converter.impl.GmlGeometryConverter;
import org.codice.ddf.spatial.ogc.wfs.catalog.mapper.MetacardMapper;
import org.codice.ddf.spatial.ogc.wfs.v2_0_0.catalog.common.Wfs20Constants;
import org.codice.ddf.spatial.ogc.wfs.v2_0_0.catalog.common.Wfs20FeatureCollection;
import org.junit.Ignore;
import org.junit.Test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.WstxDriver;
import ddf.catalog.data.AttributeDescriptor;
import ddf.catalog.data.Metacard;
import ddf.catalog.data.MetacardType;
import ddf.catalog.data.impl.BasicTypes;
import ddf.catalog.data.impl.MetacardImpl;
public class TestGenericFeatureConverter {
private static final String FEATURE_TYPE = "video_data_set";
private static final String SOURCE_ID = "WFS_2_0";
private static final String GML = "GML";
private static final String PROPERTY_PREFIX = FEATURE_TYPE + ".";
private static final String ID_ELEMENT = "id";
private static final String FILENAME_ELEMENT = "filename";
private static final String VERSION_ELEMENT = "version";
private static final String END_DATE_ELEMENT = "end_date";
private static final String HEIGHT_ELEMENT = "height";
private static final String INDEX_ID_ELEMENT = "index_id";
private static final String OTHER_TAGS_XML_ELEMENT = "other_tags_xml";
private static final String REPOSITORY_ID_ELEMENT = "repository_id";
private static final String START_DATE_ELEMENT = "start_date";
private static final String STYLE_ID_ELEMENT = "style_id";
private static final String WIDTH_ELEMENT = "width";
private static final String GROUND_GEOM_ELEMENT = "ground_geom";
private static final String STATES_TITLE_ELEMENT = "STATE_NAME";
private static final String STATES_FEATURE_TYPE = "states";
@Test
@Ignore //DDF-733
public void testUnmarshalSingleFeatureXmlToObject() {
XStream xstream = new XStream(new WstxDriver());
MetacardType metacardType = buildMetacardType();
GenericFeatureConverterWfs20 converter = new GenericFeatureConverterWfs20();
converter.setMetacardType(buildMetacardType());
converter.setSourceId(SOURCE_ID);
converter.setCoordinateOrder(WfsConstants.LAT_LON_ORDER);
xstream.registerConverter(converter);
xstream.registerConverter(new GmlGeometryConverter());
xstream.alias(FEATURE_TYPE, MetacardImpl.class);
InputStream is = TestGenericFeatureConverter.class
.getResourceAsStream("/video_data_set.xml");
Metacard mc = (Metacard) xstream.fromXML(is);
assertEquals("video_data_set.2", mc.getId());
assertEquals(FEATURE_TYPE, mc.getContentTypeName());
assertEquals(metacardType.getName(), mc.getMetacardType().getName());
assertEquals(SOURCE_ID, mc.getSourceId());
assertEquals("video_data_set.2", mc.getTitle());
assertEquals(2L, mc.getAttribute(PROPERTY_PREFIX + ID_ELEMENT).getValue());
assertEquals(Long.valueOf(1L),
mc.getAttribute(PROPERTY_PREFIX + VERSION_ELEMENT).getValue());
assertEquals(DatatypeConverter.parseDateTime("2005-04-07T09:54:38.983").getTime(),
mc.getAttribute(PROPERTY_PREFIX + END_DATE_ELEMENT).getValue());
assertEquals("/data/test_suite/video/video/videoFile.mpg",
mc.getAttribute(PROPERTY_PREFIX + FILENAME_ELEMENT).getValue());
assertEquals(720L, mc.getAttribute(PROPERTY_PREFIX + HEIGHT_ELEMENT).getValue());
assertEquals("a8a55092f0afae881099637ef7746cd8d7066270d9af4cf0f52c41dab53c4005",
mc.getAttribute(PROPERTY_PREFIX + INDEX_ID_ELEMENT).getValue());
assertEquals(getOtherTagsXml(),
mc.getAttribute(PROPERTY_PREFIX + OTHER_TAGS_XML_ELEMENT).getValue());
assertEquals(26L, mc.getAttribute(PROPERTY_PREFIX + REPOSITORY_ID_ELEMENT).getValue());
assertEquals(DatatypeConverter.parseDateTime("2005-04-07T09:53:39.000").getTime(),
mc.getAttribute(PROPERTY_PREFIX + START_DATE_ELEMENT).getValue());
assertEquals(1280L, mc.getAttribute(PROPERTY_PREFIX + WIDTH_ELEMENT).getValue());
assertEquals(getLocation(), mc.getLocation());
assertEquals(mc.getLocation(),
mc.getAttribute(PROPERTY_PREFIX + GROUND_GEOM_ELEMENT).getValue());
assertNotNull(mc.getCreatedDate());
assertNotNull(mc.getEffectiveDate());
assertNotNull(mc.getModifiedDate());
assertNotNull(mc.getContentTypeNamespace());
assertEquals(mc.getContentTypeNamespace().toString(),
Wfs20Constants.NAMESPACE_URN_ROOT + metacardType.getName());
}
@Test
public void testUnmarshalFeatureCollectionXmlToObject() {
XStream xstream = new XStream(new WstxDriver());
FeatureCollectionConverterWfs20 fcConverter = new FeatureCollectionConverterWfs20();
Map<String, FeatureConverter> fcMap = new HashMap<String, FeatureConverter>();
GenericFeatureConverterWfs20 converter = new GenericFeatureConverterWfs20();
fcMap.put("video_data_set", converter);
fcConverter.setFeatureConverterMap(fcMap);
xstream.registerConverter(fcConverter);
converter.setMetacardType(buildMetacardType());
converter.setCoordinateOrder(WfsConstants.LAT_LON_ORDER);
xstream.registerConverter(converter);
xstream.registerConverter(new GmlGeometryConverter());
xstream.alias("FeatureCollection", Wfs20FeatureCollection.class);
InputStream is = TestGenericFeatureConverter.class
.getResourceAsStream("/video_data_set_collection.xml");
Wfs20FeatureCollection wfc = (Wfs20FeatureCollection) xstream.fromXML(is);
assertEquals(4, wfc.getMembers().size());
Metacard mc = wfc.getMembers().get(0);
assertEquals(mc.getId(), "video_data_set.1");
}
@Test
public void testUnmarshalMultiQueryFeatureCollectionXmlToObject() {
XStream xstream = new XStream(new WstxDriver());
FeatureCollectionConverterWfs20 fcConverter = new FeatureCollectionConverterWfs20();
Map<String, FeatureConverter> fcMap = new HashMap<String, FeatureConverter>();
GenericFeatureConverterWfs20 converter = new GenericFeatureConverterWfs20();
fcMap.put("states", converter);
fcMap.put("streams", converter);
fcConverter.setFeatureConverterMap(fcMap);
xstream.registerConverter(fcConverter);
converter.setMetacardType(buildStatesMetacardType());
converter.setCoordinateOrder(WfsConstants.LAT_LON_ORDER);
xstream.registerConverter(converter);
xstream.alias("FeatureCollection", Wfs20FeatureCollection.class);
InputStream is = TestGenericFeatureConverter.class
.getResourceAsStream("/geoserver_sample.xml");
Wfs20FeatureCollection wfc = (Wfs20FeatureCollection) xstream.fromXML(is);
assertEquals(7, wfc.getMembers().size());
Metacard mc = wfc.getMembers().get(0);
assertEquals(mc.getId(), "states.10");
// Verifies that lat/lon was swapped to lon/lat order for the WKT conversion
// to set the metacard's location
assertTrue(mc.getLocation().startsWith(
"MULTIPOLYGON (((-89.104965 36.953869, -89.129585 36.86644, -89.166496 36.843422000000004,"));
}
@Test
public void testGeoServerLatLonSwappingForMultiPolygon() {
XStream xstream = new XStream(new WstxDriver());
FeatureCollectionConverterWfs20 fcConverter = new FeatureCollectionConverterWfs20();
Map<String, FeatureConverter> fcMap = new HashMap<String, FeatureConverter>();
GenericFeatureConverterWfs20 converter = new GenericFeatureConverterWfs20();
fcMap.put("states", converter);
fcMap.put("streams", converter);
fcConverter.setFeatureConverterMap(fcMap);
xstream.registerConverter(fcConverter);
converter.setMetacardType(buildStatesMetacardType());
converter.setCoordinateOrder(WfsConstants.LAT_LON_ORDER);
xstream.registerConverter(converter);
xstream.alias("FeatureCollection", Wfs20FeatureCollection.class);
InputStream is = TestGenericFeatureConverter.class
.getResourceAsStream("/geoserver_sample_polygon.xml");
Wfs20FeatureCollection wfc = (Wfs20FeatureCollection) xstream.fromXML(is);
assertEquals(1, wfc.getMembers().size());
Metacard mc = wfc.getMembers().get(0);
assertEquals(mc.getId(), "states.10");
// Verifies that lat/lon was swapped to lon/lat order for the WKT conversion
// to set the metacard's location
assertTrue(mc.getLocation().startsWith(
"MULTIPOLYGON (((-89.1 36.1, -89.1 37.1, -88.1 37.1, -88.1 36.1, -89.1 36.1"));
}
@Test
public void testGeoServerLatLonSwappingForPoint() {
XStream xstream = new XStream(new WstxDriver());
FeatureCollectionConverterWfs20 fcConverter = new FeatureCollectionConverterWfs20();
Map<String, FeatureConverter> fcMap = new HashMap<String, FeatureConverter>();
GenericFeatureConverterWfs20 converter = new GenericFeatureConverterWfs20();
fcMap.put("states", converter);
fcMap.put("streams", converter);
fcConverter.setFeatureConverterMap(fcMap);
xstream.registerConverter(fcConverter);
converter.setMetacardType(buildStatesMetacardType());
converter.setCoordinateOrder(WfsConstants.LAT_LON_ORDER);
xstream.registerConverter(converter);
xstream.alias("FeatureCollection", Wfs20FeatureCollection.class);
InputStream is = TestGenericFeatureConverter.class
.getResourceAsStream("/geoserver_sample_point.xml");
Wfs20FeatureCollection wfc = (Wfs20FeatureCollection) xstream.fromXML(is);
assertEquals(1, wfc.getMembers().size());
Metacard mc = wfc.getMembers().get(0);
assertEquals(mc.getId(), "states.10");
// Verifies that lat/lon was swapped to lon/lat order for the WKT conversion
// to set the metacard's location
assertTrue(mc.getLocation().startsWith("POINT (-123.26 49.41)"));
}
@Test(expected = IllegalArgumentException.class)
public void testUnmarshalNoMetacardTypeRegisteredInConverter() throws Throwable {
XStream xstream = new XStream(new WstxDriver());
xstream.registerConverter(new GenericFeatureConverterWfs20());
xstream.registerConverter(new GmlGeometryConverter());
xstream.alias(FEATURE_TYPE, Metacard.class);
InputStream is = TestGenericFeatureConverter.class
.getResourceAsStream("/video_data_set.xml");
try {
Wfs20FeatureCollection wfs = (Wfs20FeatureCollection) xstream.fromXML(is);
} catch (Exception e) {
throw e.getCause();
}
}
@Test
public void testMetacardCollectionToFeatureCollectionXml() {
XStream xstream = new XStream(new EnhancedStaxDriver());
xstream.setMode(XStream.NO_REFERENCES);
xstream.registerConverter(new FeatureCollectionConverterWfs20());
xstream.registerConverter(new GenericFeatureConverterWfs20());
xstream.registerConverter(new GmlGeometryConverter());
// Required the Implementing class. The interface would not work...
xstream.alias(Wfs20Constants.WFS_NAMESPACE_PREFIX + ":" + "FeatureCollection",
Wfs20FeatureCollection.class);
Metacard mc = new SampleMetacard().getMetacard();
Wfs20FeatureCollection wfc = new Wfs20FeatureCollection();
wfc.getMembers().add(mc);
MetacardImpl mc2 = new SampleMetacard().getMetacard();
// Ignore the hack stuff, this was just to imitate having two different
// "MetacardTypes"
mc2.setType(new MetacardType() {
@Override
public String getName() {
return "otherType";
}
@Override
public Set<AttributeDescriptor> getAttributeDescriptors() {
return BasicTypes.BASIC_METACARD.getAttributeDescriptors();
}
@Override
public AttributeDescriptor getAttributeDescriptor(String arg0) {
return BasicTypes.BASIC_METACARD.getAttributeDescriptor(arg0);
}
});
wfc.getMembers().add(mc2);
String xml = xstream.toXML(wfc);
}
@Test
@Ignore //DDF-733
public void testReadCdata() {
XStream xstream = new XStream(new WstxDriver());
String contents = "<tag>my cdata contents</tag>";
String xml = "<string><![CDATA[" + contents + "]]></string>";
String results = (String) xstream.fromXML(xml);
assertEquals(contents, results);
}
/*
* This test will check is the MetacardMapper maps the feature value of 'states.STATE_NAME' to the metacard property 'title'.
*/
@Test
public void testUnmarshalMultiQueryFeatureCollectionXmlToObjectWithMetacardMapper() {
//Create Metacard Mapper
String featureProp = "states.STATE_NAME";
String metacardAttr = "title";
MetacardMapper metacardMapper = mock(MetacardMapper.class);
when(metacardMapper.getMetacardAttribute(featureProp)).thenReturn(metacardAttr);
XStream xstream = new XStream(new WstxDriver());
FeatureCollectionConverterWfs20 fcConverter = new FeatureCollectionConverterWfs20();
Map<String, FeatureConverter> fcMap = new HashMap<String, FeatureConverter>();
GenericFeatureConverterWfs20 converter = new GenericFeatureConverterWfs20(metacardMapper);
fcMap.put("states", converter);
fcMap.put("streams", converter);
fcConverter.setFeatureConverterMap(fcMap);
xstream.registerConverter(fcConverter);
converter.setMetacardType(buildStatesMetacardType());
converter.setCoordinateOrder(WfsConstants.LAT_LON_ORDER);
xstream.registerConverter(converter);
xstream.alias("FeatureCollection", Wfs20FeatureCollection.class);
InputStream is = TestGenericFeatureConverter.class
.getResourceAsStream("/geoserver_sample.xml");
Wfs20FeatureCollection wfc = (Wfs20FeatureCollection) xstream.fromXML(is);
assertEquals(7, wfc.getMembers().size());
Metacard mc = wfc.getMembers().get(0);
assertEquals(mc.getTitle(), "Missouri");
// Verifies that lat/lon was swapped to lon/lat order for the WKT conversion
// to set the metacard's location
assertTrue(mc.getLocation().startsWith(
"MULTIPOLYGON (((-89.104965 36.953869, -89.129585 36.86644, -89.166496 36.843422000000004,"));
}
private MetacardType buildMetacardType() {
XmlSchema schema = new XmlSchema();
schema.getElements().putAll(buildElementMap(schema));
return new FeatureMetacardType(schema, new QName(FEATURE_TYPE), new ArrayList<String>(),
Wfs20Constants.GML_3_2_NAMESPACE);
}
private Map<QName, XmlSchemaElement> buildElementMap(XmlSchema schema) {
Map<QName, XmlSchemaElement> elementMap = new HashMap<QName, XmlSchemaElement>();
elementMap.put(new QName(ID_ELEMENT),
buildSchemaElement(ID_ELEMENT, schema, Constants.XSD_LONG));
elementMap.put(new QName(VERSION_ELEMENT),
buildSchemaElement(VERSION_ELEMENT, schema, Constants.XSD_LONG));
elementMap.put(new QName(END_DATE_ELEMENT),
buildSchemaElement(END_DATE_ELEMENT, schema, Constants.XSD_DATETIME));
elementMap.put(new QName(FILENAME_ELEMENT),
buildSchemaElement(FILENAME_ELEMENT, schema, Constants.XSD_STRING));
elementMap.put(new QName(HEIGHT_ELEMENT),
buildSchemaElement(HEIGHT_ELEMENT, schema, Constants.XSD_LONG));
elementMap.put(new QName(INDEX_ID_ELEMENT),
buildSchemaElement(INDEX_ID_ELEMENT, schema, Constants.XSD_STRING));
elementMap.put(new QName(OTHER_TAGS_XML_ELEMENT),
buildSchemaElement(OTHER_TAGS_XML_ELEMENT, schema, Constants.XSD_STRING));
elementMap.put(new QName(REPOSITORY_ID_ELEMENT),
buildSchemaElement(REPOSITORY_ID_ELEMENT, schema, Constants.XSD_LONG));
elementMap.put(new QName(START_DATE_ELEMENT),
buildSchemaElement(START_DATE_ELEMENT, schema, Constants.XSD_DATETIME));
elementMap.put(new QName(STYLE_ID_ELEMENT),
buildSchemaElement(STYLE_ID_ELEMENT, schema, Constants.XSD_DECIMAL));
elementMap.put(new QName(WIDTH_ELEMENT),
buildSchemaElement(WIDTH_ELEMENT, schema, Constants.XSD_LONG));
XmlSchemaElement gmlElement = new XmlSchemaElement(schema, true);
gmlElement.setSchemaType(new XmlSchemaComplexType(schema, false));
gmlElement.setSchemaTypeName(new QName(Wfs20Constants.GML_3_2_NAMESPACE, GML));
gmlElement.setName(GROUND_GEOM_ELEMENT);
elementMap.put(new QName(GROUND_GEOM_ELEMENT), gmlElement);
return elementMap;
}
private MetacardType buildStatesMetacardType() {
XmlSchema schema = new XmlSchema();
schema.getElements().putAll(buildStatesElementMap(schema));
return new FeatureMetacardType(schema, new QName(STATES_FEATURE_TYPE),
new ArrayList<String>(), Wfs20Constants.GML_3_2_NAMESPACE);
}
private Map<QName, XmlSchemaElement> buildStatesElementMap(XmlSchema schema) {
Map<QName, XmlSchemaElement> elementMap = new HashMap<QName, XmlSchemaElement>();
elementMap.put(new QName(STATES_TITLE_ELEMENT),
buildSchemaElement(STATES_TITLE_ELEMENT, schema, Constants.XSD_STRING));
XmlSchemaElement gmlElement = new XmlSchemaElement(schema, true);
gmlElement.setSchemaType(new XmlSchemaComplexType(schema, false));
gmlElement.setSchemaTypeName(new QName(Wfs20Constants.GML_3_2_NAMESPACE, GML));
gmlElement.setName("the_geom");
elementMap.put(new QName("the_geom"), gmlElement);
return elementMap;
}
private XmlSchemaElement buildSchemaElement(String elementName, XmlSchema schema,
QName typeName) {
XmlSchemaElement element = new XmlSchemaElement(schema, true);
element.setSchemaType(new XmlSchemaSimpleType(schema, false));
element.setSchemaTypeName(typeName);
element.setName(elementName);
return element;
}
private String getOtherTagsXml() {
return "<metadata>metadata goes here...</metadata>";
}
private String getLocation() {
return "POLYGON ((117.6552810668945 -30.92013931274414, 117.661361694336 -30.92383384704589, 117.6666412353516 -30.93005561828613, "
+ "117.6663589477539 -30.93280601501464, 117.6594467163086 -30.93186187744141, 117.6541137695312 -30.93780517578125, "
+ "117.6519470214844 -30.94397163391114, 117.6455535888672 -30.94255638122559, 117.6336364746094 -30.93402862548828, "
+ "117.6355285644531 -30.92874908447266, 117.6326370239258 -30.92138862609864, 117.6395568847656 -30.92236137390137, "
+ "117.6433029174805 -30.91708374023438, 117.6454467773437 -30.91711044311523, 117.6484985351563 -30.92061042785645, "
+ "117.6504135131836 -30.92061042785645, 117.6504440307617 -30.91638946533203, 117.6552810668945 -30.92013931274414))";
}
}