DiscoveryClientProtocol.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Web / System / Web / Services / Discovery / DiscoveryClientProtocol.cs / 1305376 / DiscoveryClientProtocol.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Services.Discovery { 
 
    using System.Xml.Serialization;
    using System.IO; 
    using System;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    using System.Net; 
    using System.Collections;
    using System.Diagnostics; 
    using System.Web.Services.Configuration; 
    using System.Text;
    using System.Security.Permissions; 
    using System.Globalization;
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.Web.Services.Diagnostics; 

    ///  
    ///  
    ///    [To be supplied.]
    ///  
    public class DiscoveryClientProtocol : HttpWebClientProtocol {
        private DiscoveryClientReferenceCollection references = new DiscoveryClientReferenceCollection();
        private DiscoveryClientDocumentCollection documents = new DiscoveryClientDocumentCollection();
        private Hashtable inlinedSchemas = new Hashtable(); 
        private ArrayList additionalInformation = new ArrayList();
        private DiscoveryExceptionDictionary errors = new DiscoveryExceptionDictionary(); 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public DiscoveryClientProtocol()
            : base() { 
        }
 
        internal DiscoveryClientProtocol(HttpWebClientProtocol protocol) : base(protocol) { 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public IList AdditionalInformation {
            get { 
                return additionalInformation; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public DiscoveryClientDocumentCollection Documents { 
            get { 
                return documents;
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public DiscoveryExceptionDictionary Errors { 
            get {
                return errors; 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public DiscoveryClientReferenceCollection References {
            get { 
                return references;
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        internal Hashtable InlinedSchemas 
        {
            get
            {
                return inlinedSchemas; 
            }
        } 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public DiscoveryDocument Discover(string url) {
            DiscoveryDocument doc = Documents[url] as DiscoveryDocument; 
            if (doc != null)
                return doc; 
 
            DiscoveryDocumentReference docRef = new DiscoveryDocumentReference(url);
            docRef.ClientProtocol = this; 
            References[url] = docRef;

            Errors.Clear();
            // this will auto-resolve and place the document in the Documents hashtable. 
            return docRef.Document;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public DiscoveryDocument DiscoverAny(string url) { 
            Type[] refTypes = WebServicesSection.Current.DiscoveryReferenceTypes;
            DiscoveryReference discoRef = null; 
            string contentType = null; 
            Stream stream = Download(ref url, ref contentType);
 
            Errors.Clear();
            bool allErrorsAreHtmlContentType = true;
            Exception errorInValidDocument = null;
            ArrayList specialErrorMessages = new ArrayList(); 
            foreach (Type type in refTypes) {
                if (!typeof(DiscoveryReference).IsAssignableFrom(type)) 
                    continue; 
                discoRef = (DiscoveryReference) Activator.CreateInstance(type);
                discoRef.Url = url; 
                discoRef.ClientProtocol = this;
                stream.Position = 0;
                Exception e = discoRef.AttemptResolve(contentType, stream);
                if (e == null) 
                    break;
 
                Errors[type.FullName] = e; 
                discoRef = null;
 
                InvalidContentTypeException e2 = e as InvalidContentTypeException;
                if (e2 == null || !ContentType.MatchesBase(e2.ContentType, "text/html"))
                    allErrorsAreHtmlContentType = false;
 
                InvalidDocumentContentsException e3 = e as InvalidDocumentContentsException;
                if (e3 != null) { 
                    errorInValidDocument = e; 
                    break;
                } 

                if (e.InnerException != null && e.InnerException.InnerException == null)
                    specialErrorMessages.Add(e.InnerException.Message);
            } 

            if (discoRef == null) { 
                if (errorInValidDocument != null) { 
                    StringBuilder errorMessage = new StringBuilder(Res.GetString(Res.TheDocumentWasUnderstoodButContainsErrors));
                    while (errorInValidDocument != null) { 
                        errorMessage.Append("\n  - ").Append(errorInValidDocument.Message);
                        errorInValidDocument = errorInValidDocument.InnerException;
                    }
                    throw new InvalidOperationException(errorMessage.ToString()); 
                }
                else if (allErrorsAreHtmlContentType) { 
                    throw new InvalidOperationException(Res.GetString(Res.TheHTMLDocumentDoesNotContainDiscoveryInformation)); 
                }
                else { 
                    bool same = specialErrorMessages.Count == Errors.Count && Errors.Count > 0;
                    for (int i = 1; same && i < specialErrorMessages.Count; i++) {
                        if ((string) specialErrorMessages[i-1] != (string) specialErrorMessages[i])
                            same = false; 
                    }
                    if (same) 
                        throw new InvalidOperationException(Res.GetString(Res.TheDocumentWasNotRecognizedAsAKnownDocumentType, specialErrorMessages[0])); 
                    else {
                        Exception e; 
                        StringBuilder errorMessage = new StringBuilder(Res.GetString(Res.WebMissingResource, url));
                        foreach (DictionaryEntry entry in Errors) {
                            e = (Exception)(entry.Value);
                            string refType = (string)(entry.Key); 
                            if (0 == string.Compare(refType, typeof(ContractReference).FullName, StringComparison.Ordinal)) {
                                refType = Res.GetString(Res.WebContractReferenceName); 
                            } 
                            else if (0 == string.Compare(refType, typeof(SchemaReference).FullName, StringComparison.Ordinal)) {
                                refType = Res.GetString(Res.WebShemaReferenceName); 
                            }
                            else if (0 == string.Compare(refType, typeof(DiscoveryDocumentReference).FullName, StringComparison.Ordinal)) {
                                refType = Res.GetString(Res.WebDiscoveryDocumentReferenceName);
                            } 
                            errorMessage.Append("\n- ").Append(Res.GetString(Res.WebDiscoRefReport,
                                                               refType, 
                                                               e.Message)); 
                            while (e.InnerException != null) {
                                errorMessage.Append("\n  - ").Append(e.InnerException.Message); 
                                e = e.InnerException;
                            }
                        }
                        throw new InvalidOperationException(errorMessage.ToString()); 
                    }
                } 
            } 

            if (discoRef is DiscoveryDocumentReference) 
                return ((DiscoveryDocumentReference) discoRef).Document;

            References[discoRef.Url] = discoRef;
            DiscoveryDocument doc = new DiscoveryDocument(); 
            doc.References.Add(discoRef);
            return doc; 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public Stream Download(ref string url) {
            string contentType = null; 
            return Download(ref url, ref contentType); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public Stream Download(ref string url, ref string contentType) { 
            WebRequest request = GetWebRequest(new Uri(url)); 
            request.Method = "GET";
#if DEBUG // 
            HttpWebRequest httpRequest = request as HttpWebRequest;
            if (httpRequest != null) {
                httpRequest.Timeout = httpRequest.Timeout * 2;
            } 
#endif
            WebResponse response = null; 
            try { 
                response = GetWebResponse(request);
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw;
                } 
                throw new WebException(Res.GetString(Res.ThereWasAnErrorDownloading0, url), e);
            } 
            HttpWebResponse httpResponse = response as HttpWebResponse; 
            if (httpResponse != null) {
                if (httpResponse.StatusCode != HttpStatusCode.OK) { 
                    string errorMessage = RequestResponseUtils.CreateResponseExceptionString(httpResponse);
                    throw new WebException(Res.GetString(Res.ThereWasAnErrorDownloading0, url), new WebException(errorMessage, null, WebExceptionStatus.ProtocolError, response));
                }
            } 
            Stream responseStream = response.GetResponseStream();
            try { 
                // Uri.ToString() returns the unescaped version 
                url = response.ResponseUri.ToString();
                contentType = response.ContentType; 

                if (response.ResponseUri.Scheme == Uri.UriSchemeFtp ||
                    response.ResponseUri.Scheme == Uri.UriSchemeFile) {
                    int dotIndex = response.ResponseUri.AbsolutePath.LastIndexOf('.'); 
                    if (dotIndex != -1) {
                        switch (response.ResponseUri.AbsolutePath.Substring(dotIndex + 1).ToLower(CultureInfo.InvariantCulture)) { 
                            case "xml": 
                            case "wsdl":
                            case "xsd": 
                            case "disco":
                                contentType = ContentType.TextXml;
                                break;
                            default: 
                                break;
                        } 
                    } 
                }
 
                // need to return a buffered stream (one that supports CanSeek)
                return RequestResponseUtils.StreamToMemoryStream(responseStream);
            }
            finally { 
                responseStream.Close();
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        ///  
        [Obsolete("This method will be removed from a future version. The method call is no longer required for resource discovery", false)]
        [ComVisible(false)] 
        public void LoadExternals() {} 

        internal void FixupReferences() { 
            foreach (DiscoveryReference reference in References.Values) {
                reference.LoadExternals(InlinedSchemas);
            }
            foreach (string url in InlinedSchemas.Keys) { 
                Documents.Remove(url);
            } 
        } 

        private static bool IsFilenameInUse(Hashtable filenames, string path) { 
            return filenames[path.ToLower(CultureInfo.InvariantCulture)] != null;
        }

        private static void AddFilename(Hashtable filenames, string path) { 
            filenames.Add(path.ToLower(CultureInfo.InvariantCulture), path);
        } 
 
        private static string GetUniqueFilename(Hashtable filenames, string path) {
            if (IsFilenameInUse(filenames, path)) { 
                string extension = Path.GetExtension(path);
                string allElse = path.Substring(0, path.Length - extension.Length);
                int append = 0;
                do { 
                    path = allElse + append.ToString(CultureInfo.InvariantCulture) + extension;
                    append++; 
                } while (IsFilenameInUse(filenames, path)); 
            }
 
            AddFilename(filenames, path);
            return path;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public DiscoveryClientResultCollection ReadAll(string topLevelFilename) {
            XmlSerializer ser = new XmlSerializer(typeof(DiscoveryClientResultsFile));
            Stream file = File.OpenRead(topLevelFilename);
            string topLevelPath = Path.GetDirectoryName(topLevelFilename); 
            DiscoveryClientResultsFile results = null;
            try { 
                results = (DiscoveryClientResultsFile) ser.Deserialize(file); 
                for (int i = 0; i < results.Results.Count; i++) {
                    if (results.Results[i] == null) 
                        throw new InvalidOperationException(Res.GetString(Res.WebNullRef));
                    string typeName = results.Results[i].ReferenceTypeName;
                    if (typeName == null || typeName.Length == 0)
                        throw new InvalidOperationException(Res.GetString(Res.WebRefInvalidAttribute, "referenceType")); 
                    DiscoveryReference reference = (DiscoveryReference) Activator.CreateInstance(Type.GetType(typeName));
                    reference.ClientProtocol = this; 
 
                    string url = results.Results[i].Url;
                    if (url == null || url.Length == 0) 
                        throw new InvalidOperationException(Res.GetString(Res.WebRefInvalidAttribute2, reference.GetType().FullName, "url"));
                    reference.Url = url;
                    string fileName = results.Results[i].Filename;
                    if (fileName == null || fileName.Length == 0) 
                        throw new InvalidOperationException(Res.GetString(Res.WebRefInvalidAttribute2, reference.GetType().FullName, "filename"));
 
                    Stream docFile = File.OpenRead(Path.Combine(topLevelPath, results.Results[i].Filename)); 
                    try {
                        Documents[reference.Url] = reference.ReadDocument(docFile); 
                        Debug.Assert(Documents[reference.Url] != null, "Couldn't deserialize file " + results.Results[i].Filename);
                    }
                    finally {
                        docFile.Close(); 
                    }
                    References[reference.Url] = reference; 
                } 
                ResolveAll();
            } 
            finally {
                file.Close();
            }
            return results.Results; 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public void ResolveAll() {
            // Resolve until we reach a 'steady state' (no more references added) 
            Errors.Clear();
            int resolvedCount = InlinedSchemas.Keys.Count; 
            while (resolvedCount != References.Count) { 
                resolvedCount = References.Count;
                DiscoveryReference[] refs = new DiscoveryReference[References.Count]; 
                References.Values.CopyTo(refs, 0);
                for (int i = 0; i < refs.Length; i++) {
                    DiscoveryReference discoRef = refs[i];
                    if (discoRef is DiscoveryDocumentReference) { 
                        try {
                            // Resolve discovery document references deeply 
                            ((DiscoveryDocumentReference)discoRef).ResolveAll(true); 
                        }
                        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. 
                            Errors[discoRef.Url] = e;
                            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "ResolveAll", e); 
                        } 
                    }
                    else { 
                        try {
                            discoRef.Resolve();
                        }
                        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.
                            Errors[discoRef.Url] = e; 
                            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "ResolveAll", e);
                        }
                    }
                } 
            }
            FixupReferences(); 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public void ResolveOneLevel() {
            // download everything we have a reference to, but don't recurse. 
            Errors.Clear(); 
            DiscoveryReference[] refs = new DiscoveryReference[References.Count];
            References.Values.CopyTo(refs, 0); 
            for (int i = 0; i < refs.Length; i++) {
                try {
                    refs[i].Resolve();
                } 
                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. 
                    Errors[refs[i].Url] = e;
                    if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "ResolveOneLevel", e);
                }
            } 
        }
 
        private static string GetRelativePath(string fullPath, string relativeTo) { 
            string currentDir = Path.GetDirectoryName(Path.GetFullPath(relativeTo));
 
            string answer = "";
            while (currentDir.Length > 0) {
                if (currentDir.Length <= fullPath.Length && string.Compare(currentDir, fullPath.Substring(0, currentDir.Length), StringComparison.OrdinalIgnoreCase) == 0) {
                    answer += fullPath.Substring(currentDir.Length); 
                    if (answer.StartsWith("\\", StringComparison.Ordinal))
                        answer = answer.Substring(1); 
                    return answer; 
                }
                answer += "..\\"; 
                if (currentDir.Length < 2)
                    break;
                else {
                    int lastSlash = currentDir.LastIndexOf('\\', currentDir.Length - 2); 
                    currentDir = currentDir.Substring(0, lastSlash+1);
                } 
            } 
            return fullPath;
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public DiscoveryClientResultCollection WriteAll(string directory, string topLevelFilename) { 
            DiscoveryClientResultsFile results = new DiscoveryClientResultsFile();
            Hashtable filenames = new Hashtable(); 
            string topLevelFullPath = Path.Combine(directory, topLevelFilename);

            // write out each of the documents
            DictionaryEntry[] entries = new DictionaryEntry[Documents.Count + InlinedSchemas.Keys.Count]; 
            int i = 0;
            foreach (DictionaryEntry entry in Documents) { 
                entries[i++] = entry; 
            }
            foreach (DictionaryEntry entry in InlinedSchemas) { 
                entries[i++] = entry;
            }
            foreach (DictionaryEntry entry in entries) {
                string url = (string) entry.Key; 
                object document = entry.Value;
                if (document == null) 
                    continue; 
                DiscoveryReference reference = References[url];
                string filename = reference == null ? DiscoveryReference.FilenameFromUrl(Url) : reference.DefaultFilename; 
                filename = GetUniqueFilename(filenames, Path.GetFullPath(Path.Combine(directory, filename)));
                results.Results.Add(new DiscoveryClientResult(reference == null ? null : reference.GetType(), url, GetRelativePath(filename, topLevelFullPath)));
                Stream file = File.Create(filename);
                try { 
                    reference.WriteDocument(document, file);
                } 
                finally { 
                    file.Close();
                } 
            }

            // write out the file that points to all those documents.
            XmlSerializer ser = new XmlSerializer(typeof(DiscoveryClientResultsFile)); 
            Stream topLevelFile = File.Create(topLevelFullPath);
            try { 
                ser.Serialize(new StreamWriter(topLevelFile, new UTF8Encoding(false)), results); 
            }
            finally { 
                topLevelFile.Close();
            }

            return results.Results; 
        }
 
        // 

 



        public sealed class DiscoveryClientResultsFile { 
            private DiscoveryClientResultCollection results = new DiscoveryClientResultCollection();
            ///  
            ///  
            ///    [To be supplied.]
            ///  
            public DiscoveryClientResultCollection Results {
                get {
                    return results;
                } 
            }
        } 
 
    }
 
    /// 
    /// 
    ///    [To be supplied.]
    ///  
    public sealed class DiscoveryClientResultCollection : CollectionBase {
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public DiscoveryClientResult this[int i] {
            get {
                return (DiscoveryClientResult) List[i]; 
            }
            set { 
                List[i] = value; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public int Add(DiscoveryClientResult value) { 
            return List.Add(value); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public bool Contains(DiscoveryClientResult value) {
            return List.Contains(value); 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public void Remove(DiscoveryClientResult value) { 
            List.Remove(value);
        } 
 
    }
 
    /// 
    /// 
    ///    [To be supplied.]
    ///  
    public sealed class DiscoveryClientResult {
        string referenceTypeName; 
        string url; 
        string filename;
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public DiscoveryClientResult() {
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public DiscoveryClientResult(Type referenceType, string url, string filename) {
            this.referenceTypeName = referenceType == null ? string.Empty : referenceType.FullName; 
            this.url = url;
            this.filename = filename; 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [XmlAttribute("referenceType")] 
        public string ReferenceTypeName {
            get { 
                return referenceTypeName; 
            }
            set { 
                referenceTypeName = value;
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [XmlAttribute("url")] 
        public string Url {
            get {
                return url;
            } 
            set {
                url = value; 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [XmlAttribute("filename")]
        public string Filename { 
            get { 
                return filename;
            } 
            set {
                filename = value;
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Services.Discovery { 
 
    using System.Xml.Serialization;
    using System.IO; 
    using System;
    using System.Web.Services;
    using System.Web.Services.Protocols;
    using System.Net; 
    using System.Collections;
    using System.Diagnostics; 
    using System.Web.Services.Configuration; 
    using System.Text;
    using System.Security.Permissions; 
    using System.Globalization;
    using System.Threading;
    using System.Runtime.InteropServices;
    using System.Web.Services.Diagnostics; 

    ///  
    ///  
    ///    [To be supplied.]
    ///  
    public class DiscoveryClientProtocol : HttpWebClientProtocol {
        private DiscoveryClientReferenceCollection references = new DiscoveryClientReferenceCollection();
        private DiscoveryClientDocumentCollection documents = new DiscoveryClientDocumentCollection();
        private Hashtable inlinedSchemas = new Hashtable(); 
        private ArrayList additionalInformation = new ArrayList();
        private DiscoveryExceptionDictionary errors = new DiscoveryExceptionDictionary(); 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public DiscoveryClientProtocol()
            : base() { 
        }
 
        internal DiscoveryClientProtocol(HttpWebClientProtocol protocol) : base(protocol) { 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public IList AdditionalInformation {
            get { 
                return additionalInformation; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public DiscoveryClientDocumentCollection Documents { 
            get { 
                return documents;
            } 
        }

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public DiscoveryExceptionDictionary Errors { 
            get {
                return errors; 
            }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        public DiscoveryClientReferenceCollection References {
            get { 
                return references;
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        internal Hashtable InlinedSchemas 
        {
            get
            {
                return inlinedSchemas; 
            }
        } 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public DiscoveryDocument Discover(string url) {
            DiscoveryDocument doc = Documents[url] as DiscoveryDocument; 
            if (doc != null)
                return doc; 
 
            DiscoveryDocumentReference docRef = new DiscoveryDocumentReference(url);
            docRef.ClientProtocol = this; 
            References[url] = docRef;

            Errors.Clear();
            // this will auto-resolve and place the document in the Documents hashtable. 
            return docRef.Document;
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public DiscoveryDocument DiscoverAny(string url) { 
            Type[] refTypes = WebServicesSection.Current.DiscoveryReferenceTypes;
            DiscoveryReference discoRef = null; 
            string contentType = null; 
            Stream stream = Download(ref url, ref contentType);
 
            Errors.Clear();
            bool allErrorsAreHtmlContentType = true;
            Exception errorInValidDocument = null;
            ArrayList specialErrorMessages = new ArrayList(); 
            foreach (Type type in refTypes) {
                if (!typeof(DiscoveryReference).IsAssignableFrom(type)) 
                    continue; 
                discoRef = (DiscoveryReference) Activator.CreateInstance(type);
                discoRef.Url = url; 
                discoRef.ClientProtocol = this;
                stream.Position = 0;
                Exception e = discoRef.AttemptResolve(contentType, stream);
                if (e == null) 
                    break;
 
                Errors[type.FullName] = e; 
                discoRef = null;
 
                InvalidContentTypeException e2 = e as InvalidContentTypeException;
                if (e2 == null || !ContentType.MatchesBase(e2.ContentType, "text/html"))
                    allErrorsAreHtmlContentType = false;
 
                InvalidDocumentContentsException e3 = e as InvalidDocumentContentsException;
                if (e3 != null) { 
                    errorInValidDocument = e; 
                    break;
                } 

                if (e.InnerException != null && e.InnerException.InnerException == null)
                    specialErrorMessages.Add(e.InnerException.Message);
            } 

            if (discoRef == null) { 
                if (errorInValidDocument != null) { 
                    StringBuilder errorMessage = new StringBuilder(Res.GetString(Res.TheDocumentWasUnderstoodButContainsErrors));
                    while (errorInValidDocument != null) { 
                        errorMessage.Append("\n  - ").Append(errorInValidDocument.Message);
                        errorInValidDocument = errorInValidDocument.InnerException;
                    }
                    throw new InvalidOperationException(errorMessage.ToString()); 
                }
                else if (allErrorsAreHtmlContentType) { 
                    throw new InvalidOperationException(Res.GetString(Res.TheHTMLDocumentDoesNotContainDiscoveryInformation)); 
                }
                else { 
                    bool same = specialErrorMessages.Count == Errors.Count && Errors.Count > 0;
                    for (int i = 1; same && i < specialErrorMessages.Count; i++) {
                        if ((string) specialErrorMessages[i-1] != (string) specialErrorMessages[i])
                            same = false; 
                    }
                    if (same) 
                        throw new InvalidOperationException(Res.GetString(Res.TheDocumentWasNotRecognizedAsAKnownDocumentType, specialErrorMessages[0])); 
                    else {
                        Exception e; 
                        StringBuilder errorMessage = new StringBuilder(Res.GetString(Res.WebMissingResource, url));
                        foreach (DictionaryEntry entry in Errors) {
                            e = (Exception)(entry.Value);
                            string refType = (string)(entry.Key); 
                            if (0 == string.Compare(refType, typeof(ContractReference).FullName, StringComparison.Ordinal)) {
                                refType = Res.GetString(Res.WebContractReferenceName); 
                            } 
                            else if (0 == string.Compare(refType, typeof(SchemaReference).FullName, StringComparison.Ordinal)) {
                                refType = Res.GetString(Res.WebShemaReferenceName); 
                            }
                            else if (0 == string.Compare(refType, typeof(DiscoveryDocumentReference).FullName, StringComparison.Ordinal)) {
                                refType = Res.GetString(Res.WebDiscoveryDocumentReferenceName);
                            } 
                            errorMessage.Append("\n- ").Append(Res.GetString(Res.WebDiscoRefReport,
                                                               refType, 
                                                               e.Message)); 
                            while (e.InnerException != null) {
                                errorMessage.Append("\n  - ").Append(e.InnerException.Message); 
                                e = e.InnerException;
                            }
                        }
                        throw new InvalidOperationException(errorMessage.ToString()); 
                    }
                } 
            } 

            if (discoRef is DiscoveryDocumentReference) 
                return ((DiscoveryDocumentReference) discoRef).Document;

            References[discoRef.Url] = discoRef;
            DiscoveryDocument doc = new DiscoveryDocument(); 
            doc.References.Add(discoRef);
            return doc; 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public Stream Download(ref string url) {
            string contentType = null; 
            return Download(ref url, ref contentType); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public Stream Download(ref string url, ref string contentType) { 
            WebRequest request = GetWebRequest(new Uri(url)); 
            request.Method = "GET";
#if DEBUG // 
            HttpWebRequest httpRequest = request as HttpWebRequest;
            if (httpRequest != null) {
                httpRequest.Timeout = httpRequest.Timeout * 2;
            } 
#endif
            WebResponse response = null; 
            try { 
                response = GetWebResponse(request);
            } 
            catch (Exception e) {
                if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
                    throw;
                } 
                throw new WebException(Res.GetString(Res.ThereWasAnErrorDownloading0, url), e);
            } 
            HttpWebResponse httpResponse = response as HttpWebResponse; 
            if (httpResponse != null) {
                if (httpResponse.StatusCode != HttpStatusCode.OK) { 
                    string errorMessage = RequestResponseUtils.CreateResponseExceptionString(httpResponse);
                    throw new WebException(Res.GetString(Res.ThereWasAnErrorDownloading0, url), new WebException(errorMessage, null, WebExceptionStatus.ProtocolError, response));
                }
            } 
            Stream responseStream = response.GetResponseStream();
            try { 
                // Uri.ToString() returns the unescaped version 
                url = response.ResponseUri.ToString();
                contentType = response.ContentType; 

                if (response.ResponseUri.Scheme == Uri.UriSchemeFtp ||
                    response.ResponseUri.Scheme == Uri.UriSchemeFile) {
                    int dotIndex = response.ResponseUri.AbsolutePath.LastIndexOf('.'); 
                    if (dotIndex != -1) {
                        switch (response.ResponseUri.AbsolutePath.Substring(dotIndex + 1).ToLower(CultureInfo.InvariantCulture)) { 
                            case "xml": 
                            case "wsdl":
                            case "xsd": 
                            case "disco":
                                contentType = ContentType.TextXml;
                                break;
                            default: 
                                break;
                        } 
                    } 
                }
 
                // need to return a buffered stream (one that supports CanSeek)
                return RequestResponseUtils.StreamToMemoryStream(responseStream);
            }
            finally { 
                responseStream.Close();
            } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        ///  
        [Obsolete("This method will be removed from a future version. The method call is no longer required for resource discovery", false)]
        [ComVisible(false)] 
        public void LoadExternals() {} 

        internal void FixupReferences() { 
            foreach (DiscoveryReference reference in References.Values) {
                reference.LoadExternals(InlinedSchemas);
            }
            foreach (string url in InlinedSchemas.Keys) { 
                Documents.Remove(url);
            } 
        } 

        private static bool IsFilenameInUse(Hashtable filenames, string path) { 
            return filenames[path.ToLower(CultureInfo.InvariantCulture)] != null;
        }

        private static void AddFilename(Hashtable filenames, string path) { 
            filenames.Add(path.ToLower(CultureInfo.InvariantCulture), path);
        } 
 
        private static string GetUniqueFilename(Hashtable filenames, string path) {
            if (IsFilenameInUse(filenames, path)) { 
                string extension = Path.GetExtension(path);
                string allElse = path.Substring(0, path.Length - extension.Length);
                int append = 0;
                do { 
                    path = allElse + append.ToString(CultureInfo.InvariantCulture) + extension;
                    append++; 
                } while (IsFilenameInUse(filenames, path)); 
            }
 
            AddFilename(filenames, path);
            return path;
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public DiscoveryClientResultCollection ReadAll(string topLevelFilename) {
            XmlSerializer ser = new XmlSerializer(typeof(DiscoveryClientResultsFile));
            Stream file = File.OpenRead(topLevelFilename);
            string topLevelPath = Path.GetDirectoryName(topLevelFilename); 
            DiscoveryClientResultsFile results = null;
            try { 
                results = (DiscoveryClientResultsFile) ser.Deserialize(file); 
                for (int i = 0; i < results.Results.Count; i++) {
                    if (results.Results[i] == null) 
                        throw new InvalidOperationException(Res.GetString(Res.WebNullRef));
                    string typeName = results.Results[i].ReferenceTypeName;
                    if (typeName == null || typeName.Length == 0)
                        throw new InvalidOperationException(Res.GetString(Res.WebRefInvalidAttribute, "referenceType")); 
                    DiscoveryReference reference = (DiscoveryReference) Activator.CreateInstance(Type.GetType(typeName));
                    reference.ClientProtocol = this; 
 
                    string url = results.Results[i].Url;
                    if (url == null || url.Length == 0) 
                        throw new InvalidOperationException(Res.GetString(Res.WebRefInvalidAttribute2, reference.GetType().FullName, "url"));
                    reference.Url = url;
                    string fileName = results.Results[i].Filename;
                    if (fileName == null || fileName.Length == 0) 
                        throw new InvalidOperationException(Res.GetString(Res.WebRefInvalidAttribute2, reference.GetType().FullName, "filename"));
 
                    Stream docFile = File.OpenRead(Path.Combine(topLevelPath, results.Results[i].Filename)); 
                    try {
                        Documents[reference.Url] = reference.ReadDocument(docFile); 
                        Debug.Assert(Documents[reference.Url] != null, "Couldn't deserialize file " + results.Results[i].Filename);
                    }
                    finally {
                        docFile.Close(); 
                    }
                    References[reference.Url] = reference; 
                } 
                ResolveAll();
            } 
            finally {
                file.Close();
            }
            return results.Results; 
        }
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
        public void ResolveAll() {
            // Resolve until we reach a 'steady state' (no more references added) 
            Errors.Clear();
            int resolvedCount = InlinedSchemas.Keys.Count; 
            while (resolvedCount != References.Count) { 
                resolvedCount = References.Count;
                DiscoveryReference[] refs = new DiscoveryReference[References.Count]; 
                References.Values.CopyTo(refs, 0);
                for (int i = 0; i < refs.Length; i++) {
                    DiscoveryReference discoRef = refs[i];
                    if (discoRef is DiscoveryDocumentReference) { 
                        try {
                            // Resolve discovery document references deeply 
                            ((DiscoveryDocumentReference)discoRef).ResolveAll(true); 
                        }
                        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. 
                            Errors[discoRef.Url] = e;
                            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "ResolveAll", e); 
                        } 
                    }
                    else { 
                        try {
                            discoRef.Resolve();
                        }
                        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.
                            Errors[discoRef.Url] = e; 
                            if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "ResolveAll", e);
                        }
                    }
                } 
            }
            FixupReferences(); 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public void ResolveOneLevel() {
            // download everything we have a reference to, but don't recurse. 
            Errors.Clear(); 
            DiscoveryReference[] refs = new DiscoveryReference[References.Count];
            References.Values.CopyTo(refs, 0); 
            for (int i = 0; i < refs.Length; i++) {
                try {
                    refs[i].Resolve();
                } 
                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. 
                    Errors[refs[i].Url] = e;
                    if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "ResolveOneLevel", e);
                }
            } 
        }
 
        private static string GetRelativePath(string fullPath, string relativeTo) { 
            string currentDir = Path.GetDirectoryName(Path.GetFullPath(relativeTo));
 
            string answer = "";
            while (currentDir.Length > 0) {
                if (currentDir.Length <= fullPath.Length && string.Compare(currentDir, fullPath.Substring(0, currentDir.Length), StringComparison.OrdinalIgnoreCase) == 0) {
                    answer += fullPath.Substring(currentDir.Length); 
                    if (answer.StartsWith("\\", StringComparison.Ordinal))
                        answer = answer.Substring(1); 
                    return answer; 
                }
                answer += "..\\"; 
                if (currentDir.Length < 2)
                    break;
                else {
                    int lastSlash = currentDir.LastIndexOf('\\', currentDir.Length - 2); 
                    currentDir = currentDir.Substring(0, lastSlash+1);
                } 
            } 
            return fullPath;
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
        public DiscoveryClientResultCollection WriteAll(string directory, string topLevelFilename) { 
            DiscoveryClientResultsFile results = new DiscoveryClientResultsFile();
            Hashtable filenames = new Hashtable(); 
            string topLevelFullPath = Path.Combine(directory, topLevelFilename);

            // write out each of the documents
            DictionaryEntry[] entries = new DictionaryEntry[Documents.Count + InlinedSchemas.Keys.Count]; 
            int i = 0;
            foreach (DictionaryEntry entry in Documents) { 
                entries[i++] = entry; 
            }
            foreach (DictionaryEntry entry in InlinedSchemas) { 
                entries[i++] = entry;
            }
            foreach (DictionaryEntry entry in entries) {
                string url = (string) entry.Key; 
                object document = entry.Value;
                if (document == null) 
                    continue; 
                DiscoveryReference reference = References[url];
                string filename = reference == null ? DiscoveryReference.FilenameFromUrl(Url) : reference.DefaultFilename; 
                filename = GetUniqueFilename(filenames, Path.GetFullPath(Path.Combine(directory, filename)));
                results.Results.Add(new DiscoveryClientResult(reference == null ? null : reference.GetType(), url, GetRelativePath(filename, topLevelFullPath)));
                Stream file = File.Create(filename);
                try { 
                    reference.WriteDocument(document, file);
                } 
                finally { 
                    file.Close();
                } 
            }

            // write out the file that points to all those documents.
            XmlSerializer ser = new XmlSerializer(typeof(DiscoveryClientResultsFile)); 
            Stream topLevelFile = File.Create(topLevelFullPath);
            try { 
                ser.Serialize(new StreamWriter(topLevelFile, new UTF8Encoding(false)), results); 
            }
            finally { 
                topLevelFile.Close();
            }

            return results.Results; 
        }
 
        // 

 



        public sealed class DiscoveryClientResultsFile { 
            private DiscoveryClientResultCollection results = new DiscoveryClientResultCollection();
            ///  
            ///  
            ///    [To be supplied.]
            ///  
            public DiscoveryClientResultCollection Results {
                get {
                    return results;
                } 
            }
        } 
 
    }
 
    /// 
    /// 
    ///    [To be supplied.]
    ///  
    public sealed class DiscoveryClientResultCollection : CollectionBase {
 
        ///  
        /// 
        ///    [To be supplied.] 
        /// 
        public DiscoveryClientResult this[int i] {
            get {
                return (DiscoveryClientResult) List[i]; 
            }
            set { 
                List[i] = value; 
            }
        } 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public int Add(DiscoveryClientResult value) { 
            return List.Add(value); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public bool Contains(DiscoveryClientResult value) {
            return List.Contains(value); 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public void Remove(DiscoveryClientResult value) { 
            List.Remove(value);
        } 
 
    }
 
    /// 
    /// 
    ///    [To be supplied.]
    ///  
    public sealed class DiscoveryClientResult {
        string referenceTypeName; 
        string url; 
        string filename;
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public DiscoveryClientResult() {
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public DiscoveryClientResult(Type referenceType, string url, string filename) {
            this.referenceTypeName = referenceType == null ? string.Empty : referenceType.FullName; 
            this.url = url;
            this.filename = filename; 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        [XmlAttribute("referenceType")] 
        public string ReferenceTypeName {
            get { 
                return referenceTypeName; 
            }
            set { 
                referenceTypeName = value;
            }
        }
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [XmlAttribute("url")] 
        public string Url {
            get {
                return url;
            } 
            set {
                url = value; 
            } 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        [XmlAttribute("filename")]
        public string Filename { 
            get { 
                return filename;
            } 
            set {
                filename = value;
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK