public NodeId CreateMethod(
NodeId parentId,
NodeId referenceTypeId,
NodeId nodeId,
QualifiedName browseName,
MethodAttributes attributes)
{
if (browseName == null) throw new ArgumentNullException("browseName");
try
{
m_lock.Enter();
// 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);
}
// find parent.
ILocalNode parent = null;
if (!NodeId.IsNull(parentId))
{
parent = GetManagerHandle(parentId) as ILocalNode;
if (parent == null)
{
throw ServiceResultException.Create(StatusCodes.BadParentNodeIdInvalid, "Parent node '{0}' does not exist.", parentId);
}
// validate reference.
ValidateReference(parent, referenceTypeId, false, NodeClass.Method);
}
// validate browse name.
if (QualifiedName.IsNull(browseName))
{
throw ServiceResultException.Create(StatusCodes.BadBrowseNameInvalid, "BrowsName must not be empty.");
}
// verify instance declarations.
ILocalNode instanceDeclaration = FindInstanceDeclaration(parent, browseName);
if (instanceDeclaration != null)
{
if (instanceDeclaration.NodeClass != NodeClass.Method)
{
throw ServiceResultException.Create(
StatusCodes.BadNodeClassInvalid,
"The type model requires that node with a browse name of {0} have a NodeClass of {1}.",
browseName,
instanceDeclaration.NodeClass);
}
}
// get the variable.
IMethod method = instanceDeclaration as IMethod;
// create node.
MethodNode node = new MethodNode();
// set defaults.
node.NodeId = nodeId;
node.NodeClass = NodeClass.Method;
node.BrowseName = browseName;
node.DisplayName = browseName.Name;
node.Description = null;
node.WriteMask = 0;
node.UserWriteMask = 0;
node.Executable = false;
node.UserExecutable = false;
// set defaults from instance declaration.
if (method != null)
{
node.DisplayName = method.DisplayName;
node.Description = method.Description;
node.WriteMask = (uint)method.WriteMask;
node.UserWriteMask = (uint)method.UserWriteMask;
node.Executable = method.Executable;
node.UserExecutable = method.UserExecutable;
}
// update attributes.
UpdateAttributes(node, attributes);
// Executable
if (attributes != null && (attributes.SpecifiedAttributes & (uint)NodeAttributesMask.Executable) != 0)
{
node.Executable = attributes.Executable;
}
// UserExecutable
if (attributes != null && (attributes.SpecifiedAttributes & (uint)NodeAttributesMask.UserExecutable) != 0)
{
node.UserExecutable = attributes.UserExecutable;
}
// add references with parent.
if (parent != null)
{
AddReference(parent, referenceTypeId, false, node, true);
}
// add to address space.
AddNode(node);
// return the new node id.
return node.NodeId;
}
finally
{
m_lock.Exit();
}
}