/// <summary> Constructor for a new instance of the Worker_Controller class </summary>
        /// <param name="Verbose"> Flag indicates if this should be verbose in the log file and console </param>
        public Worker_Controller(bool Verbose)
        {
            verbose           = Verbose;
            controllerStarted = DateTime.Now;
            aborted           = false;

            // Assign the database connection strings
            SobekCM_Database.Connection_String = SobekCM_Library_Settings.Database_Connections[0].Connection_String;
            Library.Database.SobekCM_Database.Connection_String = SobekCM_Library_Settings.Database_Connections[0].Connection_String;

            // Pull the values from the database and assign other setting values
            SobekCM_Library_Settings.Local_Log_Directory = Application.StartupPath + "\\Logs\\";
            DataSet settings = Library.Database.SobekCM_Database.Get_Builder_Settings_Complete(null);

            if (settings == null)
            {
                Console.WriteLine("FATAL ERROR pulling latest settings from the database: " + Library.Database.SobekCM_Database.Last_Exception.Message);
                return;
            }
            if (!SobekCM_Library_Settings.Refresh(settings))
            {
                Console.WriteLine("Error using database settings to refresh SobekCM_Library_Settings in Worker_Controller constructor");
            }

            // If this starts in an ABORTED mode, set to standard
            Builder_Operation_Flag_Enum operationFlag = Abort_Database_Mechanism.Builder_Operation_Flag;

            if ((operationFlag == Builder_Operation_Flag_Enum.ABORTING) || (operationFlag == Builder_Operation_Flag_Enum.ABORT_REQUESTED) || (operationFlag == Builder_Operation_Flag_Enum.LAST_EXECUTION_ABORTED))
            {
                Abort_Database_Mechanism.Builder_Operation_Flag = Builder_Operation_Flag_Enum.STANDARD_OPERATION;
            }
        }
        /// <summary> Continuously execute the processes in a recurring background thread </summary>
        public void Execute_In_Background()
        {
            // Load all the settings
            SobekCM_Library_Settings.Refresh(Library.Database.SobekCM_Database.Get_Settings_Complete(null));

            // Set the variable which will control background execution
            int time_between_polls = SobekCM_Library_Settings.Builder_Override_Seconds_Between_Polls;

            if ((time_between_polls < 0) || (SobekCM_Library_Settings.Database_Connections.Count == 1))
            {
                time_between_polls = Convert.ToInt32(SobekCM_Library_Settings.Builder_Seconds_Between_Polls);
            }

            // Determine the new log name
            string log_name       = "incoming_" + controllerStarted.Year + "_" + controllerStarted.Month.ToString().PadLeft(2, '0') + "_" + controllerStarted.Day.ToString().PadLeft(2, '0') + ".html";
            string local_log_name = SobekCM_Library_Settings.Local_Log_Directory + "\\" + log_name;

            // Create the new log file
            LogFileXHTML preloader_logger = new LogFileXHTML(local_log_name, "SobekCM Incoming Packages Log", "UFDC_Builder.exe", true);

            // start with warnings on imagemagick and ghostscript not being installed
            if (SobekCM_Library_Settings.ImageMagick_Executable.Length == 0)
            {
                Console.WriteLine("WARNING: Could not find ImageMagick installed.  Some image processing will be unavailable.");
                preloader_logger.AddNonError("WARNING: Could not find ImageMagick installed.  Some image processing will be unavailable.");
            }
            if (SobekCM_Library_Settings.Ghostscript_Executable.Length == 0)
            {
                Console.WriteLine("WARNING: Could not find GhostScript installed.  Some PDF processing will be unavailable.");
                preloader_logger.AddNonError("WARNING: Could not find GhostScript installed.  Some PDF processing will be unavailable.");
            }

            // Set the time for the next feed building event to 10 minutes from now
            feedNextBuildTime = DateTime.Now.Add(new TimeSpan(0, 10, 0));

            // First, step through each active configuration and see if building is currently aborted
            // while doing very minimal processes
            aborted = false;
            Console.WriteLine("Checking for initial abort condition");
            preloader_logger.AddNonError("Checking for initial abort condition");
            string abort_message = String.Empty;
            Builder_Operation_Flag_Enum abort_flag = Builder_Operation_Flag_Enum.STANDARD_OPERATION;

            foreach (Database_Instance_Configuration dbConfig in SobekCM_Library_Settings.Database_Connections)
            {
                if ((!aborted) && (dbConfig.Is_Active) && (dbConfig.Can_Abort))
                {
                    SobekCM_Database.Connection_String = dbConfig.Connection_String;
                    Library.Database.SobekCM_Database.Connection_String = dbConfig.Connection_String;

                    // Check that this should not be skipped or aborted
                    Builder_Operation_Flag_Enum operationFlag = Abort_Database_Mechanism.Builder_Operation_Flag;
                    switch (operationFlag)
                    {
                    case Builder_Operation_Flag_Enum.ABORT_REQUESTED:
                    case Builder_Operation_Flag_Enum.ABORTING:
                        abort_message = "PREVIOUS ABORT flag found in " + dbConfig.Name;
                        abort_flag    = Builder_Operation_Flag_Enum.LAST_EXECUTION_ABORTED;
                        Console.WriteLine(abort_message);
                        preloader_logger.AddNonError(abort_message);
                        aborted = true;
                        Abort_Database_Mechanism.Builder_Operation_Flag = Builder_Operation_Flag_Enum.LAST_EXECUTION_ABORTED;
                        break;

                    case Builder_Operation_Flag_Enum.NO_BUILDING_REQUESTED:
                        abort_message = "PREVIOUS NO BUILDING flag found in " + dbConfig.Name;
                        Console.WriteLine(abort_message);
                        preloader_logger.AddNonError(abort_message);
                        aborted = true;
                        break;
                    }
                }
            }

            // If initially aborted, step through each instance and set a message
            if (aborted)
            {
                // Add messages in each active instance
                foreach (Database_Instance_Configuration dbConfig in SobekCM_Library_Settings.Database_Connections)
                {
                    if (dbConfig.Is_Active)
                    {
                        Console.WriteLine("Setting previous abort flag message in " + dbConfig.Name);
                        preloader_logger.AddNonError("Setting previous abort flag message in " + dbConfig.Name);
                        SobekCM_Database.Connection_String = dbConfig.Connection_String;
                        Library.Database.SobekCM_Database.Connection_String = dbConfig.Connection_String;
                        Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", abort_message, String.Empty);

                        // Save information about this last run
                        Library.Database.SobekCM_Database.Set_Setting("Builder Version", SobekCM_Library_Settings.CURRENT_BUILDER_VERSION);
                        Library.Database.SobekCM_Database.Set_Setting("Builder Last Run Finished", DateTime.Now.ToString());
                        Library.Database.SobekCM_Database.Set_Setting("Builder Last Message", abort_message);

                        // Finally, set the builder flag appropriately
                        if (abort_flag != Builder_Operation_Flag_Enum.STANDARD_OPERATION)
                        {
                            Abort_Database_Mechanism.Builder_Operation_Flag = abort_flag;
                        }
                    }
                }

                // Do nothing else
                return;
            }

            // Build all the bulk loader objects
            List <Worker_BulkLoader> loaders = new List <Worker_BulkLoader>();
            bool activeInstanceFound         = false;

            foreach (Database_Instance_Configuration dbConfig in SobekCM_Library_Settings.Database_Connections)
            {
                if (!dbConfig.Is_Active)
                {
                    loaders.Add(null);
                    Console.WriteLine(dbConfig.Name + " is set to INACTIVE");
                    preloader_logger.AddNonError(dbConfig.Name + " is set to INACTIVE");
                }
                else
                {
                    activeInstanceFound = true;
                    SobekCM_Database.Connection_String = dbConfig.Connection_String;
                    Library.Database.SobekCM_Database.Connection_String = dbConfig.Connection_String;


                    // At this point warn on mossing the Ghostscript and ImageMagick
                    if (SobekCM_Library_Settings.ImageMagick_Executable.Length == 0)
                    {
                        Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", "WARNING: Could not find ImageMagick installed.  Some image processing will be unavailable.", String.Empty);
                    }
                    if (SobekCM_Library_Settings.Ghostscript_Executable.Length == 0)
                    {
                        Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", "WARNING: Could not find GhostScript installed.  Some PDF processing will be unavailable.", String.Empty);
                    }

                    Console.WriteLine(dbConfig.Name + " - Preparing to begin polling");
                    preloader_logger.AddNonError(dbConfig.Name + " - Preparing to begin polling");
                    Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", "Preparing to begin polling", String.Empty);

                    Worker_BulkLoader newLoader = new Worker_BulkLoader(preloader_logger, verbose, dbConfig.Name, dbConfig.Can_Abort);
                    loaders.Add(newLoader);
                }
            }

            // If no active instances, just exit
            if (!activeInstanceFound)
            {
                Console.WriteLine("No active databases in the config file");
                preloader_logger.AddError("No active databases in config file... Aborting");
                return;
            }

            bool firstRun = true;


            // Loop continually until the end hour is achieved
            do
            {
                // Is it time to build any RSS/XML feeds?
                bool rebuildRssFeeds = false;
                if (DateTime.Compare(DateTime.Now, feedNextBuildTime) >= 0)
                {
                    rebuildRssFeeds   = true;
                    feedNextBuildTime = DateTime.Now.Add(new TimeSpan(0, 10, 0));
                }

                // Step through each instance
                for (int i = 0; i < SobekCM_Library_Settings.Database_Connections.Count; i++)
                {
                    if (loaders[i] != null)
                    {
                        // Get the instance
                        Database_Instance_Configuration dbInstance = SobekCM_Library_Settings.Database_Connections[i];

                        // Set the database connection strings
                        SobekCM_Database.Connection_String = dbInstance.Connection_String;
                        Library.Database.SobekCM_Database.Connection_String = dbInstance.Connection_String;

                        // Look for abort
                        if ((dbInstance.Can_Abort) && (CheckForAbort()))
                        {
                            aborted = true;
                            if (Abort_Database_Mechanism.Builder_Operation_Flag != Builder_Operation_Flag_Enum.NO_BUILDING_REQUESTED)
                            {
                                abort_flag = Builder_Operation_Flag_Enum.LAST_EXECUTION_ABORTED;
                                Abort_Database_Mechanism.Builder_Operation_Flag = Builder_Operation_Flag_Enum.ABORTING;
                            }
                            break;
                        }

                        // Refresh all settings, etc..
                        loaders[i].Refresh_Settings_And_Item_List();

                        // Pull the abort/pause flag
                        Builder_Operation_Flag_Enum currentPauseFlag = Abort_Database_Mechanism.Builder_Operation_Flag;

                        // If not paused, run the prebuilder
                        if (currentPauseFlag != Builder_Operation_Flag_Enum.PAUSE_REQUESTED)
                        {
                            if (firstRun)
                            {
                                //    // Always build an endeca feed first (so it occurs once a day)
                                //    if (SobekCM_Library_Settings.Build_MARC_Feed_By_Default)
                                //    {
                                //        Create_Complete_MarcXML_Feed(false);
                                //    }
                                //}

                                // CLear the old logs
                                Console.WriteLine(dbInstance.Name + " - Expiring old log entries");
                                preloader_logger.AddNonError(dbInstance.Name + " - Expiring old log entries");
                                Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", "Expiring old log entries", String.Empty);
                                Library.Database.SobekCM_Database.Builder_Expire_Log_Entries(SobekCM_Library_Settings.Builder_Log_Expiration_Days);



                                // Rebuild all the static pages
                                Console.WriteLine(dbInstance.Name + " - Rebuilding all static pages");
                                preloader_logger.AddNonError(dbInstance.Name + " - Rebuilding all static pages");
                                long staticRebuildLogId = Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", "Rebuilding all static pages", String.Empty);

                                Static_Pages_Builder builder = new Static_Pages_Builder(SobekCM_Library_Settings.Application_Server_URL, SobekCM_Library_Settings.Static_Pages_Location, SobekCM_Library_Settings.Application_Server_Network);
                                builder.Rebuild_All_Static_Pages(preloader_logger, false, SobekCM_Library_Settings.Local_Log_Directory, dbInstance.Name, staticRebuildLogId);



                                // Process any pending FDA reports from the FDA Report DropBox
                                Process_Any_Pending_FDA_Reports(loaders[i]);
                            }

                            Run_BulkLoader(loaders[i], verbose);

                            // Look for abort
                            if ((!aborted) && (dbInstance.Can_Abort) && (CheckForAbort()))
                            {
                                aborted = true;
                                if (Abort_Database_Mechanism.Builder_Operation_Flag != Builder_Operation_Flag_Enum.NO_BUILDING_REQUESTED)
                                {
                                    abort_flag = Builder_Operation_Flag_Enum.LAST_EXECUTION_ABORTED;
                                    Abort_Database_Mechanism.Builder_Operation_Flag = Builder_Operation_Flag_Enum.ABORTING;
                                }
                                break;
                            }


                            if (rebuildRssFeeds)
                            {
                                loaders[i].Build_Feeds();
                            }

                            // Clear memory from this loader
                            loaders[i].Clear_Item_List();
                        }
                        else
                        {
                            preloader_logger.AddNonError(dbInstance.Name + " - Building paused");
                            Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", "Building temporarily PAUSED", String.Empty);
                        }
                    }
                }

                if (aborted)
                {
                    break;
                }


                // No longer the first run
                firstRun = false;

                // Publish the log
                publish_log_file(local_log_name);

                // Sleep for correct number of milliseconds
                Thread.Sleep(1000 * time_between_polls);
            } while (DateTime.Now.Hour < BULK_LOADER_END_HOUR);

            // Do the final work for all of the different dbInstances
            if (!aborted)
            {
                for (int i = 0; i < SobekCM_Library_Settings.Database_Connections.Count; i++)
                {
                    if (loaders[i] != null)
                    {
                        // Get the instance
                        Database_Instance_Configuration dbInstance = SobekCM_Library_Settings.Database_Connections[i];

                        // Set the database flag
                        SobekCM_Database.Connection_String = dbInstance.Connection_String;

                        // Pull the abort/pause flag
                        Builder_Operation_Flag_Enum currentPauseFlag2 = Abort_Database_Mechanism.Builder_Operation_Flag;

                        // If not paused, run the prebuilder
                        if (currentPauseFlag2 != Builder_Operation_Flag_Enum.PAUSE_REQUESTED)
                        {
                            // Refresh all settings, etc..
                            loaders[i].Refresh_Settings_And_Item_List();

                            // Initiate the recreation of the links between metadata and collections
                            Library.Database.SobekCM_Database.Admin_Update_Cached_Aggregation_Metadata_Links();
                        }

                        // Clear the memory
                        loaders[i].Clear_Item_List();
                    }
                }
            }
            else
            {
                // Mark the aborted in each instance
                foreach (Database_Instance_Configuration dbConfig in SobekCM_Library_Settings.Database_Connections)
                {
                    if (dbConfig.Is_Active)
                    {
                        Console.WriteLine("Setting abort flag message in " + dbConfig.Name);
                        preloader_logger.AddNonError("Setting abort flag message in " + dbConfig.Name);
                        SobekCM_Database.Connection_String = dbConfig.Connection_String;
                        Library.Database.SobekCM_Database.Connection_String = dbConfig.Connection_String;
                        Library.Database.SobekCM_Database.Builder_Add_Log_Entry(-1, String.Empty, "Standard", "Building ABORTED per request from database key", String.Empty);

                        // Save information about this last run
                        Library.Database.SobekCM_Database.Set_Setting("Builder Version", SobekCM_Library_Settings.CURRENT_BUILDER_VERSION);
                        Library.Database.SobekCM_Database.Set_Setting("Builder Last Run Finished", DateTime.Now.ToString());
                        Library.Database.SobekCM_Database.Set_Setting("Builder Last Message", "Building ABORTED per request");

                        // Finally, set the builder flag appropriately
                        if (abort_flag == Builder_Operation_Flag_Enum.LAST_EXECUTION_ABORTED)
                        {
                            Abort_Database_Mechanism.Builder_Operation_Flag = Builder_Operation_Flag_Enum.LAST_EXECUTION_ABORTED;
                        }
                    }
                }
            }


            // Publish the log
            publish_log_file(local_log_name);


            //// Initiate a solr/lucene index optimization since we are done loading for a while
            //if (DateTime.Now.Day % 2 == 0)
            //{
            //	if (SobekCM_Library_Settings.Document_Solr_Index_URL.Length > 0)
            //	{
            //		Console.WriteLine("Initiating Solr/Lucene document index optimization");
            //		Solr_Controller.Optimize_Document_Index(SobekCM_Library_Settings.Document_Solr_Index_URL);
            //	}
            //}
            //else
            //{
            //	if (SobekCM_Library_Settings.Page_Solr_Index_URL.Length > 0)
            //	{
            //		Console.WriteLine("Initiating Solr/Lucene page index optimization");
            //		Solr_Controller.Optimize_Page_Index(SobekCM_Library_Settings.Page_Solr_Index_URL);
            //	}
            //}
            //// Sleep for twenty minutes to end this (the index rebuild might take some time)
            //Thread.Sleep(1000 * 20 * 60);
        }
        private void complete_item_submission(SobekCM_Item Item_To_Complete, Custom_Tracer Tracer)
        {
            // If this is a newspaper type, and the pubdate has a value, try to use that for the serial heirarchy
            if ((Item_To_Complete.Behaviors.Serial_Info.Count == 0) && (Item_To_Complete.Bib_Info.Origin_Info.Date_Issued.Length > 0) && (Item_To_Complete.Bib_Info.SobekCM_Type == TypeOfResource_SobekCM_Enum.Newspaper))
            {
                DateTime asDateTime;
                if (DateTime.TryParse(Item_To_Complete.Bib_Info.Origin_Info.Date_Issued, out asDateTime))
                {
                    hierarchyCopiedFromDate = true;
                    Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(1, asDateTime.Year, asDateTime.Year.ToString());
                    switch (asDateTime.Month)
                    {
                    case 1:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "January");
                        break;

                    case 2:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "February");
                        break;

                    case 3:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "March");
                        break;

                    case 4:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "April");
                        break;

                    case 5:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "May");
                        break;

                    case 6:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "June");
                        break;

                    case 7:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "July");
                        break;

                    case 8:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "August");
                        break;

                    case 9:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "September");
                        break;

                    case 10:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "October");
                        break;

                    case 11:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "November");
                        break;

                    case 12:
                        Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(2, asDateTime.Month, "December");
                        break;
                    }

                    Item_To_Complete.Behaviors.Serial_Info.Add_Hierarchy(3, asDateTime.Day, asDateTime.Day.ToString());
                }
            }

            // Determine the in process directory for this
            string user_in_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.UserName.Replace(".", "").Replace("@", "") + "\\newitem";

            if (user.UFID.Trim().Length > 0)
            {
                user_in_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.UFID + "\\newitem";
            }

            // Ensure this directory exists
            if (!Directory.Exists(user_in_process_directory))
            {
                Directory.CreateDirectory(user_in_process_directory);
            }

            // Now, delete all the files in the processing directory
            string[] all_files = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in all_files)
            {
                File.Delete(thisFile);
            }

            // Save to the database
            Item_To_Complete.Web.File_Root = Item_To_Complete.BibID.Substring(0, 2) + "\\" + Item_To_Complete.BibID.Substring(2, 2) + "\\" + Item_To_Complete.BibID.Substring(4, 2) + "\\" + Item_To_Complete.BibID.Substring(6, 2) + "\\" + Item_To_Complete.BibID.Substring(8, 2);
            SobekCM_Database.Save_New_Digital_Resource(Item_To_Complete, false, false, user.UserName, String.Empty, -1);

            // Assign the file root and assoc file path
            Item_To_Complete.Web.AssocFilePath = Item_To_Complete.Web.File_Root + "\\" + Item_To_Complete.VID + "\\";

            // Create the static html pages
            string base_url = currentMode.Base_URL;

            try
            {
                Static_Pages_Builder staticBuilder = new Static_Pages_Builder(SobekCM_Library_Settings.System_Base_URL, SobekCM_Library_Settings.Base_Data_Directory, Translator, codeManager, itemList, iconList, webSkin);
                string filename = user_in_process_directory + "\\" + Item_To_Complete.BibID + "_" + Item_To_Complete.VID + ".html";
                staticBuilder.Create_Item_Citation_HTML(Item_To_Complete, filename, String.Empty);
            }
            catch (Exception ee)
            {
                message = message + "<br /><span style=\"color: red\"><strong>" + ee.Message + "<br />" + ee.StackTrace.Replace("\n", "<br />") + "</strong></span>";
            }

            currentMode.Base_URL = base_url;

            // Save the rest of the metadata
            Item_To_Complete.Source_Directory = user_in_process_directory;
            Item_To_Complete.Save_SobekCM_METS();
            Item_To_Complete.Save_Citation_Only_METS();

            // Add this to the cache
            itemList.Add_SobekCM_Item(Item_To_Complete);

            Database.SobekCM_Database.Add_Item_To_User_Folder(user.UserID, "Submitted Items", Item_To_Complete.BibID, Item_To_Complete.VID, 0, String.Empty, Tracer);

            // Save Bib_Level METS?
            //SobekCM.Resource_Object.Writers.OAI_Writer oaiWriter = new SobekCM.Resource_Object.Writers.OAI_Writer();
            //oaiWriter.Save_OAI_File(bibPackage, resource_folder + "\\oai_dc.xml", bibPackage.Processing_Parameters.Collection_Primary.ToLower(), createDate);

            // If there was no match, try to save to the tracking database
            Database.SobekCM_Database.Tracking_Online_Submit_Complete(Item_To_Complete.Web.ItemID, user.Full_Name, String.Empty);



            List <string>             collectionnames = new List <string>();
            MarcXML_File_ReaderWriter marcWriter      = new MarcXML_File_ReaderWriter();
            string Error_Message;
            Dictionary <string, object> options = new Dictionary <string, object>();

            options["MarcXML_File_ReaderWriter:Additional_Tags"] = Item_To_Complete.MARC_Sobek_Standard_Tags(collectionnames, true, SobekCM_Library_Settings.System_Name, SobekCM_Library_Settings.System_Abbreviation);
            marcWriter.Write_Metadata(Item_To_Complete.Source_Directory + "\\marc.xml", Item_To_Complete, options, out Error_Message);


            // Copy this to all the image servers
            SobekCM_Library_Settings.Refresh(Database.SobekCM_Database.Get_Settings_Complete(Tracer));
            string[] allFiles = Directory.GetFiles(user_in_process_directory);

            // Copy all the files over to the server
            string serverNetworkFolder = SobekCM_Library_Settings.Image_Server_Network + Item_To_Complete.Web.AssocFilePath;

            // Create the folder
            if (!Directory.Exists(serverNetworkFolder))
            {
                Directory.CreateDirectory(serverNetworkFolder);
            }

            foreach (string thisFile in allFiles)
            {
                string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                File.Copy(thisFile, destination_file, true);
            }

            // Add this to the cache
            itemList.Add_SobekCM_Item(Item_To_Complete);

            // Incrememnt the count of number of items submitted by this user
            user.Items_Submitted_Count++;

            // Delete any remaining items
            all_files = Directory.GetFiles(user_in_process_directory);
            foreach (string thisFile in all_files)
            {
                File.Delete(thisFile);
            }
        }
示例#4
0
        /// <summary> Verifies that each global object is built and builds them upon request </summary>
        /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param>
        /// <param name="Reload_All"> Flag indicates if everything should be reloaded/repopulated</param>
        /// <param name="Skins"> [REF] Collection of all the web skins </param>
        /// <param name="Translator"> [REF] Language support object which handles simple translational duties </param>
        /// <param name="Code_Manager"> [REF] List of valid collection codes, including mapping from the Sobek collections to Greenstone collections</param>
        /// <param name="All_Items_Lookup"> [REF] Lookup object used to pull basic information about any item loaded into this library </param>
        /// <param name="Icon_Dictionary"> [REF] Dictionary of information about every wordmark/icon in this digital library </param>
        /// <param name="Stats_Date_Range"> [REF] Object contains the start and end dates for the statistical data in the database </param>
        /// <param name="Thematic_Headings"> [REF] Headings under which all the highlighted collections on the main home page are organized </param>
        /// <param name="Aggregation_Aliases"> [REF] List of all existing aliases for existing aggregations </param>
        /// <param name="IP_Restrictions"> [REF] List of all IP Restriction ranges in use by this digital library </param>
        /// <param name="URL_Portals"> [REF] List of all web portals into this system </param>
        /// <param name="Mime_Types">[REF] Dictionary of MIME types by extension</param>
        public static void Build_Application_State(Custom_Tracer Tracer, bool Reload_All,
                                                   ref SobekCM_Skin_Collection Skins, ref Language_Support_Info Translator,
                                                   ref Aggregation_Code_Manager Code_Manager, ref Item_Lookup_Object All_Items_Lookup,
                                                   ref Dictionary <string, Wordmark_Icon> Icon_Dictionary,
                                                   ref Statistics_Dates Stats_Date_Range,
                                                   ref List <Thematic_Heading> Thematic_Headings,
                                                   ref Dictionary <string, string> Aggregation_Aliases,
                                                   ref IP_Restriction_Ranges IP_Restrictions,
                                                   ref Portal_List URL_Portals,
                                                   ref Dictionary <string, Mime_Type_Info> Mime_Types)
        {
            // Should we reload the data from the exteral configuraiton file?
            if (Reload_All)
            {
                SobekCM_Library_Settings.Read_Configuration_File();
                SobekCM_Database.Connection_String = SobekCM_Library_Settings.Database_Connection_String;
                SobekCM_Library_Settings.Refresh(SobekCM_Database.Get_Settings_Complete(null));
            }

            // If there is no database connection string, there is a problem
            if (String.IsNullOrEmpty(SobekCM_Library_Settings.Database_Connection_String))
            {
                throw new ApplicationException("Missing database connection string!");
            }

            // Set the database connection strings
            Resource_Object.Database.SobekCM_Database.Connection_String = SobekCM_Library_Settings.Database_Connection_String;
            SobekCM_Database.Connection_String = SobekCM_Library_Settings.Database_Connection_String;

            // Set the workflow and disposition types
            if ((SobekCM_Library_Settings.Need_Workflow_And_Disposition_Types) || (Reload_All))
            {
                SobekCM_Library_Settings.Set_Workflow_And_Disposition_Types(SobekCM_Database.All_WorkFlow_Types, SobekCM_Database.All_Possible_Disposition_Types);
            }

            // Set the metadata types
            if ((SobekCM_Library_Settings.Need_Metadata_Types) || (Reload_All))
            {
                SobekCM_Library_Settings.Set_Metadata_Types(SobekCM_Database.Get_Metadata_Fields(null));
            }

            // Set the search stop words
            if ((SobekCM_Library_Settings.Need_Search_Stop_Words) || (Reload_All))
            {
                SobekCM_Library_Settings.Search_Stop_Words = SobekCM_Database.Search_Stop_Words(Tracer);
            }

            // Check the list of thematic headings
            if ((Thematic_Headings == null) || (Reload_All))
            {
                if (Thematic_Headings != null)
                {
                    lock (Thematic_Headings)
                    {
                        if (!SobekCM_Database.Populate_Thematic_Headings(Thematic_Headings, Tracer))
                        {
                            Thematic_Headings = null;
                            throw SobekCM_Database.Last_Exception;
                        }
                    }
                }
                else
                {
                    Thematic_Headings = new List <Thematic_Heading>();
                    if (!SobekCM_Database.Populate_Thematic_Headings(Thematic_Headings, Tracer))
                    {
                        Thematic_Headings = null;
                        throw SobekCM_Database.Last_Exception;
                    }
                }
            }

            // Check the list of forwardings
            if ((Aggregation_Aliases == null) || (Reload_All))
            {
                if (Aggregation_Aliases != null)
                {
                    lock (Aggregation_Aliases)
                    {
                        SobekCM_Database.Populate_Aggregation_Aliases(Aggregation_Aliases, Tracer);
                    }
                }
                else
                {
                    Aggregation_Aliases = new Dictionary <string, string>();
                    SobekCM_Database.Populate_Aggregation_Aliases(Aggregation_Aliases, Tracer);
                }
            }

            // Check the list of constant skins
            if ((Skins == null) || (Skins.Count == 0) || (Reload_All))
            {
                if (Skins != null)
                {
                    lock (Skins)
                    {
                        SobekCM_Skin_Collection_Builder.Populate_Default_Skins(Skins, Tracer);
                    }
                }
                else
                {
                    Skins = new SobekCM_Skin_Collection();
                    SobekCM_Skin_Collection_Builder.Populate_Default_Skins(Skins, Tracer);
                }
            }

            // Check the list of all web portals
            if ((URL_Portals == null) || (URL_Portals.Count == 0) || (Reload_All))
            {
                if (URL_Portals != null)
                {
                    lock (URL_Portals)
                    {
                        SobekCM_Database.Populate_URL_Portals(URL_Portals, Tracer);
                    }
                }
                else
                {
                    URL_Portals = new Portal_List();
                    SobekCM_Database.Populate_URL_Portals(URL_Portals, Tracer);
                }
            }

            // Check the translation table has been loaded
            if ((Translator == null) || (Reload_All))
            {
                // Get the translation hashes into memory
                if (Translator != null)
                {
                    lock (Translator)
                    {
                        SobekCM_Database.Populate_Translations(Translator, Tracer);
                    }
                }
                else
                {
                    Translator = new Language_Support_Info();
                    SobekCM_Database.Populate_Translations(Translator, Tracer);
                }
            }

            // Check that the conversion from SobekCM Codes to Greenstone Codes has been loaded
            if ((Code_Manager == null) || (Reload_All))
            {
                if (Code_Manager != null)
                {
                    lock (Code_Manager)
                    {
                        SobekCM_Database.Populate_Code_Manager(Code_Manager, Tracer);
                    }
                }
                else
                {
                    Code_Manager = new Aggregation_Code_Manager();
                    SobekCM_Database.Populate_Code_Manager(Code_Manager, Tracer);
                }
            }

            // Check the statistics date range information
            if ((Stats_Date_Range == null) || (Reload_All))
            {
                if (Stats_Date_Range != null)
                {
                    // Get the translation hashes into memory
                    lock (Stats_Date_Range)
                    {
                        SobekCM_Database.Populate_Statistics_Dates(Stats_Date_Range, Tracer);
                    }
                }
                else
                {
                    Stats_Date_Range = new Statistics_Dates();
                    SobekCM_Database.Populate_Statistics_Dates(Stats_Date_Range, Tracer);
                }
            }

            // Get the Icon list
            if ((Icon_Dictionary == null) || (Reload_All))
            {
                if (Icon_Dictionary != null)
                {
                    // Get the translation hashes into memory
                    lock (Icon_Dictionary)
                    {
                        SobekCM_Database.Populate_Icon_List(Icon_Dictionary, Tracer);
                    }
                }
                else
                {
                    Icon_Dictionary = new Dictionary <string, Wordmark_Icon>();
                    SobekCM_Database.Populate_Icon_List(Icon_Dictionary, Tracer);
                }
            }

            // Check the list of ip range restrictions
            if ((IP_Restrictions == null) || (Reload_All))
            {
                if (IP_Restrictions != null)
                {
                    lock (IP_Restrictions)
                    {
                        DataTable ipRestrictionTbl = SobekCM_Database.Get_IP_Restriction_Ranges(Tracer);
                        if (ipRestrictionTbl != null)
                        {
                            IP_Restrictions.Populate_IP_Ranges(ipRestrictionTbl);
                        }
                    }
                }
                else
                {
                    DataTable ipRestrictionTbl = SobekCM_Database.Get_IP_Restriction_Ranges(Tracer);
                    if (ipRestrictionTbl != null)
                    {
                        IP_Restrictions = new IP_Restriction_Ranges();
                        IP_Restrictions.Populate_IP_Ranges(ipRestrictionTbl);
                    }
                }
            }


            // Get the MIME type list
            if ((Mime_Types == null) || (Reload_All))
            {
                if (Mime_Types != null)
                {
                    // Get the translation hashes into memory
                    lock (Mime_Types)
                    {
                        SobekCM_Database.Populate_MIME_List(Mime_Types, Tracer);
                    }
                }
                else
                {
                    Mime_Types = new Dictionary <string, Mime_Type_Info>();
                    SobekCM_Database.Populate_MIME_List(Mime_Types, Tracer);
                }
            }
        }
        private void Complete_Item_Save()
        {
            if (isProject)
            {
                // Save the new project METS
                item.Save_METS();

                // Clear the cache of this item
                Cached_Data_Manager.Remove_Project(user.UserID, item.BibID, null);

                // Redirect
                currentMode.Mode             = Display_Mode_Enum.Administrative;
                currentMode.Admin_Type       = Admin_Type_Enum.Projects;
                currentMode.My_Sobek_SubMode = String.Empty;
                HttpContext.Current.Response.Redirect(currentMode.Redirect_URL());
            }
            else
            {
                // Determine the in process directory for this
                string user_bib_vid_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.UFID + "\\metadata_updates\\" + item.BibID + "_" + item.VID;
                if (user.UFID.Trim().Length == 0)
                {
                    user_bib_vid_process_directory = SobekCM_Library_Settings.In_Process_Submission_Location + "\\" + user.UserName.Replace(".", "").Replace("@", "") + "\\metadata_updates\\" + item.BibID + "_" + item.VID;
                }

                // Ensure the folder exists and is empty to start with
                if (!Directory.Exists(user_bib_vid_process_directory))
                {
                    Directory.CreateDirectory(user_bib_vid_process_directory);
                }
                else
                {
                    // Anything older than a day should be deleted
                    string[] files = Directory.GetFiles(user_bib_vid_process_directory);
                    foreach (string thisFile in files)
                    {
                        try
                        {
                            File.Delete(thisFile);
                        }
                        catch (Exception)
                        {
                            // Not much to do here
                        }
                    }
                }

                // Update the METS file with METS note and name
                item.METS_Header.Creator_Individual = user.UserName;
                item.METS_Header.Modify_Date        = DateTime.Now;
                item.METS_Header.RecordStatus_Enum  = METS_Record_Status.METADATA_UPDATE;

                // Save the METS file and related items
                bool successful_save = true;
                try
                {
                    SobekCM_Database.Save_Digital_Resource(item, DateTime.Now, true);
                }
                catch
                {
                    successful_save = false;
                }

                // Create the static html pages
                string base_url = currentMode.Base_URL;
                try
                {
                    Static_Pages_Builder staticBuilder = new Static_Pages_Builder(SobekCM_Library_Settings.System_Base_URL, SobekCM_Library_Settings.Base_Data_Directory, Translator, codeManager, itemList, iconList, webSkin);
                    string filename = user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html";
                    staticBuilder.Create_Item_Citation_HTML(item, filename, SobekCM_Library_Settings.Image_Server_Network + item.Web.AssocFilePath);
                }
                catch (Exception)
                {
                    // Failing to make the static page is not the worst thing in the world...
                }

                currentMode.Base_URL = base_url;

                item.Source_Directory = user_bib_vid_process_directory;
                item.Save_SobekCM_METS();
                item.Save_Citation_Only_METS();


                // If this was not able to be saved in the UFDC database, try it again
                if (!successful_save)
                {
                    SobekCM_Database.Save_Digital_Resource(item, DateTime.Now, false);
                }

                // Make sure the progress has been added to this item's work log
                try
                {
                    Database.SobekCM_Database.Tracking_Online_Edit_Complete(item.Web.ItemID, user.Full_Name, String.Empty);
                }
                catch (Exception)
                {
                    // This is not critical
                }

                List <string>             collectionnames = new List <string>();
                MarcXML_File_ReaderWriter marcWriter      = new MarcXML_File_ReaderWriter();
                string Error_Message;
                Dictionary <string, object> options = new Dictionary <string, object>();
                options["MarcXML_File_ReaderWriter:Additional_Tags"] = item.MARC_Sobek_Standard_Tags(collectionnames, true, SobekCM_Library_Settings.System_Name, SobekCM_Library_Settings.System_Abbreviation);
                marcWriter.Write_Metadata(item.Source_Directory + "\\marc.xml", item, options, out Error_Message);

                // Copy this to all the image servers
                SobekCM_Library_Settings.Refresh(Database.SobekCM_Database.Get_Settings_Complete(null));
                string[] allFiles = Directory.GetFiles(user_bib_vid_process_directory);

                string serverNetworkFolder = SobekCM_Library_Settings.Image_Server_Network + item.Web.AssocFilePath;

                // Create the folder
                if (!Directory.Exists(serverNetworkFolder))
                {
                    Directory.CreateDirectory(serverNetworkFolder);
                }
                else
                {
                    // Rename any existing standard mets to keep a backup
                    if (File.Exists(serverNetworkFolder + "\\" + item.BibID + "_" + item.VID + ".mets.xml"))
                    {
                        FileInfo currentMetsFileInfo = new FileInfo(serverNetworkFolder + "\\" + item.BibID + "_" + item.VID + ".mets.xml");
                        DateTime lastModDate         = currentMetsFileInfo.LastWriteTime;
                        File.Copy(serverNetworkFolder + "\\" + item.BibID + "_" + item.VID + ".mets.xml", serverNetworkFolder + "\\" + item.BibID + "_" + item.VID + "_" + lastModDate.Year + "_" + lastModDate.Month + "_" + lastModDate.Day + ".mets.bak", true);
                    }
                }

                foreach (string thisFile in allFiles)
                {
                    string destination_file = serverNetworkFolder + "\\" + (new FileInfo(thisFile)).Name;
                    File.Copy(thisFile, destination_file, true);
                }

                // Copy the static HTML file as well
                try
                {
                    if (!Directory.Exists(SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8)))
                    {
                        Directory.CreateDirectory(SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8));
                    }
                    if (File.Exists(user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html"))
                    {
                        File.Copy(user_bib_vid_process_directory + "\\" + item.BibID + "_" + item.VID + ".html", SobekCM_Library_Settings.Static_Pages_Location + item.BibID.Substring(0, 2) + "\\" + item.BibID.Substring(2, 2) + "\\" + item.BibID.Substring(4, 2) + "\\" + item.BibID.Substring(6, 2) + "\\" + item.BibID.Substring(8) + "\\" + item.BibID + "_" + item.VID + ".html", true);
                    }
                }
                catch (Exception)
                {
                    // This is not critical
                }

                // Add this to the cache
                itemList.Add_SobekCM_Item(item, false);

                // Now, delete all the files here
                string[] all_files = Directory.GetFiles(user_bib_vid_process_directory);
                foreach (string thisFile in all_files)
                {
                    File.Delete(thisFile);
                }

                // Clear the user-specific and global cache of this item
                Cached_Data_Manager.Remove_Digital_Resource_Object(user.UserID, item.BibID, item.VID, null);
                Cached_Data_Manager.Remove_Digital_Resource_Object(item.BibID, item.VID, null);
                Cached_Data_Manager.Remove_Items_In_Title(item.BibID, null);


                // Forward to the display item again
                currentMode.Mode       = Display_Mode_Enum.Item_Display;
                currentMode.ViewerCode = "citation";
                HttpContext.Current.Response.Redirect(currentMode.Redirect_URL());
            }
        }
        /// <summary> Constructor for a new instance of the Thematic_Headings_AdminViewer class </summary>
        /// <param name="User"> Authenticated user information </param>
        /// <param name="Current_Mode">  Mode / navigation information for the current request </param>
        /// <param name="Tracer">Trace object keeps a list of each method executed and important milestones in rendering</param>
        /// <remarks> Postback from handling saving the new settings is handled here in the constructor </remarks>
        public Settings_AdminViewer(User_Object User, SobekCM_Navigation_Object Current_Mode, Custom_Tracer Tracer) : base(User)
        {
            // If the user cannot edit this, go back
            if (!User.Is_System_Admin)
            {
                currentMode.My_Sobek_Type = My_Sobek_Type_Enum.Home;
                HttpContext.Current.Response.Redirect(currentMode.Redirect_URL());
            }

            // Establish some default, starting values
            idToSetting    = new Dictionary <int, Setting_Info>();
            settingCounter = 1;
            actionMessage  = String.Empty;

            // Get the current settings from the database
            settings = SobekCM_Database.Get_Settings(Tracer);

            // Get the default URL and default system location
            string default_url      = Current_Mode.Base_URL;
            string default_location = HttpContext.Current.Request.PhysicalApplicationPath;

            // NOTE: This code is exactly the same as found in the SobekCM_Configuration tool.  That is why
            // this feels a little strange, to be loading information about all the settings, and then handling
            // the display portion late.  This allows the settings to be added or subtracted from rather easily
            // in code and also keeps the exact same code chunk to keep the configuration tool and the web
            // app both kept current simultaneously.
            string[] empty_options    = new string[] { };
            string[] boolean_options  = new[] { "true", "false" };
            string[] language_options = Web_Language_Enum_Converter.Language_Name_Array;
            Add_Setting_UI("Allow Page Image File Management", 70, boolean_options, "This option allows or disallows adding page images through the online web interface.  If it is set to false, new pages being added to an existing item must be sent through the bulk loader process.", false);
            Add_Setting_UI("Application Server Network", -1, empty_options, "Server share for the web application's network location.\n\nExample: '\\\\lib-sandbox\\Production\\'", false, default_location);
            Add_Setting_UI("Application Server URL", -1, empty_options, "Base URL which points to the web application.\n\nExamples: 'http://localhost/sobekcm/', 'http://ufdc.ufl.edu/', etc..", false, default_url);
            Add_Setting_UI("Archive DropBox", -1, empty_options, "Network location for the archive drop box.  If this is set to a value, the builder/bulk loader will place a copy of the package in this folder for archiving purposes.  This folder is where any of your archiving processes should look for new packages.", false);
            Add_Setting_UI("Builder Log Expiration in Days", 200, new[] { "10", "30", "365", "99999" }, "Number of days the SobekCM Builder logs are retained.", false, "10");
            Add_Setting_UI("Builder Operation Flag", 200, new[] { "STANDARD OPERATION", "PAUSE REQUESTED", "ABORT REQUESTED", "NO BUILDER REQUESTED" }, "Last flag set when the builder/bulk loader ran.", false);
            Add_Setting_UI("Builder Seconds Between Polls", 200, new[] { "15", "60", "300", "600" }, "Number of seconds the builder remains idle before checking for new incoming package again.", false, "60");
            Add_Setting_UI("Caching Server", -1, empty_options, "URL for the AppFabric Cache host machine, if a caching server/cluster is in use in this system.", false);
            Add_Setting_UI("Can Submit Edit Online", 70, boolean_options, "Flag dictates if users can submit items online, or if this is disabled in this system.", false);
            Add_Setting_UI("Convert Office Files to PDF", 70, boolean_options, "Flag dictates if users can submit items online, or if this is disabled in this system.", false, "false");
            Add_Setting_UI("Create MARC Feed By Default", 70, boolean_options, "Flag indicates if the builder/bulk loader should create the MARC feed by default when operating in background mode.", false);
            Add_Config_Setting("Database Type", SobekCM_Library_Settings.Database_Type_String, "Type of database used to drive the SobekCM system.\n\nCurrently, only Microsoft SQL Server is allowed with plans to add PostgreSQL to the supported database system.\n\nThis value resides in the configuration on the web server.  See your database and web server administrator to change this value.");
            Add_Config_Setting("Database Connection String", SobekCM_Library_Settings.Database_Connection_String, "Connection string used to connect to the SobekCM database\n\nThis value resides in the configuration file on the web server.  See your database and web server administrator to change this value.");
            Add_Setting_UI("Document Solr Index URL", -1, empty_options, "URL for the document-level solr index.\n\nExample: 'http://*****:*****@corp.edu;[email protected]'.\n\nThis value resides in the web.config file on the web server.  See your web server administrator to change this value.");
            Add_Config_Setting("Error HTML Page", SobekCM_Library_Settings.System_Error_URL, "Static page the user should be redirected towards if an unexpected exception occurs which cannot be handled by the web application.\n\nExample: 'http://ufdc.ufl.edu/error.html'.\n\nThis value resides in the web.config file on the web server.  See your web server administrator to change this value.");
            Add_Setting_UI("FDA Report DropBox", -1, empty_options, "Location for the builder/bulk loader to look for incoming Florida Dark Archive XML reports to process and add to the history of digital resources.", true);
            Add_Setting_UI("Files To Exclude From Downloads", -1, empty_options, "Regular expressions used to exclude files from being added by default to the downloads of resources.\n\nExample: '((.*?)\\.(jpg|tif|jp2|jpx|bmp|jpeg|gif|png|txt|pro|mets|db|xml|bak|job)$|qc_error.html)'", false);
            Add_Setting_UI("Help URL", -1, empty_options, "URL used for the main help pages about this system's basic functionality.\n\nExample (and default): 'http://ufdc.ufl.edu/'", false);
            Add_Setting_UI("Help Metadata URL", -1, empty_options, "URL used for the help pages when users request help on metadata elements during online submit and editing.\n\nExample (and default): 'http://ufdc.ufl.edu/'", false);
            Add_Setting_UI("Image Server Network", -1, empty_options, "Network location to the content for all of the digital resources (images, metadata, etc.).\n\nExample: 'C:\\inetpub\\wwwroot\\UFDC Web\\SobekCM\\content\\' or '\\\\ufdc-images\\content\\'", false, default_location + "content\\");
            Add_Setting_UI("Image Server URL", -1, empty_options, "URL which points to the digital resource images.\n\nExample: 'http://localhost/sobekcm/content/' or 'http://ufdcimages.uflib.ufl.edu/'", false, default_url + "content/");
            Add_Setting_UI("Include Partners On System Home", 70, boolean_options, "This option controls whether a PARTNERS option appears on the main system home page, assuming there are multiple institutional aggregations.", false, "false");
            Add_Setting_UI("Include TreeView On System Home", 70, boolean_options, "This option controls whether a TREE VIEW option appears on the main system home page which displays all the active aggregations hierarchically in a tree view.", false, "false");
            Add_Setting_UI("JPEG Height", 60, empty_options, "Restriction on the size of the jpeg page images' height (in pixels) when generated automatically by the builder/bulk loader.\n\nDefault: '1000'", false);
            Add_Setting_UI("JPEG Width", 60, empty_options, "Restriction on the size of the jpeg page images' width (in pixels) when generated automatically by the builder/bulk loader.\n\nDefault: '630'", false);
            Add_Setting_UI("JPEG2000 Server", -1, empty_options, "URL for the Aware JPEG2000 Server for displaying JPEG2000 images.", false);
            Add_Setting_UI("Kakadu JP2 Command", -1, empty_options, "Kakadu JPEG2000 script will override the specifications used when creating zoomable images.\n\nIf this is blank, the default specifications will be used which match those used by the National Digital Newspaper Program and University of Florida Digital Collections.", false);
            Add_Setting_UI("Log Files Directory", -1, empty_options, "Network location for the share within which the builder/bulk loader logs should be copied to become web accessible.\n\nExample: '\\\\lib-sandbox\\Design\\extra\\logs\\'", false, default_location + "design\\extra\\logs\\");
            Add_Setting_UI("Log Files URL", -1, empty_options, "URL for the builder/bulk loader logs files.\n\nExample: 'http://ufdc.ufl.edu/design/extra/logs/'", false, default_url + "design/exra/logs/");
            Add_Setting_UI("Mango Union Search Base URL", -1, empty_options, "Florida SUS state-wide catalog base URL for determining the number of physical holdings which match a given search.\n\nExample: 'http://solrcits.fcla.edu/citsZ.jsp?type=search&base=uf'", true);
            Add_Setting_UI("Mango Union Search Text", -1, empty_options, "Text to display the number of hits found in the Florida SUS-wide catalog.\n\nUse the value '%1' in the string where the number of hits should be inserted.\n\nExample: '%1 matches found in the statewide catalog'", true);
            Add_Setting_UI("MarcXML Feed Location", -1, empty_options, "Network location or share where any geneated MarcXML feed should be written.\n\nExample: '\\\\lib-sandbox\\Data\\'", false, default_location + "data\\");
            Add_Setting_UI("OAI Repository Identifier", 200, empty_options, "Identification for this repository when serving the OAI-PMH feeds.\n\nThis appears when a as 'Repository Identifier' under the OAI-Identifier when a user identifies the OAI-PMH repository.\n\nExamples: 'ufdc', 'sobekcm', 'dloc', etc..", false);
            Add_Setting_UI("OAI Repository Name", -1, empty_options, "Complete name for this repository when serving the OAI-PMH feeds.\n\nThis appears when a as 'Repository Name' when a user identifies the OAI-PMH repository.\n\nExamples: 'University of Florida Digital Collections', 'Digital Library of the Caribbean', etc..", false);
            Add_Setting_UI("OAI Resource Identifier Base", 200, empty_options, "Base identifier used for all resources found within this repository when serving them via OAI-PMH.\n\nThe complete item identifier begins with this base and then adds the bibliographic identifier (BibID) to complete the unique resource identifier.\n\nExamples: 'oai:sobekcm:', 'oai:www.uflib.ufl.edu.ufdc:', etc..", false);
            Add_Setting_UI("OCR Engine Command", -1, empty_options, "If you wish to utilize an OCR engine in the builder/bulk loader, add the command-line call to the engine here.\n\nUse %1 as a place holder for the ingoing image file name and %2 as a placeholder for the output text file name.\n\nExample: 'C:\\OCR\\Engine.exe -in %1 -out %2'", false);
            Add_Setting_UI("Page Solr Index URL", -1, empty_options, "URL for the resource-level solr index used when searching for matching pages within a single document.\n\nExample: 'http://*****:*****@corp.edu;[email protected]'", false);
            Add_Setting_UI("Shibboleth System Name", 200, empty_options, "Local name of the Shibboleth authentication system.\n\nExamples: 'GatorLink', 'PantherSoft', etc..", false);
            Add_Setting_UI("Shibboleth System URL", -1, empty_options, "URL for the Shibboleth authentication process.", false);
            Add_Setting_UI("Show Florida SUS Settings", 70, boolean_options, "Some system settings are only applicable to institutions which are part of the Florida State University System.  Setting this value to TRUE will show these settings, while FALSE will suppress them.\n\nIf this value is changed, you willl need to save the settings for it to reload and reflect the change.", false, "false");
            Add_Setting_UI("SobekCM Image Server", -1, empty_options, "URL for the SobekCM Image Server application which overlays JPEGs and JPEG2000s with highlighting on regions of interest.", false);
            Add_Setting_UI("Static Pages Location", -1, empty_options, "Location where the static files are located for providing the full citation and text for indexing, either on the same server as the web application or as a network share.\n\nIt is recommended that these files be on the same server as the web server, rather than remote storage, to increase the speed in which requests from search engine indexers can be fulfilled.\n\nExample: 'C:\\inetpub\\wwwroot\\UFDC Web\\SobekCM\\data\\'.", false, default_location + "data\\");
            Add_Setting_UI("Statistics Caching Enabled", 70, boolean_options, "Flag indicates if the basic usage and item count information should be cached for up to 24 hours as static XML files written in the web server's temp directory.\n\nThis should be enabled if your library is quite large as it can take a fair amount of time to retrieve this information and these screens are made available for search engine index robots for indexing.", false);
            Add_Setting_UI("System Base Abbreviation", 100, empty_options, "Base abbreviation to be used when the system refers to itself to the user, such as the main tabs to take a user to the home pages.\n\nThis abbreviation should be kept as short as possible.\n\nExamples: 'UFDC', 'dLOC', 'Sobek', etc..", false);
            Add_Setting_UI("System Base Name", -1, empty_options, "Overall name of the system, to be used when creating MARC records and in several other locations.", false);
            Add_Setting_UI("System Base URL", -1, empty_options, "Base URL which points to the web application.\n\nExamples: 'http://localhost/sobekcm/', 'http://ufdc.ufl.edu/', etc..", false, default_url);
            Add_Setting_UI("System Default Language", 150, language_options, "Default system user interface language.  If the user's HTML request does not include a language supported by the interface or which does not include specific translations for a field, this default language is utilized.", false, "English");
            Add_Setting_UI("System Email", -1, empty_options, "Default email address for the system, which is sent emails when users opt to contact the administrators.\n\nThis can be changed for individual aggregations but at least one email is required for the overall system.\n\nIf you are using multiple email addresses, seperate them with a semi-colon.\n\nExample: '[email protected];[email protected]'", false);
            Add_Setting_UI("System Error Email", -1, empty_options, "Email address used when a critical system error occurs which may require investigation or correction.\n\nIf you are using multiple email addresses, seperate them with a semi-colon.\n\nExample: '[email protected];[email protected]'", false);
            Add_Setting_UI("Thumbnail Height", 60, empty_options, "Restriction on the size of the page image thumbnails' height (in pixels) when generated automatically by the builder/bulk loader.\n\nDefault: '300'", false);
            Add_Setting_UI("Thumbnail Width", 60, empty_options, "Restriction on the size of the page image thumbnails' width (in pixels) when generated automatically by the builder/bulk loader.\n\nDefault: '150'", false);
            Add_Setting_UI("Web In Process Submission Location", -1, empty_options, "Location where packages are built by users during online submissions and metadata updates.\n\nThis generally needs to be on the web server and have appropriate access for read/write.\n\nIf nothing is indicated in this field, the system will automatically use the 'mySobek\\InProcess' subfolder under the web application.", false, default_location + "mySobek\\InProcess\\");
            Add_Setting_UI("Web Output Caching Minutes", 200, new[] { "0", "1", "2", "3", "5", "10", "15" }, "This setting controls how long the client's browser is instructed to cache the served web page.\n\nSetting this value higher removes the round-trip when requesting a recently requested page.  It also means that some changes may not be reflected until the refresh button is pressed.\n\nIn general, this setting is only applied to public-style pages, and not personalized pages, such as the bookshelf views.", false, "0");

            // Is this a post-back requesting to save all this data?
            if (Current_Mode.isPostBack)
            {
                NameValueCollection form = HttpContext.Current.Request.Form;
                string action_value      = form["admin_settings_action"];
                if (action_value == "save")
                {
                    // Populate all the new settings
                    Dictionary <string, string> newSettings = new Dictionary <string, string>();

                    int errors = 0;
                    // Step through each setting
                    foreach (int thisSettingCounter in idToSetting.Keys)
                    {
                        Setting_Info thisSetting = idToSetting[thisSettingCounter];
                        if (thisSetting.isVariable)
                        {
                            string setting_key = thisSetting.Key;
                            if (form["setting" + thisSettingCounter] != null)
                            {
                                string setting_value = form["setting" + thisSettingCounter];
                                newSettings[setting_key] = setting_value;
                            }
                        }
                    }

                    // Now, validate all this
                    errorBuilder = new StringBuilder();
                    isValid      = true;
                    if (validate_update_entered_data(newSettings))
                    {
                        // Try to save each setting
                        errors += newSettings.Keys.Count(thisKey => !SobekCM_Database.Set_Setting(thisKey, newSettings[thisKey]));

                        // Prepare the action message
                        if (errors > 0)
                        {
                            actionMessage = "Save completed, but with " + errors + " errors.";
                        }
                        else
                        {
                            actionMessage = "Settings saved";
                        }

                        // Get the current settings from the database
                        settings = SobekCM_Database.Get_Settings(Tracer);

                        // Assign this to be used by the system
                        SobekCM_Library_Settings.Refresh(SobekCM_Database.Get_Settings_Complete(null));
                    }
                    else
                    {
                        actionMessage = errorBuilder.ToString().Replace("\n", "<br />");
                        settings      = newSettings;
                    }
                }
            }
        }