com.tinkerpop.blueprints.oupls.sail.IndexingMatcher Maven / Gradle / Ivy
package com.tinkerpop.blueprints.oupls.sail;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import java.util.LinkedList;
import java.util.List;
/**
* A matcher which uses Blueprints indexing functionality to both index and retrieve statements. Indexing matchers
* can be created for any triple pattern.
*
* @author Joshua Shinavier (http://fortytwo.net)
*/
public class IndexingMatcher extends Matcher {
private enum PartOfSpeech {
SUBJECT, PREDICATE, OBJECT, CONTEXT
}
private final String propertyKey;
private final GraphSail.DataStore store;
/**
* Create a new indexing matcher based on the given triple pattern.
*
* @param s whether the subject is specified
* @param p whether the predicate is specified
* @param o whether the object is specified
* @param c whether the context is specified
* @param store the Blueprints data store
*/
public IndexingMatcher(final boolean s,
final boolean p,
final boolean o,
final boolean c,
final GraphSail.DataStore store) {
super(s, p, o, c);
this.store = store;
StringBuilder sb = new StringBuilder();
if (c) {
sb.append("c");
}
if (s) {
sb.append("s");
}
if (p) {
sb.append("p");
}
if (o) {
sb.append("o");
}
propertyKey = sb.toString();
}
private List addLazy(List list,
final T toAdd) {
list = null == list ? new LinkedList() : list;
list.add(toAdd);
return list;
}
private String appendToKey(final String key,
final String part) {
return null == key ? part : key + GraphSail.SEPARATOR + part;
}
public Iterable match(final Resource subject,
final URI predicate,
final Value object,
final Resource context,
final boolean includeInferred) {
List> criteria = null;
String key = null;
if (c) {
key = null == context ? GraphSail.NULL_CONTEXT_NATIVE : store.resourceToNative(context);
} else if (null != context) {
criteria = addLazy(criteria, new PartOfSpeechCriterion(PartOfSpeech.CONTEXT, store.resourceToNative(context)));
}
if (s) {
key = appendToKey(key, store.resourceToNative(subject));
} else if (null != subject) {
criteria = addLazy(criteria, new PartOfSpeechCriterion(PartOfSpeech.SUBJECT, store.resourceToNative(subject)));
}
if (p) {
key = appendToKey(key, store.uriToNative(predicate));
} else if (null != predicate) {
criteria = addLazy(criteria, new PartOfSpeechCriterion(PartOfSpeech.PREDICATE, store.uriToNative(predicate)));
}
if (o) {
key = appendToKey(key, store.valueToNative(object));
} else if (null != object) {
criteria = addLazy(criteria, new PartOfSpeechCriterion(PartOfSpeech.OBJECT, store.valueToNative(object)));
}
if (!includeInferred) {
criteria = addLazy(criteria, new NoInferenceCriterion());
}
Iterable results = store.graph.getEdges(propertyKey, key);
if (null != criteria) {
FilteredIterator.Criterion c = new FilteredIterator.CompoundCriterion(criteria);
results = new FilteredIterator(results, c);
}
return results;
}
/**
* Index a statement using this Matcher's triple pattern. The subject, predicate, object and context values
* are provided for efficiency only, and should agree with the corresponding values associated with the graph
* structure of the edge.
*
* @param statement the edge to index as an RDF statement
* @param subject the subject of the statement
* @param predicate the predicate of the statement
* @param object the object of the statement
* @param context the context of the statement
*/
public void indexStatement(final Edge statement, final Resource subject, final URI predicate, final Value object, final String context) {
StringBuilder sb = new StringBuilder();
if (c) {
sb.append(GraphSail.SEPARATOR).append(context);
}
if (s) {
sb.append(GraphSail.SEPARATOR).append(store.resourceToNative(subject));
}
if (p) {
sb.append(GraphSail.SEPARATOR).append(store.uriToNative(predicate));
}
if (o) {
sb.append(GraphSail.SEPARATOR).append(store.valueToNative(object));
}
statement.setProperty(propertyKey, sb.toString().substring(1));
}
// TODO: unindexStatement
private class PartOfSpeechCriterion implements FilteredIterator.Criterion {
private final PartOfSpeech partOfSpeech;
private final String value;
public PartOfSpeechCriterion(final PartOfSpeech partOfSpeech, final String value) {
this.partOfSpeech = partOfSpeech;
this.value = value;
}
public boolean fulfilledBy(final Edge edge) {
//GraphSail.debugEdge(edge);
//System.out.println("pos: " + partOfSpeech + ", value: " + value);
switch (partOfSpeech) {
case CONTEXT:
return value.equals(edge.getProperty(GraphSail.CONTEXT_PROP));
case OBJECT:
return value.equals(store.getValueOf(edge.getVertex(Direction.IN)));
case PREDICATE:
return value.equals(edge.getProperty(GraphSail.PREDICATE_PROP));
case SUBJECT:
return value.equals(store.getValueOf(edge.getVertex(Direction.OUT)));
default:
throw new IllegalStateException();
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy