function.datashape2.report.rq Maven / Gradle / Ivy
#
# SHACL Interpreter
#
# Olivier Corby - Wimmics Inria I3S - 2016-2020
#
prefix sh:
prefix xsh:
prefix shex:
#
# suc is success/failure of the shape
# vis true means generate a ValidationResult
#
function xsd:boolean sh:report(report, name, sh, s, suc, vis){
sh:report(report, sh:null, name, sh, sh:null, s, sh:null, sh:null, suc, vis)
}
function xsd:boolean sh:report(report, name, sh, s, p, o, suc, vis){
sh:report(report, sh:null, name, sh, sh:null, s, p, o, suc, vis)
}
function xsd:boolean sh:report(report, name, sh, cst, s, p, o, suc, vis){
sh:report(report, sh:null, name, sh, cst, s, p, o, suc, vis)
}
function xsd:boolean sh:report(report, subReport, name, sh, cst, s, p, o, suc, vis){
sh:record(name, sh, cst, sh:shaclGraph(), s, p, o, suc, vis);
if (vis && ! suc) {
sh:visit(name, s, suc) ;
return (sh:result(report, subReport, name, sh, cst, sh:shaclGraph(), s, p, o)) ;
} ;
return(true)
}
#
# create validation result in report graph
# sh: the shape
# cst: the constraint in case of sh:node
# foc: focus node
# node: value with problem
#
function xsd:boolean sh:result(report, subReport, name, sh, cst, dt:graph shape, foc, path, node){
let (res = uuid(),
def = coalesce(sh:isdefby(name), name),
sev = coalesce(xt:value(shape, sh, sh:severity), sh:Violation),
mes = sh:getTheMessage(shape, sh, cst, foc, node),
mesfun = sh:messageFunction(shape, sh, cst, foc, node),
abnode = sh:bnodeid()) {
sh:store(report, abnode, rdf:type, sh:ValidationReport);
sh:store(report, abnode, sh:conforms, false);
if (report = sh:validationReport()) {
sh:store(report, abnode, sh:result, res);
sh:store(report, res, rdf:type, sh:ValidationResult)
}
else {
sh:store(report, res, rdf:type, sh:AbstractResult)
} ;
sh:store(report, res, sh:resultSeverity, sev);
sh:store(report, res, sh:focusNode, foc);
sh:store(report, res, sh:resultMessage, mes) ;
if (coalesce(mesfun = "", false), true,
sh:store(report, res, sh:resultMessage2, mesfun)) ;
sh:store(report, res, sh:sourceConstraintComponent, def) ;
sh:store(report, res, sh:sourceShape, sh) ;
if (sh:isValue(path)) {
sh:store(report, res, sh:resultPath, sh:prettyNodeOrList(shape, path))
} ;
if (sh:isValue(node)) {
sh:store(report, res, sh:value, node)
} ;
if (isBlank(node)) {
sh:store(report, res, sh:valueDetail, sh:graphdt(shape, node))
} ;
if (isBlank(foc) && ! sh:isFast()) {
sh:store(report, res, sh:focusNodeDetail, sh:graphdt(shape, foc))
};
if (isBlank(sh)) {
#sh:document(sh);
coalesce(sh:store(report, res, sh:sourceShapeDetail, sh:getDefinition(sh)), true)
};
sh:resultFunction(report, subReport, res, sh, name, foc, path, node);
return (res)
} ;
#return (true)
}
#
# Additional report
#
function sh:record(name, sh, cst, dt:graph shape, foc, p, o, xsd:boolean suc, xsd:boolean vis) {
if (vis) {
sh:userreport(name, sh, cst, shape, foc, p, o, suc);
let (amap = sh:getrecordmap(name, suc)) {
xt:set(amap, sh, coalesce(xt:get(amap, sh), 0) + 1) ;
xt:set(amap, sh:subtotal, coalesce(xt:get(amap, sh:subtotal), 0) + 1)
} ;
let (bmap = sh:getrecordmap(sh:total, suc)) {
xt:set(bmap, sh:total, coalesce(xt:get(bmap, sh:total), 0) + 1)
}
} ;
return(true)
}
function sh:userreport(name, sh, cst, dt:graph shape, foc, p, o, xsd:boolean suc) {
if (sh:hasSetup(sh:callback),
funcall(sh:setup(sh:callback), shape, sh, cst, name, foc, p, o, suc),
true)
}
function sh:tracerecord(shape, mapmap) {
for ((key val) in mapmap) {
if (key != sh:def) {
xt:print(key);
for ((sh value) in val) {
xt:print(sh, ":", value) ;
if (isBlank(sh)) {
xt:print(xt:turtle(shape, sh))
}
} ;
xt:print("__")
}
} ;
return (true)
}
# finish
function xsd:boolean sh:success(xsd:boolean bb) {
if (bb) {
let (g =
construct { [] a sh:ValidationReport ; sh:conforms true }
where { }
) {
sh:insert(g, sh:validationReport())
}
} ;
return (true)
}
# insert report element g into report
function sh:insert(dt:graph g, dt:graph report) {
for ((s p o) in g) {
xt:insert(report, s, p, o)
}
}
function sh:store(gg, sub, pred, obj) {
xt:insert(gg, sub, pred, obj)
}
function sh:insert(gg, sub, pred, obj) {
xt:insert(gg, sub, pred, obj)
}
function sh:delete(gg, sub, pred, obj) {
xt:delete(gg, sub, pred, obj)
}
function sh:myvalidationReport() {
coalesce(tripleList, set(tripleList = xt:list()))
}
function sh:getTheMessage(shape, sh, cst, node, value) {
sh:basicMessage(shape, sh, cst)
}
#
# when shape sh has xsh:messageFunction[ us:mess(param) ]
# return funcall(us:mess, sh, node, value, param)
# use case: return contextual object in the neighborhood of node
#
function sh:messageFunction(shape, sh, cst, node, value) {
let (mf = sh:getMessageExtension(sh)) {
for ((oper name param) in mf) {
let (res = funcall(name, sh, node, value, param)) {
return (res)
}
}
} ;
return ("")
}
function sh:resultFunction(report, subReport, res, sh, oper, node, path, value) {
let (rf = sh:getResultExtension(sh)) {
if (xt:size(rf) = 0) {
set (rf = sh:getResultExtensionGlobal(sh)) ;
if (xt:size(rf) = 0 && sh:isValue(subReport)) {
# there is no resultFunction and there is a subReport: default is merge
sh:merge(report, subReport, res) ;
return (res)
}
} ;
for ((fun name param) in rf) {
funcall(name, report, subReport, res, sh, oper, node, path, value, param)
}
} ;
return (res)
}
function sh:resultFunction2(report, subReport, res, sh, oper, node, path, value) {
let (rf = sh:getResultExtension(sh)) {
for ((fun name param) in rf) {
funcall(name, report, subReport, res, sh, oper, node, path, value, param)
} ;
if (xt:size(rf) = 0 && sh:isValue(subReport)) {
# there is no resultFunction but there is a subReport: default is merge
sh:merge(report, subReport, res)
}
}
}
# ((xsh:messageFunction name param))
function sh:getMessageExtension(sh) {
sh:getShapeConstraint(sh:messageExtension, sh)
}
# ((xsh:messageFunction name param))
# sh:getFunctionExtension in constraint.rq
function sh:messageExtension(shape, sh) {
sh:getFunctionExtension(shape, sh)
}
function sh:getResultExtension(sh) {
sh:getShapeConstraint(sh:resultExtension, sh)
}
# ((xsh:resultFunction name param))
function sh:resultExtension(shape, sh) {
sh:getResultExtension(shape, sh)
}
function sh:getResultExtensionGlobal(sh) {
sh:getShapeConstraint(sh:resultExtensionGlobal, sh:resultExtensionGlobal)
}
# ((xsh:resultFunction name param))
function sh:resultExtensionGlobal(shape, sh) {
sh:getResultExtensionGlobal(shape, sh)
}
function sh:basicMessage(shape, sh, cst) {
coalesce (sh:getMessage(shape, sh, cst),
concat("Fail at: ", sh:createMessage(shape, sh, cst)))
}
function sh:createMessage(shape, sh, cst) {
if (sh:isValue(cst),
xt:turtle(shape, cst),
xt:turtle(shape, sh)
)
}
function sh:getMessage(shape, sh, cst) {
if (sh:isValue(cst),
coalesce(xt:value(shape, cst, sh:message), xt:value(shape, sh, sh:message)),
xt:value(shape, sh, sh:message)
)
}
function sh:tracefinish() {
xt:print(xt:turtle(sh:validationReport()))
}
# when suc = false, declare error on node (for future pprint)
function sh:visit(name, node, suc) {
st:visit(name, node, suc)
}
# within graph shape {}
function dt:uri sh:severity(sh) {
coalesce(xt:value(sh, sh:severity), sh:Violation)
}
function sh:message(sh){
xt:value(sh, sh:message)
}
function sh:bnodeid(){
return(bnodeid)
}
function sh:detailReport(report, detail) {
if (detail, xt:create(dt:graph), report)
}
#
# Generate a validation result and join sub reports if any with sh:detail property
# sub reports are stored in subReport graph
#
function sh:reportDetail(report, subReport, oper, sh, s, p, o, suc, vis, detail) {
sh:reportDetail(report, subReport, oper, sh, sh:null, s, p, o, suc, vis, detail)
}
function sh:reportDetail(report, subReport, oper, sh, cst, s, p, o, suc, vis, detail) {
sh:report(report, if (detail && xt:size(subReport) > 0, subReport, sh:null),
oper, sh, cst, s, p, o, suc, vis)
}
#
# url: url of current validation result
# subReport : validation report of substatement (node, boolean)
# merge subReport in current report and
# for each id in subReport, add triple: url sh:detail id
# TODO: delete sh:result triples from subReport
#
function sh:merge(report, subReport, url) {
if (sh:isValue(subReport)) {
letdyn (list = sh:collecturl(subReport), res = url, myreport = report) {
xt:merge(report, subReport) ;
map (function(id) { sh:store(myreport, res, sh:detail, id) }, list)
}
}
}
# return list of url of validation results
function sh:collecturl(report) {
let (select ?report (aggregate(?url) as ?list) where { graph ?report { ?url a sh:AbstractResult } }) {
return (list)
}
}
function sr:skipDetail(report, detail, url, shape, oper, s, p, o, exp) {
}
function sr:mergeDetail(report, detail, url, shape, oper, s, p, o, exp) {
sh:merge(report, detail, url)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy