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
ExtractionContextBlocker$1
N/A
N/A
2.56
ExtractionContextBlocker$ValvedTriplePipe
0%
0/60
0%
0/18
2.56
ExtractionContextBlocker$ValvedTriplePipeException
0%
0/10
N/A
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  
 }