summaryrefslogtreecommitdiffstats
path: root/src/wcps/server/servlet/WCPService.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/wcps/server/servlet/WCPService.java')
-rw-r--r--src/wcps/server/servlet/WCPService.java244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/wcps/server/servlet/WCPService.java b/src/wcps/server/servlet/WCPService.java
new file mode 100644
index 0000000..60e5b14
--- /dev/null
+++ b/src/wcps/server/servlet/WCPService.java
@@ -0,0 +1,244 @@
+package wcps.server.servlet;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.StringBufferInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+
+import wcps.server.core.CachedMetadataSource;
+import wcps.server.core.DbMetadataSource;
+import wcps.server.core.ProcessCoverageRequest;
+import wcps.server.core.WCPS;
+import syntaxParser.WCPSParser;
+import syntaxParser.WCPSScanner;
+import syntaxParser.WCPSRequest;
+import syntaxParser.SyntaxErrorException;
+import java.io.StringBufferInputStream;
+import org.xml.sax.InputSource;
+// This is the servlet interface of WCPS. It mostly consists of sanity checks ana initialization, the meat is onyl a few lines. The WCPS class does the actual work.
+
+// Note an important limitation: this will only return the first result if several are available. The reason is that WCPS currently has no standardized way to return multiple byte streams to the user.
+
+public class WCPService extends HttpServlet {
+
+ private static final long serialVersionUID = 84786549L;
+
+ private Properties dbParams;
+ private DbMetadataSource metadataSource;
+ private String rasdamanUrl;
+ private String rasdamanDatabase;
+ private WCPS wcps;
+
+ public void init() throws ServletException {
+
+ try {
+ dbParams = new Properties();
+ System.out.println ("WCPS: loading database properties");
+ dbParams.load( new FileInputStream( getServletContext().getRealPath( "/dbparams.properties" ) ) );
+ rasdamanUrl = dbParams.getProperty( "rasdaman_url" );
+ rasdamanDatabase = dbParams.getProperty( "rasdaman_database" );
+
+ System.out.println ("WCPS: initializing metadata database");
+ metadataSource = new DbMetadataSource( dbParams.getProperty( "metadata_driver" ), dbParams.getProperty( "metadata_url" ), dbParams.getProperty( "metadata_user" ), dbParams.getProperty( "metadata_pass" ), false );
+
+ System.out.println( "WCPS: initializing WCPS core" );
+ wcps = new WCPS( new File( getServletContext().getRealPath( "/xml/ogc/wcps/1.0.0/wcpsProcessCoverage.xsd" ) ), new CachedMetadataSource( metadataSource ) );
+
+ System.out.println( "WCPS: initialization complete" );
+ }
+ catch( Exception e ) {
+ System.out.println( "WCPS: initialization error" );
+ System.out.println( "WCPS: closing metadata database" );
+ if (metadataSource != null) {
+ metadataSource.close();
+ }
+ System.out.println( "WCPS: done with init error" );
+ throw new ServletException( "WCPS initialization error", e );
+ }
+
+ }
+
+ public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
+
+ System.out.println( "WCPS: invoked with GET" );
+ printUsage( response );
+
+ }
+
+ public void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+ System.out.println ("WCPS: invoked with POST");
+ OutputStream webOut = null;
+ try {
+ String xmlRequest = null;
+
+ if( ServletFileUpload.isMultipartContent( request ) ) {
+ @SuppressWarnings( "unchecked" ) Iterator<FileItem> fileItems = (Iterator<FileItem>) (new ServletFileUpload( new DiskFileItemFactory() )).parseRequest( request ).iterator();
+ if( !fileItems.hasNext() ) {
+ throw new IOException( "Multipart POST request contains no parts" );
+ }
+ FileItem fileItem = fileItems.next();
+ if( fileItems.hasNext() ) {
+ throw new IOException( "Multipart POST request contains too many parts" );
+ }
+ if( !fileItem.isFormField() && fileItem.getContentType().equals( "text/xml" ) ) {
+ xmlRequest = fileItem.getString ();
+ }
+ if( xmlRequest == null ) {
+ System.out.println ("WCPS: no XML file was uploaded within multipart POST request");
+ printUsage( response );
+ return;
+ }
+ System.out.println ("WCPS: received XML via a multipart POST request");
+ }
+
+ else {
+ String xml = request.getParameter( "xml" );
+ String query = request.getParameter( "query" );
+ if( xml != null ) {
+ System.out.println( "WCPS: received XML via a 'xml' parameter in a POST request" );
+ xmlRequest = xml;
+ }
+ else if( query != null ) {
+ System.out.println( "WCPS: received the following query via a 'query' parameter in a POST request:" );
+ System.out.println( query );
+ /* The JLex doesn't handle newlines well.
+ We consider them as whitespace anyway so we substitute them here.
+ */
+ query = query.replace('\n', ' ');
+ query = query.replace('\r', ' ');
+ query = query.replace('\t', ' ');
+ log(query);
+ // Initialize the parser
+ WCPSParser parser = new WCPSParser(new WCPSScanner(new StringBufferInputStream(query)));
+ try {
+ WCPSRequest wcpsRequest = (WCPSRequest)parser.debug_parse().value;
+ xmlRequest = wcpsRequest.toXML();
+ } catch (SyntaxErrorException e) {
+ FormatSyntaxException(e, response, query);
+ return;
+ }
+ System.out.println("The XML is: " + xmlRequest);
+ }
+ else {
+ System.out.println( "WCPS: no request was received" );
+ printUsage (response);
+ return;
+ }
+ }
+ System.out.println( "WCPS: received the following request:" );
+ System.out.println( xmlRequest );
+
+ System.out.println( "WCPS: preparing request" );
+ ProcessCoverageRequest processCoverageRequest = wcps.pcPrepare(rasdamanUrl, rasdamanDatabase, new InputSource(new StringBufferInputStream(xmlRequest)));
+ System.out.println( "[" + processCoverageRequest.getMime() + "] " + processCoverageRequest.getQuery());
+
+ String query = processCoverageRequest.getQuery();
+ log("Resulting RasQL query: " + query);
+ String mimetype = processCoverageRequest.getMime();
+ System.out.println( "WCPS: executing request" );
+
+ List<byte[]> results = processCoverageRequest.execute();
+
+ System.out.println( "WCPS: setting response mimetype to " + mimetype );
+ response.setContentType( mimetype );
+ System.out.println( "WCPS: returning response" );
+ webOut = response.getOutputStream();
+ webOut.write( results.get( 0 ) );
+ System.out.println( "WCPS: done" );
+ }
+ catch( Exception e ) {
+ printError( response, "Error: " + e.getMessage(), e );
+ }
+ finally {
+ if( webOut != null ) {
+ try {
+ webOut.close();
+ }
+ catch( IOException e ) {}
+ }
+ }
+ }
+
+ public void destroy() {
+
+ super.destroy();
+
+ }
+
+ public String getServletInfo() {
+
+ return "Web Coverage Processing Service";
+
+ }
+
+ private void printError( HttpServletResponse response, String message, Exception e ) throws IOException {
+
+ System.out.println( "WCPS: error" );
+ System.out.println( "WCPS: setting response mimetype to text/html; charset=utf-8" );
+ response.setContentType( "text/html; charset=utf-8" );
+ System.out.println( "WCPS: returning the following error message" );
+ e.printStackTrace( System.out );
+ System.out.println( "WCPS: end of error message" );
+ PrintWriter out = new PrintWriter( response.getOutputStream() );
+ out.println( "<html><head><title>Web Coverage Processing Service</title></head><body>" );
+ out.println( "<h1>An error has occured</h1>" );
+ out.println( "<p>" + message + "</p>" );
+ out.println( "<p>Stack trace:<br/><small>" );
+ e.printStackTrace( out );
+ out.println( "</small></p></body></html>" );
+ out.close();
+ System.out.println( "WCPS: done with error" );
+
+ }
+
+ private void printUsage( HttpServletResponse response ) throws IOException {
+
+ System.out.println( "WCPS: setting response mimetype to text/html; charset=utf-8" );
+ System.out.println( "WCPS: returning usage message" );
+ response.setContentType( "text/html; charset=utf-8" );
+ PrintWriter out = new PrintWriter( response.getOutputStream() );
+ out.println( "<html><head><title>Web Coverage Processing Service</title></head><body>" );
+ out.println( "<h1>Hello</h1>" );
+ out.println( "<p>There are 3 ways to invoke this service:</p>" );
+ out.println( "<p>1. Upload a ProcessCoverage XML request as a multupart/form-data POST request containing a file. You can use the form below.</p>" );
+ out.println( "<form action=\"\" method=\"post\" enctype=\"multipart/form-data\"><input type=\"file\" accept=\"text/xml\" size=\"64\" name=\"xmlfile\"/> <input type=\"submit\" value=\"Send\"/></form>" );
+ out.println( "<p>2. Enter a ProcessCoverage XML request and submit it as a POST request with a parameter named <b>xml</b>. You can use the form below.</p>" );
+ out.println( "<form action=\"\" method=\"post\"><textarea cols=\"64\" rows=\"16\" name=\"xml\"></textarea><input type=\"submit\" value=\"Send\"/></form>" );
+ out.println( "<p>3. Enter a ProcessCoverage request in WCPS abstract syntax and submit it as a POST request with a parameter named <b>query</b>. You can use the form below.</p>" );
+ out.println( "<form action=\"\" method=\"post\"><textarea cols=\"64\" rows=\"4\" name=\"query\"></textarea><input type=\"submit\" value=\"Send\"/></form>" );
+ out.println( "</body></html>" );
+ out.close();
+ System.out.println( "WCPS: done nothing" );
+
+ }
+
+ void FormatSyntaxException(SyntaxErrorException e,
+ HttpServletResponse response,
+ String query) throws IOException {
+// response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
+ response.setContentType("text/html; charset=utf-8");
+ PrintWriter o = new PrintWriter(response.getOutputStream());
+ o.println("<html><head><title>Web Coverage Processing Service</title></head><body>" );
+ o.println("<p>There seems to be a syntax problem with your query:</p>");
+ o.println("<p><font color='00FF00'>" + query.substring(0, e.getColumn()-1) +
+ "</font><font color='FF0000'>" + query.substring(e.getColumn()-1) +
+ "</font></p>");
+ o.println("<p>Please correct it and try again.</p></body></html>");
+ o.close();
+ System.out.println( "WCPS: Syntax Error reported");
+ }
+
+}