Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Extensions / Compilation / WCFModel / WsdlInspector.cs / 1305376 / WsdlInspector.cs
//------------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//
//-----------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Web.Services.Description;
using System.Xml;
#if WEB_EXTENSIONS_CODE
using System.Web.Resources;
#else
using Microsoft.VSDesigner.Resources.Microsoft.VSDesigner;
#endif
#if WEB_EXTENSIONS_CODE
namespace System.Web.Compilation.WCFModel
#else
namespace Microsoft.VSDesigner.WCFModel
#endif
{
///
/// This class check whether there are duplicated wsdl files in the metadata collection, and report error messages, if any contract is
/// defined differently in two wsdl files.
///
internal class WsdlInspector {
private IList importErrors;
private Dictionary portTypes;
private Dictionary messages;
///
/// constructor
///
///
private WsdlInspector(IList importErrors) {
this.importErrors = importErrors;
this.portTypes = new Dictionary();
this.messages = new Dictionary();
}
///
/// function to check duplicated items
///
///
///
///
internal static void CheckDuplicatedWsdlItems(ICollection wsdlFiles, IList importErrors) {
WsdlInspector inspector = new WsdlInspector(importErrors);
inspector.CheckServiceDescriptions(wsdlFiles);
}
///
/// check all duplicated items in a collection of files
///
///
private void CheckServiceDescriptions(ICollection wsdlFiles) {
foreach (System.Web.Services.Description.ServiceDescription wsdl in wsdlFiles) {
string targetNamespace = wsdl.TargetNamespace;
if (String.IsNullOrEmpty(targetNamespace)) {
targetNamespace = String.Empty;
}
// check all portTypes...
foreach (PortType portType in wsdl.PortTypes) {
XmlQualifiedName portTypeName = new XmlQualifiedName(portType.Name, targetNamespace);
PortType definedPortType;
if (portTypes.TryGetValue(portTypeName, out definedPortType)) {
MatchPortTypes(definedPortType, portType);
}
else {
portTypes.Add(portTypeName, portType);
}
}
// check all messages...
foreach (Message message in wsdl.Messages) {
XmlQualifiedName messageName = new XmlQualifiedName(message.Name, targetNamespace);
Message definedMessage;
if (messages.TryGetValue(messageName, out definedMessage)) {
MatchMessages(definedMessage, message);
}
else {
messages.Add(messageName, message);
}
}
}
}
///
/// Compare two port type (with same targetNamespace/name)
///
///
private void MatchPortTypes(PortType x, PortType y) {
Operation[] operationsX = new Operation[x.Operations.Count];
x.Operations.CopyTo(operationsX, 0);
Array.Sort(operationsX, new OperationComparer());
Operation[] operationsY = new Operation[y.Operations.Count];
y.Operations.CopyTo(operationsY, 0);
Array.Sort(operationsY, new OperationComparer());
MatchCollections(operationsX, operationsY,
delegate(Operation operationX, Operation operationY) {
if (operationX != null && operationY != null) {
int nameDifferent = String.Compare(operationX.Name, operationY.Name, StringComparison.Ordinal);
if (nameDifferent < 0) {
ReportUniqueOperation(operationX, x, y);
return false;
}
else if (nameDifferent > 0) {
ReportUniqueOperation(operationY, y, x);
return false;
}
else if (!MatchOperations(operationX, operationY)) {
return false;
}
return true;
}
else if (operationX != null) {
ReportUniqueOperation(operationX, x, y);
return false;
}
else if (operationY != null) {
ReportUniqueOperation(operationY, y, x);
return false;
}
return true;
}
);
}
///
/// Compare two operations (with same name)
///
///
private bool MatchOperations(Operation x, Operation y) {
if (!MatchOperationMessages(x.Messages.Input, y.Messages.Input)) {
ReportOperationDefinedDifferently(x, y);
return false;
}
if (!MatchOperationMessages(x.Messages.Output, y.Messages.Output)) {
ReportOperationDefinedDifferently(x, y);
return false;
}
OperationFault[] faultsX = new OperationFault[x.Faults.Count];
x.Faults.CopyTo(faultsX, 0);
Array.Sort(faultsX, new OperationFaultComparer());
OperationFault[] faultsY = new OperationFault[y.Faults.Count];
y.Faults.CopyTo(faultsY, 0);
Array.Sort(faultsY, new OperationFaultComparer());
if (!MatchCollections(faultsX, faultsY,
delegate(OperationFault faultX, OperationFault faultY) {
if (faultX != null && faultY != null) {
return MatchXmlQualifiedNames(faultX.Message, faultY.Message);
}
else if (faultX != null || faultY != null) {
return false;
}
return true;
}
)) {
ReportOperationDefinedDifferently(x, y);
return false;
}
return true;
}
///
/// Compare two messages in operations (with same name)
///
///
private bool MatchOperationMessages(OperationMessage x, OperationMessage y) {
if (x == null && y == null) {
return true;
}
else if (x == null || y == null) {
return false;
}
return MatchXmlQualifiedNames(x.Message, y.Message);
}
///
/// Compare two messages defined in wsdl (with same name/targetNamespace)
///
///
private void MatchMessages(Message x, Message y) {
MessagePart[] partsX = new MessagePart[x.Parts.Count];
x.Parts.CopyTo(partsX, 0);
Array.Sort(partsX, new MessagePartComparer());
MessagePart[] partsY = new MessagePart[y.Parts.Count];
y.Parts.CopyTo(partsY, 0);
Array.Sort(partsY, new MessagePartComparer());
MatchCollections(partsX, partsY,
delegate(MessagePart partX, MessagePart partY) {
if (partX != null && partY != null) {
int nameDifferent = String.Compare(partX.Name, partY.Name, StringComparison.Ordinal);
if (nameDifferent < 0) {
ReportUniqueMessagePart(partX, x, y);
return false;
}
else if (nameDifferent > 0) {
ReportUniqueMessagePart(partY, y, x);
return false;
}
else if (!MatchMessageParts(partX, partY)) {
return false;
}
return true;
}
else if (partX != null) {
ReportUniqueMessagePart(partX, x, y);
return false;
}
else if (partY != null) {
ReportUniqueMessagePart(partY, y, x);
return false;
}
return true;
}
);
}
///
/// Compare two message parts (with same name)
///
///
private bool MatchMessageParts(MessagePart partX, MessagePart partY) {
if (!MatchXmlQualifiedNames(partX.Type, partY.Type) || !MatchXmlQualifiedNames(partX.Element, partY.Element)) {
ReportMessageDefinedDifferently(partX, partX.Message, partY.Message);
return false;
}
return true;
}
///
/// compare two XmlQualifiedName
///
///
private bool MatchXmlQualifiedNames(XmlQualifiedName x, XmlQualifiedName y) {
if (x != null && y != null) {
return x == y; // XmlQualifiedName
}
return x == null && y == null;
}
///
/// Report an error when we find operation defined in one place but not another
///
///
private void ReportUniqueOperation(Operation operation, PortType portType1, PortType portType2) {
importErrors.Add(new ProxyGenerationError(
ProxyGenerationError.GeneratorState.MergeMetadata,
String.Empty,
new InvalidOperationException(
String.Format(CultureInfo.CurrentCulture, WCFModelStrings.ReferenceGroup_OperationDefinedInOneOfDuplicatedServiceContract,
portType1.Name,
portType1.ServiceDescription.RetrievalUrl,
portType2.ServiceDescription.RetrievalUrl,
operation.Name)
)
)
);
}
///
/// Report an error when we find operation defined in two places differently
///
///
private void ReportOperationDefinedDifferently(Operation x, Operation y) {
importErrors.Add(new ProxyGenerationError(
ProxyGenerationError.GeneratorState.MergeMetadata,
String.Empty,
new InvalidOperationException(
String.Format(CultureInfo.CurrentCulture, WCFModelStrings.ReferenceGroup_OperationDefinedDifferently,
x.Name,
x.PortType.Name,
x.PortType.ServiceDescription.RetrievalUrl,
y.PortType.ServiceDescription.RetrievalUrl)
)
)
);
}
///
/// Report an error when we find a part of message defined in one place but not another
///
///
private void ReportUniqueMessagePart(MessagePart part, Message message1, Message message2) {
importErrors.Add(new ProxyGenerationError(
ProxyGenerationError.GeneratorState.MergeMetadata,
String.Empty,
new InvalidOperationException(
String.Format(CultureInfo.CurrentCulture, WCFModelStrings.ReferenceGroup_FieldDefinedInOneOfDuplicatedMessage,
message1.Name,
message1.ServiceDescription.RetrievalUrl,
message2.ServiceDescription.RetrievalUrl,
part.Name)
)
)
);
}
///
/// Report an error when we find message defined in two places differently
///
///
private void ReportMessageDefinedDifferently(MessagePart part, Message x, Message y) {
importErrors.Add(new ProxyGenerationError(
ProxyGenerationError.GeneratorState.MergeMetadata,
String.Empty,
new InvalidOperationException(
String.Format(CultureInfo.CurrentCulture, WCFModelStrings.ReferenceGroup_FieldDefinedDifferentlyInDuplicatedMessage,
part.Name,
x.Name,
x.ServiceDescription.RetrievalUrl,
y.ServiceDescription.RetrievalUrl)
)
)
);
}
///
/// Helper class to sort Operations
///
///
private class OperationComparer : System.Collections.Generic.IComparer {
public int Compare(Operation x, Operation y) {
return String.Compare(x.Name, y.Name, StringComparison.Ordinal);
}
}
///
/// Helper class to sort OperationFaults
///
///
private class OperationFaultComparer : System.Collections.Generic.IComparer {
public int Compare(OperationFault x, OperationFault y) {
int namespaceResult = String.Compare(x.Message.Namespace, y.Message.Namespace, StringComparison.Ordinal);
if (namespaceResult != 0) {
return namespaceResult;
}
return String.Compare(x.Message.Name, y.Message.Name, StringComparison.Ordinal);
}
}
///
/// Helper class to sort MessageParts
///
///
private class MessagePartComparer : System.Collections.Generic.IComparer {
public int Compare(MessagePart x, MessagePart y) {
return String.Compare(x.Name, y.Name, StringComparison.Ordinal);
}
}
///
/// Helper function to compare two collections
///
///
private delegate bool MatchCollectionItemDelegate(T x, T y);
private bool MatchCollections(T[] x, T[] y, MatchCollectionItemDelegate compareItems) where T : class {
System.Collections.IEnumerator enumeratorX = x.GetEnumerator();
System.Collections.IEnumerator enumeratorY = y.GetEnumerator();
T tX;
T tY;
do {
tX = enumeratorX.MoveNext() ? (T)enumeratorX.Current : null;
tY = enumeratorY.MoveNext() ? (T)enumeratorY.Current : null;
if (tX != null && tY != null) {
if (!compareItems(tX, tY)) {
return false;
}
}
}
while (tX != null && tY != null);
return compareItems(tX, tY);
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ConfigsHelper.cs
- DiscardableAttribute.cs
- QueryableDataSourceView.cs
- StatusBarAutomationPeer.cs
- LateBoundBitmapDecoder.cs
- LinearKeyFrames.cs
- Mappings.cs
- MulticastOption.cs
- _AutoWebProxyScriptHelper.cs
- BitmapFrame.cs
- CompositeScriptReference.cs
- ContainerAction.cs
- CharAnimationBase.cs
- Encoder.cs
- SqlDataSourceSelectingEventArgs.cs
- TableLayoutColumnStyleCollection.cs
- safelink.cs
- SemaphoreSecurity.cs
- TextWriter.cs
- Directory.cs
- HttpModuleAction.cs
- DetailsViewCommandEventArgs.cs
- DPAPIProtectedConfigurationProvider.cs
- X509PeerCertificateAuthentication.cs
- DbTransaction.cs
- AttachInfo.cs
- QilLoop.cs
- SelectionPattern.cs
- WebPermission.cs
- ToolStripDesigner.cs
- CompilerTypeWithParams.cs
- D3DImage.cs
- ObjectSecurity.cs
- DCSafeHandle.cs
- InvalidFilterCriteriaException.cs
- ZoneButton.cs
- OleStrCAMarshaler.cs
- HttpCachePolicy.cs
- UTF32Encoding.cs
- XmlBinaryReader.cs
- GenericsInstances.cs
- KoreanLunisolarCalendar.cs
- DictionaryEntry.cs
- Win32SafeHandles.cs
- RequestResizeEvent.cs
- DeploymentSection.cs
- CookieParameter.cs
- ParallelTimeline.cs
- XmlDeclaration.cs
- EditingMode.cs
- FixedTextSelectionProcessor.cs
- _FtpControlStream.cs
- MethodRental.cs
- SqlConnectionPoolGroupProviderInfo.cs
- Timer.cs
- DrawingImage.cs
- XmlReflectionMember.cs
- _NestedSingleAsyncResult.cs
- RadioButton.cs
- CallbackValidator.cs
- StoryFragments.cs
- UndirectedGraph.cs
- SchemeSettingElement.cs
- X509ThumbprintKeyIdentifierClause.cs
- UnsafeNativeMethods.cs
- Color.cs
- TrackingStringDictionary.cs
- FormClosedEvent.cs
- RequestResizeEvent.cs
- SecurityState.cs
- ExceptionAggregator.cs
- SqlConnectionHelper.cs
- HandoffBehavior.cs
- WriteFileContext.cs
- ConstructorNeedsTagAttribute.cs
- SafeRightsManagementSessionHandle.cs
- UnitySerializationHolder.cs
- GPStream.cs
- StylusPointPropertyInfoDefaults.cs
- DataGridTextBoxColumn.cs
- OpenTypeLayout.cs
- ObjectConverter.cs
- FrameworkReadOnlyPropertyMetadata.cs
- FormViewDeletedEventArgs.cs
- WhitespaceRule.cs
- WeakRefEnumerator.cs
- FontEditor.cs
- ProgressBarBrushConverter.cs
- StringResourceManager.cs
- StandardToolWindows.cs
- HtmlButton.cs
- Oid.cs
- SourceLineInfo.cs
- ReferencedCollectionType.cs
- WarningException.cs
- EventMetadata.cs
- DynamicValidatorEventArgs.cs
- unsafenativemethodsother.cs
- XmlUnspecifiedAttribute.cs
- Cursors.cs