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

net.fortytwo.sesametools.RepositoryGraph Maven / Gradle / Ivy

The newest version!
package net.fortytwo.sesametools;

import info.aduna.iteration.CloseableIteration;
import org.openrdf.model.IRI;
import org.openrdf.model.Model;
import org.openrdf.model.Namespace;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;

/**
 * An adapter which wraps a RepositoryConnection as a Graph
 *
 * @author Joshua Shinavier (http://fortytwo.net)
 */
public class RepositoryGraph implements Model {
    private static final boolean INFER = false;

    private final RepositoryConnection rc;

    public RepositoryGraph(final RepositoryConnection rc) throws RepositoryException {
        this.rc = rc;
    }

    @Override
    public ValueFactory getValueFactory() {
        return rc.getValueFactory();
    }

    @Override
    public Model unmodifiable() {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set getNamespaces() {
        Function f = identity();
        return toSet(rc.getNamespaces(), f);
    }

    private  Function identity() {
        return new Function() {
            @Override
            public T apply(T t) {
                return t;
            }
        };
    }

    private  Set toSet(CloseableIteration iter,
                             Function mapping) {
        Set result  = new HashSet<>();
        try {
            while (iter.hasNext()) {
                result.add(mapping.apply(iter.next()));
            }
        } finally {
            iter.close();
        }

        return result;
    }

    @Override
    public void setNamespace(Namespace namespace) {
        rc.setNamespace(namespace.getPrefix(), namespace.getName());
    }

    @Override
    public Optional removeNamespace(String s) {
        rc.removeNamespace(s);
        return Optional.empty();
    }

    @Override
    public boolean contains(Resource resource, IRI iri, Value value, Resource... resources) {

        try (CloseableIteration iter
                     = rc.getStatements(resource, iri, value, resources)) {
            return iter.hasNext();
        }
    }

    @Override
    public boolean add(Resource s, IRI p, Value o, Resource... c) {
        try {
            rc.begin();
            rc.add(s, p, o, c);
            rc.commit();
            return true;
        } catch (RepositoryException e) {
            throw new RepositoryGraphRuntimeException(e);
        }
    }

    @Override
    public boolean clear(Resource... resources) {
        rc.clear(resources);
        // note: we don't know whether any statements are removed
        return false;
    }

    @Override
    public boolean remove(Resource resource, IRI iri, Value value, Resource... resources) {
        rc.remove(resource, iri, value, resources);
        // note: we don't know whether any statements are removed
        return false;
    }

    @Override
    public Model filter(Resource resource, IRI iri, Value value, Resource... resources) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set subjects() {
        Function f = new Function() {
            @Override
            public Resource apply(Statement statement) {
                return statement.getSubject();
            }
        };
        return toSet(rc.getStatements(null, null, null), f);
    }

    @Override
    public Set predicates() {
        Function f = new Function() {
            @Override
            public IRI apply(Statement statement) {
                return statement.getPredicate();
            }
        };
        return toSet(rc.getStatements(null, null, null), f);
    }

    @Override
    public Set objects() {
        Function f = new Function() {
            @Override
            public Value apply(Statement statement) {
                return statement.getObject();
            }
        };
        return toSet(rc.getStatements(null, null, null), f);
    }

    // note: the returned iterator contains a CloseableIteration which will not be closed
    @Override
    public Iterator match(Resource s, IRI p, Value o, Resource... c) {
        RepositoryResult result;
        try {
            result = rc.getStatements(s, p, o, INFER, c);
        } catch (RepositoryException e) {
            throw new RepositoryGraphRuntimeException(e);
        }
        return new RepositoryResultIterator(result);
    }

    @Override
    public int size() {
        try {
            return (int) rc.size();
        } catch (RepositoryException e) {
            throw new RepositoryGraphRuntimeException(e);
        }
    }

    @Override
    public boolean isEmpty() {
        return 0 == size();
    }

    @Override
    public boolean contains(Object o) {
        if (o instanceof Statement) {
            Statement st = (Statement) o;
            try {
                try (RepositoryResult result = rc.getStatements(
                        st.getSubject(), st.getPredicate(), st.getObject(), INFER, st.getContext())) {
                    return result.hasNext();
                }
            } catch (Exception e) {
                throw new RepositoryGraphRuntimeException(e);
            }
        } else {
            return false;
        }
    }

    @Override
    public Iterator iterator() {
        return match(null, null, null);
    }

    @Override
    public Object[] toArray() {
        int size = size();
        Object[] a = new Object[size];
        if (size > 0) try {
            int i = 0;
            try (RepositoryResult result = rc.getStatements(null, null, null, INFER)) {
                while (result.hasNext()) {
                    a[i] = result.next();
                    i++;
                }
            }
        } catch (Exception e) {
            throw new RepositoryGraphRuntimeException(e);
        }

        return a;
    }

    @Override
    public  T[] toArray(T[] ts) {
        // TODO: only Statement is acceptable as T
        return (T[]) toArray();
    }

    @Override
    public boolean add(Statement statement) {
        try {
            rc.add(statement);
        } catch (RepositoryException e) {
            throw new RepositoryGraphRuntimeException(e);
        }

        // the RepositoryConnection API does not provide an efficient means
        // of knowing whether the repository was changed
        return false;
    }

    @Override
    public boolean remove(Object o) {
        if (o instanceof Statement) {
            Statement st = (Statement) o;
            try {
                rc.remove(st.getSubject(), st.getPredicate(), st.getObject(), st.getContext());
            } catch (RepositoryException e) {
                throw new RepositoryGraphRuntimeException(e);
            }
        }
        // the RepositoryConnection API does not provide an efficient means of knowing whether a statement was removed
        return false;
    }

    @Override
    public boolean containsAll(Collection objects) {
        for (Object o : objects) {
            if (!contains(o)) {
                return false;
            }
        }

        return true;
    }

    @Override
    public boolean addAll(Collection statements) {
        for (Statement s : statements) {
            add(s);
        }

        return false;
    }

    @Override
    public boolean removeAll(Collection objects) {
        for (Object o : objects) {
            remove(o);
        }

        return false;
    }

    @Override
    public boolean retainAll(Collection objects) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void clear() {
        try {
            rc.clear();
        } catch (RepositoryException e) {
            throw new RepositoryGraphRuntimeException(e);
        }
    }

    private class RepositoryResultIterator implements Iterator {
        private final RepositoryResult result;

        private RepositoryResultIterator(RepositoryResult result) {
            this.result = result;
        }

        public boolean hasNext() {
            try {
                return result.hasNext();
            } catch (RepositoryException e) {
                throw new RepositoryGraphRuntimeException(e);
            }
        }

        public Statement next() {
            try {
                return (Statement) result.next();
            } catch (RepositoryException e) {
                throw new RepositoryGraphRuntimeException(e);
            }
        }

        public void remove() {
            try {
                result.remove();
            } catch (RepositoryException e) {
                throw new RepositoryGraphRuntimeException(e);
            }
        }
    }

    public class RepositoryGraphRuntimeException extends RuntimeException {
        public RepositoryGraphRuntimeException(final Throwable cause) {
            super(cause);
        }
    }
}