package org.aksw.jena_sparql_api.core; import java.io.Closeable; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.jena.query.QuerySolution; import org.apache.jena.query.ResultSet; import org.apache.jena.sparql.engine.binding.Binding; /** * @author Claus Stadler * <p/> * Date: 7/23/11 * Time: 10:54 PM * * Unlike JCDB, Jena does not provide the close method on the ResultSet, but on the object that * created the result set. Therefore: * * */ public class ResultSetClose extends ResultSetDecorator implements Closeable { private static final Logger logger = LoggerFactory.getLogger(ResultSetClose.class); private boolean isClosed = false; private boolean closeOnException = true; public ResultSetClose(ResultSet decoratee, boolean skipCheckClose) { super(decoratee); if(!skipCheckClose) { checkClose(); } } public ResultSetClose(ResultSet decoratee, boolean isClosed, boolean skipCheckClose) { super(decoratee); this.isClosed = isClosed; if(!skipCheckClose) { checkClose(); } } public ResultSetClose(ResultSet decoratee, boolean isClosed, boolean closeOnException, boolean skipCheckClose) { super(decoratee); this.isClosed = isClosed; this.closeOnException = closeOnException; if(!skipCheckClose) { checkClose(); } } /* public ResultSetClose(ResultSet decoratee, IClosable closable) { super(decoratee); //this.closable = closable; checkClose(); } */ protected boolean checkClose() { if(!isClosed) { boolean hasNext; // If an exception occurs, still try to close first Exception tmp = null; try { hasNext = decoratee.hasNext(); } catch(Exception e) { hasNext = false; tmp = e; } if(!hasNext) { try { isClosed = true ; close(); } catch(Exception e) { logger.error("Error closing an object supposedly underlying a Jena ResultSet", e); } } if(tmp != null) { throw new RuntimeException(tmp); } } return isClosed; } @Override public boolean hasNext() { return !checkClose(); } @Override public void remove() { decoratee.remove(); checkClose(); } @Override public QuerySolution nextSolution() { try { QuerySolution result = decoratee.nextSolution(); checkClose(); return result; } catch(Exception e) { if(closeOnException) { try { close(); } catch(Exception f) { throw new RuntimeException(f); } } throw new RuntimeException(e); } } @Override public Binding nextBinding() { try { Binding result = decoratee.nextBinding(); checkClose(); return result; } catch(Exception e) { if(closeOnException) { try { close(); } catch(Exception f) { throw new RuntimeException(f); } } throw new RuntimeException(e); } } @Override public void close() throws IOException { if(!isClosed) { if(decoratee instanceof Closeable) { Closeable closeable = (Closeable)decoratee; closeable.close(); isClosed = true; } } } }