You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			656 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			656 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="DiscoveryClientProtocol.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| 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;
 | |
| 
 | |
|     /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol"]/*' />
 | |
|     /// <devdoc>
 | |
|     ///    <para>[To be supplied.]</para>
 | |
|     /// </devdoc>
 | |
|     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();
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.DiscoveryClientProtocol"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public DiscoveryClientProtocol()
 | |
|             : base() {
 | |
|         }
 | |
| 
 | |
|         internal DiscoveryClientProtocol(HttpWebClientProtocol protocol) : base(protocol) {
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.AdditionalInformation"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public IList AdditionalInformation {
 | |
|             get {
 | |
|                 return additionalInformation;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.Documents"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public DiscoveryClientDocumentCollection Documents {
 | |
|             get {
 | |
|                 return documents;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.Errors"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public DiscoveryExceptionDictionary Errors {
 | |
|             get {
 | |
|                 return errors;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.References"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public DiscoveryClientReferenceCollection References {
 | |
|             get {
 | |
|                 return references;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.References"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         internal Hashtable InlinedSchemas
 | |
|         {
 | |
|             get 
 | |
|             {
 | |
|                 return inlinedSchemas;
 | |
|             }
 | |
|         }
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.Discover"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [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;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.DiscoverAny"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [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;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.Download"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
 | |
|         public Stream Download(ref string url) {
 | |
|             string contentType = null;
 | |
|             return Download(ref url, ref contentType);
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.Download1"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [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();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.LoadExternals"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// <internalonly/>
 | |
|         /// </devdoc>
 | |
|         [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;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.ReadAll"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [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;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.ResolveAll"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [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();
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.ResolveOneLevel"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [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(""+Path.DirectorySeparatorChar, StringComparison.Ordinal))
 | |
|                         answer = answer.Substring(1);
 | |
|                     return answer;
 | |
|                 }
 | |
|                 answer += ".." + Path.DirectorySeparatorChar;
 | |
|                 if (currentDir.Length < 2)
 | |
|                     break;
 | |
|                 else {
 | |
|                     int lastSlash = currentDir.LastIndexOf(Path.DirectorySeparatorChar, currentDir.Length - 2);
 | |
|                     currentDir = currentDir.Substring(0, lastSlash + 1);
 | |
|                 }
 | |
|             }
 | |
|             return fullPath;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.WriteAll"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [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();
 | |
|             /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientProtocol.DiscoveryClientResultsFile.Results"]/*' />
 | |
|             /// <devdoc>
 | |
|             ///    <para>[To be supplied.]</para>
 | |
|             /// </devdoc>
 | |
|             public DiscoveryClientResultCollection Results {
 | |
|                 get {
 | |
|                     return results;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
|     /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResultCollection"]/*' />
 | |
|     /// <devdoc>
 | |
|     ///    <para>[To be supplied.]</para>
 | |
|     /// </devdoc>
 | |
|     public sealed class DiscoveryClientResultCollection : CollectionBase {
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResultCollection.this"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public DiscoveryClientResult this[int i] {
 | |
|             get {
 | |
|                 return (DiscoveryClientResult) List[i];
 | |
|             }
 | |
|             set {
 | |
|                 List[i] = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResultCollection.Add"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public int Add(DiscoveryClientResult value) {
 | |
|             return List.Add(value);
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResultCollection.Contains"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public bool Contains(DiscoveryClientResult value) {
 | |
|             return List.Contains(value);
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResultCollection.Remove"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public void Remove(DiscoveryClientResult value) {
 | |
|             List.Remove(value);
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
|     /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResult"]/*' />
 | |
|     /// <devdoc>
 | |
|     ///    <para>[To be supplied.]</para>
 | |
|     /// </devdoc>
 | |
|     public sealed class DiscoveryClientResult {
 | |
|         string referenceTypeName;
 | |
|         string url;
 | |
|         string filename;
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResult.DiscoveryClientResult"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public DiscoveryClientResult() {
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResult.DiscoveryClientResult1"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         public DiscoveryClientResult(Type referenceType, string url, string filename) {
 | |
|             this.referenceTypeName = referenceType == null ? string.Empty : referenceType.FullName;
 | |
|             this.url = url;
 | |
|             this.filename = filename;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResult.ReferenceTypeName"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlAttribute("referenceType")]
 | |
|         public string ReferenceTypeName {
 | |
|             get {
 | |
|                 return referenceTypeName;
 | |
|             }
 | |
|             set {
 | |
|                 referenceTypeName = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResult.Url"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlAttribute("url")]
 | |
|         public string Url {
 | |
|             get {
 | |
|                 return url;
 | |
|             }
 | |
|             set {
 | |
|                 url = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\DiscoveryClientProtocol.uex' path='docs/doc[@for="DiscoveryClientResult.Filename"]/*' />
 | |
|         /// <devdoc>
 | |
|         ///    <para>[To be supplied.]</para>
 | |
|         /// </devdoc>
 | |
|         [XmlAttribute("filename")]
 | |
|         public string Filename {
 | |
|             get {
 | |
|                 return filename;
 | |
|             }
 | |
|             set {
 | |
|                 filename = value;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |