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 }