public static void CollectInstanceDeclarations(
Session session,
ComNamespaceMapper mapper,
NodeId typeId,
AeEventAttribute parent,
List<AeEventAttribute> instances,
IDictionary<string, AeEventAttribute> map)
{
// find the children.
BrowseDescription nodeToBrowse = new BrowseDescription();
if (parent == null)
{
nodeToBrowse.NodeId = typeId;
}
else
{
nodeToBrowse.NodeId = parent.NodeId;
}
nodeToBrowse.BrowseDirection = BrowseDirection.Forward;
nodeToBrowse.ReferenceTypeId = ReferenceTypeIds.HasChild;
nodeToBrowse.IncludeSubtypes = true;
nodeToBrowse.NodeClassMask = (uint)(NodeClass.Object | NodeClass.Variable);
nodeToBrowse.ResultMask = (uint)BrowseResultMask.All;
// ignore any browsing errors.
ReferenceDescriptionCollection references = Browse(session, nodeToBrowse, false);
if (references == null)
{
return;
}
// process the children.
List<NodeId> nodeIds = new List<NodeId>();
List<AeEventAttribute> children = new List<AeEventAttribute>();
for (int ii = 0; ii < references.Count; ii++)
{
ReferenceDescription reference = references[ii];
if (reference.NodeId.IsAbsolute)
{
continue;
}
// create a new declaration.
AeEventAttribute child = new AeEventAttribute();
child.RootTypeId = typeId;
child.NodeId = (NodeId)reference.NodeId;
child.BrowseName = reference.BrowseName;
child.NodeClass = reference.NodeClass;
if (!LocalizedText.IsNullOrEmpty(reference.DisplayName))
{
child.DisplayName = reference.DisplayName.Text;
}
else
{
child.DisplayName = reference.BrowseName.Name;
}
if (parent != null)
{
child.BrowsePath = new QualifiedNameCollection(parent.BrowsePath);
child.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(reference.BrowseName));
child.DisplayPath = Utils.Format("{0}/{1}", parent.DisplayPath, reference.DisplayName);
}
else
{
child.BrowsePath = new QualifiedNameCollection();
child.BrowsePathDisplayText = Utils.Format("{0}", reference.BrowseName);
child.DisplayPath = Utils.Format("{0}", reference.DisplayName);
}
child.BrowsePath.Add(reference.BrowseName);
// check if reading an overridden declaration.
AeEventAttribute overriden = null;
if (map.TryGetValue(child.BrowsePathDisplayText, out overriden))
{
child.OverriddenDeclaration = overriden;
}
map[child.BrowsePathDisplayText] = child;
// add to list.
children.Add(child);
nodeIds.Add(child.NodeId);
}
// check if nothing more to do.
if (children.Count == 0)
{
return;
}
// find the modelling rules.
List<NodeId> modellingRules = FindTargetOfReference(session, nodeIds, Opc.Ua.ReferenceTypeIds.HasModellingRule, false);
if (modellingRules != null)
{
for (int ii = 0; ii < nodeIds.Count; ii++)
{
children[ii].ModellingRule = modellingRules[ii];
// if the modelling rule is null then the instance is not part of the type declaration.
if (NodeId.IsNull(modellingRules[ii]))
{
map.Remove(children[ii].BrowsePathDisplayText);
}
}
}
// update the descriptions.
UpdateInstanceDescriptions(session, children, false);
// recusively collect instance declarations for the tree below.
for (int ii = 0; ii < children.Count; ii++)
{
if (!NodeId.IsNull(children[ii].ModellingRule))
{
instances.Add(children[ii]);
CollectInstanceDeclarations(session, mapper, typeId, children[ii], instances, map);
}
}
}