public virtual void TranslateBrowsePath(
OperationContext context,
object sourceHandle,
RelativePathElement relativePath,
IList<ExpandedNodeId> targetIds,
IList<NodeId> unresolvedTargetIds)
{
ServerSystemContext systemContext = m_systemContext.Copy(context);
IDictionary<NodeId,NodeState> operationCache = new NodeIdDictionary<NodeState>();
lock (Lock)
{
// verify that the node exists.
NodeState source = IsHandleInNamespace(sourceHandle);
if (source == null)
{
return;
}
// validate node.
if (!ValidateNode(systemContext, source))
{
return;
}
// get list of references that relative path.
INodeBrowser browser = source.CreateBrowser(
systemContext,
null,
relativePath.ReferenceTypeId,
relativePath.IncludeSubtypes,
(relativePath.IsInverse) ? BrowseDirection.Inverse : BrowseDirection.Forward,
relativePath.TargetName,
null,
false);
// check the browse names.
try
{
for (IReference reference = browser.Next(); reference != null; reference = browser.Next())
{
// ignore unknown external references.
if (reference.TargetId.IsAbsolute)
{
continue;
}
NodeState target = null;
// check for local reference.
NodeStateReference referenceInfo = reference as NodeStateReference;
if (referenceInfo != null)
{
target = referenceInfo.Target;
}
if (target == null)
{
NodeId targetId = (NodeId)reference.TargetId;
// the target may be a reference to a node in another node manager.
if (!IsNodeIdInNamespace(targetId))
{
unresolvedTargetIds.Add((NodeId)reference.TargetId);
continue;
}
// look up the target manually.
target = GetManagerHandle(systemContext, targetId, operationCache) as NodeState;
if (target == null)
{
continue;
}
}
// check browse name.
if (target.BrowseName == relativePath.TargetName)
{
if (!targetIds.Contains(reference.TargetId))
{
targetIds.Add(reference.TargetId);
}
}
}
}
finally
{
browser.Dispose();
}
}
}