ddr-models 2.0.1 → 2.1.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +23 -17
  3. data/app/models/collection.rb +1 -35
  4. data/ddr-models.gemspec +2 -1
  5. data/lib/ddr/actions.rb +1 -0
  6. data/lib/ddr/actions/virus_check.rb +28 -0
  7. data/lib/ddr/auth.rb +4 -0
  8. data/lib/ddr/auth/ability_definitions/datastream_ability_definitions.rb +7 -5
  9. data/lib/ddr/auth/grouper_gateway.rb +9 -1
  10. data/lib/ddr/auth/permissions.rb +2 -1
  11. data/lib/ddr/auth/role_based_access_controls_enforcement.rb +5 -5
  12. data/lib/ddr/auth/roles/role_types.rb +2 -1
  13. data/lib/ddr/datastreams.rb +2 -2
  14. data/lib/ddr/datastreams/administrative_metadata_datastream.rb +27 -14
  15. data/lib/ddr/datastreams/datastream_behavior.rb +13 -0
  16. data/lib/ddr/datastreams/fits_datastream.rb +88 -0
  17. data/lib/ddr/derivatives/png_generator.rb +2 -0
  18. data/lib/ddr/derivatives/ptif_generator.rb +2 -0
  19. data/lib/ddr/events/fixity_check_event.rb +2 -2
  20. data/lib/ddr/events/virus_check_event.rb +2 -14
  21. data/lib/ddr/index.rb +29 -0
  22. data/lib/ddr/index/abstract_query_result.rb +23 -0
  23. data/lib/ddr/index/connection.rb +17 -0
  24. data/lib/ddr/index/csv_query_result.rb +61 -0
  25. data/lib/ddr/index/document_builder.rb +9 -0
  26. data/lib/ddr/index/field.rb +23 -0
  27. data/lib/ddr/index/fields.rb +83 -0
  28. data/lib/ddr/index/filter.rb +48 -0
  29. data/lib/ddr/index/filters.rb +19 -0
  30. data/lib/ddr/index/legacy_license_fields.rb +14 -0
  31. data/lib/ddr/index/query.rb +35 -0
  32. data/lib/ddr/index/query_builder.rb +74 -0
  33. data/lib/ddr/index/query_clause.rb +52 -0
  34. data/lib/ddr/index/query_result.rb +70 -0
  35. data/lib/ddr/index/query_value.rb +16 -0
  36. data/lib/ddr/index/response.rb +13 -0
  37. data/lib/ddr/index/unique_key_field.rb +12 -0
  38. data/lib/ddr/index_fields.rb +7 -53
  39. data/lib/ddr/jobs.rb +1 -1
  40. data/lib/ddr/jobs/fits_file_characterization.rb +51 -0
  41. data/lib/ddr/managers.rb +1 -0
  42. data/lib/ddr/managers/technical_metadata_manager.rb +104 -0
  43. data/lib/ddr/models.rb +39 -23
  44. data/lib/ddr/models/base.rb +0 -2
  45. data/lib/ddr/models/describable.rb +1 -1
  46. data/lib/ddr/models/effective_license.rb +9 -0
  47. data/lib/ddr/models/engine.rb +13 -0
  48. data/lib/ddr/models/file_management.rb +157 -160
  49. data/lib/ddr/models/governable.rb +0 -4
  50. data/lib/ddr/models/has_admin_metadata.rb +80 -72
  51. data/lib/ddr/models/has_children.rb +1 -1
  52. data/lib/ddr/models/has_content.rb +18 -0
  53. data/lib/ddr/models/has_struct_metadata.rb +5 -1
  54. data/lib/ddr/models/indexing.rb +32 -20
  55. data/lib/ddr/models/inherited_license.rb +13 -0
  56. data/lib/ddr/models/license.rb +38 -0
  57. data/lib/ddr/models/solr_document.rb +195 -211
  58. data/lib/ddr/models/version.rb +1 -1
  59. data/lib/ddr/models/year_facet.rb +154 -0
  60. data/lib/ddr/utils.rb +13 -1
  61. data/lib/ddr/vocab/roles.rb +0 -10
  62. data/spec/controllers/including_role_based_access_controls_enforcement_spec.rb +4 -4
  63. data/spec/datastreams/fits_datastream_spec.rb +84 -0
  64. data/spec/fixtures/fits/document.xml +65 -0
  65. data/spec/fixtures/fits/image.xml +59 -0
  66. data/spec/index/filter_spec.rb +47 -0
  67. data/spec/index/filters_spec.rb +17 -0
  68. data/spec/index/query_spec.rb +19 -0
  69. data/spec/jobs/fits_file_characterization_spec.rb +52 -0
  70. data/spec/managers/technical_metadata_manager_spec.rb +140 -0
  71. data/spec/models/active_fedora_datastream_spec.rb +44 -0
  72. data/spec/models/collection_spec.rb +7 -12
  73. data/spec/models/component_spec.rb +3 -6
  74. data/spec/models/effective_license_spec.rb +49 -0
  75. data/spec/models/has_admin_metadata_spec.rb +143 -194
  76. data/spec/models/has_struct_metadata_spec.rb +2 -2
  77. data/spec/models/indexing_spec.rb +40 -0
  78. data/spec/models/solr_document_spec.rb +96 -37
  79. data/spec/models/year_facet_spec.rb +65 -0
  80. data/spec/spec_helper.rb +1 -7
  81. data/spec/support/shared_examples_for_ddr_models.rb +0 -2
  82. data/spec/support/shared_examples_for_has_content.rb +37 -3
  83. metadata +79 -32
  84. data/lib/ddr/datastreams/properties_datastream.rb +0 -25
  85. data/lib/ddr/jobs/migrate_legacy_authorization.rb +0 -23
  86. data/lib/ddr/models/has_properties.rb +0 -15
  87. data/lib/ddr/models/licensable.rb +0 -28
  88. data/spec/auth/legacy_authorization_spec.rb +0 -94
  89. data/spec/auth/legacy_roles_spec.rb +0 -32
  90. data/spec/jobs/migrate_legacy_authorization_spec.rb +0 -43
  91. data/spec/support/shared_examples_for_has_properties.rb +0 -5
  92. data/spec/support/shared_examples_for_licensable.rb +0 -15
@@ -3,7 +3,7 @@ module Ddr
3
3
  module HasChildren
4
4
 
5
5
  def first_child
6
- ActiveFedora::Base.where(association_query(:children)).order("#{Ddr::IndexFields::LOCAL_ID} ASC").first
6
+ ActiveFedora::Base.where(association_query(:children)).order("#{Ddr::Index::Fields::LOCAL_ID} ASC").first
7
7
  end
8
8
 
9
9
  end
@@ -29,12 +29,21 @@ module Ddr
29
29
  label: "Text extracted from the content file",
30
30
  control_group: "M"
31
31
 
32
+ has_metadata \
33
+ name: Ddr::Datastreams::FITS,
34
+ type: Ddr::Datastreams::FitsDatastream,
35
+ versionable: true,
36
+ label: "FITS Output for content file",
37
+ control_group: "M"
38
+
32
39
  has_attributes :original_filename, datastream: "adminMetadata", multiple: false
33
40
 
34
41
  include FileManagement
35
42
 
36
43
  around_save :update_derivatives, if: :content_changed?
37
44
 
45
+ around_save :characterize_file, if: [ :content_changed?, "Ddr::Models.characterize_files?" ]
46
+
38
47
  after_add_file do
39
48
  if file_to_add.original_name && file_to_add.dsid == "content"
40
49
  self.original_filename = file_to_add.original_name
@@ -59,6 +68,10 @@ module Ddr
59
68
  @derivatives ||= Ddr::Managers::DerivativesManager.new(self)
60
69
  end
61
70
 
71
+ def techmd
72
+ @techmd ||= Ddr::Managers::TechnicalMetadataManager.new(self)
73
+ end
74
+
62
75
  def content_size
63
76
  content.external? ? content.file_size : content.dsSize
64
77
  end
@@ -122,6 +135,11 @@ module Ddr
122
135
  derivatives.update_derivatives(:later)
123
136
  end
124
137
 
138
+ def characterize_file
139
+ yield
140
+ Resque.enqueue(Ddr::Jobs::FitsFileCharacterization, pid)
141
+ end
142
+
125
143
  def default_content_type
126
144
  "application/octet-stream"
127
145
  end
@@ -26,11 +26,15 @@ module Ddr
26
26
  structure
27
27
  end
28
28
 
29
+ def multires_image_file_paths(type='default')
30
+ ::SolrDocument.find(pid).multires_image_file_paths(type)
31
+ end
32
+
29
33
  private
30
34
 
31
35
  def find_children
32
36
  query = association_query(:children)
33
- sort = "#{Ddr::IndexFields::LOCAL_ID} ASC, #{Ddr::IndexFields::OBJECT_CREATE_DATE} ASC"
37
+ sort = "#{Ddr::Index::Fields::LOCAL_ID} ASC, #{Ddr::Index::Fields::OBJECT_CREATE_DATE} ASC"
34
38
  ActiveFedora::SolrService.query(query, sort: sort, rows: 999999)
35
39
  end
36
40
 
@@ -2,7 +2,7 @@ module Ddr
2
2
  module Models
3
3
  module Indexing
4
4
 
5
- include Ddr::IndexFields
5
+ include Ddr::Index::Fields
6
6
 
7
7
  def to_solr(solr_doc=Hash.new, opts={})
8
8
  solr_doc = super(solr_doc, opts)
@@ -11,22 +11,34 @@ module Ddr
11
11
 
12
12
  def index_fields
13
13
  fields = {
14
- TITLE => title_display,
15
- INTERNAL_URI => internal_uri,
16
- IDENTIFIER_ALL => all_identifiers,
17
- WORKFLOW_STATE => workflow_state,
18
- LOCAL_ID => local_id,
14
+ ACCESS_ROLE => roles.to_json,
19
15
  ADMIN_SET => admin_set,
16
+ BOX_NUMBER_FACET => desc_metadata_values('box_number'),
17
+ CREATOR_FACET => creator,
18
+ DATE_FACET => date,
19
+ DATE_SORT => date_sort,
20
+ DEPOSITOR => depositor,
20
21
  DISPLAY_FORMAT => display_format,
22
+ DOI => adminMetadata.doi,
23
+ IDENTIFIER_ALL => all_identifiers,
24
+ INTERNAL_URI => internal_uri,
25
+ LICENSE => license,
26
+ LICENSE_DESCRIPTION => rightsMetadata.license.description.first,
27
+ LICENSE_TITLE => rightsMetadata.license.title.first,
28
+ LICENSE_URL => rightsMetadata.license.url.first,
29
+ LOCAL_ID => local_id,
21
30
  PERMANENT_ID => permanent_id,
22
31
  PERMANENT_URL => permanent_url,
23
- ACCESS_ROLE => roles.to_json,
24
- RESOURCE_ROLE => roles.in_resource_scope.agents,
25
32
  POLICY_ROLE => roles.in_policy_scope.agents,
26
- CREATOR_FACET => creator,
27
- DATE_FACET => date,
28
- DATE_SORT => date_sort,
29
- RESEARCH_HELP_CONTACT => research_help_contact
33
+ PUBLISHER_FACET => publisher,
34
+ RESEARCH_HELP_CONTACT => research_help_contact,
35
+ RESOURCE_ROLE => roles.in_resource_scope.agents,
36
+ SERIES_FACET => desc_metadata_values('series'),
37
+ SPATIAL_FACET => desc_metadata_values('spatial'),
38
+ TITLE => title_display,
39
+ TYPE_FACET => type,
40
+ WORKFLOW_STATE => workflow_state,
41
+ YEAR_FACET => year_facet,
30
42
  }
31
43
  if respond_to? :fixity_checks
32
44
  last_fixity_check = fixity_checks.last
@@ -36,11 +48,6 @@ module Ddr
36
48
  last_virus_check = virus_checks.last
37
49
  fields.merge!(last_virus_check.to_solr) if last_virus_check
38
50
  end
39
- if respond_to? :license
40
- fields[LICENSE_DESCRIPTION] = license_description
41
- fields[LICENSE_TITLE] = license_title
42
- fields[LICENSE_URL] = license_url
43
- end
44
51
  if has_content?
45
52
  fields[CONTENT_CONTROL_GROUP] = content.controlGroup
46
53
  fields[CONTENT_SIZE] = content_size
@@ -48,6 +55,7 @@ module Ddr
48
55
  fields[MEDIA_TYPE] = content_type
49
56
  fields[MEDIA_MAJOR_TYPE] = content_major_type
50
57
  fields[MEDIA_SUB_TYPE] = content_sub_type
58
+ fields.merge! techmd.index_fields
51
59
  end
52
60
  if has_multires_image?
53
61
  fields[MULTIRES_IMAGE_FILE_PATH] = multires_image_file_path
@@ -62,9 +70,9 @@ module Ddr
62
70
  fields[COLLECTION_URI] = collection_uri
63
71
  end
64
72
  if is_a? Collection
65
- fields[DEFAULT_LICENSE_DESCRIPTION] = default_license_description
66
- fields[DEFAULT_LICENSE_TITLE] = default_license_title
67
- fields[DEFAULT_LICENSE_URL] = default_license_url
73
+ fields[DEFAULT_LICENSE_DESCRIPTION] = defaultRights.license.description.first
74
+ fields[DEFAULT_LICENSE_TITLE] = defaultRights.license.title.first
75
+ fields[DEFAULT_LICENSE_URL] = defaultRights.license.url.first
68
76
  fields[ADMIN_SET_FACET] = admin_set_facet
69
77
  fields[COLLECTION_FACET] = collection_facet
70
78
  end
@@ -106,6 +114,10 @@ module Ddr
106
114
  date.first
107
115
  end
108
116
 
117
+ def year_facet
118
+ YearFacet.call(self)
119
+ end
120
+
109
121
  end
110
122
  end
111
123
  end
@@ -0,0 +1,13 @@
1
+ module Ddr::Models
2
+ class InheritedLicense
3
+
4
+ def self.call(obj)
5
+ if obj.respond_to?(:parent) && obj.parent
6
+ EffectiveLicense.call obj.parent
7
+ elsif obj.admin_policy && (obj.admin_policy != obj)
8
+ EffectiveLicense.call obj.admin_policy
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ require "ostruct"
2
+ require "ddr_aux/client"
3
+
4
+ module Ddr::Models
5
+ class License < SimpleDelegator
6
+
7
+ class << self
8
+ def get(url)
9
+ new DdrAux::Client.find_license(url: url)
10
+ end
11
+
12
+ def all
13
+ DdrAux::Client.licenses.map { |l| new(l) }
14
+ end
15
+
16
+ def call(obj)
17
+ if obj.license
18
+ l = get obj.license
19
+ l[:licensed] = obj.pid
20
+ l
21
+ end
22
+ end
23
+ end
24
+
25
+ def initialize(args={})
26
+ super OpenStruct.new(args)
27
+ end
28
+
29
+ def to_json
30
+ to_h.to_json
31
+ end
32
+
33
+ def ==(other)
34
+ other.is_a?(self.class) && other.__getobj__ == __getobj__
35
+ end
36
+
37
+ end
38
+ end
@@ -1,275 +1,259 @@
1
1
  require 'json'
2
2
 
3
- module Ddr
4
- module Models
5
- module SolrDocument
6
- extend ActiveSupport::Concern
3
+ module Ddr::Models
4
+ module SolrDocument
5
+ extend ActiveSupport::Concern
7
6
 
8
- included do
9
- alias_method :pid, :id
10
- end
11
-
12
- def to_partial_path
13
- 'document'
14
- end
15
-
16
- def safe_id
17
- id.sub(/:/, "-")
18
- end
19
-
20
- def admin_set
21
- get(Ddr::IndexFields::ADMIN_SET)
22
- end
23
-
24
- def local_id
25
- get(Ddr::IndexFields::LOCAL_ID)
26
- end
27
-
28
- def active_fedora_model
29
- get(Ddr::IndexFields::ACTIVE_FEDORA_MODEL)
30
- end
31
-
32
- def internal_uri
33
- get(Ddr::IndexFields::INTERNAL_URI)
34
- end
35
-
36
- def object_profile
37
- @object_profile ||= get_json(Ddr::IndexFields::OBJECT_PROFILE)
38
- end
7
+ included do
8
+ alias_method :pid, :id
9
+ end
39
10
 
40
- def object_state
41
- object_profile["objState"]
42
- end
11
+ class NotFound < Error; end
43
12
 
44
- def object_create_date
45
- parse_date(object_profile["objCreateDate"])
13
+ module ClassMethods
14
+ def find(pid_or_uri)
15
+ pid = pid_or_uri.sub(/\Ainfo:fedora\//, "")
16
+ query = Ddr::Index::QueryBuilder.build { |q| q.id(pid) }
17
+ if doc = query.docs.first
18
+ return doc
19
+ end
20
+ raise NotFound, "SolrDocument not found for \"#{pid_or_uri}\"."
46
21
  end
22
+ end
47
23
 
48
- def object_modified_date
49
- parse_date(object_profile["objLastModDate"])
50
- end
24
+ def inspect
25
+ "#<#{self.class.name} id=#{id.inspect}>"
26
+ end
51
27
 
52
- def last_fixity_check_on
53
- get_date(Ddr::IndexFields::LAST_FIXITY_CHECK_ON)
28
+ def method_missing(name, *args, &block)
29
+ if args.empty? && !block
30
+ begin
31
+ field = Ddr::Index::Fields.get(name)
32
+ rescue NameError
33
+ # pass
34
+ else
35
+ # Preserves the default behavior of the deprecated method
36
+ # Blacklight::Solr::Document#get, which this procedure
37
+ # effectively replaces.
38
+ val = self[field]
39
+ return val.is_a?(Array) ? val.join(", ") : val
40
+ end
54
41
  end
42
+ super
43
+ end
55
44
 
56
- def last_fixity_check_outcome
57
- get(Ddr::IndexFields::LAST_FIXITY_CHECK_OUTCOME)
58
- end
45
+ def to_partial_path
46
+ 'document'
47
+ end
59
48
 
60
- def last_virus_check_on
61
- get_date(Ddr::IndexFields::LAST_VIRUS_CHECK_ON)
62
- end
49
+ def safe_id
50
+ id.sub(/:/, "-")
51
+ end
63
52
 
64
- def last_virus_check_outcome
65
- get(Ddr::IndexFields::LAST_VIRUS_CHECK_OUTCOME)
66
- end
53
+ def object_profile
54
+ @object_profile ||= get_json(Ddr::Index::Fields::OBJECT_PROFILE)
55
+ end
67
56
 
68
- def datastreams
69
- object_profile["datastreams"]
70
- end
57
+ def object_state
58
+ object_profile["objState"]
59
+ end
71
60
 
72
- def has_datastream?(dsID)
73
- datastreams[dsID].present?
74
- end
61
+ def object_create_date
62
+ parse_date(object_profile["objCreateDate"])
63
+ end
75
64
 
76
- def has_admin_policy?
77
- admin_policy_uri.present?
78
- end
65
+ def object_modified_date
66
+ parse_date(object_profile["objLastModDate"])
67
+ end
79
68
 
80
- def admin_policy_uri
81
- get(Ddr::IndexFields::IS_GOVERNED_BY)
82
- end
69
+ def last_fixity_check_on
70
+ get_date(Ddr::Index::Fields::LAST_FIXITY_CHECK_ON)
71
+ end
83
72
 
84
- def admin_policy_pid
85
- uri = admin_policy_uri
86
- uri &&= ActiveFedora::Base.pid_from_uri(uri)
87
- end
73
+ def last_virus_check_on
74
+ get_date(Ddr::Index::Fields::LAST_VIRUS_CHECK_ON)
75
+ end
88
76
 
89
- def admin_policy
90
- if admin_policy_pid
91
- query = ActiveFedora::SolrService.construct_query_for_pids([admin_policy_pid])
92
- self.class.new(ActiveFedora::SolrService.query(query).first)
93
- end
94
- end
77
+ def datastreams
78
+ object_profile["datastreams"]
79
+ end
95
80
 
96
- def has_children?
97
- ActiveFedora::SolrService.class_from_solr_document(self).reflect_on_association(:children).present?
98
- end
81
+ def has_datastream?(dsID)
82
+ datastreams[dsID].present?
83
+ end
99
84
 
100
- def label
101
- object_profile["objLabel"]
102
- end
85
+ def has_admin_policy?
86
+ admin_policy_uri.present?
87
+ end
103
88
 
104
- def title
105
- get(Ddr::IndexFields::TITLE)
106
- end
107
- alias_method :title_display, :title # duck-type Ddr::Models::Base
89
+ def admin_policy_uri
90
+ is_governed_by
91
+ end
108
92
 
109
- def identifier
110
- # We want the multivalued version here
111
- get(ActiveFedora::SolrService.solr_name(:identifier, :stored_searchable, type: :text))
112
- end
93
+ def admin_policy_pid
94
+ uri = admin_policy_uri
95
+ uri &&= ActiveFedora::Base.pid_from_uri(uri)
96
+ end
113
97
 
114
- def source
115
- get(ActiveFedora::SolrService.solr_name(:source, :stored_searchable, type: :text))
98
+ def admin_policy
99
+ if has_admin_policy?
100
+ self.class.find(admin_policy_uri)
116
101
  end
102
+ end
117
103
 
118
- def has_thumbnail?
119
- has_datastream?(Ddr::Datastreams::THUMBNAIL)
120
- end
104
+ def has_children?
105
+ ActiveFedora::SolrService.class_from_solr_document(self).reflect_on_association(:children).present?
106
+ end
121
107
 
122
- def has_content?
123
- has_datastream?(Ddr::Datastreams::CONTENT)
124
- end
108
+ def label
109
+ object_profile["objLabel"]
110
+ end
125
111
 
126
- def content_ds
127
- datastreams[Ddr::Datastreams::CONTENT]
128
- end
112
+ def title_display
113
+ title
114
+ end
129
115
 
130
- def content_mime_type
131
- content_ds["dsMIME"] rescue nil
132
- end
133
- # For duck-typing with Ddr::Models::HasContent
134
- alias_method :content_type, :content_mime_type
116
+ def identifier
117
+ # We want the multivalued version here
118
+ self[ActiveFedora::SolrService.solr_name(:identifier, :stored_searchable, type: :text)]
119
+ end
135
120
 
136
- def content_size
137
- get(Ddr::IndexFields::CONTENT_SIZE)
138
- end
121
+ def source
122
+ self[ActiveFedora::SolrService.solr_name(:source, :stored_searchable, type: :text)]
123
+ end
139
124
 
140
- def content_size_human
141
- get(Ddr::IndexFields::CONTENT_SIZE_HUMAN)
142
- end
125
+ def has_thumbnail?
126
+ has_datastream?(Ddr::Datastreams::THUMBNAIL)
127
+ end
143
128
 
144
- def content_checksum
145
- content_ds["dsChecksum"] rescue nil
146
- end
129
+ def has_content?
130
+ has_datastream?(Ddr::Datastreams::CONTENT)
131
+ end
147
132
 
148
- def targets
149
- @targets ||= ActiveFedora::SolrService.query(targets_query)
150
- end
133
+ def content_ds
134
+ datastreams[Ddr::Datastreams::CONTENT]
135
+ end
151
136
 
152
- def targets_count
153
- @targets_count ||= ActiveFedora::SolrService.count(targets_query)
154
- end
137
+ def content_mime_type
138
+ content_ds["dsMIME"] rescue nil
139
+ end
140
+ # For duck-typing with Ddr::Models::HasContent
141
+ alias_method :content_type, :content_mime_type
155
142
 
156
- def has_target?
157
- targets_count > 0
158
- end
143
+ def content_checksum
144
+ content_ds["dsChecksum"] rescue nil
145
+ end
159
146
 
160
- def has_default_rights?
161
- has_datastream?(Ddr::Datastreams::DEFAULT_RIGHTS)
162
- end
147
+ def targets
148
+ @targets ||= ActiveFedora::SolrService.query(targets_query)
149
+ end
163
150
 
164
- def association(name)
165
- get_pid(ActiveFedora::SolrService.solr_name(name, :symbol))
166
- end
151
+ def targets_count
152
+ @targets_count ||= ActiveFedora::SolrService.count(targets_query)
153
+ end
167
154
 
168
- def controller_name
169
- active_fedora_model.tableize
170
- end
155
+ def has_target?
156
+ targets_count > 0
157
+ end
171
158
 
172
- def inherited_license
173
- if admin_policy_pid
174
- query = ActiveFedora::SolrService.construct_query_for_pids([admin_policy_pid])
175
- results = ActiveFedora::SolrService.query(query)
176
- doc = results.map { |result| ::SolrDocument.new(result) }.first
177
- { title: doc.get(Ddr::IndexFields::DEFAULT_LICENSE_TITLE),
178
- description: doc.get(Ddr::IndexFields::DEFAULT_LICENSE_DESCRIPTION),
179
- url: doc.get(Ddr::IndexFields::DEFAULT_LICENSE_URL) }
180
- end
181
- end
159
+ def association(name)
160
+ get_pid(ActiveFedora::SolrService.solr_name(name, :symbol))
161
+ end
182
162
 
183
- def license
184
- if get(Ddr::IndexFields::LICENSE_TITLE) || get(Ddr::IndexFields::LICENSE_DESCRIPTION) || get(Ddr::IndexFields::LICENSE_URL)
185
- { title: get(Ddr::IndexFields::LICENSE_TITLE),
186
- description: get(Ddr::IndexFields::LICENSE_DESCRIPTION),
187
- url: get(Ddr::IndexFields::LICENSE_URL) }
188
- end
189
- end
163
+ def controller_name
164
+ active_fedora_model.tableize
165
+ end
190
166
 
191
- def effective_license
192
- @effective_license ||= license || inherited_license || {}
193
- end
167
+ def effective_license
168
+ @effective_license ||= EffectiveLicense.call(self)
169
+ end
194
170
 
195
- def permanent_id
196
- get(Ddr::IndexFields::PERMANENT_ID)
197
- end
171
+ def roles
172
+ @roles ||= Ddr::Auth::Roles::DetachedRoleSet.from_json(access_role)
173
+ end
198
174
 
199
- def multires_image_file_path
200
- get(Ddr::IndexFields::MULTIRES_IMAGE_FILE_PATH)
201
- end
175
+ def struct_maps
176
+ JSON.parse(fetch(Ddr::Index::Fields::STRUCT_MAPS))
177
+ rescue
178
+ {}
179
+ end
202
180
 
203
- def roles
204
- @roles ||= Ddr::Auth::Roles::DetachedRoleSet.from_json(access_role)
205
- end
181
+ def struct_map(type='default')
182
+ struct_maps.present? ? struct_maps.fetch(type) : nil
183
+ end
206
184
 
207
- def access_role
208
- get(Ddr::IndexFields::ACCESS_ROLE)
209
- end
185
+ def effective_permissions(agents)
186
+ Ddr::Auth::EffectivePermissions.call(self, agents)
187
+ end
210
188
 
211
- def display_format
212
- get(Ddr::IndexFields::DISPLAY_FORMAT)
213
- end
189
+ def research_help
190
+ research_help_contact = self[Ddr::Index::Fields::RESEARCH_HELP_CONTACT] || inherited_research_help_contact
191
+ Ddr::Contacts.get(research_help_contact) if research_help_contact
192
+ end
214
193
 
215
- def struct_maps
216
- JSON.parse(fetch(Ddr::IndexFields::STRUCT_MAPS))
217
- rescue
218
- {}
219
- end
194
+ def parent_uri
195
+ is_part_of || is_member_of_collection
196
+ end
220
197
 
221
- def struct_map(type='default')
222
- struct_maps.present? ? struct_maps.fetch(type) : nil
223
- end
198
+ def has_parent?
199
+ parent_uri.present?
200
+ end
224
201
 
225
- def effective_permissions(agents)
226
- Ddr::Auth::EffectivePermissions.call(self, agents)
202
+ def parent
203
+ if has_parent?
204
+ self.class.find(parent_uri)
227
205
  end
206
+ end
228
207
 
229
- def display_format
230
- get(Ddr::IndexFields::DISPLAY_FORMAT)
231
- end
208
+ def multires_image_file_paths(type='default')
209
+ struct_map_docs(type).map { |doc| doc.multires_image_file_path }.compact
210
+ end
232
211
 
233
- def research_help
234
- research_help_contact = self[Ddr::IndexFields::RESEARCH_HELP_CONTACT] || inherited_research_help_contact
235
- Ddr::Contacts.get(research_help_contact) if research_help_contact
236
- end
212
+ private
237
213
 
238
- private
214
+ def targets_query
215
+ "#{Ddr::Index::Fields::IS_EXTERNAL_TARGET_FOR}:#{internal_uri_for_query}"
216
+ end
239
217
 
240
- def targets_query
241
- "#{Ddr::IndexFields::IS_EXTERNAL_TARGET_FOR}:#{internal_uri_for_query}"
242
- end
218
+ def internal_uri_for_query
219
+ ActiveFedora::SolrService.escape_uri_for_query(internal_uri)
220
+ end
243
221
 
244
- def internal_uri_for_query
245
- ActiveFedora::SolrService.escape_uri_for_query(internal_uri)
246
- end
222
+ def get_date(field)
223
+ parse_date(self[field])
224
+ end
247
225
 
248
- def get_date(field)
249
- parse_date(get(field))
250
- end
226
+ def get_json(field)
227
+ JSON.parse Array(self[field]).first
228
+ end
251
229
 
252
- def get_json(field)
253
- JSON.parse Array(self[field]).first
254
- end
230
+ def parse_date(date)
231
+ Time.parse(date).localtime if date
232
+ end
255
233
 
256
- def parse_date(date)
257
- Time.parse(date).localtime if date
258
- end
234
+ def get_pid(field)
235
+ ActiveFedora::Base.pid_from_uri(self[field]) rescue nil
236
+ end
259
237
 
260
- def get_pid(field)
261
- ActiveFedora::Base.pid_from_uri(get(field)) rescue nil
238
+ def inherited_research_help_contact
239
+ if doc = admin_policy
240
+ doc.research_help_contact
262
241
  end
242
+ end
263
243
 
264
- def inherited_research_help_contact
265
- if admin_policy_pid
266
- query = ActiveFedora::SolrService.construct_query_for_pids([admin_policy_pid])
267
- results = ActiveFedora::SolrService.query(query)
268
- doc = results.map { |result| ::SolrDocument.new(result) }.first
269
- doc[Ddr::IndexFields::RESEARCH_HELP_CONTACT]
270
- end
271
- end
244
+ def struct_map_docs(type='default')
245
+ struct_map_pids(type).map { |pid| self.class.find(pid) }.compact
246
+ end
272
247
 
248
+ # For simplicity, initial implementation returns PID's only from top-level
249
+ # (i.e., not nested) div's. This is done since we have not clarified what
250
+ # an _ordered_ list of PID's should look like if struct map contains nested
251
+ # div's.
252
+ def struct_map_pids(type='default')
253
+ struct_map(type)['divs'].map { |d| d['fptrs'].present? ? d['fptrs'].first : nil}.compact
254
+ rescue
255
+ []
273
256
  end
257
+
274
258
  end
275
259
  end