MetadataImporter.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Description
  5. {
  6. using System.Collections.Generic;
  7. using System.Collections.ObjectModel;
  8. using System.Runtime;
  9. using System.Security;
  10. using System.ServiceModel;
  11. using System.ServiceModel.Channels;
  12. using System.ServiceModel.Configuration;
  13. using System.Xml;
  14. public abstract partial class MetadataImporter
  15. {
  16. readonly KeyedByTypeCollection<IPolicyImportExtension> policyExtensions;
  17. readonly Dictionary<XmlQualifiedName, ContractDescription> knownContracts = new Dictionary<XmlQualifiedName, ContractDescription>();
  18. readonly Collection<MetadataConversionError> errors = new Collection<MetadataConversionError>();
  19. readonly Dictionary<object, object> state = new Dictionary<object, object>();
  20. //prevent inheritance until we are ready to allow it.
  21. internal MetadataImporter()
  22. : this (null, MetadataImporterQuotas.Defaults)
  23. {
  24. }
  25. internal MetadataImporter(IEnumerable<IPolicyImportExtension> policyImportExtensions)
  26. : this (policyImportExtensions, MetadataImporterQuotas.Defaults)
  27. {
  28. }
  29. internal MetadataImporter(IEnumerable<IPolicyImportExtension> policyImportExtensions,
  30. MetadataImporterQuotas quotas)
  31. {
  32. if (quotas == null)
  33. {
  34. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("quotas");
  35. }
  36. if (policyImportExtensions == null)
  37. {
  38. policyImportExtensions = LoadPolicyExtensionsFromConfig();
  39. }
  40. this.Quotas = quotas;
  41. this.policyExtensions = new KeyedByTypeCollection<IPolicyImportExtension>(policyImportExtensions);
  42. }
  43. public KeyedByTypeCollection<IPolicyImportExtension> PolicyImportExtensions
  44. {
  45. get { return this.policyExtensions; }
  46. }
  47. public Collection<MetadataConversionError> Errors
  48. {
  49. get { return this.errors; }
  50. }
  51. public Dictionary<object, object> State
  52. {
  53. get { return this.state; }
  54. }
  55. public Dictionary<XmlQualifiedName, ContractDescription> KnownContracts
  56. {
  57. get { return this.knownContracts; }
  58. }
  59. // Abstract Building Methods
  60. public abstract Collection<ContractDescription> ImportAllContracts();
  61. public abstract ServiceEndpointCollection ImportAllEndpoints();
  62. internal virtual XmlElement ResolvePolicyReference(string policyReference, XmlElement contextAssertion)
  63. {
  64. return null;
  65. }
  66. internal BindingElementCollection ImportPolicy(ServiceEndpoint endpoint, Collection<Collection<XmlElement>> policyAlternatives)
  67. {
  68. foreach (Collection<XmlElement> selectedPolicy in policyAlternatives)
  69. {
  70. BindingOnlyPolicyConversionContext policyConversionContext = new BindingOnlyPolicyConversionContext(endpoint, selectedPolicy);
  71. if (TryImportPolicy(policyConversionContext))
  72. {
  73. return policyConversionContext.BindingElements;
  74. }
  75. }
  76. return null;
  77. }
  78. internal bool TryImportPolicy(PolicyConversionContext policyContext)
  79. {
  80. foreach (IPolicyImportExtension policyImporter in policyExtensions)
  81. try
  82. {
  83. policyImporter.ImportPolicy(this, policyContext);
  84. }
  85. #pragma warning suppress 56500 // covered by FxCOP
  86. catch (Exception e)
  87. {
  88. if (Fx.IsFatal(e))
  89. throw;
  90. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateExtensionException(policyImporter, e));
  91. }
  92. if (policyContext.GetBindingAssertions().Count != 0)
  93. return false;
  94. foreach (OperationDescription operation in policyContext.Contract.Operations)
  95. {
  96. if (policyContext.GetOperationBindingAssertions(operation).Count != 0)
  97. return false;
  98. foreach (MessageDescription message in operation.Messages)
  99. if (policyContext.GetMessageBindingAssertions(message).Count != 0)
  100. return false;
  101. }
  102. return true;
  103. }
  104. [Fx.Tag.SecurityNote(Critical = "uses ClientSection.UnsafeGetSection to get config in PT",
  105. Safe = "does not leak config object, just picks up extensions")]
  106. [SecuritySafeCritical]
  107. static Collection<IPolicyImportExtension> LoadPolicyExtensionsFromConfig()
  108. {
  109. return ClientSection.UnsafeGetSection().Metadata.LoadPolicyImportExtensions();
  110. }
  111. Exception CreateExtensionException(IPolicyImportExtension importer, Exception e)
  112. {
  113. string errorMessage = SR.GetString(SR.PolicyExtensionImportError, importer.GetType(), e.Message);
  114. return new InvalidOperationException(errorMessage, e);
  115. }
  116. internal class BindingOnlyPolicyConversionContext : PolicyConversionContext
  117. {
  118. static readonly PolicyAssertionCollection noPolicy = new PolicyAssertionCollection();
  119. readonly BindingElementCollection bindingElements = new BindingElementCollection();
  120. readonly PolicyAssertionCollection bindingPolicy;
  121. internal BindingOnlyPolicyConversionContext(ServiceEndpoint endpoint, IEnumerable<XmlElement> bindingPolicy)
  122. : base(endpoint)
  123. {
  124. this.bindingPolicy = new PolicyAssertionCollection(bindingPolicy);
  125. }
  126. public override BindingElementCollection BindingElements { get { return this.bindingElements; } }
  127. public override PolicyAssertionCollection GetBindingAssertions()
  128. {
  129. return this.bindingPolicy;
  130. }
  131. public override PolicyAssertionCollection GetOperationBindingAssertions(OperationDescription operation)
  132. {
  133. return noPolicy;
  134. }
  135. public override PolicyAssertionCollection GetMessageBindingAssertions(MessageDescription message)
  136. {
  137. return noPolicy;
  138. }
  139. public override PolicyAssertionCollection GetFaultBindingAssertions(FaultDescription fault)
  140. {
  141. return noPolicy;
  142. }
  143. }
  144. }
  145. }