/* Copyright (c) 2001 - 2011 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.wfs.response;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletOutputStream;
import org.geoserver.wfs.WFSTestSupport;
import org.spatialite.libs.MultiLibs;
import org.sqlite.SQLiteConfig;
import com.mockrunner.mock.web.MockHttpServletResponse;
import com.mockrunner.mock.web.MockServletInputStream;
/**
* Test the SpatiaLiteOutputFormat WFS extension.
* @author Pablo Velazquez, Geotekne, info@geotekne.com
* @author Jose Macchi, Geotekne, jmacchi@geotekne.com
*/
public class SpatiaLiteOutputFormatTest extends WFSTestSupport {
private String TempDataBaseUrl = null;
private String spatialiteLibraryUrl = null;
protected void oneTimeSetUp( ) throws Exception {
super.oneTimeSetUp();
this.spatialiteLibraryUrl = MultiLibs.loadExtension();
this.TempDataBaseUrl = null;
}
protected void oneTimeTearDown( ) throws Exception {
super.oneTimeTearDown();
new File(this.spatialiteLibraryUrl).delete();
}
/**
* Creates a connection (SQLITE type) with a temporally
* dataBase.sqlite
* @param responseInput
* @param tbl_names
* @param column_names
* @param geometries
* @return connection
*/
private Connection createTempDataBaseConnection(ByteArrayInputStream responseInput) throws Exception{
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
System.out.println(e);
}
File tempDir = File.createTempFile("spatialitemptest", ".sqlite");
FileOutputStream OStream = new FileOutputStream(tempDir);
this.TempDataBaseUrl = tempDir.getAbsolutePath();
int longitud = responseInput.available();
byte[] datos = new byte[longitud];
responseInput.read(datos);
OStream.write(datos);
SQLiteConfig config = new SQLiteConfig();
config.enableLoadExtension(true);
responseInput.close();
OStream.close();
return DriverManager.getConnection("jdbc:sqlite:"+this.TempDataBaseUrl,config.toProperties());
}
/**
* Checks that spatialite contains all the tables (once per layer) with correct geometries.
* Used by many tests to verify SpatiaLite structure.
* @param responseInput
* @param tbl_names
* @param column_names
* @param geometries
*/
private void checkGeometries(ByteArrayInputStream responseInput,String[] tbl_names,
String[] geom_columns,String[] geometries) throws Exception{
Connection conn = createTempDataBaseConnection(responseInput);
Statement stmt = conn.createStatement();
ResultSet rs;
stmt.execute("SELECT load_extension('"+this.spatialiteLibraryUrl+"')");
for(int i =0 ;i < tbl_names.length; i++ ) {
rs = stmt.executeQuery("SELECT GeometryType("+geom_columns[i]+") from "+tbl_names[i]);
assertEquals(rs.getString(1),geometries[i]);
}
conn.close();
new File(this.TempDataBaseUrl).delete();
}
/**
* Test a request with multiple layers.
* @throws Exception
*/
public void testMultiReponse() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Points,MPoints&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "Points");
checkGeometries(responseInput,new String[] {"Points","MPoints"},
new String[] {"pointProperty","multiPointProperty"},new String[]{"POINT","MULTIPOINT"});
}
/**
* Test SPATIALITE Mime format.
* @throws Exception
*/
public void testMIMEOutput() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Points&outputFormat=spatialite");
assertEquals("application/x-sqlite3", resp.getContentType());
}
/**
* Test if exist WFS Error, checking for Mime Type.
* If Mime Type is "application/xml", then an error has occurred
* @throws Exception
*/
public void testWFSError() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Points&outputFormat=spatialite");
assertNotSame("application/xml", resp.getContentType());
}
/**
* Test the content disposition
* @throws Exception
*/
public void testContentDisposition() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Points&outputFormat=spatialite");
String featureName = "Points";
assertEquals("attachment; filename=" + featureName + ".sqlite", resp
.getHeader("Content-Disposition"));
}
/**
* Test not null content.
* @throws Exception
*/
public void testContentNotNull() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Points&outputFormat=spatialite");
ByteArrayInputStream sResponse = getBinaryInputStream(resp);
int dataLengh = sResponse.available();
boolean contentNull = true;
byte[] data = new byte[dataLengh];
sResponse.read(data);
for (byte aByte : data)
if (aByte != 0){
contentNull = false;
break;
}
assertFalse(contentNull);
}
/**
* Test a Point geometry.
* @throws Exception
*/
public void testPoints() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Points&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "Points");
checkGeometries(responseInput,new String[] {"Points"},
new String[] {"pointProperty"},new String[]{"POINT"});
}
/**
* Test a MultiPoint geometry.
* @throws Exception
*/
public void testMultiPoints() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=MPoints&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "MPoints");
checkGeometries(responseInput,new String[] {"MPoints"},
new String[] {"multiPointProperty"},new String[]{"MULTIPOINT"});
}
/**
* Test a LineString geometry.
* @throws Exception
*/
public void testLines() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Lines&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "Lines");
checkGeometries(responseInput,new String[] {"Lines"},
new String[] {"lineStringProperty"},new String[]{"LINESTRING"});
}
/**
* Test a MultiLineString geometry.
* @throws Exception
*/
public void testMultiLines() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=MLines&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "MLines");
checkGeometries(responseInput,new String[] {"MLines"},
new String[] {"multiLineStringProperty"},new String[]{"MULTILINESTRING"});
}
/**
* Test a Polygon geometry.
* @throws Exception
*/
public void testPolygons() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Polygons&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "Polygons");
checkGeometries(responseInput,new String[] {"Polygons"},
new String[] {"polygonProperty"},new String[]{"POLYGON"});
}
/**
* Test a MultiPolygon geometry.
* @throws Exception
*/
public void testMultiPolygons() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=MPolygons&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "MPolygons");
checkGeometries(responseInput,new String[] {"MPolygons"},
new String[] {"multiPolygonProperty"},new String[]{"MULTIPOLYGON"});
}
/**
* Test if the SpatialMetaData has been properly loaded.
* @throws Exception
*/
public void testSpatialMetadata() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&typeName=Points&outputFormat=spatialite");
ByteArrayInputStream responseInput = getBinaryInputStream(resp);
Connection conn = createTempDataBaseConnection(responseInput);
Statement stmt = conn.createStatement();
boolean SpatialMetaData = true;
try
{
stmt.execute("SELECT count(*) FROM geometry_columns");
}catch( SQLException e ) {
SpatialMetaData = false;
}
assertTrue(SpatialMetaData);
conn.close();
new File(this.TempDataBaseUrl).delete();
}
/**
* Test format option FILENAME.
* @throws Exception
*/
public void testCustomFileName() throws Exception {
MockHttpServletResponse resp = getAsServletResponse("wfs?request=GetFeature&format_options=FILENAME:customName&typeName=Points&outputFormat=spatialite");
ByteArrayInputStream responseInput = testBasicResult(resp, "customName");
checkGeometries(responseInput,new String[] {"Points"},
new String[] {"pointProperty"},new String[]{"POINT"});
}
/**
* Test basic extension functionality: mime/type, headers,
* not empty output generation.
* @param resp
* @param featureName
* @return sResponse
* @throws Exception
*/
public ByteArrayInputStream testBasicResult(MockHttpServletResponse resp, String featureName)
throws Exception {
// check mime type
assertEquals("application/x-sqlite3", resp.getContentType());
// check the content disposition
assertEquals("attachment; filename=" + featureName + ".sqlite", resp
.getHeader("Content-Disposition"));
ByteArrayInputStream sResponse = getBinaryInputStream(resp);
// check for content (without checking in detail)
assertNotNull(sResponse);
return sResponse;
}
}