<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Signum.Engine.Basics;
using Signum.Engine.Operations.Internal;
using Signum.Entities;
using Signum.Entities.Basics;
using Signum.Utilities;

namespace Signum.Engine.Operations
{
    public class Graph<T>
         where T : class, IIdentifiable
    {
        public class Construct : _Construct<T>, IConstructOperation
        {
            protected readonly Enum key;
            Enum IOperation.Key { get { return key; } }
            Type IOperation.Type { get { return typeof(T); } }
            OperationType IOperation.OperationType { get { return OperationType.Constructor; } }
            bool IOperation.Returns { get { return true; } }
            Type IOperation.ReturnType { get { return typeof(T); } }

            //public Func<object[], T> Construct { get; set; } (inherited)
            public bool Lite { get { return false; } }


            public Construct(Enum key)
            {
                this.key = key;
            }

            IIdentifiable IConstructOperation.Construct(params object[] args)
            {
                using (HeavyProfiler.Log("Construct", () => OperationDN.UniqueKey(key)))
                {
                    OperationLogic.AssertOperationAllowed(key, inUserInterface: false);

                    using (OperationLogic.AllowSave<T>())
                    {
                        try
                        {
                            using (Transaction tr = new Transaction())
                            {
                                OperationLogDN log = new OperationLogDN
                                {
                                    Operation = MultiEnumLogic<OperationDN>.ToEntity(key),
                                    Start = TimeZoneManager.Now,
                                    User = UserHolder.Current.ToLite()
                                };

                                OnBeginOperation();

                                T entity = Construct(args);

                                OnEndOperation(entity);

                                if (!entity.IsNew)
                                    log.Target = entity.ToLite();

                                log.End = TimeZoneManager.Now;
                                using (ExecutionMode.Global())
                                    log.Save();

                                return tr.Commit(entity);
                            }
                        }
                        catch (Exception ex)
                        {
                            OperationLogic.OnErrorOperation(this, null, args, ex);
                            throw;
                        }
                    }
                }
            }

            protected virtual void OnBeginOperation()
            {
                OperationLogic.OnBeginOperation(this, null);
            }

            protected virtual void OnEndOperation(T entity)
            {
                OperationLogic.OnEndOperation(this, entity);
            }

            public virtual void AssertIsValid()
            {
                if (Construct == null)
                    throw new InvalidOperationException("Operation {0} does not have Constructor initialized".Formato(key));
            }

            public override string ToString()
            {
                return "{0} Construct {1}".Formato(key, typeof(T));
            }
        }

        public class ConstructFrom<F> : IConstructorFromOperation
            where F : class, IIdentifiable
        {
            protected readonly Enum key;
            Enum IOperation.Key { get { return key; } }
            Type IOperation.Type { get { return typeof(F); } }
            OperationType IOperation.OperationType { get { return OperationType.ConstructorFrom; } }

            public bool Lite { get; set; }
            public bool LogAlsoIfNotSaved { get; set; }

            bool IOperation.Returns { get { return true; } }
            Type IOperation.ReturnType { get { return typeof(T); } }

            bool IEntityOperation.HasCanExecute { get { return CanConstruct != null; } }

            public bool AllowsNew { get; set; }

            public Func<F, object[], T> Construct { get; set; }
            public Func<F, string> CanConstruct { get; set; }

            public ConstructFrom(Enum key)
            {
                this.key = key;
                this.Lite = true;
            }

            string IEntityOperation.CanExecute(IIdentifiable entity)
            {
                return OnCanConstruct(entity);
            }

            string OnCanConstruct(IIdentifiable entity)
            {
                if (entity.IsNew && !AllowsNew)
                    return EngineMessage.TheEntity0IsNew.NiceToString().Formato(entity);

                if (CanConstruct != null)
                    return CanConstruct((F)entity);

                return null;
            }

            IIdentifiable IConstructorFromOperation.Construct(IIdentifiable entity, params object[] args)
            {
                using (HeavyProfiler.Log("ConstructFrom", () => OperationDN.UniqueKey(key)))
                {
                    OperationLogic.AssertOperationAllowed(key, inUserInterface: false);

                    string error = OnCanConstruct(entity);
                    if (error != null)
                        throw new ApplicationException(error);

                    using (OperationLogic.AllowSave(entity.GetType()))
                    using (OperationLogic.AllowSave<T>())
                    {
                        try
                        {
                            using (Transaction tr = new Transaction())
                            {
                                OperationLogDN log = new OperationLogDN
                                {
                                    Operation = MultiEnumLogic<OperationDN>.ToEntity(key),
                                    Start = TimeZoneManager.Now,
                                    User = UserHolder.Current.ToLite(),
                                    Origin = entity.ToLiteFat(),
                                };

                                OnBeginOperation((IdentifiableEntity)entity);

                                T result = Construct((F)entity, args);

                                OnEndOperation(result);

                                log.End = TimeZoneManager.Now;

                                if (!result.IsNew || LogAlsoIfNotSaved)
                                {
                                    log.Target = result.IsNew ? null : result.ToLite();<commit_msg>ContructFrom fix null<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Signum.Engine.Basics;
using Signum.Engine.Operations.Internal;
using Signum.Entities;
using Signum.Entities.Basics;
using Signum.Utilities;

namespace Signum.Engine.Operations
{
    public class Graph<T>
         where T : class, IIdentifiable
    {
        public class Construct : _Construct<T>, IConstructOperation
        {
            protected readonly Enum key;
            Enum IOperation.Key { get { return key; } }
            Type IOperation.Type { get { return typeof(T); } }
            OperationType IOperation.OperationType { get { return OperationType.Constructor; } }
            bool IOperation.Returns { get { return true; } }
            Type IOperation.ReturnType { get { return typeof(T); } }

            //public Func<object[], T> Construct { get; set; } (inherited)
            public bool Lite { get { return false; } }


            public Construct(Enum key)
            {
                this.key = key;
            }

            IIdentifiable IConstructOperation.Construct(params object[] args)
            {
                using (HeavyProfiler.Log("Construct", () => OperationDN.UniqueKey(key)))
                {
                    OperationLogic.AssertOperationAllowed(key, inUserInterface: false);

                    using (OperationLogic.AllowSave<T>())
                    {
                        try
                        {
                            using (Transaction tr = new Transaction())
                            {
                                OperationLogDN log = new OperationLogDN
                                {
                                    Operation = MultiEnumLogic<OperationDN>.ToEntity(key),
                                    Start = TimeZoneManager.Now,
                                    User = UserHolder.Current.ToLite()
                                };

                                OnBeginOperation();

                                T entity = Construct(args);

                                OnEndOperation(entity);

                                if (!entity.IsNew)
                                    log.Target = entity.ToLite();

                                log.End = TimeZoneManager.Now;
                                using (ExecutionMode.Global())
                                    log.Save();

                                return tr.Commit(entity);
                            }
                        }
                        catch (Exception ex)
                        {
                            OperationLogic.OnErrorOperation(this, null, args, ex);
                            throw;
                        }
                    }
                }
            }

            protected virtual void OnBeginOperation()
            {
                OperationLogic.OnBeginOperation(this, null);
            }

            protected virtual void OnEndOperation(T entity)
            {
                OperationLogic.OnEndOperation(this, entity);
            }

            public virtual void AssertIsValid()
            {
                if (Construct == null)
                    throw new InvalidOperationException("Operation {0} does not have Constructor initialized".Formato(key));
            }

            public override string ToString()
            {
                return "{0} Construct {1}".Formato(key, typeof(T));
            }
        }

        public class ConstructFrom<F> : IConstructorFromOperation
            where F : class, IIdentifiable
        {
            protected readonly Enum key;
            Enum IOperation.Key { get { return key; } }
            Type IOperation.Type { get { return typeof(F); } }
            OperationType IOperation.OperationType { get { return OperationType.ConstructorFrom; } }

            public bool Lite { get; set; }
            public bool LogAlsoIfNotSaved { get; set; }

            bool IOperation.Returns { get { return true; } }
            Type IOperation.ReturnType { get { return typeof(T); } }

            bool IEntityOperation.HasCanExecute { get { return CanConstruct != null; } }

            public bool AllowsNew { get; set; }

            public Func<F, object[], T> Construct { get; set; }
            public Func<F, string> CanConstruct { get; set; }

            public ConstructFrom(Enum key)
            {
                this.key = key;
                this.Lite = true;
            }

            string IEntityOperation.CanExecute(IIdentifiable entity)
            {
                return OnCanConstruct(entity);
            }

            string OnCanConstruct(IIdentifiable entity)
            {
                if (entity.IsNew && !AllowsNew)
                    return EngineMessage.TheEntity0IsNew.NiceToString().Formato(entity);

                if (CanConstruct != null)
                    return CanConstruct((F)entity);

                return null;
            }

            IIdentifiable IConstructorFromOperation.Construct(IIdentifiable entity, params object[] args)
            {
                using (HeavyProfiler.Log("ConstructFrom", () => OperationDN.UniqueKey(key)))
                {
                    OperationLogic.AssertOperationAllowed(key, inUserInterface: false);

                    string error = OnCanConstruct(entity);
                    if (error != null)
                        throw new ApplicationException(error);

                    using (OperationLogic.AllowSave(entity.GetType()))
                    using (OperationLogic.AllowSave<T>())
                    {
                        try
                        {
                            using (Transaction tr = new Transaction())
                            {
                                OperationLogDN log = new OperationLogDN
                                {
                                    Operation = MultiEnumLogic<OperationDN>.ToEntity(key),
                                    Start = TimeZoneManager.Now,
                                    User = UserHolder.Current.ToLite(),
                                    Origin = entity.ToLiteFat(),
                                };

                                OnBeginOperation((IdentifiableEntity)entity);

                                T result = Construct((F)entity, args);

                                OnEndOperation(result);

                                log.End = TimeZoneManager.Now;

                                if ((result != null && !result.IsNew) || LogAlsoIfNotSaved)
                                {
                                    log.Target = result == null || result.IsNew ? null : result.ToLite();
{'fraction_non_alphanumeric': 0.07788533134772896, 'fraction_numerical': 0.0005956813104988831, 'mean_word_length': 1.1417636740551746, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3607532', 'n_tokens_mistral': 3014, 'n_tokens_neox': 2842, 'n_words': 655}