You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2013/04/05 01:32:13 UTC

svn commit: r1464792 - in /jena/trunk/jena-arq/src: main/java/com/hp/hpl/jena/query/ main/java/com/hp/hpl/jena/sparql/resultset/ test/java/com/hp/hpl/jena/sparql/resultset/

Author: rvesse
Date: Thu Apr  4 23:32:13 2013
New Revision: 1464792

URL: http://svn.apache.org/r1464792
Log:
Add a ResultSetPeekable interface which adds peek() and peekBinding() to the basic ResultSet interface
Add a ResultSetPeeking which is a wrapper around another ResultSet which adds peeking support
Makes ResultSetMem implement ResultSetPeekable
Expand result set tests to cover peeking

Added:
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeekable.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeeking.java
Modified:
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/query/ResultSetFactory.java
    jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetMem.java
    jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/resultset/TestResultSet.java

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/query/ResultSetFactory.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/query/ResultSetFactory.java?rev=1464792&r1=1464791&r2=1464792&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/query/ResultSetFactory.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/query/ResultSetFactory.java Thu Apr  4 23:32:13 2013
@@ -18,433 +18,456 @@
 
 package com.hp.hpl.jena.query;
 
-import java.io.InputStream ;
-import java.util.List ;
+import java.io.InputStream;
+import java.util.List;
 
-import org.apache.jena.atlas.logging.Log ;
+import org.apache.jena.atlas.logging.Log;
 
-import com.hp.hpl.jena.rdf.model.Model ;
-import com.hp.hpl.jena.rdf.model.ModelFactory ;
-import com.hp.hpl.jena.shared.NotFoundException ;
-import com.hp.hpl.jena.sparql.engine.QueryIterator ;
-import com.hp.hpl.jena.sparql.engine.ResultSetStream ;
-import com.hp.hpl.jena.sparql.graph.GraphFactory ;
-import com.hp.hpl.jena.sparql.resultset.* ;
-import com.hp.hpl.jena.sparql.sse.Item ;
-import com.hp.hpl.jena.sparql.sse.SSE ;
-import com.hp.hpl.jena.sparql.sse.builders.BuilderTable ;
-import com.hp.hpl.jena.util.FileManager ;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.shared.NotFoundException;
+import com.hp.hpl.jena.sparql.engine.QueryIterator;
+import com.hp.hpl.jena.sparql.engine.ResultSetStream;
+import com.hp.hpl.jena.sparql.graph.GraphFactory;
+import com.hp.hpl.jena.sparql.resultset.*;
+import com.hp.hpl.jena.sparql.sse.Item;
+import com.hp.hpl.jena.sparql.sse.SSE;
+import com.hp.hpl.jena.sparql.sse.builders.BuilderTable;
+import com.hp.hpl.jena.util.FileManager;
 
 /** ResultSetFactory - make result sets from places other than a query. */
 
-public class ResultSetFactory
-{
-    /** Load a result set from file or URL into a result set (memory backed).
+public class ResultSetFactory {
+    /**
+     * Load a result set from file or URL into a result set (memory backed).
+     * 
      * @param filenameOrURI
      * @return ResultSet
      */
-    
-    public static ResultSet load(String filenameOrURI)
-    {
-        return load(filenameOrURI, null) ; 
+
+    public static ResultSet load(String filenameOrURI) {
+        return load(filenameOrURI, null);
     }
-    
-    /** Load a result set from file or URL into a result set (memory backed).
+
+    /**
+     * Load a result set from file or URL into a result set (memory backed).
+     * 
      * @param filenameOrURI
      * @param format
      * @return ResultSet
      */
-    
-    public static ResultSet load(String filenameOrURI, ResultsFormat format)
-    {
-        if ( format == null )
-            format = ResultsFormat.guessSyntax(filenameOrURI) ;
-        
-        if ( format == null )
-        {
-            Log.warn(ResultSet.class, "Null format - defaulting to XML") ;
-            format = ResultsFormat.FMT_RS_XML ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_TEXT) )
-        {
-            Log.fatal(ResultSet.class, "Can't read a text result set") ;
-            throw new ResultSetException("Can't read a text result set") ;
-        }
-        
-        InputStream in = FileManager.get().open(filenameOrURI) ;
-        if ( in == null )
-            throw new NotFoundException("Not found: "+filenameOrURI) ;
-        return load(in, format) ;
+
+    public static ResultSet load(String filenameOrURI, ResultsFormat format) {
+        if (format == null)
+            format = ResultsFormat.guessSyntax(filenameOrURI);
+
+        if (format == null) {
+            Log.warn(ResultSet.class, "Null format - defaulting to XML");
+            format = ResultsFormat.FMT_RS_XML;
+        }
+
+        if (format.equals(ResultsFormat.FMT_TEXT)) {
+            Log.fatal(ResultSet.class, "Can't read a text result set");
+            throw new ResultSetException("Can't read a text result set");
+        }
+
+        InputStream in = FileManager.get().open(filenameOrURI);
+        if (in == null)
+            throw new NotFoundException("Not found: " + filenameOrURI);
+        return load(in, format);
     }
-    
-    /** Load a result set from input stream into a result set (memory backed).
+
+    /**
+     * Load a result set from input stream into a result set (memory backed).
+     * 
      * @param input
      * @param format
      * @return ResultSet
      */
-    
-    public static ResultSet load(InputStream input, ResultsFormat format)
-    {
-        if ( format == null )
-        {
-            Log.warn(ResultSet.class, "Null format - defaulting to XML") ;
-            format = ResultsFormat.FMT_RS_XML ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_RS_JSON) )
-            return JSONInput.fromJSON(input) ;
-        
-        if ( format.equals(ResultsFormat.FMT_RS_TSV) )
-            return TSVInput.fromTSV(input) ;
-        
-        if ( format.equals(ResultsFormat.FMT_RS_CSV) )
-            return CSVInput.fromCSV(input) ;
-        
-        if ( format.equals(ResultsFormat.FMT_RS_BIO) )
-            return BIOInput.fromBIO(input) ;
-        
-        if ( format.equals(ResultsFormat.FMT_RS_XML) )
-            return ResultSetFactory.fromXML(input) ;
-
-        if ( format.equals(ResultsFormat.FMT_TEXT) )
-        {
-            Log.warn(ResultSet.class, "Can't read a text result set") ;
-            throw new ResultSetException("Can't read a text result set") ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_RDF_XML) )
-        {
-            Model m = ModelFactory.createDefaultModel() ;
-            m.read(input, null) ;
-            return ResultSetFactory.fromRDF(m) ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_RDF_TTL) )
-        {
-            Model m = ModelFactory.createDefaultModel() ;
-            m.read(input, null, "TURTLE") ;
-            return ResultSetFactory.fromRDF(m) ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_RDF_N3) )
-        {
-            Model m = ModelFactory.createDefaultModel() ;
-            m.read(input, null, "N3") ;
-            return ResultSetFactory.fromRDF(m) ;
-        }
-
-        if ( format.equals(ResultsFormat.FMT_RDF_NT) )
-        {
-            Model m = ModelFactory.createDefaultModel() ;
-            m.read(input, null, "N-TRIPLES") ;
-            return ResultSetFactory.fromRDF(m) ;
+
+    public static ResultSet load(InputStream input, ResultsFormat format) {
+        if (format == null) {
+            Log.warn(ResultSet.class, "Null format - defaulting to XML");
+            format = ResultsFormat.FMT_RS_XML;
+        }
+
+        if (format.equals(ResultsFormat.FMT_RS_JSON))
+            return JSONInput.fromJSON(input);
+
+        if (format.equals(ResultsFormat.FMT_RS_TSV))
+            return TSVInput.fromTSV(input);
+
+        if (format.equals(ResultsFormat.FMT_RS_CSV))
+            return CSVInput.fromCSV(input);
+
+        if (format.equals(ResultsFormat.FMT_RS_BIO))
+            return BIOInput.fromBIO(input);
+
+        if (format.equals(ResultsFormat.FMT_RS_XML))
+            return ResultSetFactory.fromXML(input);
+
+        if (format.equals(ResultsFormat.FMT_TEXT)) {
+            Log.warn(ResultSet.class, "Can't read a text result set");
+            throw new ResultSetException("Can't read a text result set");
+        }
+
+        if (format.equals(ResultsFormat.FMT_RDF_XML)) {
+            Model m = ModelFactory.createDefaultModel();
+            m.read(input, null);
+            return ResultSetFactory.fromRDF(m);
+        }
+
+        if (format.equals(ResultsFormat.FMT_RDF_TTL)) {
+            Model m = ModelFactory.createDefaultModel();
+            m.read(input, null, "TURTLE");
+            return ResultSetFactory.fromRDF(m);
+        }
+
+        if (format.equals(ResultsFormat.FMT_RDF_N3)) {
+            Model m = ModelFactory.createDefaultModel();
+            m.read(input, null, "N3");
+            return ResultSetFactory.fromRDF(m);
+        }
+
+        if (format.equals(ResultsFormat.FMT_RDF_NT)) {
+            Model m = ModelFactory.createDefaultModel();
+            m.read(input, null, "N-TRIPLES");
+            return ResultSetFactory.fromRDF(m);
         }
 
-        Log.warn(ResultSet.class, "Unknown result set syntax: "+format) ;
-        return null ;
+        Log.warn(ResultSet.class, "Unknown result set syntax: " + format);
+        return null;
 
     }
-    
-    /** Load a result set (or any other model) from file or URL
+
+    /**
+     * Load a result set (or any other model) from file or URL
+     * 
      * @param filenameOrURI
      * @return Model
      */
-    
-    public static Model loadAsModel(String filenameOrURI)
-    {
-        return loadAsModel(null, filenameOrURI, null) ; 
-    }
-    
-    /** Load a result set (or any other model) from file or URL
-     * @param model     Load into this model (returned)
+
+    public static Model loadAsModel(String filenameOrURI) {
+        return loadAsModel(null, filenameOrURI, null);
+    }
+
+    /**
+     * Load a result set (or any other model) from file or URL
+     * 
+     * @param model
+     *            Load into this model (returned)
      * @param filenameOrURI
-     * @return Model 
+     * @return Model
      */
-    public static Model loadAsModel(Model model, String filenameOrURI)
-    {
-        return loadAsModel(model, filenameOrURI, null) ; 
+    public static Model loadAsModel(Model model, String filenameOrURI) {
+        return loadAsModel(model, filenameOrURI, null);
     }
-    
-    /** Load a result set (or any other model) from file or URL
+
+    /**
+     * Load a result set (or any other model) from file or URL
+     * 
      * @param filenameOrURI
      * @param format
      * @return Model
      */
-    
-    public static Model loadAsModel(String filenameOrURI, ResultsFormat format)
-    { return loadAsModel(null, filenameOrURI, format) ; }
-    
-    /** Load a result set (or any other model) from file or URL.
-     *  Does not have to be a result set (e.g. CONSTRUCt results) 
-     *  but it does interpret the ResultSetFormat possibilities.
-     * @param model     Load into this model (returned)
+
+    public static Model loadAsModel(String filenameOrURI, ResultsFormat format) {
+        return loadAsModel(null, filenameOrURI, format);
+    }
+
+    /**
+     * Load a result set (or any other model) from file or URL. Does not have to
+     * be a result set (e.g. CONSTRUCt results) but it does interpret the
+     * ResultSetFormat possibilities.
+     * 
+     * @param model
+     *            Load into this model (returned)
      * @param filenameOrURI
      * @param format
      * @return Model
      */
-    
-    public static Model loadAsModel(Model model, String filenameOrURI, ResultsFormat format)
-    {
-        if ( model == null )
-            model = GraphFactory.makeDefaultModel() ;
-        
-        if ( format == null )
-            format = ResultsFormat.guessSyntax(filenameOrURI) ;
-        
-        if ( format == null )
-        {
-            Log.warn(ResultSet.class, "Null format - defaulting to XML") ;
-            format = ResultsFormat.FMT_RS_XML ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_TEXT) )
-        {
-            Log.fatal(ResultSet.class, "Can't read a text result set") ;
-            throw new ResultSetException("Can't read a text result set") ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_RS_XML) || format.equals(ResultsFormat.FMT_RS_JSON))
-        {
-            InputStream in = null ;
-            try { 
-                in = FileManager.get().open(filenameOrURI) ;
-                if ( in == null )
-                    throw new NotFoundException(filenameOrURI) ;
+
+    public static Model loadAsModel(Model model, String filenameOrURI, ResultsFormat format) {
+        if (model == null)
+            model = GraphFactory.makeDefaultModel();
+
+        if (format == null)
+            format = ResultsFormat.guessSyntax(filenameOrURI);
+
+        if (format == null) {
+            Log.warn(ResultSet.class, "Null format - defaulting to XML");
+            format = ResultsFormat.FMT_RS_XML;
+        }
+
+        if (format.equals(ResultsFormat.FMT_TEXT)) {
+            Log.fatal(ResultSet.class, "Can't read a text result set");
+            throw new ResultSetException("Can't read a text result set");
+        }
+
+        if (format.equals(ResultsFormat.FMT_RS_XML) || format.equals(ResultsFormat.FMT_RS_JSON)) {
+            InputStream in = null;
+            try {
+                in = FileManager.get().open(filenameOrURI);
+                if (in == null)
+                    throw new NotFoundException(filenameOrURI);
+            } catch (NotFoundException ex) {
+                throw new NotFoundException("File not found: " + filenameOrURI);
             }
-            catch (NotFoundException ex) { throw new NotFoundException("File not found: "+filenameOrURI) ; }
-            
-            SPARQLResult x = null ;
-            
-            if ( format.equals(ResultsFormat.FMT_RS_JSON) )
-                x = JSONInput.make(in, GraphFactory.makeDefaultModel()) ;
+
+            SPARQLResult x = null;
+
+            if (format.equals(ResultsFormat.FMT_RS_JSON))
+                x = JSONInput.make(in, GraphFactory.makeDefaultModel());
             else
-                x = XMLInput.make(in, GraphFactory.makeDefaultModel()) ;
-                    
-            if ( x.isResultSet() )
-                ResultSetFormatter.asRDF(model, x.getResultSet() ) ;
+                x = XMLInput.make(in, GraphFactory.makeDefaultModel());
+
+            if (x.isResultSet())
+                ResultSetFormatter.asRDF(model, x.getResultSet());
             else
-                ResultSetFormatter.asRDF(model, x.getBooleanResult() ) ;
-        
-            return model ;
-        }
-        
-        if ( ResultsFormat.isRDFGraphSyntax(format) )
-            return FileManager.get().readModel(model, filenameOrURI) ;
-        
-        Log.fatal(ResultSet.class, "Unknown result set syntax: "+format) ;
-        return null ;
+                ResultSetFormatter.asRDF(model, x.getBooleanResult());
+
+            return model;
+        }
+
+        if (ResultsFormat.isRDFGraphSyntax(format))
+            return FileManager.get().readModel(model, filenameOrURI);
+
+        Log.fatal(ResultSet.class, "Unknown result set syntax: " + format);
+        return null;
     }
 
-    /** 
-     * Read in any kind of result kind (result set, boolean, graph)
-     * Guess the syntax based on filename/URL extension. 
+    /**
+     * Read in any kind of result kind (result set, boolean, graph) Guess the
+     * syntax based on filename/URL extension.
      */
-    public static SPARQLResult result(String filenameOrURI)
-    {
-        return result(filenameOrURI, null) ;
+    public static SPARQLResult result(String filenameOrURI) {
+        return result(filenameOrURI, null);
     }
 
-    /** 
+    /**
      * Read in any kind of result kind (result set, boolean, graph)
      */
-    
-    public static SPARQLResult result(String filenameOrURI, ResultsFormat format)
-    {
-        if ( format == null )
-            format = ResultsFormat.guessSyntax(filenameOrURI) ;
-        
-        if ( format == null )
-        {
-            Log.warn(ResultSet.class, "Null format - defaulting to XML") ;
-            format = ResultsFormat.FMT_RS_XML ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_TEXT) )
-        {
-            Log.fatal(ResultSet.class, "Can't read a text result set") ;
-            throw new ResultSetException("Can't read a text result set") ;
-        }
-        
-        if ( format.equals(ResultsFormat.FMT_RS_XML) || format.equals(ResultsFormat.FMT_RS_JSON) ||
-             format.equals(ResultsFormat.FMT_RS_TSV) || format.equals(ResultsFormat.FMT_RS_CSV) )
-        {
-            InputStream in = null ;
-            try { 
-                in = FileManager.get().open(filenameOrURI) ;
-                if ( in == null )
-                    throw new NotFoundException(filenameOrURI) ;
-            }
-            catch (NotFoundException ex) { throw new NotFoundException("File not found: "+filenameOrURI) ; }
-            
-            SPARQLResult x = null ;
-            
-            if ( format.equals(ResultsFormat.FMT_RS_JSON) )
-                return JSONInput.make(in, GraphFactory.makeDefaultModel()) ;
-            else if ( format.equals(ResultsFormat.FMT_RS_XML) )
-                return XMLInput.make(in, GraphFactory.makeDefaultModel()) ;
-            else if ( format.equals(ResultsFormat.FMT_RS_TSV) )
-            {
-                ResultSet rs = TSVInput.fromTSV(in) ;
-                return new SPARQLResult(rs) ;
-            }
-            else if ( format.equals(ResultsFormat.FMT_RS_CSV) )
-            {
-                ResultSet rs = CSVInput.fromCSV(in) ;
-                return new SPARQLResult(rs) ;
+
+    public static SPARQLResult result(String filenameOrURI, ResultsFormat format) {
+        if (format == null)
+            format = ResultsFormat.guessSyntax(filenameOrURI);
+
+        if (format == null) {
+            Log.warn(ResultSet.class, "Null format - defaulting to XML");
+            format = ResultsFormat.FMT_RS_XML;
+        }
+
+        if (format.equals(ResultsFormat.FMT_TEXT)) {
+            Log.fatal(ResultSet.class, "Can't read a text result set");
+            throw new ResultSetException("Can't read a text result set");
+        }
+
+        if (format.equals(ResultsFormat.FMT_RS_XML) || format.equals(ResultsFormat.FMT_RS_JSON)
+                || format.equals(ResultsFormat.FMT_RS_TSV) || format.equals(ResultsFormat.FMT_RS_CSV)) {
+            InputStream in = null;
+            try {
+                in = FileManager.get().open(filenameOrURI);
+                if (in == null)
+                    throw new NotFoundException(filenameOrURI);
+            } catch (NotFoundException ex) {
+                throw new NotFoundException("File not found: " + filenameOrURI);
             }
-            else if ( format.equals(ResultsFormat.FMT_RS_BIO) )
-            {
-                ResultSet rs = BIOInput.fromBIO(in) ;
-                return new SPARQLResult(rs) ;
-                
+
+            SPARQLResult x = null;
+
+            if (format.equals(ResultsFormat.FMT_RS_JSON))
+                return JSONInput.make(in, GraphFactory.makeDefaultModel());
+            else if (format.equals(ResultsFormat.FMT_RS_XML))
+                return XMLInput.make(in, GraphFactory.makeDefaultModel());
+            else if (format.equals(ResultsFormat.FMT_RS_TSV)) {
+                ResultSet rs = TSVInput.fromTSV(in);
+                return new SPARQLResult(rs);
+            } else if (format.equals(ResultsFormat.FMT_RS_CSV)) {
+                ResultSet rs = CSVInput.fromCSV(in);
+                return new SPARQLResult(rs);
+            } else if (format.equals(ResultsFormat.FMT_RS_BIO)) {
+                ResultSet rs = BIOInput.fromBIO(in);
+                return new SPARQLResult(rs);
+
             }
         }
-        
-        if (  ResultsFormat.isRDFGraphSyntax(format) )
-        {
-            Model model = FileManager.get().loadModel(filenameOrURI) ;
-            return new SPARQLResult(model) ;
-        }
-
-        Log.fatal(ResultSet.class, "Unknown result set syntax: "+format) ;
-        return null ;
-    }
-    
-    /** Read XML which is the format of the SPARQL result set format.
-     * 
-     * @param in    InputStream
-     * @return      ResultSet
-     */  
-    public static ResultSet fromXML(InputStream in)
-    {
-        return XMLInput.fromXML(in) ;
-    }
-    
-    /** Read XML which is the format of the SPARQL result set format.
-     * 
-     * @param str    String to process
-     * @return      ResultSet
-     */  
-    public static ResultSet fromXML(String str)
-    {
-        return XMLInput.fromXML(str) ;
-    }
-
-    /** Turns an RDF model, with properties and classses from the
-     * result set vocabulary, into a SPARQL result set.
-     * The result set formed is a copy in memory.
+
+        if (ResultsFormat.isRDFGraphSyntax(format)) {
+            Model model = FileManager.get().loadModel(filenameOrURI);
+            return new SPARQLResult(model);
+        }
+
+        Log.fatal(ResultSet.class, "Unknown result set syntax: " + format);
+        return null;
+    }
+
+    /**
+     * Read XML which is the format of the SPARQL result set format.
+     * 
+     * @param in
+     *            InputStream
+     * @return ResultSet
+     */
+    public static ResultSet fromXML(InputStream in) {
+        return XMLInput.fromXML(in);
+    }
+
+    /**
+     * Read XML which is the format of the SPARQL result set format.
+     * 
+     * @param str
+     *            String to process
+     * @return ResultSet
+     */
+    public static ResultSet fromXML(String str) {
+        return XMLInput.fromXML(str);
+    }
+
+    /**
+     * Turns an RDF model, with properties and classses from the result set
+     * vocabulary, into a SPARQL result set. The result set formed is a copy in
+     * memory.
      * 
      * @param model
      * @return ResultSet
      */
-    public static ResultSet fromRDF(Model model) 
-    {
-        return new RDFInput(model) ;
-    }
-
-    /** Read from an input stream which is the format of the SPARQL result set format in JSON.
-     * 
-     * @param in    InputStream
-     * @return      ResultSet
-     */  
-    public static ResultSet fromJSON(InputStream in)
-    {
-        return JSONInput.fromJSON(in) ;
-    }
-    
-    /** Read from an input stream which is the format of the SPARQL result set format in TSV.
-     * 
-     * @param in    InputStream
-     * @return      ResultSet
-     */  
-    public static ResultSet fromTSV(InputStream in)
-    {
-        return TSVInput.fromTSV(in) ;
-    }
-    
-    /** Read from an input stream which is the format of the SPARQL result set format in SSE.
-     * 
-     * @param in    InputStream
-     * @return      ResultSet
-     */  
-    public static ResultSet fromSSE(InputStream in)
-    {
-        Item item = SSE.parse(in) ;
-        Log.warn(ResultSet.class, "Reading SSE result set not full implemented") ;
-        // See SPARQLResult.  Have a level of ResultSetFactory that does "get SPARQLResult".
-        // Or just boolean/result set because those are both srx. etc. 
-        
-        BuilderTable.build(item) ;
-        return null ;
-    }
-    
-    /** Turns an RDF model, with properties and classses from the
-     * result set vocabulary, into a SPARQL result set.
-     * The result set formed is a copy in memory.
+    public static ResultSet fromRDF(Model model) {
+        return new RDFInput(model);
+    }
+
+    /**
+     * Read from an input stream which is the format of the SPARQL result set
+     * format in JSON.
+     * 
+     * @param in
+     *            InputStream
+     * @return ResultSet
+     */
+    public static ResultSet fromJSON(InputStream in) {
+        return JSONInput.fromJSON(in);
+    }
+
+    /**
+     * Read from an input stream which is the format of the SPARQL result set
+     * format in TSV.
+     * 
+     * @param in
+     *            InputStream
+     * @return ResultSet
+     */
+    public static ResultSet fromTSV(InputStream in) {
+        return TSVInput.fromTSV(in);
+    }
+
+    /**
+     * Read from an input stream which is the format of the SPARQL result set
+     * format in SSE.
+     * 
+     * @param in
+     *            InputStream
+     * @return ResultSet
+     */
+    public static ResultSet fromSSE(InputStream in) {
+        Item item = SSE.parse(in);
+        Log.warn(ResultSet.class, "Reading SSE result set not full implemented");
+        // See SPARQLResult. Have a level of ResultSetFactory that does
+        // "get SPARQLResult".
+        // Or just boolean/result set because those are both srx. etc.
+
+        BuilderTable.build(item);
+        return null;
+    }
+
+    /**
+     * Turns an RDF model, with properties and classses from the result set
+     * vocabulary, into a SPARQL result set. The result set formed is a copy in
+     * memory.
      * 
      * @param model
      * @return ResultSet
      */
-    static public ResultSet makeResults(Model model)
-    {
-        return new RDFInput(model) ;
-    }
-    
-    /** Turns an RDF model, with properties and classses from the
-     * result set vocabulary, into a SPARQL result set which is rewindable
-     * (has a .reset()operation).
-     * The result set formed is a copy in memory.
+    static public ResultSet makeResults(Model model) {
+        return new RDFInput(model);
+    }
+
+    /**
+     * Turns an RDF model, with properties and classses from the result set
+     * vocabulary, into a SPARQL result set which is rewindable (has a
+     * .reset()operation). The result set formed is a copy in memory.
      * 
      * @param model
      * @return ResultSetRewindable
      */
-    static public ResultSetRewindable makeRewindable(Model model)
-    {
-        return new RDFInput(model) ;
-    }
-    
-    /** Turn an existing result set into a rewindable one.
-     *  May take a copy - uses up the result set passed in.
+    static public ResultSetRewindable makeRewindable(Model model) {
+        return new RDFInput(model);
+    }
+
+    /**
+     * Turn an existing result set into a rewindable one. May take a copy - uses
+     * up the result set passed in.
+     * 
      * @param resultSet
      * @return ResultSetRewindable
      */
-    static public ResultSetRewindable makeRewindable(ResultSet resultSet)
-    {
-        return new ResultSetMem(resultSet) ;
-    }
-    
-
-    /** Sort an existing result set.  Experimental.
-     *  The list of variables is a list of names (strings),
-     *  with "x" for ascending in variable "x" and "-x" for
-     *  descending in variable "x"   
+    static public ResultSetRewindable makeRewindable(ResultSet resultSet) {
+        return new ResultSetMem(resultSet);
+    }
+
+    /**
+     * Turns an existing result set into one with peeking capabilities
+     * <p>
+     * Using the returned result set consumes the result set passed in, the
+     * underlying result set must be at the start in order to be made peeking.
+     * If you create such a result set you should avoid accessing the underlying
+     * result set directly as this may cause results to be missed or put the
+     * returned peekable result set into an invalid state.
+     * </p>
+     * </p> Note that rewindable results may typically also be peekable so may
+     * be more broadly applicable if you can afford the cost of loading all the
+     * results into memory. </p>
+     * 
+     * @param resultSet
+     *            Result set to wrap
+     * @return Peekable results
+     */
+    static public ResultSetPeekable makePeekable(ResultSet resultSet) {
+        return new ResultSetPeeking(resultSet);
+    }
+
+    /**
+     * Sort an existing result set. Experimental. The list of variables is a
+     * list of names (strings), with "x" for ascending in variable "x" and "-x"
+     * for descending in variable "x"
+     * 
      * @param resultSet
      * @param conditions
      * @return ResultSet
      */
-    static public ResultSet makeSorted(ResultSet resultSet, List<SortCondition> conditions)
-    {
-        return new SortedResultSet(resultSet, conditions) ;
+    static public ResultSet makeSorted(ResultSet resultSet, List<SortCondition> conditions) {
+        return new SortedResultSet(resultSet, conditions);
     }
 
-    /** Take a copy of a result set - the result set returns is an in-memory copy.
-     *  It is not attached to the original query execution object which can be closed.
+    /**
+     * Take a copy of a result set - the result set returns is an in-memory
+     * copy. It is not attached to the original query execution object which can
+     * be closed.
+     * 
      * @param results
      * @return ResultSet
      */
-    static public ResultSetRewindable copyResults(ResultSet results)
-    {
-        return new ResultSetMem(results) ; 
-    }
-    
-    /** Build a result set from one of ARQ's lower level query iterator.
-     *  @param queryIterator
-     *  @param vars     List of variables, by name, for the result set
-     *  @return ResultSet 
-     */
-    static public ResultSet create(QueryIterator queryIterator, List<String> vars)
-    {
-        return new ResultSetStream(vars, null, queryIterator) ;
+    static public ResultSetRewindable copyResults(ResultSet results) {
+        return new ResultSetMem(results);
+    }
+
+    /**
+     * Build a result set from one of ARQ's lower level query iterator.
+     * 
+     * @param queryIterator
+     * @param vars
+     *            List of variables, by name, for the result set
+     * @return ResultSet
+     */
+    static public ResultSet create(QueryIterator queryIterator, List<String> vars) {
+        return new ResultSetStream(vars, null, queryIterator);
     }
 }

Modified: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetMem.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetMem.java?rev=1464792&r1=1464791&r2=1464792&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetMem.java (original)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetMem.java Thu Apr  4 23:32:13 2013
@@ -22,6 +22,8 @@ import java.util.ArrayList ;
 import java.util.Iterator ;
 import java.util.List ;
 
+import org.apache.jena.atlas.iterator.PeekIterator;
+
 import com.hp.hpl.jena.query.QuerySolution ;
 import com.hp.hpl.jena.query.ResultSet ;
 import com.hp.hpl.jena.rdf.model.Model ;
@@ -34,7 +36,7 @@ import com.hp.hpl.jena.sparql.util.Utils
  * keep the result set in memory. */
 
 
-public class ResultSetMem implements com.hp.hpl.jena.query.ResultSetRewindable
+public class ResultSetMem implements com.hp.hpl.jena.query.ResultSetRewindable, ResultSetPeekable
 {
     // ??? Convert to use a ResultSetProcessor
     // The result set in memory
@@ -43,7 +45,7 @@ public class ResultSetMem implements com
     protected List<String> varNames = null ;
 
     private int rowNumber = 0 ;
-    private Iterator<Binding> iterator = null ;
+    private PeekIterator<Binding> iterator = null ;
     private Model model = null ;
 
     /** Create an in-memory result set from another one
@@ -168,7 +170,7 @@ public class ResultSetMem implements com
     public void rewind( ) { reset() ; }
 
     @Override
-    public void reset() { iterator = rows.iterator() ; rowNumber = 0 ; }
+    public void reset() { iterator = new PeekIterator<Binding>(rows.iterator()) ; rowNumber = 0 ; }
 
     /** Return the "row" number for the current iterator item
      */
@@ -191,4 +193,14 @@ public class ResultSetMem implements com
     @Override
     public List<String> getResultVars() { return varNames ; }
 
+    @Override
+    public QuerySolution peek() {
+        return new ResultBinding(model, peekBinding());
+    }
+
+    @Override
+    public Binding peekBinding() {
+        return this.iterator.peek();
+    }
+
 }

Added: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeekable.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeekable.java?rev=1464792&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeekable.java (added)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeekable.java Thu Apr  4 23:32:13 2013
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hp.hpl.jena.sparql.resultset;
+
+import java.util.NoSuchElementException;
+
+import com.hp.hpl.jena.query.QuerySolution;
+import com.hp.hpl.jena.query.ResultSet;
+import com.hp.hpl.jena.sparql.engine.binding.Binding;
+
+/**
+ * Interfaces for result sets that allow peeking ahead
+ *
+ */
+public interface ResultSetPeekable extends ResultSet {
+
+    /**
+     * Peek at the next query solution
+     * @return Next solution if available
+     * @throws NoSuchElementException Thrown if attempting to peek when there are no further elements
+     */
+    public QuerySolution peek();
+    
+    /**
+     * Peek at the next binding
+     * @return Next binding if available
+     * @throws NoSuchElementException THrown if attempting to peek when there are no further elements
+     */
+    public Binding peekBinding();
+}

Added: jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeeking.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeeking.java?rev=1464792&view=auto
==============================================================================
--- jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeeking.java (added)
+++ jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/resultset/ResultSetPeeking.java Thu Apr  4 23:32:13 2013
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hp.hpl.jena.sparql.resultset;
+
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.hp.hpl.jena.query.QuerySolution;
+import com.hp.hpl.jena.query.ResultSet;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.sparql.core.ResultBinding;
+import com.hp.hpl.jena.sparql.engine.binding.Binding;
+
+/**
+ * A wrapper around another result set that provides peek capabilities
+ * 
+ */
+public class ResultSetPeeking implements ResultSetPeekable {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResultSetPeekable.class);
+
+    /**
+     * Controls whether a log warning is printed if someone modifies the
+     * underlying result set externally to us
+     */
+    public static boolean warnOnSyncErrors = true;
+
+    private ResultSet results;
+    private Model model;
+    private Binding peeked = null;
+    private int rowNumber = 0;
+
+    /**
+     * Creates a peeking wrapper around another result set
+     * 
+     * @param results
+     *            Inner results
+     */
+    public ResultSetPeeking(ResultSet results) {
+        if (results == null)
+            throw new IllegalArgumentException("Inner result set cannot be null");
+        this.results = results;
+        this.model = results.getResourceModel();
+    }
+
+    @Override
+    public boolean hasNext() {
+        if (this.hasPeeked())
+            return true;
+        return this.results.hasNext();
+    }
+
+    @Override
+    public QuerySolution next() {
+        return new ResultBinding(this.model, this.nextBinding());
+    }
+
+    @Override
+    public QuerySolution nextSolution() {
+        return this.next();
+    }
+
+    @Override
+    public Binding nextBinding() {
+        if (this.hasPeeked()) {
+            Binding b = this.peeked;
+            this.peeked = null;
+            this.rowNumber++;
+            return b;
+        } else if (this.results.hasNext()) {
+            this.rowNumber++;
+            return this.results.nextBinding();
+        } else {
+            throw new NoSuchElementException();
+        }
+    }
+
+    @Override
+    public int getRowNumber() {
+        // Calculate row number based on whether we have peeked
+        return this.hasPeeked() ? this.results.getRowNumber() - 1 : this.results.getRowNumber();
+    }
+
+    @Override
+    public List<String> getResultVars() {
+        return this.results.getResultVars();
+    }
+
+    @Override
+    public Model getResourceModel() {
+        return this.model;
+    }
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException("remove() is not supported");
+    }
+
+    private boolean hasPeeked() {
+        int diff = this.results.getRowNumber() - this.rowNumber;
+        if (diff == 0) {
+            // If no difference we have not peeked
+            return false;
+        } else if (diff == 1) {
+            // If difference is one then we have peeked
+            return true;
+        } else if (diff > 1) {
+            // If difference between what we think the row number is and that of
+            // the underlying result set is > 1 then someone has moved positions
+            // in the underying result set independently
+            // Sync up with current position and report false
+            if (warnOnSyncErrors)
+                LOGGER.warn("Underlying result set was moved forward " + (diff - 1)
+                        + " result(s), this result set was synced back up but some results have been missed");
+            this.rowNumber = this.results.getRowNumber();
+            this.peeked = null;
+            return false;
+        } else {
+            // If difference is negative then someone has reset the underlying
+            // result set so we are completely out of sync, syncing back up at
+            // this point would be illegal since we have gone backwards in the
+            // stream
+            throw new IllegalStateException(
+                    "Underlying result set position has moved backwards, this result set is no longer usable");
+        }
+    }
+
+    @Override
+    public QuerySolution peek() {
+        return new ResultBinding(this.model, this.peekBinding());
+    }
+
+    @Override
+    public Binding peekBinding() {
+        if (this.hasPeeked()) {
+            return this.peeked;
+        } else if (this.results.hasNext()) {
+            this.peeked = this.results.nextBinding();
+            return this.peeked;
+        } else {
+            throw new NoSuchElementException();
+        }
+    }
+
+}

Modified: jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/resultset/TestResultSet.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/resultset/TestResultSet.java?rev=1464792&r1=1464791&r2=1464792&view=diff
==============================================================================
--- jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/resultset/TestResultSet.java (original)
+++ jena/trunk/jena-arq/src/test/java/com/hp/hpl/jena/sparql/resultset/TestResultSet.java Thu Apr  4 23:32:13 2013
@@ -22,12 +22,16 @@ import java.io.ByteArrayInputStream ;
 import java.io.ByteArrayOutputStream ;
 import java.util.ArrayList ;
 import java.util.List ;
+import java.util.NoSuchElementException;
 
 import org.apache.jena.atlas.junit.BaseTest ;
 import org.apache.jena.atlas.lib.StrUtils ;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test ;
 
 import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory;
 import com.hp.hpl.jena.query.ResultSet ;
 import com.hp.hpl.jena.query.ResultSetFactory ;
 import com.hp.hpl.jena.query.ResultSetFormatter ;
@@ -48,6 +52,18 @@ import com.hp.hpl.jena.sparql.util.Resul
 
 public class TestResultSet extends BaseTest
 {
+    @BeforeClass
+    public static void setup() {
+        // Disable warnings these tests will produce
+        ResultSetPeeking.warnOnSyncErrors = false;
+    }
+    
+    @AfterClass
+    public static void teardown() {
+        // Re-enable warnings
+        ResultSetPeeking.warnOnSyncErrors = true;
+    }
+    
     // Test reading, writing and comparison
     @Test public void test_RS_1()
     {
@@ -281,6 +297,133 @@ public class TestResultSet extends BaseT
         assertTrue(ResultSetCompare.equalsByValue(rs1, rs2)) ;
     }
     
+    // Peeking
+    @Test 
+    public void test_RS_peeking_1() {
+        ResultSetPeekable rs = makePeekable("x",  NodeFactory.createURI("tag:local"));
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        
+        // Peeking should not move the result set onwards so hasNext() should still report true
+        assertTrue(rs.hasNext());
+        
+        assertNotNull(rs.next());
+        assertFalse(rs.hasNext());
+    }
+    
+    @Test(expected=NoSuchElementException.class)
+    public void test_RS_peeking_2() {
+        ResultSetPeekable rs = makePeekable("x",  NodeFactory.createURI("tag:local"));
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        
+        // Peeking should not move the result set onwards so hasNext() should still report true
+        assertTrue(rs.hasNext());
+        
+        assertNotNull(rs.next());
+        assertFalse(rs.hasNext());
+        
+        // Peeking beyond end of results throws an error
+        rs.peek();
+    }
+    
+    @Test 
+    public void test_RS_peeking_3() {
+        // Expect that a rewindable result set will be peekable
+        ResultSetPeekable rs = (ResultSetPeekable)makeRewindable("x",  NodeFactory.createURI("tag:local"));
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        
+        // Peeking should not move the result set onwards so hasNext() should still report true
+        assertTrue(rs.hasNext());
+        
+        assertNotNull(rs.next());
+        assertFalse(rs.hasNext());
+    }
+    
+    @Test(expected=NoSuchElementException.class)
+    public void test_RS_peeking_4() {
+        // Expect that a rewindable result set will be peekable
+        ResultSetPeekable rs = (ResultSetPeekable) makeRewindable("x",  NodeFactory.createURI("tag:local"));
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        
+        // Peeking should not move the result set onwards so hasNext() should still report true
+        assertTrue(rs.hasNext());
+        
+        assertNotNull(rs.next());
+        assertFalse(rs.hasNext());
+        
+        // Peeking beyond end of results throws an error
+        rs.peek();
+    }
+    
+    @Test 
+    public void test_RS_peeking_5() {
+        // Peeking should be able to cope with people moving on the underlying result set independently
+        ResultSet inner = new ResultSetMem(make("x", NodeFactory.createURI("tag:local")), make("x", NodeFactory.createURI("tag:local")));
+        ResultSetPeekable rs = ResultSetFactory.makePeekable(inner);
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        
+        // Move on the inner result set independently
+        inner.next();
+        
+        // Since we fiddled with the underlying result set there won't be further elements available anymore
+        assertFalse(rs.hasNext());
+    }
+    
+    @Test 
+    public void test_RS_peeking_6() {
+        // Peeking should be able to cope with people moving on the underlying result set independently
+        ResultSet inner = new ResultSetMem(make("x", NodeFactory.createURI("tag:local")), make("x", NodeFactory.createURI("tag:local")), make("x", NodeFactory.createURI("tag:local")));
+        ResultSetPeekable rs = ResultSetFactory.makePeekable(inner);
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        
+        // Move on the inner result set independently
+        inner.next();
+        
+        // Since we fiddled with the underlying result set we'll be out of sync
+        // but there should still be further data available
+        assertTrue(rs.hasNext());
+    }
+    
+    @Test
+    public void test_RS_peeking_7() {
+        // Peeking may fail if someone moves backwards in the result set
+        // If we hadn't moved pass the first item this should be safe
+        ResultSetRewindable inner = makeRewindable("x", NodeFactory.createURI("tag:local"));
+        ResultSetPeekable rs = ResultSetFactory.makePeekable(inner);
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        
+        // Reset the inner result set independently
+        inner.reset();
+        
+        // Since we moved the underlying result set backwards but we hadn't gone anywhere
+        // we should still be able to safely access the underlying results
+        assertTrue(rs.hasNext());
+    }
+    
+    @Test(expected=IllegalStateException.class)
+    public void test_RS_peeking_8() {
+        // Peeking may fail if someone moves backwards in the result set
+        // If we had moved past the first item this should be an error
+        ResultSetRewindable inner = new ResultSetMem(make("x", NodeFactory.createURI("tag:local")), make("x", NodeFactory.createURI("tag:local")));
+        ResultSetPeekable rs = ResultSetFactory.makePeekable(inner);
+        assertTrue(rs.hasNext());
+        assertNotNull(rs.peek());
+        assertNotNull(rs.next());
+        
+        // Reset the inner result set independently
+        inner.reset();
+        
+        // Since we moved the underlying result set backwards and had moved somewhere we
+        // are now in an illegal state
+        rs.hasNext();
+    }
+    
     // ---- Isomorphism.
     
     /* This is from the DAWG test suite.
@@ -307,7 +450,7 @@ public class TestResultSet extends BaseT
 
     // Right mapping is:
     // b0->c3, b1->c2, b2->c1, b3->c0
-    // Currently we get, workign simply top to bottom, no backtracking:
+    // Currently we get, working simply top to bottom, no backtracking:
     // b0->c1, b1->c0, b2->c3, b3->c2, then last row fails as _:b1 is mapped to c0, b0 to c1 not (c2, c3) 
     
     private static String[] rs1$ = {
@@ -406,4 +549,15 @@ public class TestResultSet extends BaseT
         return rsw ;
     }
     
+    private ResultSetPeekable makePeekable(String var, Node val) {
+        ResultSet rs = make(var, val);
+        ResultSetPeekable rsp = ResultSetFactory.makePeekable(rs);
+        return rsp;
+    }
+    
+    private ResultSetPeekable make2Peekable(String var1, Node val1, String var2, Node val2) {
+        ResultSet rs = make(var1, val1, var2, val2);
+        ResultSetPeekable rsp = ResultSetFactory.makePeekable(rs);
+        return rsp;
+    }
 }