/* (c) 2014 - 2017 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.wfs.response;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.wfs.WFSTestSupport;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletResponse;
/**
* Test the DXFOutputFormat WFS extension.
* @author Mauro Bartolomeoli, mbarto@infosia.it
*
*/
public class DXFOutputFormatTest extends WFSTestSupport {
@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
// by default we parse layers format_options as a string
LayersKvpParser.parseAsList = false;
}
/**
* Checks that dxf contains all the elements of sequence, in order.
* Used by many tests to verify DXF structure.
* @param dxf
* @param sequence
*/
private void checkSequence(String dxf,String[] sequence,int pos) {
for(String item: sequence) {
pos=dxf.indexOf(item,pos+1);
assertTrue(pos!=-1);
}
}
/**
* Checks that dxf contains all the elements of sequence, in order.
* Used by many tests to verify DXF structure.
* @param dxf
* @param sequence
*/
private void checkSequence(String dxf,String[] sequence) {
checkSequence(dxf,sequence,-1);
}
/**
* Test a request with two queries.
*/
@Test
public void testMultiLayer() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Points,MPoints&outputFormat=dxf");
String sResponse = testBasicResult(resp, "Points_MPoints");
checkSequence(sResponse,new String[] {"LAYER","LAYER","LAYER","POINTS","LAYER","MPOINTS"});
}
/**
* Test DXF-ZIP format.
*/
@Test
public void testZipOutput() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Points&outputFormat=dxf-zip");
// check mime type
assertEquals("application/zip", resp.getContentType());
}
/**
* Test a Point geometry.
*/
@Test
public void testPoints() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Points&outputFormat=dxf");
String sResponse = testBasicResult(resp, "Points");
int pos = getGeometrySearchStart(sResponse);
assertTrue(pos != -1);
checkSequence(sResponse,new String[] {"POINT"},pos);
}
/**
* Test a MultiPoint geometry.
*/
@Test
public void testMultiPoints() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=MPoints&outputFormat=dxf");
String sResponse = testBasicResult(resp, "MPoints");
int pos = getGeometrySearchStart(sResponse);
assertTrue(pos != -1);
// has to insert two points
checkSequence(sResponse,new String[] {"POINT","POINT"},pos);
}
/**
* Test a LineString geometry.
*/
@Test
public void testLines() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Lines&outputFormat=dxf");
String sResponse = testBasicResult(resp, "Lines");
int pos = getGeometrySearchStart(sResponse);
assertTrue(pos != -1);
checkSequence(sResponse,new String[] {"LWPOLYLINE"},pos);
}
/**
* Test a MultiLineString geometry.
*/
@Test
public void testMultiLines() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=MLines&outputFormat=dxf");
String sResponse = testBasicResult(resp, "MLines");
int pos = getGeometrySearchStart(sResponse);
assertTrue(pos != -1);
// has to insert two lwpolyline
checkSequence(sResponse,new String[] {"LWPOLYLINE","LWPOLYLINE"},pos);
}
/**
* Test a Polygon geometry.
*/
@Test
public void testPolygons() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Polygons&outputFormat=dxf");
String sResponse = testBasicResult(resp, "Polygons");
int pos = getGeometrySearchStart(sResponse);
assertTrue(pos != -1);
// has to insert an lwpolyline
checkSequence(sResponse,new String[] {"LWPOLYLINE"},pos);
}
/**
* Test writeattributes option.
*/
@Test
public void testWriteAttributes() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Polygons&outputFormat=dxf&format_options=withattributes:true");
String sResponse = testBasicResult(resp, "Polygons");
int pos = getGeometrySearchStart(sResponse);
assertTrue(pos != -1);
// has to insert an attribute
checkSequence(sResponse,new String[] {"ATTRIB", "AcDbAttribute"},pos);
}
/**
* Test a MultiPolygon geometry.
*/
@Test
public void testMultiPolygons() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=MPolygons&outputFormat=dxf");
String sResponse = testBasicResult(resp, "MPolygons");
int pos = getGeometrySearchStart(sResponse);
assertTrue(pos != -1);
// has to insert two lwpolyline
checkSequence(sResponse,new String[] {"LWPOLYLINE","LWPOLYLINE"},pos);
}
/**
* Bounding Box excludes all features. Envelope is empty Envelop.expandBy(1) is still empty.
* Division by zero. The result is an invalid character in DXF, entire file is invalid.
*/
@Test
public void testEmptyBbox() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=MPolygons&outputFormat=dxf&bbox=929636,6013554.5,930744,6014601.5&srsName=EPSG:900913");
String sResponse = testBasicResult(resp, "MPolygons");
System.out.println(sResponse);
for (int i = 0; i < sResponse.length(); i++) {
char c = sResponse.charAt(i);
assertTrue("Invalid non-ASCII char: '"+c+"'", c < 128);
}
}
/**
* Test maxFeatures=0: No collection passed to writer, no geom. Result was: NPE
* Maybe exotic, but should not end in NPE.
*/
@Test
public void testEmptyCount() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=MPolygons&outputFormat=dxf&maxFeatures=0");
testBasicResult(resp, "MPolygons");
}
/**
* Test format option asblocks.
*
*/
@Test
public void testGeometryAsBlock() {
try {
// geometry as blocks false
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Polygons&outputFormat=dxf");
String sResponse = resp.getContentAsString();
assertNotNull(sResponse);
// no insert block generated
assertFalse(sResponse.indexOf("INSERT") != -1);
// geometry as blocks true
resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Polygons&outputFormat=dxf&format_options=asblocks:true");
sResponse = resp.getContentAsString();
assertNotNull(sResponse);
// one insert block generated
assertTrue(sResponse.indexOf("INSERT") != -1);
} catch (Throwable t) {
fail(t.getMessage());
}
}
/**
* Test format option version support.
*
*/
@Test
public void testVersion() throws Exception {
try {
// good request, version 14
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Polygons&outputFormat=dxf&format_options=version:14");
String sResponse = resp.getContentAsString();
assertNotNull(sResponse);
assertTrue(sResponse.startsWith(" 0"));
// bad request, version 13: not supported
resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Polygons&outputFormat=dxf&format_options=version:13");
sResponse = resp.getContentAsString();
assertNotNull(sResponse);
// has to return an exception
assertTrue(sResponse.indexOf("</ows:ExceptionReport>") != -1);
} catch (Throwable t) {
fail(t.getMessage());
}
}
/**
* Test basic extension functionality: mime/type, headers,
* not empty output generation.
* @param resp
* @param featureName
*
*/
public String testBasicResult(MockHttpServletResponse resp, String featureName)
throws Exception {
// check mime type
assertEquals("application/dxf", resp.getContentType());
// check the content disposition
assertEquals("attachment; filename=" + featureName + ".dxf", resp
.getHeader("Content-Disposition"));
// check for content (without checking in detail)
String sResponse = resp.getContentAsString();
assertNotNull(sResponse);
return sResponse;
}
/**
* Test the ltypes format option.
*/
@Test
public void testCustomLineTypes() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Lines&outputFormat=dxf&format_options=ltypes:DASHED!--_*_!0.5");
String sResponse = testBasicResult(resp, "Lines");
checkSequence(sResponse,new String[] {"DASHED"});
}
/**
* Test the colors format option.
*/
@Test
public void testCustomColors() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Points,MPoints&outputFormat=dxf&format_options=colors:1,2");
String sResponse = testBasicResult(resp, "Points_MPoints");
checkSequence(sResponse,new String[] {"LAYER","LAYER","LAYER"," 62\n 1","LAYER"," 62\n 2"});
}
/**
* Test custom naming for layers.
*/
@Test
public void testLayerNames() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Points,MPoints&outputFormat=dxf&format_options=layers:MyLayer1,MyLayer2");
String sResponse = testBasicResult(resp, "Points_MPoints");
checkSequence(sResponse,new String[] {"LAYER","LAYER","LAYER","MYLAYER1","LAYER","MYLAYER2"});
}
/**
* Test fix for GEOS-6402.
*/
@Test
public void testLayerNamesParsing() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Points,MPoints&outputFormat=dxf&format_options=layers:MyLayer1,MyLayer2");
String sResponse = testBasicResult(resp, "Points_MPoints");
checkSequence(sResponse,new String[] {"LAYER","LAYER","LAYER","MYLAYER1","LAYER","MYLAYER2"});
// now repeat the test parsing layers format_options as a list, instead of a string
LayersKvpParser.parseAsList = true;
resp = getAsServletResponse("wfs?request=GetFeature&version=1.1.0&typeName=Points,MPoints&outputFormat=dxf&format_options=layers:MyLayer1,MyLayer2");
sResponse = testBasicResult(resp, "Points_MPoints");
checkSequence(sResponse,new String[] {"LAYER","LAYER","LAYER","MYLAYER1","LAYER","MYLAYER2"});
}
/**
* Get a search starting point.
* @param response
*
*/
private int getGeometrySearchStart(String response) {
return response.indexOf("BLOCKS");
}
}