!!! this compiles only with the latest Scala compiler (nightly build) webacl
authorAlexandre Bertails <bertails@gmail.com>
Sun, 20 Nov 2011 19:25:34 -0500
branchwebacl
changeset 130 aa09c5e9d204
parent 127 550497ea4999
child 131 8c38062c7809
child 132 15f76c5508ac
!!! this compiles only with the latest Scala compiler (nightly build)
+ imported some modules from FeDeRate, using the new dependent method type feature that was missing to make this approach useful
project/build.scala
src/main/scala/EchoPlan.scala
src/main/scala/rdf/Isomorphic.scala
src/main/scala/rdf/JenaModel.scala
src/main/scala/rdf/Model.scala
src/main/scala/rdf/main.scala
src/main/scala/rdf/rdfxml.scala
src/main/scala/rdf/turtle.scala
src/main/scala/webacl/parser.scala
src/main/scala/webacl/webacl.scala
--- a/project/build.scala	Fri Nov 18 16:40:25 2011 -0500
+++ b/project/build.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -47,6 +47,7 @@
     organization := buildOrganization,
     version      := buildVersion,
     scalaVersion := buildScalaVersion,
+    scalaHome    := Some(file("/home/betehess/tools/scala")),
     parallelExecution in Test := false,
     scalacOptions ++= Seq("-deprecation", "-unchecked")
   )
--- a/src/main/scala/EchoPlan.scala	Fri Nov 18 16:40:25 2011 -0500
+++ b/src/main/scala/EchoPlan.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -41,7 +41,7 @@
       Ok ~> PlainTextContent ~> {
         val headers = req.underlying.getHeaderNames()
         val result = for (name <- headers ;
-             val nameStr = name.asInstanceOf[String]
+              nameStr = name.asInstanceOf[String]
         ) yield {
           nameStr + ": " + req.underlying.getHeader(nameStr)+"\r\n"
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/rdf/Isomorphic.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -0,0 +1,31 @@
+package org.w3.isomorphic
+
+trait PatternMatching0[R] {
+  def unapply(r:R):Boolean
+}
+
+trait Isomorphic0[R] extends Function0[R] with PatternMatching0[R]
+
+trait PatternMatching1[T,R] {
+  def unapply(r:R):Option[T]
+}
+
+trait Isomorphic1[T,R] extends Function1[T,R] with PatternMatching1[T,R]
+
+trait PatternMatching2[T1,T2,R] {
+  def unapply(r:R):Option[(T1, T2)]
+}
+
+/**
+ * basically, you have to implement both following functions
+ *   def apply(t1:T1, t2:T2):R
+ *   def unapply(r:R):Option[(T1, T2)]
+ */
+trait Isomorphic2[T1,T2,R] extends Function2[T1, T2, R] with PatternMatching2[T1,T2,R]
+
+trait PatternMatching3[T1,T2,T3,R] {
+  def unapply(r:R):Option[(T1, T2, T3)]
+}
+
+trait Isomorphic3[T1,T2,T3,R] extends Function3[T1, T2, T3, R] with PatternMatching3[T1,T2,T3,R]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/rdf/JenaModel.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -0,0 +1,143 @@
+package org.w3.rdf.jena
+
+import org.w3.rdf._
+import com.hp.hpl.jena.graph.{Graph => JenaGraph, Triple => JenaTriple, Node => JenaNode, _}
+import com.hp.hpl.jena.rdf.model.{AnonId}
+import com.hp.hpl.jena.datatypes.{RDFDatatype, TypeMapper}
+
+import org.w3.isomorphic._
+
+object Util {
+  def tryopt[T](b: => T):Option[T] =
+    try {
+      Some(b)
+    } catch {
+      case e => None
+    }
+}
+
+import Util._
+
+trait JenaModel extends Model {
+
+  case class IRI(iri: String) { override def toString = '"' + iri + '"' }
+  object IRI extends Isomorphic1[String, IRI]
+
+  class Graph(val jenaGraph: JenaGraph) extends GraphLike {
+    def iterator: Iterator[Triple] = new Iterator[Triple] {
+      val iterator = jenaGraph.find(JenaNode.ANY, JenaNode.ANY, JenaNode.ANY)
+      def hasNext = iterator.hasNext
+      def next = iterator.next
+    }
+    def ++(other: Graph): Graph = {
+      val g = Factory.createDefaultGraph
+      iterator foreach { t => g add t }
+      other.iterator foreach { t => g add t }
+      new Graph(g)
+    }
+
+    override def equals(o:Any):Boolean = ( o.isInstanceOf[Graph] && jenaGraph.isIsomorphicWith(o.asInstanceOf[Graph].jenaGraph) )
+
+  }
+
+  object Graph {
+    def empty: Graph = new Graph(Factory.createDefaultGraph)
+    def apply(elems: Triple*): Graph = apply(elems.toIterable)
+    def apply(it: Iterable[Triple]): Graph = {
+      val jenaGraph = Factory.createDefaultGraph
+      it foreach { t => jenaGraph add t }
+      new Graph(jenaGraph)
+    }
+  }
+
+  type Triple = JenaTriple
+  object Triple extends Isomorphic3[Subject, Predicate, Object, Triple] {
+    def apply(s: Subject, p: Predicate, o: Object): Triple = JenaTriple.create(s, p, o)
+    def unapply(t: Triple): Option[(Subject, Predicate, Object)] =
+      Some((t.getSubject, t.getPredicate, t.getObject))
+  }
+
+  type BNode = Node_Blank
+  object BNode extends Isomorphic1[String, BNode] {
+    def apply(label: String): BNode = {
+      val id = AnonId.create(label)
+      JenaNode.createAnon(id).asInstanceOf[Node_Blank]
+    }
+    def unapply(bn: BNode): Option[String] = tryopt(bn.getBlankNodeId.getLabelString)
+  }
+
+  type Node = JenaNode
+  type NodeIRI = Node_URI
+  object NodeIRI extends Isomorphic1[IRI, NodeIRI] {
+    def apply(iri: IRI): NodeIRI = {
+      val IRI(s) = iri
+      JenaNode.createURI(s).asInstanceOf[Node_URI]
+    }
+    def unapply(node: NodeIRI): Option[IRI] = tryopt(IRI(node.getURI))
+  }
+  type NodeBNode = Node_Blank
+  object NodeBNode extends Isomorphic1[BNode, NodeBNode] {
+    def apply(node: BNode): NodeBNode = node
+    def unapply(node: NodeBNode): Option[BNode] =
+      if (node.isBlank) Some(node) else None
+  }
+
+  type Subject = JenaNode
+  type SubjectNode = JenaNode
+  object SubjectNode extends Isomorphic1[Node, SubjectNode] {
+    def apply(node: Node): SubjectNode = node
+    def unapply(node: SubjectNode): Option[Node] = Some(node)
+  }
+
+  type Predicate = JenaNode
+  type PredicateIRI = JenaNode
+  object PredicateIRI extends Isomorphic1[IRI, PredicateIRI] {
+    def apply(iri: IRI): PredicateIRI = { val IRI(s) = iri ; JenaNode.createURI(s) }
+    def unapply(node: PredicateIRI): Option[IRI] = tryopt(IRI(node.getURI))
+  }
+
+  type Object = JenaNode
+  type ObjectNode = JenaNode
+  object ObjectNode extends Isomorphic1[Node, ObjectNode] {
+    def apply(node: Node): ObjectNode = node
+    def unapply(node: ObjectNode): Option[Node] =
+      if (node.isURI || node.isBlank) Some(node) else None
+  }
+  type ObjectLiteral = JenaNode
+  object ObjectLiteral extends Isomorphic1[Literal, ObjectLiteral] {
+    def apply(literal: Literal): ObjectLiteral = literal
+    def unapply(node: ObjectLiteral): Option[Literal] =
+      if (node.isLiteral) Some(node.asInstanceOf[Node_Literal]) else None
+  }
+
+  type Literal = Node_Literal
+  type PlainLiteral = Node_Literal
+  object PlainLiteral extends Isomorphic2[String, Option[LangTag], PlainLiteral] {
+    def apply(lit: String, langtagOption: Option[LangTag]) =
+      langtagOption match {
+        case Some(LangTag(langtag)) => JenaNode.createLiteral(lit, langtag, false).asInstanceOf[Node_Literal]
+        case None => JenaNode.createLiteral(lit).asInstanceOf[Node_Literal]
+      }
+    def unapply(literal: PlainLiteral): Option[(String, Option[LangTag])] =
+      tryopt { ( literal.getLiteralValue.toString, Option(LangTag(literal.getLiteralLanguage)) ) }
+  }
+  
+  type TypedLiteral = Node_Literal
+  lazy val mapper = TypeMapper.getInstance
+  object TypedLiteral extends Isomorphic2[String, IRI, TypedLiteral] {
+    def apply(lit: String, iri: IRI): TypedLiteral = {
+      val IRI(typ) = iri
+      JenaNode.createLiteral(lit, null, mapper.getTypeByName(typ)).asInstanceOf[Node_Literal]
+    }
+    def unapply(literal: TypedLiteral): Option[(String, IRI)] =
+      tryopt((literal.getLiteralValue.toString, IRI(literal.getLiteralDatatype.getURI)))
+  }
+
+  case class LangTag(s: String)
+  object LangTag extends Isomorphic1[String, LangTag]
+
+}
+
+object JenaModel extends JenaModel
+
+object JenaModelWithImplicits extends JenaModel with Implicits
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/rdf/Model.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -0,0 +1,137 @@
+package org.w3.rdf
+
+import org.w3.isomorphic._
+
+trait Model {
+
+  type IRI
+  trait GraphLike extends Iterable[Triple] { self =>
+    def ++(other: Graph): Graph
+  }
+  type Graph <: GraphLike
+  type Triple
+  type BNode
+  type Node
+  type NodeIRI <: Node
+  type NodeBNode <: Node
+  type Subject
+  type SubjectNode <: Subject
+  type Predicate
+  type PredicateIRI <: Predicate
+  type Object
+  type ObjectNode <: Object
+  type ObjectLiteral <: Object
+  type Literal
+  type PlainLiteral <: Literal
+  type TypedLiteral <: Literal
+  type LangTag
+
+  val IRI: Isomorphic1[String, IRI]
+
+  val Graph: {
+    def empty: Graph
+    def apply(elems: Triple*): Graph
+    def apply(it: Iterable[Triple]): Graph
+  }
+
+  val Triple: Isomorphic3[Subject, Predicate, Object, Triple]
+
+  val BNode: Isomorphic1[String, BNode]
+
+  val NodeIRI: Isomorphic1[IRI, NodeIRI]
+  val NodeBNode: Isomorphic1[BNode, NodeBNode]
+
+  val SubjectNode: Isomorphic1[Node, SubjectNode]
+
+  val PredicateIRI: Isomorphic1[IRI, PredicateIRI]
+
+  val ObjectNode: Isomorphic1[Node, ObjectNode]
+  val ObjectLiteral: Isomorphic1[Literal, ObjectLiteral]
+
+  val PlainLiteral: Isomorphic2[String, Option[LangTag], PlainLiteral]
+  val TypedLiteral: Isomorphic2[String, IRI, TypedLiteral]
+
+  val LangTag: Isomorphic1[String, LangTag]
+
+  lazy val StringDatatype = IRI("http://www.w3.org/2001/XMLSchema#string")
+  lazy val IntegerDatatype = IRI("http://www.w3.org/2001/XMLSchema#integer")
+  lazy val FloatDatatype = IRI("http://www.w3.org/2001/XMLSchema#float")
+  lazy val DateDatatype = IRI("http://www.w3.org/2001/XMLSchema#date")
+  lazy val DateTimeDatatype = IRI("http://www.w3.org/2001/XMLSchema#dateTime")
+
+}
+
+
+trait Implicits extends Model {
+  implicit def iri2nodeiri(i:IRI):Node = NodeIRI(i)
+  implicit def bnode2nodebnode(b:BNode):Node = NodeBNode(b)
+  implicit def node2subjectnode(n:Node):Subject = SubjectNode(n)
+  implicit def iri2subjectnode(i:IRI):Subject = SubjectNode(i)
+  implicit def bnode2subjectnode(b:BNode):Subject = SubjectNode(b)
+  implicit def iri2predicateiri(i:IRI):Predicate = PredicateIRI(i)
+  implicit def node2objectnode(n:Node):Object = ObjectNode(n)
+  implicit def iri2objectnode(i:IRI):Object = ObjectNode(i)
+  implicit def bnode2objectnode(b:BNode):Object = ObjectNode(b)
+  implicit def typed2object(i:TypedLiteral):Object = ObjectLiteral(i)
+  implicit def plain2object(b:PlainLiteral):Object = ObjectLiteral(b)
+}
+
+trait ConcreteModel extends Model {
+
+  case class IRI(iri: String) { override def toString = '"' + iri + '"' }
+  object IRI extends Isomorphic1[String, IRI]
+
+  case class Graph(triples:Set[Triple]) extends GraphLike {
+    def iterator = triples.iterator
+    def ++(other:Graph):Graph = Graph(triples ++ other.triples)
+  }
+  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)
+  object Triple extends Isomorphic3[Subject, Predicate, Object, Triple]
+
+  case class BNode(label:String)
+  object BNode extends Isomorphic1[String, BNode]
+
+  sealed trait Node
+  case class NodeIRI(i:IRI) extends Node
+  object NodeIRI extends Isomorphic1[IRI, NodeIRI]
+  case class NodeBNode(b:BNode) extends Node
+  object NodeBNode extends Isomorphic1[BNode, NodeBNode]
+
+  sealed trait Subject
+  case class SubjectNode(n:Node) extends Subject
+  object SubjectNode extends Isomorphic1[Node, SubjectNode]
+
+  sealed trait Predicate
+  case class PredicateIRI(i:IRI) extends Predicate
+  object PredicateIRI extends Isomorphic1[IRI, PredicateIRI]
+
+  sealed trait Object
+  case class ObjectNode(n:Node) extends Object
+  object ObjectNode extends Isomorphic1[Node, ObjectNode]
+  case class ObjectLiteral (n:Literal) extends Object
+  object ObjectLiteral extends Isomorphic1[Literal, ObjectLiteral]
+
+  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 }
+  }
+  object PlainLiteral extends Isomorphic2[String, Option[LangTag], PlainLiteral]
+  case class TypedLiteral(override val lexicalForm:String, datatype:IRI) extends Literal(lexicalForm) {
+    override def toString = "\"" + lexicalForm + "\"^^" + datatype
+  }
+  object TypedLiteral extends Isomorphic2[String, IRI, TypedLiteral]
+
+  case class LangTag(s:String)
+  object LangTag extends Isomorphic1[String, LangTag]
+
+}
+
+object ConcreteModel extends ConcreteModel
+
+object ConcreteModelWithImplicits extends ConcreteModel with Implicits
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/rdf/main.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -0,0 +1,78 @@
+package org.w3.rdf
+
+import java.io.File
+import com.hp.hpl.jena.graph.Graph
+
+
+
+
+trait ResourceManager {
+  type Resource <: BasicResource
+  trait BasicResource {
+    def hash : String
+    def duplicates(r : Resource) : Boolean
+  }
+  def create : Resource
+
+//  // Test methods: exercise is to move them outside ResourceManager
+//  def testHash(r : Resource) = assert(r.hash == "9e47088d")  
+//  def testDuplicates(r : Resource) = assert(r.duplicates(r))
+}
+
+trait FileManager extends ResourceManager {
+  type Resource <: File
+  trait File extends BasicResource {
+    def local : Boolean
+  }
+  override def create : Resource
+}
+
+class NetworkFileManager extends FileManager {
+  type Resource = RemoteFile
+  class RemoteFile extends File {
+    def local = false
+    def hash = "9e47088d"
+    def duplicates(r : Resource) = (local == r.local) && (hash == r.hash)
+  }
+  override def create : Resource = new RemoteFile
+}
+
+
+
+
+object Main {
+  
+  def main(args: Array[String]) = {
+    
+//    val turtle = new org.w3.rdf.turtle.TurtleParser(org.w3.rdf.jena.JenaModel)
+//    
+//    val g = turtle.toGraph(new File("/tmp/card.n3"))
+
+    import org.w3.rdf.jena.JenaModel
+    
+    val rdfxmlParser = org.w3.rdf.rdfxml.RDFXMLParser(JenaModel)
+    
+    val g: JenaModel.Graph = rdfxmlParser.parse(new File("/tmp/card.rdf"))
+
+//    val m:Graph = g.jenaGraph
+    
+    println(g)
+    
+    val nfm = new NetworkFileManager
+    val rf : nfm.Resource = nfm.create
+//    nfm.testHash(rf)
+//    nfm.testDuplicates(rf)
+//
+//    def testHash4(rm : ResourceManager)(r : rm.Resource) = 
+//      assert(r.hash == "9e47088d")
+//
+//    def testDuplicates4(rm : ResourceManager)(r : rm.Resource) = 
+//      assert(r.duplicates(r))
+
+      
+      
+    
+  }
+  
+  
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/rdf/rdfxml.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -0,0 +1,128 @@
+package org.w3.rdf.rdfxml
+
+//import org.w3.rdf.{Model => RDFModel, Implicits => RDFImplicits, _}
+import org.w3.rdf._
+
+import com.hp.hpl.jena.rdf.arp._
+import org.xml.sax._
+import org.xml.sax.helpers._
+import java.io._
+import java.net.{MalformedURLException, URL, URLConnection}
+import java.util.{StringTokenizer, Enumeration, Hashtable}
+import java.net.URI
+
+sealed trait ParseErrorType
+object RDFParseError extends ParseErrorType { override def toString:String = "RDF" }
+object XMLParseError extends ParseErrorType { override def toString:String = "XML" }
+
+sealed trait ParseErrorLevel
+object FatalError extends ParseErrorLevel { override def toString:String = "FatalError" }
+object Error extends ParseErrorLevel { override def toString:String = "Error" }
+object Warning extends ParseErrorLevel { override def toString:String = "Warning" }
+
+case class ParseError(
+  val message:String,
+  val errorType:ParseErrorType,
+  val level:ParseErrorLevel,
+  val column:Int,
+  val line:Int)
+
+object ParseError {
+  def fromSAXParseException(e:SAXParseException, level:ParseErrorLevel):ParseError = {
+    val message = e.getMessage
+    val errorType = if (e.isInstanceOf[ParseException]) RDFParseError else XMLParseError
+    val correctedLevel =
+      if      (message.size > 1 && message(1) == 'W') Warning
+      else if (message.size > 1 && message(1) == 'E') Error
+      else    level
+    new ParseError(message, errorType, correctedLevel, e.getColumnNumber, e.getLineNumber)
+  }
+}
+
+object RDFXMLParser {
+  
+  def apply(rdf: Model) = new Object {
+    private val parser = new RDFXMLParser
+    def parse(file:File): rdf.Graph = parser.toGraph(file)(rdf)._1
+  }
+  
+}
+
+class RDFXMLParser {
+  
+  /**
+   * http://jena.sourceforge.net/javadoc/com/hp/hpl/jena/rdf/arp/AResource.html
+   * note: see setUserData and getUserData for when BNode will be abstract
+   */
+  def toNode(a: AResource)(implicit rdf: Model): rdf.Node =
+    if (a.isAnonymous)
+      rdf.NodeBNode(rdf.BNode(a.getAnonymousID))
+    else
+      rdf.NodeIRI(rdf.IRI(a.getURI))
+  
+  def toPredicate(a: AResource)(implicit rdf: Model): rdf.Predicate =
+    rdf.PredicateIRI(rdf.IRI(a.getURI))
+  
+  def toLiteral(l: ALiteral)(implicit rdf: Model): rdf.Literal = {
+    val datatype:String = l.getDatatypeURI
+    if (datatype == null) {
+      val lang = l.getLang match {
+        case "" => None
+        case l  => Some(rdf.LangTag(l))
+      }
+      rdf.PlainLiteral(l.toString, lang)
+    } else {
+      rdf.TypedLiteral(l.toString, rdf.IRI(datatype))
+    }
+  }
+  
+  def toGraph(file:File)(implicit rdf: Model): (rdf.Graph, List[ParseError]) =
+    toGraph(new FileInputStream(file))(rdf)
+  
+  def toGraph(rdfxml:String)(implicit rdf: Model): (rdf.Graph, List[ParseError]) =
+    toGraph(new StringReader(rdfxml))(rdf)
+  
+  def toGraph(in:InputStream)(implicit rdf: Model): (rdf.Graph, List[ParseError]) =
+    toGraph(new BufferedReader(new InputStreamReader(in)))(rdf)
+  
+  def toGraph(in:Reader)(implicit rdf: Model): (rdf.Graph, List[ParseError]) = {
+    
+    // the accumulator for the triples
+    var triples = Set[rdf.Triple]()
+    
+    // the accumulators for the problems we encounter
+    var parseErrors = List[ParseError]()
+    
+    // this ErrorHandler keeps track of all the problems during the parsing
+    val errorHandler = new ErrorHandler {
+      def fatalError(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, FatalError)
+      def error(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, Error)
+      def warning(e:SAXParseException):Unit = parseErrors ::= ParseError.fromSAXParseException(e, Warning)
+    }
+    
+    // this StatementHandler read the parsed triples
+    val statementHandler = new StatementHandler {
+      def statement(s:AResource, p:AResource, o:ALiteral):Unit =
+        triples += rdf.Triple(rdf.SubjectNode(toNode(s)),
+                              toPredicate(p),
+                              rdf.ObjectLiteral(toLiteral(o)))
+      def statement(s:AResource, p:AResource, o:AResource):Unit =
+        triples += rdf.Triple(rdf.SubjectNode(toNode(s)),
+                              toPredicate(p),
+                              rdf.ObjectNode(toNode(o)))
+    }
+  
+    // http://jena.sourceforge.net/ARP/standalone.html
+  
+    val arp = new ARP
+    arp.getOptions.setStrictErrorMode
+    arp.getHandlers.setErrorHandler(errorHandler)
+    arp.getHandlers.setStatementHandler(statementHandler)
+    arp.load(in)
+  
+    // returns an immutable set and the potential errors
+    (rdf.Graph(triples), parseErrors)
+  }
+  
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/rdf/turtle.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -0,0 +1,139 @@
+package org.w3.rdf.turtle
+
+import org.w3.rdf._
+import scala.util.parsing.combinator._
+import java.net.URI
+
+object MyParsers extends RegexParsers {
+  val uri = """[a-zA-Z0-9:/#_\.\-\+]+""".r
+  val integer = """[0-9]+""".r
+  val float = """([0-9]+)?\.([0-9]+)?""".r
+  val name = """[a-zA-Z][a-zA-Z0-9_-]*|[a-zA-Z_][a-zA-Z0-9_]+""".r
+  var prefixes:Map[String, String] = Map()
+  var nextBNode = 1
+}
+
+import MyParsers._
+
+class TurtleParser extends JavaTokenParsers {
+  
+  import rdf._
+  
+  def toGraph(t:String)(implicit rdf: Model): rdf.Graph = parseAll(turtle, t).get
+
+  def toGraph(file:java.io.File)(implicit rdf: Model): rdf.Graph = {
+    val t = scala.io.Source.fromFile(file).getLines.reduceLeft(_+_)
+    parseAll(turtle, t).get
+  }
+ 
+  def turtle(implicit rdf: Model): Parser[rdf.Graph] =
+    opt(triplesblock) ^^ { case tbOPT => tbOPT.getOrElse(rdf.Graph.empty) }
+    
+  def prefixdecl(implicit rdf: Model): Parser[Unit] =
+    "@prefix" ~ name ~ ":" ~ qnameORuri ~ "." ^^ { case "@prefix"~pre~":"~u~"." => prefixes += (pre -> { val rdf.IRI(i: String) = u ; i }) }
+    
+  def triplesblock(implicit rdf: Model): Parser[rdf.Graph] =
+    rep(triplepatternOrPrefixOrBase) ^^ {
+      case pats => rdf.Graph(pats.flatten(_.toTraversable))
+    }
+    
+    def triplepatternOrPrefixOrBase(implicit rdf: Model): Parser[Option[rdf.Triple]] = (
+        triplepattern ^^ { case p => Some(p) }
+      | prefixdecl ^^ { case _ => None }
+    )
+      
+    def triplepattern(implicit rdf: Model): Parser[rdf.Triple] =
+      subject ~ predicate ~ objectt ~ "." ^^ { case s~p~o~"." => rdf.Triple(s, p, o) }
+  
+    def bnode(implicit rdf: Model): Parser[rdf.BNode] =
+      "_:"~name ^^ { case "_:"~name => rdf.BNode(name) }
+
+    def literal(implicit rdf: Model): Parser[rdf.Literal] = (
+        stringLiteral~"^^"~qnameORuri ^^ {
+        case lit~"^^"~dt => rdf.TypedLiteral(lit.substring(1,lit.size - 1), dt match {
+          case rdf.IRI("http://www.w3.org/2001/XMLSchema#string") => rdf.StringDatatype
+          case rdf.IRI("http://www.w3.org/2001/XMLSchema#integer") => rdf.IntegerDatatype
+          case rdf.IRI("http://www.w3.org/2001/XMLSchema#float") => rdf.FloatDatatype
+          case rdf.IRI("http://www.w3.org/2001/XMLSchema#date") => rdf.DateDatatype
+          case rdf.IRI("http://www.w3.org/2001/XMLSchema#dateTime") => rdf.DateTimeDatatype
+          case x => sys.error("only programed to deal with string and integer, not " + x)
+        })
+      } |
+        stringLiteral ^^ {
+        case lit => rdf.PlainLiteral(lit.substring(1,lit.size - 1), None)
+      } |
+        float ^^ { l => rdf.TypedLiteral(l, rdf.FloatDatatype) } |
+        integer ^^ { l => rdf.TypedLiteral(l, rdf.IntegerDatatype) }
+    )
+
+    def subject(implicit rdf: Model): Parser[rdf.Subject] = {
+        qnameORuri ^^ { case x => rdf.SubjectNode(rdf.NodeIRI(x)) } |
+        bnode ^^ { case x => rdf.SubjectNode(rdf.NodeBNode(x)) }
+    }
+      
+    def predicate(implicit rdf: Model): Parser[rdf.Predicate] = (
+        qnameORuri ^^ { case x => rdf.PredicateIRI(x) }
+      | "a" ^^ { x => rdf.PredicateIRI(rdf.IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
+    )
+      
+    def objectt(implicit rdf: Model): Parser[rdf.Object] = {
+        qnameORuri ^^ { case x => rdf.ObjectNode(rdf.NodeIRI(x)) } |
+        bnode ^^ { case x => rdf.ObjectNode(rdf.NodeBNode(x)) } |
+        literal ^^ { case x => rdf.ObjectLiteral(x) }
+    }
+  
+    def qnameORuri(implicit rdf: Model): Parser[rdf.IRI] = (
+        "<"~uri~">" ^^ { case "<"~x~">" => rdf.IRI(x) } |
+        name~":"~name ^^ {
+        case prefix~":"~localName => try {
+          rdf.IRI(prefixes(prefix) + localName)
+        } catch {
+          case e:java.util.NoSuchElementException =>
+            throw new Exception("unknown prefix " + prefix)
+        }
+      }
+    )
+  
+}
+
+// as the Module type does not escape from any method here, we can pass it at the constructor level
+class TurtleSerializer(rdf: Model) {
+  
+  import rdf._
+  
+  def graphString(g: Graph):String = {
+    g map {
+      t => {
+	val Triple(SubjectNode(s), PredicateIRI(p), o) = t
+	"%s %s %s" format (nodeStr(s), iriStr(p), objectStr(o))
+      }
+    } mkString "\n"
+  }
+
+  def objectStr(n: Object): String = {
+    n match {
+      // case l:ObjectLiteral => {
+      //   val x:ObjectLiteral = l
+      //   "**ObjectLiteral(" + x + ")**"
+      // }
+      case ObjectNode(n) => nodeStr(n)
+      case ObjectLiteral(l) => literalStr(l)
+      // case x => x
+    }
+  }
+
+  def nodeStr(n: Node): String = {
+    n match {
+      case NodeIRI(i) => iriStr(i)
+      case NodeBNode(b) => bnodeStr(b)
+    }
+  }
+
+  def iriStr(i: IRI): String = "<%s>" format { val IRI(s) = i; s }
+
+  def bnodeStr(b: BNode): String = "_:" + { val BNode(l) = b; l }
+ 
+  def literalStr(l: Literal): String = l.toString
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/webacl/parser.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -0,0 +1,13 @@
+package org.w3.webacl
+
+import com.hp.hpl.jena.rdf.model.Model
+
+object WebACLParser {
+  
+  def parse(model: Model): WebACL = {
+    
+    
+    null
+  }
+  
+}
\ No newline at end of file
--- a/src/main/scala/webacl/webacl.scala	Fri Nov 18 16:40:25 2011 -0500
+++ b/src/main/scala/webacl/webacl.scala	Sun Nov 20 19:25:34 2011 -0500
@@ -4,7 +4,7 @@
 import scala.util.matching.Regex
 
 case class WebACL(
-    imports: Seq[WebACL],
+    includes: Seq[WebACL],
     authorizations: Seq[Authorization]) {
   
   def authorized(
@@ -12,7 +12,7 @@
       action: Action,
       accessedResource: URL): Boolean =
     (authorizations exists { _.authorized(agent, action, accessedResource) }) ||
-    (imports exists { _.authorized(agent, action, accessedResource) })
+    (includes exists { _.authorized(agent, action, accessedResource) })
 }