mirror of
https://github.com/ZuneDev/ZuneShell.dll.git
synced 2026-07-27 13:11:51 -07:00
538 lines
22 KiB
C#
538 lines
22 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: ZuneXml.XmlDataProviderQuery
|
|
// Assembly: ZuneShell, Version=4.7.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
|
|
// MVID: FC8028F3-A47B-4FB4-B35B-11D1752D8264
|
|
// Assembly location: C:\Program Files\Zune\ZuneShell.dll
|
|
|
|
using Microsoft.Iris;
|
|
using Microsoft.Zune.Configuration;
|
|
using Microsoft.Zune.PerfTrace;
|
|
using Microsoft.Zune.Service;
|
|
using Microsoft.Zune.Shell;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Xml;
|
|
|
|
namespace ZuneXml
|
|
{
|
|
public class XmlDataProviderQuery : DataProviderQuery
|
|
{
|
|
protected EPassportPolicyId _passportTicketType;
|
|
protected HttpRequestCachePolicy _cachePolicy;
|
|
private string _lastUri;
|
|
internal int _requestGeneration;
|
|
protected bool _keepAlive;
|
|
protected bool _ignoreNamespacePrefix;
|
|
protected bool _ignoreDuplicateGenerationRequests;
|
|
protected bool _acceptGZipEncoding;
|
|
private object _errorCode;
|
|
private bool _refreshOnCacheExpire;
|
|
private Microsoft.Iris.Timer _autoRefreshTimer;
|
|
|
|
protected XmlDataProviderQuery(object queryTypeCookie)
|
|
: base(queryTypeCookie)
|
|
{
|
|
this._passportTicketType = EPassportPolicyId.None;
|
|
this._cachePolicy = HttpRequestCachePolicy.Default;
|
|
this._keepAlive = true;
|
|
this._ignoreNamespacePrefix = true;
|
|
this._ignoreDuplicateGenerationRequests = true;
|
|
this.Result = XmlDataProviderObjectFactory.CreateObject(this, this.ResultTypeCookie);
|
|
}
|
|
|
|
protected override void OnDispose()
|
|
{
|
|
base.OnDispose();
|
|
if (this._autoRefreshTimer == null)
|
|
return;
|
|
this._autoRefreshTimer.Stop();
|
|
this._autoRefreshTimer.Dispose();
|
|
this._autoRefreshTimer = null;
|
|
}
|
|
|
|
public object ErrorCode => this._errorCode;
|
|
|
|
public HttpRequestCachePolicy CachePolicy
|
|
{
|
|
get => this._cachePolicy;
|
|
set => this._cachePolicy = value;
|
|
}
|
|
|
|
public EPassportPolicyId PassportTicketType
|
|
{
|
|
get => this._passportTicketType;
|
|
set => this._passportTicketType = value;
|
|
}
|
|
|
|
public bool IgnoreDuplicateGenerationRequests
|
|
{
|
|
get => this._ignoreDuplicateGenerationRequests;
|
|
set => this._ignoreDuplicateGenerationRequests = value;
|
|
}
|
|
|
|
public bool RefreshOnCacheExpire
|
|
{
|
|
get => this._refreshOnCacheExpire;
|
|
set => this._refreshOnCacheExpire = value;
|
|
}
|
|
|
|
protected override void BeginExecute()
|
|
{
|
|
if (this.GetProperty("SendPassportTicket") is bool passportProperty)
|
|
this._passportTicketType = passportProperty ? EPassportPolicyId.MBI : EPassportPolicyId.None;
|
|
if (this.GetProperty("SendSecurePassportTicket") is bool securePassportProperty)
|
|
this._passportTicketType = securePassportProperty ? EPassportPolicyId.MBI_SSL : EPassportPolicyId.None;
|
|
if (this.GetProperty("RefreshOnCacheExpire") is bool expireProperty)
|
|
this._refreshOnCacheExpire = expireProperty;
|
|
string resourceUri = this.GetResourceUri();
|
|
string postBody = this.GetPostBody();
|
|
if (string.IsNullOrEmpty(resourceUri))
|
|
return;
|
|
this.GetDataFromResource(resourceUri, postBody, true);
|
|
}
|
|
|
|
protected virtual string GetResourceUri() => (string)null;
|
|
|
|
protected virtual string GetPostBody() => (string)null;
|
|
|
|
internal virtual bool FilterDataProviderObject(XmlDataProviderObject dataObject) => false;
|
|
|
|
protected override void OnPropertyChanged(string propertyName)
|
|
{
|
|
if (propertyName == "LocalSortBy" && this.Result != null)
|
|
((XmlDataProviderObject)this.Result).ChangeListSort((string)this.GetProperty(propertyName));
|
|
base.OnPropertyChanged(propertyName);
|
|
}
|
|
|
|
internal void GetDataFromResource(string uri, string body, bool fNewGeneration)
|
|
{
|
|
GetDataFromResourceArgs fromResourceArgs = new GetDataFromResourceArgs(uri, body, fNewGeneration);
|
|
if (Application.IsApplicationThread)
|
|
this.GetDataFromResource(fromResourceArgs);
|
|
else
|
|
Application.DeferredInvoke(new DeferredInvokeHandler(this.GetDataFromResource), fromResourceArgs);
|
|
}
|
|
|
|
private void GetDataFromResource(object obj)
|
|
{
|
|
GetDataFromResourceArgs fromResourceArgs = (GetDataFromResourceArgs)obj;
|
|
string requestUri = fromResourceArgs.Uri;
|
|
string requestBody = fromResourceArgs.Body;
|
|
bool newGeneration = fromResourceArgs.NewGeneration;
|
|
string property1 = (string)this.GetProperty("LocalSortBy");
|
|
bool fPaged = this.GetProperty("Paged") is bool property2 && property2;
|
|
XmlDataProviderObject result = null;
|
|
if (newGeneration)
|
|
{
|
|
++this._requestGeneration;
|
|
result = XmlDataProviderObjectFactory.CreateObject(this, this.ResultTypeCookie);
|
|
if (property1 != null)
|
|
result.ChangeListSort(property1);
|
|
}
|
|
else
|
|
{
|
|
result = (XmlDataProviderObject)this.Result;
|
|
if (this._ignoreDuplicateGenerationRequests && string.Equals(requestUri, this._lastUri, StringComparison.CurrentCultureIgnoreCase))
|
|
return;
|
|
}
|
|
this._lastUri = requestUri;
|
|
this.SetWorkerStatus(this._requestGeneration, DataProviderQueryStatus.RequestingData);
|
|
bool flag = false;
|
|
string localUri = null;
|
|
if (!flag)
|
|
ThreadPool.QueueUserWorkItem(arg =>
|
|
{
|
|
int requestGeneration = (int)arg;
|
|
Microsoft.Zune.Service.HttpWebRequest httpWebRequest = this.ConstructWebRequest(requestUri, requestBody);
|
|
RequestArgs requestArgs = new RequestArgs(requestGeneration, requestUri, requestBody, localUri, result, fPaged, DateTime.Now, Environment.TickCount, httpWebRequest.CachePolicy);
|
|
httpWebRequest.GetResponseAsync(new AsyncRequestComplete(this.OnRequestComplete), requestArgs);
|
|
}, _requestGeneration);
|
|
PerfTrace.TraceUICollectionEvent(UICollectionEvent.DataProviderQueryBegin, this._lastUri);
|
|
}
|
|
|
|
private void OnRequestComplete(Microsoft.Zune.Service.HttpWebResponse response, object requestArgs)
|
|
{
|
|
RequestArgs requestArgs1 = (RequestArgs)requestArgs;
|
|
Stream xmlStream = null;
|
|
try
|
|
{
|
|
xmlStream = response.StatusCode == HttpStatusCode.OK ? response.GetResponseStream() : throw new HttpWebException(response);
|
|
this.ParseXml(xmlStream, requestArgs1.m_requestGeneration, requestArgs1.m_requestUri, requestArgs1.m_requestBody, requestArgs1.m_result, requestArgs1.m_fPaged, requestArgs1.m_tmStartTime, requestArgs1.m_tcStart);
|
|
if (requestArgs1.m_cachePolicy == HttpRequestCachePolicy.Refresh && this._cachePolicy == HttpRequestCachePolicy.Default && requestArgs1.m_result.NextPage != null)
|
|
UriResourceTracker.Instance.SetResourceModified(requestArgs1.m_result.NextPage.GetPageUrl(0), true);
|
|
this.SetAutoRefreshTimer(response.Expires);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (ex is HttpWebException)
|
|
{
|
|
object statusCode = ((HttpWebException)ex).Response.StatusCode;
|
|
this.SetWorkerStatus(requestArgs1.m_requestGeneration, DataProviderQueryStatus.Error, statusCode);
|
|
}
|
|
else
|
|
this.SetWorkerStatus(requestArgs1.m_requestGeneration, DataProviderQueryStatus.Error, null);
|
|
int num = TraceSwitches.DataProviderSwitch.TraceWarning ? 1 : 0;
|
|
}
|
|
finally
|
|
{
|
|
xmlStream?.Close();
|
|
response.Close();
|
|
PerfTrace.TraceUICollectionEvent(UICollectionEvent.DataProviderQueryComplete, this._lastUri);
|
|
}
|
|
}
|
|
|
|
private void ParseXml(
|
|
Stream xmlStream,
|
|
int requestGeneration,
|
|
string requestUri,
|
|
string requestBody,
|
|
XmlDataProviderObject result,
|
|
bool fPaged,
|
|
DateTime tmStartTime,
|
|
int tcStart)
|
|
{
|
|
int num1 = 0;
|
|
int num2 = 0;
|
|
bool flag1 = false;
|
|
XmlDataProviderReader xmlReader = null;
|
|
try
|
|
{
|
|
num1 = Environment.TickCount - tcStart;
|
|
this.SetWorkerStatus(requestGeneration, DataProviderQueryStatus.ProcessingData);
|
|
StringBuilder stringBuilder = new StringBuilder(80);
|
|
int[] numArray = new int[20];
|
|
xmlReader = new XmlDataProviderReader(xmlStream);
|
|
List<XPathMatch> xpathMatchList = new List<XPathMatch>(2);
|
|
bool flag2 = false;
|
|
int num3 = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0;
|
|
XmlNodeType xmlNodeType = XmlNodeType.None;
|
|
while (xmlNodeType != XmlNodeType.None || xmlReader.Read())
|
|
{
|
|
xmlNodeType = XmlNodeType.None;
|
|
if (requestGeneration != this._requestGeneration)
|
|
{
|
|
flag2 = true;
|
|
break;
|
|
}
|
|
if (xmlReader.NodeType == XmlNodeType.Element && xmlReader.Depth < numArray.Length)
|
|
{
|
|
int depth = xmlReader.Depth;
|
|
stringBuilder.Length = depth > 0 ? numArray[depth - 1] : 0;
|
|
stringBuilder.Append('/');
|
|
if (this._ignoreNamespacePrefix)
|
|
stringBuilder.Append(xmlReader.LocalName);
|
|
else
|
|
stringBuilder.Append(xmlReader.Name);
|
|
numArray[depth] = stringBuilder.Length;
|
|
string str = stringBuilder.ToString();
|
|
if (fPaged)
|
|
{
|
|
IPageInfo nextPageInfo = this.ExtractNextPageInfo(requestUri, requestBody, str, xmlReader);
|
|
if (nextPageInfo != null)
|
|
result.NextPage = nextPageInfo;
|
|
}
|
|
Hashtable attributes = new Hashtable(3);
|
|
if (xmlReader.MoveToFirstAttribute())
|
|
{
|
|
do
|
|
{
|
|
attributes[xmlReader.Name] = xmlReader.Value;
|
|
}
|
|
while (xmlReader.MoveToNextAttribute());
|
|
}
|
|
result.ProcessXPath(str, attributes, xpathMatchList);
|
|
if (xpathMatchList.Count > 0)
|
|
{
|
|
flag1 = true;
|
|
string xmlValue = null;
|
|
if (xmlReader.Read() && (xmlNodeType = xmlReader.NodeType) == XmlNodeType.Text)
|
|
{
|
|
xmlNodeType = XmlNodeType.None;
|
|
xmlValue = xmlReader.Value;
|
|
}
|
|
ProcessXPathMatches(xpathMatchList, attributes, xmlValue, xmlReader);
|
|
}
|
|
foreach (string key in attributes.Keys)
|
|
{
|
|
result.ProcessXPath(str + "@" + key, attributes, xpathMatchList);
|
|
if (xpathMatchList.Count > 0)
|
|
{
|
|
flag1 = true;
|
|
ProcessXPathMatches(xpathMatchList, attributes, null, null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!flag2)
|
|
{
|
|
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetResult), new DeferredSetResultArgs(requestGeneration, result));
|
|
this.SetWorkerStatus(requestGeneration, DataProviderQueryStatus.Complete);
|
|
if (TraceSwitches.DataProviderSwitch.TraceWarning)
|
|
{
|
|
num2 = Environment.TickCount - tcStart;
|
|
int num4 = flag1 ? 1 : 0;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetResult), new DeferredSetResultArgs(requestGeneration, result));
|
|
this.SetWorkerStatus(requestGeneration, DataProviderQueryStatus.Error);
|
|
throw ex;
|
|
}
|
|
finally
|
|
{
|
|
xmlReader?.Close();
|
|
}
|
|
int num5 = TraceSwitches.DataProviderSwitch.TraceVerbose ? 1 : 0;
|
|
}
|
|
|
|
internal virtual IPageInfo ExtractNextPageInfo(
|
|
string requestUri,
|
|
string requestBody,
|
|
string strElementPath,
|
|
XmlDataProviderReader xmlReader)
|
|
{
|
|
if (strElementPath == "/feed/link")
|
|
{
|
|
bool flag = false;
|
|
if (xmlReader.MoveToFirstAttribute())
|
|
{
|
|
do
|
|
{
|
|
if (xmlReader.Name == "rel")
|
|
flag = xmlReader.Value == "next";
|
|
else if (xmlReader.Name == "href" && flag && !string.IsNullOrEmpty(xmlReader.Value))
|
|
return new LinkPageInfo(ConstructLinkUrl(requestUri, xmlReader.Value), requestBody);
|
|
}
|
|
while (xmlReader.MoveToNextAttribute());
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private Microsoft.Zune.Service.HttpWebRequest ConstructWebRequest(
|
|
string requestUri,
|
|
string requestBody)
|
|
{
|
|
return requestBody != null ? WebRequestHelper.ConstructWebPostRequest(requestUri, requestBody, this._passportTicketType, this._cachePolicy, this._keepAlive, this._acceptGZipEncoding) : WebRequestHelper.ConstructWebRequest(requestUri, this._passportTicketType, this._cachePolicy, this._keepAlive, this._acceptGZipEncoding);
|
|
}
|
|
|
|
private static string ConstructLinkUrl(string baseUrl, string relativeUrl)
|
|
{
|
|
string str = null;
|
|
if (relativeUrl.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
str = relativeUrl;
|
|
}
|
|
else
|
|
{
|
|
int num = baseUrl.IndexOf("//");
|
|
if (num > 0)
|
|
{
|
|
int length = baseUrl.IndexOf('/', num + 2);
|
|
if (length > 0)
|
|
str = baseUrl.Substring(0, length) + relativeUrl;
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
private static void ProcessXPathMatches(
|
|
List<XPathMatch> xpathMatches,
|
|
Hashtable attributes,
|
|
string xmlValue,
|
|
XmlDataProviderReader xmlReader)
|
|
{
|
|
foreach (XPathMatch xpathMatch in xpathMatches)
|
|
{
|
|
string str = xmlValue;
|
|
if (xpathMatch.matchingAttributeName != null)
|
|
str = (string)attributes[xpathMatch.matchingAttributeName];
|
|
if (xpathMatch.encodedXml && str != null && xmlReader != null)
|
|
xmlReader.PushElement(str);
|
|
else if (str != null)
|
|
xpathMatch.instance.SetPropertyFromStringValue(xpathMatch.propertyMapping, str);
|
|
}
|
|
xpathMatches.Clear();
|
|
}
|
|
|
|
protected void SetWorkerStatus(int requestGeneration, DataProviderQueryStatus eStatus) => this.SetWorkerStatus(requestGeneration, eStatus, null);
|
|
|
|
protected void SetWorkerStatus(
|
|
int requestGeneration,
|
|
DataProviderQueryStatus eStatus,
|
|
object errorCode)
|
|
{
|
|
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetStatus), new DeferredSetStatusArgs(requestGeneration, eStatus, errorCode));
|
|
}
|
|
|
|
private void DeferredSetStatus(object args)
|
|
{
|
|
if (!(args is DeferredSetStatusArgs deferredSetStatusArgs) || deferredSetStatusArgs.m_requestGeneration != this._requestGeneration)
|
|
return;
|
|
this.Status = deferredSetStatusArgs.m_eStatus;
|
|
this._errorCode = this.Status != DataProviderQueryStatus.Error ? null : deferredSetStatusArgs.m_errorCode;
|
|
if (this.Status == DataProviderQueryStatus.Error)
|
|
this._lastUri = null;
|
|
if (this.Result == null || this.Status != DataProviderQueryStatus.Complete)
|
|
return;
|
|
((XmlDataProviderObject)this.Result).OnQueryComplete();
|
|
}
|
|
|
|
private void SetAutoRefreshTimer(DateTime expires)
|
|
{
|
|
if (!this._refreshOnCacheExpire)
|
|
return;
|
|
Application.DeferredInvoke(new DeferredInvokeHandler(this.DeferredSetAutoRefreshTimer), expires);
|
|
}
|
|
|
|
private void DeferredSetAutoRefreshTimer(object args)
|
|
{
|
|
DateTime utcNow = DateTime.UtcNow;
|
|
DateTime dateTime = (DateTime)args;
|
|
if (dateTime == DateTime.MaxValue || dateTime <= utcNow)
|
|
{
|
|
int refreshQueryFallback = ClientConfiguration.Service.AutoRefreshQueryFallback;
|
|
dateTime = utcNow.AddMilliseconds(refreshQueryFallback);
|
|
}
|
|
if (!(dateTime != DateTime.MaxValue))
|
|
return;
|
|
if (this._autoRefreshTimer == null)
|
|
{
|
|
this._autoRefreshTimer = new Microsoft.Iris.Timer();
|
|
this._autoRefreshTimer.Tick += (sender, eventArgs) =>
|
|
{
|
|
this._autoRefreshTimer.Stop();
|
|
this.Refresh();
|
|
};
|
|
}
|
|
int num1 = new Random().Next(1, 300000);
|
|
if (dateTime > utcNow)
|
|
{
|
|
long num2 = dateTime.Subtract(utcNow).Ticks / 10000L;
|
|
if (num2 > int.MaxValue - num1)
|
|
num1 += 900000;
|
|
else
|
|
num1 += (int)num2;
|
|
}
|
|
this._autoRefreshTimer.Stop();
|
|
this._autoRefreshTimer.Interval = num1;
|
|
this._autoRefreshTimer.Start();
|
|
}
|
|
|
|
private void DeferredSetResult(object argsObj)
|
|
{
|
|
if (!(argsObj is DeferredSetResultArgs deferredSetResultArgs) || deferredSetResultArgs.m_requestGeneration != this._requestGeneration)
|
|
return;
|
|
deferredSetResultArgs.m_result.TransferToAppThread();
|
|
if (this.Result == deferredSetResultArgs.m_result)
|
|
return;
|
|
this.Result = deferredSetResultArgs.m_result;
|
|
}
|
|
|
|
private class GetDataFromResourceArgs
|
|
{
|
|
public readonly string Uri;
|
|
public readonly string Body;
|
|
public readonly bool NewGeneration;
|
|
|
|
public GetDataFromResourceArgs(string uri, string body, bool fNewGeneration)
|
|
{
|
|
this.Uri = uri;
|
|
this.Body = body;
|
|
this.NewGeneration = fNewGeneration;
|
|
}
|
|
}
|
|
|
|
private class RequestArgs
|
|
{
|
|
public readonly int m_requestGeneration;
|
|
public readonly string m_requestUri;
|
|
public readonly string m_requestBody;
|
|
public readonly string m_localUri;
|
|
public readonly XmlDataProviderObject m_result;
|
|
public readonly bool m_fPaged;
|
|
public readonly DateTime m_tmStartTime;
|
|
public readonly int m_tcStart;
|
|
public readonly HttpRequestCachePolicy m_cachePolicy;
|
|
|
|
public RequestArgs(
|
|
int requestGeneration,
|
|
string requestUri,
|
|
string requestBody,
|
|
string localUri,
|
|
XmlDataProviderObject result,
|
|
bool fPaged,
|
|
DateTime tmStartTime,
|
|
int tcStart,
|
|
HttpRequestCachePolicy cachePolicy)
|
|
{
|
|
this.m_requestGeneration = requestGeneration;
|
|
this.m_requestUri = requestUri;
|
|
this.m_requestBody = requestBody;
|
|
this.m_localUri = localUri;
|
|
this.m_result = result;
|
|
this.m_fPaged = fPaged;
|
|
this.m_tmStartTime = tmStartTime;
|
|
this.m_tcStart = tcStart;
|
|
this.m_cachePolicy = cachePolicy;
|
|
}
|
|
}
|
|
|
|
private class DeferredSetStatusArgs
|
|
{
|
|
public readonly DataProviderQueryStatus m_eStatus;
|
|
public readonly int m_requestGeneration;
|
|
public readonly object m_errorCode;
|
|
|
|
public DeferredSetStatusArgs(
|
|
int requestGeneration,
|
|
DataProviderQueryStatus eStatus,
|
|
object errorCode)
|
|
{
|
|
this.m_eStatus = eStatus;
|
|
this.m_requestGeneration = requestGeneration;
|
|
this.m_errorCode = errorCode;
|
|
}
|
|
}
|
|
|
|
private class DeferredSetResultArgs
|
|
{
|
|
public readonly XmlDataProviderObject m_result;
|
|
public readonly int m_requestGeneration;
|
|
|
|
public DeferredSetResultArgs(int requestGeneration, XmlDataProviderObject result)
|
|
{
|
|
this.m_requestGeneration = requestGeneration;
|
|
this.m_result = result;
|
|
}
|
|
}
|
|
|
|
public struct XPathMatch
|
|
{
|
|
public XmlDataProviderObject instance;
|
|
public DataProviderMapping propertyMapping;
|
|
public string matchingAttributeName;
|
|
public bool encodedXml;
|
|
|
|
public XPathMatch(
|
|
XmlDataProviderObject instance,
|
|
DataProviderMapping propertyMapping,
|
|
string matchingAttributeName,
|
|
bool encodedXml)
|
|
{
|
|
this.instance = instance;
|
|
this.propertyMapping = propertyMapping;
|
|
this.matchingAttributeName = matchingAttributeName;
|
|
this.encodedXml = encodedXml;
|
|
}
|
|
}
|
|
}
|
|
}
|