[Mulgara-svn] r1740 - in trunk: . lib src/jar/query src/jar/query/java/org/jrdf/graph src/jar/query/java/org/mulgara src/jar/query/java/org/mulgara/connection src/jar/query/java/org/mulgara/jena src/jar/query/java/org/mulgara/query/filter src/jar/query/java/org/mulgara/query/rdf

pag at mulgara.org pag at mulgara.org
Fri Jun 26 20:19:40 UTC 2009


Author: pag
Date: 2009-06-26 13:19:39 -0700 (Fri, 26 Jun 2009)
New Revision: 1740

Added:
   trunk/lib/jenatest-2.5.6.jar
   trunk/src/jar/query/java/org/mulgara/connection/JenaConnection.java
   trunk/src/jar/query/java/org/mulgara/jena/
   trunk/src/jar/query/java/org/mulgara/jena/GraphMulgara.java
   trunk/src/jar/query/java/org/mulgara/jena/JenaMulgara.java
   trunk/src/jar/query/java/org/mulgara/jena/Jenara.java
   trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java
   trunk/src/jar/query/java/org/mulgara/jena/TestGraphMulgara.java
   trunk/src/jar/query/java/org/mulgara/jena/TransactionMulgara.java
Modified:
   trunk/.classpath
   trunk/build.properties
   trunk/src/jar/query/build.xml
   trunk/src/jar/query/java/org/jrdf/graph/AbstractBlankNode.java
   trunk/src/jar/query/java/org/jrdf/graph/AbstractLiteral.java
   trunk/src/jar/query/java/org/jrdf/graph/AbstractURIReference.java
   trunk/src/jar/query/java/org/jrdf/graph/Node.java
   trunk/src/jar/query/java/org/mulgara/connection/Connection.java
   trunk/src/jar/query/java/org/mulgara/connection/DummyConnection.java
   trunk/src/jar/query/java/org/mulgara/connection/SessionConnection.java
   trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java
   trunk/src/jar/query/java/org/mulgara/query/rdf/BlankNodeImpl.java
Log:
Integrated Andy Seaborne's JenaMulgara bridge. Added the JenaTest jar to properly test this bridge. Lots of optimizations are still possible.

Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/.classpath	2009-06-26 20:19:39 UTC (rev 1740)
@@ -94,6 +94,7 @@
 	<classpathentry kind="lib" path="lib/javacc.jar"/>
 	<classpathentry kind="lib" path="lib/jboss-j2ee.jar"/>
 	<classpathentry kind="lib" path="lib/jena-2.5.6.jar"/>
+	<classpathentry kind="lib" path="lib/jenatest-2.5.6.jar"/>
 	<classpathentry kind="lib" path="lib/iri-0.5.jar"/>
 	<classpathentry kind="lib" path="lib/jetty-6.1.11.jar"/>
 	<classpathentry kind="lib" path="lib/jetty-util-6.1.11.jar"/>

Modified: trunk/build.properties
===================================================================
--- trunk/build.properties	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/build.properties	2009-06-26 20:19:39 UTC (rev 1740)
@@ -119,6 +119,7 @@
 jakarta-oro.jar          =jakarta-oro-2.0.5.jar
 jca.jar                  =connector-1_5.jar
 jena.jar                 =jena-2.5.6.jar
+jenatest.jar             =jenatest-2.5.6.jar
 jline.jar                =jline-0.9.94.jar
 iri.jar                  =iri-0.5.jar
 jetty.jar                =jetty-6.1.11.jar

Added: trunk/lib/jenatest-2.5.6.jar
===================================================================
(Binary files differ)


Property changes on: trunk/lib/jenatest-2.5.6.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/src/jar/query/build.xml
===================================================================
--- trunk/src/jar/query/build.xml	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/build.xml	2009-06-26 20:19:39 UTC (rev 1740)
@@ -21,6 +21,7 @@
 
     <path refid="common-classpath"/>
     <fileset file="${util.dist.dir}/${util.jar}"/>
+    <fileset file="${lib.dir}/${jenatest.jar}"/>
   </path>
 
   <path id="query-test-classpath">

Modified: trunk/src/jar/query/java/org/jrdf/graph/AbstractBlankNode.java
===================================================================
--- trunk/src/jar/query/java/org/jrdf/graph/AbstractBlankNode.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/jrdf/graph/AbstractBlankNode.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -77,7 +77,7 @@
    * NOTE : update this serialVersionUID when a method or a public member is
    * deleted.
    */
-  private static final long serialVersionUID = 3481053689307839406L;
+  private static final long serialVersionUID = -7634211510359964243L;
 
   /**
    * Accept a call from a TypedNodeVisitor.
@@ -105,4 +105,10 @@
   public String toString() {
     return "_:" + getID();
   }
+
+  public boolean isLiteral() { return false; }
+
+  public boolean isBlankNode() { return true; }
+
+  public boolean isURIReference() { return false; }
 }

Modified: trunk/src/jar/query/java/org/jrdf/graph/AbstractLiteral.java
===================================================================
--- trunk/src/jar/query/java/org/jrdf/graph/AbstractLiteral.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/jrdf/graph/AbstractLiteral.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -82,7 +82,7 @@
    * NOTE : update this serialVersionUID when a method or a public member is
    * deleted.
    */
-  private static final long serialVersionUID = 2589574733270452078L;
+  private static final long serialVersionUID = 1191947630907453592L;
 
   /**
    * Whether the literal is well formed XML.
@@ -251,4 +251,12 @@
 
     return appendString;
   }
+
+
+  public boolean isLiteral() { return true; }
+
+  public boolean isBlankNode() { return false; }
+
+  public boolean isURIReference() { return false; }
+
 }

Modified: trunk/src/jar/query/java/org/jrdf/graph/AbstractURIReference.java
===================================================================
--- trunk/src/jar/query/java/org/jrdf/graph/AbstractURIReference.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/jrdf/graph/AbstractURIReference.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -73,7 +73,7 @@
    * NOTE : update this serialVersionUID when a method or a public member is
    * deleted.
    */
-  private static final long serialVersionUID = 8034954863132812197L;
+  private static final long serialVersionUID = 9005249520402745489L;
 
   /** The URI of the node. */
   private URI uri;
@@ -196,4 +196,10 @@
   public int hashCode() {
     return toString().hashCode();
   }
+
+  public boolean isLiteral() { return false; }
+
+  public boolean isBlankNode() { return false; }
+
+  public boolean isURIReference() { return true; }
 }

Modified: trunk/src/jar/query/java/org/jrdf/graph/Node.java
===================================================================
--- trunk/src/jar/query/java/org/jrdf/graph/Node.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/jrdf/graph/Node.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -1,10 +1,4 @@
 /*
- * $Header$
- * $Revision: 624 $
- * $Date: 2006-06-24 21:02:12 +1000 (Sat, 24 Jun 2006) $
- *
- * ====================================================================
- *
  * The Apache Software License, Version 1.1
  *
  * Copyright (c) 2003 The JRDF Project.  All rights reserved.
@@ -67,8 +61,26 @@
  *
  * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
  * @author Andrew Newman
+ * @author Paul Gearon
  *
- * @version $Revision: 624 $
  */
 public interface Node extends Serializable, Value {
+
+  /**
+   * Indicates if this object is a literal.
+   * @return <code>true</code> if and only if the node is a Literal.
+   */
+  boolean isLiteral();
+
+  /**
+   * Indicates if this object is a BlankNode.
+   * @return <code>true</code> if and only if the node is a BlankNode.
+   */
+  boolean isBlankNode();
+
+  /**
+   * Indicates if this object is a URIReference.
+   * @return <code>true</code> if and only if the node is a URIReference.
+   */
+  boolean isURIReference();
 }

Modified: trunk/src/jar/query/java/org/mulgara/connection/Connection.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/connection/Connection.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/mulgara/connection/Connection.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -87,7 +87,7 @@
  * @copyright &copy; 2007 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
  * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
  */
-public interface Connection {
+public interface Connection extends JenaConnection {
 
   /**
    * Give login credentials and security domain to the current session.  This should only be needed

Modified: trunk/src/jar/query/java/org/mulgara/connection/DummyConnection.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/connection/DummyConnection.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/mulgara/connection/DummyConnection.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -17,6 +17,9 @@
 import org.mulgara.query.QueryException;
 import org.mulgara.server.Session;
 
+import com.hp.hpl.jena.graph.Graph;
+import com.hp.hpl.jena.rdf.model.Model;
+
 /**
  * A connection for accepting state changes at the local end with no server involvement
  *
@@ -109,5 +112,55 @@
   public boolean isRemote() {
     return false;
   }
+
+
+  public Graph connectGraph(String graphURI) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public Graph connectGraph(String graphURI, boolean createIfDoesNotExist) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public Graph connectGraph(URI graphURI, boolean createIfDoesNotExist) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public Model connectModel(String graphURI) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public Model connectModel(String graphURI, boolean createIfDoesNotExist) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public Model connectModel(URI graphURI, boolean createIfDoesNotExist) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public Graph createGraph(String graphURI) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public Model createModel(String graphURI) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public void dropGraph(String graphURI) {
+    throw new UnsupportedOperationException();
+  }
+
+
+  public void dropGraph(URI graphURI) {
+    throw new UnsupportedOperationException();
+  }
   
 }

Added: trunk/src/jar/query/java/org/mulgara/connection/JenaConnection.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/connection/JenaConnection.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/connection/JenaConnection.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -0,0 +1,106 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.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.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.connection;
+
+import java.net.URI;
+
+import com.hp.hpl.jena.graph.Graph;
+import com.hp.hpl.jena.rdf.model.Model;
+
+/**
+ * Describes operations expected by a Jena client.
+ *
+ * @created Jun 22, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+public interface JenaConnection {
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.  
+   * Does not create the remote model.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Model connectModel(String graphURI);
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model,
+   * creating the model if it does not already exist.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Model createModel(String graphURI);
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  public Model connectModel(String graphURI, boolean createIfDoesNotExist);
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.
+   * @param graphURI The URI of the Mulgara model.
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  public Model connectModel(URI graphURI, boolean createIfDoesNotExist);
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model. Does not create the remote model.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Graph connectGraph(String graphURI);
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.  
+   * Creates the remote graph if it does not already exist.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Graph createGraph(String graphURI);
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Graph.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  public Graph connectGraph(String graphURI, boolean createIfDoesNotExist);
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Graph.
+   * @param graphURI The URI of the Mulgara model.
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Graph
+   */
+  public Graph connectGraph(URI graphURI, boolean createIfDoesNotExist);
+
+
+  /**
+   * Drop the Mulgara graph/model.
+   * @param graphURI The URI of the graph
+   */
+  public void dropGraph(String graphURI);
+
+  /**
+   * Drop the Mulgara graph/model.
+   * @param graphURI The URI of the graph
+   */
+  public void dropGraph(URI graphURI);
+
+}

Modified: trunk/src/jar/query/java/org/mulgara/connection/SessionConnection.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/connection/SessionConnection.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/mulgara/connection/SessionConnection.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -12,8 +12,10 @@
 package org.mulgara.connection;
 
 import java.net.URI;
+import java.net.URISyntaxException;
 
 import org.apache.log4j.Logger;
+import org.mulgara.jena.GraphMulgara;
 import org.mulgara.query.QueryException;
 import org.mulgara.server.NonRemoteSessionException;
 import org.mulgara.server.Session;
@@ -21,6 +23,11 @@
 import org.mulgara.server.driver.SessionFactoryFinder;
 import org.mulgara.server.driver.SessionFactoryFinderException;
 
+import com.hp.hpl.jena.graph.Graph;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.shared.JenaException;
+
 /**
  * A connection for sending commands to a server using a session object.
  *
@@ -299,5 +306,138 @@
   public boolean isRemote() {
     return session != null && !session.isLocal();
   }
-  
+
+
+  ///////////////////////////////////////////////////////////////////////
+  // The JenaConnection interface
+  ///////////////////////////////////////////////////////////////////////
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model. Does not create the remote model.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Graph connectGraph(String graphURI) {
+    return connectGraph(graphURI, false);
+  }
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Graph.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  public Graph connectGraph(String graphURI, boolean createIfDoesNotExist) {
+    try {
+      return connectGraph(new URI(graphURI), createIfDoesNotExist);
+    } catch (URISyntaxException ex) {
+      throw new JenaException("JenaMulgara.connectGraph", ex);
+    }
+  }
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Graph.
+   * @param graphURI The URI of the Mulgara model.
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Graph
+   */
+  public Graph connectGraph(URI graphURI, boolean createIfDoesNotExist) {
+    if (createIfDoesNotExist) {
+      try {
+        if (!session.modelExists(graphURI)) session.createModel(graphURI, null);
+      } catch (QueryException ex) {
+        throw new JenaException(ex);
+      }
+    }
+    return new GraphMulgara(session, graphURI) ;
+  }
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.  
+   * Does not create the remote model.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Model connectModel(String graphURI) {
+    return connectModel(graphURI, false);
+  }
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  public Model connectModel(String graphURI, boolean createIfDoesNotExist) {
+    try {
+      return connectModel(new URI(graphURI), createIfDoesNotExist);
+    } catch (URISyntaxException ex) {
+      throw new JenaException("JenaMulgara.createModel", ex);
+    }
+  }
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.
+   * @param graphURI The URI of the Mulgara model.
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  public Model connectModel(URI graphURI, boolean createIfDoesNotExist) {
+    Graph g = connectGraph(graphURI, createIfDoesNotExist);
+    return ModelFactory.createModelForGraph(g);
+  }
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.  
+   * Creates the remote graph if it does not already exist.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Graph createGraph(String graphURI) {
+    return connectGraph(graphURI, true);
+  }
+
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model,
+   * creating the model if it does not already exist.
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  public Model createModel(String graphURI) {
+    return connectModel(graphURI, true);
+  }
+
+
+  /**
+   * Drop the Mulgara graph/model.
+   * @param graphURI The URI of the graph
+   */
+  public void dropGraph(String graphURI) {
+    try {
+      dropGraph(new URI(graphURI)) ;
+    } catch (URISyntaxException ex) {
+      throw new JenaException("JenaMulgara.dropGraph", ex);
+    }
+  }
+
+
+  /**
+   * Drop the Mulgara graph/model.
+   * @param graphURI The URI of the graph
+   */
+  public void dropGraph(URI graphURI) {
+    try {
+      session.removeModel(graphURI);
+    } catch (Exception ex) {
+      throw new JenaException("JenaMulgara.dropGraph", ex);
+    }
+  }
+
 }

Added: trunk/src/jar/query/java/org/mulgara/jena/GraphMulgara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/jena/GraphMulgara.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/jena/GraphMulgara.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -0,0 +1,278 @@
+package org.mulgara.jena;
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ * [See end of file]
+ */
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.jrdf.graph.ObjectNode;
+import org.jrdf.graph.PredicateNode;
+import org.jrdf.graph.SubjectNode;
+import org.mulgara.query.QueryException;
+import org.mulgara.server.Session;
+
+import com.hp.hpl.jena.graph.Capabilities;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.TransactionHandler;
+import com.hp.hpl.jena.graph.Triple;
+import com.hp.hpl.jena.graph.TripleMatch;
+import com.hp.hpl.jena.graph.impl.GraphBase;
+import com.hp.hpl.jena.graph.query.BindingQueryPlan;
+import com.hp.hpl.jena.graph.query.Domain;
+import com.hp.hpl.jena.graph.query.QueryHandler;
+import com.hp.hpl.jena.shared.JenaException;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+import com.hp.hpl.jena.util.iterator.NiceIterator;
+
+/**
+ * Represents a Jena graph as instantiated by Mulgara.
+ *
+ * @author Andy Seaborne
+ * @copyright &copy; 2008 Hewlett-Packard Development Company, LP
+ */
+public class GraphMulgara extends GraphBase {
+  // TODO Bnodes (bless 'em!) - currently skolemized, change to label skolemization.
+  // TODO Batched updates
+
+  private Session session;
+  private URI modelURI;
+  private QueryHandler queryHandler;
+  private TransactionMulgara transactionHandler = null;
+    
+  public GraphMulgara(Session session, URI modelURI) {
+    this.session = session;
+    this.modelURI = modelURI;
+    transactionHandler = new TransactionMulgara(this, session);
+    queryHandler = new PatternMulgara(this);
+  }
+    
+  public Session getSession() {
+    return session;
+  }
+
+  public URI getModelURI() {
+    return modelURI;
+  }
+
+  @Override
+  public TransactionHandler getTransactionHandler() {
+    return transactionHandler;
+  }
+
+  @Override 
+  public QueryHandler queryHandler() {
+    return queryHandler;
+  }
+    
+  @Override
+  public void performAdd(Triple t) {
+    // if (transactionHandler.inExplicitTransaction()) { }
+        
+    try {
+      Set<org.jrdf.graph.Triple> acc = prepare(t);
+      session.insert(modelURI, acc);
+    } catch (QueryException ex) {
+      throw new JenaException(ex);
+    }
+  }
+
+  @Override
+  public void performDelete(Triple t) { 
+    try {
+      Set<org.jrdf.graph.Triple> acc = prepare(t) ;
+      session.delete(modelURI, acc) ;
+    } catch (QueryException ex) {
+      throw new JenaException(ex) ;
+    }
+  }
+
+  private final Set<org.jrdf.graph.Triple> prepare(Triple t) {
+    Node s = t.getSubject();
+    Node p = t.getPredicate();
+    Node o = t.getObject();
+    return prepare(s,p,o);
+  }
+    
+  private final Set<org.jrdf.graph.Triple> prepare(Node s, Node p, Node o) {
+    try {
+//      if (s.isBlank() || o.isBlank()) throw new JenaException("GraphMulgara : blank nodes not supported yet") ; 
+      SubjectNode sNode = (SubjectNode)Jenara.n2v(s, session);
+      PredicateNode pNode = (PredicateNode)Jenara.n2v(p, session);
+      ObjectNode oNode = (ObjectNode)Jenara.n2v(o, session);
+      org.jrdf.graph.Triple mt = new org.mulgara.query.rdf.TripleImpl(sNode, pNode, oNode);
+      Set<org.jrdf.graph.Triple> acc = new HashSet<org.jrdf.graph.Triple>();
+      acc.add(mt);
+      return acc;
+    } catch (URISyntaxException ex) {
+      throw new JenaException(ex);
+    }
+  }
+
+  @Override
+  protected ExtendedIterator graphBaseFind(TripleMatch m) {
+    int length = 0;
+    Node s = m.getMatchSubject();
+    Node p = m.getMatchPredicate();
+    Node o = m.getMatchObject();
+
+    if (s == null || s.equals(Node.ANY)) {
+      s = Node.createVariable("s");
+      length++;
+    }
+    if (p == null || p.equals(Node.ANY)) {
+      p = Node.createVariable("p");
+      length++;
+    }
+    if (o == null || o.equals(Node.ANY)) {
+      o = Node.createVariable("o");
+      length++;
+    }
+
+    // Check not already a variable.
+        
+    Node[] variables = new Node[length];
+    int i = 0;
+        
+    if (s.isVariable()) variables[i++] = s;  
+    if (p.isVariable()) variables[i++] = p;
+    if (o.isVariable()) variables[i++] = o;
+        
+    Triple t = new Triple(s,p,o) ;
+    com.hp.hpl.jena.graph.query.Query graphQuery = new com.hp.hpl.jena.graph.query.Query();
+    graphQuery.addMatch(t);
+    BindingQueryPlan plan = queryHandler().prepareBindings(graphQuery, variables);
+    ExtendedIterator iter = plan.executeBindings(); // Of domains
+    return new AnswerBindingIterator(iter, variables, t);
+  }
+    
+  static class AnswerBindingIterator extends NiceIterator {
+    private ExtendedIterator iter ;
+    private final Triple triple ;
+    private Triple slot ;
+    private boolean finished ;
+        
+    public AnswerBindingIterator(ExtendedIterator iter, Node[] variables, Triple t) {
+      this.iter = iter ;
+      this.triple = t ;
+      finished = false ;
+    }
+
+
+    @Override
+    public boolean hasNext() {
+      if (finished) return false;
+
+      if (slot != null) return true;
+            
+      if (!iter.hasNext()) {
+        NiceIterator.close(iter);
+        finished = true;
+        return false;
+      }
+            
+      Domain d = (Domain)iter.next();
+      Node s = triple.getSubject();
+      Node p = triple.getPredicate();
+      Node o = triple.getObject();
+      int i = 0;
+      if (s.isVariable()) s = d.getElement(i++);
+      if (p.isVariable()) p = d.getElement(i++);
+      if (o.isVariable()) o = d.getElement(i++);
+      slot = new Triple(s,p,o);
+      return true ;
+    }
+
+    // This form is common.
+    @Override
+    public Object next() {
+      if (!hasNext()) throw new NoSuchElementException("AnswerIterator.next");
+      Triple t = slot;
+      slot = null;
+      return t;
+    }
+
+    @Override
+    public void remove() { throw new UnsupportedOperationException(); } 
+  }
+
+  //private Node bNodeProperty = Node.createURI("http://jena.hpl.hp.com/JenaMulgara#bNodeLabel") ; 
+    
+    
+  // Callbacks from the tranaction handler.
+  void transactionStart() {}
+    
+  void transactionCommit() {
+    removeBNodeLabels() ;
+    flushBNodeMapping() ;
+  }
+    
+  void transactionAbort() { 
+    // No need - the transaction rollback will do that.
+    //removeBNodeLabels() ;
+    flushBNodeMapping() ;
+  }
+    
+  void flushBNodeMapping() {
+    //nodesToValues.clear();
+    //valuesToNodes.clear() ;
+  }
+
+  void removeBNodeLabels() { }
+
+    
+  @Override
+  public void close() {
+    super.close();
+  }
+
+  @Override
+  public Capabilities getCapabilities() {
+    if (capabilities == null) capabilities = new Capabilities() {
+        public boolean sizeAccurate()                   { return true; }
+        public boolean addAllowed()                     { return true ; }
+        public boolean addAllowed( boolean every )      { return true; } 
+        public boolean deleteAllowed()                  { return true ; }
+        public boolean deleteAllowed( boolean every )   { return true; } 
+        public boolean canBeEmpty()                     { return true; }
+        public boolean iteratorRemoveAllowed()          { return false; } /* ** */
+        public boolean findContractSafe()               { return true; }
+        public boolean handlesLiteralTyping()           { return false; } /* ** */
+    }; 
+    
+    return super.getCapabilities() ;
+  }
+}
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */

Added: trunk/src/jar/query/java/org/mulgara/jena/JenaMulgara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/jena/JenaMulgara.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/jena/JenaMulgara.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -0,0 +1,217 @@
+package org.mulgara.jena;
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ * [See end of file]
+ */
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.server.NonRemoteSessionException;
+import org.mulgara.server.Session;
+import org.mulgara.server.SessionFactory;
+import org.mulgara.server.driver.SessionFactoryFinder;
+import org.mulgara.server.driver.SessionFactoryFinderException;
+
+import com.hp.hpl.jena.graph.Graph;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.shared.JenaException;
+
+/**
+ * Factory for graphs and model that provide the Jena operations over Mulgara-stored RDF data.
+ * Documentation: {@link http://jena.hpl.hp.com/wiki/JenaMulgara}
+ * @author Andy Seaborne
+ * @deprecated These methods should be accessed through {@link org.mulgara.connection.JenaConnection}
+ */
+public class JenaMulgara {
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.  
+   * Does not create the remote model.
+   * @param serverURI The server URI as a string
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  static public Model connectModel(String serverURI, String graphURI) {
+    return connectModel(serverURI, graphURI, false);
+  }
+    
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model,
+   * creating the model if it does not already exist.
+   * @param serverURI The server URI as a string
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  static public Model createModel(String serverURI, String graphURI) {
+    return connectModel(serverURI, graphURI, true);
+  }
+    
+    
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.
+   * @param serverURI The server URI as a string
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  static public Model connectModel(String serverURI, String graphURI, boolean createIfDoesNotExist) {
+    try {
+      return connectModel(createSession(serverURI), new URI(graphURI), createIfDoesNotExist);
+    } catch (URISyntaxException ex) {
+      throw new JenaException("JenaMulgara.createModel", ex);
+    }
+  }
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.
+   * @param session The Mulgara Session object
+   * @param graphURI The URI of the Mulgara model.
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  static public Model connectModel(Session session, URI graphURI, boolean createIfDoesNotExist) {
+    Graph g = connectGraph(session, graphURI, createIfDoesNotExist);
+    return ModelFactory.createModelForGraph(g);
+  }
+
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.  Does not create the remote model.
+   * @param serverURI The server URI as a string
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  static public Graph connectGraph(String serverURI, String graphURI) {
+    return connectGraph(serverURI, graphURI, false);
+  }
+    
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Model.  
+   * Creates the remote graph if it does not already exist.
+   * @param serverURI The server URI as a string
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @return A Jena Model
+   */
+  static public Graph createGraph(String serverURI, String graphURI) {
+    return connectGraph(serverURI, graphURI, true);
+  }
+    
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Graph.
+   * @param serverURI The server URI as a string
+   * @param graphURI The URI,as a string, of the Mulgara model in the server 
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Model
+   */
+  static public Graph connectGraph(String serverURI, String graphURI, boolean createIfDoesNotExist) {
+    try {
+      return connectGraph(createSession(serverURI), new URI(graphURI), createIfDoesNotExist) ;
+    } catch (URISyntaxException ex) {
+      throw new JenaException("JenaMulgara.createGraph", ex);
+    }
+  }
+    
+  /**
+   * Connect to RDF data stored in a Mulgara server as a Jena Graph.
+   * @param session The Mulgara Session object
+   * @param graphURI The URI of the Mulgara model.
+   * @param createIfDoesNotExist Create the Mulgara model if it does not already exist.
+   * @return A Jena Graph
+   */
+  static public Graph connectGraph(Session session, URI graphURI, boolean createIfDoesNotExist) {
+    if (createIfDoesNotExist) {
+      try {
+        boolean definitelyExists = false ;
+        definitelyExists = session.modelExists(graphURI);
+        if (!definitelyExists) session.createModel(graphURI, null);
+      } catch (QueryException ex) {
+        throw new JenaException(ex);
+      }
+    }
+    Graph g = new GraphMulgara(session, graphURI) ;
+    return g;
+  }
+
+
+  /**
+   * Drop the Mulgara graph/model.
+   * @param serverURI The server URI
+   * @param graphURI The URI of the graph
+   */
+  public static void dropGraph(String serverURI, String graphURI) {
+    Session session = createSession(serverURI) ;
+    try {
+      dropGraph(session, new URI(graphURI)) ;
+    } catch (URISyntaxException ex) {
+      throw new JenaException("JenaMulgara.dropGraph", ex);
+    }
+  }
+
+  /**
+   * Drop the Mulgara graph/model.
+   * @param session The session to use for dropping the graph.
+   * @param graphURI The URI of the graph
+   */
+  public static void dropGraph(Session session, URI graphURI) {
+    try {
+      session.removeModel(graphURI);
+    } catch (Exception ex) {
+      throw new JenaException("JenaMulgara.dropGraph", ex);
+    }
+  }
+
+  /**
+   * Create a Mulgara session to a server, by URI
+   * @param serverURI The URI of the server to get the session for.
+   * @return A new session.
+   */
+  public static Session createSession(String serverURI) {
+    try {
+      // Create the URI of the server
+      URI server = new URI(serverURI);
+      // Create a new session factory
+      SessionFactory sessionFactory = SessionFactoryFinder.newSessionFactory(server, true);
+      Session session = sessionFactory.newSession();
+      return session;
+    } catch (URISyntaxException ex) {
+      throw new JenaException("JenaMulgara.createSession", ex);
+    } catch (SessionFactoryFinderException ex) {
+      throw new JenaException("JenaMulgara.createSession", ex);
+    } catch (NonRemoteSessionException ex) {
+      throw new JenaException("JenaMulgara.createSession", ex);
+    } catch (QueryException ex) {
+      throw new JenaException("JenaMulgara.createSession", ex);
+    }
+  }
+}
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */

Added: trunk/src/jar/query/java/org/mulgara/jena/Jenara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/jena/Jenara.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/jena/Jenara.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -0,0 +1,200 @@
+package org.mulgara.jena;
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ * [See end of file]
+ */
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.URIReference;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintIs;
+import org.mulgara.query.Value;
+import org.mulgara.query.Variable;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.server.Session;
+
+import com.hp.hpl.jena.datatypes.RDFDatatype;
+import com.hp.hpl.jena.datatypes.TypeMapper;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.rdf.model.AnonId;
+
+/**
+ * This class was developed to allow for transitions between nodes in the Jena API
+ * and nodes in the Mulgara API.
+ * May only be used with the XA1.1 StringPool.
+ * <em>Blank node allocations will fail with the XA StringPool.</em>
+ * 
+ * @created Jun 22, 2009
+ * @author Andy Seaborne
+ * @copyright &copy; Hewlett-Packard Development Company, LP
+ */
+public class Jenara {
+
+  // removing skolemizing will require a new Resolver API to return
+  // a mapping from requested blank nodes to newly allocated blank nodes.
+
+  // Skolemized Bnodes are URIs of the form "bnode:label"
+  static boolean skolemizedBlankNodes = true;
+  static final String bNodeScheme = "bnode:";
+  static final String LABEL = BlankNodeImpl.LABEL;
+  static final int LABEL_LEN = LABEL.length();
+    
+  // UGLY (and duplicated from GraphMulgara)
+  // These maps ensure that Jena allocated nodes are associated with Mulgara nodes
+  // Mulgara allocated nodes are converted to Jena labels with appropriate identifiers
+
+  // Jena --> Mulgara
+  private static Map<Node,Value> nodesToValues = new HashMap<Node,Value>();
+  // Mulgara --> Jena
+  private static Map<Long,Node> valuesToNodes = new HashMap<Long,Node>();
+
+
+  /**
+   * Map a Jena graph node to a Mulgara value.
+   * @param x The Jena Node to convert.
+   * @param session A session to use for blank node persistence.
+   * @return A Mulgara Value.
+   * @throws URISyntaxException When creating a URIReference that refers to an invalid URI.
+   */
+  static Value n2v(Node x, Session session) throws URISyntaxException {
+    if (x.isURI()) return new URIReferenceImpl(new URI(x.getURI()));
+
+    if (x.isLiteral()) {
+      // The return types are Mulgara LiteralImpl
+      if (x.getLiteralDatatypeURI() != null) {
+        return new LiteralImpl(x.getLiteralLexicalForm(), new URI(x.getLiteralDatatypeURI()));
+      }
+      if (x.getLiteralLanguage() != null) {
+        return new LiteralImpl(x.getLiteralLexicalForm(), x.getLiteralLanguage());
+      }
+      return new LiteralImpl(x.getLiteralLexicalForm()) ;
+    }
+
+    if (x.isBlank()) {
+      // is this a previously encountered Jena-allocated node?
+      Value bn = nodesToValues.get(x);
+      if (bn != null) return bn;
+
+      // May be a Mulgara-allocated bNode (and so we we have seen before)
+      String blankLabel = x.getBlankNodeLabel();
+      if (blankLabel.startsWith(LABEL)) {
+        long id = Long.parseLong(blankLabel.substring(LABEL_LEN));
+        return new BlankNodeImpl(BlankNodeImpl.counterToNode(id));
+      }
+
+      // It's not - it's a Jena one.
+      if (skolemizedBlankNodes) {
+        String skol = bNodeScheme+x.getBlankNodeLabel();
+        return new URIReferenceImpl(new URI(skol));
+      }
+
+      // Not a Mulgara-allocated bNode.  Create a new mapping.
+      BlankNodeImpl v = new BlankNodeImpl();
+
+      nodesToValues.put(x, v);
+      valuesToNodes.put(v.getNodeId(), x);
+      return v;
+    }
+
+    throw new RuntimeException("Can't convert from Jena node : " + x) ; 
+
+  }
+
+  /**
+   * Convert a Mulgara Value to a Jena graph node.
+   * @param obj The Mulgara value to convert.
+   * @return A new Jena graph node.
+   */
+  static Node o2n(org.jrdf.graph.Node obj) {
+    if (obj == null) return Node.ANY;
+
+    // testing for org.jrdf.graph.URIReference
+    if (obj.isURIReference()) {
+      URIReference uRef = (URIReference)obj;
+      if (skolemizedBlankNodes) {
+        String x = uRef.getURI().toString();
+        if (x.startsWith(bNodeScheme)) {
+          x = x.substring(bNodeScheme.length());
+          Node n = Node.createAnon(new AnonId(x));
+          return n;
+        }
+      }
+      return Node.createURI(uRef.getURI().toString());
+    }
+
+    // testing for org.jrdf.graph.Literal
+    if (obj.isLiteral()) {
+      Literal literal = (Literal)obj;
+      if (literal.getDatatypeURI() != null) {
+        RDFDatatype type = TypeMapper.getInstance().getSafeTypeByName(literal.getDatatypeURI().toString()) ;
+        return Node.createLiteral(literal.getLexicalForm(), null, type);
+      }
+
+      return Node.createLiteral(literal.getLexicalForm(), literal.getLanguage(), null);
+    }
+          
+    if (obj.isBlankNode()) {
+      BlankNodeImpl b = (BlankNodeImpl)obj;
+      // check if this was a Jena-allocated node
+      Node jenaNode = valuesToNodes.get(b);
+      // if not known, then create a Jena node from the Mulgara ID
+      return jenaNode != null ? jenaNode : Node.createAnon(new AnonId(b.getID()));
+    }
+    throw new RuntimeException("Can't convert to Jena Node : "+obj) ; 
+  }
+
+  /**
+   * Expand a constraint expression to include a variable that is prebound to a value.
+   * @param c The constraint expression to expand.
+   * @param var The variable to be bound.
+   * @param value The value to bind the variable to.
+   * @return The new constraint expression with the prebound variable.
+   */
+  static ConstraintExpression constraint(ConstraintExpression c, Variable var, ConstraintElement value) {
+    ConstraintExpression c2 = new ConstraintIs(var, value);
+    if (c != null) {
+      return new ConstraintConjunction(c, c2);
+    } else {
+      return c2;
+    }
+  }
+ 
+}
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
\ No newline at end of file

Added: trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -0,0 +1,259 @@
+package org.mulgara.jena;
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ * [See end of file]
+ */
+
+
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.mulgara.query.*;
+import org.mulgara.server.Session;
+
+import com.hp.hpl.jena.graph.Graph;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.Triple;
+import com.hp.hpl.jena.graph.query.BindingQueryPlan;
+import com.hp.hpl.jena.graph.query.Domain;
+import com.hp.hpl.jena.graph.query.Query;
+import com.hp.hpl.jena.graph.query.SimpleQueryHandler;
+import com.hp.hpl.jena.graph.query.TreeQueryPlan;
+import com.hp.hpl.jena.shared.JenaException;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+import com.hp.hpl.jena.util.iterator.NiceIterator;
+
+/**
+ * Handles Jena query patterns in Mulgara
+ *
+ * @author Andy Seaborne
+ * @copyright &copy; 2008 Hewlett-Packard Development Company, LP
+ */
+public class PatternMulgara extends SimpleQueryHandler {
+  // Scruffy
+
+  GraphMulgara graphMulgara;
+
+  /**
+   * @param graph
+   */
+  public PatternMulgara(GraphMulgara graph) {
+    super(graph);
+    graphMulgara = graph;
+  }
+
+  @Override
+  final public TreeQueryPlan prepareTree(Graph pattern) {
+    throw new RuntimeException("prepareTree - Chris says this will not be called");
+  }
+  
+  @SuppressWarnings("unchecked")
+  static List<Order> x = Collections.EMPTY_LIST;
+  
+  @Override
+  public BindingQueryPlan prepareBindings(Query q, Node [] variables) {
+    Map<Node, Variable> vars_jm = new HashMap<Node,Variable>();
+    List<Variable> proj = new ArrayList<Variable>() ;   // Mirrors Node [] variables
+    int idx = 0;
+
+    // Allocate variables.  Projection and pattern
+    for (int i = 0; i < variables.length; i++) {
+      Node v = variables[i] ;
+      idx = allocVar(vars_jm, proj, v, idx) ;
+    }
+    
+    @SuppressWarnings("unchecked")
+    List<Triple> pattern = q.getPattern() ;
+    for (Triple t: pattern) {
+      Node s = t.getSubject();
+      Node p = t.getPredicate();
+      Node o = t.getObject();
+      idx = allocVar(vars_jm, null, s, idx);
+      idx = allocVar(vars_jm, null, p, idx);
+      idx = allocVar(vars_jm, null, o, idx);
+    }
+
+    // Mulgara constraint
+    ConstraintExpression constraint = null;
+    for (Triple t: pattern) {
+        constraint = compileTriplePattern(constraint, vars_jm, 
+                                          t.getSubject(), t.getPredicate(), t.getObject());
+    }
+
+    // Mulgara query
+    org.mulgara.query.Query query = new org.mulgara.query.Query(
+         proj,                     // Projection
+         new GraphResource(graphMulgara.getModelURI()),        // Model to query
+         constraint,               // WHERE
+         null,                     // HAVING
+         x,                        // ORDER
+         null,                     // LIMIT
+         0,                        // OFFSET
+         new UnconstrainedAnswer() // Initial Answer
+    );
+
+    // Wrap it up into an query execution instance.
+    return new BindingQueryPlanMulgara(query, graphMulgara.getSession(), proj);
+  }
+      
+  private static int allocVar(Map<Node, Variable> vars_jm, List<Variable> proj, Node v, int idx) {
+    if (!v.isVariable()) return idx ;
+    if (!vars_jm.containsKey(v)) {
+      String vn = "v"+(idx++);
+      Variable vm = new Variable(vn);
+      vars_jm.put(v, vm);
+      if (proj != null) proj.add(vm);
+    }
+    return idx ;
+  }
+  
+  private ConstraintExpression compileTriplePattern(ConstraintExpression c,
+                                                           Map<Node,Variable> vars_jm,
+                                                           Node s, Node p, Node o) {
+    try {
+      ConstraintElement sElt = compile(vars_jm, s);
+      ConstraintElement pElt = compile(vars_jm, p);
+      ConstraintElement oElt = compile(vars_jm, o);
+
+      ConstraintExpression c2 = new ConstraintImpl(sElt, pElt, oElt);
+
+      if (c != null) return new org.mulgara.query.ConstraintConjunction(c, c2);
+      else return c2;
+
+    } catch (Exception ex) {
+      throw new JenaException("Failed to compile: ("+s+" "+p+" "+o+")");
+    }
+  }
+
+  private ConstraintElement compile(Map<Node, Variable> vars, Node n) throws URISyntaxException {
+    if (n.isVariable()) return vars.get(n);
+    else return Jenara.n2v(n, graphMulgara.getSession());
+  }
+
+
+  static class BindingQueryPlanMulgara implements BindingQueryPlan {
+    org.mulgara.query.Query query;
+    AnswerIterator iter;
+    private List<Variable> projection;
+    private Session session;
+    
+    public BindingQueryPlanMulgara(org.mulgara.query.Query query,
+                                   Session session,
+                                   List<Variable> proj) {
+      this.query = query ;
+      this.session = session ;
+      this.projection = proj ;
+    }
+    
+    public ExtendedIterator executeBindings() {
+      try {
+        Answer answer = session.query(query); 
+        // Must reset
+        answer.beforeFirst();
+        iter = new AnswerIterator(answer, projection);
+        return iter;
+
+      } catch (Exception ex) {
+        throw new JenaException("Failed to executeBindings");
+      }
+    }
+  }  
+  
+  // original comment of extending NiceIterator<Domain>
+  static class AnswerIterator extends NiceIterator {
+    private Answer answer;
+    private Domain slot = null;
+    private boolean finished = false;
+    private List<Variable> proj;
+
+    AnswerIterator(Answer answer, List<Variable> proj) {
+      this.answer = answer;
+      this.proj = proj;
+    }
+
+    @Override
+    public boolean hasNext() {
+      if (finished) return false;
+
+      if (slot != null) return true;
+      try {
+        if (! answer.next()) {
+            close();
+            return false;
+        }
+        slot = convert();
+
+      } catch (TuplesException ex) {
+        ex.printStackTrace();
+        return false;
+      }
+
+      return slot != null;
+    }
+
+    Domain convert() throws TuplesException {
+      Domain d = new Domain(proj.size());
+      for (int i = 0; i < proj.size(); i++) {
+        Node n = Jenara.o2n((org.jrdf.graph.Node)answer.getObject(i));
+        d.setElement(i, n);
+      }
+      return d ;
+    }
+
+    @Override
+    public Object next() {
+      if (!hasNext()) throw new NoSuchElementException("AnswerIterator.next");
+      Domain d = slot;
+      slot = null;
+      return d;
+    }
+
+    @Override
+    public void close() {
+      if (finished) return;
+      finished = true;
+      try {
+        answer.close();
+      } catch (TuplesException ex) {
+        ex.printStackTrace();
+      }
+    }
+
+    @Override
+    public void remove() { throw new UnsupportedOperationException(); } 
+  }     
+}
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */

Added: trunk/src/jar/query/java/org/mulgara/jena/TestGraphMulgara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/jena/TestGraphMulgara.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/jena/TestGraphMulgara.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -0,0 +1,113 @@
+package org.mulgara.jena;
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ * [See end of file]
+ */
+
+import org.mulgara.query.QueryException;
+
+import com.hp.hpl.jena.graph.Graph;
+import com.hp.hpl.jena.graph.TransactionHandler;
+import com.hp.hpl.jena.graph.query.QueryHandler;
+import com.hp.hpl.jena.graph.test.AbstractTestGraph;
+import com.hp.hpl.jena.shared.Command;
+import com.hp.hpl.jena.shared.JenaException;
+
+/**
+ * Test suite for the Jena bridge
+ *
+ * @created Jun 22, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2008 Hewlett-Packard Development Company, LP
+ */
+public class TestGraphMulgara extends AbstractTestGraph {
+
+  public TestGraphMulgara() {
+    super("GraphMulgara") ;
+  }
+
+  // Create new session each time.
+  // The Mulgara model must be created once (and possibly deleted) because of
+  // Mulgara Session.modelExists fails if the model never existed 
+  @SuppressWarnings("deprecation")
+  @Override
+  public Graph getGraph() {
+    try {
+      JenaMulgara.dropGraph("rmi://localhost/server1", "data:,test");
+    } catch (JenaException e) {
+      if (!(e.getCause() instanceof QueryException)) throw e;
+    }
+    return JenaMulgara.createGraph("rmi://localhost/server1", "data:,test") ;
+  }
+  
+  // This test is wrong in AbstractTestGraph for Mulgara.
+  @Override public void testHasTransactions() {
+    Graph g = getGraph();
+    TransactionHandler th = g.getTransactionHandler();
+    assertTrue(th.transactionsSupported()) ;
+    
+    th.begin(); th.abort();
+    
+    th.begin(); th.commit();
+    /* */
+    Command cmd = new Command() 
+    { public Object execute() { return null; } };
+    try { th.executeInTransaction( cmd ); } 
+    catch (UnsupportedOperationException x) {}
+  }
+
+  @Override public void testContainsNode() {
+    Graph g = getGraph();
+    graphAdd( g, "a P b; _c P1 _d; a P2 12" );
+    QueryHandler qh = g.queryHandler();
+    assertTrue( qh.containsNode( node( "a" ) ) );
+    assertTrue( qh.containsNode( node( "P" ) ) );
+    assertTrue( qh.containsNode( node( "b" ) ) );
+    assertTrue( qh.containsNode( node( "_c" ) ) );
+    assertTrue( qh.containsNode( node( "_d" ) ) );
+    assertTrue( qh.containsNode( node( "P2" ) ) );
+    assertTrue( qh.containsNode( node( "12" ) ) );
+    /* */
+    assertFalse( qh.containsNode( node( "x" ) ) );
+    assertFalse( qh.containsNode( node( "_y" ) ) );
+    assertFalse( qh.containsNode( node( "99" ) ) );
+  }
+  
+  // Tests that do not apply.
+  @Override public void testIsomorphismFile() {}
+  @Override public void testContainsFluid() {}
+
+  // These assume remove from an iterator.
+  @Override public void testRemoveAllEvent() {}
+  @Override public void testRemoveAll() {}
+  @Override public void testRemoveSPO() {}
+}
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
\ No newline at end of file

Added: trunk/src/jar/query/java/org/mulgara/jena/TransactionMulgara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/jena/TransactionMulgara.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/jena/TransactionMulgara.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -0,0 +1,112 @@
+package org.mulgara.jena;
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ * [See end of file]
+ */
+
+import org.apache.log4j.Logger;
+import org.mulgara.query.QueryException;
+import org.mulgara.server.Session;
+
+import com.hp.hpl.jena.graph.impl.TransactionHandlerBase;
+import com.hp.hpl.jena.shared.JenaException;
+
+/**
+ * Manages Jena transactions using the Mulgara transaction framework.
+ *
+ * @author Andy Seaborne
+ * @copyright &copy; 2008 Hewlett-Packard Development Company, LP
+ */
+class TransactionMulgara extends TransactionHandlerBase {
+
+  @SuppressWarnings("unused")
+  private static Logger log = Logger.getLogger(TransactionMulgara.class.getName()) ;
+
+  GraphMulgara mGraph ;
+  Session session  ;
+  boolean transactionActive = false ;
+
+  boolean inExplicitTransaction() {
+    return transactionActive;
+  }
+  
+  TransactionMulgara(GraphMulgara mGraph, Session session) {
+    this.session = session;
+    this.mGraph = mGraph;
+  }
+
+  private static void fatal(Exception ex) {
+    throw new JenaException(ex);
+  }
+  
+  private static void fatal(String msg) {
+    throw new JenaException(msg);
+  }
+  
+  public void abort() {
+    try {
+      if (!transactionActive) fatal("abort: Not in an explicit transaction");
+        session.rollback();
+        transaction(false);
+      } catch (QueryException ex) {
+        ex.printStackTrace();
+      }
+  }
+
+  public void begin() {
+    if (transactionActive) fatal("begin: Transaction already started");
+    transaction(true);
+  }
+  
+  public void commit() {
+    try {
+      if (!transactionActive) fatal("commit: Not in an explicit transaction") ;
+      session.commit() ;
+      transaction(false) ;
+    } catch (QueryException ex) {
+      ex.printStackTrace();
+    }
+  }
+
+  public boolean transactionsSupported() {
+    return true ;
+  }
+
+  private void transaction(boolean transactionOn) {
+    try {
+      session.setAutoCommit(!transactionOn) ;
+      transactionActive = transactionOn ;
+    } catch (QueryException ex) {
+      fatal(ex);
+    }
+  }
+}
+
+/*
+ * (c) Copyright 2008 Hewlett-Packard Development Company, LP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */

Modified: trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -148,5 +148,8 @@
     public static final Null NULL = new Null();
     public int hashCode() { return -1; }
     public String stringValue() { return "null"; }
+    public boolean isBlankNode() { return false; }
+    public boolean isLiteral() { return false; }
+    public boolean isURIReference() { return false; }
   }
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/rdf/BlankNodeImpl.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/rdf/BlankNodeImpl.java	2009-06-26 20:16:26 UTC (rev 1739)
+++ trunk/src/jar/query/java/org/mulgara/query/rdf/BlankNodeImpl.java	2009-06-26 20:19:39 UTC (rev 1740)
@@ -64,7 +64,7 @@
    * NOTE : update this serialVersionUID when a method or a public member is
    * deleted.
    */
-  static final long serialVersionUID = -3557083462564312948L;
+  private static final long serialVersionUID = 8304792420513868988L;
 
   /** The unique node id for the blank node. */
   private long nodeId;
@@ -74,14 +74,22 @@
   /** The mask that can remove the BLANK_NODE_BIT on nodes that use it. */
   static final private long COUNTER_MASK = 0x3FFFFFFFFFFFFFFFL;
 
+  /** The bit that indicates a blank node on nodes that use it. */
+  static final long BLANK_NODE_BIT = 0x4000000000000000L;
 
+  /** The label used for printing blank nodes. */
+  static final public String LABEL = "node";
+
+  /** The label used for printing blank nodes. */
+  static final private String _LABEL = "_node";
+
   /**
    * Create an empty blank node.  Just a place holder.
    */
   public BlankNodeImpl() {
     // Do nothing
     this(0);
-    stringValue = "node0";
+    stringValue = LABEL + "0";
   }
 
   /**
@@ -91,7 +99,7 @@
    */
   public BlankNodeImpl(long newNodeId) {
     nodeId = newNodeId;
-    stringValue = "node" + printable(nodeId);
+    stringValue = LABEL + printable(nodeId);
   }
 
 
@@ -110,7 +118,7 @@
    */
   public void setNodeId(long nodeId) {
     this.nodeId = nodeId;
-    stringValue = "node" + printable(nodeId);
+    stringValue = LABEL + printable(nodeId);
   }
 
 
@@ -159,7 +167,7 @@
    * @return the string value of the uri and node id.
    */
   public String toString() {
-    return "_node" + printable(nodeId);
+    return _LABEL + printable(nodeId);
   }
 
   public String getID() {
@@ -170,4 +178,13 @@
   private long printable(long l) {
     return l > 0 ? COUNTER_MASK & l : l;
   }
+
+  /**
+   * Duplicate of the BlankNodeAllocator utility to convert a blank node code to a counter value.
+   * @param counter The blank node value, with the blank node bit turned off.
+   * @return A value with the blank node bit turned on.
+   */
+  public static final long counterToNode(long counter) {
+    return counter | BLANK_NODE_BIT;
+  }
 }




More information about the Mulgara-svn mailing list