/// <summary> Constructor for a new instance of the Worker_BulkLoader class </summary> /// <param name="Logger"> Log file object for logging progress </param> /// <param name="Verbose"> Flag indicates if the builder is in verbose mode, where it should log alot more information </param> /// <param name="InstanceName"> Name of this instance, likely from the Builder config </param> /// <param name="Can_Abort"></param> public Worker_BulkLoader(LogFileXHTML Logger, bool Verbose, string InstanceName, bool Can_Abort ) { // Save the log file and verbose flag logger = Logger; verbose = Verbose; instanceName = InstanceName; canAbort = Can_Abort; multiInstanceBuilder = SobekCM_Library_Settings.Database_Connections.Count > 1; Add_NonError_To_Log("Worker_BulkLoader.Constructor: Start", verbose, String.Empty, String.Empty, -1); // Create the METS validation objects thisMetsValidator = new SobekCM_METS_Validator( String.Empty ); metsSchemeValidator = new METS_Validator_Object(false); Add_NonError_To_Log("Worker_BulkLoader.Constructor: Created Validators", verbose, String.Empty, String.Empty, -1); // Create new list of collections to build aggregations_to_refresh = new List<string>(); items_by_aggregation = new Dictionary<string, List<string>>(); // get all the info Refresh_Settings_And_Item_List(); // Ensure there is SOME instance name if (instanceName.Length == 0) instanceName = SobekCM_Library_Settings.System_Name; // Create the new statics page builder staticBuilder = new Static_Pages_Builder(SobekCM_Library_Settings.Application_Server_URL, SobekCM_Library_Settings.Static_Pages_Location, SobekCM_Library_Settings.Application_Server_Network); Add_NonError_To_Log("Worker_BulkLoader.Constructor: Created Static Pages Builder", verbose, String.Empty, String.Empty, -1); // Get the list of collection codes codeManager = new Aggregation_Code_Manager(); SobekCM_Database.Populate_Code_Manager(codeManager, null); Add_NonError_To_Log("Worker_BulkLoader.Constructor: Populated code manager with " + codeManager.All_Aggregations.Count + " aggregations.", verbose, String.Empty, String.Empty, -1); // Set some defaults aborted = false; // Get the executable path/file for ghostscript and imagemagick ghostscript_executable = SobekCM_Library_Settings.Ghostscript_Executable; imagemagick_executable = SobekCM_Library_Settings.ImageMagick_Executable; Add_NonError_To_Log("Worker_BulkLoader.Constructor: Done", verbose, String.Empty, String.Empty, -1); }
/// <summary> Checks that each file in the package is present in the directory. </summary> /// <param name="thisPackage">Package to check</param> /// <param name="matchCheckSums">Flag indicates whether to match checksums</param> /// <returns>TRUE if everything validates, otherwise FALSE </returns> public static bool Validate_Files(SobekCM_Item thisPackage, bool matchCheckSums) { // Build the METS validator and validate the files SobekCM_METS_Validator validator = new SobekCM_METS_Validator(thisPackage); return validator.Check_Files(thisPackage.Source_Directory, matchCheckSums); }
/// <summary> Checks that each file in the package is present in the directory. </summary> /// <param name="matchCheckSums">Flag indicates whether to match checksums</param> /// <returns>TRUE if everything validates, otherwise FALSE </returns> /// <remarks> This sets the Validation_Errors property of this object </remarks> public bool Validate_Files(bool matchCheckSums) { // Build the METS validator and validate the files SobekCM_METS_Validator validator = new SobekCM_METS_Validator(this); bool returnVal = validator.Check_Files(Source_Directory, matchCheckSums); // Save the validation errors validationErrors = returnVal ? String.Empty : validator.ValidationError; return returnVal; }
/// <summary> Validates the metadata for each folder and classified as package either adding /// a new item or updating an existing item versus a package requesting a delete </summary> /// <param name="BuilderFolder"> Builder folder upon which to perform all work </param> /// <param name="IncomingPackages"> List of valid incoming packages, which may be modified by this process </param> /// <param name="Deletes"> List of valid deletes, which may be modifyed by this process </param> public override void DoWork(Actionable_Builder_Source_Folder BuilderFolder, List<Incoming_Digital_Resource> IncomingPackages, List<Incoming_Digital_Resource> Deletes) { if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Perform_BulkLoader: Begin validating and classifying packages in incoming/process folders", "Verbose", String.Empty, String.Empty, -1); // If the maximum number of (incoming, non-delete) packages have already been set aside to process, no need to continue on this folder if ((MultiInstance_Builder_Settings.Instance_Package_Limit > 0) && (IncomingPackages.Count >= MultiInstance_Builder_Settings.Instance_Package_Limit)) { OnProcess("...Package validation aborted - maximum number of packages ( " + MultiInstance_Builder_Settings.Instance_Package_Limit + " ) reached", "Verbose", String.Empty, String.Empty, -1); return; } try { // Only continue if the processing folder exists and has subdirectories if ((Directory.Exists(BuilderFolder.Processing_Folder)) && (Directory.GetDirectories(BuilderFolder.Processing_Folder).Length > 0)) { // Get the list of all packages in the processing folder if (Settings.Builder.Verbose_Flag) OnProcess("....Validate packages for " + BuilderFolder.Folder_Name, "Verbose", String.Empty, String.Empty, -1); List<Incoming_Digital_Resource> packages = BuilderFolder.Packages_For_Processing; if (packages.Count > 0) { // Create the METS validation objects if (thisMetsValidator == null) { if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Constructor: Created Validators", "Verbose", String.Empty, String.Empty, -1); thisMetsValidator = new SobekCM_METS_Validator(String.Empty); metsSchemeValidator = new METS_Validator_Object(false); } // Step through each package foreach (Incoming_Digital_Resource resource in packages) { // Validate the categorize the package if (Settings.Builder.Verbose_Flag) OnProcess("........Checking '" + resource.Folder_Name + "'", "Verbose", resource.Folder_Name.Replace("_", ":"), String.Empty, -1); // If there is no METS file, use special code to check this if (Directory.GetFiles(resource.Resource_Folder, "*.mets*").Length == 0) { DirectoryInfo noMetsDirInfo = new DirectoryInfo(resource.Resource_Folder); string vid = noMetsDirInfo.Name; if (noMetsDirInfo.Parent != null) // Should never be null { string bibid = noMetsDirInfo.Parent.Name; if ((vid.Length == 16) && (vid[10] == '_')) { bibid = vid.Substring(0, 10); vid = vid.Substring(11, 5); } // Is this allowed in this incomnig folder? if (BuilderFolder.Allow_Folders_No_Metadata) { if (itemTable == null) { DataSet itemListFromDb = SobekCM_Database.Get_Item_List(true, null); // Reload the settings if (itemListFromDb == null) { OnError("ValidateAndClassifyModule : Unable to pull the item table from the database", String.Empty, String.Empty, -1); return; } // Save the item table itemTable = itemListFromDb.Tables[0]; } DataRow[] selected = itemTable.Select("BibID='" + bibid + "' and VID='" + vid + "'"); if (selected.Length > 0) { resource.BibID = bibid; resource.VID = vid; resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.FOLDER_OF_FILES; IncomingPackages.Add(resource); } else { OnError("METS-less folder is not a valid BibID/VID combination", resource.Folder_Name.Replace("_", ":"), "NONE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " in " + BuilderFolder.Folder_Name + " to the failures folder", resource.Folder_Name.Replace("_", ":"), "NONE", -1); } } } else { OnError("METS-less folders are not allowed in " + BuilderFolder.Folder_Name, bibid + ":" + vid, "NONE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " in " + BuilderFolder.Folder_Name + " to the failures folder", resource.Folder_Name.Replace("_", ":"), "NONE", -1); } } } } else { long validateId = OnProcess("....Validating METS file for " + resource.Folder_Name, "Folder Process", resource.Folder_Name.Replace("_", ":"), "UNKNOWN", -1); string validation_errors = Validate_and_Read_METS(resource, thisMetsValidator, metsSchemeValidator); // Save any errors to the main log if (validation_errors.Length > 0) { // Save the validation errors to the main log Save_Validation_Errors_To_Log(validation_errors, resource.Source_Folder.Folder_Name.Replace("_", ":"), validateId); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " in " + BuilderFolder.Folder_Name + " to the failures folder", resource.Folder_Name.Replace("_", ":"), "NONE", -1); } } else { // Categorize remaining packages by type switch (resource.Resource_Type) { case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.PARTIAL_PACKAGE: case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.COMPLETE_PACKAGE: IncomingPackages.Add(resource); break; case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.METADATA_UPDATE: if (BuilderFolder.Allow_Metadata_Updates) { IncomingPackages.Add(resource); } else { OnError("Metadata update is not allowed in " + BuilderFolder.Folder_Name, resource.Folder_Name.Replace("_", ":"), "METADATA UPDATE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " to failures", resource.Folder_Name.Replace("_", ":"), String.Empty, -1); } } break; case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.DELETE: if (BuilderFolder.Allow_Deletes) { Deletes.Add(resource); } else { OnError("Delete is not allowed in " + BuilderFolder.Folder_Name, resource.Folder_Name.Replace("_", ":"), "DELETE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " to failures", resource.Folder_Name.Replace("_", ":"), String.Empty, -1); } } break; } } } // If the maximum number of (incoming, non-delete) packages has now been met, no need to classify anymore if ((MultiInstance_Builder_Settings.Instance_Package_Limit > 0) && (IncomingPackages.Count >= MultiInstance_Builder_Settings.Instance_Package_Limit)) { OnProcess("...Package validation aborted - maximum number of packages ( " + MultiInstance_Builder_Settings.Instance_Package_Limit + " ) reached", "Verbose", String.Empty, String.Empty, -1); return; } } } } } catch (Exception ee) { OnError("Error in harvesting packages from processing : " + ee.Message + "\n" + ee.StackTrace , String.Empty, String.Empty, -1); } }
/// <summary> Validates and reads the data from the METS file associated with this incoming digital resource </summary> /// <param name="Resource"></param> /// <param name="ThisMetsValidator"></param> /// <param name="MetsSchemeValidator"></param> /// <returns></returns> public string Validate_and_Read_METS(Incoming_Digital_Resource Resource, SobekCM_METS_Validator ThisMetsValidator, METS_Validator_Object MetsSchemeValidator) { if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Start ( " + Resource.Folder_Name + " )", "Verbose", String.Empty, String.Empty, -1); // Determine invalid bib id and vid for any errors string invalid_bibid = String.Empty; string invalid_vid = String.Empty; string bib_vid = String.Empty; if ((Resource.Folder_Name.Length == 16) && (Resource.Folder_Name[10] == '_')) { invalid_bibid = Resource.Folder_Name.Substring(0, 10); invalid_vid = Resource.Folder_Name.Substring(11, 5); bib_vid = invalid_bibid + ":" + invalid_vid; } else if (Resource.Folder_Name.Length == 10) { invalid_bibid = Resource.Folder_Name; invalid_vid = "none"; bib_vid = invalid_bibid + ":" + invalid_vid; } // Verify that a METS file exists if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Check for METS existence", "Verbose", bib_vid, String.Empty, -1); if (ThisMetsValidator.METS_Existence_Check(Resource.Resource_Folder) == false) { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, ThisMetsValidator.ValidationError, "Missing"); return ThisMetsValidator.ValidationError; } // Get the name of this METS file string[] mets_files = Directory.GetFiles(Resource.Resource_Folder, invalid_bibid + "_" + invalid_vid + ".mets*"); string mets_file = String.Empty; try { mets_file = mets_files.Length == 0 ? Directory.GetFiles(Resource.Resource_Folder, "*mets*")[0] : mets_files[0]; } catch (Exception) { Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Unable to locate correct METS file", "UNKNOWN"); } if (mets_file == String.Empty) { Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Unable to locate correct METS file", "UNKNOWN"); } // check the mets file against the scheme FileInfo metsFileInfo = new FileInfo(mets_file); if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Validate against " + metsFileInfo.Name + " against the schema", "Verbose", bib_vid, String.Empty, -1); if (MetsSchemeValidator.Validate_Against_Schema(mets_file) == false) { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, MetsSchemeValidator.Errors, "UNKNOWN", "METS Scheme Validation Error"); return MetsSchemeValidator.Errors; } SobekCM_Item returnValue; try { if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Read validated METS file", "Verbose", Resource.Folder_Name.Replace("_", ":"), "UNKNOWN", -1); returnValue = SobekCM_Item.Read_METS(mets_file); } catch { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Error encountered while reading the METS file '" + mets_file, "UNKNOWN"); return "Error encountered while reading the METS file '" + mets_file; } // If the METS file was read, determine if this is valid by the METS type if (returnValue != null) { // If there is a bibid and no vid, check to see what's going on here if ((returnValue.BibID.Length == 10) && (returnValue.VID.Length == 0)) { DataRow[] matches = itemTable.Select("BibID='" + returnValue.BibID + "'"); if (matches.Length == 0) { returnValue.VID = "00001"; } else { if ((matches.Length == 1) && (matches[0]["VID"].ToString() == "00001")) returnValue.VID = "00001"; else { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "METS file does not have a VID and belongs to a multi-volume title", Resource.METS_Type_String); return "METS file does not have a VID and belongs to a multi-volume title"; } } } // Do the basic check first if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Perform basic check", "Verbose", Resource.Resource_Folder.Replace("_", ":"), Resource.METS_Type_String, -1); if (!ThisMetsValidator.SobekCM_Standard_Check(returnValue, Resource.Resource_Folder)) { // Save this error log and return null Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, ThisMetsValidator.ValidationError, Resource.METS_Type_String); return ThisMetsValidator.ValidationError; } // If this is a COMPLETE package, check files if (returnValue.METS_Header.RecordStatus_Enum == METS_Record_Status.COMPLETE) { if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Check resource files (existence and checksum)", "Verbose", Resource.Resource_Folder.Replace("_", ":"), Resource.METS_Type_String, -1); // check if all files exist in the package and the MD5 checksum if the checksum flag is true if (!ThisMetsValidator.Check_Files(Resource.Resource_Folder, Settings.Builder.VerifyCheckSum)) { // Save this error log and return null Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, ThisMetsValidator.ValidationError, Resource.METS_Type_String); return ThisMetsValidator.ValidationError; } } // This is apparently valid, so do some final checks and copying into the resource wrapper Resource.BibID = returnValue.BibID; Resource.VID = returnValue.VID; switch (returnValue.METS_Header.RecordStatus_Enum) { case METS_Record_Status.METADATA_UPDATE: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.METADATA_UPDATE; break; case METS_Record_Status.COMPLETE: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.COMPLETE_PACKAGE; break; case METS_Record_Status.PARTIAL: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.PARTIAL_PACKAGE; break; case METS_Record_Status.DELETE: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.DELETE; break; case METS_Record_Status.BIB_LEVEL: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.BIB_LEVEL; break; } if (Settings.Builder.Verbose_Flag) OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Complete - validated", "Verbose", Resource.Resource_Folder.Replace("_", ":"), Resource.METS_Type_String, -1); return String.Empty; } // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Error encountered while reading the METS file '" + mets_file, "UNKNOWN"); return "Error encountered while reading the METS file '" + mets_file; }
/// <summary> Method releases all resources </summary> /// <remarks> Method is overridden to release XML/METS validator objects </remarks> public override void ReleaseResources() { thisMetsValidator = null; metsSchemeValidator = null; itemTable = null; }
/// <summary> Validates the metadata for each folder and classified as package either adding /// a new item or updating an existing item versus a package requesting a delete </summary> /// <param name="BuilderFolder"> Builder folder upon which to perform all work </param> /// <param name="IncomingPackages"> List of valid incoming packages, which may be modified by this process </param> /// <param name="Deletes"> List of valid deletes, which may be modifyed by this process </param> public override void DoWork(Actionable_Builder_Source_Folder BuilderFolder, List <Incoming_Digital_Resource> IncomingPackages, List <Incoming_Digital_Resource> Deletes) { if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Perform_BulkLoader: Begin validating and classifying packages in incoming/process folders", "Verbose", String.Empty, String.Empty, -1); } // If the maximum number of (incoming, non-delete) packages have already been set aside to process, no need to continue on this folder if ((MultiInstance_Builder_Settings.Instance_Package_Limit > 0) && (IncomingPackages.Count >= MultiInstance_Builder_Settings.Instance_Package_Limit)) { OnProcess("...Package validation aborted - maximum number of packages ( " + MultiInstance_Builder_Settings.Instance_Package_Limit + " ) reached", "Verbose", String.Empty, String.Empty, -1); return; } try { // Only continue if the processing folder exists and has subdirectories if ((Directory.Exists(BuilderFolder.Processing_Folder)) && (Directory.GetDirectories(BuilderFolder.Processing_Folder).Length > 0)) { // Get the list of all packages in the processing folder if (Settings.Builder.Verbose_Flag) { OnProcess("....Validate packages for " + BuilderFolder.Folder_Name, "Verbose", String.Empty, String.Empty, -1); } List <Incoming_Digital_Resource> packages = BuilderFolder.Packages_For_Processing; if (packages.Count > 0) { // Create the METS validation objects if (thisMetsValidator == null) { if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Constructor: Created Validators", "Verbose", String.Empty, String.Empty, -1); } thisMetsValidator = new SobekCM_METS_Validator(String.Empty); metsSchemeValidator = new METS_Validator_Object(false); } // Step through each package foreach (Incoming_Digital_Resource resource in packages) { // Validate the categorize the package if (Settings.Builder.Verbose_Flag) { OnProcess("........Checking '" + resource.Folder_Name + "'", "Verbose", resource.Folder_Name.Replace("_", ":"), String.Empty, -1); } // If there is no METS file, use special code to check this if (Directory.GetFiles(resource.Resource_Folder, "*.mets*").Length == 0) { DirectoryInfo noMetsDirInfo = new DirectoryInfo(resource.Resource_Folder); string vid = noMetsDirInfo.Name; if (noMetsDirInfo.Parent != null) // Should never be null { string bibid = noMetsDirInfo.Parent.Name; if ((vid.Length == 16) && (vid[10] == '_')) { bibid = vid.Substring(0, 10); vid = vid.Substring(11, 5); } // Is this allowed in this incomnig folder? if (BuilderFolder.Allow_Folders_No_Metadata) { if (itemTable == null) { DataSet itemListFromDb = Engine_Library.Database.Engine_Database.Item_List(true, null); // Reload the settings if (itemListFromDb == null) { OnError("ValidateAndClassifyModule : Unable to pull the item table from the database", String.Empty, String.Empty, -1); return; } // Save the item table itemTable = itemListFromDb.Tables[0]; } DataRow[] selected = itemTable.Select("BibID='" + bibid + "' and VID='" + vid + "'"); if (selected.Length > 0) { resource.BibID = bibid; resource.VID = vid; resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.FOLDER_OF_FILES; IncomingPackages.Add(resource); } else { OnError("METS-less folder is not a valid BibID/VID combination", resource.Folder_Name.Replace("_", ":"), "NONE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " in " + BuilderFolder.Folder_Name + " to the failures folder", resource.Folder_Name.Replace("_", ":"), "NONE", -1); } } } else { OnError("METS-less folders are not allowed in " + BuilderFolder.Folder_Name, bibid + ":" + vid, "NONE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " in " + BuilderFolder.Folder_Name + " to the failures folder", resource.Folder_Name.Replace("_", ":"), "NONE", -1); } } } } else { long validateId = OnProcess("....Validating METS file for " + resource.Folder_Name, "Folder Process", resource.Folder_Name.Replace("_", ":"), "UNKNOWN", -1); string validation_errors = Validate_and_Read_METS(resource, thisMetsValidator, metsSchemeValidator); // Save any errors to the main log if (validation_errors.Length > 0) { // Save the validation errors to the main log Save_Validation_Errors_To_Log(validation_errors, resource.Source_Folder.Folder_Name.Replace("_", ":"), validateId); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " in " + BuilderFolder.Folder_Name + " to the failures folder", resource.Folder_Name.Replace("_", ":"), "NONE", -1); } } else { // Categorize remaining packages by type switch (resource.Resource_Type) { case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.PARTIAL_PACKAGE: case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.COMPLETE_PACKAGE: IncomingPackages.Add(resource); break; case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.METADATA_UPDATE: if (BuilderFolder.Allow_Metadata_Updates) { IncomingPackages.Add(resource); } else { OnError("Metadata update is not allowed in " + BuilderFolder.Folder_Name, resource.Folder_Name.Replace("_", ":"), "METADATA UPDATE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " to failures", resource.Folder_Name.Replace("_", ":"), String.Empty, -1); } } break; case Incoming_Digital_Resource.Incoming_Digital_Resource_Type.DELETE: if (BuilderFolder.Allow_Deletes) { Deletes.Add(resource); } else { OnError("Delete is not allowed in " + BuilderFolder.Folder_Name, resource.Folder_Name.Replace("_", ":"), "DELETE", -1); // Move this resource if (!resource.Move(BuilderFolder.Failures_Folder)) { OnError("Unable to move folder " + resource.Folder_Name + " to failures", resource.Folder_Name.Replace("_", ":"), String.Empty, -1); } } break; } } } // If the maximum number of (incoming, non-delete) packages has now been met, no need to classify anymore if ((MultiInstance_Builder_Settings.Instance_Package_Limit > 0) && (IncomingPackages.Count >= MultiInstance_Builder_Settings.Instance_Package_Limit)) { OnProcess("...Package validation aborted - maximum number of packages ( " + MultiInstance_Builder_Settings.Instance_Package_Limit + " ) reached", "Verbose", String.Empty, String.Empty, -1); return; } } } } } catch (Exception ee) { OnError("Error in harvesting packages from processing : " + ee.Message + "\n" + ee.StackTrace, String.Empty, String.Empty, -1); } }
/// <summary> Validates and reads the data from the METS file associated with this incoming digital resource </summary> /// <param name="Resource"></param> /// <param name="ThisMetsValidator"></param> /// <param name="MetsSchemeValidator"></param> /// <returns></returns> public string Validate_and_Read_METS(Incoming_Digital_Resource Resource, SobekCM_METS_Validator ThisMetsValidator, METS_Validator_Object MetsSchemeValidator) { if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Start ( " + Resource.Folder_Name + " )", "Verbose", String.Empty, String.Empty, -1); } // Determine invalid bib id and vid for any errors string invalid_bibid = String.Empty; string invalid_vid = String.Empty; string bib_vid = String.Empty; if ((Resource.Folder_Name.Length == 16) && (Resource.Folder_Name[10] == '_')) { invalid_bibid = Resource.Folder_Name.Substring(0, 10); invalid_vid = Resource.Folder_Name.Substring(11, 5); bib_vid = invalid_bibid + ":" + invalid_vid; } else if (Resource.Folder_Name.Length == 10) { invalid_bibid = Resource.Folder_Name; invalid_vid = "none"; bib_vid = invalid_bibid + ":" + invalid_vid; } // Verify that a METS file exists if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Check for METS existence", "Verbose", bib_vid, String.Empty, -1); } if (ThisMetsValidator.METS_Existence_Check(Resource.Resource_Folder) == false) { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, ThisMetsValidator.ValidationError, "Missing"); return(ThisMetsValidator.ValidationError); } // Get the name of this METS file string[] mets_files = Directory.GetFiles(Resource.Resource_Folder, invalid_bibid + "_" + invalid_vid + ".mets*"); string mets_file = String.Empty; try { mets_file = mets_files.Length == 0 ? Directory.GetFiles(Resource.Resource_Folder, "*mets*")[0] : mets_files[0]; } catch (Exception) { Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Unable to locate correct METS file", "UNKNOWN"); } if (mets_file == String.Empty) { Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Unable to locate correct METS file", "UNKNOWN"); } // check the mets file against the scheme FileInfo metsFileInfo = new FileInfo(mets_file); if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Validate against " + metsFileInfo.Name + " against the schema", "Verbose", bib_vid, String.Empty, -1); } if (MetsSchemeValidator.Validate_Against_Schema(mets_file) == false) { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, MetsSchemeValidator.Errors, "UNKNOWN", "METS Scheme Validation Error"); return(MetsSchemeValidator.Errors); } SobekCM_Item returnValue; try { if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Read validated METS file", "Verbose", Resource.Folder_Name.Replace("_", ":"), "UNKNOWN", -1); } returnValue = SobekCM_Item.Read_METS(mets_file); } catch { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Error encountered while reading the METS file '" + mets_file, "UNKNOWN"); return("Error encountered while reading the METS file '" + mets_file); } // If the METS file was read, determine if this is valid by the METS type if (returnValue != null) { // If there is a bibid and no vid, check to see what's going on here if ((returnValue.BibID.Length == 10) && (returnValue.VID.Length == 0)) { DataRow[] matches = itemTable.Select("BibID='" + returnValue.BibID + "'"); if (matches.Length == 0) { returnValue.VID = "00001"; } else { if ((matches.Length == 1) && (matches[0]["VID"].ToString() == "00001")) { returnValue.VID = "00001"; } else { // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "METS file does not have a VID and belongs to a multi-volume title", Resource.METS_Type_String); return("METS file does not have a VID and belongs to a multi-volume title"); } } } // Do the basic check first if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Perform basic check", "Verbose", Resource.Resource_Folder.Replace("_", ":"), Resource.METS_Type_String, -1); } if (!ThisMetsValidator.SobekCM_Standard_Check(returnValue, Resource.Resource_Folder)) { // Save this error log and return null Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, ThisMetsValidator.ValidationError, Resource.METS_Type_String); return(ThisMetsValidator.ValidationError); } // If this is a COMPLETE package, check files if (returnValue.METS_Header.RecordStatus_Enum == METS_Record_Status.COMPLETE) { if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Check resource files (existence and checksum)", "Verbose", Resource.Resource_Folder.Replace("_", ":"), Resource.METS_Type_String, -1); } // check if all files exist in the package and the MD5 checksum if the checksum flag is true if (!ThisMetsValidator.Check_Files(Resource.Resource_Folder, Settings.Builder.VerifyCheckSum)) { // Save this error log and return null Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, ThisMetsValidator.ValidationError, Resource.METS_Type_String); return(ThisMetsValidator.ValidationError); } } // This is apparently valid, so do some final checks and copying into the resource wrapper Resource.BibID = returnValue.BibID; Resource.VID = returnValue.VID; switch (returnValue.METS_Header.RecordStatus_Enum) { case METS_Record_Status.METADATA_UPDATE: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.METADATA_UPDATE; break; case METS_Record_Status.COMPLETE: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.COMPLETE_PACKAGE; break; case METS_Record_Status.PARTIAL: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.PARTIAL_PACKAGE; break; case METS_Record_Status.DELETE: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.DELETE; break; case METS_Record_Status.BIB_LEVEL: Resource.Resource_Type = Incoming_Digital_Resource.Incoming_Digital_Resource_Type.BIB_LEVEL; break; } if (Settings.Builder.Verbose_Flag) { OnProcess("ValidateAndClassifyModule.Validate_and_Read_METS: Complete - validated", "Verbose", Resource.Resource_Folder.Replace("_", ":"), Resource.METS_Type_String, -1); } return(String.Empty); } // Save this error log and return the error Create_Error_Log(Resource.Resource_Folder, Resource.Folder_Name, "Error encountered while reading the METS file '" + mets_file, "UNKNOWN"); return("Error encountered while reading the METS file '" + mets_file); }