public override void compileSingleCE(Rule.IRule rule) { ICondition[] conds = rule.Conditions; ICondition condition = conds[0]; ExistCondition cond = (ExistCondition)condition; BaseNode base_Renamed = cond.LastNode; BaseJoin bjoin = new ExistJoinFrst(ruleCompiler.Engine.nextNodeId()); if (base_Renamed != null) { if (base_Renamed is BaseAlpha) { ((BaseAlpha)base_Renamed).addSuccessorNode(bjoin, ruleCompiler.Engine, ruleCompiler.Memory); } else if (base_Renamed is BaseJoin) { ((BaseJoin)base_Renamed).addSuccessorNode(bjoin, ruleCompiler.Engine, ruleCompiler.Memory); } } else { // the rule doesn't have a literal constraint so we need to Add // ExistJoinFrst as a child ObjectTypeNode otn = ruleCompiler.findObjectTypeNode(cond.TemplateName); otn.addSuccessorNode(bjoin, ruleCompiler.Engine, ruleCompiler.Memory); } // important, do not call this before ExistJoinFrst is added // if it's called first, the List<Object> will return index // out of bound, since there's nothing in the list cond.addNode(bjoin); rule.addJoinNode(bjoin); }
public override void compileSingleCE(Rule.IRule rule) { ICondition[] conds = rule.Conditions; ObjectCondition oc = (ObjectCondition)conds[0]; if (oc.Negated) { // the ObjectCondition is negated, so we need to // handle it appropriate. This means we need to // Add a LIANode to _IntialFact and attach a NOTNode // to the LIANode. ObjectTypeNode otn = (ObjectTypeNode)ruleCompiler.Inputnodes.Get(ruleCompiler.Engine.InitFact); LIANode lianode = ruleCompiler.findLIANode(otn); NotJoin njoin = new NotJoin(ruleCompiler.Engine.nextNodeId()); njoin.Bindings = new Binding[0]; lianode.addSuccessorNode(njoin, ruleCompiler.Engine, ruleCompiler.Memory); // Add the join to the rule object rule.addJoinNode(njoin); oc.LastNode.addSuccessorNode(njoin, ruleCompiler.Engine, ruleCompiler.Memory); } else if (oc.Nodes.Count == 0) { // this means the rule has a binding, but no conditions ObjectTypeNode otn = ruleCompiler.findObjectTypeNode(oc.TemplateName); LIANode lianode = new LIANode(ruleCompiler.Engine.nextNodeId()); otn.addSuccessorNode(lianode, ruleCompiler.Engine, ruleCompiler.Memory); rule.Conditions[0].addNode(lianode); } }
public override void compileFirstJoin(ICondition condition, Rule.IRule rule) { ObjectCondition cond = (ObjectCondition)condition; ObjectTypeNode otn = ruleCompiler.findObjectTypeNode(cond.TemplateName); // the LeftInputAdapterNode is the first node to propogate to // the first joinNode of the rule LIANode node = new LIANode(ruleCompiler.Engine.nextNodeId()); // if the condition doesn't have any nodes, we want to Add it to // the objectType node if one doesn't already exist. // otherwise we Add it to the last AlphaNode if (cond.Nodes.Count == 0) { // try to find the existing LIANode for the given ObjectTypeNode // if we don't do this, we end up with multiple LIANodes // descending directly from the ObjectTypeNode LIANode existingLIANode = ruleCompiler.findLIANode(otn); if (existingLIANode == null) { otn.addSuccessorNode(node, ruleCompiler.Engine, ruleCompiler.Memory); cond.addNode(node); } else { existingLIANode.incrementUseCount(); cond.addNode(existingLIANode); } } else { // Add the LeftInputAdapterNode to the last alphaNode // In the case of node sharing, the LIANode could be the last // alphaNode, so we have to check and only Add the node to // the condition if it isn't a LIANode BaseAlpha old = (BaseAlpha)cond.LastNode; //if the last node of condition has a LIANode successor, //the LIANode should be shared with the new CE followed by another CE. // Houzhanbin,10/16/2007 BaseNode[] successors = (BaseNode[])old.SuccessorNodes; for (int i = 0; i < successors.Length; i++) { if (successors[i] is LIANode) { cond.addNode(successors[i]); return; } } if (!(old is LIANode)) { old.addSuccessorNode(node, ruleCompiler.Engine, ruleCompiler.Memory); cond.addNode(node); } } }
private async Task BuildViewAsync(ConnectionNode connectionNode) { connectionNode.Nodes.Clear(); try { pbMain.Visible = true; await _scriptManager.GenerateScriptAsync(connectionNode.ConnectionName, new Progress <MergeProgress>(ShowProgress)); if (!_scriptManager.Actions.Any()) { btnExecute.Enabled = false; tbScript.Text = $"{_scriptManager.Syntax.CommentPrefix} Nothing to execute -- no model differences were found."; return; } tbScript.Text = _scriptManager.Script.ToString(); foreach (var actionTypeGrp in _scriptManager.Actions.GroupBy(item => item.ActionType)) { ActionTypeNode actionTypeNode = new ActionTypeNode(actionTypeGrp.Key, actionTypeGrp.Count()); connectionNode.Nodes.Add(actionTypeNode); foreach (var objectTypeGrp in actionTypeGrp.GroupBy(item => item.ObjectType)) { ObjectTypeNode objectTypeNode = new ObjectTypeNode(objectTypeGrp.Key, objectTypeGrp.Count()); actionTypeNode.Nodes.Add(objectTypeNode); foreach (var action in objectTypeGrp) { ActionNode ndAction = new ActionNode(action); ndAction.StartLine = _scriptManager.LineRanges[action].Start; ndAction.EndLine = _scriptManager.LineRanges[action].End; ndAction.ValidationErrors = _scriptManager.ValidationErrors[action].ToArray(); objectTypeNode.Nodes.Add(ndAction); } } } connectionNode.Checked = true; connectionNode.ExpandAll(); } finally { pbMain.Visible = false; string status = "Ready"; if (_scriptManager.Stopwatch != null) { status += $", ran in {_scriptManager.Stopwatch.ElapsedMilliseconds:n0}ms"; } tslStatus.Text = status; } }
public void testOneSlot() { Defclass dc = new Defclass(typeof(TestBean2)); Deftemplate dtemp = dc.createDeftemplate("testBean2"); TestBean2 bean = new TestBean2(); Slot[] slts = dtemp.AllSlots; ObjectTypeNode otn = new ObjectTypeNode(1, dtemp); AlphaNode an = new AlphaNode(1); slts[0].Value = ConversionUtils.convert(110); an.Operator = Constants.EQUAL; an.Slot = (slts[0]); Console.WriteLine("node::" + an.ToString()); Assert.IsNotNull(an.ToString(), "Should have a value."); }
public void testTwoSlots() { Defclass dc = new Defclass(typeof(TestBean2)); Deftemplate dtemp = dc.createDeftemplate("testBean2"); TestBean2 bean = new TestBean2(); Slot[] slts = dtemp.AllSlots; ObjectTypeNode otn = new ObjectTypeNode(1, dtemp); AlphaNode an1 = new AlphaNode(1); AlphaNode an2 = new AlphaNode(1); slts[0].Value = ("testString"); slts[1].Value = (ConversionUtils.convert(999)); an1.Slot = (slts[0]); an1.Operator = (Constants.EQUAL); Console.WriteLine("node::" + an1.toPPString()); Assert.IsNotNull(an1.toPPString()); an2.Slot = (slts[1]); an2.Operator = (Constants.GREATER); Console.WriteLine("node::" + an2.toPPString()); Assert.IsNotNull(an2.toPPString()); }
/// <summary> The first step is to connect the exist join to the parent on the left side. /// The second step is to connect it to the parent on the right. For the right /// side, if the objectCondition doesn't have any nodes, we attach it to the /// objectType node. /// </summary> public void connectJoinNode(ICondition previousCondition, ICondition condition, BaseJoin previousJoinNode, BaseJoin joinNode) { if (previousJoinNode != null) { ruleCompiler.attachJoinNode(previousJoinNode, (BaseJoin)joinNode); } else { ruleCompiler.attachJoinNode(previousCondition.LastNode, (BaseJoin)joinNode); } // Current we have to Add the ExistJoin for the right side, which should be either // an alphaNode or the objectTypeNode ObjectCondition oc = getObjectCondition(condition); ObjectTypeNode otn = ruleCompiler.findObjectTypeNode(oc.TemplateName); if (oc.Nodes.Count > 0) { ruleCompiler.attachJoinNode(oc.LastNode, (BaseJoin)joinNode); } else { otn.addSuccessorNode(joinNode, ruleCompiler.Engine, ruleCompiler.Engine.WorkingMemory); } }
public Node ReadNode(NodeId nodeId) { // build list of attributes. SortedDictionary<uint,DataValue> attributes = new SortedDictionary<uint,DataValue>(); attributes.Add(Attributes.NodeId, null); attributes.Add(Attributes.NodeClass, null); attributes.Add(Attributes.BrowseName, null); attributes.Add(Attributes.DisplayName, null); attributes.Add(Attributes.Description, null); attributes.Add(Attributes.WriteMask, null); attributes.Add(Attributes.UserWriteMask, null); attributes.Add(Attributes.DataType, null); attributes.Add(Attributes.ValueRank, null); attributes.Add(Attributes.ArrayDimensions, null); attributes.Add(Attributes.AccessLevel, null); attributes.Add(Attributes.UserAccessLevel, null); attributes.Add(Attributes.Historizing, null); attributes.Add(Attributes.MinimumSamplingInterval, null); attributes.Add(Attributes.EventNotifier, null); attributes.Add(Attributes.Executable, null); attributes.Add(Attributes.UserExecutable, null); attributes.Add(Attributes.IsAbstract, null); attributes.Add(Attributes.InverseName, null); attributes.Add(Attributes.Symmetric, null); attributes.Add(Attributes.ContainsNoLoops, null); // build list of values to read. ReadValueIdCollection itemsToRead = new ReadValueIdCollection(); foreach (uint attributeId in attributes.Keys) { ReadValueId itemToRead = new ReadValueId(); itemToRead.NodeId = nodeId; itemToRead.AttributeId = attributeId; itemsToRead.Add(itemToRead); } // read from server. DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; ResponseHeader responseHeader = Read( null, 0, TimestampsToReturn.Neither, itemsToRead, out values, out diagnosticInfos); ClientBase.ValidateResponse(values, itemsToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead); // process results. int? nodeClass = null; for (int ii = 0; ii < itemsToRead.Count; ii++) { uint attributeId = itemsToRead[ii].AttributeId; // the node probably does not exist if the node class is not found. if (attributeId == Attributes.NodeClass) { if (!DataValue.IsGood(values[ii])) { throw ServiceResultException.Create(values[ii].StatusCode, ii, diagnosticInfos, responseHeader.StringTable); } // check for valid node class. nodeClass = values[ii].Value as int?; if (nodeClass == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not have a valid value for NodeClass: {0}.", values[ii].Value); } } else { if (!DataValue.IsGood(values[ii])) { // check for unsupported attributes. if (values[ii].StatusCode == StatusCodes.BadAttributeIdInvalid) { continue; } // all supported attributes must be readable. if (attributeId != Attributes.Value) { throw ServiceResultException.Create(values[ii].StatusCode, ii, diagnosticInfos, responseHeader.StringTable); } } } attributes[attributeId] = values[ii]; } Node node = null; DataValue value = null; switch ((NodeClass)nodeClass.Value) { default: { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not have a valid value for NodeClass: {0}.", nodeClass.Value); } case NodeClass.Object: { ObjectNode objectNode = new ObjectNode(); value = attributes[Attributes.EventNotifier]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Object does not support the EventNotifier attribute."); } objectNode.EventNotifier = (byte)attributes[Attributes.EventNotifier].GetValue(typeof(byte)); node = objectNode; break; } case NodeClass.ObjectType: { ObjectTypeNode objectTypeNode = new ObjectTypeNode(); value = attributes[Attributes.IsAbstract]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "ObjectType does not support the IsAbstract attribute."); } objectTypeNode.IsAbstract = (bool)attributes[Attributes.IsAbstract].GetValue(typeof(bool)); node = objectTypeNode; break; } case NodeClass.Variable: { VariableNode variableNode = new VariableNode(); // DataType Attribute value = attributes[Attributes.DataType]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Variable does not support the DataType attribute."); } variableNode.DataType = (NodeId)attributes[Attributes.DataType].GetValue(typeof(NodeId)); // ValueRank Attribute value = attributes[Attributes.ValueRank]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Variable does not support the ValueRank attribute."); } variableNode.ValueRank = (int)attributes[Attributes.ValueRank].GetValue(typeof(int)); // ArrayDimensions Attribute value = attributes[Attributes.ArrayDimensions]; if (value != null) { if (value.Value == null) { variableNode.ArrayDimensions = new uint[0]; } else { variableNode.ArrayDimensions = (uint[])value.GetValue(typeof(uint[])); } } // AccessLevel Attribute value = attributes[Attributes.AccessLevel]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Variable does not support the AccessLevel attribute."); } variableNode.AccessLevel = (byte)attributes[Attributes.AccessLevel].GetValue(typeof(byte)); // UserAccessLevel Attribute value = attributes[Attributes.UserAccessLevel]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Variable does not support the UserAccessLevel attribute."); } variableNode.UserAccessLevel = (byte)attributes[Attributes.UserAccessLevel].GetValue(typeof(byte)); // Historizing Attribute value = attributes[Attributes.Historizing]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Variable does not support the Historizing attribute."); } variableNode.Historizing = (bool)attributes[Attributes.Historizing].GetValue(typeof(bool)); // MinimumSamplingInterval Attribute value = attributes[Attributes.MinimumSamplingInterval]; if (value != null) { variableNode.MinimumSamplingInterval = Convert.ToDouble(attributes[Attributes.MinimumSamplingInterval].Value); } node = variableNode; break; } case NodeClass.VariableType: { VariableTypeNode variableTypeNode = new VariableTypeNode(); // IsAbstract Attribute value = attributes[Attributes.IsAbstract]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "VariableType does not support the IsAbstract attribute."); } variableTypeNode.IsAbstract = (bool)attributes[Attributes.IsAbstract].GetValue(typeof(bool)); // DataType Attribute value = attributes[Attributes.DataType]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "VariableType does not support the DataType attribute."); } variableTypeNode.DataType = (NodeId)attributes[Attributes.DataType].GetValue(typeof(NodeId)); // ValueRank Attribute value = attributes[Attributes.ValueRank]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "VariableType does not support the ValueRank attribute."); } variableTypeNode.ValueRank = (int)attributes[Attributes.ValueRank].GetValue(typeof(int)); // ArrayDimensions Attribute value = attributes[Attributes.ArrayDimensions]; if (value != null && value.Value != null) { variableTypeNode.ArrayDimensions = (uint[])attributes[Attributes.ArrayDimensions].GetValue(typeof(uint[])); } node = variableTypeNode; break; } case NodeClass.Method: { MethodNode methodNode = new MethodNode(); // Executable Attribute value = attributes[Attributes.Executable]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Method does not support the Executable attribute."); } methodNode.Executable = (bool)attributes[Attributes.Executable].GetValue(typeof(bool)); // UserExecutable Attribute value = attributes[Attributes.UserExecutable]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Method does not support the UserExecutable attribute."); } methodNode.UserExecutable = (bool)attributes[Attributes.UserExecutable].GetValue(typeof(bool)); node = methodNode; break; } case NodeClass.DataType: { DataTypeNode dataTypeNode = new DataTypeNode(); // IsAbstract Attribute value = attributes[Attributes.IsAbstract]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "DataType does not support the IsAbstract attribute."); } dataTypeNode.IsAbstract = (bool)attributes[Attributes.IsAbstract].GetValue(typeof(bool)); node = dataTypeNode; break; } case NodeClass.ReferenceType: { ReferenceTypeNode referenceTypeNode = new ReferenceTypeNode(); // IsAbstract Attribute value = attributes[Attributes.IsAbstract]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "ReferenceType does not support the IsAbstract attribute."); } referenceTypeNode.IsAbstract = (bool)attributes[Attributes.IsAbstract].GetValue(typeof(bool)); // Symmetric Attribute value = attributes[Attributes.Symmetric]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "ReferenceType does not support the Symmetric attribute."); } referenceTypeNode.Symmetric = (bool)attributes[Attributes.IsAbstract].GetValue(typeof(bool)); // InverseName Attribute value = attributes[Attributes.InverseName]; if (value != null && value.Value != null) { referenceTypeNode.InverseName = (LocalizedText)attributes[Attributes.InverseName].GetValue(typeof(LocalizedText)); } node = referenceTypeNode; break; } case NodeClass.View: { ViewNode viewNode = new ViewNode(); // EventNotifier Attribute value = attributes[Attributes.EventNotifier]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "View does not support the EventNotifier attribute."); } viewNode.EventNotifier = (byte)attributes[Attributes.EventNotifier].GetValue(typeof(byte)); // ContainsNoLoops Attribute value = attributes[Attributes.ContainsNoLoops]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "View does not support the ContainsNoLoops attribute."); } viewNode.ContainsNoLoops = (bool)attributes[Attributes.ContainsNoLoops].GetValue(typeof(bool)); node = viewNode; break; } } // NodeId Attribute value = attributes[Attributes.NodeId]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not support the NodeId attribute."); } node.NodeId = (NodeId)attributes[Attributes.NodeId].GetValue(typeof(NodeId)); node.NodeClass = (NodeClass)nodeClass.Value; // BrowseName Attribute value = attributes[Attributes.BrowseName]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not support the BrowseName attribute."); } node.BrowseName = (QualifiedName)attributes[Attributes.BrowseName].GetValue(typeof(QualifiedName)); // DisplayName Attribute value = attributes[Attributes.DisplayName]; if (value == null) { throw ServiceResultException.Create(StatusCodes.BadUnexpectedError, "Node does not support the DisplayName attribute."); } node.DisplayName = (LocalizedText)attributes[Attributes.DisplayName].GetValue(typeof(LocalizedText)); // Description Attribute value = attributes[Attributes.Description]; if (value != null && value.Value != null) { node.Description = (LocalizedText)attributes[Attributes.Description].GetValue(typeof(LocalizedText)); } // WriteMask Attribute value = attributes[Attributes.WriteMask]; if (value != null) { node.WriteMask = (uint)attributes[Attributes.WriteMask].GetValue(typeof(uint)); } // UserWriteMask Attribute value = attributes[Attributes.UserWriteMask]; if (value != null) { node.WriteMask = (uint)attributes[Attributes.UserWriteMask].GetValue(typeof(uint)); } return node; }
/// <summary> /// Creates an ObjectType node in the address space. /// </summary> public NodeId CreateObjectType( NodeId parentId, NodeId nodeId, QualifiedName browseName, ObjectTypeAttributes attributes) { try { m_lock.Enter(); // validate browse name. if (QualifiedName.IsNull(browseName)) { throw ServiceResultException.Create(StatusCodes.BadBrowseNameInvalid, "BrowseName must not be empty."); } // check for null node id. if (NodeId.IsNull(nodeId)) { nodeId = CreateUniqueNodeId(); } // check if node id exists. if (m_nodes.Exists(nodeId)) { throw ServiceResultException.Create(StatusCodes.BadNodeIdExists, "NodeId '{0}' already exists.", nodeId); } // set the BaseObjectType as the default. if (parentId == null) { parentId = ObjectTypes.BaseObjectType; } // find parent. IObjectType parent = GetManagerHandle(parentId) as IObjectType; if (parent == null) { throw ServiceResultException.Create(StatusCodes.BadParentNodeIdInvalid, "Parent node '{0}' does not exist or is not an ObjectType.", parentId); } // validate reference. ValidateReference(parent, ReferenceTypeIds.HasSubtype, false, NodeClass.ObjectType); // create node. ObjectTypeNode node = new ObjectTypeNode(); node.NodeId = nodeId; node.NodeClass = NodeClass.ObjectType; node.BrowseName = browseName; UpdateAttributes(node, attributes); // IsAbstract if (attributes != null && (attributes.SpecifiedAttributes & (uint)NodeAttributesMask.IsAbstract) != 0) { node.IsAbstract = attributes.IsAbstract; } else { node.IsAbstract = false; } // add reference from parent. AddReference(parent, ReferenceTypeIds.HasSubtype, false, node, true); // add the node. AddNode(node); // return the new node id. return node.NodeId; } finally { m_lock.Exit(); } }
/// <summary> Compile a single ObjectCondition and create the alphaNodes and/or Bindings /// </summary> public override void compile(ICondition condition, int position, Rule.IRule rule, bool alphaMemory) { TemporalCondition cond = (TemporalCondition)condition; ObjectTypeNode otn = ruleCompiler.findObjectTypeNode(cond.TemplateName); // we set remember match to false, since the rule is temporal bool switchMatch = false; if (rule.RememberMatch) { rule.RememberMatch = false; switchMatch = true; } if (otn != null) { BaseAlpha2 first = null; BaseAlpha2 previous = null; BaseAlpha2 current = null; ITemplate templ = cond.Deftemplate; IConstraint[] constrs = cond.Constraints; for (int idx = 0; idx < constrs.Length; idx++) { IConstraint cnstr = constrs[idx]; if (cnstr is LiteralConstraint) { current = ruleCompiler.compileConstraint((LiteralConstraint)cnstr, templ, rule); } else if (cnstr is AndLiteralConstraint) { current = ruleCompiler.compileConstraint((AndLiteralConstraint)cnstr, templ, rule); } else if (cnstr is OrLiteralConstraint) { current = ruleCompiler.compileConstraint((OrLiteralConstraint)cnstr, templ, rule); } else if (cnstr is BoundConstraint) { ruleCompiler.compileConstraint((BoundConstraint)cnstr, templ, rule, position); } else if (cnstr is PredicateConstraint) { current = ruleCompiler.compileConstraint((PredicateConstraint)cnstr, templ, rule, position); } // we Add the node to the previous if (first == null) { first = current; previous = current; } else if (current != previous) { try { previous.addSuccessorNode(current, ruleCompiler.Engine, ruleCompiler.Memory); // now set the previous to current previous = current; } catch (AssertException e) { // send an event } } } if (first != null) { attachAlphaNode(otn, first, cond); } } if (!cond.Negated) { position++; } if (switchMatch) { rule.RememberMatch = true; } }
/// <summary> /// Returns the value of an attribute. /// </summary> public void Read( ReadValueId request, DataValue result, DiagnosticInfo diagnosticInfo) { lock (m_lock) { // find the node to read. Node source = m_nodes.Find(request.NodeId); result.ServerTimestamp = DateTime.UtcNow; if (source == null) { result.StatusCode = new StatusCode(StatusCodes.BadNodeIdUnknown); return; } result.Value = Variant.Null; // switch on the attribute value. switch (request.AttributeId) { case Attributes.NodeId: { result.Value = new Variant(source.NodeId); break; } case Attributes.NodeClass: { result.Value = new Variant(DataTypes.EnumToMask(source.NodeClass)); break; } case Attributes.BrowseName: { result.Value = new Variant(source.BrowseName); break; } case Attributes.DisplayName: { result.Value = new Variant(source.DisplayName); break; } case Attributes.Description: { result.Value = new Variant(source.Description); break; } case Attributes.WriteMask: { result.Value = new Variant(source.WriteMask); break; } case Attributes.UserWriteMask: { result.Value = new Variant(source.UserWriteMask); break; } case Attributes.Value: { // check if another component has installed a read callback. ReadValueEventHandler callback = null; if (m_callbacks.TryGetValue(source.NodeId.Identifier, out callback)) { result.Value = new Variant(callback()); break; } // use the value cached in the node otherwise. VariableNode variable = source as VariableNode; if (variable != null) { result.Value = variable.Value; result.SourceTimestamp = DateTime.UtcNow; // The Value attribute requires a SourceTimestamp. break; } VariableTypeNode variableType = source as VariableTypeNode; if (variableType != null) { result.Value = variableType.Value; result.SourceTimestamp = DateTime.UtcNow; // The Value attribute requires a SourceTimestamp. break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.DataType: { VariableNode variable = source as VariableNode; if (variable != null) { result.Value = new Variant(variable.DataType); break; } VariableTypeNode variableType = source as VariableTypeNode; if (variableType != null) { result.Value = new Variant(variableType.DataType); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.ValueRank: { VariableNode variable = source as VariableNode; if (variable != null) { result.Value = new Variant(variable.ValueRank); break; } VariableTypeNode variableType = source as VariableTypeNode; if (variableType != null) { result.Value = new Variant(variableType.ValueRank); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.MinimumSamplingInterval: { VariableNode variable = source as VariableNode; if (variable != null) { result.Value = new Variant(variable.MinimumSamplingInterval); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.Historizing: { VariableNode variable = source as VariableNode; if (variable != null) { result.Value = new Variant(variable.Historizing); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.AccessLevel: { VariableNode variable = source as VariableNode; if (variable != null) { result.Value = new Variant(variable.AccessLevel); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.UserAccessLevel: { VariableNode variable = source as VariableNode; if (variable != null) { result.Value = new Variant(variable.UserAccessLevel); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.EventNotifier: { ObjectNode objectn = source as ObjectNode; if (objectn != null) { result.Value = new Variant(objectn.EventNotifier); break; } ViewNode view = source as ViewNode; if (view != null) { result.Value = new Variant(view.EventNotifier); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.Executable: { MethodNode method = source as MethodNode; if (method != null) { result.Value = new Variant(method.Executable); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.UserExecutable: { MethodNode method = source as MethodNode; if (method != null) { result.Value = new Variant(method.UserExecutable); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.ContainsNoLoops: { ViewNode view = source as ViewNode; if (view != null) { result.Value = new Variant(view.ContainsNoLoops); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.InverseName: { ReferenceTypeNode referenceType = source as ReferenceTypeNode; if (referenceType != null) { result.Value = new Variant(referenceType.InverseName); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.IsAbstract: { DataTypeNode dataType = source as DataTypeNode; if (dataType != null) { result.Value = new Variant(dataType.IsAbstract); break; } ReferenceTypeNode referenceType = source as ReferenceTypeNode; if (referenceType != null) { result.Value = new Variant(referenceType.IsAbstract); break; } ObjectTypeNode objectType = source as ObjectTypeNode; if (objectType != null) { result.Value = new Variant(objectType.IsAbstract); break; } VariableTypeNode variableType = source as VariableTypeNode; if (variableType != null) { result.Value = new Variant(variableType.IsAbstract); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } case Attributes.Symmetric: { ReferenceTypeNode referenceType = source as ReferenceTypeNode; if (referenceType != null) { result.Value = new Variant(referenceType.Symmetric); break; } result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } default: { result.StatusCode = new StatusCode(StatusCodes.BadAttributeIdInvalid); break; } } } }