don't reinvent the wheel; move attribute validation logic from Oms to AttributeImplementation
This commit is contained in:
parent
3a96529a21
commit
0e40deb35b
@ -30,10 +30,13 @@ public abstract class AttributeImplementation<T> : AttributeImplementation
|
|||||||
}
|
}
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override IEnumerable<Type>? ValidDataTypes => [ typeof(T) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class AttributeImplementation : ClassImplementation
|
public abstract class AttributeImplementation : ClassImplementation
|
||||||
{
|
{
|
||||||
|
protected virtual IEnumerable<Type>? ValidDataTypes { get; }
|
||||||
protected abstract object? ConvertFromInternal(Oms oms, object? value);
|
protected abstract object? ConvertFromInternal(Oms oms, object? value);
|
||||||
|
|
||||||
public object? ReadDerivedData(BinaryReader br)
|
public object? ReadDerivedData(BinaryReader br)
|
||||||
@ -53,9 +56,19 @@ public abstract class AttributeImplementation : ClassImplementation
|
|||||||
ExecuteBuildElementInternal(oms, targetInstance, elementContent, elementContentInstance, objCell);
|
ExecuteBuildElementInternal(oms, targetInstance, elementContent, elementContentInstance, objCell);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract bool IsValidValueInternal(object value);
|
protected virtual void ValidateInternal(Oms oms, InstanceHandle attributeInstance, object value)
|
||||||
public bool IsValidValue(object value)
|
|
||||||
{
|
{
|
||||||
return IsValidValueInternal(value);
|
// do nothing by default
|
||||||
|
}
|
||||||
|
public void Validate(Oms oms, InstanceHandle attributeInstance, object value)
|
||||||
|
{
|
||||||
|
if (ValidDataTypes != null)
|
||||||
|
{
|
||||||
|
if (value != null && !ValidDataTypes.Contains(value.GetType()))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(String.Format("value {0} cannot be converted to attribute type `{1}`", value is string ? "\"" + value.ToString() + "\"" : value, oms.GetInstanceText(attributeInstance)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ValidateInternal(oms, attributeInstance, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,9 +54,4 @@ public class BooleanAttributeImplementation : AttributeImplementation<bool>
|
|||||||
objCell.Add("value", oms.GetAttributeValue<bool>(targetInstance, elementContentInstance));
|
objCell.Add("value", oms.GetAttributeValue<bool>(targetInstance, elementContentInstance));
|
||||||
objCell.Add("text", oms.GetAttributeValue<bool>(targetInstance, elementContentInstance) ? "Yes" : "No");
|
objCell.Add("text", oms.GetAttributeValue<bool>(targetInstance, elementContentInstance) ? "Yes" : "No");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool IsValidValueInternal(object value)
|
|
||||||
{
|
|
||||||
return value is bool;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -61,9 +61,4 @@ public class DateAttributeImplementation : AttributeImplementation<DateTime>
|
|||||||
objCell.Add("text", dt.ToString());
|
objCell.Add("text", dt.ToString());
|
||||||
objCell.Add("dateTimePrecision", "DAY");
|
objCell.Add("dateTimePrecision", "DAY");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool IsValidValueInternal(object value)
|
|
||||||
{
|
|
||||||
return value is DateTime;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -55,9 +55,21 @@ public class NumericAttributeImplementation : AttributeImplementation<decimal>
|
|||||||
objCell.Add("precision", 6);
|
objCell.Add("precision", 6);
|
||||||
objCell.Add("format", "#0.######");
|
objCell.Add("format", "#0.######");
|
||||||
}
|
}
|
||||||
|
protected override void ValidateInternal(Oms oms, InstanceHandle attributeInstance, object value)
|
||||||
protected override bool IsValidValueInternal(object value)
|
|
||||||
{
|
{
|
||||||
return value is decimal;
|
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MinimumValue), out decimal minimumValue))
|
||||||
|
{
|
||||||
|
if (((decimal)value) < minimumValue)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", minimumValue - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MaximumValue), out decimal maximumValue))
|
||||||
|
{
|
||||||
|
if (((decimal)value) > maximumValue)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", maximumValue - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,8 +78,25 @@ public class TextAttributeImplementation : AttributeImplementation<string>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool IsValidValueInternal(object value)
|
protected override void ValidateInternal(Oms oms, InstanceHandle attributeInstance, object value)
|
||||||
{
|
{
|
||||||
return value is string;
|
if (!(value is string))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("value for TextAttribute must be System.String");
|
||||||
|
}
|
||||||
|
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MinimumLength), out decimal minimumLength))
|
||||||
|
{
|
||||||
|
if (((string)value).Length < minimumLength)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be greater than {0} characters", minimumLength - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MaximumLength), out decimal maximumLength))
|
||||||
|
{
|
||||||
|
if (((string)value).Length > maximumLength)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be less than {0} characters", maximumLength + 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -908,7 +908,11 @@ public abstract class Oms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValidateConstraintsForAttribute(InstanceHandle source, InstanceHandle attribute, object value)
|
public void ValidateConstraintsForAttribute(InstanceHandle attribute, object value)
|
||||||
|
{
|
||||||
|
ValidateConstraintsForAttribute(InstanceHandle.Empty, attribute, value);
|
||||||
|
}
|
||||||
|
public void ValidateConstraintsForAttribute(InstanceHandle source, InstanceHandle attribute, object value)
|
||||||
{
|
{
|
||||||
if (!ValidateConstraints)
|
if (!ValidateConstraints)
|
||||||
return;
|
return;
|
||||||
@ -924,11 +928,10 @@ public abstract class Oms
|
|||||||
InstanceHandle a_NumericAttribute = GetInstance(KnownInstanceGuids.Classes.NumericAttribute);
|
InstanceHandle a_NumericAttribute = GetInstance(KnownInstanceGuids.Classes.NumericAttribute);
|
||||||
InstanceHandle a_DateAttribute = GetInstance(KnownInstanceGuids.Classes.DateAttribute);
|
InstanceHandle a_DateAttribute = GetInstance(KnownInstanceGuids.Classes.DateAttribute);
|
||||||
|
|
||||||
InstanceHandle sourceParentClass = GetParentClass(source);
|
|
||||||
|
|
||||||
bool Verify_Classes_Contain_Attributes = false;
|
bool Verify_Classes_Contain_Attributes = false;
|
||||||
if (Verify_Classes_Contain_Attributes)
|
if (Verify_Classes_Contain_Attributes && source != InstanceHandle.Empty)
|
||||||
{
|
{
|
||||||
|
InstanceHandle sourceParentClass = GetParentClass(source);
|
||||||
if (!RecursiveClassHasAttribute(sourceParentClass, attribute))
|
if (!RecursiveClassHasAttribute(sourceParentClass, attribute))
|
||||||
{
|
{
|
||||||
string name = GetAttributeValue<string>(attribute, GetInstance(KnownAttributeGuids.Text.Name));
|
string name = GetAttributeValue<string>(attribute, GetInstance(KnownAttributeGuids.Text.Name));
|
||||||
@ -936,54 +939,15 @@ public abstract class Oms
|
|||||||
throw new ArgumentException(String.Format("Undefined attribute `{0}` on class `{1}`", name ?? GetGlobalIdentifier(attribute).ToString("b"), sourceParentClassName ?? GetGlobalIdentifier(sourceParentClass).ToString("b")));
|
throw new ArgumentException(String.Format("Undefined attribute `{0}` on class `{1}`", name ?? GetGlobalIdentifier(attribute).ToString("b"), sourceParentClassName ?? GetGlobalIdentifier(sourceParentClass).ToString("b")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsInstanceOf(attribute, a_TextAttribute))
|
Guid parentClassGuid = GetGlobalIdentifier(GetParentClass(attribute));
|
||||||
|
IEnumerable<AttributeImplementation> attrs = ClassImplementations.GetAll<AttributeImplementation>();
|
||||||
|
foreach (AttributeImplementation impl in attrs)
|
||||||
{
|
{
|
||||||
if (!(value is string))
|
if (impl.ClassGuid == parentClassGuid)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("value for TextAttribute must be System.String");
|
impl.Validate(this, attribute, value);
|
||||||
}
|
// throw new ArgumentException(String.Format("value {0} cannot be converted to a `{1}`", value is string ? "\"" + value + "\"" : value, Oms.GetInstanceText(Oms.GetParentClass(parm))), nameof(value));
|
||||||
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MinimumLength), out decimal minimumLength))
|
|
||||||
{
|
|
||||||
if (((string)value).Length < minimumLength)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be greater than {0} characters", minimumLength - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MaximumLength), out decimal maximumLength))
|
|
||||||
{
|
|
||||||
if (((string)value).Length > maximumLength)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be less than {0} characters", maximumLength + 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (IsInstanceOf(attribute, a_BooleanAttribute))
|
|
||||||
{
|
|
||||||
if (!(value is bool))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("value for BooleanAttribute must be System.Boolean");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (IsInstanceOf(attribute, a_NumericAttribute))
|
|
||||||
{
|
|
||||||
if (!(value is decimal))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("value for NumericAttribute must be System.Decimal");
|
|
||||||
}
|
|
||||||
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MinimumValue), out decimal minimumValue))
|
|
||||||
{
|
|
||||||
if (((decimal)value) < minimumValue)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", minimumValue - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MaximumValue), out decimal maximumValue))
|
|
||||||
{
|
|
||||||
if (((decimal)value) > maximumValue)
|
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", maximumValue - 1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1001,14 +965,14 @@ public abstract class Oms
|
|||||||
IReadOnlyCollection<InstanceHandle> superclasses = GetRelatedInstances(sourceParentClass, GetInstance(KnownRelationshipGuids.Class__has_super__Class));
|
IReadOnlyCollection<InstanceHandle> superclasses = GetRelatedInstances(sourceParentClass, GetInstance(KnownRelationshipGuids.Class__has_super__Class));
|
||||||
if (superclasses != null)
|
if (superclasses != null)
|
||||||
{
|
{
|
||||||
foreach (InstanceHandle ir in superclasses)
|
foreach (InstanceHandle ir in superclasses)
|
||||||
{
|
|
||||||
if (RecursiveClassHasAttribute(ir, attribute))
|
|
||||||
{
|
{
|
||||||
return true;
|
if (RecursiveClassHasAttribute(ir, attribute))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -190,18 +190,6 @@ public class OmsContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private void ValidateAttributeConstraints(InstanceHandle parm, object value)
|
|
||||||
{
|
|
||||||
Guid parentClassGuid = Oms.GetGlobalIdentifier(Oms.GetParentClass(parm));
|
|
||||||
IEnumerable<AttributeImplementation> attrs = Oms.ClassImplementations.GetAll<AttributeImplementation>();
|
|
||||||
foreach (AttributeImplementation impl in attrs)
|
|
||||||
{
|
|
||||||
if (impl.ClassGuid == parentClassGuid && !impl.IsValidValue(value))
|
|
||||||
{
|
|
||||||
throw new ArgumentException(String.Format("value {0} cannot be converted to a `{1}`", value is string ? "\"" + value + "\"" : value, Oms.GetInstanceText(Oms.GetParentClass(parm))), nameof(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetWorkData(IInstanceReference parm, object? value)
|
public void SetWorkData(IInstanceReference parm, object? value)
|
||||||
{
|
{
|
||||||
@ -236,7 +224,7 @@ public class OmsContext
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ValidateAttributeConstraints(parm, value);
|
Oms.ValidateConstraintsForAttribute(parm, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_WorkData[parm] = value;
|
_WorkData[parm] = value;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user