[VIVO-1872] - Add download option to SPARQL Query page (#164)

* Add download option to SPARQL Query page

* Set SPARQL query results content type even if downloading

* Address pull request comments
This commit is contained in:
Ben 2020-05-27 22:58:20 -06:00 committed by GitHub
parent 42c69ef04b
commit e198fce908
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 16 deletions

View file

@ -40,6 +40,8 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.utils.http.AcceptHeaderParsingException;
import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException;
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.RdfResultMediaType;
import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.ResultSetMediaType;
/**
* Present the SPARQL Query form, and execute the queries.
@ -110,11 +112,20 @@ public class SparqlQueryController extends FreemarkerHttpServlet {
.getRDFService();
String queryString = req.getParameter("query");
boolean download = Boolean.parseBoolean(req.getParameter("download"));
Query query = SparqlQueryUtils.create(queryString);
try {
String format = interpretRequestedFormats(req, queryString);
String format = interpretRequestedFormats(req, query);
SparqlQueryApiExecutor core = SparqlQueryApiExecutor.instance(
rdfService, queryString, format);
resp.setContentType(core.getMediaType());
if (download) {
String extension = getFilenameExtension(req, query, format);
resp.setHeader("Content-Transfer-Encoding", "binary");
resp.setHeader("Content-disposition", "attachment; filename=query-results." + extension);
}
core.executeAndFormat(resp.getOutputStream());
} catch (InvalidQueryTypeException e) {
do400BadRequest("Query type is not SELECT, ASK, CONSTRUCT, "
@ -132,8 +143,7 @@ public class SparqlQueryController extends FreemarkerHttpServlet {
}
private String interpretRequestedFormats(HttpServletRequest req,
String queryString) throws NotAcceptableException {
Query query = SparqlQueryUtils.create(queryString);
Query query) throws NotAcceptableException {
String parameterName = (query.isSelectType() || query.isAskType()) ? "resultFormat"
: "rdfResultFormat";
String parameterValue = req.getParameter(parameterName);
@ -145,6 +155,20 @@ public class SparqlQueryController extends FreemarkerHttpServlet {
}
}
private String getFilenameExtension(HttpServletRequest req,
Query query, String format) {
String extension;
if (query.isSelectType() || query.isAskType()) {
ResultSetMediaType mediaType = ResultSetMediaType.fromContentType(format);
extension = mediaType.getExtension();
}
else {
RdfResultMediaType mediaType = RdfResultMediaType.fromContentType(format);
extension = mediaType.getExtension();
}
return extension;
}
private void do400BadRequest(String message, HttpServletResponse resp)
throws IOException {
resp.setStatus(400);

View file

@ -12,17 +12,17 @@ import java.util.Map;
* and DESCRIBE).
*/
public enum RdfResultMediaType {
TEXT("text/plain", true, "NTRIPLE", "N-TRIPLE"),
TEXT("text/plain", true, "NTRIPLE", "N-TRIPLE", "nt"),
RDF_XML("application/rdf+xml", true, "RDFXML", "RDF/XML"),
RDF_XML("application/rdf+xml", true, "RDFXML", "RDF/XML", "rdf"),
N3("text/n3", true, "N3", "N3"),
N3("text/n3", true, "N3", "N3", "n3"),
TTL("text/turtle", false, "N3", "TTL"),
TTL("text/turtle", false, "N3", "TTL", "ttl"),
JSON("application/json", false, "N3", "JSON"),
JSON("application/json", false, "N3", "JSON", "json"),
JSON_LD("application/ld+json", false, "N3", "JSON");
JSON_LD("application/ld+json", false, "N3", "JSON", "jsonld");
// ----------------------------------------------------------------------
// Keep a map of content types, for easy conversion back and forth
@ -79,12 +79,18 @@ public enum RdfResultMediaType {
*/
private final String jenaResponseFormat;
/**
* What extension should be used if file is downloaded?
*/
private final String extension;
private RdfResultMediaType(String contentType, boolean nativeFormat,
String serializationFormat, String jenaResponseFormat) {
String serializationFormat, String jenaResponseFormat, String extension) {
this.contentType = contentType;
this.nativeFormat = nativeFormat;
this.serializationFormat = serializationFormat;
this.jenaResponseFormat = jenaResponseFormat;
this.extension = extension;
}
public String getContentType() {
@ -103,4 +109,8 @@ public enum RdfResultMediaType {
return jenaResponseFormat;
}
public String getExtension() {
return extension;
}
}

View file

@ -12,15 +12,15 @@ import java.util.Map;
* SELECT and ASK).
*/
public enum ResultSetMediaType {
TEXT("text/plain", true, "TEXT", null),
TEXT("text/plain", true, "TEXT", null, "txt"),
CSV("text/csv", true, "CSV", null),
CSV("text/csv", true, "CSV", null, "csv"),
TSV("text/tab-separated-values", false, "CSV", "tsv"),
TSV("text/tab-separated-values", false, "CSV", "tsv", "tsv"),
XML("application/sparql-results+xml", true, "XML", null),
XML("application/sparql-results+xml", true, "XML", null, "xml"),
JSON("application/sparql-results+json", true, "JSON", null);
JSON("application/sparql-results+json", true, "JSON", null, "json");
// ----------------------------------------------------------------------
// Keep a map of content types, for easy conversion back and forth
@ -78,12 +78,18 @@ public enum ResultSetMediaType {
*/
private final String jenaResponseFormat;
/**
* What extension should be used if file is downloaded?
*/
private final String extension;
private ResultSetMediaType(String contentType, boolean nativeFormat,
String rdfServiceFormat, String jenaResponseFormat) {
String rdfServiceFormat, String jenaResponseFormat, String extension) {
this.contentType = contentType;
this.nativeFormat = nativeFormat;
this.rdfServiceFormat = rdfServiceFormat;
this.jenaResponseFormat = jenaResponseFormat;
this.extension = extension;
}
public String getContentType() {
@ -102,4 +108,8 @@ public enum ResultSetMediaType {
return jenaResponseFormat;
}
public String getExtension() {
return extension;
}
}

View file

@ -27,6 +27,11 @@
<label><input type='radio' name='rdfResultFormat' value='application/json'>JSON-LD</label>
</div>
<div class="options">
<input type="checkbox" id="download" name="download" value="true">
<label for="download"> Save results to file</label><br>
</div>
<input class="submit" type="submit" value="Run Query" />
</form>
</div><!-- content -->