PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/System.Management.Automation/engine/ThirdPartyAdapter.cs

https://gitlab.com/unofficial-mirrors/PowerShell
C# | 327 lines | 210 code | 47 blank | 70 comment | 17 complexity | 6a0d2f7a5587e10adf4153fa2b036ca8 MD5 | raw file
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License.
  3. using System.Collections.Generic;
  4. using System.Collections.ObjectModel;
  5. using System.Reflection;
  6. namespace System.Management.Automation
  7. {
  8. /// <summary>
  9. /// Internal wrapper for third-party adapters (PSPropertyAdapter)
  10. /// </summary>
  11. internal class ThirdPartyAdapter : PropertyOnlyAdapter
  12. {
  13. internal ThirdPartyAdapter(Type adaptedType, PSPropertyAdapter externalAdapter)
  14. {
  15. AdaptedType = adaptedType;
  16. _externalAdapter = externalAdapter;
  17. }
  18. /// <summary>
  19. /// The type this instance is adapting
  20. /// </summary>
  21. internal Type AdaptedType { get; }
  22. /// <summary>
  23. /// The type of the external adapter
  24. /// </summary>
  25. internal Type ExternalAdapterType
  26. {
  27. get
  28. {
  29. return _externalAdapter.GetType();
  30. }
  31. }
  32. /// <summary>
  33. /// Returns the TypeNameHierarchy out of an object
  34. /// </summary>
  35. protected override IEnumerable<string> GetTypeNameHierarchy(object obj)
  36. {
  37. Collection<string> typeNameHierarchy = null;
  38. try
  39. {
  40. typeNameHierarchy = _externalAdapter.GetTypeNameHierarchy(obj);
  41. }
  42. catch (Exception exception)
  43. {
  44. throw new ExtendedTypeSystemException(
  45. "PSPropertyAdapter.GetTypeNameHierarchyError",
  46. exception,
  47. ExtendedTypeSystem.GetTypeNameHierarchyError, obj.ToString());
  48. }
  49. if (typeNameHierarchy == null)
  50. {
  51. throw new ExtendedTypeSystemException(
  52. "PSPropertyAdapter.NullReturnValueError",
  53. null,
  54. ExtendedTypeSystem.NullReturnValueError, "PSPropertyAdapter.GetTypeNameHierarchy");
  55. }
  56. return typeNameHierarchy;
  57. }
  58. /// <summary>
  59. /// Retrieves all the properties available in the object.
  60. /// </summary>
  61. protected override void DoAddAllProperties<T>(object obj, PSMemberInfoInternalCollection<T> members)
  62. {
  63. Collection<PSAdaptedProperty> properties = null;
  64. try
  65. {
  66. properties = _externalAdapter.GetProperties(obj);
  67. }
  68. catch (Exception exception)
  69. {
  70. throw new ExtendedTypeSystemException(
  71. "PSPropertyAdapter.GetProperties",
  72. exception,
  73. ExtendedTypeSystem.GetProperties, obj.ToString());
  74. }
  75. if (properties == null)
  76. {
  77. throw new ExtendedTypeSystemException(
  78. "PSPropertyAdapter.NullReturnValueError",
  79. null,
  80. ExtendedTypeSystem.NullReturnValueError, "PSPropertyAdapter.GetProperties");
  81. }
  82. foreach (PSAdaptedProperty property in properties)
  83. {
  84. InitializeProperty(property, obj);
  85. members.Add(property as T);
  86. }
  87. }
  88. /// <summary>
  89. /// Returns null if propertyName is not a property in the adapter or
  90. /// the corresponding PSProperty with its adapterData set to information
  91. /// to be used when retrieving the property.
  92. /// </summary>
  93. protected override PSProperty DoGetProperty(object obj, string propertyName)
  94. {
  95. PSAdaptedProperty property = null;
  96. try
  97. {
  98. property = _externalAdapter.GetProperty(obj, propertyName);
  99. }
  100. catch (Exception exception)
  101. {
  102. throw new ExtendedTypeSystemException(
  103. "PSPropertyAdapter.GetProperty",
  104. exception,
  105. ExtendedTypeSystem.GetProperty, propertyName, obj.ToString());
  106. }
  107. if (property != null)
  108. {
  109. InitializeProperty(property, obj);
  110. }
  111. return property;
  112. }
  113. /// <summary>
  114. /// Ensures that the adapter and base object are set in the given PSAdaptedProperty
  115. /// </summary>
  116. private void InitializeProperty(PSAdaptedProperty property, object baseObject)
  117. {
  118. if (property.adapter == null)
  119. {
  120. property.adapter = this;
  121. property.baseObject = baseObject;
  122. }
  123. }
  124. /// <summary>
  125. /// Returns true if the property is settable
  126. /// </summary>
  127. protected override bool PropertyIsSettable(PSProperty property)
  128. {
  129. PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
  130. Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
  131. try
  132. {
  133. return _externalAdapter.IsSettable(adaptedProperty);
  134. }
  135. catch (Exception exception)
  136. {
  137. throw new ExtendedTypeSystemException(
  138. "PSPropertyAdapter.PropertyIsSettableError",
  139. exception,
  140. ExtendedTypeSystem.PropertyIsSettableError, property.Name);
  141. }
  142. }
  143. /// <summary>
  144. /// Returns true if the property is gettable
  145. /// </summary>
  146. protected override bool PropertyIsGettable(PSProperty property)
  147. {
  148. PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
  149. Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
  150. try
  151. {
  152. return _externalAdapter.IsGettable(adaptedProperty);
  153. }
  154. catch (Exception exception)
  155. {
  156. throw new ExtendedTypeSystemException(
  157. "PSPropertyAdapter.PropertyIsGettableError",
  158. exception,
  159. ExtendedTypeSystem.PropertyIsGettableError, property.Name);
  160. }
  161. }
  162. /// <summary>
  163. /// Returns the value from a property coming from a previous call to DoGetProperty
  164. /// </summary>
  165. protected override object PropertyGet(PSProperty property)
  166. {
  167. PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
  168. Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
  169. try
  170. {
  171. return _externalAdapter.GetPropertyValue(adaptedProperty);
  172. }
  173. catch (Exception exception)
  174. {
  175. throw new ExtendedTypeSystemException(
  176. "PSPropertyAdapter.PropertyGetError",
  177. exception,
  178. ExtendedTypeSystem.PropertyGetError, property.Name);
  179. }
  180. }
  181. /// <summary>
  182. /// Sets the value of a property coming from a previous call to DoGetProperty
  183. /// </summary>
  184. protected override void PropertySet(PSProperty property, object setValue, bool convertIfPossible)
  185. {
  186. PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
  187. Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
  188. try
  189. {
  190. _externalAdapter.SetPropertyValue(adaptedProperty, setValue);
  191. }
  192. catch (SetValueException) { throw; }
  193. catch (Exception exception)
  194. {
  195. throw new ExtendedTypeSystemException(
  196. "PSPropertyAdapter.PropertySetError",
  197. exception,
  198. ExtendedTypeSystem.PropertySetError, property.Name);
  199. }
  200. }
  201. /// <summary>
  202. /// Returns the name of the type corresponding to the property
  203. /// </summary>
  204. protected override string PropertyType(PSProperty property, bool forDisplay)
  205. {
  206. PSAdaptedProperty adaptedProperty = property as PSAdaptedProperty;
  207. Diagnostics.Assert(adaptedProperty != null, "ThirdPartyAdapter should only receive PSAdaptedProperties");
  208. string propertyTypeName = null;
  209. try
  210. {
  211. propertyTypeName = _externalAdapter.GetPropertyTypeName(adaptedProperty);
  212. }
  213. catch (Exception exception)
  214. {
  215. throw new ExtendedTypeSystemException(
  216. "PSPropertyAdapter.PropertyTypeError",
  217. exception,
  218. ExtendedTypeSystem.PropertyTypeError, property.Name);
  219. }
  220. return propertyTypeName ?? "System.Object";
  221. }
  222. private PSPropertyAdapter _externalAdapter;
  223. }
  224. /// <summary>
  225. /// User-defined property adapter
  226. /// </summary>
  227. /// <remarks>
  228. /// This class is used to expose a simplified version of the type adapter API
  229. /// </remarks>
  230. public abstract class PSPropertyAdapter
  231. {
  232. /// <summary>
  233. /// Returns the type hierarchy for the given object
  234. /// </summary>
  235. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
  236. public virtual Collection<string> GetTypeNameHierarchy(object baseObject)
  237. {
  238. if (baseObject == null)
  239. {
  240. throw new ArgumentNullException("baseObject");
  241. }
  242. Collection<string> types = new Collection<String>();
  243. for (Type type = baseObject.GetType(); type != null; type = type.BaseType)
  244. {
  245. types.Add(type.FullName);
  246. }
  247. return types;
  248. }
  249. /// <summary>
  250. /// Returns a list of the adapted properties
  251. /// </summary>
  252. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
  253. public abstract Collection<PSAdaptedProperty> GetProperties(object baseObject);
  254. /// <summary>
  255. /// Returns a specific property, or null if the base object does not contain the given property
  256. /// </summary>
  257. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "object")]
  258. public abstract PSAdaptedProperty GetProperty(object baseObject, string propertyName);
  259. /// <summary>
  260. /// Returns true if the given property is settable
  261. /// </summary>
  262. public abstract bool IsSettable(PSAdaptedProperty adaptedProperty);
  263. /// <summary>
  264. /// Returns true if the given property is gettable
  265. /// </summary>
  266. public abstract bool IsGettable(PSAdaptedProperty adaptedProperty);
  267. /// <summary>
  268. /// Returns the value of a given property
  269. /// </summary>
  270. public abstract object GetPropertyValue(PSAdaptedProperty adaptedProperty);
  271. /// <summary>
  272. /// Sets the value of a given property
  273. /// </summary>
  274. public abstract void SetPropertyValue(PSAdaptedProperty adaptedProperty, object value);
  275. /// <summary>
  276. /// Returns the type for a given property
  277. /// </summary>
  278. public abstract string GetPropertyTypeName(PSAdaptedProperty adaptedProperty);
  279. }
  280. }