/// <summary>
			/// Create a <see cref="Column"/> instance.
			/// </summary>
			/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
			/// <returns>Returns the created <see cref="Column"/>.</returns>
			protected override Column Create(IMansionWebContext context)
			{
				return new ExpressionColumn(GetAttributes(context))
				       {
				       	epxression = expressionScriptService.Parse(context, new LiteralResource(GetRequiredAttribute<string>(context, "expression")))
				       };
			}
        /// <summary>
        /// Executes the handler within the given <paramref name="context"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/> in which to execute the current request.</param>
        /// <param name="outputPipe">The <see cref="WebOutputPipe"/> to which the must should be written.</param>
        protected override void DoExecute(IMansionWebContext context, WebOutputPipe outputPipe)
        {
            // retrieve the resource
            var originalResourcePath = context.Request.RequestUrl.Path.Substring(Prefix.Length + 1);
            var resourcePath = new RelativeResourcePath(originalResourcePath, true);

            // set output pipe properties
            outputPipe.Response.ContentType = WebUtilities.GetMimeType(originalResourcePath);
            outputPipe.Encoding = Encoding.UTF8;

            // if the resource does not exist, send a 404
            if (!resourceService.Exists(context, resourcePath))
            {
                // send 404
                outputPipe.Response.StatusCode = HttpStatusCode.NotFound;
                outputPipe.Response.StatusDescription = "Not Found";
                return;
            }

            // merge all the resources
            foreach (var resource in resourceService.Get(context, resourcePath))
            {
                // parse the resource script
                var script = scriptService.Parse(context, resource);

                // execute the script and write the result back to the output pipe
                outputPipe.Writer.Write(script.Execute<string>(context));
            }

            // set expires header age
            outputPipe.Response.CacheSettings.Expires = DateTime.Now.AddYears(1);
        }
        /// <summary>
        /// Executes the handler within the given <paramref name="context"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/> in which to execute the current request.</param>
        /// <param name="outputPipe">The <see cref="WebOutputPipe"/> to which the must should be written.</param>
        protected override void DoExecute(IMansionWebContext context, WebOutputPipe outputPipe)
        {
            // retrieve the resource
            var originalResourcePath = context.Request.RequestUrl.Path.Substring(Prefix.Length + 1);
            var resourcePath = new RelativeResourcePath(originalResourcePath, false);

            // set output pipe properties
            outputPipe.Response.ContentType = WebUtilities.GetMimeType(originalResourcePath);
            outputPipe.Encoding = Encoding.UTF8;

            // if the resource exist process it otherwise 404
            if (!resourceService.Exists(context, resourcePath))
            {
                // send 404
                outputPipe.Response.StatusCode = HttpStatusCode.NotFound;
                outputPipe.Response.StatusDescription = "Not Found";
                return;
            }

            // parse the resource script
            var resource = resourceService.GetSingle(context, resourcePath);

            // stream the file
            using (var reader = resource.OpenForReading())
                reader.RawStream.CopyTo(outputPipe.RawStream);

            // set expires header age
            outputPipe.Response.CacheSettings.Expires = DateTime.Now.AddYears(1);
        }
		/// <summary>
		/// Validates the state of this control.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="form">The <see cref="Form"/> to which this control belongs.</param>
		/// <param name="results">The <see cref="ValidationResults"/> in which the validation results are stored.</param>
		protected override void DoValidate(IMansionWebContext context, Form form, ValidationResults results)
		{
			// loop over all the controls
			foreach (var control in FormControls)
				control.Validate(context, form, results);
			base.DoValidate(context, form, results);
		}
			/// <summary>
			/// Create a <see cref="Column"/> instance.
			/// </summary>
			/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
			/// <returns>Returns the created <see cref="Column"/>.</returns>
			protected override Column Create(IMansionWebContext context)
			{
				return new PropertyColumn(GetAttributes(context))
				       {
				       	propertyName = GetRequiredAttribute<string>(context, "propertyName")
				       };
			}
        /// <summary>
        /// Generates a URL for <paramref name="node"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/>.</param>
        /// <param name="node">The <see cref="Node"/> for which to generate the URL.</param>
        /// <returns>Returns the generated <see cref="Url"/>.</returns>
        public Url Generate(IMansionWebContext context, Node node)
        {
            // validate arguments
            if (context == null)
                throw new ArgumentNullException("context");
            if (node == null)
                throw new ArgumentNullException("node");

            // initialize the service
            Initialize(context);

            // get the node type
            var nodeType = typeService.Load(context, node.Pointer.Type);

            // get the generator
            NodeUrlGenerator generator;
            if (!generators.TryGetValue(nodeType, out generator))
                throw new InvalidOperationException(string.Format("Could not find url generator for type {0}, does the type exist?", nodeType.Name));

            // construct the base url
            var url = Url.CreateUrl(context);

            // generate the url
            generator.Generate(context, node, nodeType, url);

            // return the generated uri
            return url;
        }
		/// <summary>
		/// Renders the header of the column on which this sorter is working.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="templateService">The <see cref="ITemplateService"/>.</param>
		/// <param name="dataset">The <see cref="Dataset"/> rendered in this column.</param>
		/// <exception cref="ArgumentNullException">Thrown if one of the parameters is null.</exception>
		public void RenderHeader(IMansionWebContext context, ITemplateService templateService, Dataset dataset)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (templateService == null)
				throw new ArgumentNullException("templateService");
			if (dataset == null)
				throw new ArgumentNullException("dataset");

			// determine if this column sort is active
			var activeSort = dataset.Sorts.FirstOrDefault();

			// check if there is an active sort
			var active = false;
			var ascending = false;
			if (activeSort != null && PropertyName.Equals(activeSort.PropertyName, StringComparison.OrdinalIgnoreCase))
			{
				active = true;
				ascending = activeSort.Ascending;
			}

			// create the sort properties
			var properties = new PropertyBag
			                 {
			                 	{"active", active},
			                 	{"direction", ascending},
			                 	{"sortParameter", PropertyName + " " + (ascending ? "desc" : "asc")}
			                 };

			using (context.Stack.Push("ColumnSortProperties", properties))
				templateService.Render(context, "GridControl" + GetType().Name + "Header").Dispose();
		}
		/// <summary>
		/// Handels the incomming CKFinder command.
		/// </summary>
		/// <param name="context">The incoming <see cref="IMansionWebContext"/>.</param>
		/// <param name="response"> </param>
		/// <exception cref="ConnectorException">Thrown when an error occured while handling the command.</exception>
		public void Handle(IMansionWebContext context, WebResponse response)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (response == null)
				throw new ArgumentNullException("response");

			try
			{
				//set values
				Request = context.Request;
				Response = response;

				// get the upload service
				AssetService = context.Nucleus.ResolveSingle<IAssetService>();

				// get the asset type
				AssetType = AssetService.ParseResourceType(context, Request.RequestUrl.QueryString["type"] ?? string.Empty);

				// get the current folder
				CurrentAssetFolder = AssetService.ParseFolder(context, AssetType, Request.RequestUrl.QueryString["currentFolder"] ?? "/");

				// invoke concrete implementation
				DoHandle(context);
			}
			catch (ThreadAbortException)
			{
				// thread is aborted, so don't throw any new exceptions
			}
			catch (Exception)
			{
				throw new ConnectorException(ErrorCodes.Unknown);
			}
		}
		/// <summary>
		/// Maps the properties of the row.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="row">The row which to map.</param>
		/// <returns>Returns the mapped result.</returns>
		protected override IPropertyBag DoMapRowProperties(IMansionWebContext context, IPropertyBag row)
		{
			return new PropertyBag
			       {
			       	{"value", row.Get(context, valueProperty, string.Empty)},
			       	{"label", row.Get(context, labelProperty, string.Empty)}
			       };
		}
		/// <summary>
		/// Processes the <paramref name="step"/> after the <paramref name="form"/> is submitted back to the server with valid data.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="form">The <see cref="Form"/>.</param>
		/// <param name="step">The <see cref="Step"/>.</param>
		protected override void Process(IMansionWebContext context, Form form, Step step)
		{
			// filter on actions
			if (actions.Count != 0 && !actions.Contains(form.State.CurrentAction))
				return;

			action(context, form, step);
		}
		/// <summary>
		/// Render this control.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="templateService">The <see cref="ITemplateService"/>.</param>
		protected override void DoRender(IMansionWebContext context, ITemplateService templateService)
		{
			// loop over all the controls and render them
			using (templateService.Render(context, GetType().Name + "Control"))
			{
				foreach (var control in Controls)
					control.Render(context, templateService);
			}
		}
 /// <summary>
 /// Gets the content which to add to the message.
 /// </summary>
 /// <param name="context">The <see cref="IMansionWebContext"/>.</param>
 /// <returns>Returns the content.</returns>
 protected override string GetContent(IMansionWebContext context)
 {
     // get the content
     var content = new StringBuilder();
     using (var pipe = new StringOutputPipe(content))
     using (context.OutputPipeStack.Push(pipe))
         ExecuteChildTags(context);
     return content.ToString();
 }
		/// <summary>
		/// Maps the properties of the row.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="row">The row which to map.</param>
		/// <returns>Returns the mapped result.</returns>
		public IPropertyBag Map(IMansionWebContext context, IPropertyBag row)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (row == null)
				throw new ArgumentNullException("row");
			return DoMapRowProperties(context, row);
		}
		/// <summary>
		/// Loads the <see cref="FormState"/> of a particular <paramref name="form"/> from the <paramref name="context"/>.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="form">The <see cref="Form"/> for which to load the state.</param>
		/// <returns>Returns the loaded <see cref="FormState"/>.</returns>
		public FormState LoadState(IMansionWebContext context, Form form)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (form == null)
				throw new ArgumentNullException("form");
			return DoLoadState(context, form);
		}
        /// <summary>
        /// Allows the configuration of the given <paramref name="handler"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/>.</param>
        /// <param name="handler">The <see cref="RequestHandler"/> selected to handle the request.</param>
        /// <exception cref="ArgumentNullException">Thrown if one of the parameters is null.</exception>
        public void Configure(IMansionWebContext context, RequestHandler handler)
        {
            // validate arguments
            if (context == null)
                throw new ArgumentNullException("context");
            if (handler == null)
                throw new ArgumentNullException("handler");

            // invoke template method
            DoConfigure(context, handler);
        }
		/// <summary>
		/// Handels the incomming CKFinder command.
		/// </summary>
		/// <param name="context">The incoming <see cref="IMansionWebContext"/>.</param>
		/// <param name="connectorNode">The <see cref="XElement"/> of the connector node.</param>
		/// <param name="currentFolderElement">The <see cref="XElement"/> of the current folder node.</param>
		/// <exception cref="ConnectorException">Thrown when an error occured while handling the command.</exception>
		protected override void DoHandle(IMansionWebContext context, XElement connectorNode, XElement currentFolderElement)
		{
			// get the new folder name
			var folderName = (Request.RequestUrl.QueryString["newFolderName"] ?? string.Empty);

			// create the folder
			var createdFolder = AssetService.CreateFolder(context, CurrentAssetFolder, folderName);

			// append the new folder response
			connectorNode.Append(new XElement("NewFolder")).SetAttributeValue("name", createdFolder.Label);
		}
		/// <summary>
		/// Stores the <see cref="FormState"/> of a particular <paramref name="form"/> in the <paramref name="context"/>.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="form">The <see cref="Form"/> for which to store the state.</param>
		/// <param name="state">The <see cref="FormState"/> which to save.</param>
		public void StoreState(IMansionWebContext context, Form form, FormState state)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (form == null)
				throw new ArgumentNullException("form");
			if (state == null)
				throw new ArgumentNullException("state");
			DoStoreState(context, form, state);
		}
        /// <summary>
        /// Constructs a route <see cref="Url"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/>.</param>
        /// <param name="controller">The name of the controller.</param>
        /// <param name="action">The name of the action.</param>
        /// <param name="parammeters">The parameters.</param>
        /// <returns>Returnt the <see cref="Url"/> for the route.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/>, <paramref name="controller"/> or <paramref name="action"/> is null.</exception>
        public static Url BuildRoute(IMansionWebContext context, string controller, string action, params string[] parammeters)
        {
            // validate arguments
            if (context == null)
                throw new ArgumentNullException("context");
            if (string.IsNullOrEmpty(controller))
                throw new ArgumentNullException("controller");
            if (string.IsNullOrEmpty(action))
                throw new ArgumentNullException("action");

            return AssembleRoute(context, new[] {controller, action}, parammeters);
        }
		/// <summary>
		/// Renders a cell of this column.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="templateService">The <see cref="ITemplateService"/>.</param>
		/// <param name="dataset">The <see cref="Dataset"/> rendered in this column.</param>
		/// <param name="row">The being rendered.</param>
		protected override void DoRenderCell(IMansionWebContext context, ITemplateService templateService, Dataset dataset, IPropertyBag row)
		{
			// create the cell properties
			var cellProperties = new PropertyBag
			                     {
			                     	{"value", epxression.Execute<object>(context)}
			                     };

			// render the cell
			using (context.Stack.Push("CellProperties", cellProperties))
				templateService.Render(context, "GridControlExpressionColumnContent").Dispose();
		}
        /// <summary>
        /// Executes the handler within the given <paramref name="context"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/> in which to execute the current request.</param>
        /// <returns>Returns the <see cref="WebResponse"/>.</returns>
        protected override WebResponse DoExecute(IMansionWebContext context)
        {
            // create a new response
            var response = WebResponse.Create(context);

            // retrieve the resource
            var originalResourcePath = context.Request.RequestUrl.Path.Substring(Prefix.Length + 1);

            // split the path
            var pathParts = originalResourcePath.Split(Dispatcher.Constants.UrlPartTrimCharacters, StringSplitOptions.RemoveEmptyEntries);

            // parse the path
            var contentPath = contentService.ParsePath(context, new PropertyBag {
                {"category", pathParts[0]},
                {"relativePath", string.Join(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), pathParts)}
            });

            // if the resource exist process it otherwise 404
            if (!contentService.Exists(context, contentPath))
            {
                // send 404
                response.StatusCode = HttpStatusCode.NotFound;
                response.StatusDescription = "Not Found";
                return response;
            }

            // get the resource
            var resource = contentService.GetResource(context, contentPath);
            var len = resource.Length;

            // set the headers
            response.Headers.Add("Content-Length", len.ToString(CultureInfo.InvariantCulture));
            response.ContentType = WebUtilities.GetMimeType(originalResourcePath);

            // set the content response
            response.Contents = stream => {
                // stream the file
                var buffer = new byte[1024];
                using (var reader = resource.OpenForReading())
                {
                    int bytes;
                    while (len > 0 && (bytes = reader.RawStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        stream.Write(buffer, 0, bytes);
                        len -= bytes;
                    }
                }
            };

            // return the response
            return response;
        }
        /// <summary>
        /// Executes the handler within the given <paramref name="context"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/> in which to execute the current request.</param>
        /// <returns>Returns the <see cref="WebResponse"/>.</returns>
        protected override WebResponse DoExecute(IMansionWebContext context)
        {
            // create the response
            var response = WebResponse.Create(context);

            // create an web output pipe, push it to the stack and allow implementors to process the request on it
            using (var outputPipe = new WebOutputPipe(response))
            using (context.OutputPipeStack.Push(outputPipe))
                DoExecute(context, outputPipe);

            // return the response
            return response;
        }
Exemple #22
0
		/// <summary>
		/// Renders the header of this column.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="templateService">The <see cref="ITemplateService"/>.</param>
		/// <param name="dataset">The <see cref="Dataset"/> rendered in this column.</param>
		public void RenderHeaderFilter(IMansionWebContext context, ITemplateService templateService, Dataset dataset)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (templateService == null)
				throw new ArgumentNullException("templateService");
			if (dataset == null)
				throw new ArgumentNullException("dataset");

			// invoke template method
			DoRenderHeaderFilter(context, templateService, dataset);
		}
        /// <summary>
        /// Constructs a backoffice route <see cref="Url"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/>.</param>
        /// <param name="area">The area.</param>
        /// <param name="controller">The name of the controller.</param>
        /// <param name="action">The name of the action.</param>
        /// <param name="nodeId">The node id.</param>
        /// <param name="parammeters">The parameters.</param>
        /// <returns>Returnt the <see cref="Url"/> for the route.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/>, <paramref name="area"/>, <paramref name="controller"/> or <paramref name="action"/> is null.</exception>
        public static Url BuildBackofficeRouteWithArea(IMansionWebContext context, string area, string controller, string action, int nodeId, params string[] parammeters)
        {
            // validate arguments
            if (context == null)
                throw new ArgumentNullException("context");
            if (string.IsNullOrEmpty(area))
                throw new ArgumentNullException("area");
            if (string.IsNullOrEmpty(controller))
                throw new ArgumentNullException("controller");
            if (string.IsNullOrEmpty(action))
                throw new ArgumentNullException("action");

            return AssembleRoute(context, new[] {area, controller, action}, parammeters, nodeId, true);
        }
		/// <summary>
		/// Execute the <see cref="Action"/>s on this object..
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="form">The <see cref="Form"/>.</param>
		/// <param name="step">The <see cref="Step"/>.</param>
		protected static void ExecuteActions(IMansionWebContext context, Form form, Step step)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (form == null)
				throw new ArgumentNullException("form");

			// first execute actions on step
			step.DoExecuteActions(context, form, step);

			// finally execute actions on form
			form.DoExecuteActions(context, form, step);
		}
		/// <summary>
		/// Handels the incomming CKFinder command.
		/// </summary>
		/// <param name="context">The incoming <see cref="IMansionWebContext"/>.</param>
		/// <param name="connectorNode">The <see cref="XElement"/> of the connector node.</param>
		/// <param name="currentFolderElement">The <see cref="XElement"/> of the current folder node.</param>
		/// <exception cref="ConnectorException">Thrown when an error occured while handling the command.</exception>
		protected override void DoHandle(IMansionWebContext context, XElement connectorNode, XElement currentFolderElement)
		{
			// create the folder element
			var foldersElement = connectorNode.Append(new XElement("Folders"));

			// loop over all the folders beneath the current folder
			foreach (var child in AssetService.RetrieveFolders(context, CurrentAssetFolder))
			{
				var folderElement = foldersElement.Append(new XElement("Folder"));
				folderElement.SetAttributeValue("name", child.Label);
				folderElement.SetAttributeValue("hasChildren", true);
				folderElement.SetAttributeValue("acl", GetACLMask(child));
			}
		}
		/// <summary>
		/// Handels the incomming CKFinder command.
		/// </summary>
		/// <param name="context">The incoming <see cref="IMansionWebContext"/>.</param>
		/// <param name="connectorNode">The <see cref="XElement"/> of the connector node.</param>
		/// <exception cref="ConnectorException">Thrown when an error occured while handling the command.</exception>
		protected override sealed void DoHandle(IMansionWebContext context, XElement connectorNode)
		{
			// set the resource type attribtute
			connectorNode.SetAttributeValue("resourceType", AssetType.Label);

			// add current folder
			var currentFolderElement = connectorNode.Append(new XElement("CurrentFolder"));
			currentFolderElement.SetAttributeValue("path", CurrentAssetFolder.Path);
			currentFolderElement.SetAttributeValue("url", FormatUri(CurrentAssetFolder.Url));
			currentFolderElement.SetAttributeValue("acl", GetACLMask(CurrentAssetFolder));

			// invoke the template method
			DoHandle(context, connectorNode, currentFolderElement);
		}
		/// <summary>
		/// Renders the header of this column.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="templateService">The <see cref="ITemplateService"/>.</param>
		/// <param name="dataset">The <see cref="Dataset"/> rendered in this column.</param>
		public void RenderHeader(IMansionWebContext context, ITemplateService templateService, Dataset dataset)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (templateService == null)
				throw new ArgumentNullException("templateService");
			if (dataset == null)
				throw new ArgumentNullException("dataset");

			// invoke the template
			using (context.Stack.Push("FilterProperties", Properties))
				DoRenderHeader(context, templateService, dataset);
		}
		/// <summary>
		/// Executes the validation rule.
		/// </summary>
		/// <param name="context">The <see cref="IMansionWebContext"/>.</param>
		/// <param name="form">The <see cref="Form"/> being validated.</param>
		/// <param name="control">The actual <see cref="FormControl"/> being validated.</param>
		/// <param name="results">The <see cref="ValidationResults"/> containing the validation results.</param>
		public void Validate(IMansionWebContext context, Form form, FormControl control, ValidationResults results)
		{
			// validate arguments
			if (context == null)
				throw new ArgumentNullException("context");
			if (form == null)
				throw new ArgumentNullException("form");
			if (control == null)
				throw new ArgumentNullException("control");
			if (results == null)
				throw new ArgumentNullException("results");

			// invoke template method
			DoValidate(context, form, control, results);
		}
        /// <summary>
        /// Executes the handler within the given <paramref name="context"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/> in which to execute the current request.</param>
        /// <returns>Returns the <see cref="WebResponse"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="context"/> is null.</exception>
        public WebResponse Execute(IMansionWebContext context)
        {
            // validate arguments
            if (context == null)
                throw new ArgumentNullException("context");

            // get the response from the before pipeline, or this request handler
            var response = BeforePipeline.Execute(context) ?? DoExecute(context);

            // finally execute the after pipeline
            AfterPipeline.Execute(context, response);

            // return the response
            return response;
        }
        /// <summary>
        /// Generates an URL for the <paramref name="node"/>.
        /// </summary>
        /// <param name="context">The <see cref="IMansionWebContext"/>.</param>
        /// <param name="node">The <see cref="Node"/> for which to generate the URL.</param>
        /// <param name="nodeType">The <see cref="ITypeDefinition"/> of the node.</param>
        /// <param name="url">The <see cref="Url"/> which to use to build the url.</param>
        public void Generate(IMansionWebContext context, Node node, ITypeDefinition nodeType, Url url)
        {
            // validate arguments
            if (context == null)
                throw new ArgumentNullException("context");
            if (node == null)
                throw new ArgumentNullException("node");
            if (nodeType == null)
                throw new ArgumentNullException("nodeType");
            if (url == null)
                throw new ArgumentNullException("url");

            // invoke template method
            DoGenerate(context, node, nodeType, url);
        }