/// <inheritdoc />
        public virtual ODataPath Translate(ODataPathTemplate path, ODataTemplateTranslateContext context)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // calculate every time
            IList <ODataPathSegment> segments = new List <ODataPathSegment>();

            foreach (var segment in path.Segments)
            {
                ODataPathSegment odataSegment = segment.Translate(context);
                if (odataSegment == null)
                {
                    return(null);
                }

                segments.Add(odataSegment);
            }

            return(new ODataPath(segments));
        }
示例#2
0
        /// <inheritdoc />
        public virtual ODataPath Translate(ODataPathTemplate path, ODataTemplateTranslateContext context)
        {
            if (path == null)
            {
                throw Error.ArgumentNull(nameof(path));
            }

            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            // calculate every time
            foreach (var segment in path)
            {
                if (!segment.TryTranslate(context))
                {
                    return(null);
                }
            }

            return(new ODataPath(context.Segments));
        }
        /// <summary>
        /// Generates all templates for the given <see cref="ODataPathTemplate"/>
        /// </summary>
        /// <param name="path">The given path template.</param>
        /// <returns>All path templates.</returns>
        public static IEnumerable <string> GetTemplates(this ODataPathTemplate path)
        {
            if (path == null)
            {
                throw Error.ArgumentNull(nameof(path));
            }

            IList <StringBuilder> templates = new List <StringBuilder>
            {
                new StringBuilder()
            };

            int count = path.Segments.Count;

            for (int index = 0; index < count; index++)
            {
                ODataSegmentTemplate segment = path.Segments[index];

                if (segment.Kind == ODataSegmentKind.Key)
                {
                    KeySegmentTemplate keySg = segment as KeySegmentTemplate;
                    if (keySg.Count == 1)
                    {
                        templates = CombinateTemplates(templates, "(" + segment.Literal + ")", "/" + segment.Literal);
                    }
                    else
                    {
                        templates = CombinateTemplate(templates, "(" + segment.Literal + ")");
                    }

                    continue;
                }

                if (index != 0)
                {
                    templates = CombinateTemplate(templates, "/");
                }

                // create =>  ~.../navigation/{key}/$ref
                if (segment.Kind == ODataSegmentKind.NavigationLink)
                {
                    NavigationPropertyLinkSegmentTemplate navigationLinkSegment = (NavigationPropertyLinkSegmentTemplate)segment;
                    if (index == count - 1)
                    {
                        // we don't have the other segment
                        templates = CombinateTemplates(templates, $"{navigationLinkSegment.Segment.NavigationProperty.Name}/$ref");
                    }
                    else
                    {
                        ODataSegmentTemplate nextSegment = path.Segments[index + 1];
                        if (nextSegment.Kind == ODataSegmentKind.Key)
                        {
                            // append "navigation property"
                            templates = CombinateTemplates(templates, navigationLinkSegment.Segment.NavigationProperty.Name);

                            // append "key"
                            KeySegmentTemplate keySg = nextSegment as KeySegmentTemplate;
                            if (keySg.Count == 1)
                            {
                                templates = CombinateTemplates(templates, "(" + nextSegment.Literal + ")", "/" + nextSegment.Literal);
                            }
                            else
                            {
                                templates = CombinateTemplate(templates, "(" + nextSegment.Literal + ")");
                            }

                            // append $ref
                            templates = CombinateTemplates(templates, "/$ref");
                            index++; // skip the key segment after $ref.
                        }
                        else
                        {
                            templates = CombinateTemplates(templates, $"{navigationLinkSegment.Segment.NavigationProperty.Name}/$ref");
                        }
                    }

                    continue;
                }

                if (segment.Kind == ODataSegmentKind.Action)
                {
                    ActionSegmentTemplate action = (ActionSegmentTemplate)segment;
                    templates = CombinateTemplates(templates, action.Action.FullName(), action.Action.Name);
                }
                else if (segment.Kind == ODataSegmentKind.Function)
                {
                    FunctionSegmentTemplate function = (FunctionSegmentTemplate)segment;
                    templates = CombinateTemplates(templates, function.Literal, function.UnqualifiedIdentifier);
                }
                else
                {
                    templates = CombinateTemplate(templates, segment.Literal);
                }
            }

            return(templates.Select(t => t.ToString()));
        }
        /// <summary>
        /// Generates all templates for the given <see cref="ODataPathTemplate"/>.
        /// All templates mean:
        /// 1) for key segment, we have key in parenthesis and key as segment.
        /// 2) for bound function segment, we have qualified function call and unqualified function call.
        /// </summary>
        /// <param name="path">The given path template.</param>
        /// <param name="options">The route options.</param>
        /// <returns>All path templates.</returns>
        public static IEnumerable <string> GetTemplates(this ODataPathTemplate path, ODataRouteOptions options = null)
        {
            if (path == null)
            {
                throw Error.ArgumentNull(nameof(path));
            }

            options = options ?? ODataRouteOptions.Default;

            IList <StringBuilder> templates = new List <StringBuilder>
            {
                new StringBuilder()
            };

            int count = path.Segments.Count;

            for (int index = 0; index < count; index++)
            {
                ODataSegmentTemplate segment = path.Segments[index];

                if (segment.Kind == ODataSegmentKind.Key)
                {
                    // for key segment, if it's single key, let's add key as segment template also
                    // otherwise, we only add the key in parenthesis template.
                    KeySegmentTemplate keySg = segment as KeySegmentTemplate;
                    templates = AppendKeyTemplate(templates, keySg, options);
                    continue;
                }

                if (index != 0)
                {
                    templates = CombinateTemplate(templates, "/");
                }

                // create =>  ~.../navigation/{key}/$ref
                if (segment.Kind == ODataSegmentKind.NavigationLink)
                {
                    NavigationLinkSegmentTemplate navigationLinkSegment = (NavigationLinkSegmentTemplate)segment;
                    if (index == count - 1)
                    {
                        // we don't have the other segment
                        templates = CombinateTemplates(templates, $"{navigationLinkSegment.Segment.NavigationProperty.Name}/$ref");
                    }
                    else
                    {
                        ODataSegmentTemplate nextSegment = path.Segments[index + 1];
                        if (nextSegment.Kind == ODataSegmentKind.Key)
                        {
                            // append "navigation property"
                            templates = CombinateTemplates(templates, navigationLinkSegment.Segment.NavigationProperty.Name);

                            // append "key"
                            KeySegmentTemplate keySg = nextSegment as KeySegmentTemplate;
                            templates = AppendKeyTemplate(templates, keySg, options);

                            // append $ref
                            templates = CombinateTemplates(templates, "/$ref");
                            index++; // skip the key segment after $ref.
                        }
                        else
                        {
                            templates = CombinateTemplates(templates, $"{navigationLinkSegment.Segment.NavigationProperty.Name}/$ref");
                        }
                    }

                    continue;
                }

                if (segment.Kind == ODataSegmentKind.Action)
                {
                    ActionSegmentTemplate action = (ActionSegmentTemplate)segment;
                    templates = AppendActionTemplate(templates, action, options);
                }
                else if (segment.Kind == ODataSegmentKind.Function)
                {
                    FunctionSegmentTemplate function = (FunctionSegmentTemplate)segment;
                    templates = AppendFunctionTemplate(templates, function, options);
                }
                else
                {
                    templates = CombinateTemplate(templates, segment.Literal);
                }
            }

            return(templates.Select(t => t.ToString()));
        }
        /// <summary>
        /// Gets the whole supported template belongs to a <see cref="ODataPathTemplate"/>.
        /// We supports:
        /// 1. Key as segment if it's single key (We doesn't consider the alternate key so far)
        /// 2. Unqualified function/action call
        /// 3. Optional parameters combination.
        /// </summary>
        /// <param name="path">The input path template.</param>
        /// <returns>The whole path template string.</returns>
        public static IEnumerable <string> GetAllTemplates(this ODataPathTemplate path)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            IList <StringBuilder> templates = new List <StringBuilder>
            {
                new StringBuilder()
            };

            int index = 0;

            foreach (ODataSegmentTemplate segment in path.Segments)
            {
                if (segment.Kind == ODataSegmentKind.Key)
                {
                    KeySegmentTemplate keySg = segment as KeySegmentTemplate;
                    if (keySg.Count == 1)
                    {
                        templates = CombinateTemplates(templates, "(" + segment.Literal + ")", "/" + segment.Literal);
                    }
                    else
                    {
                        templates = CombinateTemplate(templates, "(" + segment.Literal + ")");
                    }

                    index++;
                    continue;
                }

                if (index != 0)
                {
                    templates = CombinateTemplate(templates, "/");
                }
                index++;

                if (segment.Kind == ODataSegmentKind.Action)
                {
                    ActionSegmentTemplate action = (ActionSegmentTemplate)segment;
                    templates = CombinateTemplates(templates, action.Action.FullName(), action.Action.Name);
                }
                else if (segment.Kind == ODataSegmentKind.Function)
                {
                    FunctionSegmentTemplate function          = (FunctionSegmentTemplate)segment;
                    IList <string>          functionTemplates = function.Function.GenerateFunctionTemplates();
                    templates = CombinateTemplates(templates, functionTemplates);
                }
                else if (segment.Kind == ODataSegmentKind.FunctionImport)
                {
                    FunctionImportSegmentTemplate functionImport = (FunctionImportSegmentTemplate)segment;
                    IList <string> functionTemplates             = functionImport.FunctionImport.Function.GenerateFunctionTemplates();
                    templates = CombinateTemplates(templates, functionTemplates);
                }
                else
                {
                    templates = CombinateTemplate(templates, segment.Literal);
                }
            }

            return(templates.Select(t => t.ToString()));
        }