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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/cul/hydra/controller.rb +22 -0
  3. data/app/controllers/concerns/cul/hydra/resolver.rb +69 -0
  4. data/app/controllers/concerns/cul/hydra/thumbnails.rb +62 -0
  5. data/app/controllers/concerns/cul/scv/hydra/controller.rb +3 -19
  6. data/app/controllers/concerns/cul/scv/hydra/resolver.rb +2 -65
  7. data/app/controllers/concerns/cul/scv/hydra/thumbnails.rb +3 -59
  8. data/app/models/concept.rb +1 -1
  9. data/app/models/concerns/cul/hydra/models.rb +24 -0
  10. data/app/models/concerns/cul/hydra/models/aggregator.rb +121 -0
  11. data/app/models/concerns/cul/hydra/models/common.rb +220 -0
  12. data/app/models/concerns/cul/hydra/models/image_resource.rb +78 -0
  13. data/app/models/concerns/cul/hydra/models/linkable_resources.rb +108 -0
  14. data/app/models/concerns/cul/hydra/models/resource.rb +87 -0
  15. data/app/models/concerns/cul/scv/hydra/models.rb +1 -13
  16. data/app/models/concerns/cul/scv/hydra/models/aggregator.rb +1 -116
  17. data/app/models/concerns/cul/scv/hydra/models/common.rb +1 -213
  18. data/app/models/concerns/cul/scv/hydra/models/image_resource.rb +3 -75
  19. data/app/models/concerns/cul/scv/hydra/models/linkable_resources.rb +3 -105
  20. data/app/models/concerns/cul/scv/hydra/models/resource.rb +2 -83
  21. data/app/models/cul/hydra/datastreams/dc_metadata.rb +107 -0
  22. data/app/models/cul/hydra/datastreams/mods_document.rb +195 -0
  23. data/app/models/cul/hydra/datastreams/struct_metadata.rb +176 -0
  24. data/app/models/cul/scv/hydra/datastreams/dc_metadata.rb +5 -104
  25. data/app/models/cul/scv/hydra/datastreams/mods_document.rb +5 -178
  26. data/app/models/cul/scv/hydra/datastreams/struct_metadata.rb +5 -174
  27. data/app/models/dc_document.rb +1 -1
  28. data/app/models/generic_aggregator.rb +5 -5
  29. data/app/models/generic_object.rb +2 -2
  30. data/app/models/generic_resource.rb +4 -4
  31. data/app/models/mets_structured_aggregator.rb +2 -2
  32. data/app/models/resource.rb +3 -3
  33. data/app/models/resource_aggregator.rb +3 -3
  34. data/fixtures/spec/CUL_MODS/mods-subjects.xml +24 -0
  35. data/lib/cul_hydra.rb +18 -0
  36. data/lib/cul_hydra/access_controls_enforcement.rb +53 -0
  37. data/lib/cul_hydra/controllers.rb +13 -0
  38. data/lib/cul_hydra/controllers/aggregates.rb +93 -0
  39. data/lib/cul_hydra/controllers/aggregator_controller_helper.rb +27 -0
  40. data/lib/cul_hydra/controllers/catalog.rb +12 -0
  41. data/lib/cul_hydra/controllers/content_aggregators.rb +81 -0
  42. data/lib/cul_hydra/controllers/datastreams.rb +145 -0
  43. data/lib/cul_hydra/controllers/helpers.rb +10 -0
  44. data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/active_fedora_helper_behavior.rb +1 -1
  45. data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/application_helper_behavior.rb +1 -1
  46. data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/dc_metadata_helper_behavior.rb +1 -1
  47. data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/hydra_assets_helper_behavior.rb +1 -1
  48. data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/hydra_autocomplete_helper_behavior.rb +1 -1
  49. data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/hydra_uploader_helper_behavior.rb +1 -1
  50. data/lib/{cul_scv_hydra → cul_hydra}/controllers/helpers/resources_helper_behavior.rb +1 -1
  51. data/lib/cul_hydra/controllers/resources.rb +161 -0
  52. data/lib/cul_hydra/controllers/static_image_aggregators.rb +105 -0
  53. data/lib/cul_hydra/controllers/suggestions.rb +126 -0
  54. data/lib/cul_hydra/controllers/terms.rb +205 -0
  55. data/lib/cul_hydra/engine.rb +31 -0
  56. data/lib/cul_hydra/fedora.rb +41 -0
  57. data/lib/cul_hydra/fedora/dummy_object.rb +37 -0
  58. data/lib/cul_hydra/fedora/rubydora_patch.rb +16 -0
  59. data/lib/cul_hydra/fedora/url_helper_behavior.rb +32 -0
  60. data/lib/cul_hydra/indexer.rb +84 -0
  61. data/lib/cul_hydra/om.rb +7 -0
  62. data/lib/cul_hydra/om/standard_mods.rb +115 -0
  63. data/lib/cul_hydra/risearch_members.rb +92 -0
  64. data/lib/cul_hydra/solrizer.rb +10 -0
  65. data/lib/cul_hydra/solrizer/extractor.rb +27 -0
  66. data/lib/cul_hydra/solrizer/mods_fieldable.rb +435 -0
  67. data/lib/cul_hydra/solrizer/terminology_based_solrizer.rb +35 -0
  68. data/lib/cul_hydra/solrizer/value_mapper.rb +46 -0
  69. data/lib/{cul_scv_hydra/solrizer/field_mapper.rb → cul_hydra/solrizer_patch.rb} +0 -0
  70. data/lib/cul_hydra/version.rb +8 -0
  71. data/lib/cul_hydra/version.rb~ +8 -0
  72. data/lib/cul_scv_fedora/dummy_object.rb +1 -30
  73. data/lib/cul_scv_fedora/rubydora_patch.rb +3 -7
  74. data/lib/cul_scv_fedora/url_helper_behavior.rb +3 -23
  75. data/lib/cul_scv_hydra.rb +5 -32
  76. data/lib/cul_scv_hydra/access_controls_enforcement.rb +3 -50
  77. data/lib/cul_scv_hydra/controllers.rb +10 -10
  78. data/lib/cul_scv_hydra/controllers/aggregates.rb +1 -86
  79. data/lib/cul_scv_hydra/controllers/aggregator_controller_helper.rb +4 -23
  80. data/lib/cul_scv_hydra/controllers/catalog.rb +5 -9
  81. data/lib/cul_scv_hydra/controllers/content_aggregators.rb +4 -77
  82. data/lib/cul_scv_hydra/controllers/datastreams.rb +3 -140
  83. data/lib/cul_scv_hydra/controllers/helpers.rb +44 -8
  84. data/lib/cul_scv_hydra/controllers/resources.rb +4 -157
  85. data/lib/cul_scv_hydra/controllers/static_image_aggregators.rb +4 -100
  86. data/lib/cul_scv_hydra/controllers/suggestions.rb +4 -122
  87. data/lib/cul_scv_hydra/controllers/terms.rb +4 -201
  88. data/lib/cul_scv_hydra/engine.rb +1 -1
  89. data/lib/cul_scv_hydra/indexer.rb +3 -82
  90. data/lib/cul_scv_hydra/om.rb +2 -2
  91. data/lib/cul_scv_hydra/om/standard_mods.rb +1 -108
  92. data/lib/cul_scv_hydra/risearch_members.rb +4 -89
  93. data/lib/cul_scv_hydra/solrizer.rb +5 -6
  94. data/lib/cul_scv_hydra/solrizer/extractor.rb +1 -25
  95. data/lib/cul_scv_hydra/solrizer/scv_mods_fieldable.rb +4 -429
  96. data/lib/cul_scv_hydra/solrizer/terminology_based_solrizer.rb +4 -32
  97. data/lib/cul_scv_hydra/solrizer/value_mapper.rb +1 -44
  98. data/lib/cul_scv_hydra/version.rb +5 -5
  99. data/lib/tasks/index.rake +2 -2
  100. data/lib/tasks/transform.rake +23 -0
  101. metadata +55 -12
@@ -1,87 +1,6 @@
1
1
  module Cul::Scv::Hydra::Models::Resource
2
- extend ActiveSupport::Concern
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
- if self.is_a? ::ActiveFedora::SemanticNode
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