Skip to content

Package: AbstractListIterator

AbstractListIterator

nameinstructionbranchcomplexitylinemethod
AbstractListIterator(ListDescriptor, StorageConnector)
M: 0 C: 47
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
contexts()
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
first()
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getCurrentNode()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
hasNext()
M: 0 C: 8
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
moveCursor(Resource)
M: 0 C: 18
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
remove(Resource, Property, RDFNode)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
removeWithoutReconnect()
M: 8 C: 42
84%
M: 2 C: 8
80%
M: 2 C: 4
67%
M: 0 C: 9
100%
M: 0 C: 1
100%
resolveNextListNode()
M: 0 C: 51
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
static {...}
M: 0 C: 1
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
verifySuccessorCount()
M: 0 C: 28
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 6
100%
M: 0 C: 1
100%

Coverage

1: /**
2: * Copyright (C) 2020 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.jena.list;
16:
17: import cz.cvut.kbss.ontodriver.descriptor.ListDescriptor;
18: import cz.cvut.kbss.ontodriver.exception.IntegrityConstraintViolatedException;
19: import cz.cvut.kbss.ontodriver.jena.connector.StorageConnector;
20: import cz.cvut.kbss.ontodriver.jena.exception.ListProcessingException;
21: import cz.cvut.kbss.ontodriver.model.Axiom;
22: import cz.cvut.kbss.ontodriver.model.NamedResource;
23: import org.apache.jena.rdf.model.Property;
24: import org.apache.jena.rdf.model.RDFNode;
25: import org.apache.jena.rdf.model.Resource;
26: import org.apache.jena.rdf.model.Statement;
27:
28: import java.util.Collection;
29: import java.util.Collections;
30: import java.util.NoSuchElementException;
31: import java.util.Set;
32:
33: import static org.apache.jena.rdf.model.ResourceFactory.createProperty;
34: import static org.apache.jena.rdf.model.ResourceFactory.createResource;
35:
36: abstract class AbstractListIterator {
37:
38: final StorageConnector connector;
39:
40: final Property hasListProperty;
41: final Property hasNextProperty;
42:
43: final String context;
44:
45: int index;
46: private boolean removed = false;
47:
48: Resource previousNode;
49: Resource currentNode;
50: Collection<Statement> cursor;
51:
52: AbstractListIterator(ListDescriptor descriptor, StorageConnector connector) {
53: this.hasListProperty = createProperty(descriptor.getListProperty().getIdentifier().toString());
54: this.hasNextProperty = createProperty(descriptor.getNextNode().getIdentifier().toString());
55:• this.context = descriptor.getContext() != null ? descriptor.getContext().toString() : null;
56: this.connector = connector;
57: this.index = -1;
58: this.currentNode = createResource(descriptor.getListOwner().getIdentifier().toString());
59: moveCursor(currentNode);
60: }
61:
62: protected Set<String> contexts() {
63:• return context != null ? Collections.singleton(context) : Collections.emptySet();
64: }
65:
66: void moveCursor(Resource from) {
67:• this.cursor = connector.find(from, first() ? hasListProperty : hasNextProperty, null, contexts());
68: }
69:
70: void resolveNextListNode() {
71: verifySuccessorCount();
72: final RDFNode node = cursor.iterator().next().getObject();
73:• if (!node.isURIResource()) {
74: throw new ListProcessingException("Expected successor of node " + currentNode + " to be a named resource.");
75: }
76: final Resource item = node.asResource();
77: index++;
78: this.removed = false;
79: this.previousNode = currentNode;
80: this.currentNode = item;
81: moveCursor(currentNode);
82: }
83:
84: boolean first() {
85:• return index == -1;
86: }
87:
88: boolean hasNext() {
89:• return !cursor.isEmpty();
90: }
91:
92: void verifySuccessorCount() {
93:• if (!hasNext()) {
94: throw new NoSuchElementException("No more elements available.");
95: }
96:• if (cursor.size() > 1) {
97: throw new IntegrityConstraintViolatedException(
98: "Encountered multiple successors of list node " + currentNode.getURI());
99: }
100: }
101:
102: void remove(Resource subject, Property property, RDFNode object) {
103: connector.remove(subject, property, object, context);
104: }
105:
106: abstract Axiom<NamedResource> nextAxiom();
107:
108: abstract NamedResource nextValue();
109:
110: /**
111: * Only returns current node.
112: * <p>
113: * Does not advance the iterator like {@link #nextAxiom()} and {@link #nextValue()} do.
114: *
115: * @return Current list node
116: */
117: Resource getCurrentNode() {
118: return currentNode;
119: }
120:
121: /**
122: * Removes the current node without reconnecting the subsequent nodes to the previous one.
123: */
124: void removeWithoutReconnect() {
125:• if (first()) {
126: throw new IllegalStateException("Cannot call remove before calling next.");
127: }
128:• if (removed) {
129: throw new IllegalStateException("Cannot call remove multiple times on one element.");
130: }
131:• assert previousNode != null;
132:• assert currentNode != null;
133:• remove(previousNode, index == 0 ? hasListProperty : hasNextProperty, currentNode);
134: this.removed = true;
135: }
136:
137: abstract void replace(Resource replacement);
138: }