Skip to content

Commit 746c03d

Browse files
committed
jena-owl2: rename Graphs#getBase -> Graphs#getPrimary + add Graphs#unwrap; remove UnionGraph#withBase (was useless); other changes; fix bug in UnionGraphImpl#remove
1 parent 7b4117f commit 746c03d

File tree

8 files changed

+238
-69
lines changed

8 files changed

+238
-69
lines changed

src/main/java/com/github/sszuev/jena/ontapi/OntModelFactory.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,18 @@ public static UnionGraph createUnionGraph(Graph base) {
8585
* @see org.apache.jena.rdf.model.ModelFactory#createDefaultModel()
8686
*/
8787
public static Model createDefaultModel() {
88-
return new ModelCom(createDefaultGraph());
88+
return createDefaultModel(createDefaultGraph());
89+
}
90+
91+
/**
92+
* Creates default RDF Model implementation wrapping the given graph.
93+
*
94+
* @param graph {@link Graph}, not {@code null}
95+
* @return {@link Model}
96+
* @see org.apache.jena.rdf.model.ModelFactory#createDefaultModel()
97+
*/
98+
public static Model createDefaultModel(Graph graph) {
99+
return new ModelCom(Objects.requireNonNull(graph));
89100
}
90101

91102
/**
@@ -245,7 +256,7 @@ public static OntModel createModel(Graph graph, OntSpecification spec, GraphRepo
245256
UnionGraph union;
246257
if (graph instanceof UnionGraph) {
247258
union = (UnionGraph) graph;
248-
Graphs.flatTree((UnionGraph) graph).forEach(it -> {
259+
Graphs.flatHierarchy((UnionGraph) graph).forEach(it -> {
249260
Graphs.findOntologyNameNode(it.getBaseGraph()).orElseGet(() -> Graphs.createOntologyHeaderNode(it, null));
250261
ontUnionGraphRepository.put(it);
251262
});
@@ -256,7 +267,7 @@ public static OntModel createModel(Graph graph, OntSpecification spec, GraphRepo
256267
.toString();
257268
repository.put(name, it);
258269
});
259-
union = ontUnionGraphRepository.put(Graphs.getBase(graph));
270+
union = ontUnionGraphRepository.put(Graphs.getPrimary(graph));
260271
}
261272
ReasonerFactory reasonerFactory = spec.getReasonerFactory();
262273
if (reasonerFactory == null) {

src/main/java/com/github/sszuev/jena/ontapi/UnionGraph.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,6 @@ public interface UnionGraph extends Graph {
8585
*/
8686
UnionGraph removeSubGraph(Graph graph);
8787

88-
/**
89-
* Creates a copy of this graph with replacement the base.
90-
* Changing hierarchy of the new graph will change hierarchy of this graph and vice versa.
91-
* This can be useful for building graph's manager.
92-
* @param base {@code Graph}, new base, not {@code null}
93-
* @return {@link UnionGraph} a new instance with new {@code base} but with the hierarchy inheriting from this graph
94-
*/
95-
UnionGraph withBase(Graph base);
96-
9788
/**
9889
* Adds the specified graph to the underlying graph collection if it is absent.
9990
*

src/main/java/com/github/sszuev/jena/ontapi/impl/UnionGraphImpl.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ public void remove(Node s, Node p, Node o) {
206206
Triple t = Triple.createMatch(s, p, o);
207207
UnionGraph.EventManager em = getEventManager();
208208
em.onDeleteTriple(this, t);
209-
base.remove(s, p, o);
209+
super.remove(s, p, o);
210210
em.notifyEvent(this, GraphEvents.remove(s, p, o));
211211
}
212212

@@ -270,11 +270,6 @@ public UnionGraph removeSubGraph(Graph graph) {
270270
return this;
271271
}
272272

273-
@Override
274-
public UnionGraph withBase(Graph base) {
275-
return new UnionGraphImpl(base, getSubGraphs(), getEventManager(), isDistinct());
276-
}
277-
278273
protected void removeUnion(Graph graph) {
279274
if (!(graph instanceof UnionGraphImpl)) {
280275
return;
@@ -619,12 +614,12 @@ public void notifySuperGraphAdded(UnionGraph graph, UnionGraph superGraph) {
619614

620615
@Override
621616
public void onRemoveSubGraph(UnionGraph graph, Graph subGraph) {
622-
listeners(Listener.class).forEach(it -> it.onRemoveSubGraph(graph, graph));
617+
listeners(Listener.class).forEach(it -> it.onRemoveSubGraph(graph, subGraph));
623618
}
624619

625620
@Override
626621
public void notifySubGraphRemoved(UnionGraph graph, Graph subGraph) {
627-
listeners(Listener.class).forEach(it -> it.notifySubGraphRemoved(graph, graph));
622+
listeners(Listener.class).forEach(it -> it.notifySubGraphRemoved(graph, subGraph));
628623
}
629624

630625
@Override

src/main/java/com/github/sszuev/jena/ontapi/impl/repositories/OntUnionGraphListener.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ public void onDeleteTriple(UnionGraph graph, Triple triple) {
6262

6363
@Override
6464
public void onAddSubGraph(UnionGraph graph, Graph subGraph) {
65-
if (Graphs.isOntGraph(Graphs.getBase(subGraph))) {
66-
Node ontology = Graphs.findOntologyNameNode(Graphs.getBase(subGraph))
65+
if (Graphs.isOntGraph(Graphs.getPrimary(subGraph))) {
66+
Node ontology = Graphs.findOntologyNameNode(Graphs.getPrimary(subGraph))
6767
.orElseThrow(() -> new OntJenaException.IllegalArgument("Unnamed or misconfigured graph is specified"));
6868
if (!ontology.isURI()) {
6969
throw new OntJenaException.IllegalArgument("Anonymous graph specified");
@@ -80,7 +80,7 @@ public void onClear(UnionGraph graph) {
8080

8181
@Override
8282
public void notifySubGraphAdded(UnionGraph thisGraph, Graph subGraph) {
83-
if (Graphs.isOntGraph(Graphs.getBase(subGraph))) {
83+
if (Graphs.isOntGraph(Graphs.getPrimary(subGraph))) {
8484
Graph ontSubGraphBase = OntUnionGraphRepository.getBase(subGraph);
8585
Node ontSubGraphIri = Graphs.findOntologyNameNode(ontSubGraphBase)
8686
.filter(Node::isURI)

src/main/java/com/github/sszuev/jena/ontapi/utils/Graphs.java

Lines changed: 107 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
import org.apache.jena.graph.Triple;
1111
import org.apache.jena.graph.compose.Dyadic;
1212
import org.apache.jena.graph.compose.Polyadic;
13+
import org.apache.jena.graph.impl.WrappedGraph;
1314
import org.apache.jena.mem.GraphMem;
1415
import org.apache.jena.reasoner.InfGraph;
1516
import org.apache.jena.shared.PrefixMapping;
17+
import org.apache.jena.sparql.graph.GraphWrapper;
1618
import org.apache.jena.sparql.util.graph.GraphUtils;
1719
import org.apache.jena.util.iterator.ExtendedIterator;
1820
import org.apache.jena.util.iterator.NullIterator;
@@ -58,7 +60,7 @@ public class Graphs {
5860
*
5961
* @param graph {@link Graph}
6062
* @return {@code Stream} of {@link Graph}s
61-
* @see Graphs#getBase(Graph)
63+
* @see Graphs#getPrimary(Graph)
6264
* @see UnionGraph
6365
* @see Polyadic
6466
* @see Dyadic
@@ -77,12 +79,9 @@ public static Stream<Graph> directSubGraphs(Graph graph) {
7779
}
7880

7981
/**
80-
* Extracts the base (primary) base graph from a composite or wrapper graph if it is possible
82+
* Gets the base (primary) base graph from a composite or wrapper graph if it is possible
8183
* otherwise returns the same graph.
8284
* If the specified graph is {@link Dyadic}, the left part is considered as base graph.
83-
* Note: wrappers ({@link org.apache.jena.graph.impl.WrappedGraph} and {@link org.apache.jena.sparql.graph.GraphWrapper})
84-
* are intentionally not included in the consideration:
85-
* any sub-instances of that class are considered as indivisible.
8685
*
8786
* @param graph {@link Graph}
8887
* @return {@link Graph}
@@ -91,9 +90,37 @@ public static Stream<Graph> directSubGraphs(Graph graph) {
9190
* @see org.apache.jena.graph.compose.MultiUnion
9291
* @see Polyadic
9392
* @see Dyadic
93+
*/
94+
public static Graph getPrimary(Graph graph) {
95+
if (graph instanceof UnionGraph) {
96+
return ((UnionGraph) graph).getBaseGraph();
97+
}
98+
if (graph instanceof Polyadic) {
99+
return ((Polyadic) graph).getBaseGraph();
100+
}
101+
if (graph instanceof Dyadic) {
102+
return ((Dyadic) graph).getL();
103+
}
104+
return graph;
105+
}
106+
107+
/**
108+
* Unwraps the base (primary) base graph from a composite or wrapper graph if it is possible
109+
* otherwise returns the same graph.
110+
* If the specified graph is {@link Dyadic}, the left part is considered as base graph.
111+
*
112+
* @param graph {@link Graph}
113+
* @return {@link Graph}
114+
* @see #isWrapper(Graph)
115+
* @see UnionGraph
116+
* @see org.apache.jena.graph.compose.MultiUnion
117+
* @see Polyadic
118+
* @see Dyadic
94119
* @see InfGraph
120+
* @see GraphWrapper
121+
* @see WrappedGraph
95122
*/
96-
public static Graph getBase(Graph graph) {
123+
public static Graph unwrap(Graph graph) {
97124
if (isGraphMem(graph)) {
98125
return graph;
99126
}
@@ -105,6 +132,14 @@ public static Graph getBase(Graph graph) {
105132
if (!seen.add(g)) {
106133
continue;
107134
}
135+
if (g instanceof GraphWrapper) {
136+
candidates.add(((GraphWrapper) g).get());
137+
continue;
138+
}
139+
if (g instanceof WrappedGraph) {
140+
candidates.add(((WrappedGraph) g).getWrapped());
141+
continue;
142+
}
108143
if (g instanceof UnionGraph) {
109144
candidates.add(((UnionGraph) g).getBaseGraph());
110145
continue;
@@ -125,6 +160,22 @@ public static Graph getBase(Graph graph) {
125160
return graph;
126161
}
127162

163+
/**
164+
* Answers {@code true} if the given graph can be unwrapped.
165+
*
166+
* @param g {@link Graph}
167+
* @return boolean
168+
* @see #unwrap(Graph)
169+
*/
170+
public static boolean isWrapper(Graph g) {
171+
return g instanceof GraphWrapper ||
172+
g instanceof WrappedGraph ||
173+
g instanceof UnionGraph ||
174+
g instanceof Polyadic ||
175+
g instanceof Dyadic ||
176+
g instanceof InfGraph;
177+
}
178+
128179
/**
129180
* Answers {@code true} if the graph specified is {@code GraphMem}.
130181
*
@@ -154,6 +205,20 @@ public static boolean isGraphInf(Graph graph) {
154205
* @return {@code Stream} of {@link Graph}s
155206
*/
156207
public static Stream<Graph> dataGraphs(Graph graph) {
208+
return flatTree(graph, Graphs::unwrap, Graphs::directSubGraphs);
209+
}
210+
211+
/**
212+
* Lists all indivisible data graphs extracted from the composite or wrapper graph;
213+
*
214+
* @param graph {@link Graph}
215+
* @param getBase a {@link Function} to extract primary graph
216+
* @param listSubGraphs a {@link Function} to extract subgraphs
217+
* @return {@code Stream} of {@link Graph}s
218+
*/
219+
public static Stream<Graph> flatTree(Graph graph,
220+
Function<Graph, Graph> getBase,
221+
Function<Graph, Stream<Graph>> listSubGraphs) {
157222
if (graph == null) {
158223
return Stream.empty();
159224
}
@@ -169,9 +234,9 @@ public static Stream<Graph> dataGraphs(Graph graph) {
169234
if (!seen.add(g)) {
170235
continue;
171236
}
172-
Graph bg = getBase(g);
237+
Graph bg = getBase.apply(g);
173238
res.add(bg);
174-
directSubGraphs(g).forEach(queue::add);
239+
listSubGraphs.apply(g).forEach(queue::add);
175240
}
176241
return res.stream();
177242
}
@@ -184,7 +249,7 @@ public static Stream<Graph> dataGraphs(Graph graph) {
184249
* @return {@code boolean}
185250
*/
186251
public static boolean isSameBase(Graph left, Graph right) {
187-
return Objects.equals(getBase(left), getBase(right));
252+
return Objects.equals(unwrap(left), unwrap(right));
188253
}
189254

190255
/**
@@ -203,7 +268,7 @@ public static boolean isDistinct(Graph graph) {
203268
}
204269
if (graph instanceof UnionGraph) {
205270
UnionGraph u = (UnionGraph) graph;
206-
return u.isDistinct() || !u.hasSubGraph() && isDistinct(getBase(u));
271+
return u.isDistinct() || !u.hasSubGraph() && isDistinct(getPrimary(u));
207272
}
208273
return false;
209274
}
@@ -226,7 +291,7 @@ public static boolean isSized(Graph graph) {
226291
if (directSubGraphs(graph).findFirst().isPresent()) {
227292
return false;
228293
}
229-
return isGraphMem(getBase(graph));
294+
return isGraphMem(getPrimary(graph));
230295
}
231296

232297
/**
@@ -243,7 +308,7 @@ public static long size(Graph graph) {
243308
if (directSubGraphs(graph).findFirst().isPresent()) {
244309
return Iterators.count(graph.find());
245310
}
246-
return getBase(graph).size();
311+
return getPrimary(graph).size();
247312
}
248313

249314
/**
@@ -262,7 +327,7 @@ public static UnionGraph makeOntUnionFrom(Graph graph, Function<Graph, UnionGrap
262327
if (isGraphMem(graph)) {
263328
return wrapAsUnion.apply(graph);
264329
}
265-
return makeOntUnion(getBase(graph), dataGraphs(graph).collect(Collectors.toSet()), wrapAsUnion);
330+
return makeOntUnion(getPrimary(graph), dataGraphs(graph).collect(Collectors.toSet()), wrapAsUnion);
266331
}
267332

268333
/**
@@ -314,14 +379,14 @@ public static UnionGraph makeOntUnion(Graph graph,
314379
}
315380

316381
/**
317-
* Lists all graphs in the tree which is specified as {@code UnionGraph}.
382+
* Lists all graphs in the tree that is specified as {@code UnionGraph}.
318383
*
319384
* @param graph {@link UnionGraph}
320385
* @return {@code Stream} of {@link UnionGraph}s
321386
* @see UnionGraph#superGraphs()
322387
* @see UnionGraph#subGraphs()
323388
*/
324-
public static Stream<UnionGraph> flatTree(UnionGraph graph) {
389+
public static Stream<UnionGraph> flatHierarchy(UnionGraph graph) {
325390
Objects.requireNonNull(graph);
326391
Set<UnionGraph> res = new LinkedHashSet<>();
327392
Deque<UnionGraph> queue = new ArrayDeque<>();
@@ -415,21 +480,40 @@ public static Node createOntologyHeaderNode(Graph graph, String uriOrNull) {
415480
}
416481

417482
/**
418-
* Creates a new ontology header ({@code node rdf:type owl:Ontology}) for the specified node,
483+
* Creates (if absents) a new ontology header ({@code node rdf:type owl:Ontology}) for the specified node,
419484
* removing existing ontology headers (if any) and moving their contents to the new header.
485+
* Note that a valid ontology must have a single header,
486+
* but there could be multiple headers in imports closure.
420487
*
421488
* @param graph {@link Graph}
422489
* @param newOntology {@link Node} the new ontology header (iri or blank)
423490
* @return {@code newOntology}
424491
*/
425492
public static Node makeOntologyHeaderNode(Graph graph, Node newOntology) {
426-
List<Triple> prev = Iterators.addAll(Iterators.flatMap(
493+
Objects.requireNonNull(graph, "graph is null");
494+
Objects.requireNonNull(newOntology, "ontology node is null");
495+
Set<Triple> prev = Iterators.addAll(Iterators.flatMap(
427496
graph.find(Node.ANY, RDF.type.asNode(), OWL.Ontology.asNode()),
428-
it -> graph.find(it.getSubject(), Node.ANY, Node.ANY)), new ArrayList<>());
429-
430-
prev.forEach(graph::delete);
431-
graph.add(newOntology, RDF.type.asNode(), OWL.Ontology.asNode());
432-
prev.forEach(triple -> graph.add(newOntology, triple.getPredicate(), triple.getObject()));
497+
it -> graph.find(it.getSubject(), Node.ANY, Node.ANY)), new HashSet<>());
498+
Set<Node> subjects = prev.stream().map(Triple::getSubject).collect(Collectors.toSet());
499+
if (subjects.contains(newOntology)) {
500+
if (subjects.size() == 1) {
501+
// nothing to do
502+
return newOntology;
503+
}
504+
} else {
505+
graph.add(newOntology, RDF.type.asNode(), OWL.Ontology.asNode());
506+
}
507+
prev.forEach(t -> {
508+
if (!newOntology.equals(t.getSubject())) {
509+
graph.delete(t);
510+
}
511+
});
512+
prev.forEach(t -> {
513+
if (!newOntology.equals(t.getSubject())) {
514+
graph.add(newOntology, t.getPredicate(), t.getObject());
515+
}
516+
});
433517
return newOntology;
434518
}
435519

@@ -713,7 +797,7 @@ public static Node createNode(String iri) {
713797
}
714798

715799
/**
716-
* Answers {@code true} if all parts of the given RDF triple are URIs (i.e. not blank nodes or literals).
800+
* Answers {@code true} if all parts of the given RDF triple are URIs (i.e., not blank nodes or literals).
717801
*
718802
* @param triple a regular graph {@link Triple}, not {@code null}
719803
* @return {@code boolean}

0 commit comments

Comments
 (0)