// // Copyright (c) Microsoft Corporation. All rights reserved. // using System.Collections.Generic; using System.Collections.ObjectModel; using System.Reflection; namespace System.Management.Automation { /// /// Internal wrapper for third-party adapters (PSPropertyAdapter) /// internal class ThirdPartyAdapter : PropertyOnlyAdapter { internal ThirdPartyAdapter(Type adaptedType, PSPropertyAdapter externalAdapter) { AdaptedType = adaptedType; _externalAdapter = externalAdapter; } /// /// The type this instance is adapting /// internal Type AdaptedType { get; } /// /// The type of the external adapter /// internal Type ExternalAdapterType { get { return _externalAdapter.GetType(); } } /// /// Returns the TypeNameHierarchy out of an object /// protected override IEnumerable GetTypeNameHierarchy(object obj) { Collection 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; } /// /// Retrieves all the properties available in the object. /// protected override void DoAddAllProperties(object obj, PSMemberInfoInternalCollection members) { Collection 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); } } /// /// 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. /// 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; } /// /// Ensures that the adapter and base object are set in the given PSAdaptedProperty /// private void InitializeProperty(PSAdaptedProperty property, object baseObject) { if (property.adapter == null) { property.adapter = this; property.baseObject = baseObject; } } /// /// Returns true if the property is settable /// 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); } } /// /// Returns true if the property is gettable /// 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); } } /// /// Returns the value from a property coming from a previous call to DoGetProperty /// 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); } } /// /// Sets the value of a property coming from a previous call to DoGetProperty /// 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); } } /// /// Returns the name of the type corresponding to the property /// 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; } /// /// User-defined property adapter /// /// /// This class is used to expose a simplified version of the type adapter API /// public abstract class PSPropertyAdapter { /// /// Returns the type hierarchy for the given object /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")] public virtual Collection GetTypeNameHierarchy(object baseObject) { if (baseObject == null) { throw new ArgumentNullException("baseObject"); } Collection types = new Collection(); for (Type type = baseObject.GetType(); type != null; type = type.GetTypeInfo().BaseType) { types.Add(type.FullName); } return types; } /// /// Returns a list of the adapted properties /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")] public abstract Collection GetProperties(object baseObject); /// /// Returns a specific property, or null if the base object does not contain the given property /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")] public abstract PSAdaptedProperty GetProperty(object baseObject, string propertyName); /// /// Returns true if the given property is settable /// public abstract bool IsSettable(PSAdaptedProperty adaptedProperty); /// /// Returns true if the given property is gettable /// public abstract bool IsGettable(PSAdaptedProperty adaptedProperty); /// /// Returns the value of a given property /// public abstract object GetPropertyValue(PSAdaptedProperty adaptedProperty); /// /// Sets the value of a given property /// public abstract void SetPropertyValue(PSAdaptedProperty adaptedProperty, object value); /// /// Returns the type for a given property /// public abstract string GetPropertyTypeName(PSAdaptedProperty adaptedProperty); } }