Skip to content

Commit 34c6f90

Browse files
larisaVasilemichelu89larisaVasileGeorgiana
authored
Fix/cannot use langstring entity value (#166)
* Loading of entity value possible now * Include lang string entity value defintion * do not add properties with empty values * add new e2e test for lang string * Run prettier and add one condition in testing file --------- Co-authored-by: Michele Santoro <[email protected]> Co-authored-by: Georgiana-Larisa Vasile <[email protected]>
1 parent 1decbde commit 34c6f90

File tree

10 files changed

+344
-79
lines changed

10 files changed

+344
-79
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
2+
#
3+
# See the AUTHORS file(s) distributed with this work for
4+
# additional information regarding authorship.
5+
#
6+
# This Source Code Form is subject to the terms of the Mozilla Public
7+
# License, v. 2.0. If a copy of the MPL was not distributed with this
8+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
9+
#
10+
# SPDX-License-Identifier: MPL-2.0
11+
12+
@prefix samm: <urn:samm:org.eclipse.esmf.samm:meta-model:2.1.0#> .
13+
@prefix samm-c: <urn:samm:org.eclipse.esmf.samm:characteristic:2.1.0#> .
14+
@prefix samm-e: <urn:samm:org.eclipse.esmf.samm:entity:2.1.0#> .
15+
@prefix unit: <urn:samm:org.eclipse.esmf.samm:unit:2.1.0#> .
16+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
17+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
18+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
19+
@prefix : <urn:samm:com.boschsemanticstack.digitalcv.quality:0.2.0#> .
20+
21+
:DefaultAspect a samm:Aspect ;
22+
samm:properties ( :property ) ;
23+
samm:operations ( ) ;
24+
samm:events ( ) .
25+
26+
:property a samm:Property ;
27+
samm:characteristic :Enumeration .
28+
:Enumeration a samm-c:Enumeration ;
29+
samm:dataType :Mode ;
30+
samm-c:values ( :Complaint10 :Complaint20 ) .
31+
32+
:Mode a samm:Entity ;
33+
samm:properties ( :modeCode [ samm:property :modeDescription; samm:notInPayload true ] :modeValue ) .
34+
35+
:Complaint10 a :Mode ;
36+
:modeCode "10"^^xsd:positiveInteger ;
37+
:modeDescription ( "Test"@de "Test"@en ) ;
38+
:modeValue ( "Test"@de "Test"@en ) .
39+
40+
:Complaint20 a :Mode ;
41+
:modeCode "20"^^xsd:positiveInteger ;
42+
:modeDescription ( "Test"@de "Test"@en ) ;
43+
:modeValue ( "Test"@de "Test"@en ) .
44+
45+
:modeCode a samm:Property ;
46+
samm:characteristic :ModeCode .
47+
48+
:modeDescription a samm:Property ;
49+
samm:characteristic :ModeDescription .
50+
51+
:modeValue a samm:Property ;
52+
samm:characteristic :ModeValue .
53+
54+
:ModeCode a samm-c:Enumeration ;
55+
samm:dataType xsd:positiveInteger ;
56+
samm-c:values ( "10"^^xsd:positiveInteger "20"^^xsd:positiveInteger ) .
57+
58+
:ModeDescription a samm-c:Collection ;
59+
samm:dataType rdf:langString .
60+
61+
:ModeValue a samm-c:Collection ;
62+
samm:dataType rdf:langString .
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
2+
#
3+
# See the AUTHORS file(s) distributed with this work for
4+
# additional information regarding authorship.
5+
#
6+
# This Source Code Form is subject to the terms of the Mozilla Public
7+
# License, v. 2.0. If a copy of the MPL was not distributed with this
8+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
9+
#
10+
# SPDX-License-Identifier: MPL-2.0
11+
12+
@prefix samm: <urn:samm:org.eclipse.esmf.samm:meta-model:2.1.0#> .
13+
@prefix samm-c: <urn:samm:org.eclipse.esmf.samm:characteristic:2.1.0#> .
14+
@prefix samm-e: <urn:samm:org.eclipse.esmf.samm:entity:2.1.0#> .
15+
@prefix unit: <urn:samm:org.eclipse.esmf.samm:unit:2.1.0#> .
16+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
17+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
18+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
19+
@prefix : <urn:samm:com.boschsemanticstack.digitalcv.quality:0.2.0#> .
20+
21+
:DefaultAspect a samm:Aspect ;
22+
samm:properties ( :property ) ;
23+
samm:operations ( ) ;
24+
samm:events ( ) .
25+
26+
:property a samm:Property ;
27+
samm:characteristic :Enumeration .
28+
29+
:Enumeration a samm-c:Enumeration ;
30+
samm:dataType :Mode ;
31+
samm-c:values ( :Complaint10 :Complaint20 ) .
32+
33+
:Mode a samm:Entity ;
34+
samm:properties ( :modeCode [ samm:property :modeDescription; samm:notInPayload true ] :modeValue ) .
35+
36+
:Complaint10 a :Mode ;
37+
:modeCode "10"^^xsd:positiveInteger ;
38+
:modeDescription ( "Test"@de "Test"@en ) ;
39+
:modeValue "Test"@de .
40+
41+
:Complaint20 a :Mode ;
42+
:modeCode "20"^^xsd:positiveInteger ;
43+
:modeDescription ( "Test"@de "Test"@en ) ;
44+
:modeValue "Test"@de .
45+
46+
:modeCode a samm:Property ;
47+
samm:characteristic :ModeCode .
48+
49+
:modeDescription a samm:Property ;
50+
samm:characteristic :ModeDescription .
51+
52+
:modeValue a samm:Property ;
53+
samm:characteristic :ModeValue .
54+
55+
:ModeCode a samm-c:Enumeration ;
56+
samm:dataType xsd:positiveInteger ;
57+
samm-c:values ( "10"^^xsd:positiveInteger "20"^^xsd:positiveInteger ) .
58+
59+
:ModeDescription a samm-c:Collection ;
60+
samm:dataType rdf:langString .
61+
62+
:ModeValue a samm:Characteristic ;
63+
samm:dataType rdf:langString .

core/apps/ame-e2e/src/integration/editor/edit-property.cy.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -520,16 +520,11 @@ describe('Test edit property', () => {
520520
.then(() => cyHelp.clickSaveButton())
521521
.then(() => cy.getUpdatedRDF())
522522
.then(rdf => {
523-
expect(rdf).to.contain(':property1 a samm:Property;\n' + ' samm:characteristic :Characteristic1.');
524-
expect(rdf).to.contain(
525-
':AspectDefault a samm:Aspect;\n' +
526-
' samm:properties ([\n' +
527-
' samm:property :property1;\n' +
528-
' samm:optional true\n' +
529-
']);\n' +
530-
' samm:operations ();\n' +
531-
' samm:events ().\n',
532-
);
523+
expect(rdf).to.contain(':property1 a samm:Property;');
524+
expect(rdf).to.contain('samm:characteristic :Characteristic1.');
525+
expect(rdf).to.contain('samm:properties ([\n samm:property :property1;\n');
526+
expect(rdf).to.contain('samm:optional true\n])');
527+
expect(rdf).not.to.contain('notInPayload');
533528
});
534529
});
535530

@@ -559,13 +554,10 @@ describe('Test edit property', () => {
559554
.then(() => cyHelp.clickSaveButton())
560555
.then(() => cy.getUpdatedRDF())
561556
.then(rdf => {
562-
expect(rdf).to.contain(
563-
':Entity1 a samm:Entity;\n' +
564-
' samm:properties ([\n' +
565-
' samm:property :property2;\n' +
566-
' samm:notInPayload true\n' +
567-
']).',
568-
);
557+
expect(rdf).to.contain(':Entity1 a samm:Entity;\n');
558+
expect(rdf).to.contain('samm:properties ([\n samm:property :property2;\n');
559+
expect(rdf).to.contain('samm:notInPayload true\n])');
560+
expect(rdf).not.to.contain('optional');
569561
});
570562
});
571563

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH
3+
*
4+
* See the AUTHORS file(s) distributed with this work for
5+
* additional information regarding authorship.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
10+
*
11+
* SPDX-License-Identifier: MPL-2.0
12+
*/
13+
14+
/// <reference types="Cypress" />
15+
16+
describe('Export entity value', () => {
17+
it('should have entity value with rdf lang string properties values', () => {
18+
cy.intercept('POST', 'http://localhost:9091/ame/api/models/validate', {fixture: 'model-validation-response.json'});
19+
cy.visitDefault();
20+
cy.fixture('/entity-value/validFileText')
21+
.as('rdfString')
22+
.then(rdfString => cy.loadModel(rdfString))
23+
.then(() => cy.getUpdatedRDF())
24+
.then(rdf => {
25+
expect(rdf).to.contain(':Complaint10 a :Mode;');
26+
expect(rdf).to.contain(':modeCode "10"^^xsd:positiveInteger;');
27+
expect(rdf).to.contain(':modeDescription ("Test"@de "Test"@en);');
28+
expect(rdf).to.contain(':ModeDescription a samm-c:Collection;');
29+
expect(rdf).to.contain('samm:dataType rdf:langString');
30+
expect(rdf).to.contain('ModeValue a samm:Characteristic');
31+
expect(rdf).to.contain('samm:dataType rdf:langString');
32+
expect(rdf).to.contain(':modeValue "Test"@de');
33+
});
34+
});
35+
36+
it('should have entity value with rdf lang string with two Collections', () => {
37+
cy.intercept('POST', 'http://localhost:9091/ame/api/models/validate', {fixture: 'model-validation-response.json'});
38+
cy.visitDefault();
39+
cy.fixture('/entity-value/twoCollectionSet')
40+
.as('rdfString')
41+
.then(rdfString => cy.loadModel(rdfString))
42+
.then(() => cy.getUpdatedRDF())
43+
.then(rdf => {
44+
expect(rdf).to.contain(':Complaint10 a :Mode;');
45+
expect(rdf).to.contain(':modeDescription ("Test"@de "Test"@en);');
46+
expect(rdf).to.contain(':ModeDescription a samm-c:Collection;');
47+
expect(rdf).to.contain(':ModeValue a samm-c:Collection');
48+
expect(rdf).to.contain(':modeValue ("Test"@de "Test"@en)');
49+
});
50+
});
51+
});

core/apps/ame/src/app/app.component.scss

Lines changed: 0 additions & 12 deletions
This file was deleted.

core/apps/ame/src/app/app.component.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {SearchesStateService} from '@ame/utils';
2727
@Component({
2828
selector: 'ame-root',
2929
templateUrl: './app.component.html',
30-
styleUrls: ['./app.component.scss'],
3130
})
3231
export class AppComponent implements OnInit {
3332
private language = 'en';

core/libs/aspect-exporter/src/lib/rdf-list/rdf-list.service.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,37 @@ export class RdfListService implements CreateEmptyRdfList, EmptyRdfList {
8080
return this;
8181
}
8282

83+
pushEntityValueLangString(
84+
source: SourceElementType,
85+
...elements: Array<{
86+
predicate: NamedNode;
87+
literal: Quad_Object;
88+
}>
89+
) {
90+
const subject = DataFactory.namedNode(source.aspectModelUrn);
91+
const preparedList = elements.map(({predicate}) => {
92+
const {list, created} = this.getListOrCreateNew(subject, predicate);
93+
return {list, created, predicate};
94+
});
95+
96+
if (!preparedList.length) {
97+
return this;
98+
}
99+
100+
preparedList
101+
.filter(list => list.created)
102+
.forEach(({list, predicate}) => {
103+
const listElements = this.getListElements(list);
104+
const elementsToBeAdded = elements.filter(element => element.predicate.id === predicate.id).map(({literal}) => literal);
105+
106+
if (elementsToBeAdded.length) {
107+
this.recreateList(list, [...listElements.map(({node}) => node), ...elementsToBeAdded]);
108+
}
109+
});
110+
111+
return this;
112+
}
113+
83114
remove(source: SourceElementType, ...elements: ListElementType[]) {
84115
const preparedList = this.getFilteredElements(source, elements);
85116
if (preparedList === null || preparedList.created) {

core/libs/aspect-exporter/src/lib/visitor/entity-value/entity-value-visitor.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,27 @@ describe('Entity value visitor', () => {
4545
property: {
4646
aspectModelUrn: 'propertyUrn1',
4747
getDeepLookUpDataType: jest.fn().mockReturnValue({getUrn: () => 'dataTypeUrn1'}),
48+
characteristic: {
49+
dataType: {
50+
urn: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString',
51+
getUrn: jest.fn().mockReturnValue({getUrn: () => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'}),
52+
},
53+
},
4854
},
4955
};
5056
const mockProperty2: any = {
5157
property: {
5258
aspectModelUrn: 'propertyUrn2',
5359
getDeepLookUpDataType: jest.fn().mockReturnValue({getUrn: () => 'dataTypeUrn2'}),
60+
characteristic: {
61+
dataType: {
62+
urn: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString',
63+
getUrn: jest.fn().mockReturnValue({getUrn: () => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'}),
64+
},
65+
},
5466
},
5567
};
68+
5669
const mockEntityValue1: any = {
5770
aspectModelUrn: 'entityValueUrn1',
5871
metaModelVersion: '1.2.3',

core/libs/aspect-exporter/src/lib/visitor/entity-value/entity-value-visitor.ts

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@
1212
*/
1313

1414
import {Injectable} from '@angular/core';
15-
import {DefaultEntityValue, EntityValueProperty, LangStringProperty} from '@ame/meta-model';
15+
import {DefaultCollection, DefaultEntityValue, EntityValueProperty, LangStringProperty} from '@ame/meta-model';
1616
import {ModelService, RdfService} from '@ame/rdf/services';
17-
import {DataFactory} from 'n3';
17+
import {DataFactory, Literal, NamedNode} from 'n3';
1818
import {BaseVisitor} from '../base-visitor';
1919
import {isDataTypeLangString} from '@ame/shared';
20+
import {RdfListService} from '../../rdf-list';
21+
import {Samm} from '@ame/vocabulary';
2022

2123
@Injectable()
2224
export class EntityValueVisitor extends BaseVisitor<DefaultEntityValue> {
2325
constructor(
26+
private rdfListService: RdfListService,
2427
public modelService: ModelService,
2528
rdfService: RdfService,
2629
) {
@@ -42,22 +45,60 @@ export class EntityValueVisitor extends BaseVisitor<DefaultEntityValue> {
4245
const {aspectModelUrn} = entityValue;
4346
const rdfModel = this.modelService.currentRdfModel;
4447

45-
entityValue.properties.forEach(property => {
46-
const object = this.createObjectForRDF(property);
47-
const {key, value} = property;
48+
const {propertyCollectionWithLangString, property} = entityValue.properties.reduce(
49+
(acc, property) => (
50+
isDataTypeLangString(property.key.property) && property.key.property.characteristic instanceof DefaultCollection
51+
? acc.propertyCollectionWithLangString.push(property)
52+
: acc.property.push(property),
53+
acc
54+
),
55+
{
56+
propertyCollectionWithLangString: [],
57+
property: [],
58+
},
59+
);
60+
61+
if (propertyCollectionWithLangString.length) {
62+
const withoutEmptyLangString = propertyCollectionWithLangString.filter(prop => {
63+
return prop.value.value !== null && prop.value.value !== undefined;
64+
});
65+
66+
const langStringRdfObject = withoutEmptyLangString.map(this.createObjectForCollectionLangStringRDF.bind(this));
67+
this.rdfListService.pushEntityValueLangString(entityValue, ...langStringRdfObject);
68+
}
69+
70+
if (property.length) {
71+
const propertiesWithoutEmptyLangString = property.filter(prop => {
72+
const urn = prop.key.property?.characteristic?.dataType?.getUrn();
73+
return !(urn === `${Samm.RDF_URI}#langString` && prop.value === '');
74+
});
4875

49-
rdfModel.store.addQuad(DataFactory.namedNode(aspectModelUrn), DataFactory.namedNode(key.property.aspectModelUrn), object);
76+
propertiesWithoutEmptyLangString.forEach(property => {
77+
const rdfObject = this.createObjectForRDF(property);
78+
const {key, value} = property;
79+
80+
rdfModel.store.addQuad(DataFactory.namedNode(aspectModelUrn), DataFactory.namedNode(key.property.aspectModelUrn), rdfObject);
81+
82+
this.handleExternalReference(value, aspectModelUrn);
83+
});
84+
}
85+
}
5086

51-
this.handleExternalReference(value, aspectModelUrn);
52-
});
87+
private createObjectForCollectionLangStringRDF(ev: EntityValueProperty): {predicate: NamedNode; literal: Literal} {
88+
const langString = ev.value as LangStringProperty;
89+
const predicate = DataFactory.namedNode(ev.key.property.aspectModelUrn);
90+
return {
91+
predicate: predicate,
92+
literal: DataFactory.literal(langString?.value?.toString(), langString?.language?.toString()),
93+
};
5394
}
5495

55-
private createObjectForRDF({key, value}: EntityValueProperty): any {
96+
private createObjectForRDF({key, value}: EntityValueProperty): NamedNode | Literal {
5697
if (value instanceof DefaultEntityValue) {
5798
return DataFactory.namedNode(value.aspectModelUrn);
5899
}
59100

60-
if (isDataTypeLangString(key.property)) {
101+
if (isDataTypeLangString(key.property) && !(key.property.characteristic instanceof DefaultCollection)) {
61102
const langString = value as LangStringProperty;
62103
return DataFactory.literal(langString?.value?.toString(), langString?.language?.toString());
63104
}

0 commit comments

Comments
 (0)