2020-03-24 11:08:37 -07:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
2018-02-13 09:23:53 -08:00
|
|
|
// Licensed under the MIT License.
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2019-04-30 10:25:11 +05:00
|
|
|
using System.Globalization;
|
2016-03-30 14:20:52 -07:00
|
|
|
using System.Management.Automation;
|
|
|
|
|
using System.Management.Automation.Internal;
|
|
|
|
|
|
|
|
|
|
namespace Microsoft.PowerShell.Commands.Internal.Format
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2019-01-10 02:07:41 +05:00
|
|
|
/// Internal class to manage the grouping algorithm for the
|
2019-01-06 04:40:24 +05:00
|
|
|
/// format-xxx commands.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// </summary>
|
|
|
|
|
internal sealed class GroupingInfoManager
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2019-01-06 04:40:24 +05:00
|
|
|
/// Initialize with the grouping property data.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// </summary>
|
2018-12-29 08:25:49 +05:00
|
|
|
/// <param name="groupingExpression">Name of the grouping property.</param>
|
|
|
|
|
/// <param name="displayLabel">Display name of the property.</param>
|
2018-06-20 00:23:11 -07:00
|
|
|
internal void Initialize(PSPropertyExpression groupingExpression, string displayLabel)
|
2016-03-30 14:20:52 -07:00
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
_groupingKeyExpression = groupingExpression;
|
|
|
|
|
_label = displayLabel;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal object CurrentGroupingKeyPropertyValue
|
|
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
get { return _currentGroupingKeyPropertyValue; }
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal string GroupingKeyDisplayName
|
|
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
get
|
2016-03-30 14:20:52 -07:00
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
if (_label != null)
|
|
|
|
|
return _label;
|
|
|
|
|
return _groupingKeyDisplayName;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-10 02:07:41 +05:00
|
|
|
/// Compute the string value of the grouping property.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// </summary>
|
2018-12-29 08:25:49 +05:00
|
|
|
/// <param name="so">Object to use to compute the property value.</param>
|
2018-12-25 21:43:03 +05:00
|
|
|
/// <returns>True if there was an update.</returns>
|
2016-07-29 13:02:49 -07:00
|
|
|
internal bool UpdateGroupingKeyValue(PSObject so)
|
2016-03-30 14:20:52 -07:00
|
|
|
{
|
2020-07-30 16:06:38 -07:00
|
|
|
if (_groupingKeyExpression == null)
|
2016-03-30 14:20:52 -07:00
|
|
|
return false;
|
|
|
|
|
|
2018-06-20 00:23:11 -07:00
|
|
|
List<PSPropertyExpressionResult> results = _groupingKeyExpression.GetValues(so);
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
// if we have more that one match, we have to select the first one
|
2020-07-30 16:06:38 -07:00
|
|
|
if (results.Count > 0 && results[0].Exception == null)
|
2016-03-30 14:20:52 -07:00
|
|
|
{
|
|
|
|
|
// no exception got thrown, so we can update
|
|
|
|
|
object newValue = results[0].Result;
|
2016-07-29 13:02:49 -07:00
|
|
|
object oldValue = _currentGroupingKeyPropertyValue;
|
2016-03-30 14:20:52 -07:00
|
|
|
|
2016-07-29 13:02:49 -07:00
|
|
|
_currentGroupingKeyPropertyValue = newValue;
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
// now do the comparison
|
2016-07-29 13:02:49 -07:00
|
|
|
bool update = !(IsEqual(_currentGroupingKeyPropertyValue, oldValue) ||
|
|
|
|
|
IsEqual(oldValue, _currentGroupingKeyPropertyValue));
|
2016-03-30 14:20:52 -07:00
|
|
|
|
2020-07-30 16:06:38 -07:00
|
|
|
if (update && _label == null)
|
2016-03-30 14:20:52 -07:00
|
|
|
{
|
2016-07-29 13:02:49 -07:00
|
|
|
_groupingKeyDisplayName = results[0].ResolvedExpression.ToString();
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
2018-12-23 22:20:06 -08:00
|
|
|
|
2016-03-30 14:20:52 -07:00
|
|
|
return update;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// we had no matches or we could not get the value:
|
2017-01-16 13:31:14 -08:00
|
|
|
// NOTICE: we need to do this to avoid starting a new group every time
|
2016-03-30 14:20:52 -07:00
|
|
|
// there is a failure to read the grouping property.
|
|
|
|
|
// For example, for AD, there are objects that throw when trying
|
|
|
|
|
// to read the "distinguishedName" property (used by the brokered property "ParentPath)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static bool IsEqual(object first, object second)
|
|
|
|
|
{
|
2018-08-10 19:20:27 +02:00
|
|
|
if (LanguagePrimitives.TryCompare(first, second, true, CultureInfo.CurrentCulture, out int result))
|
2016-03-30 14:20:52 -07:00
|
|
|
{
|
2018-08-10 19:20:27 +02:00
|
|
|
return result == 0;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
2018-08-10 19:20:27 +02:00
|
|
|
// Note that this will occur if the objects do not support
|
|
|
|
|
// IComparable. We fall back to comparing as strings.
|
|
|
|
|
|
2016-03-30 14:20:52 -07:00
|
|
|
// being here means the first object doesn't support ICompare
|
|
|
|
|
// or an Exception was raised win Compare
|
|
|
|
|
string firstString = PSObject.AsPSObject(first).ToString();
|
|
|
|
|
string secondString = PSObject.AsPSObject(second).ToString();
|
|
|
|
|
|
2020-06-25 07:30:40 +01:00
|
|
|
return string.Equals(firstString, secondString, StringComparison.CurrentCultureIgnoreCase);
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-10 02:07:41 +05:00
|
|
|
/// Value of the display label passed in.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// </summary>
|
2016-07-29 13:02:49 -07:00
|
|
|
private string _label = null;
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-10 02:07:41 +05:00
|
|
|
/// Value of the current active grouping key.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// </summary>
|
2016-07-29 13:02:49 -07:00
|
|
|
private string _groupingKeyDisplayName = null;
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-10 02:07:41 +05:00
|
|
|
/// Name of the current grouping key.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// </summary>
|
2018-06-20 00:23:11 -07:00
|
|
|
private PSPropertyExpression _groupingKeyExpression = null;
|
2016-03-30 14:20:52 -07:00
|
|
|
|
|
|
|
|
/// <summary>
|
2019-01-10 02:07:41 +05:00
|
|
|
/// The current value of the grouping key.
|
2016-03-30 14:20:52 -07:00
|
|
|
/// </summary>
|
2016-07-29 13:02:49 -07:00
|
|
|
private object _currentGroupingKeyPropertyValue = AutomationNull.Value;
|
2016-03-30 14:20:52 -07:00
|
|
|
}
|
|
|
|
|
}
|