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

cz.cvut.kbss.ontodriver.sesame.ListHandler Maven / Gradle / Ivy

/**
 * Copyright (C) 2020 Czech Technical University in Prague
 * 

* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later * version. *

* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. You should have received a copy of the GNU General Public License along with this program. If not, see * . */ package cz.cvut.kbss.ontodriver.sesame; import cz.cvut.kbss.ontodriver.descriptor.*; import cz.cvut.kbss.ontodriver.exception.IntegrityConstraintViolatedException; import cz.cvut.kbss.ontodriver.model.Axiom; import cz.cvut.kbss.ontodriver.model.NamedResource; import cz.cvut.kbss.ontodriver.sesame.connector.Connector; import cz.cvut.kbss.ontodriver.sesame.exceptions.SesameDriverException; import cz.cvut.kbss.ontodriver.sesame.util.SesameUtils; import org.eclipse.rdf4j.model.*; import java.util.*; /** * Base class for list handlers. *

* List handlers are responsible for loading and persisting lists. * * @param List descriptor type * @param List value descriptor type */ abstract class ListHandler { protected final Connector connector; protected final ValueFactory vf; ListHandler(Connector connector, ValueFactory vf) { this.connector = connector; this.vf = vf; } /** * Loads axioms representing list described by the specified list descriptor. * * @return Collection of axioms representing sequence values * @throws SesameDriverException When storage access error occurs */ List> loadList(T listDescriptor) throws SesameDriverException { final List> axioms = new ArrayList<>(); final SesameIterator it = createIterator(listDescriptor); while (it.hasNext()) { axioms.add(it.nextAxiom()); } return axioms; } abstract SesameIterator createIterator(T listDescriptor) throws SesameDriverException; /** * Persists list values specified by the descriptor. *

* The values are saved in the order in which they appear in the descriptor. * * @param listValueDescriptor Describes values to persist * @throws SesameDriverException When storage access error occurs */ void persistList(V listValueDescriptor) throws SesameDriverException { if (listValueDescriptor.getValues().isEmpty()) { return; } final Collection statements = new ArrayList<>(listValueDescriptor.getValues() .size()); final IRI head = createListHead(listValueDescriptor, statements); statements.addAll(createListRest(head, listValueDescriptor)); connector.addStatements(statements); } abstract IRI createListHead(V valueDescriptor, Collection listStatements) throws SesameDriverException; abstract List createListRest(IRI head, V valueDescriptor) throws SesameDriverException; /** * Updates list with values specified by the descriptor. * * @param listValueDescriptor Describes the updated values * @throws SesameDriverException When storage access error occurs */ void updateList(V listValueDescriptor) throws SesameDriverException { if (listValueDescriptor.getValues().isEmpty()) { clearList(listValueDescriptor); } else if (isOldListEmpty(owner(listValueDescriptor), hasList(listValueDescriptor), listValueDescriptor.getListProperty().isInferred(), contexts(listValueDescriptor))) { persistList(listValueDescriptor); } else { mergeList(listValueDescriptor); } } private boolean isOldListEmpty(Resource owner, IRI hasListProperty, boolean includeInferred, Set contexts) throws SesameDriverException { final Collection stmts = connector.findStatements(owner, hasListProperty, null, includeInferred, contexts); return stmts.isEmpty(); } abstract void clearList(V listDescriptor) throws SesameDriverException; private void mergeList(V listDescriptor) throws SesameDriverException { final SesameIterator it = iterator(listDescriptor); final MergeResult mergeResult = mergeWithOriginalList(listDescriptor, it); removeObsoletes(it); assert mergeResult.i > 0; assert mergeResult.previous != null; if (mergeResult.i < listDescriptor.getValues().size()) { appendNewNodes(listDescriptor, mergeResult); } } abstract SesameIterator iterator(V listDescriptor) throws SesameDriverException; abstract MergeResult mergeWithOriginalList(V listDescriptor, SesameIterator it) throws SesameDriverException; abstract void appendNewNodes(V listDescriptor, MergeResult mergeResult) throws SesameDriverException; private void removeObsoletes(SesameIterator it) throws SesameDriverException { while (it.hasNext()) { it.nextNode(); it.remove(); } } Resource extractListNode(Collection stmts, IRI nodeAssertion) { if (stmts.size() > 1) { throw new IntegrityConstraintViolatedException( "Invalid number of values found for assertion " + nodeAssertion + ". Expected 1, got " + stmts.size()); } final Value val = stmts.iterator().next().getObject(); if (!(val instanceof Resource)) { throw new IntegrityConstraintViolatedException( "Invalid property value. Expected object property value, got literal."); } return (Resource) val; } Set contexts(ListDescriptor listDescriptor) { final IRI ctx = sesameIri(listDescriptor.getContext()); return ctx != null ? Collections.singleton(ctx) : Collections.emptySet(); } IRI context(ListDescriptor listDescriptor) { return sesameIri(listDescriptor.getContext()); } IRI owner(ListDescriptor listDescriptor) { return sesameIri(listDescriptor.getListOwner().getIdentifier()); } IRI hasList(ListDescriptor listDescriptor) { return sesameIri(listDescriptor.getListProperty().getIdentifier()); } IRI hasNext(ListDescriptor listDescriptor) { return sesameIri(listDescriptor.getNextNode().getIdentifier()); } IRI sesameIri(java.net.URI uri) { return SesameUtils.toSesameIri(uri, vf); } /** * Creates handler for simple lists. * * @param connector Storage connector * @param vf Sesame value factory * @return List handler */ static ListHandler createForSimpleList( Connector connector, ValueFactory vf) { assert connector != null; assert vf != null; return new SimpleListHandler(connector, vf); } /** * Creates handler for referenced lists. * * @param connector Storage connector * @param vf Sesame value factory * @return List handler */ static ListHandler createForReferencedList( Connector connector, ValueFactory vf) { assert connector != null; assert vf != null; return new ReferencedListHandler(connector, vf); } static final class MergeResult { protected final int i; final Resource previous; MergeResult(int i, Resource node) { this.i = i; this.previous = node; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy