1 package eu.fbk.knowledgestore.server.http.jaxrs;
2
3 import java.util.List;
4 import java.util.Set;
5
6 import javax.ws.rs.Consumes;
7 import javax.ws.rs.FormParam;
8 import javax.ws.rs.GET;
9 import javax.ws.rs.HttpMethod;
10 import javax.ws.rs.POST;
11 import javax.ws.rs.Path;
12 import javax.ws.rs.Produces;
13 import javax.ws.rs.QueryParam;
14 import javax.ws.rs.core.GenericType;
15 import javax.ws.rs.core.Response;
16 import javax.ws.rs.core.Response.Status;
17
18 import com.google.common.collect.Sets;
19
20 import org.codehaus.enunciate.jaxrs.TypeHint;
21 import org.openrdf.model.URI;
22
23 import eu.fbk.knowledgestore.Operation;
24 import eu.fbk.knowledgestore.OperationException;
25 import eu.fbk.knowledgestore.Outcome;
26 import eu.fbk.knowledgestore.data.Data;
27 import eu.fbk.knowledgestore.data.Stream;
28 import eu.fbk.knowledgestore.internal.jaxrs.Protocol;
29 import eu.fbk.knowledgestore.internal.rdf.RDFUtil;
30
31
32
33
34
35
36
37 @Path("/" + Protocol.PATH_SPARQL)
38 public class Sparql extends Resource {
39
40 @GET
41 @Produces(Protocol.MIME_TYPES_ALL)
42 @TypeHint(Stream.class)
43 public Response get(
44 @QueryParam(Protocol.PARAMETER_DEFAULT_GRAPH) final List<String> defaultGraphs,
45 @QueryParam(Protocol.PARAMETER_NAMED_GRAPH) final List<String> namedGraphs,
46 @QueryParam(Protocol.PARAMETER_QUERY) final String query) throws OperationException {
47 return query(query, defaultGraphs, namedGraphs);
48 }
49
50 @POST
51 @Consumes("application/x-www-form-urlencoded")
52 @Produces(Protocol.MIME_TYPES_ALL)
53 @TypeHint(Stream.class)
54 public Response postURLencoded(
55 @FormParam(Protocol.PARAMETER_DEFAULT_GRAPH) final List<String> defaultGraphs,
56 @FormParam(Protocol.PARAMETER_NAMED_GRAPH) final List<String> namedGraphs,
57 @FormParam(Protocol.PARAMETER_QUERY) final String query) throws OperationException {
58 return query(query, defaultGraphs, namedGraphs);
59 }
60
61 @POST
62 @Consumes("application/sparql-query")
63 @Produces(Protocol.MIME_TYPES_ALL)
64 @TypeHint(Stream.class)
65 public Response postDirect(
66 @QueryParam(Protocol.PARAMETER_DEFAULT_GRAPH) final List<String> defaultGraphs,
67 @QueryParam(Protocol.PARAMETER_NAMED_GRAPH) final List<String> namedGraphs,
68 final String query) throws OperationException {
69 return query(query, defaultGraphs, namedGraphs);
70 }
71
72 private Response query(final String query, final List<String> defaultGraphs,
73 final List<String> namedGraphs) throws OperationException {
74
75
76 checkNotNull(query, Outcome.Status.ERROR_INVALID_INPUT, "Missing query");
77
78
79 final String form;
80 final Operation.Sparql operation;
81 try {
82 form = RDFUtil.detectSparqlForm(query);
83 operation = getSession().sparql(query)
84 .timeout(getTimeout())
85 .defaultGraphs(parseGraphURIs(defaultGraphs))
86 .namedGraphs(parseGraphURIs(namedGraphs));
87 } catch (final RuntimeException ex) {
88 throw new OperationException(newOutcome(Outcome.Status.ERROR_INVALID_INPUT, "%s",
89 ex.getMessage()), ex);
90 }
91
92
93 final GenericType<?> type;
94 if (form.equals("construct") || form.equals("describe")) {
95 init(false, Protocol.MIME_TYPES_RDF, null, null);
96 type = Protocol.STREAM_OF_STATEMENTS;
97 } else if (form.equals("select")) {
98 init(false, Protocol.MIME_TYPES_SPARQL_TUPLE, null, null);
99 type = Protocol.STREAM_OF_TUPLES;
100 } else {
101 init(false, Protocol.MIME_TYPES_SPARQL_BOOLEAN, null, null);
102 type = Protocol.STREAM_OF_BOOLEANS;
103 }
104
105
106
107 Stream<?> entity;
108 if (getMethod().equals(HttpMethod.HEAD)) {
109 entity = Stream.create();
110 } else if (type == Protocol.STREAM_OF_STATEMENTS) {
111 entity = operation.execTriples();
112 } else if (type == Protocol.STREAM_OF_TUPLES) {
113 entity = operation.execTuples();
114 } else if (type == Protocol.STREAM_OF_BOOLEANS) {
115 entity = Stream.create(operation.execBoolean());
116 } else {
117 throw new Error("Unexpected type: " + type);
118 }
119
120
121 return newResponseBuilder(Status.OK, closeOnCompletion(entity), type).build();
122 }
123
124 private static Set<URI> parseGraphURIs(final List<String> strings) {
125 if (strings == null || strings.isEmpty()) {
126 return null;
127 }
128 final Set<URI> uris = Sets.newHashSetWithExpectedSize(strings.size());
129 for (final String string : strings) {
130 uris.add(Data.getValueFactory().createURI(string));
131 }
132 return uris;
133 }
134
135 }