ddr-models 1.2.0

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 (188) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +12 -0
  3. data/README.md +5 -0
  4. data/Rakefile +37 -0
  5. data/app/models/attachment.rb +7 -0
  6. data/app/models/collection.rb +54 -0
  7. data/app/models/component.rb +15 -0
  8. data/app/models/item.rb +19 -0
  9. data/app/models/solr_document.rb +36 -0
  10. data/app/models/target.rb +8 -0
  11. data/config/initializers/active_fedora_base.rb +77 -0
  12. data/config/initializers/active_fedora_datastream.rb +5 -0
  13. data/config/initializers/ddr.rb +8 -0
  14. data/config/initializers/devise.rb +245 -0
  15. data/config/initializers/devise.rb~ +245 -0
  16. data/config/initializers/subscriptions.rb +15 -0
  17. data/config/routes.rb +2 -0
  18. data/db/migrate/20141021233359_create_events.rb +28 -0
  19. data/db/migrate/20141021234156_create_minted_ids.rb +19 -0
  20. data/db/migrate/20141103192146_create_workflow_state.rb +13 -0
  21. data/db/migrate/20141104181418_create_users.rb +34 -0
  22. data/db/migrate/20141104181418_create_users.rb~ +6 -0
  23. data/lib/ddr-models.rb +1 -0
  24. data/lib/ddr/actions.rb +8 -0
  25. data/lib/ddr/actions/fixity_check.rb +35 -0
  26. data/lib/ddr/auth.rb +45 -0
  27. data/lib/ddr/auth.rb~ +47 -0
  28. data/lib/ddr/auth/ability.rb +204 -0
  29. data/lib/ddr/auth/ability.rb~ +204 -0
  30. data/lib/ddr/auth/group_service.rb +53 -0
  31. data/lib/ddr/auth/group_service.rb~ +53 -0
  32. data/lib/ddr/auth/grouper_service.rb +76 -0
  33. data/lib/ddr/auth/grouper_service.rb~ +77 -0
  34. data/lib/ddr/auth/remote_group_service.rb +35 -0
  35. data/lib/ddr/auth/remote_group_service.rb~ +35 -0
  36. data/lib/ddr/auth/superuser.rb +13 -0
  37. data/lib/ddr/auth/superuser.rb~ +9 -0
  38. data/lib/ddr/auth/user.rb +71 -0
  39. data/lib/ddr/auth/user.rb~ +65 -0
  40. data/lib/ddr/configurable.rb +34 -0
  41. data/lib/ddr/datastreams.rb +32 -0
  42. data/lib/ddr/datastreams/content_metadata_datastream.rb +147 -0
  43. data/lib/ddr/datastreams/datastream_behavior.rb +95 -0
  44. data/lib/ddr/datastreams/descriptive_metadata_datastream.rb +84 -0
  45. data/lib/ddr/datastreams/properties_datastream.rb +25 -0
  46. data/lib/ddr/datastreams/role_assignments_datastream.rb +19 -0
  47. data/lib/ddr/events.rb +17 -0
  48. data/lib/ddr/events/creation_event.rb +12 -0
  49. data/lib/ddr/events/event.rb +163 -0
  50. data/lib/ddr/events/fixity_check_event.rb +43 -0
  51. data/lib/ddr/events/ingestion_event.rb +12 -0
  52. data/lib/ddr/events/preservation_event_behavior.rb +37 -0
  53. data/lib/ddr/events/preservation_event_type.rb +24 -0
  54. data/lib/ddr/events/reindex_object_after_save.rb +18 -0
  55. data/lib/ddr/events/update_event.rb +9 -0
  56. data/lib/ddr/events/validation_event.rb +11 -0
  57. data/lib/ddr/events/virus_check_event.rb +30 -0
  58. data/lib/ddr/index_fields.rb +39 -0
  59. data/lib/ddr/metadata.rb +22 -0
  60. data/lib/ddr/metadata/duke_terms.rb +15 -0
  61. data/lib/ddr/metadata/premis_event.rb +59 -0
  62. data/lib/ddr/metadata/rdf_vocabulary_parser.rb +45 -0
  63. data/lib/ddr/metadata/roles_vocabulary.rb +10 -0
  64. data/lib/ddr/metadata/sources/duketerms.rdf.xml +856 -0
  65. data/lib/ddr/metadata/vocabulary.rb +37 -0
  66. data/lib/ddr/models.rb +60 -0
  67. data/lib/ddr/models/access_controllable.rb +23 -0
  68. data/lib/ddr/models/base.rb +37 -0
  69. data/lib/ddr/models/describable.rb +81 -0
  70. data/lib/ddr/models/engine.rb +58 -0
  71. data/lib/ddr/models/error.rb +12 -0
  72. data/lib/ddr/models/event_loggable.rb +36 -0
  73. data/lib/ddr/models/file_management.rb +183 -0
  74. data/lib/ddr/models/fixity_checkable.rb +20 -0
  75. data/lib/ddr/models/governable.rb +48 -0
  76. data/lib/ddr/models/has_attachments.rb +12 -0
  77. data/lib/ddr/models/has_children.rb +21 -0
  78. data/lib/ddr/models/has_content.rb +114 -0
  79. data/lib/ddr/models/has_content_metadata.rb +16 -0
  80. data/lib/ddr/models/has_properties.rb +15 -0
  81. data/lib/ddr/models/has_role_assignments.rb +17 -0
  82. data/lib/ddr/models/has_thumbnail.rb +27 -0
  83. data/lib/ddr/models/has_workflow.rb +29 -0
  84. data/lib/ddr/models/indexing.rb +53 -0
  85. data/lib/ddr/models/licensable.rb +28 -0
  86. data/lib/ddr/models/minted_id.rb +10 -0
  87. data/lib/ddr/models/permanent_identification.rb +48 -0
  88. data/lib/ddr/models/solr_document.rb +193 -0
  89. data/lib/ddr/models/version.rb +5 -0
  90. data/lib/ddr/notifications.rb +15 -0
  91. data/lib/ddr/services.rb +8 -0
  92. data/lib/ddr/services/id_service.rb +48 -0
  93. data/lib/ddr/utils.rb +153 -0
  94. data/lib/ddr/workflow.rb +8 -0
  95. data/lib/ddr/workflow/workflow_state.rb +39 -0
  96. data/spec/dummy/README.rdoc +28 -0
  97. data/spec/dummy/Rakefile +6 -0
  98. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  99. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  100. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  101. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  102. data/spec/dummy/app/models/user.rb +5 -0
  103. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  104. data/spec/dummy/bin/bundle +3 -0
  105. data/spec/dummy/bin/rails +4 -0
  106. data/spec/dummy/bin/rake +4 -0
  107. data/spec/dummy/config.ru +4 -0
  108. data/spec/dummy/config/application.rb +29 -0
  109. data/spec/dummy/config/boot.rb +5 -0
  110. data/spec/dummy/config/database.yml +25 -0
  111. data/spec/dummy/config/environment.rb +5 -0
  112. data/spec/dummy/config/environments/development.rb +37 -0
  113. data/spec/dummy/config/environments/production.rb +78 -0
  114. data/spec/dummy/config/environments/test.rb +39 -0
  115. data/spec/dummy/config/initializers/assets.rb +8 -0
  116. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  117. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  118. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  119. data/spec/dummy/config/initializers/inflections.rb +16 -0
  120. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  121. data/spec/dummy/config/initializers/session_store.rb +3 -0
  122. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  123. data/spec/dummy/config/locales/en.yml +23 -0
  124. data/spec/dummy/config/routes.rb +56 -0
  125. data/spec/dummy/config/secrets.yml +22 -0
  126. data/spec/dummy/db/development.sqlite3 +0 -0
  127. data/spec/dummy/db/schema.rb +80 -0
  128. data/spec/dummy/db/test.sqlite3 +0 -0
  129. data/spec/dummy/log/development.log +4974 -0
  130. data/spec/dummy/log/test.log +55627 -0
  131. data/spec/dummy/public/404.html +67 -0
  132. data/spec/dummy/public/422.html +67 -0
  133. data/spec/dummy/public/500.html +66 -0
  134. data/spec/dummy/public/favicon.ico +0 -0
  135. data/spec/factories/attachment_factories.rb +15 -0
  136. data/spec/factories/collection_factories.rb +16 -0
  137. data/spec/factories/component_factories.rb +15 -0
  138. data/spec/factories/event_factories.rb +7 -0
  139. data/spec/factories/item_factories.rb +16 -0
  140. data/spec/factories/target_factories.rb +11 -0
  141. data/spec/factories/test_model_factories.rb +133 -0
  142. data/spec/factories/user_factories.rb +7 -0
  143. data/spec/factories/user_factories.rb~ +7 -0
  144. data/spec/features/grouper_integration_spec.rb~ +21 -0
  145. data/spec/fixtures/contentMetadata.xml +37 -0
  146. data/spec/fixtures/image1.tiff +0 -0
  147. data/spec/fixtures/image2.tiff +0 -0
  148. data/spec/fixtures/image3.tiff +0 -0
  149. data/spec/fixtures/library-devil.tiff +0 -0
  150. data/spec/fixtures/sample.docx +0 -0
  151. data/spec/fixtures/sample.pdf +0 -0
  152. data/spec/fixtures/target.png +0 -0
  153. data/spec/models/ability_spec.rb +248 -0
  154. data/spec/models/ability_spec.rb~ +245 -0
  155. data/spec/models/active_fedora_base_spec.rb +107 -0
  156. data/spec/models/active_fedora_datastream_spec.rb +121 -0
  157. data/spec/models/attachment_spec.rb +13 -0
  158. data/spec/models/collection_spec.rb +33 -0
  159. data/spec/models/component_spec.rb +8 -0
  160. data/spec/models/descriptive_metadata_datastream_spec.rb +102 -0
  161. data/spec/models/events_spec.rb +64 -0
  162. data/spec/models/file_management_spec.rb +179 -0
  163. data/spec/models/has_role_assignments_spec.rb +29 -0
  164. data/spec/models/has_workflow_spec.rb +54 -0
  165. data/spec/models/item_spec.rb +8 -0
  166. data/spec/models/permanent_identification_spec.rb +65 -0
  167. data/spec/models/role_assignments_datastream_spec.rb +25 -0
  168. data/spec/models/superuser_spec.rb +13 -0
  169. data/spec/models/superuser_spec.rb~ +13 -0
  170. data/spec/models/target_spec.rb +8 -0
  171. data/spec/models/user_spec.rb +60 -0
  172. data/spec/models/user_spec.rb~ +56 -0
  173. data/spec/services/group_service_spec.rb +75 -0
  174. data/spec/services/group_service_spec.rb~ +71 -0
  175. data/spec/services/id_service_spec.rb +33 -0
  176. data/spec/spec_helper.rb +125 -0
  177. data/spec/support/shared_examples_for_access_controllables.rb +6 -0
  178. data/spec/support/shared_examples_for_associations.rb +8 -0
  179. data/spec/support/shared_examples_for_ddr_models.rb +7 -0
  180. data/spec/support/shared_examples_for_describables.rb +63 -0
  181. data/spec/support/shared_examples_for_event_loggables.rb +3 -0
  182. data/spec/support/shared_examples_for_events.rb +179 -0
  183. data/spec/support/shared_examples_for_governables.rb +17 -0
  184. data/spec/support/shared_examples_for_has_content.rb +136 -0
  185. data/spec/support/shared_examples_for_has_content_metadata.rb +74 -0
  186. data/spec/support/shared_examples_for_has_properties.rb +5 -0
  187. data/spec/support/shared_examples_for_indexing.rb +36 -0
  188. metadata +562 -0
@@ -0,0 +1,20 @@
1
+ module Ddr
2
+ module Models
3
+ module FixityCheckable
4
+
5
+ def datastreams_to_validate
6
+ datastreams.select { |dsid, ds| ds.has_content? }
7
+ end
8
+
9
+ def fixity_checks
10
+ Ddr::Events::FixityCheckEvent.for_object(self)
11
+ end
12
+
13
+ # Returns a Ddr::Actions::FixityCheck::Result for the object
14
+ def fixity_check
15
+ Ddr::Actions::FixityCheck.execute(self)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,48 @@
1
+ module Ddr
2
+ module Models
3
+ module Governable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ belongs_to :admin_policy, :property => :is_governed_by, :class_name => "Collection"
8
+ end
9
+
10
+ def inherited_permissions
11
+ admin_policy ? admin_policy.default_permissions : []
12
+ end
13
+
14
+ def inherited_rights
15
+ admin_policy.datastreams[Ddr::Datastreams::DEFAULT_RIGHTS] if admin_policy
16
+ end
17
+
18
+ # Creates convenience methods:
19
+ # inherited_discover_users, inherited_discover_groups,
20
+ # inherited_read_users, inherited_read_groups,
21
+ # inherited_edit_user, inherited_edit_groups
22
+ ["discover", "read", "edit"].each do |access|
23
+ ["user", "group"].each do |type|
24
+ define_method("inherited_#{access}_#{type}s") do
25
+ admin_policy ? admin_policy.send("default_#{access}_#{type}s") : []
26
+ end
27
+ end
28
+ end
29
+
30
+ def inherited_license
31
+ admin_policy.default_license if admin_policy
32
+ end
33
+
34
+ def copy_admin_policy_from(other)
35
+ # XXX In active-fedora 7.0 can do
36
+ # self.admin_policy = other.admin_policy
37
+ self.admin_policy_id = case
38
+ when other.has_admin_policy?
39
+ other.admin_policy_id
40
+ when other.is_a?(Collection)
41
+ other.pid
42
+ end
43
+ # self.admin_policy_id = other.admin_policy_id if other.has_admin_policy?
44
+ end
45
+
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ module Ddr
2
+ module Models
3
+ module HasAttachments
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_many :attachments, property: :is_attached_to, class_name: 'Attachment'
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Ddr
2
+ module Models
3
+ module HasChildren
4
+ extend ActiveSupport::Concern
5
+
6
+ def first_child
7
+ if datastreams.include?(Ddr::Datastreams::CONTENT_METADATA) && datastreams[Ddr::Datastreams::CONTENT_METADATA].has_content?
8
+ first_child_pid = datastreams[Ddr::Datastreams::CONTENT_METADATA].first_pid
9
+ else
10
+ first_child_pid = ActiveFedora::SolrService.query(association_query(:children), rows: 1, sort: "#{Ddr::IndexFields::IDENTIFIER} ASC").first["id"]
11
+ end
12
+ begin
13
+ ActiveFedora::Base.find(first_child_pid, :cast => true) if first_child_pid
14
+ rescue ActiveFedora::ObjectNotFound
15
+ nil
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,114 @@
1
+ require 'openssl'
2
+
3
+ module Ddr
4
+ module Models
5
+ module HasContent
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ has_file_datastream name: Ddr::Datastreams::CONTENT,
10
+ versionable: true,
11
+ label: "Content file for this object",
12
+ control_group: "M"
13
+
14
+ has_attributes :original_filename, datastream: "properties", multiple: false
15
+
16
+ validates_presence_of :content
17
+
18
+ include Hydra::Derivatives
19
+ include FileManagement unless include?(FileManagement)
20
+
21
+ around_save :update_thumbnail, if: :content_changed?
22
+
23
+ after_add_file do
24
+ if file_to_add.original_name && file_to_add.dsid == "content"
25
+ self.original_filename = file_to_add.original_name
26
+ end
27
+ end
28
+
29
+ delegate :validate_checksum!, to: :content
30
+ end
31
+
32
+ # Convenience method wrapping FileManagement#add_file
33
+ def upload file, opts={}
34
+ add_file(file, Ddr::Datastreams::CONTENT, opts)
35
+ end
36
+
37
+ # Set content to file and save
38
+ def upload! file, opts={}
39
+ upload(file, opts)
40
+ save
41
+ end
42
+
43
+ def content_size
44
+ content.external? ? content.file_size : content.dsSize
45
+ end
46
+
47
+ def content_human_size
48
+ ActiveSupport::NumberHelper.number_to_human_size(content_size) if content_size
49
+ end
50
+
51
+ def content_type
52
+ content.mimeType
53
+ end
54
+
55
+ def content_major_type
56
+ content_type.split("/").first
57
+ end
58
+
59
+ def content_sub_type
60
+ content_type.split("/").last
61
+ end
62
+
63
+ def content_type= mime_type
64
+ self.content.mimeType = mime_type
65
+ end
66
+
67
+ def image?
68
+ content_major_type == "image"
69
+ end
70
+
71
+ def pdf?
72
+ content_type == "application/pdf"
73
+ end
74
+
75
+ def generate_thumbnail
76
+ return false unless thumbnailable?
77
+ transform_datastream :content, { thumbnail: { size: "100x100>", datastream: "thumbnail" } }
78
+ thumbnail_changed?
79
+ end
80
+
81
+ def generate_thumbnail!
82
+ generate_thumbnail && save
83
+ end
84
+
85
+ def virus_checks
86
+ Ddr::Events::VirusCheckEvent.for_object(self)
87
+ end
88
+
89
+ def content_changed?
90
+ content.external? ? content.dsLocation_changed? : content.content_changed?
91
+ end
92
+
93
+ protected
94
+
95
+ def update_thumbnail
96
+ yield
97
+ if thumbnailable?
98
+ generate_thumbnail!
99
+ else
100
+ thumbnail.delete
101
+ end
102
+ end
103
+
104
+ def thumbnailable?
105
+ has_content? && (image? || pdf?)
106
+ end
107
+
108
+ def default_content_type
109
+ "application/octet-stream"
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,16 @@
1
+ module Ddr
2
+ module Models
3
+ module HasContentMetadata
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_file_datastream :name => Ddr::Datastreams::CONTENT_METADATA,
8
+ :type => Ddr::Datastreams::ContentMetadataDatastream,
9
+ :versionable => true,
10
+ :label => "Structural Content Data for this object",
11
+ :control_group => 'M'
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ module Ddr
2
+ module Models
3
+ module HasProperties
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_metadata name: Ddr::Datastreams::PROPERTIES,
8
+ type: Ddr::Datastreams::PropertiesDatastream,
9
+ versionable: true,
10
+ label: "Properties for this object",
11
+ control_group: 'M'
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Ddr
2
+ module Models
3
+ module HasRoleAssignments
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_metadata name: "roleAssignments",
8
+ type: Ddr::Datastreams::RoleAssignmentsDatastream,
9
+ versionable: true,
10
+ control_group: "M"
11
+
12
+ delegate :principal_has_role?, to: :roleAssignments
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ module Ddr
2
+ module Models
3
+ module HasThumbnail
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_file_datastream name: Ddr::Datastreams::THUMBNAIL,
8
+ versionable: true,
9
+ label: "Thumbnail for this object",
10
+ control_group: 'M'
11
+ end
12
+
13
+ def thumbnail_changed?
14
+ thumbnail.content_changed?
15
+ end
16
+
17
+ def copy_thumbnail_from(other)
18
+ if other && other.has_thumbnail?
19
+ self.thumbnail.content = other.thumbnail.content
20
+ self.thumbnail.mimeType = other.thumbnail.mimeType if thumbnail_changed?
21
+ end
22
+ thumbnail_changed?
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module Ddr
2
+ module Models
3
+ module HasWorkflow
4
+ extend ActiveSupport::Concern
5
+
6
+ PUBLISHED = Ddr::Workflow::WorkflowState::PUBLISHED
7
+ UNPUBLISHED = nil
8
+
9
+ def workflow_state
10
+ Ddr::Workflow::WorkflowState.workflow_state_for_object(self)
11
+ end
12
+
13
+ def published?
14
+ self.workflow_state == PUBLISHED
15
+ end
16
+
17
+ def publish!
18
+ Ddr::Workflow::WorkflowState.set_for_object(self, PUBLISHED)
19
+ update_index
20
+ end
21
+
22
+ def unpublish!
23
+ Ddr::Workflow::WorkflowState.set_for_object(self, UNPUBLISHED)
24
+ update_index
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,53 @@
1
+ module Ddr
2
+ module Models
3
+ module Indexing
4
+
5
+ def to_solr(solr_doc=Hash.new, opts={})
6
+ solr_doc = super(solr_doc, opts)
7
+ solr_doc.merge index_fields
8
+ end
9
+
10
+ def index_fields
11
+ fields = {
12
+ Ddr::IndexFields::TITLE => title_display,
13
+ Ddr::IndexFields::INTERNAL_URI => internal_uri,
14
+ Ddr::IndexFields::IDENTIFIER => identifier_sort,
15
+ Ddr::IndexFields::PERMANENT_ID => permanent_id,
16
+ Ddr::IndexFields::WORKFLOW_STATE => workflow_state
17
+ }
18
+ if respond_to? :fixity_checks
19
+ last_fixity_check = fixity_checks.last
20
+ fields.merge!(last_fixity_check.to_solr) if last_fixity_check
21
+ end
22
+ if respond_to? :virus_checks
23
+ last_virus_check = virus_checks.last
24
+ fields.merge!(last_virus_check.to_solr) if last_virus_check
25
+ end
26
+ if respond_to?(:original_filename) && original_filename.present?
27
+ fields[Ddr::IndexFields::ORIGINAL_FILENAME] = original_filename
28
+ end
29
+ if has_content?
30
+ fields[Ddr::IndexFields::CONTENT_CONTROL_GROUP] = content.controlGroup
31
+ fields[Ddr::IndexFields::CONTENT_SIZE] = content_size
32
+ fields[Ddr::IndexFields::CONTENT_SIZE_HUMAN] = content_human_size
33
+ fields[Ddr::IndexFields::MEDIA_TYPE] = content_type
34
+ fields[Ddr::IndexFields::MEDIA_MAJOR_TYPE] = content_major_type
35
+ fields[Ddr::IndexFields::MEDIA_SUB_TYPE] = content_sub_type
36
+ end
37
+ fields
38
+ end
39
+
40
+ def title_display
41
+ return title.first if title.present?
42
+ return identifier.first if identifier.present?
43
+ return original_filename if respond_to?(:original_filename) && original_filename.present?
44
+ "[#{pid}]"
45
+ end
46
+
47
+ def identifier_sort
48
+ identifier.first
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,28 @@
1
+ module Ddr
2
+ module Models
3
+ module Licensable
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ has_attributes :license_title, datastream: Ddr::Datastreams::RIGHTS_METADATA, at: [:license, :title], multiple: false
8
+ has_attributes :license_description, datastream: Ddr::Datastreams::RIGHTS_METADATA, at: [:license, :description], multiple: false
9
+ has_attributes :license_url, datastream: Ddr::Datastreams::RIGHTS_METADATA, at: [:license, :url], multiple: false
10
+ end
11
+
12
+ def license
13
+ if license_title.present? or license_description.present? or license_url.present?
14
+ {title: license_title, description: license_description, url: license_url}.with_indifferent_access
15
+ end
16
+ end
17
+
18
+ def license=(new_license)
19
+ raise ArgumentError unless new_license.is_a?(Hash)
20
+ l = new_license.with_indifferent_access
21
+ self.license_title = l[:title]
22
+ self.license_description = l[:description]
23
+ self.license_url = l[:url]
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,10 @@
1
+ module Ddr
2
+ module Models
3
+ class MintedId < ActiveRecord::Base
4
+
5
+ validates_presence_of :minted_id
6
+ validates_uniqueness_of :minted_id
7
+
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,48 @@
1
+ module Ddr
2
+ module Models
3
+ module PermanentIdentification
4
+ extend ActiveSupport::Concern
5
+
6
+ PERMALINK_BASE_URL = 'http://id.library.duke.edu/'
7
+
8
+ included do
9
+ has_attributes :permanent_id, datastream: Ddr::Datastreams::PROPERTIES, multiple: false
10
+ after_create :assign_permanent_identifier
11
+
12
+ def self.permalink(permanent_id)
13
+ PERMALINK_BASE_URL + permanent_id
14
+ end
15
+
16
+ end
17
+
18
+ def permalink
19
+ self.class.permalink(permanent_id)
20
+ end
21
+
22
+ protected
23
+
24
+ def assign_permanent_identifier
25
+ reload
26
+ unless permanent_id.present?
27
+ event_args = { pid: self.pid, summary: "Assigned permanent ID" }
28
+ begin
29
+ self.permanent_id = Ddr::Services::IdService.mint
30
+ if save(validate: false)
31
+ MintedId.find_by(minted_id: self.permanent_id).update(referent: self.pid)
32
+ event_args[:outcome] = Ddr::Events::Event::SUCCESS
33
+ event_args[:detail] = "Assigned permanent ID #{self.permanent_id} to #{self.pid}"
34
+ else
35
+ raise "Could not save object #{self.pid} with permanent identifier #{self.permanent_id}"
36
+ end
37
+ rescue Exception => e
38
+ event_args[:outcome] = Ddr::Events::Event::FAILURE
39
+ event_args[:detail] = "Unable to assign permanent ID to #{self.pid}"
40
+ Rails.logger.error("Error assigning permanent ID to #{self.pid}: #{e}")
41
+ end
42
+ Ddr::Notifications.notify_event(:update, event_args)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end