UNPKG

rdf2hk

Version:

This library converts RDF to Hyperknowledge Description

354 lines (307 loc) 11.2 kB
/* * Copyright (c) 2016-present, IBM Research * Licensed under The MIT License [see LICENSE for details] */ "use strict"; const HK = require("hklib"); const HKTypes = HK.Types; const Link = HK.Link; const VirtualLink = HK.VirtualLink; const HKConstants = HK.Constants; const Constants = require("./constants"); const hk = require("./hk"); const Utils = require("./utils"); const uuid = require("uuid"); const MD5 = require("md5.js"); function HKSerializer(sharedGraph, options) { this.graph = sharedGraph; this.nodeResourceType = hk.NODE_URI; this.contextResourceType = hk.CONTEXT_URI; this.virtualContextResourceType = hk.VIRTUAL_CONTEXT_URI; this.virtualNodeResourceType = hk.VIRTUAL_NODE_URI; this.virtualLinkResourceType = hk.VIRTUAL_LINK_URI; this.connectorResourceType = hk.CONNECTOR_URI; this.linkResourceType = hk.LINK_URI; this.trailResourceType = hk.TRAIL_URI; this.refResourceType = hk.REF_URI; this.isAPredicate = hk.ISA_URI; this.bodyResource = `<${Constants.HK_NULL}>`; this.hasParent = hk.HAS_PARENT_URI; this.hasBlankId = hk.HAS_BLANK_ID_URI; this.references = hk.REFERENCES_URI; this.hasBind = hk.HAS_BIND_URI; this.usesConnector = hk.USES_CONNECTOR_URI; this.boundRole = hk.BOUND_ROLE_URI; this.boundComponent = hk.BOUND_COMPONENT_URI; this.boundAnchor = hk.BOUND_ANCHOR_URI; this.className = hk.CLASSNAME_URI; this.hasRole = hk.HAS_ROLE_URI; this.hasRoleName = hk.HAS_ROLE_NAME_URI; this.hasRoleType = hk.HAS_ROLE_TYPE_URI; this.hasAnchor = hk.HAS_ANCHOR_URI; this.anchorKey = hk.ANCHOR_KEY_URI; this.anchorType = hk.ANCHOR_TYPE_URI; // compressReification = false this.compressReification = options.compressReification || false; this.inverseRefNode = options.inverseRefNode || false; this.preserveAnchorIds = options.convertOwlTime || false; this.reifyAnchorProperties = options.convertOwlTime || false; this.owlTimeSerializer = options.owlTimeSerializer; } HKSerializer.prototype.serialize = function (entity) { let graph = this.graph; let parentUri = undefined; if (entity.parent) { parentUri = entity.parent; } else { parentUri = this.bodyResource; } let entityUri = entity.id; switch (entity.type) { case HKTypes.CONNECTOR: { let classNameLiteral = Utils.createLiteralObject(entity.className); graph.add(entityUri, this.isAPredicate, this.connectorResourceType, parentUri); graph.add(entityUri, this.className, classNameLiteral, parentUri); if (this.compressReification) { for (let k in entity.roles) { let roleUri = compressRoleInUri(k); let roleTypeUri = Utils.createLiteralObject(entity.roles[k]); graph.add(entityUri, roleUri, roleTypeUri, parentUri); } } else { let bnode = `_:${uuid()}`; graph.add(entityUri, this.hasRole, bnode, parentUri); graph.add(bnode, this.hasRoleName, bnode, parentUri); for (let k in entity.roles) { let roleNameLit = Utils.createLiteralObject(k); let roleTypeLit = Utils.createLiteralObject(entity.roles[k]); graph.add(bnode, this.hasRoleName, roleNameLit, parentUri); graph.add(bnode, this.hasRoleType, roleTypeLit, parentUri); } } break; } case HKTypes.CONTEXT: { let parentContext = parentUri; if (!parentContext) { parentContext = this.bodyResource; } graph.add(entityUri, this.isAPredicate, this.contextResourceType, parentUri); graph.add(entityUri, this.hasParent, parentContext, parentUri); _serializeAnchors.call(this, entityUri, entity, parentUri, graph); break; } case HKTypes.VIRTUAL_CONTEXT: { let parentContext = parentUri; if (!parentContext) { parentContext = this.bodyResource; } graph.add(entityUri, this.isAPredicate, this.virtualContextResourceType, parentUri); graph.add(entityUri, this.hasParent, parentContext, parentUri); _serializeAnchors.call(this, entityUri, entity, parentUri, graph); break; } case HKTypes.LINK: { let connectorUri = entity.connector; if (!this.compressReification) { graph.add(entityUri, this.isAPredicate, this.linkResourceType, parentUri); } graph.add(entityUri, this.usesConnector, connectorUri, parentUri); let link = new Link(entity); // Reificate binds link.forEachBind((role, comp, anchor) => { let compNode = comp; if (Utils.isBlankNode(compNode)) { compNode = Utils.createBlankNodeUri(compNode.substr(2)); } if (!this.compressReification) { let bnode = `_:${uuid()}`; let roleLiteral = Utils.createLiteralObject(role); let anchorId = this.preserveAnchorIds ? anchor : Utils.createLiteralObject(anchor); graph.add(entityUri, this.hasBind, bnode, parentUri); graph.add(bnode, this.boundRole, roleLiteral, parentUri); graph.add(bnode, this.boundComponent, compNode, parentUri); graph.add(bnode, this.boundAnchor, anchorId, parentUri); } else { let roleUri = compressRoleInUri(role); graph.add(entityUri, roleUri, compNode, parentUri); if (anchor !== HKConstants.LAMBDA) { let anchorId = this.preserveAnchorIds ? anchor : Utils.createLiteralObject(`${comp}#${anchor}`); graph.add(entityUri, roleUri, anchorId, parentUri); } } }); break; } case HKTypes.VIRTUAL_LINK: { let connectorUri = entity.connector; if (!this.compressReification) { graph.add(entityUri, this.isAPredicate, this.virtualLinkResourceType, parentUri); } graph.add(entityUri, this.usesConnector, connectorUri, parentUri); let link = new VirtualLink(entity); // Reificate binds link.forEachBind((role, comp, anchor) => { let compNode = comp; if (Utils.isBlankNode(compNode)) { compNode = Utils.createBlankNodeUri(compNode.substr(2)); } if (!this.compressReification) { let bnode = `_:${uuid()}`; let roleLiteral = Utils.createLiteralObject(role); let anchorId = this.preserveAnchorIds ? anchor : Utils.createLiteralObject(anchor); graph.add(entityUri, this.hasBind, bnode, parentUri); graph.add(bnode, this.boundRole, roleLiteral, parentUri); graph.add(bnode, this.boundComponent, compNode, parentUri); graph.add(bnode, this.boundAnchor, anchorId, parentUri); } else { let roleUri = compressRoleInUri(role); graph.add(entityUri, roleUri, compNode, parentUri); if (anchor !== HKConstants.LAMBDA) { let anchorId = this.preserveAnchorIds ? anchor : Utils.createLiteralObject(`${comp}#${anchor}`); graph.add(entityUri, roleUri, anchorId, parentUri); } } }); break; } case HKTypes.NODE: { if (Utils.isBlankNode(entityUri)) { let uri = Utils.createBlankNodeUri(entityUri.substr(2)); graph.add(uri, this.isAPredicate, this.nodeResourceType, parentUri); graph.add(entityUri, hk.REFERENCED_BY_URI, uri, parentUri); } else { graph.add(entityUri, this.isAPredicate, this.nodeResourceType, parentUri); } _serializeAnchors.call(this, entityUri, entity, parentUri, graph); break; } case HKTypes.VIRTUAL_NODE: { if (Utils.isBlankNode(entityUri)) { let uri = Utils.createBlankNodeUri(entityUri.substr(2)); graph.add(uri, this.isAPredicate, this.virtualNodeResourceType, parentUri); graph.add(entityUri, hk.REFERENCED_BY_URI, uri, parentUri); } else { graph.add(entityUri, this.isAPredicate, this.virtualNodeResourceType, parentUri); } _serializeAnchors.call(this, entityUri, entity, parentUri, graph); break; } case HKTypes.REFERENCE: { let referencedNode = entity.ref; graph.add(entityUri, this.isAPredicate, this.refResourceType, parentUri); if (Utils.isBlankNode(entityUri)) { graph.add(referencedNode, hk.REFERENCED_BY_URI, entityUri, parentUri); } else if (this.inverseRefNode) { graph.add(entityUri, hk.REFERENCES_URI, referencedNode, parentUri); } else { graph.add(entityUri, this.references, referencedNode, parentUri); } _serializeAnchors.call(this, entityUri, entity, parentUri, graph); break; } case HKTypes.TRAIL: { graph.add(entityUri, this.isAPredicate, this.trailResourceType, parentUri); break; } default: _serializeAnchors.call(this, entityUri, entity, parentUri, graph); break; } } function compressRoleInUri(role) { return `<${Constants.HK_ROLE_PREFIX}/${encodeURIComponent(role)}>`; } function compressAnchorInUri(entityId, key) { let hash = new MD5().update(`${encodeURIComponent(entityId)}/${encodeURIComponent(key)}`).digest("hex"); return `<${Constants.HK_ANCHOR_PREFIX}/${hash}>`; } function _serializeAnchors(uri, entity, parentUri, graph) { if (entity.hasOwnProperty("interfaces")) { for (let k in entity.interfaces) { let interf = entity.interfaces[k]; let key = interf.key || k; let interfaceNode = this.preserveAnchorIds ? key : compressAnchorInUri(entity.id, key); if (key) { graph.add(uri, this.hasAnchor, interfaceNode, parentUri); const keyLabel = Utils.isUri(key) ? Utils.getLabelFromUri(key) : key; graph.add(interfaceNode, this.anchorKey, Utils.createLiteralObject(keyLabel), parentUri); if (interf.type) { graph.add(interfaceNode, this.anchorType, Utils.createLiteralObject(interf.type), parentUri); } let properties = interf.properties || {}; for (let p in properties) { let prop = properties[p]; if (prop !== null && prop !== undefined) { if (this.reifyAnchorProperties && this.owlTimeSerializer) { this.owlTimeSerializer.serializeTemporalAnchorProperty(interfaceNode, p, prop, parentUri, properties); } else { graph.add(interfaceNode, p, Utils.createLiteralObject(prop), parentUri); } } } } } } } HKSerializer.compressRoleInUri = compressRoleInUri; module.exports = HKSerializer;