IEnumerable<XmlNode> DoParseTag(ITemplateParsingState templateParsingState, IDictionary<string, object> getParameters, XmlElement element) { // Generate the xml StringBuilder xml = new StringBuilder( string.Format("<html xmlns=\"{0}\"><head></head><body>", templateParsingState.TemplateDocument.FirstChild.NamespaceURI), element.OuterXml.Length); foreach (XmlNode xmlNode in element.ChildNodes) if (xmlNode is XmlText) xml.Append(((XmlText)xmlNode).InnerText); else xml.Append(xmlNode.OuterXml); xml.Append("</body></html>"); XmlDocument xmlDocument; try { xmlDocument = templateParsingState.LoadXmlDocument( xml.ToString(), templateParsingState.GetXmlParseMode(element), element.OuterXml); } catch (WebResultsOverrideException wroe) { templateParsingState.ReplaceNodes( element, templateParsingState.GenerateWarningNode(wroe.WebResults.ResultsAsString)); return new XmlNode[0]; } // import the new tags IEnumerable<XmlNode> importedNodes = Enumerable<XmlNode>.FastCopy(Enumerable<XmlNode>.Cast( xmlDocument.FirstChild.ChildNodes[1].ChildNodes)); templateParsingState.ReplaceNodes(element, importedNodes); return importedNodes; }
private void LoadComponent( ITemplateParsingState templateParsingState, IDictionary<string, object> getParameters, XmlElement element) { XmlAttribute srcAttribute = (XmlAttribute)element.Attributes.GetNamedItem("src", templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace); XmlAttribute urlAttribute = (XmlAttribute)element.Attributes.GetNamedItem("url", templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace); // handle GET parameters // First, handle oc:getpassthrough IDictionary<string, object> myGetParameters; XmlAttribute getpassthroughAttribute = (XmlAttribute)element.Attributes.GetNamedItem("getpassthough", templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace); if (null == getpassthroughAttribute) { myGetParameters = DictionaryFunctions.Create<string, object>(getParameters); myGetParameters.Remove("Method"); myGetParameters.Remove("Action"); } else { if ("false" == getpassthroughAttribute.Value) myGetParameters = new Dictionary<string, object>(); else { myGetParameters = DictionaryFunctions.Create<string, object>(getParameters); myGetParameters.Remove("Method"); myGetParameters.Remove("Action"); } } // Next, pull out get parameters from the tag foreach (XmlAttribute attribute in element.Attributes) if ("" == attribute.NamespaceURI) myGetParameters[attribute.LocalName] = attribute.Value; if ((null == srcAttribute) && (null == urlAttribute)) // Remove empty components element.ParentNode.RemoveChild(element); else if ((null != srcAttribute) && (null != urlAttribute)) templateParsingState.ReplaceNodes( element, templateParsingState.GenerateWarningNode("Either oc:src or oc:url can be specified; you can not choose both: " + element.OuterXml)); else if (null != srcAttribute) { string fileName = templateParsingState.FileHandlerFactoryLocator.FileSystemResolver.GetAbsolutePath( templateParsingState.GetCWD(element), srcAttribute.Value); IFileContainer fileContainer; try { fileContainer = templateParsingState.FileHandlerFactoryLocator.FileSystemResolver.ResolveFile(fileName); } catch (FileDoesNotExist fdne) { log.Warn("An attempt was made to use a non-existant file in a template", fdne); templateParsingState.ReplaceNodes( element, templateParsingState.GenerateWarningNode(fileName + " not found")); return; } templateParsingState.WebConnection.TouchedFiles.Add(fileContainer); // If the user doesn't have permission for the component and the component has something to use instead, use it if (null == fileContainer.LoadPermission(templateParsingState.WebConnection.Session.User.Id) && element.HasChildNodes) { XmlNode replacement = element.OwnerDocument.CreateElement("div"); foreach (XmlNode errorNode in element.ChildNodes) replacement.AppendChild(errorNode); element.ParentNode.InsertAfter(replacement, element); element.ParentNode.RemoveChild(element); } else { // If the user has permission, resolve the component and deal with default errors XmlDocument componentDocument; // TODO: GET Parameters try { componentDocument = templateParsingState.LoadXmlDocumentAndReplaceGetParameters( myGetParameters, fileContainer, templateParsingState.GetXmlParseMode(element)); XmlNode firstChild = componentDocument.FirstChild; XmlNodeList replacementNodes; if ((firstChild.LocalName == "componentdef") && (firstChild.NamespaceURI == templateParsingState.TemplateHandlerLocator.TemplatingConstants.TemplateNamespace)) replacementNodes = firstChild.ChildNodes; else replacementNodes = componentDocument.ChildNodes; templateParsingState.SetCWD(replacementNodes, fileContainer.ParentDirectoryHandler.FileContainer.FullPath); templateParsingState.ReplaceNodes(element, replacementNodes); } catch (WebResultsOverrideException wroe) { templateParsingState.ReplaceNodes( element, templateParsingState.GenerateWarningNode(wroe.WebResults.ResultsAsString)); } catch (Exception e) { log.Error("An error occured when loading a component", e); templateParsingState.ReplaceNodes( element, templateParsingState.GenerateWarningNode("An unhandled error occured. See the system logs for more information")); } } } else if (null != urlAttribute) { XmlNode resultNode; string url = urlAttribute.Value; foreach (KeyValuePair<string, object> getParameter in myGetParameters) url = HTTPStringFunctions.AppendGetParameter(url, getParameter.Key, getParameter.Value.ToString()); try { if (url.StartsWith("https://")) resultNode = templateParsingState.GenerateWarningNode("https component nodes aren't supported due to certificate complexities"); else if (url.StartsWith("http://")) { HttpResponseHandler httpResponse = templateParsingState.WebConnection.Session.HttpWebClient.Get(url); if ("text/xml" == httpResponse.ContentType) resultNode = templateParsingState.LoadXmlDocument("<html xmlns=\"" + templateParsingState.TemplateHandlerLocator.TemplatingConstants.HtmlNamespace + "\"><head></head><body>" + httpResponse.AsString() + "</body></html>", XmlParseMode.Xml, templateParsingState.GetCWD(element)).FirstChild.ChildNodes[1]; else resultNode = element.OwnerDocument.CreateTextNode(httpResponse.AsString()); } else try { ShellWebConnection shellWebConnection = new BlockingShellWebConnection( url, templateParsingState.WebConnection, null, templateParsingState.WebConnection.CookiesFromBrowser); IWebResults shellResults = shellWebConnection.GenerateResultsForClient(); if ("text/xml" == shellResults.ContentType) resultNode = templateParsingState.LoadXmlDocument("<html xmlns=\"" + templateParsingState.TemplateHandlerLocator.TemplatingConstants.HtmlNamespace + "\"><head></head><body>" + shellResults.ResultsAsString + "</body></html>", XmlParseMode.Xml, templateParsingState.GetCWD( element)).FirstChild.ChildNodes[1]; else resultNode = element.OwnerDocument.CreateTextNode(shellResults.ResultsAsString); } catch (WebResultsOverrideException wroe) { resultNode = templateParsingState.GenerateWarningNode(wroe.WebResults.ResultsAsString); } } catch (Exception e) { log.Error("An error occured when loading a component", e); resultNode = templateParsingState.GenerateWarningNode("An unhandled error occured. See the system logs for more information"); } templateParsingState.ReplaceNodes(element, resultNode); } }