Skip to content
This repository was archived by the owner on Feb 15, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
34c56ab
Fix QualifierType
br-iosb Sep 24, 2021
4e21ae2
Fix for Operations
br-iosb Sep 24, 2021
4dde61d
Fixes for Optional Category and AdministrativeInformation
br-iosb Sep 24, 2021
94f8ea7
Updated NodeSet
br-iosb Sep 24, 2021
4cfe3f0
Operation Mapping
br-iosb Sep 24, 2021
2be965b
Update Opc.Ua.I4AAS_V3Draft.NodeSet2.xml
br-iosb Sep 24, 2021
7f9519a
Folders are optional now, only created when list is not empty
br-iosb Sep 24, 2021
9fb2432
Merge branch 'admin-shell-io:main' into fix/ua-nodeset-fixes
br-iosb Sep 27, 2021
3f2da69
fix IdShort in test objects
br-iosb Sep 27, 2021
dd2ed6e
first adjustments to AASUtils resolve
br-iosb Sep 27, 2021
a6c21b1
fix for NPE when no implementation class is available
br-iosb Sep 27, 2021
d4f691c
optimized logger statement
br-iosb Sep 27, 2021
f3c2b57
Changed UAObject as Key since Reference Object might be duplicates
br-iosb Sep 29, 2021
7a77ae8
experimental tests and adjustments
br-iosb Sep 29, 2021
f52da0f
Fix LangString for DisplayName
br-iosb Oct 6, 2021
66fb1ee
Comment IDShort of CD
br-iosb Oct 6, 2021
17a646a
Comment on missing mapping rule for KeyElements of CD
br-iosb Oct 6, 2021
30cac1b
Added missing ValueTypeParser
br-iosb Oct 6, 2021
9f2b742
Merge pull request #5 from admin-shell-io/main
br-iosb Oct 25, 2021
d81320e
Merge remote-tracking branch 'origin/main' into fix/ua-nodeset-fixes
br-iosb Oct 25, 2021
2c21f7a
Update ValueTypeMapper.java
br-iosb Oct 25, 2021
02e30f6
Test Updates with Validation
br-iosb Oct 25, 2021
2b0b31c
Update IntegrationTests.java
br-iosb Oct 25, 2021
5f082d4
Added License Header
br-iosb Oct 26, 2021
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ local.properties
**.flattened-pom.xml
nbactions.xml
testJsonSerialization.json
dataformat-uanodeset/jsonExpected.json
dataformat-uanodeset/jsonActual.json
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ public static <T extends Referable> T resolve(Reference reference, AssetAdminist
int i = reference.getKeys().size() - 1;
if (type != null) {
Class<?> actualType = keyTypeToClass(reference.getKeys().get(i).getType());
if (actualType == null) {
log.warn("reference {} could not be resolved as key type has no known class.",
asString(reference));
return null;
}
if (!type.isAssignableFrom(actualType)) {
log.warn("reference {} could not be resolved as target type is not assignable from actual type (target: {}, actual: {})",
asString(reference), type.getName(), actualType.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ AASIdentifiableType_Identification,5037,Object
AASKeyDataType_Encoding_DefaultBinary,5038,Object
AASKeyDataType_Encoding_DefaultXml,5039,Object
AASKeyDataType_Encoding_DefaultJson,5040,Object
AASOperationType_InputVariable,5041,Object
AASOrderedSubmodelElementCollectionType_SubmodelElement,5042,Object
AASCustomConceptDescriptionType_DataSpecification,5043,Object
AASIrdiConceptDescriptionType_IsCaseOf,5044,Object
Expand All @@ -100,6 +101,8 @@ AASEnvironmentType_AAS_AssetInformation_BillOfMaterial,5047,Object
AASCustomConceptDescriptionType_IsCaseOf,5048,Object
AASAssetInformationType_SpecificAssetId,5049,Object
AASAssetAdministrationShellType_AssetInformation_SpecificAssetId,5050,Object
AASOperationType_OutputVariable,5051,Object
AASOperationType_InOutputVariable,5052,Object
AASEnvironmentType_AAS_Identification,5101,Object
AASEnvironmentType_Asset,5103,Object
AASEnvironmentType_Asset_Administration,5150,Object
Expand Down
154 changes: 87 additions & 67 deletions dataformat-uanodeset/nodeset/i4aas/Opc.Ua.I4AAS_V3Draft.NodeSet2.xml

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions dataformat-uanodeset/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.admin-shell.aas</groupId>
<artifactId>dataformat-json</artifactId>
<version>${revision}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.admin-shell.aas</groupId>
<artifactId>validator</artifactId>
<version>${revision}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>${jsonassert.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
import io.adminshell.aas.v3.model.AssetAdministrationShell;
import io.adminshell.aas.v3.model.AssetInformation;

public class AssetAdministrationShellMapper extends IdentifiableMapper<AssetAdministrationShell> implements HasDataSpecificationMapper {
public class AssetAdministrationShellMapper extends IdentifiableMapper<AssetAdministrationShell>
implements HasDataSpecificationMapper {

public AssetAdministrationShellMapper(AssetAdministrationShell src, MappingContext ctx) {
super(src, ctx);
Expand All @@ -47,14 +48,15 @@ protected void mapAndAttachChildren() {

private void mapAsset() {
AssetInformation assetInformation = source.getAssetInformation();
if (assetInformation != null) {
if (assetInformation != null) {
UAObject uaAsset = new AssetInformationMapper(assetInformation, ctx).map();
attachAsComponent(target, uaAsset);
}
}

private void mapSubmodels() {
UAObject smFolder = createReferenceList(AAS_SUBMODELREFERENCES_LIST_BROWSENAME);
UAObject smFolder = source.getSubmodels().isEmpty() ? null
: createReferenceList(AAS_SUBMODELREFERENCES_LIST_BROWSENAME);
List<io.adminshell.aas.v3.model.Reference> submodels = source.getSubmodels();
for (int i = 0; i < submodels.size(); i++) {
io.adminshell.aas.v3.model.Reference reference = submodels.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ protected void mapAndAttachChildren() {
attachAsComponent(target, uaIdentification);
}

UAObject uaBomList = createReferenceList(ASSETINFO_BILL_OF_MATERIAL_BROWSENAME);
List<Reference> billOfMaterials = source.getBillOfMaterials();
UAObject uaBomList = billOfMaterials.isEmpty() ? null : createReferenceList(ASSETINFO_BILL_OF_MATERIAL_BROWSENAME);
for (int i = 0; i < billOfMaterials.size(); i++) {
Reference reference = billOfMaterials.get(i);
UAObject uaBomListEntry = new ReferenceMapper(reference, ctx, ASSETINFO_BILL_OF_MATERIAL_BROWSENAME + "_" + i).map();
Expand All @@ -70,7 +70,7 @@ protected void mapAndAttachChildren() {
attachAsComponent(target, uaThumbnail);
}

UAObject folder = createIdentifierKeyValuePairList(ASSETINFO_SPECIFIC_ASSET_ID_BROWSENAME);
UAObject folder = source.getSpecificAssetIds().isEmpty() ? null : createIdentifierKeyValuePairList(ASSETINFO_SPECIFIC_ASSET_ID_BROWSENAME);
for (IdentifierKeyValuePair identifierKeyValuePair : source.getSpecificAssetIds()) {
UAObject uaIdKVP = new IdentifierKeyValuePairMapper(identifierKeyValuePair, ctx).map();
attachAsComponent(folder, uaIdKVP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
import io.adminshell.aas.v3.model.IdentifierType;
import io.adminshell.aas.v3.model.Reference;

public class ConceptDescriptionMapper extends IdentifiableMapper<ConceptDescription> implements HasDataSpecificationMapper {
public class ConceptDescriptionMapper extends IdentifiableMapper<ConceptDescription>
implements HasDataSpecificationMapper {

public ConceptDescriptionMapper(ConceptDescription src, MappingContext ctx) {
super(src, ctx);
Expand All @@ -43,12 +44,12 @@ protected UAObject createTargetObject() {
} else if (IdentifierType.CUSTOM == idType) {
addTypeReference(I4AASIdentifier.AASCustomConceptDescriptionType);
}
if (identification.getIdentifier() != null) {
//conflict: I4AAS says idshort, OPC UA says value
target.setBrowseName(createModelBrowseName(identification.getIdentifier()));
}
// if (identification.getIdentifier() != null) {
// // TODO: I4AAS says idshort, OPC UA says value. Currently there is no mapping target for IdShort of ConceptDescription
// target.setBrowseName(createModelBrowseName(identification.getIdentifier()));
// }
}

return target;
}

Expand All @@ -58,12 +59,11 @@ protected void mapAndAttachChildren() {

mapDataSpecification(source, target, ctx);

UAObject createFolder = createReferenceList("IsCaseOf");
UAObject createFolder = source.getIsCaseOfs().isEmpty() ? null : createReferenceList("IsCaseOf");
for (Reference reference : source.getIsCaseOfs()) {
UAObject uaRef = new ReferenceMapper(reference, ctx, reference.getKeys().get(0).getValue()).map();
attachAsComponent(createFolder, uaRef);
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ public interface HasDataSpecificationMapper {

public default void mapDataSpecification(HasDataSpecification source, UAObject target, MappingContext ctx) {

UAObject folder = I4AASMapper.createFolder(target, I4AASConstants.DATASPECIFICATION_BROWSENAME, ctx,
I4AASIdentifier.AASReferenceList);
UAObject folder = source.getEmbeddedDataSpecifications().isEmpty() ? null
: I4AASMapper.createFolder(target, I4AASConstants.DATASPECIFICATION_BROWSENAME, ctx,
I4AASIdentifier.AASReferenceList);

List<EmbeddedDataSpecification> embeddedDataSpecifications = source.getEmbeddedDataSpecifications();
for (int i = 0; i < embeddedDataSpecifications.size(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ protected String deriveDefaultName() {
if (source instanceof io.adminshell.aas.v3.model.IdentifierType) {
return IDENTIFICATION_IDTYPE_BROWSENAME;
}
if (source instanceof io.adminshell.aas.v3.model.DataTypeIEC61360) {
return IDENTIFICATION_DATATYPE_BROWSENAME;
}
return source.getClass().getSimpleName();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.adminshell.aas.v3.dataformat.i4aas.mappers;

import java.util.List;

import org.opcfoundation.ua._2011._03.uanodeset.ListOfReferences;
import org.opcfoundation.ua._2011._03.uanodeset.LocalizedText;
import org.opcfoundation.ua._2011._03.uanodeset.Reference;
Expand All @@ -23,19 +25,24 @@
import org.opcfoundation.ua._2011._03.uanodeset.UAObject;
import org.opcfoundation.ua._2011._03.uanodeset.UAVariable;

import com.google.common.base.Strings;

import io.adminshell.aas.v3.dataformat.i4aas.mappers.utils.BasicIdentifier;
import io.adminshell.aas.v3.dataformat.i4aas.mappers.utils.I4AASConstants;
import io.adminshell.aas.v3.dataformat.i4aas.mappers.utils.I4AASIdentifier;
import io.adminshell.aas.v3.dataformat.i4aas.mappers.utils.UaIdentifier;
import io.adminshell.aas.v3.model.LangString;
import io.adminshell.aas.v3.model.Referable;

/**
* Generic base class used for all mapper implementation.
* Generic base class used for all mapper implementation.
*
* @param <SOURCE> mapping source
* @param <TARGET> mapping target
*/
public abstract class I4AASMapper<SOURCE, TARGET extends UANode> implements I4AASConstants{
public abstract class I4AASMapper<SOURCE, TARGET extends UANode> implements I4AASConstants {

public static boolean CHECK_NS_INTERN_REFERENCES_ATTACHED = false;

protected MappingContext ctx;
protected SOURCE source;
Expand All @@ -57,16 +64,37 @@ public final TARGET map() {
target = createTargetObject();
addToNodeset();
mapAndAttachChildren();
if (CHECK_NS_INTERN_REFERENCES_ATTACHED) {
checkChildrenAttached();
}
return target;
}

private void checkChildrenAttached() {
target.getReferences().getReference().forEach(ref -> {
if (ref.getValue().startsWith("ns=" + ctx.getModelNsIndex())) {
List<UANode> uaObjectOrUAVariableOrUAMethod = ctx.getNodeSet().getUAObjectOrUAVariableOrUAMethod();
boolean found = false;
for (UANode uaNode : uaObjectOrUAVariableOrUAMethod) {
found = found || uaNode.getNodeId().equals(ref.getValue());
}
if (!found) {
throw new IllegalStateException(
String.format("parent %s misses child %s", target.getNodeId(), ref.getValue()));
}
}
});
}

/**
* @return return the object filled with attributes directly bound to the target.
* @return return the object filled with attributes directly bound to the
* target.
*/
protected abstract TARGET createTargetObject();

/**
* action to be called when the children objects must be mapped and attached to the target.
* action to be called when the children objects must be mapped and attached to
* the target.
*/
protected abstract void mapAndAttachChildren();

Expand All @@ -92,12 +120,14 @@ private static final void addTypeReferenceFor(UANode anyNode, BasicIdentifier id
}
ListOfReferences references = anyNode.getReferences();
if (idForType instanceof I4AASIdentifier) {
references.getReference().add(Reference.builder().withReferenceType(UaIdentifier.HasTypeDefinition.getName())
.withValue(ctx.getI4aasNodeIdAsString((I4AASIdentifier) idForType)).build());
references.getReference()
.add(Reference.builder().withReferenceType(UaIdentifier.HasTypeDefinition.getName())
.withValue(ctx.getI4aasNodeIdAsString((I4AASIdentifier) idForType)).build());
}
if (idForType instanceof UaIdentifier) {
references.getReference().add(Reference.builder().withReferenceType(UaIdentifier.HasTypeDefinition.getName())
.withValue(ctx.getUaBaseNodeIdAsString((UaIdentifier) idForType)).build());
references.getReference()
.add(Reference.builder().withReferenceType(UaIdentifier.HasTypeDefinition.getName())
.withValue(ctx.getUaBaseNodeIdAsString((UaIdentifier) idForType)).build());
}
}

Expand All @@ -108,11 +138,18 @@ protected static final LocalizedText createLocalizedText(String value) {
protected final String createBrowseName(String name, int namespaceIndx) {
return namespaceIndx + ":" + name;
}

protected final String createModelBrowseName(String name) {
return ctx.getModelNsIndex() + ":" + name;
}


protected final String createModelBrowseName(Referable ref) {
if (ref != null && !Strings.isNullOrEmpty(ref.getIdShort())) {
return ctx.getModelNsIndex() + ":" + ref.getIdShort();
}
throw new IllegalArgumentException("Referable is null or does not contain a valid IdShort.");
}

protected final String createI4AASBrowseName(String name) {
return ctx.getI4aasNsIndex() + ":" + name;
}
Expand All @@ -125,7 +162,8 @@ private static final String createI4AASBrowseName(String name, MappingContext ct
return ctx.getI4aasNsIndex() + ":" + name;
}

public static final UAObject createFolder(UAObject target, String folderName, MappingContext ctx, BasicIdentifier folderSubtype) {
public static final UAObject createFolder(UAObject target, String folderName, MappingContext ctx,
BasicIdentifier folderSubtype) {
UAObject folder = UAObject.builder().withNodeId(ctx.newModelNodeIdAsString())
.withBrowseName(createI4AASBrowseName(folderName, ctx)).withDisplayName(createLocalizedText(folderName))
.build();
Expand All @@ -134,18 +172,17 @@ public static final UAObject createFolder(UAObject target, String folderName, Ma
attachAsComponent((UAObject) target, folder);
return folder;
}


public final UAObject createReferenceList(String folderName) {
return createFolder((UAObject) target, folderName, ctx, I4AASIdentifier.AASReferenceList);
}

public final UAObject createSubmodelElementList(String folderName){
return createFolder((UAObject)target, folderName, ctx, I4AASIdentifier.AASSubmodelElementList);
public final UAObject createSubmodelElementList(String folderName) {
return createFolder((UAObject) target, folderName, ctx, I4AASIdentifier.AASSubmodelElementList);
}

public final UAObject createIdentifierKeyValuePairList(String folderName) {
return createFolder((UAObject)target, folderName, ctx, I4AASIdentifier.AASIdentifierKeyValuePairList);
return createFolder((UAObject) target, folderName, ctx, I4AASIdentifier.AASIdentifierKeyValuePairList);
}

protected static void attachAsType(UAInstance parent, UAInstance child, BasicIdentifier typeId) {
Expand All @@ -167,8 +204,8 @@ protected static final void attachAsProperty(UAObject parent, UAVariable child)
child.setParentNodeId(parent.getNodeId());
attachAsType(parent, child, UaIdentifier.HasProperty);
}
protected static final void attachAsComponent(UAObject parent, UAObject child) {

protected static final void attachAsComponent(UAObject parent, UAInstance child) {
child.setParentNodeId(parent.getNodeId());
attachAsType(parent, child, UaIdentifier.HasComponent);
}
Expand All @@ -177,11 +214,11 @@ protected static final void attachAsOrderedComponent(UAObject parent, UAObject c
child.setParentNodeId(parent.getNodeId());
attachAsType(parent, child, UaIdentifier.HasOrderedComponent);
}

protected static final void attachAsDictionaryEntry(UAObject parent, UAObject child) {
attachAsType(parent, child, UaIdentifier.HasDictionaryEntry);
}

protected static final void attachAsAddIn(UAObject parent, UAObject child) {
attachAsType(parent, child, UaIdentifier.HasAddIn);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ private void mapIdentification() {
UAVariable mappedEnum = new I4AASEnumMapper(sourceIdType, ctx).map();
attachAsProperty(uaObject, mappedEnum);
}

ctx.addIdentifierUaObject(source.getIdentification(), target);
}

private void mapAdministration() {
UAObject uaAdministration = new AdministrationMapper(source.getAdministration(), ctx).map();
attachAsComponent(target, uaAdministration);
if (source.getAdministration() != null) {
UAObject uaAdministration = new AdministrationMapper(source.getAdministration(), ctx).map();
attachAsComponent(target, uaAdministration);
}
}

}
Loading