Files
PowerShell-PowerShell/src/System.Management.Automation/engine/ThirdPartyAdapter.cs
T
Steve Lee 4bc52d2358 Use consistent '(c)' for copyright symbol (#5210)
- Remove the year about copyright
- Fix casing of `All rights reserved`
- Replace Unicode characters representing single quote with a single quote
2017-10-26 14:12:19 -07:00

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);
}
}