ddr-core 0.2.1

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 (132) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +12 -0
  3. data/README.md +27 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/config/ddr_core_manifest.js +0 -0
  6. data/app/controllers/users/omniauth_callbacks_controller.rb +11 -0
  7. data/app/controllers/users/sessions_controller.rb +15 -0
  8. data/app/models/concerns/ddr/captionable.rb +25 -0
  9. data/app/models/concerns/ddr/describable.rb +108 -0
  10. data/app/models/concerns/ddr/governable.rb +25 -0
  11. data/app/models/concerns/ddr/has_admin_metadata.rb +141 -0
  12. data/app/models/concerns/ddr/has_attachments.rb +10 -0
  13. data/app/models/concerns/ddr/has_children.rb +10 -0
  14. data/app/models/concerns/ddr/has_content.rb +132 -0
  15. data/app/models/concerns/ddr/has_extracted_text.rb +10 -0
  16. data/app/models/concerns/ddr/has_intermediate_file.rb +25 -0
  17. data/app/models/concerns/ddr/has_multires_image.rb +14 -0
  18. data/app/models/concerns/ddr/has_parent.rb +18 -0
  19. data/app/models/concerns/ddr/has_struct_metadata.rb +21 -0
  20. data/app/models/concerns/ddr/has_thumbnail.rb +33 -0
  21. data/app/models/concerns/ddr/solr_document_behavior.rb +429 -0
  22. data/app/models/concerns/ddr/streamable.rb +25 -0
  23. data/app/models/ddr/admin_set.rb +28 -0
  24. data/app/models/ddr/attachment.rb +14 -0
  25. data/app/models/ddr/collection.rb +28 -0
  26. data/app/models/ddr/component.rb +31 -0
  27. data/app/models/ddr/contact.rb +23 -0
  28. data/app/models/ddr/digest.rb +8 -0
  29. data/app/models/ddr/file.rb +40 -0
  30. data/app/models/ddr/item.rb +36 -0
  31. data/app/models/ddr/language.rb +31 -0
  32. data/app/models/ddr/media_type.rb +22 -0
  33. data/app/models/ddr/resource.rb +94 -0
  34. data/app/models/ddr/rights_statement.rb +25 -0
  35. data/app/models/ddr/target.rb +17 -0
  36. data/config/initializers/devise.rb +262 -0
  37. data/config/locales/ddr-core.en.yml +85 -0
  38. data/config/routes.rb +3 -0
  39. data/db/migrate/20141104181418_create_users.rb +34 -0
  40. data/db/migrate/20141107124012_add_columns_to_user.rb +46 -0
  41. data/lib/ddr-core.rb +1 -0
  42. data/lib/ddr/auth.rb +80 -0
  43. data/lib/ddr/auth/ability.rb +18 -0
  44. data/lib/ddr/auth/ability_definitions.rb +26 -0
  45. data/lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb +9 -0
  46. data/lib/ddr/auth/ability_definitions/alias_ability_definitions.rb +23 -0
  47. data/lib/ddr/auth/ability_definitions/attachment_ability_definitions.rb +13 -0
  48. data/lib/ddr/auth/ability_definitions/collection_ability_definitions.rb +28 -0
  49. data/lib/ddr/auth/ability_definitions/component_ability_definitions.rb +13 -0
  50. data/lib/ddr/auth/ability_definitions/item_ability_definitions.rb +13 -0
  51. data/lib/ddr/auth/ability_definitions/lock_ability_definitions.rb +13 -0
  52. data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +16 -0
  53. data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +39 -0
  54. data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +9 -0
  55. data/lib/ddr/auth/ability_factory.rb +10 -0
  56. data/lib/ddr/auth/abstract_ability.rb +48 -0
  57. data/lib/ddr/auth/affiliation.rb +14 -0
  58. data/lib/ddr/auth/affiliation_groups.rb +20 -0
  59. data/lib/ddr/auth/anonymous_ability.rb +7 -0
  60. data/lib/ddr/auth/auth_context.rb +109 -0
  61. data/lib/ddr/auth/auth_context_factory.rb +13 -0
  62. data/lib/ddr/auth/detached_auth_context.rb +19 -0
  63. data/lib/ddr/auth/dynamic_groups.rb +13 -0
  64. data/lib/ddr/auth/effective_permissions.rb +12 -0
  65. data/lib/ddr/auth/effective_roles.rb +9 -0
  66. data/lib/ddr/auth/failure_app.rb +16 -0
  67. data/lib/ddr/auth/group.rb +40 -0
  68. data/lib/ddr/auth/grouper_gateway.rb +70 -0
  69. data/lib/ddr/auth/groups.rb +32 -0
  70. data/lib/ddr/auth/ldap_gateway.rb +74 -0
  71. data/lib/ddr/auth/permissions.rb +18 -0
  72. data/lib/ddr/auth/remote_groups.rb +14 -0
  73. data/lib/ddr/auth/role_based_access_controls_enforcement.rb +56 -0
  74. data/lib/ddr/auth/roles.rb +28 -0
  75. data/lib/ddr/auth/roles/role.rb +121 -0
  76. data/lib/ddr/auth/roles/role_type.rb +23 -0
  77. data/lib/ddr/auth/roles/role_types.rb +52 -0
  78. data/lib/ddr/auth/superuser_ability.rb +7 -0
  79. data/lib/ddr/auth/test_helpers.rb +22 -0
  80. data/lib/ddr/auth/user.rb +54 -0
  81. data/lib/ddr/auth/web_auth_context.rb +29 -0
  82. data/lib/ddr/core.rb +110 -0
  83. data/lib/ddr/core/engine.rb +8 -0
  84. data/lib/ddr/core/version.rb +5 -0
  85. data/lib/ddr/error.rb +16 -0
  86. data/lib/ddr/files.rb +13 -0
  87. data/lib/ddr/fits.rb +189 -0
  88. data/lib/ddr/index.rb +29 -0
  89. data/lib/ddr/index/abstract_query_result.rb +22 -0
  90. data/lib/ddr/index/connection.rb +38 -0
  91. data/lib/ddr/index/csv_query_result.rb +84 -0
  92. data/lib/ddr/index/document_builder.rb +9 -0
  93. data/lib/ddr/index/field.rb +35 -0
  94. data/lib/ddr/index/field_attribute.rb +22 -0
  95. data/lib/ddr/index/fields.rb +154 -0
  96. data/lib/ddr/index/filter.rb +139 -0
  97. data/lib/ddr/index/query.rb +82 -0
  98. data/lib/ddr/index/query_builder.rb +185 -0
  99. data/lib/ddr/index/query_clause.rb +112 -0
  100. data/lib/ddr/index/query_params.rb +40 -0
  101. data/lib/ddr/index/query_result.rb +102 -0
  102. data/lib/ddr/index/response.rb +30 -0
  103. data/lib/ddr/index/sort_order.rb +28 -0
  104. data/lib/ddr/index/unique_key_field.rb +12 -0
  105. data/lib/ddr/managers.rb +9 -0
  106. data/lib/ddr/managers/manager.rb +13 -0
  107. data/lib/ddr/managers/technical_metadata_manager.rb +141 -0
  108. data/lib/ddr/structure.rb +188 -0
  109. data/lib/ddr/structures/agent.rb +49 -0
  110. data/lib/ddr/structures/component_type_term.rb +29 -0
  111. data/lib/ddr/structures/div.rb +64 -0
  112. data/lib/ddr/structures/f_locat.rb +54 -0
  113. data/lib/ddr/structures/file.rb +52 -0
  114. data/lib/ddr/structures/file_grp.rb +35 -0
  115. data/lib/ddr/structures/file_sec.rb +22 -0
  116. data/lib/ddr/structures/fptr.rb +31 -0
  117. data/lib/ddr/structures/mets_hdr.rb +37 -0
  118. data/lib/ddr/structures/mptr.rb +49 -0
  119. data/lib/ddr/structures/struct_map.rb +40 -0
  120. data/lib/ddr/utils.rb +185 -0
  121. data/lib/ddr/vocab.rb +22 -0
  122. data/lib/ddr/vocab/asset.rb +51 -0
  123. data/lib/ddr/vocab/contact.rb +9 -0
  124. data/lib/ddr/vocab/display.rb +9 -0
  125. data/lib/ddr/vocab/duke_terms.rb +13 -0
  126. data/lib/ddr/vocab/rdf_vocabulary_parser.rb +43 -0
  127. data/lib/ddr/vocab/roles.rb +25 -0
  128. data/lib/ddr/vocab/sources/duketerms.rdf +870 -0
  129. data/lib/ddr/vocab/vocabulary.rb +37 -0
  130. data/lib/ddr/workflow.rb +8 -0
  131. data/lib/tasks/ddr/core_tasks.rake +4 -0
  132. metadata +428 -0
@@ -0,0 +1,29 @@
1
+ module Ddr::Structures
2
+ class ComponentTypeTerm
3
+
4
+ CONFIG_FILE = ::File.join(Rails.root, 'config', 'structure_component_type.yml')
5
+
6
+ @@lookup = {}
7
+
8
+ def self.term(media_type)
9
+ hit = lookup_table.detect { |k,v| media_type =~ k }
10
+ hit.last if hit
11
+ end
12
+
13
+ def self.lookup_table
14
+ load_lookup if @@lookup.empty?
15
+ @@lookup
16
+ end
17
+
18
+ def self.load_lookup
19
+ config = YAML::load(::File.read(CONFIG_FILE))
20
+ config.each do |type_term, media_types|
21
+ media_types.each do |media_type|
22
+ lookup_key = Regexp.new("\\A#{media_type.gsub('*', '.*')}\\Z")
23
+ @@lookup[lookup_key] = type_term
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,64 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'div' node
4
+ #
5
+ class Div < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def label
12
+ self['LABEL']
13
+ end
14
+
15
+ def order
16
+ self['ORDER']
17
+ end
18
+
19
+ def orderlabel
20
+ self['ORDERLABEL']
21
+ end
22
+
23
+ def type
24
+ self['TYPE']
25
+ end
26
+
27
+ def divs
28
+ xpath('xmlns:div').map { |node| Div.new(node) }
29
+ end
30
+
31
+ def fptrs
32
+ xpath('xmlns:fptr').map { |node| Fptr.new(node) }
33
+ end
34
+
35
+ def mptrs
36
+ xpath('xmlns:mptr').map { |node| Mptr.new(node) }
37
+ end
38
+
39
+ def <=>(other)
40
+ order.to_i <=> other.order.to_i
41
+ end
42
+
43
+ def dereferenced_hash
44
+ contents = []
45
+ contents.concat(divs.map { |div| div.dereferenced_hash }) unless divs.empty?
46
+ contents.concat(fptrs.map { |fptr| fptr.dereferenced_hash }) unless fptrs.empty?
47
+ contents.concat(mptrs.map { |mptr| mptr.dereferenced_hash }) unless mptrs.empty?
48
+ dh = { id: id, label: label, order: order, orderlabel: orderlabel, type: type }.compact
49
+ dh[:contents] = contents unless contents.empty?
50
+ dh
51
+ end
52
+
53
+ def self.build(args)
54
+ node = Nokogiri::XML::Node.new('div', args[:document])
55
+ node['ID'] = args[:id] if args[:id]
56
+ node['LABEL'] = args[:label] if args[:label]
57
+ node['ORDER'] = args[:order] if args[:order]
58
+ node['ORDERLABEL'] = args[:orderlabel] if args[:orderlabel]
59
+ node['TYPE'] = args[:type] if args[:type]
60
+ node
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,54 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'FLocat' node
4
+ #
5
+ class FLocat < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def loctype
12
+ self['LOCTYPE']
13
+ end
14
+
15
+ def otherloctype
16
+ self['OTHERLOCTYPE']
17
+ end
18
+
19
+ def use
20
+ self['USE']
21
+ end
22
+
23
+ def href
24
+ self['xlink:href']
25
+ end
26
+
27
+ def ark?
28
+ loctype == 'ARK'
29
+ end
30
+
31
+ def ark
32
+ href if ark?
33
+ end
34
+
35
+ def effective_use
36
+ use ? use : File.new(parent).effective_use
37
+ end
38
+
39
+ def repo_id
40
+ SolrDocument.find_by_permanent_id(ark).id if ark?
41
+ end
42
+
43
+ def self.build(args)
44
+ node = Nokogiri::XML::Node.new('FLocat', args[:document])
45
+ node['ID'] = args[:id] if args[:id]
46
+ node['LOCTYPE'] = args[:loctype] if args[:loctype]
47
+ node['OTHERLOCTYPE'] = args[:otherloctype] if args[:otherloctype]
48
+ node['USE'] = args[:use] if args[:use]
49
+ node['xlink:href'] = args[:href] if args[:href]
50
+ node
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,52 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'file' node
4
+ #
5
+ class File < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def use
12
+ self['USE']
13
+ end
14
+
15
+ def files
16
+ xpath('xmlns:file').map { |node| File.new(node) }
17
+ end
18
+
19
+ def flocats
20
+ xpath('xmlns:FLocat').map { |node| FLocat.new(node) }
21
+ end
22
+
23
+ def effective_use
24
+ if use
25
+ use
26
+ else
27
+ case parent.name
28
+ when "file"
29
+ File.new(parent).effective_use
30
+ when "fileGrp"
31
+ FileGrp.new(parent).effective_use
32
+ end
33
+ end
34
+ end
35
+
36
+ def repo_ids
37
+ flocats.map(&:repo_id)
38
+ end
39
+
40
+ def self.build(args)
41
+ node = Nokogiri::XML::Node.new('file', args[:document])
42
+ node['ID'] = args[:id] if args[:id]
43
+ node['USE'] = args[:use] if args[:use]
44
+ node
45
+ end
46
+
47
+ def self.find(structure, fileid)
48
+ structure.files[fileid]
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,35 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'fileGrp' node
4
+ #
5
+ class FileGrp < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def use
12
+ self['USE']
13
+ end
14
+
15
+ def filegrps
16
+ xpath('xmlns:filegrp').map { |node| FileGrp.new(node) }
17
+ end
18
+
19
+ def files
20
+ xpath('xmlns:file').map { |node| File.new(node) }
21
+ end
22
+
23
+ def effective_use
24
+ use
25
+ end
26
+
27
+ def self.build(args)
28
+ node = Nokogiri::XML::Node.new('fileGrp', args[:document])
29
+ node['ID'] = args[:id] if args[:id]
30
+ node['USE'] = args[:use] if args[:use]
31
+ node
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'fileSec' node
4
+ #
5
+ class FileSec < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def filegrps
12
+ xpath('xmlns:fileGrp').map { |node| FileGrp.new(node) }
13
+ end
14
+
15
+ def self.build(args)
16
+ node = Nokogiri::XML::Node.new('fileSec', args[:document])
17
+ node['ID'] = args[:id] if args[:id]
18
+ node
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'fptr' node
4
+ #
5
+ class Fptr < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def fileid
12
+ self['FILEID']
13
+ end
14
+
15
+ def dereferenced_hash
16
+ structure = Ddr::Structure.new(document)
17
+ file = File.find(structure, fileid)
18
+ repo_id = file.repo_ids.first
19
+ use = file.flocats.first.effective_use
20
+ { id: id, repo_id: repo_id, use: use }.compact
21
+ end
22
+
23
+ def self.build(args)
24
+ node = Nokogiri::XML::Node.new('fptr', args[:document])
25
+ node['ID'] = args[:id] if args[:id]
26
+ node['FILEID'] = args[:fileid] if args[:fileid]
27
+ node
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'metsHdr' node
4
+ #
5
+ class MetsHdr < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def createdate
12
+ self['CREATEDATE']
13
+ end
14
+
15
+ def lastmoddate
16
+ self['LASTMODDATE']
17
+ end
18
+
19
+ def recordstatus
20
+ self['RECORDSTATUS']
21
+ end
22
+
23
+ def agents
24
+ xpath('xmlns:agent').map { |node| Agent.new(node) }
25
+ end
26
+
27
+ def self.build(args)
28
+ node = Nokogiri::XML::Node.new('metsHdr', args[:document])
29
+ node['ID'] = args[:id] if args[:id]
30
+ node['CREATEDATE'] = args[:createdate] if args[:createdate]
31
+ node['LASTMODDATE'] = args[:lastmoddate] if args[:lastmoddate]
32
+ node['RECORDSTATUS'] = args[:recordstatus] if args[:recordstatus]
33
+ node
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,49 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'mptr' node
4
+ #
5
+ class Mptr < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def loctype
12
+ self['LOCTYPE']
13
+ end
14
+
15
+ def otherloctype
16
+ self['OTHERLOCTYPE']
17
+ end
18
+
19
+ def href
20
+ self['xlink:href']
21
+ end
22
+
23
+ def ark?
24
+ loctype == 'ARK'
25
+ end
26
+
27
+ def ark
28
+ href if ark?
29
+ end
30
+
31
+ def repo_id
32
+ SolrDocument.find_by_permanent_id(ark).id if ark?
33
+ end
34
+
35
+ def dereferenced_hash
36
+ { id: id, repo_id: repo_id }.compact
37
+ end
38
+
39
+ def self.build(args)
40
+ node = Nokogiri::XML::Node.new('mptr', args[:document])
41
+ node['ID'] = args[:id] if args[:id]
42
+ node['LOCTYPE'] = args[:loctype] if args[:loctype]
43
+ node['OTHERLOCTYPE'] = args[:otherloctype] if args[:otherloctype]
44
+ node['xlink:href'] = args[:href] if args[:href]
45
+ node
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,40 @@
1
+ module Ddr::Structures
2
+ #
3
+ # Wraps a Nokogiri (XML) 'structMap' node
4
+ #
5
+ class StructMap < SimpleDelegator
6
+
7
+ def id
8
+ self['ID']
9
+ end
10
+
11
+ def label
12
+ self['LABEL']
13
+ end
14
+
15
+ def type
16
+ self['TYPE']
17
+ end
18
+
19
+ def divs
20
+ xpath('xmlns:div').map { |node| Div.new(node) }
21
+ end
22
+
23
+ def dereferenced_hash
24
+ contents = []
25
+ contents.concat(divs.map { |div| div.dereferenced_hash }) unless divs.empty?
26
+ dh = { id: id, label: label, type: type }.compact
27
+ dh[:contents] = contents unless contents.empty?
28
+ dh
29
+ end
30
+
31
+ def self.build(args)
32
+ node = Nokogiri::XML::Node.new('structMap', args[:document])
33
+ node['ID'] = args[:id] if args[:id]
34
+ node['LABEL'] = args[:label] if args[:label]
35
+ node['TYPE'] = args[:type] if args[:type]
36
+ node
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,185 @@
1
+ require 'openssl'
2
+
3
+ module Ddr::Utils
4
+ extend Deprecation
5
+
6
+ def self.digest content, algorithm
7
+ raise TypeError, "Algorithm must be a string: #{algorithm.inspect}" unless algorithm.is_a?(String)
8
+ digest_class = OpenSSL::Digest.const_get(algorithm.sub("-", "").to_sym)
9
+ digest_class.new(content).to_s
10
+ rescue NameError => e
11
+ raise ArgumentError, "Invalid algorithm: #{algorithm}"
12
+ end
13
+
14
+ def self.file_or_path?(file)
15
+ file_path(file)
16
+ rescue ArgumentError
17
+ false
18
+ end
19
+
20
+ def self.file_path?(file)
21
+ # length is a sanity check
22
+ file.is_a?(String) && (file.length < 1024) && File.exist?(file)
23
+ end
24
+
25
+ def self.file_path(file)
26
+ if file.respond_to?(:path)
27
+ ::File.absolute_path(file.path)
28
+ elsif file_path?(file)
29
+ file
30
+ else
31
+ raise ArgumentError, "Argument is neither a File nor a path to an existing file."
32
+ end
33
+ end
34
+
35
+ def self.file_name_for(file)
36
+ if file.respond_to?(:original_filename) && file.original_filename.present?
37
+ file.original_filename
38
+ else
39
+ File.basename file_path(file)
40
+ end
41
+ end
42
+
43
+ def self.file_uri?(uri)
44
+ return false unless uri
45
+ URI.parse(uri).scheme == "file"
46
+ end
47
+
48
+ def self.sanitize_filename(file_name)
49
+ return unless file_name
50
+ raise ArgumentError, "file_name argument must be a string" unless file_name.is_a?(String)
51
+ raise ArgumentError, "file_name argument must not include path" if file_name.include?(File::SEPARATOR)
52
+ file_name.gsub(/[^\w\.\-]/,"_")
53
+ end
54
+
55
+ # Return file path for URI string
56
+ # Should reverse .path_to_uri
57
+ # "file:/path/to/file" => "/path/to/file"
58
+ # @param uri [String] The URI string to pathify
59
+ # @return [String] the file path
60
+ def self.path_from_uri(uri_string)
61
+ uri = URI.parse(uri_string)
62
+ unless uri.scheme == "file"
63
+ raise ArgumentError, "URI does not have the file: scheme."
64
+ end
65
+ URI.unescape(uri.path)
66
+ end
67
+
68
+ # Return URI string for file path
69
+ # Should reverse .path_from_uri
70
+ # "/path/to/file" => "file:/path/to/file"
71
+ # @param path [String] the file path
72
+ # @return [String] the file: URI string
73
+ def self.path_to_uri(path)
74
+ uri = URI.parse URI.escape(path)
75
+ uri.scheme = "file"
76
+ uri.to_s
77
+ end
78
+
79
+ def self.ds_as_of_date_time(ds)
80
+ ds.create_date_string
81
+ end
82
+
83
+ ### DDRevo ################################
84
+ # Needs replacements for ActiveFedora::Base.find_each call.
85
+ ### DDRevo ################################
86
+ # # # Find an object with a given identifier and return its PID.
87
+ # # Returns the PID if a single object is found.
88
+ # # Returns nil if no object is found.
89
+ # # Raises Ddr::Models::Error if more than one object is found.
90
+ # # Options can be provided to limit the scope of matching objects
91
+ # # model: Will only consider objects of that model
92
+ # # collection: Will only consider objects that either are that collection or which are
93
+ # # direct children of that collection (i.e., effectively searches a collection and its
94
+ # # items for an object with the given identifier)
95
+ # def self.pid_for_identifier(identifier, opts={})
96
+ # model = opts.fetch(:model, nil)
97
+ # collection = opts.fetch(:collection, nil)
98
+ # objs = []
99
+ # ActiveFedora::Base.find_each( { Ddr::Index::Fields::IDENTIFIER_ALL => identifier }, { :cast => true } ) { |o| objs << o }
100
+ # pids = []
101
+ # objs.each { |obj| pids << obj.pid }
102
+ # if model.present?
103
+ # objs.each { |obj| pids.delete(obj.pid) unless obj.is_a?(model.constantize) }
104
+ # end
105
+ # if collection.present?
106
+ # objs.each do |obj|
107
+ # pids.delete(obj.pid) unless obj == collection || obj.parent == collection
108
+ # end
109
+ # end
110
+ # case pids.size
111
+ # when 0
112
+ # nil
113
+ # when 1
114
+ # pids.first
115
+ # else
116
+ # raise Ddr::Models::Error, I18n.t('ddr.errors.multiple_object_matches', :criteria => "identifier #{identifier}")
117
+ # end
118
+ # end
119
+
120
+ ### DDRevo ################################
121
+ # This probably isn't relevant in DDRevo context.
122
+ ### DDRevo ################################
123
+ # # Returns the reflection object for a given model name and relationship name
124
+ # # E.g., relationship_object_reflection("Item", "parent") returns the reflection object for
125
+ # # an Item's parent relationship. This reflection object can then be used to obtain the
126
+ # # class of the relationship object using the reflection_object_class(reflection) method below.
127
+ # def self.relationship_object_reflection(model, relationship_name)
128
+ # reflection = nil
129
+ # if model
130
+ # begin
131
+ # reflections = model.constantize.reflections
132
+ # rescue NameError
133
+ # # nothing to do here except that we can't return the appropriate reflection
134
+ # else
135
+ # reflections.each do |reflect|
136
+ # if reflect[0].eql?(relationship_name.to_sym)
137
+ # reflection = reflect
138
+ # end
139
+ # end
140
+ # end
141
+ # end
142
+ # return reflection
143
+ # end
144
+
145
+ ### DDRevo ################################
146
+ # This probably isn't relevant in DDRevo context.
147
+ ### DDRevo ################################
148
+ # # Returns the class associated with the :class_name attribute in the options of a reflection
149
+ # # E.g., reflection_object_class(relationship_object_reflection("Item", "parent")) returns the
150
+ # # Collection class.
151
+ # def self.reflection_object_class(reflection)
152
+ # reflection_object_model = nil
153
+ # klass = nil
154
+ # if reflection[1].options[:class_name]
155
+ # reflection_object_model = reflection[1].options[:class_name]
156
+ # else
157
+ # reflection_object_model = ActiveSupport::Inflector.camelize(reflection[0])
158
+ # end
159
+ # if reflection_object_model
160
+ # begin
161
+ # klass = reflection_object_model.constantize
162
+ # rescue NameError
163
+ # # nothing to do here except that we can't return the reflection object class
164
+ # end
165
+ # end
166
+ # return klass
167
+ # end
168
+
169
+ # Returns a string suitable to index as a Solr date
170
+ # @param dt [Date, DateTime, Time] the date/time
171
+ # @return [String]
172
+ def self.solr_date(dt)
173
+ return if dt.nil?
174
+ dt.to_time.utc.iso8601
175
+ end
176
+
177
+ def self.solr_dates(dts)
178
+ dts.map { |dt| solr_date(dt) }
179
+ end
180
+
181
+ class << self
182
+ alias_method :file_name, :file_name_for
183
+ end
184
+
185
+ end