177 lines
6.5 KiB
C#
177 lines
6.5 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="DiscoveryReference.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
namespace System.Web.Services.Discovery {
|
||
|
|
||
|
using System;
|
||
|
using System.Xml.Serialization;
|
||
|
using System.Text.RegularExpressions;
|
||
|
using System.IO;
|
||
|
using System.Text;
|
||
|
using System.Threading;
|
||
|
using System.Collections;
|
||
|
using System.Diagnostics;
|
||
|
using System.Web.Services.Diagnostics;
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
public abstract class DiscoveryReference {
|
||
|
|
||
|
private DiscoveryClientProtocol clientProtocol;
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.ClientProtocol"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
[XmlIgnore]
|
||
|
public DiscoveryClientProtocol ClientProtocol {
|
||
|
get { return clientProtocol; }
|
||
|
set { clientProtocol = value; }
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.DefaultFilename"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
[XmlIgnore]
|
||
|
public virtual string DefaultFilename {
|
||
|
get {
|
||
|
return FilenameFromUrl(Url);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.WriteDocument"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
public abstract void WriteDocument(object document, Stream stream);
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.ReadDocument"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
public abstract object ReadDocument(Stream stream);
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.Url"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
[XmlIgnore]
|
||
|
public abstract string Url {
|
||
|
get;
|
||
|
set;
|
||
|
}
|
||
|
|
||
|
internal virtual void LoadExternals(Hashtable loadedExternals) {
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.FilenameFromUrl"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
public static string FilenameFromUrl(string url) {
|
||
|
// get everything after the last /, not including the one at the end of the string
|
||
|
int lastSlash = url.LastIndexOf('/', url.Length - 1);
|
||
|
if (lastSlash >= 0) url = url.Substring(lastSlash + 1);
|
||
|
|
||
|
// get everything up to the first dot (the filename)
|
||
|
int firstDot = url.IndexOf('.');
|
||
|
if (firstDot >= 0) url = url.Substring(0, firstDot);
|
||
|
|
||
|
// make sure we don't include the question mark and stuff that follows it
|
||
|
int question = url.IndexOf('?');
|
||
|
if (question >= 0) url = url.Substring(0, question);
|
||
|
if (url == null || url.Length == 0)
|
||
|
return "item";
|
||
|
return MakeValidFilename(url);
|
||
|
}
|
||
|
|
||
|
private static bool FindChar(char ch, char[] chars) {
|
||
|
for (int i = 0; i < chars.Length; i++) {
|
||
|
if (ch == chars[i])
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
internal static string MakeValidFilename(string filename) {
|
||
|
if (filename == null)
|
||
|
return null;
|
||
|
|
||
|
StringBuilder sb = new StringBuilder(filename.Length);
|
||
|
for (int i = 0; i < filename.Length; i++) {
|
||
|
char c = filename[i];
|
||
|
if (!FindChar(c, Path.InvalidPathChars))
|
||
|
sb.Append(c);
|
||
|
}
|
||
|
string name = sb.ToString();
|
||
|
if (name.Length == 0)
|
||
|
name = "item";
|
||
|
|
||
|
return Path.GetFileName(name);
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.Resolve"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
public void Resolve() {
|
||
|
if (ClientProtocol == null)
|
||
|
throw new InvalidOperationException(Res.GetString(Res.WebResolveMissingClientProtocol));
|
||
|
|
||
|
if (ClientProtocol.Documents[Url] != null)
|
||
|
return;
|
||
|
if (ClientProtocol.InlinedSchemas[Url] != null)
|
||
|
return;
|
||
|
|
||
|
string newUrl = Url;
|
||
|
string oldUrl = Url;
|
||
|
string contentType = null;
|
||
|
Stream stream = ClientProtocol.Download(ref newUrl, ref contentType);
|
||
|
if (ClientProtocol.Documents[newUrl] != null) {
|
||
|
Url = newUrl;
|
||
|
return;
|
||
|
}
|
||
|
try {
|
||
|
Url = newUrl;
|
||
|
Resolve(contentType, stream);
|
||
|
}
|
||
|
catch {
|
||
|
Url = oldUrl;
|
||
|
throw;
|
||
|
}
|
||
|
finally {
|
||
|
stream.Close();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal Exception AttemptResolve(string contentType, Stream stream) {
|
||
|
try {
|
||
|
Resolve(contentType, stream);
|
||
|
return null;
|
||
|
}
|
||
|
catch (Exception e) {
|
||
|
if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException) {
|
||
|
throw;
|
||
|
}
|
||
|
if (Tracing.On) Tracing.ExceptionCatch(TraceEventType.Warning, this, "AttemptResolve", e);
|
||
|
return e;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <include file='doc\DiscoveryReference.uex' path='docs/doc[@for="DiscoveryReference.Resolve1"]/*' />
|
||
|
/// <devdoc>
|
||
|
/// <para>[To be supplied.]</para>
|
||
|
/// </devdoc>
|
||
|
protected internal abstract void Resolve(string contentType, Stream stream);
|
||
|
|
||
|
internal static string UriToString(string baseUrl, string relUrl) {
|
||
|
return (new Uri(new Uri(baseUrl), relUrl)).GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
|
||
|
}
|
||
|
}
|
||
|
}
|