using System; using System.Linq; using Artemis.Storage.Entities.Profile.Abstract; using Artemis.Storage.Entities.Profile.Conditions; namespace Artemis.Core { /// /// A group containing zero to many s which it evaluates using a boolean specific /// operator /// public class DataModelConditionGroup : DataModelConditionPart { private bool _disposed; /// /// Creates a new instance of the class /// /// public DataModelConditionGroup(DataModelConditionPart parent) { Parent = parent; Entity = new DataModelConditionGroupEntity(); } /// /// Creates a new instance of the class /// /// /// public DataModelConditionGroup(DataModelConditionPart parent, DataModelConditionGroupEntity entity) { Parent = parent; Entity = entity; BooleanOperator = (BooleanOperator) Entity.BooleanOperator; foreach (DataModelConditionPartEntity childEntity in Entity.Children) { if (childEntity is DataModelConditionGroupEntity groupEntity) AddChild(new DataModelConditionGroup(this, groupEntity)); else if (childEntity is DataModelConditionListEntity listEntity) AddChild(new DataModelConditionList(this, listEntity)); else if (childEntity is DataModelConditionEventEntity eventEntity) AddChild(new DataModelConditionEvent(this, eventEntity)); else if (childEntity is DataModelConditionGeneralPredicateEntity predicateEntity) AddChild(new DataModelConditionGeneralPredicate(this, predicateEntity)); else if (childEntity is DataModelConditionListPredicateEntity listPredicateEntity) AddChild(new DataModelConditionListPredicate(this, listPredicateEntity)); else if (childEntity is DataModelConditionEventPredicateEntity eventPredicateEntity) AddChild(new DataModelConditionEventPredicate(this, eventPredicateEntity)); } } /// /// Gets or sets the boolean operator of this group /// public BooleanOperator BooleanOperator { get; set; } internal DataModelConditionGroupEntity Entity { get; set; } /// public override bool Evaluate() { if (_disposed) throw new ObjectDisposedException("DataModelConditionGroup"); // Empty groups are always true if (Children.Count == 0) return true; // Groups with only one child ignore the boolean operator if (Children.Count == 1) return Children[0].Evaluate(); switch (BooleanOperator) { case BooleanOperator.And: return Children.All(c => c.Evaluate()); case BooleanOperator.Or: return Children.Any(c => c.Evaluate()); case BooleanOperator.AndNot: return Children.All(c => !c.Evaluate()); case BooleanOperator.OrNot: return Children.Any(c => !c.Evaluate()); default: throw new ArgumentOutOfRangeException(); } } #region IDisposable /// protected override void Dispose(bool disposing) { _disposed = true; foreach (DataModelConditionPart child in Children) child.Dispose(); base.Dispose(disposing); } #endregion /// internal override bool EvaluateObject(object target) { if (_disposed) throw new ObjectDisposedException("DataModelConditionGroup"); // Empty groups are always true if (Children.Count == 0) return true; // Groups with only one child ignore the boolean operator if (Children.Count == 1) return Children[0].EvaluateObject(target); return BooleanOperator switch { BooleanOperator.And => Children.All(c => c.EvaluateObject(target)), BooleanOperator.Or => Children.Any(c => c.EvaluateObject(target)), BooleanOperator.AndNot => Children.All(c => !c.EvaluateObject(target)), BooleanOperator.OrNot => Children.Any(c => !c.EvaluateObject(target)), _ => throw new ArgumentOutOfRangeException() }; } internal override void Save() { Entity.BooleanOperator = (int) BooleanOperator; Entity.Children.Clear(); Entity.Children.AddRange(Children.Select(c => c.GetEntity())); foreach (DataModelConditionPart child in Children) child.Save(); } internal override DataModelConditionPartEntity GetEntity() { return Entity; } } /// /// Represents a boolean operator /// public enum BooleanOperator { /// /// All the conditions in the group should evaluate to true /// And, /// /// Any of the conditions in the group should evaluate to true /// Or, /// /// All the conditions in the group should evaluate to false /// AndNot, /// /// Any of the conditions in the group should evaluate to false /// OrNot } }