+ hacked a Scalatra-based servlet for the RDFValidator. It's a thin layer on top of FeDeRate/RDFXML
--- a/project/build/Project.scala Thu Dec 02 16:51:59 2010 -0500
+++ b/project/build/Project.scala Thu Dec 02 16:53:45 2010 -0500
@@ -1,15 +1,13 @@
import sbt._
-trait Common extends BasicScalaProject {
- val scalatools = "scala-tools" at "http://scala-tools.org/repo-snapshots"
- val scalatest = "org.scalatest" % "scalatest" % "1.2-for-scala-2.8.0.final-SNAPSHOT" % "test"
-}
-
class RDFValidator(info: ProjectInfo) extends DefaultWebProject(info) {
override def compileOptions = super.compileOptions ++ Seq(Unchecked, Deprecation, ExplainTypes)
override def defaultExcludes = super.defaultExcludes || "*~"
+ // val scalatools = "scala-tools" at "http://scala-tools.org/repo-snapshots"
+ // val scalatest = "org.scalatest" % "scalatest" % "1.2-for-scala-2.8.0.final-SNAPSHOT" % "test"
+
val jettyConf = config("jetty")
val jettyDep = "org.eclipse.jetty" % "jetty-webapp" % "7.0.2.v20100331" % "compile,jetty"
override def jettyClasspath = managedClasspath(jettyConf)
@@ -18,4 +16,27 @@
val jena = "com.hp.hpl.jena" % "jena" % "2.6.3"
val jenaIri = "com.hp.hpl.jena" % "iri" % "0.8" from "http://openjena.org/repo/com/hp/hpl/jena/iri/0.8/iri-0.8.jar"
+ val scalatraVersion = "2.0.0-SNAPSHOT"
+ val scalatra = "org.scalatra" %% "scalatra" % scalatraVersion
+ val scalate = "org.scalatra" %% "scalatra-scalate" % scalatraVersion
+ val servletApi = "org.mortbay.jetty" % "servlet-api" % "2.5-20081211" % "provided"
+
+ val scalatest = "org.scalatra" %% "scalatra-scalatest" % scalatraVersion % "test"
+ val slf4jBinding = "ch.qos.logback" % "logback-classic" % "0.9.26" % "runtime"
+
+ // http://groups.google.com/group/simple-build-tool/msg/1f17b43807d06cda
+ override def testClasspath = super.testClasspath +++ buildCompilerJar
+
+ val sonatypeNexusSnapshots = "Sonatype Nexus Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
+ // For Scalate
+ val fuseSourceSnapshots = "FuseSource Snapshot Repository" at "http://repo.fusesource.com/nexus/content/repositories/snapshots"
+
+// val turtle = "w3c" %% "turtle" % "1.0"
+ val rdfxml = "w3c" %% "rdfxml" % "1.0" intransitive()
+ val rdf = "w3c" %% "rdf" % "1.0" intransitive()
+
+ val databinder_net = "databinder.net repository" at "http://databinder.net/repo"
+ val dispatch = "net.databinder" %% "dispatch-http" % "0.7.7"
+
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/scala/RDFValidator.scala Thu Dec 02 16:53:45 2010 -0500
@@ -0,0 +1,129 @@
+package org.w3.rdfvalidator
+
+import org.scalatra._
+import java.net.URL
+import javax.servlet.http._
+
+import dispatch._
+import Http._
+import scala.xml.{NodeSeq, Comment, Elem}
+
+import org.w3.sw.rdf._
+import org.w3.sw.rdfxml._
+
+object RDFValidator {
+ val rdfxmlParser = new org.w3.sw.rdfxml.RDFXML
+
+ def toString(t:Triple):Elem = <li><span>{ toString(t.s) }</span> <span>{ toString(t.p) }</span> <span>{ toString(t.o) }</span></li>
+ def toString(s:Subject):String = {
+ val SubjectNode(n) = s
+ toString(n)
+ }
+ def toString(p:Predicate):String = {
+ val PredicateIRI(iri) = p
+ toString(iri)
+ }
+ def toString(iri:IRI):String = {
+ val IRI(i) = iri
+ "<"+i+">"
+ }
+ def toString(bnode:BNode):String = {
+ val BNode(label) = bnode
+ "_:"+label
+ }
+ def toString(n:Node):String = {
+ n match {
+ case NodeIRI(iri) => toString(iri)
+ case NodeBNode(bnode) => toString(bnode)
+ }
+ }
+ def toString(o:Object):String = o match {
+ case ObjectNode(n) => toString(n)
+ case ObjectLiteral(l) => toString(l)
+ }
+ def toString(l:Literal):String = l match {
+ case PlainLiteral(lexicalForm, langtag) => "\"" + lexicalForm + "\"" + { if (langtag.isDefined) ("@"+langtag.get) else "" }
+ case TypedLiteral(lexicalForm, datatype) => "\"" + lexicalForm + "\"^^" + toString(datatype)
+ }
+
+ def message(title:String, description:String):NodeSeq =
+ <message type="info">
+ <title>{ title }</title>
+ <description>{ description }</description>
+ </message>
+
+ def renderMessage(graph:Graph) =
+ if (graph.nonEmpty)
+ <message type="info">
+ <title>Parsed triples</title>
+ <description>{ <ol>{ graph map { toString(_) } }</ol> }</description>
+ </message>
+ else
+ Comment(" no parsed triple ")
+
+ def renderMessage(e:ParseError) = {
+ val title = e.errorType match {
+ case RDFParseError => "RDF issue"
+ case XMLParseError => "XML issue"
+ }
+ val errorType = e.level match {
+ case Warning => "warning"
+ case FatalError | Error => "error"
+ }
+ <message type={ errorType }>
+ <title>{ title }</title>
+ <description>{ e.message }</description>
+ </message>
+ }
+
+}
+
+
+
+class RDFValidator extends ScalatraServlet {
+
+ import RDFValidator._
+
+ get("/*", request.getParameter("uri") != null) {
+ contentType = "text/xml"
+ val uri = request.getParameter("uri")
+ val http = new Http
+ try {
+ http(uri >> { in => {
+ val (graph, parseErrors) = rdfxmlParser.toGraph(in)
+ val statusValue =
+ if (parseErrors exists { e => e.level == FatalError || e.level == Error })
+ "failed"
+ else
+ "passed"
+ <observationresponse xmlns="http://www.w3.org/2009/10/unicorn/observationresponse" xml:lang="en" ref={ uri }>
+ <status value={ statusValue }/>
+ { renderMessage(graph) }
+ { parseErrors map { renderMessage(_) } }
+ </observationresponse>
+ }})
+ } catch {
+ case StatusCode(code, contents) => {
+ <observationresponse xmlns="http://www.w3.org/2009/10/unicorn/observationresponse" xml:lang="en" ref={ uri }>
+ <status value="failed"/>
+ { message("HTTP "+code, contents) }
+ </observationresponse>
+ }
+ case e:Exception => {
+ e.printStackTrace
+ <observationresponse xmlns="http://www.w3.org/2009/10/unicorn/observationresponse" xml:lang="en" ref={ uri }>
+ <status value="failed"/>
+ <message type="info">
+ <title>Something wrong happened</title>
+ <description>{ e.getMessage }</description>
+ </message>
+ </observationresponse>
+ }
+ }
+ }
+
+ notFound {
+ "notFound"
+ }
+
+}
--- a/src/main/webapp/WEB-INF/web.xml Thu Dec 02 16:51:59 2010 -0500
+++ b/src/main/webapp/WEB-INF/web.xml Thu Dec 02 16:53:45 2010 -0500
@@ -5,34 +5,24 @@
This is the friggin' RDF Validator
</description>
+ <!-- <filter> -->
+ <!-- <filter-name>rdfvalidator</filter-name> -->
+ <!-- <filter-class>org.w3.rdfvalidator.RDFValidator</filter-class> -->
+ <!-- </filter> -->
+
+ <!-- <filter-mapping> -->
+ <!-- <filter-name>rdfvalidator</filter-name> -->
+ <!-- <url-pattern>/*</url-pattern> -->
+ <!-- </filter-mapping> -->
+
<servlet>
- <servlet-name>RDFValidatorServlet</servlet-name>
- <servlet-class>org.w3c.rdfvalidator.ARPServlet</servlet-class>
- <init-param>
- <param-name>SERVLET_TMP_DIR</param-name>
- <param-value>RDFValidator/ARPServlet.tmp</param-value>
- </init-param>
- <init-param>
- <param-name>BITMAPPED_FONT</param-name>
- <param-value>cyberbit</param-value> <!-- might try cyberbit, ariel, arialuni -->
- </init-param>
- <init-param>
- <param-name>VECTOR_FONT</param-name>
- <param-value>Courier</param-value> <!-- might try Courier, arialuni -->
- </init-param>
- <init-param>
- <param-name>RENDER_DOT</param-name>
- <param-value>RDFValidator/renderDot</param-value>
- </init-param>
- <init-param>
- <param-name>LOG_A_LOT</param-name>
- <param-value>1</param-value>
- </init-param>
+ <servlet-name>rdfvalidator</servlet-name>
+ <servlet-class>org.w3.rdfvalidator.RDFValidator</servlet-class>
</servlet>
<servlet-mapping>
- <servlet-name>RDFValidatorServlet</servlet-name>
- <url-pattern>/rdfval</url-pattern>
+ <servlet-name>rdfvalidator</servlet-name>
+ <url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/RDFValidatorTest.scala Thu Dec 02 16:53:45 2010 -0500
@@ -0,0 +1,30 @@
+package org.w3.rdfvalidator
+
+import org.scalatra.test.scalatest._
+import org.scalatest.matchers._
+
+class RDFValidatorTest extends ScalatraFunSuite with ShouldMatchers {
+
+ addServlet(classOf[RDFValidator], "/*")
+
+ def validate(uri:String, expectedUnicornStatus:String, contains:String) =
+ test(uri) {
+ get("/rdfvalidator?uri="+uri) {
+ status should equal (200)
+ val unicornStatus = (scala.xml.XML.loadString(body) \ "status" \ "@value").head.asInstanceOf[scala.xml.Text].toString
+ unicornStatus should equal (expectedUnicornStatus)
+ body should include (contains)
+ }
+ }
+
+ def failed(uri:String, contains:String) =
+ validate(uri, "failed", contains)
+
+ def passed(uri:String, contains:String) =
+ validate(uri, "passed", contains)
+
+ failed("http://www.w3.org/2000/10/rdf-tests/rdfcore/rdf-containers-syntax-vs-schema/error001.rdf", "E206")
+ failed("http://www.w3.org/2000/10/rdf-tests/rdfcore/rdf-containers-syntax-vs-schema/error002.rdf", "E204")
+ passed("http://www.w3.org/People/Berners-Lee/card.rdf", "")
+
+}