~ migrated db-specific URI parsing into RDB2RDF
authorEric Prud'hommeaux <eric@w3.org>
Sun, 31 Jan 2010 09:32:43 -0500
changeset 146 b9a9d66f3a33
parent 145 5fa8b27f1391
child 147 e4597da0affe
~ migrated db-specific URI parsing into RDB2RDF
src/main/scala/RDB2RDFMain.scala
src/main/scala/SPARQL.scala
src/test/scala/RDB2RDFTest.scala
src/test/scala/SparqlTest.scala
--- a/src/main/scala/RDB2RDFMain.scala	Sun Jan 31 08:10:01 2010 -0500
+++ b/src/main/scala/RDB2RDFMain.scala	Sun Jan 31 09:32:43 2010 -0500
@@ -74,6 +74,46 @@
   case class RDFNoder(relation:sql.Relation, binding:FullOrPartialBinding) extends SQL2RDFValueMapper(binding)
   case class RDFBNoder(relation:sql.Relation, binding:FullOrPartialBinding) extends SQL2RDFValueMapper(binding)
 
+  case class ObjUri(stem:Stem, rel:Rel, attr:Attr, v:CellValue)
+  case class Stem(s:String) {
+    override def toString = "" + s
+  }
+  case class Rel(s:String) { // !! NUKE
+    override def toString = "" + s
+  }
+  case class Attr(s:String) {
+    override def toString = "" + s
+  }
+  case class CellValue(s:String)
+  case class PUri(stem:Stem, rel:Rel, attr:Attr) {
+    override def toString = "<" + stem + "/" + rel + "#" + attr + ">"
+  }
+  /* stemURI + '/' + (\w+) + '#' (\w+) */
+  def parsePredicateURI(u:sparql.Uri):PUri = {
+    val x:String = u.s
+    val uri = new URI(x)
+    val path = uri.getPath().split("/").toList.filterNot(_ == "")
+    val subPath = path.slice(0, path.size - 1).mkString("/")
+    val stem = uri.getScheme() + "://" + uri.getAuthority + "/" + subPath
+    PUri(Stem(stem), Rel(path.last), Attr(uri.getFragment))
+  }
+
+  /* stemURI + '/' (\w+) '/' (\w+) '.' (\w+) '#record' */
+  def parseObjectURI(u:sparql.Uri):ObjUri = {
+    val x:String = u.s
+    val uri = new URI(x)
+    val path = uri.getPath().split("/").toList.filterNot(_ == "")
+    val subPath = path.slice(0, path.size - 2).mkString("/")
+    val rel = path(path.size - 2)
+    val attrPair = path(path.size-1).split("\\.")
+    val stem = uri.getScheme() + "://" + uri.getAuthority + "/" + subPath
+    assert("record" == uri.getFragment)
+    ObjUri(Stem(stem), Rel(rel), Attr(attrPair(0)), CellValue(attrPair(1)))
+  }
+/*
+Sparql.parseObjectURI(
+Sparql.parsePredicateURI(
+*/
   def relAliasFromS(s:sparql.S):sql.RelAlias = {
     s match {
       case sparql.SUri(ob) => relAliasFromNode(ob)
@@ -89,8 +129,8 @@
     }
   }
 
-  def relAliasFromNode(u:sparql.ObjUri):sql.RelAlias = {
-    val sparql.ObjUri(stem, rel, sparql.Attr(a), sparql.CellValue(v)) = u
+  def relAliasFromNode(u:sparql.Uri):sql.RelAlias = {
+    val ObjUri(stem, rel, Attr(a), CellValue(v)) = parseObjectURI(u)
     sql.RelAlias(sql.Name("R_" + a + v))
   }
 
@@ -105,7 +145,7 @@
 
   def attrAliasNameFromVar(v:sparql.Var):sql.Name = sql.Name("" + v.s)
 
-  def uriConstraint(state:R2RState, constrainMe:sql.RelAliasAttribute, u:sparql.ObjUri, enforeForeignKeys:Boolean):R2RState = {
+  def uriConstraint(state:R2RState, constrainMe:sql.RelAliasAttribute, u:ObjUri, enforeForeignKeys:Boolean):R2RState = {
     val relvar =
       if (enforeForeignKeys)
 	sql.RelAliasAttribute(constrainMe.relalias, sql.Attribute(sql.Name(u.attr.s)))
@@ -197,7 +237,8 @@
     val sparql.TriplePattern(s, p, o) = triple
     p match {
       case sparql.PVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
-      case sparql.PUri(stem, spRel, spAttr) => {
+      case sparql.PUri(uri) => {
+	val PUri(stem, spRel, spAttr) = parsePredicateURI(uri)
 	/* Attributes that come from the predicate: */
 	val rel = sql.Relation(sql.Name(spRel.s))
 	val attr = sql.Attribute(sql.Name(spAttr.s))
@@ -206,7 +247,7 @@
 	/* Attributes that come from the subject: */
 	val objattr = sql.RelAliasAttribute(relalias, attr)
 	val state_postSubj = s match {
-	  case sparql.SUri(u) => uriConstraint(stateP, sql.RelAliasAttribute(relalias, db.relationdescs(rel).primarykey.get), u, true)
+	  case sparql.SUri(u) => uriConstraint(stateP, sql.RelAliasAttribute(relalias, db.relationdescs(rel).primarykey.get), parseObjectURI(u), true)
 	  case sparql.SVar(v) => varConstraint(stateP, relalias, db.relationdescs(rel).primarykey, v, db, rel)
 	}
 	val state_subjJoin = R2RState(state_postSubj.joins + sql.InnerJoin(sql.AliasedResource(rel,relalias), None), state_postSubj.varmap, state_postSubj.exprs)
@@ -244,7 +285,7 @@
 	}
 	o match {
 	  case sparql.OLit(l) => literalConstraint(state_fkeys, targetattr, l, dt)
-	  case sparql.OUri(u) => uriConstraint    (state_fkeys, targetattr, u, enforceForeignKeys)
+	  case sparql.OUri(u) => uriConstraint    (state_fkeys, targetattr, parseObjectURI(u), enforceForeignKeys)
 	  case sparql.OVar(v) => varConstraint    (state_fkeys, targetattr.relalias, Some(targetattr.attribute), v, db, targetrel)
 	}
       }
@@ -365,7 +406,7 @@
       case sparql.TermVar(v) => { // :sparql.Var
 	val l = varToAttribute(varmap, v)
 	val r = rTerm match {
-	  case sparql.TermUri(obj) => null // :sparql.ObjUri
+	  case sparql.TermUri(obj) => null // :sparql.Uri
 	  case sparql.TermVar(v) => { // :sparql.Var
 	    sql.PrimaryExpressionAttr(varToAttribute(varmap, v))
 	  }
--- a/src/main/scala/SPARQL.scala	Sun Jan 31 08:10:01 2010 -0500
+++ b/src/main/scala/SPARQL.scala	Sun Jan 31 09:32:43 2010 -0500
@@ -29,20 +29,18 @@
 case class GraphGraphPattern(gp:GraphPattern) extends GraphPattern
 
 case class TriplePattern(s:S, p:P, o:O)
-case class ObjUri(stem:Stem, rel:Rel, attr:Attr, v:CellValue)
-case class CellValue(s:String)
 
 sealed abstract class S
-case class SUri(obj:ObjUri) extends S {
-  override def toString = "" + obj
+case class SUri(u:Uri) extends S {
+  override def toString = "" + u
 }
 case class SVar(v:Var) extends S {
   override def toString = "" + v
 }
 
 sealed abstract class O
-case class OUri(obj:ObjUri) extends O {
-  override def toString = "" + obj
+case class OUri(u:Uri) extends O {
+  override def toString = "" + u
 }
 case class OVar(v:Var) extends O {
   override def toString = "" + v
@@ -52,8 +50,8 @@
 }
 
 sealed abstract class P
-case class PUri(stem:Stem, rel:Rel, attr:Attr) extends P {
-  override def toString = "<" + stem + "/" + rel + "#" + attr + ">"
+case class PUri(u:Uri) extends P {
+  override def toString = "" + u
 }
 case class PVar(v:Var) extends P {
   override def toString = "" + v
@@ -63,18 +61,12 @@
   override def toString = "" + lit
 }
 
-case class Stem(s:String) {
-  override def toString = "" + s
-}
-case class Attr(s:String) {
-  override def toString = "" + s
-}
-case class Rel(s:String) {
-  override def toString = "" + s
+case class Var(s:String) {
+  override def toString = "?" + s
 }
 
-case class Var(s:String) {
-  override def toString = "?" + s
+case class Uri(s:String) {
+  override def toString = "<" + s + ">"
 }
 
 case class Expression(conjuncts:List[PrimaryExpression])
@@ -84,7 +76,7 @@
 case class SparqlTermExpression(term:Term)
 
 sealed abstract class Term
-case class TermUri(obj:ObjUri) extends Term
+case class TermUri(u:Uri) extends Term
 case class TermVar(v:Var) extends Term
 case class TermLit(lit:Literal) extends Term
 
@@ -101,7 +93,7 @@
     "{" ~ opt(triplesblock) ~ "}" ^^ { case "{"~tbOPT~"}" => tbOPT.getOrElse(TriplesBlock(List[TriplePattern]())) }
 
   def prefixdecls:Parser[Unit] =
-    "PREFIX" ~ name ~ ":" ~ qnameORuri ^^ { case "PREFIX"~pre~":"~u => prefixes += (pre -> u) }
+    "PREFIX" ~ name ~ ":" ~ qnameORuri ^^ { case "PREFIX"~pre~":"~u => prefixes += (pre -> u.s) }
 
   def filter:Parser[Expression] =
     "FILTER" ~ "(" ~ expression ~ ")" ^^ { case "FILTER"~"("~expression~")" => expression }
@@ -118,7 +110,7 @@
   )
 
   def value:Parser[SparqlTermExpression] = (
-      qnameORuri ^^ { case x => SparqlTermExpression(TermUri(Sparql.parseObjectURI(x))) }
+      qnameORuri ^^ { case x => SparqlTermExpression(TermUri(x)) }
     | varr ^^ { x => SparqlTermExpression(TermVar(x)) }
     | literal ^^ { x => SparqlTermExpression(TermLit(x)) }
   )
@@ -182,24 +174,24 @@
     subject ~ predicate ~ objectt ^^ { case s~p~o => TriplePattern(s, p, o) }
 
   def subject:Parser[S] = (
-      qnameORuri ^^ { case x => SUri(Sparql.parseObjectURI(x)) }
+      qnameORuri ^^ { case x => SUri(x) }
     | varr ^^ { x => SVar(x) }
   )
 
   def predicate:Parser[P] =
-    qnameORuri ^^ { case x => Sparql.parsePredicateURI(x) }
+    qnameORuri ^^ { x => PUri(x) }
 
   def objectt:Parser[O] = (
-      qnameORuri ^^ { case x => OUri(Sparql.parseObjectURI(x)) }
+      qnameORuri ^^ { case x => OUri(x) }
     | varr ^^ { x => OVar(x) }
     | literal ^^ { x => OLit(x) }
   )
 
-  def qnameORuri:Parser[String] = (
-      "<"~uri~">" ^^ { case "<"~x~">" => x }
+  def qnameORuri:Parser[Uri] = (
+      "<"~uri~">" ^^ { case "<"~x~">" => Uri(x) }
     | name~":"~name ^^ {
       case prefix~":"~localName => try {
-	prefixes(prefix) + localName
+	Uri(prefixes(prefix) + localName)
       } catch {
 	case e:java.util.NoSuchElementException =>
 	  throw new Exception("unknown prefix " + prefix)
@@ -210,7 +202,7 @@
   def literal:Parser[Literal] =
       stringLiteral~"^^"~qnameORuri ^^
       {
-	case lit~"^^"~dt => Literal(RDFLiteral(lit.substring(1,lit.size - 1), dt match {
+	case lit~"^^"~dt => Literal(RDFLiteral(lit.substring(1,lit.size - 1), dt.s match {
 	  case "http://www.w3.org/2001/XMLSchema#string" => RDFLiteral.StringDatatype
 	  case "http://www.w3.org/2001/XMLSchema#integer" => RDFLiteral.IntegerDatatype
 	  case "http://www.w3.org/2001/XMLSchema#date" => RDFLiteral.DateDatatype
@@ -225,25 +217,4 @@
 
 object Sparql {
 
-  /* stemURI + '/' + (\w+) + '#' (\w+) */
-  def parsePredicateURI(x:String):PUri = {
-    val uri = new URI(x)
-    val path = uri.getPath().split("/").toList.filterNot(_ == "")
-    val subPath = path.slice(0, path.size - 1).mkString("/")
-    val stem = uri.getScheme() + "://" + uri.getAuthority + "/" + subPath
-    PUri(Stem(stem), Rel(path.last), Attr(uri.getFragment))
-  }
-
-  /* stemURI + '/' (\w+) '/' (\w+) '.' (\w+) '#record' */
-  def parseObjectURI(x:String):ObjUri = {
-    val uri = new URI(x)
-    val path = uri.getPath().split("/").toList.filterNot(_ == "")
-    val subPath = path.slice(0, path.size - 2).mkString("/")
-    val rel = path(path.size - 2)
-    val attrPair = path(path.size-1).split("\\.")
-    val stem = uri.getScheme() + "://" + uri.getAuthority + "/" + subPath
-    assert("record" == uri.getFragment)
-    ObjUri(Stem(stem), Rel(rel), Attr(attrPair(0)), CellValue(attrPair(1)))
-  }
-
 }
--- a/src/test/scala/RDB2RDFTest.scala	Sun Jan 31 08:10:01 2010 -0500
+++ b/src/test/scala/RDB2RDFTest.scala	Sun Jan 31 09:32:43 2010 -0500
@@ -124,6 +124,23 @@
    * on a post-query transformation against those returing turtle atoms.
    */
 
+  test("decompose a predicate uri in stem, rel and attr") {
+    val uri = sparql.Uri("http://hr.example/our/favorite/DB/Employee#lastName")
+    val puri:RDB2RDF.PUri = RDB2RDF.parsePredicateURI(uri)
+    assert(puri === RDB2RDF.PUri(RDB2RDF.Stem("http://hr.example/our/favorite/DB"),
+				 RDB2RDF.Rel("Employee"),
+				 RDB2RDF.Attr("lastName")))
+  }
+
+  test("decompose a object uri in stem, rel and attr") {
+    val uri = sparql.Uri("http://hr.example/our/favorite/DB/Employee/id.18#record")
+    val objuri:RDB2RDF.ObjUri = RDB2RDF.parseObjectURI(uri)
+    assert(objuri === RDB2RDF.ObjUri(RDB2RDF.Stem("http://hr.example/our/favorite/DB"),
+				     RDB2RDF.Rel("Employee"),
+				     RDB2RDF.Attr("id"),
+				     RDB2RDF.CellValue("18")))
+  }
+
   /* Disable turtle string-izing (RDB2RDF parm 5) and return native format: */
   test("?s <p> <x>") {
     val sparqlParser = Sparql()
--- a/src/test/scala/SparqlTest.scala	Sun Jan 31 08:10:01 2010 -0500
+++ b/src/test/scala/SparqlTest.scala	Sun Jan 31 09:32:43 2010 -0500
@@ -11,7 +11,7 @@
     val e = """
 ?emp      <http://hr.example/DB/Employee#lastName>   "bob"^^<http://www.w3.org/2001/XMLSchema#string>
 """
-    val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),OLit(Literal(RDFLiteral("bob",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string"))))))))
+    val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Uri("http://hr.example/DB/Employee#lastName")),OLit(Literal(RDFLiteral("bob",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string"))))))))
     assert(expected === (a.parseAll(a.triplesblock, e).get))
   }
 
@@ -20,7 +20,7 @@
     val e = """
 ?emp      <http://hr.example/DB/Employee#age>   "21"^^<http://www.w3.org/2001/XMLSchema#integer>
 """
-    val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("age")),OLit(Literal(RDFLiteral("21",Datatype(new URI("http://www.w3.org/2001/XMLSchema#integer"))))))))
+    val expected = TriplesBlock(List(TriplePattern(SVar(Var("emp")),PUri(Uri("http://hr.example/DB/Employee#age")),OLit(Literal(RDFLiteral("21",Datatype(new URI("http://www.w3.org/2001/XMLSchema#integer"))))))))
     assert(expected === (a.parseAll(a.triplesblock, e).get))
   }
 
@@ -36,15 +36,15 @@
 	List(
 	  TriplePattern(
 	    SVar(Var("emp")),
-	    PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+	    PUri(Uri("http://hr.example/DB/Employee#lastName")),
 	    OVar(Var("empName"))),
 	  TriplePattern(
 	    SVar(Var("emp")),
-	    PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+	    PUri(Uri("http://hr.example/DB/Employee#manager")),
 	    OVar(Var("manager"))),
 	  TriplePattern(
 	    SVar(Var("manager")),
-	    PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+	    PUri(Uri("http://hr.example/DB/Employee#lastName")),
 	    OVar(Var("managName")))))
     assert(tps === a.parseAll(a.triplesblock, e).get)
   }
@@ -105,7 +105,7 @@
 	  List(
 	    TriplePattern(
 	      SVar(Var("emp")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+		PUri(Uri("http://hr.example/DB/Employee#lastName")),
 	      OVar(Var("empName"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -126,7 +126,7 @@
 	  List(
 	    TriplePattern(
 	      SVar(Var("emp")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+		PUri(Uri("http://hr.example/DB/Employee#lastName")),
 	      OVar(Var("empName"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -147,7 +147,7 @@
 	    List(
 	      TriplePattern(
 		SVar(Var("emp")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+		PUri(Uri("http://hr.example/DB/Employee#lastName")),
 		OVar(Var("empName"))))),
 	  Expression(List(
 	    PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("manBday"))),
@@ -173,15 +173,15 @@
 	  List(
 	    TriplePattern(
 	      SVar(Var("emp")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+		PUri(Uri("http://hr.example/DB/Employee#lastName")),
 	      OVar(Var("empName"))),
 	    TriplePattern(
 	      SVar(Var("emp")),
-	      PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+	      PUri(Uri("http://hr.example/DB/Employee#manager")),
 	      OVar(Var("manager"))),
 	    TriplePattern(
 	      SVar(Var("manager")),
-	      PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+	      PUri(Uri("http://hr.example/DB/Employee#lastName")),
 	      OVar(Var("managName"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -219,7 +219,7 @@
 	  List(
 	    TriplePattern(
 	      SVar(Var("x")),
-	      PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+	      PUri(Uri("http://hr.example/DB/Employee#manager")),
 	      OVar(Var("y"))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -237,13 +237,13 @@
 	    List(
 	      TriplePattern(
 		SVar(Var("x")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		PUri(Uri("http://hr.example/DB/Employee#manager")),
 		OVar(Var("y"))))),
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
 		SVar(Var("x")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		PUri(Uri("http://hr.example/DB/Employee#manager")),
 		OVar(Var("y"))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -261,13 +261,13 @@
 	    List(
 	      TriplePattern(
 		SVar(Var("x")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		PUri(Uri("http://hr.example/DB/Employee#manager")),
 		OVar(Var("y"))))),
 	  TriplesBlock(
 	    List(
 	      TriplePattern(
 		SVar(Var("x")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		PUri(Uri("http://hr.example/DB/Employee#manager")),
 		OVar(Var("y"))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -285,14 +285,14 @@
 	    List(
 	      TriplePattern(
 		SVar(Var("x")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		PUri(Uri("http://hr.example/DB/Employee#manager")),
 		OVar(Var("y"))))),
 	  OptionalGraphPattern(
 	    TriplesBlock(
 	      List(
 		TriplePattern(
 		  SVar(Var("x")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		  PUri(Uri("http://hr.example/DB/Employee#manager")),
 		  OVar(Var("y")))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -310,7 +310,7 @@
 	    List(
 	      TriplePattern(
 		SVar(Var("x")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		PUri(Uri("http://hr.example/DB/Employee#manager")),
 		OVar(Var("y")))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -328,14 +328,14 @@
 	    List(
 	      TriplePattern(
 		SVar(Var("x")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		PUri(Uri("http://hr.example/DB/Employee#manager")),
 		OVar(Var("y"))))),
 	  MinusGraphPattern(
 	    TriplesBlock(
 	      List(
 		TriplePattern(
 		  SVar(Var("x")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+		  PUri(Uri("http://hr.example/DB/Employee#manager")),
 		  OVar(Var("y")))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
@@ -361,37 +361,37 @@
 	    List(
 	      TriplePattern(
 		SVar(Var("who")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+		PUri(Uri("http://hr.example/DB/Employee#lastName")),
 		OLit(Literal(RDFLiteral("Smith",Datatype(new URI("http://www.w3.org/2001/XMLSchema#string")))))))),
 	  TableDisjunction(List(
 	    TriplesBlock(
 	      List(
 		TriplePattern(
 		  SVar(Var("above")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Manage"),Attr("manages")),
+		  PUri(Uri("http://hr.example/DB/Manage#manages")),
 		  OVar(Var("who"))),
 		TriplePattern(
 		  SVar(Var("above")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Manage"),Attr("manager")),
+		  PUri(Uri("http://hr.example/DB/Manage#manager")),
 		  OVar(Var("manager"))),
 		TriplePattern(
 		  SVar(Var("manager")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+		  PUri(Uri("http://hr.example/DB/Employee#lastName")),
 		  OVar(Var("name")))
 	      )),
 	    TriplesBlock(
 	      List(
 		TriplePattern(
 		  SVar(Var("below")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Manage"),Attr("manager")),
+		  PUri(Uri("http://hr.example/DB/Manage#manager")),
 		  OVar(Var("who"))),
 		TriplePattern(
 		  SVar(Var("below")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Manage"),Attr("manages")),
+		  PUri(Uri("http://hr.example/DB/Manage#manages")),
 		  OVar(Var("managed"))),
 		TriplePattern(
 		  SVar(Var("managed")),
-		  PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+		  PUri(Uri("http://hr.example/DB/Employee#lastName")),
 		  OVar(Var("name")))
 	      )))))))
     assert(tps === a.parseAll(a.select, e).get)
@@ -412,32 +412,15 @@
 """
     val tps =
       Select(SparqlAttributeList(List(Var("emp1Name"), Var("emp2Name"), Var("emp3Name"))),
-       TableFilter(TableConjunction(List(TriplesBlock(List(TriplePattern(SVar(Var("emp1")), PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")), OVar(Var("emp1Name"))))),
-					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(SVar(Var("emp1")), PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("birthday")), OVar(Var("birthday")))))),
-					 TriplesBlock(List(TriplePattern(SVar(Var("emp2")), PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")), OVar(Var("emp2Name"))))),
-					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(SVar(Var("emp2")), PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("birthday")), OVar(Var("birthday")))))),
-					 TriplesBlock(List(TriplePattern(SVar(Var("emp4")),PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("birthday")),OVar(Var("birthday"))))))),
+       TableFilter(TableConjunction(List(TriplesBlock(List(TriplePattern(SVar(Var("emp1")), PUri(Uri("http://hr.example/DB/Employee#lastName")), OVar(Var("emp1Name"))))),
+					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(SVar(Var("emp1")), PUri(Uri("http://hr.example/DB/Employee#birthday")), OVar(Var("birthday")))))),
+					 TriplesBlock(List(TriplePattern(SVar(Var("emp2")), PUri(Uri("http://hr.example/DB/Employee#lastName")), OVar(Var("emp2Name"))))),
+					 OptionalGraphPattern(TriplesBlock(List(TriplePattern(SVar(Var("emp2")), PUri(Uri("http://hr.example/DB/Employee#birthday")), OVar(Var("birthday")))))),
+					 TriplesBlock(List(TriplePattern(SVar(Var("emp4")),PUri(Uri("http://hr.example/DB/Employee#birthday")),OVar(Var("birthday"))))))),
 		   Expression(List(PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("emp1Name"))),SparqlTermExpression(TermVar(Var("emp2Name")))), PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("emp2Name"))),SparqlTermExpression(TermVar(Var("emp3Name")))), PrimaryExpressionLt(SparqlTermExpression(TermVar(Var("emp3Name"))),SparqlTermExpression(TermVar(Var("emp4Name"))))))))
     assert(tps === a.parseAll(a.select, e).get)
   }
 
-  test("decompose a predicate uri in stem, rel and attr") {
-    val uri = "http://hr.example/our/favorite/DB/Employee#lastName"
-    val puri:PUri = Sparql.parsePredicateURI(uri)
-    assert(puri === PUri(Stem("http://hr.example/our/favorite/DB"),
-			 Rel("Employee"),
-			 Attr("lastName")))
-  }
-
-  test("decompose a object uri in stem, rel and attr") {
-    val uri = "http://hr.example/our/favorite/DB/Employee/id.18#record"
-    val objuri:ObjUri = Sparql.parseObjectURI(uri)
-    assert(objuri === ObjUri(Stem("http://hr.example/our/favorite/DB"),
-			 Rel("Employee"),
-			 Attr("id"),
-			 CellValue("18")))
-  }
-
   test("CONSTRUCT") {
     val a = Sparql()
     val e = """
@@ -451,13 +434,13 @@
 	  List(
 	    TriplePattern(
 	      SVar(Var("emp")),
-		PUri(Stem("http://foo.example/"),Rel("person"),Attr("lname")),
+	      PUri(Uri("http://foo.example/person#lname")),
 	      OVar(Var("empName"))))),
 	TriplesBlock(
 	  List(
 	    TriplePattern(
 	      SVar(Var("emp")),
-		PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("lastName")),
+	      PUri(Uri("http://hr.example/DB/Employee#lastName")),
 	      OVar(Var("empName"))))))
     assert(tps === a.parseAll(a.construct, e).get)
   }