diff options
Diffstat (limited to 'Xamarin.Forms.Pages.Azure/AzureDataSource.cs')
-rw-r--r-- | Xamarin.Forms.Pages.Azure/AzureDataSource.cs | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/Xamarin.Forms.Pages.Azure/AzureDataSource.cs b/Xamarin.Forms.Pages.Azure/AzureDataSource.cs new file mode 100644 index 00000000..907421cb --- /dev/null +++ b/Xamarin.Forms.Pages.Azure/AzureDataSource.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; + +namespace Xamarin.Forms.Pages.Azure +{ + public class AzureDataSource : BaseDataSource + { + readonly ObservableCollection<IDataItem> _dataItems = new ObservableCollection<IDataItem>(); + Task _currentParseTask; + bool _initialized; + AzureSource _source; + + public AzureDataSource() + { + } + + internal AzureDataSource(JToken rootToken) + { + ParseJsonToken(rootToken); + } + + public AzureSource Source + { + get + { + return _source; + } + set + { + if (_source == value) + return; + _source = value; + + _dataItems.Clear(); + if (value != null && _initialized) + { + _currentParseTask = ParseJson(); + _currentParseTask.ContinueWith(t => { throw t.Exception; }, TaskContinuationOptions.OnlyOnFaulted); + } + } + } + + protected override async Task<IList<IDataItem>> GetRawData() + { + if (!_initialized) + { + Task task = _currentParseTask = ParseJson(); + await task; + } + else if (_currentParseTask != null && _currentParseTask.IsCompleted == false) + await _currentParseTask; + return _dataItems; + } + + protected override object GetValue(string key) + { + IDataItem target = _dataItems.FirstOrDefault(d => d.Name == key); + return target?.Value; + } + + protected override bool SetValue(string key, object value) + { + IDataItem target = _dataItems.FirstOrDefault(d => d.Name == key); + if (target == null) + { + _dataItems.Add(new DataItem(key, value)); + return true; + } + if (target.Value == value) + return false; + target.Value = value; + return true; + } + + object GetValueForJToken(JToken token) + { + switch (token.Type) + { + case JTokenType.Object: + case JTokenType.Array: + return new AzureDataSource(token); + case JTokenType.Constructor: + case JTokenType.Property: + case JTokenType.Comment: + throw new NotImplementedException(); + case JTokenType.Integer: + return (int)token; + case JTokenType.Float: + return (float)token; + case JTokenType.Raw: + case JTokenType.String: + return (string)token; + case JTokenType.Boolean: + return (bool)token; + case JTokenType.Date: + return (DateTime)token; + case JTokenType.Bytes: + return (byte[])token; + case JTokenType.Guid: + return (Guid)token; + case JTokenType.Uri: + return (Uri)token; + case JTokenType.TimeSpan: + return (TimeSpan)token; + default: + return null; + } + } + + async Task ParseJson() + { + _initialized = true; + + if (Source == null) + return; + + IsLoading = true; + var jtoken = await Source.GetJson(); + ParseJsonToken(jtoken); + IsLoading = false; + } + + void ParseJsonToken(JToken token) + { + var jArray = token as JArray; + var jObject = token as JObject; + if (jArray != null) + { + for (var i = 0; i < jArray.Count; i++) + { + JToken obj = jArray[i]; + _dataItems.Add(new DataItem(i.ToString(), GetValueForJToken(obj))); + } + } + else if (jObject != null) + { + foreach (KeyValuePair<string, JToken> kvp in jObject) + { + _dataItems.Add(new DataItem(kvp.Key, GetValueForJToken(kvp.Value))); + } + } + } + } +} |