Skip to content

Commit 5dffbe9

Browse files
committed
Merge branch 'feature/quad-transformations'
2 parents 82c6493 + 9d55530 commit 5dffbe9

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed

packages.lisp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@
9898
#:make-match-up-to-scanned-token
9999
#:make-token-match
100100
#:make-string-literal
101-
#:make-rdfliteral))
101+
#:make-rdfliteral
102+
#:string-literal-string))
102103

103104
(defpackage #:type-cache
104105
(:use :common-lisp)

sparql-ast/manipulation.lisp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,15 @@ Assumes URI-STRING is wrapped."
9090
:string string
9191
:token term)))
9292

93-
(defun make-rdfliteral (string)
93+
(defun make-rdfliteral (string &key datatype-match)
9494
"This constructs an ebnf::|RDFLiteral| from STRING.
9595
9696
Currently supports only string, but could be extended with datatype and lang keywords when necessary."
9797
(handle-update-unit::make-nested-match
98-
`(ebnf::|RDFLiteral| ,(make-string-literal string))))
98+
`(ebnf::|RDFLiteral|
99+
,(make-string-literal string)
100+
,@(and datatype-match
101+
(list "^^" datatype-match)))))
99102

100103
(defun make-string-literal (string)
101104
"Constructs a string literal for string, escaping as necessary."
@@ -104,6 +107,31 @@ Currently supports only string, but could be extended with datatype and lang key
104107
,(make-token-match 'ebnf::|STRING_LITERAL_LONG2|
105108
(sparql-escape-string string)))))
106109

110+
(defun string-literal-string (ebnf-string)
111+
"Gets the original string for an 'ebnf::|String|, unescaping as necessary.
112+
113+
Escapes quoting but not special characters such as \\t and \\n."
114+
(let* ((specific-match (first (match-submatches ebnf-string)))
115+
(term (sparql-parser:match-term specific-match))
116+
(string (sparql-parser:terminal-match-string specific-match)))
117+
(case term
118+
(ebnf::|STRING_LITERAL_LONG1|
119+
(cl-ppcre:regex-replace-all "\\\\(['\\\\])"
120+
(subseq string 3 (- (length string) 3))
121+
"\\1"))
122+
(ebnf::|STRING_LITERAL_LONG2|
123+
(cl-ppcre:regex-replace-all "\\\\([\"\\\\])"
124+
(subseq string 3 (- (length string) 3))
125+
"\\1"))
126+
(ebnf::|STRING_LITERAL1|
127+
(cl-ppcre:regex-replace-all "\\\\([\'\\\\])"
128+
(subseq string 1 (1- (length string)))
129+
"\\1"))
130+
(ebnf::|STRING_LITERAL2|
131+
(cl-ppcre:regex-replace-all "\\\\([\"\\\\])"
132+
(subseq string 1 (1- (length string)))
133+
"\\1")))))
134+
107135
(defun make-word-match (string)
108136
"Constructs a match for fixed content in the EBNF.
109137

test/scenario.lisp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@
118118
:ext "http://mu.semte.ch/vocabularies/ext/"
119119
:schema "http://schema.org/"
120120
:books "http://example.com/books/"
121-
:favorites "http://mu.semte.ch/favorites/")
121+
:favorites "http://mu.semte.ch/favorites/"
122+
:geo "http://www.opengis.net/ont/geosparql#")
122123

123124
(acl:supply-allowed-group "public")
124125

@@ -142,7 +143,8 @@
142143

143144
(acl:define-graph acl::public-data ("http://mu.semte.ch/graphs/public")
144145
("foaf:Person" acl::-> acl::_)
145-
("schema:Book" acl::-> acl::_))
146+
("schema:Book" acl::-> acl::_)
147+
("geo:Geometry" acl::-> acl::_))
146148
(acl:define-graph acl::user-data ("http://mu.semte.ch/graphs/personal/")
147149
(acl::_
148150
acl::-> "ext:hasBook"
@@ -364,6 +366,32 @@
364366
}"))
365367

366368
(with-impersonation-for :joll
369+
(quad-transformations:define-quad-transformation (quad method)
370+
;; fix wktLiteral string representation
371+
(let* ((object (quad:object quad))
372+
(datatype-match (and
373+
(sparql-parser:match-p object)
374+
(eq (sparql-parser:match-term object) 'ebnf::|RDFLiteral|)
375+
(= 3 (length (sparql-parser:match-submatches object)))
376+
(third (sparql-parser:match-submatches object))))
377+
(datatype-uri (and datatype-match
378+
(detect-quads::quad-term-uri
379+
(first
380+
(sparql-parser:match-submatches datatype-match)))))
381+
(string-value (and (sparql-parser:match-p object)
382+
(eq (sparql-parser:match-term object) 'ebnf::|RDFLiteral|)
383+
(sparql-manipulation:string-literal-string
384+
(first (sparql-parser:match-submatches object))))))
385+
(if (and datatype-uri
386+
(string= "http://www.opengis.net/ont/geosparql#wktLiteral" datatype-uri)
387+
(search "https://www.opengis.net/" string-value))
388+
(let ((new-quad (quad:copy quad))
389+
(new-string (cl-ppcre:regex-replace "https://" string-value "http://")))
390+
(setf (quad:object new-quad)
391+
(sparql-manipulation:make-rdfliteral new-string :datatype-match datatype-match))
392+
(quad-transformations:update new-quad))
393+
(quad-transformations:keep))))
394+
367395
(format t "~&Joll can write a book title with the right URI and no type.~%")
368396

369397
(server:execute-query-for-context
@@ -462,7 +490,19 @@
462490
(server:execute-query-for-context
463491
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
464492
PREFIX mu: <http://mu.semte.ch/vocabularies/core/>
465-
INSERT DATA { <http://book-store.example.com/books/my-book> mu:uuid \"123\"^^xsd:string. }"))
493+
INSERT DATA { <http://book-store.example.com/books/my-book> mu:uuid \"123\"^^xsd:string. }")
494+
495+
(server:execute-query-for-context
496+
"PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
497+
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
498+
PREFIX mu: <http://mu.semte.ch/vocabularies/core/>
499+
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
500+
INSERT DATA {
501+
<http://book-store.example.com/geometries/a>
502+
a geo:Geometry;
503+
geo:asWKT \"<https://www.opengis.net/def/crs/EPSG/0/31370> POINT (155822.2 132723.18)\"^^<http://www.opengis.net/ont/geosparql#wktLiteral>.
504+
}"))
505+
466506
(with-impersonation-for :jack
467507
;; can insert some random content
468508
(server:execute-query-for-context
@@ -499,5 +539,4 @@
499539
"PREFIX ext: <http://mu.semte.ch/vocabularies/ext/>
500540
INSERT DATA {
501541
ext:myDisplay ext:anotherThing \"Another thing\".
502-
}")
503-
)))
542+
}"))))

updates/quad-transformations.lisp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
(loop for function in *user-quad-transform-functions*
1414
do
1515
(setf current-quads
16-
(loop for quad in quads
16+
(loop for quad in current-quads
1717
for (new-quads changedp)
1818
= (multiple-value-list (funcall function quad :method method))
1919
when changedp
2020
do (setf any-quads-changed-p t)
2121
if changedp
2222
append new-quads
2323
else
24-
append quads)))
24+
append (list quad))))
2525
(values current-quads any-quads-changed-p))
2626
(values quads nil)))
2727

0 commit comments

Comments
 (0)