module Ddr # # Wraps a Nokogiri (XML) 'mets' Document # class Structure < SimpleDelegator # Indicates whether the structure is externally provided or maintained by the repository itself (i.e., is the # default structure for the object). EXTERNALLY_PROVIDED = 'provided'.freeze REPOSITORY_MAINTAINED = 'repository'.freeze TYPE_DEFAULT = 'default'.freeze # Based on the PCDM Extension 'Use' ontology -- https://github.com/duraspace/pcdm/blob/master/pcdm-ext/use.rdf USE_EXTRACTED_TEXT = 'ExtractedText'.freeze USE_INTERMEDIATE_FILE = 'IntermediateFile'.freeze USE_ORIGINAL_FILE = 'OriginalFile'.freeze USE_PRESERVATION_MASTER_FILE = 'PreservationMasterFile'.freeze USE_SERVICE_FILE = 'ServiceFile'.freeze USE_THUMBNAIL_IMAGE = 'ThumbnailImage'.freeze USE_TRANSCRIPT = 'Transcript'.freeze def filesec @filesec ||= Ddr::Structures::FileSec.new(fileSec_node) end def files @files ||= collect_files end def uses @uses ||= collect_uses end def structmap(type=nil) sm = type ? structMap_node(type) : structMap_nodes.first @structmap ||= Ddr::Structures::StructMap.new(sm) end def structmaps @structmaps ||= structMap_nodes.map { |sm| Ddr::Structures::StructMap.new(sm) } end def metshdr @metshdr ||= Ddr::Structures::MetsHdr.new(metsHdr_node) end def creator @creator ||= metshdr.empty? ? nil : Ddr::Structures::MetsHdr.new(metsHdr_node).agents.first.name end def repository_maintained? creator == Ddr::Structures::Agent::NAME_REPOSITORY_DEFAULT end def dereferenced_structure deref_struct = {} structmaps.each do |sm| deref_struct[sm.type] = sm.dereferenced_hash end deref_struct end def as_xml_document __getobj__ end def add_metshdr(id:nil, createdate:nil, lastmoddate:nil, recordstatus:nil) metshdr = Ddr::Structures::MetsHdr.build(id: id, createdate: createdate, lastmoddate: lastmoddate, recordstatus: recordstatus, document: as_xml_document) root.add_child(metshdr) metshdr end def add_agent(parent:, id:nil, role:, otherrole:nil, type:nil, othertype:nil, name:nil) agent = Ddr::Structures::Agent.build(id: id, role: role, otherrole: otherrole, type: type, othertype: othertype, name: name, document: as_xml_document) parent.add_child(agent) agent end def add_filesec(id:nil) filesec = Ddr::Structures::FileSec.build(id: id, document: as_xml_document) root.add_child(filesec) filesec end def add_filegrp(parent:, id:nil, use:nil) filegrp = Ddr::Structures::FileGrp.build(id: id, use: use, document: as_xml_document) parent.add_child(filegrp) filegrp end def add_file(parent:, id: "id_" + SecureRandom.uuid, use:nil) file = Ddr::Structures::File.build(id: id, use: use, document: as_xml_document) parent.add_child(file) file end def add_flocat(parent:, id:nil, loctype:'ARK', otherloctype: nil, use:nil, href:) flocat = Ddr::Structures::FLocat.build(id: id, loctype: loctype, otherloctype: otherloctype, use: use, href: href, document: as_xml_document) parent.add_child(flocat) flocat end def add_structmap(id:nil, label:nil, type:) structmap = Ddr::Structures::StructMap.build(id: id, label: label, type: type, document: as_xml_document) root.add_child(structmap) structmap end def add_div(parent:, id:nil, label:nil, order:nil, orderlabel: nil, type:nil) div = Ddr::Structures::Div.build(id: id, label: label, order:order, orderlabel: orderlabel, type: type, document: as_xml_document) parent.add_child(div) div end def add_fptr(parent:, id: nil, fileid:) fptr = Ddr::Structures::Fptr.build(id: id, fileid: fileid, document: as_xml_document) parent.add_child(fptr) fptr end def add_mptr(parent:, id: nil, loctype:'ARK', otherloctype: nil, href:) mptr = Ddr::Structures::Mptr.build(id: id, loctype: loctype, otherloctype: otherloctype, href: href, document: as_xml_document) parent.add_child(mptr) mptr end private def fileSec_node xpath("//xmlns:fileSec").first end def structMap_nodes xpath("//xmlns:structMap") end def structMap_node(type) xpath("//xmlns:structMap[@TYPE='#{type}']").first end def metsHdr_node xpath("//xmlns:metsHdr") end def file_nodes xpath("//xmlns:file") end def flocat_nodes xpath("//xmlns:FLocat") end def collect_files files = {} file_nodes.each do |file_node| file = Ddr::Structures::File.new(file_node) files[file.id] = file end files end def collect_uses uses = {} flocat_nodes.each do |flocat_node| flocat = Ddr::Structures::FLocat.new(flocat_node) uses[flocat.effective_use] ||= [] uses[flocat.effective_use] << flocat end uses end def self.xml_template Nokogiri::XML( '' ) do |config| config.noblanks end end end end