--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/Filesystem.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,68 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+
+import java.io._
+import java.net.URL
+import org.slf4j.{Logger, LoggerFactory}
+import com.hp.hpl.jena.rdf.model._
+import com.hp.hpl.jena.shared.JenaException
+import sys.error
+import scalaz._
+import Scalaz._
+
+class Filesystem(
+ baseDirectory: File,
+ val basePath: String,
+ val lang: String = "RDF/XML-ABBREV")(mode: RWWMode) extends ResourceManager {
+
+ val logger: Logger = LoggerFactory.getLogger(this.getClass)
+
+ def sanityCheck(): Boolean = baseDirectory.exists
+
+ def resource(url: URL): Resource = new Resource {
+ val relativePath: String = url.getPath.replaceAll("^"+basePath.toString+"/?", "")
+ val fileOnDisk = new File(baseDirectory, relativePath)
+
+ private def createFileOnDisk(): Unit = {
+ // 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))
+ }
+
+ def get(): Validation[Throwable, Model] = {
+ val model = ModelFactory.createDefaultModel()
+ if (fileOnDisk.exists()) {
+ val fis = new FileInputStream(fileOnDisk)
+ try {
+ val reader = model.getReader(lang)
+ reader.read(model, fis, url.toString)
+ } catch {
+ case je:JenaException => error("@@@")
+ }
+ fis.close()
+ model.success
+ } else {
+ mode match {
+ case AllResourcesAlreadyExist => model.success
+ case ResourcesDontExistByDefault => new FileNotFoundException().fail
+ }
+ }
+ }
+
+ def save(model: Model): Validation[Throwable, Unit] =
+ try {
+ createFileOnDisk()
+ val fos = new FileOutputStream(fileOnDisk)
+ val writer = model.getWriter(lang)
+ writer.write(model, fos, url.toString)
+ fos.close().success
+ } catch {
+ case t => t.fail
+ }
+
+ }
+
+}
--- a/src/main/scala/Main.scala Mon Oct 10 17:47:51 2011 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-package org.w3.readwriteweb
-
-import javax.servlet._
-import javax.servlet.http._
-import unfiltered.request._
-import unfiltered.response._
-import unfiltered.jetty._
-
-import java.io._
-import scala.io.Source
-import java.net.URL
-
-import org.slf4j.{Logger, LoggerFactory}
-
-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
-import Query.{QueryTypeSelect => SELECT, QueryTypeAsk => ASK,
- QueryTypeConstruct => CONSTRUCT, QueryTypeDescribe => DESCRIBE}
-
-import scalaz._
-import Scalaz._
-
-import org.w3.readwriteweb.util._
-
-class ReadWriteWeb(rm: ResourceManager) {
-
- val logger:Logger = LoggerFactory.getLogger(this.getClass)
-
- def isHTML(accepts:List[String]):Boolean = {
- val accept = accepts.headOption
- accept == Some("text/html") || accept == Some("application/xhtml+xml")
- }
-
- /** I believe some documentation is needed here, as many different tricks
- * are used to make this code easy to read and still type-safe
- *
- * Planify.apply takes an Intent, which is defined in Cycle by
- * type Intent [-A, -B] = PartialFunction[HttpRequest[A], ResponseFunction[B]]
- * the corresponding syntax is: case ... => ...
- *
- * this code makes use of the Validation monad. For example of how to use it, see
- * http://scalaz.googlecode.com/svn/continuous/latest/browse.sxr/scalaz/example/ExampleValidation.scala.html
- *
- * the Resource abstraction returns Validation[Throwable, ?something]
- * we use the for monadic constructs.
- * Everything construct are mapped to Validation[ResponseFunction, ResponseFuntion],
- * the left value always denoting the failure. Hence, the rest of the for-construct
- * is not evaluated, but let the reader of the code understand clearly what's happening.
- *
- * This mapping is made possible with the failMap method. I couldn't find an equivalent
- * in the ScalaZ API so I made my own through an implicit.
- *
- * At last, Validation[ResponseFunction, ResponseFuntion] is exposed as a ResponseFunction
- * through another implicit conversion. It saves us the call to the Validation.lift() method
- */
- val read = unfiltered.filter.Planify {
- case req @ Path(path) if path startsWith rm.basePath => {
- val baseURI = req.underlying.getRequestURL.toString
- val r:Resource = rm.resource(new URL(baseURI))
- req match {
- case GET(_) & Accept(accepts) if isHTML(accepts) => {
- val source = Source.fromFile("src/main/resources/skin.html")("UTF-8")
- val body = source.getLines.mkString("\n")
- Ok ~> ViaSPARQL ~> ContentType("text/html") ~> ResponseString(body)
- }
- case GET(_) | HEAD(_) =>
- for {
- model <- r.get() failMap { x => NotFound }
- encoding = RDFEncoding(req)
- } yield {
- req match {
- case GET(_) => Ok ~> ViaSPARQL ~> ContentType(encoding.toContentType) ~> ResponseModel(model, baseURI, encoding)
- case HEAD(_) => Ok ~> ViaSPARQL ~> ContentType(encoding.toContentType)
- }
- }
- case PUT(_) =>
- for {
- bodyModel <- modelFromInputStream(Body.stream(req), baseURI) failMap { t => BadRequest ~> ResponseString(t.getStackTraceString) }
- _ <- r.save(bodyModel) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString) }
- } yield Created
- case POST(_) => {
- Post.parse(Body.stream(req), baseURI) match {
- case PostUnknown => {
- logger.info("Couldn't parse the request")
- BadRequest ~> ResponseString("You MUST provide valid content for either: SPARQL UPDATE, SPARQL Query, RDF/XML, TURTLE")
- }
- case PostUpdate(update) => {
- logger.info("SPARQL UPDATE:\n" + update.toString())
- for {
- model <- r.get() failMap { t => NotFound }
- // TODO: we should handle an error here
- _ = UpdateAction.execute(update, model)
- _ <- r.save(model) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString)}
- } yield Ok
- }
- case PostRDF(diffModel) => {
- logger.info("RDF content:\n" + diffModel.toString())
- for {
- model <- r.get() failMap { t => NotFound }
- // TODO: we should handle an error here
- _ = model.add(diffModel)
- _ <- r.save(model) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString)}
- } yield Ok
- }
- case PostQuery(query) => {
- logger.info("SPARQL Query:\n" + query.toString())
- lazy val encoding = RDFEncoding(req)
- for {
- model <- r.get() failMap { t => NotFound }
- } yield {
- val qe:QueryExecution = QueryExecutionFactory.create(query, model)
- query.getQueryType match {
- case SELECT =>
- Ok ~> ContentType("application/sparql-results+xml") ~> ResponseResultSet(qe.execSelect())
- case ASK =>
- Ok ~> ContentType("application/sparql-results+xml") ~> ResponseResultSet(qe.execAsk())
- case CONSTRUCT => {
- val result:Model = qe.execConstruct()
- Ok ~> ContentType(encoding.toContentType) ~> ResponseModel(model, baseURI, encoding)
- }
- case DESCRIBE => {
- val result:Model = qe.execDescribe()
- Ok ~> ContentType(encoding.toContentType) ~> ResponseModel(model, baseURI, encoding)
- }
- }
- }
- }
- }
- }
- case _ => MethodNotAllowed ~> Allow("GET", "PUT", "POST")
- }
- }
-
- }
-
-}
-
-
-import org.clapper.argot._
-import ArgotConverters._
-
-object ReadWriteWebMain {
-
- val logger:Logger = LoggerFactory.getLogger(this.getClass)
-
- val parser = new ArgotParser("read-write-web")
-
- val mode = parser.option[RWWMode](List("mode"), "m", "wiki mode") {
- (sValue, opt) =>
- sValue match {
- case "wiki" => AllResourcesAlreadyExist
- case "strict" => ResourcesDontExistByDefault
- case _ => throw new ArgotConversionException("Option %s: must be either wiki or strict" format (opt.name, sValue))
- }
- }
-
- val rdfLanguage = parser.option[String](List("language"), "l", "RDF language") {
- (sValue, opt) =>
- sValue match {
- case "n3" => "N3"
- case "turtle" => "N3"
- case "rdfxml" => "RDF/XML-ABBREV"
- case _ => throw new ArgotConversionException("Option %s: must be either n3, turtle or rdfxml" format (opt.name, sValue))
- }
- }
-
- val port = parser.parameter[Int]("port", "Port to use", false)
-
- val rootDirectory = parser.parameter[File]("rootDirectory", "root directory", false) {
- (sValue, opt) => {
- val file = new File(sValue)
- if (! file.exists)
- throw new ArgotConversionException("Option %s: %s must be a valid path" format (opt.name, sValue))
- else
- file
- }
- }
-
- val baseURL = parser.parameter[String]("baseURL", "base URL", false)
-
- // regular Java main
- def main(args: Array[String]) {
-
- try {
- parser.parse(args)
- } catch {
- case e: ArgotUsageException => println(e.message); System.exit(1)
- }
-
- val filesystem =
- new Filesystem(
- rootDirectory.value.get,
- baseURL.value.get,
- lang=rdfLanguage.value getOrElse "N3")(mode.value getOrElse ResourcesDontExistByDefault)
-
- val app = new ReadWriteWeb(filesystem)
-
- // configures and launches a Jetty server
- unfiltered.jetty.Http(port.value.get).filter {
- // a jee Servlet filter that logs HTTP requests
- new Filter {
- def destroy():Unit = ()
- def doFilter(request:ServletRequest, response:ServletResponse, chain:FilterChain):Unit = {
- val r:HttpServletRequest = request.asInstanceOf[HttpServletRequest]
- val method = r.getMethod
- val uri = r.getRequestURI
- logger.info("%s %s" format (method, uri))
- chain.doFilter(request, response)
- }
- def init(filterConfig:FilterConfig):Unit = ()
- }
- // Unfiltered filters
- }.context("/public"){ ctx:ContextBuilder =>
- ctx.resources(MyResourceManager.fromClasspath("public/").toURI.toURL)
- }.filter(app.read).run()
-
- }
-
-}
-
--- a/src/main/scala/Post.scala Mon Oct 10 17:47:51 2011 -0400
+++ b/src/main/scala/Post.scala Tue Oct 11 22:09:02 2011 -0400
@@ -1,54 +1,61 @@
package org.w3.readwriteweb
-import java.io._
+import org.w3.readwriteweb.util.modelFromString
+
+import java.io.{InputStream, StringReader}
import scala.io.Source
-
import org.slf4j.{Logger, LoggerFactory}
-
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
-import org.w3.readwriteweb.util._
-
sealed trait Post
-case class PostUpdate(update:UpdateRequest) extends Post
-case class PostRDF(model:Model) extends Post
-case class PostQuery(query:Query) extends Post
+
+case class PostUpdate(update: UpdateRequest) extends Post
+
+case class PostRDF(model: Model) extends Post
+
+case class PostQuery(query: Query) extends Post
+
case object PostUnknown extends Post
+
import scalaz._
import Scalaz._
object Post {
- val logger:Logger = LoggerFactory.getLogger(this.getClass)
+ val logger: Logger = LoggerFactory.getLogger(this.getClass)
- def parse(is:InputStream, baseURI:String):Post = {
+ def parse(is: InputStream, baseURI:String): Post = {
val source = Source.fromInputStream(is, "UTF-8")
val s = source.getLines.mkString("\n")
parse(s, baseURI)
}
- def parse(s:String, baseURI:String):Post = {
+ def parse(s: String, baseURI: String): Post = {
val reader = new StringReader(s)
+
def postUpdate =
try {
- val update:UpdateRequest = UpdateFactory.create(s, baseURI)
+ val update: UpdateRequest = UpdateFactory.create(s, baseURI)
PostUpdate(update).success
} catch {
- case qpe:QueryParseException => qpe.fail
+ case qpe: QueryParseException => qpe.fail
}
+
def postRDF =
modelFromString(s, baseURI) flatMap { model => PostRDF(model).success }
+
def postQuery =
try {
val query = QueryFactory.create(s)
PostQuery(query).success
} catch {
- case qe:QueryException => qe.fail
+ case qe: QueryException => qe.fail
}
+
postUpdate | (postRDF | (postQuery | PostUnknown))
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/ReadWriteWebMain.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,82 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+
+import javax.servlet._
+import javax.servlet.http._
+import unfiltered.jetty._
+import java.io.File
+import Console.err
+import org.slf4j.{Logger, LoggerFactory}
+
+import org.clapper.argot._
+import ArgotConverters._
+
+object ReadWriteWebMain {
+
+ val logger: Logger = LoggerFactory.getLogger(this.getClass)
+
+ val parser = new ArgotParser("read-write-web")
+
+ val mode = parser.option[RWWMode](List("mode"), "m", "wiki mode") {
+ (sValue, opt) =>
+ sValue match {
+ case "wiki" => AllResourcesAlreadyExist
+ case "strict" => ResourcesDontExistByDefault
+ case _ => throw new ArgotConversionException("Option %s: must be either wiki or strict" format (opt.name, sValue))
+ }
+ }
+
+ val rdfLanguage = parser.option[String](List("language"), "l", "RDF language") {
+ (sValue, opt) =>
+ sValue match {
+ case "n3" => "N3"
+ case "turtle" => "N3"
+ case "rdfxml" => "RDF/XML-ABBREV"
+ case _ => throw new ArgotConversionException("Option %s: must be either n3, turtle or rdfxml" format (opt.name, sValue))
+ }
+ }
+
+ val port = parser.parameter[Int]("port", "Port to use", false)
+
+ val rootDirectory = parser.parameter[File]("rootDirectory", "root directory", false) {
+ (sValue, opt) => {
+ val file = new File(sValue)
+ if (! file.exists)
+ throw new ArgotConversionException("Option %s: %s must be a valid path" format (opt.name, sValue))
+ else
+ file
+ }
+ }
+
+ val baseURL = parser.parameter[String]("baseURL", "base URL", false)
+
+ // regular Java main
+ def main(args: Array[String]) {
+
+ try {
+ parser.parse(args)
+ } catch {
+ case e: ArgotUsageException => err.println(e.message); sys.exit(1)
+ }
+
+ val filesystem =
+ new Filesystem(
+ rootDirectory.value.get,
+ baseURL.value.get,
+ lang=rdfLanguage.value getOrElse "N3")(mode.value getOrElse ResourcesDontExistByDefault)
+
+ val app = new ReadWriteWeb(filesystem)
+
+ // configures and launches a Jetty server
+ unfiltered.jetty.Http(port.value.get)
+ .filter(new FilterLogger(logger))
+ .context("/public") {
+ ctx: ContextBuilder =>
+ ctx.resources(ClasspathUtils.fromClasspath("public/").toURI.toURL)
+ }.filter(app.plan).run()
+
+ }
+
+}
+
--- a/src/main/scala/Resource.scala Mon Oct 10 17:47:51 2011 -0400
+++ b/src/main/scala/Resource.scala Tue Oct 11 22:09:02 2011 -0400
@@ -1,83 +1,20 @@
package org.w3.readwriteweb
-import java.io._
-import java.net.URL
-
-import org.slf4j.{Logger, LoggerFactory}
-
-import com.hp.hpl.jena.rdf.model._
-import com.hp.hpl.jena.shared.JenaException
-
import org.w3.readwriteweb.util._
+import java.net.URL
+import com.hp.hpl.jena.rdf.model._
import scalaz._
import Scalaz._
-import _root_.scala.sys.error
-
trait ResourceManager {
- def basePath:String
- def sanityCheck():Boolean
- def resource(url:URL):Resource
+ def basePath: String
+ def sanityCheck(): Boolean
+ def resource(url: URL): Resource
}
trait Resource {
- def get():Validation[Throwable, Model]
- def save(model:Model):Validation[Throwable, Unit]
+ def get(): Validation[Throwable, Model]
+ def save(model: Model): Validation[Throwable, Unit]
}
-class Filesystem(
- baseDirectory: File,
- val basePath: String,
- val lang: String = "RDF/XML-ABBREV")(mode: RWWMode) extends ResourceManager {
-
- val logger:Logger = LoggerFactory.getLogger(this.getClass)
-
- def sanityCheck():Boolean = baseDirectory.exists
-
- def resource(url:URL):Resource = new Resource {
- val relativePath:String = url.getPath.replaceAll("^"+basePath.toString+"/?", "")
- val fileOnDisk = new File(baseDirectory, relativePath)
-
- private def createFileOnDisk():Unit = {
- // 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))
- }
-
- def get(): Validation[Throwable, Model] = {
- val model = ModelFactory.createDefaultModel()
- if (fileOnDisk.exists()) {
- val fis = new FileInputStream(fileOnDisk)
- try {
- val reader = model.getReader(lang)
- reader.read(model, fis, url.toString)
- } catch {
- case je:JenaException => error("@@@")
- }
- fis.close()
- model.success
- } else {
- mode match {
- case AllResourcesAlreadyExist => model.success
- case ResourcesDontExistByDefault => new FileNotFoundException().fail
- }
- }
- }
-
- def save(model:Model):Validation[Throwable, Unit] =
- try {
- createFileOnDisk()
- val fos = new FileOutputStream(fileOnDisk)
- val writer = model.getWriter(lang)
- writer.write(model, fos, url.toString)
- fos.close().success
- } catch {
- case t => t.fail
- }
-
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/plan.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,135 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+
+import unfiltered.request._
+import unfiltered.response._
+
+import scala.io.Source
+import java.net.URL
+
+import org.slf4j.{Logger, LoggerFactory}
+
+import com.hp.hpl.jena.rdf.model.Model
+import com.hp.hpl.jena.query.{Query, QueryExecution, QueryExecutionFactory}
+import com.hp.hpl.jena.update.UpdateAction
+import Query.{QueryTypeSelect => SELECT,
+ QueryTypeAsk => ASK,
+ QueryTypeConstruct => CONSTRUCT,
+ QueryTypeDescribe => DESCRIBE}
+
+import scalaz._
+import Scalaz._
+
+class ReadWriteWeb(rm: ResourceManager) {
+
+ val logger: Logger = LoggerFactory.getLogger(this.getClass)
+
+ def isHTML(accepts: List[String]): Boolean = {
+ val accept = accepts.headOption
+ accept == Some("text/html") || accept == Some("application/xhtml+xml")
+ }
+
+ /** I believe some documentation is needed here, as many different tricks
+ * are used to make this code easy to read and still type-safe
+ *
+ * Planify.apply takes an Intent, which is defined in Cycle by
+ * type Intent [-A, -B] = PartialFunction[HttpRequest[A], ResponseFunction[B]]
+ * the corresponding syntax is: case ... => ...
+ *
+ * this code makes use of the Validation monad. For example of how to use it, see
+ * http://scalaz.googlecode.com/svn/continuous/latest/browse.sxr/scalaz/example/ExampleValidation.scala.html
+ *
+ * the Resource abstraction returns Validation[Throwable, ?something]
+ * we use the for monadic constructs.
+ * Everything construct are mapped to Validation[ResponseFunction, ResponseFuntion],
+ * the left value always denoting the failure. Hence, the rest of the for-construct
+ * is not evaluated, but let the reader of the code understand clearly what's happening.
+ *
+ * This mapping is made possible with the failMap method. I couldn't find an equivalent
+ * in the ScalaZ API so I made my own through an implicit.
+ *
+ * At last, Validation[ResponseFunction, ResponseFuntion] is exposed as a ResponseFunction
+ * through another implicit conversion. It saves us the call to the Validation.lift() method
+ */
+ val plan = unfiltered.filter.Planify {
+ case req @ Path(path) if path startsWith rm.basePath => {
+ val baseURI = req.underlying.getRequestURL.toString
+ val r: Resource = rm.resource(new URL(baseURI))
+ req match {
+ case GET(_) & Accept(accepts) if isHTML(accepts) => {
+ val source = Source.fromFile("src/main/resources/skin.html")("UTF-8")
+ val body = source.getLines.mkString("\n")
+ Ok ~> ViaSPARQL ~> ContentType("text/html") ~> ResponseString(body)
+ }
+ case GET(_) | HEAD(_) =>
+ for {
+ model <- r.get() failMap { x => NotFound }
+ encoding = RDFEncoding(req)
+ } yield {
+ req match {
+ case GET(_) => Ok ~> ViaSPARQL ~> ContentType(encoding.toContentType) ~> ResponseModel(model, baseURI, encoding)
+ case HEAD(_) => Ok ~> ViaSPARQL ~> ContentType(encoding.toContentType)
+ }
+ }
+ case PUT(_) =>
+ for {
+ bodyModel <- modelFromInputStream(Body.stream(req), baseURI) failMap { t => BadRequest ~> ResponseString(t.getStackTraceString) }
+ _ <- r.save(bodyModel) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString) }
+ } yield Created
+ case POST(_) => {
+ Post.parse(Body.stream(req), baseURI) match {
+ case PostUnknown => {
+ logger.info("Couldn't parse the request")
+ BadRequest ~> ResponseString("You MUST provide valid content for either: SPARQL UPDATE, SPARQL Query, RDF/XML, TURTLE")
+ }
+ case PostUpdate(update) => {
+ logger.info("SPARQL UPDATE:\n" + update.toString())
+ for {
+ model <- r.get() failMap { t => NotFound }
+ // TODO: we should handle an error here
+ _ = UpdateAction.execute(update, model)
+ _ <- r.save(model) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString)}
+ } yield Ok
+ }
+ case PostRDF(diffModel) => {
+ logger.info("RDF content:\n" + diffModel.toString())
+ for {
+ model <- r.get() failMap { t => NotFound }
+ // TODO: we should handle an error here
+ _ = model.add(diffModel)
+ _ <- r.save(model) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString)}
+ } yield Ok
+ }
+ case PostQuery(query) => {
+ logger.info("SPARQL Query:\n" + query.toString())
+ lazy val encoding = RDFEncoding(req)
+ for {
+ model <- r.get() failMap { t => NotFound }
+ } yield {
+ val qe: QueryExecution = QueryExecutionFactory.create(query, model)
+ query.getQueryType match {
+ case SELECT =>
+ Ok ~> ContentType("application/sparql-results+xml") ~> ResponseResultSet(qe.execSelect())
+ case ASK =>
+ Ok ~> ContentType("application/sparql-results+xml") ~> ResponseResultSet(qe.execAsk())
+ case CONSTRUCT => {
+ val result: Model = qe.execConstruct()
+ Ok ~> ContentType(encoding.toContentType) ~> ResponseModel(model, baseURI, encoding)
+ }
+ case DESCRIBE => {
+ val result: Model = qe.execDescribe()
+ Ok ~> ContentType(encoding.toContentType) ~> ResponseModel(model, baseURI, encoding)
+ }
+ }
+ }
+ }
+ }
+ }
+ case _ => MethodNotAllowed ~> Allow("GET", "PUT", "POST")
+ }
+ }
+
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/rdfLanguage.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,31 @@
+package org.w3.readwriteweb
+
+import unfiltered.request._
+
+sealed trait RDFEncoding {
+ def toContentType:String
+}
+
+case object RDFXML extends RDFEncoding {
+ def toContentType = "application/rdf+xml"
+}
+
+case object TURTLE extends RDFEncoding {
+ def toContentType = "text/turtle"
+}
+
+object RDFEncoding {
+
+ def apply(contentType:String):RDFEncoding =
+ contentType match {
+ case "text/turtle" => TURTLE
+ case "application/rdf+xml" => RDFXML
+ case _ => RDFXML
+ }
+
+ def apply(req:HttpRequest[_]):RDFEncoding = {
+ val contentType = Accept(req).headOption
+ contentType map { RDFEncoding(_) } getOrElse RDFXML
+ }
+
+}
--- a/src/main/scala/util.scala Mon Oct 10 17:47:51 2011 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-package org.w3.readwriteweb
-
-import javax.servlet._
-import javax.servlet.http._
-import unfiltered.request._
-import unfiltered.response._
-import unfiltered.jetty._
-
-import java.io._
-import scala.io.Source
-
-import scalaz._
-import Scalaz._
-
-import _root_.scala.sys.error
-
-import org.slf4j.{Logger, LoggerFactory}
-
-import com.hp.hpl.jena.rdf.model._
-import com.hp.hpl.jena.query._
-import com.hp.hpl.jena.update._
-
-import unfiltered.request._
-import unfiltered.response._
-import unfiltered.jetty._
-
-sealed trait RWWMode
-case object AllResourcesAlreadyExist extends RWWMode
-case object ResourcesDontExistByDefault extends RWWMode
-
-sealed trait RDFEncoding {
- def toContentType:String
-}
-case object RDFXML extends RDFEncoding {
- def toContentType = "application/rdf+xml"
-}
-case object TURTLE extends RDFEncoding {
- def toContentType = "text/turtle"
-}
-
-object RDFEncoding {
-
- def apply(contentType:String):RDFEncoding =
- contentType match {
- case "text/turtle" => TURTLE
- case "application/rdf+xml" => RDFXML
- case _ => RDFXML
- }
-
- def apply(req:HttpRequest[_]):RDFEncoding = {
- val contentType = Accept(req).headOption
- contentType map { RDFEncoding(_) } getOrElse RDFXML
- }
-
-}
-
-trait ValidationW[E, S] {
- val validation:Validation[E, S]
- def failMap[EE](f:E => EE):Validation[EE, S] = validation.fail map f validation
-}
-
-package object util {
-
- val defaultLang = "RDF/XML-ABBREV"
-
- class MSAuthorVia(value:String) extends ResponseHeader("MS-Author-Via", List(value))
- object ViaSPARQL extends MSAuthorVia("SPARQL")
-
- object ResponseModel {
- def apply(model:Model, base:String, encoding:RDFEncoding):ResponseStreamer =
- new ResponseStreamer {
- def stream(os:OutputStream):Unit =
- encoding match {
- case RDFXML => model.getWriter("RDF/XML-ABBREV").write(model, os, base)
- case TURTLE => model.getWriter("TURTLE").write(model, os, base)
- }
- }
- }
-
- object ResponseResultSet {
- def apply(rs:ResultSet):ResponseStreamer =
- new ResponseStreamer {
- def stream(os:OutputStream):Unit = ResultSetFormatter.outputAsXML(os, rs)
- }
- def apply(result:Boolean):ResponseStreamer =
- new ResponseStreamer {
- def stream(os:OutputStream):Unit = ResultSetFormatter.outputAsXML(os, result)
- }
- }
-
- def modelFromInputStream(
- is:InputStream,
- base:String,
- lang:String = "RDF/XML-ABBREV"):Validation[Throwable, Model] =
- try {
- val m = ModelFactory.createDefaultModel()
- m.read(is, base, lang)
- m.success
- } catch {
- case t => t.fail
- }
-
- def modelFromString(s:String,
- base:String,
- lang:String = "RDF/XML-ABBREV"):Validation[Throwable, Model] =
- try {
- val reader = new StringReader(s)
- val m = ModelFactory.createDefaultModel()
- m.read(reader, base, lang)
- m.success
- } catch {
- case t => t.fail
- }
-
- implicit def wrapValidation[E, S](v:Validation[E,S]):ValidationW[E, S] =
- new ValidationW[E, S] { val validation = v }
-
- implicit def unwrap[E, F <: E, S <: E](v:Validation[F,S]):E = v.fold(e => e, s => s)
-
-}
-
-
-import java.io.{File, FileWriter}
-import java.util.jar._
-import scala.collection.JavaConversions._
-import scala.io.Source
-import java.net.{URL, URLDecoder}
-import org.slf4j.{Logger, LoggerFactory}
-
-/** useful stuff to read resources from the classpath */
-object MyResourceManager {
-
- val logger:Logger = LoggerFactory.getLogger(this.getClass)
-
- val clazz:Class[_] = this.getClass
- val classloader = this.getClass.getClassLoader
-
- /** http://www.uofr.net/~greg/java/get-resource-listing.html
- */
- def getResourceListing(path:String):List[String] = {
- var dirURL:URL = classloader.getResource(path)
- if (dirURL != null && dirURL.getProtocol == "file") {
- /* A file path: easy enough */
- new File(dirURL.toURI).list.toList
- } else {
- if (dirURL == null) {
- val me = clazz.getName().replace(".", "/")+".class"
- dirURL = classloader.getResource(me)
- }
- if (dirURL.getProtocol == "jar") {
- val jarPath = dirURL.getPath.substring(5, dirURL.getPath().indexOf("!"))
- val jar:JarFile = new JarFile(URLDecoder.decode(jarPath, "UTF-8"))
- val entries = jar.entries filter { _.getName startsWith path } map { e => {
- var entry = e.getName substring path.length
- val checkSubdir = entry indexOf "/"
- if (checkSubdir >= 0) entry = entry.substring(0, checkSubdir)
- entry
- } }
- entries filterNot { _.isEmpty } toList
- } else
- error("Cannot list files for URL "+dirURL);
- }
- }
-
- /** extract a path found in the classpath
- *
- * @return the file on disk
- */
- def fromClasspath(path:String, base:File = new File("src/main/resources")):File = {
- val workingPath = new File(base, path)
- if (workingPath isDirectory) {
- workingPath
- } else {
- val dir = new File(System.getProperty("java.io.tmpdir"),
- "virtual-trainer-" + scala.util.Random.nextInt(10000).toString)
- if (! dir.mkdir()) logger.error("Couldn't extract %s from jar to %s" format (path, dir.getAbsolutePath))
- val entries = getResourceListing(path) foreach { entry => {
- val url = classloader.getResource(path + entry)
- val content = Source.fromURL(url, "UTF-8").getLines.mkString("\n")
- val writer = new FileWriter(new File(dir, entry))
- writer.write(content)
- writer.close()
- }
- }
- dir
- }
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/util/ClasspathUtils.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,69 @@
+package org.w3.readwriteweb.util
+
+import java.io.{File, FileWriter}
+import java.util.jar._
+import scala.collection.JavaConversions._
+import scala.io.Source
+import java.net.{URL, URLDecoder}
+import org.slf4j.{Logger, LoggerFactory}
+
+/** useful stuff to read resources from the classpath */
+object ClasspathUtils {
+
+ val logger: Logger = LoggerFactory.getLogger(this.getClass)
+
+ val clazz: Class[_] = this.getClass
+ val classloader = this.getClass.getClassLoader
+
+ /** http://www.uofr.net/~greg/java/get-resource-listing.html
+ */
+ def getResourceListing(path: String): List[String] = {
+ var dirURL: URL = classloader.getResource(path)
+ if (dirURL != null && dirURL.getProtocol == "file") {
+ /* A file path: easy enough */
+ new File(dirURL.toURI).list.toList
+ } else {
+ if (dirURL == null) {
+ val me = clazz.getName().replace(".", "/")+".class"
+ dirURL = classloader.getResource(me)
+ }
+ if (dirURL.getProtocol == "jar") {
+ val jarPath = dirURL.getPath.substring(5, dirURL.getPath().indexOf("!"))
+ val jar: JarFile = new JarFile(URLDecoder.decode(jarPath, "UTF-8"))
+ val entries = jar.entries filter { _.getName startsWith path } map { e => {
+ var entry = e.getName substring path.length
+ val checkSubdir = entry indexOf "/"
+ if (checkSubdir >= 0) entry = entry.substring(0, checkSubdir)
+ entry
+ } }
+ entries filterNot { _.isEmpty } toList
+ } else
+ sys.error("Cannot list files for URL "+dirURL);
+ }
+ }
+
+ /** extract a path found in the classpath
+ *
+ * @return the file on disk
+ */
+ def fromClasspath(path: String, base: File = new File("src/main/resources")): File = {
+ val workingPath = new File(base, path)
+ if (workingPath isDirectory) {
+ workingPath
+ } else {
+ val dir = new File(System.getProperty("java.io.tmpdir"),
+ "virtual-trainer-" + scala.util.Random.nextInt(10000).toString)
+ if (! dir.mkdir()) logger.error("Couldn't extract %s from jar to %s" format (path, dir.getAbsolutePath))
+ val entries = getResourceListing(path) foreach { entry => {
+ val url = classloader.getResource(path + entry)
+ val content = Source.fromURL(url, "UTF-8").getLines.mkString("\n")
+ val writer = new FileWriter(new File(dir, entry))
+ writer.write(content)
+ writer.close()
+ }
+ }
+ dir
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/util/FilterLogger.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,28 @@
+package org.w3.readwriteweb
+
+import javax.servlet._
+import javax.servlet.http._
+import unfiltered.jetty._
+import java.io.File
+import org.slf4j.{Logger, LoggerFactory}
+
+/** a simple JEE Servlet filter that logs HTTP requests
+ */
+class FilterLogger(logger: Logger) extends Filter {
+
+ def destroy(): Unit = ()
+
+ def doFilter(
+ request: ServletRequest,
+ response: ServletResponse,
+ chain: FilterChain): Unit = {
+ val r: HttpServletRequest = request.asInstanceOf[HttpServletRequest]
+ val method = r.getMethod
+ val uri = r.getRequestURI
+ logger.info("%s %s" format (method, uri))
+ chain.doFilter(request, response)
+ }
+
+ def init(filterConfig: FilterConfig): Unit = ()
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/util/ValidationW.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,13 @@
+package org.w3.readwriteweb.util
+
+import scalaz._
+import Scalaz._
+
+trait ValidationW[E, S] {
+
+ val validation: Validation[E, S]
+
+ def failMap[EE](f: E => EE): Validation[EE, S] =
+ validation.fail map f validation
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/util/mode.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,7 @@
+package org.w3.readwriteweb
+
+sealed trait RWWMode
+
+case object AllResourcesAlreadyExist extends RWWMode
+
+case object ResourcesDontExistByDefault extends RWWMode
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/util/package.scala Tue Oct 11 22:09:02 2011 -0400
@@ -0,0 +1,70 @@
+package org.w3.readwriteweb
+
+import java.io._
+import com.hp.hpl.jena.rdf.model._
+import com.hp.hpl.jena.query._
+import unfiltered.response._
+import scalaz._
+import Scalaz._
+
+package object util {
+
+ val defaultLang = "RDF/XML-ABBREV"
+
+ class MSAuthorVia(value: String) extends ResponseHeader("MS-Author-Via", List(value))
+
+ object ViaSPARQL extends MSAuthorVia("SPARQL")
+
+ object ResponseModel {
+ def apply(model: Model, base: String, encoding: RDFEncoding): ResponseStreamer =
+ new ResponseStreamer {
+ def stream(os: OutputStream): Unit =
+ encoding match {
+ case RDFXML => model.getWriter("RDF/XML-ABBREV").write(model, os, base)
+ case TURTLE => model.getWriter("TURTLE").write(model, os, base)
+ }
+ }
+ }
+
+ object ResponseResultSet {
+ def apply(rs: ResultSet): ResponseStreamer =
+ new ResponseStreamer {
+ def stream(os: OutputStream): Unit = ResultSetFormatter.outputAsXML(os, rs)
+ }
+ def apply(result: Boolean): ResponseStreamer =
+ new ResponseStreamer {
+ def stream(os: OutputStream):Unit = ResultSetFormatter.outputAsXML(os, result)
+ }
+ }
+
+ def modelFromInputStream(
+ is: InputStream,
+ base: String,
+ lang: String = "RDF/XML-ABBREV"): Validation[Throwable, Model] =
+ try {
+ val m = ModelFactory.createDefaultModel()
+ m.read(is, base, lang)
+ m.success
+ } catch {
+ case t => t.fail
+ }
+
+ def modelFromString(
+ s: String,
+ base: String,
+ lang: String = "RDF/XML-ABBREV"): Validation[Throwable, Model] =
+ try {
+ val reader = new StringReader(s)
+ val m = ModelFactory.createDefaultModel()
+ m.read(reader, base, lang)
+ m.success
+ } catch {
+ case t => t.fail
+ }
+
+ implicit def wrapValidation[E, S](v: Validation[E,S]): ValidationW[E, S] =
+ new ValidationW[E, S] { val validation = v }
+
+ implicit def unwrap[E, F <: E, S <: E](v: Validation[F,S]): E = v.fold(e => e, s => s)
+
+}
--- a/src/test/scala/util/specs.scala Mon Oct 10 17:47:51 2011 -0400
+++ b/src/test/scala/util/specs.scala Tue Oct 11 22:09:02 2011 -0400
@@ -23,7 +23,7 @@
def resourceManager: ResourceManager
- def setup = { _.filter(new ReadWriteWeb(resourceManager).read) }
+ def setup = { _.filter(new ReadWriteWeb(resourceManager).plan) }
}