private static void ReadErrorHandler(XmlNode node, RewriterConfiguration config)
        {
            XmlNode codeNode = node.Attributes[Constants.AttrCode];

            if (codeNode == null)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrCode), node);
            }

            XmlNode typeNode = node.Attributes[Constants.AttrType];
            XmlNode urlNode  = node.Attributes[Constants.AttrUrl];

            if (typeNode == null && urlNode == null)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrUrl), node);
            }

            IRewriteErrorHandler handler = null;

            if (typeNode != null)
            {
                // <error-handler code="500" url="/oops.aspx" />
                handler = TypeHelper.Activate(typeNode.Value, null) as IRewriteErrorHandler;
                if (handler == null)
                {
                    throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.InvalidTypeSpecified));
                }
            }
            else
            {
                handler = new DefaultErrorHandler(urlNode.Value);
            }

            config.ErrorHandlers.Add(Convert.ToInt32(codeNode.Value), handler);
        }
        private static void ReadActions(XmlNode node, IList<IRewriteAction> actions, RewriterConfiguration config)
        {
            XmlNode childNode = node.FirstChild;
            while (childNode != null)
            {
                if (childNode.NodeType == XmlNodeType.Element)
                {
                    IList<IRewriteActionParser> parsers = config.ActionParserFactory.GetParsers(childNode.LocalName);
                    if (parsers != null)
                    {
                        bool parsed = false;
                        foreach (IRewriteActionParser parser in parsers)
                        {
                            IRewriteAction action = parser.Parse(childNode, config);
                            if (action != null)
                            {
                                parsed = true;
                                actions.Add(action);
                            }
                        }

                        if (!parsed)
                        {
                            throw new ConfigurationErrorsException(
                                MessageProvider.FormatString(Message.ElementNotAllowed, node.FirstChild.Name), node);
                        }
                    }
                }

                childNode = childNode.NextSibling;
            }
        }
        private static void ReadMapping(XmlNode node, RewriterConfiguration config)
        {
            // Name attribute.
            XmlNode nameNode = node.Attributes[Constants.AttrName];

            // Mapper type not specified.  Load in the hash map.
            StringDictionary map = new StringDictionary();

            foreach (XmlNode mapNode in node.ChildNodes)
            {
                if (mapNode.NodeType == XmlNodeType.Element)
                {
                    if (mapNode.LocalName == Constants.ElementMap)
                    {
                        string fromValue = mapNode.GetRequiredAttribute(Constants.AttrFrom, true);
                        string toValue   = mapNode.GetRequiredAttribute(Constants.AttrTo, true);

                        map.Add(fromValue, toValue);
                    }
                    else
                    {
                        throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNotAllowed, mapNode.LocalName), node);
                    }
                }
            }

            config.TransformFactory.AddTransform(new StaticMappingTransform(nameNode.Value, map));
        }
        /// <summary>
        /// Load RewriterConfiguration Instance to XmlNode
        /// </summary>
        /// <param name="node">XmlNode</param>
        /// <returns></returns>
        public static RewriterConfiguration LoadFromNode(XmlNode node)
        {
            RewriterConfiguration configuration = RewriterConfigurationReader.Read(node);

            //HttpRuntime.Cache.Add(_cacheName, configuration, null, DateTime.Now.AddHours(1.0), TimeSpan.Zero, CacheItemPriority.Normal, null);
            return(configuration);
        }
        private static void ReadRule(XmlNode node, RewriterConfiguration config)
        {
            bool parsed = false;
            IList <IRewriteActionParser> parsers = config.ActionParserFactory.GetParsers(node.LocalName);

            if (parsers != null)
            {
                foreach (IRewriteActionParser parser in parsers)
                {
                    if (!parser.AllowsNestedActions && node.ChildNodes.Count > 0)
                    {
                        throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNoElements, parser.Name), node);
                    }

                    if (!parser.AllowsAttributes && node.Attributes.Count > 0)
                    {
                        throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNoAttributes, parser.Name), node);
                    }

                    IRewriteAction rule = parser.Parse(node, config);
                    if (rule != null)
                    {
                        config.Rules.Add(rule);
                        parsed = true;
                        break;
                    }
                }
            }

            if (!parsed)
            {
                // No parsers recognised to handle this node.
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNotAllowed, node.LocalName), node);
            }
        }
        private static void ReadRegisterParser(XmlNode node, RewriterConfiguration config)
        {
            XmlNode typeNode = node.Attributes[Constants.AttrParser];

            if (typeNode == null)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrParser), node);
            }

            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
            }

            object parser = TypeHelper.Activate(typeNode.Value, null);
            IRewriteActionParser actionParser = parser as IRewriteActionParser;

            if (actionParser != null)
            {
                config.ActionParserFactory.AddParser(actionParser);
            }

            IRewriteConditionParser conditionParser = parser as IRewriteConditionParser;

            if (conditionParser != null)
            {
                config.ConditionParserPipeline.AddParser(conditionParser);
            }
        }
        /// <summary>
        /// Loads the configuration from the .config file, with caching.
        /// </summary>
        /// <returns>The configuration.</returns>
        public static RewriterConfiguration Load()
        {
            XmlNode section = ConfigurationManager.GetSection(Constants.RewriterNode) as XmlNode;
            RewriterConfiguration config = null;

            XmlNode filenameNode = section.Attributes.GetNamedItem(Constants.AttrFile);

            if (filenameNode != null)
            {
                string filename = HttpContext.Current.Server.MapPath(filenameNode.Value);
                config = LoadFromFile(filename);
                if (config != null)
                {
                    CacheDependency fileDependency = new CacheDependency(filename);
                    HttpRuntime.Cache.Add(_cacheName, config, fileDependency, DateTime.UtcNow.AddHours(1.0), TimeSpan.Zero, CacheItemPriority.Default, null);
                }
            }

            if (config == null)
            {
                config = LoadFromNode(section);
                HttpRuntime.Cache.Add(_cacheName, config, null, DateTime.UtcNow.AddHours(1.0), TimeSpan.Zero, CacheItemPriority.Default, null);
            }

            return(config);
        }
        private static void ReadRegisterLogger(XmlNode node, RewriterConfiguration config)
        {
            // Type attribute.
            XmlNode typeNode = node.Attributes[Constants.AttrLogger];

            if (typeNode == null)
            {
                throw new ConfigurationErrorsException(
                          MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrLogger),
                          node);
            }

            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(
                          MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister),
                          node);
            }

            // Logger type specified.  Create an instance and add it
            // as the mapper handler for this map.
            var logger = TypeHelper.Activate(typeNode.Value, null) as IRewriteLogger;

            if (logger != null)
            {
                config.Logger = logger;
            }
        }
		private void ReadAttributeActions(XmlNode node, bool allowFinal, IList actions, RewriterConfiguration config)
		{
			int i = 0;
			while (i < node.Attributes.Count)
			{
				XmlNode attrNode = node.Attributes[i++];

				IList parsers = config.ActionParserFactory.GetParsers(String.Format(Constants.AttributeAction, node.LocalName, attrNode.LocalName));
				if (parsers != null)
				{
					foreach (IRewriteActionParser parser in parsers)
					{
						IRewriteAction action = parser.Parse(node, config);
						if (action != null)
						{
							if (action.Processing == RewriteProcessing.ContinueProcessing || allowFinal)
							{
								actions.Add(action);
								break;
							}
						}
					}
				}
			}
		}
        private static void ReadRegisterTransform(XmlNode node, RewriterConfiguration config)
        {
            // Type attribute.
            XmlNode typeNode = node.Attributes[Constants.AttrTransform];

            if (typeNode == null)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrTransform), node);
            }

            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
            }

            // Transform type specified.  Create an instance and add it
            // as the mapper handler for this map.
            IRewriteTransform handler = TypeHelper.Activate(typeNode.Value, null) as IRewriteTransform;

            if (handler != null)
            {
                config.TransformFactory.AddTransform(handler);
            }
            else
            {
                // TODO: Error due to type.
            }
        }
 public IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
 {
     XmlNode statusCodeNode = node.Attributes.GetNamedItem("status");
     if (statusCodeNode == null)
     {
         return null;
     }
     return new MVCStatusAction((HttpStatusCode)Convert.ToInt32(statusCodeNode.Value));
 }
 private static void ReadDefaultDocuments(XmlNode node, RewriterConfiguration config)
 {
     foreach (XmlNode childNode in node.ChildNodes)
     {
         if (childNode.NodeType == XmlNodeType.Element && childNode.LocalName == Constants.ElementDocument)
         {
             config.DefaultDocuments.Add(childNode.InnerText);
         }
     }
 }
 private static void ReadDefaultDocuments(XmlNode node, RewriterConfiguration config)
 {
     foreach (XmlNode childNode in node.ChildNodes)
     {
         if (childNode.NodeType == XmlNodeType.Element && childNode.LocalName == Constants.ElementDocument)
         {
             config.DefaultDocuments.Add(childNode.InnerText);
         }
     }
 }
        /// <summary>
        /// Reads configuration information from the given XML Node.
        /// </summary>
        /// <param name="section">The XML node to read configuration from.</param>
        /// <returns>The configuration information.</returns>
        public static RewriterConfiguration Read(XmlNode section)
        {
            if (section == null)
            {
                throw new ArgumentNullException("section");
            }

            RewriterConfiguration config = RewriterConfiguration.Create();

            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            foreach (XmlNode node in section.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    if (node.LocalName == Constants.ElementErrorHandler)
                    {
                        ReadErrorHandler(node, config);
                    }
                    else if (node.LocalName == Constants.ElementDefaultDocuments)
                    {
                        ReadDefaultDocuments(node, config);
                    }
                    else if (node.LocalName == Constants.ElementRegister)
                    {
                        if (node.Attributes[Constants.AttrParser] != null)
                        {
                            ReadRegisterParser(node, config);
                        }
                        else if (node.Attributes[Constants.AttrTransform] != null)
                        {
                            ReadRegisterTransform(node, config);
                        }
                        else if (node.Attributes[Constants.AttrLogger] != null)
                        {
                            ReadRegisterLogger(node, config);
                        }
                    }
                    else if (node.LocalName == Constants.ElementMapping)
                    {
                        ReadMapping(node, config);
                    }
                    else
                    {
                        ReadRule(node, config);
                    }
                }
            }
            return(config);
        }
        /// <summary>
        ///     Parses conditions from the node.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="conditions">Conditions list to add new conditions to.</param>
        /// <param name="negative">Whether the conditions should be negated.</param>
        /// <param name="config">Rewriter configuration</param>
        protected void ParseConditions(XmlNode node, IList<IRewriteCondition> conditions, bool negative,
                                       RewriterConfiguration config)
        {
            if (config == null)
            {
                return;
            }
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (conditions == null)
            {
                throw new ArgumentNullException("conditions");
            }

            // Parse attribute-based conditions.
            foreach (IRewriteConditionParser parser in config.ConditionParserPipeline)
            {
                IRewriteCondition condition = parser.Parse(node);
                if (condition != null)
                {
                    if (negative)
                    {
                        condition = new NegativeCondition(condition);
                    }

                    conditions.Add(condition);
                }
            }

            // Now, process the nested <and> conditions.
            XmlNode childNode = node.FirstChild;
            while (childNode != null)
            {
                if (childNode.NodeType == XmlNodeType.Element)
                {
                    if (childNode.LocalName == Constants.ElementAnd)
                    {
                        ParseConditions(childNode, conditions, negative, config);

                        XmlNode childNode2 = childNode.NextSibling;
                        node.RemoveChild(childNode);
                        childNode = childNode2;
                        continue;
                    }
                }

                childNode = childNode.NextSibling;
            }
        }
Exemple #16
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="contextFacade">The context facade to use.</param>
        /// <param name="configuration">The configuration to use.</param>
        public RewriterEngine(IContextFacade contextFacade, RewriterConfiguration configuration)
        {
            if (contextFacade == null)
            {
                throw new ArgumentNullException("contextFacade");
            }
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }

            ContextFacade = contextFacade;
            _configuration = configuration;
        }
        /// <summary>
        /// Parses the node.
        /// </summary>
        /// <param name="node">The node to parse.</param>
        /// <param name="config">The rewriter configuration.</param>
        /// <returns>The parsed action, or null if no action parsed.</returns>
        public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            string headerName = XmlNodeExtensions.GetRequiredAttribute(node, Constants.AttrHeader);
            string headerValue = XmlNodeExtensions.GetRequiredAttribute(node, Constants.AttrValue, true);

            return new AddHeaderAction(headerName, headerValue);
        }
        /// <summary>
        ///     Parses the node.
        /// </summary>
        /// <param name="node">The node to parse.</param>
        /// <param name="config">The rewriter configuration.</param>
        /// <returns>The parsed action, or null if no action parsed.</returns>
        public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            string cookieName = node.GetRequiredAttribute(Constants.AttrCookie);
            string cookieValue = node.GetRequiredAttribute(Constants.AttrValue, true);

            return new SetCookieAction(cookieName, cookieValue);
        }
        /// <summary>
        /// Parses the node.
        /// </summary>
        /// <param name="node">The node to parse.</param>
        /// <param name="config">The rewriter configuration.</param>
        /// <returns>The parsed action, or null if no action parsed.</returns>
        public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            string propertyName = XmlNodeExtensions.GetRequiredAttribute(node, Constants.AttrProperty);
            string appSettingKey = XmlNodeExtensions.GetRequiredAttribute(node, Constants.AttrKey);

            return new SetAppSettingPropertyAction(propertyName, appSettingKey);
        }
        /// <summary>
        ///     Reads configuration information from the given XML Node.
        /// </summary>
        /// <param name="config">The rewriter configuration object to populate.</param>
        /// <param name="section">The XML node to read configuration from.</param>
        /// <returns>The configuration information.</returns>
        public static void Read(RewriterConfiguration config, XmlNode section)
        {
            if (section == null)
            {
                throw new ArgumentNullException("section");
            }

            foreach (XmlNode node in section.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    if (node.LocalName == Constants.ElementErrorHandler)
                    {
                        ReadErrorHandler(node, config);
                    }
                    else if (node.LocalName == Constants.ElementDefaultDocuments)
                    {
                        ReadDefaultDocuments(node, config);
                    }
                    else if (node.LocalName == Constants.ElementRegister)
                    {
                        if (node.Attributes[Constants.AttrParser] != null)
                        {
                            ReadRegisterParser(node, config);
                        }
                        else if (node.Attributes[Constants.AttrTransform] != null)
                        {
                            ReadRegisterTransform(node, config);
                        }
                        else if (node.Attributes[Constants.AttrLogger] != null)
                        {
                            ReadRegisterLogger(node, config);
                        }
                    }
                    else if (node.LocalName == Constants.ElementMapping)
                    {
                        ReadMapping(node, config);
                    }
                    else
                    {
                        ReadRule(node, config);
                    }
                }
            }
        }
        private static void ReadRegisterLogger(XmlNode node, RewriterConfiguration config)
        {
            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
            }

            string type = XmlNodeExtensions.GetRequiredAttribute(node, Constants.AttrLogger);

            // Logger type specified.  Create an instance and add it
            // as the mapper handler for this map.
            IRewriteLogger logger = TypeHelper.Activate(type, null) as IRewriteLogger;

            if (logger != null)
            {
                config.Logger = logger;
            }
        }
        /// <summary>
        /// Parses the node.
        /// </summary>
        /// <param name="node">The node to parse.</param>
        /// <param name="config">The rewriter configuration.</param>
        /// <returns>The parsed action, or null if no action parsed.</returns>
        public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            XmlNode statusCodeNode = node.Attributes.GetNamedItem(Constants.AttrStatus);
            if (statusCodeNode == null)
            {
                return null;
            }

            return new SetStatusAction((HttpStatusCode)Convert.ToInt32(statusCodeNode.Value));
        }
        private static void ReadRegisterTransform(XmlNode node, RewriterConfiguration config)
        {
            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
            }

            string type = node.GetRequiredAttribute(Constants.AttrTransform);

            // Transform type specified.
            // Create an instance and add it as the mapper handler for this map.
            IRewriteTransform transform = TypeHelper.Activate(type, null) as IRewriteTransform;

            if (transform == null)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.InvalidTypeSpecified, type, typeof(IRewriteTransform)), node);
            }

            config.TransformFactory.AddTransform(transform);
        }
        private static void ReadRegisterTransform(XmlNode node, RewriterConfiguration config)
        {
            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(
                    MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
            }

            string type = node.GetRequiredAttribute(Constants.AttrTransform);

            // Transform type specified.
            // Create an instance and add it as the mapper handler for this map.
            var transform = TypeHelper.Activate(type, null) as IRewriteTransform;
            if (transform == null)
            {
                throw new ConfigurationErrorsException(
                    MessageProvider.FormatString(Message.InvalidTypeSpecified, type, typeof (IRewriteTransform)), node);
            }

            config.TransformFactory.AddTransform(transform);
        }
        /// <summary>
        ///     Parses the action.
        /// </summary>
        /// <param name="node">The node to parse.</param>
        /// <param name="config">The rewriter configuration.</param>
        /// <returns>The parsed action, null if no action parsed.</returns>
        public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            var rule = new ConditionalAction();

            // Process the conditions on the element.
            bool negative = (node.LocalName == Constants.ElementUnless);
            ParseConditions(node, rule.Conditions, negative, config);

            // Next, process the actions on the element.
            ReadActions(node, rule.Actions, config);

            return rule;
        }
        /// <summary>
        ///     Parses the node.
        /// </summary>
        /// <param name="node">The node to parse.</param>
        /// <param name="config">The rewriter configuration.</param>
        /// <returns>The parsed action, or null if no action parsed.</returns>
        public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            string to = node.GetRequiredAttribute(Constants.AttrTo, true);

            XmlNode processingNode = node.Attributes[Constants.AttrProcessing];

            var processing = RewriteProcessing.ContinueProcessing;
            if (processingNode != null)
            {
                if (processingNode.Value == Constants.AttrValueRestart)
                {
                    processing = RewriteProcessing.RestartProcessing;
                }
                else if (processingNode.Value == Constants.AttrValueStop)
                {
                    processing = RewriteProcessing.StopProcessing;
                }
                else if (processingNode.Value != Constants.AttrValueContinue)
                {
                    throw new ConfigurationErrorsException(
                        MessageProvider.FormatString(Message.ValueOfProcessingAttribute, processingNode.Value,
                                                     Constants.AttrValueContinue, Constants.AttrValueRestart,
                                                     Constants.AttrValueStop), node);
                }
            }

            var action = new RewriteAction(to, processing);
            ParseConditions(node, action.Conditions, false, config);
            return action;
        }
        /// <summary>
        /// Parses the node.
        /// </summary>
        /// <param name="node">The node to parse.</param>
        /// <param name="config">The rewriter configuration.</param>
        /// <returns>The parsed action, or null if no action parsed.</returns>
        public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            string to = node.GetRequiredAttribute(Constants.AttrTo, true);

            bool permanent = true;
            XmlNode permanentNode = node.Attributes.GetNamedItem(Constants.AttrPermanent);
            if (permanentNode != null)
            {
                if (!bool.TryParse(permanentNode.Value, out permanent))
                {
                    throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.InvalidBooleanAttribute, Constants.AttrPermanent), node);
                }
            }

            RedirectAction action = new RedirectAction(to, permanent);
            ParseConditions(node, action.Conditions, false, config);
            return action;
        }
        /// <summary>
        /// Load RewriterConfiguration Instance
        /// </summary>
        /// <returns></returns>
        public static RewriterConfiguration Load()
        {
            XmlNode section = System.Configuration.ConfigurationManager.GetSection(Constants.RewriterNode) as XmlNode;
            RewriterConfiguration configuration = null;
            XmlNode namedItem = section.Attributes.GetNamedItem(Constants.AttrFile);

            if (namedItem != null)
            {
                string filename = HttpContext.Current.Server.MapPath(namedItem.Value);
                configuration = LoadFromFile(filename);
                if (configuration != null)
                {
                    CacheDependency dependencies = new CacheDependency(filename);
                    HttpRuntime.Cache.Add(_cacheName, configuration, dependencies, DateTime.Now.AddHours(1.0), TimeSpan.Zero, CacheItemPriority.Normal, null);
                }
            }
            if (configuration == null)
            {
                configuration = LoadFromNode(section);
                HttpRuntime.Cache.Add(_cacheName, configuration, null, DateTime.Now.AddHours(1.0), TimeSpan.Zero, CacheItemPriority.Normal, null);
            }
            return(configuration);
        }
        private static void ReadErrorHandler(XmlNode node, RewriterConfiguration config)
        {
            string code = node.GetRequiredAttribute(Constants.AttrCode);

            XmlNode typeNode = node.Attributes[Constants.AttrType];
            XmlNode urlNode  = node.Attributes[Constants.AttrUrl];

            if (typeNode == null && urlNode == null)
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrUrl), node);
            }

            IRewriteErrorHandler handler = null;

            if (typeNode != null)
            {
                // <error-handler code="500" url="/oops.aspx" />
                handler = TypeHelper.Activate(typeNode.Value, null) as IRewriteErrorHandler;
                if (handler == null)
                {
                    throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.InvalidTypeSpecified, typeNode.Value, typeof(IRewriteErrorHandler)), node);
                }
            }
            else
            {
                handler = new DefaultErrorHandler(urlNode.Value);
            }

            int statusCode;

            if (!Int32.TryParse(code, out statusCode))
            {
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.InvalidHttpStatusCode, code), node);
            }

            config.ErrorHandlers.Add(statusCode, handler);
        }
 /// <summary>
 /// Parses the node.
 /// </summary>
 /// <param name="node">The node to parse.</param>
 /// <param name="config">The rewriter configuration.</param>
 /// <returns>The parsed action, or null if no action parsed.</returns>
 public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
 {
     return new MethodNotAllowedAction();
 }
 /// <summary>
 /// Parses the node.
 /// </summary>
 /// <param name="node">The node to parse.</param>
 /// <param name="config">The rewriter configuration.</param>
 /// <returns>The parsed action, or null if no action parsed.</returns>
 public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
 {
     return new ForbiddenAction();
 }
 /// <summary>
 ///     Parses the action.
 /// </summary>
 /// <param name="node">The node to parse.</param>
 /// <param name="config">The rewriter configuration.</param>
 /// <returns>The parsed action, null if no action parsed.</returns>
 public abstract IRewriteAction Parse(XmlNode node, RewriterConfiguration config);
        private static void ReadErrorHandler(XmlNode node, RewriterConfiguration config)
		{
			XmlNode codeNode = node.Attributes[Constants.AttrCode];
			if (codeNode == null)
			{
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrCode), node);
			}

			XmlNode typeNode = node.Attributes[Constants.AttrType];
			XmlNode urlNode = node.Attributes[Constants.AttrUrl];
			if (typeNode == null && urlNode == null)
			{
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrUrl), node);
			}

			IRewriteErrorHandler handler = null;
			if (typeNode != null)
			{
				// <error-handler code="500" url="/oops.aspx" />
				handler = TypeHelper.Activate(typeNode.Value, null) as IRewriteErrorHandler;
				if (handler == null)
				{
                    throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.InvalidTypeSpecified));
				}
			}
			else
			{
				handler = new DefaultErrorHandler(urlNode.Value);
			}

			config.ErrorHandlers.Add(Convert.ToInt32(codeNode.Value), handler);
		}
		private static void ReadRegisterTransform(XmlNode node, RewriterConfiguration config)
		{
			// Type attribute.
			XmlNode typeNode = node.Attributes[Constants.AttrTransform];
			if (typeNode == null)
			{
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrTransform), node);
			}

			if (node.ChildNodes.Count > 0)
			{
                throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
			}

			// Transform type specified.  Create an instance and add it
			// as the mapper handler for this map.
			IRewriteTransform handler = TypeHelper.Activate(typeNode.Value, null) as IRewriteTransform;
			if (handler != null)
			{
				config.TransformFactory.AddTransform(handler);
			}
			else
			{
				// TODO: Error due to type.
			}
		}
        private static void ReadRegisterParser(XmlNode node, RewriterConfiguration config)
        {
            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(
                    MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
            }

            string type = node.GetRequiredAttribute(Constants.AttrParser);

            object parser = TypeHelper.Activate(type, null);
            var actionParser = parser as IRewriteActionParser;
            if (actionParser != null)
            {
                config.ActionParserFactory.AddParser(actionParser);
            }

            var conditionParser = parser as IRewriteConditionParser;
            if (conditionParser != null)
            {
                config.ConditionParserPipeline.AddParser(conditionParser);
            }
        }
        private static void ReadErrorHandler(XmlNode node, RewriterConfiguration config)
        {
            string code = node.GetRequiredAttribute(Constants.AttrCode);

            XmlNode typeNode = node.Attributes[Constants.AttrType];
            XmlNode urlNode = node.Attributes[Constants.AttrUrl];
            if (typeNode == null && urlNode == null)
            {
                throw new ConfigurationErrorsException(
                    MessageProvider.FormatString(Message.AttributeRequired, Constants.AttrUrl), node);
            }

            IRewriteErrorHandler handler = null;
            if (typeNode != null)
            {
                // <error-handler code="500" url="/oops.aspx" />
                handler = TypeHelper.Activate(typeNode.Value, null) as IRewriteErrorHandler;
                if (handler == null)
                {
                    throw new ConfigurationErrorsException(
                        MessageProvider.FormatString(Message.InvalidTypeSpecified, typeNode.Value,
                                                     typeof (IRewriteErrorHandler)), node);
                }
            }
            else
            {
                handler = new DefaultErrorHandler(urlNode.Value);
            }

            int statusCode;
            if (!Int32.TryParse(code, out statusCode))
            {
                throw new ConfigurationErrorsException(
                    MessageProvider.FormatString(Message.InvalidHttpStatusCode, code), node);
            }

            config.ErrorHandlers.Add(statusCode, handler);
        }
        private static void ReadMapping(XmlNode node, RewriterConfiguration config)
        {
            // Name attribute.
            XmlNode nameNode = node.Attributes[Constants.AttrName];

            // Mapper type not specified.  Load in the hash map.
            var map = new StringDictionary();
            foreach (XmlNode mapNode in node.ChildNodes)
            {
                if (mapNode.NodeType == XmlNodeType.Element)
                {
                    if (mapNode.LocalName == Constants.ElementMap)
                    {
                        string fromValue = mapNode.GetRequiredAttribute(Constants.AttrFrom, true);
                        string toValue = mapNode.GetRequiredAttribute(Constants.AttrTo, true);

                        map.Add(fromValue, toValue);
                    }
                    else
                    {
                        throw new ConfigurationErrorsException(
                            MessageProvider.FormatString(Message.ElementNotAllowed, mapNode.LocalName), node);
                    }
                }
            }

            config.TransformFactory.AddTransform(new StaticMappingTransform(nameNode.Value, map));
        }
        private static void ReadRule(XmlNode node, RewriterConfiguration config)
        {
            bool parsed = false;
            IList<IRewriteActionParser> parsers = config.ActionParserFactory.GetParsers(node.LocalName);
            if (parsers != null)
            {
                foreach (IRewriteActionParser parser in parsers)
                {
                    if (!parser.AllowsNestedActions && node.ChildNodes.Count > 0)
                    {
                        throw new ConfigurationErrorsException(
                            MessageProvider.FormatString(Message.ElementNoElements, parser.Name), node);
                    }

                    if (!parser.AllowsAttributes && node.Attributes.Count > 0)
                    {
                        throw new ConfigurationErrorsException(
                            MessageProvider.FormatString(Message.ElementNoAttributes, parser.Name), node);
                    }

                    IRewriteAction rule = parser.Parse(node, config);
                    if (rule != null)
                    {
                        config.Rules.Add(rule);
                        parsed = true;
                        break;
                    }
                }
            }

            if (!parsed)
            {
                // No parsers recognised to handle this node.
                throw new ConfigurationErrorsException(
                    MessageProvider.FormatString(Message.ElementNotAllowed, node.LocalName), node);
            }
        }
        private static void ReadRegisterLogger(XmlNode node, RewriterConfiguration config)
        {
            if (node.ChildNodes.Count > 0)
            {
                throw new ConfigurationErrorsException(
                    MessageProvider.FormatString(Message.ElementNoElements, Constants.ElementRegister), node);
            }

            string type = node.GetRequiredAttribute(Constants.AttrLogger);

            // Logger type specified.  Create an instance and add it
            // as the mapper handler for this map.
            var logger = TypeHelper.Activate(type, null) as IRewriteLogger;
            if (logger != null)
            {
                config.Logger = logger;
            }
        }
 /// <summary>
 /// Parses the node.
 /// </summary>
 /// <param name="node">The node to parse.</param>
 /// <param name="config">The rewriter configuration.</param>
 /// <returns>The parsed action, or null if no action parsed.</returns>
 public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
 {
     return new NotImplementedAction();
 }