1 package eu.fbk.dkm.pikes.kv;
2
3 import java.util.Collection;
4 import java.util.List;
5 import java.util.Objects;
6 import java.util.Set;
7 import java.util.function.Predicate;
8
9 import javax.annotation.Nullable;
10
11 import com.google.common.collect.ImmutableSet;
12 import com.google.common.collect.Lists;
13 import com.google.common.collect.Sets;
14
15 import org.eclipse.rdf4j.model.Statement;
16 import org.eclipse.rdf4j.model.Value;
17 import org.eclipse.rdf4j.rio.RDFHandler;
18 import org.eclipse.rdf4j.rio.RDFHandlerException;
19
20 import eu.fbk.rdfpro.AbstractRDFHandlerWrapper;
21 import eu.fbk.rdfpro.RDFHandlers;
22 import eu.fbk.rdfpro.util.QuadModel;
23
24 public interface KeyQuadSource {
25
26 default QuadModel get(final Value key) {
27 Objects.requireNonNull(key);
28 final QuadModel model = QuadModel.create();
29 get(key, model);
30 return model;
31 }
32
33 boolean get(Value key, RDFHandler handler) throws RDFHandlerException;
34
35 default boolean get(final Value key, final Collection<Statement> model) {
36 Objects.requireNonNull(key);
37 Objects.requireNonNull(model);
38 try {
39 return get(key, RDFHandlers.wrap(model));
40 } catch (final RDFHandlerException ex) {
41 throw new Error(ex);
42 }
43 }
44
45 default QuadModel getAll(final Iterable<? extends Value> keys) {
46 Objects.requireNonNull(keys);
47 final QuadModel model = QuadModel.create();
48 getAll(keys, model);
49 return model;
50 }
51
52 default int getAll(final Iterable<? extends Value> keys, final RDFHandler handler)
53 throws RDFHandlerException {
54 Objects.requireNonNull(keys);
55 Objects.requireNonNull(handler);
56 int result = 0;
57 for (final Value key : keys instanceof Set ? keys : ImmutableSet.copyOf(keys)) {
58 final boolean found = get(key, handler);
59 result += found ? 1 : 0;
60 }
61 return result;
62 }
63
64 default int getAll(final Iterable<? extends Value> keys, final Collection<Statement> model) {
65 Objects.requireNonNull(keys);
66 Objects.requireNonNull(model);
67 try {
68 return getAll(keys, RDFHandlers.wrap(model));
69 } catch (final RDFHandlerException ex) {
70 throw new Error(ex);
71 }
72 }
73
74 default QuadModel getRecursive(final Iterable<? extends Value> keys,
75 @Nullable final Predicate<Value> matcher) {
76 Objects.requireNonNull(keys);
77 final QuadModel model = QuadModel.create();
78 getRecursive(keys, matcher, model);
79 return model;
80 }
81
82 default int getRecursive(final Iterable<? extends Value> keys,
83 @Nullable final Predicate<Value> matcher, final RDFHandler handler)
84 throws RDFHandlerException {
85
86 Objects.requireNonNull(keys);
87
88 final Set<Value> visited = Sets.newHashSet();
89 final List<Value> queue = Lists.newLinkedList(keys);
90
91 final RDFHandler sink = new AbstractRDFHandlerWrapper(handler) {
92
93 @Override
94 public void handleStatement(final Statement stmt) throws RDFHandlerException {
95 super.handleStatement(stmt);
96 enqueueIfMatches(stmt.getSubject());
97 enqueueIfMatches(stmt.getPredicate());
98 enqueueIfMatches(stmt.getObject());
99 enqueueIfMatches(stmt.getContext());
100 }
101
102 private void enqueueIfMatches(@Nullable final Value value) {
103 if (value != null && (matcher == null || matcher.test(value))) {
104 queue.add(value);
105 }
106 }
107
108 };
109
110 int result = 0;
111 while (!queue.isEmpty()) {
112 final Value key = queue.remove(0);
113 if (visited.add(key)) {
114 final boolean found = get(key, sink);
115 result += found ? 1 : 0;
116 }
117 }
118 return result;
119 }
120
121 default int getRecursive(final Iterable<? extends Value> keys,
122 @Nullable final Predicate<Value> matcher, final Collection<Statement> model) {
123 Objects.requireNonNull(keys);
124 Objects.requireNonNull(model);
125 try {
126 return getRecursive(keys, matcher, RDFHandlers.wrap(model));
127 } catch (final RDFHandlerException ex) {
128 throw new Error(ex);
129 }
130 }
131
132 }