winget-cli

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

TypeHelpers.cs (10807B)


      1 // -----------------------------------------------------------------------------
      2 // <copyright file="TypeHelpers.cs" company="Microsoft Corporation">
      3 //     Copyright (c) Microsoft Corporation. Licensed under the MIT License.
      4 // </copyright>
      5 // -----------------------------------------------------------------------------
      6 
      7 namespace Microsoft.Management.Configuration.Processor.Helpers
      8 {
      9     using System;
     10     using System.Collections;
     11     using System.Collections.Generic;
     12     using System.Reflection;
     13     using Microsoft.Management.Configuration.Processor.Exceptions;
     14     using Microsoft.Management.Configuration.Processor.Extensions;
     15     using Microsoft.Management.Configuration.SetProcessorFactory;
     16     using Windows.Foundation.Collections;
     17 
     18     /// <summary>
     19     /// Type helpers.
     20     /// </summary>
     21     internal static class TypeHelpers
     22     {
     23         /// <summary>
     24         /// Verifies a property exists.
     25         /// </summary>
     26         /// <param name="obj">Dynamic object.</param>
     27         /// <param name="name">Name of property.</param>
     28         /// <returns>True if property exists.</returns>
     29         public static bool PropertyExists(dynamic obj, string name)
     30         {
     31             return obj.GetType().GetProperty(name) is not null;
     32         }
     33 
     34         /// <summary>
     35         /// Verifies a property exists with the specified type.
     36         /// </summary>
     37         /// <typeparam name="TType">Expected type.</typeparam>
     38         /// <param name="obj">Dynamic object.</param>
     39         /// <param name="name">Name of property.</param>
     40         /// <returns>True if property and is of the specified type.</returns>
     41         public static bool PropertyWithTypeExists<TType>(dynamic obj, string name)
     42         {
     43             return PropertyExists(obj, name) &&
     44                    obj.GetType().GetProperty(name).PropertyType == typeof(TType);
     45         }
     46 
     47         /// <summary>
     48         /// Verifies the property exist and is an enum.
     49         /// </summary>
     50         /// <param name="obj">Dynamic object.</param>
     51         /// <param name="name">Name of property.</param>
     52         /// <returns>True if property exists and is an enum.</returns>
     53         public static bool PropertyExistsAndIsEnum(dynamic obj, string name)
     54         {
     55             return PropertyExists(obj, name) &&
     56                    obj.GetType().GetProperty(name).PropertyType.IsEnum;
     57         }
     58 
     59         /// <summary>
     60         /// Verifies the property exists and is a list. Use this when you don't know the type of the List.
     61         /// </summary>
     62         /// <param name="obj">Dynamic object.</param>
     63         /// <param name="name">Name of property.</param>
     64         /// <returns>True if property exists and is a list.</returns>
     65         public static bool PropertyExistsAndIsList(dynamic obj, string name)
     66         {
     67             return PropertyExists(obj, name) &&
     68                    obj.GetType().GetProperty(name).PropertyType.IsGenericType &&
     69                    obj.GetType().GetProperty(name).PropertyType.GetGenericTypeDefinition() == typeof(List<>);
     70         }
     71 
     72         /// <summary>
     73         /// Gets all the properties and values from an object.
     74         /// </summary>
     75         /// <param name="obj">Object.</param>
     76         /// <returns>ValueSet with properties names and values.</returns>
     77         public static ValueSet GetAllPropertiesValues(object obj)
     78         {
     79             var result = new ValueSet();
     80             foreach (PropertyInfo property in obj.GetType().GetProperties())
     81             {
     82                 var key = property.Name;
     83                 var value = GetCompatibleValueSetValueOfProperty(property.PropertyType, property.GetValue(obj));
     84                 result.Add(key, value);
     85             }
     86 
     87             return result;
     88         }
     89 
     90         /// <summary>
     91         /// Gets a compatible type for a ValueSet value.
     92         /// </summary>
     93         /// <param name="type">Type.</param>
     94         /// <param name="value">Value.</param>
     95         /// <returns>Value converted to a compatible type.</returns>
     96         public static object? GetCompatibleValueSetValueOfProperty(Type type, object? value)
     97         {
     98             if (value == null)
     99             {
    100                 return null;
    101             }
    102 
    103             // Specialize here.
    104             if (type.IsEnum)
    105             {
    106                 return value.ToString();
    107             }
    108             else if (type == typeof(Hashtable))
    109             {
    110                 Hashtable hashtable = (Hashtable)value;
    111                 return hashtable.ToValueSet();
    112             }
    113             else if (type.IsArray)
    114             {
    115                 var valueSetArray = new ValueSet();
    116                 int index = 0;
    117                 foreach (object arrayObj in (Array)value)
    118                 {
    119                     var arrayValue = GetCompatibleValueSetValueOfProperty(arrayObj.GetType(), arrayObj);
    120                     if (arrayValue != null)
    121                     {
    122                         valueSetArray.Add(index.ToString(), arrayValue);
    123                         index++;
    124                     }
    125                 }
    126 
    127                 if (valueSetArray.Count > 0)
    128                 {
    129                     valueSetArray.Add("treatAsArray", true);
    130                 }
    131 
    132                 return valueSetArray;
    133             }
    134             else if (type == typeof(string))
    135             {
    136                 // Ignore empty strings.
    137                 string propertyString = (string)value;
    138                 if (!string.IsNullOrEmpty(propertyString))
    139                 {
    140                     return propertyString;
    141                 }
    142                 else
    143                 {
    144                     return null;
    145                 }
    146             }
    147             else if (type.IsValueType)
    148             {
    149                 return value;
    150             }
    151 
    152             // This might be too restrictive but anything else is going to be some object that we don't support anyway.
    153             throw new UnitPropertyUnsupportedException(value.GetType());
    154         }
    155 
    156         /// <summary>
    157         /// Converts PowerShellConfigurationProcessorPolicy string value to PwshConfigurationProcessorPolicy.
    158         /// </summary>
    159         /// <param name="value">PowerShellConfigurationProcessorPolicy value.</param>
    160         /// <returns>PwshConfigurationProcessorPolicy.</returns>
    161         public static PwshConfigurationProcessorPolicy ToPwshConfigurationProcessorPolicy(PowerShellConfigurationProcessorPolicy value)
    162         {
    163             return value switch
    164             {
    165                 PowerShellConfigurationProcessorPolicy.Unrestricted => PwshConfigurationProcessorPolicy.Unrestricted,
    166                 PowerShellConfigurationProcessorPolicy.RemoteSigned => PwshConfigurationProcessorPolicy.RemoteSigned,
    167                 PowerShellConfigurationProcessorPolicy.AllSigned => PwshConfigurationProcessorPolicy.AllSigned,
    168                 PowerShellConfigurationProcessorPolicy.Restricted => PwshConfigurationProcessorPolicy.Restricted,
    169                 PowerShellConfigurationProcessorPolicy.Bypass => PwshConfigurationProcessorPolicy.Bypass,
    170                 PowerShellConfigurationProcessorPolicy.Undefined => PwshConfigurationProcessorPolicy.Undefined,
    171                 _ => throw new InvalidOperationException(),
    172             };
    173         }
    174 
    175         /// <summary>
    176         /// Converts PwshConfigurationProcessorPolicy string value to PowerShellConfigurationProcessorPolicy.
    177         /// </summary>
    178         /// <param name="value">PwshConfigurationProcessorPolicy value.</param>
    179         /// <returns>PowerShellConfigurationProcessorPolicy.</returns>
    180         public static PowerShellConfigurationProcessorPolicy ToPowerShellConfigurationProcessorPolicy(PwshConfigurationProcessorPolicy value)
    181         {
    182             return value switch
    183             {
    184                 PwshConfigurationProcessorPolicy.Unrestricted => PowerShellConfigurationProcessorPolicy.Unrestricted,
    185                 PwshConfigurationProcessorPolicy.RemoteSigned => PowerShellConfigurationProcessorPolicy.RemoteSigned,
    186                 PwshConfigurationProcessorPolicy.AllSigned => PowerShellConfigurationProcessorPolicy.AllSigned,
    187                 PwshConfigurationProcessorPolicy.Restricted => PowerShellConfigurationProcessorPolicy.Restricted,
    188                 PwshConfigurationProcessorPolicy.Bypass => PowerShellConfigurationProcessorPolicy.Bypass,
    189                 PwshConfigurationProcessorPolicy.Undefined => PowerShellConfigurationProcessorPolicy.Undefined,
    190                 _ => throw new InvalidOperationException(),
    191             };
    192         }
    193 
    194         /// <summary>
    195         /// Converts PowerShellConfigurationProcessorLocation string value to PwshConfigurationProcessorLocation.
    196         /// </summary>
    197         /// <param name="value">PowerShellConfigurationProcessorLocation value.</param>
    198         /// <returns>PwshConfigurationProcessorLocation.</returns>
    199         public static PwshConfigurationProcessorLocation ToPwshConfigurationProcessorLocation(PowerShellConfigurationProcessorLocation value)
    200         {
    201             return value switch
    202             {
    203                 PowerShellConfigurationProcessorLocation.CurrentUser => PwshConfigurationProcessorLocation.CurrentUser,
    204                 PowerShellConfigurationProcessorLocation.AllUsers => PwshConfigurationProcessorLocation.AllUsers,
    205                 PowerShellConfigurationProcessorLocation.WinGetModulePath => PwshConfigurationProcessorLocation.WinGetModulePath,
    206                 PowerShellConfigurationProcessorLocation.Custom => PwshConfigurationProcessorLocation.Custom,
    207                 _ => throw new InvalidOperationException(),
    208             };
    209         }
    210 
    211         /// <summary>
    212         /// Converts PwshConfigurationProcessorLocation string value to PowerShellConfigurationProcessorLocation.
    213         /// </summary>
    214         /// <param name="value">PwshConfigurationProcessorLocation value.</param>
    215         /// <returns>PowerShellConfigurationProcessorLocation.</returns>
    216         public static PowerShellConfigurationProcessorLocation ToPowerShellConfigurationProcessorLocation(PwshConfigurationProcessorLocation value)
    217         {
    218             return value switch
    219             {
    220                 PwshConfigurationProcessorLocation.CurrentUser => PowerShellConfigurationProcessorLocation.CurrentUser,
    221                 PwshConfigurationProcessorLocation.AllUsers => PowerShellConfigurationProcessorLocation.AllUsers,
    222                 PwshConfigurationProcessorLocation.WinGetModulePath => PowerShellConfigurationProcessorLocation.WinGetModulePath,
    223                 PwshConfigurationProcessorLocation.Custom => PowerShellConfigurationProcessorLocation.Custom,
    224                 _ => throw new InvalidOperationException(),
    225             };
    226         }
    227     }
    228 }