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

Commit 66d3028

Browse files
Add recursive finding of internal elements.
Some refactoring
1 parent 2bd797f commit 66d3028

4 files changed

Lines changed: 87 additions & 86 deletions

File tree

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

Lines changed: 74 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
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+
2324
import java.beans.IntrospectionException;
2425
import java.beans.Introspector;
2526
import java.beans.PropertyDescriptor;
@@ -63,8 +64,8 @@ public T map(AmlParser parser, MappingContext context) throws MappingException {
6364
return (T) fromAttribute(parser, (AttributeType) parser.getCurrent(), context);
6465
} else if (InternalElementType.class.isAssignableFrom(parser.getCurrent().getClass())) {
6566
return (T) fromInternalElement(parser, (InternalElementType) parser.getCurrent(), context);
66-
} else if(SystemUnitFamilyType.class.isAssignableFrom(parser.getCurrent().getClass())){
67-
return (T) fromSystemUnitFamily(parser, (SystemUnitFamilyType) parser.getCurrent(),context);
67+
} else if (SystemUnitFamilyType.class.isAssignableFrom(parser.getCurrent().getClass())) {
68+
return (T) fromSystemUnitFamily(parser, (SystemUnitFamilyType) parser.getCurrent(), context);
6869
}
6970
} else {
7071
if (Collection.class.isAssignableFrom(context.getProperty().getReadMethod().getReturnType())) {
@@ -79,9 +80,9 @@ public T map(AmlParser parser, MappingContext context) throws MappingException {
7980
/**
8081
* Reads expected object from given attribute.
8182
*
82-
* @param parser the AML parser
83+
* @param parser the AML parser
8384
* @param attribute the attribute to read from
84-
* @param context the mapping context
85+
* @param context the mapping context
8586
* @return the read object or null if not present
8687
* @throws MappingException if reading object fails
8788
*/
@@ -124,9 +125,9 @@ protected Object getValue(AttributeType attribute) {
124125
/**
125126
* Reads expected object from given InternalElement.
126127
*
127-
* @param parser the AML parser
128+
* @param parser the AML parser
128129
* @param internalElement the InternalElement to read from
129-
* @param context the mapping context
130+
* @param context the mapping context
130131
* @return the read object or null if not present
131132
* @throws MappingException if reading object fails
132133
*/
@@ -143,9 +144,9 @@ protected Object fromInternalElement(AmlParser parser, InternalElementType inter
143144
/**
144145
* Reads expected object from given SystemUnitFamily.
145146
*
146-
* @param parser the AML parser
147+
* @param parser the AML parser
147148
* @param systemUnitFamilyType the SystemUnitFamily to read from
148-
* @param context the mapping context
149+
* @param context the mapping context
149150
* @return the read object or null if not present
150151
* @throws MappingException if reading object fails
151152
*/
@@ -163,8 +164,8 @@ protected Object fromSystemUnitFamily(AmlParser parser, SystemUnitFamilyType sys
163164
* Recursively calls context.map(...) on all properties except those
164165
* explicitely ignored and sets them on the parent.
165166
*
166-
* @param parent the parent object to read all properties for
167-
* @param parser the AMLParser
167+
* @param parent the parent object to read all properties for
168+
* @param parser the AMLParser
168169
* @param context the MappingContext
169170
* @throws MappingException if mapping fails
170171
*/
@@ -193,8 +194,8 @@ protected void mapProperties(Object parent, AmlParser parser, MappingContext con
193194
/**
194195
* Helper method to create a new instance for a given type.
195196
*
196-
* @param <T> type information
197-
* @param type type to instantiate
197+
* @param <T> type information
198+
* @param type type to instantiate
198199
* @param context the MappingContext
199200
* @return an instance of the provided type
200201
* @throws MappingException if instantiation fails
@@ -209,7 +210,7 @@ protected <T> T newInstance(Class<T> type, MappingContext context) throws Mappin
209210

210211
protected Class<?> getAasType(String name) {
211212
return Stream.concat(ReflectionHelper.INTERFACES.stream(),
212-
ReflectionHelper.INTERFACES_WITHOUT_DEFAULT_IMPLEMENTATION.stream())
213+
ReflectionHelper.INTERFACES_WITHOUT_DEFAULT_IMPLEMENTATION.stream())
213214
.filter(x -> x.getSimpleName().equals(name))
214215
.findAny()
215216
.orElse(null);
@@ -232,7 +233,7 @@ protected boolean isAasType(Class<?> type) {
232233
* @param attribute The attribute to extract the type from
233234
* @return the type of the attribute
234235
* @throws MappingException if type information is missing or invalid or
235-
* type could not be resolved
236+
* type could not be resolved
236237
*/
237238
protected Class<?> typeFromAttribute(AttributeType attribute, MappingContext context) throws MappingException {
238239
if (attribute.getRefSemantic() == null || attribute.getRefSemantic().isEmpty()) {
@@ -263,7 +264,7 @@ protected Class<?> typeFromAttribute(AttributeType attribute, MappingContext con
263264
// Optional<PropertyDescriptor> property = AasUtils.getAasProperties(type.get()).stream().filter(x -> x.getName().equals(type)).findFirst();
264265
try {
265266

266-
String oldPropertyName = ((PropertyNamingStrategy)context.getPropertyNamingStrategy()).getOldName(type, attribute,attributePathElements[1]);
267+
String oldPropertyName = ((PropertyNamingStrategy) context.getPropertyNamingStrategy()).getOldName(type, attribute, attributePathElements[1]);
267268
Optional<PropertyDescriptor> property = Stream.of(Introspector.getBeanInfo(type).getPropertyDescriptors())
268269
.filter(x -> x.getName().equalsIgnoreCase(oldPropertyName == null ? attributePathElements[1] : oldPropertyName)).findFirst();
269270
if (property.isPresent()) {
@@ -285,7 +286,7 @@ protected Class<?> typeFromAttribute(AttributeType attribute, MappingContext con
285286
* @param internalElement The InternalElement to extract the type from
286287
* @return the type of the attribute
287288
* @throws MappingException if type information is missing or invalid or
288-
* type could not be resolved
289+
* type could not be resolved
289290
*/
290291
protected Class<?> typeFromInternalElement(InternalElementType internalElement) throws MappingException {
291292
if (internalElement.getRoleRequirements() == null || internalElement.getRoleRequirements().getRefBaseRoleClassPath() == null) {
@@ -310,7 +311,7 @@ protected Class<?> typeFromInternalElement(InternalElementType internalElement)
310311
* @param systemUnitFamilyType The SystemUnitFamily to extract the type from
311312
* @return the type of the attribute
312313
* @throws MappingException if type information is missing or invalid or
313-
* type could not be resolved
314+
* type could not be resolved
314315
*/
315316
protected Class<?> typeFromSystemUnit(SystemUnitFamilyType systemUnitFamilyType) throws MappingException {
316317
if (systemUnitFamilyType.getSupportedRoleClass() == null || systemUnitFamilyType.getSupportedRoleClass().get(0) == null) {
@@ -346,19 +347,19 @@ protected Collection mapCollectionValueProperty(AmlParser parser, MappingContext
346347
return result;
347348
} else {
348349
AttributeType attribute = findAttribute(parser.getCurrent(), context.getProperty(), context, parser.getRefSemanticPrefix());
349-
if(attribute==null)return null;
350+
if (attribute == null) return null;
350351
List<AttributeType> attributeTypes = attribute.getAttribute();
351352
Collection result = new ArrayList<>();
352353
CAEXObject current = parser.getCurrent();
353-
if(!attributeTypes.isEmpty()){
354-
for(AttributeType attributeType : attributeTypes){
354+
if (!attributeTypes.isEmpty()) {
355+
for (AttributeType attributeType : attributeTypes) {
355356
parser.setCurrent(attributeType);
356-
Object object = context.withoutProperty().map(contentType,parser);
357+
Object object = context.withoutProperty().map(contentType, parser);
357358
result.add(object);
358359
}
359360
} else {
360361
parser.setCurrent(attribute);
361-
Object object = context.withoutProperty().map(contentType,parser);
362+
Object object = context.withoutProperty().map(contentType, parser);
362363
result.add(object);
363364
}
364365
parser.setCurrent(current);
@@ -406,26 +407,26 @@ protected Object propertyFromAttribute(AmlParser parser, AttributeType attribute
406407
return result;
407408
}
408409

409-
protected String getDataTypeFromAttribute(AttributeType attributeType){
410-
if(attributeType == null || attributeType.getAttributeDataType() == null){
410+
protected String getDataTypeFromAttribute(AttributeType attributeType) {
411+
if (attributeType == null || attributeType.getAttributeDataType() == null) {
411412
return null;
412413
}
413414
String attributeDataType = attributeType.getAttributeDataType();
414415
return attributeDataType.substring(attributeDataType.lastIndexOf(":") + 1);
415416
}
416417

417418
protected void setValueDataTypeFromAttributeDataType(AmlParser parser, Object parent, String attributeRefWithAttributeDataType, Class aasClazz) throws MappingException {
418-
if(parser == null || parent == null)return;
419+
if (parser == null || parent == null) return;
419420

420421
AttributeType attributeType = findAttributesByCorrespondingAttributePath(parser.getCurrent(),
421422
attributeRefWithAttributeDataType).stream().findFirst().orElse(null);
422-
if(attributeType != null){
423+
if (attributeType != null) {
423424
try {
424425
String dataType = getDataTypeFromAttribute(attributeType);
425426
List<Method> methods = List.of(aasClazz.getMethods());
426-
Method method = methods.stream().filter(x->x.getName().contains("setValueType")).findFirst().orElse(null);
427-
if(method == null)return;
428-
method.invoke(parent,dataType);
427+
Method method = methods.stream().filter(x -> x.getName().contains("setValueType")).findFirst().orElse(null);
428+
if (method == null) return;
429+
method.invoke(parent, dataType);
429430
} catch (InvocationTargetException | IllegalAccessException ex) {
430431
throw new MappingException(String.format("error setting value type for property with ID=%s and Name=%s", parser.getCurrent().getID(), parser.getCurrent().getName()), ex);
431432
}
@@ -447,7 +448,7 @@ protected String findInternalLinkTarget(InternalElementType internalElement, Pro
447448
}
448449

449450
protected AttributeType findAttribute(CAEXObject parent, PropertyDescriptor property, MappingContext context) throws MappingException {
450-
return findAttribute(parent, property,context,AmlParser.DEFAULT_REFSEMANTIC_PREFIX);
451+
return findAttribute(parent, property, context, AmlParser.DEFAULT_REFSEMANTIC_PREFIX);
451452
}
452453

453454
protected AttributeType findAttribute(CAEXObject parent, PropertyDescriptor property, MappingContext context, String refSemanticPrefix) throws MappingException {
@@ -464,7 +465,7 @@ protected AttributeType findAttribute(CAEXObject parent, PropertyDescriptor prop
464465

465466
// TODO not working because of missing property renaming strategy
466467
protected List<AttributeType> findAttributes(CAEXObject parent, PropertyDescriptor property, MappingContext context) {
467-
return findAttributes(parent, property,context, AmlParser.DEFAULT_REFSEMANTIC_PREFIX);
468+
return findAttributes(parent, property, context, AmlParser.DEFAULT_REFSEMANTIC_PREFIX);
468469
}
469470

470471
protected List<AttributeType> findAttributes(CAEXObject parent, PropertyDescriptor property, MappingContext context, String refSemanticPrefix) {
@@ -476,7 +477,7 @@ protected List<AttributeType> findAttributes(CAEXObject parent, PropertyDescript
476477
return findAttributesByCorrespondingAttributePath(parent, refSemantic);
477478
}
478479

479-
protected List<AttributeType> findAttributesByCorrespondingAttributePath(CAEXObject parent, String correspondingAttributePath){
480+
protected List<AttributeType> findAttributesByCorrespondingAttributePath(CAEXObject parent, String correspondingAttributePath) {
480481
return findAttributes(parent,
481482
x -> x.getRefSemantic().stream().anyMatch(y -> y.getCorrespondingAttributePath().equalsIgnoreCase(correspondingAttributePath)));
482483
}
@@ -489,63 +490,25 @@ protected List<AttributeType> findAttributes(CAEXObject parent, Predicate<Attrib
489490
return ((AttributeType) parent).getAttribute().stream().filter(filter).collect(Collectors.toList());
490491
} else if (InternalElementType.class.isAssignableFrom(parent.getClass())) {
491492
return ((InternalElementType) parent).getAttribute().stream().filter(filter).collect(Collectors.toList());
492-
} else if(SystemUnitFamilyType.class.isAssignableFrom(parent.getClass())) {
493+
} else if (SystemUnitFamilyType.class.isAssignableFrom(parent.getClass())) {
493494
return ((SystemUnitFamilyType) parent).getAttribute().stream().filter(filter).collect(Collectors.toList());
494495
}
495496
return List.of();
496497
}
497498

498499
protected List<InternalElementType> findInternalElements(CAEXObject parent, Class desiredType, boolean acceptSubtypes, MappingContext context) {
499-
if (parent == null || !(InternalElementType.class.isAssignableFrom(parent.getClass()) || SystemUnitFamilyType.class.isAssignableFrom(parent.getClass()))) {
500+
if (parent == null || !(SystemUnitClassType.class.isAssignableFrom(parent.getClass()))) {
500501
return List.of();
501502
}
502-
503-
if(SystemUnitFamilyType.class.isAssignableFrom(parent.getClass())){
504-
return findInternalElements((SystemUnitFamilyType) parent, desiredType,acceptSubtypes,context);
505-
}
506-
507-
return findInternalElements((InternalElementType) parent, desiredType, acceptSubtypes, context);
503+
return findInternalElements((SystemUnitClassType) parent, desiredType, acceptSubtypes, context);
508504
}
509505

510-
protected List<InternalElementType> findInternalElements(SystemUnitFamilyType parent, Class desiredType, boolean acceptSubtypes, MappingContext context) {
511-
if (desiredType == null || context == null || parent == null) {
512-
return List.of();
513-
}
514-
Predicate<InternalElementType> filter = x -> {
515-
String role = x.getRoleRequirements() != null ? x.getRoleRequirements().getRefBaseRoleClassPath() : "";
516-
if (role.startsWith(context.getDocumentInfo().getAssetAdministrationShellRoleClassLib())) {
517-
String actualClassName = role.substring(context.getDocumentInfo().getAssetAdministrationShellRoleClassLib().length() + 1);
518-
Optional<Class> actualType = ReflectionHelper.INTERFACES.stream().filter(y -> y.getSimpleName().equals(actualClassName)).findFirst();
519-
if (actualType.isPresent()) {
520-
if (acceptSubtypes) {
521-
return desiredType.isAssignableFrom(actualType.get());
522-
}
523-
return desiredType.equals(actualType.get());
524-
}
525-
}
526-
return false;
527-
};
528-
return parent.getInternalElement().stream().filter(filter).collect(Collectors.toList());
529-
}
530506

531-
protected List<InternalElementType> findInternalElements(InternalElementType parent, Class desiredType, boolean acceptSubtypes, MappingContext context) {
507+
protected List<InternalElementType> findInternalElements(SystemUnitClassType parent, Class desiredType, boolean acceptSubtypes, MappingContext context) {
532508
if (desiredType == null || context == null) {
533509
return List.of();
534510
}
535-
return findInternalElements(parent, x -> {
536-
String role = x.getRoleRequirements() != null ? x.getRoleRequirements().getRefBaseRoleClassPath() : "";
537-
if (role.startsWith(context.getDocumentInfo().getAssetAdministrationShellRoleClassLib())) {
538-
String actualClassName = role.substring(context.getDocumentInfo().getAssetAdministrationShellRoleClassLib().length() + 1);
539-
Optional<Class> actualType = ReflectionHelper.INTERFACES.stream().filter(y -> y.getSimpleName().equals(actualClassName)).findFirst();
540-
if (actualType.isPresent()) {
541-
if (acceptSubtypes) {
542-
return desiredType.isAssignableFrom(actualType.get());
543-
}
544-
return desiredType.equals(actualType.get());
545-
}
546-
}
547-
return false;
548-
});
511+
return getAllMatchingInternalElements(null, parent, desiredType, acceptSubtypes, context);
549512
}
550513

551514
protected List<InternalElementType> findInternalElements(CAEXObject parent, Predicate<InternalElementType> filter) {
@@ -559,11 +522,45 @@ protected List<InternalElementType> findInternalElements(InternalElementType par
559522
if (parent == null || filter == null) {
560523
return List.of();
561524
}
562-
return parent.getInternalElement().stream().filter(filter).collect(Collectors.toList());
525+
return getAllInternalElements(null, parent).stream().filter(filter).collect(Collectors.toList());
563526
}
564527

565-
private void getAllMatchingInternalElements(Predicate<InternalElementType> filter, List<InternalElementType> resultList){
566528

529+
//get recursive all internal elements of parent
530+
private List<InternalElementType> getAllInternalElements(List<InternalElementType> resultList, SystemUnitClassType parent) {
531+
if (resultList == null) resultList = new ArrayList<>();
532+
resultList.addAll(parent.getInternalElement());
533+
for (InternalElementType internalElementType : parent.getInternalElement()) {
534+
getAllInternalElements(resultList, internalElementType);
535+
}
536+
return resultList;
537+
}
538+
539+
private List<InternalElementType> getAllMatchingInternalElements(List<InternalElementType> resultList,
540+
SystemUnitClassType parent, Class desiredType,
541+
boolean acceptSubtypes, MappingContext context) {
542+
543+
if(resultList == null)resultList= new ArrayList<>();
544+
545+
List<InternalElementType> internalElementTypes = parent.getInternalElement();
546+
for(InternalElementType internalElement : internalElementTypes){
547+
String role = internalElement.getRoleRequirements() != null ? internalElement.getRoleRequirements().getRefBaseRoleClassPath() : "";
548+
if (role.startsWith(context.getDocumentInfo().getAssetAdministrationShellRoleClassLib())) {
549+
String actualClassName = role.substring(context.getDocumentInfo().getAssetAdministrationShellRoleClassLib().length() + 1);
550+
Optional<Class> actualType = ReflectionHelper.INTERFACES.stream().filter(y -> y.getSimpleName().equals(actualClassName)).findFirst();
551+
if (actualType.isPresent()) {
552+
if (acceptSubtypes && desiredType.isAssignableFrom(actualType.get())) {
553+
resultList.add(internalElement);
554+
} else if(desiredType.equals(actualType.get())){
555+
resultList.add(internalElement);
556+
}
557+
}
558+
} else {
559+
getAllMatchingInternalElements(resultList, internalElement, desiredType, acceptSubtypes, context);
560+
}
561+
}
562+
563+
return resultList;
567564
}
568565

569566

0 commit comments

Comments
 (0)