// Copyright (C) Stichting Deltares 2018. All rights reserved.
//
// This file is part of the application DAM - UI.
//
// DAM - UI is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
// All names, logos, and references to "Deltares" are registered trademarks of
// Stichting Deltares and remain full property of Stichting Deltares at all times.
// All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Deltares.Standard.Validation;
namespace Deltares.Standard.Specifications.Extensions
{
public static class SpecificationExtensions
{
public static IEnumerable GetBySpecification(this IEnumerable collection, ISpecification specification)
{
return collection.Where(specification.IsSatisfiedBy);
}
public static bool IsSatisfiedBySpecification(this T source, ISpecification specification)
{
return specification.IsSatisfiedBy(source);
}
public static bool IsNotSatisfiedBySpecification(this T source, ISpecification specification)
{
return !IsSatisfiedBySpecification(source, specification);
}
public static IEnumerable Validate(this T source, string groupName)
{
throw new NotImplementedException();
}
public static IEnumerable Validate(this T source)
{
var validationResults = new List();
foreach (var attribute in source.GetType().GetCustomAttributes(false))
{
var specAttr = attribute as SpecificationBaseAttribute;
if (specAttr != null)
{
if (IsNotSatisfiedBySpecification(source, (ISpecification)specAttr.Specification))
AddValidationResult(source, validationResults, specAttr);
}
}
foreach (PropertyInfo property in source.GetType().GetProperties())
{
foreach (object attribute in property.GetCustomAttributes(true))
{
var specAttr = attribute as SpecificationBaseAttribute;
if (specAttr != null)
{
object candidateValue = property.GetValue(source, null);
if (!specAttr.Specification.IsSatisfiedBy(candidateValue))
AddValidationResult(property, validationResults, specAttr);
}
else
{
var minAttr = attribute as MinimumAttribute;
if (minAttr != null)
{
var gte =
new GreaterThanOrEqualToSpecification(property.Name, minAttr.AttributeValue);
if (!gte.IsSatisfiedBy(source))
{
validationResults.Add(new ValidationResult()
{
Subject = property,
MessageType = ValidationResultType.Error,
Error = new ValidationException(string.Format("The property or field {0} has the value {1} which is less then the specification {2}",
property.Name, gte.CandidateValue, minAttr.AttributeValue))
});
}
}
else
{
var maxAttr = attribute as MaximumAttribute;
if (maxAttr != null)
{
var lte =
new LessThanOrEqualToSpecification(property.Name, maxAttr.AttributeValue);
if (!lte.IsSatisfiedBy(source))
{
validationResults.Add(new ValidationResult()
{
Subject = property,
MessageType = ValidationResultType.Error,
Error = new ValidationException(string.Format("The property or field {0} has the value {1} which is greater then the specification {2}",
property.Name, lte.CandidateValue, maxAttr.AttributeValue))
});
}
}
}
}
}
}
return validationResults;
}
private static void AddValidationResult(object subject, ICollection validationResults, SpecificationBaseAttribute specAttr)
{
string message = specAttr.NotSatisfiedText;
if (string.IsNullOrWhiteSpace(message))
message = specAttr.Specification.Description;
if (string.IsNullOrWhiteSpace(message))
message = specAttr.Specification.Name;
if (string.IsNullOrWhiteSpace(message))
message = specAttr.Specification.ToString();
validationResults.Add(new ValidationResult()
{
Subject = subject,
MessageType = ValidationResultType.Error,
Error = new ValidationException(message)
});
}
}
}