Example #1
0
        private ICondition ParseConditionElement(XElement element, ParserContext context)
        {
            var scope = Scope.Url;

            var    isNumericIndex   = false;
            string scopeIndexString = null;
            var    scopeIndexInt    = 0;
            var    indexIsANumber   = false;

            var    isNumericValue = false;
            string text           = null;
            var    value          = 0;
            var    defaultValue   = 0;
            var    valueIsANumber = false;

            var    compareOperation    = CompareOperation.MatchRegex;
            string customConditionName = null;
            var    inverted            = false;
            var    ignoreCase          = true;

            if (element.HasAttributes)
            {
                foreach (var attribute in element.Attributes())
                {
                    switch (attribute.Name.LocalName.ToLower())
                    {
                    case "scope":
                        if (!Enum.TryParse(attribute.Value, true, out scope))
                        {
                            throw new Exception(attribute.Value + " is not a valid scope");
                        }
                        break;

                    case "index":
                        scopeIndexString = attribute.Value;
                        indexIsANumber   = int.TryParse(attribute.Value, out scopeIndexInt);
                        break;

                    case "test":
                        if (!Enum.TryParse(attribute.Value, true, out compareOperation))
                        {
                            customConditionName = attribute.Value;
                        }
                        break;

                    case "value":
                        text           = attribute.Value;
                        valueIsANumber = int.TryParse(attribute.Value, out value);
                        break;

                    case "negate":
                        inverted = attribute.Value.ToLower() == "true";
                        break;

                    case "ignorecase":
                        ignoreCase = attribute.Value.ToLower() == "true";
                        break;
                    }
                }
            }

            switch (scope)
            {
            case Scope.PathElement:
            case Scope.HostElement:
            case Scope.OriginalPathElement:
            case Scope.ConditionGroup:
            case Scope.MatchGroup:
                isNumericIndex = true;
                isNumericValue = false;
                break;

            case Scope.ServerVariable:
            case Scope.Header:
            case Scope.OriginalHeader:
                isNumericIndex = false;
                isNumericValue = valueIsANumber;
                break;

            case Scope.Literal:
                isNumericIndex = indexIsANumber;
                isNumericValue = indexIsANumber;
                break;

            default:
                isNumericIndex = false;
                isNumericValue = false;
                break;
            }

            var valueGetter = isNumericIndex
                ? ConstructValueGetter(scope, scopeIndexInt)
                : ConstructValueGetter(scope, scopeIndexString);

            if (customConditionName != null)
            {
                return(_customTypeRegistrar.ConstructCondition(customConditionName, element, valueGetter));
            }

            if (isNumericValue)
            {
                return(_factory.Create <INumberMatch>()
                       .Initialize(valueGetter, compareOperation, value, inverted, defaultValue));
            }

            return(_factory.Create <IStringMatch>()
                   .Initialize(valueGetter, compareOperation, text, inverted, ignoreCase));
        }