/// <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);
        }
Esempio n. 2
0
        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;
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
 /// <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()));
 }
Esempio n. 6
0
 /// <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()));
 }
Esempio n. 7
0
 /// <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());
 }
Esempio n. 8
0
 /// <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('/'));
 }
Esempio n. 9
0
 /// <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('/'));
 }
Esempio n. 10
0
        /// <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);
 }