/// <summary> /// Updates this instance in case the wrapped <see cref="UANode" /> is recognized in the model. /// </summary> /// <param name="node">The node <see cref="UANode" /> containing definition to be added to the model.</param> /// <param name="addReference">Used to add new reference to the common collection of references.</param> /// <exception cref="ArgumentException">node - Argument must not be null</exception> public void Update(UANode node, Action <UAReferenceContext> addReference) { if (node == null) { throw new ArgumentException(nameof(node), $"Argument must not be null at {nameof(Update)} "); } if (this.UANode != null) { Log.TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.NodeIdDuplicated, string.Format("The {0} is already defined and is removed from further processing.", node.NodeId.ToString()))); return; } UANode = node; this.BrowseName = node.BrowseName.Parse(Log.TraceEvent); if (QualifiedName.IsNull(this.BrowseName)) { NodeId _id = NodeId.Parse(UANode.NodeId); this.BrowseName = new QualifiedName($"EmptyBrowseName_{_id.IdentifierPart}", _id.NamespaceIndex); Log.TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.EmptyBrowseName, $"New identifier {this.BrowseName} is generated to proceed.")); } if (node.References == null) { return; } foreach (Reference _reference in node.References) { UAReferenceContext _newReference = new UAReferenceContext(_reference, this.m_AddressSpaceContext, this); switch (_newReference.ReferenceKind) { case ReferenceKindEnum.Custom: case ReferenceKindEnum.HasComponent: case ReferenceKindEnum.HasProperty: break; case ReferenceKindEnum.HasModellingRule: ModelingRule = _newReference.GetModelingRule(); break; case ReferenceKindEnum.HasSubtype: //TODO Part 3 7.10 HasSubtype - add test cases #35 m_BaseTypeNode = _newReference.SourceNode; break; case ReferenceKindEnum.HasTypeDefinition: //Recognize problems with P3.7.13 HasTypeDefinition ReferenceType #39 m_BaseTypeNode = _newReference.TargetNode; break; } addReference(_newReference); } }
/// <summary> /// Builds the symbolic identifier. /// </summary> /// <param name="path">The browse path.</param> public void BuildSymbolicId(List <string> path) { if (this.UANode == null) { Log.TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.DanglingReferenceTarget, $"The target node NodeId={this.NodeIdContext}, current path {string.Join(", ", path)}")); return; } IEnumerable <UAReferenceContext> _parentConnector = m_AddressSpaceContext.GetReferences2Me(this).Where <UAReferenceContext>(x => x.ChildConnector); Debug.Assert(_parentConnector.Count <UAReferenceContext>() <= 1); //TODO #40; ValidateAndExportModel shall export also instances #40 UAReferenceContext _connector = _parentConnector.FirstOrDefault <UAReferenceContext>(); if (_connector != null) { _connector.BuildSymbolicId(path); } string _BranchName = string.IsNullOrEmpty(this.UANode.SymbolicName) ? this.BrowseName.Name : this.UANode.SymbolicName; path.Add(_BranchName); }
/// <summary> /// Builds the symbolic identifier. /// </summary> /// <param name="path">The browse path.</param> /// <param name="traceEvent">A delegate <see cref="Action{TraceMessage}"/> encapsulates an action to report any errors and trace processing progress.</param> internal void BuildSymbolicId(List <string> path, Action <TraceMessage> traceEvent) { if (this.UANode == null) { traceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.DanglingReferenceTarget, "")); return; } IEnumerable <UAReferenceContext> _parentConnector = m_AddressSpaceContext.GetReferences2Me(this).Where <UAReferenceContext>(x => x.ChildConnector); Debug.Assert(_parentConnector.Count <UAReferenceContext>() <= 1); UAReferenceContext _connector = _parentConnector.FirstOrDefault <UAReferenceContext>(); if (_connector != null) { _connector.BuildSymbolicId(path, traceEvent); } string _BranchName = String.IsNullOrEmpty(this.UANode.SymbolicName) ? this.m_BrowseName.Name : this.UANode.SymbolicName; path.Add(_BranchName); }
internal static UAReferenceContext NewReferenceStub (Reference reference, AddressSpaceContext addressSpaceContext, UAModelContext modelContext, UANodeContext parentNode, Action <TraceMessage> traceEvent) { UANodeContext targetNode = modelContext.GetOrCreateNodeContext(reference.Value, true, traceEvent); UAReferenceContext _stb = new UAReferenceContext() { m_Context = addressSpaceContext, ParentNode = parentNode, SourceNode = reference.IsForward ? parentNode : targetNode, ModelNode = reference, TargetNode = reference.IsForward ? targetNode : parentNode, TypeNode = modelContext.GetOrCreateNodeContext(reference.ReferenceType, true, traceEvent), }; if (_stb.TypeNode != null && _stb.TypeNode.NodeIdContext.NamespaceIndex == 0) { _stb.ReferenceKind = _stb.GetReferenceKind(_stb.TypeNode); } return(_stb); }
private void ImportUANode(UANode node, UAModelContext modelContext, Action <TraceMessage> traceEvent) { try { if (node == null) { m_TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.NodeCannotBeNull, "At Importing UANode.")); } NodeId nodeId = modelContext.ImportNodeId(node.NodeId, false, m_TraceEvent); UANodeContext _newNode = null; string nodeIdKey = nodeId.ToString(); if (!m_NodesDictionary.TryGetValue(nodeIdKey, out _newNode)) { _newNode = new UANodeContext(this, modelContext, nodeId); _newNode.Update(node, traceEvent); m_NodesDictionary.Add(nodeIdKey, _newNode); } else { if (_newNode.UANode != null) { m_TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.NodeIdDuplicated, String.Format("The {0} is already defined.", node.NodeId.ToString()))); } _newNode.Update(node, traceEvent); } foreach (Reference _rf in node.References) { UAReferenceContext _rs = UAReferenceContext.NewReferenceStub(_rf, this, modelContext, _newNode, m_TraceEvent); if (!m_References.ContainsKey(_rs.Key)) { m_References.Add(_rs.Key, _rs); } } } catch (Exception _ex) { string _msg = String.Format("ImportUANode {1} is interrupted by exception {0}", _ex.Message, node.NodeId); m_TraceEvent(TraceMessage.DiagnosticTraceMessage(_msg)); } }
private void Update(IMethodInstanceFactory nodeDesign, UAMethod nodeSet, UAReferenceContext parentReference) { if (nodeSet.ArgumentDescription != null) { foreach (UAMethodArgument _argument in nodeSet.ArgumentDescription) { if (_argument.Description == null) { continue; } foreach (XML.LocalizedText _description in _argument.Description) { nodeDesign.AddArgumentDescription(_argument.Name, _description.Locale, _description.Value); } } } nodeDesign.Executable = !nodeSet.Executable ? nodeSet.Executable : new Nullable <bool>(); nodeDesign.UserExecutable = !nodeSet.UserExecutable ? nodeSet.UserExecutable : new Nullable <bool>(); nodeDesign.MethodDeclarationId = nodeSet.MethodDeclarationId; nodeDesign.ReleaseStatus = nodeSet.ReleaseStatus.ConvertToReleaseStatus(); nodeDesign.AddInputArguments(x => GetParameters(x)); nodeDesign.AddOutputArguments(x => GetParameters(x)); }
/// <summary> /// Validates <paramref name="nodeContext"/> and exports it using an object of <see cref="IModelFactory"/> type. /// </summary> /// <param name="nodeContext">The node context to be validated and exported.</param> /// <param name="exportFactory">A model export factory.</param> /// <param name="parentReference">The reference to parent node.</param> /// <param name="traceEvent">The trace event.</param> /// <returns>An object of <see cref="INodeFactory"/>.</returns> internal static void ValidateExportNode(IUANodeBase nodeContext, INodeContainer exportFactory, UAReferenceContext parentReference, Action <TraceMessage> traceEvent) { Debug.Assert(nodeContext != null, "Validator.ValidateExportNode the argument nodeContext is null."); //TODO Handle HasComponent ReferenceType errors. #42 if (nodeContext.UANode == null) { string _msg = string.Format("The node {0} is undefined", nodeContext.NodeIdContext); BuildError _be = null; if (parentReference == null || parentReference.ReferenceKind == ReferenceKindEnum.HasProperty) { _be = BuildError.UndefinedHasPropertyTarget; } else { _be = BuildError.UndefinedHasComponentTarget; } TraceMessage _traceMessage = TraceMessage.BuildErrorTraceMessage(_be, _msg); traceEvent(_traceMessage); CreateModelDesignStub(exportFactory); } else { string nodeType = nodeContext.UANode.GetType().Name; switch (nodeType) { case "UAReferenceType": CreateNode <IReferenceTypeFactory, UAReferenceType>(exportFactory.AddNodeFactory <IReferenceTypeFactory>, nodeContext, (x, y) => Update(x, y, traceEvent), UpdateType, traceEvent); break; case "UADataType": CreateNode <IDataTypeFactory, UADataType>(exportFactory.AddNodeFactory <IDataTypeFactory>, nodeContext, (x, y) => Update(x, y, nodeContext.UAModelContext, traceEvent), UpdateType, traceEvent); break; case "UAVariableType": CreateNode <IVariableTypeFactory, UAVariableType>(exportFactory.AddNodeFactory <IVariableTypeFactory>, nodeContext, (x, y) => Update(x, y, nodeContext, traceEvent), UpdateType, traceEvent); break; case "UAObjectType": CreateNode <IObjectTypeFactory, UAObjectType>(exportFactory.AddNodeFactory <IObjectTypeFactory>, nodeContext, Update, UpdateType, traceEvent); break; case "UAView": CreateNode <IViewInstanceFactory, UAView>(exportFactory.AddNodeFactory <IViewInstanceFactory>, nodeContext, (x, y) => Update(x, y, traceEvent), UpdateInstance, traceEvent); break; case "UAMethod": CreateNode <IMethodInstanceFactory, UAMethod>(exportFactory.AddNodeFactory <IMethodInstanceFactory>, nodeContext, (x, y) => Update(x, y, nodeContext, parentReference, traceEvent), UpdateInstance, traceEvent); break; case "UAVariable": if (parentReference == null || parentReference.ReferenceKind == ReferenceKindEnum.HasProperty) { CreateNode <IPropertyInstanceFactory, UAVariable>(exportFactory.AddNodeFactory <IPropertyInstanceFactory>, nodeContext, (x, y) => Update(x, y, nodeContext, parentReference, traceEvent), UpdateInstance, traceEvent); } else { CreateNode <IVariableInstanceFactory, UAVariable>(exportFactory.AddNodeFactory <IVariableInstanceFactory>, nodeContext, (x, y) => Update(x, y, nodeContext, parentReference, traceEvent), UpdateInstance, traceEvent); } break; case "UAObject": CreateNode <IObjectInstanceFactory, UAObject>(exportFactory.AddNodeFactory <IObjectInstanceFactory>, nodeContext, (x, y) => Update(x, y, traceEvent), UpdateInstance, traceEvent); break; default: Debug.Assert(false, "Wrong node type"); break; } } }
private static void Update(IVariableInstanceFactory variableInstance, UAVariable nodeSet, IUANodeBase nodeContext, UAReferenceContext parentReference, Action <TraceMessage> traceEvent) { try { Update(variableInstance, nodeSet, nodeContext, traceEvent); variableInstance.ReferenceType = parentReference == null ? null : parentReference.GetReferenceTypeName(); if (nodeContext.IsProperty) { traceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.WrongReference2Variable, string.Format("Creating Variable - wrong reference type {0}", parentReference.ReferenceKind.ToString()))); } } catch (Exception _ex) { traceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.WrongReference2Property, string.Format("Cannot resolve the reference for Variable because of error {0} at: {1}.", _ex, _ex.StackTrace))); } }
internal static UAReferenceContext NewReferenceStub(Reference reference, AddressSpaceContext addressSpaceContext, UAModelContext modelContext, UANodeContext parentNode, Action<TraceMessage> traceEvent) { UANodeContext targetNode = modelContext.GetOrCreateNodeContext(reference.Value, true, traceEvent); UAReferenceContext _stb = new UAReferenceContext() { m_Context = addressSpaceContext, ParentNode = parentNode, SourceNode = reference.IsForward ? parentNode : targetNode, ModelNode = reference, TargetNode = reference.IsForward ? targetNode : parentNode, TypeNode = modelContext.GetOrCreateNodeContext(reference.ReferenceType, true, traceEvent), }; if (_stb.TypeNode != null && _stb.TypeNode.NodeIdContext.NamespaceIndex == 0) _stb.ReferenceKind = _stb.GetReferenceKind(_stb.TypeNode); return _stb; }
/// <summary> /// Validates <paramref name="nodeContext" /> and exports it using an object of <see cref="IModelFactory" /> type. /// </summary> /// <param name="nodeContext">The node context to be validated and exported.</param> /// <param name="exportFactory">A model export factory.</param> /// <param name="parentReference">The reference to parent node.</param> /// <exception cref="ApplicationException">In {nameof(ValidateExportNode)}</exception> public void ValidateExportNode(IUANodeBase nodeContext, INodeContainer exportFactory, UAReferenceContext parentReference) { Debug.Assert(nodeContext != null, "Validator.ValidateExportNode the argument nodeContext is null."); //TODO Handle HasComponent ReferenceType errors. #42 if (Object.ReferenceEquals(nodeContext.UANode, null)) { string _msg = string.Format("The node {0} is undefined", nodeContext.NodeIdContext); BuildError _be = null; if (parentReference == null || parentReference.ReferenceKind == ReferenceKindEnum.HasProperty) { _be = BuildError.UndefinedHasPropertyTarget; } else { _be = BuildError.UndefinedHasComponentTarget; } TraceMessage _traceMessage = TraceMessage.BuildErrorTraceMessage(_be, _msg); Log.TraceEvent(_traceMessage); CreateModelDesignStub(exportFactory); } else { switch (nodeContext.UANode.NodeClassEnum) { case NodeClassEnum.UADataType: CreateNode <IDataTypeFactory, UADataType>(exportFactory.AddNodeFactory <IDataTypeFactory>, nodeContext, (x, y) => Update(x, y), UpdateType); break; case NodeClassEnum.UAMethod: CreateNode <IMethodInstanceFactory, UAMethod>(exportFactory.AddNodeFactory <IMethodInstanceFactory>, nodeContext, (x, y) => Update(x, y, parentReference), UpdateInstance); break; case NodeClassEnum.UAObject: CreateNode <IObjectInstanceFactory, UAObject>(exportFactory.AddNodeFactory <IObjectInstanceFactory>, nodeContext, (x, y) => Update(x, y), UpdateInstance); break; case NodeClassEnum.UAObjectType: CreateNode <IObjectTypeFactory, UAObjectType>(exportFactory.AddNodeFactory <IObjectTypeFactory>, nodeContext, Update, UpdateType); break; case NodeClassEnum.UAReferenceType: CreateNode <IReferenceTypeFactory, UAReferenceType>(exportFactory.AddNodeFactory <IReferenceTypeFactory>, nodeContext, (x, y) => Update(x, y), UpdateType); break; case NodeClassEnum.UAVariable: if (parentReference.ReferenceKind == ReferenceKindEnum.HasProperty) { CreateNode <IPropertyInstanceFactory, UAVariable>(exportFactory.AddNodeFactory <IPropertyInstanceFactory>, nodeContext, (x, y) => Update(x, y, nodeContext, parentReference), UpdateInstance); } else { CreateNode <IVariableInstanceFactory, UAVariable>(exportFactory.AddNodeFactory <IVariableInstanceFactory>, nodeContext, (x, y) => Update(x, y, nodeContext, parentReference), UpdateInstance); } break; case NodeClassEnum.UAVariableType: CreateNode <IVariableTypeFactory, UAVariableType>(exportFactory.AddNodeFactory <IVariableTypeFactory>, nodeContext, (x, y) => Update(x, y), UpdateType); break; case NodeClassEnum.UAView: CreateNode <IViewInstanceFactory, UAView>(exportFactory.AddNodeFactory <IViewInstanceFactory>, nodeContext, (x, y) => Update(x, y), UpdateInstance); break; case NodeClassEnum.Unknown: throw new ApplicationException($"In {nameof(ValidateExportNode)} unexpected NodeClass value"); } } }
private void Update(IPropertyInstanceFactory propertyInstance, UAVariable nodeSet, IUANodeBase nodeContext, UAReferenceContext parentReference) { try { Update(propertyInstance, nodeSet); propertyInstance.ReferenceType = parentReference == null ? null : parentReference.GetReferenceTypeName(); if (!nodeContext.IsProperty) { Log.TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.WrongReference2Property, $"Creating Property {nodeContext.BrowseName}- wrong reference type {parentReference.ReferenceKind.ToString()}")); } } catch (Exception _ex) { Log.TraceEvent(TraceMessage.BuildErrorTraceMessage(BuildError.WrongReference2Property, string.Format("Cannot resolve the reference for Property because of error {0} at: {1}.", _ex, _ex.StackTrace))); } }
private static void Update(IMethodInstanceFactory nodeDesign, UAMethod nodeSet, UANodeContext nodeContext, UAReferenceContext parentReference, Action <TraceMessage> traceEvent) { //TODO add test case validate parentReference nodeDesign.Executable = !nodeSet.Executable ? nodeSet.Executable : new Nullable <bool>(); nodeDesign.UserExecutable = !nodeSet.UserExecutable ? nodeSet.UserExecutable : new Nullable <bool>(); nodeDesign.AddInputArguments(x => nodeContext.GetParameters(x, traceEvent)); nodeDesign.AddOutputArguments(x => nodeContext.GetParameters(x, traceEvent)); //MethodDeclarationId is ignored }