Skip to content

Method: createIterator(ReferencedListDescriptor)

1: /**
2: * Copyright (C) 2022 Czech Technical University in Prague
3: *
4: * This program is free software: you can redistribute it and/or modify it under
5: * the terms of the GNU General Public License as published by the Free Software
6: * Foundation, either version 3 of the License, or (at your option) any
7: * later version.
8: *
9: * This program is distributed in the hope that it will be useful, but WITHOUT
10: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12: * details. You should have received a copy of the GNU General Public License
13: * along with this program. If not, see <http://www.gnu.org/licenses/>.
14: */
15: package cz.cvut.kbss.ontodriver.sesame;
16:
17: import cz.cvut.kbss.ontodriver.descriptor.ReferencedListDescriptor;
18: import cz.cvut.kbss.ontodriver.descriptor.ReferencedListValueDescriptor;
19: import cz.cvut.kbss.ontodriver.model.NamedResource;
20: import cz.cvut.kbss.ontodriver.sesame.connector.Connector;
21: import cz.cvut.kbss.ontodriver.sesame.exceptions.SesameDriverException;
22: import org.eclipse.rdf4j.model.IRI;
23: import org.eclipse.rdf4j.model.Resource;
24: import org.eclipse.rdf4j.model.Statement;
25: import org.eclipse.rdf4j.model.ValueFactory;
26:
27: import java.util.*;
28:
29: public class ReferencedListHandler extends
30: ListHandler<ReferencedListDescriptor, ReferencedListValueDescriptor> {
31:
32: private int sequenceCounter = 0;
33:
34: ReferencedListHandler(Connector connector, ValueFactory vf) {
35: super(connector, vf);
36: }
37:
38: @Override
39: SesameIterator createIterator(ReferencedListDescriptor listDescriptor) throws SesameDriverException {
40: return new ReferencedListIterator(listDescriptor, connector, vf);
41: }
42:
43: @Override
44: IRI createListHead(ReferencedListValueDescriptor listValueDescriptor,
45: Collection<Statement> statements) throws SesameDriverException {
46: final IRI owner = owner(listValueDescriptor);
47: final IRI hasList = hasList(listValueDescriptor);
48: final IRI hasContent = hasContent(listValueDescriptor);
49: final IRI context = context(listValueDescriptor);
50: final IRI nodeUri = generateSequenceNode(owner, context);
51: statements.add(vf.createStatement(owner, hasList, nodeUri, context));
52: final IRI nodeContent = sesameIri(listValueDescriptor.getValues().get(0).getIdentifier());
53: statements.add(vf.createStatement(nodeUri, hasContent, nodeContent, context));
54: return nodeUri;
55: }
56:
57: private IRI hasContent(ReferencedListDescriptor listDescriptor) {
58: return sesameIri(listDescriptor.getNodeContent().getIdentifier());
59: }
60:
61: private IRI generateSequenceNode(IRI owner, IRI context) throws SesameDriverException {
62: final String uriBase = owner.stringValue();
63: boolean unique;
64: IRI node;
65: do {
66: node = vf.createIRI(uriBase + "-SEQ_" + sequenceCounter++);
67: final Collection<Statement> stmts = connector.findStatements(node, null, null, false,
68: context != null ? Collections.singleton(context) : Collections.emptySet());
69: unique = stmts.isEmpty();
70: } while (!unique);
71: return node;
72: }
73:
74: @Override
75: List<Statement> createListRest(IRI headNode, ReferencedListValueDescriptor listValueDescriptor)
76: throws SesameDriverException {
77: final IRI owner = owner(listValueDescriptor);
78: final IRI hasNext = hasNext(listValueDescriptor);
79: final IRI hasContent = hasContent(listValueDescriptor);
80: final IRI context = context(listValueDescriptor);
81: IRI previous = headNode;
82: final List<Statement> statements = new ArrayList<>(
83: listValueDescriptor.getValues().size() * 2);
84: final Iterator<NamedResource> it = listValueDescriptor.getValues().iterator();
85: // Skip the first element, it is already in the head
86: it.next();
87: while (it.hasNext()) {
88: final IRI content = sesameIri(it.next().getIdentifier());
89: previous = createListNode(owner, hasNext, hasContent, content, context, previous, statements);
90: }
91: return statements;
92: }
93:
94: private IRI createListNode(IRI owner, IRI hasNext, IRI hasContent, IRI content, IRI context, Resource previous,
95: Collection<Statement> statements) throws SesameDriverException {
96: final IRI node = generateSequenceNode(owner, context);
97: statements.add(vf.createStatement(previous, hasNext, node, context));
98: statements.add(vf.createStatement(node, hasContent, content, context));
99: return node;
100: }
101:
102: @Override
103: void clearList(ReferencedListValueDescriptor listDescriptor) throws SesameDriverException {
104: final IRI hasNext = hasNext(listDescriptor);
105: final IRI hasContent = hasContent(listDescriptor);
106: final boolean includeInferred = listDescriptor.getListProperty().isInferred();
107: final Set<IRI> context = contexts(listDescriptor);
108: Resource previous = owner(listDescriptor);
109: IRI currentProperty = hasList(listDescriptor);
110: final Collection<Statement> toRemove = new ArrayList<>();
111: Collection<Statement> next;
112: do {
113: next = connector.findStatements(previous, currentProperty, null, includeInferred, context);
114: if (!next.isEmpty()) {
115: final Resource node = extractListNode(next, currentProperty);
116: toRemove.addAll(next);
117: toRemove.addAll(connector.findStatements(node, hasContent, null, includeInferred, context));
118: previous = node;
119: }
120: currentProperty = hasNext;
121: } while (!next.isEmpty());
122: connector.removeStatements(toRemove);
123: }
124:
125: @Override
126: SesameIterator iterator(ReferencedListValueDescriptor listDescriptor) throws SesameDriverException {
127: return new ReferencedListIterator(listDescriptor, connector, vf);
128: }
129:
130: @Override
131: MergeResult mergeWithOriginalList(ReferencedListValueDescriptor listDescriptor, SesameIterator it)
132: throws SesameDriverException {
133: int i = 0;
134: Resource node = null;
135: while (it.hasNext() && i < listDescriptor.getValues().size()) {
136: node = it.nextNode();
137: final Resource content = it.currentContent();
138: final NamedResource newNode = listDescriptor.getValues().get(i);
139: if (!content.stringValue().equals(newNode.getIdentifier().toString())) {
140: it.replaceCurrentWith(newNode);
141: }
142: i++;
143: }
144: return new MergeResult(i, node);
145: }
146:
147: @Override
148: void appendNewNodes(ReferencedListValueDescriptor listDescriptor, MergeResult mergeResult)
149: throws SesameDriverException {
150: int i = mergeResult.i;
151: Resource previous = mergeResult.previous;
152: final IRI owner = owner(listDescriptor);
153: final IRI hasNext = hasNext(listDescriptor);
154: final IRI hasContent = hasContent(listDescriptor);
155: final IRI context = context(listDescriptor);
156: assert i > 0;
157: final Collection<Statement> toAdd = new ArrayList<>((listDescriptor.getValues().size() - i) * 2);
158: while (i < listDescriptor.getValues().size()) {
159: final IRI content = sesameIri(listDescriptor.getValues().get(i).getIdentifier());
160: previous = createListNode(owner, hasNext, hasContent, content, context, previous, toAdd);
161: i++;
162: }
163: connector.addStatements(toAdd);
164: }
165: }