Package: ReferencedListHandler
ReferencedListHandler
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ReferencedListHandler(OwlapiAdapter, OntologySnapshot) |
|
|
|
|
|
||||||||||||||||||||
addNewNodes(ReferencedListValueDescriptor, int, NamedResource) |
|
|
|
|
|
||||||||||||||||||||
createListAxioms(ReferencedListValueDescriptor) |
|
|
|
|
|
||||||||||||||||||||
isOrigEmpty(ReferencedListValueDescriptor) |
|
|
|
|
|
||||||||||||||||||||
iterator(ListDescriptor) |
|
|
|
|
|
||||||||||||||||||||
loadList(ReferencedListDescriptor) |
|
|
|
|
|
||||||||||||||||||||
mergeLists(ReferencedListValueDescriptor) |
|
|
|
|
|
||||||||||||||||||||
persistList(ReferencedListValueDescriptor) |
|
|
|
|
|
||||||||||||||||||||
removeObsoleteNodes(ReferencedListIterator) |
|
|
|
|
|
||||||||||||||||||||
static {...} |
|
|
|
|
|
||||||||||||||||||||
updateList(ReferencedListValueDescriptor) |
|
|
|
|
|
||||||||||||||||||||
verifyNotRdfList(ReferencedListValueDescriptor) |
|
|
|
|
|
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.ListDescriptor;
21: import cz.cvut.kbss.ontodriver.descriptor.ReferencedListDescriptor;
22: import cz.cvut.kbss.ontodriver.descriptor.ReferencedListValueDescriptor;
23: import cz.cvut.kbss.ontodriver.model.Axiom;
24: import cz.cvut.kbss.ontodriver.model.NamedResource;
25: import cz.cvut.kbss.ontodriver.owlapi.AxiomAdapter;
26: import cz.cvut.kbss.ontodriver.owlapi.OwlapiAdapter;
27: import cz.cvut.kbss.ontodriver.owlapi.change.TransactionalChange;
28: import cz.cvut.kbss.ontodriver.owlapi.connector.OntologySnapshot;
29: import org.semanticweb.owlapi.model.OWLOntology;
30:
31: import java.util.ArrayList;
32: import java.util.List;
33:
34: public class ReferencedListHandler {
35:
36: static final int NEXT_NODE_GENERATION_THRESHOLD = 100;
37:
38: protected final OwlapiAdapter owlapiAdapter;
39: protected final AxiomAdapter axiomAdapter;
40:
41: protected final OWLOntology ontology;
42:
43: protected final OntologySnapshot snapshot;
44:
45: public ReferencedListHandler(OwlapiAdapter owlapiAdapter, OntologySnapshot snapshot) {
46: this.owlapiAdapter = owlapiAdapter;
47: this.axiomAdapter = new AxiomAdapter(snapshot.getDataFactory());
48: this.snapshot = snapshot;
49: this.ontology = snapshot.getOntology();
50: }
51:
52: public List<Axiom<?>> loadList(ReferencedListDescriptor descriptor) {
53: final List<Axiom<?>> list = new ArrayList<>();
54: final ReferencedListIterator<?> iterator = iterator(descriptor);
55:• while (iterator.hasNext()) {
56: list.add(iterator.next());
57: }
58: return list;
59: }
60:
61: public <V> void persistList(ReferencedListValueDescriptor<V> descriptor) {
62:• if (descriptor.getValues().isEmpty()) {
63: return;
64: }
65: verifyNotRdfList(descriptor);
66: owlapiAdapter.addTransactionalChanges(snapshot.applyChanges(createListAxioms(descriptor)));
67: }
68:
69: /**
70: * OWL does no support RDF lists because it uses them internally, and it would not be possible to distinguish
71: * internal RDF lists from user-defined ones.
72: *
73: * @param descriptor Value descriptor
74: * @throws IllegalArgumentException When the descriptor describes an RDF list terminated by RDF nil
75: */
76: private static void verifyNotRdfList(ReferencedListValueDescriptor<?> descriptor) {
77:• if (descriptor.isTerminatedByNil()) {
78: throw new IllegalArgumentException("RDF nil-terminated lists are not supported by the OWL API driver.");
79: }
80: }
81:
82: <V> ReferencedListIterator<V> iterator(ListDescriptor descriptor) {
83:• assert descriptor instanceof ReferencedListDescriptor;
84:
85: final ReferencedListDescriptor desc = (ReferencedListDescriptor) descriptor;
86:• if (desc.getListProperty().isInferred() || desc.getNextNode().isInferred() ||
87:• desc.getNodeContent().isInferred()) {
88: return new InferredReferencedListIterator<>(desc, snapshot, axiomAdapter);
89: } else {
90: return new ReferencedListIterator<>(desc, snapshot, axiomAdapter);
91: }
92: }
93:
94: <V> List<TransactionalChange> createListAxioms(ReferencedListValueDescriptor<V> descriptor) {
95: final ReferencedListNodeGenerator nodeGenerator = new ReferencedListNodeGenerator(descriptor, axiomAdapter, ontology);
96: NamedResource previousNode = descriptor.getListOwner();
97: nodeGenerator.setIndex(0);
98:• for (V value : descriptor.getValues()) {
99: previousNode = nodeGenerator.addListNode(previousNode, value);
100: }
101: return nodeGenerator.getChanges();
102: }
103:
104: public <V> void updateList(ReferencedListValueDescriptor<V> descriptor) {
105:• if (descriptor.getValues().isEmpty()) {
106: removeObsoleteNodes(iterator(descriptor));
107:• } else if (isOrigEmpty(descriptor)) {
108: persistList(descriptor);
109: } else {
110: verifyNotRdfList(descriptor);
111: mergeLists(descriptor);
112: }
113: }
114:
115: <V> boolean isOrigEmpty(ReferencedListValueDescriptor<V> descriptor) {
116: final ReferencedListIterator<V> it = iterator(descriptor);
117:• return !it.hasNext();
118: }
119:
120: <V> void addNewNodes(ReferencedListValueDescriptor<V> descriptor, int index, NamedResource lastNode) {
121:• if (index >= descriptor.getValues().size()) {
122: return;
123: }
124: final ReferencedListNodeGenerator nodeGenerator = new ReferencedListNodeGenerator(descriptor, axiomAdapter, ontology);
125: nodeGenerator.setIndex(index);
126:• for (; index < descriptor.getValues().size(); index++) {
127: final V nextValue = descriptor.getValues().get(index);
128: lastNode = nodeGenerator.addListNode(lastNode, nextValue);
129: }
130: owlapiAdapter.addTransactionalChanges(snapshot.applyChanges(nodeGenerator.getChanges()));
131: }
132:
133: private <V> void mergeLists(ReferencedListValueDescriptor<V> descriptor) {
134: final ReferencedListIterator<V> it = iterator(descriptor);
135: final List<V> values = descriptor.getValues();
136: final List<TransactionalChange> changes = new ArrayList<>(values.size());
137: int i = 0;
138: NamedResource lastNode = null;
139:• while (it.hasNext() && i < values.size()) {
140: final V newValue = values.get(i);
141: final V currentValue = it.nextValue();
142:• if (!newValue.equals(currentValue)) {
143: changes.addAll(snapshot.applyChanges(it.replaceNode(newValue)));
144: }
145: lastNode = it.getCurrentNode();
146: i++;
147: }
148: owlapiAdapter.addTransactionalChanges(changes);
149:• assert lastNode != null;
150: removeObsoleteNodes(it);
151: addNewNodes(descriptor, i, lastNode);
152: }
153:
154: private <V> void removeObsoleteNodes(ReferencedListIterator<V> iterator) {
155:• if (!iterator.hasNext()) {
156: return;
157: }
158: final List<TransactionalChange> changes = new ArrayList<>();
159:• while (iterator.hasNext()) {
160: iterator.next();
161: changes.addAll(iterator.removeWithoutReconnect());
162: }
163: owlapiAdapter.addTransactionalChanges(snapshot.applyChanges(changes));
164: }
165:
166: }