/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wms.georss; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.File; import java.io.FileOutputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.geoserver.data.test.MockData; import org.geoserver.wms.WMSMapContent; import org.geoserver.wms.WMSTestSupport; import org.geoserver.wms.georss.GeoRSSTransformerBase.GeometryEncoding; import org.geotools.data.Query; import org.geotools.factory.CommonFactoryFinder; import org.geotools.factory.GeoTools; import org.geotools.map.FeatureLayer; import org.junit.Test; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class RSSGeoRSSTransformerTest extends WMSTestSupport { FilterFactory ff = CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints()); @Test public void testChannelDescription() throws Exception { WMSMapContent map = new WMSMapContent(createGetMapRequest(MockData.BASIC_POLYGONS)); map.addLayer(createMapLayer(MockData.BASIC_POLYGONS)); map.layers().get(0).getUserData().put("abstract", "Test Abstract"); Document document; try { document = getRSSResponse(map, AtomGeoRSSTransformer.GeometryEncoding.LATLONG); } finally { map.dispose(); } Element element = document.getDocumentElement(); assertEquals("rss", element.getNodeName()); Element channel = (Element) element.getElementsByTagName("channel").item(0); NodeList description = channel.getElementsByTagName("description"); assertEquals("Test Abstract", description.item(0).getChildNodes().item(0).getNodeValue()); } @Test public void testLinkTemplate() throws Exception { WMSMapContent map = new WMSMapContent(createGetMapRequest(MockData.BASIC_POLYGONS)); map.addLayer(createMapLayer(MockData.BASIC_POLYGONS)); try { File linkFile = new File(testData.getDataDirectoryRoot().getAbsolutePath() + "/workspaces/cite/cite/BasicPolygons/link.ftl"); FileOutputStream out = new FileOutputStream(linkFile); out.write("http://dummp.com".getBytes()); out.close(); } catch (Exception e) { System.out.println("Error writing link.ftl: " + e); } Document document; try { document = getRSSResponse(map, AtomGeoRSSTransformer.GeometryEncoding.LATLONG); } finally { map.dispose(); } Element element = document.getDocumentElement(); assertEquals("rss", element.getNodeName()); NodeList items = element.getElementsByTagName("item"); int n = getFeatureSource(MockData.BASIC_POLYGONS).getCount(Query.ALL); assertEquals(n, items.getLength()); for (int i = 0; i < items.getLength(); i++) { Element item = (Element) items.item(i); assertEquals("http://dummp.com", item.getElementsByTagName("link").item(0).getChildNodes().item(0).getNodeValue()); } } @Test public void testLatLongInternal() throws Exception { WMSMapContent map = new WMSMapContent(createGetMapRequest(MockData.BASIC_POLYGONS)); map.addLayer(createMapLayer(MockData.BASIC_POLYGONS)); Document document; try { document = getRSSResponse(map, AtomGeoRSSTransformer.GeometryEncoding.LATLONG); } finally { map.dispose(); } Element element = document.getDocumentElement(); assertEquals("rss", element.getNodeName()); NodeList items = element.getElementsByTagName("item"); int n = getFeatureSource(MockData.BASIC_POLYGONS).getCount(Query.ALL); assertEquals(n, items.getLength()); for (int i = 0; i < items.getLength(); i++) { Element item = (Element) items.item(i); assertEquals(1, item.getElementsByTagName("geo:lat").getLength()); assertEquals(1, item.getElementsByTagName("geo:long").getLength()); } } @Test public void testLatLongWMS() throws Exception { Document document = getAsDOM( "wms/reflect?format_options=encoding:latlong&format=application/rss+xml&layers=" + MockData.BASIC_POLYGONS.getPrefix() + ":" + MockData.BASIC_POLYGONS.getLocalPart() ); Element element = document.getDocumentElement(); assertEquals("rss", element.getNodeName()); NodeList items = element.getElementsByTagName("item"); int n = getFeatureSource(MockData.BASIC_POLYGONS).getCount(Query.ALL); assertEquals(n, items.getLength()); for (int i = 0; i < items.getLength(); i++) { Element item = (Element) items.item(i); assertEquals(1, item.getElementsByTagName("geo:lat").getLength()); assertEquals(1, item.getElementsByTagName("geo:long").getLength()); } } @Test public void testSimpleInternal() throws Exception { WMSMapContent map = new WMSMapContent(createGetMapRequest(MockData.BASIC_POLYGONS)); map.addLayer(createMapLayer(MockData.BASIC_POLYGONS)); Document document; try { // print(document); document = getRSSResponse(map, GeoRSSTransformerBase.GeometryEncoding.SIMPLE); } finally { map.dispose(); } Element element = document.getDocumentElement(); assertEquals("rss", element.getNodeName()); NodeList entries = element.getElementsByTagName("item"); int n = getFeatureSource(MockData.BASIC_POLYGONS).getCount(Query.ALL); assertEquals(n, entries.getLength()); for (int i = 0; i < entries.getLength(); i++) { Element entry = (Element) entries.item(i); assertEquals(1, entry.getElementsByTagName("georss:polygon").getLength()); } } @Test public void testSimpleWMS() throws Exception { Document document = getAsDOM( "wms/reflect?format_options=encoding:simple&format=application/rss+xml&layers=" + MockData.BASIC_POLYGONS.getPrefix() + ":" + MockData.BASIC_POLYGONS.getLocalPart() ); Element element = document.getDocumentElement(); assertEquals("rss", element.getNodeName()); NodeList entries = element.getElementsByTagName("item"); int n = getFeatureSource(MockData.BASIC_POLYGONS).getCount(Query.ALL); assertEquals(n, entries.getLength()); for (int i = 0; i < entries.getLength(); i++) { Element entry = (Element) entries.item(i); assertEquals(1, entry.getElementsByTagName("georss:polygon").getLength()); } } @Test public void testGmlWMS() throws Exception { Document document = getAsDOM( "wms/reflect?format_options=encoding:gml&format=application/rss+xml&layers=" + MockData.BASIC_POLYGONS.getPrefix() + ":" + MockData.BASIC_POLYGONS.getLocalPart() ); Element element = document.getDocumentElement(); assertEquals("rss", element.getNodeName()); NodeList entries = element.getElementsByTagName("item"); int n = getFeatureSource(MockData.BASIC_POLYGONS).getCount(Query.ALL); assertEquals(n, entries.getLength()); for (int i = 0; i < entries.getLength(); i++) { Element entry = (Element) entries.item(i); assertEquals(1, entry.getElementsByTagName("gml:Polygon").getLength()); } } @Test public void testFilter() throws Exception { // Set up a map context with a filtered layer WMSMapContent map = new WMSMapContent(createGetMapRequest(MockData.BUILDINGS)); Document document; try { FeatureLayer layer = (FeatureLayer) createMapLayer(MockData.BUILDINGS); Filter f = ff.equals(ff.property("ADDRESS"), ff.literal("215 Main Street")); layer.setQuery(new Query(MockData.BUILDINGS.getLocalPart(), f)); map.addLayer(layer); document = getRSSResponse(map, AtomGeoRSSTransformer.GeometryEncoding.LATLONG); } finally { map.dispose(); } NodeList items = document.getDocumentElement().getElementsByTagName("item"); assertEquals(1, items.getLength()); } @Test public void testReproject() throws Exception { // Set up a map context with a projected layer WMSMapContent map = new WMSMapContent(createGetMapRequest(MockData.LINES)); map.addLayer(createMapLayer(MockData.LINES)); Document document; try { document = getRSSResponse(map, AtomGeoRSSTransformer.GeometryEncoding.LATLONG); } finally { map.dispose(); } NodeList items = document.getDocumentElement().getElementsByTagName("item"); // check all items are there assertEquals(1, items.getLength()); // check coordinates are in wgs84, originals aren't for (int i = 0; i < items.getLength(); i++) { Element item = (Element) items.item(i); double lat = Double.parseDouble(getOrdinate(item, "geo:lat")); double lon = Double.parseDouble(getOrdinate(item, "geo:long")); assertTrue("Expected valid latitude value: " + lat, lat >= -90 && lat <= 90); assertTrue("Expected valid longitude value: " + lon, lon >= -180 && lon <= 180); } } String getOrdinate(Element item, String ordinate) { return item.getElementsByTagName(ordinate).item(0).getChildNodes().item(0).getNodeValue(); } /** * Returns a DOM given a map context and a geometry encoder */ Document getRSSResponse(WMSMapContent map, GeometryEncoding encoding) throws TransformerException, ParserConfigurationException, FactoryConfigurationError, SAXException, IOException { RSSGeoRSSTransformer tx = new RSSGeoRSSTransformer(getWMS()); tx.setGeometryEncoding(encoding); tx.setIndentation(2); ByteArrayOutputStream output = new ByteArrayOutputStream(); tx.transform(map, output); DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = docBuilder.parse(new ByteArrayInputStream(output.toByteArray())); return document; } }