~ GET and POST works as expected
authorAlexandre Bertails <bertails@w3.org>
Fri, 26 Aug 2011 13:52:51 -0400
changeset 5 c26795ac2c5b
parent 4 c680119084ba
child 6 392d9bd433b7
~ GET and POST works as expected
src/main/scala/Main.scala
src/test/scala/Test.scala
--- a/src/main/scala/Main.scala	Fri Aug 26 00:05:16 2011 -0400
+++ b/src/main/scala/Main.scala	Fri Aug 26 13:52:51 2011 -0400
@@ -14,6 +14,10 @@
 import com.hp.hpl.jena.rdf.model._
 import com.hp.hpl.jena.query._
 import com.hp.hpl.jena.update._
+import com.hp.hpl.jena.shared.JenaException
+
+class MSAuthorVia(value:String) extends ResponseHeader("MS-Author-Via", List(value))
+object ViaSPARQL extends MSAuthorVia("SPARQL")
 
 // holds some Unfiltered plans
 class ReadWriteWeb(base:File) {
@@ -23,32 +27,75 @@
   val echo = unfiltered.filter.Planify {
     case Path(Seg("echo" :: p :: Nil)) => ResponseString(p)
   }
-
+  
   val read = unfiltered.filter.Planify {
     case req @ Path(path) => {
-      val fis = new FileInputStream(new File(base, path))
-      /* http://jena.sourceforge.net/tutorial/RDF_API/index.html#ch-Reading%20RDF */
-      val model:Model = ModelFactory.createDefaultModel()
-      model.read(fis, "http://www.w3.org/People/Berners-Lee/")
+      val baseURI = req.underlying.getRequestURL.toString  
+      val fileOnDisk = new File(base, path)
+      
+      
+      def foo():(OutputStream, Model) = {
+        // get empty model if file not on disk
+        val model = ModelFactory.createDefaultModel()
+        if (fileOnDisk exists) {
+          val fis = new FileInputStream(fileOnDisk)
+          model.read(fis, baseURI)
+          fis.close()
+        }
+        // if file does not exist, create it
+        if (! fileOnDisk.exists) {
+          // create parent directory if needed
+          val parent = fileOnDisk.getParentFile
+          if (! parent.exists) println(parent.mkdirs)
+          val r = fileOnDisk.createNewFile()
+          logger.debug("Create file %s with success: %s" format (fileOnDisk.getAbsolutePath, r.toString))
+        }
+        val fos = new FileOutputStream(fileOnDisk)
+        (fos, model)
+      }
+      def loadModel(file:File):Model = {
+        val fis = new FileInputStream(fileOnDisk)
+        val m = ModelFactory.createDefaultModel()
+        try {
+          m.read(fis, baseURI)
+        } catch {
+          case je:JenaException => logger.error("File %s was eitheir empty or corrupted: considered as empty graph" format fileOnDisk.getAbsolutePath)
+        }
+        fis.close()
+        m
+      }
       req match {
         case GET(_) => {
-          Ok ~> new ResponseStreamer {
+          val model:Model = loadModel(fileOnDisk)
+          Ok ~> ViaSPARQL ~> new ResponseStreamer {
             def stream(os:OutputStream):Unit = {
-              /* http://jena.sourceforge.net/tutorial/RDF_API/index.html#ch-Writing%20RDF */
-              // val lang = "RDF/XML-ABBREV"
-              val lang = "TURTLE"
-              model.write(os, lang)
+              val lang = "RDF/XML-ABBREV" // "TURTLE"
+              model.write(os, lang, baseURI)
             }
           }
         }
+        case PUT(_) => {
+          val bodyModel = {
+            val m = ModelFactory.createDefaultModel()
+            m.read(Body.stream(req), baseURI)
+            m
+          }
+          val (fos, _) = foo()
+          bodyModel.write(fos, "RDF/XML-ABBREV", baseURI)
+          fos.close()
+          Ok ~> ResponseString("don't know what to return")
+        }
         case POST(_) => {
-          val bodyStream = Body.stream(req)
           /* http://openjena.org/ARQ/javadoc/com/hp/hpl/jena/update/UpdateFactory.html */
-          val update:UpdateRequest = UpdateFactory.read(bodyStream)
+          val update:UpdateRequest = UpdateFactory.read(Body.stream(req))
+          val (fos, model) = foo()
           UpdateAction.execute(update, model)
+          model.write(fos)
+          fos.close()
+          // give back the modified model
           Ok ~> new ResponseStreamer {
             def stream(os:OutputStream):Unit = {
-              val lang = "TURTLE"
+              val lang = "RDF/XML-ABBREV"
               model.write(os, lang)
             }
           }
--- a/src/test/scala/Test.scala	Fri Aug 26 00:05:16 2011 -0400
+++ b/src/test/scala/Test.scala	Fri Aug 26 13:52:51 2011 -0400
@@ -5,15 +5,26 @@
 import unfiltered.response._
 import unfiltered.request._
 import dispatch._
-import java.io.File
+import java.io._
+
+import com.hp.hpl.jena.rdf.model._
+import com.hp.hpl.jena.query._
+import com.hp.hpl.jena.update._
+
+// a Handler that returns the http code
+object HttpCode {
+  def apply(req:Request):Handler[Int] = new Handler(req, (c, r, e) => c, null)
+}
 
 object ReadWriteWebSpec extends Specification with unfiltered.spec.jetty.Served {
 
+  val base = new File("src/main/resources")
+  
   def post(req:Request, body:String) = (req <<< body).copy(method="POST")
 
-  def setup = { _.filter(new ReadWriteWeb(new File("src/main/resources")).read) }
+  def setup = { _.filter(new ReadWriteWeb(base).read) }
 
-  val timBL = host / "/People/Berners-Lee/card#i"
+  val timBL = host / "People/Berners-Lee/card#i"
     
   "GET on TimBL's FOAF profile" should {
     "return something" in {
@@ -22,25 +33,33 @@
     }
   }
 
-  val update = host / "People/Berners-Lee/card#i"
+  val joe = host / "2007/wiki/people/JoeLambda"
+  val joeOnDisk = new File(base, "2007/wiki/people/JoeLambda")
+  if (joeOnDisk.exists) joeOnDisk.delete()
     
-  val sparqlAdd =
+  val insert =
 """
-PREFIX dc: <http://purl.org/dc/elements/1.1/>
-INSERT DATA
-{ 
-  <http://example/book1> dc:title "A new book" ;
-                         dc:creator "A.N.Other" .
-}
+INSERT DATA { <http://dig.csail.xvm.mit.edu/2007/wiki/people/JoeLambda#JL> <http://xmlns.com/foaf/0.1/age> 66 }
 """
-
-  "SPARQL UPDATE on TimBL's FOAF profile" should {
-    "return something new" in {
-      val body:String = Http(post(timBL, sparqlAdd) as_str)
-      // println(body)
-      body must be matching ".*A new book.*"
-//      println("here")
+        
+  "INSERT query on Joe's URI" should {
+    "return a 200" in {
+      val httpCode:Int = Http(HttpCode(post(joe, insert)))
+      httpCode must_== 200
+    }
+    "create the corresponding file on disk" in {
+      joeOnDisk must exist
+    }
+    "create a valid rdf document with exactly one triple" in {
+      val model = Http(joe >> { is => {
+        val m = ModelFactory.createDefaultModel()
+        m.read(is, joe.path)
+        m
+      } } )
+      model.size must_== 1
     }
   }
+
+  if (joeOnDisk.exists) joeOnDisk.delete()
   
 }