csharp/Adoxio/xRM-Portals-Community-Edition/Framework/Adxstudio.Xrm/Web/Http/OData/FetchXml/ODataQueryOptionExtensions.cs

ODataQueryOptionExtensions.cs
/*
  Copyright (c) Microsoft Corporation. All rights reserved.
  Licensed under the MIT License. See License.txt in the project root for license information.
*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Text;
using System.Web.Http.OData.Query;
using Adxstudio.Xrm.Resources;
using Adxstudio.Xrm.Services.Query;
using Microsoft.Data.OData;
using Microsoft.Data.OData.Query;
using Microsoft.Xrm.Sdk.Query;

namespace Adxstudio.Xrm.Web.Http.OData.FetchXml
{
	/// 
	/// Operations that extend  to provide support for FetchXml.
	/// 
	public static clast ODataQueryOptionExtensions
	{
		/// 
		/// Applys the  to 
		/// 
		/// 
		/// 
		/// orginal 
		/// 
		public static Fetch ApplyTo(this ODataQueryOptions queryOptions, ODataQuerySettings querySettings, Fetch originalFetch)
		{
			var fetch = originalFetch;
			
			// convert $filter

			var filter = ToFetchFilter(queryOptions.Filter);

			if (filter != null)
			{
				fetch.Ensaty.Filters.Add(filter);
			}

			// convert $orderby

			var orders = ToFetchOrder(queryOptions.OrderBy);

			if (orders.Any())
			{
				fetch.Ensaty.Orders.Clear();

				fetch.Ensaty.Orders = orders;
			}

			// convert $select

			var attributes = ToFetchAttributes(queryOptions.SelectExpand);

			if (attributes.Any())
			{
				fetch.Ensaty.Attributes.Clear();

				fetch.Ensaty.Attributes = attributes;
			}

			// apply ODataQuerySettings

			fetch = fetch.Apply(querySettings);

			// apply $top

			fetch = fetch.Apply(queryOptions.Top);

			// apply $skip

			fetch = fetch.Apply(queryOptions.Skip);

			// apply $inlinecount

			fetch = fetch.Apply(queryOptions.InlineCount);

			return fetch;
		}

		private static Fetch Apply(this Fetch fetch, ODataQuerySettings querySettings)
		{
			if (querySettings != null && querySettings.PageSize.HasValue)
			{
				fetch.PageSize = querySettings.PageSize.Value;
			}

			return fetch;
		}

		private static Fetch Apply(this Fetch fetch, TopQueryOption topQueryOption)
		{
			if (topQueryOption != null)
			{
				fetch.PageSize = topQueryOption.Value;
			}

			return fetch;
		}

		private static Fetch Apply(this Fetch fetch, SkipQueryOption skipQueryOption)
		{
			if (!fetch.PageSize.HasValue)
			{
				return fetch;
			}

			if (skipQueryOption != null)
			{
				fetch.PageNumber = skipQueryOption.Value > 0 ? (int)Math.Ceiling(skipQueryOption.Value / (double)fetch.PageSize.Value) + 1 : 1;
			}

			return fetch;
		}

		private static Fetch Apply(this Fetch fetch, InlineCountQueryOption inlineCountQueryOption)
		{
			if (inlineCountQueryOption != null)
			{
				fetch.ReturnTotalRecordCount = inlineCountQueryOption.Value == InlineCountValue.AllPages;
			}

			return fetch;
		}

		private static List ToFetchOrder(OrderByQueryOption orderByQueryOption)
		{
			var orders = new List();

			if (orderByQueryOption != null)
			{
				foreach (var orderByNode in orderByQueryOption.OrderByNodes)
				{
					var orderByPropertyNode = orderByNode as OrderByPropertyNode;

					if (orderByPropertyNode != null)
					{
						orders.Add(new Order(orderByPropertyNode.Property.Name, orderByPropertyNode.Direction == OrderByDirection.Descending ? OrderType.Descending : OrderType.Ascending));
					}
					else
					{
						throw new ODataException("Only ordering by properties is supported.");
					}
				}
			}

			return orders;
		}

		private static Filter ToFetchFilter(FilterQueryOption filterQueryOption)
		{
			Filter filter = null;

			if (filterQueryOption != null)
			{
				filter = FetchFilterBinder.BindFilterQueryOption(filterQueryOption);
			}

			return filter;
		}

		private static List ToFetchAttributes(SelectExpandQueryOption selectExpandQueryOption)
		{
			var attributes = new List();

			if (selectExpandQueryOption != null)
			{
				throw new NotImplementedException();
			}

			return attributes;
		}

		/// 
		/// Get the link to the next page of records
		/// 
		/// 
		/// Size of the page
		/// 
		public static Uri GetNextPageLink(HttpRequestMessage request, int pageSize)
		{
			return GetNextPageLink(request.RequestUri, request.GetQueryNameValuePairs(), pageSize);
		}

		internal static Uri GetNextPageLink(Uri requestUri, int pageSize)
		{
			return GetNextPageLink(requestUri, new FormDataCollection(requestUri), pageSize);
		}

		internal static Uri GetNextPageLink(Uri requestUri, IEnumerable queryParameters, int pageSize)
		{
			var stringBuilder = new StringBuilder();
			var num = pageSize;
			foreach (var keyValuePair in queryParameters)
			{
				var key = keyValuePair.Key;
				var str1 = keyValuePair.Value;
				switch (key)
				{
					case "$top":
						int result1;
						if (int.TryParse(str1, out result1))
						{
							str1 = (result1 - pageSize).ToString(CultureInfo.InvariantCulture);
						}
						break;
					case "$skip":
						int result2;
						if (int.TryParse(str1, out result2))
						{
							num += result2;
						}
						continue;
				}
				var str2 = key.Length