You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			278 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			278 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="ContractReference.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>                                                                
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| namespace System.Web.Services.Discovery {
 | |
| 
 | |
|     using System;
 | |
|     using System.Net;
 | |
|     using System.Xml.Serialization;
 | |
|     using System.Web.Services.Description;
 | |
|     using System.IO;
 | |
|     using System.Xml;
 | |
|     using System.Xml.Schema;
 | |
|     using System.Web.Services.Protocols;
 | |
|     using System.Text;
 | |
|     using System.Collections;
 | |
|     using System.Threading;
 | |
|     using System.Diagnostics;
 | |
|     using System.Web.Services.Diagnostics;
 | |
| 
 | |
|     /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference"]/*' />
 | |
|     /// <devdoc>
 | |
|     ///    <para>[To be supplied.]</para>
 | |
|     /// </devdoc>
 | |
|     [XmlRoot("contractRef", Namespace = ContractReference.Namespace)]
 | |
|     public class ContractReference : DiscoveryReference {
 | |
| 
 | |
|         /// <include file='doc\contractreference.uex' path='docs/doc[@for="contractreference.namespace"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public const string Namespace = "http://schemas.xmlsoap.org/disco/scl/";
 | |
| 
 | |
|         private string docRef;
 | |
|         private string reference;
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.ContractReference"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public ContractReference() {
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.ContractReference1"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public ContractReference(string href) {
 | |
|             Ref = href;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.ContractReference2"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public ContractReference(string href, string docRef) {
 | |
|             Ref = href;
 | |
|             DocRef = docRef;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.Ref"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlAttribute("ref")]
 | |
|         public string Ref {
 | |
|             get {
 | |
|                 return reference;
 | |
|             }
 | |
|             set {
 | |
|                 reference = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.DocRef"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlAttribute("docRef")]
 | |
|         public string DocRef {
 | |
|             get {
 | |
|                 return docRef;
 | |
|             }
 | |
|             set {
 | |
|                 docRef = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.Url"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlIgnore]
 | |
|         public override string Url {
 | |
|             get {
 | |
|                 return Ref;
 | |
|             }
 | |
|             set {
 | |
|                 Ref = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal override void LoadExternals(Hashtable loadedExternals) {
 | |
|             ServiceDescription contract = null;
 | |
| 
 | |
|             try {
 | |
|                 contract = Contract;
 | |
|             }
 | |
|             catch (Exception e) {
 | |
|                 if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
 | |
|                     throw;
 | |
|                 }
 | |
|                 // don't let the exception out - keep going. Just add it to the list of errors.
 | |
|                 ClientProtocol.Errors[Url] = e;
 | |
|                 if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "LoadExternals", e);
 | |
|             }
 | |
|             if (contract != null) {
 | |
|                 foreach (XmlSchema schema in Contract.Types.Schemas) {
 | |
|                     SchemaReference.LoadExternals(schema, Url, ClientProtocol, loadedExternals);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.Contract"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlIgnore]
 | |
|         public ServiceDescription Contract {
 | |
|             get {
 | |
|                 if (ClientProtocol == null)
 | |
|                     throw new InvalidOperationException(Res.GetString(Res.WebMissingClientProtocol));
 | |
|                 object document = ClientProtocol.Documents[Url];
 | |
|                 if (document == null) {
 | |
|                     Resolve();
 | |
|                     document = ClientProtocol.Documents[Url];
 | |
|                 }
 | |
|                 ServiceDescription contract = document as ServiceDescription;
 | |
|                 if (contract == null) {
 | |
|                     throw new InvalidOperationException(Res.GetString(Res.WebInvalidDocType,
 | |
|                                                       typeof(ServiceDescription).FullName,
 | |
|                                                       document == null ? string.Empty : document.GetType().FullName,
 | |
|                                                       Url));
 | |
|                 }
 | |
|                 return contract;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.DefaultFilename"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlIgnore]
 | |
|         public override string DefaultFilename {
 | |
|             get {
 | |
|                 string fileName = MakeValidFilename(Contract.Name);
 | |
|                 if (fileName == null || fileName.Length == 0)
 | |
|                     fileName = FilenameFromUrl(Url);
 | |
|                 return Path.ChangeExtension(fileName, ".wsdl");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.WriteDocument"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public override void WriteDocument(object document, Stream stream) {
 | |
|             ((ServiceDescription) document).Write(new StreamWriter(stream, new UTF8Encoding(false)));
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.ReadDocument"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public override object ReadDocument(Stream stream) {
 | |
|             return ServiceDescription.Read(stream, true);
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\ContractReference.uex' path='docs/doc[@for="ContractReference.Resolve"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         protected internal override void Resolve(string contentType, Stream stream) {
 | |
|             if (ContentType.IsHtml(contentType))
 | |
|                 throw new InvalidContentTypeException(Res.GetString(Res.WebInvalidContentType, contentType), contentType);
 | |
|             ServiceDescription serviceDescription = ClientProtocol.Documents[Url] as ServiceDescription;
 | |
|             if ( serviceDescription == null ) {
 | |
|                 serviceDescription = ServiceDescription.Read(stream, true);
 | |
|                 serviceDescription.RetrievalUrl = Url;
 | |
|                 ClientProtocol.Documents[Url] = serviceDescription;
 | |
|             }
 | |
| 
 | |
|             ClientProtocol.References[Url] = this;
 | |
| 
 | |
|             ArrayList importUrls = new ArrayList();
 | |
|             foreach (Import import in serviceDescription.Imports)
 | |
|                 if (import.Location != null)
 | |
|                     importUrls.Add(import.Location);
 | |
|             foreach (XmlSchema schema in serviceDescription.Types.Schemas) {
 | |
|                 foreach (XmlSchemaExternal external in schema.Includes) {
 | |
|                     if (external.SchemaLocation != null && external.SchemaLocation.Length > 0) {
 | |
|                         importUrls.Add(external.SchemaLocation);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             foreach (string urlFromImport in importUrls) {
 | |
|                 // make the (possibly) relative Uri in the contract fully qualified with respect to the contract URL
 | |
|                 string importUrl = UriToString(Url, urlFromImport);
 | |
|                 if ( ClientProtocol.Documents[importUrl] != null ) {
 | |
|                     continue;
 | |
|                 }
 | |
| 
 | |
|                 string oldUrl = importUrl;
 | |
|                 try {
 | |
|                     stream = ClientProtocol.Download(ref importUrl, ref contentType);
 | |
|                     try {
 | |
|                         //Proceed only if not been here before
 | |
|                         if ( ClientProtocol.Documents[importUrl] == null ) {
 | |
|                             XmlTextReader reader = new XmlTextReader(new StreamReader(stream, RequestResponseUtils.GetEncoding(contentType)));
 | |
|                             reader.WhitespaceHandling = WhitespaceHandling.Significant;
 | |
|                             reader.XmlResolver = null;
 | |
|                             reader.DtdProcessing = DtdProcessing.Prohibit;
 | |
|                             //Resolve on WSDL and XSD will go recursivelly
 | |
|                             if (ServiceDescription.CanRead(reader)) {
 | |
|                                 ServiceDescription doc = ServiceDescription.Read(reader, true);
 | |
|                                 doc.RetrievalUrl = importUrl;
 | |
|                                 ClientProtocol.Documents[importUrl] = doc;
 | |
|                                 ContractReference contractReference = new ContractReference(importUrl, null);
 | |
|                                 contractReference.ClientProtocol = ClientProtocol;
 | |
|                                 try {
 | |
|                                     contractReference.Resolve(contentType, stream);
 | |
|                                 }
 | |
|                                 catch (Exception e) {
 | |
|                                     if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
 | |
|                                         throw;
 | |
|                                     }
 | |
|                                     contractReference.Url = oldUrl;
 | |
|                                     if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "Resolve", e);
 | |
|                                 }
 | |
|                             }
 | |
|                             else if (reader.IsStartElement("schema", XmlSchema.Namespace)) {
 | |
|                                 ClientProtocol.Documents[importUrl] = XmlSchema.Read(reader, null);
 | |
|                                 SchemaReference schemaReference = new SchemaReference(importUrl);
 | |
|                                 schemaReference.ClientProtocol = ClientProtocol;
 | |
|                                 try {
 | |
|                                     schemaReference.Resolve(contentType, stream);
 | |
|                                 }
 | |
|                                 catch (Exception e) {
 | |
|                                     if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
 | |
|                                         throw;
 | |
|                                     }
 | |
|                                     schemaReference.Url = oldUrl;
 | |
|                                     if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "Resolve", e);
 | |
|                                 }
 | |
|                             }
 | |
|                             // If it's not XML, or we don't know what kind of XML it is, skip the file.  The user 
 | |
|                             // will have to download the dependent file(s) manually, but at least we will continue 
 | |
|                             // to discover files instead of throwing an exception.
 | |
|                         }
 | |
|                     }
 | |
|                     finally {
 | |
|                         stream.Close();
 | |
|                     }
 | |
|                 }
 | |
|                 catch (Exception e) {
 | |
|                     if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
 | |
|                         throw;
 | |
|                     }
 | |
|                     throw new InvalidDocumentContentsException(Res.GetString(Res.TheWSDLDocumentContainsLinksThatCouldNotBeResolved, importUrl), e);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |