Skip to content

Package: ReferencedListIterator

ReferencedListIterator

nameinstructionbranchcomplexitylinemethod
ReferencedListIterator(ReferencedListDescriptor, OntologySnapshot, AxiomAdapter)
M: 0 C: 56
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
assertionToOwlProperty(Assertion)
M: 7 C: 24
77%
M: 1 C: 2
67%
M: 1 C: 2
67%
M: 1 C: 4
80%
M: 0 C: 1
100%
doStep()
M: 0 C: 49
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 15
100%
M: 0 C: 1
100%
extractNodeContent()
M: 0 C: 46
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
getCurrentNode()
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getNextNode()
M: 0 C: 20
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
hasNext()
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
icViolatedException(String, int)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$extractNodeContent$1(MultilingualString, OWLObject)
M: 8 C: 18
69%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 0 C: 5
100%
M: 0 C: 1
100%
lambda$hasNext$0(OWLIndividual)
M: 0 C: 2
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$replaceDataPropertyContent$2(List, OWLObject)
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
next()
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
nextValue()
M: 0 C: 14
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
removeWithoutReconnect()
M: 0 C: 45
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
replaceDataPropertyContent(Object)
M: 0 C: 35
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
replaceNode(Object)
M: 4 C: 60
94%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 10
100%
M: 0 C: 1
100%
resolveCurrentContent()
M: 4 C: 33
89%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 6
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%
verifyContentValueCount(Collection)
M: 17 C: 55
76%
M: 4 C: 10
71%
M: 4 C: 4
50%
M: 2 C: 13
87%
M: 0 C: 1
100%

Coverage

1: /*
2: * JOPA
3: * Copyright (C) 2024 Czech Technical University in Prague
4: *
5: * This library is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public
7: * License as published by the Free Software Foundation; either
8: * version 3.0 of the License, or (at your option) any later version.
9: *
10: * This library is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this library.
17: */
18: package cz.cvut.kbss.ontodriver.owlapi.list;
19:
20: import cz.cvut.kbss.ontodriver.descriptor.ReferencedListDescriptor;
21: import cz.cvut.kbss.ontodriver.exception.IntegrityConstraintViolatedException;
22: import cz.cvut.kbss.ontodriver.model.Assertion;
23: import cz.cvut.kbss.ontodriver.model.Axiom;
24: import cz.cvut.kbss.ontodriver.model.MultilingualString;
25: import cz.cvut.kbss.ontodriver.model.NamedResource;
26: import cz.cvut.kbss.ontodriver.owlapi.AxiomAdapter;
27: import cz.cvut.kbss.ontodriver.owlapi.change.MutableAddAxiom;
28: import cz.cvut.kbss.ontodriver.owlapi.change.MutableRemoveAxiom;
29: import cz.cvut.kbss.ontodriver.owlapi.change.TransactionalChange;
30: import cz.cvut.kbss.ontodriver.owlapi.connector.OntologySnapshot;
31: import cz.cvut.kbss.ontodriver.owlapi.util.OwlapiUtils;
32: import org.semanticweb.owlapi.model.IRI;
33: import org.semanticweb.owlapi.model.OWLDataFactory;
34: import org.semanticweb.owlapi.model.OWLIndividual;
35: import org.semanticweb.owlapi.model.OWLLiteral;
36: import org.semanticweb.owlapi.model.OWLNamedIndividual;
37: import org.semanticweb.owlapi.model.OWLObject;
38: import org.semanticweb.owlapi.model.OWLObjectProperty;
39: import org.semanticweb.owlapi.model.OWLOntology;
40: import org.semanticweb.owlapi.model.OWLProperty;
41: import org.semanticweb.owlapi.search.EntitySearcher;
42:
43: import java.util.ArrayList;
44: import java.util.Collection;
45: import java.util.Collections;
46: import java.util.HashSet;
47: import java.util.Iterator;
48: import java.util.List;
49: import java.util.NoSuchElementException;
50: import java.util.Set;
51: import java.util.stream.Collectors;
52: import java.util.stream.Stream;
53:
54: class ReferencedListIterator<T> extends OwlapiListIterator<T> {
55:
56: final OWLObjectProperty hasNextProperty;
57: final OWLProperty hasContentProperty;
58:
59: final OWLOntology ontology;
60: private final OWLDataFactory dataFactory;
61:
62: final AxiomAdapter axiomAdapter;
63:
64: OWLIndividual previousNode;
65: OWLIndividual currentNode;
66: OWLObjectProperty previousNextNodeProperty;
67: OWLObjectProperty currentNextNodeProperty;
68: Collection<? extends OWLObject> nextItem;
69:
70: final ReferencedListDescriptor descriptor;
71:
72: ReferencedListIterator(ReferencedListDescriptor descriptor, OntologySnapshot snapshot, AxiomAdapter axiomAdapter) {
73: this.ontology = snapshot.getOntology();
74: this.dataFactory = snapshot.getDataFactory();
75: this.descriptor = descriptor;
76: this.hasNextProperty = dataFactory.getOWLObjectProperty(IRI.create(descriptor.getNextNode().getIdentifier()));
77: this.hasContentProperty = assertionToOwlProperty(descriptor.getNodeContent());
78: this.axiomAdapter = axiomAdapter;
79: this.currentNextNodeProperty = dataFactory
80: .getOWLObjectProperty(IRI.create(descriptor.getListProperty().getIdentifier()));
81: this.previousNextNodeProperty = currentNextNodeProperty;
82: this.currentNode = OwlapiUtils.getIndividual(descriptor.getListOwner(), dataFactory);
83: this.previousNode = currentNode;
84: }
85:
86: private OWLProperty assertionToOwlProperty(Assertion a) {
87:• switch (a.getType()) {
88: case OBJECT_PROPERTY:
89: return dataFactory
90: .getOWLObjectProperty(IRI.create(descriptor.getNodeContent().getIdentifier()));
91: case DATA_PROPERTY:
92: return dataFactory.getOWLDataProperty(IRI.create(descriptor.getNodeContent().getIdentifier()));
93: default:
94: throw new IllegalArgumentException("Node content property cannot be type " + a.getType());
95: }
96: }
97:
98: @Override
99: public boolean hasNext() {
100: return EntitySearcher.getObjectPropertyValues(currentNode, currentNextNodeProperty, ontology)
101: .anyMatch(e -> true);
102: }
103:
104: void doStep() {
105: final Collection<OWLIndividual> nextNodes =
106: EntitySearcher.getObjectPropertyValues(currentNode, currentNextNodeProperty, ontology)
107: .collect(Collectors.toSet());
108:• if (nextNodes.isEmpty()) {
109: this.nextItem = Collections.emptyList();
110: return;
111: }
112: checkMaxSuccessors(currentNextNodeProperty, nextNodes);
113: this.previousNextNodeProperty = currentNextNodeProperty;
114: this.currentNextNodeProperty = hasNextProperty; // This just switches from hasList to hasNext
115: final OWLIndividual node = nextNodes.iterator().next();
116: checkIsNamed(node);
117: this.previousNode = currentNode;
118: this.currentNode = node;
119: this.nextItem = resolveCurrentContent();
120: }
121:
122: private Collection<? extends OWLObject> resolveCurrentContent() {
123:• if (hasContentProperty.isOWLObjectProperty()) {
124: return EntitySearcher.getObjectPropertyValues(currentNode, hasContentProperty.asOWLObjectProperty(), ontology)
125: .collect(Collectors.toSet());
126: } else {
127:• assert hasContentProperty.isOWLDataProperty();
128: return EntitySearcher.getDataPropertyValues(currentNode, hasContentProperty.asOWLDataProperty(), ontology)
129: .collect(Collectors.toSet());
130: }
131: }
132:
133: @Override
134: public Axiom<T> next() {
135: final T value = nextValue();
136: return axiomAdapter
137: .createAxiom(NamedResource.create(currentNode.asOWLNamedIndividual().getIRI().toURI()),
138: descriptor.getNodeContent(), value);
139: }
140:
141: @Override
142: T nextValue() {
143: doStep();
144:• if (nextItem.isEmpty()) {
145: throw new NoSuchElementException("There are no more elements.");
146: }
147: return extractNodeContent();
148: }
149:
150: protected T extractNodeContent() {
151: verifyContentValueCount(nextItem);
152:• if (nextItem.size() == 1) {
153: final OWLObject value = nextItem.iterator().next();
154:• if (value.isIndividual()) {
155: final OWLIndividual individual = (OWLIndividual) value;
156: checkIsNamed(individual);
157: return (T) NamedResource.create(individual.asOWLNamedIndividual().getIRI().toURI());
158: } else {
159: final OWLLiteral literal = (OWLLiteral) value;
160: return (T) OwlapiUtils.owlLiteralToValue(literal);
161: }
162: } else {
163: final MultilingualString mls = new MultilingualString();
164: nextItem.forEach(n -> {
165:• assert n instanceof OWLLiteral;
166: final OWLLiteral lit = (OWLLiteral) n;
167:• assert lit.getLang() != null;
168: mls.set(lit.getLang(), lit.getLiteral());
169: });
170: return (T) mls;
171: }
172: }
173:
174: private void verifyContentValueCount(Collection<? extends OWLObject> values) {
175:• if (values.isEmpty()) {
176: throw icViolatedException(currentNode.toStringID(), 0);
177: }
178: final Set<String> langs = new HashSet<>();
179:• if (values.size() == 1) {
180: return;
181: }
182:• for (OWLObject s : values) {
183:• if (s.isIndividual()) {
184: throw icViolatedException(currentNode.toStringID(), values.size());
185: }
186:• assert s instanceof OWLLiteral;
187: final OWLLiteral literal = (OWLLiteral) s;
188:• if (literal.getLang() != null && !langs.contains(literal.getLang())) {
189: langs.add(literal.getLang());
190: } else {
191: throw icViolatedException(currentNode.toStringID(), values.size());
192: }
193: }
194: }
195:
196: private static IntegrityConstraintViolatedException icViolatedException(String nodeId, int count) {
197: return new IntegrityConstraintViolatedException("Expected exactly one content statement for node <" + nodeId + ">, but got " + count);
198: }
199:
200: @Override
201: public NamedResource getCurrentNode() {
202: return NamedResource.create(currentNode.asOWLNamedIndividual().getIRI().toURI());
203: }
204:
205: @Override
206: List<TransactionalChange> removeWithoutReconnect() {
207: final List<TransactionalChange> changes = new ArrayList<>(2);
208: changes.add(new MutableRemoveAxiom(ontology,
209: dataFactory.getOWLObjectPropertyAssertionAxiom(previousNextNodeProperty, previousNode, currentNode)));
210: final OWLIndividual nextNode = getNextNode();
211:• if (nextNode != null) {
212: changes.add(new MutableRemoveAxiom(ontology,
213: dataFactory.getOWLObjectPropertyAssertionAxiom(currentNextNodeProperty, currentNode, nextNode)));
214: }
215: return changes;
216: }
217:
218: private OWLIndividual getNextNode() {
219: final Stream<OWLIndividual> nextOnes =
220: EntitySearcher.getObjectPropertyValues(currentNode, currentNextNodeProperty, ontology);
221: final Iterator<OWLIndividual> it = nextOnes.iterator();
222:• return it.hasNext() ? it.next() : null;
223: }
224:
225: @Override
226: List<TransactionalChange> replaceNode(T newValue) {
227: // We know there is exactly one, because nextItem has to have been called before this method
228: final List<TransactionalChange> changes;
229:• if (hasContentProperty.isOWLObjectProperty()) {
230:• assert nextItem.size() == 1;
231: final OWLObject originalContent = nextItem.iterator().next();
232: final OWLNamedIndividual newContent = OwlapiUtils.getIndividual((NamedResource) newValue, dataFactory);
233: changes = List.of(
234: new MutableRemoveAxiom(ontology, dataFactory.getOWLObjectPropertyAssertionAxiom(hasContentProperty.asOWLObjectProperty(), currentNode, (OWLIndividual) originalContent)),
235: new MutableAddAxiom(ontology, dataFactory.getOWLObjectPropertyAssertionAxiom(hasContentProperty.asOWLObjectProperty(), currentNode, newContent)));
236: } else {
237: changes = replaceDataPropertyContent(newValue);
238: }
239: return changes;
240: }
241:
242: private List<TransactionalChange> replaceDataPropertyContent(T newValue) {
243: final List<TransactionalChange> result = new ArrayList<>(nextItem.size() + 1);
244: nextItem.forEach(o -> result.add(new MutableRemoveAxiom(ontology, dataFactory.getOWLDataPropertyAssertionAxiom(hasContentProperty.asOWLDataProperty(), currentNode, (OWLLiteral) o))));
245: final ReferencedListNodeGenerator nodeGenerator = new ReferencedListNodeGenerator(descriptor, axiomAdapter, ontology);
246: result.addAll(nodeGenerator.generateNodeContent(getCurrentNode(), newValue));
247: return result;
248: }
249: }