Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

RDFa and JSON representations for RESTful semantic resources

  • Loading branch information...
commit a44b5b971b7f2a09ce34b7e61cf7c764cc559b9c 1 parent 713ba6b
@antoniogarrote authored
Showing with 141 additions and 37 deletions.
  1. +1 −0  project.clj
  2. +10 −31 src/plaza/examples/webapp.clj
  3. +130 −6 src/plaza/rest/core.clj
View
1  project.clj
@@ -6,6 +6,7 @@
[com.hp.hpl.jena/arq "2.8.3"]
[net.rootdev/java-rdfa "0.3"]
[compojure "0.4.0-RC3"]
+ [hiccup "0.2.5"]
[ring/ring-jetty-adapter "0.2.0"]
[nu.validator.htmlparser/htmlparser "1.2.0"]
[com.franz/openrdf-sesame-onejar "2.2"]
View
41 src/plaza/examples/webapp.clj
@@ -3,8 +3,8 @@
;; @date 07.06.2010
(ns plaza.examples.webapp
- (:use plaza.rest.core
- plaza.rdf.implementations.jena
+ (:use [plaza.rest.core])
+ (:use plaza.rdf.implementations.jena
compojure.core
compojure.response
ring.adapter.jetty
@@ -36,6 +36,7 @@
(let [pattern (str (:resource-qname-prefix environment) (:resource-qname-local environment))]
(clojure.contrib.str-utils2/replace pattern ":id" (get (:params request) "id")))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Resource functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn make-environment-map [resource-or-symbol path ts opts]
@@ -105,28 +106,6 @@
(= (:request-method request#) :delete) (handle-delete id# request# env#)
:else (handle-method-not-allowed request# env#))))))))
-(def *resource* (make-rdfs-schema "http://test.com/Person"
- :name {:uri "http://test.com/name" :range :string}
- :age {:uri "http://test.com/age" :range :int}))
-
-
-(def *resource-map* (model-to-argument-map *resource*))
-
-(def *resource-type* "http://test.com/Person")
-(def *resource-qname-prefix* "http://test.com/")
-(def *resource-qname-local* "Person")
-(def *id-gen-function* default-uuid-gen)
-(def *resource-ts* :resource)
-
-;;; Handlers
-
-(def *resource-map* (model-to-argument-map *resource*))
-
-(def *resource-type* "http://test.com/Person")
-(def *resource-qname-prefix* "http://test.com/")
-(def *resource-qname-local* "Person")
-(def *id-gen-function* default-uuid-gen)
-(def *resource-ts* :resource)
;;; Handlers
@@ -136,7 +115,7 @@
results (rd (ts (:resource-ts environment)) query)
triples (distinct (flatten-1 results))]
(log :info (str "GET REQUEST -> mapping:" mapping " triples:" triples))
- {:body (render-triples triples (mime-to-format request))
+ {:body (render-triples triples (mime-to-format request) (:resource environment))
:headers {"Content-Type" (format-to-mime request)}
:status 200}))
@@ -152,7 +131,7 @@
(doseq [t query] (log :info t))
(log :info (str "VALUES"))
(doseq [t triples-to-update] (log :info t))
- {:body (render-triples triples (mime-to-format request))
+ {:body (render-triples triples (mime-to-format request) (:resource environment))
:headers {"Content-Type" (format-to-mime request)}
:status 200}))
@@ -160,7 +139,7 @@
(let [mapping (apply-resource-argument-map (:params request) (:resource-map environment))
query (build-single-resource-query-from-resource-map mapping id)
results (in (ts (:resource-ts environment)) query)
- triples (distinct (flatten-1 results))]
+ triples (distinct (flatten-1 results) (:resource environment))]
(log :info (str "DELETE REQUEST -> mapping:" mapping " triples:" triples))
{:body (render-triples triples (mime-to-format request))
:headers {"Content-Type" (format-to-mime request)}
@@ -172,8 +151,8 @@
query (build-query-from-resource-map mapping (:resource-type environment))
results (rd (ts (:resource-ts environment)) query)
triples (distinct (flatten-1 results))]
- (log :info (str "GET REQUEST -> mapping:" mapping " triples:" triples))
- {:body (render-triples triples (mime-to-format request))
+ (log :info (str "GET REQUEST -> mapping:" mapping " triples:" triples))
+ {:body (render-triples triples (mime-to-format request) (:resource environment))
:headers {"Content-Type" (format-to-mime request)}
:status 200}))
@@ -184,7 +163,7 @@
triples (conj triples-pre [resource-id rdf:type (:resource-type environment)])]
(log :info (str "POST REQUEST -> id:" resource-id " mapping:" mapping " triples:" triples))
(out (ts (:resource-ts environment)) triples)
- {:body (render-triples triples :xml)
+ {:body (render-triples triples :xml (:resource environment))
:headers {"Content-Type" "application/xml"}
:status 201}))
@@ -194,7 +173,7 @@
results (in (ts (:resource-ts environment)) query)
triples (distinct (flatten-1 results))]
(log :info (str "GET REQUEST -> mapping:" mapping " query:" query))
- {:body (render-triples triples (mime-to-format request))
+ {:body (render-triples triples (mime-to-format request) (:resource environment))
:headers {"Content-Type" (format-to-mime request)}
:status 200}))
View
136 src/plaza/rest/core.clj
@@ -4,12 +4,14 @@
(ns plaza.rest.core
(:use
+ [hiccup.core]
[plaza.utils]
[plaza.rdf.core]
[plaza.rdf.schemas]
[plaza.rdf.sparql]
[plaza.rdf.predicates]
- [clojure.contrib.logging :only [log]]))
+ [clojure.contrib.logging :only [log]])
+ (:require [clojure.contrib.json :as json]))
(defn resource-argument-map [& mapping]
@@ -56,16 +58,124 @@
(defn build-model-from-resource-map [uri map]
(defmodel (model-add-triples (build-triples-from-resource-map uri map))))
-(defn render-triples [triples format]
- (let [m (defmodel (model-add-triples triples))
- w (java.io.StringWriter.)]
- (output-string m w format)
- (.toString w)))
+(defn to-js3-triples
+ ([ts]
+ (let [tsp (map (fn [[s p o]]
+ (if (is-literal o)
+ [(str s) (str p) {:value (literal-value o) :datatype (literal-datatype-uri o)}]
+ [(str s) (str p) (str o)]))
+ ts)]
+ (json/json-str tsp))))
+
+(defn to-json-triples
+ ([ts schema]
+ (if (empty? ts)
+ (json/json-str [])
+ (let [gts (group-by (fn [[s p o]] (str s)) ts)]
+ (if (= 1 (count (keys gts)))
+ (let [tsp (reduce (fn [acum [s p o]]
+ (if (is-literal o)
+ (let [pred (property-alias schema (str p))
+ value (literal-value o)]
+ (if (nil? pred) acum
+ (assoc acum pred value)))
+ (let [pred (property-alias schema (str p))]
+ (if (nil? pred) acum
+ (assoc acum pred (str o))))))
+ {} (first (vals gts)))]
+ (json/json-str (assoc tsp :uri (str (first (keys gts))))))
+ (json/json-str (map (fn [[s tss]]
+ (let [jsts (reduce (fn [acum [s p o]]
+ (if (is-literal o)
+ (let [pred (property-alias schema (str p))
+ value (literal-value o)]
+ (if (nil? pred) acum
+ (assoc acum pred value)))
+ (let [pred (property-alias schema (str p))]
+ (if (nil? pred) acum
+ (assoc acum pred (str o))))))
+ {} tss)]
+ (assoc jsts :uri (str s))))
+ gts)))))))
+
+(defn extract-ns [uri]
+ (if (empty? (filter #(= \# %1) uri))
+ (str (clojure.contrib.string/join "/" (drop-last (clojure.contrib.string/split #"/" uri))) "/")
+ (str (first (clojure.contrib.string/split #"#" uri)) "#")))
+
+(defn add-ns
+ [[mapping counter] ns]
+ (if (empty? (filter #(= ns %1) (keys mapping)))
+ [(assoc mapping ns (str "ns" counter)) (inc counter)]
+ [mapping counter]))
+
+(defn collect-ns [ts]
+ (first (reduce (fn [[acum c] [s p o]]
+ (if (is-literal o)
+ (let [nss (extract-ns (str s))
+ nsp (extract-ns (str p))]
+ (-> [acum c]
+ (add-ns nss)
+ (add-ns nsp)))
+ (let [nss (extract-ns (str s))
+ nsp (extract-ns (str p))
+ nso (extract-ns (str o))]
+ (-> [acum c]
+ (add-ns nss)
+ (add-ns nsp)
+ (add-ns nso)))))
+ [{} 0] ts)))
+
+(defn build-curie [nsmap uri]
+ (let [prefix (first (filter #(= 2 (alength (.split uri %1))) (keys nsmap)))
+ val (get nsmap prefix)
+ local (aget (.split uri prefix) 1)]
+ (str val ":" local)))
+
+(defn to-rdfa-triple
+ ([s ts schema nsmap]
+ [:div {:about (str s)} [:a {:href (str s)} (str s)]
+ [:ul (map (fn [[s p o]]
+ [:li (if (is-literal o)
+ [:span (str (keyword-to-string (property-alias schema (str p))) ": ")
+ [:span {:property (build-curie nsmap (str p)) :datatype (literal-datatype-uri o)} (literal-value o)]]
+ [:span (str (keyword-to-string (property-alias schema (str p))) ": ")
+ [:a {:href (str o) :rel (build-curie nsmap (str p))} (str o)]])]) ts)]]))
+
+(defn ns-list [nsmap]
+ (reduce (fn [acum [k v]] (if (= k "/") acum (assoc acum (str "xmlns:" v) k))) {} nsmap))
+
+(defn to-rdfa-triples
+ ([ts schema]
+ (let [nsmap (collect-ns ts)
+ gts (group-by (fn [[s p o]] (str s)) ts)
+ rdfa-ts (map (fn [[s tsp]] (to-rdfa-triple s tsp schema nsmap)) gts)
+ nslistp (assoc (ns-list nsmap) :xmlns "http://www.w3.org/1999/xhtml")
+ nslistpp (assoc nslistp :version "XHTML+RDFa 1.0")]
+ (html [:html nslistpp
+ [:head [:title ""]]
+ [:body
+ rdfa-ts]]))))
+
+(defn render-triples [triples format schema]
+ (if (or (= format :json) (= format :js3) (= format :js))
+ (if (or (= format :json) (= format :js))
+ (to-json-triples triples schema)
+ (to-js3-triples triples))
+ (if (or (= format :html) (= format :xhtml) (= format :rdfa))
+ (to-rdfa-triples triples schema)
+ (let [m (defmodel (model-add-triples triples))
+ w (java.io.StringWriter.)]
+ (output-string m w format)
+ (.toString w)))))
+
(defn supported-format [format]
(condp = format
"application/xml" :xml
"text/rdf+n3" :n3
"application/x-turtle" :turtle
+ "text/html" :rdfa
+ "application/xhtml+xml" :rdfa
"*/*" :xml
nil))
@@ -92,6 +202,14 @@
"ttl" :ttl
"application/x-turtle" :turtle
"turtle" :turtle
+ "json" :json
+ "js" :json
+ "js3" :js3
+ "xhtml" :rdfa
+ "html" :rdfa
+ "text/html" :rdfa
+ "application/xhtml+xml" :rdfa
+ "rdfa" :rdfa
:xml)))
(defn format-to-mime [request]
@@ -105,6 +223,12 @@
"n3" "text/rdf+n3"
"ttl" "application/x-turtle"
"turtle" "application/x-turtle"
+ "json" "application/json"
+ "js" "application/json"
+ "js3" "application/json"
+ "rdfa" "application/html+xml"
+ "html" "text/html"
+ "xhtml" "application/html+xml"
"application/xml")))
(defn default-uuid-gen [prefix local request]
Please sign in to comment.
Something went wrong with that request. Please try again.