/// <summary>
/// Returns the references for the node that meets the criteria specified.
/// </summary>
protected virtual ReferenceDescription GetReferenceDescription(
ServerSystemContext context,
Dictionary<NodeId,NodeState> cache,
IReference reference,
ContinuationPoint continuationPoint)
{
ServerSystemContext systemContext = m_systemContext.Copy(context);
// create the type definition reference.
ReferenceDescription description = new ReferenceDescription();
description.NodeId = reference.TargetId;
description.SetReferenceType(continuationPoint.ResultMask, reference.ReferenceTypeId, !reference.IsInverse);
// check if reference is in the view.
if (!IsReferenceInView(context, continuationPoint, reference))
{
return null;
}
// do not cache target parameters for remote nodes.
if (reference.TargetId.IsAbsolute)
{
// only return remote references if no node class filter is specified.
if (continuationPoint.NodeClassMask != 0)
{
return null;
}
return description;
}
NodeState target = null;
// check for local reference.
NodeStateReference referenceInfo = reference as NodeStateReference;
if (referenceInfo != null)
{
target = referenceInfo.Target;
}
// check for internal reference.
if (target == null)
{
NodeHandle handle = GetManagerHandle(context, (NodeId)reference.TargetId, null) as NodeHandle;
if (handle != null)
{
target = ValidateNode(context, handle, null);
}
}
// the target may be a reference to a node in another node manager. In these cases
// the target attributes must be fetched by the caller. The Unfiltered flag tells the
// caller to do that.
if (target == null)
{
description.Unfiltered = true;
return description;
}
// apply node class filter.
if (continuationPoint.NodeClassMask != 0 && ((continuationPoint.NodeClassMask & (uint)target.NodeClass) == 0))
{
return null;
}
// check if target is in the view.
if (!IsNodeInView(context, continuationPoint, target))
{
return null;
}
// look up the type definition.
NodeId typeDefinition = null;
BaseInstanceState instance = target as BaseInstanceState;
if (instance != null)
{
typeDefinition = instance.TypeDefinitionId;
}
// set target attributes.
description.SetTargetAttributes(
continuationPoint.ResultMask,
target.NodeClass,
target.BrowseName,
target.DisplayName,
typeDefinition);
return description;
}