Search in sources :

Example 1 with StructureType

use of org.eclipse.milo.opcua.stack.core.types.enumerated.StructureType in project milo by eclipse.

the class DataTypeDictionaryGenerator method createStructuredType.

private StructuredType createStructuredType(StructureDescription description) {
    QualifiedName name = description.getName();
    StructureDefinition definition = description.getStructureDefinition();
    StructureType structureType = definition.getStructureType();
    StructuredType structuredType = new StructuredType();
    structuredType.setName(name.getName());
    // Create a combined list of StructuredFields from all parent types
    LinkedList<StructureDefinition> definitions = new LinkedList<>();
    definitions.addFirst(definition);
    NodeId baseDataTypeId = definition.getBaseDataType();
    while (baseDataTypeId != null && baseDataTypeId.isNotNull() && !Identifiers.Structure.equals(baseDataTypeId) && !Identifiers.Union.equals(baseDataTypeId)) {
        StructureDescription baseDescription = structureDescriptions.get(baseDataTypeId);
        StructureDefinition baseDefinition = baseDescription.getStructureDefinition();
        definitions.addFirst(baseDefinition);
        baseDataTypeId = baseDefinition.getBaseDataType();
    }
    LinkedHashMap<String, StructureField> allFields = new LinkedHashMap<>();
    for (StructureDefinition d : definitions) {
        for (StructureField f : d.getFields()) {
            allFields.put(f.getName(), f);
        }
    }
    List<StructureField> fields = new ArrayList<>(allFields.values());
    if (structureType == StructureType.StructureWithOptionalFields) {
        int optionalFieldCount = 0;
        for (StructureField field : fields) {
            if (field.getIsOptional()) {
                optionalFieldCount++;
                FieldType fieldType = new FieldType();
                fieldType.setName(field.getName() + "Present");
                fieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "Bit"));
                structuredType.getField().add(fieldType);
            }
        }
        if (optionalFieldCount > 0) {
            int reservedFieldCount = (optionalFieldCount + 31) / 32;
            for (int i = 0; i < reservedFieldCount; i++) {
                long reservedBits = 32 - optionalFieldCount;
                optionalFieldCount -= 32;
                FieldType fieldType = new FieldType();
                fieldType.setLength(reservedBits);
                fieldType.setName("Reserved" + i);
                fieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "Bit"));
                structuredType.getField().add(fieldType);
            }
        }
    } else if (structureType == StructureType.Union) {
        FieldType fieldType = new FieldType();
        fieldType.setName("SwitchField");
        fieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "UInt32"));
        structuredType.getField().add(fieldType);
    }
    long switchValue = 0L;
    for (StructureField field : fields) {
        String fieldName = field.getName();
        NodeId fieldDataTypeId = field.getDataType();
        DataTypeLocation dataTypeLocation = dataTypeLookup.apply(fieldDataTypeId);
        String dataTypeName = dataTypeLocation.dataTypeName;
        String dictionaryNamespaceUri = dataTypeLocation.dictionaryNamespaceUri;
        namespaces.add(dictionaryNamespaceUri);
        FieldType fieldType = new FieldType();
        fieldType.setName(fieldName);
        fieldType.setTypeName(new QName(dictionaryNamespaceUri, dataTypeName));
        if (structureType == StructureType.StructureWithOptionalFields) {
            if (field.getIsOptional()) {
                fieldType.setSwitchField(fieldName + "Present");
            }
        } else if (structureType == StructureType.Union) {
            fieldType.setSwitchField("SwitchField");
            fieldType.setSwitchValue(++switchValue);
        }
        if (field.getValueRank() >= 1) {
            // Fixed-dimension array... specify a LengthField
            FieldType lengthFieldType = new FieldType();
            lengthFieldType.setName(fieldName + "Length");
            lengthFieldType.setTypeName(new QName(Namespaces.OPC_UA_BSD, "Int32"));
            if (structureType == StructureType.StructureWithOptionalFields) {
                if (field.getIsOptional()) {
                    lengthFieldType.setSwitchField(fieldName + "Present");
                }
            } else if (structureType == StructureType.Union) {
                fieldType.setSwitchField("SwitchField");
                fieldType.setSwitchValue(switchValue);
            }
            structuredType.getField().add(lengthFieldType);
            fieldType.setLengthField(fieldName + "Length");
        } else if (field.getValueRank() != -1) {
            // Not scalar, not fixed-dimension, not supported
            throw new IllegalArgumentException("cannot encode field \"" + fieldName + "\" " + "with ValueRank: %s" + field.getValueRank());
        }
        structuredType.getField().add(fieldType);
    }
    return structuredType;
}
Also used : StructureField(org.eclipse.milo.opcua.stack.core.types.structured.StructureField) QName(javax.xml.namespace.QName) QualifiedName(org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) StructuredType(org.opcfoundation.opcua.binaryschema.StructuredType) StructureDescription(org.eclipse.milo.opcua.stack.core.types.structured.StructureDescription) LinkedHashMap(java.util.LinkedHashMap) FieldType(org.opcfoundation.opcua.binaryschema.FieldType) StructureDefinition(org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition) StructureType(org.eclipse.milo.opcua.stack.core.types.enumerated.StructureType) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)

Aggregations

ArrayList (java.util.ArrayList)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedList (java.util.LinkedList)1 QName (javax.xml.namespace.QName)1 NodeId (org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)1 QualifiedName (org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName)1 StructureType (org.eclipse.milo.opcua.stack.core.types.enumerated.StructureType)1 StructureDefinition (org.eclipse.milo.opcua.stack.core.types.structured.StructureDefinition)1 StructureDescription (org.eclipse.milo.opcua.stack.core.types.structured.StructureDescription)1 StructureField (org.eclipse.milo.opcua.stack.core.types.structured.StructureField)1 FieldType (org.opcfoundation.opcua.binaryschema.FieldType)1 StructuredType (org.opcfoundation.opcua.binaryschema.StructuredType)1