예제 #1
0
        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);
            }
        }