mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
- Remove the year about copyright - Fix casing of `All rights reserved` - Replace Unicode characters representing single quote with a single quote
329 lines
11 KiB
C#
329 lines
11 KiB
C#
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.Reflection;
|
|
|
|
namespace System.Management.Automation
|
|
{
|
|
/// <summary>
|
|
/// Internal wrapper for third-party adapters (PSPropertyAdapter)
|
|
/// </summary>
|
|
internal class ThirdPartyAdapter : PropertyOnlyAdapter
|
|
{
|
|
internal ThirdPartyAdapter(Type adaptedType, PSPropertyAdapter externalAdapter)
|
|
{
|
|
AdaptedType = adaptedType;
|
|
_externalAdapter = externalAdapter;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The type this instance is adapting
|
|
/// </summary>
|
|
internal Type AdaptedType { get; }
|
|
|
|
/// <summary>
|
|
/// The type of the external adapter
|
|
/// </summary>
|
|
internal Type ExternalAdapterType
|
|
{
|
|
get
|
|
{
|
|
return _externalAdapter.GetType();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the TypeNameHierarchy out of an object
|
|
/// </summary>
|
|
protected override IEnumerable<string> GetTypeNameHierarchy(object obj)
|
|
{
|
|
Collection<string> typeNameHierarchy = null;
|
|
|
|
try
|
|
{
|
|
typeNameHierarchy = _externalAdapter.GetTypeNameHierarchy(obj);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.GetTypeNameHierarchyError",
|
|
exception,
|
|
ExtendedTypeSystem.GetTypeNameHierarchyError, obj.ToString());
|
|
}
|
|
|
|
if (typeNameHierarchy == null)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.NullReturnValueError",
|
|
null,
|
|
ExtendedTypeSystem.NullReturnValueError, "PSPropertyAdapter.GetTypeNameHierarchy");
|
|
}
|
|
|
|
return typeNameHierarchy;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves all the properties available in the object.
|
|
/// </summary>
|
|
protected override void DoAddAllProperties<T>(object obj, PSMemberInfoInternalCollection<T> members)
|
|
{
|
|
Collection<PSAdaptedProperty> properties = null;
|
|
|
|
try
|
|
{
|
|
properties = _externalAdapter.GetProperties(obj);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.GetProperties",
|
|
exception,
|
|
ExtendedTypeSystem.GetProperties, obj.ToString());
|
|
}
|
|
|
|
if (properties == null)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.NullReturnValueError",
|
|
null,
|
|
ExtendedTypeSystem.NullReturnValueError, "PSPropertyAdapter.GetProperties");
|
|
}
|
|
|
|
foreach (PSAdaptedProperty property in properties)
|
|
{
|
|
InitializeProperty(property, obj);
|
|
|
|
members.Add(property as T);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns null if propertyName is not a property in the adapter or
|
|
/// the corresponding PSProperty with its adapterData set to information
|
|
/// to be used when retrieving the property.
|
|
/// </summary>
|
|
protected override PSProperty DoGetProperty(object obj, string propertyName)
|
|
{
|
|
PSAdaptedProperty property = null;
|
|
|
|
try
|
|
{
|
|
property = _externalAdapter.GetProperty(obj, propertyName);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.GetProperty",
|
|
exception,
|
|
ExtendedTypeSystem.GetProperty, propertyName, obj.ToString());
|
|
}
|
|
|
|
if (property != null)
|
|
{
|
|
InitializeProperty(property, obj);
|
|
}
|
|
|
|
return property;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensures that the adapter and base object are set in the given PSAdaptedProperty
|
|
/// </summary>
|
|
private void InitializeProperty(PSAdaptedProperty property, object baseObject)
|
|
{
|
|
if (property.adapter == null)
|
|
{
|
|
property.adapter = this;
|
|
property.baseObject = baseObject;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the property is settable
|
|
/// </summary>
|
|
protected override bool PropertyIsSettable(PSProperty property)
|
|
{
|
|
PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
|
|
|
|
Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
|
|
|
|
try
|
|
{
|
|
return _externalAdapter.IsSettable(adaptedProperty);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.PropertyIsSettableError",
|
|
exception,
|
|
ExtendedTypeSystem.PropertyIsSettableError, property.Name);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the property is gettable
|
|
/// </summary>
|
|
protected override bool PropertyIsGettable(PSProperty property)
|
|
{
|
|
PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
|
|
|
|
Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
|
|
|
|
try
|
|
{
|
|
return _externalAdapter.IsGettable(adaptedProperty);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.PropertyIsGettableError",
|
|
exception,
|
|
ExtendedTypeSystem.PropertyIsGettableError, property.Name);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the value from a property coming from a previous call to DoGetProperty
|
|
/// </summary>
|
|
protected override object PropertyGet(PSProperty property)
|
|
{
|
|
PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
|
|
|
|
Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
|
|
|
|
try
|
|
{
|
|
return _externalAdapter.GetPropertyValue(adaptedProperty);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.PropertyGetError",
|
|
exception,
|
|
ExtendedTypeSystem.PropertyGetError, property.Name);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the value of a property coming from a previous call to DoGetProperty
|
|
/// </summary>
|
|
protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
|
|
{
|
|
PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
|
|
|
|
Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
|
|
|
|
try
|
|
{
|
|
_externalAdapter.SetPropertyValue(adaptedProperty, setValue);
|
|
}
|
|
catch (SetValueException) { throw; }
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.PropertySetError",
|
|
exception,
|
|
ExtendedTypeSystem.PropertySetError, property.Name);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the name of the type corresponding to the property
|
|
/// </summary>
|
|
protected override string PropertyType(PSProperty property, bool forDisplay)
|
|
{
|
|
PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
|
|
|
|
Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
|
|
|
|
string propertyTypeName = null;
|
|
|
|
try
|
|
{
|
|
propertyTypeName = _externalAdapter.GetPropertyTypeName(adaptedProperty);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new ExtendedTypeSystemException(
|
|
"PSPropertyAdapter.PropertyTypeError",
|
|
exception,
|
|
ExtendedTypeSystem.PropertyTypeError, property.Name);
|
|
}
|
|
|
|
return propertyTypeName ?? "System.Object";
|
|
}
|
|
|
|
private PSPropertyAdapter _externalAdapter;
|
|
}
|
|
|
|
/// <summary>
|
|
/// User-defined property adapter
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This class is used to expose a simplified version of the type adapter API
|
|
/// </remarks>
|
|
public abstract class PSPropertyAdapter
|
|
{
|
|
/// <summary>
|
|
/// Returns the type hierarchy for the given object
|
|
/// </summary>
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
|
|
public virtual Collection<string> GetTypeNameHierarchy(object baseObject)
|
|
{
|
|
if (baseObject == null)
|
|
{
|
|
throw new ArgumentNullException("baseObject");
|
|
}
|
|
|
|
Collection<string> types = new Collection<String>();
|
|
|
|
for (Type type = baseObject.GetType(); type != null; type = type.GetTypeInfo().BaseType)
|
|
{
|
|
types.Add(type.FullName);
|
|
}
|
|
|
|
return types;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a list of the adapted properties
|
|
/// </summary>
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
|
|
public abstract Collection<PSAdaptedProperty> GetProperties(object baseObject);
|
|
|
|
/// <summary>
|
|
/// Returns a specific property, or null if the base object does not contain the given property
|
|
/// </summary>
|
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
|
|
public abstract PSAdaptedProperty GetProperty(object baseObject, string propertyName);
|
|
|
|
/// <summary>
|
|
/// Returns true if the given property is settable
|
|
/// </summary>
|
|
public abstract bool IsSettable(PSAdaptedProperty adaptedProperty);
|
|
|
|
/// <summary>
|
|
/// Returns true if the given property is gettable
|
|
/// </summary>
|
|
public abstract bool IsGettable(PSAdaptedProperty adaptedProperty);
|
|
|
|
/// <summary>
|
|
/// Returns the value of a given property
|
|
/// </summary>
|
|
public abstract object GetPropertyValue(PSAdaptedProperty adaptedProperty);
|
|
|
|
/// <summary>
|
|
/// Sets the value of a given property
|
|
/// </summary>
|
|
public abstract void SetPropertyValue(PSAdaptedProperty adaptedProperty, object value);
|
|
|
|
/// <summary>
|
|
/// Returns the type for a given property
|
|
/// </summary>
|
|
public abstract string GetPropertyTypeName(PSAdaptedProperty adaptedProperty);
|
|
}
|
|
}
|