Skip to content

Commit 53ff0ac

Browse files
committed
GH-3510: Sparql Adapter System
1 parent 08a53e1 commit 53ff0ac

File tree

76 files changed

+5360
-1549
lines changed

Some content is hidden

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

76 files changed

+5360
-1549
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.jena.query.*;
2828
import org.apache.jena.riot.WebContent;
2929
import org.apache.jena.riot.web.HttpNames;
30+
import org.apache.jena.sparql.adapter.ParseCheckUtils;
3031
import org.apache.jena.sparql.core.Var;
3132
import org.apache.jena.sparql.engine.binding.Binding;
3233
import org.apache.jena.sparql.exec.http.Params;
@@ -46,7 +47,7 @@ public abstract class ExecHTTPBuilder<X, Y> {
4647
protected String serviceURL = null;
4748
private Query query = null;
4849
protected String queryString = null;
49-
protected boolean parseCheck = true;
50+
protected Boolean parseCheck = null;
5051
private HttpClient httpClient = null;
5152
protected Map<String, String> httpHeaders = new HashMap<>();
5253
protected Params params = Params.create();
@@ -88,6 +89,10 @@ public Y parseCheck(boolean parseCheck) {
8889
return thisBuilder();
8990
}
9091

92+
protected boolean effectiveParseCheck() {
93+
return ParseCheckUtils.effectiveParseCheck(parseCheck, contextAcc);
94+
}
95+
9196
/** Set the query - this also sets the query string to agree with the query argument. */
9297
public Y query(Query query) {
9398
Objects.requireNonNull(query);
@@ -102,14 +107,14 @@ public Y query(Query query) {
102107
*/
103108
public Y query(String queryStr) {
104109
Objects.requireNonNull(queryStr);
105-
Query query = parseCheck ? QueryFactory.create(queryStr) : null;
110+
Query query = effectiveParseCheck() ? QueryFactory.create(queryStr) : null;
106111
setQuery(query, queryStr);
107112
return thisBuilder();
108113
}
109114

110115
public Y query(String queryStr, Syntax syntax) {
111116
Objects.requireNonNull(queryStr);
112-
Query query = QueryFactory.create(queryStr, syntax);
117+
Query query = effectiveParseCheck() ? QueryFactory.create(queryStr, syntax) : null;
113118
setQuery(query, queryStr);
114119
return thisBuilder();
115120
}

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
@@ -19,13 +19,18 @@
1919
package org.apache.jena.http.sys;
2020

2121
import java.net.http.HttpClient;
22-
import java.util.*;
22+
import java.util.ArrayList;
23+
import java.util.HashMap;
24+
import java.util.List;
25+
import java.util.Map;
26+
import java.util.Objects;
27+
import java.util.Optional;
2328
import java.util.concurrent.TimeUnit;
24-
import java.util.stream.Collectors;
2529

2630
import org.apache.jena.graph.Node;
2731
import org.apache.jena.http.HttpEnv;
2832
import org.apache.jena.query.ARQ;
33+
import org.apache.jena.sparql.adapter.ParseCheckUtils;
2934
import org.apache.jena.sparql.core.Var;
3035
import org.apache.jena.sparql.engine.binding.Binding;
3136
import org.apache.jena.sparql.exec.http.Params;
@@ -37,110 +42,14 @@
3742
import org.apache.jena.sys.JenaSystem;
3843
import org.apache.jena.update.Update;
3944
import org.apache.jena.update.UpdateException;
40-
import org.apache.jena.update.UpdateFactory;
4145
import org.apache.jena.update.UpdateRequest;
4246

4347
public abstract class ExecUpdateHTTPBuilder<X, Y> {
4448

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

14251
protected String serviceURL;
143-
protected boolean parseCheck = true;
52+
protected Boolean parseCheck = null;
14453
private UpdateEltAcc updateEltAcc = new UpdateEltAcc();
14554

14655
protected Params params = Params.create();
@@ -173,7 +82,7 @@ public Y update(UpdateRequest updateRequest) {
17382

17483
public Y update(String updateRequestString) {
17584
Objects.requireNonNull(updateRequestString);
176-
if (parseCheck) {
85+
if (effectiveParseCheck()) {
17786
updateEltAcc.add(updateRequestString);
17887
} else {
17988
updateEltAcc.addString(updateRequestString);
@@ -205,6 +114,10 @@ public Y parseCheck(boolean parseCheck) {
205114
return thisBuilder();
206115
}
207116

117+
protected boolean effectiveParseCheck() {
118+
return ParseCheckUtils.effectiveParseCheck(parseCheck, contextAcc);
119+
}
120+
208121
public Y substitution(Binding binding) {
209122
binding.forEach(this.substitutionMap::put);
210123
return thisBuilder();
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.jena.http.sys;
20+
21+
import java.util.Objects;
22+
23+
import org.apache.jena.update.Update;
24+
import org.apache.jena.update.UpdateRequest;
25+
26+
/** Update element. Either an Update object or a string. */
27+
public record UpdateElt(Update update, String updateString) {
28+
UpdateElt(Update update) { this(Objects.requireNonNull(update), null); }
29+
UpdateElt(String updateString) { this(null, Objects.requireNonNull(updateString)); }
30+
public boolean isParsed() { return update != null; }
31+
32+
@Override
33+
public String toString() {
34+
return isParsed()
35+
? new UpdateRequest(update()).toString() // Reuse UpdateRequest's serialization approach
36+
: updateString();
37+
}
38+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.jena.http.sys;
20+
21+
import java.util.ArrayList;
22+
import java.util.Collections;
23+
import java.util.Iterator;
24+
import java.util.List;
25+
import java.util.stream.Collectors;
26+
27+
import org.apache.jena.update.Update;
28+
import org.apache.jena.update.UpdateFactory;
29+
import org.apache.jena.update.UpdateRequest;
30+
31+
/** Accumulator for update elements. Can build an overall string or UpdateRequest from the elements. */
32+
public class UpdateEltAcc implements Iterable<UpdateElt> {
33+
/** Delimiter for joining multiple SPARQL update strings into a single one.
34+
* The delimiter takes into account that the last line of a statement may be a single-line-comment. */
35+
public static final String DELIMITER = "\n;\n";
36+
37+
private List<UpdateElt> updateOperations = new ArrayList<>();
38+
private List<UpdateElt> updateOperationsView = Collections.unmodifiableList(updateOperations);
39+
private boolean isParsed = true; // True iff there are no strings in updateOperations
40+
41+
public boolean isParsed() {
42+
return isParsed;
43+
}
44+
45+
public void add(UpdateElt updateElt) {
46+
isParsed = isParsed && updateElt.isParsed();
47+
updateOperations.add(updateElt);
48+
}
49+
50+
public void add(Update update) {
51+
add(new UpdateElt(update));
52+
}
53+
54+
/** Add a string by parsing it. */
55+
public void add(String updateRequestString) {
56+
UpdateRequest updateRequest = UpdateFactory.create(updateRequestString);
57+
add(updateRequest);
58+
}
59+
60+
public void add(UpdateRequest updateRequest) {
61+
updateRequest.getOperations().forEach(this::add);
62+
}
63+
64+
/** Add a string without parsing it. */
65+
public void addString(String updateRequestString) {
66+
add(new UpdateElt(updateRequestString));
67+
}
68+
69+
/** Attempt to build an UpdateRequest from the state of this accumulator. Attempts to parse any string elements. */
70+
public UpdateRequest buildUpdateRequest() {
71+
return addToUpdateRequest(new UpdateRequest());
72+
}
73+
74+
public UpdateRequest addToUpdateRequest(UpdateRequest updateRequest) {
75+
for (UpdateElt elt : updateOperations) {
76+
if (elt.isParsed()) {
77+
updateRequest.add(elt.update());
78+
} else {
79+
try {
80+
updateRequest.add(elt.updateString());
81+
} catch (Exception e) {
82+
// Expose the string that failed to parse
83+
e.addSuppressed(new RuntimeException("Failed to parse: " + elt.updateString()));
84+
throw e;
85+
}
86+
}
87+
}
88+
return updateRequest;
89+
}
90+
91+
public void clear() {
92+
updateOperations.clear();
93+
isParsed = true;
94+
}
95+
96+
public boolean isEmpty() {
97+
return updateOperations.isEmpty();
98+
}
99+
100+
@Override
101+
public Iterator<UpdateElt> iterator() {
102+
return updateOperationsView.iterator();
103+
}
104+
105+
public String buildString() {
106+
return updateOperations.stream()
107+
.map(UpdateElt::toString)
108+
.collect(Collectors.joining(DELIMITER));
109+
}
110+
}

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
@@ -30,6 +30,7 @@
3030
import org.apache.jena.sparql.engine.binding.Binding;
3131
import org.apache.jena.sparql.engine.binding.BindingLib;
3232
import org.apache.jena.sparql.exec.QueryExecDatasetBuilder;
33+
import org.apache.jena.sparql.exec.QueryExecDatasetBuilderDeferred;
3334
import org.apache.jena.sparql.exec.QueryExecutionCompat;
3435
import org.apache.jena.sparql.util.Context;
3536
import org.apache.jena.sparql.util.Symbol;
@@ -46,7 +47,7 @@ public class QueryExecutionDatasetBuilder implements QueryExecutionBuilder {
4647
private Dataset dataset = null;
4748

4849
public QueryExecutionDatasetBuilder() {
49-
builder = QueryExecDatasetBuilder.create();
50+
builder = QueryExecDatasetBuilderDeferred.create();
5051
}
5152

5253
@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
@@ -104,6 +104,11 @@ public static void sendGraphToStream(Graph graph, StreamRDF stream, String baseU
104104
stream.base(baseURI);
105105
if ( prefixMap != null )
106106
sendPrefixesToStream(prefixMap, stream) ;
107+
sendGraphTriplesToStream(graph, stream);
108+
}
109+
110+
/** Send only the triples of graph to a StreamRDF */
111+
public static void sendGraphTriplesToStream(Graph graph, StreamRDF stream) {
107112
ExtendedIterator<Triple> iter = graph.find(null, null, null) ;
108113
try {
109114
StreamRDFOps.sendTriplesToStream(iter, stream) ;

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,12 @@ public class ARQConstants
317317
public static final Symbol registryExtensions =
318318
SystemARQ.allocSymbol("registryExtensions") ;
319319

320-
public static void init() {}
320+
public static final Symbol registrySparqlDispatchers =
321+
SystemARQ.allocSymbol("registrySparqlDispatchers") ;
322+
323+
/** Symbol for disabling parse checks of queries and updates when executing them against a dataset */
324+
public static final Symbol parseCheck =
325+
SystemARQ.allocSymbol("parseCheck") ;
321326

327+
public static void init() {}
322328
}

0 commit comments

Comments
 (0)