Skip to content

Commit 1b4ae7a

Browse files
committed
GH-4055: Pass context into update operations
1 parent 11651c8 commit 1b4ae7a

23 files changed

Lines changed: 317 additions & 93 deletions

File tree

jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -610,12 +610,12 @@ else if ( uri != null )
610610
else
611611
parserBaseURI = null;
612612

613-
StreamManager sMgr = streamManager;
614-
if ( sMgr == null )
615-
sMgr = StreamManager.get(context);
613+
StreamManager streamMgr = streamManager;
614+
if ( streamMgr == null )
615+
streamMgr = StreamManager.get(context);
616616

617617
// Can't build the profile here as it is Lang/conneg dependent.
618-
return new RDFParser(uri, path, stringToParse, inputStream, javaReader, sMgr,
618+
return new RDFParser(uri, path, stringToParse, inputStream, javaReader, streamMgr,
619619
appAcceptHeader, httpHeaders,
620620
httpClient,
621621
hintLang, forceLang,

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ public static StreamManager get(Context context) {
9090
return get();
9191
}
9292

93+
/**
94+
* Set the {@code StreamManager} in the context.
95+
*/
96+
public static void set(Context context, StreamManager streamManager) {
97+
context.set(SysRIOT.sysStreamManager, streamManager);
98+
}
99+
93100
/**
94101
* Set the global {@code StreamManager}.
95102
*/

jena-arq/src/main/java/org/apache/jena/sparql/engine/QueryEngineBase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ private DatasetGraph prepareDataset(DatasetGraph originalDataset, Query query) {
7777
if ( ! query.hasDatasetDescription() )
7878
throw new QueryExecException("No dataset and no dataset description for query");
7979

80+
// dsg == null.
81+
// This is the only case where the code will process FROM/FROM NAMED by
82+
// reading resources. When dgs != null, FROM/FROM NAMED pick graphs from
83+
// the dataset and form a dynamic dataset.
84+
8085
// DatasetDescription : Build it.
8186
String baseURI = query.getBaseURI();
8287
if ( baseURI == null )

jena-arq/src/main/java/org/apache/jena/sparql/lang/UpdateParser.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,24 @@
3333
import org.apache.jena.sparql.modify.UpdateSink;
3434
import org.apache.jena.util.FileUtils;
3535

36-
/**
36+
/**
3737
* This class provides the root of lower level access to all the update parsers.
3838
* Each subclass hides the details of the per-language exception handlers and other
39-
* javacc details.
39+
* javacc details.
4040
*/
4141

4242
public abstract class UpdateParser
4343
{
4444
protected UpdateParser() {}
45-
46-
/** Parse a string */
45+
46+
/** Parse a string */
4747
public final void parse(UpdateSink sink, Prologue prologue, String updateString) throws QueryParseException {
4848
Reader r = new StringReader(updateString);
4949
executeParse(sink, prologue, r);
5050
}
5151

52-
/** Parse an input stream */
52+
/** Parse an input stream */
5353
public final void parse(UpdateSink sink, Prologue prologue, InputStream input) throws QueryParseException {
54-
// BOM processing moved to the grammar.
5554
Reader r = FileUtils.asBufferedUTF8(input);
5655
executeParse(sink, prologue, r);
5756
}
@@ -65,7 +64,7 @@ public void parse(UpdateSink sink, Prologue prologue, Reader r) {
6564

6665
// Subclass action.
6766
protected abstract void executeParse(UpdateSink sink, Prologue prologue, Reader r);
68-
67+
6968
public static boolean canParse(Syntax syntaxURI) {
7069
return UpdateParserRegistry.get().containsFactory(syntaxURI);
7170
}

jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateEngineWorker.java

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static org.apache.jena.sparql.modify.TemplateLib.remapDefaultGraph;
2525
import static org.apache.jena.sparql.modify.TemplateLib.template;
2626

27+
import java.io.InputStream;
2728
import java.util.ArrayList;
2829
import java.util.Collection;
2930
import java.util.Iterator;
@@ -44,6 +45,8 @@
4445
import org.apache.jena.query.Query;
4546
import org.apache.jena.riot.*;
4647
import org.apache.jena.riot.system.PrefixMap;
48+
import org.apache.jena.riot.system.StreamRDF;
49+
import org.apache.jena.riot.system.StreamRDFLib;
4750
import org.apache.jena.sparql.ARQInternalErrorException;
4851
import org.apache.jena.sparql.core.*;
4952
import org.apache.jena.sparql.engine.Timeouts;
@@ -142,7 +145,7 @@ protected void execDropClear(UpdateDropClear update, Node g, boolean isClear) {
142145
boolean auto = autoSilent && !isClear;
143146
executeOperation( auto || update.isSilent(), () -> {
144147
if ( g != null && !datasetGraph.containsGraph(g) )
145-
throw errorEx("No such graph: " + g);
148+
throw errorEx("No such graph: " + g);
146149
if ( isClear ) {
147150
if ( g == null || datasetGraph.containsGraph(g) )
148151
graphOrThrow(datasetGraph, g).clear();
@@ -190,6 +193,7 @@ public void visit(UpdateLoad update) {
190193
// LOAD SILENT? iri ( INTO GraphRef )?
191194
String source = update.getSource();
192195
Node dest = update.getDest();
196+
193197
executeOperation(update.isSilent(), ()->{
194198
Graph graph = graphOrThrow(datasetGraph, dest);
195199
// We must load buffered if silent so that the dataset graph sees
@@ -198,39 +202,30 @@ public void visit(UpdateLoad update) {
198202
try {
199203
boolean loadBuffered = update.isSilent() || ! datasetGraph.supportsTransactionAbort();
200204
if ( dest == null ) {
201-
// LOAD SILENT? iri
205+
// LOAD SILENT? iri -- no INTO
202206
// Quads accepted (extension).
203207
if ( loadBuffered ) {
204208
DatasetGraph dsg2 = DatasetGraphFactory.create();
205-
RDFDataMgr.read(dsg2, source);
209+
loadReadQuads(source, dsg2, context);
210+
// Parsing seceded.
206211
dsg2.find().forEachRemaining(datasetGraph::add);
207212
} else {
208-
RDFDataMgr.read(datasetGraph, source);
213+
// Transactional and not SILENT.
214+
loadReadQuads(source, datasetGraph, context);
209215
}
210216
return;
211217
}
212218
// LOAD SILENT? iri INTO GraphRef
213-
// Load triples. To give a decent error message and also not have the usual
214-
// parser behaviour of just selecting default graph triples when the
215-
// destination is a graph, we need to do the same steps as RDFParser.parseURI,
216-
// with different checking.
219+
// Load triples.
217220
TypedInputStream input = RDFDataMgr.open(source);
218-
String contentType = input.getContentType();
219-
Lang lang = RDFDataMgr.determineLang(source, contentType, Lang.TTL);
220-
if ( lang == null )
221-
throw new UpdateException("Failed to determine the syntax for '"+source+"'");
222-
if ( ! RDFLanguages.isTriples(lang) )
223-
throw new UpdateException("Attempt to load quads into a graph");
224-
RDFParser parser = RDFParser
225-
.source(input.getInputStream())
226-
.forceLang(lang)
227-
.build();
221+
Lang lang = determineLang(source, input);
222+
228223
if ( loadBuffered ) {
229224
Graph g = GraphFactory.createGraphMem();
230-
parser.parse(g);
225+
loadReadTriples(input, lang, g, context);
231226
GraphUtil.addInto(graph, g);
232227
} else {
233-
parser.parse(graph);
228+
loadReadTriples(input, lang, graph, context);
234229
}
235230
} catch (RiotException ex) {
236231
if ( !update.isSilent() ) {
@@ -240,6 +235,43 @@ public void visit(UpdateLoad update) {
240235
});
241236
}
242237

238+
// To give a decent error message, and also not have the usual
239+
// parser behaviour of just selecting default graph triples when
240+
// the destination is a graph, we need to do the same steps as
241+
// RDFParser.parseURI with different checking.
242+
private static Lang determineLang(String source, TypedInputStream input) {
243+
String contentType = input.getContentType();
244+
Lang lang = RDFDataMgr.determineLang(source, contentType, Lang.TTL);
245+
if ( lang == null )
246+
throw new UpdateException("Failed to determine the syntax for '"+source+"'");
247+
if ( ! RDFLanguages.isTriples(lang) )
248+
throw new UpdateException("Attempt to load quads into a graph");
249+
return lang;
250+
}
251+
252+
/** Load data into a dataset graph. The context has the stream manager. */
253+
private static void loadReadQuads(String source, DatasetGraph destination, Context context) {
254+
StreamRDF parserDest = StreamRDFLib.dataset(destination);
255+
// RDFParser picks up the stream manager from the context if not set.
256+
//StreamManager streamMgr = StreamManager.get(context);
257+
RDFParser.source(source)
258+
//.streamManager(streamMgr)
259+
.context(context)
260+
.parse(parserDest);
261+
}
262+
263+
/** Load data into a graph. The context has the stream manager. */
264+
private static void loadReadTriples(InputStream input, Lang lang, Graph destination, Context context) {
265+
StreamRDF parserDest = StreamRDFLib.graph(destination);
266+
// RDFParser picks up the stream manager from the context if not set.
267+
//StreamManager streamMgr = StreamManager.get(context);
268+
RDFParser.source(input)
269+
.forceLang(lang)
270+
//.streamManager(streamMgr)
271+
.context(context)
272+
.parse(parserDest);
273+
}
274+
243275
@Override
244276
public void visit(UpdateAdd update) {
245277
executeOperation(update.isSilent(), ()->{

jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateRequestSink.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,14 @@
2828
import org.apache.jena.update.Update ;
2929
import org.apache.jena.update.UpdateRequest ;
3030

31+
/**
32+
* Accumulate {@link Update Updates} (the individual update operations) in an
33+
* {@link UpdateRequest}.
34+
*/
3135
public class UpdateRequestSink implements UpdateSink
3236
{
3337
private final UpdateRequest updateRequest;
34-
38+
3539
public UpdateRequestSink(UpdateRequest updateRequest) {
3640
this.updateRequest = updateRequest;
3741
}
@@ -44,7 +48,7 @@ public void send(Update update) {
4448
@Override
4549
public void flush()
4650
{ }
47-
51+
4852
@Override
4953
public void close()
5054
{ }
@@ -53,15 +57,13 @@ public void close()
5357
public QuadDataAccSink createInsertDataSink() {
5458
QuadDataAcc quads = new QuadDataAcc();
5559
send(new UpdateDataInsert(quads));
56-
5760
return quads;
5861
}
5962

6063
@Override
6164
public QuadDataAccSink createDeleteDataSink() {
6265
QuadDataAcc quads = new QuadDataAcc();
6366
send(new UpdateDataDelete(quads));
64-
6567
return quads;
6668
}
6769
}

jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateVisitorSink.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@
2828
import org.apache.jena.update.Update ;
2929

3030
/**
31-
* UpdateSink that sends every Update to a worker except for the quads
32-
* of INSERT DATA, DELETE DATA which do to special sinks.
31+
* UpdateSink that sends every Update to a worker except for the quads
32+
* of INSERT DATA, DELETE DATA which go to special sinks.
3333
*/
3434
public class UpdateVisitorSink implements UpdateSink
3535
{
3636
private final UpdateVisitor worker;
3737
private final Sink<Quad> addSink;
3838
private final Sink<Quad> delSink;
39-
39+
4040
public UpdateVisitorSink(UpdateVisitor worker, Sink<Quad> addSink, Sink<Quad> delSink) {
4141
this.worker = worker;
4242
this.addSink = addSink;
@@ -47,7 +47,7 @@ public UpdateVisitorSink(UpdateVisitor worker, Sink<Quad> addSink, Sink<Quad> de
4747
public void send(Update update) {
4848
update.visit(worker);
4949
}
50-
50+
5151
// The sink for INSERT DATA, DELETE DATA to go straight to sink handlers.
5252
@Override
5353
public QuadDataAccSink createInsertDataSink() {

jena-arq/src/main/java/org/apache/jena/sparql/modify/UsingList.java

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,62 @@
2727
import java.util.List;
2828

2929
import org.apache.jena.graph.Node ;
30+
import org.apache.jena.sparql.modify.request.UpdateWithUsing;
31+
import org.apache.jena.update.Update;
32+
import org.apache.jena.update.UpdateException;
33+
import org.apache.jena.update.UpdateRequest;
3034

3135
public class UsingList
3236
{
3337
public UsingList() { }
34-
38+
3539
private List<Node> using = new ArrayList<>() ;
3640
private List<Node> usingNamed = new ArrayList<>() ;
37-
41+
3842
public void addUsing(Node node) { using.add(node) ; }
3943
public void addAllUsing(Collection<Node> nodes) { using.addAll(nodes); }
4044
public void addUsingNamed(Node node) { usingNamed.add(node) ; }
4145
public void addAllUsingNamed(Collection<Node> nodes) { usingNamed.addAll(nodes); }
42-
46+
4347
public List<Node> getUsing() { return Collections.unmodifiableList(using) ; }
4448
public List<Node> getUsingNamed() { return Collections.unmodifiableList(usingNamed) ; }
45-
49+
4650
public boolean usingIsPresent() { return using.size() > 0 || usingNamed.size() > 0 ; }
51+
52+
/**
53+
* This modifies the {@link Update Updates} of the {@link UpdateRequest}.
54+
* The using list may come from the protocol so this
55+
* operation converts a request+protocol into a
56+
* self-contained UpdateRequest.
57+
*/
58+
public static UpdateRequest modifyUpdateForUsingList(UpdateRequest updateRequest, UsingList usingList) {
59+
if ( usingList == null || ! usingList.usingIsPresent() )
60+
return updateRequest;
61+
UpdateRequest request = new UpdateRequest();
62+
updateRequest.forEach(update->{
63+
Update update2 = modifyUpdateForUsingList(update, usingList);
64+
request.add(update2);
65+
});
66+
return request;
67+
}
68+
69+
/**
70+
* This modifies the {@link Update}.
71+
* The using list may come from the protocol so this
72+
* operation converts a request+protocol into a
73+
* self-contained UpdateRequest.
74+
*/
75+
public static Update modifyUpdateForUsingList(Update update, UsingList usingList) {
76+
if ( usingList == null || ! usingList.usingIsPresent() )
77+
return update;
78+
if ( ! ( update instanceof UpdateWithUsing upu ) )
79+
return update;
80+
if ( upu.getUsing().size() != 0 || upu.getUsingNamed().size() != 0 || upu.getWithIRI() != null )
81+
throw new UpdateException("SPARQL Update: Protocol using-graph-uri or using-named-graph-uri present where update request has USING, USING NAMED or WITH");
82+
for ( Node node : usingList.getUsing() )
83+
upu.addUsing(node);
84+
for ( Node node : usingList.getUsingNamed() )
85+
upu.addUsingNamed(node);
86+
return update;
87+
}
4788
}

jena-arq/src/main/java/org/apache/jena/sparql/modify/UsingUpdateSink.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,8 @@
2121

2222
package org.apache.jena.sparql.modify;
2323

24-
import org.apache.jena.graph.Node ;
2524
import org.apache.jena.sparql.modify.request.QuadDataAccSink ;
26-
import org.apache.jena.sparql.modify.request.UpdateWithUsing ;
2725
import org.apache.jena.update.Update ;
28-
import org.apache.jena.update.UpdateException ;
2926

3027
/**
3128
* Adds using clauses from the UsingList to UpdateWithUsing operations; will throw an
@@ -44,17 +41,8 @@ public UsingUpdateSink(UpdateSink sink, UsingList usingList) {
4441
public void send(Update update) {
4542
// ---- check USING/USING NAMED/WITH not used.
4643
// ---- update request to have USING/USING NAMED
47-
if ( null != usingList && usingList.usingIsPresent() ) {
48-
if ( update instanceof UpdateWithUsing ) {
49-
UpdateWithUsing upu = (UpdateWithUsing)update;
50-
if ( upu.getUsing().size() != 0 || upu.getUsingNamed().size() != 0 || upu.getWithIRI() != null )
51-
throw new UpdateException("SPARQL Update: Protocol using-graph-uri or using-named-graph-uri present where update request has USING, USING NAMED or WITH");
52-
for ( Node node : usingList.getUsing() )
53-
upu.addUsing(node);
54-
for ( Node node : usingList.getUsingNamed() )
55-
upu.addUsingNamed(node);
56-
}
57-
}
44+
if ( null != usingList && usingList.usingIsPresent() )
45+
update = UsingList.modifyUpdateForUsingList(update, usingList);
5846
sink.send(update);
5947
}
6048

jena-arq/src/main/java/org/apache/jena/sparql/modify/request/UpdateLoad.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public class UpdateLoad extends Update
3535
private final Node dest;
3636
private boolean silent;
3737

38-
3938
public UpdateLoad(String source, String dest) {
4039
this(source, NodeFactory.createURI(dest), false);
4140
}

0 commit comments

Comments
 (0)