##### Coverage Report - org.apache.any23.filter.ExtractionContextBlocker

Classes in this File | Line Coverage | Branch Coverage | Complexity
ExtractionContextBlocker |
0% | 0/55
0% | 0/8
| 2.56;2.56
ExtractionContextBlocker$1 |
N/A | N/A
N/A | N/A
| 2.56;2.56
ExtractionContextBlocker$ValvedTriplePipe |
0% | 0/60
0% | 0/18
| 2.56;2.56
ExtractionContextBlocker$ValvedTriplePipeException |
0% | 0/10
N/A | N/A
| 2.56;2.56

1 |  |
     /*
2 |  |
      * Licensed to the Apache Software Foundation (ASF) under one or more
3 |  |
      * contributor license agreements.  See the NOTICE file distributed with
4 |  |
      * this work for additional information regarding copyright ownership.
5 |  |
      * The ASF licenses this file to You under the Apache License, Version 2.0
6 |  |
      * (the "License"); you may not use this file except in compliance with
7 |  |
      * the License.  You may obtain a copy of the License at
8 |  |
      *
9 |  |
      *  http://www.apache.org/licenses/LICENSE-2.0
10 |  |
      *
11 |  |
      * Unless required by applicable law or agreed to in writing, software
12 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
13 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 |  |
      * See the License for the specific language governing permissions and
15 |  |
      * limitations under the License.
16 |  |
      */
17 |  |
18 |  |
     package org.apache.any23.filter;
19 |  |
20 |  |
     import org.apache.any23.extractor.ExtractionContext;
21 |  |
     import org.apache.any23.writer.TripleHandler;
22 |  |
     import org.apache.any23.writer.TripleHandlerException;
23 |  |
     import org.openrdf.model.Resource;
24 |  |
     import org.openrdf.model.URI;
25 |  |
     import org.openrdf.model.Value;
26 |  |
27 |  |
     import java.util.ArrayList;
28 |  |
     import java.util.HashMap;
29 |  |
     import java.util.List;
30 |  |
     import java.util.Map;
31 |  |
32 |  |
     /**
33 |  |
      * A wrapper around a {@link TripleHandler} that can block and unblock
34 |  |
      * calls to the handler, either for the entire document, or for
35 |  |
      * individual {@link ExtractionContext}s. A document is initially
36 |  |
      * blocked and must be explicitly unblocked. Contexts are initially
37 |  |
      * unblocked and must be explicitly blocked. Unblocking a document
38 |  |
      * unblocks all contexts as well.
39 |  |
      * This class it thread-safe.
40 |  |
      *
41 |  |
      * @author Richard Cyganiak (richard@cyganiak.de)
42 |  |
      */
43 | 0 |
     public class ExtractionContextBlocker implements TripleHandler {
44 |  |
45 |  |
         private TripleHandler wrapped;
46 |  |
47 | 0 |
         private Map<String, ValvedTriplePipe> contextQueues = new HashMap<String, ValvedTriplePipe>();
48 |  |
49 |  |
         private boolean documentBlocked;
50 |  |
51 | 0 |
         public ExtractionContextBlocker(TripleHandler wrapped) {
52 | 0 |
             this.wrapped = wrapped;
53 | 0 |
         }
54 |  |
55 |  |
         public boolean isDocBlocked() {
56 | 0 |
             return documentBlocked;
57 |  |
         }
58 |  |
59 |  |
         public synchronized void blockContext(ExtractionContext context) {
60 | 0 |
             if (!documentBlocked) return;
61 |  |
             try {
62 | 0 |
                 contextQueues.get(context.getUniqueID()).block();
63 | 0 |
             } catch (ValvedTriplePipeException e) {
64 | 0 |
                 throw new RuntimeException("Error while blocking context", e);
65 | 0 |
             }
66 | 0 |
         }
67 |  |
68 |  |
         public synchronized void unblockContext(ExtractionContext context) {
69 |  |
             try {
70 | 0 |
                 contextQueues.get(context.getUniqueID()).unblock();
71 | 0 |
             } catch (ValvedTriplePipeException e) {
72 | 0 |
                 throw new RuntimeException("Error while unblocking context", e);
73 | 0 |
             }
74 | 0 |
         }
75 |  |
76 |  |
         public synchronized void startDocument(URI documentURI) throws TripleHandlerException {
77 | 0 |
             wrapped.startDocument(documentURI);
78 | 0 |
             documentBlocked = true;
79 | 0 |
         }
80 |  |
81 |  |
         public synchronized void openContext(ExtractionContext context) throws TripleHandlerException {
82 | 0 |
             contextQueues.put(context.getUniqueID(), new ValvedTriplePipe(context));
83 | 0 |
         }
84 |  |
85 |  |
         public synchronized void closeContext(ExtractionContext context) {
86 |  |
             // Empty. We'll close all contexts when the document is finished.
87 | 0 |
         }
88 |  |
89 |  |
         public synchronized void unblockDocument() {
90 | 0 |
             if (!documentBlocked) return;
91 | 0 |
             documentBlocked = false;
92 | 0 |
             for (ValvedTriplePipe pipe : contextQueues.values()) {
93 |  |
                 try {
94 | 0 |
                     pipe.unblock();
95 | 0 |
                 } catch (ValvedTriplePipeException e) {
96 | 0 |
                     throw new RuntimeException("Error while unblocking context", e);
97 | 0 |
                 }
98 |  |
             }
99 | 0 |
         }
100 |  |
101 |  |
         public synchronized void receiveTriple(Resource s, URI p, Value o, URI g, ExtractionContext context)
102 |  |
         throws TripleHandlerException {
103 |  |
             try {
104 | 0 |
                 contextQueues.get(context.getUniqueID()).receiveTriple(s, p, o, g);
105 | 0 |
             } catch (ValvedTriplePipeException e) {
106 | 0 |
                 throw new TripleHandlerException(
107 |  |
                         String.format("Error while receiving triple %s %s %s", s, p, o),
108 |  |
                         e
109 |  |
                 );
110 | 0 |
             }
111 | 0 |
         }
112 |  |
113 |  |
         public synchronized void receiveNamespace(String prefix, String uri, ExtractionContext context)
114 |  |
         throws TripleHandlerException {
115 |  |
             try {
116 | 0 |
                 contextQueues.get(context.getUniqueID()).receiveNamespace(prefix, uri);
117 | 0 |
             } catch (ValvedTriplePipeException e) {
118 | 0 |
                 throw new TripleHandlerException(
119 |  |
                         String.format("Error while receiving namespace %s:%s", prefix, uri),
120 |  |
                         e
121 |  |
                 );
122 | 0 |
             }
123 | 0 |
         }
124 |  |
125 |  |
         public synchronized void close() throws TripleHandlerException {
126 | 0 |
             closeDocument();
127 | 0 |
             wrapped.close();
128 | 0 |
         }
129 |  |
130 |  |
         public synchronized void endDocument(URI documentURI) throws TripleHandlerException {
131 | 0 |
             closeDocument();
132 | 0 |
             wrapped.endDocument(documentURI);
133 | 0 |
         }
134 |  |
135 |  |
         public void setContentLength(long contentLength) {
136 |  |
             // Empty.
137 | 0 |
         }
138 |  |
139 |  |
         private void closeDocument() {
140 | 0 |
             for (ValvedTriplePipe pipe : contextQueues.values()) {
141 |  |
                 try {
142 | 0 |
                     pipe.close();
143 | 0 |
                 } catch (ValvedTriplePipeException e) {
144 | 0 |
                     throw new RuntimeException("Error closing document", e);
145 | 0 |
                 }
146 |  |
             }
147 | 0 |
             contextQueues.clear();
148 | 0 |
         }
149 |  |
150 | 0 |
         private class ValvedTriplePipeException extends Exception {
151 |  |
152 | 0 |
             private ValvedTriplePipeException(String s) {
153 | 0 |
                 super(s);
154 | 0 |
             }
155 |  |
156 | 0 |
             private ValvedTriplePipeException(Throwable throwable) {
157 | 0 |
                 super(throwable);
158 | 0 |
             }
159 |  |
160 | 0 |
             private ValvedTriplePipeException(String s, Throwable throwable) {
161 | 0 |
                 super(s, throwable);
162 | 0 |
             }
163 |  |
164 |  |
         }
165 |  |
166 |  |
         private class ValvedTriplePipe {
167 |  |
168 |  |
             private final ExtractionContext context;
169 |  |
170 | 0 |
             private final List<Resource> subjects = new ArrayList<Resource>();
171 |  |
172 | 0 |
             private final List<URI> predicates = new ArrayList<URI>();
173 |  |
174 | 0 |
             private final List<Value> objects = new ArrayList<Value>();
175 |  |
176 | 0 |
             private final List<URI> graphs = new ArrayList<URI>();
177 |  |
178 | 0 |
             private final List<String> prefixes = new ArrayList<String>();
179 |  |
180 | 0 |
             private final List<String> uris = new ArrayList<String>();
181 |  |
182 | 0 |
             private boolean blocked = false;
183 |  |
184 | 0 |
             private boolean hasReceivedTriples = false;
185 |  |
186 | 0 |
             ValvedTriplePipe(ExtractionContext context) {
187 | 0 |
                 this.context = context;
188 | 0 |
             }
189 |  |
190 |  |
             void receiveTriple(Resource s, URI p, Value o, URI g) throws ValvedTriplePipeException {
191 | 0 |
                 if (blocked) {
192 | 0 |
                     subjects.add(s);
193 | 0 |
                     predicates.add(p);
194 | 0 |
                     objects.add(o);
195 | 0 |
                     graphs.add(g);
196 |  |
                 } else {
197 | 0 |
                     sendTriple(s, p, o, g);
198 |  |
                 }
199 | 0 |
             }
200 |  |
201 |  |
             void receiveNamespace(String prefix, String uri) throws ValvedTriplePipeException {
202 | 0 |
                 if (blocked) {
203 | 0 |
                     prefixes.add(prefix);
204 | 0 |
                     uris.add(uri);
205 |  |
                 } else {
206 | 0 |
                     sendNamespace(prefix, uri);
207 |  |
                 }
208 | 0 |
             }
209 |  |
210 |  |
             void block() throws ValvedTriplePipeException {
211 | 0 |
                 if (blocked) return;
212 | 0 |
                 blocked = true;
213 | 0 |
             }
214 |  |
215 |  |
             void unblock() throws ValvedTriplePipeException {
216 | 0 |
                 if (!blocked) return;
217 | 0 |
                 blocked = false;
218 | 0 |
                 for (int i = 0; i < prefixes.size(); i++) {
219 | 0 |
                     sendNamespace(prefixes.get(i), uris.get(i));
220 |  |
                 }
221 | 0 |
                 for (int i = 0; i < subjects.size(); i++) {
222 | 0 |
                     sendTriple(subjects.get(i), predicates.get(i), objects.get(i), graphs.get(i));
223 |  |
                 }
224 | 0 |
             }
225 |  |
226 |  |
             void close() throws ValvedTriplePipeException {
227 | 0 |
                 if (hasReceivedTriples) {
228 |  |
                     try {
229 | 0 |
                         wrapped.closeContext(context);
230 | 0 |
                     } catch (TripleHandlerException e) {
231 | 0 |
                         throw new ValvedTriplePipeException("Error while closing the triple hanlder", e);
232 | 0 |
                     }
233 |  |
                 }
234 | 0 |
             }
235 |  |
236 |  |
             private void sendTriple(Resource s, URI p, Value o, URI g) throws ValvedTriplePipeException {
237 | 0 |
                 if (!hasReceivedTriples) {
238 |  |
                     try {
239 | 0 |
                     wrapped.openContext(context);
240 | 0 |
                     } catch(TripleHandlerException e) {
241 | 0 |
                         throw new ValvedTriplePipeException("Error while opening the triple handler", e);
242 | 0 |
                     }
243 | 0 |
                     hasReceivedTriples = true;
244 |  |
                 }
245 |  |
                 try {
246 | 0 |
                     wrapped.receiveTriple(s, p, o, g, context);
247 | 0 |
                 } catch (TripleHandlerException e) {
248 | 0 |
                     throw new ValvedTriplePipeException("Error while opening the triple handler", e);
249 | 0 |
                 }
250 | 0 |
             }
251 |  |
252 |  |
             private void sendNamespace(String prefix, String uri) throws ValvedTriplePipeException {
253 | 0 |
                 if (!hasReceivedTriples) {
254 |  |
                     try {
255 | 0 |
                         wrapped.openContext(context);
256 | 0 |
                     } catch (TripleHandlerException e) {
257 | 0 |
                         throw new ValvedTriplePipeException("Error while sending the namespace", e);
258 | 0 |
                     }
259 | 0 |
                     hasReceivedTriples = true;
260 |  |
                 }
261 |  |
                 try {
262 | 0 |
                     wrapped.receiveNamespace(prefix, uri, context);
263 | 0 |
                 } catch (TripleHandlerException e) {
264 | 0 |
                     throw new ValvedTriplePipeException("Error while receiving the namespace", e);            }
265 | 0 |
             }
266 |  |
         }
267 |  |
268 |  |
     }