winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ConfigurationSetProcessorFactoryBase.cs (7096B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="ConfigurationSetProcessorFactoryBase.cs" company="Microsoft Corporation">
      3 //     Copyright (c) Microsoft Corporation. Licensed under the MIT License.
      4 // </copyright>
      5 // -----------------------------------------------------------------------------
      6 
      7 namespace Microsoft.Management.Configuration.Processor.Factory
      8 {
      9     using System;
     10     using System.Runtime.CompilerServices;
     11     using Microsoft.Management.Configuration;
     12     using Microsoft.Management.Configuration.Processor.DSCv3.Helpers;
     13     using Microsoft.Management.Configuration.Processor.Set;
     14 
     15     /// <summary>
     16     /// IConfigurationSetProcessorFactory base implementation.
     17     /// </summary>
     18     internal abstract partial class ConfigurationSetProcessorFactoryBase : IDiagnosticsSink
     19     {
     20         private bool isCreateProcessorInvoked = false;
     21 
     22         // Backing variables for properties that are restricted in limit mode.
     23         private ConfigurationSet? limitationSet;
     24 
     25         /// <summary>
     26         /// Initializes a new instance of the <see cref="ConfigurationSetProcessorFactoryBase"/> class.
     27         /// </summary>
     28         public ConfigurationSetProcessorFactoryBase()
     29         {
     30         }
     31 
     32         /// <summary>
     33         /// Diagnostics event; useful for logging and/or verbose output.
     34         /// </summary>
     35         public event EventHandler<IDiagnosticInformation>? Diagnostics;
     36 
     37         /// <summary>
     38         /// Gets or sets the minimum diagnostic level to send.
     39         /// </summary>
     40         public DiagnosticLevel MinimumLevel { get; set; } = DiagnosticLevel.Informational;
     41 
     42         /// <summary>
     43         /// Gets or sets the limitation set. Limitation set can only be set once.
     44         /// </summary>
     45         public ConfigurationSet? LimitationSet
     46         {
     47             get
     48             {
     49                 return this.limitationSet;
     50             }
     51 
     52             set
     53             {
     54                 if (this.IsLimitMode())
     55                 {
     56                     throw new InvalidOperationException("Setting LimitationSet in limit mode is invalid.");
     57                 }
     58 
     59                 this.limitationSet = value;
     60             }
     61         }
     62 
     63         /// <summary>
     64         /// Gets the configuration unit processor details for the given unit.
     65         /// </summary>
     66         /// <param name="incomingSet">Configuration Set.</param>
     67         /// <returns>Configuration set processor.</returns>
     68         public IConfigurationSetProcessor CreateSetProcessor(ConfigurationSet? incomingSet)
     69         {
     70             try
     71             {
     72                 bool isLimitMode = this.IsLimitMode();
     73                 this.OnDiagnostics(DiagnosticLevel.Informational, $"The set processor factory is running in limit mode: {isLimitMode}.");
     74 
     75                 this.CheckLimitMode();
     76 
     77                 ConfigurationSet? set = isLimitMode ? this.limitationSet : incomingSet;
     78 
     79                 this.OnDiagnostics(DiagnosticLevel.Verbose, $"Creating set processor for `{set?.Name ?? "<null>"}`...");
     80 
     81                 if (set != null && (set.Parameters.Count > 0 || set.Variables.Count > 0))
     82                 {
     83                     this.OnDiagnostics(DiagnosticLevel.Error, $"  Parameters/variables are not yet supported.");
     84                     throw new NotImplementedException();
     85                 }
     86 
     87                 IConfigurationSetProcessor result = this.CreateSetProcessorInternal(set, isLimitMode);
     88 
     89                 this.OnDiagnostics(DiagnosticLevel.Verbose, "... done creating set processor.");
     90 
     91                 return result;
     92             }
     93             catch (Exception ex)
     94             {
     95                 this.OnDiagnostics(DiagnosticLevel.Error, ex.ToString());
     96                 throw;
     97             }
     98         }
     99 
    100         /// <inheritdoc />
    101         void IDiagnosticsSink.OnDiagnostics(DiagnosticLevel level, string message)
    102         {
    103             this.OnDiagnostics(level, message);
    104         }
    105 
    106         /// <summary>
    107         /// Sends diagnostics if appropriate.
    108         /// </summary>
    109         /// <param name="level">The level of this diagnostic message.</param>
    110         /// <param name="message">The diagnostic message.</param>
    111         internal void OnDiagnostics(DiagnosticLevel level, string message)
    112         {
    113             EventHandler<IDiagnosticInformation>? diagnostics = this.Diagnostics;
    114             if (diagnostics != null && level >= this.MinimumLevel)
    115             {
    116                 this.InvokeDiagnostics(diagnostics, level, message);
    117             }
    118         }
    119 
    120         /// <summary>
    121         /// Determines if diagnostics are enabled.
    122         /// This allows optimizing out string construction for some cases.
    123         /// </summary>
    124         /// <returns>True if diagnostics are enabled; false if not.</returns>
    125         protected bool AreDiagnosticsEnabled()
    126         {
    127             return this.Diagnostics != null;
    128         }
    129 
    130         /// <summary>
    131         /// Gets the configuration unit processor details for the given unit.
    132         /// </summary>
    133         /// <param name="set">Configuration Set.</param>
    134         /// <param name="isLimitMode">Whether the processor should be in limit mode.</param>
    135         /// <returns>Configuration set processor.</returns>
    136         protected abstract IConfigurationSetProcessor CreateSetProcessorInternal(ConfigurationSet? set, bool isLimitMode);
    137 
    138         /// <summary>
    139         /// Gets a value indicating whether the factory is operation in limit mode.
    140         /// </summary>
    141         /// <returns>True if the factory is in limit mode, false otherwise.</returns>
    142         protected bool IsLimitMode()
    143         {
    144             return this.limitationSet != null;
    145         }
    146 
    147         /// <summary>
    148         /// Sends diagnostics to the given handler.
    149         /// </summary>
    150         /// <param name="diagnostics">The handler to invoke.</param>
    151         /// <param name="level">The level of this diagnostic message.</param>
    152         /// <param name="message">The diagnostic message.</param>
    153         private void InvokeDiagnostics(EventHandler<IDiagnosticInformation> diagnostics, DiagnosticLevel level, string message)
    154         {
    155             Helpers.DiagnosticInformation information = new ()
    156             {
    157                 Level = level,
    158                 Message = message,
    159             };
    160             diagnostics.Invoke(this, information);
    161         }
    162 
    163         [MethodImpl(MethodImplOptions.Synchronized)]
    164         private void CheckLimitMode()
    165         {
    166             if (!this.IsLimitMode())
    167             {
    168                 return;
    169             }
    170 
    171             if (this.isCreateProcessorInvoked)
    172             {
    173                 this.OnDiagnostics(DiagnosticLevel.Error, "CreateSetProcessor is already invoked in limit mode.");
    174                 throw new InvalidOperationException("CreateSetProcessor is already invoked in limit mode.");
    175             }
    176             else
    177             {
    178                 this.isCreateProcessorInvoked = true;
    179             }
    180         }
    181     }
    182 }