cul_scv_hydra 0.22.6 → 0.22.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/concerns/cul/hydra/controller.rb +22 -0
- data/app/controllers/concerns/cul/hydra/resolver.rb +69 -0
- data/app/controllers/concerns/cul/hydra/thumbnails.rb +62 -0
- data/app/controllers/concerns/cul/scv/hydra/controller.rb +3 -19
- data/app/controllers/concerns/cul/scv/hydra/resolver.rb +2 -65
- data/app/controllers/concerns/cul/scv/hydra/thumbnails.rb +3 -59
- data/app/models/concept.rb +1 -1
- data/app/models/concerns/cul/hydra/models.rb +24 -0
- data/app/models/concerns/cul/hydra/models/aggregator.rb +121 -0
- data/app/models/concerns/cul/hydra/models/common.rb +220 -0
- data/app/models/concerns/cul/hydra/models/image_resource.rb +78 -0
- data/app/models/concerns/cul/hydra/models/linkable_resources.rb +108 -0
- data/app/models/concerns/cul/hydra/models/resource.rb +87 -0
- data/app/models/concerns/cul/scv/hydra/models.rb +1 -13
- data/app/models/concerns/cul/scv/hydra/models/aggregator.rb +1 -116
- data/app/models/concerns/cul/scv/hydra/models/common.rb +1 -213
- data/app/models/concerns/cul/scv/hydra/models/image_resource.rb +3 -75
- data/app/models/concerns/cul/scv/hydra/models/linkable_resources.rb +3 -105
- data/app/models/concerns/cul/scv/hydra/models/resource.rb +2 -83
- data/app/models/cul/hydra/datastreams/dc_metadata.rb +107 -0
- data/app/models/cul/hydra/datastreams/mods_document.rb +195 -0
- data/app/models/cul/hydra/datastreams/struct_metadata.rb +176 -0
- data/app/models/cul/scv/hydra/datastreams/dc_metadata.rb +5 -104
- data/app/models/cul/scv/hydra/datastreams/mods_document.rb +5 -178
- data/app/models/cul/scv/hydra/datastreams/struct_metadata.rb +5 -174
- data/app/models/dc_document.rb +1 -1
- data/app/models/generic_aggregator.rb +5 -5
- data/app/models/generic_object.rb +2 -2
- data/app/models/generic_resource.rb +4 -4
- data/app/models/mets_structured_aggregator.rb +2 -2
- data/app/models/resource.rb +3 -3
- data/app/models/resource_aggregator.rb +3 -3
- data/fixtures/spec/CUL_MODS/mods-subjects.xml +24 -0
- data/lib/cul_hydra.rb +18 -0
- data/lib/cul_hydra/access_controls_enforcement.rb +53 -0
- data/lib/cul_hydra/controllers.rb +13 -0
- data/lib/cul_hydra/controllers/aggregates.rb +93 -0
- data/lib/cul_hydra/controllers/aggregator_controller_helper.rb +27 -0
- data/lib/cul_hydra/controllers/catalog.rb +12 -0
- data/lib/cul_hydra/controllers/content_aggregators.rb +81 -0
- data/lib/cul_hydra/controllers/datastreams.rb +145 -0
- data/lib/cul_hydra/controllers/helpers.rb +10 -0
- data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/active_fedora_helper_behavior.rb +1 -1
- data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/application_helper_behavior.rb +1 -1
- data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/dc_metadata_helper_behavior.rb +1 -1
- data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/hydra_assets_helper_behavior.rb +1 -1
- data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/hydra_autocomplete_helper_behavior.rb +1 -1
- data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/hydra_uploader_helper_behavior.rb +1 -1
- data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/resources_helper_behavior.rb +1 -1
- data/lib/cul_hydra/controllers/resources.rb +161 -0
- data/lib/cul_hydra/controllers/static_image_aggregators.rb +105 -0
- data/lib/cul_hydra/controllers/suggestions.rb +126 -0
- data/lib/cul_hydra/controllers/terms.rb +205 -0
- data/lib/cul_hydra/engine.rb +31 -0
- data/lib/cul_hydra/fedora.rb +41 -0
- data/lib/cul_hydra/fedora/dummy_object.rb +37 -0
- data/lib/cul_hydra/fedora/rubydora_patch.rb +16 -0
- data/lib/cul_hydra/fedora/url_helper_behavior.rb +32 -0
- data/lib/cul_hydra/indexer.rb +84 -0
- data/lib/cul_hydra/om.rb +7 -0
- data/lib/cul_hydra/om/standard_mods.rb +115 -0
- data/lib/cul_hydra/risearch_members.rb +92 -0
- data/lib/cul_hydra/solrizer.rb +10 -0
- data/lib/cul_hydra/solrizer/extractor.rb +27 -0
- data/lib/cul_hydra/solrizer/mods_fieldable.rb +435 -0
- data/lib/cul_hydra/solrizer/terminology_based_solrizer.rb +35 -0
- data/lib/cul_hydra/solrizer/value_mapper.rb +46 -0
- data/lib/{cul_scv_hydra/solrizer/field_mapper.rb → cul_hydra/solrizer_patch.rb} +0 -0
- data/lib/cul_hydra/version.rb +8 -0
- data/lib/cul_hydra/version.rb~ +8 -0
- data/lib/cul_scv_fedora/dummy_object.rb +1 -30
- data/lib/cul_scv_fedora/rubydora_patch.rb +3 -7
- data/lib/cul_scv_fedora/url_helper_behavior.rb +3 -23
- data/lib/cul_scv_hydra.rb +5 -32
- data/lib/cul_scv_hydra/access_controls_enforcement.rb +3 -50
- data/lib/cul_scv_hydra/controllers.rb +10 -10
- data/lib/cul_scv_hydra/controllers/aggregates.rb +1 -86
- data/lib/cul_scv_hydra/controllers/aggregator_controller_helper.rb +4 -23
- data/lib/cul_scv_hydra/controllers/catalog.rb +5 -9
- data/lib/cul_scv_hydra/controllers/content_aggregators.rb +4 -77
- data/lib/cul_scv_hydra/controllers/datastreams.rb +3 -140
- data/lib/cul_scv_hydra/controllers/helpers.rb +44 -8
- data/lib/cul_scv_hydra/controllers/resources.rb +4 -157
- data/lib/cul_scv_hydra/controllers/static_image_aggregators.rb +4 -100
- data/lib/cul_scv_hydra/controllers/suggestions.rb +4 -122
- data/lib/cul_scv_hydra/controllers/terms.rb +4 -201
- data/lib/cul_scv_hydra/engine.rb +1 -1
- data/lib/cul_scv_hydra/indexer.rb +3 -82
- data/lib/cul_scv_hydra/om.rb +2 -2
- data/lib/cul_scv_hydra/om/standard_mods.rb +1 -108
- data/lib/cul_scv_hydra/risearch_members.rb +4 -89
- data/lib/cul_scv_hydra/solrizer.rb +5 -6
- data/lib/cul_scv_hydra/solrizer/extractor.rb +1 -25
- data/lib/cul_scv_hydra/solrizer/scv_mods_fieldable.rb +4 -429
- data/lib/cul_scv_hydra/solrizer/terminology_based_solrizer.rb +4 -32
- data/lib/cul_scv_hydra/solrizer/value_mapper.rb +1 -44
- data/lib/cul_scv_hydra/version.rb +5 -5
- data/lib/tasks/index.rake +2 -2
- data/lib/tasks/transform.rake +23 -0
- metadata +55 -12
@@ -1,87 +1,6 @@
|
|
1
1
|
module Cul::Scv::Hydra::Models::Resource
|
2
|
-
|
3
|
-
# constants #
|
4
|
-
IMAGE_MIME_TYPES = [
|
5
|
-
'image/bmp',
|
6
|
-
'image/gif',
|
7
|
-
'image/jpeg',
|
8
|
-
'image/png',
|
9
|
-
'image/tiff'
|
10
|
-
]
|
11
|
-
|
2
|
+
extend ActiveSupport::Concern
|
12
3
|
included do
|
13
|
-
|
14
|
-
props = {
|
15
|
-
"image_width" => :image_width,
|
16
|
-
"image_length" => :image_length,
|
17
|
-
"x_sampling" => :x_sampling,
|
18
|
-
"y_sampling" => :y_sampling,
|
19
|
-
"sampling_unit" => :sampling_unit,
|
20
|
-
"extent" => :extent,
|
21
|
-
}
|
22
|
-
props.each { |x, y|
|
23
|
-
class_eval %Q{
|
24
|
-
def #{x}
|
25
|
-
return relationships[:#{y.to_s}]
|
26
|
-
}
|
27
|
-
}
|
28
|
-
|
29
|
-
after_create :resource!
|
30
|
-
end
|
31
|
-
if self.respond_to? :has_datastream
|
32
|
-
has_datastream :name => "CONTENT", :type=>::ActiveFedora::Datastream, :versionable => true
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def resource!
|
37
|
-
add_relationship(:rdf_type, Cul::Scv::Hydra::Models::RESOURCE_TYPE.to_s)
|
38
|
-
@metadata_is_dirty = true
|
39
|
-
update
|
40
|
-
end
|
41
|
-
|
42
|
-
def add_content_blob(blob, opts)
|
43
|
-
file_name = opts[:file_name]
|
44
|
-
mime = opts[:mime_type].nil? ? mime_type(file_name) : opts[:mime_type]
|
45
|
-
add_file_datastream(blob, :label=>file_name, :mimeType=>mime, :dsid => 'CONTENT')
|
46
|
-
set_title_and_label( file_name, :only_if_blank=>true )
|
47
|
-
if IMAGE_MIME_TYPES.include? mime
|
48
|
-
blob.rewind
|
49
|
-
# retrieve Nokogiri of image property RDF
|
50
|
-
image_properties = Cul::Image::Properties.identify(blob)
|
51
|
-
if image_properties
|
52
|
-
image_prop_nodes = image_properties.nodeset
|
53
|
-
relsext = datastreams['RELS-EXT']
|
54
|
-
image_prop_nodes.each { |node|
|
55
|
-
if node["resource"]
|
56
|
-
is_literal = false
|
57
|
-
object = RDF::URI.new(node["resource"])
|
58
|
-
else
|
59
|
-
is_literal = true
|
60
|
-
object = RDF::Literal(node.text)
|
61
|
-
end
|
62
|
-
subject = RDF::URI(internal_uri)
|
63
|
-
predicate = RDF::URI("#{node.namespace.href}#{node.name}")
|
64
|
-
query = RDF::Query.new({ :subject => {predicate => :object}})
|
65
|
-
relationships(predicate).dup.each { |stmt|
|
66
|
-
relationships.delete(stmt)
|
67
|
-
}
|
68
|
-
add_relationship(predicate,object, is_literal)
|
69
|
-
relationships_are_dirty=true
|
70
|
-
}
|
71
|
-
# add mimetype to DC:format values
|
72
|
-
self.datastreams['DC'].update_values({[:format] => mime})
|
73
|
-
end
|
74
|
-
end
|
75
|
-
blob.rewind
|
76
|
-
end
|
77
|
-
|
78
|
-
private
|
79
|
-
|
80
|
-
# Return the mimeType for a given file name
|
81
|
-
# @param [String] file_name The filename to use to get the mimeType
|
82
|
-
# @return [String] mimeType for filename passed in. Default: application/octet-stream if mimeType cannot be determined
|
83
|
-
def mime_type file_name
|
84
|
-
mime_types = MIME::Types.of(file_name)
|
85
|
-
mime_type = mime_types.empty? ? "application/octet-stream" : mime_types.first.content_type
|
4
|
+
include Cul::Hydra::Models::Resource
|
86
5
|
end
|
87
6
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'active-fedora'
|
2
|
+
module Cul
|
3
|
+
module Hydra
|
4
|
+
module Datastreams
|
5
|
+
class DCMetadata < ::ActiveFedora::OmDatastream
|
6
|
+
|
7
|
+
after_save :action_after_save
|
8
|
+
set_terminology do |t|
|
9
|
+
t.root(:path=>"dc", :namespace_prefix=>"oai_dc",
|
10
|
+
"xmlns:oai_dc"=>"http://www.openarchives.org/OAI/2.0/oai_dc/",
|
11
|
+
"xmlns:dc"=>"http://purl.org/dc/elements/1.1/",
|
12
|
+
:schema=>"http://www.openarchives.org/OAI/2.0/oai_dc.xsd")
|
13
|
+
t.dc_contributor(:path=>"contributor",
|
14
|
+
:namespace_prefix=>"dc",
|
15
|
+
:index_as=>[:displayable, :searchable])
|
16
|
+
t.dc_coverage(:path=>"coverage",
|
17
|
+
:namespace_prefix=>"dc",
|
18
|
+
:index_as=>[:displayable, :searchable])
|
19
|
+
t.dc_creator(:path=>"creator",
|
20
|
+
:namespace_prefix=>"dc",
|
21
|
+
:index_as=>[:displayable, :searchable])
|
22
|
+
t.dc_date(:path=>"date",
|
23
|
+
:namespace_prefix=>"dc",
|
24
|
+
:index_as=>[:displayable, :searchable])
|
25
|
+
t.dc_description(:path=>"description",
|
26
|
+
:namespace_prefix=>"dc",
|
27
|
+
:index_as=>[:displayable, :searchable])
|
28
|
+
t.dc_format(:path=>"format",
|
29
|
+
:namespace_prefix=>"dc",
|
30
|
+
:index_as=>[:displayable, :facetable])
|
31
|
+
t.dc_identifier(:path=>"identifier",
|
32
|
+
:namespace_prefix=>"dc",
|
33
|
+
:type=>:string,
|
34
|
+
:index_as=>[:symbol])
|
35
|
+
t.dc_language(:path=>"language",
|
36
|
+
:namespace_prefix=>"dc",
|
37
|
+
:index_as=>[:displayable, :searchable])
|
38
|
+
t.dc_publisher(:path=>"publisher",
|
39
|
+
:namespace_prefix=>"dc",
|
40
|
+
:index_as=>[:displayable, :searchable])
|
41
|
+
t.dc_relation(:path=>"relation",
|
42
|
+
:namespace_prefix=>"dc",
|
43
|
+
:index_as=>[:displayable, :searchable])
|
44
|
+
t.dc_rights(:path=>"rights",
|
45
|
+
:namespace_prefix=>"dc",
|
46
|
+
:index_as=>[:displayable, :searchable])
|
47
|
+
t.dc_source(:path=>"source",
|
48
|
+
:namespace_prefix=>"dc",
|
49
|
+
:index_as=>[:displayable, :searchable])
|
50
|
+
t.dc_subject(:path=>"subject",
|
51
|
+
:namespace_prefix=>"dc",
|
52
|
+
:index_as=>[:displayable, :searchable])
|
53
|
+
t.dc_title(:path=>"title",
|
54
|
+
:namespace_prefix=>"dc",
|
55
|
+
:index_as=>[:displayable, :searchable])
|
56
|
+
t.dc_type(:path=>"type",
|
57
|
+
:namespace_prefix=>"dc",
|
58
|
+
:index_as=>[:displayable, :facetable])
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.xml_template
|
62
|
+
|
63
|
+
Nokogiri::XML::Document.parse(<<-src
|
64
|
+
<oai_dc:dc
|
65
|
+
xmlns:oai_dc='http://www.openarchives.org/OAI/2.0/oai_dc/'
|
66
|
+
xmlns:dc='http://purl.org/dc/elements/1.1/'
|
67
|
+
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
|
68
|
+
xsi:schemaLocation='http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd'></oai_dc:dc>
|
69
|
+
src
|
70
|
+
)
|
71
|
+
end
|
72
|
+
# Because FCRepo 3.5+ modifies DC on saves (to ensure that PID is a dc:identifier value),
|
73
|
+
# this datastream's content must be reloaded after saves
|
74
|
+
def action_after_save
|
75
|
+
@content = nil
|
76
|
+
@ng_xml = nil
|
77
|
+
remove_instance_variable(:@ng_xml)
|
78
|
+
end
|
79
|
+
|
80
|
+
def prefix
|
81
|
+
#if ::ActiveFedora::VERSION >= '8'
|
82
|
+
# Rails.logger.warn("the prefix method of #{self.class.name} was overriden to maintain backwards compatibility")
|
83
|
+
#end
|
84
|
+
''
|
85
|
+
end
|
86
|
+
|
87
|
+
def method_missing method, *args
|
88
|
+
query = false
|
89
|
+
_mname = method.id2name
|
90
|
+
if _mname[-1,1] == '?'
|
91
|
+
query = true
|
92
|
+
_mname = _mname[0,_mname.length-1]
|
93
|
+
end
|
94
|
+
_msym = _mname.to_sym
|
95
|
+
has_term = self.class.terminology.has_term?(_msym)
|
96
|
+
return false if query and not has_term
|
97
|
+
_r = super(_mname.to_sym, *args)
|
98
|
+
if query
|
99
|
+
_r.length > 0
|
100
|
+
else
|
101
|
+
_r
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require 'active-fedora'
|
2
|
+
require 'solrizer'
|
3
|
+
require 'cul_scv_hydra/solrizer'
|
4
|
+
module Cul
|
5
|
+
module Hydra
|
6
|
+
module Datastreams
|
7
|
+
class ModsDocument < ::ActiveFedora::OmDatastream
|
8
|
+
include ::OM::XML::TerminologyBasedSolrizer
|
9
|
+
include Cul::Hydra::Solrizer::TerminologyBasedSolrizer
|
10
|
+
include Cul::Hydra::Solrizer::ModsFieldable
|
11
|
+
|
12
|
+
#map_field("lib_repo_sim", :marc_to_facet)
|
13
|
+
#map_field("lib_repo_long_ssim", :marc_to_display)
|
14
|
+
#map_field("lib_project_sim", :project_to_facet)
|
15
|
+
|
16
|
+
set_terminology do |t|
|
17
|
+
t.root(:path=>"mods",
|
18
|
+
:xmlns=>"http://www.loc.gov/mods/v3",
|
19
|
+
:schema=>"http://www.loc.gov/standards/mods/v3/mods-3-4.xsd") {
|
20
|
+
}
|
21
|
+
|
22
|
+
t.main_title_info(:path=>'titleInfo', :index_as=>[], :attributes=>{:type=>:none}){
|
23
|
+
t.non_sort(:path=>"nonSort", :index_as=>[])
|
24
|
+
t.main_title(:path=>"title", :index_as=>[])
|
25
|
+
}
|
26
|
+
|
27
|
+
t.title(:proxy=>[:mods, :main_title_info, :main_title], :type=>:string,
|
28
|
+
:index_as=>[:searchable, :sortable])
|
29
|
+
t.title_display(:proxy=>[:mods, :main_title_info], :type=>:string,
|
30
|
+
:index_as=>[:displayable])
|
31
|
+
|
32
|
+
t.search_title_info(:path=>'titleInfo', :index_as=>[]){
|
33
|
+
t.search_title(:path=>'title', :index_as=>[:textable])
|
34
|
+
}
|
35
|
+
t.part(:path=>"relatedItem", :attributes=>{:type=>"constituent"}, :index_as=>[]){
|
36
|
+
t.part_title_info(:path=>'titleInfo', :index_as=>[]){
|
37
|
+
t.lib_part(:path=>'title',:index_as=>[])
|
38
|
+
}
|
39
|
+
}
|
40
|
+
t.project(:path=>"relatedItem", :attributes=>{:type=>"host", :displayLabel=>"Project"}, :index_as=>[]){
|
41
|
+
t.project_title_info(:path=>'titleInfo', :index_as=>[]){
|
42
|
+
t.lib_project(:path=>'title',:index_as=>[])
|
43
|
+
}
|
44
|
+
}
|
45
|
+
t.collection(:path=>"relatedItem", :attributes=>{:type=>"host", :displayLabel=>"Collection"}, :index_as=>[]){
|
46
|
+
t.collection_title_info(:path=>'titleInfo', :index_as=>[]){
|
47
|
+
t.lib_collection(:path=>'title', :index_as=>[])
|
48
|
+
}
|
49
|
+
}
|
50
|
+
t.lib_project(:proxy=>[:project,:project_title_info], :index_as=>[:project_textable])
|
51
|
+
t.lib_collection(:proxy=>[:collection,:collection_title_info], :index_as=>[:displayable])
|
52
|
+
t.lib_part(:proxy=>[:part,:part_title_info], :index_as=>[:displayable, :textable])
|
53
|
+
# pattern matches
|
54
|
+
t.identifier(:path=>"identifier", :attributes=>{:type=>"local"}, :type=>:string, :index_as=>[:symbol, :textable])
|
55
|
+
t.clio(:path=>"identifier", :attributes=>{:type=>"CLIO"}, :data_type=>:symbol, :index_as=>[:symbol, :textable])
|
56
|
+
t.abstract(:index_as=>[:displayable, :textable])
|
57
|
+
t.table_of_contents(:path=>"tableOfContents", :index_as=>[:displayable, :textable])
|
58
|
+
t.subject(:index_as=>[:textable]){
|
59
|
+
t.topic(:index_as=>[:facetable, :displayable])
|
60
|
+
t.geographic(:index_as=>[:facetable])
|
61
|
+
t.hierarchical_geographic(:path=>'hierarchicalGeographic', :index_as=>[]){
|
62
|
+
t.country(:index_as=>[:symbol, :textable])
|
63
|
+
t.province(:index_as=>[:symbol, :textable])
|
64
|
+
t.region(:index_as=>[:symbol, :textable])
|
65
|
+
t.state(:index_as=>[:symbol, :textable])
|
66
|
+
t.county(:index_as=>[:symbol, :textable])
|
67
|
+
t.borough(:path=>'citySection', :attributes=>{:'citySectionType'=>"borough"}, :index_as=>[:symbol, :textable])
|
68
|
+
t.city(:index_as=>[:symbol, :textable])
|
69
|
+
t.neighborhood(:path=>'citySection', :attributes=>{:'citySectionType'=>"neighborhood"}, :index_as=>[:symbol, :textable])
|
70
|
+
t.zip_code(:path=>'citySection', :attributes=>{:'citySectionType'=>"zip code"}, :index_as=>[:symbol, :textable])
|
71
|
+
t.street(:path=>'citySection', :attributes=>{:'citySectionType'=>"street"}, :index_as=>[:symbol, :textable])
|
72
|
+
}
|
73
|
+
}
|
74
|
+
t.type_of_resource(:path=>"typeOfResource", :index_as=>[:displayable])
|
75
|
+
t.physical_description(:path=>"physicalDescription", :index_as=>[]){
|
76
|
+
t.form_marc(:path=>"form", :attributes=>{:authority=>"marcform"}, :index_as=>[:displayable])
|
77
|
+
t.form_aat(:path=>"form", :attributes=>{:authority=>"aat"}, :index_as=>[:displayable, :facetable])
|
78
|
+
t.form_local(:path=>"form", :attributes=>{:authority=>"local"}, :index_as=>[:displayable, :facetable])
|
79
|
+
t.form(:attributes=>{:authority=>:none}, :index_as=>[:displayable])
|
80
|
+
t.form_nomarc(:path=>"form[@authority !='marcform']", :index_as=>[])
|
81
|
+
t.extent(:path=>"extent", :index_as=>[:searchable, :displayable])
|
82
|
+
t.reformatting_quality(:path=>"reformattingQuality", :index_as=>[:displayable])
|
83
|
+
t.internet_media_type(:path=>"internetMediaType", :index_as=>[:displayable])
|
84
|
+
t.digital_origin(:path=>"digitalOrigin", :index_as=>[:displayable])
|
85
|
+
}
|
86
|
+
t.lib_format(:proxy=>[:physical_description, :form_nomarc], :index_as=>[:displayable, :facetable, :textable])
|
87
|
+
t.location(:path=>"location", :index_as=>[]){
|
88
|
+
t.repo_text(:path=>"physicalLocation",:attributes=>{:authority=>:none}, :index_as=>[])
|
89
|
+
t.lib_repo(:path=>"physicalLocation",
|
90
|
+
:attributes=>{:authority=>"marcorg"},
|
91
|
+
:index_as=>[:textable])
|
92
|
+
t.shelf_locator(:path=>"shelfLocator", :index_as=>[:textable, :displayable])
|
93
|
+
t.sublocation(:path=>"sublocation", :index_as=>[:textable, :displayable])
|
94
|
+
t.url
|
95
|
+
}
|
96
|
+
t.top_level_location_url(:proxy=>[:mods, :location, :url])
|
97
|
+
t.lib_repo(:proxy=>[:location, :lib_repo], :type=>:text,
|
98
|
+
:index_as=>[:marc_code_textable])
|
99
|
+
t.name_usage_primary(
|
100
|
+
:path=>'name',:attributes=>{:usage=>'primary'},
|
101
|
+
:index_as=>[]){
|
102
|
+
t.name_part(:path=>'namePart', :index_as=>[])
|
103
|
+
}
|
104
|
+
t.primary_name(proxy: [:name_usage_primary,:name_part], index_as: :facetable)
|
105
|
+
#t.name_corporate(
|
106
|
+
# :path=>'name',:attributes=>{:type=>'corporate'},
|
107
|
+
# :index_as=>[:facetable, :displayable],
|
108
|
+
# :variant_of=>{:field_base=>:lib_name}){
|
109
|
+
# t.name_part(
|
110
|
+
# :path=>'namePart',
|
111
|
+
# :index_as=>[])
|
112
|
+
#}
|
113
|
+
t.note(:path=>"note", :index_as=>[:textable])
|
114
|
+
t.access_condition(:path=>"accessCondition", :attributes=>{:type=>"useAndReproduction"}, :index_as => [:searchable, :symbol])
|
115
|
+
t.record_info(:path=>"recordInfo", :index_as=>[]) {
|
116
|
+
t.record_creation_date(:path=>"recordCreationDate",:attributes=>{:encoding=>"w3cdtf"}, :index_as=>[])
|
117
|
+
t.record_content_source(:path=>"recordContentSource",:attributes=>{:authority=>"marcorg"}, :index_as=>[])
|
118
|
+
t.language_of_cataloging(:path=>"languageOfCataloging", :index_as=>[]){
|
119
|
+
t.language_term(:path=>"languageTerm", :index_as=>[], :attributes=>{:type=>:none})
|
120
|
+
t.language_code(:path=>"languageTerm",:attributes=>{:type=>'code',:authority=>"iso639-2b"}, :index_as=>[])
|
121
|
+
}
|
122
|
+
t.record_origin(:path=>"recordOrigin", :index_as=>[])
|
123
|
+
}
|
124
|
+
t.language_term(:proxy=>[:record_info, :language_of_cataloging, :language_term])
|
125
|
+
t.language_code(:proxy=>[:record_info, :language_of_cataloging, :language_code])
|
126
|
+
|
127
|
+
t.language(:index_as=>[]){
|
128
|
+
t.language_term_text(:path=>"languageTerm", :attributes=>{:authority=>'iso639-2b',:type=>'text'}, :index_as=>[:symbol, :textable])
|
129
|
+
t.language_term_code(:path=>"languageTerm", :attributes=>{:authority=>'iso639-2b',:type=>'code'}, :index_as=>[:symbol, :textable])
|
130
|
+
}
|
131
|
+
|
132
|
+
t.origin_info(:path=>"originInfo", :index_as=>[]){
|
133
|
+
t.date_issued(:path=>"dateIssued", :attributes=>{:encoding=>'w3cdtf',:keyDate=>'yes'}, :index_as=>[:displayable, :textable])
|
134
|
+
t.date_issued_start(:path=>"dateIssued", :attributes=>{:encoding=>'w3cdtf',:keyDate=>'yes',:point=>'start'}, :index_as=>[:displayable, :textable])
|
135
|
+
t.date_issued_end(:path=>"dateIssued", :attributes=>{:encoding=>'w3cdtf',:point=>'end'}, :index_as=>[:displayable, :textable])
|
136
|
+
t.date_issued_textual(:path=>"dateIssued", :attributes=>{:encoding=>:none, :keyDate=>:none}, :index_as=>[:textable])
|
137
|
+
|
138
|
+
t.date_created(:path=>"dateCreated", :attributes=>{:encoding=>'w3cdtf',:keyDate=>'yes'}, :index_as=>[:displayable, :textable])
|
139
|
+
t.date_created_start(:path=>"dateCreated", :attributes=>{:encoding=>'w3cdtf',:keyDate=>'yes',:point=>'start'}, :index_as=>[:displayable, :textable])
|
140
|
+
t.date_created_end(:path=>"dateCreated", :attributes=>{:encoding=>'w3cdtf',:point=>'end'}, :index_as=>[:displayable, :textable])
|
141
|
+
t.date_created_textual(:path=>"dateCreated", :attributes=>{:encoding=>:none, :keyDate=>:none}, :index_as=>[:textable])
|
142
|
+
|
143
|
+
t.date_other(:path=>"dateOther", :attributes=>{:encoding=>'w3cdtf',:keyDate=>'yes'}, :index_as=>[:displayable, :textable])
|
144
|
+
t.date_other_start(:path=>"dateOther", :attributes=>{:encoding=>'w3cdtf',:keyDate=>'yes',:point=>'start'}, :index_as=>[:displayable, :textable])
|
145
|
+
t.date_other_end(:path=>"dateOther", :attributes=>{:encoding=>'w3cdtf',:point=>'end'}, :index_as=>[:displayable, :textable])
|
146
|
+
t.date_other_textual(:path=>"dateOther", :attributes=>{:encoding=>:none, :keyDate=>:none}, :index_as=>[:textable])
|
147
|
+
|
148
|
+
t.publisher(:index_as=>[:displayable])
|
149
|
+
t.edition(:index_as=>[:displayable])
|
150
|
+
}
|
151
|
+
t.lib_publisher(:proxy=>[:mods, :origin_info, :publisher], :index_as=>[:displayable])
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.xml_template
|
155
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
156
|
+
xml.mods(:version=>"3.4",
|
157
|
+
"xmlns"=>"http://www.loc.gov/mods/v3",
|
158
|
+
"xmlns:xlink"=>"http://www.w3.org/1999/xlink",
|
159
|
+
"xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance"){
|
160
|
+
}
|
161
|
+
end
|
162
|
+
builder.doc.encoding = 'UTF-8'
|
163
|
+
# for some reason, this is the only way to get an equivalent nokogiri root node; the attribute can't be in the original builder call
|
164
|
+
builder.doc.root["xsi:schemaLocation"] = 'http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-4.xsd'
|
165
|
+
return builder.doc
|
166
|
+
end
|
167
|
+
|
168
|
+
def prefix
|
169
|
+
#if ::ActiveFedora::VERSION >= '8'
|
170
|
+
# Rails.logger.warn("the prefix method of #{self.class.name} was overriden to maintain backwards compatibility")
|
171
|
+
#end
|
172
|
+
''
|
173
|
+
end
|
174
|
+
|
175
|
+
def method_missing method, *args
|
176
|
+
query = false
|
177
|
+
_mname = method.id2name
|
178
|
+
if _mname[-1,1] == '?'
|
179
|
+
query = true
|
180
|
+
_mname = _mname[0,_mname.length-1]
|
181
|
+
end
|
182
|
+
_msym = _mname.to_sym
|
183
|
+
has_term = self.class.terminology.has_term?(_msym)
|
184
|
+
return false if query and not has_term
|
185
|
+
_r = super(_mname.to_sym, *args)
|
186
|
+
if query
|
187
|
+
_r.length > 0
|
188
|
+
else
|
189
|
+
_r
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module Cul
|
2
|
+
module Hydra
|
3
|
+
module Datastreams
|
4
|
+
class StructMetadata < ::ActiveFedora::Datastream
|
5
|
+
include ::ActiveFedora::Datastreams::NokogiriDatastreams
|
6
|
+
|
7
|
+
def self.default_attributes
|
8
|
+
super.merge(:controlGroup => 'M', :mimeType => 'text/xml')
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.xml_template
|
12
|
+
Nokogiri::XML::Document.parse("<mets:structMap xmlns:mets=\"http://www.loc.gov/METS/\">")
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.div_template(prefix="mets")
|
16
|
+
prefix.nil? ? '<div/>' : "<#{prefix}:div/>"
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(digital_object=nil, dsid=nil, options={})
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
# Indicates that this datastream has metadata content.
|
24
|
+
# @return true
|
25
|
+
def metadata?
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
def autocreate?
|
30
|
+
changed_attributes.has_key? :profile
|
31
|
+
end
|
32
|
+
|
33
|
+
def label=(value)
|
34
|
+
struct_map["LABEL"] = value
|
35
|
+
ng_xml_will_change!
|
36
|
+
end
|
37
|
+
|
38
|
+
def label
|
39
|
+
struct_map["LABEL"]
|
40
|
+
end
|
41
|
+
|
42
|
+
def type=(value)
|
43
|
+
struct_map["TYPE"] = value
|
44
|
+
ng_xml_will_change!
|
45
|
+
end
|
46
|
+
|
47
|
+
def type
|
48
|
+
struct_map["TYPE"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def prefix
|
52
|
+
prefix = nil
|
53
|
+
ng_xml.namespaces.each do |p, href|
|
54
|
+
prefix = p.sub(/xmlns:/,'') if href == "http://www.loc.gov/METS/"
|
55
|
+
end
|
56
|
+
prefix
|
57
|
+
end
|
58
|
+
|
59
|
+
def struct_map
|
60
|
+
prefix = self.prefix
|
61
|
+
path = prefix.nil? ? 'xmlns:structMap' : "#{prefix}:structMap"
|
62
|
+
ng_xml.xpath(path, ng_xml.namespaces).first
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_div_node(parent=nil, atts={})
|
66
|
+
if parent.nil?
|
67
|
+
parent = struct_map
|
68
|
+
end
|
69
|
+
divNode = parent.add_child(StructMetadata.div_template(parent.namespace.prefix)).first
|
70
|
+
[:label, :order, :contentids]. each do |key|
|
71
|
+
divNode[key.to_s.upcase] = atts[key].to_s if atts.has_key? key
|
72
|
+
end
|
73
|
+
ng_xml_will_change! if (divNode.document == ng_xml.document)
|
74
|
+
divNode
|
75
|
+
end
|
76
|
+
|
77
|
+
def divs_with_attribute(descend=true, name=nil, value=nil)
|
78
|
+
prefix = self.prefix || 'xmlns'
|
79
|
+
xpath = descend ? "//#{prefix}:div" : "/#{prefix}:structMap/#{prefix}:div"
|
80
|
+
if !name.nil?
|
81
|
+
xpath << "[@#{name}"
|
82
|
+
if !value.nil?
|
83
|
+
xpath << "='#{value}'"
|
84
|
+
end
|
85
|
+
xpath << ']'
|
86
|
+
end
|
87
|
+
ng_xml.xpath(xpath, ng_xml.namespaces)
|
88
|
+
end
|
89
|
+
|
90
|
+
def first_ordered_content_div
|
91
|
+
divs_with_contentids_attr = self.divs_with_attribute(true, 'CONTENTIDS')
|
92
|
+
sorted_divs_with_contentids_attr = divs_with_contentids_attr.sort_by{ |node|
|
93
|
+
node.attr("ORDER").to_i
|
94
|
+
}
|
95
|
+
return sorted_divs_with_contentids_attr.first
|
96
|
+
end
|
97
|
+
|
98
|
+
# a convenience method for setting attributes and creating divs (if necessary) for R/V structure
|
99
|
+
# returns the mets:structMap node
|
100
|
+
def recto_verso!
|
101
|
+
self.type= 'physical' unless self.type == 'physical'
|
102
|
+
self.label= 'Sides' unless self.label == 'Sides'
|
103
|
+
create_div_node struct_map, {:order=>'1'} unless divs_with_attribute(false,'ORDER','1').first
|
104
|
+
create_div_node struct_map, {:order=>'2'} unless divs_with_attribute(false,'ORDER','2').first
|
105
|
+
if (div = divs_with_attribute(false,'ORDER','1').first)
|
106
|
+
div['LABEL'] = 'Recto' unless div['LABEL'] == 'Recto'
|
107
|
+
end
|
108
|
+
if (div = divs_with_attribute(false,'ORDER','2').first)
|
109
|
+
div['LABEL'] = 'Verso' unless div['LABEL'] == 'Verso'
|
110
|
+
end
|
111
|
+
struct_map
|
112
|
+
end
|
113
|
+
|
114
|
+
def recto
|
115
|
+
divs_with_attribute(false, 'LABEL', 'Recto').first
|
116
|
+
end
|
117
|
+
|
118
|
+
def verso
|
119
|
+
divs_with_attribute(false, 'LABEL', 'Verso').first
|
120
|
+
end
|
121
|
+
|
122
|
+
def to_solr(doc={})
|
123
|
+
doc[:structured_bsi] = (has_content? ? 'true' : 'false')
|
124
|
+
doc
|
125
|
+
end
|
126
|
+
|
127
|
+
def proxies
|
128
|
+
divs = divs_with_attribute(true)
|
129
|
+
graph_context_uri = RDF::URI("info:fedora/#{self.pid}")
|
130
|
+
file_system = self.type.eql?(RDF::NFO[:"#Filesystem"].to_s)
|
131
|
+
divs.collect do |div|
|
132
|
+
proxy_uri_chain = proxy_uri_chain_for(div)
|
133
|
+
proxy_resource_uri = proxy_uri_chain.pop
|
134
|
+
if div['CONTENTIDS']
|
135
|
+
subclass = file_system ?
|
136
|
+
NFO::FileDataObject : SC::Canvas
|
137
|
+
proxy = subclass.new(proxy_resource_uri, graph_context_uri)
|
138
|
+
proxy.proxyFor = RDF::URI(div['CONTENTIDS'])
|
139
|
+
else
|
140
|
+
subclass = file_system ?
|
141
|
+
NFO::Folder : SC::Sequence
|
142
|
+
proxy = subclass.new(proxy_resource_uri, graph_context_uri)
|
143
|
+
end
|
144
|
+
if div.parent and div.parent.name == 'div'
|
145
|
+
proxy.belongsToContainer = proxy_uri_for(div.parent)
|
146
|
+
end
|
147
|
+
proxy.isPartOf = proxy_uri_chain unless proxy_uri_chain.empty?
|
148
|
+
proxy.index = div['ORDER']
|
149
|
+
proxy.label = div['LABEL']
|
150
|
+
proxy
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
def ancestors(node)
|
156
|
+
current = node
|
157
|
+
labels = []
|
158
|
+
while (current.name == 'div')
|
159
|
+
labels.unshift URI.escape(current['LABEL'])
|
160
|
+
current = current.parent
|
161
|
+
end
|
162
|
+
labels
|
163
|
+
end
|
164
|
+
def proxy_uri_chain_for(node)
|
165
|
+
uris = []
|
166
|
+
ancestors(node).inject(RDF::URI("info:fedora/#{self.pid}/#{self.dsid}")) {|m,a| (uris << m/a).last}
|
167
|
+
uris
|
168
|
+
end
|
169
|
+
def proxy_uri_for(node)
|
170
|
+
# uri = segments.inject(base_uri) {|m,a| m/a}
|
171
|
+
ancestors(node).inject(RDF::URI("info:fedora/#{self.pid}/#{self.dsid}")) {|m,a| m/a}
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|