You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2014/01/02 22:00:48 UTC

svn commit: r1554915 [1/2] - in /jena/Scratch/AFS/Dev/src: ./ dev/ dev/g2/ dsg/ element/ opexec/ opt/

Author: andy
Date: Thu Jan  2 21:00:47 2014
New Revision: 1554915

URL: http://svn.apache.org/r1554915
Log:
Sync

Added:
    jena/Scratch/AFS/Dev/src/
    jena/Scratch/AFS/Dev/src/dev/
    jena/Scratch/AFS/Dev/src/dev/BindingN.java
    jena/Scratch/AFS/Dev/src/dev/DevAFS.java
    jena/Scratch/AFS/Dev/src/dev/LogMain.java
    jena/Scratch/AFS/Dev/src/dev/ModelReadCloseTestZip.java
    jena/Scratch/AFS/Dev/src/dev/RunAFS.java
    jena/Scratch/AFS/Dev/src/dev/RunBase.java
    jena/Scratch/AFS/Dev/src/dev/TestModelCreation.java
    jena/Scratch/AFS/Dev/src/dev/g2/
    jena/Scratch/AFS/Dev/src/dev/g2/Index.java
    jena/Scratch/AFS/Dev/src/dev/g2/IndexImpl.java
    jena/Scratch/AFS/Dev/src/dev/g2/MultiBunch.java
    jena/Scratch/AFS/Dev/src/dev/g2/MultiBunchSimple.java
    jena/Scratch/AFS/Dev/src/dev/g2/TupleDex.java
    jena/Scratch/AFS/Dev/src/dev/g2/TupleIndex.java
    jena/Scratch/AFS/Dev/src/dev/rdfs.java
    jena/Scratch/AFS/Dev/src/dev/rules.java
    jena/Scratch/AFS/Dev/src/dsg/
    jena/Scratch/AFS/Dev/src/dsg/DSG_Notify.java
    jena/Scratch/AFS/Dev/src/element/
    jena/Scratch/AFS/Dev/src/element/ElementTransform.java
    jena/Scratch/AFS/Dev/src/element/ElementTransformCopyBase.java
    jena/Scratch/AFS/Dev/src/element/ElementTransformSubst.java
    jena/Scratch/AFS/Dev/src/element/ElementTransformer.java
    jena/Scratch/AFS/Dev/src/element/ExprTransformNodeElement.java
    jena/Scratch/AFS/Dev/src/element/MainElt.java
    jena/Scratch/AFS/Dev/src/element/NodeTransformSubst.java
    jena/Scratch/AFS/Dev/src/element/QueryTransformOps.java
    jena/Scratch/AFS/Dev/src/element/TestQueryOps.java
    jena/Scratch/AFS/Dev/src/element/TestSubstitution.java
    jena/Scratch/AFS/Dev/src/element/TransEltLib.java
    jena/Scratch/AFS/Dev/src/element/UpdateTransformOps.java
    jena/Scratch/AFS/Dev/src/opexec/
    jena/Scratch/AFS/Dev/src/opexec/OpExecutorExample.java
    jena/Scratch/AFS/Dev/src/opt/
    jena/Scratch/AFS/Dev/src/opt/Jena384_SubstitueFilterOptimize.java
    jena/Scratch/AFS/Dev/src/opt/OptMain.java
    jena/Scratch/AFS/Dev/src/opt/TransformFilterEquality2.java

Added: jena/Scratch/AFS/Dev/src/dev/BindingN.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/BindingN.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/BindingN.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/BindingN.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,123 @@
+/*
+ * 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 dev;
+
+import java.util.Iterator ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.ARQInternalErrorException ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.engine.binding.Binding ;
+import com.hp.hpl.jena.sparql.engine.binding.BindingBase ;
+import com.hp.hpl.jena.sparql.engine.binding.BindingMap ;
+import com.hp.hpl.jena.sparql.engine.binding.BindingUtils ;
+
+public class BindingN extends BindingBase implements BindingMap
+{
+    protected BindingN() { this(null) ; }
+    
+    protected BindingN(Binding _parent)
+    {
+        super(_parent) ;
+    }
+
+    // Cost = object overhead + parent + 3*var + 3*node always. 
+    // Or dynamically switch to using a pair of [].
+    // Or switch to a single binding unit (cost = object overhead + parent + var + node -> not much)  
+    
+    private Var var1 = null ;
+    private Node node1 = null ;
+    
+    private Var var2 = null ;
+    private Node node2 = null ;
+
+    private Var var3 = null ;
+    private Node node3 = null ;
+    
+    @Override
+    protected Iterator<Var> vars1()
+    {
+        return null ;
+    }
+    
+    @Override
+    protected int size1()
+    {
+        if ( var1 == null ) return 0 ;
+        if ( var2 == null ) return 1 ;
+        if ( var3 == null ) return 2 ;
+        return 3 ;
+    }
+    
+    @Override
+    protected boolean isEmpty1()
+    {
+        return var1 == null ;
+    }
+    
+    @Override
+    protected boolean contains1(Var var)
+    {
+        if ( var == null ) return false ;
+
+        if ( var1 == null ) return false ;
+        if ( var.equals(var1) ) return true ;
+
+        if ( var2 == null ) return false ;
+        if ( var.equals(var2) ) return true ;
+
+        if ( var3 == null ) return false ;
+        if ( var.equals(var3) ) return true ;
+        
+        return false ;
+    }
+    
+    @Override
+    protected Node get1(Var var)
+    {
+        if ( var == null ) return null ;
+        
+        if ( var1 == null ) return null ;
+        if ( var.equals(var1) ) return node1 ;
+        
+        if ( var2 == null ) return null ;
+        if ( var.equals(var2) ) return node2 ;
+        
+        if ( var3 == null ) return null ;
+        if ( var.equals(var3) ) return node3 ;
+        
+        return null ;
+    }
+
+    @Override
+    public void add(Var var, Node node)
+    {
+        if ( var1 != null ) { var1 = var ; node1 = node ; return ; }
+        if ( var2 != null ) { var2 = var ; node2 = node ; return ; }
+        if ( var3 != null ) { var3 = var ; node3 = node ; return ; }
+        throw new ARQInternalErrorException("BindingN: already full") ;
+    }
+
+    @Override
+    final public void addAll(Binding other)
+    {
+        BindingUtils.addAll(this, other) ;
+    }
+}
+

Added: jena/Scratch/AFS/Dev/src/dev/DevAFS.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/DevAFS.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/DevAFS.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/DevAFS.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,24 @@
+/*
+ * 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 dev;
+
+public class DevAFS
+{
+    // De-mess top level directories.
+}

Added: jena/Scratch/AFS/Dev/src/dev/LogMain.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/LogMain.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/LogMain.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/LogMain.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,131 @@
+/*
+ * 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 dev;
+
+import java.io.ByteArrayInputStream ;
+import java.io.IOException ;
+import java.io.UnsupportedEncodingException ;
+
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.atlas.logging.LogCtl ;
+import org.apache.jena.atlas.logging.java.ConsoleHandlerStdout ;
+import org.slf4j.LoggerFactory ;
+
+public class LogMain
+{
+    static { LogCtl.setLog4j() ; }
+    public static void main(String ... args) //throws SecurityException, IOException
+    {
+        mainSLF4j() ;
+        mainJUL() ;
+    }
+    
+    public static void logNetwork()
+    {
+        // org.apache.log4j.net.SimpleSocketServer 6000 log4j.properties
+        // org.apache.log4j.net.SocketServer 6000 log4j.properties DIR
+        //   log4j.properties logging
+        //   DIR is one config file per host
+
+        LogCtl.setLog4j("log4j-net.properties") ;    // Re-initialize log4j.
+        LoggerFactory.getLogger("HELLO").info("Message") ;
+        System.out.println("Exit") ;
+        System.exit(0) ;
+    }
+    
+    private static void mainSLF4j()
+    {
+
+        org.slf4j.Logger logger_slf4j = org.slf4j.LoggerFactory.getLogger(dev.RunAFS.class) ;
+        logger_slf4j.error("org.slf4j") ;
+    }        
+        
+        
+        
+    private static void mainJUL()
+    {
+        String s = StrUtils.strjoinNL(
+                                      // Handlers - output
+                                      // All (comma separated)
+                                      //"handlers=java.util.logging.ConsoleHandler,atlas.logging.java.ConsoleHandlerStdout",
+                                      
+                                      // Atlas.
+                                      //"handlers=atlas.logging.java.ConsoleHandlerStdout" ,
+                                      
+                                      // Provided by the JRE
+                                      "handlers=java.util.logging.ConsoleHandler" ,
+                                      
+                                      // Formatting and levels
+                                      //"atlas.logging.java.ConsoleHandlerStdout.level=ALL",
+                                      //"atlas.logging.java.ConsoleHandlerStdout.formatter=atlas.logging.java.TextFormatter",
+                                      
+                                      "java.util.logging.ConsoleHandler.level=INFO"
+                                      //, "java.util.logging.ConsoleHandler.formatter=atlas.logging.java.TextFormatter"
+                                      ) ;   
+        
+        try
+        {
+            java.util.logging.LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(s.getBytes("UTF-8"))) ;
+        } catch (SecurityException ex)
+        {
+            ex.printStackTrace();
+        } catch (UnsupportedEncodingException ex)
+        {
+            ex.printStackTrace();
+        } catch (IOException ex)
+        {
+            ex.printStackTrace();
+        }
+
+        //System.setProperty("java.util.logging.config.file", "logging.properties") ;
+        //LogManager.getLogManager().readConfiguration() ;
+        
+        java.util.logging.Logger log = java.util.logging.Logger.getLogger(RunAFS.class.getName()) ;
+        //log.setLevel(Level.WARNING) ;
+
+        // Default output, Atlas/Java logging formatter.
+        log.info("Hello World") ;
+        
+        // Because the parent has the plumbed in ConsoleHandler
+        log.setUseParentHandlers(false) ;
+        log.addHandler(new ConsoleHandlerStdout()) ;
+        log.info("Hello World (part 2)") ;
+         
+//        // -- Remove any ConsoleHanlder
+//        Handler[] handlers = log.getHandlers() ;
+//        for ( Handler h : handlers )
+//        {
+//            if ( h instanceof ConsoleHandler )
+//                log.removeHandler(h) ;
+//        }
+        log.info("Hello World (part 3)") ;
+        System.out.println("(End)") ;
+        
+        
+//        // ---- 
+//        System.setProperty("log4j.configuration", "file:log4j.properties") ;
+//        
+//        
+//        org.apache.log4j.Logger log4j = org.apache.log4j.Logger.getLogger(Run.class);
+//        log4j.setLevel(org.apache.log4j.Level.ALL) ;
+//        log4j.info("Log4j direct") ;
+        
+        // Must have the right logger adapter on the classpath: slf4j-log4j... or slf4j-
+    }
+}

Added: jena/Scratch/AFS/Dev/src/dev/ModelReadCloseTestZip.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/ModelReadCloseTestZip.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/ModelReadCloseTestZip.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/ModelReadCloseTestZip.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,153 @@
+/*
+ * 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 dev ;
+
+import java.io.ByteArrayInputStream ;
+import java.io.IOException ;
+import java.io.InputStream ;
+
+import org.apache.jena.riot.IO_Jena ;
+import org.junit.Assert ;
+import org.junit.Test ;
+
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.ModelFactory ;
+
+/**
+ * This class tests to make sure that Model.read(InputStream) does not call
+ * close() on the InputStream handed to it when it is finished.  The creator
+ * of the InputStream should be the one to manage its lifecycle.  If the
+ * Model does call close(), this can break InputStreams that you can still
+ * read more data from after -1 is returned from read().
+ * 
+ * ZipInputStream is an example of a class with this behavior.  Below is
+ * a code snippet that will fail for all Model.read() calls except the
+ * Jena N-Triples parser.
+ * 
+ * ZipInputStream zin = new ZipInputStream(new FileInputStream("file.zip"));
+ * ZipEntry ze = null;
+ * while ((ze = zin.getNextEntry()) != null)
+ * {
+ *    String filename = ze.getName();
+ *    Model m = ModelFactory.createDefaultModel();
+ *    m.read(zin, null, "N-TRIPLES");
+ *    
+ *    // Closes the current ZIP entry and positions the stream for reading
+ *    // the next entry.
+ *    zin.closeEntry();
+ * }
+ * zin.close();
+ * 
+ * Test Results for Jena 2.6.3 and ARQ 2.8.5
+ * -----------------------------------------
+ * TestJenaReaderNTriples: PASSED
+ *       TestJenaReaderN3: ERROR
+ *   TestJenaReaderRDFXML: FAILED
+ * TestRIOTReaderNTriples: FAILED
+ *       TestRIOTReaderN3: FAILED
+ *   TestRIOTReaderRDFXML: FAILED
+ * 
+ * NOTE: A work-around is to us an InputStream wrapper that delegates all
+ *       calls except close(), which does nothing.
+ */
+public class ModelReadCloseTestZip
+{
+   @Test
+   public void TestJenaReaderNTriples()
+   {
+      IO_Jena.resetJena();
+      readNTriples();
+   }
+      
+   @Test
+   public void TestJenaReaderN3()
+   {
+       IO_Jena.resetJena();
+       readN3();
+   }
+   
+   @Test
+   public void TestJenaReaderRDFXML()
+   {
+       IO_Jena.resetJena();
+       readRDFXML();
+   }
+   
+   @Test
+   public void TestRIOTReaderNTriples()
+   {
+       IO_Jena.wireIntoJena();
+       readNTriples();
+   }
+      
+   @Test
+   public void TestRIOTReaderN3()
+   {
+       IO_Jena.wireIntoJena();
+       readN3();
+   }
+
+   @Test
+   public void TestRIOTReaderRDFXML()
+   {
+       IO_Jena.wireIntoJena();
+      readRDFXML();
+   }
+   
+   void readNTriples()
+   {
+      performRead("<http://example.org/test> <http://www.w3.org/2000/01/rdf-schema#label> \"Test\" .", "N-TRIPLES");
+   }
+   
+   void readN3()
+   {
+      performRead("<http://example.org/test> <http://www.w3.org/2000/01/rdf-schema#label> \"Test\" .", "N3");
+   }
+   
+   void readRDFXML()
+   {
+      performRead(
+         "<?xml version=\"1.0\"?>" +
+            "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\">" +
+            "<rdf:Description rdf:about=\"http://example.org/test\" rdfs:label=\"Test\">" +
+            "</rdf:Description>" +
+            "</rdf:RDF>",
+         "RDF/XML");
+   }
+   
+   void performRead(String triples, String lang)
+   {
+      // Create an InputStream that doesn't like to be closed
+      InputStream in = new ByteArrayInputStream(triples.getBytes())
+      {
+         /**
+          * @throws IOException
+          * @see java.io.InputStream#close()
+          */
+         @Override
+         public void close() throws IOException
+         {
+            Assert.fail("Close should not be called.");
+         }
+      };
+      
+      Model m = ModelFactory.createDefaultModel();
+      m.read(in, null, lang);
+   }
+}

Added: jena/Scratch/AFS/Dev/src/dev/RunAFS.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/RunAFS.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/RunAFS.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/RunAFS.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,106 @@
+/*
+ * 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 dev;
+
+import java.util.Iterator ;
+
+import org.apache.jena.atlas.logging.LogCtl ;
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.iri.IRIFactory ;
+import org.apache.jena.iri.Violation ;
+import org.apache.jena.iri.ViolationCodes ;
+
+public class RunAFS
+{
+    static { LogCtl.setLog4j() ; }
+    
+    public static void exit(int code)
+    {
+        System.out.println("DONE") ;
+        System.exit(code) ;
+    }
+    
+    
+    static public void main(String ... args) throws Exception
+    { 
+    }
+    
+
+    static IRIFactory iriFactory = new IRIFactory();
+    static {
+        // IRIFactory.iriImplementation() ...
+        iriFactory.useSpecificationIRI(true);
+        iriFactory.useSchemeSpecificRules("*",true);
+
+        iriFactory.shouldViolation(false,true);
+
+        // Moderate it -- allow unwise chars and any scheme name.
+        iriFactory.setIsError(ViolationCodes.UNWISE_CHARACTER,false);
+        iriFactory.setIsWarning(ViolationCodes.UNWISE_CHARACTER,false);
+
+        iriFactory.setIsError(ViolationCodes.UNREGISTERED_IANA_SCHEME,false);
+        iriFactory.setIsWarning(ViolationCodes.UNREGISTERED_IANA_SCHEME,false);
+
+        iriFactory.create("");
+
+    }
+    
+    private static void iriTest(String iriStr)
+    {
+        System.out.println("IRI =  "+iriStr) ;
+        IRIFactory factory = iriFactory ;
+        
+        IRI iri = factory.create(iriStr) ;
+        System.out.println("IRI => "+iri.toDisplayString()) ;
+        
+        
+        Iterator<Violation> iter = iri.violations(true) ;
+        for ( ; iter.hasNext();  )
+        {
+            Violation v = iter.next();
+            String x = (v.isError()?"ERROR":"WARN ") ;
+            
+            int code = v.getViolationCode() ;
+            
+//            // Treat these with low priority.
+//            if ( code == Violation.LOWERCASE_PREFERRED ||
+//                code == Violation.PERCENT_ENCODING_SHOULD_BE_UPPERCASE )
+//            {
+//                continue ;
+//            }
+            
+            System.out.printf("%s  %s\n", x, v.getShortMessage()) ;
+        }
+    }
+    
+      // ---- Helpers
+    
+    private static final String NL = "\n" ;
+
+    public static String divider = "---- ----" ;
+
+    private static String nextDivider = null ;
+    
+    public static void divider()
+    {
+        if ( nextDivider != null )
+            System.out.println(nextDivider) ;
+        nextDivider = divider ;
+    }
+}

Added: jena/Scratch/AFS/Dev/src/dev/RunBase.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/RunBase.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/RunBase.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/RunBase.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,236 @@
+/*
+ * 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 dev;
+
+import java.util.Iterator ;
+
+import org.apache.jena.atlas.io.IndentedWriter ;
+import org.apache.jena.atlas.json.JSON ;
+import org.apache.jena.atlas.json.JsonValue ;
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.iri.IRIFactory ;
+import org.apache.jena.iri.Violation ;
+import org.apache.jena.riot.checker.CheckerIRI ;
+import org.apache.jena.riot.system.ErrorHandlerFactory ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.* ;
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.shared.PrefixMapping ;
+import com.hp.hpl.jena.sparql.ARQConstants ;
+import com.hp.hpl.jena.sparql.ARQException ;
+import com.hp.hpl.jena.sparql.algebra.Algebra ;
+import com.hp.hpl.jena.sparql.algebra.Op ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ;
+import com.hp.hpl.jena.sparql.engine.ExecutionContext ;
+import com.hp.hpl.jena.sparql.expr.Expr ;
+import com.hp.hpl.jena.sparql.expr.ExprEvalException ;
+import com.hp.hpl.jena.sparql.expr.NodeValue ;
+import com.hp.hpl.jena.sparql.function.FunctionEnv ;
+import com.hp.hpl.jena.sparql.function.FunctionEnvBase ;
+import com.hp.hpl.jena.sparql.sse.SSE ;
+import com.hp.hpl.jena.sparql.util.* ;
+import com.hp.hpl.jena.update.* ;
+import com.hp.hpl.jena.util.FileManager ;
+
+public class RunBase
+{
+
+    public static String divider = "----------------------------------------" ;
+    public static String nextDivider = null ;
+    public static void divider()
+    {
+        if ( nextDivider != null )
+            System.out.println(nextDivider) ;
+        nextDivider = divider ;
+    }
+    
+    public static void exit(int code)
+    {
+        System.out.flush() ;
+        System.out.println("DONE") ;
+        System.exit(code) ;
+    }
+
+    public static void runTest(String dir, String dataFile, String queryFile)
+    {
+        if ( ! dir.endsWith("/") )
+            dir = dir + "/" ;
+        String queryArg = "--query="+dir+queryFile ;
+        String dataArg = "--data="+dir+dataFile ;
+        arq.sparql.main(/*"--engine=ref",*/ dataArg, queryArg) ;
+    }
+
+    public static void json()
+    {
+        // JSON
+        // ** Double space for end of object, end of object. 
+        JsonValue obj = JSON.readAny("D.json") ;
+        IndentedWriter out = new IndentedWriter(System.out) ; 
+        out.setFlatMode(true) ;
+        //out.setEndOfLineMarker("$") ;
+        JSON.write(out, obj) ;
+        out.flush() ;
+        System.exit(0) ;
+        
+
+    }
+    
+    public static void processIRI(String iriStr)
+    {
+        IRI iri = IRIFactory.iriImplementation().create(iriStr) ;
+        System.out.println(iri) ;
+        System.out.println("Relative: "+iri.isRelative()) ;
+
+        Iterator<Violation> vIter = iri.violations(true) ;
+        for ( ; vIter.hasNext() ; )
+        {
+            Violation v = vIter.next() ;
+            System.out.println(v.getShortMessage()) ;
+            //System.out.println(v.getSpecificationURL()) ;
+        }
+        System.out.println(iriStr + " ==> "+iri) ;
+        CheckerIRI.iriViolations(iri, ErrorHandlerFactory.errorHandlerWarn) ;
+        System.exit(0) ;
+    }
+    
+    public static void analyseQuery(String ...queryString)
+    {
+        String qs = StrUtils.strjoinNL(queryString) ;
+        Query query = QueryFactory.create(qs) ;
+        Op op = Algebra.compile(query) ;
+        divider() ;
+        System.out.println(op) ;
+        Op op2 = Algebra.optimize(op) ;
+        divider() ;
+        System.out.println(op2) ;
+        divider() ;
+    }
+
+    
+    public static void execTimed(Query query, Model model)
+    {
+//        System.out.println(ARQ.VERSION); 
+//        System.out.println(Jena.VERSION); 
+
+        Timer timer = new Timer() ;
+        timer.startTimer() ;
+        exec(query, model) ;
+        long time = timer.endTimer() ;
+        System.out.printf("Time = %.2fs\n", time/1000.0) ;
+    }
+
+    public static void exec(Query query, Model model)
+    {
+        QueryExecution qexec = QueryExecutionFactory.create(query, model) ;
+        QueryExecUtils.executeQuery(query, qexec) ;
+    }
+    
+    
+    public static NodeValue eval(String string)
+    {
+        try {
+            Expr expr = ExprUtils.parse(string) ;
+            return expr.eval(null, new FunctionEnvBase()) ;
+        } catch (ExprEvalException ex)
+        {
+            ex.printStackTrace(System.err) ;
+            return null ;
+        }
+    }
+    
+    public static void qexpr(String exprStr)
+    {
+        try {
+            PrefixMapping pmap = PrefixMapping.Factory.create()  ;
+            pmap.setNsPrefixes(ARQConstants.getGlobalPrefixMap()) ;
+            pmap.setNsPrefix("", "http://example/") ;
+            pmap.setNsPrefix("ex", "http://example/ns#") ;
+
+            Expr expr = ExprUtils.parse(exprStr, pmap) ;
+            // Default action
+            ARQ.getContext().set(ARQConstants.sysCurrentTime, NodeFactoryExtra.nowAsDateTime()) ;
+            FunctionEnv env = new ExecutionContext(ARQ.getContext(), null, null, null) ; 
+            NodeValue r = expr.eval(null, env) ;
+            //System.out.println(r.asQuotedString()) ;
+            Node n = r.asNode() ;
+            String s = FmtUtils.stringForNode(n) ;
+            System.out.println(s) ;
+        } catch (ARQException ex)
+        {
+            System.out.println(" ** "+ex) ;
+        }
+    }
+    
+    public static void runQTest(String dir, String manifest)
+    {
+        if ( ! dir.endsWith("/") )
+            dir = dir + "/" ;
+        String []a1 = { "--strict", dir+manifest } ;
+        arq.qtest.main(a1) ;
+        System.exit(0 ) ; 
+  
+    }
+
+
+    public static void execUpdate(String update)
+    {
+        UpdateRequest request = UpdateFactory.create(update) ;
+        DatasetGraph dsg = DatasetGraphFactory.createMem() ;
+        GraphStore gs = GraphStoreFactory.create(dsg) ;
+        UpdateAction.execute(request, gs) ;
+        SSE.write(gs) ;
+        System.exit(0) ;
+    }
+
+    public static void execUpdateFile(String updatefile)
+    {
+        UpdateRequest req = UpdateFactory.read(updatefile) ;
+        System.out.println(req) ;
+
+        GraphStore gs = GraphStoreFactory.create() ;
+        UpdateProcessor action = UpdateExecutionFactory.create(req, gs) ;
+        action.execute() ;
+
+        SSE.write(gs) ;
+        exit(0) ;
+    }    
+    
+    public static void execQueryCode(String datafile, String queryfile)
+    {
+        Model model = FileManager.get().loadModel(datafile) ;
+        Query query = QueryFactory.read(queryfile) ;
+        
+        QuerySolutionMap initialBinding = new QuerySolutionMap();
+        //initialBinding.add("s", model.createResource("http://example/x1")) ;
+        initialBinding.add("o", model.createResource("http://example/z")) ;
+        
+        QueryExecution qExec = QueryExecutionFactory.create(query, model, initialBinding) ;
+        ResultSetFormatter.out(qExec.execSelect()) ;
+    }
+
+    public static void execRemote(String service, String queryString)
+    {
+        arq.rsparql.main("--service="+service, queryString) ;
+        System.exit(0) ;
+    }
+}
+

Added: jena/Scratch/AFS/Dev/src/dev/TestModelCreation.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/TestModelCreation.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/TestModelCreation.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/TestModelCreation.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,43 @@
+/*
+ * 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 dev;
+
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.ModelFactory ;
+import com.hp.hpl.jena.sparql.util.Timer ;
+
+public class TestModelCreation
+{
+    public static void main(String...argv)
+    {
+        //org.openjena.atlas.logging.Log.setLog4j() ;
+        int N = 1000000 ;
+        Object[] objects = new Object[100] ;
+        Timer t = new Timer() ;
+        t.startTimer() ;
+        for ( int i = 0 ; i < N; i++ )
+        {
+            Model m = ModelFactory.createDefaultModel() ;
+            //Map<Object, Object> m = new HashMap<Object, Object>() ;
+            objects[i%100] = m ;
+        }
+        long millis = t.endTimer() ;
+        System.out.printf("Time = %.2fs for %,d creations. Rate = %,.2f objects/s\n", millis/1000.0, N, N*(1000.0/millis)) ;
+    }
+}

Added: jena/Scratch/AFS/Dev/src/dev/g2/Index.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/g2/Index.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/g2/Index.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/g2/Index.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,39 @@
+/*
+ * 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 dev.g2 ;
+
+import java.util.Iterator;
+
+/** A simplified "map" interface */
+public interface Index<K, V>
+{
+    public V get(K key) ;
+
+    public void put(K key, V value) ;
+
+    public void remove(K key) ;
+
+    public int size() ;
+
+    public boolean isEmpty() ;
+
+    //public Collection<V> values() { return map.values() ; }
+    public Iterator<K> keys() ;
+
+}

Added: jena/Scratch/AFS/Dev/src/dev/g2/IndexImpl.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/g2/IndexImpl.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/g2/IndexImpl.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/g2/IndexImpl.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,52 @@
+/*
+ * 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 dev.g2;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.jena.atlas.lib.DS ;
+
+/** Simplified map */
+public class IndexImpl<K, V> implements Index<K, V> 
+{
+    private Map<K,V> map = DS.map() ;
+    
+    public IndexImpl() {}
+    
+    @Override
+    public V get(K key) { return map.get(key) ; }
+    @Override
+    public void put(K key, V value) { map.put(key, value) ; }
+    
+    @Override
+    public void remove(K key) { map.remove(key) ; }
+    
+    @Override
+    public int size() { return map.size() ; }
+    @Override
+    public boolean isEmpty() { return map.isEmpty() ; }
+    
+    //public Collection<V> values() { return map.values() ; }
+    @Override
+    public Iterator<K> keys() { return map.keySet().iterator() ; }
+    
+    @Override
+    public String toString() { return map.toString() ; }
+}

Added: jena/Scratch/AFS/Dev/src/dev/g2/MultiBunch.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/g2/MultiBunch.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/g2/MultiBunch.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/g2/MultiBunch.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,55 @@
+/*
+ * 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 dev.g2;
+
+import java.util.Iterator;
+
+import org.apache.jena.atlas.lib.Pair ;
+
+/** A storage of (K, Collection<V>) - i.e. a multivalued map; only one occurence of each distinct V per K */ 
+public interface MultiBunch<K,V>
+{
+//    /** Lookup a key : iterator preferred */ 
+//    public Collection<V> get(K key) ;
+    
+    public boolean contains(K key, V value) ;
+    
+    /** All keys */
+    public Iterator<K> keys() ;
+    
+    /** All values associated with a key */
+    public Iterator<V> iterator(K key) ;
+    
+    /** Everything */
+    public Iterator<Pair<K,V>> iterator() ;
+
+    /** Add a key/value pair, return true if the bunch was altered */
+    public boolean add(K key, V value) ;
+
+    /** Remove a key/value pair, return true if the bunch was altered */
+    public boolean remove(K key, V value) ;
+
+    /** Remove all key/value pairs */
+    public void clear() ;
+
+    public boolean isEmpty() ;
+    
+    public long size() ;
+
+}

Added: jena/Scratch/AFS/Dev/src/dev/g2/MultiBunchSimple.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/g2/MultiBunchSimple.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/g2/MultiBunchSimple.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/g2/MultiBunchSimple.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,139 @@
+/*
+ * 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 dev.g2;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.atlas.iterator.IteratorConcat ;
+import org.apache.jena.atlas.iterator.NullIterator ;
+import org.apache.jena.atlas.iterator.Transform ;
+import org.apache.jena.atlas.lib.Pair ;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+
+/** TEMPORARY implementation */ 
+public class MultiBunchSimple<K, V> implements MultiBunch<K, V>
+{
+    private Index<K, Collection<V>> index ;
+    //static Iterator<V> zero = new NullIterator<V>() ;
+    
+    public MultiBunchSimple()
+    {
+        clear() ;
+    }
+    
+    @Override
+    public boolean add(K key, V value)
+    {
+        Collection<V> set = index.get(key) ;
+        if ( set == null )
+        {
+            set = new ArrayList<V>() ;
+            index.put(key, set) ;
+        }
+        return set.add(value) ;
+    }
+    
+    @Override
+    public boolean remove(K key, V value)
+    {
+        Collection<V> set = index.get(key) ;
+        if ( set == null )
+            return false ;
+        return set.remove(value) ;
+    }
+
+    @Override
+    public void clear()
+    { index = new IndexImpl<K,  Collection<V>>() ;}
+
+    @Override
+    public boolean contains(K key, V value)
+    {
+        Collection<V> set = index.get(key) ;
+        if ( set == null )
+            return false ;
+        return set.contains(value) ;
+    }
+
+    @Override
+    public boolean isEmpty()
+    {
+        if ( index.isEmpty() ) return true ;
+        for( Iterator<K> iter = index.keys() ; iter.hasNext(); )
+        {
+            K key = iter.next() ;
+            if ( ! index.get(key).isEmpty() )
+                return false ;
+        }
+        return false ;
+    }
+
+    @Override
+    public long size()
+    {
+        long num = 0 ;
+        for( Iterator<K> iter = index.keys() ; iter.hasNext(); )
+        {
+            K key = iter.next() ;
+            num += index.get(key).size() ;
+        }
+        return num ;
+    }
+
+    @Override
+    public Iterator<V> iterator(K key)
+    {
+        Collection<V> set = index.get(key) ;
+        if ( set == null )
+            return new NullIterator<V>() ;
+        return set.iterator() ;
+    }
+
+    @Override
+    public Iterator<Pair<K, V>> iterator()
+    {
+        IteratorConcat<Pair<K,V>> concat = new IteratorConcat<Pair<K,V>>() ;
+        Iterator<K> keys = index.keys() ;
+        for ( ; keys.hasNext(); )
+        {
+            final K key = keys.next() ;
+            Transform<V, Pair<K,V>> t = new Transform<V, Pair<K,V>>(){
+
+                @Override
+                public Pair<K, V> convert(V value)
+                {
+                    return new Pair<K,V>(key, value) ;
+                }} ;
+            concat.add(Iter.map(index.get(key), t)) ;
+        }
+        return concat ;
+    }
+
+    @Override
+    public Iterator<K> keys()
+    {
+        return index.keys() ;
+    }
+    
+    @Override
+    public String toString() { return index.toString() ; }
+}

Added: jena/Scratch/AFS/Dev/src/dev/g2/TupleDex.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/g2/TupleDex.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/g2/TupleDex.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/g2/TupleDex.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,219 @@
+/*
+ * 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 dev.g2;
+
+import org.apache.jena.atlas.iterator.* ;
+import org.apache.jena.atlas.lib.ColumnMap ;
+import org.apache.jena.atlas.lib.Tuple ;
+
+import java.util.Iterator;
+
+
+import com.hp.hpl.jena.graph.Node;
+
+public class TupleDex 
+{
+    // Currently assumes 3-Tuple.
+    // Later support into N-tuple with a M<=N key 
+    // Reconsider naming.
+    
+    Index<Node, MultiBunch<Node, Node>> index = new IndexImpl<Node, MultiBunch<Node, Node>>() ;
+    ColumnMap colMap ;
+    Transform<Tuple<Node>, Tuple<Node>> unmap ;
+
+    
+    static Iterator<Tuple<Node>> zero = new NullIterator<Tuple<Node>>() ;
+    
+    public TupleDex(ColumnMap cm){ 
+        this.colMap = cm ;
+        this.unmap = new Transform<Tuple<Node>, Tuple<Node>> () {
+            @Override
+            public Tuple<Node> convert(Tuple<Node> item)
+            {
+                return colMap.unmap(item) ;
+            }} ;
+    }
+    
+    public boolean add(Tuple<Node> tuple)
+    {
+        Node n1 = colMap.fetchSlot(0, tuple) ; 
+        Node n2 = colMap.fetchSlot(1, tuple) ;
+        Node n3 = colMap.fetchSlot(2, tuple) ;
+        
+        MultiBunch<Node, Node> bunch = index.get(n1) ;
+        // XXX Adjust the MultiBunch implementation as it grows.
+        if ( bunch == null )
+        {
+            bunch = new MultiBunchSimple<Node, Node>() ;
+            index.put(n1, bunch) ;
+        }
+        return bunch.add(n2, n3) ;
+        
+    }
+    
+    public boolean remove(Tuple<Node> tuple)
+    {
+        Node n1 = colMap.fetchSlot(0, tuple) ; 
+        Node n2 = colMap.fetchSlot(1, tuple) ;
+        Node n3 = colMap.fetchSlot(2, tuple) ;
+    
+        MultiBunch<Node, Node> bunch = index.get(n1) ;
+        if ( bunch == null )
+            return false ;
+        boolean b = bunch.remove(n2, n3) ;
+        // Could adjust the MultiBunch implementation as it shrinks
+        // but if we are doing a lot of removals (e.g. implicit removeAll), then that makes work 
+        if ( bunch.isEmpty() )
+            index.put(n1, null) ;
+        return b ;
+    }
+
+    public Iterator<Tuple<Node>> find(Tuple<Node> tuple)
+    {
+        tuple = colMap.map(tuple) ;
+        Iterator<Tuple<Node>> iter = find(tuple.get(0), tuple.get(1), tuple.get(2)) ;
+        return Iter.map(iter, unmap) ; 
+    }
+    
+    private Iterator<Tuple<Node>> find(final Node x, final Node y, Node z)
+    {
+        if ( x == null )
+        {
+            // X=? (Maybe Y and Z - 4 cases) 
+            Iterator<Node> iter1 = index.keys() ;
+            IteratorConcat<Tuple<Node>> iter = new IteratorConcat<Tuple<Node>>() ;
+            for ( ; iter1.hasNext() ; )
+            {
+                Node node1 = iter1.next() ;
+                MultiBunch<Node, Node> bunch = index.get(node1) ;
+//                if ( bunch == null )
+//                    continue ;  // ???!!!
+                iter.add(find1(node1, bunch, y, z)) ;
+            }
+            return iter ;
+        }
+        
+        MultiBunch<Node, Node> bunch = index.get(x) ;
+        
+        if ( bunch == null )
+            return zero ;
+
+        if ( y != null )
+        {
+            if ( z != null )
+            {
+                // X Y Z - 1 case
+                if ( bunch.contains(y, z) )
+                    return new SingletonIterator<Tuple<Node>>(Tuple.createTuple(x,y,z)) ;
+                else
+                    return zero ;
+            }
+            // X Y ? - 1 case
+            Iterator<Node> zPart = bunch.iterator(y) ;
+            return find2(x, y, zPart) ;
+        }
+        // y is null.
+        // X ? ? or X ? Z - 2 cases 
+        // Total cases: 8
+        
+        // -----
+        return find1(x, bunch, y, z) ;
+    }
+
+    private Iterator<Tuple<Node>> find1(Node x, MultiBunch<Node, Node> bunch, final Node y, final Node z)
+    {
+//        if ( bunch == null )
+//            return zero ;
+        
+        IteratorConcat<Tuple<Node>> iter = new IteratorConcat<Tuple<Node>>() ;
+        
+        Iterator<Node> iter1 = bunch.keys() ;
+        
+        for ( ; iter1.hasNext() ;  )
+        {
+            Node key = iter1.next() ;
+            Iterator<Node> part3 = bunch.iterator(key) ;
+            Iterator<Tuple<Node>> iter2 = find2(x, key, part3) ;
+            iter.add(iter2) ;
+        }
+        if ( y == null && z == null )
+            return iter ;
+        // Some sort of scan.
+        Filter<Tuple<Node>> filter = new Filter<Tuple<Node>>() {
+            @Override
+            public boolean accept(Tuple<Node> tuple)
+            {
+                if ( y != null && !y.equals(tuple.get(1)) ) return false ;
+                if ( z != null && !z.equals(tuple.get(2)) ) return false ;
+                return true ;
+            }} ;
+        return Iter.filter(iter, filter) ; 
+    }
+    
+    private Iterator<Tuple<Node>> find2(final Node x, final Node y, Iterator<Node> part)
+    {
+        Transform<Node, Tuple<Node>> t = new Transform<Node, Tuple<Node>>(){
+            @Override
+            public Tuple<Node> convert(Node item)
+            {
+                return Tuple.createTuple(x, y, item) ;
+            }} ;
+        Iterator<Tuple<Node>> iter2 = Iter.map(part, t) ;
+        return iter2 ;
+    }
+    
+    private static void checkNotNull(Node x)
+    {
+        if ( x == null ) throw new RuntimeException("Null") ;
+    }
+    private static void checkNull(Node x)
+    {
+        if ( x != null ) throw new RuntimeException("Not null: "+x) ;
+    }
+
+    public int weight(Tuple<Node> tuple)
+    {
+//        System.out.println("Index: "+this) ;
+//        System.out.println("Weight: "+tuple) ;
+//        
+//        System.out.println("  "+colMap.fetchSlot(0, tuple)) ;
+//        System.out.println("  "+colMap.fetchSlot(1, tuple)) ;
+//        System.out.println("  "+colMap.fetchSlot(2, tuple)) ;
+//        System.out.println("Mapped: "+colMap.map(tuple)) ;
+//        
+        if ( undef(colMap.fetchSlot(0, tuple)) ) return 0 ;
+        if ( undef(colMap.fetchSlot(1, tuple)) ) return 1 ;
+        if ( undef(colMap.fetchSlot(2, tuple)) ) return 2 ;
+        return 3 ;
+    }
+    
+    private boolean undef(Object x)
+    { return x == null ; }
+
+    @Override
+    public String toString()
+    {
+        return label() ;
+    }
+    
+    public String label()
+    {
+        return colMap.getLabel() ; 
+    }
+}

Added: jena/Scratch/AFS/Dev/src/dev/g2/TupleIndex.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/g2/TupleIndex.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/g2/TupleIndex.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/g2/TupleIndex.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,90 @@
+/*
+ * 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 dev.g2;
+
+import org.apache.jena.atlas.iterator.IteratorConcat ;
+import org.apache.jena.atlas.lib.DS ;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+
+
+public class TupleIndex<T> //extends Index<T, Index<T, Collection<T>>>
+{
+    // Top : Hash of T -> (T, T*) 
+    private Index<T, IndexImpl<T, Collection<T>>> map = new IndexImpl<T, IndexImpl<T, Collection<T>>>() ;
+    
+    public TupleIndex() {}
+    
+    public Index<T, Collection<T>> get(T key1) { return map.get(key1) ; }
+    
+    public Collection<T> get(T key1, T key2) { return map.get(key1).get(key2) ; }
+    
+    public Iterator<T> keys() { return map.keys() ; }
+    
+    public void put(T key1, T key2, T value)
+    { 
+        IndexImpl<T, Collection<T>> x = map.get(key1) ;
+        if ( x == null )
+        {
+            x = new IndexImpl<T, Collection<T>>() ;
+            map.put(key1, x) ;
+        }
+        
+        Collection<T> z = x.get(key2) ;
+        if ( z == null )
+        {
+            z = DS.list() ;
+            x.put(key2, z) ;
+        }
+        z.add(value) ;
+    }
+    
+    public void remove(T key1, T key2)
+    {
+        Index<T, Collection<T>> x = map.get(key1) ;
+        if ( x == null )
+            return ;
+        x.remove(key2) ;
+        if ( x.size() == 0 )
+            map.remove(key1) ;
+    }
+    
+    public Iterator<T> flatten()
+    {
+        // Accumulating iterator.
+        IteratorConcat<T> all = new IteratorConcat<T>() ;
+        for ( Iterator<T> iter = map.keys() ; iter.hasNext() ; )
+        {
+            T k1 = iter.next();
+            Index<T, Collection<T>> x =  map.get(k1) ;
+            for (Iterator<T> iter2 = x.keys() ; iter.hasNext() ; )
+            {
+                T k2 = iter2.next();
+                Collection<T> y = x.get(k2) ;
+                all.add(y.iterator()) ;
+            }
+        }
+        return all ;
+    }
+    
+    public int size() { return map.size() ; }
+    public boolean isEmpty() { return map.isEmpty() ; }
+}

Added: jena/Scratch/AFS/Dev/src/dev/rdfs.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/rdfs.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/rdfs.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/rdfs.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,119 @@
+/*
+ * 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 dev;
+
+import java.util.Iterator;
+
+import arq.cmdline.CmdMain;
+
+import com.hp.hpl.jena.rdf.model.InfModel;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.StmtIterator;
+import com.hp.hpl.jena.reasoner.Reasoner;
+import com.hp.hpl.jena.reasoner.ReasonerRegistry;
+import com.hp.hpl.jena.sparql.util.Utils;
+import com.hp.hpl.jena.util.FileManager;
+
+/** Apply RDFS reasoning to data and schema */
+
+public class rdfs extends CmdMain
+{
+    public static void main(String[] argv)
+    {
+        new rdfs(argv).mainRun() ;
+    }
+    
+    private rdfs(String[] argv)
+    {
+        super(argv) ;
+        super.add("simple", false) ;
+        super.add("schema", true) ;
+    }
+
+    @Override
+    protected void exec()
+    {
+        Model modelSchema = ModelFactory.createDefaultModel() ;
+        Model modelData = ModelFactory.createDefaultModel() ;
+
+        for ( Iterator<?> iter = super.getValues("schema").iterator(); iter.hasNext() ; )
+        {
+            String filename = (String)iter.next();
+            FileManager.get().readModel(modelSchema, filename) ;
+        }
+
+        for ( Iterator<?> iter = super.getPositional().iterator(); iter.hasNext() ; )
+        {
+            String filename = (String)iter.next();
+            FileManager.get().readModel(modelData, filename) ;
+        }
+
+        Reasoner reasoner = null ;
+        if ( super.contains("simple") )
+        {
+            System.out.println("# Simple") ;
+            reasoner = ReasonerRegistry.getRDFSSimpleReasoner() ;
+        }
+        else
+            reasoner = ReasonerRegistry.getRDFSReasoner() ;
+        
+        
+        
+        // Fetch the rule set and create the reasoner
+//        BuiltinRegistry.theRegistry.register(new Deduce());
+//        Map prefixes = new HashMap();
+//        List rules = loadRules((String)cl.getItem(0), prefixes);
+//        Reasoner reasoner = new GenericRuleReasoner(rules);
+        
+        System.out.println("# Schema") ;
+        modelSchema.write(System.out, "TTL") ;
+        System.out.println() ;
+        
+        System.out.println("# Data") ;
+        modelData.write(System.out, "TTL") ;
+        System.out.println() ;
+        
+        InfModel infModel = ModelFactory.createInfModel(reasoner, modelSchema, modelData) ;
+        infModel.prepare();
+        
+        System.out.println("# Find") ;
+        StmtIterator sIter = infModel.listStatements(infModel.createResource("http://example/x"), null, (RDFNode)null) ;
+        while(sIter.hasNext())
+            System.out.println(sIter.nextStatement()) ;
+        System.out.println() ;
+        
+        System.out.println("# Deductions") ;
+        Model deductions = infModel.getDeductionsModel() ;
+        deductions.write(System.out, "TTL") ;
+        System.out.println() ;
+
+        System.out.println("# All") ;
+        infModel.write(System.out, "TTL") ;
+        System.out.println() ;
+    }
+
+
+    @Override
+    protected String getCommandName()
+    {
+        return Utils.className(this) ;
+    } 
+}

Added: jena/Scratch/AFS/Dev/src/dev/rules.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dev/rules.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dev/rules.java (added)
+++ jena/Scratch/AFS/Dev/src/dev/rules.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,136 @@
+/*
+ * 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 dev;
+
+import java.io.BufferedReader ;
+import java.io.File ;
+import java.util.HashMap ;
+import java.util.Iterator ;
+import java.util.List ;
+import java.util.Map ;
+
+import arq.cmdline.ArgDecl ;
+import arq.cmdline.CmdMain ;
+
+import com.hp.hpl.jena.rdf.model.InfModel ;
+import com.hp.hpl.jena.rdf.model.Model ;
+import com.hp.hpl.jena.rdf.model.ModelFactory ;
+import com.hp.hpl.jena.reasoner.Reasoner ;
+import com.hp.hpl.jena.reasoner.rulesys.GenericRuleReasoner ;
+import com.hp.hpl.jena.reasoner.rulesys.Rule ;
+import com.hp.hpl.jena.sparql.util.Utils ;
+import com.hp.hpl.jena.util.FileManager ;
+import com.hp.hpl.jena.util.FileUtils ;
+
+/** Apply a rule set */
+
+public class rules extends CmdMain
+{
+    ArgDecl argRules = new ArgDecl(ArgDecl.HasValue, "rules", "rule") ;
+    
+    public static void main(String[] argv)
+    {
+        new rules(argv).mainRun() ;
+    }
+    
+    private rules(String[] argv)
+    {
+        super(argv) ;
+        super.add("rules", true) ;
+    }
+
+    @Override
+    protected void exec()
+    {
+        try
+        {
+            Model modelData = ModelFactory.createDefaultModel() ;
+
+            for ( Iterator<?> iter = super.getPositional().iterator(); iter.hasNext() ; )
+            {
+                String filename = (String)iter.next();
+                FileManager.get().readModel(modelData, filename) ;
+            }
+
+            if ( super.getValues(argRules).size() != 0 )
+            {
+                System.err.println("Exactly one rules file") ;
+                System.exit(1) ;
+            }
+
+            String rulesFile = super.getValue(argRules) ;
+
+            Map<String, String> prefixes = new HashMap<String, String>();
+            List<Rule> rules = loadRules(rulesFile, prefixes) ;
+            Reasoner reasoner = new GenericRuleReasoner(rules);
+
+            InfModel infModel = ModelFactory.createInfModel(reasoner, modelData) ;
+            infModel.prepare();
+
+            System.out.println("# Deductions") ;
+            Model deductions = infModel.getDeductionsModel() ;
+            deductions.write(System.out, "TTL") ;
+            System.out.println() ;
+
+            System.out.println("# All") ;
+            infModel.write(System.out, "TTL") ;
+            System.out.println() ;
+        } catch (Exception ex)
+        {
+            ex.printStackTrace();
+        }
+    }
+
+    /**
+     * Load a set of rule definitions including processing of
+     * comment lines and any initial prefix definition lines.
+     * Also notes the prefix definitions for adding to a later inf model.
+     */
+    public static List<Rule> loadRules(String filename, Map<String, String> prefixes) {
+        String fname = filename;
+        if (fname.startsWith("file:///")) {
+            fname = File.separator + fname.substring(8);
+        } else if (fname.startsWith("file:/")) {
+            fname = File.separator + fname.substring(6);
+        } else if (fname.startsWith("file:")) {
+            fname = fname.substring(5);
+        }
+
+        BufferedReader src = FileUtils.openResourceFile(fname);
+        return loadRules(src, prefixes);
+    }
+    
+    /**
+     * Load a set of rule definitions including processing of
+     * comment lines and any initial prefix definition lines.
+     * Also notes the prefix definitions for adding to a later inf model.
+     */
+    public static List<Rule> loadRules(BufferedReader src, Map<String, String> prefixes) {
+        Rule.Parser parser = Rule.rulesParserFromReader(src);
+        List<Rule> rules = Rule.parseRules(parser);
+        prefixes.putAll(parser.getPrefixMap());
+        return rules;
+    }
+
+    @Override
+    protected String getCommandName()
+    {
+        return Utils.className(this) ;
+    } 
+}

Added: jena/Scratch/AFS/Dev/src/dsg/DSG_Notify.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/dsg/DSG_Notify.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/dsg/DSG_Notify.java (added)
+++ jena/Scratch/AFS/Dev/src/dsg/DSG_Notify.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,181 @@
+/*
+ * 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 dsg;
+
+import java.util.ArrayList ;
+import java.util.Iterator ;
+import java.util.List ;
+
+import org.apache.jena.atlas.event.Event ;
+import org.apache.jena.atlas.event.EventManager ;
+import org.apache.jena.atlas.event.EventType ;
+
+import com.hp.hpl.jena.graph.Graph ;
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.core.DatasetGraph ;
+import com.hp.hpl.jena.sparql.core.DatasetGraphWrapper ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+
+/** DatasetGraphWrapper that adds
+ * events to change operations 
+ * on a DatasetGraph. */
+
+public class DSG_Notify extends DatasetGraphWrapper
+{
+    // Need to intercept iterator.remove and do a notify.
+    
+    //Enum-ization?
+    static final String URI                 = "http://apache.org/jena/dataset" ;
+    static final EventType etAddQuad        = new EventType(URI+"addQuad") ;
+    static final EventType etDeleteQuad     = new EventType(URI+"deleteQuad") ;
+    static final EventType etDeleteAnyQuad  = new EventType(URI+"deleteAnyQuad") ;
+    static final EventType etAddGraph       = new EventType(URI+"addGraph") ;
+    static final EventType etRemoveQuad     = new EventType(URI+"removeGraph") ;
+    static final EventType etClose          = new EventType(URI+"close") ;
+    
+    private final class IteratorNotifyQuad implements Iterator<Quad>
+    {
+        private Quad lastSeenQuad = null ;
+        protected final Iterator<Quad> iterator ;
+        
+        public IteratorNotifyQuad(Iterator<Quad> iter) { iterator = iter ; }
+        
+        @Override
+        public boolean hasNext()        { return iterator.hasNext() ; }
+        
+        @Override
+        public Quad next()                 
+        { 
+            lastSeenQuad = iterator.next() ;
+            return lastSeenQuad ;
+        }
+        
+        @Override
+        public void remove()            
+        { 
+            if ( lastSeenQuad == null ) 
+                throw new IllegalStateException("IteratorNotifyQuad.remove: illegal state: .next no yet called (quad null)") ;
+            deleteEvent(lastSeenQuad) ;
+            iterator.remove() ;
+        }
+    }
+    
+    public DSG_Notify(DatasetGraph dsg)
+    {
+        super(dsg) ;
+    }
+
+    @Override
+    public void add(Quad quad)
+    {
+        addEvent(quad) ;
+        super.add(quad) ;
+    }
+    
+    public void addEvent(Quad quad)
+    {
+        Event ev = new Event(etAddQuad, quad) ;
+        EventManager.send(this, ev) ;
+    }
+
+    @Override
+    public void delete(Quad quad)
+    {
+        deleteEvent(quad) ;
+    }
+
+    public void deleteEvent(Quad quad)
+    {
+        Event ev = new Event(etDeleteQuad, quad) ;
+        EventManager.send(this, ev) ;
+    }
+
+    private final static int ChunkSize = 100 ;
+    
+    @Override
+    public void deleteAny(Node g, Node s, Node p, Node o)
+    {
+        List<Quad> quads = new ArrayList<Quad>(ChunkSize) ;
+        
+        // Need to do this manually.
+        // get a chunk ; repeat.
+
+        while(true)
+        {
+            Iterator<Quad> iter = find(g,s,p,o) ;
+            if ( ! iter.hasNext() )
+                break ;
+            
+            int count = 0 ;
+            
+            for ( ; count < ChunkSize ; count++ )
+            {
+                if ( ! iter.hasNext() )
+                    break ;
+                Quad q = iter.next() ;
+                quads.add(q) ;
+            }
+            
+            for ( int i = 0 ; i < quads.size() ; i++ )
+                // With event.
+                delete(quads.get(i)) ;
+        }
+    }
+
+    @Override
+    public void setDefaultGraph(Graph g)
+    {}
+
+    @Override
+    public void addGraph(Node graphName, Graph graph)
+    {}
+
+    @Override
+    public void removeGraph(Node graphName)
+    {}
+
+    @Override
+    public void close()
+    {}
+    
+    
+    @Override
+    public Iterator<Quad> find()
+    {
+        return new IteratorNotifyQuad(super.getWrapped().find()) ;
+    }
+
+    @Override
+    public Iterator<Quad> find(Quad quad)
+    {
+        return new IteratorNotifyQuad(super.getWrapped().find(quad)) ;
+    }
+
+    @Override
+    public Iterator<Quad> find(Node g, Node s, Node p, Node o)
+    {
+        return new IteratorNotifyQuad(super.getWrapped().find(g, s, p, o)) ;
+    }
+
+    @Override
+    public Iterator<Quad> findNG(Node g, Node s, Node p, Node o)
+    {
+        return new IteratorNotifyQuad(super.getWrapped().findNG(g, s, p, o)) ;
+    }
+}

Added: jena/Scratch/AFS/Dev/src/element/ElementTransform.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/element/ElementTransform.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/element/ElementTransform.java (added)
+++ jena/Scratch/AFS/Dev/src/element/ElementTransform.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,51 @@
+/**
+ * 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 element;
+
+import java.util.List ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.Expr ;
+import com.hp.hpl.jena.sparql.syntax.* ;
+
+/** Transformation function on an Element
+ *  @see ElementTransformer
+ */
+public interface ElementTransform
+{
+    public Element transform(ElementTriplesBlock el) ;
+    public Element transform(ElementPathBlock el) ;
+    public Element transform(ElementFilter el, Expr expr2) ;
+    public Element transform(ElementAssign el, Var v, Expr expr2) ;
+    public Element transform(ElementBind el, Var v, Expr expr2) ;
+    public Element transform(ElementData el) ;
+    public Element transform(ElementUnion el, List<Element> elements) ;
+    public Element transform(ElementOptional el, Element opElt) ;
+    public Element transform(ElementGroup el, List<Element> members) ;
+    public Element transform(ElementDataset el, Element subElt) ;
+    public Element transform(ElementNamedGraph el, Node gn, Element subElt) ;
+    public Element transform(ElementExists el, Element subElt) ;
+    public Element transform(ElementNotExists el, Element subElt) ;
+    public Element transform(ElementMinus el, Element eltRHS) ;
+    public Element transform(ElementService el, Node service, Element subElt) ;
+    public Element transform(ElementSubQuery el, Query query) ;
+}
+

Added: jena/Scratch/AFS/Dev/src/element/ElementTransformCopyBase.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/element/ElementTransformCopyBase.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/element/ElementTransformCopyBase.java (added)
+++ jena/Scratch/AFS/Dev/src/element/ElementTransformCopyBase.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,142 @@
+/**
+ * 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 element ;
+
+import java.util.List ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.expr.Expr ;
+import com.hp.hpl.jena.sparql.syntax.* ;
+
+/** Create a copy if the Element(s) below have chanaged */
+public class ElementTransformCopyBase implements ElementTransform {
+    // Note the use of == as object pointer equality.
+
+    @Override
+    public Element transform(ElementTriplesBlock el) {
+        return el ;
+    }
+
+    @Override
+    public Element transform(ElementPathBlock el) {
+        return el ;
+    }
+
+    @Override
+    public Element transform(ElementFilter el, Expr expr2) {
+        if ( el.getExpr() == expr2 )
+            return el ;
+        return new ElementFilter(expr2) ;
+    }
+
+    @Override
+    public Element transform(ElementAssign el, Var v, Expr expr2) {
+        if ( el.getVar() == v && el.getExpr() == expr2 )
+            return el ;
+        return new ElementAssign(v, expr2) ;
+    }
+
+    @Override
+    public Element transform(ElementBind el, Var v, Expr expr2) {
+        if ( el.getVar() == v && el.getExpr() == expr2 )
+            return el ;
+        return new ElementAssign(v, expr2) ;
+    }
+
+    @Override
+    public Element transform(ElementData el) {
+        return el ;
+    }
+
+    @Override
+    public Element transform(ElementUnion el, List<Element> elts) {
+        if ( el.getElements() == elts )
+            return el ;
+        ElementUnion el2 = new ElementUnion() ;
+        el2.getElements().addAll(elts) ;
+        return el2 ;
+    }
+
+    @Override
+    public Element transform(ElementOptional el, Element elt1) {
+        if ( el.getOptionalElement() == elt1 )
+            return el ;
+        return new ElementOptional(elt1) ;
+    }
+
+    @Override
+    public Element transform(ElementGroup el, List<Element> elts) {
+        if ( el.getElements() == elts )
+            return el ;
+        ElementGroup el2 = new ElementGroup() ;
+        el2.getElements().addAll(elts) ;
+        return el2 ;
+    }
+
+    @Override
+    public Element transform(ElementDataset el, Element elt1) {
+        if ( el.getPatternElement() == elt1 )
+            return el ;
+        return new ElementDataset(el.getDataset(), elt1) ;
+    }
+
+    @Override
+    public Element transform(ElementNamedGraph el, Node gn, Element elt1) {
+        if ( el.getGraphNameNode() == gn && el.getElement() == elt1 )
+            return el ;
+        return new ElementNamedGraph(gn, elt1) ;
+    }
+
+    @Override
+    public Element transform(ElementExists el, Element elt1) {
+        if ( el.getElement() == elt1 )
+            return el ;
+        return new ElementExists(elt1) ;
+    }
+
+    @Override
+    public Element transform(ElementNotExists el, Element elt1) {
+        if ( el.getElement() == elt1 )
+            return el ;
+        return new ElementNotExists(elt1) ;
+    }
+
+    @Override
+    public Element transform(ElementMinus el, Element elt1) {
+        if ( el.getMinusElement() == elt1 )
+            return el ;
+        return new ElementMinus(elt1) ;
+    }
+
+    @Override
+    public Element transform(ElementService el, Node service, Element elt1) {
+        if ( el.getServiceNode() == service && el.getElement() == elt1 )
+            return el ;
+        return new ElementService(service, elt1, el.getSilent()) ;
+    }
+
+    @Override
+    public Element transform(ElementSubQuery el, Query query) {
+        if ( el.getQuery() == query )
+            return el ;
+        return new ElementSubQuery(query) ;
+    }
+}

Added: jena/Scratch/AFS/Dev/src/element/ElementTransformSubst.java
URL: http://svn.apache.org/viewvc/jena/Scratch/AFS/Dev/src/element/ElementTransformSubst.java?rev=1554915&view=auto
==============================================================================
--- jena/Scratch/AFS/Dev/src/element/ElementTransformSubst.java (added)
+++ jena/Scratch/AFS/Dev/src/element/ElementTransformSubst.java Thu Jan  2 21:00:47 2014
@@ -0,0 +1,104 @@
+/**
+ * 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 element ;
+
+import java.util.Map ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.Triple ;
+import com.hp.hpl.jena.sparql.core.TriplePath ;
+import com.hp.hpl.jena.sparql.core.Var ;
+import com.hp.hpl.jena.sparql.graph.NodeTransform ;
+import com.hp.hpl.jena.sparql.syntax.Element ;
+import com.hp.hpl.jena.sparql.syntax.ElementPathBlock ;
+import com.hp.hpl.jena.sparql.syntax.ElementTriplesBlock ;
+
+/** An ElementTransform which replaces occurences of a variable with a Node value.*/
+public class ElementTransformSubst extends ElementTransformCopyBase {
+    // NodeTransform
+
+    private final NodeTransform nodeTransform ;
+
+    public ElementTransformSubst(Map<Var, Node> mapping) {
+        this.nodeTransform = new NodeTransformSubst(mapping) ;
+    }
+
+    @Override
+    public Element transform(ElementTriplesBlock el) {
+        ElementTriplesBlock etb = new ElementTriplesBlock() ;
+        boolean changed = false ;
+        for (Triple t : el.getPattern()) {
+            Triple t2 = transform(t) ;
+            changed = changed || t != t2 ;
+            etb.addTriple(t2) ;
+        }
+        if ( changed )
+            return etb ;
+        return el ;
+    }
+
+    @Override
+    public Element transform(ElementPathBlock el) {
+        ElementPathBlock epb = new ElementPathBlock() ;
+        boolean changed = false ;
+        for (TriplePath p : el.getPattern()) {
+            TriplePath p2 = transform(p) ;
+            changed = changed || p != p2 ;
+            epb.addTriplePath(p2) ;
+        }
+        if ( changed )
+            return epb ;
+        return el ;
+    }
+
+    private TriplePath transform(TriplePath path) {
+        Node s = path.getSubject() ;
+        Node s1 = transform(s) ;
+        Node o = path.getObject() ;
+        Node o1 = transform(o) ;
+
+        if ( path.isTriple() ) {
+            Node p = path.getPredicate() ;
+            Node p1 = transform(p) ;
+            if ( s == s1 && p == p1 && o == o1 )
+                return path ;
+            return new TriplePath(Triple.create(s1, p1, o1)) ;
+        }
+        if ( s == s1 && o == o1 )
+            return path ;
+        return new TriplePath(s1, path.getPath(), o1) ;
+    }
+
+    private Triple transform(Triple triple) {
+        Node s = triple.getSubject() ;
+        Node s1 = transform(s) ;
+        Node p = triple.getPredicate() ;
+        Node p1 = transform(p) ;
+        Node o = triple.getObject() ;
+        Node o1 = transform(o) ;
+
+        if ( s == s1 && p == p1 && o == o1 )
+            return triple ;
+        return Triple.create(s1, p1, o1) ;
+    }
+
+    private Node transform(Node n) {
+        return nodeTransform.convert(n) ;
+    }
+}