All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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