Пример #1
0
        /// <summary>
        /// Reconfigures this UI (can be called multiple times throughout controls lifetime) to facilitate the population of DemandsInitialization
        /// properties on an underlying type (e.g. if your collection is ProcessTask and your argument type is ProcessTaskArgument then your underlying type could
        /// be AnySeparatorFileAttacher or MDFAttacher).  Note that while T is IArgumentHost, it also should be tied to one or more interfaces (e.g. IAttacher) and able to host
        /// any child of that interface of which argumentsAreForUnderlyingType is the currently configured concrete class (e.g. AnySeparatorFileAttacher).
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="argumentsAreForUnderlyingType"></param>
        /// <param name="catalogueRepository"></param>
        public void Setup(IArgumentHost parent, Type argumentsAreForUnderlyingType, ICatalogueRepository catalogueRepository)
        {
            _parent          = parent;
            _argumentsAreFor = argumentsAreForUnderlyingType;

            lblTypeUnloadable.Visible = _argumentsAreFor == null;

            _valueUisFactory = new ArgumentValueUIFactory();

            if (_argumentsAreFor != null)
            {
                lblClassName.Text = _argumentsAreFor.FullName;
            }

            helpIcon1.Left = lblClassName.Right;

            if (_argumentsAreFor != null)
            {
                btnViewSourceCode.Enabled = ViewSourceCodeDialog.GetSourceForFile(_argumentsAreFor.Name + ".cs") != null;
                btnViewSourceCode.Left    = helpIcon1.Right;

                var summary = catalogueRepository.CommentStore.GetTypeDocumentationIfExists(argumentsAreForUnderlyingType);

                if (summary != null)
                {
                    helpIcon1.SetHelpText(_argumentsAreFor.Name, summary);
                }

                RefreshArgumentList();
            }
        }
Пример #2
0
        public ExecuteCommandSetArgument(IBasicActivateItems activator, CommandLineObjectPicker picker) : base(activator)
        {
            if (picker.Arguments.Count != 3)
            {
                SetImpossible($"Wrong number of parameters supplied to command, expected 3 but got {picker.Arguments.Count}");
                return;
            }

            if (!picker.HasArgumentOfType(0, typeof(IMapsDirectlyToDatabaseTable)))
            {
                SetImpossible("First parameter must be an IArgumentHost DatabaseEntity");
                return;
            }

            _host = picker[0].GetValueForParameterOfType(typeof(IMapsDirectlyToDatabaseTable)) as IArgumentHost;

            if (_host == null)
            {
                SetImpossible("First parameter must be an IArgumentHost");
                return;
            }

            var args = _host.GetAllArguments();

            _arg = args.FirstOrDefault(a => a.Name.Equals(picker[1].RawValue));

            if (_arg == null)
            {
                SetImpossible($"Could not find argument called '{picker[1].RawValue}' on '{_host}'.  Arguments found were {string.Join(",",args.Select(a=>a.Name))}");
                return;
            }

            Type argType;

            try
            {
                argType = _arg.GetConcreteSystemType();
            }
            catch (Exception e)
            {
                SetImpossible("Failed to get system Type of argument:" + e);
                return;
            }

            if (argType == null)
            {
                SetImpossible($"Argument '{_arg.Name}' has no listed Type");
                return;
            }


            if (!picker[2].HasValueOfType(argType))
            {
                SetImpossible($"Provided value '{picker[2].RawValue}' does not match expected Type '{argType.Name}' of argument '{_arg.Name}'");
                return;
            }

            _value = picker[2].GetValueForParameterOfType(argType);
        }
Пример #3
0
        public ArgumentValuePipelineUI(ICatalogueRepository catalogueRepository, IArgumentHost parent, Type argumentType)
        {
            InitializeComponent();

            string typeName = parent.GetClassNameWhoArgumentsAreFor();

            _typeOfUnderlyingClass = catalogueRepository.MEF.GetType(typeName);

            if (_typeOfUnderlyingClass == null)
            {
                throw new Exception("Could not identify a Type called " + typeName + " in any loaded assemblies");
            }
        }
Пример #4
0
        /// <summary>
        /// Synchronizes all arguments (See SyncArgumentsForClass) for the supplied class (<paramref name="underlyingClassTypeForWhichArgumentsWillPopulate"/>) and returns the mapping
        /// between <see cref="IArgument"/> (which stores the value) and public class property (<see cref="RequiredPropertyInfo"/>)
        /// </summary>
        /// <param name="host"></param>
        /// <param name="underlyingClassTypeForWhichArgumentsWillPopulate"></param>
        /// <returns></returns>
        public Dictionary <IArgument, RequiredPropertyInfo> GetDemandDictionary(IArgumentHost host, Type underlyingClassTypeForWhichArgumentsWillPopulate)
        {
            var toReturn = new Dictionary <IArgument, RequiredPropertyInfo>();

            SyncArgumentsForClass(host, underlyingClassTypeForWhichArgumentsWillPopulate);

            var required = GetRequiredProperties(underlyingClassTypeForWhichArgumentsWillPopulate);

            foreach (var key in host.GetAllArguments())
            {
                toReturn.Add(key, required.Single(e => e.Name == key.Name));
            }

            return(toReturn);
        }
Пример #5
0
        /// <summary>
        /// Interrogates a class via reflection and enumerates it's properties to find any that have the attribute [DemandsInitialization]
        /// Each one of these that is found is created as a ProcessTaskArgument of the appropriate Name and PropertyType under the parent ProcessTask
        /// </summary>
        /// <returns>Each new ProcessTaskArgument created - note that it will not return existing ones that were already present (and therefore not created)</returns>
        public IEnumerable <IArgument> CreateArgumentsForClassIfNotExistsGeneric(
            Type underlyingClassTypeForWhichArgumentsWillPopulate, IArgumentHost host,
            IArgument[] existingArguments)
        {
            var classType = underlyingClassTypeForWhichArgumentsWillPopulate;

            //get all the properties that must be set on AnySeparatorFileAttacher (Those marked with the attribute DemandsInitialization
            var propertiesWeHaveToSet = GetRequiredProperties(classType);

            foreach (var required in propertiesWeHaveToSet)
            {
                //theres already a property with the same name
                if (existingArguments.Any(a => a.Name.Equals(required.Name)))
                {
                    continue;
                }

                //create a new one
                var argument = host.CreateNewArgument();

                //set the type and name
                argument.SetType(required.PropertyInfo.PropertyType);
                argument.Name = required.Name;

                DemandsInitializationAttribute attribute = required.Demand;
                argument.Description = attribute.Description;

                if (attribute.DefaultValue != null)
                {
                    argument.SetValue(attribute.DefaultValue);
                }

                var saveable = argument as ISaveable;

                if (saveable != null)
                {
                    saveable.SaveToDatabase();
                }

                yield return(argument);
            }
        }
Пример #6
0
        /// <summary>
        /// Reconfigures this UI (can be called multiple times throughout controls lifetime) to facilitate the population of DemandsInitialization
        /// properties on an underlying type (e.g. if your collection is ProcessTask and your argument type is ProcessTaskArgument then your underlying type could
        /// be AnySeparatorFileAttacher or MDFAttacher).  Note that while T is IArgumentHost, it also should be tied to one or more interfaces (e.g. IAttacher) and able to host
        /// any child of that interface of which argumentsAreForUnderlyingType is the currently configured concrete class (e.g. AnySeparatorFileAttacher).
        /// </summary>
        /// <param name="activator"></param>
        /// <param name="parent"></param>
        /// <param name="argumentsAreForUnderlyingType"></param>
        /// <param name="catalogueRepository"></param>
        public void Setup(IActivateItems activator, IArgumentHost parent, Type argumentsAreForUnderlyingType, ICatalogueRepository catalogueRepository)
        {
            _parent          = parent;
            _argumentsAreFor = argumentsAreForUnderlyingType;
            _activator       = activator;

            bool typeLoadable = !(_argumentsAreFor == null);

            lblTypeUnloadable.Visible = !typeLoadable;

            lblClassName.Visible         = typeLoadable;
            helpIcon1.Visible            = typeLoadable;
            lblArgumentsTitle.Visible    = typeLoadable;
            pArguments.Visible           = typeLoadable;
            lblComponentNotFound.Visible = !pArguments.Visible;

            _valueUisFactory = new ArgumentValueUIFactory();

            if (_argumentsAreFor != null)
            {
                lblClassName.Text = UsefulStuff.PascalCaseStringToHumanReadable(_argumentsAreFor.Name);
            }

            helpIcon1.Left = lblClassName.Right;

            if (_argumentsAreFor != null)
            {
                var summary = catalogueRepository.CommentStore.GetTypeDocumentationIfExists(argumentsAreForUnderlyingType);

                if (summary != null)
                {
                    helpIcon1.SetHelpText(_argumentsAreFor.Name, summary);
                }
                else
                {
                    helpIcon1.ClearHelpText();
                }

                RefreshArgumentList();
            }
        }
Пример #7
0
        /// <summary>
        /// Creates <see cref="IArgument"/> instances for all demanded properties (See <see cref="GetRequiredProperties"/>) of the given class and deletes any old arguments
        /// which are no longer required by the class (e.g. due to an API change).
        /// </summary>
        /// <param name="host"></param>
        /// <param name="underlyingClassTypeForWhichArgumentsWillPopulate"></param>
        public void SyncArgumentsForClass(IArgumentHost host, Type underlyingClassTypeForWhichArgumentsWillPopulate)
        {
            if (host.GetClassNameWhoArgumentsAreFor() != underlyingClassTypeForWhichArgumentsWillPopulate.FullName)
            {
                throw new ExpectedIdenticalStringsException("IArgumentHost is not currently hosting the Type requested for sync", host.GetClassNameWhoArgumentsAreFor(), underlyingClassTypeForWhichArgumentsWillPopulate.FullName);
            }

            var existingArguments = host.GetAllArguments().ToList();
            var required          = GetRequiredProperties(underlyingClassTypeForWhichArgumentsWillPopulate);

            //get rid of arguments that are no longer required
            foreach (var argumentsNotRequired in existingArguments.Where(e => required.All(r => r.Name != e.Name)))
            {
                ((IDeleteable)argumentsNotRequired).DeleteInDatabase();
            }

            //create new arguments
            existingArguments.AddRange(CreateArgumentsForClassIfNotExistsGeneric(underlyingClassTypeForWhichArgumentsWillPopulate, host, existingArguments.ToArray()));

            //handle mismatches of Type/incompatible values / unloaded Types etc
            foreach (var r in required)
            {
                var existing = existingArguments.SingleOrDefault(e => e.Name == r.Name);

                if (existing == null)
                {
                    throw new Exception("Despite creating new Arguments for class '" + underlyingClassTypeForWhichArgumentsWillPopulate + "' we do not have an IArgument called '" + r.Name + "' in the database (host='" + host + "')");
                }

                if (existing.GetSystemType() != r.PropertyInfo.PropertyType)
                {
                    //user wants to fix the problem
                    existing.SetType(r.PropertyInfo.PropertyType);
                    ((ISaveable)existing).SaveToDatabase();
                }
            }
        }
Пример #8
0
 public ExecuteCommandSetArgument(IBasicActivateItems activator, IArgumentHost host, IArgument arg, object value) : base(activator)
 {
     _host  = host;
     _arg   = arg;
     _value = value;
 }
Пример #9
0
        private void CreateLine(IArgumentHost parent, IArgument argument, RequiredPropertyInfo required, float maxArgNameWidth)
        {
            Label name = new Label();

            HelpIcon helpIcon = new HelpIcon();

            helpIcon.SetHelpText(GetSystemTypeName(argument.GetSystemType()) ?? "Unrecognised Type:" + argument.Type, required.Demand.Description);
            helpIcon.Dock = DockStyle.Right;

            string spaceSeparatedArgumentName = UsefulStuff.PascalCaseStringToHumanReadable(argument.Name);

            name.Height    = helpIcon.Height;
            name.Text      = spaceSeparatedArgumentName;
            name.TextAlign = ContentAlignment.MiddleLeft;
            name.Dock      = DockStyle.Left;
            name.Width     = (int)maxArgNameWidth + 3 /*padding*/;

            RAGSmiley ragSmiley = new RAGSmiley();

            if (required.Demand.Mandatory && string.IsNullOrWhiteSpace(argument.Value))
            {
                ragSmiley.Fatal(new Exception("Property " + argument.Name + " is Mandatory"));
            }

            var args = new ArgumentValueUIArgs();

            args.Parent      = parent;
            args.Type        = argument.GetSystemType();
            args.ContextText = required.Demand.ContextText;

            try
            {
                args.InitialValue = argument.GetValueAsSystemType();
            }
            catch (Exception e)
            {
                //add the text value value and report the error
                if (_valueUisFactory.CanHandleInvalidStringData(args.Type))
                {
                    args.InitialValue = argument.Value;
                }
                else
                {
                    args.InitialValue = null;
                }

                ragSmiley.Fatal(e);
            }


            args.Required            = required;
            args.CatalogueRepository = (ICatalogueRepository)argument.Repository;
            args.Setter = (v) =>
            {
                ragSmiley.Reset();

                try
                {
                    argument.SetValue(v);
                    argument.SaveToDatabase();

                    argument.GetValueAsSystemType();

                    if (required.Demand.Mandatory && (v == null || string.IsNullOrWhiteSpace(v.ToString())))
                    {
                        ragSmiley.Fatal(new Exception("Property " + argument.Name + " is Mandatory"));
                    }
                }
                catch (Exception ex)
                {
                    ragSmiley.OnCheckPerformed(new CheckEventArgs("Failed to set property properly", CheckResult.Fail, ex));
                }
            };
            args.Fatal = ragSmiley.Fatal;

            var valueui = (Control)_valueUisFactory.Create(_activator, args);

            valueui.Dock = DockStyle.Fill;

            Panel p = new Panel();

            p.Height = Math.Max(Math.Max(lblClassName.Height, helpIcon.Height), valueui.Height);
            p.Dock   = DockStyle.Top;

            name.Location = new Point(0, 0);
            p.Controls.Add(name);

            helpIcon.Left = name.Right;
            p.Controls.Add(helpIcon);

            ragSmiley.Dock = DockStyle.Right;
            p.Controls.Add(ragSmiley);
            p.Controls.Add(valueui);

            name.Height = p.Height;

            Label hr = new Label();

            hr.AutoSize    = false;
            hr.BorderStyle = BorderStyle.FixedSingle;
            hr.Height      = 1;
            hr.Dock        = DockStyle.Bottom;
            p.Controls.Add(hr);

            valueui.BringToFront();
            pArguments.Controls.Add(p);
        }
Пример #10
0
 /// <inheritdoc cref = "CreateArgumentsForClassIfNotExistsGeneric(Type,IArgumentHost,IArgument[])"/>
 /// <typeparam name="T">A class with one or more Properties marked with DemandsInitialization</typeparam>
 /// <returns>Each new ProcessTaskArgument created - note that it will not return existing ones that were already present (and therefore not created)</returns>
 public IEnumerable <IArgument> CreateArgumentsForClassIfNotExistsGeneric <T>(IArgumentHost host, IArgument[] existingArguments)
 {
     return(CreateArgumentsForClassIfNotExistsGeneric(typeof(T), host, existingArguments));
 }
Пример #11
0
        private void CreateLine(IArgumentHost parent, IArgument argument, RequiredPropertyInfo required)
        {
            Label name = new Label();

            HelpIcon helpIcon = new HelpIcon();

            helpIcon.SetHelpText(GetSystemTypeName(argument.GetSystemType()) ?? "Unrecognised Type:" + argument.Type, required.Demand.Description);
            helpIcon.Anchor = AnchorStyles.Top | AnchorStyles.Left;

            string spaceSeparatedArgumentName = UsefulStuff.PascalCaseStringToHumanReadable(argument.Name);

            name.Height    = helpIcon.Height;
            name.Text      = spaceSeparatedArgumentName;
            name.TextAlign = ContentAlignment.MiddleLeft;
            name.AutoSize  = true;
            name.Anchor    = AnchorStyles.Top | AnchorStyles.Left;

            RAGSmiley ragSmiley = new RAGSmiley();

            if (required.Demand.Mandatory && string.IsNullOrWhiteSpace(argument.Value))
            {
                ragSmiley.Fatal(new Exception("Property " + argument.Name + " is Mandatory"));
            }

            var args = new ArgumentValueUIArgs();

            args.Parent = parent;
            args.Type   = argument.GetSystemType();

            try
            {
                args.InitialValue = argument.GetValueAsSystemType();
            }
            catch (Exception e)
            {
                //add the text value value and report the error
                if (_valueUisFactory.CanHandleInvalidStringData(args.Type))
                {
                    args.InitialValue = argument.Value;
                }
                else
                {
                    args.InitialValue = null;
                }

                ragSmiley.Fatal(e);
            }


            args.Required            = required;
            args.CatalogueRepository = (ICatalogueRepository)argument.Repository;
            args.Setter = (v) =>
            {
                ragSmiley.Reset();

                try
                {
                    argument.SetValue(v);
                    argument.SaveToDatabase();

                    argument.GetValueAsSystemType();

                    if (required.Demand.Mandatory && (v == null || string.IsNullOrWhiteSpace(v.ToString())))
                    {
                        ragSmiley.Fatal(new Exception("Property " + argument.Name + " is Mandatory"));
                    }
                }
                catch (Exception ex)
                {
                    ragSmiley.OnCheckPerformed(new CheckEventArgs("Failed to set property properly", CheckResult.Fail, ex));
                }
            };
            args.Fatal = ragSmiley.Fatal;

            var valueui = (Control)_valueUisFactory.Create(args);

            valueui.Anchor = name.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
            _valueUIs.Add(valueui);

            Panel p = new Panel();

            p.Height      = Math.Max(Math.Max(lblClassName.Height, helpIcon.Height), valueui.Height);
            p.Width       = pArguments.ClientRectangle.Width;
            p.Anchor      = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
            p.BorderStyle = BorderStyle.FixedSingle;
            p.Location    = new Point(0, _currentY);
            _currentY    += p.Height;

            name.Location = new Point(0, 0);
            p.Controls.Add(name);

            helpIcon.Left = name.Right;
            p.Controls.Add(helpIcon);

            ragSmiley.Left   = p.Width - ragSmiley.Width;
            ragSmiley.Anchor = AnchorStyles.Right | AnchorStyles.Top;
            p.Controls.Add(ragSmiley);

            valueui.Left    = helpIcon.Right;
            valueui.Width   = p.Width - (helpIcon.Right + ragSmiley.Left);
            _maxValueUILeft = Math.Max(_maxValueUILeft, valueui.Left);
            p.Controls.Add(valueui);
            p.MinimumSize = new Size(ragSmiley.Right, p.Height);

            name.Height = p.Height;

            pArguments.Controls.Add(p);
        }
Пример #12
0
        private IEnumerable <PreLoadDiscardedColumn> GetAllPreloadDiscardedColumnsInScope(ICatalogueRepository repository, IArgumentHost parent)
        {
            if (parent is ProcessTask || parent is LoadMetadata)
            {
                return(GetTableInfosInScope(repository, parent).SelectMany(t => t.PreLoadDiscardedColumns));
            }

            return(repository.GetAllObjects <PreLoadDiscardedColumn>());
        }
Пример #13
0
        private IEnumerable <ColumnInfo> GetColumnInfosInScope(ICatalogueRepository repository, IArgumentHost parent)
        {
            if (parent is ProcessTask || parent is LoadMetadata)
            {
                return(GetTableInfosInScope(repository, parent).SelectMany(ti => ti.ColumnInfos));
            }

            return(repository.GetAllObjects <ColumnInfo>());
        }
Пример #14
0
        private IEnumerable <TableInfo> GetTableInfosInScope(ICatalogueRepository repository, IArgumentHost parent)
        {
            if (parent is ProcessTask pt)
            {
                return(pt.GetTableInfos());
            }

            if (parent is LoadMetadata lmd)
            {
                return(lmd.GetDistinctTableInfoList(true));
            }

            return(repository.GetAllObjects <TableInfo>());
        }