Skip to content
Snippets Groups Projects

Include Linting

15 files
+ 3295
2204
Compare changes
  • Side-by-side
  • Inline
Files
15
import Vue from 'vue'
import Vue from 'vue';
import factory from 'rdf-ext';
import SHACLValidator from 'rdf-validate-shacl';
@@ -13,14 +13,22 @@ export default Vue.extend({
};
},
methods: {
async validateMetadata(formData: any, quads: Array<Quad>, applicationProfileId: string) {
async validateMetadata(
formData: any,
quads: Array<Quad>,
applicationProfileId: string
) {
// RDF/JSON => JSON-LD since the loadDataset function doesn't support RDF/JSON
const combinedDataObject = [];
const dataObject = this.processDataObject(formData, applicationProfileId);
combinedDataObject.push(dataObject);
// rdfs:subClassOf definitions have to be included for the validation to work with inheritance
const subClasses = quads.filter((quad) => quad.predicate.value === 'http://www.w3.org/2000/01/rdf-schema#subClassOf');
const subClasses = quads.filter(
(quad) =>
quad.predicate.value ===
'http://www.w3.org/2000/01/rdf-schema#subClassOf'
);
for (const subClassQuad of subClasses) {
combinedDataObject.push({
'@id': subClassQuad.subject.value,
@@ -32,37 +40,50 @@ export default Vue.extend({
});
}
// The non-referenced shapes have also to be represented
const nonReferenced = subClasses.filter((quad) =>
!subClasses.some((subQuad) => subQuad.subject.value === quad.object.value));
const nonReferenced = subClasses.filter(
(quad) =>
!subClasses.some(
(subQuad) => subQuad.subject.value === quad.object.value
)
);
for (const nonReference of nonReferenced) {
combinedDataObject.push({
'@id': nonReference.object.value,
});
}
const data = await this.loadDataset(JSON.stringify(combinedDataObject), 'application/ld+json', null);
const data = await this.loadDataset(
JSON.stringify(combinedDataObject),
'application/ld+json',
null
);
const validator = new SHACLValidator(quads);
const report = validator.validate(data);
this.$emit('isValid', report.conforms);
return report;
},
async getQuads (data: string, mimeType: string, baseUri: string | null) : Promise<Array<Quad>> {
async getQuads(
data: string,
mimeType: string,
baseUri: string | null
): Promise<Array<Quad>> {
const input = new Readable({
read: () => {
input.push(data);
input.push(null);
}
},
});
const quads = [] as Array<Quad>;
return new Promise((resolve) => {
rdfParser.parse(input, { contentType: mimeType, baseIRI: baseUri })
rdfParser
.parse(input, { contentType: mimeType, baseIRI: baseUri })
.on('data', (quad: Quad) => {
quads.push(quad);
})
.on('end', () => resolve(quads));
});
},
async loadDataset (data: string, mimeType: string, baseUri: string | null) {
async loadDataset(data: string, mimeType: string, baseUri: string | null) {
const quads = await this.getQuads(data, mimeType, baseUri);
const dataSet = factory.dataset();
for (const quad of quads) {
@@ -74,41 +95,67 @@ export default Vue.extend({
this.shapes = [];
this.fillShapesListRecursive(quads, this.shapes, currentShape);
},
fillShapesListRecursive(quads: Array<Quad>, shapes: Array<string>, currentShape: string) {
fillShapesListRecursive(
quads: Array<Quad>,
shapes: Array<string>,
currentShape: string
) {
if (!shapes.includes(currentShape)) {
shapes.push(currentShape);
const subClasses = quads.filter((quad) =>
quad.predicate.value === 'http://www.w3.org/2000/01/rdf-schema#subClassOf'
&& quad.subject.value === currentShape)
const subClasses = quads
.filter(
(quad) =>
quad.predicate.value ===
'http://www.w3.org/2000/01/rdf-schema#subClassOf' &&
quad.subject.value === currentShape
)
.map((quad) => quad.object.value);
for (const subClass of subClasses) {
this.fillShapesListRecursive(quads, shapes, subClass);
}
}
},
async retrieveQuads(SHACLDefinition: string, mimeType: string, applicationProfileId: string) : Promise<Array<Quad>> {
async retrieveQuads(
SHACLDefinition: string,
mimeType: string,
applicationProfileId: string
): Promise<Array<Quad>> {
if (SHACLDefinition !== '') {
return this.getQuads(SHACLDefinition, mimeType, applicationProfileId);
}
return [];
},
retrieveProperties(SHACLDefinition: string, quads: Array<Quad>, applicationProfileId: string) : Array<Quad> {
retrieveProperties(
SHACLDefinition: string,
quads: Array<Quad>,
applicationProfileId: string
): Array<Quad> {
if (SHACLDefinition !== '') {
this.fillShapesList(quads, applicationProfileId);
const propertySets = quads.filter((quad) =>
quad.predicate.value === 'http://www.w3.org/ns/shacl#property'
&& this.shapes.includes(quad.subject.value)
).map((quad) => quad.object.value);
return quads.filter((quad) => propertySets.includes(quad.subject.value));
const propertySets = quads
.filter(
(quad) =>
quad.predicate.value === 'http://www.w3.org/ns/shacl#property' &&
this.shapes.includes(quad.subject.value)
)
.map((quad) => quad.object.value);
return quads.filter((quad) =>
propertySets.includes(quad.subject.value)
);
}
return [];
},
retrievePropertyOrder(properties: Array<Quad>) {
const propertySubjects = this.getPropertySubjects(properties);
let highestOrder = Math.max(...properties.filter((property) =>
property.predicate.value === 'http://www.w3.org/ns/shacl#order'
).map((property) => Number(property.object.value)));
let highestOrder = Math.max(
...properties
.filter(
(property) =>
property.predicate.value === 'http://www.w3.org/ns/shacl#order'
)
.map((property) => Number(property.object.value))
);
if (highestOrder === -Infinity) {
highestOrder = 0;
}
@@ -117,17 +164,20 @@ export default Vue.extend({
let manualOrder = highestOrder + 1;
for (const propertySubject of propertySubjects) {
let currentOrder = 0;
const orderDefinitions = properties.filter((property) =>
property.subject.value === propertySubject
&& property.predicate.value === 'http://www.w3.org/ns/shacl#order');
const orderDefinitions = properties.filter(
(property) =>
property.subject.value === propertySubject &&
property.predicate.value === 'http://www.w3.org/ns/shacl#order'
);
if (orderDefinitions.length > 0) {
currentOrder = Number(orderDefinitions[0].object.value);
} else {
currentOrder = manualOrder;
manualOrder++;
}
unmappedSubjects[currentOrder] = properties.filter((property) =>
property.subject.value === propertySubject);
unmappedSubjects[currentOrder] = properties.filter(
(property) => property.subject.value === propertySubject
);
}
return unmappedSubjects;
@@ -139,20 +189,31 @@ export default Vue.extend({
const dataObject = {} as any;
dataObject['@type'] = applicationProfileId;
for (const nodeName of Object.keys(formData)) {
if (formData[nodeName].some((element: any) => element['value'] !== "")) {
if (
formData[nodeName].some((element: any) => element['value'] !== '')
) {
dataObject[nodeName] = [];
for (const metadataEntry of formData[nodeName]) {
// skip empty and repeating values for ['@id'] or ['@value']
if (metadataEntry['value'] !== '') {
if (metadataEntry['type'] === 'uri' && !dataObject[nodeName].some((element: any) => element['@id'] === metadataEntry['value'])) {
if (
metadataEntry['type'] === 'uri' &&
!dataObject[nodeName].some(
(element: any) => element['@id'] === metadataEntry['value']
)
) {
dataObject[nodeName].push({
'@id': metadataEntry['value'],
'@type': metadataEntry['datatype']
'@type': metadataEntry['datatype'],
});
} else if (!dataObject[nodeName].some((element: any) => element['@value'] === metadataEntry['value'])) {
} else if (
!dataObject[nodeName].some(
(element: any) => element['@value'] === metadataEntry['value']
)
) {
dataObject[nodeName].push({
'@value': metadataEntry['value'],
'@type': metadataEntry['datatype']
'@type': metadataEntry['datatype'],
});
}
}
@@ -161,5 +222,5 @@ export default Vue.extend({
}
return dataObject;
},
}
},
});
Loading