175 lines
6.6 KiB
C#
175 lines
6.6 KiB
C#
|
//-----------------------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
namespace System.ServiceModel.Description
|
||
|
{
|
||
|
using System.Collections.Generic;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Runtime;
|
||
|
using System.Security;
|
||
|
using System.ServiceModel;
|
||
|
using System.ServiceModel.Channels;
|
||
|
using System.ServiceModel.Configuration;
|
||
|
using System.Xml;
|
||
|
|
||
|
public abstract partial class MetadataImporter
|
||
|
{
|
||
|
readonly KeyedByTypeCollection<IPolicyImportExtension> policyExtensions;
|
||
|
readonly Dictionary<XmlQualifiedName, ContractDescription> knownContracts = new Dictionary<XmlQualifiedName, ContractDescription>();
|
||
|
readonly Collection<MetadataConversionError> errors = new Collection<MetadataConversionError>();
|
||
|
readonly Dictionary<object, object> state = new Dictionary<object, object>();
|
||
|
|
||
|
//prevent inheritance until we are ready to allow it.
|
||
|
internal MetadataImporter()
|
||
|
: this (null, MetadataImporterQuotas.Defaults)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
internal MetadataImporter(IEnumerable<IPolicyImportExtension> policyImportExtensions)
|
||
|
: this (policyImportExtensions, MetadataImporterQuotas.Defaults)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
internal MetadataImporter(IEnumerable<IPolicyImportExtension> policyImportExtensions,
|
||
|
MetadataImporterQuotas quotas)
|
||
|
{
|
||
|
if (quotas == null)
|
||
|
{
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("quotas");
|
||
|
}
|
||
|
|
||
|
if (policyImportExtensions == null)
|
||
|
{
|
||
|
policyImportExtensions = LoadPolicyExtensionsFromConfig();
|
||
|
}
|
||
|
|
||
|
this.Quotas = quotas;
|
||
|
this.policyExtensions = new KeyedByTypeCollection<IPolicyImportExtension>(policyImportExtensions);
|
||
|
}
|
||
|
|
||
|
public KeyedByTypeCollection<IPolicyImportExtension> PolicyImportExtensions
|
||
|
{
|
||
|
get { return this.policyExtensions; }
|
||
|
}
|
||
|
|
||
|
public Collection<MetadataConversionError> Errors
|
||
|
{
|
||
|
get { return this.errors; }
|
||
|
}
|
||
|
|
||
|
public Dictionary<object, object> State
|
||
|
{
|
||
|
get { return this.state; }
|
||
|
}
|
||
|
|
||
|
public Dictionary<XmlQualifiedName, ContractDescription> KnownContracts
|
||
|
{
|
||
|
get { return this.knownContracts; }
|
||
|
}
|
||
|
|
||
|
// Abstract Building Methods
|
||
|
public abstract Collection<ContractDescription> ImportAllContracts();
|
||
|
public abstract ServiceEndpointCollection ImportAllEndpoints();
|
||
|
|
||
|
internal virtual XmlElement ResolvePolicyReference(string policyReference, XmlElement contextAssertion)
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
internal BindingElementCollection ImportPolicy(ServiceEndpoint endpoint, Collection<Collection<XmlElement>> policyAlternatives)
|
||
|
{
|
||
|
foreach (Collection<XmlElement> selectedPolicy in policyAlternatives)
|
||
|
{
|
||
|
BindingOnlyPolicyConversionContext policyConversionContext = new BindingOnlyPolicyConversionContext(endpoint, selectedPolicy);
|
||
|
|
||
|
if (TryImportPolicy(policyConversionContext))
|
||
|
{
|
||
|
return policyConversionContext.BindingElements;
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
internal bool TryImportPolicy(PolicyConversionContext policyContext)
|
||
|
{
|
||
|
foreach (IPolicyImportExtension policyImporter in policyExtensions)
|
||
|
try
|
||
|
{
|
||
|
policyImporter.ImportPolicy(this, policyContext);
|
||
|
}
|
||
|
#pragma warning suppress 56500 // covered by FxCOP
|
||
|
catch (Exception e)
|
||
|
{
|
||
|
if (Fx.IsFatal(e))
|
||
|
throw;
|
||
|
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateExtensionException(policyImporter, e));
|
||
|
}
|
||
|
|
||
|
if (policyContext.GetBindingAssertions().Count != 0)
|
||
|
return false;
|
||
|
|
||
|
foreach (OperationDescription operation in policyContext.Contract.Operations)
|
||
|
{
|
||
|
if (policyContext.GetOperationBindingAssertions(operation).Count != 0)
|
||
|
return false;
|
||
|
|
||
|
foreach (MessageDescription message in operation.Messages)
|
||
|
if (policyContext.GetMessageBindingAssertions(message).Count != 0)
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
[Fx.Tag.SecurityNote(Critical = "uses ClientSection.UnsafeGetSection to get config in PT",
|
||
|
Safe = "does not leak config object, just picks up extensions")]
|
||
|
[SecuritySafeCritical]
|
||
|
static Collection<IPolicyImportExtension> LoadPolicyExtensionsFromConfig()
|
||
|
{
|
||
|
return ClientSection.UnsafeGetSection().Metadata.LoadPolicyImportExtensions();
|
||
|
}
|
||
|
|
||
|
Exception CreateExtensionException(IPolicyImportExtension importer, Exception e)
|
||
|
{
|
||
|
string errorMessage = SR.GetString(SR.PolicyExtensionImportError, importer.GetType(), e.Message);
|
||
|
return new InvalidOperationException(errorMessage, e);
|
||
|
}
|
||
|
|
||
|
internal class BindingOnlyPolicyConversionContext : PolicyConversionContext
|
||
|
{
|
||
|
static readonly PolicyAssertionCollection noPolicy = new PolicyAssertionCollection();
|
||
|
readonly BindingElementCollection bindingElements = new BindingElementCollection();
|
||
|
readonly PolicyAssertionCollection bindingPolicy;
|
||
|
|
||
|
internal BindingOnlyPolicyConversionContext(ServiceEndpoint endpoint, IEnumerable<XmlElement> bindingPolicy)
|
||
|
: base(endpoint)
|
||
|
{
|
||
|
this.bindingPolicy = new PolicyAssertionCollection(bindingPolicy);
|
||
|
}
|
||
|
|
||
|
public override BindingElementCollection BindingElements { get { return this.bindingElements; } }
|
||
|
|
||
|
public override PolicyAssertionCollection GetBindingAssertions()
|
||
|
{
|
||
|
return this.bindingPolicy;
|
||
|
}
|
||
|
|
||
|
public override PolicyAssertionCollection GetOperationBindingAssertions(OperationDescription operation)
|
||
|
{
|
||
|
return noPolicy;
|
||
|
}
|
||
|
|
||
|
public override PolicyAssertionCollection GetMessageBindingAssertions(MessageDescription message)
|
||
|
{
|
||
|
return noPolicy;
|
||
|
}
|
||
|
|
||
|
public override PolicyAssertionCollection GetFaultBindingAssertions(FaultDescription fault)
|
||
|
{
|
||
|
return noPolicy;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|