Probably the easiest way to do this is by means of a SPARQL query.
The query would be using a property path expression to express this path. Since you want to know if there exists a path for a given starting point and ending point, I assume a "yes" or "no" answer is good enough. So we can do a boolean ASK query:
ASK WHERE { :s (:p1|:p2|:p3)+ :o . }
This will return true
if a path of any length exists between :s
and :o
that consists of some combination of properties :p1
, :p2
, and :p3
.
Since you can't execute a SPARQL query directly on a Model
, you will need to create an in-memory Repository
and add your Model
to it before doing the query, like so:
Model model = ...; // your model
// create and initialize a temporary in-memory store
Repository rep = new SailRepository(new MemoryStore());
rep.initialize();
try (RepositoryConnection conn = rep.getConnection()) {
// load the model into the repository
conn.add(model);
// execute the query
String query = "ASK WHERE { :s (:p1|:p2|:p3)+ :o . }";
boolean pathExists = conn.prepareBooleanQuery(query).evaluate();
}
Alternatively, you can implement the path traversal yourself by means of a simple recursive method.
Model model = ...; // your model
IRI start = ... ; // your start point :s
IRI end = ...; // your end point :o .
IRI p1 = ...;
IRI p2 = ...;
IRI p3 = ... ;
boolean pathExists = pathExists(model, start, end, p1, p2, p3);
With the actual method being something like this:
boolean pathExists(Model m, IRI start, IRI end, IRI... properties) {
for(IRI p: properties) {
Model fromStart = m.filter(start, p, null);
if (fromStart.contains(start, p, end)) {
return true;
}
else {
for (Value obj: fromStart.objects()) {
if (obj instanceof Resource) {
if(pathExists(m, obj, end, properties)) {
return true;
}
}
}
}
}
return false;
}
...you may need to extend that a little bit (with a list of visited intermediate nodes to avoid infinite loops), but it illustrates the basic principle I hope. In any case, using a SPARQL query is far easier.