--- a/directmapping/src/main/scala/DirectMapping.scala Fri Jan 07 12:50:06 2011 -0500
+++ b/directmapping/src/main/scala/DirectMapping.scala Fri Jan 07 19:20:00 2011 -0500
@@ -1,9 +1,48 @@
package org.w3.sw.directmapping
-object DirectMapping {
+import org.w3.sw._
- import org.w3.sw.rdb.RDB._
- import org.w3.sw.rdf._
+import org.w3.sw.rdb.RDB._
+
+trait DirectMapping[IRI,
+ Graph <: Traversable[Triple],
+ Triple,
+ BNode,
+ Node,
+ NodeIRI <: Node,
+ NodeBNode <: Node,
+ Subject,
+ SubjectNode <: Subject,
+ Predicate,
+ PredicateIRI <: Predicate,
+ Object,
+ ObjectNode <: Object,
+ ObjectLiteral <: Object,
+ Literal,
+ PlainLiteral <: Literal,
+ TypedLiteral <: Literal,
+ LangTag] {
+
+ val RDFModule:RDFModule[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag]
+
+ import RDFModule._
/** A KeyMap associates the candidate key and key values with the
* node for any tuple in a unique relation. */
@@ -101,10 +140,10 @@
if (r.pk.isDefined) {
/** Table has a primkary key. */
val vs = t.lexvaluesNoNulls(r.pk.get.attrs)
- nodemap(r.name, r.pk.get.attrs, vs)
+ NodeIRI(nodemap(r.name, r.pk.get.attrs, vs))
} else
/** Table has no primkary key (but has some candidate keys). */
- freshbnode()
+ NodeBNode(freshbnode())
(r.candidates.map(k => {
val values:List[CellValue] = k.attrs.map(a => t(a))
(k, values)
@@ -115,7 +154,7 @@
def directDB (db:Database) : Graph = {
val idxables = db.keySet.toSet filter { rn => !db(rn).candidates.isEmpty }
val nodeMap:NodeMap = idxables map {rn => rn -> relation2KeyMap(db(rn))}
- db.keySet.toSet.flatMap((rn:RelName) => directR(db(rn), nodeMap, db))
+ Graph(db.keySet flatMap { (rn:RelName) => directR(db(rn), nodeMap, db) })
}
def directR (r:Relation, nodes:NodeMap, db:Database) : Graph =
@@ -123,7 +162,7 @@
* We know this because relations with candidate keys are mapped to unique
* subjects, and potentially redundant rows get unique blank node subjects.
*/
- r.body.flatMap(t => directT(t, r, nodes, db)).toSet
+ Graph(r.body flatMap { t => directT(t, r, nodes, db) })
def directT (t:Tuple, r:Relation, nodes:NodeMap, db:Database) : Set[Triple] = {
val s:Node =
@@ -134,7 +173,7 @@
nodes.ultimateReferent(r.name, k, vs, db)
} else
/** Table has no candidate keys. */
- freshbnode()
+ NodeBNode(freshbnode())
directS(s, t, r, nodes, db)
}
@@ -154,7 +193,9 @@
val p = predicatemap (rn, List(a))
val l = t.lexvalue(a).get
val o = literalmap(l, h.sqlDatatype(a))
- Triple(s, p, o)
+ Triple(SubjectNode(s),
+ PredicateIRI(p),
+ ObjectLiteral(o))
}
def directN (s:Node, as:List[AttrName], r:Relation, t:Tuple, nodes:NodeMap) : Triple = {
val p = predicatemap (r.name, as)
@@ -166,8 +207,8 @@
error("Relation " + target.rel + " has no attributes (" + target.key + ") to match " + r.name + t)
if (!nodes(target.rel)(target.key).contains(ls))
error("Relation " + target.rel + "(" + target.key + ") has no values " + ls + " to match " + r.name + t)
- val o:Object = nodes(target.rel)(target.key)(ls)
- Triple(s, p, o)
+ val o:Object = ObjectNode(nodes(target.rel)(target.key)(ls))
+ Triple(SubjectNode(s), PredicateIRI(p), o)
}
// These implicits make nodemap and predicatemap functions prettier.
--- a/directmapping/src/test/scala/DirectMappingTest.scala Fri Jan 07 12:50:06 2011 -0500
+++ b/directmapping/src/test/scala/DirectMappingTest.scala Fri Jan 07 19:20:00 2011 -0500
@@ -1,17 +1,76 @@
package org.w3.sw.directmapping
-import org.w3.sw.rdf._
+import org.w3.sw._
import org.w3.sw.rdb.RDB._
import org.w3.sw.sql
-import org.w3.sw.turtle
-import org.w3.sw.directmapping.DirectMapping._
+import org.w3.sw.turtle.Turtle
+//import org.w3.sw.directmapping.DirectMapping
import java.io.File
import org.scalatest.FunSuite
-class FundamentalTest extends FunSuite {
+class FundamentalTestWithRDF extends FundamentalTest(RDFConcreteModuleWithImplicits)
- test("NodeMap") {
+abstract class FundamentalTest[IRI,
+ Graph <: Traversable[Triple],
+ Triple,
+ BNode,
+ Node,
+ NodeIRI <: Node,
+ NodeBNode <: Node,
+ Subject,
+ SubjectNode <: Subject,
+ Predicate,
+ PredicateIRI <: Predicate,
+ Object,
+ ObjectNode <: Object,
+ ObjectLiteral <: Object,
+ Literal,
+ PlainLiteral <: Literal,
+ TypedLiteral <: Literal,
+ LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag])
+extends FunSuite { self =>
+
+ import RDFModule._
+
+ val DirectMapping = new DirectMapping[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag] { val RDFModule = self.RDFModule }
+ import DirectMapping._
+
+ test("NodeMap") {
val ck1:CandidateKey = CandidateKey("name", "ssn")
val ck2:CandidateKey = CandidateKey("ID")
@@ -19,8 +78,8 @@
val v21:List[CellValue] = List(LexicalValue("alice"), LexicalValue("8"))
val v12:List[CellValue] = List(LexicalValue("18"))
val v22:List[CellValue] = List(LexicalValue("23"))
- val s1:Node = BNode("1")
- val s2:Node = BNode("2")
+ val s1:Node = NodeBNode(BNode("1"))
+ val s2:Node = NodeBNode(BNode("2"))
val data:Set[(List[(CandidateKey, List[CellValue])], Node)] =
Set((List((ck1, v11),(ck2, v21)), s1),
(List((ck1, v12),(ck2, v22)), s2))
@@ -37,10 +96,94 @@
}
-class Test extends FunSuite {
+
+
+
+
+
+class DirectMappingTestWithRDF extends DirectMappingTest(RDFConcreteModuleWithImplicits)
+
+
+
+abstract class DirectMappingTest[IRI,
+ Graph <: Traversable[Triple],
+ Triple,
+ BNode,
+ Node,
+ NodeIRI <: Node,
+ NodeBNode <: Node,
+ Subject,
+ SubjectNode <: Subject,
+ Predicate,
+ PredicateIRI <: Predicate,
+ Object,
+ ObjectNode <: Object,
+ ObjectLiteral <: Object,
+ Literal,
+ PlainLiteral <: Literal,
+ TypedLiteral <: Literal,
+ LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag])
+extends FunSuite { self =>
+
+ import RDFModule._
+
+ val DirectMapping = new DirectMapping[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag] { val RDFModule = self.RDFModule }
+ import DirectMapping._
val SqlParser = sql.SqlParser()
- val TurtleParser = turtle.Turtle()
+
+ val TurtleParser = new Turtle[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag] { val RDFModule = self.RDFModule }
def testDirectMapping(testName:String, db:Database, expectedGraph:Graph):Unit =
test(testName) {
@@ -50,7 +193,7 @@
def testDirectMapping(testName:String, dbFile:File, expectedGraphFile:File):Unit = {
val db = SqlParser.toDB(dbFile)
- val expectedGraph = TurtleParser.toGraph(expectedGraphFile)
+ val expectedGraph:Graph = TurtleParser.toGraph(expectedGraphFile)
testDirectMapping(testName, db, expectedGraph)
}
--- a/rdf/src/main/scala/RDF.scala Fri Jan 07 12:50:06 2011 -0500
+++ b/rdf/src/main/scala/RDF.scala Fri Jan 07 19:20:00 2011 -0500
@@ -1,66 +1,97 @@
package org.w3.sw
-trait RDFModel {
+import org.w3.isomorphic._
- import org.w3.isomorphic._
+trait RDFModule[IRI,
+ Graph <: Traversable[Triple],
+ Triple,
+ BNode,
+ Node,
+ NodeIRI <: Node,
+ NodeBNode <: Node,
+ Subject,
+ SubjectNode <: Subject,
+ Predicate,
+ PredicateIRI <: Predicate,
+ Object,
+ ObjectNode <: Object,
+ ObjectLiteral <: Object,
+ Literal,
+ PlainLiteral <: Literal,
+ TypedLiteral <: Literal,
+ LangTag] {
- type IRI
val IRI : Isomorphic1[String, IRI]
- // it should actually be an Ordered Set
- type Graph <: Traversable[Triple]
val Graph : {
def empty:Graph
def apply(elems:Triple*):Graph
def apply(it:Iterable[Triple]):Graph
}
- type Triple
val Triple : Isomorphic3[Subject, Predicate, Object, Triple]
- type BNode
val BNode : Isomorphic1[String, BNode]
- // sealed type Node: NodeIRI NodeBNode
- type Node
- type NodeIRI <: Node
- type NodeBNode <: Node
val NodeIRI : Isomorphic1[IRI, NodeIRI]
val NodeBNode : Isomorphic1[BNode, NodeBNode]
- type Subject
- type SubjectNode <: Subject
val SubjectNode : Isomorphic1[Node, SubjectNode]
- type Predicate
- type PredicateIRI <: Predicate
val PredicateIRI : Isomorphic1[IRI, PredicateIRI]
- type Object
- type ObjectNode <: Object
- type ObjectLiteral <: Object
val ObjectNode : Isomorphic1[Node, ObjectNode]
val ObjectLiteral : Isomorphic1[Literal, ObjectLiteral]
- // val lexicalForm:String
- type Literal
- type PlainLiteral <: Literal
- type TypedLiteral <: Literal
val PlainLiteral : Isomorphic2[String, Option[LangTag], PlainLiteral]
val TypedLiteral : Isomorphic2[String, IRI, TypedLiteral]
- type LangTag
val LangTag : Isomorphic1[String, LangTag]
- val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
- val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
- val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
- val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
+ lazy val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
+ lazy val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
+ lazy val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
+ lazy val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
}
-trait RDFImplicits extends RDFModel {
+trait RDFModuleWithImplicits[IRI,
+ Graph <: Traversable[Triple],
+ Triple,
+ BNode,
+ Node,
+ NodeIRI <: Node,
+ NodeBNode <: Node,
+ Subject,
+ SubjectNode <: Subject,
+ Predicate,
+ PredicateIRI <: Predicate,
+ Object,
+ ObjectNode <: Object,
+ ObjectLiteral <: Object,
+ Literal,
+ PlainLiteral <: Literal,
+ TypedLiteral <: Literal,
+ LangTag]
+extends RDFModule[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag] {
implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
@@ -74,9 +105,7 @@
implicit def plain2object(b:PlainLiteral):Object = ObjectLiteral(b)
}
-trait RDF extends RDFModel {
-
- import org.w3.isomorphic._
+object RDFConcreteModel {
case class IRI(iri:String) { override def toString = '"' + iri + '"' }
object IRI extends Isomorphic1[String, IRI]
@@ -129,72 +158,56 @@
}
-object RDF extends RDF
-
-// object rdf {
-
-// case class Graph(triples:Set[Triple])
-// object Graph {
-// def empty:Graph = Graph(Set[Triple]())
-// def apply(elems:Triple*):Graph = Graph(Set[Triple](elems:_*))
-// def apply(it:Iterable[Triple]):Graph = Graph(it.toSet)
-// }
-
-// case class Triple (s:Subject, p:Predicate, o:Object)
-
-// sealed abstract class Node // factor out IRIs and BNodes
-// case class NodeIRI(i:IRI) extends Node
-// implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
-// case class NodeBNode(b:BNode) extends Node
-// implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
-
-// sealed abstract class Subject
-// case class SubjectNode(n:Node) extends Subject
-// implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
-// implicit def iri2subjectnode(i:IRI):Subject = SubjectNode(i)
-// implicit def bnode2subjectnode(b:BNode):Subject = SubjectNode(b)
-
-// sealed abstract class Predicate
-// case class PredicateIRI(i:IRI) extends Predicate
-// implicit def iri2predicateiri(i:IRI):Predicate = PredicateIRI(i)
+import RDFConcreteModel._
+trait RDFConcreteModule extends RDFModule[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag] {
+ val IRI = RDFConcreteModel.IRI
+ val Graph = RDFConcreteModel.Graph
+ val Triple = RDFConcreteModel.Triple
+ val BNode = RDFConcreteModel.BNode
+ val NodeIRI = RDFConcreteModel.NodeIRI
+ val NodeBNode = RDFConcreteModel.NodeBNode
+ val SubjectNode = RDFConcreteModel.SubjectNode
+ val PredicateIRI = RDFConcreteModel.PredicateIRI
+ val ObjectNode = RDFConcreteModel.ObjectNode
+ val ObjectLiteral = RDFConcreteModel.ObjectLiteral
+ val PlainLiteral = RDFConcreteModel.PlainLiteral
+ val TypedLiteral = RDFConcreteModel.TypedLiteral
+ val LangTag = RDFConcreteModel.LangTag
+}
-// sealed abstract class Object
-// case class ObjectNode(n:Node) extends Object
-// implicit def node2objectnode(n:Node):Object = ObjectNode(n)
-// implicit def iri2objectnode(i:IRI):Object = ObjectNode(i)
-// implicit def bnode2objectnode(b:BNode):Object = ObjectNode(b)
-// case class ObjectLiteral (n:Literal) extends Object
-
-// case class IRI(iri:String) {
-// override def toString = '"' + iri + '"'
-// }
-// case class BNode(label:String)
-
-// sealed abstract class Literal(val lexicalForm:String)
-
-// case class PlainLiteral(override val lexicalForm:String, langtag:Option[LangTag]) extends Literal(lexicalForm) {
-// override def toString = "\"" + lexicalForm + "\"" + { if (langtag.isDefined) langtag.get }
-// }
-// implicit def typed2object(i:TypedLiteral):Object = ObjectLiteral(i)
-
-// case class TypedLiteral(override val lexicalForm:String, datatype:IRI) extends Literal(lexicalForm) {
-// override def toString = "\"" + lexicalForm + "\"^^" + datatype
-// }
-// implicit def plain2object(b:PlainLiteral):Object = ObjectLiteral(b)
-
-// case class LangTag(s:String)
-
-// val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
-// val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
-// val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
-// val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
-
-// }
-
-// // object Literal {
-// // val StringDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#string"))
-// // val IntegerDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#integer"))
-// // val DateDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#date"))
-// // // val DateTimeDatatype = Datatype(IRI("http://www.w3.org/2001/XMLSchema#dateTime"))
-// // }
-
+object RDFConcreteModule extends RDFConcreteModule
+object RDFConcreteModuleWithImplicits extends RDFConcreteModule with RDFModuleWithImplicits[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag]
--- a/turtle/src/main/scala/turtle.scala Fri Jan 07 12:50:06 2011 -0500
+++ b/turtle/src/main/scala/turtle.scala Fri Jan 07 19:20:00 2011 -0500
@@ -1,6 +1,6 @@
package org.w3.sw.turtle
-import org.w3.sw.RDFModel
+import org.w3.sw._
//import org.w3.sw.{RDF => RDFModel}
import scala.util.parsing.combinator._
import java.net.URI
@@ -15,78 +15,115 @@
import MyParsers._
-case class Turtle(RDFModel:RDFModel) extends JavaTokenParsers {
-
- import RDFModel._
-
- def toGraph(t:String):Graph = parseAll(turtle, t).get
-
- def toGraph(file:java.io.File):Graph = {
- val t = scala.io.Source.fromFile(file).getLines.reduceLeft(_+_)
- parseAll(turtle, t).get
- }
-
- def turtle:Parser[Graph] =
- opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(Graph.empty) }
-
- def prefixdecl:Parser[Unit] =
- "@prefix" ~ name ~ ":" ~ qnameORuri ~ "." ^^ { case "@prefix"~pre~":"~u~"." => prefixes += (pre -> { val IRI(iri) = u ; iri }) }
-
- def triplesblock:Parser[Graph] =
- rep(triplepatternOrPrefixOrBase) ^^ { case pats => Graph(pats.flatten) }
-
- def triplepatternOrPrefixOrBase:Parser[Option[Triple]] = (
- triplepattern ^^ { case p => Some(p) }
- | prefixdecl ^^ { case _ => None }
- )
-
- def triplepattern:Parser[Triple] =
- subject ~ predicate ~ objectt ~ "." ^^ { case s~p~o~"." => Triple(s, p, o) }
-
- def subject:Parser[Subject] = (
- qnameORuri ^^ { case x => SubjectNode(NodeIRI(x)) }
- | bnode ^^ { case x => SubjectNode(NodeBNode(x)) }
- )
+trait Turtle[IRI,
+ Graph <: Traversable[Triple],
+ Triple,
+ BNode,
+ Node,
+ NodeIRI <: Node,
+ NodeBNode <: Node,
+ Subject,
+ SubjectNode <: Subject,
+ Predicate,
+ PredicateIRI <: Predicate,
+ Object,
+ ObjectNode <: Object,
+ ObjectLiteral <: Object,
+ Literal,
+ PlainLiteral <: Literal,
+ TypedLiteral <: Literal,
+ LangTag]
+ extends JavaTokenParsers {
+
+ val RDFModule:RDFModule[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag]
- def predicate:Parser[Predicate] = (
- qnameORuri ^^ { case x => PredicateIRI(x) }
- | "a" ^^ { x => PredicateIRI(IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
- )
-
- def objectt:Parser[Object] = (
- qnameORuri ^^ { case x => ObjectNode(NodeIRI(x)) }
- | bnode ^^ { case x => ObjectNode(NodeBNode(x)) }
- | literal ^^ { case x => ObjectLiteral(x) }
- )
+ import RDFModule._
- def qnameORuri:Parser[IRI] = (
- "<"~uri~">" ^^ { case "<"~x~">" => IRI(x) }
- | name~":"~name ^^ {
- case prefix~":"~localName => try {
- IRI(prefixes(prefix) + localName)
- } catch {
- case e:java.util.NoSuchElementException =>
- throw new Exception("unknown prefix " + prefix)
- }
- }
- )
+ def toGraph(t:String):Graph = parseAll(turtle, t).get
- def bnode:Parser[BNode] =
- "_:"~name ^^ { case "_:"~name => BNode(name) }
+ def toGraph(file:java.io.File):Graph = {
+ val t = scala.io.Source.fromFile(file).getLines.reduceLeft(_+_)
+ parseAll(turtle, t).get
+ }
- def literal:Parser[Literal] = (
- stringLiteral~"^^"~qnameORuri ^^
- {
- case lit~"^^"~dt => TypedLiteral(lit.substring(1,lit.size - 1), dt match {
- case IRI("http://www.w3.org/2001/XMLSchema#string") => StringDatatype
- case IRI("http://www.w3.org/2001/XMLSchema#integer") => IntegerDatatype
- case IRI("http://www.w3.org/2001/XMLSchema#date") => DateDatatype
- case IRI("http://www.w3.org/2001/XMLSchema#dateTime") => DateTimeDatatype
- case x => error("only programed to deal with string and integer, not " + x)
- })
- }
- | integer ^^ { l => TypedLiteral(l, IntegerDatatype) }
- )
+ def turtle:Parser[Graph] =
+ opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(RDFModule.Graph.empty) }
+
+ def prefixdecl:Parser[Unit] =
+ "@prefix" ~ name ~ ":" ~ qnameORuri ~ "." ^^ { case "@prefix"~pre~":"~u~"." => prefixes += (pre -> { val IRI(iri) = u ; iri }) }
+
+ def triplesblock:Parser[Graph] =
+ rep(triplepatternOrPrefixOrBase) ^^ { case pats => Graph(pats.flatten) }
+
+ def triplepatternOrPrefixOrBase:Parser[Option[Triple]] = (
+ triplepattern ^^ { case p => Some(p) }
+ | prefixdecl ^^ { case _ => None }
+ )
+
+ def triplepattern:Parser[Triple] =
+ subject ~ predicate ~ objectt ~ "." ^^ { case s~p~o~"." => Triple(s, p, o) }
+
+ def subject:Parser[Subject] = (
+ qnameORuri ^^ { case x => SubjectNode(NodeIRI(x)) }
+ | bnode ^^ { case x => SubjectNode(NodeBNode(x)) }
+ )
+
+ def predicate:Parser[Predicate] = (
+ qnameORuri ^^ { case x => PredicateIRI(x) }
+ | "a" ^^ { x => PredicateIRI(IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
+ )
+
+ def objectt:Parser[Object] = (
+ qnameORuri ^^ { case x => ObjectNode(NodeIRI(x)) }
+ | bnode ^^ { case x => ObjectNode(NodeBNode(x)) }
+ | literal ^^ { case x => ObjectLiteral(x) }
+ )
+
+ def qnameORuri:Parser[IRI] = (
+ "<"~uri~">" ^^ { case "<"~x~">" => IRI(x) }
+ | name~":"~name ^^ {
+ case prefix~":"~localName => try {
+ IRI(prefixes(prefix) + localName)
+ } catch {
+ case e:java.util.NoSuchElementException =>
+ throw new Exception("unknown prefix " + prefix)
+ }
+ }
+ )
+
+ def bnode:Parser[BNode] =
+ "_:"~name ^^ { case "_:"~name => BNode(name) }
+
+ def literal:Parser[Literal] = (
+ stringLiteral~"^^"~qnameORuri ^^
+ {
+ case lit~"^^"~dt => TypedLiteral(lit.substring(1,lit.size - 1), dt match {
+ case IRI("http://www.w3.org/2001/XMLSchema#string") => StringDatatype
+ case IRI("http://www.w3.org/2001/XMLSchema#integer") => IntegerDatatype
+ case IRI("http://www.w3.org/2001/XMLSchema#date") => DateDatatype
+ case IRI("http://www.w3.org/2001/XMLSchema#dateTime") => DateTimeDatatype
+ case x => error("only programed to deal with string and integer, not " + x)
+ })
+ }
+ | integer ^^ { l => TypedLiteral(l, IntegerDatatype) }
+ )
}
--- a/turtle/src/test/scala/turtleTest.scala Fri Jan 07 12:50:06 2011 -0500
+++ b/turtle/src/test/scala/turtleTest.scala Fri Jan 07 19:20:00 2011 -0500
@@ -1,15 +1,67 @@
package org.w3.sw.turtle
-import org.w3.sw.{RDF, RDFModel, RDFImplicits}
+import org.w3.sw._
import org.scalatest.FunSuite
-class TurtleTestWithRDF extends TurtleTest(new RDF with RDFImplicits { })
+class TurtleTestWithRDF extends TurtleTest(RDFConcreteModuleWithImplicits)
-abstract class TurtleTest(RDFModel:RDFModel with RDFImplicits) extends FunSuite {
+abstract class TurtleTest[IRI,
+ Graph <: Traversable[Triple],
+ Triple,
+ BNode,
+ Node,
+ NodeIRI <: Node,
+ NodeBNode <: Node,
+ Subject,
+ SubjectNode <: Subject,
+ Predicate,
+ PredicateIRI <: Predicate,
+ Object,
+ ObjectNode <: Object,
+ ObjectLiteral <: Object,
+ Literal,
+ PlainLiteral <: Literal,
+ TypedLiteral <: Literal,
+ LangTag](val RDFModule:RDFModuleWithImplicits[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag])
+extends FunSuite { self =>
- import RDFModel._
+ import RDFModule._
- val turtleParser = Turtle(RDFModel)
+ val turtleParser = new Turtle[IRI,
+ Graph,
+ Triple,
+ BNode,
+ Node,
+ NodeIRI,
+ NodeBNode,
+ Subject,
+ SubjectNode,
+ Predicate,
+ PredicateIRI,
+ Object,
+ ObjectNode,
+ ObjectLiteral,
+ Literal,
+ PlainLiteral,
+ TypedLiteral,
+ LangTag] { val RDFModule = self.RDFModule }
test("directgraph_emp_adder") {
val directgraph_emp_adder:Graph =