Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ public static String displayStr(Triple t) {
return displayStrNodes(t.getSubject(), t.getPredicate(), t.getObject());
}

public static String displayStr(Quad q) {
if ( q == null )
return nullStr;
return displayStrNodes(q.getGraph(), q.getSubject(), q.getPredicate(), q.getObject());
}

public static String displayStr(Node node) {
if ( node == null )
return nullStr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
public class StreamRDFWrapper implements StreamRDF
{
protected final StreamRDF other ;
public final StreamRDF get() { return other; }

public StreamRDFWrapper(StreamRDF other) { this.other = other ; }

@Override
public void start()
{ other.start() ; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,19 @@ public static StreamRDF getWriterStream(OutputStream output, RDFFormat format, C
if ( context == null )
context = RIOT.getContext().copy();
StreamRDF stream = x.create(output, format, context);
if ( ! RDFLanguages.isQuads(format.getLang()) )
stream = triplesOnly(stream);
return stream ;
}


/* What to do if a quad is seen when writing in a triples-only syntax. */
private static StreamRDF triplesOnly(StreamRDF stream) {
// StreamTriplesOnly converts default graph quads to triples.
// Otherwise, throw exception.
return StreamTriplesOnly.exceptionOnQuads(stream);
}

public static boolean registered(Lang lang) {
RDFFormat fmt = registry.defaultSerialization(lang) ;
return registry.contains(fmt) ;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

package org.apache.jena.riot.system;

import java.util.function.Function;

import org.apache.jena.riot.RiotException;
import org.apache.jena.riot.out.NodeFmtLib;
import org.apache.jena.sparql.core.Quad;

/**
Expand All @@ -27,27 +31,51 @@
*/
public class StreamTriplesOnly extends StreamRDFWrapper {

public static StreamRDF actionIfQuads(StreamRDF stream, Runnable action) {
public static enum QuadPolicy { CALL, IGNORE }

/** Exception on non-delfault graph quad */
private static Function<Quad, QuadPolicy> actionException = (q) -> {
throw new RiotException("Quad in Triple output: "+NodeFmtLib.str(q));
};

/** Replace an existing wrapper with a new policy for quads */
public static StreamRDF setActionIfQuads(StreamRDF stream, Function<Quad, QuadPolicy> action) {
// Strip existing layers.
while ( stream instanceof StreamTriplesOnly stream2 ) {
stream = stream2.get();
}
return addActionIfQuads(stream, action);
}

/** Add a new policy layer for quads */
public static StreamRDF addActionIfQuads(StreamRDF stream, Function<Quad, QuadPolicy> action) {
return new StreamTriplesOnly(stream, action);
}

private boolean seenQuads = false;
private final Runnable action;
/** Throw a {@link RiotException} if a non-default graph quad is seen. */
public static StreamRDF exceptionOnQuads(StreamRDF stream) {
return new StreamTriplesOnly(stream, actionException);
}

private QuadPolicy quadAction = QuadPolicy.CALL;
// The policy when seeing a quad that isn't in the default graph.
// Return true for "continue calling"
// Return false for "don't call again, ignore from now on"
private final Function<Quad, QuadPolicy> action;

private StreamTriplesOnly(StreamRDF sink, Runnable action) {
private StreamTriplesOnly(StreamRDF sink, Function<Quad, QuadPolicy> action) {
super(sink) ;
this.action = action;
}

@Override
public void quad(Quad quad) {
if ( quad.isTriple() || quad.isDefaultGraph() || quad.isUnionGraph() ) {
if ( quad.getGraph() == null || quad.isTriple() || quad.isDefaultGraph() ) {
triple(quad.asTriple()) ;
return;
}
if ( ! seenQuads ) {
action.run();
seenQuads = true;
if ( quadAction == QuadPolicy.CALL ) {
quadAction = action.apply(quad);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
* <p>
* For N-Quads and N-triples use {@link WriterStreamRDFPlain}.
*/

public abstract class WriterStreamRDFBase implements StreamRDF
{
// What did we do last?
Expand Down
13 changes: 7 additions & 6 deletions jena-cmds/src/main/java/riotcmd/CmdLangParse.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.zip.GZIPOutputStream;

import arq.cmdline.ModContext;
Expand Down Expand Up @@ -82,12 +83,12 @@ protected String getSummary() {
}

protected List<ParseRecord> outcomes = new ArrayList<>();

protected OutputStream outputWrite = System.out;
protected StreamRDF parserOutputStream = null;
protected String parserBaseIRI = null;
protected boolean passRelativeURIs = false;
protected String writerBaseIRI = null;

@Override
protected void processModulesAndArgs() {
cmdStrictMode = super.contains(argStrict);
Expand Down Expand Up @@ -202,18 +203,18 @@ protected void exec() {

if ( ! modLangParse.mergeQuads() && ! isQuadsOutput() ) {
// Only pass through triples.
final StreamRDF dest = parserOutputStream;
if ( isStreamingOutput() ) {
Runnable action = () -> {
Function<Quad, StreamTriplesOnly.QuadPolicy> action = (quad) -> {
// dest may be significantly buffered over the top of the output stream.
// The log message does not necessarily come out in the right place - it may be early.
// "Best effort" attempt to align log message to output.
IO.flush(outputWrite);
Log.warn(SysRIOT.getLogger(), "Quads in triples output - quads ignored.");
return StreamTriplesOnly.QuadPolicy.IGNORE;
};
parserOutputStream = StreamTriplesOnly.actionIfQuads(parserOutputStream, action);
} else {
// Not streaming - code can issue error before formatting.
parserOutputStream = StreamTriplesOnly.setActionIfQuads(parserOutputStream, action);
}
// If not streaming, leave to the writer,
}

// If QuadsToTriples is added here, then counts will be "triples only"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public Node makeNode(Object o) {

/**
* Make a node or path from the object using the query prefix mapping.
*
*
* @param o the object to make the node or path from.
* @return A node or path.
* @see Converters#makeNodeOrPath(Object, PrefixMapping)
Expand All @@ -108,7 +108,7 @@ private Object makeNodeOrPath(Object o) {
* <li>Will create a literal representation if the parseNode() fails or for any
* other object type.</li>
* </ul>
*
*
* @param o the object that should be interpreted as a path or a node.
* @param pMapping the prefix mapping to resolve path or node with
* @return the Path or Node
Expand Down Expand Up @@ -146,7 +146,7 @@ public ElementSubQuery asSubQuery() {
* @param p the predicate object
* @param o the object object.
* @return a TriplePath
* @deprecated Use {@link makeTriplePaths(Object, Object, Object)}
* @deprecated Use {@link #makeTriplePaths(Object, Object, Object)}
*/
@Deprecated(since="5.0.0")
public TriplePath makeTriplePath(Object s, Object p, Object o) {
Expand All @@ -156,7 +156,7 @@ public TriplePath makeTriplePath(Object s, Object p, Object o) {
}
return new TriplePath(Triple.create(makeNode(s), (Node) po, makeNode(o)));
}

/**
* Make a collecton triple path from the objects.
*
Expand All @@ -166,7 +166,7 @@ public TriplePath makeTriplePath(Object s, Object p, Object o) {
* <li>Will return the enclosed Node from a FrontsNode</li>
* <li>Will return the object if it is a Node.</li>
* <li>For {@code subject} and {@code object} <em>only</em>, if the object is a collection, will convert each item
* in the collection into a node and create an RDF list. All RDF list nodes are included in the collection.</li>
* in the collection into a node and create an RDF list. All RDF list nodes are included in the collection.</li>
* <li>If the object is a String
* <ul>
* <li>For <code>predicate</code> <em>only</em>, will attempt to parse as a path</li>
Expand Down Expand Up @@ -201,7 +201,7 @@ public Expr makeExpr(String expression) throws QueryParseException {

/**
* A convenience method to quote a string.
*
*
* @param q the string to quote.
*
* Will use single quotes if there are no single quotes in the string or if the
Expand All @@ -219,7 +219,7 @@ public static String quote(String q) {

/**
* Verify that any Node_Variable nodes are returned as Var nodes.
*
*
* @param n the node to check
* @return the node n or a new Var if n is an instance of Node_Variable
* @deprecated use {@link Converters#checkVar(Node)}
Expand All @@ -240,7 +240,7 @@ public static Node checkVar(Node n) {
* <li>Will create a literal representation if the parseNode() fails or for any
* other object type.</li>
* </ul>
*
*
* @param o The object to convert (may be null).
* @param pMapping The prefix mapping to use for prefix resolution.
* @return The Node value.
Expand Down Expand Up @@ -287,7 +287,7 @@ protected AbstractQueryBuilder() {

/**
* Get the HandlerBlock for this query builder.
*
*
* @return The associated handler block.
*/
public abstract HandlerBlock getHandlerBlock();
Expand All @@ -304,7 +304,7 @@ public ValuesHandler getValuesHandler() {

/**
* Gets the where handler used by this QueryBuilder.
*
*
* @return the where handler used by this QueryBuilder.
*/
public final WhereHandler getWhereHandler() {
Expand All @@ -313,7 +313,7 @@ public final WhereHandler getWhereHandler() {

/**
* Adds the contents of the whereClause to the where clause of this builder.
*
*
* @param whereClause the where clause to add.
* @return this builder for chaining.
*/
Expand Down Expand Up @@ -410,7 +410,7 @@ public T setBase(Object base) {

/**
* Creates a collection of nodes from an iterator of Objects.
*
*
* @param iter the iterator of objects, may be null or empty.
* @param prefixMapping the PrefixMapping to use when nodes are created.
* @return a Collection of nodes or null if iter is null or empty.
Expand All @@ -424,7 +424,7 @@ public static Collection<Node> makeValueNodes(Iterator<?> iter, PrefixMapping pr
/**
* Creates a collection of nodes from an iterator of Objects. Uses the prefix
* mapping from the PrologHandler.
*
*
* @param iter the iterator of objects, may be null or empty.
* @return a Collection of nodes or null if iter is null or empty.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ public void testBulkRequestsOverCachedEmptyResultSets() {
" SERVICE <loop:cache:bulk+5> { ?s rdfs:label ?l }",
"}");

Dataset ds = RDFParser.fromString(dataStr).lang(Lang.TURTLE).toDataset();
Dataset ds = RDFParser.fromString(dataStr, Lang.TURTLE).toDataset();
Query query = QueryFactory.create(queryStr);

int rsSize;
Expand Down