/// <summary> /// Processes the node references to calculate all relevant properties. Must be called after finishing import of all the parent models. /// </summary> /// <param name="nodeFactory">The node container.</param> /// <param name="traceEvent">A delegate <see cref="Action{TraceMessage}"/> encapsulates an action to report any errors and trace processing progress.</param> internal void CalculateNodeReferences(INodeFactory nodeFactory, Action <TraceMessage> traceEvent) { m_ModelingRule = new Nullable <ModelingRules>(); List <UAReferenceContext> _children = new List <UAReferenceContext>(); Dictionary <string, UANodeContext> _derivedChildren = null; foreach (UAReferenceContext _rfx in m_AddressSpaceContext.GetMyReferences(this)) { switch (_rfx.ReferenceKind) { case ReferenceKindEnum.Custom: XmlQualifiedName _ReferenceType = _rfx.GetReferenceTypeName(traceEvent); if (_ReferenceType == XmlQualifiedName.Empty) { BuildError _err = BuildError.DanglingReferenceTarget; traceEvent(TraceMessage.BuildErrorTraceMessage(_err, "Information")); } IReferenceFactory _or = nodeFactory.NewReference(); _or.IsInverse = !_rfx.Reference.IsForward; _or.ReferenceType = _ReferenceType; _or.TargetId = _rfx.BrowsePath(traceEvent); break; case ReferenceKindEnum.HasComponent: if (_rfx.SourceNodeContext == this) { _children.Add(_rfx); } break; case ReferenceKindEnum.HasProperty: if ((_rfx.SourceNodeContext == this) && (!(_rfx.SourceNodeContext.UANode is UADataType) || _rfx.TargetNodeContext.UANode.BrowseName.CompareTo("EnumStrings") != 0)) { _children.Add(_rfx); } break; case ReferenceKindEnum.HasModellingRule: m_ModelingRule = _rfx.GetModelingRule(); break; case ReferenceKindEnum.HasSubtype: //TODO Part 3 7.10 HasSubtype - add test cases #35 m_BaseTypeNode = _rfx.SourceNodeContext; break; case ReferenceKindEnum.HasTypeDefinition: //Recognize problems with P3.7.13 HasTypeDefinition ReferenceType #39 m_BaseTypeNode = _rfx.TargetNodeContext; _derivedChildren = _rfx.TargetNodeContext.GetDerivedChildren(); Debug.Assert(!IsProperty, "Has property "); m_IsProperty = _rfx.TargetNodeContext.IsPropertyVariableType; break; } } _children = _children.Where <UAReferenceContext>(x => _derivedChildren == null || !_derivedChildren.ContainsKey(x.TargetNodeContext.m_BrowseName.Name)).ToList <UAReferenceContext>(); foreach (UAReferenceContext _rc in _children) { Validator.ValidateExportNode(_rc.TargetNodeContext, nodeFactory, _rc, traceEvent); } }
/// <summary> /// Processes the node references to calculate all relevant properties. Must be called after finishing import of all the parent models. /// </summary> /// <param name="nodeFactory">The node container.</param> /// <param name="validator">The validator.</param> /// <exception cref="ArgumentNullException"><paramref name="nodeFactory"/> must not be null.</exception> void IUANodeBase.CalculateNodeReferences(INodeFactory nodeFactory, IValidator validator) { if (nodeFactory == null) { throw new ArgumentNullException(nameof(nodeFactory), $"{nodeFactory} must not be null in {nameof(IUANodeBase.CalculateNodeReferences)}"); } if (validator is null) { throw new ArgumentNullException(nameof(validator), $"{nameof(validator)} must not be null in {nameof(IUANodeBase.CalculateNodeReferences)}"); } List <UAReferenceContext> _children = new List <UAReferenceContext>(); foreach (UAReferenceContext _rfx in m_AddressSpaceContext.GetMyReferences(this)) { switch (_rfx.ReferenceKind) { case ReferenceKindEnum.Custom: XmlQualifiedName _ReferenceType = _rfx.GetReferenceTypeName(); if (_ReferenceType == XmlQualifiedName.Empty) { BuildError _err = BuildError.DanglingReferenceTarget; Log.TraceEvent(TraceMessage.BuildErrorTraceMessage(_err, "Information")); } IReferenceFactory _or = nodeFactory.NewReference(); _or.IsInverse = !_rfx.Reference.IsForward; _or.ReferenceType = _ReferenceType; _or.TargetId = _rfx.BrowsePath(); break; case ReferenceKindEnum.HasComponent: if (_rfx.SourceNode == this) { _children.Add(_rfx); } break; case ReferenceKindEnum.HasProperty: if ((_rfx.SourceNode == this) && (_rfx.SourceNode.UANode.NodeClassEnum != NodeClassEnum.UADataType)) { _children.Add(_rfx); } break; case ReferenceKindEnum.HasModellingRule: break; case ReferenceKindEnum.HasSubtype: break; case ReferenceKindEnum.HasTypeDefinition: //Recognize problems with P3.7.13 HasTypeDefinition ReferenceType #39 IsProperty = _rfx.TargetNode.IsPropertyVariableType; break; } } Dictionary <string, IUANodeBase> _derivedChildren = m_BaseTypeNode == null ? new Dictionary <string, IUANodeBase>() : m_BaseTypeNode.GetDerivedInstances(); foreach (UAReferenceContext _rc in _children) { try { IUANodeBase _instanceDeclaration = null; if (!string.IsNullOrEmpty(_rc.TargetNode.BrowseName.Name)) { _instanceDeclaration = _derivedChildren.ContainsKey(_rc.TargetNode.BrowseName.Name) ? _derivedChildren[_rc.TargetNode.BrowseName.Name] : null; } if (_rc.TargetNode.Equals(_instanceDeclaration)) { continue; } _rc.TargetNode.RemoveInheritedValues(_instanceDeclaration); validator.ValidateExportNode(_rc.TargetNode, nodeFactory, _rc); } catch (Exception) { throw; } } }