예제 #1
0
 protected ITextHolderResolver <TContext> FindResolver(TextHolder holder)
 {
     if (UseDeclaredPreiories)
     {
         var ret = FindCustomResolver(holder);
         if (ret != null)
         {
             return(ret);
         }
     }
     else
     {
         foreach (var method in ResolvingMethods)
         {
             var ret = method(holder);
             if (ret != null)
             {
                 return(ret);
             }
         }
     }
     if (!holder.IsOptional())
     {
         LogError("No resolvers found for holder: {0}.", holder);
     }
     return(null);
 }
예제 #2
0
        public void PushContext(IDictionary <string, object> input, ISeekable text, TextHolder parentHolder, bool skipOutput = false, bool disableLogging = false)
        {
            var holderDefinitions = parentHolder == null ? null : Context.PreparsedHolders.GetOrDefault(parentHolder.Name);

            if (parentHolder != null && Context.Holders.ContainsKey(parentHolder.Name))
            {
                parentHolder = Context.Holders[parentHolder.Name];
            }
            var newC = new TemplatorParsingContext(skipOutput)
            {
                Input            = input,
                ParentHolder     = parentHolder,
                Logger           = disableLogging ? null : (Context != null && Context.Nesting) ? new TemplatorLogger() : Config.Logger,
                Text             = text ?? Context?.Text,
                PreparsedHolders = holderDefinitions?.Children
            };

            if (Stack == null)
            {
                Context = newC;
                Stack   = new Stack <TemplatorParsingContext>();
                if (input == null)
                {
                    NoInput = true;
                }
                return;
            }
            Stack.Push(Context);
            Context = newC;
        }
예제 #3
0
        public virtual object ResolveValue(TextHolder holder, TContext mapperContext)
        {
            if (ResolverMethod == null)
            {
                return(ResolvedValue);
            }
            switch (ValueLifeCycle)
            {
            case ResolveLifeCycle.PerResolve:
                return(ResolverMethod(holder, mapperContext));

            case ResolveLifeCycle.Singleton:
                return(ResolvedValue ?? (ResolvedValue = ResolverMethod(holder, mapperContext)));

            case ResolveLifeCycle.PerContext:
                if (!mapperContext.Data.ContainsKey(this))
                {
                    mapperContext.Data.Add(this, ResolverMethod(holder, mapperContext));
                }
                return(mapperContext.Data.GetOrDefault(this));

            case ResolveLifeCycle.PerTemplate:
                if (!mapperContext.Root.Data.ContainsKey(this))
                {
                    mapperContext.Root.Data.Add(this, ResolverMethod(holder, mapperContext));
                }
                return(mapperContext.Root.Data.GetOrDefault(this));

            default:
                return(null);
            }
        }
예제 #4
0
        public static Pair <string, string> Get2Params(TemplatorParser parser, TextHolder holder, string keyword, string delimitor)
        {
            var p  = new SeekableString((string)holder[keyword]);
            var p1 = p.ReadTo(true, parser.Config.EscapePrefix, delimitor);
            var p2 = p.Left;

            return(new Pair <string, string>(p1, p2));
        }
예제 #5
0
 public virtual void OnHolderCreated(string text, TextHolder holder)
 {
     if (holder != null)
     {
         Config.OnHolderFound?.Invoke(this, new TemplatorEventArgs {
             Holder = holder, Input = Context.Input
         });
     }
 }
예제 #6
0
        public static void SetParentInputCount(TemplatorParser parser, TextHolder holder, int?count)
        {
            if (parser.ParentContext == null)
            {
                return;
            }
            var key = (parser.StackLevel - 1) + holder.Name + "InputCount";

            parser.ParentContext[key] = count;
        }
예제 #7
0
        public static void SetParentInputIndex(TemplatorParser parser, TextHolder holder, int?index)
        {
            if (parser.ParentContext == null)
            {
                return;
            }
            var key = (parser.StackLevel - 1) + holder.Name + "InputIndex";

            parser.ParentContext[key] = index;
        }
예제 #8
0
        public static int?GetParentInputIndex(TemplatorParser parser, TextHolder holder)
        {
            if (parser.ParentContext == null)
            {
                return(null);
            }
            var key = (parser.StackLevel - 1) + holder.Name + "InputIndex";

            return((int?)parser.ParentContext[key]);
        }
예제 #9
0
        public static TextHolder GetHolder(IDictionary <string, object> input, string key, TemplatorConfig config, bool creatIfNoFound = true)
        {
            TextHolder holder  = null;
            var        holders = input.GetOrDefault(config.KeyHolders) as IDictionary <string, TextHolder>;

            if (holders != null && holders.ContainsKey(key))
            {
                holder = holders[key];
            }
            return(holder ?? (creatIfNoFound ? new TextHolder(key) : null));
        }
예제 #10
0
 public override bool Match(TextHolder holder, T context)
 {
     if (_matching == null)
     {
         throw new InvalidOperationException("Custom resolver doesn't have rule to match with the text holders");
     }
     return(_matching(holder, context) &&
            MatchCollection(holder.Children != null, IsCollection) &&
            Match(holder.Category, Categories) &&
            Match(holder.Name, Names) &&
            Match(context.Path, Hierarchies));
 }
예제 #11
0
        public static TextHolder Clone(this TextHolder holder)
        {
            var ret = new TextHolder(holder.Name)
            {
                Category = holder.Category,
                Keywords = holder.Keywords.Select(k => k.Create()).ToList(),
                Params   = holder.Params.Copy()
            };

            if (holder.Children != null)
            {
                ret.Children = holder.Children.ToDictionary(c => c.Key, c => c.Value.Clone());
            }
            return(ret);
        }
예제 #12
0
        private static object KeywordPostParse(TemplatorParser parser, TextHolder holder, object current, TemplatorKeyword key)
        {
            if (current.IsNullOrEmptyValue() && !key.HandleNullOrEmpty)
            {
                return(current);
            }
            var ret = key.OnGetValue(holder, parser, current);

            if (((key.ManipulateInput && parser.Config.SaveManipulatedResults) ||
                 (key.CalculateInput && parser.Config.CacheCalculatedResults)) && !key.IndicatesOptional)
            {
                parser.CacheValue(holder.Name, ret, true);
            }
            return(ret);
        }
예제 #13
0
 public static object Aggregate(this TemplatorParser parser, object current, TextHolder holder, string aggregateField, IDictionary <string, object> input, Func <object, object, object> aggregateFunc)
 {
     foreach (var c in aggregateField.Split(Constants.SemiDelimChar))
     {
         string left;
         var    fieldName = c.GetUntil(".", out left);
         if (!left.IsNullOrWhiteSpace())
         {
             var list = GetChildCollection(input, fieldName, parser.Config);
             current = list.EmptyIfNull().Aggregate(current, (current1, subInput) => parser.Aggregate(current1, holder, left, subInput, aggregateFunc));
         }
         else
         {
             var value = GetUnformmatedValue(parser, fieldName, input);
             current = aggregateFunc(current, value);
         }
     }
     return(current);
 }
예제 #14
0
        public static object GetValue(TemplatorParser parser, TextHolder holder, IDictionary <string, object> input, object defaultRet)
        {
            object value = null;

            if (input != null && input.ContainsKey(holder.Name))
            {
                value = input[holder.Name];
            }
            if (value == null)
            {
                value = holder.Keywords.EmptyIfNull().Where(k => k.CalculateInput && k.OnGetValue != null)
                        .Aggregate((object)null, (current, k) => KeywordPostParse(parser, holder, current, k));
            }
            value = value ?? parser.RequireValue(parser, holder, defaultRet, input);
            value = holder.Keywords.EmptyIfNull().Where(key => !key.CalculateInput && key.OnGetValue != null)
                    .Aggregate(value, (current, k) => KeywordPostParse(parser, holder, current, k));
            if (parser.Context.ChildResultBefore.Length > 0 || parser.Context.ChildResultAfter.Length > 0)
            {
                value = String.Concat(parser.Context.ChildResultBefore, value, parser.Context.ChildResultAfter);
            }
            var logger = parser.Context.ChildLogger as TemplatorLogger;

            if (logger != null)
            {
                foreach (var en in logger.Errors)
                {
                    parser.Context.Logger?.LogError(en.FileName, en.Line, en.Column, en.EndLineNumber, en.EndColumnNumber, en.Message);
                }
            }
            if (null == value)
            {
                if (defaultRet != null)
                {
                    value = defaultRet;
                }
                else
                {
                    parser.LogError("'{0}' is required", holder.Name);
                }
            }
            return(value);
        }
예제 #15
0
        public object RequireValue(object sender, TextHolder holder, object defaultRet = null, IDictionary <string, object> input = null)
        {
            var recursiveCheckKey = StackLevel + holder.Name + "$Processing";
            var dict = input ?? Context.Input ?? Context.Params;

            if ((bool?)dict.GetOrDefault(recursiveCheckKey, null) == true)
            {
                dict.Remove(recursiveCheckKey);
                return(defaultRet);
            }
            dict[recursiveCheckKey] = true;
            if (Config.OnRequireInput != null)
            {
                var args = new TemplatorEventArgs {
                    Holder = holder, Input = input ?? Context.Input
                };
                Config.OnRequireInput(this, args);
                dict.Remove(recursiveCheckKey);
                return(args.Value ?? defaultRet);
            }
            dict.Remove(recursiveCheckKey);
            return(defaultRet);
        }
예제 #16
0
        public static bool EvalulateCondition(TemplatorParser parser, IDictionary <string, object> input, TextHolder holder, string condition, object eav)
        {
            var not = false;

            if (condition != null && condition.StartsWith("!"))
            {
                not       = true;
                condition = condition.Substring(1, condition.Length - 1);
            }
            if (!condition.IsNullOrEmptyValue())
            {
                eav = GetInputValue(parser, condition, input);
                eav = eav ?? parser.RequireValue(parser, GetHolder(input, condition, parser.Config));
            }
            var hasValue = eav == null || (parser.Config.EmptyAsNulls && eav.IsNullOrEmptyValue());

            return(not == hasValue);
        }
예제 #17
0
        protected HierarchResolver <TContext> FindHierachyResolver(TextHolder holder)
        {
            var list = HierarchyResolvers.GetOrDefault(Context.Path);

            return(list?.FirstOrDefault(item => item.Match(holder, Context)));
        }
예제 #18
0
 public static bool IsCollection(this TextHolder holder)
 {
     return(holder.Children != null);
 }
예제 #19
0
 public static bool EvalulateCondition(TemplatorParser parser, TextHolder holder, string condition, object eav)
 {
     return(EvalulateCondition(parser, parser.Context.Input, holder, condition, eav));
 }
예제 #20
0
        public static int?GetInputIndex(TemplatorParser parser, TextHolder holder)
        {
            var key = parser.StackLevel + holder.Name + "InputIndex";

            return((int?)parser.Context[key]);
        }
예제 #21
0
 public static bool ContainsKey(this TextHolder holder, string key)
 {
     return(holder?.Params != null && holder.Params.ContainsKey(key));
 }
예제 #22
0
        public static void SetInputIndex(TemplatorParser parser, TextHolder holder, int?index)
        {
            var key = parser.StackLevel + holder.Name + "InputIndex";

            parser.Context[key] = index;
        }
예제 #23
0
 public static bool IsOptional(this TextHolder holder)
 {
     return(holder.Keywords.Any(k => k.IndicatesOptional));
 }
예제 #24
0
        public static void SetInputCount(TemplatorParser parser, TextHolder holder, int?count)
        {
            var key = parser.StackLevel + holder.Name + "InputCount";

            parser.Context[key] = count;
        }
예제 #25
0
 public override bool Match(TextHolder holder, T context)
 {
     return(_name == holder.Name && MatchCollection(holder.Children != null, IsCollection) && Match(holder.Category, Categories) && Match(context.Path, Hierarchies));
 }
예제 #26
0
 public abstract bool Match(TextHolder holder, TContext context);
예제 #27
0
        protected NameResolver <TContext> FindNameResolver(TextHolder holder)
        {
            var list = NameResolvers.GetOrDefault(holder.Name);

            return(list?.FirstOrDefault(item => item.Match(holder, Context)));
        }
예제 #28
0
 protected ITextHolderResolver <TContext> FindCustomResolver(TextHolder holder)
 {
     return(CustomResolvers.FirstOrDefault(item => item.Match(holder, Context)));
 }
예제 #29
0
 public override bool Match(TextHolder holder, T context)
 {
     return(_path == context.Path && MatchCollection(holder.Children != null, IsCollection) && Match(holder.Category, Categories) && Match(holder.Name, Names));
 }
예제 #30
0
        protected CategoryResolver <TContext> FindCategoryResolver(TextHolder holder)
        {
            var list = CategoryResolvers.GetOrDefault(holder.Category);

            return(list?.FirstOrDefault(item => item.Match(holder, Context)));
        }