@ulb-darmstadt/shacl-form 1.7.1 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/form-bootstrap.js +1 -1
- package/dist/form-default.js +1 -1
- package/dist/form-material.js +1 -1
- package/dist/form.d.ts +3 -3
- package/dist/plugins/leaflet.js +1 -1
- package/dist/plugins/mapbox.js +1 -1
- package/dist/property-template.d.ts +1 -0
- package/package.json +1 -1
- package/src/form.ts +6 -2
- package/src/property-template.ts +7 -0
- package/src/property.ts +17 -0
- package/src/util.ts +23 -13
|
@@ -31,6 +31,7 @@ export declare class ShaclPropertyTemplate {
|
|
|
31
31
|
languageIn: Term[] | undefined;
|
|
32
32
|
datatype: NamedNode | undefined;
|
|
33
33
|
hasValue: Term | undefined;
|
|
34
|
+
qualifiedValueShape: Term | undefined;
|
|
34
35
|
owlImports: NamedNode[];
|
|
35
36
|
config: Config;
|
|
36
37
|
extendedShapes: NamedNode[] | undefined;
|
package/package.json
CHANGED
package/src/form.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ShaclNode } from './node'
|
|
2
2
|
import { Config } from './config'
|
|
3
3
|
import { ClassInstanceProvider, Plugin, listPlugins, registerPlugin } from './plugin'
|
|
4
|
-
import { Store, NamedNode, DataFactory } from 'n3'
|
|
5
|
-
import { DCTERMS_PREDICATE_CONFORMS_TO, RDF_PREDICATE_TYPE, SHACL_OBJECT_NODE_SHAPE, SHACL_PREDICATE_TARGET_CLASS } from './constants'
|
|
4
|
+
import { Store, NamedNode, DataFactory, Quad } from 'n3'
|
|
5
|
+
import { DCTERMS_PREDICATE_CONFORMS_TO, PREFIX_SHACL, RDF_PREDICATE_TYPE, SHACL_OBJECT_NODE_SHAPE, SHACL_PREDICATE_TARGET_CLASS } from './constants'
|
|
6
6
|
import { Editor, Theme } from './theme'
|
|
7
7
|
import { serialize } from './serialize'
|
|
8
8
|
import { Validator } from 'shacl-engine'
|
|
@@ -156,6 +156,10 @@ export class ShaclForm extends HTMLElement {
|
|
|
156
156
|
|
|
157
157
|
this.config.shapesGraph.deleteGraph('')
|
|
158
158
|
this.shape?.toRDF(this.config.shapesGraph)
|
|
159
|
+
if (this.shape) {
|
|
160
|
+
// add node target for validation. this is required in case of missing sh:targetClass in root shape
|
|
161
|
+
this.config.shapesGraph.add(new Quad(this.shape.shaclSubject, DataFactory.namedNode(PREFIX_SHACL + 'targetNode'), this.shape.nodeId, undefined))
|
|
162
|
+
}
|
|
159
163
|
try {
|
|
160
164
|
const dataset = this.config.shapesGraph
|
|
161
165
|
const report = await new Validator(dataset, { details: true, factory: DataFactory }).validate({ dataset })
|
package/src/property-template.ts
CHANGED
|
@@ -31,6 +31,9 @@ const mappers: Record<string, (template: ShaclPropertyTemplate, term: Term) => v
|
|
|
31
31
|
[`${PREFIX_SHACL}languageIn`]: (template, term) => { template.languageIn = template.config.lists[term.value]; template.datatype = DataFactory.namedNode(PREFIX_RDF + 'langString') },
|
|
32
32
|
[`${PREFIX_SHACL}defaultValue`]: (template, term) => { template.defaultValue = term },
|
|
33
33
|
[`${PREFIX_SHACL}hasValue`]: (template, term) => { template.hasValue = term },
|
|
34
|
+
[`${PREFIX_SHACL}qualifiedValueShape`]: (template, term) => { template.qualifiedValueShape = term },
|
|
35
|
+
[`${PREFIX_SHACL}qualifiedMinCount`]: (template, term) => { template.minCount = parseInt(term.value) },
|
|
36
|
+
[`${PREFIX_SHACL}qualifiedMaxCount`]: (template, term) => { template.maxCount = parseInt(term.value) },
|
|
34
37
|
[OWL_PREDICATE_IMPORTS.id]: (template, term) => { template.owlImports.push(term as NamedNode) },
|
|
35
38
|
[SHACL_PREDICATE_CLASS.id]: (template, term) => {
|
|
36
39
|
template.class = term as NamedNode
|
|
@@ -79,6 +82,7 @@ export class ShaclPropertyTemplate {
|
|
|
79
82
|
languageIn: Term[] | undefined
|
|
80
83
|
datatype: NamedNode | undefined
|
|
81
84
|
hasValue: Term | undefined
|
|
85
|
+
qualifiedValueShape: Term | undefined
|
|
82
86
|
owlImports: NamedNode[] = []
|
|
83
87
|
|
|
84
88
|
config: Config
|
|
@@ -88,6 +92,9 @@ export class ShaclPropertyTemplate {
|
|
|
88
92
|
this.parent = parent
|
|
89
93
|
this.config = config
|
|
90
94
|
this.merge(quads)
|
|
95
|
+
if (this.qualifiedValueShape) {
|
|
96
|
+
this.merge(config.shapesGraph.getQuads(this.qualifiedValueShape, null, null, null))
|
|
97
|
+
}
|
|
91
98
|
}
|
|
92
99
|
|
|
93
100
|
merge(quads: Quad[]): ShaclPropertyTemplate {
|
package/src/property.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { ShaclPropertyTemplate } from './property-template'
|
|
|
8
8
|
import { Editor, fieldFactory } from './theme'
|
|
9
9
|
import { toRDF } from './serialize'
|
|
10
10
|
import { findPlugin } from './plugin'
|
|
11
|
+
import { RDF_PREDICATE_TYPE, SHACL_PREDICATE_TARGET_CLASS } from './constants'
|
|
11
12
|
|
|
12
13
|
export class ShaclProperty extends HTMLElement {
|
|
13
14
|
template: ShaclPropertyTemplate
|
|
@@ -46,6 +47,22 @@ export class ShaclProperty extends HTMLElement {
|
|
|
46
47
|
const values = valueSubject ? config.dataGraph.getQuads(valueSubject, this.template.path, null, null) : []
|
|
47
48
|
let valuesContainHasValue = false
|
|
48
49
|
for (const value of values) {
|
|
50
|
+
// ignore values that do not conform to this property.
|
|
51
|
+
// this might be the case when there are multiple properties with the same sh:path in a NodeShape.
|
|
52
|
+
if (this.template.node) {
|
|
53
|
+
const targetClasses = config.shapesGraph.getObjects(this.template.node, SHACL_PREDICATE_TARGET_CLASS, null)
|
|
54
|
+
if (targetClasses.length > 0) {
|
|
55
|
+
let hasTargetClass = false
|
|
56
|
+
for (let i = 0; i < targetClasses.length && !hasTargetClass; i++) {
|
|
57
|
+
if (config.dataGraph.getQuads(value.object, RDF_PREDICATE_TYPE, targetClasses[i], null).length > 0) {
|
|
58
|
+
hasTargetClass = true
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!hasTargetClass) {
|
|
62
|
+
continue
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
49
66
|
this.addPropertyInstance(value.object)
|
|
50
67
|
if (this.template.hasValue && value.object.equals(this.template.hasValue)) {
|
|
51
68
|
valuesContainHasValue = true
|
package/src/util.ts
CHANGED
|
@@ -85,22 +85,32 @@ function findClassInstancesFromOwlImports(clazz: NamedNode, context: ShaclNode |
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
export function findInstancesOf(clazz: NamedNode, template: ShaclPropertyTemplate, indent = 0): InputListEntry[] {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
88
|
+
let instances: Term[]
|
|
89
|
+
// if template has sh:in, then just use that as class instances
|
|
90
|
+
if (template.shaclIn) {
|
|
91
|
+
const list = template.config.lists[template.shaclIn]
|
|
92
|
+
instances = list?.length ? list : []
|
|
93
|
+
} else {
|
|
94
|
+
// find instances in the shapes graph
|
|
95
|
+
instances = template.config.shapesGraph.getSubjects(RDF_PREDICATE_TYPE, clazz, SHAPES_GRAPH)
|
|
96
|
+
// find instances in the data graph
|
|
97
|
+
instances.push(...template.config.dataGraph.getSubjects(RDF_PREDICATE_TYPE, clazz, null))
|
|
98
|
+
// find instances in imported taxonomies
|
|
99
|
+
findClassInstancesFromOwlImports(clazz, template, template.config.shapesGraph, instances)
|
|
98
100
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
|
|
102
|
+
const entries = createInputListEntries(instances, template.config.shapesGraph, template.config.languages, indent)
|
|
103
|
+
// build inheritance tree only if sh:in is not defined
|
|
104
|
+
if (template.shaclIn === undefined) {
|
|
105
|
+
for (const subClass of template.config.shapesGraph.getSubjects(RDFS_PREDICATE_SUBCLASS_OF, clazz, null)) {
|
|
102
106
|
entries.push(...findInstancesOf(subClass as NamedNode, template, indent + 1))
|
|
103
107
|
}
|
|
108
|
+
if (template.config.shapesGraph.getQuads(clazz, RDF_PREDICATE_TYPE, OWL_OBJECT_NAMED_INDIVIDUAL, null).length > 0) {
|
|
109
|
+
entries.push(...createInputListEntries([ clazz ], template.config.shapesGraph, template.config.languages, indent))
|
|
110
|
+
for (const subClass of template.config.shapesGraph.getSubjects(SKOS_PREDICATE_BROADER, clazz, null)) {
|
|
111
|
+
entries.push(...findInstancesOf(subClass as NamedNode, template, indent + 1))
|
|
112
|
+
}
|
|
113
|
+
}
|
|
104
114
|
}
|
|
105
115
|
return entries
|
|
106
116
|
}
|