require 'cul/fedora/image/image' require 'pathname' require 'rexml/document' require 'uri' module Cul module Fedora module Arm AGGREGATOR_FOXML = < {0[title]} BATCH {0[dc_type]} {0[id]} {0[rels]} INGEST # >> METADATA_FOXML = < {0[title]} BATCH Text text/xml Columbia University Libraries {0[identifier]} {0[source]} {0[rels]} {0[metadata]} INGEST # >> RESOURCE_FOXML = < BATCH Columbia University Libraries {0[dc_type]} {0[mime]} {0[pid]} {0[src]} {0[rels]} RESOURCE # >> class FoxmlBuilder include Cul::Fedora::Image STATIC_IMAGE_DEFAULTS = { :content_model => 'ldpd:StaticImageAggregator', :title => 'Image Aggregator', :title_attr => 'Image Aggregator', :dc_type => 'Image', } CONTENT_DEFAULTS = { :content_model => 'ldpd:ContentAggregator', :title => 'Generic Content Aggregator', :title_attr => 'Generic Content Aggregator', :dc_type => 'InteractiveResource', } METADATA_DEFAULTS = { :content_model => 'ldpd:MODSMetadata', :dc_type => 'Text', :dc_format => 'text/xml' } RESOURCE_DEFAULTS = { :content_model => 'ldpd:Resource' } DEFAULTS = { :staticimage_aggregator => STATIC_IMAGE_DEFAULTS, :content_aggregator => CONTENT_DEFAULTS, :metadata => METADATA_DEFAULTS, :image_resource => RESOURCE_DEFAULTS, :resource => RESOURCE_DEFAULTS } TEMPLATES = { :aggregator => Cul::Fedora::Arm::AGGREGATOR_FOXML, :metadata => Cul::Fedora::Arm::METADATA_FOXML, :resource => Cul::Fedora::Arm::RESOURCE_FOXML } METADATA_FOR = "" MEMBER_OF = "" UTF8_MARKER = "\xEF\xBB\xBF" def build(value_hash) template_type = value_hash[:template_type] model_type = value_hash[:model_type] value_default_key = (template_type.downcase + "_" + model_type.downcase).intern subs = {} if(DEFAULTS.has_key?(value_default_key)) subs = value_hash.merge(DEFAULTS[value_default_key]) now = Time.now subs[:timestamp] = now.strftime("%Y-%m-%dT%H:%M:%S.000Z") subs[:rels] = build_rels(subs) else subs = value_hash.merge({:timestamp=>Time.now.strftime("%Y-%m-%dT%H:%M:%S.000Z")}) subs[:rels] = build_rels(subs) end if (subs.has_key?(:source)) subs[:source].strip! if(subs[:source].length > 0) if (subs[:source].index('http:') != 0) if(subs[:model_type].eql?('Metadata')) subs[:metadata] = File.open(subs[:source]){|file| file.read() } subs.merge!(parse_mods(subs[:metadata])) end subs[:source] = 'file:/' + Pathname.new(subs[:source]).realpath subs[:datastream_type] = 'E' else subs[:datastream_type] = 'M' end end end template_key = model_type.downcase.intern if(TEMPLATES.has_key?(template_key)) return sub_values(subs,TEMPLATES[template_key]) else raise "Unknown model type #{value_hash[:model_type]}" end end protected def parse_mods(data) # attempt to assign title/title_attr and identifier result = {} xml = REXML::Document.new(data) element = xml.elements["/mods/titleInfo/title"] if (element) result[:title] = element.text result[:title_attr] = URI.escape(element.text) end element = xml.elements["/mods/recordInfo/recordIdentifier"] if (element) result[:identifier] = element.text elsif (element = xml.elements["/mods/identifier"]) result[:identifier] = element.text end result end def build_rels(value_hash) if (value_hash[:target].nil?) return '' end rels = '' targets = value_hash[:target].split(';') tmp = value_hash[:model_type].downcase.eql?('metadata') ? METADATA_FOR : MEMBER_OF targets.each {|target| rels += sprintf(tmp,target) } if (value_hash[:model_type].eql?('Resource') and not value_hash[:dc_format].index('Image').nil?) image_props = analyze_image(value_hash[:source]) value_hash[:mime] = image_props[:mime] image_rels = map_image_properties(image_props) image_rels.each {|rel| rels += rel } end rels end def sub_values(value_hash,template) data = template.gsub(/\{0\[(\w+)\]\}/) {|match| value_hash[$1.intern] } data.strip! if (data.index(UTF8_MARKER) == 0) data.slice!(0...UTF8_MARKER.length) end data end end end end end