--- a/src/main/scala/plan.scala Sun Nov 13 21:55:08 2011 -0500
+++ b/src/main/scala/plan.scala Sun Nov 13 22:39:17 2011 -0500
@@ -2,12 +2,9 @@
import auth.{AuthZ, NullAuthZ}
import org.w3.readwriteweb.util._
-
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
@@ -15,11 +12,12 @@
QueryTypeAsk => ASK,
QueryTypeConstruct => CONSTRUCT,
QueryTypeDescribe => DESCRIBE}
-
-import scalaz.{Resource => _}
+import scalaz.{Resource => _, Scalaz, Validation}
+import Scalaz._
import unfiltered.request._
import unfiltered.Cycle
import unfiltered.response._
+import javax.security.auth.Subject
//object ReadWriteWeb {
//
@@ -50,9 +48,9 @@
* ( Note that we don't want to protect this intent, since that would be to apply the security to all other applications,
* many of which may want different authorization implementations )
*/
- def intent : Cycle.Intent[Req, Res] = {
- case req @ Path(path) if path startsWith rm.basePath => authz.protect(rwwIntent)(manif)(req)
- }
+// def intent : Cycle.Intent[Req, Res] = {
+// case req @ Path(path) if path startsWith rm.basePath => authz.protect(rwwIntent)(manif)(req)
+// }
/**
* The core ReadWrite web function
@@ -73,101 +71,116 @@
* At last, Validation[ResponseFunction, ResponseFuntion] is exposed as a ResponseFunction
* through another implicit conversion. It saves us the call to the Validation.fold() method
*/
- def rwwIntent = (req: HttpRequest[Req]) => {
-
- val Authoritative(uri: URL, representation: Representation) = req
- val r: Resource = rm.resource(uri)
- val res: ResponseFunction[Res] = req match {
- case GET(_) if representation == HTMLRepr => {
- val source = Source.fromFile("src/main/resources/skin.html")("UTF-8")
- val body = source.getLines.mkString("\n")
- Ok ~> ViaSPARQL ~> ContentType("text/html") ~> ResponseString(body)
+ type AuthenticatedRequest = (HttpRequest[Req], Subject)
+ type ValidationRequest = Validation[ResponseFunction[Res], AuthenticatedRequest]
+ type ValidationResponse = Validation[ResponseFunction[Res], ResponseFunction[Res]]
+
+ def composableIntent(validationReq: ValidationRequest): ValidationResponse = validationReq flatMap {
+ case (req, subject) => {
+ val Authoritative(uri: URL, representation: Representation) = req
+ val r: Resource = rm.resource(uri)
+ val res: ValidationResponse = req match {
+ case GET(_) if representation == HTMLRepr => {
+ val source = Source.fromFile("src/main/resources/skin.html")("UTF-8")
+ val body = source.getLines.mkString("\n")
+ val r = Ok ~> ViaSPARQL ~> ContentType("text/html") ~> ResponseString(body)
+ r.success
+ }
+ case GET(_) | HEAD(_) =>
+ for {
+ model <- r.get() failMap { x => NotFound }
+ lang = representation match {
+ case RDFRepr(l) => l
+ case _ => Lang.default
}
- case GET(_) | HEAD(_) =>
- for {
- model <- r.get() failMap { x => NotFound }
- lang = representation match {
- case RDFRepr(l) => l
- case _ => Lang.default
- }
- } yield {
- val res = req match {
- case GET(_) => Ok ~> ViaSPARQL ~> ContentType(lang.contentType) ~> ResponseModel(model, uri, lang)
- case HEAD(_) => Ok ~> ViaSPARQL ~> ContentType(lang.contentType)
- }
- res ~> ContentLocation( uri.toString ) // without this netty (perhaps jetty too?) sends very weird headers, breaking tests
- }
- case PUT(_) & RequestLang(lang) if representation == DirectoryRepr => {
- for {
- bodyModel <- modelFromInputStream(Body.stream(req), uri, lang) failMap { t => BadRequest ~> ResponseString(t.getStackTraceString) }
- _ <- r.createDirectory(bodyModel) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString) }
- } yield Created
+ } yield {
+ val res = req match {
+ case GET(_) => Ok ~> ViaSPARQL ~> ContentType(lang.contentType) ~> ResponseModel(model, uri, lang)
+ case HEAD(_) => Ok ~> ViaSPARQL ~> ContentType(lang.contentType)
}
- case PUT(_) & RequestLang(lang) =>
+ res ~> ContentLocation( uri.toString ) // without this netty (perhaps jetty too?) sends very weird headers, breaking tests
+ }
+ case PUT(_) & RequestLang(lang) if representation == DirectoryRepr => {
+ for {
+ bodyModel <- modelFromInputStream(Body.stream(req), uri, lang) failMap { t => BadRequest ~> ResponseString(t.getStackTraceString) }
+ _ <- r.createDirectory(bodyModel) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString) }
+ } yield Created
+ }
+ case PUT(_) & RequestLang(lang) =>
+ for {
+ bodyModel <- modelFromInputStream(Body.stream(req), uri, lang) failMap { t => BadRequest ~> ResponseString(t.getStackTraceString) }
+ _ <- r.save(bodyModel) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString) }
+ } yield Created
+ case PUT(_) => {
+ val r = BadRequest ~> ResponseString("Content-Type MUST be one of: " + Lang.supportedAsString)
+ r.fail
+ }
+ case POST(_) & RequestContentType(ct) if Post.supportContentTypes contains ct => {
+ Post.parse(Body.stream(req), uri, ct) match {
+ case PostUnknown => {
+ logger.info("Couldn't parse the request")
+ val r = BadRequest ~> ResponseString("You MUST provide valid content for given Content-Type: " + ct)
+ r.success
+ }
+ case PostUpdate(update) => {
+ logger.info("SPARQL UPDATE:\n" + update.toString())
for {
- bodyModel <- modelFromInputStream(Body.stream(req), uri, lang) failMap { t => BadRequest ~> ResponseString(t.getStackTraceString) }
- _ <- r.save(bodyModel) failMap { t => InternalServerError ~> ResponseString(t.getStackTraceString) }
- } yield Created
- case PUT(_) =>
- BadRequest ~> ResponseString("Content-Type MUST be one of: " + Lang.supportedAsString)
- case POST(_) & RequestContentType(ct) if Post.supportContentTypes contains ct => {
- Post.parse(Body.stream(req), uri, ct) match {
- case PostUnknown => {
- logger.info("Couldn't parse the request")
- BadRequest ~> ResponseString("You MUST provide valid content for given Content-Type: " + ct)
- }
- 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 lang = RequestLang(req) getOrElse Lang.default
- 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(lang.contentType) ~> ResponseModel(model, uri, lang)
- }
- case DESCRIBE => {
- val result: Model = qe.execDescribe()
- Ok ~> ContentType(lang.contentType) ~> ResponseModel(model, uri, lang)
- }
- }
+ 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 lang = RequestLang(req) getOrElse Lang.default
+ 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(lang.contentType) ~> ResponseModel(model, uri, lang)
+ }
+ case DESCRIBE => {
+ val result: Model = qe.execDescribe()
+ Ok ~> ContentType(lang.contentType) ~> ResponseModel(model, uri, lang)
}
}
}
}
- case POST(_) =>
- BadRequest ~> ResponseString("Content-Type MUST be one of: " + Post.supportedAsString)
- case _ => MethodNotAllowed ~> Allow("GET", "PUT", "POST")
}
- res
}
+ case POST(_) => {
+ val r = BadRequest ~> ResponseString("Content-Type MUST be one of: " + Post.supportedAsString)
+ r.fail
+ }
+ case _ => {
+ val r = MethodNotAllowed ~> Allow("GET", "PUT", "POST")
+ r.fail
+ }
+ }
+ res
+ }
+ }
+
-}
\ No newline at end of file
+}
--- a/src/main/scala/util/package.scala Sun Nov 13 21:55:08 2011 -0500
+++ b/src/main/scala/util/package.scala Sun Nov 13 22:39:17 2011 -0500
@@ -33,7 +33,7 @@
case t => t.fail
}
- implicit def wrapValidation[E, S](v: Validation[E,S]): ValidationW[E, S] =
+ 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)