1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.rdf.api;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Optional;
32 import java.util.concurrent.ConcurrentHashMap;
33 import java.util.stream.Stream;
34
35 import org.junit.Assume;
36 import org.junit.Before;
37 import org.junit.Test;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public abstract class AbstractGraphTest {
54
55 protected RDF factory;
56 protected Graph graph;
57 protected IRI alice;
58 protected IRI bob;
59 protected IRI name;
60 protected IRI knows;
61 protected IRI member;
62 protected BlankNode bnode1;
63 protected BlankNode bnode2;
64 protected Literal aliceName;
65 protected Literal bobName;
66 protected Literal secretClubName;
67 protected Literal companyName;
68 protected Triple bobNameTriple;
69
70
71
72
73
74
75
76
77 protected abstract RDF createFactory();
78
79 @Before
80 public void createGraphAndAdd() {
81 factory = createFactory();
82 graph = factory.createGraph();
83 assertEquals(0, graph.size());
84
85 alice = factory.createIRI("http://example.com/alice");
86 bob = factory.createIRI("http://example.com/bob");
87 name = factory.createIRI("http://xmlns.com/foaf/0.1/name");
88 knows = factory.createIRI("http://xmlns.com/foaf/0.1/knows");
89 member = factory.createIRI("http://xmlns.com/foaf/0.1/member");
90 try {
91 bnode1 = factory.createBlankNode("org1");
92 bnode2 = factory.createBlankNode("org2");
93 } catch (final UnsupportedOperationException ex) {
94
95 }
96
97 try {
98 secretClubName = factory.createLiteral("The Secret Club");
99 companyName = factory.createLiteral("A company");
100 aliceName = factory.createLiteral("Alice");
101 bobName = factory.createLiteral("Bob", "en-US");
102 } catch (final UnsupportedOperationException ex) {
103
104 }
105
106 if (aliceName != null) {
107 graph.add(alice, name, aliceName);
108 }
109 graph.add(alice, knows, bob);
110
111 if (bnode1 != null) {
112 graph.add(alice, member, bnode1);
113 }
114
115 if (bobName != null) {
116 try {
117 bobNameTriple = factory.createTriple(bob, name, bobName);
118 } catch (final UnsupportedOperationException ex) {
119
120 }
121 if (bobNameTriple != null) {
122 graph.add(bobNameTriple);
123 }
124 }
125 if (bnode1 != null) {
126 graph.add(factory.createTriple(bob, member, bnode1));
127 graph.add(factory.createTriple(bob, member, bnode2));
128 if (secretClubName != null) {
129 graph.add(bnode1, name, secretClubName);
130 graph.add(bnode2, name, companyName);
131 }
132 }
133 }
134
135 @Test
136 public void size() throws Exception {
137 assertTrue(graph.size() > 0);
138 Assume.assumeNotNull(bnode1, bnode2, aliceName, bobName, secretClubName, companyName, bobNameTriple);
139
140 assertEquals(8, graph.size());
141 }
142
143 @Test
144 public void iterate() throws Exception {
145
146 Assume.assumeTrue(graph.size() > 0);
147
148 final List<Triple> triples = new ArrayList<>();
149 for (final Triple t : graph.iterate()) {
150 triples.add(t);
151 }
152 assertEquals(graph.size(), triples.size());
153 if (bobNameTriple != null) {
154 assertTrue(triples.contains(bobNameTriple));
155 }
156
157
158 final Iterable<Triple> iterate = graph.iterate();
159 final Iterator<Triple> it = iterate.iterator();
160
161 assertTrue(it.hasNext());
162 it.next();
163 closeIterable(iterate);
164
165
166
167 long count = 0;
168 final Iterable<Triple> iterable = graph.iterate();
169 for (@SuppressWarnings("unused") final
170 Triple t : iterable) {
171 count++;
172 }
173 assertEquals(graph.size(), count);
174 }
175
176
177
178
179 private void closeIterable(final Iterable<Triple> iterate) throws Exception {
180 if (iterate instanceof AutoCloseable) {
181 ((AutoCloseable) iterate).close();
182 }
183 }
184
185 @Test
186 public void iterateFilter() throws Exception {
187 final List<RDFTerm> friends = new ArrayList<>();
188 final IRI alice = factory.createIRI("http://example.com/alice");
189 final IRI knows = factory.createIRI("http://xmlns.com/foaf/0.1/knows");
190 for (final Triple t : graph.iterate(alice, knows, null)) {
191 friends.add(t.getObject());
192 }
193 assertEquals(1, friends.size());
194 assertEquals(bob, friends.get(0));
195
196
197 final Iterable<Triple> iterate = graph.iterate(bob, knows, alice);
198 for (final Triple unexpected : iterate) {
199 fail("Unexpected triple " + unexpected);
200 }
201
202 }
203
204 @Test
205 public void contains() throws Exception {
206 assertFalse(graph.contains(bob, knows, alice));
207
208 assertTrue(graph.contains(alice, knows, bob));
209
210 try (Stream<? extends Triple> stream = graph.stream()) {
211 final Optional<? extends Triple> first = stream.skip(4).findFirst();
212 Assume.assumeTrue(first.isPresent());
213 final Triple existingTriple = first.get();
214 assertTrue(graph.contains(existingTriple));
215 }
216
217 final Triple nonExistingTriple = factory.createTriple(bob, knows, alice);
218 assertFalse(graph.contains(nonExistingTriple));
219
220 Triple triple = null;
221 try {
222 triple = factory.createTriple(alice, knows, bob);
223 } catch (final UnsupportedOperationException ex) {
224 }
225 if (triple != null) {
226
227
228 }
229 }
230
231 @Test
232 public void remove() throws Exception {
233 final long fullSize = graph.size();
234 graph.remove(alice, knows, bob);
235 final long shrunkSize = graph.size();
236 assertEquals(1, fullSize - shrunkSize);
237
238 graph.remove(alice, knows, bob);
239 assertEquals(shrunkSize, graph.size());
240
241 graph.add(alice, knows, bob);
242 graph.add(alice, knows, bob);
243 graph.add(alice, knows, bob);
244
245
246 assertTrue(graph.size() > shrunkSize);
247
248
249 graph.remove(alice, knows, bob);
250 assertEquals(shrunkSize, graph.size());
251
252 Triple otherTriple;
253 try (Stream<? extends Triple> stream = graph.stream()) {
254 final Optional<? extends Triple> anyTriple = stream.findAny();
255 Assume.assumeTrue(anyTriple.isPresent());
256 otherTriple = anyTriple.get();
257 }
258
259 graph.remove(otherTriple);
260 assertEquals(shrunkSize - 1, graph.size());
261 graph.remove(otherTriple);
262 assertEquals(shrunkSize - 1, graph.size());
263
264
265 graph.add(otherTriple);
266
267
268 assertTrue(graph.size() >= shrunkSize);
269 }
270
271 @Test
272 public void clear() throws Exception {
273 graph.clear();
274 assertFalse(graph.contains(alice, knows, bob));
275 assertEquals(0, graph.size());
276 graph.clear();
277 assertEquals(0, graph.size());
278 }
279
280 @Test
281 public void getTriples() throws Exception {
282 long tripleCount;
283 try (Stream<? extends Triple> stream = graph.stream()) {
284 tripleCount = stream.count();
285 }
286 assertTrue(tripleCount > 0);
287
288 try (Stream<? extends Triple> stream = graph.stream()) {
289 assertTrue(stream.allMatch(t -> graph.contains(t)));
290 }
291
292
293 Assume.assumeNotNull(bnode1, bnode2, aliceName, bobName, secretClubName, companyName, bobNameTriple);
294 assertEquals(8, tripleCount);
295 }
296
297 @Test
298 public void getTriplesQuery() throws Exception {
299
300 try (Stream<? extends Triple> stream = graph.stream(alice, null, null)) {
301 final long aliceCount = stream.count();
302 assertTrue(aliceCount > 0);
303 Assume.assumeNotNull(aliceName);
304 assertEquals(3, aliceCount);
305 }
306
307 Assume.assumeNotNull(bnode1, bnode2, bobName, companyName, secretClubName);
308 try (Stream<? extends Triple> stream = graph.stream(null, name, null)) {
309 assertEquals(4, stream.count());
310 }
311 Assume.assumeNotNull(bnode1);
312 try (Stream<? extends Triple> stream = graph.stream(null, member, null)) {
313 assertEquals(3, stream.count());
314 }
315 }
316
317 @Test
318 public void addBlankNodesFromMultipleGraphs() {
319
320 try {
321
322 final Graph g1 = createGraph1();
323 final Graph g2 = createGraph2();
324
325
326 final Graph g3 = factory.createGraph();
327 addAllTriples(g1, g3);
328 addAllTriples(g2, g3);
329
330
331
332
333
334
335 final Map<String, BlankNodeOrIRI> whoIsWho = new ConcurrentHashMap<>();
336
337
338
339
340
341 final IRI name = factory.createIRI("http://xmlns.com/foaf/0.1/name");
342 try (Stream<? extends Triple> stream = g3.stream(null, name, null)) {
343 stream.parallel().forEach(t -> whoIsWho.put(t.getObject().ntriplesString(), t.getSubject()));
344 }
345
346 assertEquals(4, whoIsWho.size());
347
348 assertEquals(4, new HashSet<>(whoIsWho.values()).size());
349
350 final BlankNodeOrIRI b1Alice = whoIsWho.get("\"Alice\"");
351 assertNotNull(b1Alice);
352 final BlankNodeOrIRI b2Bob = whoIsWho.get("\"Bob\"");
353 assertNotNull(b2Bob);
354 final BlankNodeOrIRI b1Charlie = whoIsWho.get("\"Charlie\"");
355 assertNotNull(b1Charlie);
356 final BlankNodeOrIRI b2Dave = whoIsWho.get("\"Dave\"");
357 assertNotNull(b2Dave);
358
359
360 notEquals(b1Alice, b2Bob);
361 notEquals(b1Alice, b1Charlie);
362 notEquals(b1Alice, b2Dave);
363 notEquals(b2Bob, b1Charlie);
364 notEquals(b2Bob, b2Dave);
365 notEquals(b1Charlie, b2Dave);
366
367
368
369 final IRI hasChild = factory.createIRI("http://example.com/hasChild");
370 assertTrue(g3.contains(b1Alice, hasChild, b2Bob));
371 assertTrue(g3.contains(b2Dave, hasChild, b1Charlie));
372
373 assertFalse(g3.contains(b1Alice, hasChild, b1Alice));
374 assertFalse(g3.contains(b1Alice, hasChild, b1Charlie));
375 assertFalse(g3.contains(b1Alice, hasChild, b2Dave));
376
377 assertFalse(g3.contains(b2Dave, hasChild, b1Alice));
378 assertFalse(g3.contains(b2Dave, hasChild, b1Alice));
379
380
381 assertFalse(g3.contains(b2Bob, hasChild, null));
382 assertFalse(g3.contains(b1Charlie, hasChild, null));
383 } catch (final UnsupportedOperationException ex) {
384 Assume.assumeNoException(ex);
385 }
386 }
387
388 private void notEquals(final BlankNodeOrIRI node1, final BlankNodeOrIRI node2) {
389 assertFalse(node1.equals(node2));
390
391
392 assertFalse(node1.ntriplesString().equals(node2.ntriplesString()));
393 }
394
395
396
397
398
399
400
401
402
403
404
405
406 private void addAllTriples(final Graph source, final Graph target) {
407
408
409
410
411
412 try (Stream<? extends Triple> stream = source.stream()) {
413 stream.unordered().sequential().forEach(t -> target.add(t));
414 }
415 }
416
417
418
419
420
421 private Graph createGraph1() {
422 final RDF factory1 = createFactory();
423
424 final IRI name = factory1.createIRI("http://xmlns.com/foaf/0.1/name");
425 final Graph g1 = factory1.createGraph();
426 final BlankNode b1 = createOwnBlankNode("b1", "0240eaaa-d33e-4fc0-a4f1-169d6ced3680");
427 g1.add(b1, name, factory1.createLiteral("Alice"));
428
429 final BlankNode b2 = createOwnBlankNode("b2", "9de7db45-0ce7-4b0f-a1ce-c9680ffcfd9f");
430 g1.add(b2, name, factory1.createLiteral("Bob"));
431
432 final IRI hasChild = factory1.createIRI("http://example.com/hasChild");
433 g1.add(b1, hasChild, b2);
434
435 return g1;
436 }
437
438
439
440
441
442
443
444
445
446 private BlankNode createOwnBlankNode(final String name, final String uuid) {
447 return new BlankNode() {
448 @Override
449 public String ntriplesString() {
450 return "_: " + name;
451 }
452
453 @Override
454 public String uniqueReference() {
455 return uuid;
456 }
457
458 @Override
459 public int hashCode() {
460 return uuid.hashCode();
461 }
462
463 @Override
464 public boolean equals(final Object obj) {
465 if (!(obj instanceof BlankNode)) {
466 return false;
467 }
468 final BlankNode other = (BlankNode) obj;
469 return uuid.equals(other.uniqueReference());
470 }
471 };
472 }
473
474 private Graph createGraph2() {
475 final RDF factory2 = createFactory();
476 final IRI name = factory2.createIRI("http://xmlns.com/foaf/0.1/name");
477
478 final Graph g2 = factory2.createGraph();
479
480 final BlankNode b1 = createOwnBlankNode("b1", "bc8d3e45-a08f-421d-85b3-c25b373abf87");
481 g2.add(b1, name, factory2.createLiteral("Charlie"));
482
483 final BlankNode b2 = createOwnBlankNode("b2", "2209097a-5078-4b03-801a-6a2d2f50d739");
484 g2.add(b2, name, factory2.createLiteral("Dave"));
485
486 final IRI hasChild = factory2.createIRI("http://example.com/hasChild");
487
488 g2.add(b2, hasChild, b1);
489 return g2;
490 }
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509 @Test
510 public void whyJavaStreamsMightNotTakeOverFromSparql() throws Exception {
511 Assume.assumeNotNull(bnode1, bnode2, secretClubName);
512
513 try (Stream<? extends Triple> stream = graph.stream(null, knows, null)) {
514 assertEquals("\"The Secret Club\"",
515
516 stream.filter(t -> !graph.contains((BlankNodeOrIRI) t.getObject(), knows, t.getSubject()))
517 .map(knowsTriple -> {
518 try (Stream<? extends Triple> memberOf = graph
519
520
521 .stream((BlankNodeOrIRI) knowsTriple.getObject(), member, null)) {
522 return memberOf
523
524
525 .filter(memberTriple -> graph.contains(knowsTriple.getSubject(), member,
526
527 memberTriple.getObject()))
528 .findFirst().get().getObject();
529 }
530 })
531
532 .map(org -> {
533 try (Stream<? extends Triple> orgName = graph.stream((BlankNodeOrIRI) org, name,
534 null)) {
535 return orgName.findFirst().get().getObject().ntriplesString();
536 }
537 }).findFirst().get());
538 }
539 }
540 }