From 80d5602deaaf3b1e00e73bde41e8c06100bb94e7 Mon Sep 17 00:00:00 2001 From: jeb228 Date: Tue, 14 Dec 2010 16:41:46 +0000 Subject: [PATCH] NIHVIVO-1363 Create a separate controller to handle AJAX sparql queries. The calling sequence changes slightly. --- webapp/config/web.xml | 9 ++ .../ajax/SparqlQueryAjaxController.java | 110 ++++++++++++++++++ .../controller/ajax/VitroAjaxController.java | 54 +++++++++ 3 files changed, 173 insertions(+) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java diff --git a/webapp/config/web.xml b/webapp/config/web.xml index ab26cfc5d..3d43ce6a9 100644 --- a/webapp/config/web.xml +++ b/webapp/config/web.xml @@ -1255,6 +1255,15 @@ /edit/primitiveDelete + + ajaxSparqlQuery + edu.cornell.mannlib.vitro.webapp.controller.ajax.SparqlQueryAjaxController + + + ajaxSparqlQuery + /ajax/sparqlQuery + + fetch diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java new file mode 100644 index 000000000..2f9414352 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/SparqlQueryAjaxController.java @@ -0,0 +1,110 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.ajax; + +import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; +import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.hp.hpl.jena.query.DataSource; +import com.hp.hpl.jena.query.Dataset; +import com.hp.hpl.jena.query.DatasetFactory; +import com.hp.hpl.jena.query.Query; +import com.hp.hpl.jena.query.QueryExecution; +import com.hp.hpl.jena.query.QueryExecutionFactory; +import com.hp.hpl.jena.query.QueryFactory; +import com.hp.hpl.jena.query.ResultSet; +import com.hp.hpl.jena.query.ResultSetFormatter; +import com.hp.hpl.jena.query.Syntax; +import com.hp.hpl.jena.rdf.model.Model; + +import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; + +/** + * Handle an AJAX request for a SPARQL query. On entry, the "query" parameter + * contains the query string. + * + * The result is delivered in JSON format. + */ +public class SparqlQueryAjaxController extends VitroAjaxController { + private static final Log log = LogFactory + .getLog(SparqlQueryAjaxController.class); + + private static final String PARAMETER_QUERY = "query"; + private static final String RESPONSE_MIME_TYPE = "application/javascript"; + + /** + * If you are logged in, you can use this servlet. + */ + @Override + protected boolean testIsAuthorized(HttpServletRequest request) { + return LoginStatusBean.getBean(request).isLoggedIn(); + } + + @Override + protected void doRequest(VitroRequest vreq, HttpServletResponse response) + throws ServletException, IOException { + + Model model = vreq.getJenaOntModel(); + if (model == null) { + log.error("JenaOntModel not found."); + response.sendError(SC_INTERNAL_SERVER_ERROR, + "JenaOntModel not found"); + return; + } + + String queryParam = vreq.getParameter(PARAMETER_QUERY); + log.debug("queryParam was : " + queryParam); + if ((queryParam == null) || queryParam.isEmpty()) { + response.sendError(SC_NOT_FOUND, "'" + PARAMETER_QUERY + + "' parameter is required"); + } + + Query query = QueryFactory.create(queryParam, Syntax.syntaxARQ); + if (!query.isSelectType()) { + log.debug("Not a 'select' query."); + response.sendError(SC_NOT_FOUND, + "Only 'select' queries are allowed."); + } + + Dataset dataset = chooseDatasetToQueryAgainst(vreq); + + executeQuery(response, query, dataset); + return; + } + + private Dataset chooseDatasetToQueryAgainst(VitroRequest vreq) { + Dataset dataset = vreq.getDataset(); + if (dataset != null) { + return dataset; + } + + DataSource dataSource = DatasetFactory.create(); + dataSource.setDefaultModel(vreq.getJenaOntModel()); + return dataSource; + } + + private void executeQuery(HttpServletResponse response, Query query, + Dataset dataset) throws IOException { + QueryExecution qe = QueryExecutionFactory.create(query, dataset); + try { + ResultSet results = qe.execSelect(); + response.setContentType(RESPONSE_MIME_TYPE); + OutputStream out = response.getOutputStream(); + ResultSetFormatter.outputAsJSON(out, results); + } finally { + qe.close(); + } + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java new file mode 100644 index 000000000..12b90dfdd --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java @@ -0,0 +1,54 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.ajax; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; + +/** + * A base class for servlets that handle AJAX requests. + */ +public abstract class VitroAjaxController extends HttpServlet { + /** + * Sub-classes must implement this method to verify that the user is + * authorized to execute this request. + */ + protected abstract boolean testIsAuthorized(HttpServletRequest request); + + /** + * Sub-classes must implement this method to handle both GET and POST + * requests. + */ + protected abstract void doRequest(VitroRequest vreq, + HttpServletResponse resp) throws ServletException, IOException; + + /** + * Sub-classes should not override this. Instead, implement doRequest(). + */ + @Override + protected final void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + VitroRequest vreq = new VitroRequest(req); + if (testIsAuthorized(vreq)) { + doRequest(vreq, resp); + } else { + resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Not authorized"); + } + } + + /** + * Sub-classes should not override this. Instead, implement doRequest(). + */ + @Override + protected final void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + doGet(req, resp); + } + +}