private bool VerifyFilterResults(
Node node,
BrowseDescription description,
ReferenceDescriptionCollection actualList)
{
NodeId referenceTypeId = description.ReferenceTypeId;
BrowseDirection browseDirection = description.BrowseDirection;
bool includeSubtypes = description.IncludeSubtypes;
NodeClass nodeClassMask = (NodeClass)description.NodeClassMask;
// nothing to verify if no master list.
ReferenceDescriptionCollection masterList = node.Handle as ReferenceDescriptionCollection;
if (masterList == null)
{
return true;
}
// cannot verify filter if filter criteria not returned.
BrowseResultMask requiredMask = (BrowseResultMask.ReferenceTypeId | BrowseResultMask.IsForward | BrowseResultMask.NodeClass);
if ((description.ResultMask & (uint)requiredMask) != (uint)requiredMask)
{
return true;
}
bool success = true;
// look for missing references.
for (int ii = 0; ii < masterList.Count; ii++)
{
ReferenceDescription reference = masterList[ii];
if (nodeClassMask != NodeClass.Unspecified && (reference.NodeClass & nodeClassMask) == 0)
{
continue;
}
if ((browseDirection == BrowseDirection.Inverse && reference.IsForward) || (browseDirection == BrowseDirection.Forward && !reference.IsForward))
{
continue;
}
if (reference.ReferenceTypeId != referenceTypeId)
{
if (!includeSubtypes)
{
continue;
}
if (!Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, referenceTypeId))
{
continue;
}
}
bool found = false;
for (int jj = 0; jj < actualList.Count; jj++)
{
if (actualList[jj].NodeId == reference.NodeId && actualList[jj].IsForward == reference.IsForward && actualList[jj].ReferenceTypeId == reference.ReferenceTypeId)
{
found = true;
break;
}
}
if (!found)
{
Log(
"Did not return expected target when browsing Node '{0}'. NodeId = {1}, NodeClassMask = {2}, ReferenceFilter = {3}, TargetName = {4}, NodeClass = {5}, ReferenceType = {6}, TargetId = {7}.",
node,
node.NodeId,
nodeClassMask,
Session.TypeTree.FindReferenceTypeName(referenceTypeId),
reference.DisplayName,
reference.NodeClass,
Session.TypeTree.FindReferenceTypeName(reference.ReferenceTypeId),
reference.NodeId);
success = false;
}
}
// look for extra references.
for (int ii = 0; ii < actualList.Count; ii++)
{
bool found = false;
for (int jj = 0; jj < masterList.Count; jj++)
{
ReferenceDescription reference = masterList[jj];
if (nodeClassMask != NodeClass.Unspecified && (reference.NodeClass & nodeClassMask) == 0)
{
continue;
}
if (actualList[ii].NodeId != reference.NodeId || actualList[ii].IsForward != reference.IsForward || actualList[ii].ReferenceTypeId != reference.ReferenceTypeId)
{
continue;
}
if ((browseDirection != BrowseDirection.Inverse && reference.IsForward) || (browseDirection != BrowseDirection.Forward && !reference.IsForward))
{
if (!includeSubtypes)
{
if (reference.ReferenceTypeId == referenceTypeId)
{
found = true;
break;
}
}
else
{
if (Session.TypeTree.IsTypeOf(reference.ReferenceTypeId, referenceTypeId))
{
found = true;
break;
}
}
}
Log(
"Returned invalid target when browsing Node '{0}'. NodeId = {1}, NodeClassMask = {2}, ReferenceFilter = {3}, TargetName = {4}, NodeClass = {5}, ReferenceType = {6}, TargetId = {7}.",
node,
node.NodeId,
nodeClassMask,
Session.TypeTree.FindReferenceTypeName(referenceTypeId),
reference.DisplayName,
reference.NodeClass,
Session.TypeTree.FindReferenceTypeName(reference.ReferenceTypeId),
reference.NodeId);
success = false;
break;
}
if (!found)
{
Log(
"Returned unexpected target when browsing Node '{0}'. NodeId = {1}, NodeClassMask = {2}, ReferenceFilter = {3}, TargetName = {4}, NodeClass = {5}, ReferenceType = {6}, TargetId = {7}.",
node,
node.NodeId,
nodeClassMask,
Session.TypeTree.FindReferenceTypeName(referenceTypeId),
actualList[ii].DisplayName,
actualList[ii].NodeClass,
Session.TypeTree.FindReferenceTypeName(actualList[ii].ReferenceTypeId),
actualList[ii].NodeId);
success = false;
continue;
}
}
return success;
}