1

I would like to filter a Model, get all the triples which has a specific predicate and a subject of type C. The below code does not return any result, does any one has any idea how to implement it?

return triples.filter(null,  new URIImpl(property.getFullIRI()), null).filter
(null, RDF.TYPE,new URIImpl(C.getFullIRI()));
Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73
jd466
  • 547
  • 1
  • 6
  • 20

1 Answers1

1

The problem is that you are applying the second filter on the result of the first - but the result of the first filter only contains triples with the property on which you filtered - so the second filter can never return anything but an empty result (since no triple in the intermediate result will have the rdf:type predicate).

Since you are expressing a secondary constraint that is 'non-sequential' in this fashion, you can not solve this by just filtering alone. You will need to construct a new Model and fill with the data as you go along. Something along these lines:

 // always use a ValueFactory, avoid instantiating URIImpl directly.
 ValueFactory vf = ValueFactoryImpl().getInstance(); 
 URI c = vf.createURI(C.getFullIRI());
 URI prop = vf.createURI(property.getFullIRI())

 // create a new Model for the resulting triple collection
 Model result = new LinkedHashModel();

 // filter on the supplied property
 Model propMatches = triples.filter(null, prop, null);
 for(Resource subject: propMatches.subjects()) {

    // check if the selected subject is of the supplied type
    if (triples.contains(subject, RDF.TYPE, c)) {
          // add the type triple to the result
          result.add(subject, RDF.TYPE, c);

          // add the property triple(s) to the result 
          result.addAll(propMatches.filter(subject, null, null));
    }
 }
 return result;

The above works for Sesame 2. If you are using Sesame 4 (which supports Java 8 and its Stream API), you can do this more easily, like so:

return triples.stream().filter(st -> 
          {
              if (prop.equals(st.getPredicate()) {
                   // add this triple if its subject has the correct type
                   return triples.contains(st.getSubject(), RDF.TYPE, c));
              } else if (RDF.TYPE.equals(st.getPredicate()) 
                          && c.equals(st.getObject()) {
                   // add this triple if its subject has the correct prop
                   return triples.contains(st.getSubject(), prop, null);
              }
              return false;
          }).collect(Collectors.toCollection(LinkedHashModel::new));  
Jeen Broekstra
  • 21,642
  • 4
  • 51
  • 73