private void ValidateReference(
ILocalNode source,
NodeId referenceTypeId,
bool isInverse,
NodeClass targetNodeClass)
{
// find reference type.
IReferenceType referenceType = GetLocalNode(referenceTypeId) as IReferenceType;
if (referenceType == null)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceTypeIdInvalid, "Reference type '{0}' does not exist.", referenceTypeId);
}
// swap the source and target for inverse references.
NodeClass sourceNodeClass = source.NodeClass;
if (isInverse)
{
sourceNodeClass = targetNodeClass;
targetNodeClass = source.NodeClass;
}
// check HasComponent references.
if (m_server.TypeTree.IsTypeOf(referenceTypeId, ReferenceTypeIds.HasComponent))
{
if ((sourceNodeClass & (NodeClass.Object | NodeClass.Variable | NodeClass.ObjectType | NodeClass.VariableType)) == 0)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceNotAllowed, "Source node cannot be used with HasComponent references.");
}
if ((targetNodeClass & (NodeClass.Object | NodeClass.Variable | NodeClass.Method)) == 0)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceNotAllowed, "Target node cannot be used with HasComponent references.");
}
if (targetNodeClass == NodeClass.Variable)
{
if ((targetNodeClass & (NodeClass.Variable | NodeClass.VariableType)) == 0)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceNotAllowed, "A Variable must be a component of an Variable or VariableType.");
}
}
if (targetNodeClass == NodeClass.Method)
{
if ((sourceNodeClass & (NodeClass.Object | NodeClass.ObjectType)) == 0)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceNotAllowed, "A Method must be a component of an Object or ObjectType.");
}
}
}
// check HasProperty references.
if (m_server.TypeTree.IsTypeOf(referenceTypeId, ReferenceTypes.HasProperty))
{
if (targetNodeClass != NodeClass.Variable)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceNotAllowed, "Targets of HasProperty references must be Variables.");
}
}
// check HasSubtype references.
if (m_server.TypeTree.IsTypeOf(referenceTypeId, ReferenceTypeIds.HasSubtype))
{
if ((sourceNodeClass & (NodeClass.DataType | NodeClass.ReferenceType | NodeClass.ObjectType | NodeClass.VariableType)) == 0)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceNotAllowed, "Source node cannot be used with HasSubtype references.");
}
if (targetNodeClass != sourceNodeClass)
{
throw ServiceResultException.Create(StatusCodes.BadReferenceNotAllowed, "The source and target cannot be connected by a HasSubtype reference.");
}
}
// TBD - check rules for other reference types.
}
#endregion