Skip to content
This repository was archived by the owner on Feb 15, 2024. It is now read-only.

Commit 27dd892

Browse files
committed
fixed some issues with attribute naming (e.g. now using singular names instead of plural names)
1 parent 58b59bd commit 27dd892

19 files changed

Lines changed: 814 additions & 323 deletions

dataformat-aml/src/main/java/io/adminshell/aas/v3/dataformat/aml/serialization/AasToAmlMapper.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,20 @@
3737
import io.adminshell.aas.v3.dataformat.aml.serialization.mappers.SubmodelMapper;
3838
import io.adminshell.aas.v3.dataformat.aml.serialization.mappers.ViewMapper;
3939
import io.adminshell.aas.v3.dataformat.aml.model.caex.CAEXFile;
40+
import io.adminshell.aas.v3.dataformat.aml.serialization.mappers.ConceptDescriptionMapper;
41+
import io.adminshell.aas.v3.dataformat.aml.serialization.mappers.PropertyMapper;
42+
import io.adminshell.aas.v3.dataformat.aml.serialization.mappers.RangeMapper;
4043
import io.adminshell.aas.v3.dataformat.aml.serialization.mappers.ReferenceMapper;
4144
import io.adminshell.aas.v3.dataformat.mapping.MappingException;
4245
import io.adminshell.aas.v3.dataformat.mapping.MappingProvider;
4346
import io.adminshell.aas.v3.model.AssetAdministrationShellEnvironment;
44-
import io.adminshell.aas.v3.model.ConceptDescription;
4547
import io.adminshell.aas.v3.model.LangString;
4648
import io.adminshell.aas.v3.model.Qualifier;
4749
import io.adminshell.aas.v3.model.Referable;
4850
import org.slf4j.LoggerFactory;
4951
import io.adminshell.aas.v3.dataformat.mapping.SourceBasedMapper;
52+
import io.adminshell.aas.v3.model.MultiLanguageProperty;
53+
import io.adminshell.aas.v3.model.Reference;
5054

5155
/**
5256
* Maps an AssetAdministrationShellEnvironment to an AML file
@@ -68,9 +72,9 @@ public CAEXFile map(AssetAdministrationShellEnvironment env, AmlSerializationCon
6872
AbstractClassNamingStrategy classNamingStrategy = new NumberingClassNamingStrategy();
6973
classNamingStrategy.registerCustomNaming(LangString.class, x -> "aml-lang=" + x.getLanguage());
7074
PropertyNamingStrategy propertyNamingStrategy = new PropertyNamingStrategy();
71-
propertyNamingStrategy.registerCustomNaming(Referable.class, "descriptions", "description");
72-
propertyNamingStrategy.registerCustomNaming(Qualifier.class, x -> "qualifier:" + x.getType() + "=" + x.getValue());
73-
propertyNamingStrategy.registerCustomNaming(ConceptDescription.class, "isCaseOfs", "isCaseOf");
75+
propertyNamingStrategy.registerCustomNaming(Referable.class, "descriptions", "description", true);
76+
propertyNamingStrategy.registerCustomNaming(MultiLanguageProperty.class, "values", "value", true);
77+
propertyNamingStrategy.registerCustomNaming(Qualifier.class, x -> "qualifier:" + x.getType() + "=" + x.getValue(), false);
7478
MappingProvider<SourceBasedMapper> mappingProvider = new MappingProvider<>(
7579
SourceBasedMapper.class,
7680
new DefaultMapper(),
@@ -93,6 +97,9 @@ public CAEXFile map(AssetAdministrationShellEnvironment env, AmlSerializationCon
9397
mappingProvider.register(new RelationshipElementMapper());
9498
mappingProvider.register(new DataSpecificationIEC61360Mapper());
9599
mappingProvider.register(new ViewMapper());
100+
mappingProvider.register(new PropertyMapper());
101+
mappingProvider.register(new RangeMapper());
102+
mappingProvider.register(new ConceptDescriptionMapper());
96103
MappingContext context = new MappingContext(
97104
mappingProvider,
98105
classNamingStrategy,

dataformat-aml/src/main/java/io/adminshell/aas/v3/dataformat/aml/serialization/AmlGenerator.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,13 +382,14 @@ public AttributeType.RefSemantic refSemantic(Class<?> type, String propertyName)
382382
}
383383

384384
/**
385-
* Creates a refSemantic object for a given property
385+
* Creates a refSemantic object for a given property and property name.
386386
*
387387
* @param property the property
388+
* @param propertyName the property name to use in the refSemantic.
388389
* @return the generated refSemantic object
389390
*/
390-
public AttributeType.RefSemantic refSemantic(PropertyDescriptor property) {
391-
return refSemantic(property.getReadMethod().getDeclaringClass(), property.getName());
391+
public AttributeType.RefSemantic refSemantic(PropertyDescriptor property, String propertyName) {
392+
return refSemantic(property.getReadMethod().getDeclaringClass(), propertyName);
392393
}
393394

394395
/**

dataformat-aml/src/main/java/io/adminshell/aas/v3/dataformat/aml/serialization/DefaultCollectionMapper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,12 @@ protected void asAttribute(Collection<T> collection, AmlGenerator generator, Map
5555
generator.add(builder.build());
5656
}
5757
}
58+
59+
@Override
60+
protected String getAttributeName(Collection<T> value, MappingContext context) {
61+
return context.getAttributeNamingStrategy().getName(
62+
context.getProperty().getReadMethod().getDeclaringClass(),
63+
value,
64+
context.getProperty().getName());
65+
}
5866
}

dataformat-aml/src/main/java/io/adminshell/aas/v3/dataformat/aml/serialization/DefaultMapper.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import io.adminshell.aas.v3.dataformat.core.ReflectionHelper;
2121
import io.adminshell.aas.v3.dataformat.core.util.AasUtils;
2222
import io.adminshell.aas.v3.dataformat.mapping.MappingException;
23-
import io.adminshell.aas.v3.model.MultiLanguageProperty;
2423
import io.adminshell.aas.v3.model.Referable;
2524
import java.beans.PropertyDescriptor;
2625
import java.lang.reflect.InvocationTargetException;
@@ -95,7 +94,12 @@ protected InternalElementType.RoleRequirements getRoleRequirementClass(T value,
9594
}
9695

9796
protected AttributeType.RefSemantic getRefSemantic(T value, AmlGenerator generator, MappingContext context) {
98-
return generator.refSemantic(context.getProperty());
97+
return generator.refSemantic(
98+
context.getProperty(),
99+
context.getAttributeNamingStrategy().getNameForRefSemantic(
100+
context.getProperty().getReadMethod().getGenericReturnType(),
101+
value,
102+
context.getProperty().getName()));
99103
}
100104

101105
protected String getInternalElementName(Object value, MappingContext context) {
@@ -105,12 +109,6 @@ protected String getInternalElementName(Object value, MappingContext context) {
105109
null);
106110
}
107111

108-
// protected String getId(T value, AmlGenerator generator, MappingContext context) {
109-
// if (value != null && Referable.class.isAssignableFrom(value.getClass())) {
110-
// return context.getId(AasUtils.asReference(generator.getReference(), (Referable) value));
111-
// }
112-
// return context.getId(null);
113-
// }
114112
protected String getAttributeName(T value, MappingContext context) {
115113
return context.getAttributeNamingStrategy().getName(
116114
context.getProperty().getReadMethod().getGenericReturnType(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (c) 2021 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e. V.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.adminshell.aas.v3.dataformat.aml.serialization.mappers;
17+
18+
import io.adminshell.aas.v3.dataformat.aml.model.caex.AttributeType;
19+
import io.adminshell.aas.v3.dataformat.aml.model.caex.InternalElementType;
20+
import io.adminshell.aas.v3.dataformat.aml.serialization.AmlGenerator;
21+
import io.adminshell.aas.v3.dataformat.aml.serialization.DefaultMapper;
22+
import io.adminshell.aas.v3.dataformat.aml.serialization.MappingContext;
23+
import io.adminshell.aas.v3.dataformat.core.util.AasUtils;
24+
import io.adminshell.aas.v3.dataformat.mapping.MappingException;
25+
import java.beans.PropertyDescriptor;
26+
import java.lang.reflect.InvocationTargetException;
27+
import java.util.Arrays;
28+
import java.util.List;
29+
import java.util.Optional;
30+
import java.util.stream.Collectors;
31+
32+
/**
33+
* Abstract base class for AAS types that have the properties 'value' and
34+
* 'valueType' that ensures valueType is serialized as attribute of value
35+
*
36+
*/
37+
public abstract class AbstractElementMapperWithValueType<T> extends DefaultMapper<T> {
38+
39+
protected static final String PROPERTY_VALUE_NAME = "value";
40+
protected static final String PROPERTY_VALUE_TYPE_NAME = "valueType";
41+
protected static final String PROPERTY_VALUE_TYPE_NAMESPACE_PREFIX = "xs:";
42+
private List<String> typedProperties = List.of(PROPERTY_VALUE_NAME);
43+
44+
protected AbstractElementMapperWithValueType(String... typedProperties) {
45+
super(PROPERTY_VALUE_TYPE_NAME);
46+
this.typedProperties = Arrays.asList(typedProperties);
47+
}
48+
49+
protected AbstractElementMapperWithValueType() {
50+
super(PROPERTY_VALUE_TYPE_NAME);
51+
}
52+
53+
@Override
54+
protected InternalElementType.Builder toInternalElement(T value, AmlGenerator generator, MappingContext context) throws MappingException {
55+
InternalElementType original = super.toInternalElement(value, generator, context).build();
56+
Optional<PropertyDescriptor> valueTypeProperty = AasUtils.getAasProperties(value.getClass()).stream()
57+
.filter(x -> PROPERTY_VALUE_TYPE_NAME.equals(x.getName()))
58+
.findFirst();
59+
List<AttributeType> untouchedAttributes = original.getAttribute().stream()
60+
.filter(x -> !typedProperties.contains(x.getName()))
61+
.collect(Collectors.toList());
62+
InternalElementType.Builder builder = InternalElementType
63+
.copyOf(original)
64+
.withAttribute(untouchedAttributes);
65+
for (String property : typedProperties) {
66+
Optional<AttributeType> attributeToType = original.getAttribute().stream()
67+
.filter(x -> property.equals(x.getName()))
68+
.findFirst();
69+
if (attributeToType.isPresent()) {
70+
AttributeType.Builder typedAttributeBuilder = AttributeType.copyOf(attributeToType.get());
71+
if (valueTypeProperty.isPresent()) {
72+
try {
73+
typedAttributeBuilder = typedAttributeBuilder.withAttributeDataType(
74+
PROPERTY_VALUE_TYPE_NAMESPACE_PREFIX + valueTypeProperty.get().getReadMethod().invoke(value));
75+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
76+
throw new MappingException(String.format("error reading property %s", PROPERTY_VALUE_TYPE_NAME));
77+
}
78+
}
79+
builder = builder.addAttribute(typedAttributeBuilder.build());
80+
}
81+
}
82+
return builder;
83+
}
84+
85+
@Override
86+
protected AttributeType.Builder toAttribute(T value, AmlGenerator generator, MappingContext context) throws MappingException {
87+
AttributeType original = super.toAttribute(value, generator, context).build();
88+
Optional<PropertyDescriptor> valueTypeProperty = AasUtils.getAasProperties(value.getClass()).stream()
89+
.filter(x -> PROPERTY_VALUE_TYPE_NAME.equals(x.getName()))
90+
.findFirst();
91+
List<AttributeType> untouchedAttributes = original.getAttribute().stream()
92+
.filter(x -> !typedProperties.contains(x.getName()))
93+
.collect(Collectors.toList());
94+
AttributeType.Builder builder = AttributeType
95+
.copyOf(original)
96+
.withAttribute(untouchedAttributes);
97+
for (String property : typedProperties) {
98+
Optional<AttributeType> attributeToType = original.getAttribute().stream()
99+
.filter(x -> property.equals(x.getName()))
100+
.findFirst();
101+
if (attributeToType.isPresent()) {
102+
AttributeType.Builder typedAttributeBuilder = AttributeType.copyOf(attributeToType.get());
103+
if (valueTypeProperty.isPresent()) {
104+
try {
105+
typedAttributeBuilder = typedAttributeBuilder.withAttributeDataType(
106+
PROPERTY_VALUE_TYPE_NAMESPACE_PREFIX + valueTypeProperty.get().getReadMethod().invoke(value));
107+
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
108+
throw new MappingException(String.format("error reading property %s", PROPERTY_VALUE_TYPE_NAME));
109+
}
110+
}
111+
builder = builder.addAttribute(typedAttributeBuilder.build());
112+
}
113+
}
114+
return builder;
115+
}
116+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2021 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e. V.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.adminshell.aas.v3.dataformat.aml.serialization.mappers;
17+
18+
import io.adminshell.aas.v3.dataformat.aml.model.caex.AttributeType;
19+
import io.adminshell.aas.v3.dataformat.aml.model.caex.AttributeType.RefSemantic;
20+
import io.adminshell.aas.v3.dataformat.aml.model.caex.InternalElementType;
21+
import io.adminshell.aas.v3.dataformat.aml.serialization.AmlGenerator;
22+
import io.adminshell.aas.v3.dataformat.aml.serialization.DefaultMapper;
23+
import io.adminshell.aas.v3.dataformat.aml.serialization.MappingContext;
24+
import io.adminshell.aas.v3.dataformat.mapping.MappingException;
25+
import io.adminshell.aas.v3.model.ConceptDescription;
26+
import java.util.List;
27+
import java.util.Optional;
28+
import java.util.stream.Collectors;
29+
30+
public class ConceptDescriptionMapper extends DefaultMapper<ConceptDescription> {
31+
32+
protected static final String PROPERTY_IS_CASE_OF_NAME = "isCaseOf";
33+
protected static final String PROPERTY_IS_CASE_OFS_NAME = PROPERTY_IS_CASE_OF_NAME + "s";
34+
35+
@Override
36+
protected InternalElementType.Builder toInternalElement(ConceptDescription value, AmlGenerator generator, MappingContext context) throws MappingException {
37+
InternalElementType original = super.toInternalElement(value, generator, context).build();
38+
List<AttributeType> untouchedAttributes = original.getAttribute().stream()
39+
.filter(x -> !PROPERTY_IS_CASE_OFS_NAME.equals(x.getName()))
40+
.collect(Collectors.toList());
41+
InternalElementType.Builder builder = InternalElementType
42+
.copyOf(original)
43+
.withAttribute(untouchedAttributes);
44+
Optional<AttributeType> isCaseOfAttribute = original.getAttribute().stream()
45+
.filter(x -> PROPERTY_IS_CASE_OFS_NAME.equals(x.getName()))
46+
.findFirst();
47+
if (isCaseOfAttribute.isPresent()) {
48+
String path = isCaseOfAttribute.get().getRefSemantic().get(0).getCorrespondingAttributePath();
49+
String newPath = path.substring(0, path.lastIndexOf("/") + 1) + PROPERTY_IS_CASE_OF_NAME;
50+
builder = builder.addAttribute(AttributeType
51+
.copyOf(isCaseOfAttribute.get())
52+
.withName(PROPERTY_IS_CASE_OF_NAME)
53+
.withRefSemantic(RefSemantic.copyOf(isCaseOfAttribute.get().getRefSemantic().get(0))
54+
.withCorrespondingAttributePath(newPath)
55+
.build())
56+
.build());
57+
}
58+
return builder;
59+
}
60+
}

dataformat-aml/src/main/java/io/adminshell/aas/v3/dataformat/aml/serialization/mappers/LangStringCollectionMapper.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
import io.adminshell.aas.v3.dataformat.aml.serialization.AmlGenerator;
2020
import io.adminshell.aas.v3.dataformat.aml.serialization.MappingContext;
2121
import io.adminshell.aas.v3.dataformat.aml.model.caex.AttributeType;
22+
import io.adminshell.aas.v3.dataformat.aml.serialization.DefaultCollectionMapper;
2223
import io.adminshell.aas.v3.model.LangString;
2324
import java.lang.reflect.ParameterizedType;
2425
import java.util.Collection;
2526
import java.util.stream.Collectors;
2627

27-
public class LangStringCollectionMapper extends DefaultMapper<Collection<LangString>> {
28+
public class LangStringCollectionMapper extends DefaultCollectionMapper<LangString> {
2829

2930
private static final String NAME_PREFIX = "aml-lang=";
3031

@@ -43,7 +44,12 @@ public void map(Collection<LangString> value, AmlGenerator generator, MappingCon
4344
context.getProperty().getReadMethod().getDeclaringClass(),
4445
value,
4546
context.getProperty().getName()))
46-
.withRefSemantic(generator.refSemantic(context.getProperty()))
47+
.withRefSemantic(generator.refSemantic(
48+
context.getProperty(),
49+
context.getAttributeNamingStrategy().getNameForRefSemantic(
50+
context.getProperty().getReadMethod().getDeclaringClass(),
51+
value,
52+
context.getProperty().getName())))
4753
.addAttribute(value.stream()
4854
.map(x -> AttributeType.builder()
4955
.withName(NAME_PREFIX + x.getLanguage())
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) 2021 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e. V.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.adminshell.aas.v3.dataformat.aml.serialization.mappers;
17+
18+
import io.adminshell.aas.v3.model.Property;
19+
20+
public class PropertyMapper extends AbstractElementMapperWithValueType<Property> {
21+
22+
}

dataformat-aml/src/main/java/io/adminshell/aas/v3/dataformat/aml/serialization/mappers/QualifierMapper.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,12 @@
1515
*/
1616
package io.adminshell.aas.v3.dataformat.aml.serialization.mappers;
1717

18-
import io.adminshell.aas.v3.dataformat.aml.serialization.DefaultMapper;
1918
import io.adminshell.aas.v3.dataformat.aml.serialization.AmlGenerator;
2019
import io.adminshell.aas.v3.dataformat.aml.serialization.MappingContext;
2120
import io.adminshell.aas.v3.dataformat.mapping.MappingException;
2221
import io.adminshell.aas.v3.model.Qualifier;
2322

24-
public class QualifierMapper extends DefaultMapper<Qualifier> {
23+
public class QualifierMapper extends AbstractElementMapperWithValueType<Qualifier> {
2524

2625
@Override
2726
public void map(Qualifier value, AmlGenerator generator, MappingContext context) throws MappingException {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) 2021 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e. V.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.adminshell.aas.v3.dataformat.aml.serialization.mappers;
17+
18+
import io.adminshell.aas.v3.model.Range;
19+
20+
public class RangeMapper extends AbstractElementMapperWithValueType<Range> {
21+
22+
protected static final String PROPERTY_MIN_NAME = "min";
23+
protected static final String PROPERTY_MAX_NAME = "max";
24+
25+
public RangeMapper() {
26+
super(PROPERTY_MIN_NAME, PROPERTY_MAX_NAME);
27+
}
28+
}

0 commit comments

Comments
 (0)