protected virtual void AddReverseReferences(IDictionary<NodeId, IList<IReference>> externalReferences)
{
foreach (NodeState source in m_predefinedNodes.Values)
{
// assign a default value to any variable value.
BaseVariableState variable = source as BaseVariableState;
if (variable != null && variable.Value == null)
{
variable.Value = TypeInfo.GetDefaultValue(variable.DataType, variable.ValueRank, Server.TypeTree);
}
// add reference from supertype for type nodes.
BaseTypeState type = source as BaseTypeState;
if (type != null && !NodeId.IsNull(type.SuperTypeId))
{
if (!IsNodeIdInNamespace(type.SuperTypeId))
{
AddExternalReference(
type.SuperTypeId,
ReferenceTypeIds.HasSubtype,
false,
type.NodeId,
externalReferences);
}
}
IList<IReference> references = new List<IReference>();
source.GetReferences(SystemContext, references);
for (int ii = 0; ii < references.Count; ii++)
{
IReference reference = references[ii];
// nothing to do with external nodes.
if (reference.TargetId == null || reference.TargetId.IsAbsolute)
{
continue;
}
NodeId targetId = (NodeId)reference.TargetId;
// add inverse reference to internal targets.
NodeState target = null;
if (m_predefinedNodes.TryGetValue(targetId, out target))
{
if (!target.ReferenceExists(reference.ReferenceTypeId, !reference.IsInverse, source.NodeId))
{
target.AddReference(reference.ReferenceTypeId, !reference.IsInverse, source.NodeId);
}
continue;
}
// check for inverse references to external notifiers.
if (reference.IsInverse && reference.ReferenceTypeId == ReferenceTypeIds.HasNotifier)
{
AddRootNotifier(source);
}
// nothing more to do for references to nodes managed by this manager.
if (IsNodeIdInNamespace(targetId))
{
continue;
}
// add external reference.
AddExternalReference(
targetId,
reference.ReferenceTypeId,
!reference.IsInverse,
source.NodeId,
externalReferences);
}
}
}