src/main/java/au/id/djc/rdftemplate/selector/Traversal.java (4083B) - raw
1 package au.id.djc.rdftemplate.selector; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.List; 7 8 import org.apache.commons.collections15.CollectionUtils; 9 10 import com.hp.hpl.jena.rdf.model.Property; 11 import com.hp.hpl.jena.rdf.model.RDFNode; 12 import com.hp.hpl.jena.rdf.model.ResIterator; 13 import com.hp.hpl.jena.rdf.model.Resource; 14 import com.hp.hpl.jena.rdf.model.StmtIterator; 15 import org.apache.commons.lang.builder.ToStringBuilder; 16 17 public class Traversal { 18 19 private String propertyNamespace; 20 private String propertyLocalName; 21 private boolean inverse = false; 22 private Predicate predicate; 23 private List<Comparator<RDFNode>> sortOrder = new ArrayList<Comparator<RDFNode>>(); 24 private Integer subscript; 25 26 private class SortComparator implements Comparator<RDFNode> { 27 @Override 28 public int compare(RDFNode left, RDFNode right) { 29 for (Comparator<RDFNode> comparator: sortOrder) { 30 int result = comparator.compare(left, right); 31 if (result != 0) 32 return result; 33 } 34 return 0; 35 } 36 } 37 38 public List<RDFNode> traverse(RDFNode node) { 39 if (!node.isResource()) { 40 throw new SelectorEvaluationException("Attempted to traverse non-resource node " + node); 41 } 42 Resource resource = (Resource) node; 43 Property property = resource.getModel().createProperty(propertyNamespace, propertyLocalName); 44 List<RDFNode> destinations = new ArrayList<RDFNode>(); 45 if (!inverse) { 46 for (StmtIterator it = resource.listProperties(property); it.hasNext(); ) { 47 destinations.add(it.nextStatement().getObject()); 48 } 49 } else { 50 for (ResIterator it = resource.getModel().listResourcesWithProperty(property, node); it.hasNext(); ) { 51 destinations.add(it.nextResource()); 52 } 53 } 54 CollectionUtils.filter(destinations, predicate); 55 if (!sortOrder.isEmpty()) 56 Collections.sort(destinations, new SortComparator()); 57 if (subscript != null) { 58 if (destinations.size() <= subscript) { 59 throw new SelectorEvaluationException("Cannot apply subscript " + subscript + " to nodes " + destinations); 60 } 61 destinations = Collections.singletonList(destinations.get(subscript)); 62 } 63 return destinations; 64 } 65 66 @Override 67 public String toString() { 68 return new ToStringBuilder(this) 69 .append("propertyNamespace", propertyNamespace) 70 .append("propertyLocalName", propertyLocalName) 71 .append("inverse", inverse) 72 .append("predicate", predicate) 73 .append("sortOrder", sortOrder) 74 .append("subscript", subscript) 75 .toString(); 76 } 77 78 public String getPropertyLocalName() { 79 return propertyLocalName; 80 } 81 82 public void setPropertyLocalName(String propertyLocalName) { 83 this.propertyLocalName = propertyLocalName; 84 } 85 86 public String getPropertyNamespace() { 87 return propertyNamespace; 88 } 89 90 public void setPropertyNamespace(String propertyNamespace) { 91 this.propertyNamespace = propertyNamespace; 92 } 93 94 public boolean isInverse() { 95 return inverse; 96 } 97 98 public void setInverse(boolean inverse) { 99 this.inverse = inverse; 100 } 101 102 public Predicate getPredicate() { 103 return predicate; 104 } 105 106 public void setPredicate(Predicate predicate) { 107 this.predicate = predicate; 108 } 109 110 public List<Comparator<RDFNode>> getSortOrder() { 111 return sortOrder; 112 } 113 114 public void addSortOrderComparator(Comparator<RDFNode> selector) { 115 this.sortOrder.add(selector); 116 } 117 118 public Integer getSubscript() { 119 return subscript; 120 } 121 122 public void setSubscript(Integer subscript) { 123 this.subscript = subscript; 124 } 125 126 }