예제 #1
0
            /// <summary>
            /// Test if parameter is a key.
            /// </summary>
            /// <param name="argument"></param>
            /// <param name="occuranceIndex"></param>
            /// <returns>false if <paramref name="argument"/> is a key</returns>
            public bool QualifyArgument(ILineArgument argument, int occuranceIndex)
            {
                if (argument is ILineArgument <ILineHint, string, string> lineHint)
                {
                    return(true);
                }
                if (argument is ILineArgument <ILineCanonicalKey, string, string> lineCanonicalKey)
                {
                    return(false);
                }
                if (argument is ILineArgument <ILineNonCanonicalKey, string, string> lineNonCanonicalKey)
                {
                    return(false);
                }
                if (argument is ILineArgument <ILineParameter, string, string> lineParameter)
                {
                    IParameterInfo pi;
                    if (ParameterInfos.TryGetValue(lineParameter.Argument0, out pi))
                    {
                        if (typeof(ILineKey).Equals(pi.InterfaceType) || typeof(ILineCanonicalKey).Equals(pi.InterfaceType) || typeof(ILineNonCanonicalKey).Equals(pi.InterfaceType))
                        {
                            return(false);
                        }
                    }
                }

                return(true);
            }
예제 #2
0
        /// <summary>
        /// Append new <see cref="ILine"/> with <paramref name="arguments"/>.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="arguments"></param>
        /// <returns>Part</returns>
        /// <exception cref="ArgumentNullException">If appender is null</exception>
        /// <exception cref="LineException">If append failed</exception>
        public static ILine Append(this ILine line, ILineArgument arguments)
        {
            ILine result;

            if (line.GetAppender().TryCreate(line, arguments, out result))
            {
                return(result);
            }
            throw new LineException(arguments, $"Could not append.");
        }
            public bool TryCreate(ILineFactory factory, ILine previous, ILineArgument arguments, out ILine line)
            {
                ILine result = previous;

                foreach (var f in factories)
                {
                    if (!f.TryCreate(factory, result, arguments, out result))
                    {
                        line = default; return(false);
                    }
                }
                line = result;
                return(true);
            }
예제 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="argument"></param>
 /// <param name="occuranceIndex"></param>
 /// <returns></returns>
 public bool QualifyArgument(ILineArgument argument, int occuranceIndex = -1)
 {
     if (argument is ILineArgument <ILineParameter, string, string> parameter)
     {
         return(parameter.Argument0 != "Culture");
     }
     if (argument is ILineArgument <ILineNonCanonicalKey, string, string> key)
     {
         return(key.Argument0 != "Culture");
     }
     if (argument is ILineArgument <ILineCulture, CultureInfo> culture)
     {
         return(false);
     }
     return(true);
 }
예제 #5
0
        /// <summary>
        /// Create line (part) with <paramref name="arguments"/>.
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="previous"></param>
        /// <param name="arguments"></param>
        /// <returns>appended part</returns>
        /// <exception cref="LineException">If append failed due to unexpected reason</exception>
        public static ILine Create(this ILineFactory factory, ILine previous, ILineArgument arguments)
        {
            ILine result = null;

            if (factory.TryCreate(previous, arguments, out result))
            {
                return(result);
            }
            ILineFactoryByArgument argumentAdapter;

            if (LineFactoryByArgumentAdapter.Default.TryGet(arguments.GetType(), out argumentAdapter) && argumentAdapter.TryCreate(factory, previous, arguments, out result))
            {
                return(result);
            }
            throw new LineException(arguments, "Could not be appended");
        }
 public bool TryCreate(ILineFactory factory, ILine previous, ILineArgument arguments, out ILine line)
 {
     if (arguments is ILineArgument <Intf> )
     {
         Intf result;
         if (factory is ILineFactory <Intf> casted && casted.TryCreate(factory, previous, out result))
         {
             line = result; return(true);
         }
         ILineFactory <Intf> _casted;
         if (factory is ILineFactoryCastable castable && ((_casted = castable.Cast <Intf>()) != null) && _casted.TryCreate(factory, previous, out result))
         {
             line = result; return(true);
         }
     }
     line = default;
     return(false);
 }
예제 #7
0
        /// <summary>
        /// Create line (part) with <paramref name="arguments"/>.
        /// </summary>
        /// <param name="factory"></param>
        /// <param name="previous"></param>
        /// <param name="arguments"></param>
        /// <param name="line"></param>
        /// <returns>try if create succeeded</returns>
        /// <exception cref="LineException">If append failed due to unexpected reason</exception>
        public static bool TryCreate(this ILineFactory factory, ILine previous, ILineArgument arguments, out ILine line)
        {
            if (factory == null)
            {
                line = previous; return(false);
            }
            if (factory is ILineFactoryByArgument argFactory && argFactory.TryCreate(factory, previous, arguments, out line))
            {
                return(true);
            }
            ILineFactoryByArgument argumentAdapter;

            if (LineFactoryByArgumentAdapter.Default.TryGet(arguments.GetType(), out argumentAdapter) && argumentAdapter.TryCreate(factory, previous, arguments, out line))
            {
                return(true);
            }
            line = default;
            return(false);
        }
예제 #8
0
 /// <summary>
 /// Qualify argument
 /// </summary>
 /// <param name="argument"></param>
 /// <param name="occuranceIndex"></param>
 /// <returns></returns>
 public bool QualifyArgument(ILineArgument argument, int occuranceIndex = -1)
 {
     if (argument is ILineArgument <ILineParameter, string, string> lineParameter)
     {
         return(QualifyParameter(lineParameter.Argument0, lineParameter.Argument1, occuranceIndex, typeof(ILineParameter)));
     }
     else if (argument is ILineArgument <ILineHint, string, string> lineHint)
     {
         return(QualifyParameter(lineHint.Argument0, lineHint.Argument1, occuranceIndex, typeof(ILineHint)));
     }
     else if (argument is ILineArgument <ILineCanonicalKey, string, string> lineCanonicalKey)
     {
         return(QualifyParameter(lineCanonicalKey.Argument0, lineCanonicalKey.Argument1, occuranceIndex, typeof(ILineCanonicalKey)));
     }
     else if (argument is ILineArgument <ILineNonCanonicalKey, string, string> lineNonCanonicalKey)
     {
         return(QualifyParameter(lineNonCanonicalKey.Argument0, lineNonCanonicalKey.Argument1, occuranceIndex, typeof(ILineNonCanonicalKey)));
     }
     return(true);
 }
예제 #9
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);
        }
예제 #10
0
 /// <summary>
 /// Append new <see cref="ILine"/> with <paramref name="arguments"/>.
 /// </summary>
 /// <param name="line"></param>
 /// <param name="arguments"></param>
 /// <param name="result"></param>
 /// <returns>Part</returns>
 /// <exception cref="ArgumentNullException">If appender is null</exception>
 /// <exception cref="LineException">If append failed</exception>
 public static bool TryAppend(this ILine line, ILineArgument arguments, out ILine result)
 => line.GetAppender().TryCreate(line, arguments, out result);
예제 #11
0
 /// <summary>
 /// Try to resolve parameter into line arguments.
 ///
 /// For example parameter "Culture" is resolved to <see cref="ILineArgument"/> that produces <see cref="ILineCulture"/> with <see cref="CultureInfo"/>.
 /// </summary>
 /// <param name="resolver"></param>
 /// <param name="previous">(optional) previous parts</param>
 /// <param name="parameterName"></param>
 /// <param name="parameterValue"></param>
 /// <param name="resolvedLineArgument"></param>
 /// <returns></returns>
 public static bool TryResolveParameter(this IResolver resolver, ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument)
 {
     if (resolver is IParameterResolver parameterResolver)
     {
         return(parameterResolver.TryResolveParameter(previous, parameterName, parameterValue, out resolvedLineArgument));
     }
     resolvedLineArgument = default;
     return(false);
 }
        /// <summary>
        /// Resolve "Culture" parameter into arguments.
        /// </summary>
        /// <param name="previous">(optional)</param>
        /// <param name="parameterName"></param>
        /// <param name="parameterValue"></param>
        /// <param name="resolvedLineArgument"></param>
        /// <returns></returns>
        public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument)
        {
            if (parameterValue != null && parameterValue != "" && parameterName == "Culture")
            {
                CultureInfo cultureInfo;
                if (TryResolve(parameterValue, out cultureInfo))
                {
                    resolvedLineArgument = new LineArgument <ILineCulture, CultureInfo>(cultureInfo);
                    return(true);
                }
            }

            resolvedLineArgument = default;
            return(false);
        }
        /// <summary>
        /// Resolve "Culture" parameter into arguments.
        /// </summary>
        /// <param name="previous">(optional)</param>
        /// <param name="parameterName"></param>
        /// <param name="parameterValue"></param>
        /// <param name="resolvedLineArgument"></param>
        /// <returns></returns>
        public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument)
        {
            if (parameterValue != null && parameterValue != "" && parameterName == "PluralRules")
            {
                IPluralRules value;
                if (TryResolve(parameterValue, out value))
                {
                    resolvedLineArgument = new LineArgument <ILinePluralRules, IPluralRules>(value);
                    return(true);
                }
            }

            resolvedLineArgument = default;
            return(false);
        }
예제 #14
0
        /// <summary>
        /// Try to resolve parameter into line arguments.
        /// </summary>
        /// <param name="previous">(optional) previous parts</param>
        /// <param name="parameterName"></param>
        /// <param name="parameterValue"></param>
        /// <param name="resolvedLineArgument"></param>
        /// <returns></returns>
        public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument)
        {
            List <IParameterResolver> list = resolversByParameterName.TryGetList(parameterName);

            if (list != null)
            {
                foreach (IParameterResolver resolver in list)
                {
                    if (resolver.TryResolveParameter(previous, parameterName, parameterValue, out resolvedLineArgument))
                    {
                        return(true);
                    }
                }
            }

            resolvedLineArgument = default;
            return(false);
        }
예제 #15
0
        /// <summary>
        /// Resolve "StringFormat" and "String" into respective line arguments.
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="parameterName"></param>
        /// <param name="parameterValue"></param>
        /// <param name="resolvedLineArgument"></param>
        /// <returns></returns>
        public bool TryResolveParameter(ILine previous, string parameterName, string parameterValue, out ILineArgument resolvedLineArgument)
        {
            if (parameterValue != null && parameterValue != "")
            {
                if (parameterName == "String")
                {
                    IStringFormat stringFormat = previous.FindStringFormat() ?? CSharpFormat.Default;
                    IString       value        = stringFormat.Parse(parameterValue);
                    resolvedLineArgument = new LineArgument <ILineString, IString>(value);
                    return(true);
                }
                else if (parameterName == "StringFormat")
                {
                    IStringFormat stringFormat;
                    if (TryResolve(parameterValue, out stringFormat))
                    {
                        resolvedLineArgument = new LineArgument <ILineStringFormat, IStringFormat>(stringFormat);
                        return(true);
                    }
                }
            }

            resolvedLineArgument = default;
            return(false);
        }