/// <summary> /// Gets MetadataItem object for URI relative path under the specified EntityContainer instance /// </summary> /// <param name="container">The EntityContainer instance</param> /// <param name="pathSegment">The URI relative path</param> /// <param name="uriType">Output parameter of UriType value</param> /// <returns>The MetadataItem instance if one is found; null otherwise</returns> private static MetadataItem GetTargetType(EntityContainer container, IEnumerable <string> pathSegment, ref UriType uriType) { ODataUriItem curr = new ODataUriItem(container, UriType.URI_Container); foreach (var segment in pathSegment) { // to normalize first segment string segmentKey; string segmentCore = ResourcePathHelper.ParseSegment(segment, out segmentKey); ODataUriItem subItem = curr.GetItem(segmentCore); if (subItem == null) { uriType = UriType.URIUNKNOWN; return(null); } if (subItem.uriType == UriType.URI1 && !string.IsNullOrEmpty(segmentKey)) { subItem = new ODataUriItem(((EntitySet)subItem.Item).ElementType, UriType.URI2); } curr = subItem; } uriType = curr.uriType; return(curr.Item); }
/// <summary> /// Gets the short name of the entity for the context /// </summary> /// <param name="context">The context object which directly or indirectly points to an entry</param> /// <returns>The short name of entity</returns> public static string GetEntityName(ServiceContext context) { string entityName = context.EntityTypeShortName; if (string.IsNullOrEmpty(entityName)) { var edmxHelper = new EdmxHelper(XElement.Parse(context.MetadataDocument)); var segments = ResourcePathHelper.GetPathSegments(context); var segsToEntity = GetEntryUriSegments(segments.Take(segments.Count() - 1), edmxHelper); UriType uriType; var target = edmxHelper.GetTargetType(segsToEntity, out uriType); entityName = ((EntityType)target).Name; } return(entityName); }
/// <summary> /// Checks whether the entity type definition has any property mapping /// </summary> /// <param name="meta">The metadata document</param> /// <param name="entityType">The entity type</param> /// <returns>flag of proerty being mapped</returns> public static bool HasPropertyMapping(XElement meta, string entityType) { if (meta == null) { throw new ArgumentNullException("meta"); } if (string.IsNullOrEmpty(entityType)) { throw new ArgumentException("parameter should not be null or empty", "entityType"); } const string tmplXPath2EntityType = @"//*[local-name()='EntityType' and @Name = '{0}']"; const string xPath2Property = @"./*[local-name()='Property' and @m:FC_KeepInContent='false']"; string typeShortName = ResourcePathHelper.GetBaseName(entityType); string xPath2EntityType = string.Format(tmplXPath2EntityType, typeShortName); var nodeEntityType = meta.XPathSelectElement(xPath2EntityType, ODataNamespaceManager.Instance); var nodeProperty = nodeEntityType.XPathSelectElement(xPath2Property, ODataNamespaceManager.Instance); if (nodeProperty != null) { return(true); } else { string baseType = nodeEntityType.GetAttributeValue("BaseType"); if (baseType == null) { return(false); } else { return(HasPropertyMapping(meta, baseType)); } } }
/// <summary> /// Gets segments of URI relative path from ServiceContext instance /// </summary> /// <param name="context">The ServiceContext instance</param> /// <returns>The segments of relative path</returns> public static IEnumerable <string> GetPathSegments(ServiceContext context) { var path = context.DestinationBasePath.Substring(context.ServiceBaseUri.AbsoluteUri.Length); return(ResourcePathHelper.GetPathSegments(path)); }
/// <summary> /// Builds the uri for purpose of probing any remaining entries satisfying the request of service context /// use the last entry's token in the feed as the marker of skiptoken; /// and reduce the $top count if top was in context request URI. /// </summary> /// <param name="context">The service context object</param> /// <returns>Uri object if a meaningful prober can be constructed; null otherwise </returns> private static Uri ConstructProbeUri(ServiceContext context) { Uri result = null; JObject response = JsonParserHelper.GetResponseObject(context); if (response != null) { JArray entries = JsonParserHelper.GetEntries(response); if (entries != null) { JObject lastEntry = JsonParserHelper.GetLastEntry(entries); if (lastEntry != null) { string lastToken = JsonParserHelper.GetTokenOfEntry(lastEntry); string lastTokenOfValues = ResourcePathHelper.GetValuesOfKey(lastToken); var uri = context.Destination; ResourcePathHelper pathHelper = new ResourcePathHelper(uri); // replace top value with the reduced value, if $top was in context request string topValue = pathHelper.GetQueryValue("$top"); if (!string.IsNullOrEmpty(topValue)) { pathHelper.RemoveQueryOption("$top"); int entriesGot = entries.Count; int entriesToGet; if (Int32.TryParse(topValue, out entriesToGet) && entriesToGet > entriesGot) { int entriesLeft = entriesToGet - entriesGot; pathHelper.AddQueryOption("$top", entriesLeft.ToString(CultureInfo.InvariantCulture)); } } // set up new skiptoken query pathHelper.RemoveQueryOption("$skiptoken"); pathHelper.AddQueryOption("$skiptoken", lastTokenOfValues); result = new Uri(pathHelper.Product); } } } return result; }
/// <summary> /// Builds the uri for purpose of probing the empty feed based on the base uri string. /// </summary> /// <param name="context">The service context object</param> /// <returns>Uri object if a meaningful prober can be constructed; null otherwise </returns> private static Uri ConstructProbeUri(ServiceContext context) { int safetyTopping = 20; Uri result = null; // find out how many entries in the base feed Uri uriFeedCount = new Uri(context.DestinationBasePath + "/$count"); var resp = WebHelper.Get(uriFeedCount, Constants.AcceptHeaderAtom, RuleEngineSetting.Instance().DefaultMaximumPayloadSize, context.RequestHeaders); if (resp.StatusCode.HasValue && resp.StatusCode.Value == System.Net.HttpStatusCode.OK && !string.IsNullOrEmpty(resp.ResponsePayload)) { string payload = resp.ResponsePayload.Trim(); int count = 0; if (Int32.TryParse(payload, out count) && count >= 0) { int countToSkip = count + safetyTopping; Uri uriBaseFeed = new Uri(context.DestinationBasePath); ResourcePathHelper pathHelper = new ResourcePathHelper(uriBaseFeed); pathHelper.AddQueryOption("$skip", countToSkip.ToString(CultureInfo.InvariantCulture)); result = new Uri(pathHelper.Product); } } return result; }