Skip to content
Snippets Groups Projects
Select Git revision
  • Issue/2960-infiniteLoop
  • Issue/2960-fixValidationForAP
  • dev protected
  • master default protected
  • Issue/2920-fixRemovingValues
  • Hotfix/2957-styleAndUpgrade
  • Hotfix/2955-storingFail
  • Issue/2943-uiFeedback
  • Issue/2551-enhanceSymbolDescriptionsInApplicationProfile
  • Issue/2598-vue3
  • Issue/2804-templateUI
  • Issue/2805-ignoreTemplatingValues
  • Issue/2851-fixBooleanInFormGenerator
  • Issue/2759-showMissingField
  • Issue/2703-vocabularyList
  • Issue/2729-fixSlowLoadingOfInstances
  • Issue/2525-fixedFixValues
  • Hotfix/2681-validationErrors
  • testing
  • Issue/2408-hasValue
  • v4.0.5
  • v4.0.4
  • v4.0.3
  • v4.0.2
  • v4.0.1
  • v4.0.0
  • v3.6.3
  • v3.6.2
  • v3.6.1
  • v3.6.0
  • v3.5.7
  • v3.5.6
  • v3.5.5
  • v3.5.4
  • v3.5.3
  • v3.5.2
  • v3.5.1
  • v3.5.0
  • v3.4.0
  • v3.3.0
40 results

LinkedDataHandler.ts

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    LinkedDataHandler.ts 4.71 KiB
    import Vue from 'vue';
    
    import factory from 'rdf-ext';
    import SHACLValidator from 'rdf-validate-shacl';
    import rdfParser from 'rdf-parse';
    import { Readable } from 'stream';
    import { prefixes } from '@zazuko/rdf-vocabularies';
    import type { Dataset, Quad, Quad_Object, Quad_Subject } from 'rdf-js';
    
    export default Vue.extend({
      data() {
        return {
          errorMessages: {} as { [nodeName: string]: Quad_Object[] },
          timeOutId: 0,
          validationDebounce: 500,
        };
      },
      methods: {
        getMetadataSubject(metadata: Dataset): Quad_Subject {
          let subjectNode: Quad_Subject = factory.blankNode();
          const rdfType = factory.namedNode(prefixes.rdf + 'type');
          if (metadata.size) {
            for (const entry of metadata.match(undefined, rdfType)) {
              subjectNode = entry.subject;
              break;
            }
          }
          return subjectNode;
        },
        triggerMetadataValidation(metadata: Dataset, dataset: Dataset): void {
          if (this.timeOutId) {
            clearTimeout(this.timeOutId);
          }
          this.timeOutId = setTimeout(async () => {
            const combinedMetadata = factory.dataset(Array.from(metadata));
    
            // rdfs:subClassOf definitions have to be included for the validation to work with inheritance
            const subClasses = dataset.match(
              null,
              factory.namedNode(prefixes.rdfs + 'subClassOf')
            );
            for (const subClassQuad of subClasses) {
              combinedMetadata.add(subClassQuad);
            }
    
            // Describe that the selected value for a class relationship is a value of that class to satisfy validation
            const pathRelations = dataset.match(
              null,
              factory.namedNode(prefixes.sh + 'path')
            );
            const classRelations = Array.from(pathRelations).map((pathRelation) => {
              return {
                path: pathRelation.object,
                classRelations: dataset.match(
                  pathRelation.subject,
                  factory.namedNode(prefixes.sh + 'class')
                ),
              };
            });
            for (const classRelation of classRelations.filter(
              (entry) => entry.classRelations && entry.classRelations.size
            )) {
              const metadataRelations = metadata.match(
                undefined,
                classRelation.path
              );
              if (metadataRelations.size) {
                for (const metadataRelation of metadataRelations) {
                  for (const classEntry of classRelation.classRelations) {
                    combinedMetadata.add(
                      factory.quad(
                        metadataRelation.object as Quad_Subject,
                        factory.namedNode(prefixes.rdf + 'type'),
                        classEntry.object
                      )
                    );
                  }
                }
              }
            }
    
            const validator = new SHACLValidator(dataset);
            const report = validator.validate(combinedMetadata);
            this.$emit('isValid', report);
            this.errorMessages = {};
            for (const result of report.results) {
              if (result.path) {
                const path = result.path;
                if (
                  metadata.some(
                    (entry) =>
                      entry.predicate.value === path.value &&
                      entry.object.value !== ''
                  )
                ) {
                  this.errorMessages[path.value] = result.message;
                }
              }
            }
            return report;
          }, this.validationDebounce) as unknown as number;
        },
        async getQuads(
          data: string,
          mimeType: string,
          baseUri: string | undefined
        ): Promise<Dataset> {
          const input = new Readable({
            read: () => {
              input.push(data);
              input.push(null);
            },
          });
          const dataset = factory.dataset();
          return new Promise((resolve) => {
            rdfParser
              .parse(input, { contentType: mimeType, baseIRI: baseUri })
              .on('data', (quad: Quad) => {
                dataset.add(quad);
              })
              .on('end', () => resolve(dataset as unknown as Dataset));
          });
        },
        async loadDataset(
          data: string,
          mimeType: string,
          baseUri: string | undefined
        ): Promise<Dataset> {
          const quads = await this.getQuads(data, mimeType, baseUri);
          const dataSet = factory.dataset();
          for (const quad of quads) {
            dataSet.add(quad);
          }
          return dataSet as unknown as Dataset;
        },
        async retrieveDataset(
          shapes: string,
          mimeType: string,
          selectedShape: string
        ): Promise<Dataset> {
          if (shapes !== '') {
            return await this.getQuads(
              shapes,
              mimeType,
              selectedShape ? selectedShape : 'https://purl.org/coscine/ap/'
            );
          }
          return factory.dataset() as unknown as Dataset;
        },
      },
    });