/// <summary> Constructor for a new instance of the Web_Content_HtmlSubwriter class </summary>
        /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Static_Web_Content"> Object contains all the basic information about this info display </param>
        /// <param name="Site_Map"> Optional site map object used to render a navigational tree-view on left side of page</param>
        public Web_Content_HtmlSubwriter(Item_Aggregation Hierarchy_Object, SobekCM_Navigation_Object Current_Mode, SobekCM_Skin_Object HTML_Skin, HTML_Based_Content Static_Web_Content, SobekCM_SiteMap Site_Map)
        {
            base.Current_Aggregation = Hierarchy_Object;
            currentMode = Current_Mode;
            Skin = HTML_Skin;

            thisStaticBrowseObject = Static_Web_Content;
            siteMap = Site_Map;

            // If there is a sitemap, check if this is a robot request and then if the URL
            // for the sitemap pages is URL restricted
            if ((siteMap != null) && (siteMap.Is_URL_Restricted_For_Robots) && (currentMode.Is_Robot))
            {
                if (currentMode.Base_URL != siteMap.Restricted_Robot_URL)
                {
                    currentMode.Base_URL = siteMap.Restricted_Robot_URL;
                    string redirect_url = currentMode.Redirect_URL();

                    HttpContext.Current.Response.Status = "301 Moved Permanently";
                    HttpContext.Current.Response.AddHeader("Location", redirect_url);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                    currentMode.Request_Completed = true;
                    return;
                }
            }
        }
        /// <summary> Stores a site map navigational object for static web content pages </summary>
        /// <param name="StoreObject"> Sitemap object to be locally cached </param>
        /// <param name="SiteMap_File"> Name of the site map file which indicates the site map to retrieve from memory </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering</param>
        public static void Store_Site_Map( SobekCM_SiteMap StoreObject, string SiteMap_File, Custom_Tracer Tracer)
        {
            // If the cache is disabled, just return before even tracing
            if (Disabled)
                return;

            // Determine the key
            string key = "SITEMAP_" + SiteMap_File;

            // Store this on the local cache, if not there and storing on the cache server failed
            if (HttpContext.Current.Cache[key] == null)
            {
                if (Tracer != null)
                {
                    Tracer.Add_Trace("Cached_Data_Manager.Store_Site_Map", "Adding object '" + key + "' to the local cache with expiration of 3 minutes");
                }

                HttpContext.Current.Cache.Insert(key, StoreObject, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(3));
            }
        }
        /// <summary> Constructor for a new instance of the Text_MainWriter class </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
        /// <param name="Results_Statistics"> Information about the entire set of results for a search or browse </param>
        /// <param name="Paged_Results"> Single page of results for a search or browse, within the entire set </param>
        /// <param name="Browse_Object"> Object contains all the basic information about any browse or info display </param>
        /// <param name="Current_Item"> Current item to display </param>
        /// <param name="Current_Page"> Current page within the item</param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Current_User"> Currently logged on user </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Item_List"> Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Stats_Date_Range"> Object contains the start and end dates for the statistical data in the database </param>
        /// <param name="Search_History"> List of recent searches performed against this digital library </param>
        /// <param name="Icon_Dictionary"> Dictionary of information about every wordmark/icon in this digital library, used to build the wordmarks subpage </param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the main home page are organized </param>
        /// <param name="Public_Folder"> Object contains the information about the public folder to display </param>
        /// <param name="Aggregation_Aliases"> List of all existing aliases for existing aggregations </param>
        /// <param name="Web_Skin_Collection"> Collection of all the web skins </param>
        /// <param name="Checked_Items"> List of all items which are currently checked out for single fair use and the IP address currently viewing the item</param>
        /// <param name="IP_Restrictions"> Any possible restriction on item access by IP ranges </param>
        /// <param name="URL_Portals"> List of all web portals into this system </param>
        /// <param name="Site_Map"> Optional site map object used to render a navigational tree-view on left side of static web content pages </param>
        /// <param name="Items_In_Title"> List of items within the current title ( used for the Item Group display )</param>
        /// <param name="Static_Web_Content"> HTML content-based browse, info, or imple CMS-style web content objects.  These are objects which are read from a static HTML file and much of the head information must be maintained </param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        public Html_MainWriter(SobekCM_Navigation_Object Current_Mode,
            Item_Aggregation Hierarchy_Object,
            Search_Results_Statistics Results_Statistics,
            List<iSearch_Title_Result> Paged_Results,
            Item_Aggregation_Child_Page Browse_Object,
            SobekCM_Item Current_Item,
            Page_TreeNode Current_Page,
            SobekCM_Skin_Object HTML_Skin,
            User_Object Current_User,
            Language_Support_Info Translator,
            Aggregation_Code_Manager Code_Manager,
            Item_Lookup_Object Item_List,
            Statistics_Dates Stats_Date_Range,
            Recent_Searches Search_History,
            Dictionary<string, Wordmark_Icon> Icon_Dictionary,
            List<Thematic_Heading> Thematic_Headings,
            Public_User_Folder Public_Folder,
            Dictionary<string, string> Aggregation_Aliases,
            SobekCM_Skin_Collection Web_Skin_Collection,
            Checked_Out_Items_List Checked_Items,
            IP_Restriction_Ranges IP_Restrictions,
            Portal_List URL_Portals,
            SobekCM_SiteMap Site_Map,
            SobekCM_Items_In_Title Items_In_Title,
            HTML_Based_Content Static_Web_Content,
            Custom_Tracer Tracer )
            : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object,  Current_Item, Current_Page, Static_Web_Content)
        {
            // Save parameters
            htmlSkin = HTML_Skin;
            translator = Translator;
            codeManager = Code_Manager;
            itemList = Item_List;
            statsDateRange = Stats_Date_Range;
            searchHistory = Search_History;
            currentUser = Current_User;
            iconList = Icon_Dictionary;
            thematicHeadings = Thematic_Headings;
            publicFolder = Public_Folder;
            aggregationAliases = Aggregation_Aliases;
            webSkins = Web_Skin_Collection;
            checkedItems = Checked_Items;
            ipRestrictionInfo = IP_Restrictions;
            urlPortals = URL_Portals;
            siteMap = Site_Map;
            itemsInTitle = Items_In_Title;

            // Set some defaults

            // Handle basic events which may be fired by the internal header
            if (HttpContext.Current.Request.Form["internal_header_action"] != null)
            {
                // Pull the action value
                string internalHeaderAction = HttpContext.Current.Request.Form["internal_header_action"].Trim();

                // Was this to hide or show the header?
                if ((internalHeaderAction == "hide") || (internalHeaderAction == "show"))
                {
                    // Pull the current visibility from the session
                    bool shown = !((HttpContext.Current.Session["internal_header"] != null) && (HttpContext.Current.Session["internal_header"].ToString() == "hidden"));
                    if ((internalHeaderAction == "hide") && (shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "hidden";
                        currentMode.Redirect();
                        return;
                    }
                    if ((internalHeaderAction == "show") && (!shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "shown";
                        currentMode.Redirect();
                        return;
                    }
                }
            }

            try
            {

                // Create the html sub writer now
                switch (Current_Mode.Mode)
                {
                    case Display_Mode_Enum.Internal:
                        subwriter = new Internal_HtmlSubwriter(iconList, currentUser, codeManager);
                        break;

                    case Display_Mode_Enum.Statistics:
                        subwriter = new Statistics_HtmlSubwriter(searchHistory, codeManager, statsDateRange);
                        break;

                    case Display_Mode_Enum.Preferences:
                        subwriter = new Preferences_HtmlSubwriter(currentMode);
                        break;

                    case Display_Mode_Enum.Error:
                        subwriter = new Error_HtmlSubwriter(false);
                        // Send the email now
                        if (currentMode.Caught_Exception != null)
                        {
                            if (currentMode.Error_Message.Length == 0)
                                currentMode.Error_Message = "Unknown exception caught";
                            Email_Information(currentMode.Error_Message, currentMode.Caught_Exception, Tracer, false);
                        }
                        break;

                    case Display_Mode_Enum.Legacy_URL:
                        subwriter = new LegacyUrl_HtmlSubwriter();
                        break;

                    case Display_Mode_Enum.Item_Print:
                        subwriter = new Print_Item_HtmlSubwriter(currentItem, codeManager, translator, currentMode);
                        break;

                    case Display_Mode_Enum.Contact:

                        StringBuilder builder = new StringBuilder();
                        builder.Append("\n\nSUBMISSION INFORMATION\n");
                        builder.Append("\tDate:\t\t\t\t" + DateTime.Now.ToString() + "\n");
                        string lastMode = String.Empty;
                        try
                        {
                            if (HttpContext.Current.Session["Last_Mode"] != null)
                                lastMode = HttpContext.Current.Session["Last_Mode"].ToString();
                            builder.Append("\tIP Address:\t\t\t" + HttpContext.Current.Request.UserHostAddress + "\n");
                            builder.Append("\tHost Name:\t\t\t" + HttpContext.Current.Request.UserHostName + "\n");
                            builder.Append("\tBrowser:\t\t\t" + HttpContext.Current.Request.Browser.Browser + "\n");
                            builder.Append("\tBrowser Platform:\t\t" + HttpContext.Current.Request.Browser.Platform + "\n");
                            builder.Append("\tBrowser Version:\t\t" + HttpContext.Current.Request.Browser.Version + "\n");
                            builder.Append("\tBrowser Language:\t\t");
                            bool first = true;
                            string[] languages = HttpContext.Current.Request.UserLanguages;
                            if (languages != null)
                                foreach (string thisLanguage in languages)
                                {
                                    if (first)
                                    {
                                        builder.Append(thisLanguage);
                                        first = false;
                                    }
                                    else
                                    {
                                        builder.Append(", " + thisLanguage);
                                    }
                                }

                            builder.Append("\n\nHISTORY\n");
                            if (HttpContext.Current.Session["LastSearch"] != null)
                                builder.Append("\tLast Search:\t\t" + HttpContext.Current.Session["LastSearch"] + "\n");
                            if (HttpContext.Current.Session["LastResults"] != null)
                                builder.Append("\tLast Results:\t\t" + HttpContext.Current.Session["LastResults"] + "\n");
                            if (HttpContext.Current.Session["Last_Mode"] != null)
                                builder.Append("\tLast Mode:\t\t\t" + HttpContext.Current.Session["Last_Mode"] + "\n");
                            builder.Append("\tURL:\t\t\t\t" + HttpContext.Current.Items["Original_URL"]);
                        }
                        catch
                        {

                        }
                        subwriter = new Contact_HtmlSubwriter(lastMode, builder.ToString(), currentMode, hierarchyObject);
                        break;

                    case Display_Mode_Enum.Contact_Sent:
                        subwriter = new Contact_HtmlSubwriter(String.Empty, String.Empty, currentMode, hierarchyObject);
                        break;

                    case Display_Mode_Enum.Simple_HTML_CMS:
                        subwriter = new Web_Content_HtmlSubwriter(hierarchyObject, currentMode, htmlSkin, htmlBasedContent, siteMap);
                        break;

                    case Display_Mode_Enum.My_Sobek:
                        subwriter = new MySobek_HtmlSubwriter(results_statistics, paged_results, codeManager, itemList, hierarchyObject, htmlSkin, translator, currentMode, currentItem, currentUser, iconList, statsDateRange, webSkins, Tracer);
                        break;

                    case Display_Mode_Enum.Administrative:
                        subwriter = new Admin_HtmlSubwriter(codeManager, itemList, hierarchyObject, htmlSkin, translator, currentMode, aggregationAliases, webSkins, currentUser, ipRestrictionInfo, iconList, urlPortals, thematicHeadings, Tracer);
                        break;

                    case Display_Mode_Enum.Results:
                        subwriter = new Search_Results_HtmlSubwriter(results_statistics, paged_results, codeManager, translator, itemList, currentUser);
                        break;

                    case Display_Mode_Enum.Public_Folder:
                        subwriter = new Public_Folder_HtmlSubwriter(results_statistics, paged_results, codeManager, translator, itemList, currentUser, publicFolder);
                        break;

                    case Display_Mode_Enum.Search:
                    case Display_Mode_Enum.Aggregation:
                        subwriter = new Aggregation_HtmlSubwriter(hierarchyObject, currentMode, htmlSkin, translator, thisBrowseObject, results_statistics, paged_results, codeManager, itemList, thematicHeadings, currentUser, htmlBasedContent, Tracer);
                        break;

                    case Display_Mode_Enum.Item_Display:
                        if ((!currentMode.Invalid_Item) && (currentItem != null))
                        {
                            bool show_toc = false;
                            if (HttpContext.Current.Session["Show TOC"] != null)
                            {
                                Boolean.TryParse(HttpContext.Current.Session["Show TOC"].ToString(), out show_toc);
                            }

                            // Check that this item is not checked out by another user
                            bool itemCheckedOutByOtherUser = false;
                            if (currentItem.Behaviors.CheckOut_Required)
                            {
                                if (!checkedItems.Check_Out(currentItem.Web.ItemID, HttpContext.Current.Request.UserHostAddress))
                                {
                                    itemCheckedOutByOtherUser = true;
                                }
                            }

                            // Check to see if this is IP restricted
                            string restriction_message = String.Empty;
                            if (currentItem.Behaviors.IP_Restriction_Membership > 0)
                            {
                                if (HttpContext.Current != null)
                                {
                                    int user_mask = (int)HttpContext.Current.Session["IP_Range_Membership"];
                                    int comparison = currentItem.Behaviors.IP_Restriction_Membership & user_mask;
                                    if (comparison == 0)
                                    {
                                        int restriction = currentItem.Behaviors.IP_Restriction_Membership;
                                        int restriction_counter = 0;
                                        while (restriction % 2 != 1)
                                        {
                                            restriction = restriction >> 1;
                                            restriction_counter++;
                                        }
                                        restriction_message = ipRestrictionInfo[restriction_counter].Item_Restricted_Statement;
                                    }
                                }
                            }

                            // Create the item viewer writer
                            subwriter = new Item_HtmlSubwriter(currentItem, currentPage, currentUser, codeManager, translator, show_toc, (SobekCM_Library_Settings.JP2ServerUrl.Length > 0), currentMode, hierarchyObject, restriction_message, itemsInTitle, Tracer);
                            ((Item_HtmlSubwriter)subwriter).Item_Checked_Out_By_Other_User = itemCheckedOutByOtherUser;
                        }
                        else
                        {
                            // Create the invalid item html subwrite and write the HTML
                            subwriter = new Error_HtmlSubwriter(true);
                        }
                        break;

                }
            }
            catch (Exception ee)
            {
                // Send to the dashboard
                if ((HttpContext.Current.Request.UserHostAddress == "127.0.0.1") || (HttpContext.Current.Request.UserHostAddress == HttpContext.Current.Request.ServerVariables["LOCAL_ADDR"]) || (HttpContext.Current.Request.Url.ToString().IndexOf("localhost") >= 0))
                {
                    Tracer.Add_Trace("Html_MainWriter.Constructor", "Exception caught!", Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("Html_MainWriter.Constructor", ee.Message, Custom_Trace_Type_Enum.Error);
                    Tracer.Add_Trace("Html_MainWriter.Constructor", ee.StackTrace, Custom_Trace_Type_Enum.Error);

                    // Wrap this into the SobekCM Exception
                    SobekCM_Traced_Exception newException = new SobekCM_Traced_Exception("Exception caught while building the mode-specific HTML Subwriter", ee, Tracer);

                    // Save this to the session state, and then forward to the dashboard
                    HttpContext.Current.Session["Last_Exception"] = newException;
                    HttpContext.Current.Response.Redirect("dashboard.aspx", false);
                    Current_Mode.Request_Completed = true;

                    return;
                }
                else
                {
                    subwriter = new Error_HtmlSubwriter(false);
                }
            }

            if (subwriter != null)
            {
                subwriter.Mode = currentMode;
                subwriter.Skin = htmlSkin;
                subwriter.Current_Aggregation = hierarchyObject;
            }
        }
        /// <summary> Reads an existing site map file and returns the fully built <see cref="SobekCM_SiteMap" /> object </summary>
        /// <param name="SiteMap_File"> Sitemap file to read </param>
        /// <returns> Fully built sitemap object </returns>
        public static SobekCM_SiteMap Read_SiteMap_File(string SiteMap_File)
        {
            Stream reader = null;
            XmlTextReader nodeReader = null;
            SobekCM_SiteMap siteMap = null;
            int nodeValue = 1;

            Stack<SobekCM_SiteMap_Node> nodesStack = new Stack<SobekCM_SiteMap_Node>();

            try
            {
                // Create and open the readonly file stream
                reader = new FileStream(SiteMap_File, FileMode.Open, FileAccess.Read);

                // create the XML node reader
                nodeReader = new XmlTextReader(reader);

                // Read through the XML document
                while (nodeReader.Read())
                {
                    if (nodeReader.NodeType == XmlNodeType.Element)
                    {
                        // Handle the main sitemap tag
                        if (nodeReader.Name == "siteMap")
                        {
                            // This is the first node read, so it may have additional information
                            siteMap = new SobekCM_SiteMap();

                            // Look for the optional default breadcrumbs attribute
                            if (nodeReader.MoveToAttribute("default_breadcrumb"))
                            {
                                siteMap.Default_Breadcrumb = nodeReader.Value;
                            }

                            // Look for the optional width attribute
                            if (nodeReader.MoveToAttribute("width"))
                            {
                                short width;
                                Int16.TryParse(nodeReader.Value, out width);
                                siteMap.Width = width;
                            }

                            // Look for the optional url restriction attribute
                            if (nodeReader.MoveToAttribute("restrictedRobotUrl"))
                            {
                                siteMap.Restricted_Robot_URL = nodeReader.Value;
                            }
                        }

                        // Handle a new siteMapNode
                        if (nodeReader.Name == "siteMapNode")
                        {
                            string url = String.Empty;
                            string title = String.Empty;
                            string description = String.Empty;
                            bool empty = false;

                            // Before moving to any attributes, check to see if this is empty
                            if (nodeReader.IsEmptyElement)
                                empty = true;

                            // Step through the attributes
                            while (nodeReader.MoveToNextAttribute())
                            {
                                switch (nodeReader.Name)
                                {
                                    case "url":
                                        url = nodeReader.Value;
                                        break;

                                    case "title":
                                        title = nodeReader.Value;
                                        break;

                                    case "description":
                                        description = nodeReader.Value;
                                        break;
                                }
                            }

                            // Create the new node
                            SobekCM_SiteMap_Node newNode = new SobekCM_SiteMap_Node(url, title, description, nodeValue++);

                            // Add to the parent
                            if (nodesStack.Count == 0)
                            {
                                // This is the first node read so it should be the root node
                                if (siteMap != null) siteMap.RootNodes.Add(newNode);
                            }
                            else
                            {
                                nodesStack.Peek().Add_Child_Node(newNode);
                            }

                            // Add this to the stack, at least until the end of this node is found
                            // if this is not an empty element
                            if (!empty)
                                nodesStack.Push(newNode);
                        }
                    }
                    else if ((nodeReader.NodeType == XmlNodeType.EndElement) && ( nodeReader.Name == "siteMapNode" ))
                    {
                        nodesStack.Pop();
                    }
                }
            }
            finally
            {
                if (nodeReader != null)
                    nodeReader.Close();
                if (reader != null)
                    reader.Close();
            }

            return siteMap;
        }
        /// <summary> Gets the simple CMS/info object and text to display </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Base_Directory"> Base directory location under which the the CMS/info source file will be found</param>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <param name="Simple_Web_Content"> [OUT] Built browse object which contains information like title, banner, etc.. and the entire text to be displayed </param>
        /// <param name="Site_Map"> [OUT] Optional navigational site map object related to this page </param>
        /// <returns>TRUE if successful, otherwise FALSE </returns>
        /// <remarks> This always pulls the data directly from disk; this text is not cached. </remarks>
        public bool Get_Simple_Web_Content_Text(SobekCM_Navigation_Object Current_Mode, string Base_Directory, Custom_Tracer Tracer, out HTML_Based_Content Simple_Web_Content, out SobekCM_SiteMap Site_Map )
        {
            if (Tracer != null)
            {
                Tracer.Add_Trace("SobekCM_Assistant.Get_Simple_Web_Content_Text", String.Empty);
            }

            Site_Map = null;

            string source = Current_Mode.Page_By_FileName;
            Simple_Web_Content = HTML_Based_Content_Reader.Read_HTML_File(source, true, Tracer);

            if (Simple_Web_Content == null)
            {
                Current_Mode.Error_Message = "Unable to retrieve simple text item '" + Current_Mode.Info_Browse_Mode.Replace("_","\\") + "'";
                return false;
            }

            if ( Simple_Web_Content.Static_Text.Length == 0 )
            {
                Current_Mode.Error_Message = "Unable to read the file for display";
                return false;
            }

            // Now, check for any "server-side include" directorives in the source text
            int include_index = Simple_Web_Content.Static_Text.IndexOf("<%INCLUDE");
            while(( include_index > 0 ) && ( Simple_Web_Content.Static_Text.IndexOf("%>", include_index ) > 0 ))
            {
                int include_finish_index = Simple_Web_Content.Static_Text.IndexOf("%>", include_index) + 2;
                string include_statement = Simple_Web_Content.Static_Text.Substring(include_index, include_finish_index - include_index);
                string include_statement_upper = include_statement.ToUpper();
                int file_index = include_statement_upper.IndexOf("FILE");
                string filename_to_include = String.Empty;
                if (file_index > 0)
                {
                    // Pull out the possible file name
                    string possible_file_name = include_statement.Substring(file_index + 4);
                    int file_start = -1;
                    int file_end = -1;
                    int char_index = 0;

                    // Find the start of the file information
                    while ((file_start < 0) && (char_index < possible_file_name.Length))
                    {
                        if ((possible_file_name[char_index] != '"') && (possible_file_name[char_index] != '=') && (possible_file_name[char_index] != ' '))
                        {
                            file_start = char_index;
                        }
                        else
                        {
                            char_index++;
                        }
                    }

                    // Find the end of the file information
                    if (file_start >= 0)
                    {
                        char_index++;
                        while ((file_end < 0) && (char_index < possible_file_name.Length))
                        {
                            if ((possible_file_name[char_index] == '"') || (possible_file_name[char_index] == ' ') || (possible_file_name[char_index] == '%'))
                            {
                                file_end = char_index;
                            }
                            else
                            {
                                char_index++;
                            }
                        }
                    }

                    // Get the filename
                    if ((file_start > 0) && (file_end > 0))
                    {
                        filename_to_include = possible_file_name.Substring(file_start, file_end - file_start);
                    }
                }

                // Remove the include and either place in the text from the indicated file,
                // or just remove
                if ((filename_to_include.Length > 0 ) && (File.Exists(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + filename_to_include)))
                {
                    // Define the value for the include text
                    string include_text;

                    // Look in the cache for this
                    object returnValue = HttpContext.Current.Cache.Get("INCLUDE_" + filename_to_include );
                    if (returnValue != null)
                    {
                        include_text = returnValue.ToString();
                    }
                    else
                    {
                        try
                        {
                            // Pull from the file
                            StreamReader reader = new StreamReader(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + filename_to_include);
                            include_text = reader.ReadToEnd();
                            reader.Close();

                            // Store on the cache for two minutes, if no indication not to
                            if ( include_statement_upper.IndexOf("NOCACHE") < 0 )
                                HttpContext.Current.Cache.Insert("INCLUDE_" + filename_to_include, include_text, null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(2));
                        }
                        catch(Exception)
                        {
                            include_text = "Unable to read the soruce file ( " + filename_to_include + " )";
                        }
                    }

                    // Replace the text with the include file
                    Simple_Web_Content.Static_Text = Simple_Web_Content.Static_Text.Replace(include_statement, include_text);
                    include_index = Simple_Web_Content.Static_Text.IndexOf("<%INCLUDE", include_index + include_text.Length - 1 );
                }
                else
                {
                    // No suitable name was found, or it doesn't exist so just remove the INCLUDE completely
                    Simple_Web_Content.Static_Text = Simple_Web_Content.Static_Text.Replace(include_statement, "");
                    include_index = Simple_Web_Content.Static_Text.IndexOf("<%INCLUDE", include_index );
                }
            }

            // Look for a site map
            if (Simple_Web_Content.SiteMap.Length > 0)
            {
                // Look in the cache first
                Site_Map = Cached_Data_Manager.Retrieve_Site_Map(Simple_Web_Content.SiteMap, Tracer);

                // If this was NULL, pull it
                if (Site_Map == null)
                {
                    // Only continue if the file exists
                    if (File.Exists(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + Simple_Web_Content.SiteMap))
                    {
                        if (Tracer != null)
                        {
                            Tracer.Add_Trace("SobekCM_Assistant.Get_Simple_Web_Content_Text", "Reading site map file");
                        }

                        // Try to read this sitemap file
                        Site_Map = SobekCM_SiteMap_Reader.Read_SiteMap_File(SobekCM_Library_Settings.Base_Directory + "design\\webcontent\\" + Simple_Web_Content.SiteMap);

                        // If the sitemap file was succesfully read, cache it
                        if (Site_Map != null)
                        {
                            Cached_Data_Manager.Store_Site_Map(Site_Map, Simple_Web_Content.SiteMap, Tracer);
                        }
                    }
                }
            }

            // Since this is not cached, we can apply the individual user settings to the static text which was read right here
            Simple_Web_Content.Static_Text = Simple_Web_Content.Apply_Settings_To_Static_Text(Simple_Web_Content.Static_Text, null, Current_Mode.Skin, Current_Mode.Base_Skin, Current_Mode.Base_URL, Current_Mode.URL_Options(), Tracer);

            return true;
        }
Exemple #6
0
        /// <summary> Reads an existing site map file and returns the fully built <see cref="SobekCM_SiteMap" /> object </summary>
        /// <param name="SiteMap_File"> Sitemap file to read </param>
        /// <returns> Fully built sitemap object </returns>
        public static SobekCM_SiteMap Read_SiteMap_File(string SiteMap_File)
        {
            Stream          reader     = null;
            XmlTextReader   nodeReader = null;
            SobekCM_SiteMap siteMap    = null;
            int             nodeValue  = 1;

            Stack <SobekCM_SiteMap_Node> nodesStack = new Stack <SobekCM_SiteMap_Node>();

            try
            {
                // Create and open the readonly file stream
                reader = new FileStream(SiteMap_File, FileMode.Open, FileAccess.Read);

                // create the XML node reader
                nodeReader = new XmlTextReader(reader);

                // Read through the XML document
                while (nodeReader.Read())
                {
                    if (nodeReader.NodeType == XmlNodeType.Element)
                    {
                        // Handle the main sitemap tag
                        if (nodeReader.Name == "siteMap")
                        {
                            // This is the first node read, so it may have additional information
                            siteMap = new SobekCM_SiteMap();

                            // Look for the optional default breadcrumbs attribute
                            if (nodeReader.MoveToAttribute("default_breadcrumb"))
                            {
                                siteMap.Default_Breadcrumb = nodeReader.Value;
                            }

                            // Look for the optional width attribute
                            if (nodeReader.MoveToAttribute("width"))
                            {
                                short width;
                                Int16.TryParse(nodeReader.Value, out width);
                                siteMap.Width = width;
                            }

                            // Look for the optional url restriction attribute
                            if (nodeReader.MoveToAttribute("restrictedRobotUrl"))
                            {
                                siteMap.Restricted_Robot_URL = nodeReader.Value;
                            }
                        }

                        // Handle a new siteMapNode
                        if (nodeReader.Name == "siteMapNode")
                        {
                            string url         = String.Empty;
                            string title       = String.Empty;
                            string description = String.Empty;
                            bool   empty       = false;

                            // Before moving to any attributes, check to see if this is empty
                            if (nodeReader.IsEmptyElement)
                            {
                                empty = true;
                            }

                            // Step through the attributes
                            while (nodeReader.MoveToNextAttribute())
                            {
                                switch (nodeReader.Name)
                                {
                                case "url":
                                    url = nodeReader.Value;
                                    break;

                                case "title":
                                    title = nodeReader.Value;
                                    break;

                                case "description":
                                    description = nodeReader.Value;
                                    break;
                                }
                            }

                            // Create the new node
                            SobekCM_SiteMap_Node newNode = new SobekCM_SiteMap_Node(url, title, description, nodeValue++);

                            // Add to the parent
                            if (nodesStack.Count == 0)
                            {
                                // This is the first node read so it should be the root node
                                if (siteMap != null)
                                {
                                    siteMap.RootNodes.Add(newNode);
                                }
                            }
                            else
                            {
                                nodesStack.Peek().Add_Child_Node(newNode);
                            }

                            // Add this to the stack, at least until the end of this node is found
                            // if this is not an empty element
                            if (!empty)
                            {
                                nodesStack.Push(newNode);
                            }
                        }
                    }
                    else if ((nodeReader.NodeType == XmlNodeType.EndElement) && (nodeReader.Name == "siteMapNode"))
                    {
                        nodesStack.Pop();
                    }
                }
            }
            finally
            {
                if (nodeReader != null)
                {
                    nodeReader.Close();
                }
                if (reader != null)
                {
                    reader.Close();
                }
            }

            return(siteMap);
        }
        /// <summary> Constructor for a new instance of the Text_MainWriter class </summary>
        /// <param name="Current_Mode"> Mode / navigation information for the current request</param>
        /// <param name="Hierarchy_Object"> Current item aggregation object to display </param>
        /// <param name="Results_Statistics"> Information about the entire set of results for a search or browse </param>
        /// <param name="Paged_Results"> Single page of results for a search or browse, within the entire set </param>
        /// <param name="Browse_Object"> Object contains all the basic information about any browse or info display </param>
        /// <param name="Current_Item"> Current item to display </param>
        /// <param name="Current_Page"> Current page within the item</param>
        /// <param name="HTML_Skin"> HTML Web skin which controls the overall appearance of this digital library </param>
        /// <param name="Current_User"> Currently logged on user </param>
        /// <param name="Translator"> Language support object which handles simple translational duties </param>
        /// <param name="Code_Manager"> List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="Item_List"> Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Stats_Date_Range"> Object contains the start and end dates for the statistical data in the database </param>
        /// <param name="Search_History"> List of recent searches performed against this digital library </param>
        /// <param name="Icon_Dictionary"> Dictionary of information about every wordmark/icon in this digital library, used to build the wordmarks subpage </param>
        /// <param name="Thematic_Headings"> Headings under which all the highlighted collections on the main home page are organized </param>
        /// <param name="Public_Folder"> Object contains the information about the public folder to display </param>
        /// <param name="Aggregation_Aliases"> List of all existing aliases for existing aggregations </param>
        /// <param name="Web_Skin_Collection"> Collection of all the web skins </param>
        /// <param name="Checked_Items"> List of all items which are currently checked out for single fair use and the IP address currently viewing the item</param>
        /// <param name="IP_Restrictions"> Any possible restriction on item access by IP ranges </param>
        /// <param name="URL_Portals"> List of all web portals into this system </param>
        /// <param name="Site_Map"> Optional site map object used to render a navigational tree-view on left side of static web content pages </param>
        /// <param name="Items_In_Title"> List of items within the current title ( used for the Item Group display )</param>
        /// <param name="Static_Web_Content"> HTML content-based browse, info, or imple CMS-style web content objects.  These are objects which are read from a static HTML file and much of the head information must be maintained </param>
        public Html_MainWriter(SobekCM_Navigation_Object Current_Mode,
            Item_Aggregation Hierarchy_Object,
            Search_Results_Statistics Results_Statistics,
            List<iSearch_Title_Result> Paged_Results,
            Item_Aggregation_Browse_Info Browse_Object,
            SobekCM_Item Current_Item,
            Page_TreeNode Current_Page,
            SobekCM_Skin_Object HTML_Skin,
            User_Object Current_User,
            Language_Support_Info Translator,
            Aggregation_Code_Manager Code_Manager,
            Item_Lookup_Object Item_List,
            Statistics_Dates Stats_Date_Range,
            Recent_Searches Search_History,
            Dictionary<string, Wordmark_Icon> Icon_Dictionary,
            List<Thematic_Heading> Thematic_Headings,
            Public_User_Folder Public_Folder,
            Dictionary<string, string> Aggregation_Aliases,
            SobekCM_Skin_Collection Web_Skin_Collection,
            Checked_Out_Items_List Checked_Items,
            IP_Restriction_Ranges IP_Restrictions,
            Portal_List URL_Portals,
            SobekCM_SiteMap Site_Map,
            SobekCM_Items_In_Title Items_In_Title,
            HTML_Based_Content Static_Web_Content )
            : base(Current_Mode, Hierarchy_Object, Results_Statistics, Paged_Results, Browse_Object,  Current_Item, Current_Page, Static_Web_Content)
        {
            // Save parameters
            htmlSkin = HTML_Skin;
            translator = Translator;
            codeManager = Code_Manager;
            itemList = Item_List;
            statsDateRange = Stats_Date_Range;
            searchHistory = Search_History;
            currentUser = Current_User;
            iconList = Icon_Dictionary;
            thematicHeadings = Thematic_Headings;
            publicFolder = Public_Folder;
            aggregationAliases = Aggregation_Aliases;
            webSkins = Web_Skin_Collection;
            checkedItems = Checked_Items;
            ipRestrictionInfo = IP_Restrictions;
            urlPortals = URL_Portals;
            siteMap = Site_Map;
            itemsInTitle = Items_In_Title;

            // Set some defaults
            finishPageInAddFinalHtmlMethod = false;

            // Handle basic events which may be fired by the internal header

            if (HttpContext.Current.Request.Form["internal_header_action"] != null)
            {
                // Pull the action value
                string internalHeaderAction = HttpContext.Current.Request.Form["internal_header_action"].Trim();

                // Was this to hide or show the header?
                if ((internalHeaderAction == "hide") || (internalHeaderAction == "show"))
                {
                    // Pull the current visibility from the session
                    bool shown = true;
                    if ((HttpContext.Current.Session["internal_header"] != null) && (HttpContext.Current.Session["internal_header"].ToString() == "hidden"))
                    {
                        shown = false;
                    }
                    if ((internalHeaderAction == "hide") && (shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "hidden";
                        HttpContext.Current.Response.Redirect(currentMode.Redirect_URL(), true);
                    }
                    if ((internalHeaderAction == "show") && (!shown))
                    {
                        HttpContext.Current.Session["internal_header"] = "shown";
                        HttpContext.Current.Response.Redirect(currentMode.Redirect_URL(), true);
                    }
                }
            }
        }