/// <summary>
        /// Evaluate placeholders into string values.
        /// </summary>
        /// <param name="line">original requesting line</param>
        /// <param name="resolvedLine">(optional Line that was matched from IAsset or inlines</param>
        /// <param name="pluralLine">(optional) Line that was matched from IAsset or inlines for plural value</param>
        /// <param name="placeholders"></param>
        /// <param name="features">contextual data</param>
        /// <param name="placeholder_values">collection where strings are placed, one for each placeholder</param>
        /// <param name="culture">the culture in which to evaluate</param>
        void EvaluatePlaceholderValues(ILine line, ILine resolvedLine, ILine pluralLine, IPlaceholder[] placeholders, ref LineFeatures features, ref StructList12 <string> placeholder_values, CultureInfo culture)
        {
            PlaceholderExpressionEvaluator placeholder_evaluator = new PlaceholderExpressionEvaluator();

            placeholder_evaluator.Args = features.ValueArgs;
            placeholder_evaluator.FunctionEvaluationCtx.Culture        = culture;
            placeholder_evaluator.FunctionEvaluationCtx.Line           = line;
            placeholder_evaluator.FunctionEvaluationCtx.ResolvedLine   = resolvedLine;
            placeholder_evaluator.FunctionEvaluationCtx.PluralLine     = pluralLine;
            placeholder_evaluator.FunctionEvaluationCtx.StringResolver = this;
            placeholder_evaluator.FunctionEvaluationCtx.EnumResolver   = EnumResolver;
            if (features.FormatProviders.Count == 1)
            {
                placeholder_evaluator.FunctionEvaluationCtx.FormatProvider = features.FormatProviders[0];
            }
            else if (features.FormatProviders.Count > 1)
            {
                placeholder_evaluator.FunctionEvaluationCtx.FormatProvider = new FormatProviderComposition(features.FormatProviders.ToArray());
            }
            if (features.Functions.Count == 1)
            {
                placeholder_evaluator.FunctionEvaluationCtx.Functions = features.Functions[0];
            }
            else if (features.Functions.Count > 1)
            {
                placeholder_evaluator.FunctionEvaluationCtx.Functions = new FunctionsMap(features.Functions);
            }
            for (int i = 0; i < placeholders.Length; i++)
            {
                try
                {
                    // Get placeholder
                    IPlaceholder ph = placeholders[i];
                    // Evaluate value
                    string ph_value = placeholder_evaluator.toString(placeholder_evaluator.Evaluate(ph.Expression));
                    // Add to array
                    placeholder_values.Add(ph_value);
                    // Update code
                    features.Status.UpPlaceholder(placeholder_evaluator.Status);
                }
                catch (Exception e)
                {
                    // Log exceptions
                    features.Log(e);
                    // Mark error
                    features.Status.UpPlaceholder(LineStatus.PlaceholderErrorExpressionEvaluation);
                    // Put empty value
                    placeholder_values.Add(null);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Try parse <paramref name="str"/> into parameters.
        /// </summary>
        /// <param name="str"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public override bool TryParse(string str, ref StructList12 <KeyValuePair <string, string> > parameters)
        {
            if (str == null)
            {
                return(false);
            }
            MatchCollection matches = ParsePattern.Matches(str);

            foreach (Match m in matches)
            {
                if (!m.Success)
                {
                    return(false);
                }
                Group k_key = m.Groups["key"], k_value = m.Groups["value"];
                if (!k_key.Success || !k_value.Success)
                {
                    return(false);
                }
                string parameterName  = UnescapeLiteral(k_key.Value);
                string parameterValue = UnescapeLiteral(k_value.Value);
                parameters.Add(new KeyValuePair <string, string>(parameterName, parameterValue));
            }
            return(true);
        }
Пример #3
0
        /// <summary>
        /// Prune out arguments that are disqualified by <paramref name="qualifier"/>.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="qualifier">Argument qualifier that is used for determining which parts to keep in the line</param>
        /// <param name="lineFactory">(optional) extra line factory</param>
        /// <returns>a modified <paramref name="line"/></returns>
        /// <exception cref="LineException"></exception>
        public static ILine Prune(this ILine line, ILineQualifier qualifier, ILineFactory lineFactory = null)
        {
            // Qualified parts to append. Order: tail to root.
            StructList12 <ILineArgument> list = new StructList12 <ILineArgument>();

            ILineArgumentQualifier lineArgumentQualifier = qualifier as ILineArgumentQualifier;

            // Earliest qualified line part. The start tail, where to start appending qualified parts
            ILine startTail = line;

            // Line part's arguments. Order: root to tail
            StructList8 <ILineArgument> tmp = new StructList8 <ILineArgument>();
            // Start tail buffered args. Order: root to tail
            StructList8 <ILineArgument> startTailArgsBuffer = new StructList8 <ILineArgument>();

            // Add parts
            for (ILine l = line; l != null; l = l.GetPreviousPart())
            {
                tmp.Clear();
                if (l is ILineArgumentEnumerable lineArguments)
                {
                    foreach (ILineArgument lineArgument in lineArguments)
                    {
                        tmp.Add(lineArgument);
                    }
                }
                if (l is ILineArgument argument)
                {
                    tmp.Add(argument);
                }

                // Now qualify
                bool   linePartQualifies = true;
                string parameterName, parameterValue;
                for (int i = tmp.Count - 1; i >= 0; i--)
                {
                    ILineArgument a = tmp[i];

                    bool argumentQualifies = true;
                    if (lineArgumentQualifier != null)
                    {
                        // Qualify as an argument.
                        if (!a.IsNonCanonicalKey())
                        {
                            argumentQualifies = lineArgumentQualifier.QualifyArgument(a);
                        }
                        // Qualify as non-canonical parameter
                        else if (a.TryGetParameter(out parameterName, out parameterValue))
                        {
                            // Calculate occurance index
                            int occIx = -1;
                            if (lineArgumentQualifier.NeedsOccuranceIndex)
                            {
                                occIx = 0;
                                for (int j = i - 1; j >= 0; j--)
                                {
                                    ILineArgument b = list[j];
                                    string        parameterName2, parameterValue2;
                                    if (b.TryGetParameter(out parameterName2, out parameterValue2))
                                    {
                                        continue;
                                    }
                                    if (parameterValue2 != null && parameterName == parameterName2)
                                    {
                                        occIx++;
                                    }
                                }
                            }
                            argumentQualifies = lineArgumentQualifier.QualifyArgument(a, occIx);
                        }
                    }
                    if (!argumentQualifies)
                    {
                        tmp.RemoveAt(i);
                    }
                    linePartQualifies &= argumentQualifies;
                }

                // This part didn't qualify
                if (!linePartQualifies)
                {
                    // Append previous start tail to append args
                    if (startTailArgsBuffer.Count > 0)
                    {
                        for (int i = 0; i < startTailArgsBuffer.Count; i++)
                        {
                            list.Add(startTailArgsBuffer[i]);
                        }
                        startTailArgsBuffer.Clear();
                        startTail = null;
                    }
                    // Add parts that did qualify to append list
                    for (int i = 0; i < tmp.Count; i++)
                    {
                        list.Add(tmp[i]);
                    }
                    // preceding part might be better for start tail
                    startTail = l.GetPreviousPart();
                }
                else
                // This part qualified
                {
                    // Add to start tail buffer, in case preceding startTail fails qualifications
                    for (int i = 0; i < tmp.Count; i++)
                    {
                        startTailArgsBuffer.Add(tmp[i]);
                    }
                }
            }


            // Append qualified parts.
            ILineFactory appender1 = null;

            line.TryGetAppender(out appender1);

            // Nothing qualified, no start, create dummy
            if (startTail == null && list.Count == 0)
            {
                // Create dummy
                ILineFactory appender2 = null;
                line.TryGetAppender(out appender2);
                ILinePart dummy = null;
                if (lineFactory == null || !lineFactory.TryCreate(null, out dummy))
                {
                    if (appender2 == null || !appender2.TryCreate(null, out dummy))
                    {
                        throw new LineException(line, $"LineFactory doesn't have capability to create {nameof(ILinePart)}");
                    }
                }
                return(dummy);
            }

            // Append parts
            ILine result = startTail;

            for (int i = list.Count - 1; i >= 0; i--)
            {
                ILineArgument arg = list[i];
                if (lineFactory == null || !lineFactory.TryCreate(result, arg, out result))
                {
                    if (appender1 == null || !appender1.TryCreate(result, arg, out result))
                    {
                        throw new LineException(line, $"LineFactory doesn't have capability to concat {arg}");
                    }
                }
            }
            return(result);
        }
            /// <summary>
            /// Forward event
            /// </summary>
            /// <param name="sender"></param>
            void OnEvent(object sender)
            {
                var _observer = Observer;

                if (_observer == null)
                {
                    return;
                }

                // Create new token
                if (!IsDisposing)
                {
                    this.changeToken = FileProvider.Watch(Filter);
                }

                // Get new snapshot
                DateTimeOffset time = DateTimeOffset.UtcNow;
                Dictionary <string, IEntry> newSnapshot = ReadSnapshot();

                // List of events
                StructList12 <IEvent> events = new StructList12 <IEvent>();

                // Find adds
                foreach (KeyValuePair <string, IEntry> newEntry in newSnapshot)
                {
                    string path = newEntry.Key;
                    // Find matching previous entry
                    IEntry prevEntry;
                    if (previousSnapshot.TryGetValue(path, out prevEntry))
                    {
                        // Send change event
                        if (!EntryComparer.PathDateLengthTypeEqualityComparer.Equals(newEntry.Value, prevEntry))
                        {
                            events.Add(new ChangeEvent(this, time, path));
                        }
                    }
                    // Send create event
                    else
                    {
                        events.Add(new CreateEvent(this, time, path));
                    }
                }
                // Find Deletes
                foreach (KeyValuePair <string, IEntry> oldEntry in previousSnapshot)
                {
                    string path = oldEntry.Key;
                    if (!newSnapshot.ContainsKey(path))
                    {
                        events.Add(new DeleteEvent(this, time, path));
                    }
                }

                // Replace entires
                previousSnapshot = newSnapshot;

                // Dispatch events
                if (events.Count > 0)
                {
                    ((FileSystemBase)this.FileSystem).DispatchEvents(ref events);
                }

                // Start watching again
                if (!IsDisposing)
                {
                    this.watcher = changeToken.RegisterChangeCallback(OnEvent, this);
                }
            }