Files

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;
}
}
}
}