Skip to content

Commit 5921bcb

Browse files
committed
GH-3510: Sparql Adapter System
1 parent dbade7d commit 5921bcb

74 files changed

Lines changed: 5308 additions & 1542 deletions

File tree

Some content is hidden

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

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: 12 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@
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;
3438
import org.apache.jena.sparql.exec.http.Params;
@@ -40,110 +44,14 @@
4044
import org.apache.jena.sys.JenaSystem;
4145
import org.apache.jena.update.Update;
4246
import org.apache.jena.update.UpdateException;
43-
import org.apache.jena.update.UpdateFactory;
4447
import org.apache.jena.update.UpdateRequest;
4548

4649
public abstract class ExecUpdateHTTPBuilder<X, Y> {
4750

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-
14351
static { JenaSystem.init(); }
14452

14553
protected String serviceURL;
146-
protected boolean parseCheck = true;
54+
protected Boolean parseCheck = null;
14755
private UpdateEltAcc updateEltAcc = new UpdateEltAcc();
14856

14957
protected Params params = Params.create();
@@ -176,7 +84,7 @@ public Y update(UpdateRequest updateRequest) {
17684

17785
public Y update(String updateRequestString) {
17886
Objects.requireNonNull(updateRequestString);
179-
if (parseCheck) {
87+
if (effectiveParseCheck()) {
18088
updateEltAcc.add(updateRequestString);
18189
} else {
18290
updateEltAcc.addString(updateRequestString);
@@ -208,6 +116,10 @@ public Y parseCheck(boolean parseCheck) {
208116
return thisBuilder();
209117
}
210118

119+
protected boolean effectiveParseCheck() {
120+
return ParseCheckUtils.effectiveParseCheck(parseCheck, contextAcc);
121+
}
122+
211123
public Y substitution(Binding binding) {
212124
binding.forEach(this.substitutionMap::put);
213125
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
@@ -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) ;

0 commit comments

Comments
 (0)