package de.ifgi.lod4wfs.web;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Scanner;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import de.ifgi.lod4wfs.core.Utils;
import de.ifgi.lod4wfs.core.WFSFeature;
import de.ifgi.lod4wfs.facade.Facade;
/**
* @author Jim Jones
*/
public class ServletWFS extends HttpServlet
{
/**
* Automatically generated serial version UID.
*/
private static final long serialVersionUID = 1463163373195766944L;
private static Logger logger = Logger.getLogger("Web-Interface");
public ServletWFS(){
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
Enumeration<String> listParameters = request.getParameterNames();
response.addHeader("Access-Control-Allow-Origin","*");
response.addHeader("Access-Control-Allow-Methods","GET,POST");
response.addHeader("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept");
String CapabilitiesDocuemnt = new String();
String currentVersion = new String();
String currentRequest = new String();
String currentService = new String();
String currentTypeName = new String();
String currentSRSName = new String();
String currentOutputFormat = new String();
String currentOptionsFormat = new String();
String currentMaxFeature = new String();
System.out.println("\nIncoming request:\n");
while (listParameters.hasMoreElements()) {
String parameter = (String) listParameters.nextElement();
System.out.println(parameter + " -> "+ request.getParameter(parameter)+"");
if (parameter.toUpperCase().equals("VERSION")) {
currentVersion=request.getParameter(parameter);
}
if(parameter.toUpperCase().equals("REQUEST")){
currentRequest=request.getParameter(parameter);
}
if(parameter.toUpperCase().equals("TYPENAME")){
currentTypeName=request.getParameter(parameter);
}
if(parameter.toUpperCase().equals("SRSNAME")){
currentSRSName=request.getParameter(parameter);
}
if(parameter.toUpperCase().equals("SERVICE")){
currentService=request.getParameter(parameter);
}
if(parameter.toUpperCase().equals("OUTPUTFORMAT")){
currentOutputFormat=request.getParameter(parameter);
}
if(parameter.toUpperCase().equals("FORMAT_OPTIONS")){
currentOptionsFormat=request.getParameter(parameter);
}
if (parameter.toUpperCase().equals("MAXFEATURE")) {
currentMaxFeature = request.getParameter(parameter);
}
}
/**
* Checking if the current request is valid
*/
String validRequest = new String();
validRequest = this.validateRequest(currentVersion, currentRequest, currentService, currentTypeName, currentSRSName, currentOutputFormat, currentOptionsFormat);
if(validRequest.equals("valid")){
System.out.println("\n");
/**
* GetCapabilities request
*/
if(currentRequest.toUpperCase().equals("GETCAPABILITIES")){
if(currentVersion.equals("1.0.0")){
logger.info("Processing " + currentRequest + " ...");
CapabilitiesDocuemnt = Facade.getInstance().getCapabilities(currentVersion);
}
response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println(CapabilitiesDocuemnt);
logger.info(currentRequest + " request delivered. ");
/**
* GetFeature request
*/
} else if (currentRequest.toUpperCase().equals("GETFEATURE")) {
WFSFeature layer = new WFSFeature();
layer.setName(currentTypeName);
logger.info("Processing " + currentRequest + " request for the feature [" + layer.getName() + "] ...");
response.setStatus(HttpServletResponse.SC_OK);
if (currentOutputFormat.toUpperCase().equals("TEXT/JAVASCRIPT")) {
if (currentOptionsFormat.toUpperCase().equals("CALLBACK:LOADGEOJSON")){
layer.setOutputFormat("geojson");
response.setContentType("text/javascript");
response.getWriter().println("loadGeoJson(" + Facade.getInstance().getFeature(layer) + ")");
} else if (currentOptionsFormat.toUpperCase().equals("JSON")){
layer.setOutputFormat("json");
response.setContentType("text/javascript");
response.getWriter().println(Facade.getInstance().getFeature(layer));
} else if (currentOptionsFormat.toUpperCase().equals("GEOJSON")){
layer.setOutputFormat("geojson");
response.setContentType("text/javascript");
response.getWriter().println(Facade.getInstance().getFeature(layer));
} else if (currentOptionsFormat.toUpperCase().equals("ZIP")){
response.setContentType("application/zip");
File zipFile = Utils.compressFile(Facade.getInstance().getFeature(layer), layer.getName().replace(":", "_") + ".json");
byte[] buffer = new byte[128];
logger.info("Feature " + layer.getName() + " successfully compressed.");
FileInputStream fileInput = new FileInputStream(zipFile);
response.setHeader("Content-Disposition", "attachment;filename=\"" + layer.getName().replace(":", "_") + ".zip\"");
int totalRead = 0;
int readBytes = 0;
while(totalRead < zipFile.length()) {
if(zipFile.length()-totalRead > 128) {
readBytes = fileInput.read(buffer, 0, 128);
totalRead += readBytes;
} else {
readBytes=fileInput.read(buffer,0,(int)zipFile.length() - totalRead);
totalRead= totalRead+readBytes;
}
response.getOutputStream().write(buffer, 0, readBytes);
}
fileInput.close();
} else {
response.getWriter().println(Facade.getInstance().getFeature(layer));
}
} else if (currentOutputFormat.toUpperCase().equals("GML2") ||
currentOutputFormat.toUpperCase().isEmpty()) {
layer.setOutputFormat("xml");
if (currentOptionsFormat.toUpperCase().equals("ZIP")){
response.setContentType("application/zip");
File zipFile = Utils.compressFile(Facade.getInstance().getFeature(layer), layer.getName().replace(":", "_")+".xml");
byte[] buffer = new byte[128];
logger.info("Feature [" + layer.getName() + "] successfully compressed.");
FileInputStream fileInput = new FileInputStream(zipFile);
response.setHeader("Content-Disposition", "attachment;filename=\"" + layer.getName().replace(":", "_") + ".zip\"");
int totalRead = 0;
int readBytes = 0;
while(totalRead < zipFile.length()) {
if(zipFile.length()-totalRead > 128) {
readBytes = fileInput.read(buffer, 0, 128);
totalRead += readBytes;
} else {
readBytes=fileInput.read(buffer,0,(int)zipFile.length() - totalRead);
totalRead= totalRead+readBytes; }
response.getOutputStream().write(buffer, 0, readBytes);
}
fileInput.close();
} else {
response.setContentType("text/xml");
response.getWriter().println(Facade.getInstance().getFeature(layer));
}
}
logger.info(currentRequest + " request delivered. \n");
/**
* DescribeFeatureType request
*/
} else if (currentRequest.toUpperCase().equals("DESCRIBEFEATURETYPE")) {
WFSFeature layer = new WFSFeature();
layer.setName(currentTypeName);
response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK);
logger.info("Processing " + currentRequest + " request for the feature ["+ layer.getName() + "] ...");
response.getWriter().println(Facade.getInstance().describeFeatureType(layer));
logger.info(currentRequest + " request delivered.");
}
} else {
response.getWriter().println(validRequest);
}
}
private String validateRequest(String version, String request, String service, String typeName, String SRS, String outputFormat, String formatOptions){
String result = new String();
boolean valid = true;
try {
result = new Scanner(new File("wfs/ServiceExceptionReport.xml")).useDelimiter("\\Z").next();
if(!service.toUpperCase().equals("WFS")){
if(service.isEmpty()){
result = result.replace("PARAM_REPORT", "No service provided in the request.");
result = result.replace("PARAM_CODE", "ServiceNotProvided");
logger.error("No service provided in the request.");
} else {
result = result.replace("PARAM_REPORT", "Service " + service + " is not supported by this server.");
result = result.replace("PARAM_CODE", "ServiceNotSupported");
logger.error("Service " + service + " is not supported by this server.");
}
valid = false;
} else if (!version.equals("1.0.0")){
if (version.isEmpty()){
result = result.replace("PARAM_REPORT", "Web Feature Service version not informed.");
result = result.replace("PARAM_CODE", "VersionNotProvided");
logger.error("Web Feature Service version not informed.");
} else {
result = result.replace("PARAM_REPORT", "WFS version " + version + " is not supported by this server.");
result = result.replace("PARAM_CODE", "VersionNotSupported");
logger.error("WFS version " + version + " is not supported by this server.");
}
valid = false;
} else if(!request.toUpperCase().equals("GETCAPABILITIES") &&
!request.toUpperCase().equals("DESCRIBEFEATURETYPE") &&
!request.toUpperCase().equals("GETFEATURE")){
result = result.replace("PARAM_REPORT", "Operation " + request + " not supported by WFS.");
result = result.replace("PARAM_CODE", "OperationNotSupported");
logger.error("Operation " + request + " not supported by WFS.");
valid = false;
} else if (request.toUpperCase().equals("DESCRIBEFEATURETYPE") && typeName.isEmpty()){
result = result.replace("PARAM_REPORT", "No feature provided for " + request + ".");
result = result.replace("PARAM_CODE", "FeatureNotProvided");
logger.error("No feature provided for " + request + ".");
valid = false;
} else if (request.toUpperCase().equals("GETFEATURE") && typeName.isEmpty()){
result = result.replace("PARAM_REPORT", "No feature provided for " + request + ".");
result = result.replace("PARAM_CODE", "FeatureNotProvided");
logger.error("No feature provided for " + request + ".");
valid = false;
/**
* Supported output formats:
* GeoJSON (text/javascript)
* GML2
* ZIP
*/
} else if (!outputFormat.toUpperCase().equals("TEXT/JAVASCRIPT") &&
!outputFormat.isEmpty() && //GML2 is assumed for requests without an explicit output format.
!outputFormat.toUpperCase().equals("GML2")){
result = result.replace("PARAM_REPORT", "Invalid output format for " + request + ". The output format '"+ outputFormat + "' is not supported.");
result = result.replace("PARAM_CODE", "InvalidOutputFormat");
logger.error("Invalid output format for " + request + ". The output format " + outputFormat + " is not supported.");
valid = false;
} else if (!formatOptions.toUpperCase().equals("ZIP") &&
!formatOptions.toUpperCase().equals("CALLBACK:LOADGEOJSON") &&
!formatOptions.toUpperCase().equals("JSON") &&
!formatOptions.toUpperCase().equals("GEOJSON") &&
!formatOptions.toUpperCase().isEmpty()){
result = result.replace("PARAM_REPORT", "Invalid output format option for " + request + ". The output format option '" + formatOptions + "' is not supported.");
result = result.replace("PARAM_CODE", "InvalidOutputFormatOption");
logger.error("Invalid output format option for " + request + ". The output format option '" + formatOptions + "' is not supported.");
valid = false;
}// else if (currentMax)
if(!valid){
result = result.replace("PARAM_LOCATOR", request);
} else {
result = "valid";
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return result;
}
}