use of org.opcfoundation.opcua.binaryschema.StructuredType 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;
}
use of org.opcfoundation.opcua.binaryschema.StructuredType in project milo by eclipse.
the class BsdParser method parse.
/**
* Parse an XML document containing a type dictionary conforming to the OPC Binary XML Schema.
*
* @param inputStream the {@link InputStream} to read the XML document from.
* @return a {@link DictionaryDescription}.
* @throws JAXBException if parsing fails.
*/
public DictionaryDescription parse(InputStream inputStream) throws JAXBException {
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
TypeDictionary typeDictionary = (TypeDictionary) context.createUnmarshaller().unmarshal(inputStream);
List<CodecDescription> enumCodecs = typeDictionary.getOpaqueTypeOrEnumeratedTypeOrStructuredType().stream().filter(typeDescription -> typeDescription instanceof EnumeratedType).map(typeDescription -> {
EnumeratedType enumeratedType = (EnumeratedType) typeDescription;
logger.debug("EnumeratedType: {}", typeDescription.getName());
return new CodecDescription(getEnumCodec(enumeratedType), enumeratedType.getName());
}).collect(toList());
List<CodecDescription> structCodecs = typeDictionary.getOpaqueTypeOrEnumeratedTypeOrStructuredType().stream().filter(typeDescription -> typeDescription instanceof StructuredType).map(typeDescription -> {
StructuredType structuredType = (StructuredType) typeDescription;
logger.debug("StructuredType: {}", typeDescription.getName());
return new CodecDescription(getStructCodec(structuredType), structuredType.getName());
}).collect(toList());
return new DictionaryDescription(typeDictionary.getTargetNamespace(), enumCodecs, structCodecs);
}
Aggregations