/// <summary> /// Translates an ODL path to Web API path. /// </summary> /// <param name="path">The ODL path to be translated.</param> /// <param name="model">The model used to translate.</param> /// <param name="unresolvedPathSegment">Unresolved path segment.</param> /// <param name="id">The key segment from $id.</param> /// <param name="enableUriTemplateParsing">Specifies the ODL path is template or not.</param> /// <param name="parameterAliasNodes">The parameter alias nodes info.</param> /// <param name="queryString">The query string.</param> /// <returns>The translated Web API path.</returns> public static ODataPath TranslateODLPathToWebAPIPath( Semantic.ODataPath path, IEdmModel model, UnresolvedPathSegment unresolvedPathSegment, KeySegment id, bool enableUriTemplateParsing, IDictionary <string, SingleValueNode> parameterAliasNodes, NameValueCollection queryString) { if (path == null) { throw Error.ArgumentNull("path"); } if (model == null) { throw Error.ArgumentNull("model"); } if (parameterAliasNodes == null) { throw Error.ArgumentNull("parameterAliasNodes"); } IList <ODataPathSegment> segments = path.WalkWith( new ODataPathSegmentTranslator(model, enableUriTemplateParsing, parameterAliasNodes, queryString)) .SelectMany(s => s).ToList(); if (unresolvedPathSegment != null) { segments.Add(unresolvedPathSegment); } if (!enableUriTemplateParsing) { AppendIdForRef(segments, id); } ReverseRefPathSegmentAndKeyValuePathSegment(segments); ODataPath odataPath = new ODataPath(segments); odataPath.ODLPath = path; return(odataPath); }
private static Uri GenerateContainmentODataPathSegments(EntityInstanceContext entityContext, bool isEntityId) { Contract.Assert(entityContext != null); Contract.Assert( entityContext.NavigationSource.NavigationSourceKind() == EdmNavigationSourceKind.ContainedEntitySet); Contract.Assert(entityContext.Request != null); ODataPath path = entityContext.Request.ODataProperties().Path; if (path == null) { throw Error.InvalidOperation(SRResources.ODataPathMissing); } ODL.ODataPath odlPath = path.ODLPath; odlPath = new ContainmentPathBuilder().TryComputeCanonicalContainingPath(odlPath); path = ODataPathSegmentTranslator.TranslateODLPathToWebAPIPath( odlPath, entityContext.EdmModel, unresolvedPathSegment: null, id: null, enableUriTemplateParsing: false, parameterAliasNodes: new Dictionary <string, ODL.SingleValueNode>(), queryString: new NameValueCollection()); List <ODataPathSegment> odataPath = path.Segments.ToList(); odataPath.Add(new EntitySetPathSegment((IEdmEntitySetBase)entityContext.NavigationSource)); odataPath.Add(new KeyValuePathSegment(ConventionsHelpers.GetEntityKeyValue(entityContext))); if (!isEntityId) { bool isSameType = entityContext.EntityType == entityContext.NavigationSource.EntityType(); if (!isSameType) { odataPath.Add(new CastPathSegment(entityContext.EntityType)); } } string odataLink = entityContext.Url.CreateODataLink(odataPath); return(odataLink == null ? null : new Uri(odataLink)); }
private static ODataPath Parse( IEdmModel model, string serviceRoot, string odataPath, ODataUriResolverSetttings resolverSettings, bool enableUriTemplateParsing) { ODataUriParser uriParser; Uri serviceRootUri = null; Uri fullUri = null; NameValueCollection queryString = null; if (enableUriTemplateParsing) { uriParser = new ODataUriParser(model, new Uri(odataPath, UriKind.Relative)); uriParser.EnableUriTemplateParsing = true; } else { Contract.Assert(serviceRoot != null); serviceRootUri = new Uri( serviceRoot.EndsWith("/", StringComparison.Ordinal) ? serviceRoot : serviceRoot + "/"); fullUri = new Uri(serviceRootUri, odataPath); queryString = fullUri.ParseQueryString(); uriParser = new ODataUriParser(model, serviceRootUri, fullUri); } uriParser.UrlConventions = resolverSettings.UrlConventions; uriParser.Resolver = resolverSettings.CreateResolver(model); Semantic.ODataPath path; UnresolvedPathSegment unresolvedPathSegment = null; Semantic.KeySegment id = null; try { path = uriParser.ParsePath(); } catch (ODataUnrecognizedPathException ex) { if (ex.ParsedSegments != null && ex.ParsedSegments.Count() > 0 && (ex.ParsedSegments.Last().EdmType is IEdmComplexType || ex.ParsedSegments.Last().EdmType is IEdmEntityType) && ex.CurrentSegment != ODataSegmentKinds.Count) { if (ex.UnparsedSegments.Count() == 0) { path = new Semantic.ODataPath(ex.ParsedSegments); unresolvedPathSegment = new UnresolvedPathSegment(ex.CurrentSegment); } else { // Throw ODataException if there is some segment following the unresolved segment. throw new ODataException(Error.Format( SRResources.InvalidPathSegment, ex.UnparsedSegments.First(), ex.CurrentSegment)); } } else { throw; } } if (!enableUriTemplateParsing && path.LastSegment is Semantic.NavigationPropertyLinkSegment) { IEdmCollectionType lastSegmentEdmType = path.LastSegment.EdmType as IEdmCollectionType; if (lastSegmentEdmType != null) { Semantic.EntityIdSegment entityIdSegment = null; bool exceptionThrown = false; try { entityIdSegment = uriParser.ParseEntityId(); if (entityIdSegment != null) { // Create another ODataUriParser to parse $id, which is absolute or relative. ODataUriParser parser = new ODataUriParser(model, serviceRootUri, entityIdSegment.Id); id = parser.ParsePath().LastSegment as Semantic.KeySegment; } } catch (ODataException) { // Exception was thrown while parsing the $id. // We will throw another exception about the invalid $id. exceptionThrown = true; } if (exceptionThrown || (entityIdSegment != null && (id == null || !(id.EdmType.IsOrInheritsFrom(lastSegmentEdmType.ElementType.Definition) || lastSegmentEdmType.ElementType.Definition.IsOrInheritsFrom(id.EdmType))))) { throw new ODataException(Error.Format(SRResources.InvalidDollarId, queryString.Get("$id"))); } } } ODataPath webAPIPath = ODataPathSegmentTranslator.TranslateODataLibPathToWebApiPath( path, model, unresolvedPathSegment, id, enableUriTemplateParsing, uriParser.ParameterAliasNodes); CheckNavigableProperty(webAPIPath, model); return webAPIPath; }
private static ODataPath Parse( IEdmModel model, string serviceRoot, string odataPath, ODataUriResolverSetttings resolverSettings, bool enableUriTemplateParsing) { ODataUriParser uriParser; Uri serviceRootUri = null; Uri fullUri = null; NameValueCollection queryString = null; if (enableUriTemplateParsing) { uriParser = new ODataUriParser(model, new Uri(odataPath, UriKind.Relative)); uriParser.EnableUriTemplateParsing = true; } else { Contract.Assert(serviceRoot != null); serviceRootUri = new Uri( serviceRoot.EndsWith("/", StringComparison.Ordinal) ? serviceRoot : serviceRoot + "/"); fullUri = new Uri(serviceRootUri, odataPath); queryString = fullUri.ParseQueryString(); uriParser = new ODataUriParser(model, serviceRootUri, fullUri); } uriParser.Resolver = resolverSettings.CreateResolver(); Semantic.ODataPath path; UnresolvedPathSegment unresolvedPathSegment = null; Semantic.KeySegment id = null; try { path = uriParser.ParsePath(); } catch (ODataUnrecognizedPathException ex) { if (ex.ParsedSegments != null && ex.ParsedSegments.Count() > 0 && (ex.ParsedSegments.Last().EdmType is IEdmComplexType || ex.ParsedSegments.Last().EdmType is IEdmEntityType) && ex.CurrentSegment != ODataSegmentKinds.Count) { if (ex.UnparsedSegments.Count() == 0) { path = new Semantic.ODataPath(ex.ParsedSegments); unresolvedPathSegment = new UnresolvedPathSegment(ex.CurrentSegment); } else { // Throw ODataException if there is some segment following the unresolved segment. throw new ODataException(Error.Format( SRResources.InvalidPathSegment, ex.UnparsedSegments.First(), ex.CurrentSegment)); } } else { throw; } } if (!enableUriTemplateParsing && path.LastSegment is Semantic.NavigationPropertyLinkSegment) { IEdmCollectionType lastSegmentEdmType = path.LastSegment.EdmType as IEdmCollectionType; if (lastSegmentEdmType != null) { Semantic.EntityIdSegment entityIdSegment = null; bool exceptionThrown = false; try { entityIdSegment = uriParser.ParseEntityId(); if (entityIdSegment != null) { // Create another ODataUriParser to parse $id, which is absolute or relative. ODataUriParser parser = new ODataUriParser(model, serviceRootUri, entityIdSegment.Id); id = parser.ParsePath().LastSegment as Semantic.KeySegment; } } catch (ODataException) { // Exception was thrown while parsing the $id. // We will throw another exception about the invalid $id. exceptionThrown = true; } if (exceptionThrown || (entityIdSegment != null && (id == null || !(id.EdmType.IsOrInheritsFrom(lastSegmentEdmType.ElementType.Definition) || lastSegmentEdmType.ElementType.Definition.IsOrInheritsFrom(id.EdmType))))) { throw new ODataException(Error.Format(SRResources.InvalidDollarId, queryString.Get("$id"))); } } } ODataPath webAPIPath = ODataPathSegmentTranslator.TranslateODLPathToWebAPIPath( path, model, unresolvedPathSegment, id, enableUriTemplateParsing, uriParser.ParameterAliasNodes); CheckNavigableProperty(webAPIPath, model); return(webAPIPath); }
/// <summary> /// Computes the <see cref="IEdmNavigationSource"/> of the resource identified by this <see cref="ODataPath"/>. /// </summary> /// <param name="path">Path to compute the set for.</param> /// <returns>The <see cref="IEdmNavigationSource"/> of the resource, or null if the path does not identify a /// resource that is part of a set.</returns> public static IEdmNavigationSource NavigationSource(this ODataPath path) { return(path.LastSegment.TranslateWith(new DetermineNavigationSourceTranslator())); }
/// <summary> /// Computes whether or not the resource identified by this <see cref="ODataPath"/> is a collection. /// </summary> /// <param name="path">Path to perform the computation on.</param> /// <returns>True if the resource if a feed or collection of primitive or complex types. False otherwise.</returns> public static bool IsCollection(this ODataPath path) { return(path.LastSegment.TranslateWith(new IsCollectionTranslator())); }
/// <summary> /// Computes the <see cref="IEdmTypeReference"/> of the resource identified by this <see cref="ODataPath"/>. /// </summary> /// <param name="path">Path to compute the type for.</param> /// <returns>The <see cref="IEdmTypeReference"/> of the resource, or null if the path does not identify a /// resource with a type.</returns> public static IEdmTypeReference EdmType(this ODataPath path) { return(path.LastSegment.EdmType.ToTypeReference()); }
/// <summary> /// Get the string representation of <see cref="ODataPath"/>. /// mainly translate Query Url path. /// </summary> /// <param name="path">Path to perform the computation on.</param> /// <param name="urlConventions">Mark whether key is segment</param> /// <returns>The string representation of the Query Url path.</returns> public static string ToResourcePathString(this ODataPath path, ODataUrlConventions urlConventions) { return(string.Concat(path.WalkWith(new PathSegmentToResourcePathTranslator(urlConventions.UrlConvention)).ToArray()).TrimStart('/')); }
/// <summary> /// Get the string representation of <see cref="ODataPath"/>. /// mainly translate Context Url path. /// </summary> /// <param name="path">Path to perform the computation on.</param> /// <returns>The string representation of the Context Url path.</returns> public static string ToContextUrlPathString(this ODataPath path) { return(string.Concat(path.WalkWith(PathSegmentToContextUrlPathTranslator.DefaultInstance).ToArray()).TrimStart('/')); }
/// <summary> /// Computes whether or not the ODataPath targets at an individual property. /// </summary> /// <param name="path">Path to perform the computation on.</param> /// <returns>True if the the ODataPath targets at an individual property. False otherwise.</returns> public static bool IsIndividualProperty(this ODataPath path) { ODataPathSegment lastSegmentWithTypeCast = path.TrimEndingTypeSegment().LastSegment; return(lastSegmentWithTypeCast is PropertySegment || lastSegmentWithTypeCast is OpenPropertySegment); }
/// <summary> /// /// </summary> /// <param name="path"></param> /// <returns></returns> public virtual ODataPath HandleUnresolvedODataPath(Semantic.ODataPath path) { return(null); }