| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 | using System;using System.Linq;using System.Linq.Expressions;using System.Reflection;namespace InABox.Core{    public class StandardProperty : IProperty    {        public Type _class;        private Func<object, object> _getter;        private Func<object, object> _nullSafeGetter;        private string _name = "";        private Action<object, object?> _setter;        private bool _checkedExpressions;        public string _type = "";        public Type _propertyType = typeof(object);        public StandardProperty()        {            Editor = new NullEditor();            HasEditor = false;        }        public string Class        {            get => _class.EntityName();            set            {                _class = CoreUtils.GetEntity(value);                ClearExpressions();            }        }        public Type? ClassType        {            get => _class;            set            {                _class = value ?? typeof(object);            }        }        public string Name        {            get => _name;            set            {                _name = value;                ClearExpressions();            }        }        public string Type        {            get => _type;            set            {                Type propType;                try                {                    propType = CoreUtils.GetEntityOrNull(_type) ?? typeof(object);                }                catch                {                    propType = typeof(object);                }                PropertyType = propType; // Invoke other setter to ensure consistency of functionality            }        }        public Type PropertyType        {            get => _propertyType;            set            {                _propertyType = value;                _type = value.EntityName();                IsEntityLink = _propertyType.HasInterface(typeof(IEntityLink));                IsEnclosedEntity = _propertyType.HasInterface(typeof(IEnclosedEntity));                IsParent = IsEnclosedEntity || IsEntityLink;            }        }        public PropertyInfo Property { get; set; }        //[ComboLookupEditor(typeof(PropertyEditorLookups))]        public BaseEditor Editor { get; set; }        public bool HasEditor { get; set; }        public string Caption { get; set; }        public string Comment { get; set; }        private decimal _propertySequence;        private long _sequence;        public long Sequence        {            get => _sequence;            set            {                _sequence = value;                _propertySequence = CalculatePropertySequence();            }        }        [NullEditor]        public string Page { get; set; }        public bool Required { get; set; }        public LoggablePropertyAttribute? Loggable { get; set; }        private IProperty? _parent;        public IProperty? Parent        {            get => _parent;            set            {                _parent = value;                _propertySequence = CalculatePropertySequence();            }        }        public bool IsEntityLink { get; set; }        public bool IsEnclosedEntity { get; set; }        public bool IsParent { get; set; }        private bool? _calculated;        public bool IsCalculated        {            get            {                if (!_calculated.HasValue)                {                    _calculated = Property.GetCustomAttribute<AggregateAttribute>() != null                        || Property.GetCustomAttribute<ComplexFormulaAttribute>() != null                        || Property.GetCustomAttribute<FormulaAttribute>() != null                        || Property.GetCustomAttribute<ConditionAttribute>() != null                        || Property.GetCustomAttribute<ChildEntityAttribute>() != null                        || this.GetParent(x => x.IsCalculated) != null;                }                return _calculated.Value;            }        }        private bool IsPropertyPersistable(StandardProperty? prop)        {            if (prop == null)                return true;            if (prop.Property.GetCustomAttribute<DoNotPersist>() != null)                return false;            return IsPropertyPersistable(prop.Parent as StandardProperty);        }        private bool IsPropertySerializable(StandardProperty? prop)        {            if (prop == null)                return true;            if (prop.Property.GetCustomAttribute<DoNotSerialize>() != null)                return false;            return IsPropertySerializable(prop.Parent as StandardProperty);        }        public bool IsPersistable => IsPropertyPersistable(this);        public bool IsSerializable => IsPropertySerializable(this);                private bool? _dbColumn;        public bool IsDBColumn        {            get            {                if (!_dbColumn.HasValue)                {                    _dbColumn = !IsCalculated                        && IsPersistable                        && Property.CanWrite                        && (!this.HasParentEntityLink() || (Parent?.HasParentEntityLink() != true && Property.Name == "ID"));                }                return _dbColumn.Value;            }        }        public TAttribute? GetAttribute<TAttribute>() where TAttribute : Attribute        {            return Property.GetCustomAttribute<TAttribute>();        }        public Expression Expression()        {            return CoreUtils.CreateMemberExpression(_class, Name);        }        public Func<object, object> Getter()        {            if (_getter is null) CheckExpressions();            return _getter;        }        Func<object, object> IProperty.NullSafeGetter()        {            _nullSafeGetter ??= Expressions.Getter(_class, _name, propagateNulls: true);            return _nullSafeGetter;        }        public Action<object, object?> Setter()        {            if (_setter is null) CheckExpressions();            return _setter;        }        public decimal PropertySequence() => _propertySequence;        private decimal CalculatePropertySequence()        {            var sequence = 0.0M;            IProperty? property = this;            while(property != null)            {                sequence = property.Sequence + sequence / 1000.0M;                property = property.Parent;            }            return sequence;        }        public override string ToString()        {            return string.Format("{0}.{1}", Class, Name);        }        private void ClearExpressions()        {            _checkedExpressions = false;            _getter = null;            _setter = null;        }        private void CheckExpressions()        {            if(_checkedExpressions) return;            if (_class == null)                return;            if (string.IsNullOrEmpty(_name))                return;            try            {                _getter = Expressions.Getter(_class, _name);            }            catch (Exception e)            {                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));            }            try            {                _setter = Expressions.Setter(_class, _name);            }            catch (Exception e)            {                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));            }            _checkedExpressions = true;        }    }}
 |