Skip to content

Commit

Permalink
[Enhancement #209, WIP] Working on refactoring list iterators in RDF4…
Browse files Browse the repository at this point in the history
…J driver to support data property values in referenced lists.
  • Loading branch information
ledsoft committed Nov 26, 2023
1 parent 8eb649b commit a38b443
Show file tree
Hide file tree
Showing 23 changed files with 473 additions and 388 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public interface Lists {
* @throws OntoDriverException If an ontology access error occurs
* @throws IllegalStateException If called on a closed connection
*/
void persistReferencedList(ReferencedListValueDescriptor descriptor) throws OntoDriverException;
<T> void persistReferencedList(ReferencedListValueDescriptor<T> descriptor) throws OntoDriverException;

/**
* Updates referenced list based on the values in the specified list descriptor.
Expand All @@ -108,5 +108,5 @@ public interface Lists {
* @throws OntoDriverException If an ontology access error occurs
* @throws IllegalStateException If called on a closed connection
*/
void updateReferencedList(ReferencedListValueDescriptor descriptor) throws OntoDriverException;
<T> void updateReferencedList(ReferencedListValueDescriptor<T> descriptor) throws OntoDriverException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
import java.util.List;
import java.util.Objects;

public class ReferencedListValueDescriptor extends ReferencedListDescriptorImpl implements ListValueDescriptor<Object> {
public class ReferencedListValueDescriptor<T> extends ReferencedListDescriptorImpl implements ListValueDescriptor<T> {

private final List<Object> values;
private final List<T> values;

public ReferencedListValueDescriptor(NamedResource listOwner, Assertion listProperty,
Assertion nextNode, Assertion nodeContent) {
Expand All @@ -36,12 +36,12 @@ public ReferencedListValueDescriptor(NamedResource listOwner, Assertion listProp
}

@Override
public List<Object> getValues() {
public List<T> getValues() {
return Collections.unmodifiableList(values);
}

@Override
public void addValue(Object value) {
public void addValue(T value) {
Objects.requireNonNull(value);
values.add(value);
}
Expand All @@ -60,7 +60,7 @@ public boolean equals(Object obj) {
return true;
if (obj == null || getClass() != obj.getClass())
return false;
ReferencedListValueDescriptor other = (ReferencedListValueDescriptor) obj;
ReferencedListValueDescriptor<?> other = (ReferencedListValueDescriptor<?>) obj;
if (!descriptor.equals(other.descriptor))
return false;
if (!getNodeContent().equals(other.getNodeContent()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import cz.cvut.kbss.ontodriver.model.*;
import cz.cvut.kbss.ontodriver.rdf4j.connector.Connector;
import cz.cvut.kbss.ontodriver.rdf4j.util.Rdf4jUtils;
import cz.cvut.kbss.ontodriver.rdf4j.util.ValueConverter;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
Expand All @@ -32,7 +33,7 @@
import java.util.HashSet;
import java.util.Set;

abstract class AbstractListIterator implements ListIterator {
abstract class AbstractListIterator<JT> implements ListIterator<JT> {

protected final Resource listOwner;
protected final IRI hasListProperty;
Expand All @@ -43,6 +44,8 @@ abstract class AbstractListIterator implements ListIterator {
protected final Connector connector;
protected final ValueFactory vf;

protected final ValueConverter valueConverter;

public AbstractListIterator(ListDescriptor listDescriptor, Connector connector, ValueFactory vf) {
this.listOwner = Rdf4jUtils.toRdf4jIri(listDescriptor.getListOwner().getIdentifier(), vf);
this.hasListProperty = Rdf4jUtils.toRdf4jIri(listDescriptor.getListProperty()
Expand All @@ -52,6 +55,7 @@ public AbstractListIterator(ListDescriptor listDescriptor, Connector connector,
this.includeInferred = listDescriptor.getListProperty().isInferred();
this.connector = connector;
this.vf = vf;
this.valueConverter = new ValueConverter(vf);
}

protected Set<IRI> contexts() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import cz.cvut.kbss.ontodriver.rdf4j.connector.Connector;
import cz.cvut.kbss.ontodriver.rdf4j.exception.Rdf4jDriverException;
import cz.cvut.kbss.ontodriver.rdf4j.util.Rdf4jUtils;
import cz.cvut.kbss.ontodriver.rdf4j.util.ValueConverter;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import cz.cvut.kbss.ontodriver.rdf4j.connector.Connector;
import cz.cvut.kbss.ontodriver.rdf4j.connector.SubjectPredicateContext;
import cz.cvut.kbss.ontodriver.rdf4j.exception.Rdf4jDriverException;
import cz.cvut.kbss.ontodriver.rdf4j.util.ValueConverter;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
* @param <T> List descriptor type
* @param <V> List value descriptor type
*/
abstract class ListHandler<T extends ListDescriptor, V extends ListValueDescriptor> {
abstract class ListHandler<T extends ListDescriptor, V extends ListValueDescriptor<?>> {

protected final Connector connector;
protected final ValueFactory vf;
Expand All @@ -54,14 +54,14 @@ abstract class ListHandler<T extends ListDescriptor, V extends ListValueDescript
*/
List<Axiom<NamedResource>> loadList(T listDescriptor) throws Rdf4jDriverException {
final List<Axiom<NamedResource>> axioms = new ArrayList<>();
final ListIterator it = createIterator(listDescriptor);
final ListIterator<?> it = createIterator(listDescriptor);
while (it.hasNext()) {
axioms.add(it.nextAxiom());
}
return axioms;
}

abstract ListIterator createIterator(T listDescriptor) throws Rdf4jDriverException;
abstract ListIterator<?> createIterator(T listDescriptor) throws Rdf4jDriverException;

/**
* Persists list values specified by the descriptor.
Expand All @@ -75,8 +75,7 @@ void persistList(V listValueDescriptor) throws Rdf4jDriverException {
if (listValueDescriptor.getValues().isEmpty()) {
return;
}
final Collection<Statement> statements = new ArrayList<>(listValueDescriptor.getValues()
.size());
final Collection<Statement> statements = new ArrayList<>(listValueDescriptor.getValues().size());
final IRI head = createListHead(listValueDescriptor, statements);
statements.addAll(createListRest(head, listValueDescriptor));
connector.addStatements(statements);
Expand Down Expand Up @@ -113,7 +112,7 @@ private boolean isOldListEmpty(Resource owner, IRI hasListProperty, boolean incl
abstract void clearList(V listDescriptor) throws Rdf4jDriverException;

private void mergeList(V listDescriptor) throws Rdf4jDriverException {
final ListIterator it = iterator(listDescriptor);
final ListIterator<?> it = iterator(listDescriptor);
final MergeResult mergeResult = mergeWithOriginalList(listDescriptor, it);
removeObsoletes(it);
assert mergeResult.i > 0;
Expand All @@ -123,13 +122,13 @@ private void mergeList(V listDescriptor) throws Rdf4jDriverException {
}
}

abstract ListIterator iterator(V listDescriptor) throws Rdf4jDriverException;
abstract ListIterator<?> iterator(V listDescriptor) throws Rdf4jDriverException;

abstract MergeResult mergeWithOriginalList(V listDescriptor, ListIterator it) throws Rdf4jDriverException;
abstract MergeResult mergeWithOriginalList(V listDescriptor, ListIterator<?> it) throws Rdf4jDriverException;

abstract void appendNewNodes(V listDescriptor, MergeResult mergeResult) throws Rdf4jDriverException;

private void removeObsoletes(ListIterator it) throws Rdf4jDriverException {
private void removeObsoletes(ListIterator<?> it) throws Rdf4jDriverException {
while (it.hasNext()) {
it.nextNode();
it.remove();
Expand Down Expand Up @@ -197,7 +196,7 @@ static ListHandler<SimpleListDescriptor, SimpleListValueDescriptor> createForSim
* @param vf RDF4J value factory
* @return List handler
*/
static ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> createForReferencedList(
static ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor<?>> createForReferencedList(
Connector connector, ValueFactory vf) {
assert connector != null;
assert vf != null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@
import cz.cvut.kbss.ontodriver.rdf4j.exception.Rdf4jDriverException;
import org.eclipse.rdf4j.model.Resource;

interface ListIterator {
interface ListIterator<JT> {

boolean hasNext() throws Rdf4jDriverException;

Resource nextNode() throws Rdf4jDriverException;

Resource currentContent() throws Rdf4jDriverException;
JT currentContent() throws Rdf4jDriverException;

// Change to JT
Axiom<NamedResource> nextAxiom() throws Rdf4jDriverException;

void remove() throws Rdf4jDriverException;

void replaceCurrentWith(NamedResource newNode) throws Rdf4jDriverException;
void replaceCurrentWith(JT newNode) throws Rdf4jDriverException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import cz.cvut.kbss.ontodriver.exception.IdentifierGenerationException;
import cz.cvut.kbss.ontodriver.exception.OntoDriverException;
import cz.cvut.kbss.ontodriver.model.Axiom;
import cz.cvut.kbss.ontodriver.model.NamedResource;
import cz.cvut.kbss.ontodriver.rdf4j.config.Constants;
import cz.cvut.kbss.ontodriver.rdf4j.config.RuntimeConfiguration;
import cz.cvut.kbss.ontodriver.rdf4j.connector.Connector;
Expand Down Expand Up @@ -209,12 +210,12 @@ StatementExecutor getQueryExecutor() {
return connector;
}

ListHandler<SimpleListDescriptor, SimpleListValueDescriptor> getSimpleListHandler() throws Rdf4jDriverException {
ListHandler<SimpleListDescriptor, SimpleListValueDescriptor, NamedResource> getSimpleListHandler() throws Rdf4jDriverException {
startTransactionIfNotActive();
return ListHandler.createForSimpleList(connector, valueFactory);
}

ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> getReferencedListHandler() throws
ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor<?>, ?> getReferencedListHandler() throws
Rdf4jDriverException {
startTransactionIfNotActive();
return ListHandler.createForReferencedList(connector, valueFactory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public List<Axiom<NamedResource>> loadReferencedList(ReferencedListDescriptor de
}

@Override
public void persistReferencedList(ReferencedListValueDescriptor descriptor)
public <T> void persistReferencedList(ReferencedListValueDescriptor<T> descriptor)
throws OntoDriverException {
verifyArgs(descriptor);
adapter.getReferencedListHandler().persistList(descriptor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,45 @@

import cz.cvut.kbss.ontodriver.descriptor.ReferencedListDescriptor;
import cz.cvut.kbss.ontodriver.descriptor.ReferencedListValueDescriptor;
import cz.cvut.kbss.ontodriver.model.NamedResource;
import cz.cvut.kbss.ontodriver.model.Assertion;
import cz.cvut.kbss.ontodriver.rdf4j.connector.Connector;
import cz.cvut.kbss.ontodriver.rdf4j.exception.Rdf4jDriverException;
import cz.cvut.kbss.ontodriver.rdf4j.util.ValueConverter;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;

import java.util.*;

public class ReferencedListHandler extends
ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> {
public class ReferencedListHandler<VT> extends
ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor<VT>, VT> {

private int sequenceCounter = 0;

private final ValueConverter valueConverter;

ReferencedListHandler(Connector connector, ValueFactory vf) {
super(connector, vf);
this.valueConverter = new ValueConverter(vf);
}

@Override
ListIterator createIterator(ReferencedListDescriptor listDescriptor) throws Rdf4jDriverException {
return new ReferencedListIterator(listDescriptor, connector, vf);
ListIterator<VT> createIterator(ReferencedListDescriptor listDescriptor) throws Rdf4jDriverException {
return new ReferencedListIterator<>(listDescriptor, connector, vf);
}

@Override
IRI createListHead(ReferencedListValueDescriptor listValueDescriptor,
IRI createListHead(ReferencedListValueDescriptor<VT> listValueDescriptor,
Collection<Statement> statements) throws Rdf4jDriverException {
final IRI owner = owner(listValueDescriptor);
final IRI hasList = hasList(listValueDescriptor);
final IRI hasContent = hasContent(listValueDescriptor);
final IRI context = context(listValueDescriptor);
final IRI nodeUri = generateSequenceNode(owner, context);
statements.add(vf.createStatement(owner, hasList, nodeUri, context));
final IRI nodeContent = toRdf4jIri(listValueDescriptor.getValues().get(0).getIdentifier());
final Value nodeContent = toRdf4jValue(listValueDescriptor.getListProperty(), listValueDescriptor.getValues().get(0));
statements.add(vf.createStatement(nodeUri, hasContent, nodeContent, context));
return nodeUri;
}
Expand All @@ -61,6 +66,10 @@ private IRI hasContent(ReferencedListDescriptor listDescriptor) {
return toRdf4jIri(listDescriptor.getNodeContent().getIdentifier());
}

private Value toRdf4jValue(Assertion a, Object value) throws Rdf4jDriverException {
return valueConverter.toRdf4jValue(a, new cz.cvut.kbss.ontodriver.model.Value<>(value));
}

private IRI generateSequenceNode(IRI owner, IRI context) throws Rdf4jDriverException {
final String uriBase = owner.stringValue();
boolean unique;
Expand All @@ -75,7 +84,7 @@ private IRI generateSequenceNode(IRI owner, IRI context) throws Rdf4jDriverExcep
}

@Override
List<Statement> createListRest(IRI headNode, ReferencedListValueDescriptor listValueDescriptor)
List<Statement> createListRest(IRI headNode, ReferencedListValueDescriptor<VT> listValueDescriptor)
throws Rdf4jDriverException {
final IRI owner = owner(listValueDescriptor);
final IRI hasNext = hasNext(listValueDescriptor);
Expand All @@ -84,17 +93,17 @@ List<Statement> createListRest(IRI headNode, ReferencedListValueDescriptor listV
IRI previous = headNode;
final List<Statement> statements = new ArrayList<>(
listValueDescriptor.getValues().size() * 2);
final Iterator<NamedResource> it = listValueDescriptor.getValues().iterator();
final Iterator<?> it = listValueDescriptor.getValues().iterator();
// Skip the first element, it is already in the head
it.next();
while (it.hasNext()) {
final IRI content = toRdf4jIri(it.next().getIdentifier());
final Value content = toRdf4jValue(listValueDescriptor.getListProperty(), it.next());
previous = createListNode(owner, hasNext, hasContent, content, context, previous, statements);
}
return statements;
}

private IRI createListNode(IRI owner, IRI hasNext, IRI hasContent, IRI content, IRI context, Resource previous,
private IRI createListNode(IRI owner, IRI hasNext, IRI hasContent, Value content, IRI context, Resource previous,
Collection<Statement> statements) throws Rdf4jDriverException {
final IRI node = generateSequenceNode(owner, context);
statements.add(vf.createStatement(previous, hasNext, node, context));
Expand All @@ -103,7 +112,7 @@ private IRI createListNode(IRI owner, IRI hasNext, IRI hasContent, IRI content,
}

@Override
void clearList(ReferencedListValueDescriptor listDescriptor) throws Rdf4jDriverException {
void clearList(ReferencedListValueDescriptor<VT> listDescriptor) throws Rdf4jDriverException {
final IRI hasNext = hasNext(listDescriptor);
final IRI hasContent = hasContent(listDescriptor);
final boolean includeInferred = listDescriptor.getListProperty().isInferred();
Expand All @@ -126,29 +135,29 @@ void clearList(ReferencedListValueDescriptor listDescriptor) throws Rdf4jDriverE
}

@Override
ListIterator iterator(ReferencedListValueDescriptor listDescriptor) throws Rdf4jDriverException {
return new ReferencedListIterator(listDescriptor, connector, vf);
ListIterator<VT> iterator(ReferencedListValueDescriptor<VT> listDescriptor) throws Rdf4jDriverException {
return new ReferencedListIterator<>(listDescriptor, connector, vf);
}

@Override
MergeResult mergeWithOriginalList(ReferencedListValueDescriptor listDescriptor, ListIterator it)
MergeResult mergeWithOriginalList(ReferencedListValueDescriptor<VT> listDescriptor, ListIterator<VT> it)
throws Rdf4jDriverException {
int i = 0;
Resource node = null;
while (it.hasNext() && i < listDescriptor.getValues().size()) {
node = it.nextNode();
final Resource content = it.currentContent();
final NamedResource newNode = listDescriptor.getValues().get(i);
if (!content.stringValue().equals(newNode.getIdentifier().toString())) {
it.replaceCurrentWith(newNode);
final Object content = it.currentContent();
final Object newNode = listDescriptor.getValues().get(i);
if (!content.equals(newNode)) {
it.replaceCurrentWith((VT) newNode);
}
i++;
}
return new MergeResult(i, node);
}

@Override
void appendNewNodes(ReferencedListValueDescriptor listDescriptor, MergeResult mergeResult)
void appendNewNodes(ReferencedListValueDescriptor<VT> listDescriptor, MergeResult mergeResult)
throws Rdf4jDriverException {
int i = mergeResult.i;
Resource previous = mergeResult.previous;
Expand All @@ -159,7 +168,7 @@ void appendNewNodes(ReferencedListValueDescriptor listDescriptor, MergeResult me
assert i > 0;
final Collection<Statement> toAdd = new ArrayList<>((listDescriptor.getValues().size() - i) * 2);
while (i < listDescriptor.getValues().size()) {
final IRI content = toRdf4jIri(listDescriptor.getValues().get(i).getIdentifier());
final Value content = toRdf4jValue(listDescriptor.getListProperty(), listDescriptor.getValues().get(i));
previous = createListNode(owner, hasNext, hasContent, content, context, previous, toAdd);
i++;
}
Expand Down
Loading

0 comments on commit a38b443

Please sign in to comment.