This is an automated email from the ASF dual-hosted git repository. andy pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/jena.git
commit e06fcf579609857e9a3c8f260950d4b50cacce4b Author: Andy Seaborne <[email protected]> AuthorDate: Sat Jul 13 19:10:03 2024 +0100 GraphUtils.getAsFilename --- .../jena/sparql/core/assembler/AssemblerUtils.java | 34 +++++++++ .../core/assembler/InMemDatasetAssembler.java | 31 +------- .../apache/jena/sparql/util/graph/GraphUtils.java | 82 +++++++++++++++++++--- .../src/main/java/tdb/cmdline/ModTDBDataset.java | 4 +- .../assembler/{VocabTDB.java => VocabTDB1.java} | 0 5 files changed, 112 insertions(+), 39 deletions(-) diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/AssemblerUtils.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/AssemblerUtils.java index c9eca6a850..7c4b2224c2 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/AssemblerUtils.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/AssemblerUtils.java @@ -22,6 +22,8 @@ import org.apache.jena.assembler.Assembler ; import org.apache.jena.assembler.ConstAssembler ; import org.apache.jena.assembler.JA ; import org.apache.jena.assembler.assemblers.AssemblerGroup ; +import org.apache.jena.graph.Node; +import org.apache.jena.graph.NodeFactory; import org.apache.jena.query.* ; import org.apache.jena.rdf.model.Model ; import org.apache.jena.rdf.model.ModelFactory ; @@ -30,12 +32,14 @@ import org.apache.jena.rdf.model.ResourceFactory ; import org.apache.jena.riot.RDFDataMgr ; import org.apache.jena.shared.PrefixMapping ; import org.apache.jena.sparql.ARQException ; +import org.apache.jena.sparql.core.DatasetGraph; import org.apache.jena.sparql.util.Context ; import org.apache.jena.sparql.util.MappingRegistry ; import org.apache.jena.sparql.util.Symbol ; import org.apache.jena.sparql.util.TypeNotUniqueException ; import org.apache.jena.sparql.util.graph.GraphUtils ; import org.apache.jena.sys.JenaSystem ; +import org.apache.jena.system.Txn; import org.apache.jena.vocabulary.RDFS ; import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.*; @@ -167,6 +171,36 @@ public class AssemblerUtils return context; } + /** + * Process {@code ja:data}. + * <p> + * The object value refers to a file, either by string name or a {@code file:} + * URI. If it is a string, a relative filename will be relative to the JVM + * current directory. If it is a {@code file:} URI, a relative filename will be + * relative to the assembler file and it's base URI. + */ + public static void loadData(DatasetGraph dataset, Resource root) { + Txn.executeWrite(dataset, ()->{ + // Load data into the default graph + // This also loads quads into the dataset. + GraphUtils.multiValueAsFilename(root, JA.data) + .forEach(filename -> RDFDataMgr.read(dataset, filename)); + + // load data into named graphs + GraphUtils.multiValueResource(root, DatasetAssemblerVocab.pNamedGraph).forEach(namedGraphResource -> { + final String graphName = GraphUtils.getAsStringValue(namedGraphResource, DatasetAssemblerVocab.pGraphName); + if (namedGraphResource.hasProperty(JA.data)) { + GraphUtils.multiValueAsFilename(namedGraphResource, JA.data) + .forEach(filename -> { + Node gn = NodeFactory.createURI(graphName); + RDFDataMgr.read(dataset.getGraph(gn), filename); + }); + } + }); + }); + } + + /** Look for and merge in context declarations. * e.g. * <pre> diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/InMemDatasetAssembler.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/InMemDatasetAssembler.java index 652903a6f7..21e80dc27f 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/InMemDatasetAssembler.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/assembler/InMemDatasetAssembler.java @@ -18,25 +18,16 @@ package org.apache.jena.sparql.core.assembler; -import static org.apache.jena.assembler.JA.data; -import static org.apache.jena.riot.RDFDataMgr.read; +import static org.apache.jena.sparql.core.assembler.AssemblerUtils.loadData; import static org.apache.jena.sparql.core.assembler.AssemblerUtils.mergeContext; -import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pGraphName; -import static org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab.pNamedGraph; -import static org.apache.jena.sparql.util.graph.GraphUtils.getAsStringValue; -import static org.apache.jena.sparql.util.graph.GraphUtils.multiValueAsString; -import static org.apache.jena.sparql.util.graph.GraphUtils.multiValueResource; import java.util.Map; import org.apache.jena.assembler.Assembler; -import org.apache.jena.graph.Node; -import org.apache.jena.graph.NodeFactory; import org.apache.jena.query.Dataset; import org.apache.jena.rdf.model.Resource; import org.apache.jena.sparql.core.DatasetGraph; import org.apache.jena.sparql.core.DatasetGraphFactory; -import org.apache.jena.system.Txn; import org.apache.jena.vocabulary.RDF; /** @@ -63,25 +54,9 @@ public class InMemDatasetAssembler extends NamedDatasetAssembler { if ( ! root.hasProperty( RDF.type, DatasetAssemblerVocab.tDatasetTxnMem ) ) checkType(root, DatasetAssemblerVocab.tMemoryDataset); final DatasetGraph dataset = DatasetGraphFactory.createTxnMem(); + // Load from JA.data + loadData(dataset, root); - Txn.executeWrite(dataset, ()->{ - // Load data into the default graph - // This also loads quads into the dataset. - multiValueAsString(root, data) - .forEach(dataURI -> read(dataset, dataURI)); - - // load data into named graphs - multiValueResource(root, pNamedGraph).forEach(namedGraphResource -> { - final String graphName = getAsStringValue(namedGraphResource, pGraphName); - if (namedGraphResource.hasProperty(data)) { - multiValueAsString(namedGraphResource, data) - .forEach(namedGraphData -> { - Node gn = NodeFactory.createURI(graphName); - read(dataset.getGraph(gn), namedGraphData); - }); - } - }); - }); mergeContext(root, dataset.getContext()); return dataset; } diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphUtils.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphUtils.java index d73cb4e90c..813abe424b 100644 --- a/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphUtils.java +++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/graph/GraphUtils.java @@ -18,14 +18,21 @@ package org.apache.jena.sparql.util.graph; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import org.apache.jena.atlas.iterator.Iter; +import org.apache.jena.atlas.lib.IRILib; import org.apache.jena.atlas.lib.ListUtils; import org.apache.jena.graph.Graph; import org.apache.jena.graph.Node; import org.apache.jena.graph.Triple; -import org.apache.jena.query.*; +import org.apache.jena.irix.IRIs; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.QuerySolutionMap; import org.apache.jena.rdf.model.*; import org.apache.jena.shared.PropertyNotFoundException; import org.apache.jena.sparql.util.NotUniqueException; @@ -40,8 +47,6 @@ import org.apache.jena.vocabulary.RDF; public class GraphUtils { - // Only used by DatasetDescriptionAssembler - // (and DatasetDescriptionAssembler itself is unused) /** * Get all the literals for a resource-property. */ @@ -57,8 +62,9 @@ public class GraphUtils { return values; } - /** Get a list of the URIs (as strings) and strings - * @see #getAsStringValue + /** + * Get a list of the URIs (as strings) and strings + * @see #getAsStringValue */ public static List<String> multiValueAsString(Resource r, Property p) { List<RDFNode> nodes = multiValue(r, p); @@ -68,13 +74,36 @@ public class GraphUtils { if ( n.isLiteral() ) { values.add(((Literal)n).getString()); } - if ( n.isURIResource() ) { + else if ( n.isURIResource() ) { values.add(((Resource)n).getURI()); } } return values; } + /** + * Get a list of the string and URIs treating each as a filenames, + * that is strings and file: URIs converted to filenames. + * @see #getAsFilename + */ + public static List<String> multiValueAsFilename(Resource r, Property p) { + List<RDFNode> nodes = multiValue(r, p); + List<String> values = new ArrayList<>(); + + for ( RDFNode n : nodes ) { + if ( n.isLiteral() ) { + values.add(((Literal)n).getString()); + } + else if ( n.isURIResource() ) { + Resource x = n.asResource(); + String fn = asFilename(x); + if ( fn != null ) + values.add(fn); + } + } + return values; + } + public static List<RDFNode> multiValue(Resource r, Property p) { List<RDFNode> values = new ArrayList<>(); StmtIterator sIter = r.listProperties(p); @@ -161,13 +190,49 @@ public class GraphUtils { RDFNode obj = getAsRDFNode(r, p); if ( obj == null ) return null; - if ( obj.isResource() ) + if ( obj.isURIResource() ) return obj.asResource().getURI(); if ( obj.isLiteral() ) return obj.asLiteral().getString(); throw new UnsupportedOperationException("Not a URI or a string"); } + /** + * Get a string for a filename, + * either a string (filename as-=is) or a "file:" URI, translated to a filename. + * Otherwise throw an exception. + */ + public static String getAsFilename(Resource r, Property p) { + RDFNode obj = getAsRDFNode(r, p); + if ( obj == null ) + return null; + if ( obj.isURIResource() ) { + Resource x = obj.asResource(); + String fn = asFilename(x); + if ( fn == null ) + throw new UnsupportedOperationException("Not a file: URI"); + return fn; + } + if ( obj.isLiteral() ) + return obj.asLiteral().getString(); + throw new UnsupportedOperationException("Not a file: URI or a string"); + } + + /** + * Return a filename from a file: URI. + * If it is not a file: URI, return null. + */ + private static String asFilename(Resource r) { + String uri = r.getURI(); + if ( uri == null ) + return null; + String scheme = IRIs.scheme(uri); + if ( ! scheme.equalsIgnoreCase("file") ) + return null; + String fn = IRILib.IRIToFilename(uri); + return fn; + } + public static RDFNode getAsRDFNode(Resource r, Property p) { if ( !atmostOneProperty(r, p) ) throw new NotUniqueException(r, p); @@ -225,7 +290,6 @@ public class GraphUtils { try(QueryExecution qExec = QueryExecution.model(model).query(q).initialBinding(qsm).build() ) { return ListUtils.toList( QueryExecUtils.getAll(qExec, "root").stream().map(r->(Resource)r)); - } } diff --git a/jena-cmds/src/main/java/tdb/cmdline/ModTDBDataset.java b/jena-cmds/src/main/java/tdb/cmdline/ModTDBDataset.java index a04fd11173..d08eb337be 100644 --- a/jena-cmds/src/main/java/tdb/cmdline/ModTDBDataset.java +++ b/jena-cmds/src/main/java/tdb/cmdline/ModTDBDataset.java @@ -34,7 +34,7 @@ import org.apache.jena.shared.JenaException; import org.apache.jena.sparql.core.assembler.AssemblerUtils; import org.apache.jena.sparql.core.assembler.DatasetAssemblerVocab; import org.apache.jena.tdb1.TDB1Factory; -import org.apache.jena.tdb1.assembler.VocabTDB; +import org.apache.jena.tdb1.assembler.VocabTDB1; import org.apache.jena.tdb1.base.file.Location; import org.apache.jena.tdb1.transaction.DatasetGraphTransaction; @@ -73,7 +73,7 @@ public class ModTDBDataset extends ModDataset { Dataset thing = null; // Two variants: plain dataset with a TDB graph or a TDB dataset. try { - thing = (Dataset)AssemblerUtils.build(modAssembler.getAssemblerFile(), VocabTDB.tDatasetTDB); + thing = (Dataset)AssemblerUtils.build(modAssembler.getAssemblerFile(), VocabTDB1.tDatasetTDB); if ( thing != null && !(thing.asDatasetGraph() instanceof DatasetGraphTransaction) ) Log.warn(this, "Unexpected: Not a TDB dataset for type DatasetTDB"); diff --git a/jena-tdb1/src/main/java/org/apache/jena/tdb1/assembler/VocabTDB.java b/jena-tdb1/src/main/java/org/apache/jena/tdb1/assembler/VocabTDB1.java similarity index 100% rename from jena-tdb1/src/main/java/org/apache/jena/tdb1/assembler/VocabTDB.java rename to jena-tdb1/src/main/java/org/apache/jena/tdb1/assembler/VocabTDB1.java
