private void recursively_build_all_files_list(List <SobekCM_File_Info> returnValue, List <Page_TreeNode> handledPages, abstract_TreeNode thisNode) { // Since this is pre-order, first 'visit' this if (thisNode.Page) { Page_TreeNode pageNode = (Page_TreeNode)thisNode; if (!handledPages.Contains(pageNode)) { foreach (SobekCM_File_Info file in pageNode.Files) { returnValue.Add(file); } handledPages.Add(pageNode); } } // is this a division node? .. which can have children .. if (!thisNode.Page) { Division_TreeNode thisDivNode = (Division_TreeNode)thisNode; // Do the same for all the children foreach (abstract_TreeNode childNode in thisDivNode.Nodes) { recursively_build_all_files_list(returnValue, handledPages, childNode); } } }
private void preorder_build(List <abstract_TreeNode> collection, abstract_TreeNode thisNode, bool only_add_pages) { // Since this is pre-order, first 'visit' this if (!only_add_pages) { collection.Add(thisNode); } else { // If we are just getting pages, only add if it is not already added if ((thisNode.Page) && (!collection.Contains(thisNode))) { collection.Add(thisNode); } } // is this a division node? .. which can have children .. if (!thisNode.Page) { Division_TreeNode thisDivNode = (Division_TreeNode)thisNode; // Do the same for all the children foreach (abstract_TreeNode childNode in thisDivNode.Nodes) { preorder_build(collection, childNode, only_add_pages); } } }
/// <summary> Adds a file object (with the appropriate divisions and pages) to this tree </summary> /// <param name="New_File"> New file object to add </param> /// <param name="Label"> Label for the page containing this file, if it is a new page </param> /// <remarks> This is generally used to add just a single file. To add many files, better logic should be implemented </remarks> public void Add_File(SobekCM_File_Info New_File, string Label) { // Determine the upper case name string systemname_upper = New_File.File_Name_Sans_Extension; // Look for a page/entity which has the same file name, else it will be added to the last division foreach (abstract_TreeNode rootNode in Roots) { if (recursively_add_file(rootNode, New_File, systemname_upper)) { return; } } // If not found, find the last division if (Roots.Count > 0) { if (!Roots[Roots.Count - 1].Page) { // Get his last division Division_TreeNode lastDivision = (Division_TreeNode)Roots[Roots.Count - 1]; // Find the last division then while ((lastDivision.Nodes.Count > 0) && (!lastDivision.Nodes[lastDivision.Nodes.Count - 1].Page)) { lastDivision = (Division_TreeNode)lastDivision.Nodes[lastDivision.Nodes.Count - 1]; } // Add this as a new page on the last division Page_TreeNode newPage = new Page_TreeNode(Label); lastDivision.Add_Child(newPage); // Now, add this file to the page newPage.Files.Add(New_File); } else { // No divisions at all, but pages exist at the top level, which is okay Page_TreeNode pageNode = (Page_TreeNode)Roots[Roots.Count - 1]; // Now, add this file to the page pageNode.Files.Add(New_File); } } else { // No nodes exist, so add a MAIN division node Division_TreeNode newDivNode = new Division_TreeNode("Main", String.Empty); Roots.Add(newDivNode); // Add this as a new page on the new division Page_TreeNode newPage = new Page_TreeNode(Label); newDivNode.Add_Child(newPage); // Now, add this file to the page newPage.Files.Add(New_File); } }
private void preorder_build(List <abstract_TreeNode> Collection, abstract_TreeNode ThisNode, bool OnlyAddPages, bool PagesMustHaveFiles) { // Since this is pre-order, first 'visit' this if (!OnlyAddPages) { Collection.Add(ThisNode); } else { // If we are just getting pages, only add if it is not already added if ((ThisNode.Page) && (!Collection.Contains(ThisNode))) { // If you just add all files, just add it here if (!PagesMustHaveFiles) { Collection.Add(ThisNode); } else { // Must ensure this page has files to add it Page_TreeNode asPage = ThisNode as Page_TreeNode; if (asPage != null) { if ((asPage.Files != null) && (asPage.Files.Count > 0)) { Collection.Add(asPage); } } } } } // is this a division node? .. which can have children .. if (!ThisNode.Page) { Division_TreeNode thisDivNode = (Division_TreeNode)ThisNode; // Do the same for all the children foreach (abstract_TreeNode childNode in thisDivNode.Nodes) { preorder_build(Collection, childNode, OnlyAddPages, PagesMustHaveFiles); } } }
private bool recursively_add_file(abstract_TreeNode Node, SobekCM_File_Info New_File, string SystemName_Upper) { // If this is a page, check for a match first if (Node.Page) { Page_TreeNode pageNode = (Page_TreeNode)Node; if (pageNode.Files.Count >= 1) { if (pageNode.Files[0].File_Name_Sans_Extension == SystemName_Upper) { // Belongs to this page. Now, just make sure it doesn't already exist foreach (SobekCM_File_Info thisFile in pageNode.Files) { if (thisFile.System_Name.ToUpper() == New_File.System_Name.ToUpper()) { return(true); } } // Not found, so add it to this page pageNode.Files.Add(New_File); return(true); } } } // If this was a division, check all pages if (!Node.Page) { Division_TreeNode divNode = (Division_TreeNode)Node; foreach (abstract_TreeNode childNodes in divNode.Nodes) { if (recursively_add_file(childNodes, New_File, SystemName_Upper)) { return(true); } } } // If nothing found that matches under this node, return false return(false); }
private bool recursively_check_for_any_files(abstract_TreeNode Node) { if (Node.Page) { if (((Page_TreeNode)Node).Files.Count > 0) { return(true); } } if (!Node.Page) { Division_TreeNode divNode = (Division_TreeNode)Node; foreach (abstract_TreeNode TreeNode in divNode.Nodes) { if (recursively_check_for_any_files(TreeNode)) { return(true); } } } return(false); }
/// <summary> Reads metadata from an open stream and saves to the provided item/package </summary> /// <param name="Input_Stream"> Open stream to read metadata from </param> /// <param name="Return_Package"> Package into which to read the metadata </param> /// <param name="Options"> Dictionary of any options which this metadata reader/writer may utilize </param> /// <param name="Error_Message">[OUTPUT] Explanation of the error, if an error occurs during reading </param> /// <returns>TRUE if successful, otherwise FALSE </returns> /// <remarks> Accepts two options: (1) 'METS_File_ReaderWriter:Minimize_File_Info' which tells whether the reader /// should just skip the file reading portion completely, and just read the bibliographic data ( Default is FALSE). /// (2) 'METS_File_ReaderWriter:Support_Divisional_dmdSec_amdSec' </remarks> public bool Read_Metadata(Stream Input_Stream, SobekCM_Item Return_Package, Dictionary<string, object> Options, out string Error_Message) { Error_Message = String.Empty; // Read the options from the dictionary of options bool minimizeFileInfo = false; if (Options != null) { if (Options.ContainsKey("METS_File_ReaderWriter:Minimize_File_Info")) bool.TryParse(Options["METS_File_ReaderWriter:Minimize_File_Info"].ToString(), out minimizeFileInfo); if (Options.ContainsKey("METS_File_ReaderWriter:Support_Divisional_dmdSec_amdSec")) { bool supportDivisionalDmdSecAmdSec; bool.TryParse(Options["METS_File_ReaderWriter:Support_Divisional_dmdSec_amdSec"].ToString(), out supportDivisionalDmdSecAmdSec); } } // Keep a list of all the files created, by file id, as additional data is gathered // from the different locations ( amdSec, fileSec, structmap ) Dictionary<string, SobekCM_File_Info> files_by_fileid = new Dictionary<string, SobekCM_File_Info>(); // For now, to do support for old way of doing downloads, build a list to hold // the deprecated download files List<Download_Info_DEPRECATED> deprecatedDownloads = new List<Download_Info_DEPRECATED>(); // Need to store the unanalyzed sections of dmdSec and amdSec until we determine if // the scope is the whole package, or the top-level div. We use lists as the value since // several sections may have NO id and the METS may even (incorrectly) have multiple sections // with the same ID Dictionary<string, List<Unanalyzed_METS_Section>> dmdSec = new Dictionary<string, List<Unanalyzed_METS_Section>>(); Dictionary<string, List<Unanalyzed_METS_Section>> amdSec = new Dictionary<string, List<Unanalyzed_METS_Section>>(); // Dictionaries store the link between dmdSec and amdSec id's to single divisions Dictionary<string, abstract_TreeNode> division_dmdids = new Dictionary<string, abstract_TreeNode>(); Dictionary<string, abstract_TreeNode> division_amdids = new Dictionary<string, abstract_TreeNode>(); try { // Try to read the XML XmlReader r = new XmlTextReader(Input_Stream); // Begin stepping through each of the XML nodes while (r.Read()) { #region Handle some processing instructions requested by Florida SUS's / FLVC (hope to deprecate) // Handle some processing instructions requested by Florida SUS's / FLVC if (r.NodeType == XmlNodeType.ProcessingInstruction) { if (r.Name.ToLower() == "fcla") { string value = r.Value.ToLower(); if (value.IndexOf("fda=\"yes\"") >= 0) { DAITSS_Info daitssInfo = Return_Package.Get_Metadata_Module(GlobalVar.DAITSS_METADATA_MODULE_KEY) as DAITSS_Info; if (daitssInfo == null) { daitssInfo = new DAITSS_Info(); Return_Package.Add_Metadata_Module(GlobalVar.DAITSS_METADATA_MODULE_KEY, daitssInfo); } daitssInfo.toArchive = true; } if (value.IndexOf("fda=\"no\"") >= 0) { DAITSS_Info daitssInfo2 = Return_Package.Get_Metadata_Module(GlobalVar.DAITSS_METADATA_MODULE_KEY) as DAITSS_Info; if (daitssInfo2 == null) { daitssInfo2 = new DAITSS_Info(); Return_Package.Add_Metadata_Module(GlobalVar.DAITSS_METADATA_MODULE_KEY, daitssInfo2); } daitssInfo2.toArchive = false; } } } #endregion if (r.NodeType == XmlNodeType.Element) { switch (r.Name.Replace("METS:", "")) { case "mets": if (r.MoveToAttribute("OBJID")) Return_Package.METS_Header.ObjectID = r.Value; break; case "metsHdr": read_mets_header(r.ReadSubtree(), Return_Package); break; case "dmdSec": case "dmdSecFedora": Unanalyzed_METS_Section thisDmdSec = store_dmd_sec(r.ReadSubtree()); if ( dmdSec.ContainsKey(thisDmdSec.ID)) dmdSec[thisDmdSec.ID].Add(thisDmdSec); else { List<Unanalyzed_METS_Section> newDmdSecList = new List<Unanalyzed_METS_Section>(); newDmdSecList.Add(thisDmdSec); dmdSec[thisDmdSec.ID] = newDmdSecList; } break; case "amdSec": Unanalyzed_METS_Section thisAmdSec = store_amd_sec(r.ReadSubtree()); if (amdSec.ContainsKey(thisAmdSec.ID)) amdSec[thisAmdSec.ID].Add(thisAmdSec); else { List<Unanalyzed_METS_Section> newAmdSecList = new List<Unanalyzed_METS_Section> {thisAmdSec}; amdSec[thisAmdSec.ID] = newAmdSecList; } break; case "fileSec": read_file_sec(r.ReadSubtree(), minimizeFileInfo, files_by_fileid); break; case "structMap": if (!r.IsEmptyElement) { read_struct_map(r.ReadSubtree(), Return_Package, files_by_fileid, division_dmdids, division_amdids); } break; case "behaviorSec": read_behavior_sec(r.ReadSubtree(), Return_Package); break; } } } // writer.Close(); r.Close(); } catch { // Do nothinh } Input_Stream.Close(); // Load some options for interoperability Dictionary<string, object> options = new Dictionary<string, object>(); options.Add("SobekCM_FileInfo_METS_amdSec_ReaderWriter:Files_By_FileID", files_by_fileid); #region Process the previously stored dmd sections // Now, process the previously stored dmd sections foreach (string thisDmdSecId in dmdSec.Keys) { // Could be multiple stored sections with the same (or no) ID foreach (Unanalyzed_METS_Section metsSection in dmdSec[thisDmdSecId]) { XmlReader reader = XmlReader.Create(new StringReader(metsSection.Inner_XML)); string mdtype = String.Empty; string othermdtype = String.Empty; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (reader.Name.ToLower().Replace("mets:", "") == "mdwrap") { if (reader.MoveToAttribute("MDTYPE")) mdtype = reader.Value; if (reader.MoveToAttribute("OTHERMDTYPE")) othermdtype = reader.Value; // NOt crazy about this part, but sometimes people do not use the OTHERMDTYPE // tag correctly, and just use the LABEL to differentiate the types if ((mdtype == "OTHER") && (othermdtype.Length == 0) && (reader.MoveToAttribute("LABEL"))) othermdtype = reader.Value; // Now, determine if this was a division-level read, or a package-wide if (division_dmdids.ContainsKey(thisDmdSecId)) { // Division level dmdSec // Get the division abstract_TreeNode node = division_dmdids[thisDmdSecId]; // Get an appropriate reader from the metadata configuration iDivision_dmdSec_ReaderWriter rw = ResourceObjectSettings.MetadataConfig.Get_Division_DmdSec_ReaderWriter(mdtype, othermdtype); // Is this dmdSec analyzable? (i.e., did we find an appropriate reader/writer?) if (rw == null) { node.Add_Unanalyzed_DMDSEC(metsSection); } else { rw.Read_dmdSec(reader, node, options); } } else { // Package-level dmdSec // Get an appropriate reader from the metadata configuration iPackage_dmdSec_ReaderWriter rw = ResourceObjectSettings.MetadataConfig.Get_Package_DmdSec_ReaderWriter(mdtype, othermdtype); // Is this dmdSec analyzable? (i.e., did we find an appropriate reader/writer?) if (rw == null) { Return_Package.Add_Unanalyzed_DMDSEC(metsSection); } else { rw.Read_dmdSec(reader, Return_Package, options); } } } } } } } #endregion #region Process the previously stored amd sections // Now, process the previously stored amd sections foreach (string thisAmdSecId in amdSec.Keys) { // Could be multiple stored sections with the same (or no) ID foreach (Unanalyzed_METS_Section metsSection in amdSec[thisAmdSecId]) { XmlReader reader = XmlReader.Create(new StringReader(metsSection.Inner_XML)); string mdtype = String.Empty; string othermdtype = String.Empty; while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (reader.Name.ToLower().Replace("mets:", "") == "mdwrap") { if (reader.MoveToAttribute("MDTYPE")) mdtype = reader.Value; if (reader.MoveToAttribute("OTHERMDTYPE")) othermdtype = reader.Value; // Package-level amdSec // Get an appropriate reader from the metadata configuration iPackage_amdSec_ReaderWriter rw = ResourceObjectSettings.MetadataConfig.Get_Package_AmdSec_ReaderWriter(mdtype, othermdtype); // Is this amdSec analyzable? (i.e., did we find an appropriate reader/writer?) if (rw == null) { Return_Package.Add_Unanalyzed_AMDSEC(metsSection); } else { rw.Read_amdSec(reader, Return_Package, options); } } } } } } #endregion #region Special code used for moving downloads into the structure map system, and out of the old SobekCM METS section // For backward compatability, move from the old download system to the // new structure. This has to happen here at the end so that we have access // Were there some downloads added here? if (deprecatedDownloads.Count > 0) { // Get the list of downloads from the download tree List<SobekCM_File_Info> newStructureDownloads = Return_Package.Divisions.Download_Tree.All_Files; // Step through each download in the old system foreach (Download_Info_DEPRECATED thisDownload in deprecatedDownloads) { // Get the label (if there is one) string label = thisDownload.Label; string filename = thisDownload.FileName; bool found = false; if ((filename.Length == 0) && (thisDownload.File_ID.Length > 0)) { if (files_by_fileid.ContainsKey(thisDownload.File_ID)) { SobekCM_File_Info thisDownloadFile = files_by_fileid[thisDownload.File_ID]; filename = thisDownloadFile.System_Name; // Ensure a file of this name doesn't already exist foreach (SobekCM_File_Info existingFile in newStructureDownloads) { if (existingFile.System_Name.ToUpper().Trim() == filename.ToUpper().Trim()) { found = true; break; } } // Not found, so add it if (!found) { // Determine the label if it was missing or identical to file name if ((label.Length == 0) || (label == filename)) { label = filename; int first_period_index = label.IndexOf('.'); if (first_period_index > 0) { label = label.Substring(0, first_period_index); } } // Add the root to the download tree, if not existing Division_TreeNode newRoot; if (Return_Package.Divisions.Download_Tree.Roots.Count == 0) { newRoot = new Division_TreeNode("Main", String.Empty); Return_Package.Divisions.Download_Tree.Roots.Add(newRoot); } else { newRoot = (Division_TreeNode) Return_Package.Divisions.Download_Tree.Roots[0]; } // Add a page for this, with the provided label if there was one Page_TreeNode newPage = new Page_TreeNode(label); newRoot.Nodes.Add(newPage); // Now, add this existing file newPage.Files.Add(thisDownloadFile); // Add to the list of files added (in case it appears twice) newStructureDownloads.Add(thisDownloadFile); } } } else { // Ensure a file of this name doesn't already exist foreach (SobekCM_File_Info existingFile in newStructureDownloads) { if (existingFile.System_Name.ToUpper().Trim() == filename.ToUpper().Trim()) { found = true; break; } } // Not found, so add it if (!found) { // Determine the label if it was missing or identical to file name if ((label.Length == 0) || (label == filename)) { label = filename; int first_period_index = label.IndexOf('.'); if (first_period_index > 0) { label = label.Substring(0, first_period_index); } } // Add the root to the download tree, if not existing Division_TreeNode newRoot; if (Return_Package.Divisions.Download_Tree.Roots.Count == 0) { newRoot = new Division_TreeNode("Main", String.Empty); Return_Package.Divisions.Download_Tree.Roots.Add(newRoot); } else { newRoot = (Division_TreeNode) Return_Package.Divisions.Download_Tree.Roots[0]; } // Add a page for this, with the provided label if there was one Page_TreeNode newPage = new Page_TreeNode(label); newRoot.Nodes.Add(newPage); // Now, add this existing file SobekCM_File_Info thisDownloadFile = new SobekCM_File_Info(filename); newPage.Files.Add(thisDownloadFile); // Add to the list of files added (in case it appears twice) newStructureDownloads.Add(thisDownloadFile); } } } } #endregion #region Special code for distributing any page-level coordinate information read from the old SobekCM coordinate metadata // Get the geospatial data GeoSpatial_Information geoSpatial = Return_Package.Get_Metadata_Module(GlobalVar.GEOSPATIAL_METADATA_MODULE_KEY) as GeoSpatial_Information; if ((geoSpatial != null) && ( geoSpatial.Polygon_Count > 0 )) { // See if any has the page sequence filled out, which means it came from the old metadata system bool redistribute = false; foreach (Coordinate_Polygon thisPolygon in geoSpatial.Polygons) { if (thisPolygon.Page_Sequence > 0) { redistribute = true; break; } } // If we need to redistribute, get started! if (redistribute) { // Get the pages, by sequence List<abstract_TreeNode> pagesBySequence = Return_Package.Divisions.Physical_Tree.Pages_PreOrder; List<Coordinate_Polygon> polygonsToRemove = new List<Coordinate_Polygon>(); // Step through each polygon foreach (Coordinate_Polygon thisPolygon in geoSpatial.Polygons) { if ((thisPolygon.Page_Sequence > 0) && ( thisPolygon.Page_Sequence <= pagesBySequence.Count )) { // Get the page abstract_TreeNode thisPageFromSequence = pagesBySequence[thisPolygon.Page_Sequence - 1]; // We can assume this page does not already have the coordiantes GeoSpatial_Information thisPageCoord = new GeoSpatial_Information(); thisPageFromSequence.Add_Metadata_Module( GlobalVar.GEOSPATIAL_METADATA_MODULE_KEY, thisPageCoord ); thisPageCoord.Add_Polygon( thisPolygon); // Remove this from the package-level coordinates polygonsToRemove.Add(thisPolygon); } } // Now, remove all polygons flagged to be removed foreach (Coordinate_Polygon thisPolygon in polygonsToRemove) { geoSpatial.Remove_Polygon(thisPolygon); } } } #endregion #region Copy any serial hierarchy in the Behaviors.Serial_Info part into the bib portion, if not there // Do some final cleanup on the SERIAL HIERARCHY if ((Return_Package.Behaviors.hasSerialInformation) && (Return_Package.Behaviors.Serial_Info.Count > 0)) { if ((Return_Package.Bib_Info.Series_Part_Info.Enum1.Length == 0) && (Return_Package.Bib_Info.Series_Part_Info.Year.Length == 0)) { if (Return_Package.Bib_Info.SobekCM_Type == TypeOfResource_SobekCM_Enum.Newspaper) { Return_Package.Bib_Info.Series_Part_Info.Year = Return_Package.Behaviors.Serial_Info[0].Display; Return_Package.Bib_Info.Series_Part_Info.Year_Index = Return_Package.Behaviors.Serial_Info[0].Order; if (Return_Package.Behaviors.Serial_Info.Count > 1) { Return_Package.Bib_Info.Series_Part_Info.Month = Return_Package.Behaviors.Serial_Info[1].Display; Return_Package.Bib_Info.Series_Part_Info.Month_Index = Return_Package.Behaviors.Serial_Info[1].Order; } } if (Return_Package.Behaviors.Serial_Info.Count > 2) { Return_Package.Bib_Info.Series_Part_Info.Day = Return_Package.Behaviors.Serial_Info[2].Display; Return_Package.Bib_Info.Series_Part_Info.Day_Index = Return_Package.Behaviors.Serial_Info[2].Order; } } else { Return_Package.Bib_Info.Series_Part_Info.Enum1 = Return_Package.Behaviors.Serial_Info[0].Display; Return_Package.Bib_Info.Series_Part_Info.Enum1_Index = Return_Package.Behaviors.Serial_Info[0].Order; if (Return_Package.Behaviors.Serial_Info.Count > 1) { Return_Package.Bib_Info.Series_Part_Info.Enum2 = Return_Package.Behaviors.Serial_Info[1].Display; Return_Package.Bib_Info.Series_Part_Info.Enum2_Index = Return_Package.Behaviors.Serial_Info[1].Order; } if (Return_Package.Behaviors.Serial_Info.Count > 2) { Return_Package.Bib_Info.Series_Part_Info.Enum3 = Return_Package.Behaviors.Serial_Info[2].Display; Return_Package.Bib_Info.Series_Part_Info.Enum3_Index = Return_Package.Behaviors.Serial_Info[2].Order; } } } #endregion return true; }
private void read_struct_map(XmlReader r, SobekCM_Item package, Dictionary<string, SobekCM_File_Info> files_by_fileid, Dictionary<string, abstract_TreeNode> division_dmdids, Dictionary<string, abstract_TreeNode> division_amdids ) { Stack<abstract_TreeNode> parentNodes = new Stack<abstract_TreeNode>(); Dictionary<string, abstract_TreeNode> divisions_by_id = new Dictionary<string, abstract_TreeNode>(); string divID; string divType = String.Empty; string divLabel = String.Empty; string fileID = String.Empty; string dmdid = String.Empty; string amdid = String.Empty; ushort divOrder = 0; bool mainDivisionFound = false; abstract_TreeNode parentNode; Division_Tree thisDivTree = null; // Loop through reading each XML node do { // get the right division information based on node type switch (r.NodeType) { // if EndElement, move up tree case XmlNodeType.EndElement: if (r.Name == "METS:structMap") { return; } if (r.Name == "METS:div") { // If there are more than one parent on the "parent stack" pop one off if (parentNodes.Count > 0) parentNodes.Pop(); } break; // if new element, add name and traverse tree case XmlNodeType.Element: // Is this the beginning of a structure map if (r.Name == "METS:structMap") { thisDivTree = package.Divisions.Physical_Tree; if (r.MoveToAttribute("TYPE")) { if (r.Value.ToUpper() == "OTHER") thisDivTree = package.Divisions.Download_Tree; } } // Is this a new division? if ((r.Name == "METS:div") && (r.HasAttributes)) { // Since this is a new division, get all the possible attribute values or set to empty string dmdid = (r.MoveToAttribute("DMDID") ? r.Value : String.Empty); amdid = (r.MoveToAttribute("AMDID") ? r.Value : String.Empty); divID = (r.MoveToAttribute("DMDID") ? r.Value : String.Empty); divType = (r.MoveToAttribute("TYPE") ? r.Value : String.Empty); divLabel = (r.MoveToAttribute("LABEL") ? r.Value : String.Empty); // Get the order if (r.MoveToAttribute("ORDER")) { if (!UInt16.TryParse(r.Value, out divOrder)) divOrder = 0; } else if (r.MoveToAttribute("ORDERLABEL")) { if (!UInt16.TryParse(r.Value, out divOrder)) divOrder = 0; } else { divOrder = 0; } // Was this an outer division, or the main division? if (!mainDivisionFound) { // This is an outer wrapper and NOT the MAIN division, so save this as an // outer division (division greater than current digital resources), such as // used sometimes for serials or journals. if (divType.ToUpper() != "MAIN") { if (!package.Divisions.Contains_Outer_Division(divLabel, divType)) { package.Divisions.Add_Outer_Division(divLabel, divOrder, divType); } } else { mainDivisionFound = true; } } else { // Get the parent node, if there is one parentNode = parentNodes.Count > 0 ? parentNodes.Peek() : null; // Create this division abstract_TreeNode bibNode; if (divType.ToUpper() == "PAGE") bibNode = new Page_TreeNode(divLabel); else bibNode = new Division_TreeNode(divType, divLabel); // Check to make sure no repeat here if (divID.IndexOf("_repeat") > 0) { divID = divID.Substring(0, divID.IndexOf("_repeat")); if (divisions_by_id.ContainsKey(divID)) { bibNode = divisions_by_id[divID]; } } // Get the DMD sec or AMD sec's if (dmdid.Length > 0) { string[] divDmdSecIds = dmdid.Split(" ".ToCharArray()); foreach( string thisId in divDmdSecIds ) { division_dmdids[thisId] = bibNode; } } if (amdid.Length > 0) { string[] divAmdSecIds = amdid.Split(" ".ToCharArray()); foreach (string thisId in divAmdSecIds) { division_amdids[thisId] = bibNode; } } // If there is a parent, add to it if (parentNode != null) { ((Division_TreeNode) parentNode).Nodes.Add(bibNode); } else { // No parent, so add this to the root thisDivTree.Roots.Add(bibNode); } // Now, add this to the end of the parent list, in case it has children if (!r.IsEmptyElement) { parentNodes.Push(bibNode); } } r.MoveToElement(); } // Is this a new file pointer applying to the last division? if ((r.Name == "METS:fptr") && (r.MoveToAttribute("FILEID"))) { // Get this file id fileID = r.Value; // Get the file from the files by id dictionary if (files_by_fileid.ContainsKey(fileID)) { SobekCM_File_Info thisFile = files_by_fileid[fileID]; abstract_TreeNode pageParentNode = null; if (parentNodes.Count > 0) pageParentNode = parentNodes.Peek(); if ((pageParentNode != null) && (pageParentNode.Page)) { Page_TreeNode asPageNode = (Page_TreeNode) pageParentNode; if (!asPageNode.Files.Contains(thisFile)) asPageNode.Files.Add(thisFile); } else { if (pageParentNode == null) { thisDivTree.Add_File(thisFile); } else { Division_TreeNode asDivNode = (Division_TreeNode) pageParentNode; Page_TreeNode newPage = new Page_TreeNode(); asDivNode.Add_Child(newPage); //parentNodes.Push(newPage); newPage.Files.Add(thisFile); } } } } break; } // end switch } while (r.Read()); }
/// <summary> Adds a file object (with the appropriate divisions and pages) to this tree </summary> /// <param name="New_File"> New file object to add </param> /// <param name="Label"> Label for the page containing this file, if it is a new page </param> /// <remarks> This is generally used to add just a single file. To add many files, better logic should be implemented </remarks> public void Add_File(SobekCM_File_Info New_File, string Label) { // Determine the upper case name string systemname_upper = New_File.File_Name_Sans_Extension; // Look for a page/entity which has the same file name, else it will be added to the last division foreach (abstract_TreeNode rootNode in Roots) { if (recursively_add_file(rootNode, New_File, systemname_upper)) { return; } } // If not found, find the last division if (Roots.Count > 0) { if (!Roots[Roots.Count - 1].Page) { // Get his last division Division_TreeNode lastDivision = (Division_TreeNode) Roots[Roots.Count - 1]; // Find the last division then while ((lastDivision.Nodes.Count > 0) && (!lastDivision.Nodes[lastDivision.Nodes.Count - 1].Page)) { lastDivision = (Division_TreeNode) lastDivision.Nodes[lastDivision.Nodes.Count - 1]; } // Add this as a new page on the last division Page_TreeNode newPage = new Page_TreeNode(Label); lastDivision.Add_Child(newPage); // Now, add this file to the page newPage.Files.Add(New_File); } else { // No divisions at all, but pages exist at the top level, which is okay Page_TreeNode pageNode = (Page_TreeNode) Roots[Roots.Count - 1]; // Now, add this file to the page pageNode.Files.Add(New_File); } } else { // No nodes exist, so add a MAIN division node Division_TreeNode newDivNode = new Division_TreeNode("Main", String.Empty); Roots.Add(newDivNode); // Add this as a new page on the new division Page_TreeNode newPage = new Page_TreeNode(Label); newDivNode.Add_Child(newPage); // Now, add this file to the page newPage.Files.Add(New_File); } }
/// <summary> Adds all of the file information to a digital resource package by analyzing the directory </summary> /// <param name="BIBPackage">Digital resource package to enrich</param> /// <param name="FilesFilter"> Files to be added as page image files ( such as "*.tif|*.jpg|*.jp2" )</param> /// <param name="RecursivelyIncludeSubfolders"> Flag indicates if all files in subfolders should also be added </param> /// <param name="PageImagesInSeperateFoldersCanBeSamePage"> If two images with the same root are found in subfolders, should </param> public static void Add_All_Files(SobekCM_Item BIBPackage, string FilesFilter, bool RecursivelyIncludeSubfolders, bool PageImagesInSeperateFoldersCanBeSamePage) { // Get the set of file filters within a list List<string> file_filters = new List<string>(); if (FilesFilter.IndexOf("|") < 0) { file_filters.Add(FilesFilter.ToUpper()); } else { string[] splitter = FilesFilter.Split("|".ToCharArray()); foreach (string thisFilter in splitter) { file_filters.Add(thisFilter.ToUpper()); } } // Get the files from the current directory (or recursive directories) Builder_Page_File_Collection fileCollection = new Builder_Page_File_Collection(); get_files_from_current_directory(fileCollection, file_filters, BIBPackage.Source_Directory, String.Empty, RecursivelyIncludeSubfolders); // Now, determine which files are already in the METS file. // Build a collection of file objects from the METS List<SobekCM_File_Info> metsFiles = new List<SobekCM_File_Info>(); Builder_Page_File_Collection metsFileCollection = new Builder_Page_File_Collection(); Dictionary<SobekCM_File_Info, Page_TreeNode> fileToPage = new Dictionary<SobekCM_File_Info, Page_TreeNode>(); Dictionary<Page_TreeNode, Division_TreeNode> pageToDiv = new Dictionary<Page_TreeNode, Division_TreeNode>(); foreach (abstract_TreeNode rootNode in BIBPackage.Divisions.Physical_Tree.Roots) { recursively_add_all_METS_files(rootNode, metsFiles, metsFileCollection, fileToPage, pageToDiv, file_filters); } // Determine which files to delete from the METS package List<SobekCM_File_Info> deletes = new List<SobekCM_File_Info>(); foreach (SobekCM_File_Info thisFile in metsFiles) { if ((thisFile.METS_LocType == SobekCM_File_Info_Type_Enum.SYSTEM) && (!File.Exists(BIBPackage.Source_Directory + "//" + thisFile.System_Name))) { deletes.Add(thisFile); } } // Delete the files, and related pages foreach (SobekCM_File_Info thisFile in deletes) { metsFiles.Remove(thisFile); Page_TreeNode thisPage = fileToPage[thisFile]; if (thisPage != null) { thisPage.Files.Remove(thisFile); Division_TreeNode thisDiv = pageToDiv[thisPage]; if (thisDiv != null) { thisDiv.Nodes.Remove(thisPage); } } // Remove this from the other mets list int index = 0; int deleteIndex = -1; foreach (Builder_Page_File thisPageFile in metsFileCollection) { if (thisPageFile.FullName.ToUpper() == thisFile.System_Name.ToUpper()) { deleteIndex = index; break; } index++; } if (deleteIndex >= 0) { metsFileCollection.RemoveAt(deleteIndex); } } // Now, recursively check each division and remove empty divisions int rootNodeCounter = 0; while (rootNodeCounter < BIBPackage.Divisions.Physical_Tree.Roots.Count) { abstract_TreeNode rootNode = BIBPackage.Divisions.Physical_Tree.Roots[rootNodeCounter]; if (recursively_remove_empty_divisions(rootNode)) BIBPackage.Divisions.Physical_Tree.Roots.Remove(rootNode); else rootNodeCounter++; } // Build the list of all the remaining files Hashtable filesPresent = new Hashtable(); foreach (SobekCM_File_Info thisFile in metsFiles) { filesPresent[thisFile.System_Name] = thisFile; } // Determine which files need to be added Builder_Page_File_Collection addFiles = new Builder_Page_File_Collection(); foreach (Builder_Page_File thisFile in fileCollection) { if (!filesPresent.Contains(thisFile.FullName_With_Relative_Directory)) { addFiles.Add(thisFile); } } // Add files that need to be added if (addFiles.Count > 0) { // Make sure there is at least one division if (BIBPackage.Divisions.Physical_Tree.Roots.Count == 0) { Division_TreeNode newRootNode = new Division_TreeNode("Main", String.Empty); BIBPackage.Divisions.Physical_Tree.Roots.Add(newRootNode); } // Create the map of file names to pages Dictionary<string, Page_TreeNode> file_to_page_hash = new Dictionary<string, Page_TreeNode>(); List<abstract_TreeNode> pageNodes = BIBPackage.Divisions.Physical_Tree.Pages_PreOrder; foreach (Page_TreeNode pageNode in pageNodes) { if (pageNode.Files.Count > 0) { string first_page_name = pageNode.Files[0].File_Name_Sans_Extension; if (first_page_name.IndexOf(".") > 0) first_page_name = first_page_name.Substring(0, first_page_name.IndexOf(".")); if ((PageImagesInSeperateFoldersCanBeSamePage) || (pageNode.Files[0].METS_LocType == SobekCM_File_Info_Type_Enum.URL)) { if (first_page_name.IndexOf("\\") > 0) { string[] slash_splitter = first_page_name.Split("\\".ToCharArray()); first_page_name = slash_splitter[slash_splitter.Length - 1]; } } if (!file_to_page_hash.ContainsKey(first_page_name.ToUpper())) { file_to_page_hash[first_page_name.ToUpper()] = pageNode; } } } // If there are no existing pages, this can be easily assembled if (metsFiles.Count == 0) { try { // Get the first division Division_TreeNode firstDiv = (Division_TreeNode) BIBPackage.Divisions.Physical_Tree.Roots[0]; // Add each file foreach (Builder_Page_File thisFile in addFiles) { // Create the new METS file object SobekCM_File_Info newFileForMETS = new SobekCM_File_Info(thisFile.FullName_With_Relative_Directory); // Get the root of this file, to put all files of the same root on the same page string thisFileShort = newFileForMETS.File_Name_Sans_Extension; if (PageImagesInSeperateFoldersCanBeSamePage) { if (thisFileShort.IndexOf("\\") > 0) { string[] slash_splitter = thisFileShort.Split("\\".ToCharArray()); thisFileShort = slash_splitter[slash_splitter.Length - 1]; } } // Is this a pre-existing root ( therefore pre-existing page )? if (file_to_page_hash.ContainsKey(thisFileShort)) { // Just add this file to the pre-existing page file_to_page_hash[thisFileShort].Files.Add(newFileForMETS); } else { // This needs a new page then Page_TreeNode newPage = new Page_TreeNode(); newPage.Files.Add(newFileForMETS); firstDiv.Nodes.Add(newPage); // Add this page to the hash, so it is not added again later file_to_page_hash[thisFileShort] = newPage; } } } catch { } } else { // Configure the initial pointers Builder_Page_File previous_file = null; Builder_Page_File next_file = metsFileCollection[0]; Builder_Page_File new_file = addFiles[0]; int new_file_counter = 1; int next_file_counter = 1; // Loop through each file to be added while (new_file != null) { // Create the new METS file object SobekCM_File_Info newFileForMETS = new SobekCM_File_Info(new_file.FullName_With_Relative_Directory); // Get the root of this file, to put all files of the same root on the same page string thisFileShort = newFileForMETS.File_Name_Sans_Extension; if (PageImagesInSeperateFoldersCanBeSamePage) { if (thisFileShort.IndexOf("\\") > 0) { string[] slash_splitter = thisFileShort.Split("\\".ToCharArray()); thisFileShort = slash_splitter[slash_splitter.Length - 1]; } } // First, ensure that we have not already added a page for this if (file_to_page_hash.ContainsKey(thisFileShort)) { // Just add this file to the pre-existing page file_to_page_hash[thisFileShort].Files.Add(newFileForMETS); } else { // Move to the right part of the existing files list while ((new_file.CompareTo(next_file) > 0) && (next_file != null)) { previous_file = next_file; if (next_file_counter < metsFileCollection.Count) { next_file = metsFileCollection[next_file_counter++]; } else { next_file = null; } } // Add the page for this and link the new file Page_TreeNode newPage = new Page_TreeNode(); newPage.Files.Add(newFileForMETS); file_to_page_hash[thisFileShort] = newPage; // Get the parent division and add this page in the right place // Check there was a previous page, otherwise this inserts at the very beginning if (previous_file == null) { abstract_TreeNode abstractNode = BIBPackage.Divisions.Physical_Tree.Roots[0]; Division_TreeNode lastDivNode = (Division_TreeNode) abstractNode; while (!abstractNode.Page) { lastDivNode = (Division_TreeNode) abstractNode; if (lastDivNode.Nodes.Count > 0) { abstractNode = lastDivNode.Nodes[0]; } else { break; } } lastDivNode.Nodes.Insert(0, newPage); metsFileCollection.Insert(new_file); new_file.METS_Division = lastDivNode; new_file.METS_Page = newPage; next_file = metsFileCollection[0]; } else { Division_TreeNode parentDivNode = previous_file.METS_Division; Page_TreeNode previousPageNode = previous_file.METS_Page; int previousFileIndex = parentDivNode.Nodes.IndexOf(previousPageNode); if (previousFileIndex + 1 >= parentDivNode.Nodes.Count) parentDivNode.Nodes.Add(newPage); else parentDivNode.Nodes.Insert(previousFileIndex + 1, newPage); next_file = previous_file; next_file_counter--; new_file.METS_Division = parentDivNode; new_file.METS_Page = newPage; metsFileCollection.Insert(new_file); } } // Move to the next new file if (new_file_counter < addFiles.Count) { new_file = addFiles[new_file_counter++]; } else { new_file = null; } } } } }
private void recurse_through_and_find_child_parent_relationship( Division_TreeNode parentNode ) { foreach (abstract_TreeNode childNode in parentNode.Nodes) { if (childNode.Page) { childToParent[(Page_TreeNode) childNode] = parentNode; } else { recurse_through_and_find_child_parent_relationship((Division_TreeNode) childNode); } } }
private void recurse_through_tree( Division_TreeNode parentNode, TreeNode parentViewNode, List<TreeNode> nodes, List<TreeNode> selectedNodes, List<TreeNode> pathNodes, ref int sequence ) { foreach (abstract_TreeNode absNode in parentNode.Nodes ) { if ( absNode.Page ) { sequence++; foreach( TreeNode thisNode in nodes ) { thisNode.Value = sequence.ToString(); } if (sequence >= currentMode.Page) { if (!tocSelectedComplete) { selectedNodes.AddRange(pathNodes); tocSelectedComplete = true; } else { if (sequence == currentMode.Page) { selectedNodes.AddRange(pathNodes); } } } nodes.Clear(); } else { Division_TreeNode divNode = (Division_TreeNode) absNode; TreeNode treeViewNode = new TreeNode { Text = string.Format("<span class=\"SobekTocTreeViewItem\" Title='{0}'>{1}</span>", divNode.Display_Label, divNode.Display_Short_Label) }; parentViewNode.ChildNodes.Add( treeViewNode ); nodes.Add(treeViewNode); List<TreeNode> pathNodes2 = new List<TreeNode> {treeViewNode}; recurse_through_tree(divNode, treeViewNode, nodes, selectedNodes, pathNodes2, ref sequence ); } } }
/// <summary> Saves the data rendered by this element to the provided bibliographic object during postback </summary> /// <param name="Bib"> Object into which to save the user's data, entered into the html rendered by this element </param> /// <remarks> This currently does not to anything, as this element is not fully implemented </remarks> public override void Save_To_Bib(SobekCM_Item Bib) { // Collect the list of download_files and download_labels from the form string[] getKeys = HttpContext.Current.Request.Form.AllKeys; string filename = String.Empty; List<string> download_files = new List<string>(); List<string> download_labels = new List<string>(); foreach (string thisKey in getKeys) { if (thisKey.IndexOf(html_element_name.Replace("_", "") + "_select") == 0) { filename = HttpContext.Current.Request.Form[thisKey]; } if (thisKey.IndexOf(html_element_name.Replace("_", "") + "_text") == 0) { if (filename.Length > 0) { string label = HttpContext.Current.Request.Form[thisKey]; download_files.Add(filename.Replace(".*","")); download_labels.Add(label); } filename = String.Empty; } } // Collect the list of download files and download labels from the package List<string> existing_files = new List<string>(); List<string> existing_labels = new List<string>(); List<abstract_TreeNode> downloadGroups = Bib.Divisions.Download_Tree.Pages_PreOrder; foreach (Page_TreeNode thisDownload in downloadGroups) { if (thisDownload.Files.Count > 0) { string base_file = thisDownload.Files[0].File_Name_Sans_Extension; if (!existing_files.Contains(base_file)) { existing_files.Add(base_file ); existing_labels.Add(thisDownload.Label); } } } // Now, compare the current list of downloads to the new list bool different = false; if (download_files.Count != existing_files.Count) { different = true; } else { // Same number of downloads, so step through and compare the files and labels for (int i = 0; i < download_files.Count; i++) { // Get the index of this on the existing list int index = existing_files.IndexOf(download_files[i].ToUpper()); if (index < 0) { different = true; break; } if (existing_labels[index].Trim() != download_labels[i].Trim()) { different = true; break; } } } // If this was different clear the existing downloads and load the new ones if (different) { // Get the directory for this package string directory = SobekCM_Library_Settings.Image_Server_Network + Bib.Web.AssocFilePath; // Clear existing Bib.Divisions.Download_Tree.Clear(); // No nodes exist, so add a MAIN division node Division_TreeNode newDivNode = new Division_TreeNode("Main", String.Empty); Bib.Divisions.Download_Tree.Roots.Add(newDivNode); // Add a page for each for (int i = 0; i < download_files.Count; i++) { // Get the list of matching files string[] files = Directory.GetFiles(directory, download_files[i] + ".*"); if (files.Length > 0) { // Add this as a new page on the new division Page_TreeNode newPage = new Page_TreeNode(download_labels[i]); newDivNode.Add_Child(newPage); // Add all the files next foreach (SobekCM_File_Info newFile in files.Select(thisFile => (new FileInfo(thisFile)).Name).Select(add_filename => new SobekCM_File_Info(add_filename))) { newPage.Files.Add(newFile); } } } } }
/// <summary> /// Clears all the page labels, division types and names, and reorders the pages by filename /// </summary> private void Clear_Pagination_And_Reorder_Pages() { SortedDictionary<string, Page_TreeNode> nodeToFilename = new SortedDictionary<string, Page_TreeNode>(); int newPageCount = 0; // Add each page node to a sorted list/dictionary and clear the label foreach (Page_TreeNode thisNode in qc_item.Divisions.Physical_Tree.Pages_PreOrder) { thisNode.Label = String.Empty; string file_sans = "missing" + newPageCount; if (( thisNode.Files != null ) && ( thisNode.Files.Count > 0 )) file_sans = thisNode.Files[0].File_Name_Sans_Extension; if (!nodeToFilename.ContainsKey(file_sans)) { nodeToFilename[file_sans] = thisNode; newPageCount++; } } // Clear the physical (TOC) tree qc_item.Divisions.Physical_Tree.Clear(); // Add the main node to the physical (TOC) division tree Division_TreeNode mainNode = new Division_TreeNode("Main", String.Empty); qc_item.Divisions.Physical_Tree.Roots.Add(mainNode); //Update the web Page count for this item qc_item.Web.Clear_Pages_By_Sequence(); // Add back each page, in order by filename (sans extension) for (int i = 0; i < nodeToFilename.Count; i++) { mainNode.Add_Child(nodeToFilename.ElementAt(i).Value); qc_item.Web.Add_Pages_By_Sequence(nodeToFilename.ElementAt(i).Value); } //Update the QC web page count as well qc_item.Web.Static_PageCount = newPageCount; // Save the updated item to the session HttpContext.Current.Session[qc_item.BibID + "_" + qc_item.VID + " QC Work"] = qc_item; // Save to the temporary QC work section try { // Ensure the directory exists under the user's temporary mySobek InProcess folder if (!Directory.Exists(userInProcessDirectory)) Directory.CreateDirectory(userInProcessDirectory); // Save the METS qc_item.Save_METS(metsInProcessFile); } catch (Exception) { throw; } }
private static void read_struct_map(XmlReader R, SobekCM_Item Package, Dictionary<string, SobekCM_File_Info> FilesByFileid, Dictionary<string, abstract_TreeNode> DivisionDmdids, Dictionary<string, abstract_TreeNode> DivisionAmdids ) { Stack<abstract_TreeNode> parentNodes = new Stack<abstract_TreeNode>(); Dictionary<string, abstract_TreeNode> divisions_by_id = new Dictionary<string, abstract_TreeNode>(); bool mainDivisionFound = false; Division_Tree thisDivTree = null; // Loop through reading each XML node do { // get the right division information based on node type switch (R.NodeType) { // if EndElement, move up tree case XmlNodeType.EndElement: if ((R.Name == "METS:structMap") || ( R.Name == "structMap" )) { return; } if ((R.Name == "METS:div") || (R.Name == "div")) { // If there are more than one parent on the "parent stack" pop one off if (parentNodes.Count > 0) parentNodes.Pop(); } break; // if new element, add name and traverse tree case XmlNodeType.Element: // Is this the beginning of a structure map if ((R.Name == "METS:structMap") || (R.Name == "structMap")) { thisDivTree = Package.Divisions.Physical_Tree; if (R.MoveToAttribute("TYPE")) { if (R.Value.ToUpper() == "OTHER") thisDivTree = Package.Divisions.Download_Tree; } } // Is this a new division? if (((R.Name == "METS:div") || ( R.Name == "div" )) && (R.HasAttributes)) { // Since this is a new division, get all the possible attribute values or set to empty string string dmdid = (R.MoveToAttribute("DMDID") ? R.Value : String.Empty); string amdid = (R.MoveToAttribute("AMDID") ? R.Value : String.Empty); string divID = (R.MoveToAttribute("DMDID") ? R.Value : String.Empty); string divType = (R.MoveToAttribute("TYPE") ? R.Value : String.Empty); string divLabel = (R.MoveToAttribute("LABEL") ? R.Value : String.Empty); // Get the order ushort divOrder; if (R.MoveToAttribute("ORDER")) { if (!UInt16.TryParse(R.Value, out divOrder)) divOrder = 0; } else if (R.MoveToAttribute("ORDERLABEL")) { if (!UInt16.TryParse(R.Value, out divOrder)) divOrder = 0; } else { divOrder = 0; } // Was this an outer division, or the main division? if (!mainDivisionFound) { // This is an outer wrapper and NOT the MAIN division, so save this as an // outer division (division greater than current digital resources), such as // used sometimes for serials or journals. if (divType.ToUpper() != "MAIN") { if (!Package.Divisions.Contains_Outer_Division(divLabel, divType)) { Package.Divisions.Add_Outer_Division(divLabel, divOrder, divType); } } else { mainDivisionFound = true; } } else { // Get the parent node, if there is one abstract_TreeNode parentNode = parentNodes.Count > 0 ? parentNodes.Peek() : null; // Create this division abstract_TreeNode bibNode; if (divType.ToUpper() == "PAGE") bibNode = new Page_TreeNode(divLabel); else bibNode = new Division_TreeNode(divType, divLabel); // Check to make sure no repeat here if (divID.IndexOf("_repeat") > 0) { divID = divID.Substring(0, divID.IndexOf("_repeat")); if (divisions_by_id.ContainsKey(divID)) { bibNode = divisions_by_id[divID]; } } // Get the DMD sec or AMD sec's if (dmdid.Length > 0) { string[] divDmdSecIds = dmdid.Split(" ".ToCharArray()); foreach( string thisId in divDmdSecIds ) { DivisionDmdids[thisId] = bibNode; } } if (amdid.Length > 0) { string[] divAmdSecIds = amdid.Split(" ".ToCharArray()); foreach (string thisId in divAmdSecIds) { DivisionAmdids[thisId] = bibNode; } } // If there is a parent, add to it if (parentNode != null) { ((Division_TreeNode) parentNode).Nodes.Add(bibNode); } else { // No parent, so add this to the root thisDivTree.Roots.Add(bibNode); } // Now, add this to the end of the parent list, in case it has children if (!R.IsEmptyElement) { parentNodes.Push(bibNode); } } R.MoveToElement(); } // Is this a new file pointer applying to the last division? if (((R.Name == "METS:fptr") || (R.Name == "fptr")) && (R.MoveToAttribute("FILEID"))) { // Get this file id string fileID = R.Value; // Get the file from the files by id dictionary if (FilesByFileid.ContainsKey(fileID)) { SobekCM_File_Info thisFile = FilesByFileid[fileID]; abstract_TreeNode pageParentNode = null; if (parentNodes.Count > 0) pageParentNode = parentNodes.Peek(); if ((pageParentNode != null) && (pageParentNode.Page)) { Page_TreeNode asPageNode = (Page_TreeNode) pageParentNode; if (!asPageNode.Files.Contains(thisFile)) asPageNode.Files.Add(thisFile); } else { if (pageParentNode == null) { thisDivTree.Add_File(thisFile); } else { Division_TreeNode asDivNode = (Division_TreeNode) pageParentNode; Page_TreeNode newPage = new Page_TreeNode(); asDivNode.Add_Child(newPage); //parentNodes.Push(newPage); newPage.Files.Add(thisFile); } } } } // Is this a new METS pointer, often seen when importing from DSpace if ((R.Name == "METS:mptr") || (R.Name == "mptr")) { // Get the parent label string parentLabel = String.Empty; // Look for a parent node (should be one) if (parentNodes.Count > 0) { abstract_TreeNode pageParentNode = parentNodes.Peek(); parentLabel = pageParentNode.Label; } else if (Package.Divisions.Outer_Division_Count > 0) { parentLabel = Package.Divisions.Outer_Divisions[Package.Divisions.Outer_Division_Count - 1].Label; } if ((!String.IsNullOrEmpty(parentLabel)) && (String.Compare(parentLabel, "Parent of this DSpace Object", StringComparison.OrdinalIgnoreCase) == 0)) { // Is this a HANDLE reference? string locType = (R.MoveToAttribute("LOCTYPE") ? R.Value : String.Empty).ToUpper(); string href = (R.MoveToAttribute("xlink:href") ? R.Value : String.Empty); // If this has a handle href, make that the aggregation if ((locType == "HANDLE") && (href.Length > 0)) { Package.Behaviors.Add_Aggregation(href); } } } break; } // end switch } while (R.Read()); }
/// <summary> Create a test digital resource item </summary> /// <param name="directory">Directory for the package source directory</param> /// <returns>Fully built test bib package</returns> public static SobekCM_Item Create(string directory) { SobekCM_Item testPackage = new SobekCM_Item(); // Add all the METS header information testPackage.METS_Header.Create_Date = new DateTime(2007, 1, 1); testPackage.METS_Header.Modify_Date = DateTime.Now; testPackage.METS_Header.Creator_Individual = "Mark Sullivan"; testPackage.METS_Header.Add_Creator_Individual_Notes("Programmer of new SobekCM.Resource_Object"); testPackage.METS_Header.Add_Creator_Individual_Notes("Adding coordinates"); testPackage.METS_Header.Creator_Organization = "University of Florida"; testPackage.METS_Header.Creator_Software = "SobekCM Bib Package Test"; testPackage.METS_Header.RecordStatus_Enum = METS_Record_Status.COMPLETE; testPackage.METS_Header.Add_Creator_Org_Notes("This test package was done to test DLCs new METS package"); // Add all the MODS elements Abstract_Info testAbstract = testPackage.Bib_Info.Add_Abstract("This is a sample abstract", "en"); testPackage.Bib_Info.Add_Abstract("Tämä on esimerkki abstrakteja", "fin"); testAbstract.Display_Label = "Summary Abstract"; testAbstract.Type = "summary"; testPackage.Bib_Info.Access_Condition.Text = "All rights are reserved by source institution."; testPackage.Bib_Info.Access_Condition.Language = "en"; testPackage.Bib_Info.Access_Condition.Type = "restrictions on use"; testPackage.Bib_Info.Access_Condition.Display_Label = "Rights"; testPackage.Bib_Info.Add_Identifier("000123234", "OCLC", "Electronic OCLC"); testPackage.Bib_Info.Add_Identifier("182-asdsd-28k", "DOI"); testPackage.Bib_Info.Add_Language("English", String.Empty, "en"); testPackage.Bib_Info.Add_Language("Finnish"); testPackage.Bib_Info.Add_Language(String.Empty, "ita", String.Empty); testPackage.Bib_Info.Location.Holding_Code = "MVS"; testPackage.Bib_Info.Location.Holding_Name = "From the Private Library of Mark Sullivan"; testPackage.Bib_Info.Location.PURL = "http://www.uflib.ufl.edu/ufdc/?b=CA00000000"; testPackage.Bib_Info.Location.Other_URL = "http://www.fnhm.edu"; testPackage.Bib_Info.Location.Other_URL_Display_Label = "Specimen Information"; testPackage.Bib_Info.Location.Other_URL_Note = "Specimen FLAS 125342 Database"; testPackage.Bib_Info.Location.EAD_URL = "http://digital.uflib.ufl.edu/"; testPackage.Bib_Info.Location.EAD_Name = "Digital Library Center Finding Guide"; testPackage.Bib_Info.Main_Entity_Name.Name_Type = Name_Info_Type_Enum.Personal; testPackage.Bib_Info.Main_Entity_Name.Full_Name = "Brown, B.F."; testPackage.Bib_Info.Main_Entity_Name.Terms_Of_Address = "Dr."; testPackage.Bib_Info.Main_Entity_Name.Display_Form = "B.F. Brown"; testPackage.Bib_Info.Main_Entity_Name.Affiliation = "Chemistry Dept., American University"; testPackage.Bib_Info.Main_Entity_Name.Description = "Chemistry Professor Emeritus"; testPackage.Bib_Info.Main_Entity_Name.Add_Role("Author"); Zoological_Taxonomy_Info taxonInfo = new Zoological_Taxonomy_Info(); testPackage.Add_Metadata_Module(GlobalVar.ZOOLOGICAL_TAXONOMY_METADATA_MODULE_KEY, taxonInfo); taxonInfo.Scientific_Name = "Ctenomys sociabilis"; taxonInfo.Higher_Classification = "Animalia; Chordata; Vertebrata; Mammalia; Theria; Eutheria; Rodentia; Hystricognatha; Hystricognathi; Ctenomyidae; Ctenomyini; Ctenomys"; taxonInfo.Kingdom = "Animalia"; taxonInfo.Phylum = "Chordata"; taxonInfo.Class = "Mammalia"; taxonInfo.Order = "Rodentia"; taxonInfo.Family = "Ctenomyidae"; taxonInfo.Genus = "Ctenomys"; taxonInfo.Specific_Epithet = "sociabilis"; taxonInfo.Taxonomic_Rank = "species"; taxonInfo.Common_Name = "Social Tuco-Tuco"; Name_Info name1 = new Name_Info(); name1.Name_Type = Name_Info_Type_Enum.Personal; name1.Given_Name = "John Paul"; name1.Terms_Of_Address = "Pope; II"; name1.Dates = "1920-2002"; name1.User_Submitted = true; testPackage.Bib_Info.Add_Named_Entity(name1); Name_Info name2 = new Name_Info(); name2.Name_Type = Name_Info_Type_Enum.Conference; name2.Full_Name = "Paris Peace Conference (1919-1920)"; name2.Dates = "1919-1920"; testPackage.Bib_Info.Add_Named_Entity(name2); Name_Info name3 = new Name_Info(); name3.Name_Type = Name_Info_Type_Enum.Corporate; name3.Full_Name = "United States -- Court of Appeals (2nd Court)"; testPackage.Bib_Info.Add_Named_Entity(name3); Name_Info name4 = new Name_Info(); name4.Name_Type = Name_Info_Type_Enum.Personal; name4.Full_Name = "Wilson, Mary"; name4.Display_Form = "Mary 'Weels' Wilson"; name4.Given_Name = "Mary"; name4.Family_Name = "Wilson"; name4.ID = "NAM4"; name4.Terms_Of_Address = "2nd"; name4.Add_Role("illustrator"); name4.Add_Role("cartographer"); testPackage.Bib_Info.Add_Named_Entity(name4); Name_Info donor = new Name_Info(); donor.Name_Type = Name_Info_Type_Enum.Personal; donor.Full_Name = "Livingston, Arthur"; donor.Description = "Gift in honor of Arthur Livingston"; donor.Terms_Of_Address = "3rd"; donor.Add_Role("honoree", String.Empty); testPackage.Bib_Info.Donor = donor; testPackage.Bib_Info.Main_Title.NonSort = "The "; testPackage.Bib_Info.Main_Title.Title = "Man Who Would Be King"; testPackage.Bib_Info.Main_Title.Subtitle = "The story of succession in England"; Title_Info title1 = new Title_Info("homme qui voulut être roi", Title_Type_Enum.Translated); title1.NonSort = "L'"; title1.Language = "fr"; testPackage.Bib_Info.Add_Other_Title(title1); Title_Info title2 = new Title_Info(); title2.Title = "Man Who Be King"; title2.Display_Label = "also known as"; title2.NonSort = "The"; title2.Title_Type = Title_Type_Enum.Alternative; testPackage.Bib_Info.Add_Other_Title(title2); Title_Info title3 = new Title_Info(); title3.Title = "Great works of England"; title3.Authority = "naf"; title3.Add_Part_Name("Second Portion"); title3.Add_Part_Number("2nd"); title3.Title_Type = Title_Type_Enum.Uniform; title3.User_Submitted = true; testPackage.Bib_Info.Add_Other_Title(title3); testPackage.Bib_Info.Add_Note("Funded by the NEH", Note_Type_Enum.Funding); testPackage.Bib_Info.Add_Note("Based on a play which originally appeared in France as \"Un peu plus tard, un peu plus tôt\"").User_Submitted = true; testPackage.Bib_Info.Add_Note("Anne Baxter (Louise), Maria Perschy (Angela), Gustavo Rojo (Bill), Reginald Gilliam (Mr. Johnson), [Catherine Elliot?] (Aunt Sallie), Ben Tatar (waiter)", Note_Type_Enum.Performers, "Performed By"); testPackage.Bib_Info.Origin_Info.Add_Place("New York", "nyu", "usa"); testPackage.Bib_Info.Origin_Info.Date_Issued = "1992"; testPackage.Bib_Info.Origin_Info.MARC_DateIssued_Start = "1992"; testPackage.Bib_Info.Origin_Info.MARC_DateIssued_End = "1993"; testPackage.Bib_Info.Origin_Info.Date_Copyrighted = "1999"; testPackage.Bib_Info.Origin_Info.Edition = "2nd"; Publisher_Info newPub = testPackage.Bib_Info.Add_Publisher("Published for the American Vacuum Society by the American Institute of Physics"); newPub.Add_Place("New York, New York"); newPub.User_Submitted = true; testPackage.Bib_Info.Add_Publisher("University of Florida Press House").Add_Place("Gainesville, FL"); testPackage.Bib_Info.Add_Manufacturer("Addison Randly Publishing House"); testPackage.Bib_Info.Original_Description.Extent = "1 sound disc (56 min.) : digital ; 3/4 in."; testPackage.Bib_Info.Original_Description.Add_Note("The sleeve of this sound disc was damaged in a fire"); testPackage.Bib_Info.Original_Description.Add_Note("The disc has a moderate amount of scratches, but still plays"); testPackage.Bib_Info.Series_Part_Info.Day = "18"; testPackage.Bib_Info.Series_Part_Info.Day_Index = 18; testPackage.Bib_Info.Series_Part_Info.Month = "Syyskuu"; testPackage.Bib_Info.Series_Part_Info.Month_Index = 9; testPackage.Bib_Info.Series_Part_Info.Year = "1992"; testPackage.Bib_Info.Series_Part_Info.Year_Index = 1992; testPackage.Bib_Info.Series_Part_Info.Enum1 = "Volume 12"; testPackage.Bib_Info.Series_Part_Info.Enum1_Index = 12; testPackage.Bib_Info.Series_Part_Info.Enum2 = "Issue 3"; testPackage.Bib_Info.Series_Part_Info.Enum2_Index = 3; testPackage.Bib_Info.Series_Part_Info.Enum3 = "Part 1"; testPackage.Bib_Info.Series_Part_Info.Enum3_Index = 1; testPackage.Behaviors.Serial_Info.Add_Hierarchy(1, 1992, "1992"); testPackage.Behaviors.Serial_Info.Add_Hierarchy(2, 9, "Syyskuu"); testPackage.Behaviors.Serial_Info.Add_Hierarchy(3, 18, "18"); testPackage.Bib_Info.SeriesTitle.Title = "Shakespeare's most famous musicals"; testPackage.Bib_Info.Add_Target_Audience("young adults"); testPackage.Bib_Info.Add_Target_Audience("adolescent", "marctarget"); testPackage.Bib_Info.SobekCM_Type = TypeOfResource_SobekCM_Enum.Newspaper; // Add cartographic subject Subject_Info_Cartographics newCartographics = testPackage.Bib_Info.Add_Cartographics_Subject(); newCartographics.Scale = "1:2000"; newCartographics.Projection = "Conical Projection"; newCartographics.Coordinates = "E 72°--E 148°/N 13°--N 18°"; // Add hierarchical geographic subject Subject_Info_HierarchicalGeographic hierarchical = testPackage.Bib_Info.Add_Hierarchical_Geographic_Subject(); hierarchical.Continent = "North America"; hierarchical.Country = "United States of America"; hierarchical.State = "Kansas"; hierarchical.County = "Butler"; hierarchical.City = "Augusta"; // Add hierarchical geographic subject Subject_Info_HierarchicalGeographic hierarchical2 = testPackage.Bib_Info.Add_Hierarchical_Geographic_Subject(); hierarchical2.Region = "Arctic Ocean"; // Add hierarchical geographic subject Subject_Info_HierarchicalGeographic hierarchical3 = testPackage.Bib_Info.Add_Hierarchical_Geographic_Subject(); hierarchical3.Island = "Puerto Rico"; hierarchical3.Language = "English"; hierarchical3.Province = "Provincial"; hierarchical3.Territory = "Puerto Rico"; hierarchical3.Area = "Intercontinental areas (Western Hemisphere)"; // Add a name subject Subject_Info_Name subjname1 = testPackage.Bib_Info.Add_Name_Subject(); subjname1.Authority = "lcsh"; subjname1.Full_Name = "Garcia Lorca, Federico"; subjname1.Dates = "1898-1936"; subjname1.Add_Geographic("Russia"); subjname1.Add_Geographic("Moscow"); subjname1.Add_Genre("maps"); subjname1.User_Submitted = true; // Add a title information subject Subject_Info_TitleInfo subjtitle1 = testPackage.Bib_Info.Add_Title_Subject(); subjtitle1.Title_Type = Title_Type_Enum.Uniform; subjtitle1.Authority = "naf"; subjtitle1.Title = "Missale Carnotense"; // Add a standard subject Subject_Info_Standard subject1 = testPackage.Bib_Info.Add_Subject(); subject1.Authority = "lcsh"; subject1.Add_Topic("Real property"); subject1.Add_Geographic("Mississippi"); subject1.Add_Geographic("Tippah County"); subject1.Add_Genre("Maps"); // Add a standard subject Subject_Info_Standard subject2 = testPackage.Bib_Info.Add_Subject(); subject2.Add_Occupation("Migrant laborers"); subject2.Add_Genre("School district case files"); // Add a standard subject Subject_Info_Standard subject3 = testPackage.Bib_Info.Add_Subject(); subject3.Authority = "lctgm"; subject3.Add_Topic("Educational buildings"); subject3.Add_Geographic("Washington (D.C.)"); subject3.Add_Temporal("1890-1910"); // Add a standard subject Subject_Info_Standard subject4 = testPackage.Bib_Info.Add_Subject(); subject4.Authority = "rvm"; subject4.Language = "french"; subject4.Add_Topic("Église catholique"); subject4.Add_Topic("Histoire"); subject4.Add_Temporal("20e siècle"); // Add record information testPackage.Bib_Info.Record.Add_Catalog_Language(new Language_Info("English", "eng", "en")); testPackage.Bib_Info.Record.Add_Catalog_Language(new Language_Info("French", "fre", "fr")); testPackage.Bib_Info.Record.MARC_Creation_Date = "080303"; testPackage.Bib_Info.Record.Add_MARC_Record_Content_Sources("FUG"); testPackage.Bib_Info.Record.Record_Origin = "Imported from (OCLC)001213124"; // Test the items which are in the non-MODS portion of the Bib_Info object testPackage.BibID = "MVS0000001"; testPackage.VID = "00001"; testPackage.Bib_Info.SortDate = 1234; testPackage.Bib_Info.SortTitle = "MAN WHO WOULD BE KING"; testPackage.Bib_Info.Add_Temporal_Subject(1990, 2002, "Recent history"); testPackage.Bib_Info.Add_Temporal_Subject(1990, 2002, "Lähihistoria"); testPackage.Bib_Info.Source.Code = "UF"; testPackage.Bib_Info.Source.Statement = "University of Florida"; // Add an affiliation Affiliation_Info affiliation1 = new Affiliation_Info(); affiliation1.University = "University of Florida"; affiliation1.Campus = "Gainesville Campus"; affiliation1.College = "College of Engineering"; affiliation1.Department = "Computer Engineering Department"; affiliation1.Unit = "Robotics"; affiliation1.Name_Reference = "NAM4"; testPackage.Bib_Info.Add_Affiliation(affiliation1); // Add a related item Related_Item_Info relatedItem1 = new Related_Item_Info(); relatedItem1.SobekCM_ID = "UF00001234"; relatedItem1.Relationship = Related_Item_Type_Enum.Preceding; relatedItem1.Publisher = "Gainesville Sun Publishing House"; relatedItem1.Add_Note(new Note_Info("Digitized with funding from NEH", Note_Type_Enum.Funding)); relatedItem1.Add_Note(new Note_Info("Gainesville Bee was the precursor to this item")); relatedItem1.Main_Title.NonSort = "The"; relatedItem1.Main_Title.Title = "Gainesville Bee"; relatedItem1.Add_Identifier("01234353", "oclc"); relatedItem1.Add_Identifier("002232311", "aleph"); Name_Info ri_name = new Name_Info(); ri_name.Full_Name = "Hills, Bryan"; ri_name.Terms_Of_Address = "Mr."; ri_name.Name_Type = Name_Info_Type_Enum.Personal; ri_name.Add_Role("author"); relatedItem1.Add_Name(ri_name); relatedItem1.URL = @"http://www.uflib.ufl.edu/ufdc/?b=UF00001234"; relatedItem1.URL_Display_Label = "Full Text"; testPackage.Bib_Info.Add_Related_Item(relatedItem1); // Add another related item Related_Item_Info relatedItem2 = new Related_Item_Info(); relatedItem2.Relationship = Related_Item_Type_Enum.Succeeding; relatedItem2.SobekCM_ID = "UF00009999"; relatedItem2.Main_Title.NonSort = "The"; relatedItem2.Main_Title.Title = "Daily Sun"; relatedItem2.Add_Identifier("0125437", "oclc"); relatedItem2.Add_Note("Name change occured in Fall 1933"); relatedItem2.Start_Date = "Fall 1933"; relatedItem2.End_Date = "December 31, 1945"; testPackage.Bib_Info.Add_Related_Item(relatedItem2); // Add some processing parameters testPackage.Behaviors.Add_Aggregation("JUV"); testPackage.Behaviors.Add_Aggregation("DLOC"); testPackage.Behaviors.Add_Aggregation("DLOSA1"); testPackage.Behaviors.Add_Aggregation("ALICE"); testPackage.Behaviors.Add_Aggregation("ARTE"); testPackage.Web.GUID = "GUID!"; testPackage.Behaviors.Add_Wordmark("DLOC"); testPackage.Behaviors.Add_Wordmark("UFSPEC"); testPackage.Behaviors.Main_Thumbnail = "00001thm.jpg"; // Add some downloads testPackage.Divisions.Download_Tree.Add_File("MVS_Complete.PDF"); testPackage.Divisions.Download_Tree.Add_File("MVS_Complete.MP2"); testPackage.Divisions.Download_Tree.Add_File("MVS_Part1.MP2"); testPackage.Divisions.Download_Tree.Add_File("MVS_Part1.PDF"); // Add some coordinate information GeoSpatial_Information geoSpatial = new GeoSpatial_Information(); testPackage.Add_Metadata_Module(GlobalVar.GEOSPATIAL_METADATA_MODULE_KEY, geoSpatial); geoSpatial.Add_Point(29.530151, -82.301459, "Lake Wauberg"); geoSpatial.Add_Point(29.634352, -82.350640, "Veterinary School"); Coordinate_Polygon polygon = new Coordinate_Polygon(); polygon.Label = "University of Florida Campus"; polygon.Add_Edge_Point(new Coordinate_Point(29.651435, -82.339869, String.Empty)); polygon.Add_Edge_Point(new Coordinate_Point(29.641216, -82.340298, String.Empty)); polygon.Add_Edge_Point(new Coordinate_Point(29.629503, -82.371969, String.Empty)); polygon.Add_Edge_Point(new Coordinate_Point(29.649645, -82.371712, String.Empty)); polygon.Add_Inner_Point(29.649794, -82.351971, "Stadium"); polygon.Add_Inner_Point(29.650988, -82.341156, "Library"); geoSpatial.Add_Polygon(polygon); Coordinate_Line line = new Coordinate_Line(); line.Label = "Waldo Road"; line.Add_Point(29.652852, -82.310944, "Gainesville"); line.Add_Point(29.716681, -82.268372, String.Empty); line.Add_Point(29.791494, -82.167778, "Waldo"); geoSpatial.Add_Line(line); // Add some performing arts information Performing_Arts_Info partInfo = new Performing_Arts_Info(); testPackage.Add_Metadata_Module("PerformingArts", partInfo); partInfo.Performance = "Hamlet"; partInfo.Performance_Date = "August 12, 1923"; Performer performer1 = partInfo.Add_Performer("Sullivan, Mark"); performer1.Sex = "M"; performer1.LifeSpan = "1873-"; performer1.Occupation = "actor"; performer1.Title = "Mr."; Performer performer2 = partInfo.Add_Performer("Waldbart, Julia"); performer2.Sex = "F"; performer2.LifeSpan = "1876-"; performer2.Occupation = "actress"; performer2.Title = "Mrs."; // Add some oral history information Oral_Interview_Info oralInfo = new Oral_Interview_Info(); testPackage.Add_Metadata_Module( "OralInterview", oralInfo); oralInfo.Interviewee = "Edwards, Herm"; oralInfo.Interviewer = "Proctor, Samual"; // Add some learning object resource information LearningObjectMetadata lomInfo = new LearningObjectMetadata(); testPackage.Add_Metadata_Module( GlobalVar.IEEE_LOM_METADATA_MODULE_KEY, lomInfo ); lomInfo.AggregationLevel = AggregationLevelEnum.level3; lomInfo.Status = StatusEnum.draft; LOM_System_Requirements lomReq1 = new LOM_System_Requirements(); lomReq1.RequirementType = RequirementTypeEnum.operating_system; lomReq1.Name.Value = "Windows"; lomReq1.MinimumVersion = "Windows XP"; lomReq1.MaximumVersion = "Windows 7"; lomInfo.Add_SystemRequirements(lomReq1); LOM_System_Requirements lomReq2 = new LOM_System_Requirements(); lomReq2.RequirementType = RequirementTypeEnum.software; lomReq2.Name.Value = "Java SDK"; lomReq2.MinimumVersion = "1.7.1"; lomReq2.MaximumVersion = "2.09"; lomInfo.Add_SystemRequirements(lomReq2); lomInfo.InteractivityType = InteractivityTypeEnum.mixed; lomInfo.Add_LearningResourceType("exercise"); lomInfo.Add_LearningResourceType("Tutorials", "encdlwebpedagogicaltype"); lomInfo.InteractivityLevel = InteractivityLevelEnum.high; lomInfo.Add_IntendedEndUserRole(IntendedEndUserRoleEnum.learner); lomInfo.Add_Context("Undergraduate lower division", "enclearningcontext"); lomInfo.Add_Context("15", "grade"); lomInfo.Add_Context("16", "grade"); lomInfo.Add_Context("5", "group"); lomInfo.Add_TypicalAgeRange("suitable for children over 7", "en"); lomInfo.Add_TypicalAgeRange("2-8"); lomInfo.DifficultyLevel = DifficultyLevelEnum.medium; lomInfo.TypicalLearningTime = "PT45M"; LOM_Classification lomClassification1 = new LOM_Classification(); lomInfo.Add_Classification(lomClassification1); lomClassification1.Purpose.Value = "Discipline"; LOM_TaxonPath lomTaxonPath1 = new LOM_TaxonPath(); lomClassification1.Add_TaxonPath(lomTaxonPath1); lomTaxonPath1.Add_SourceName("ARIADNE"); LOM_Taxon lomTaxon1 = new LOM_Taxon(); lomTaxonPath1.Add_Taxon(lomTaxon1); lomTaxon1.ID = "BF120"; lomTaxon1.Add_Entry("Work_History", "en"); lomTaxon1.Add_Entry("Historie", "nl"); LOM_Taxon lomTaxon2 = new LOM_Taxon(); lomTaxonPath1.Add_Taxon(lomTaxon2); lomTaxon2.ID = "BF120.1"; lomTaxon2.Add_Entry("American Work_History", "en"); LOM_Taxon lomTaxon3 = new LOM_Taxon(); lomTaxonPath1.Add_Taxon(lomTaxon3); lomTaxon3.ID = "BF120.1.4"; lomTaxon3.Add_Entry("American Civil War", "en"); LOM_Classification lomClassification2 = new LOM_Classification(); lomInfo.Add_Classification(lomClassification2); lomClassification2.Purpose.Value = "Educational Objective"; LOM_TaxonPath lomTaxonPath2 = new LOM_TaxonPath(); lomClassification2.Add_TaxonPath(lomTaxonPath2); lomTaxonPath2.Add_SourceName("Common Core Standards", "en"); LOM_Taxon lomTaxon4 = new LOM_Taxon(); lomTaxonPath2.Add_Taxon(lomTaxon4); lomTaxon4.ID = "CCS.Math.Content"; LOM_Taxon lomTaxon5 = new LOM_Taxon(); lomTaxonPath2.Add_Taxon(lomTaxon5); lomTaxon5.ID = "3"; lomTaxon5.Add_Entry("Grade 3", "en"); LOM_Taxon lomTaxon6 = new LOM_Taxon(); lomTaxonPath2.Add_Taxon(lomTaxon6); lomTaxon6.ID = "OA"; lomTaxon6.Add_Entry("Operations and Algebraic Thinking", "en"); LOM_Taxon lomTaxon7 = new LOM_Taxon(); lomTaxonPath2.Add_Taxon(lomTaxon7); lomTaxon7.ID = "A"; lomTaxon7.Add_Entry("Represent and solve problems involving multiplication and division.", "en"); LOM_Taxon lomTaxon8 = new LOM_Taxon(); lomTaxonPath2.Add_Taxon(lomTaxon8); lomTaxon8.ID = "3"; lomTaxon8.Add_Entry("Use multiplication and division within 100 to solve word problems in situations involving equal groups, arrays, and measurement quantities, e.g., by using drawings and equations with a symbol for the unknown number to represent the problem.", "en"); LOM_TaxonPath lomTaxonPath3 = new LOM_TaxonPath(); lomClassification2.Add_TaxonPath(lomTaxonPath3); lomTaxonPath3.Add_SourceName("Common Core Standards", "en"); LOM_Taxon lomTaxon14 = new LOM_Taxon(); lomTaxonPath3.Add_Taxon(lomTaxon14); lomTaxon14.ID = "CCS.Math.Content"; LOM_Taxon lomTaxon15 = new LOM_Taxon(); lomTaxonPath3.Add_Taxon(lomTaxon15); lomTaxon15.ID = "3"; lomTaxon15.Add_Entry("Grade 3", "en"); LOM_Taxon lomTaxon16 = new LOM_Taxon(); lomTaxonPath3.Add_Taxon(lomTaxon16); lomTaxon16.ID = "OA"; lomTaxon16.Add_Entry("Operations and Algebraic Thinking", "en"); LOM_Taxon lomTaxon17 = new LOM_Taxon(); lomTaxonPath3.Add_Taxon(lomTaxon17); lomTaxon17.ID = "A"; lomTaxon17.Add_Entry("Represent and solve problems involving multiplication and division.", "en"); LOM_Taxon lomTaxon18 = new LOM_Taxon(); lomTaxonPath3.Add_Taxon(lomTaxon18); lomTaxon18.ID = "4"; lomTaxon18.Add_Entry("Determine the unknown whole number in a multiplication or division equation relating three whole numbers. For example, determine the unknown number that makes the equation true in each of the equations 8 × ? = 48, 5 = _ ÷ 3, 6 × 6 = ?", "en"); // Add some views and interfaces testPackage.Behaviors.Clear_Web_Skins(); testPackage.Behaviors.Add_Web_Skin("dLOC"); testPackage.Behaviors.Add_Web_Skin("UFDC"); testPackage.Behaviors.Add_View(View_Enum.JPEG2000); testPackage.Behaviors.Add_View(View_Enum.JPEG); testPackage.Behaviors.Add_View(View_Enum.RELATED_IMAGES); testPackage.Behaviors.Add_View(View_Enum.HTML, "Full Document", "MVS001214.html"); // Create the chapters and pages and link them Division_TreeNode chapter1 = new Division_TreeNode("Chapter", "First Chapter"); Page_TreeNode page1 = new Page_TreeNode("First Page"); Page_TreeNode page2 = new Page_TreeNode("Page 2"); chapter1.Nodes.Add(page1); chapter1.Nodes.Add(page2); Division_TreeNode chapter2 = new Division_TreeNode("Chapter", "Last Chapter"); Page_TreeNode page3 = new Page_TreeNode("Page 3"); Page_TreeNode page4 = new Page_TreeNode("Last Page"); chapter2.Nodes.Add(page3); chapter2.Nodes.Add(page4); testPackage.Divisions.Physical_Tree.Roots.Add(chapter1); testPackage.Divisions.Physical_Tree.Roots.Add(chapter2); // Create the files SobekCM_File_Info file1_1 = new SobekCM_File_Info("2000626_0001.jp2", 2120, 1100); SobekCM_File_Info file1_2 = new SobekCM_File_Info("2000626_0001.jpg", 630, 330); SobekCM_File_Info file1_3 = new SobekCM_File_Info("2000626_0001.tif"); SobekCM_File_Info file2_1 = new SobekCM_File_Info("2000626_0002.jp2", 1754, 2453); SobekCM_File_Info file2_2 = new SobekCM_File_Info("2000626_0002.jpg", 630, 832); SobekCM_File_Info file2_3 = new SobekCM_File_Info("2000626_0002.tif"); SobekCM_File_Info file3_1 = new SobekCM_File_Info("2000626_0003.jp2", 2321, 1232); SobekCM_File_Info file3_2 = new SobekCM_File_Info("2000626_0003.jpg", 630, 342); SobekCM_File_Info file3_3 = new SobekCM_File_Info("2000626_0003.tif"); SobekCM_File_Info file4_1 = new SobekCM_File_Info("2000626_0004.jp2", 2145, 1024); SobekCM_File_Info file4_2 = new SobekCM_File_Info("2000626_0004.jpg", 630, 326); SobekCM_File_Info file4_3 = new SobekCM_File_Info("2000626_0004.tif"); // Link the files to the pages page1.Files.Add(file1_1); page1.Files.Add(file1_2); page1.Files.Add(file1_3); page2.Files.Add(file2_1); page2.Files.Add(file2_2); page2.Files.Add(file2_3); page3.Files.Add(file3_1); page3.Files.Add(file3_2); page3.Files.Add(file3_3); page4.Files.Add(file4_1); page4.Files.Add(file4_2); page4.Files.Add(file4_3); // Add the DAITSS information DAITSS_Info daitssInfo = new DAITSS_Info(); daitssInfo.Account = "FTU"; daitssInfo.SubAccount = "CLAS"; daitssInfo.Project = "UFDC"; daitssInfo.toArchive = true; testPackage.Add_Metadata_Module(GlobalVar.DAITSS_METADATA_MODULE_KEY, daitssInfo); // Save this package testPackage.Source_Directory = directory; return testPackage; }
/// <summary> Save all the data from form post-back into the item in memory, and /// return all the page information for those pages which are CHECKED (with the checkbox) </summary> /// <returns> Returns TRUE if successful, otherwise FALSE </returns> private bool Save_From_Form_Request_To_Item(string FilenameToMoveAfter, string FilenameToOmit, out List<QC_Viewer_Page_Division_Info> Selected_Page_Div_From_Form) { bool returnValue = true; // Get the current page number int current_qc_viewer_page_num = 1; if (CurrentRequest.ViewerCode.Replace("qc", "").Length > 0) Int32.TryParse(CurrentRequest.ViewerCode.Replace("qc", ""), out current_qc_viewer_page_num); // First, build a dictionary of all the pages ( filename --> page division object ) Dictionary<Page_TreeNode, Division_TreeNode> pages_to_division = new Dictionary<Page_TreeNode, Division_TreeNode>(); Dictionary<string, Page_TreeNode> pages_by_name = new Dictionary<string, Page_TreeNode>(); List<Page_TreeNode> page_list = new List<Page_TreeNode>(); List<string> page_filename_list = new List<string>(); Division_TreeNode lastDivision = null; //Autonumber the remaining pages based on the selected option if (autonumber_mode_from_form == 0 || autonumber_mode_from_form == 1) { autonumber_mode = autonumber_mode_from_form; bool reached_last_page = false; bool reached_next_div = false; int number = 0; if (autonumber_number_system == "decimal") number = Int32.Parse(autonumber_number_only) + 1; else if (autonumber_number_system.ToLower() == "roman") //number = RomanToNumber(autonumber_number_only) + 1; number = Int32.Parse(autonumber_number_only) + 1; //Do the autonumbering first foreach (abstract_TreeNode thisNode in qc_item.Divisions.Physical_Tree.Divisions_PreOrder) { //Is this a division or a page node? if (thisNode.Page) { Page_TreeNode thisPage = (Page_TreeNode)thisNode; //Verify the page if (thisPage.Files.Count > 0) { string filename = thisPage.Files[0].File_Name_Sans_Extension; if (filename == hidden_autonumber_filename) { reached_last_page = true; } //if the last page displayed on the screen has been reached else if (reached_last_page == true) { //Mode "0": Autonumber all pages of current division //Mode "1": Autonumber all pages of the entire document if ((autonumber_mode_from_form == 0 && reached_next_div == false) || (autonumber_mode_from_form == 1)) { if (autonumber_number_system == "decimal") thisPage.Label = autonumber_text_only + number.ToString(); else if (autonumber_number_system == "ROMAN") { thisPage.Label = autonumber_text_only + NumberToRoman(number).ToUpper(); } else { thisPage.Label = autonumber_text_only + NumberToRoman(number).ToLower(); } number++; } } } } else if (reached_last_page) { reached_next_div = true; } } } //Move/Delete Pages as appropriate foreach (abstract_TreeNode thisNode in qc_item.Divisions.Physical_Tree.Divisions_PreOrder) { // Is this a division, or page node? if (thisNode.Page) { Page_TreeNode thisPage = (Page_TreeNode)thisNode; // Verify the page if (thisPage.Files.Count > 0) { string filename = thisPage.Files[0].File_Name_Sans_Extension; pages_by_name[filename] = thisPage; page_filename_list.Add(filename); } // Add to the list of pages page_list.Add(thisPage); // Save the link from the page, up to the division pages_to_division[thisPage] = lastDivision; } else { lastDivision = (Division_TreeNode)thisNode; } } // Step through and collect all the form data List<QC_Viewer_Page_Division_Info> page_div_from_form = new List<QC_Viewer_Page_Division_Info>(); List<Page_TreeNode> existing_pages_in_window = new List<Page_TreeNode>(); //Get the list of pages to be moved Selected_Page_Div_From_Form = new List<QC_Viewer_Page_Division_Info>(); try { // Now, step through each of the pages in the return string[] keysFromForm = HttpContext.Current.Request.Form.AllKeys; foreach (string thisKey in keysFromForm) { // Has this gotten to the next page? if ((thisKey.IndexOf("filename") == 0) && (thisKey.Length > 8)) { // Create the qc viewer page information, and assign the filename QC_Viewer_Page_Division_Info thisInfo = new QC_Viewer_Page_Division_Info { Filename = HttpContext.Current.Request.Form[thisKey] }; // Get the index to use for all the other keys string thisIndex = thisKey.Substring(8); // Get the page name thisInfo.Page_Label = HttpContext.Current.Request.Form["textbox" + thisIndex]; // Was this page selected with the checkbox? (for bulk delete or move) //Get this info only if the move/delete operations are explicitly triggered if (hidden_request == "delete_page" || hidden_request == "delete_selected_pages" || hidden_request == "move_selected_pages") { if ((HttpContext.Current.Request.Form["chkMoveThumbnail" + thisIndex] != null) || (thisInfo.Filename == FilenameToOmit)) { thisInfo.Checkbox_Selected = true; Selected_Page_Div_From_Form.Add(thisInfo); } } // Is this a new division? if (HttpContext.Current.Request.Form["newdiv" + thisIndex] != null) { thisInfo.New_Division = true; // Get the new division type/label thisInfo.Division_Type = HttpContext.Current.Request.Form["selectDivType" + thisIndex].Trim().Replace("!", ""); thisInfo.Division_Label = String.Empty; if (HttpContext.Current.Request.Form["txtDivName" + thisIndex] != null) thisInfo.Division_Label = HttpContext.Current.Request.Form["txtDivName" + thisIndex].Trim(); if (thisInfo.Division_Type.Length == 0) thisInfo.Division_Type = "Chapter"; // Get the division config, based on the division type if (qc_profile[thisInfo.Division_Type] != null) { QualityControl_Division_Config divInfo = qc_profile[thisInfo.Division_Type]; if (divInfo.BaseTypeName.Length > 0) { thisInfo.Division_Label = thisInfo.Division_Type; thisInfo.Division_Type = divInfo.BaseTypeName; } else if (!divInfo.isNameable) { thisInfo.Division_Label = String.Empty; } } } else { thisInfo.New_Division = false; } // Add this page to the collection page_div_from_form.Add(thisInfo); // Also, collect the page node from the mets/resource for clearing later if (pages_by_name.ContainsKey(thisInfo.Filename)) { Page_TreeNode existing_pagenode = pages_by_name[thisInfo.Filename]; existing_pages_in_window.Add(existing_pagenode); } } } // Determine the "window" that the user was seeing int window_first_page_index = page_filename_list.Count - 1; int window_last_page_index = 0; foreach (QC_Viewer_Page_Division_Info thisInfo in page_div_from_form) { // Get the filename and then get the order int page_order = page_filename_list.IndexOf(thisInfo.Filename); if (page_order < window_first_page_index) window_first_page_index = page_order; if (page_order > window_last_page_index) window_last_page_index = page_order; } // TODO: Do some sanity checks here to ensure it worked // Determine if the first page was part of an existing division (and not the first page in that division) Page_TreeNode window_first_page = page_list[window_first_page_index]; Division_TreeNode window_first_division = pages_to_division[window_first_page]; Division_TreeNode existing_division_containing_first_page = null; if (window_first_division.Nodes.IndexOf(window_first_page) > 0) existing_division_containing_first_page = window_first_division; // Collect any additional, non-cleared pages from the division which contained the last page originally List<Page_TreeNode> remnant_pages = new List<Page_TreeNode>(); Page_TreeNode window_last_page = page_list[window_last_page_index]; Division_TreeNode window_last_division = pages_to_division[window_last_page]; if (window_last_division.Nodes.IndexOf(window_last_page) < window_last_division.Nodes.Count) { for (int i = window_last_division.Nodes.IndexOf(window_last_page) + 1; i < window_last_division.Nodes.Count; i++) { remnant_pages.Add((Page_TreeNode)window_last_division.Nodes[i]); } } // Clear the window pages completely, including the remnant pages, which we add back at the end int index_within_chapter_roots_to_begin_insert = qc_item.Divisions.Physical_Tree.Roots.Count; foreach (Page_TreeNode thisNode in existing_pages_in_window) { // Get the parent division, to clear this Division_TreeNode parentNode = pages_to_division[thisNode]; parentNode.Nodes.Remove(thisNode); // What is the index within the list of chapters int this_root_index = qc_item.Divisions.Physical_Tree.Roots.IndexOf(parentNode) + 1; // Does this clear out the chapter completely? if (parentNode.Nodes.Count == 0) { qc_item.Divisions.Physical_Tree.Roots.Remove(parentNode); this_root_index--; } // If this insert point is prior to the previously collected insert point, use this one for the first chapter if (this_root_index < index_within_chapter_roots_to_begin_insert) index_within_chapter_roots_to_begin_insert = this_root_index; } foreach (Page_TreeNode thisNode in remnant_pages) { // Get the parent division, to clear this window_last_division.Nodes.Remove(thisNode); // Does this clear out the chapter completely? if (window_last_division.Nodes.Count == 0) { qc_item.Divisions.Physical_Tree.Roots.Remove(window_last_division); } } int move_into_division_index = -1; int move_into_node_index = -1; // Add each page from the original form Division_TreeNode last_added_division = existing_division_containing_first_page; foreach (QC_Viewer_Page_Division_Info pageInfo in page_div_from_form) { // Is this a new division? if (pageInfo.New_Division) { // If there was a last division, ensure some pages were added and add to the METS if (last_added_division != null) { // Were any pages added to this last div? if (last_added_division.Nodes.Count > 0) { // Since there were pages, add this to the METS qc_item.Divisions.Physical_Tree.Roots.Insert(index_within_chapter_roots_to_begin_insert++, last_added_division); } } // Create the new division last_added_division = new Division_TreeNode(pageInfo.Division_Type, pageInfo.Division_Label); } // Get the page tree node and assign the new page label Page_TreeNode thisPage = pages_by_name[pageInfo.Filename]; thisPage.Label = pageInfo.Page_Label; // Add this page to the last division (possibly just created above) assuming it is // not marked for removal (either by mass delete or mass move) if (!pageInfo.Checkbox_Selected) last_added_division.Add_Child(thisPage); else { // Save the built page node for later, in case they will be MOVED pageInfo.METS_StructMap_Page_Node = thisPage; } // Were we involved in a mass move, in which case we are looking for the insertion point? if ((FilenameToMoveAfter.Length > 0) && (move_into_division_index < 0) && (pageInfo.Filename == FilenameToMoveAfter)) { move_into_division_index = index_within_chapter_roots_to_begin_insert; move_into_node_index = last_added_division.Nodes.Count; } } // Handle all the remnant by adding to the last division foreach (Page_TreeNode thisNode in remnant_pages) { last_added_division.Add_Child(thisNode); } // Handle any unfinished divisions // If there was a last division, ensure some pages were added and add to the METS if (last_added_division != null) { // Were any pages added to this last div? if (last_added_division.Nodes.Count > 0) { // Since there were pages, add this to the METS if (index_within_chapter_roots_to_begin_insert > qc_item.Divisions.Physical_Tree.Roots.Count) index_within_chapter_roots_to_begin_insert = qc_item.Divisions.Physical_Tree.Roots.Count; qc_item.Divisions.Physical_Tree.Roots.Insert(index_within_chapter_roots_to_begin_insert++, last_added_division); } } // Insert any pages which were moved if ((FilenameToMoveAfter.Length > 0) && (Selected_Page_Div_From_Form.Count > 0)) { // TODO: Check for the lack of any divisions what-so-ever within the METS. If so, add one. Division_TreeNode divNodeToInsertWithin = null; // Get the division if (move_into_division_index >= 0) divNodeToInsertWithin = (Division_TreeNode)qc_item.Divisions.Physical_Tree.Roots[move_into_division_index]; else if (FilenameToMoveAfter == "[BEFORE FIRST]") { divNodeToInsertWithin = (Division_TreeNode)qc_item.Divisions.Physical_Tree.Roots[0]; move_into_node_index = 0; } if (divNodeToInsertWithin != null) { // Insert each page in order foreach (QC_Viewer_Page_Division_Info insertPage in Selected_Page_Div_From_Form) { divNodeToInsertWithin.Nodes.Insert(move_into_node_index++, insertPage.METS_StructMap_Page_Node); } } } // Save the updated to the session HttpContext.Current.Session[qc_item.BibID + "_" + qc_item.VID + " QC Work"] = qc_item; // Save to the temporary QC work section // Ensure the directory exists under the user's temporary mySobek InProcess folder if (!Directory.Exists(userInProcessDirectory)) Directory.CreateDirectory(userInProcessDirectory); // Save the METS qc_item.Save_METS(metsInProcessFile); // Determine the total size of the package before saving string[] all_files_final = Directory.GetFiles(userInProcessDirectory); double size = all_files_final.Aggregate<string, double>(0, (current, thisFile) => current + (((new FileInfo(thisFile)).Length) / 1024)); qc_item.DiskSize_KB = size; } catch (Exception e) { string error_folder = UI_ApplicationCache_Gateway.Settings.Servers.Image_Server_Network + qc_item.Web.AssocFilePath + "\\sobek_files"; if (!Directory.Exists(error_folder)) Directory.CreateDirectory(error_folder); string error_message_file = "qc_error_" + DateTime.Now.Year + "_" + DateTime.Now.Month.ToString().PadLeft(2, '0') + "_" + DateTime.Now.Day.ToString().PadLeft(2, '0') + "_" + DateTime.Now.Hour.ToString().PadLeft(2, '0') + "_" + DateTime.Now.Minute.ToString().PadLeft(2, '0') + "_" + DateTime.Now.Second.ToString().PadLeft(2, '0') + "_" + DateTime.Now.Millisecond + ".txt"; StreamWriter writer = new StreamWriter(error_folder + "\\" + error_message_file, true); writer.WriteLine("EXCEPTION CAUGHT DURING SAVE_FROM_FORM_REQUEST_TO_ITEM METHOD (2nd spot)"); writer.WriteLine(); writer.WriteLine(e.Message); writer.WriteLine(); writer.WriteLine(e.StackTrace); writer.WriteLine(); try { writer.WriteLine(qc_item.Divisions.Physical_Tree.Pages_PreOrder.Count + " PAGES"); } catch { writer.WriteLine("ERROR GETTING PAGE COUNT"); } writer.Flush(); writer.Close(); // Also, send an email Email_Helper.SendEmail("*****@*****.**", "QC Error caught on " + qc_item.BibID + ":" + qc_item.VID, "EXCEPTION CAUGHT DURING SAVE_FROM_FORM_REQUEST_TO_ITEM METHOD\n\n" + e.Message + "\n\n" + e.StackTrace, false, UI_ApplicationCache_Gateway.Settings.System.System_Name); // Rethrow this error throw new ApplicationException(e.Message); } // Return the flag indicating success return returnValue; }
private void recurse_through_tree(Division_TreeNode ParentNode, TreeNode ParentViewNode, List<TreeNode> Nodes, List<TreeNode> SelectedNodes, List<TreeNode> PathNodes, ref int Sequence) { foreach (abstract_TreeNode absNode in ParentNode.Nodes) { if (absNode.Page) { Sequence++; foreach (TreeNode thisNode in Nodes) { thisNode.Value = Sequence.ToString(); } if (Sequence >= RequestSpecificValues.Current_Mode.Page) { if (!tocSelectedComplete) { SelectedNodes.AddRange(PathNodes); tocSelectedComplete = true; } else { if (Sequence == RequestSpecificValues.Current_Mode.Page) { SelectedNodes.AddRange(PathNodes); } } } Nodes.Clear(); } else { Division_TreeNode divNode = (Division_TreeNode)absNode; TreeNode treeViewNode = new TreeNode { Text = string.Format("<span class=\"SobekTocTreeViewItem\" Title='{0}'>{1}</span>", divNode.Display_Label, divNode.Display_Short_Label) }; ParentViewNode.ChildNodes.Add(treeViewNode); Nodes.Add(treeViewNode); List<TreeNode> pathNodes2 = new List<TreeNode> { treeViewNode }; recurse_through_tree(divNode, treeViewNode, Nodes, SelectedNodes, pathNodes2, ref Sequence); } } }
/// <summary> This provides an opportunity for the viewer to perform any pre-display work /// which is necessary before entering any of the rendering portions </summary> /// <param name="Tracer"> Trace object keeps a list of each method executed and important milestones in rendering </param> public void Perform_PreDisplay_Work(Custom_Tracer Tracer) { //Get the item details from the DB Item_Detail = Engine_Database.Get_Item_Information(BriefItem.BibID, BriefItem.VID, Tracer); if (Item_Detail != null) { //get the main thumbnail & JPEG filenames from the database mainThumbnailFileName_from_db = Item_Detail["MainThumbnailFile"].ToString(); mainJPGFileName_from_db = Item_Detail["MainJPEGFile"].ToString(); //Get the filenames without the extensions int length_thumbnail = mainThumbnailFileName_from_db.IndexOf("thm.jpg"); int lengthJpeg = mainJPGFileName_from_db.IndexOf(".jpg"); if (length_thumbnail > 0) mainThumbnailFileName_from_db = mainThumbnailFileName_from_db.Substring(0, length_thumbnail); if (lengthJpeg > 0) mainJPGFileName_from_db = mainJPGFileName_from_db.Substring(0, lengthJpeg); } //Get the Drag & Drop setting from the user options makeSortable = CurrentUser.Get_Setting("QC_ItemViewer:SortableMode", 3); // Get the proper number of thumbnails per page // First, pull the thumbnails per page from the user options thumbnailsPerPage = CurrentUser.Get_Setting("QC_ItemViewer:ThumbnailsPerPage", 1000); // Or was there a new value in the URL? if (CurrentRequest.Thumbnails_Per_Page >= -1) { CurrentUser.Add_Setting("QC_ItemViewer:ThumbnailsPerPage", CurrentRequest.Thumbnails_Per_Page); thumbnailsPerPage = CurrentRequest.Thumbnails_Per_Page.HasValue ? CurrentRequest.Thumbnails_Per_Page.Value : -100; // Now, reset the value in the navigation object, since we won't need to set it again CurrentRequest.Thumbnails_Per_Page = -100; } // -1 means to display all thumbnails (which is now capped at 1000) if (thumbnailsPerPage == -1) thumbnailsPerPage = 1000; // Get the proper size of thumbnails per page // First, pull the thumbnails per page from the user options thumbnailSize = CurrentUser.Get_Setting("QC_ItemViewer:ThumbnailSize", 1); // Or was there a new value in the URL? if (CurrentRequest.Size_Of_Thumbnails > -1) { CurrentUser.Add_Setting("QC_ItemViewer:ThumbnailSize", CurrentRequest.Size_Of_Thumbnails); thumbnailSize = CurrentRequest.Size_Of_Thumbnails.HasValue ? CurrentRequest.Size_Of_Thumbnails.Value : -1; //Now reset the current mode value since we won't need to set it again CurrentRequest.Size_Of_Thumbnails = -1; } // Get the autonumbering mode // First, pull the autonumbering mode from the user options autonumber_mode = CurrentUser.Get_Setting("QC_ItemViewer:AutonumberingMode", 0); //Also pull the Sortable mode from the user options makeSortable = CurrentUser.Get_Setting("QC_ItemViewer:SortableMode", 3); // Ensure there are no pages directly under the item List<abstract_TreeNode> add_to_new_main = new List<abstract_TreeNode>(); foreach (abstract_TreeNode rootNode in qc_item.Divisions.Physical_Tree.Roots) { if (rootNode.Page) { add_to_new_main.Add(rootNode); } } if (add_to_new_main.Count > 0) { Division_TreeNode newMain = new Division_TreeNode("Main", String.Empty); qc_item.Divisions.Physical_Tree.Roots.Add(newMain); foreach (abstract_TreeNode thisNode in add_to_new_main) newMain.Add_Child(thisNode); } // Now, build a list from child node to parent node childToParent = new Dictionary<Page_TreeNode, Division_TreeNode>(); foreach (abstract_TreeNode rootNode in qc_item.Divisions.Physical_Tree.Roots) { if (!rootNode.Page) { recurse_through_and_find_child_parent_relationship((Division_TreeNode)rootNode); } } }