44
55class DspaceMetadata
66 def initialize ( thesis )
7- @dc = { } . compare_by_identity
8- @dc [ 'dc.publisher' ] = 'Massachusetts Institute of Technology'
9- @dc [ 'dc.type' ] = 'Thesis'
7+ @metadata_entries = [ ]
8+ add_metadata ( 'dc.publisher' , 'Massachusetts Institute of Technology' )
9+ add_metadata ( 'dc.type' , 'Thesis' )
1010 title ( thesis )
1111 contributors ( thesis . users , thesis . advisors )
1212 departments ( thesis . departments )
@@ -17,22 +17,26 @@ def initialize(thesis)
1717
1818 # Generates JSON metadata file required for submission to DSS.
1919 def serialize_dss_metadata
20- { 'metadata' => @dc . map { |k , v | { 'key' => k , 'value' => v } } } . to_json
20+ if Flipflop . enabled? ( :dspace_v8_metadata )
21+ serialize_dspace8 . to_json
22+ else
23+ { 'metadata' => serialize_dspace6 } . to_json
24+ end
2125 end
2226
2327 def title ( thesis )
24- @dc [ 'dc.title' ] = thesis . title
25- @dc [ 'dc.description.abstract' ] = thesis . abstract if thesis . abstract
26- @dc [ 'dc.date.issued' ] = thesis . grad_date . strftime ( '%Y-%m' )
28+ add_metadata ( 'dc.title' , thesis . title )
29+ add_metadata ( 'dc.description.abstract' , thesis . abstract ) if thesis . abstract
30+ add_metadata ( 'dc.date.issued' , thesis . grad_date . strftime ( '%Y-%m' ) )
2731 end
2832
2933 def contributors ( thesis_users , thesis_advisors )
3034 thesis_users . each do |a |
31- @dc [ 'dc.contributor.author' ] = a . preferred_name
35+ add_metadata ( 'dc.contributor.author' , a . preferred_name )
3236 end
3337 parse_orcids ( thesis_users )
3438 thesis_advisors . each do |adv |
35- @dc [ 'dc.contributor.advisor' ] = adv . name
39+ add_metadata ( 'dc.contributor.advisor' , adv . name )
3640 end
3741 end
3842
@@ -44,49 +48,98 @@ def parse_orcids(thesis_users)
4448 return unless orcids . present?
4549
4650 orcids . each do |orcid |
47- @dc [ 'dc.identifier.orcid' ] = orcid
51+ add_metadata ( 'dc.identifier.orcid' , orcid )
4852 end
4953 end
5054
5155 def departments ( thesis_depts )
5256 thesis_depts . each do |d |
53- @dc [ 'dc.contributor.department' ] = d . name_dspace
57+ add_metadata ( 'dc.contributor.department' , d . name_dspace )
5458 end
5559 end
5660
5761 def degrees ( thesis_degrees )
5862 thesis_degrees . each do |degree |
59- @dc [ 'dc.description.degree' ] = degree . abbreviation
60- @dc [ 'thesis.degree.name' ] = degree . name_dspace
63+ add_metadata ( 'dc.description.degree' , degree . abbreviation )
64+ add_metadata ( 'thesis.degree.name' , degree . name_dspace )
6165 end
6266
6367 # Degree types should not be repeated if they are the same type.
6468 types = thesis_degrees . map { |degree | degree . degree_type . name } . uniq
6569 types . each do |t |
66- @dc [ 'mit.thesis.degree' ] = t
70+ add_metadata ( 'mit.thesis.degree' , t )
6771 end
6872 end
6973
7074 def copyright ( thesis_copyright , thesis_license )
7175 if thesis_copyright . holder != 'Author' # copyright holder is anyone but author
72- @dc [ 'dc.rights' ] = thesis_copyright . statement_dspace
73- @dc [ 'dc.rights' ] = "Copyright #{ thesis_copyright . holder } "
74- @dc [ 'dc.rights.uri' ] = thesis_copyright . url if thesis_copyright . url
76+ add_metadata ( 'dc.rights' , thesis_copyright . statement_dspace )
77+ add_metadata ( 'dc.rights' , "Copyright #{ thesis_copyright . holder } " )
78+ add_metadata ( 'dc.rights.uri' , thesis_copyright . url ) if thesis_copyright . url
7579 elsif thesis_license # author holds copyright and provides a license
76- @dc [ 'dc.rights' ] = thesis_license . map_license_type
77- @dc [ 'dc.rights' ] = 'Copyright retained by author(s)'
80+ add_metadata ( 'dc.rights' , thesis_license . map_license_type )
81+ add_metadata ( 'dc.rights' , 'Copyright retained by author(s)' )
7882
7983 # Theoretically both license and copyright URLs are required for publication, but there are no constraints on
8084 # the models, and we want to future-proof this.
81- @dc [ 'dc.rights.uri' ] = thesis_license . evaluate_license_url
85+ add_metadata ( 'dc.rights.uri' , thesis_license . evaluate_license_url )
8286 else # author holds copyright and no license provided
83- @dc [ 'dc.rights' ] = thesis_copyright . statement_dspace
84- @dc [ 'dc.rights' ] = 'Copyright retained by author(s)'
85- @dc [ 'dc.rights.uri' ] = thesis_copyright . url if thesis_copyright . url
87+ add_metadata ( 'dc.rights' , thesis_copyright . statement_dspace )
88+ add_metadata ( 'dc.rights' , 'Copyright retained by author(s)' )
89+ add_metadata ( 'dc.rights.uri' , thesis_copyright . url ) if thesis_copyright . url
8690 end
8791 end
8892
8993 def date_transferred ( files )
90- @dc [ 'dc.date.submitted' ] = files . select { |file | file . purpose == 'thesis_pdf' } . first . blob . created_at
94+ add_metadata ( 'dc.date.submitted' , files . select { |file | file . purpose == 'thesis_pdf' } . first . blob . created_at )
95+ end
96+
97+ private
98+
99+ def add_metadata ( key , value )
100+ return if value . nil?
101+
102+ @metadata_entries << { 'key' => key , 'value' => value }
103+ end
104+
105+ # DSpace 6 expects metadata to be sent as a flat array of key/value pairs under
106+ # a top-level "metadata" key (added by serialize_dss_metadata).
107+ #
108+ # Example returned by this method:
109+ # [
110+ # { 'key' => 'dc.title', 'value' => 'My Thesis' },
111+ # { 'key' => 'dc.contributor.author', 'value' => 'Student, Second' },
112+ # { 'key' => 'dc.contributor.author', 'value' => 'Student, Third' }
113+ # ]
114+ def serialize_dspace6
115+ @metadata_entries
116+ end
117+
118+ # DSpace 8 expects top-level metadata keys, where each key maps to an array of
119+ # value objects. We convert from our internal flat entries so both DSpace 6 and
120+ # DSpace 8 serializers can share the same source data.
121+ #
122+ # Example returned by this method:
123+ # {
124+ # 'dc.title' => [{ 'value' => 'My Thesis' }],
125+ # 'dc.contributor.author' => [
126+ # { 'value' => 'Student, Second' },
127+ # { 'value' => 'Student, Third' }
128+ # ]
129+ # }
130+ #
131+ # Note: language is intentionally omitted for now (out of scope).
132+ def serialize_dspace8
133+ result = { }
134+
135+ @metadata_entries . each do |entry |
136+ key = entry [ 'key' ]
137+ value = entry [ 'value' ]
138+
139+ result [ key ] ||= [ ]
140+ result [ key ] << { 'value' => value }
141+ end
142+
143+ result
91144 end
92145end
0 commit comments