[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:
parent
42c69ef04b
commit
e198fce908
4 changed files with 65 additions and 16 deletions
|
@ -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.AcceptHeaderParsingException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException;
|
import edu.cornell.mannlib.vitro.webapp.utils.http.NotAcceptableException;
|
||||||
import edu.cornell.mannlib.vitro.webapp.utils.sparql.SparqlQueryUtils;
|
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.
|
* Present the SPARQL Query form, and execute the queries.
|
||||||
|
@ -110,11 +112,20 @@ public class SparqlQueryController extends FreemarkerHttpServlet {
|
||||||
.getRDFService();
|
.getRDFService();
|
||||||
|
|
||||||
String queryString = req.getParameter("query");
|
String queryString = req.getParameter("query");
|
||||||
|
boolean download = Boolean.parseBoolean(req.getParameter("download"));
|
||||||
|
Query query = SparqlQueryUtils.create(queryString);
|
||||||
try {
|
try {
|
||||||
String format = interpretRequestedFormats(req, queryString);
|
String format = interpretRequestedFormats(req, query);
|
||||||
SparqlQueryApiExecutor core = SparqlQueryApiExecutor.instance(
|
SparqlQueryApiExecutor core = SparqlQueryApiExecutor.instance(
|
||||||
rdfService, queryString, format);
|
rdfService, queryString, format);
|
||||||
resp.setContentType(core.getMediaType());
|
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());
|
core.executeAndFormat(resp.getOutputStream());
|
||||||
} catch (InvalidQueryTypeException e) {
|
} catch (InvalidQueryTypeException e) {
|
||||||
do400BadRequest("Query type is not SELECT, ASK, CONSTRUCT, "
|
do400BadRequest("Query type is not SELECT, ASK, CONSTRUCT, "
|
||||||
|
@ -132,8 +143,7 @@ public class SparqlQueryController extends FreemarkerHttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String interpretRequestedFormats(HttpServletRequest req,
|
private String interpretRequestedFormats(HttpServletRequest req,
|
||||||
String queryString) throws NotAcceptableException {
|
Query query) throws NotAcceptableException {
|
||||||
Query query = SparqlQueryUtils.create(queryString);
|
|
||||||
String parameterName = (query.isSelectType() || query.isAskType()) ? "resultFormat"
|
String parameterName = (query.isSelectType() || query.isAskType()) ? "resultFormat"
|
||||||
: "rdfResultFormat";
|
: "rdfResultFormat";
|
||||||
String parameterValue = req.getParameter(parameterName);
|
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)
|
private void do400BadRequest(String message, HttpServletResponse resp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
resp.setStatus(400);
|
resp.setStatus(400);
|
||||||
|
|
|
@ -12,17 +12,17 @@ import java.util.Map;
|
||||||
* and DESCRIBE).
|
* and DESCRIBE).
|
||||||
*/
|
*/
|
||||||
public enum RdfResultMediaType {
|
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
|
// Keep a map of content types, for easy conversion back and forth
|
||||||
|
@ -79,12 +79,18 @@ public enum RdfResultMediaType {
|
||||||
*/
|
*/
|
||||||
private final String jenaResponseFormat;
|
private final String jenaResponseFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What extension should be used if file is downloaded?
|
||||||
|
*/
|
||||||
|
private final String extension;
|
||||||
|
|
||||||
private RdfResultMediaType(String contentType, boolean nativeFormat,
|
private RdfResultMediaType(String contentType, boolean nativeFormat,
|
||||||
String serializationFormat, String jenaResponseFormat) {
|
String serializationFormat, String jenaResponseFormat, String extension) {
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
this.nativeFormat = nativeFormat;
|
this.nativeFormat = nativeFormat;
|
||||||
this.serializationFormat = serializationFormat;
|
this.serializationFormat = serializationFormat;
|
||||||
this.jenaResponseFormat = jenaResponseFormat;
|
this.jenaResponseFormat = jenaResponseFormat;
|
||||||
|
this.extension = extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
|
@ -103,4 +109,8 @@ public enum RdfResultMediaType {
|
||||||
return jenaResponseFormat;
|
return jenaResponseFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getExtension() {
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,15 +12,15 @@ import java.util.Map;
|
||||||
* SELECT and ASK).
|
* SELECT and ASK).
|
||||||
*/
|
*/
|
||||||
public enum ResultSetMediaType {
|
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
|
// Keep a map of content types, for easy conversion back and forth
|
||||||
|
@ -78,12 +78,18 @@ public enum ResultSetMediaType {
|
||||||
*/
|
*/
|
||||||
private final String jenaResponseFormat;
|
private final String jenaResponseFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What extension should be used if file is downloaded?
|
||||||
|
*/
|
||||||
|
private final String extension;
|
||||||
|
|
||||||
private ResultSetMediaType(String contentType, boolean nativeFormat,
|
private ResultSetMediaType(String contentType, boolean nativeFormat,
|
||||||
String rdfServiceFormat, String jenaResponseFormat) {
|
String rdfServiceFormat, String jenaResponseFormat, String extension) {
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
this.nativeFormat = nativeFormat;
|
this.nativeFormat = nativeFormat;
|
||||||
this.rdfServiceFormat = rdfServiceFormat;
|
this.rdfServiceFormat = rdfServiceFormat;
|
||||||
this.jenaResponseFormat = jenaResponseFormat;
|
this.jenaResponseFormat = jenaResponseFormat;
|
||||||
|
this.extension = extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
|
@ -102,4 +108,8 @@ public enum ResultSetMediaType {
|
||||||
return jenaResponseFormat;
|
return jenaResponseFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getExtension() {
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,11 @@
|
||||||
<label><input type='radio' name='rdfResultFormat' value='application/json'>JSON-LD</label>
|
<label><input type='radio' name='rdfResultFormat' value='application/json'>JSON-LD</label>
|
||||||
</div>
|
</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" />
|
<input class="submit" type="submit" value="Run Query" />
|
||||||
</form>
|
</form>
|
||||||
</div><!-- content -->
|
</div><!-- content -->
|
||||||
|
|
Loading…
Add table
Reference in a new issue