Skip to content

Resolve entity instances for Sorted Set #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}\\dist\\index.js",
"preLaunchTask": "tsc: build - tsconfig.json",
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*
* SPDX-License-Identifier: MPL-2.0
*/

import {Type} from '../type';
import {Characteristic, DefaultCharacteristic} from './default-characteristic';
import {DefaultEntityInstance} from '../default-entity-instance';
Expand Down
35 changes: 33 additions & 2 deletions src/aspect-meta-model/characteristic/default-sorted-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,40 @@
import {DefaultCollection} from './default-collection';
import {Characteristic} from './default-characteristic';
import {Type} from '../type';
import { DefaultEntityInstance } from '../default-entity-instance';
import { DefaultEntity } from '../default-entity';
import { Enumeration } from './default-enumeration';

export class DefaultSortedSet extends DefaultCollection {
constructor(metaModelVersion: string, aspectModelUrn: string, name: string, elementCharacteristic?: Characteristic, dataType?: Type) {
export class DefaultSortedSet extends DefaultCollection implements Enumeration {
constructor(metaModelVersion: string, aspectModelUrn: string, name: string, elementCharacteristic?: Characteristic, dataType?: Type,private _values?: Array<DefaultEntityInstance | string | number>) {
super(metaModelVersion, aspectModelUrn, name, false, true, elementCharacteristic, dataType);
}
public set values(values: Array<DefaultEntityInstance | string | number>) {
this._values = values;
}

public get values(): Array<DefaultEntityInstance | string | number> {
return this._values;
}

/**
* Find the index of the given value in the values array.
*
* @return returns the index of the value or -1
*/
public indexOf(value: string): number {
if (!this.values) {
return -1;
}

if (this.dataType && this.dataType.isComplex) {
const propertyValue = (<DefaultEntity>this.dataType).properties.find(property => property.isNotInPayload === false);

return this.values.findIndex((valueEntry: DefaultEntityInstance) => {
return valueEntry[propertyValue.name] === value;
});
} else {
return this.values.findIndex(valueEntry => valueEntry === value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
*
* See the AUTHORS file(s) distributed with this work for
* additional information regarding authorship.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

import {Quad} from "n3";

export interface MultiLanguageText {
value: string;
language: string;
}

export class CharacteristicInstantiatorUtil {

public static resolveValues(quad: Quad, dataType: string): string | number {
if (!dataType || !dataType.includes('#')) {
return `${quad.object.value}`;
}

switch (dataType.split('#')[1]) {
case 'decimal':
case 'integer':
case 'double':
case 'float':
case 'byte':
case 'short':
case 'int':
case 'long':
case 'unsignedByte':
case 'unsignedLong':
case 'unsignedInt':
case 'unsignedShort':
case 'positiveInteger':
case 'nonNegativeInteger':
case 'negativeInteger':
case 'nonPositiveInteger':
return Number(quad.object.value);
default:
return `${quad.object.value}`;
}
}

public static solveBlankNodeValues(resolvedBlankNodes: Array<Quad>): Array<MultiLanguageText> {
return resolvedBlankNodes.length > 0 ? resolvedBlankNodes.map(item => this.createLanguageObject(item)) : [];
}

public static getPredicateKey(quad: Quad): string {
return quad.predicate.value.split('#')[1];
}

public static createLanguageObject(quad: Quad): MultiLanguageText {
return {value: quad.object.value, language: (quad.object as any).language};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ import {DefaultEnumeration, Enumeration} from '../../aspect-meta-model/character
import {Samm} from '../../vocabulary';
import {EntityInstantiator} from '../entity-instantiator';
import {DefaultEntityInstance} from '../../aspect-meta-model/default-entity-instance';

export interface MultiLanguageText {
value: string;
language: string;
}
import {CharacteristicInstantiatorUtil, MultiLanguageText} from './characteristic-instantiator-util';

export class EnumerationCharacteristicInstantiator extends CharacteristicInstantiator {
constructor(metaModelElementInstantiator: MetaModelElementInstantiator, nextProcessor: CharacteristicInstantiator) {
Expand All @@ -33,7 +29,6 @@ export class EnumerationCharacteristicInstantiator extends CharacteristicInstant
const samm = this.metaModelElementInstantiator.samm;
const sammC = this.metaModelElementInstantiator.sammC;
const enumeration = this.creatEnumerationObject();

const dataType = quads.find(quad => this.samm.isDataTypeProperty(quad.predicate.value));

quads.forEach(quad => {
Expand All @@ -57,38 +52,10 @@ export class EnumerationCharacteristicInstantiator extends CharacteristicInstant
private getEnumerationValues(quad: Quad, dataType: string): Array<string | number | DefaultEntityInstance> {
const quads = this.metaModelElementInstantiator.rdfModel.resolveBlankNodes(quad.object.value);
return quads.map(quadValue =>
Util.isLiteral(quadValue.object) ? this.resolveValues(quadValue, dataType) : this.resolveEntityInstance(quadValue)
Util.isLiteral(quadValue.object) ? CharacteristicInstantiatorUtil.resolveValues(quadValue, dataType) : this.resolveEntityInstance(quadValue)
);
}

private resolveValues(quad: Quad, dataType: string): string | number {
if (!dataType || !dataType.includes('#')) {
return `${quad.object.value}`;
}

switch (dataType.split('#')[1]) {
case 'decimal':
case 'integer':
case 'double':
case 'float':
case 'byte':
case 'short':
case 'int':
case 'long':
case 'unsignedByte':
case 'unsignedLong':
case 'unsignedInt':
case 'unsignedShort':
case 'positiveInteger':
case 'nonNegativeInteger':
case 'negativeInteger':
case 'nonPositiveInteger':
return Number(quad.object.value);
default:
return `${quad.object.value}`;
}
}

protected resolveEntityInstance(quad: Quad): DefaultEntityInstance {
const entityInstanceQuads = this.metaModelElementInstantiator.rdfModel.store.getQuads(quad.object, null, null, null);
const entityTypeQuad = entityInstanceQuads.find(
Expand Down Expand Up @@ -118,7 +85,7 @@ export class EnumerationCharacteristicInstantiator extends CharacteristicInstant
// create the related instance and attach the metamodel element to it
const entityInstance = new DefaultEntityInstance(quad.object.value.split('#')[1], entity, descriptions);
entityInstanceQuads.forEach(quad => {
const predicateKey = this.getPredicateKey(quad);
const predicateKey = CharacteristicInstantiatorUtil.getPredicateKey(quad);
entityInstance[predicateKey] = this.resolveQuadObject(quad);
});

Expand All @@ -130,29 +97,17 @@ export class EnumerationCharacteristicInstantiator extends CharacteristicInstant
private resolveQuadObject(quad: Quad): MultiLanguageText | Array<MultiLanguageText> | string {
if (Util.isBlankNode(quad.object)) {
const resolvedBlankNodes = this.metaModelElementInstantiator.rdfModel.resolveBlankNodes(quad.object.value);
return this.solveBlankNodeValues([...resolvedBlankNodes]);
return CharacteristicInstantiatorUtil.solveBlankNodeValues([...resolvedBlankNodes]);
}

if (((quad.object as any).datatypeString === Samm.RDF_LANG_STRING) ||
((quad.object as any).datatypeString === Samm.XML_LANG_STRING)) {
return this.createLanguageObject(quad);
return CharacteristicInstantiatorUtil.createLanguageObject(quad);
}

return quad.object.value;
}

private solveBlankNodeValues(resolvedBlankNodes: Array<Quad>): Array<MultiLanguageText> {
return resolvedBlankNodes.length > 0 ? resolvedBlankNodes.map(item => this.createLanguageObject(item)) : [];
}

private getPredicateKey(quad: Quad): string {
return quad.predicate.value.split('#')[1];
}

private createLanguageObject(quad: Quad): MultiLanguageText {
return {value: quad.object.value, language: (quad.object as any).language};
}

shouldProcess(nameNode: NamedNode): boolean {
return this.metaModelElementInstantiator.sammC.EnumerationCharacteristic().equals(nameNode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,103 @@

import {CharacteristicInstantiator} from '../characteristic/characteristic-instantiator';
import {MetaModelElementInstantiator} from '../meta-model-element-instantiator';
import {NamedNode} from 'n3';
import {Collection} from '../../aspect-meta-model';
import {CollectionCharacteristicInstantiator} from './collection-characteristic-instantiator';
import {DefaultSortedSet} from '../../aspect-meta-model/characteristic/default-sorted-set';

import {NamedNode, Quad, Util} from 'n3';
import {Characteristic} from '../../aspect-meta-model';
import {Samm} from '../../vocabulary';
import {EntityInstantiator} from '../entity-instantiator';
import {DefaultEntityInstance} from '../../aspect-meta-model/default-entity-instance';
import {CharacteristicInstantiatorUtil, MultiLanguageText} from './characteristic-instantiator-util';

export class SortedSetCharacteristicInstantiator extends CollectionCharacteristicInstantiator {
constructor(metaModelElementInstantiator: MetaModelElementInstantiator, nextProcessor: CharacteristicInstantiator) {
super(metaModelElementInstantiator, nextProcessor);
}

protected creatCollectionObject(): Collection {
protected processElement(quads: Array<Quad>): Characteristic {
const samm = this.metaModelElementInstantiator.samm;
const sammC = this.metaModelElementInstantiator.sammC;
const sortedSet = this.creatCollectionObject();

const dataType = quads.find(quad => this.samm.isDataTypeProperty(quad.predicate.value));

quads.forEach(quad => {
if (samm.isValueProperty(quad.predicate.value) || sammC.isValuesProperty(quad.predicate.value)) {
if (Util.isBlankNode(quad.object)) {
sortedSet.values = this.getEnumerationValues(quad, dataType?.object.value);
}
}
});
return sortedSet;
}

protected creatCollectionObject(): any {
return new DefaultSortedSet(null, null, null, null);
}

shouldProcess(nameNode: NamedNode): boolean {
return this.metaModelElementInstantiator.sammC.SortedSetCharacteristic().equals(nameNode);
}

protected resolveEntityInstance(quad: Quad): DefaultEntityInstance {
const entityInstanceQuads = this.metaModelElementInstantiator.rdfModel.store.getQuads(quad.object, null, null, null);
const entityTypeQuad = entityInstanceQuads.find(
entityInstanceQuad => entityInstanceQuad.predicate.value === `${Samm.RDF_URI}#type`
);

if (entityTypeQuad) {
const entity = new EntityInstantiator(this.metaModelElementInstantiator).createEntity(
this.metaModelElementInstantiator.rdfModel.store.getQuads(entityTypeQuad.object, null, null, null)
);

// determine the description of the value/instance if defined
const descriptionQuad = entityInstanceQuads.find(
quad =>
quad.predicate.id.toLowerCase().includes('description') &&
entity.properties.find(property => property.isNotInPayload === false && quad.predicate.id)
);
const descriptions = new Map<string, string>();
if (descriptionQuad) {
entityInstanceQuads
.filter(quad => quad.predicate.id === descriptionQuad.predicate.id)
.forEach(quad =>
descriptions.set(this.metaModelElementInstantiator.rdfModel.getLocale(quad) || 'en', quad.object.value)
);
}

// create the related instance and attach the metamodel element to it
const entityInstance = new DefaultEntityInstance(quad.object.value.split('#')[1], entity, descriptions);
entityInstanceQuads.forEach(quad => {
const predicateKey = CharacteristicInstantiatorUtil.getPredicateKey(quad);
entityInstance[predicateKey] = this.resolveQuadObject(quad);
});

return entityInstance;
}
throw new Error(`Could resolve Entity instance ${entityTypeQuad.subject.value}`);
}

private resolveQuadObject(quad: Quad): MultiLanguageText | Array<MultiLanguageText> | string {
if (Util.isBlankNode(quad.object)) {
const resolvedBlankNodes = this.metaModelElementInstantiator.rdfModel.resolveBlankNodes(quad.object.value);
return CharacteristicInstantiatorUtil.solveBlankNodeValues([...resolvedBlankNodes]);
}

if (((quad.object as any).datatypeString === Samm.RDF_LANG_STRING) ||
((quad.object as any).datatypeString === Samm.XML_LANG_STRING)) {
return CharacteristicInstantiatorUtil.createLanguageObject(quad);
}

return quad.object.value;
}

private getEnumerationValues(quad: Quad, dataType: string): Array<string | number | DefaultEntityInstance> {
const quads = this.metaModelElementInstantiator.rdfModel.resolveBlankNodes(quad.object.value);
return quads.map(quadValue =>
Util.isLiteral(quadValue.object) ? CharacteristicInstantiatorUtil.resolveValues(quadValue, dataType) : this.resolveEntityInstance(quadValue)
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
import {CharacteristicInstantiator} from '../characteristic/characteristic-instantiator';
import {MetaModelElementInstantiator} from '../meta-model-element-instantiator';
import {NamedNode, Quad, Util} from 'n3';
import {Characteristic} from '../../aspect-meta-model';
import {Characteristic, Enumeration} from '../../aspect-meta-model';
import {DefaultState} from '../../aspect-meta-model/characteristic/default-state';
import {EnumerationCharacteristicInstantiator} from './enumeration-characteristic-instantiator';
import {Enumeration} from '../../aspect-meta-model/characteristic/default-enumeration';

export class StateCharacteristicInstantiator extends EnumerationCharacteristicInstantiator {
constructor(metaModelElementInstantiator: MetaModelElementInstantiator, nextProcessor: CharacteristicInstantiator) {
Expand Down
Loading