use of org.eclipse.milo.opcua.sdk.core.nodes.VariableTypeNode in project milo by eclipse.
the class AttributeReader method getEncodingId.
@Nullable
private static NodeId getEncodingId(AttributeContext context, UaServerNode node, QualifiedName encodingName) {
// TODO avoid dynamic lookup by registering codecs with their associated DataType and Encoding name
NodeId dataTypeId;
if (node instanceof VariableNode) {
dataTypeId = ((VariableNode) node).getDataType();
} else if (node instanceof VariableTypeNode) {
dataTypeId = ((VariableTypeNode) node).getDataType();
} else {
return null;
}
AddressSpaceManager addressSpaceManager = context.getServer().getAddressSpaceManager();
UaNode dataTypeNode = addressSpaceManager.getManagedNode(dataTypeId).orElse(null);
if (dataTypeNode != null) {
return dataTypeNode.getReferences().stream().filter(r -> r.isForward() && Identifiers.HasEncoding.equals(r.getReferenceTypeId())).flatMap(r -> opt2stream(addressSpaceManager.getManagedNode(r.getTargetNodeId()))).filter(n -> encodingName.equals(n.getBrowseName())).map(Node::getNodeId).findFirst().orElse(null);
} else {
return null;
}
}
use of org.eclipse.milo.opcua.sdk.core.nodes.VariableTypeNode in project milo by eclipse.
the class NodeFactory method createNodeTree.
public Tree<UaNode> createNodeTree(NodeId rootNodeId, NodeId typeDefinitionId, InstantiationCallback instantiationCallback) throws UaException {
AddressSpaceManager addressSpaceManager = context.getServer().getAddressSpaceManager();
if (!addressSpaceManager.getManagedNode(typeDefinitionId).isPresent()) {
throw new UaException(StatusCodes.Bad_NodeIdUnknown, "unknown type definition: " + typeDefinitionId);
}
NamespaceTable namespaceTable = context.getServer().getNamespaceTable();
InstanceDeclarationHierarchy idh;
try {
idh = IDH_CACHE.get(typeDefinitionId, () -> {
LoggerFactory.getLogger(NodeFactory.class).debug("InstanceDeclarationHierarchy cache " + "miss for typeDefinitionId={}", typeDefinitionId);
return InstanceDeclarationHierarchy.create(addressSpaceManager, namespaceTable, typeDefinitionId);
});
} catch (ExecutionException e) {
throw new UaException(StatusCodes.Bad_InternalError, e);
}
NodeTable nodeTable = idh.getNodeTable();
ReferenceTable referenceTable = idh.getReferenceTable();
Map<BrowsePath, UaNode> nodes = new HashMap<>();
for (Map.Entry<BrowsePath, NodeId> entry : nodeTable.nodes.entrySet()) {
BrowsePath browsePath = entry.getKey();
NodeId nodeId = entry.getValue();
UaNode node = addressSpaceManager.getManagedNode(nodeId).orElse(null);
if (browsePath.parent == null) {
if (node instanceof UaObjectTypeNode) {
UaNode instance = instanceFromTypeDefinition(rootNodeId, (UaObjectTypeNode) node);
nodes.put(browsePath, instance);
} else if (node instanceof UaVariableTypeNode) {
UaNode instance = instanceFromTypeDefinition(rootNodeId, (UaVariableTypeNode) node);
nodes.put(browsePath, instance);
} else {
throw new UaException(StatusCodes.Bad_InternalError);
}
} else {
// Non-root Nodes are all instance declarations
NodeId instanceNodeId = instanceNodeId(rootNodeId, browsePath);
if (node instanceof UaMethodNode) {
UaMethodNode declaration = (UaMethodNode) node;
UaMethodNode instance = new UaMethodNode(context, instanceNodeId, declaration.getBrowseName(), declaration.getDisplayName(), declaration.getDescription(), declaration.getWriteMask(), declaration.getUserWriteMask(), declaration.isExecutable(), declaration.isUserExecutable());
nodes.put(browsePath, instance);
} else if (node instanceof UaObjectNode) {
UaObjectNode declaration = (UaObjectNode) node;
ExpandedNodeId instanceTypeDefinitionId = getTypeDefinition(referenceTable, browsePath);
UaNode typeDefinitionNode = addressSpaceManager.getManagedNode(instanceTypeDefinitionId).orElse(null);
if (typeDefinitionNode instanceof ObjectTypeNode) {
boolean optional = isOptionalDeclaration(declaration);
if (!optional || instantiationCallback.includeOptionalNode(typeDefinitionNode.getNodeId(), declaration.getBrowseName())) {
UaObjectNode instance = instanceFromTypeDefinition(instanceNodeId, (ObjectTypeNode) typeDefinitionNode);
instance.setBrowseName(declaration.getBrowseName());
instance.setDisplayName(declaration.getDisplayName());
instance.setDescription(declaration.getDescription());
instance.setWriteMask(declaration.getWriteMask());
instance.setUserWriteMask(declaration.getUserWriteMask());
instance.setEventNotifier(declaration.getEventNotifier());
nodes.put(browsePath, instance);
}
} else {
throw new UaException(StatusCodes.Bad_InternalError, "expected type definition for " + instanceTypeDefinitionId);
}
} else if (node instanceof UaVariableNode) {
UaVariableNode declaration = (UaVariableNode) node;
ExpandedNodeId instanceTypeDefinitionId = getTypeDefinition(referenceTable, browsePath);
UaNode typeDefinitionNode = addressSpaceManager.getManagedNode(instanceTypeDefinitionId).orElse(null);
if (typeDefinitionNode instanceof VariableTypeNode) {
boolean optional = isOptionalDeclaration(declaration);
if (!optional || instantiationCallback.includeOptionalNode(typeDefinitionNode.getNodeId(), declaration.getBrowseName())) {
UaVariableNode instance = instanceFromTypeDefinition(instanceNodeId, (VariableTypeNode) typeDefinitionNode);
instance.setBrowseName(declaration.getBrowseName());
instance.setDisplayName(declaration.getDisplayName());
instance.setDescription(declaration.getDescription());
instance.setWriteMask(declaration.getWriteMask());
instance.setUserWriteMask(declaration.getUserWriteMask());
instance.setValue(declaration.getValue());
instance.setDataType(declaration.getDataType());
instance.setValueRank(declaration.getValueRank());
instance.setArrayDimensions(declaration.getArrayDimensions());
instance.setAccessLevel(declaration.getAccessLevel());
instance.setUserAccessLevel(declaration.getUserAccessLevel());
nodes.put(browsePath, instance);
}
} else {
throw new UaException(StatusCodes.Bad_InternalError, "expected type definition for " + instanceTypeDefinitionId);
}
} else {
throw new UaException(StatusCodes.Bad_InternalError, "not an instance declaration: " + node);
}
}
}
nodes.forEach((browsePath, node) -> {
List<ReferenceTable.RefRow> references = referenceTable.getReferences(browsePath);
references.forEach(t -> {
NodeId referenceTypeId = t.nodeId;
ReferenceTable.RefTarget target = t.target;
if (!Identifiers.HasModellingRule.equals(referenceTypeId)) {
if (target.targetNodeId != null) {
node.addReference(new Reference(node.getNodeId(), referenceTypeId, target.targetNodeId, true));
} else {
BrowsePath targetPath = target.targetPath;
UaNode targetNode = nodes.get(targetPath);
if (targetNode != null) {
node.addReference(new Reference(node.getNodeId(), referenceTypeId, targetNode.getNodeId().expanded(), true));
}
}
}
});
context.getNodeManager().addNode(node);
});
Tree<UaNode> nodeTree = nodeTable.getBrowsePathTree().map(nodes::get);
notifyInstantiationCallback(nodeTree, instantiationCallback);
return nodeTree;
}
use of org.eclipse.milo.opcua.sdk.core.nodes.VariableTypeNode in project milo by eclipse.
the class AttributeReader method readAttribute.
public static DataValue readAttribute(AttributeContext context, UaServerNode node, AttributeId attributeId, @Nullable TimestampsToReturn timestamps, @Nullable String indexRange, @Nullable QualifiedName encodingName) {
try {
AttributeContext internalContext = new AttributeContext(context.getServer());
NodeClass nodeClass = node.getNodeClass();
if (attributeId == AttributeId.Value && nodeClass == NodeClass.Variable) {
Set<AccessLevel> accessLevels = getAccessLevels(node, internalContext);
if (!accessLevels.contains(AccessLevel.CurrentRead)) {
throw new UaException(StatusCodes.Bad_NotReadable);
}
Set<AccessLevel> userAccessLevels = getUserAccessLevels(node, context);
if (!userAccessLevels.contains(AccessLevel.CurrentRead)) {
throw new UaException(StatusCodes.Bad_UserAccessDenied);
}
}
if (encodingName != null && encodingName.isNotNull()) {
if (attributeId != AttributeId.Value) {
throw new UaException(StatusCodes.Bad_DataEncodingInvalid);
}
NodeId dataTypeId;
if (node instanceof VariableNode) {
dataTypeId = ((VariableNode) node).getDataType();
} else if (node instanceof VariableTypeNode) {
dataTypeId = ((VariableTypeNode) node).getDataType();
} else {
throw new UaException(StatusCodes.Bad_DataEncodingInvalid);
}
boolean structured = isStructureSubtype(context.getServer(), dataTypeId);
if (!structured) {
throw new UaException(StatusCodes.Bad_DataEncodingInvalid);
}
}
final DataValue.Builder dvb = node.getAttribute(context, attributeId).copy();
// Maybe transcode the structure...
if (dvb.value.isNotNull()) {
final Object valueObject = dvb.value.getValue();
Class<?> valueClazz = valueObject.getClass();
if (valueClazz.isArray() && ArrayUtil.getType(valueObject) == ExtensionObject.class) {
Object newValue = transformArray(valueObject, (ExtensionObject xo) -> transcode(context, node, xo, encodingName), ExtensionObject.class);
dvb.setValue(new Variant(newValue));
} else if (valueClazz == ExtensionObject.class) {
ExtensionObject xo = (ExtensionObject) valueObject;
Object newValue = transcode(context, node, xo, encodingName);
dvb.setValue(new Variant(newValue));
}
}
// Apply index range if provided...
if (indexRange != null) {
NumericRange range = NumericRange.parse(indexRange);
Object valueAtRange = NumericRange.readFromValueAtRange(dvb.value, range);
dvb.setValue(new Variant(valueAtRange));
}
// Add or remove timestamps based on TimestampsToReturn...
if (timestamps != null) {
dvb.applyTimestamps(attributeId, timestamps);
}
return dvb.build();
} catch (UaException e) {
return new DataValue(e.getStatusCode());
}
}
use of org.eclipse.milo.opcua.sdk.core.nodes.VariableTypeNode in project milo by eclipse.
the class NodeFactory method notifyInstantiationCallback.
protected void notifyInstantiationCallback(Tree<UaNode> nodeTree, InstantiationCallback instantiationCallback) {
nodeTree.traverseWithParent((node, parentNode) -> {
if (parentNode instanceof UaObjectNode && node instanceof UaMethodNode) {
UaMethodNode methodNode = (UaMethodNode) node;
instantiationCallback.onMethodAdded((UaObjectNode) parentNode, methodNode);
} else if (node instanceof UaObjectNode) {
UaObjectNode objectNode = (UaObjectNode) node;
ObjectTypeNode objectTypeNode = objectNode.getTypeDefinitionNode();
instantiationCallback.onObjectAdded(parentNode, objectNode, objectTypeNode.getNodeId());
} else if (node instanceof UaVariableNode) {
UaVariableNode variableNode = (UaVariableNode) node;
VariableTypeNode variableTypeNode = variableNode.getTypeDefinitionNode();
instantiationCallback.onVariableAdded(parentNode, variableNode, variableTypeNode.getNodeId());
}
});
}
Aggregations