Dear list,
I want to replace all the RDF lists in a model which have contents equal
to given input RDF list 'old' with a copies of an RDF list 'fresh'.
Following the advise in
https://jena.apache.org/documentation/javadoc/jena/org/apache/jena/rdf/model/RDFList.html#removeList--,
I remove all lists equal to 'old' and update old's heads to new copies
of fresh.
However, running the code has two results, either it fails with the
exception:
Exception in thread "main"
org.apache.jena.shared.PropertyNotFoundException:
http://www.w3.org/1999/02/22-rdf-syntax-ns#first
at
org.apache.jena.rdf.model.impl.ModelCom.getRequiredProperty(ModelCom.java:1231)
at
org.apache.jena.rdf.model.impl.ResourceImpl.getRequiredProperty(ResourceImpl.java:172)
at
org.apache.jena.rdf.model.impl.RDFListImpl.sameListAs(RDFListImpl.java:876)
at ListTest.substituteNonEmptyRDFList(ListTest.java:39)
at ListTest.main(ListTest.java:65)
or it outputs a model where the replaced list seems OK, but does not
seem to be recognized as a proper RDF list (due to the lack of terse
list formatting):
@prefix ex: <http://example.com#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
ex:fresh1 ex:hasList ( ex:B1 ex:B2 ) .
ex:old1 ex:hasList [ a rdf:List ;
rdf:first ex:B1 ;
rdf:rest [ a rdf:List ;
rdf:first ex:B2 ;
rdf:rest ()
]
] .
Running code example and input data attached.
Grateful for all help.
Regards,
Martin G. Skjæveland
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.RDFList;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.ResourceFactory;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.util.FileManager;
import org.apache.jena.vocabulary.RDF;
public class ListTest {
private static Model readModel (String file, String serialisation) {
return FileManager.get().loadModel(file, serialisation);
}
// collect all non-empty lists
public static Set<RDFList> getNonEmptyRDFLists (Model model) {
Set<RDFList> lists = new HashSet<>();
for (Resource head : model.listSubjectsWithProperty(RDF.first).toSet()) {
if (!model.listResourcesWithProperty(RDF.rest, head).hasNext() && // make sure that we are at the first element
head.canAs(RDFList.class)) {
lists.add(head.as(RDFList.class));
}
}
return lists;
}
public static void substituteNonEmptyRDFList (Model model, RDFList old, RDFList fresh) {
// Remove all old lists:
List<RDFNode> oldHeads = new ArrayList<>();
Set<RDFList> lists = getNonEmptyRDFLists(model);
for (RDFList l : lists) {
if (l.sameListAs(old)){
l.removeList();
oldHeads.add(l);
}
}
// replace pointers to old lists to new copies of fresh lists:
for (RDFNode n : oldHeads) {
RDFList freshCopy = fresh.copy();
for (Statement s: model.listStatements(null, null, n).toList()) {
s.changeObject(freshCopy);
}
}
}
public static void main (String[] args) {
// read model
String file = "src/test/resource/rdf/lists2.ttl";
Model model = ListTest.readModel(file, "turtle");
// get list to replace: old and fresh
String ex = "http://example.com#";
RDFList old1 = model.listObjectsOfProperty(ResourceFactory.createResource(ex + "old1"), ResourceFactory.createProperty(ex + "hasList")).next().as(RDFList.class);
RDFList fresh1 = model.listObjectsOfProperty(ResourceFactory.createResource(ex + "fresh1"), ResourceFactory.createProperty(ex + "hasList")).next().as(RDFList.class);
ListTest.substituteNonEmptyRDFList(model, old1, fresh1);
model.write(System.out, "turtle");
}
}
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ex: <http://example.com#> .
ex:old1 ex:hasList (ex:A1 ex:A2 ex:A3) .
ex:fresh1 ex:hasList (ex:B1 ex:B2) .