Skip to content

Commit 6964b4d

Browse files
committed
GH-3510: Sparql Adapter System
1 parent dbade7d commit 6964b4d

File tree

75 files changed

+5643
-1542
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+5643
-1542
lines changed

jena-arq/src/main/java/org/apache/jena/http/sys/ExecHTTPBuilder.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.jena.query.*;
3131
import org.apache.jena.riot.WebContent;
3232
import org.apache.jena.riot.web.HttpNames;
33+
import org.apache.jena.sparql.adapter.ParseCheckUtils;
3334
import org.apache.jena.sparql.core.Var;
3435
import org.apache.jena.sparql.engine.binding.Binding;
3536
import org.apache.jena.sparql.exec.http.Params;
@@ -49,16 +50,12 @@ public abstract class ExecHTTPBuilder<X, Y> {
4950
protected String serviceURL = null;
5051
private Query query = null;
5152
protected String queryString = null;
52-
protected boolean parseCheck = true;
53+
protected Boolean parseCheck = null;
5354
private HttpClient httpClient = null;
5455
protected Map<String, String> httpHeaders = new HashMap<>();
5556
protected Params params = Params.create();
5657
private ContextAccumulator contextAcc = ContextAccumulator.newBuilder(()->ARQ.getContext());
5758

58-
// Accept choice by the application. Deprecated - Superseded by acceptHeader(String) which sets all header fields explicitly.
59-
@Deprecated(forRemoval = true)
60-
protected String appAcceptHeader = null;
61-
6259
protected String selectAcceptHeader = WebContent.defaultSparqlResultsHeader;
6360
protected String askAcceptHeader = WebContent.defaultSparqlAskHeader;
6461
protected String graphAcceptHeader = WebContent.defaultGraphAcceptHeader;
@@ -91,6 +88,10 @@ public Y parseCheck(boolean parseCheck) {
9188
return thisBuilder();
9289
}
9390

91+
protected boolean effectiveParseCheck() {
92+
return ParseCheckUtils.effectiveParseCheck(parseCheck, contextAcc);
93+
}
94+
9495
/** Set the query - this also sets the query string to agree with the query argument. */
9596
public Y query(Query query) {
9697
Objects.requireNonNull(query);
@@ -105,14 +106,14 @@ public Y query(Query query) {
105106
*/
106107
public Y query(String queryStr) {
107108
Objects.requireNonNull(queryStr);
108-
Query query = parseCheck ? QueryFactory.create(queryStr) : null;
109+
Query query = effectiveParseCheck() ? QueryFactory.create(queryStr) : null;
109110
setQuery(query, queryStr);
110111
return thisBuilder();
111112
}
112113

113114
public Y query(String queryStr, Syntax syntax) {
114115
Objects.requireNonNull(queryStr);
115-
Query query = QueryFactory.create(queryStr, syntax);
116+
Query query = effectiveParseCheck() ? QueryFactory.create(queryStr, syntax) : null;
116117
setQuery(query, queryStr);
117118
return thisBuilder();
118119
}
@@ -266,10 +267,8 @@ public Y substitution(Var var, Node value) {
266267
}
267268

268269
/** Setting this header overrides any other header. */
269-
@SuppressWarnings("removal")
270270
public Y acceptHeader(String acceptHeader) {
271271
Objects.requireNonNull(acceptHeader);
272-
this.appAcceptHeader = acceptHeader;
273272
this.selectAcceptHeader = acceptHeader;
274273
this.askAcceptHeader = acceptHeader;
275274
this.graphAcceptHeader = acceptHeader;

jena-arq/src/main/java/org/apache/jena/http/sys/ExecUpdateHTTPBuilder.java

Lines changed: 13 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@
2222
package org.apache.jena.http.sys;
2323

2424
import java.net.http.HttpClient;
25-
import java.util.*;
25+
import java.util.ArrayList;
26+
import java.util.HashMap;
27+
import java.util.List;
28+
import java.util.Map;
29+
import java.util.Objects;
2630
import java.util.concurrent.TimeUnit;
27-
import java.util.stream.Collectors;
2831

2932
import org.apache.jena.graph.Node;
3033
import org.apache.jena.http.HttpEnv;
3134
import org.apache.jena.query.ARQ;
35+
import org.apache.jena.sparql.adapter.ParseCheckUtils;
3236
import org.apache.jena.sparql.core.Var;
3337
import org.apache.jena.sparql.engine.binding.Binding;
38+
import org.apache.jena.sparql.exec.UpdateEltAcc;
3439
import org.apache.jena.sparql.exec.http.Params;
3540
import org.apache.jena.sparql.exec.http.UpdateSendMode;
3641
import org.apache.jena.sparql.syntax.syntaxtransform.UpdateTransformOps;
@@ -40,110 +45,14 @@
4045
import org.apache.jena.sys.JenaSystem;
4146
import org.apache.jena.update.Update;
4247
import org.apache.jena.update.UpdateException;
43-
import org.apache.jena.update.UpdateFactory;
4448
import org.apache.jena.update.UpdateRequest;
4549

4650
public abstract class ExecUpdateHTTPBuilder<X, Y> {
4751

48-
/** Update element. Either an Update object or a string. */
49-
private record UpdateElt(Update update, String updateString) {
50-
UpdateElt(Update update) { this(Objects.requireNonNull(update), null); }
51-
UpdateElt(String updateString) { this(null, Objects.requireNonNull(updateString)); }
52-
boolean isParsed() { return update != null; }
53-
54-
@Override
55-
public String toString() {
56-
return isParsed()
57-
? new UpdateRequest(update()).toString() // Reuse UpdateRequest's serialization approach
58-
: updateString();
59-
}
60-
}
61-
62-
/** Accumulator for update elements. Can build an overall string or UpdateRequest from the elements. */
63-
private class UpdateEltAcc implements Iterable<UpdateElt> {
64-
/** Delimiter for joining multiple SPARQL update strings into a single one.
65-
* The delimiter takes into account that the last line of a statement may be a single-line-comment. */
66-
public static final String DELIMITER = "\n;\n";
67-
68-
private List<UpdateElt> updateOperations = new ArrayList<>();
69-
private List<UpdateElt> updateOperationsView = Collections.unmodifiableList(updateOperations);
70-
private boolean isParsed = true; // True iff there are no strings in updateOperations
71-
72-
public boolean isParsed() {
73-
return isParsed;
74-
}
75-
76-
public void add(UpdateElt updateElt) {
77-
isParsed = isParsed && updateElt.isParsed();
78-
updateOperations.add(updateElt);
79-
}
80-
81-
public void add(Update update) {
82-
add(new UpdateElt(update));
83-
}
84-
85-
/** Add a string by parsing it. */
86-
public void add(String updateRequestString) {
87-
UpdateRequest updateRequest = UpdateFactory.create(updateRequestString);
88-
add(updateRequest);
89-
}
90-
91-
public void add(UpdateRequest updateRequest) {
92-
updateRequest.getOperations().forEach(this::add);
93-
}
94-
95-
/** Add a string without parsing it. */
96-
public void addString(String updateRequestString) {
97-
add(new UpdateElt(updateRequestString));
98-
}
99-
100-
/** Attempt to build an UpdateRequest from the state of this accumulator. Attempts to parse any string elements. */
101-
public UpdateRequest buildUpdateRequest() {
102-
return addToUpdateRequest(new UpdateRequest());
103-
}
104-
105-
public UpdateRequest addToUpdateRequest(UpdateRequest updateRequest) {
106-
for (UpdateElt elt : updateOperations) {
107-
if (elt.isParsed()) {
108-
updateRequest.add(elt.update());
109-
} else {
110-
try {
111-
updateRequest.add(elt.updateString());
112-
} catch (Exception e) {
113-
// Expose the string that failed to parse
114-
e.addSuppressed(new RuntimeException("Failed to parse: " + elt.updateString()));
115-
throw e;
116-
}
117-
}
118-
}
119-
return updateRequest;
120-
}
121-
122-
public void clear() {
123-
updateOperations.clear();
124-
isParsed = true;
125-
}
126-
127-
public boolean isEmpty() {
128-
return updateOperations.isEmpty();
129-
}
130-
131-
@Override
132-
public Iterator<UpdateElt> iterator() {
133-
return updateOperationsView.iterator();
134-
}
135-
136-
public String buildString() {
137-
return updateOperations.stream()
138-
.map(UpdateElt::toString)
139-
.collect(Collectors.joining(DELIMITER));
140-
}
141-
}
142-
14352
static { JenaSystem.init(); }
14453

14554
protected String serviceURL;
146-
protected boolean parseCheck = true;
55+
protected Boolean parseCheck = null;
14756
private UpdateEltAcc updateEltAcc = new UpdateEltAcc();
14857

14958
protected Params params = Params.create();
@@ -176,7 +85,7 @@ public Y update(UpdateRequest updateRequest) {
17685

17786
public Y update(String updateRequestString) {
17887
Objects.requireNonNull(updateRequestString);
179-
if (parseCheck) {
88+
if (effectiveParseCheck()) {
18089
updateEltAcc.add(updateRequestString);
18190
} else {
18291
updateEltAcc.addString(updateRequestString);
@@ -208,6 +117,10 @@ public Y parseCheck(boolean parseCheck) {
208117
return thisBuilder();
209118
}
210119

120+
protected boolean effectiveParseCheck() {
121+
return ParseCheckUtils.effectiveParseCheck(parseCheck, contextAcc);
122+
}
123+
211124
public Y substitution(Binding binding) {
212125
binding.forEach(this.substitutionMap::put);
213126
return thisBuilder();

jena-arq/src/main/java/org/apache/jena/query/QueryExecutionDatasetBuilder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.jena.sparql.engine.binding.Binding;
3434
import org.apache.jena.sparql.engine.binding.BindingLib;
3535
import org.apache.jena.sparql.exec.QueryExecDatasetBuilder;
36+
import org.apache.jena.sparql.exec.QueryExecDatasetBuilderDeferred;
3637
import org.apache.jena.sparql.exec.QueryExecutionCompat;
3738
import org.apache.jena.sparql.util.Context;
3839
import org.apache.jena.sparql.util.Symbol;
@@ -49,7 +50,7 @@ public class QueryExecutionDatasetBuilder implements QueryExecutionBuilder {
4950
private Dataset dataset = null;
5051

5152
public QueryExecutionDatasetBuilder() {
52-
builder = QueryExecDatasetBuilder.create();
53+
builder = QueryExecDatasetBuilderDeferred.create();
5354
}
5455

5556
@Override

jena-arq/src/main/java/org/apache/jena/riot/system/StreamRDFOps.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public static void sendGraphToStream(Graph graph, StreamRDF stream, String baseU
107107
stream.base(baseURI);
108108
if ( prefixMap != null )
109109
sendPrefixesToStream(prefixMap, stream) ;
110+
sendGraphTriplesToStream(graph, stream);
111+
}
112+
113+
/** Send only the triples of graph to a StreamRDF */
114+
public static void sendGraphTriplesToStream(Graph graph, StreamRDF stream) {
110115
ExtendedIterator<Triple> iter = graph.find(null, null, null) ;
111116
try {
112117
StreamRDFOps.sendTriplesToStream(iter, stream) ;

jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,14 @@ public class ARQConstants
326326
public static final Symbol registryExtensions =
327327
SystemARQ.allocSymbol("registryExtensions") ;
328328

329-
public static void init() {}
329+
/** The registry of adapters that implement SPARQL operations
330+
* for different types of datasets. */
331+
public static final Symbol registrySparqlAdapters =
332+
SystemARQ.allocSymbol("registrySparqlAdapters") ;
333+
334+
/** Symbol for disabling parse checks of queries and updates when executing them against a dataset */
335+
public static final Symbol parseCheck =
336+
SystemARQ.allocSymbol("parseCheck") ;
330337

338+
public static void init() {}
331339
}

jena-arq/src/main/java/org/apache/jena/sparql/SystemARQ.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.apache.jena.reasoner.InfGraph ;
3232
import org.apache.jena.sparql.core.DatasetGraph ;
3333
import org.apache.jena.sparql.core.GraphView ;
34+
import org.apache.jena.sparql.exec.QueryExec ;
35+
import org.apache.jena.sparql.exec.UpdateExec ;
3436
import org.apache.jena.sparql.graph.GraphWrapper ;
3537
import org.apache.jena.sparql.util.Symbol ;
3638

@@ -68,6 +70,11 @@ public class SystemARQ
6870
*/
6971
public static boolean EnableCDTs = true ;
7072

73+
/**
74+
* Control for {@link QueryExec} and {@link UpdateExec} builders for {@link DatasetGraph} instances.
75+
*/
76+
public static boolean DeferredExecBuilders = true;
77+
7178
/**
7279
* Sync a Model if it provides the underlying graph provides sync . Do nothing
7380
* otherwise.

0 commit comments

Comments
 (0)