Skip to content
Snippets Groups Projects
Select Git revision
  • 7559a8b41bb4ec4984899fa4f9ab12fb39e55889
  • main default protected
  • renovate/lock-file-maintenance
  • demo protected
  • person-select-custom
  • dbp-translation-component
  • icon-set-mapping
  • port-i18next-parser
  • remove-sentry
  • favorites-and-recent-files
  • revert-6c632dc6
  • lit2
  • advertisement
  • wc-part
  • automagic
  • publish
  • wip-cleanup
  • demo-file-handling
18 results

jsonld.js

Blame
  • jsonld.js 9.46 KiB
    import {send as notify} from './notification';
    import * as utils from './utils';
    import {createInstance} from './src/i18n';
    
    export default class JSONLD {
        constructor(baseApiUrl, entities) {
            this.entities = entities;
            this.baseApiUrl = baseApiUrl;
    
            let idToEntityNameMatchList = {};
            for (const entityName in entities) {
                const id = entities[entityName]['@id'];
                idToEntityNameMatchList[id] = entityName;
            }
    
            this.idToEntityNameMatchList = idToEntityNameMatchList;
        }
    
        static async getInstance(apiUrl, lang = 'de') {
            let promise = JSONLD.promises[apiUrl];
            if (promise === undefined) {
                promise = new Promise((resolve, reject) => {
                    JSONLD._initialize(
                        apiUrl,
                        (instance) => resolve(instance),
                        (error) => reject(error),
                        lang
                    );
                });
                JSONLD.promises[apiUrl] = promise;
            }
            return promise;
        }
    
        static initialize(apiUrl, successFnc, failureFnc, lang = 'de') {
            console.warn('DEPRECATED: JSONLD.initialize(), use JSONLD.getInstance() instead');
            JSONLD._initialize(apiUrl, successFnc, failureFnc, lang);
        }
    
        static doInitializationOnce(apiUrl) {
            // No longer needed, remove any calls
            console.warn('DEPRECATED: JSONLD.doInitializationOnce() calls can be removed');
        }
    
        static _initialize(apiUrl, successFnc, failureFnc, lang = 'de') {
            JSONLD._i18n.changeLanguage(lang);
    
            // if init api call was already successfully finished execute the success function
            if (JSONLD.instances[apiUrl] !== undefined) {
                if (typeof successFnc == 'function') successFnc(JSONLD.instances[apiUrl]);
    
                return;
            }
    
            // init the arrays
            if (JSONLD.successFunctions[apiUrl] === undefined) JSONLD.successFunctions[apiUrl] = [];
            if (JSONLD.failureFunctions[apiUrl] === undefined) JSONLD.failureFunctions[apiUrl] = [];
    
            // add success and failure functions
            if (typeof successFnc == 'function') JSONLD.successFunctions[apiUrl].push(successFnc);
            if (typeof failureFnc == 'function') JSONLD.failureFunctions[apiUrl].push(failureFnc);
    
            if (!apiUrl || JSONLD.initStarted[apiUrl] !== undefined) {
                return;
            }
    
            JSONLD.initStarted[apiUrl] = true;
            JSONLD._doInitialization(apiUrl);
        }
    
        static _doInitialization(apiUrl) {
            const xhr = new XMLHttpRequest();
            const i18n = JSONLD._i18n;
            xhr.open('GET', apiUrl, true);
    
            xhr.onreadystatechange = function () {
                if (xhr.readyState !== 4) {
                    return;
                }
    
                if (xhr.status === 200) {
                    const json = JSON.parse(xhr.responseText);
    
                    let entryPoints = {};
                    for (let property in json) {
                        // for some reason the properties start with a lower case character
                        if (!property.startsWith('@'))
                            entryPoints[property.toLowerCase()] = json[property];
                    }
    
                    // read the link header of the api response
                    //                const utils = require("./utils");
                    const links = utils.parseLinkHeader(this.getResponseHeader('link'));
    
                    // get the hydra apiDocumentation url
                    const apiDocUrl = links['http://www.w3.org/ns/hydra/core#apiDocumentation'];
    
                    if (apiDocUrl !== undefined) {
                        // load the hydra apiDocumentation
                        const docXhr = new XMLHttpRequest();
                        docXhr.open('GET', apiDocUrl, true);
                        docXhr.setRequestHeader('Content-Type', 'application/json');
                        docXhr.onreadystatechange = function () {
                            if (docXhr.readyState !== 4) {
                                return;
                            }
    
                            if (docXhr.status === 200) {
                                JSONLD._gatherEntities(docXhr, apiUrl, entryPoints);
                            } else {
                                JSONLD._executeFailureFunctions(
                                    apiUrl,
                                    i18n.t('jsonld.api-documentation-server', {apiUrl: apiDocUrl})
                                );
                            }
                        };
    
                        docXhr.send();
                    } else {
                        JSONLD._executeFailureFunctions(
                            apiUrl,
                            i18n.t('jsonld.error-hydra-documentation-url-not-set', {apiUrl: apiUrl})
                        );
                    }
                } else {
                    JSONLD._executeFailureFunctions(
                        apiUrl,
                        i18n.t('jsonld.error-api-server', {apiUrl: apiUrl})
                    );
                }
            };
    
            xhr.send();
        }
    
        /**
         * Gather the entities
         *
         * @param docXhr
         * @param apiUrl
         * @param entryPoints
         */
        static _gatherEntities(docXhr, apiUrl, entryPoints) {
            const json = JSON.parse(docXhr.responseText);
            const supportedClasses = json['hydra:supportedClass'];
    
            let entities = {};
            const baseUrl = utils.parseBaseUrl(apiUrl);
    
            // gather the entities
            supportedClasses.forEach(function (classData) {
                // add entry point url
                const entityName = classData['hydra:title'];
                let entryPoint = entryPoints[entityName.toLowerCase()];
                if (entryPoint !== undefined && !entryPoint.startsWith('http'))
                    entryPoint = baseUrl + entryPoint;
                classData['@entryPoint'] = entryPoint;
    
                entities[entityName] = classData;
            });
    
            const instance = new JSONLD(baseUrl, entities);
            JSONLD.instances[apiUrl] = instance;
    
            // return the initialized JSONLD object
            if (JSONLD.successFunctions[apiUrl] !== undefined) {
                for (const fnc of JSONLD.successFunctions[apiUrl]) {
                    if (typeof fnc == 'function') {
                        fnc(instance);
                    }
                }
            }
            JSONLD.successFunctions[apiUrl] = [];
        }
    
        /**
         * Execute failure functions and send general notification
         *
         * @param apiUrl
         * @param message
         */
        static _executeFailureFunctions(apiUrl, message = '') {
            const i18n = JSONLD._i18n;
            if (JSONLD.failureFunctions[apiUrl] !== undefined) {
                for (const fnc of JSONLD.failureFunctions[apiUrl]) {
                    if (typeof fnc == 'function') {
                        fnc(new Error(message));
                    }
                }
            }
            JSONLD.failureFunctions[apiUrl] = [];
    
            if (message !== '') {
                notify({
                    summary: i18n.t('error.summary'),
                    body: message,
                    type: 'danger',
                });
            }
        }
    
        getEntityForIdentifier(identifier) {
            let entityName = this.getEntityNameForIdentifier(identifier);
            return this.getEntityForEntityName(entityName);
        }
    
        getEntityForEntityName(entityName) {
            return this.entities[entityName];
        }
    
        getApiUrlForEntityName(entityName) {
            const entity = this.getEntityForEntityName(entityName);
    
            if (entity === undefined || entity['@entryPoint'] === undefined) {
                throw new Error(`Entity "${entityName}" not found!`);
            }
    
            return entity['@entryPoint'];
        }
    
        getEntityNameForIdentifier(identifier) {
            return this.idToEntityNameMatchList[identifier];
        }
    
        getApiIdentifierList() {
            let keys = [];
            for (const property in this.idToEntityNameMatchList) {
                keys.push(property);
            }
    
            return keys;
        }
    
        /**
         * Expands a member of a list to a object with schema.org properties
         *
         * @param member
         * @param [context]
         */
        expandMember(member, context) {
            if (context === undefined) {
                context = member['@context'];
            }
    
            let result = {'@id': member['@id']};
            for (const key of Object.keys(context)) {
                const value = context[key];
                if (member[key] !== undefined) result[value] = member[key];
            }
    
            return result;
        }
    
        /**
         * Compacts an expanded member of a list to a object with local properties
         *
         * @param member
         * @param localContext
         */
        compactMember(member, localContext) {
            let result = {};
    
            for (const property in localContext) {
                const value = member[localContext[property]];
    
                if (value !== undefined) {
                    result[property] = value;
                }
            }
    
            return result;
        }
    
        /**
         * Transforms hydra members to a local context
         *
         * @param data
         * @param localContext
         * @returns {Array} An array of transformed objects
         */
        transformMembers(data, localContext) {
            const members = data['hydra:member'];
    
            if (members === undefined || members.length === 0) {
                return [];
            }
    
            const otherContext = data['@context'];
            let results = [];
            let that = this;
    
            members.forEach(function (member) {
                results.push(that.compactMember(that.expandMember(member, otherContext), localContext));
            });
    
            return results;
        }
    }
    
    JSONLD._i18n = createInstance();
    JSONLD.instances = {};
    JSONLD.successFunctions = {};
    JSONLD.failureFunctions = {};
    JSONLD.initStarted = {};
    JSONLD.promises = {};