/*
* This file is part of PetaScope.
*
* PetaScope is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* PetaScope is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with PetaScope. If not, see .
*
* For more information please see
* or contact Peter Baumann via .
*
* Copyright 2009 Jacobs University Bremen, Peter Baumann.
*/
package petascope.wcps.server.core;
import petascope.wcps.server.exceptions.InvalidCrsException;
import petascope.wcps.server.exceptions.ResourceException;
import petascope.wcps.server.exceptions.WCPSException;
import petascope.wcps.server.exceptions.InvalidWcpsRequestException;
import petascope.wcps.grammar.WCPSRequest;
import petascope.wcps.grammar.wcpsLexer;
import petascope.wcps.grammar.wcpsParser;
import petascope.wcps.grammar.wcpsParser.wcpsRequest_return;
import java.io.IOException;
import java.io.StringReader;
import org.antlr.runtime.RecognitionException;
import org.odmg.DBag;
import org.odmg.Database;
import org.odmg.Implementation;
import org.odmg.ODMGException;
import org.odmg.OQLQuery;
import org.odmg.QueryException;
import org.odmg.Transaction;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import rasj.RasGMArray;
import rasj.RasImplementation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.xml.sax.InputSource;
/** A WCPS ProcessCoveragesRequest request provides a (just one) rasdaman query, that it executes.
*
* Internally, it relies on XmlRequest, which computes the RasQL query.
*
*/
public class ProcessCoveragesRequest {
private String database;
private IDynamicMetadataSource source;
private String url;
private WCPS wcps;
private String rasqlQuery;
private String mime;
private XmlQuery xmlQuery;
public ProcessCoveragesRequest(String url, String database, Node node, IDynamicMetadataSource source, WCPS wcps)
throws WCPSException, InvalidWcpsRequestException, ResourceException, SAXException, IOException, InvalidCrsException {
super();
this.source = source;
this.url = url;
this.database = database;
this.wcps = wcps;
Node child = node.getFirstChild();
this.rasqlQuery = null;
System.err.println("Parsing ProcessCoveragesRequest node: " + child.getNodeName());
if (child.getNodeName().equals("ProcessCoveragesRequest") == false) {
throw new WCPSException("The document contains an unrecognized node : "
+ child.getNodeName());
}
child = child.getFirstChild();
while (child.getNodeName().equals("#text")) {
child = child.getNextSibling();
}
if (child.getNodeName().equals("query") == false) {
throw new WCPSException("Could not find node : " + child.getNodeName());
}
// "child" is now the node .
Node queryNode = child.getFirstChild();
while (queryNode.getNodeName().equals("#text")) {
queryNode = queryNode.getNextSibling();
}
/**
* The following code is essential. It handles the two cases:
* 1) the xml contains an request
* 2) the xml contains an request
*/
if (queryNode.getNodeName().equals("xmlSyntax")) {
System.err.println("Found XML Syntax query");
this.xmlQuery = new XmlQuery(this.source);
xmlQuery.startParsing(queryNode);
} else if (queryNode.getNodeName().equals("abstractSyntax")) {
try {
String abstractQuery = queryNode.getFirstChild().getNodeValue();
System.err.println("Found Abstract Syntax query: " + abstractQuery);
String xmlString = abstractQueryToXmlQuery(abstractQuery);
InputSource xmlStringSource = new InputSource(new StringReader(xmlString));
System.err.println("Coverted the Abstract syntax query to an XML query:");
System.err.println("***********************************************");
System.err.println(xmlString);
System.err.println("***********************************************");
ProcessCoveragesRequest newRequest = wcps.pcPrepare(url, database, xmlStringSource);
this.xmlQuery = newRequest.getXmlRequestStructure();
} catch (RecognitionException e) {
throw new WCPSException("Abstract Syntax query is invalid: "
+ e.getMessage());
}
} else {
throw new WCPSException("Error ! Unexpected node: " + queryNode.getNodeName());
}
// If everything went well, we now have a proper value for "xmlQuery"
this.rasqlQuery = xmlQuery.toRasQL();
System.err.println("Final RasQL query: " + rasqlQuery);
this.mime = xmlQuery.getMimeType();
}
public static String abstractQueryToXmlQuery(String abstractQuery) throws RecognitionException {
CharStream cs = new ANTLRStringStream(abstractQuery);
wcpsLexer lexer = new wcpsLexer(cs);
CommonTokenStream tokens = new CommonTokenStream();
tokens.setTokenSource(lexer);
wcpsParser parser = new wcpsParser(tokens);
wcpsRequest_return rrequest = parser.wcpsRequest();
WCPSRequest request = rrequest.value;
String xmlRequest = request.toXML();
return xmlRequest;
}
public String getMime() {
return mime;
}
private XmlQuery getXmlRequestStructure() {
return xmlQuery;
}
public String getRasqlQuery() {
return this.rasqlQuery;
}
public List execute() throws ResourceException {
ArrayList results = new ArrayList();
if (this.rasqlQuery != null) {
Implementation impl = new RasImplementation(url);
Database db = impl.newDatabase();
try {
db.open(database, Database.OPEN_READ_ONLY);
} catch (ODMGException odmge) {
try {
db.close();
} catch (ODMGException e) {
}
throw new ResourceException("Could not connect to rasdaman at "
+ url + ", database "
+ database, odmge);
}
Transaction tr = impl.newTransaction();
tr.begin();
OQLQuery q = impl.newOQLQuery();
DBag resultSet;
try {
q.create(this.getRasqlQuery());
resultSet = (DBag) q.execute();
if (resultSet != null) {
Iterator resultIterator = resultSet.iterator();
while (resultIterator.hasNext()) {
Object current = resultIterator.next();
try {
RasGMArray resultArray =
(RasGMArray) current;
results.add(resultArray.getArray());
} catch (ClassCastException e) { // not a RasGMarray
if (!mime.equals("text/plain")) {
throw new ResourceException(
"Incompatible mime and data type!");
}
System.err.println("result="
+ current.toString());
results.add(current.toString().getBytes());
}
/*
* if (mime.equals("text/plain")) {
* System.err.println("dataType is :" + resultArray.getBaseTypeSchema().toString());
* }
*/
}
}
} catch (QueryException qe) {
tr.commit();
try {
db.close();
} catch (ODMGException odmge) {
}
throw new ResourceException("Could not evaluate rasdaman query: '"
+ getRasqlQuery() + "'. Cause: " + qe.getMessage(), qe);
}
tr.commit();
try {
db.close();
} catch (ODMGException odmge) {
}
}
if (mime.equals("text/plain")) {
}
return results;
}
}