ddr-core 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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,84 @@
1
+ require "csv"
2
+
3
+ module Ddr::Index
4
+ class CSVQueryResult < AbstractQueryResult
5
+
6
+ MAX_ROWS = 10**8 # Just set to a really high number :)
7
+ CSV_MV_SEPARATOR = ";"
8
+
9
+ delegate :headers, :to_s, :to_csv, to: :table
10
+
11
+ def delete_empty_columns!
12
+ table.by_col!.delete_if { |c, vals| vals.all?(&:nil?) }
13
+ end
14
+
15
+ def each(&block)
16
+ table.by_row!.each(&block)
17
+ end
18
+
19
+ def [](index_or_header)
20
+ table.by_col_or_row![index_or_header]
21
+ end
22
+
23
+ def table
24
+ @table ||= CSV.parse(data, csv_opts)
25
+ end
26
+
27
+ def csv_opts
28
+ { headers: csv_headers,
29
+ converters: [convert_semicolons, convert_escaped_newlines],
30
+ return_headers: false,
31
+ write_headers: true,
32
+ }
33
+ end
34
+
35
+ def solr_csv_opts
36
+ { "csv.mv.separator" => CSV_MV_SEPARATOR,
37
+ "csv.header" => solr_csv_header?,
38
+ "rows" => solr_csv_rows,
39
+ "wt" => "csv",
40
+ }
41
+ end
42
+
43
+ def query_field_headings
44
+ query.fields.map { |f| f.respond_to?(:heading) ? f.heading : f.to_s }
45
+ end
46
+
47
+ def csv_headers
48
+ :first_row
49
+ end
50
+
51
+ def solr_csv_header?
52
+ query.fields.empty?
53
+ end
54
+
55
+ def solr_csv_rows
56
+ query.rows || MAX_ROWS
57
+ end
58
+
59
+ def solr_csv_params
60
+ params.merge(solr_csv_opts)
61
+ end
62
+
63
+ def data
64
+ if solr_csv_header?
65
+ solr_data
66
+ else
67
+ [ query_field_headings.join(","), solr_data ].join("\n")
68
+ end
69
+ end
70
+
71
+ def solr_data
72
+ Connection.get("select", params: solr_csv_params)
73
+ end
74
+
75
+ def convert_semicolons
76
+ lambda { |f| f.gsub(/\\#{CSV_MV_SEPARATOR}/, CSV_MV_SEPARATOR) rescue f }
77
+ end
78
+
79
+ def convert_escaped_newlines
80
+ lambda { |f| f.gsub(/\\r/, "\r").gsub(/\\n/, "\n") rescue f }
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,9 @@
1
+ module Ddr::Index
2
+ class DocumentBuilder
3
+
4
+ def self.build(doc)
5
+ ::SolrDocument.new(doc)
6
+ end
7
+
8
+ end
9
+ end
@@ -0,0 +1,35 @@
1
+ require 'solrizer'
2
+
3
+ module Ddr::Index
4
+ class Field < SimpleDelegator
5
+
6
+ attr_reader :base
7
+
8
+ def initialize(base, *args)
9
+ @base = base.to_s
10
+ name = if args.empty?
11
+ @base
12
+ elsif args.last.is_a?(Hash) && args.last[:solr_name]
13
+ args.last[:solr_name]
14
+ else
15
+ Solrizer.solr_name(base, *args)
16
+ end
17
+ super(name)
18
+ end
19
+
20
+ def label
21
+ I18n.t "#{i18n_base}.label", default: base.titleize
22
+ end
23
+
24
+ def heading
25
+ I18n.t "#{i18n_base}.heading", default: base
26
+ end
27
+
28
+ private
29
+
30
+ def i18n_base
31
+ "ddr.index.fields.#{base}"
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ require "virtus"
2
+
3
+ module Ddr::Index
4
+ class FieldAttribute < Virtus::Attribute
5
+
6
+ def self.coerce(value)
7
+ case value
8
+ when Field
9
+ value
10
+ when String
11
+ Field.new(value)
12
+ when Symbol
13
+ Fields.get(value)
14
+ end
15
+ end
16
+
17
+ def coerce(value)
18
+ self.class.coerce(value)
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,154 @@
1
+ module Ddr::Index
2
+ module Fields
3
+
4
+ ID = UniqueKeyField.instance
5
+
6
+ ACCESS_ROLE = Field.new :access_role, :stored_sortable
7
+ ADMIN_POLICY_ID = Field.new :admin_policy_id, :symbol
8
+ ADMIN_SET = Field.new :admin_set, :stored_sortable
9
+ ADMIN_SET_FACET = Field.new :admin_set_facet, :facetable
10
+ ADMIN_SET_TITLE = Field.new :admin_set_title, :stored_sortable
11
+ AFFILIATION = Field.new :affiliation, :stored_searchable
12
+ AFFILIATION_FACET = Field.new :affiliation_facet, :facetable
13
+ ALEPH_ID = Field.new :aleph_id, :stored_sortable
14
+ ALL_TEXT = Field.new :all_text, solr_name: "all_text_timv"
15
+ ARRANGER_FACET = Field.new :arranger_facet, :facetable
16
+ ASPACE_ID = Field.new :aspace_id, :stored_sortable
17
+ ATTACHED_FILES_HAVING_CONTENT = Field.new :attached_files_having_content, :symbol
18
+ ATTACHED_TO_ID = Field.new :attached_to_id, :symbol
19
+ BIBLICAL_BOOK_FACET = Field.new :biblical_book_facet, :facetable
20
+ BOX_NUMBER_FACET = Field.new :box_number_facet, :facetable
21
+ CATEGORY_FACET = Field.new :category_facet, :facetable
22
+ CHAPTER_AND_VERSE_FACET = Field.new :chapter_and_verse_facet, :facetable
23
+ COLLECTION_FACET = Field.new :collection_facet, :facetable
24
+ COLLECTION_ID = Field.new :collection_id, :symbol
25
+ COLLECTION_TITLE = Field.new :collection_title, :stored_sortable
26
+ COMMON_MODEL_NAME = Field.new :common_model_name, :stored_sortable
27
+ COMPANY_FACET = Field.new :company_facet, :facetable
28
+ COMPOSER_FACET = Field.new :composer_facet, :facetable
29
+ CONTENT_CREATE_DATE = Field.new :content_create_date, :stored_sortable, type: :date
30
+ CONTENT_SIZE = Field.new :content_size, solr_name: "content_size_lsi"
31
+ CONTENT_SIZE_HUMAN = Field.new :content_size_human, :symbol
32
+ CONTRIBUTOR_FACET = Field.new :contributor_facet, :facetable
33
+ CREATOR_FACET = Field.new :creator_facet, :facetable
34
+ DATE_FACET = Field.new :date_facet, :facetable
35
+ DATE_SORT = Field.new :date_sort, :sortable
36
+ DC_IS_PART_OF = Field.new :isPartOf, :symbol
37
+ DEPOSITOR = Field.new :depositor, :stored_sortable
38
+ DISPLAY_FORMAT = Field.new :display_format, :stored_sortable
39
+ DOI = Field.new :doi, :symbol
40
+ EAD_ID = Field.new :ead_id, :stored_sortable
41
+ ENGRAVER_FACET = Field.new :engraver_facet, :facetable
42
+ EXTRACTED_TEXT = Field.new :extracted_text, solr_name: "extracted_text_tsm"
43
+ FOLDER_FACET = Field.new :folder_facet, :facetable
44
+ FOR_COLLECTION_ID = Field.new :for_collection_id, :symbol
45
+ FORMAT_FACET = Field.new :format_facet, :facetable
46
+ GENRE_FACET = Field.new :genre_facet, :facetable
47
+ IDENTIFIER_ALL = Field.new :identifier_all, :symbol
48
+ ILLUSTRATED_FACET = Field.new :illustrated_facet, :facetable
49
+ ILLUSTRATOR_FACET = Field.new :illustrator_facet, :facetable
50
+ INGESTED_BY = Field.new :ingested_by, :stored_sortable
51
+ INGESTION_DATE = Field.new :ingestion_date, :stored_sortable, type: :date
52
+ INSTRUMENTATION_FACET = Field.new :instrumentation_facet, :facetable
53
+ INTERVIEWER_NAME_FACET = Field.new :interviewer_name_facet, :facetable
54
+ IS_FORMAT_OF = Field.new :isFormatOf, :symbol
55
+ IS_LOCKED = Field.new :is_locked, :stored_sortable
56
+ # Keeping IS_MEMBER_OF_COLLECTION and IS_PART_OF for now for backwards compatibility
57
+ IS_MEMBER_OF_COLLECTION = Field.new :is_member_of_collection, :symbol
58
+ IS_PART_OF = Field.new :is_part_of, :symbol
59
+ LANGUAGE_FACET = Field.new :language_facet, :facetable
60
+ LANGUAGE_NAME = Field.new :language_name, :stored_searchable
61
+ LAST_FIXITY_CHECK_ON = Field.new :last_fixity_check_on, :stored_sortable, type: :date
62
+ LAST_FIXITY_CHECK_OUTCOME = Field.new :last_fixity_check_outcome, :symbol
63
+ LAST_VIRUS_CHECK_ON = Field.new :last_virus_check_on, :stored_sortable, type: :date
64
+ LAST_VIRUS_CHECK_OUTCOME = Field.new :last_virus_check_outcome, :symbol
65
+ LICENSE = Field.new :license, :stored_sortable
66
+ LITHOGRAPHER_FACET = Field.new :lithographer_facet, :facetable
67
+ LOCAL_ID = Field.new :local_id, :stored_sortable
68
+ LYRICIST_FACET = Field.new :lyricist_facet, :facetable
69
+ MEDIA_SUB_TYPE = Field.new :content_media_sub_type, :facetable
70
+ MEDIA_MAJOR_TYPE = Field.new :content_media_major_type, :facetable
71
+ MEDIA_TYPE = Field.new :content_media_type, :symbol
72
+ MEDIUM_FACET = Field.new :medium_facet, :facetable
73
+ MULTIRES_IMAGE_FILE_PATH = Field.new :multires_image_file_path, :stored_sortable
74
+ NESTED_PATH = Field.new :nested_path, :stored_sortable
75
+ NESTED_PATH_TEXT = Field.new :nested_path_text, :searchable
76
+ ORIGINAL_FILENAME = Field.new :original_filename, :stored_sortable
77
+ PARENT_ID = Field.new :parent_id, :symbol
78
+ PERFORMER_FACET = Field.new :performer_facet, :facetable
79
+ PERMANENT_ID = Field.new :permanent_id, :stored_sortable
80
+ PERMANENT_URL = Field.new :permanent_url, :stored_sortable
81
+ PLACEMENT_COMPANY_FACET = Field.new :placement_company_facet, :facetable
82
+ POLICY_ROLE = Field.new :policy_role, :symbol
83
+ PRODUCER_FACET = Field.new :producer_facet, :facetable
84
+ PRODUCT_FACET = Field.new :product_facet, :facetable
85
+ PUBLICATION_FACET = Field.new :publication_facet, :facetable
86
+ PUBLISHER_FACET = Field.new :publisher_facet, :facetable
87
+ RESEARCH_HELP_CONTACT = Field.new :research_help_contact, :stored_sortable
88
+ RESOURCE_CREATE_DATE = Field.new :created_at, :stored_sortable, type: :date
89
+ RESOURCE_MODEL = Field.new :resource_model, solr_name: "internal_resource_ssim"
90
+ RESOURCE_MODIFIED_DATE = Field.new :updated_at, :stored_sortable, type: :date
91
+ RESOURCE_ROLE = Field.new :resource_role, :symbol
92
+ RIGHTS_NOTE = Field.new :rights_note, :stored_searchable
93
+ ROLL_NUMBER_FACET = Field.new :roll_number_facet, :facetable
94
+ SERIES_FACET = Field.new :series_facet, :facetable
95
+ SETTING_FACET = Field.new :setting_facet, :facetable
96
+ SPATIAL_FACET = Field.new :spatial_facet, :facetable
97
+ STREAMABLE_MEDIA_TYPE = Field.new :streamable_media_type, :stored_sortable
98
+ STRUCTURE = Field.new :structure, solr_name: "structure_ss"
99
+ STRUCTURE_SOURCE = Field.new :structure_source, :stored_sortable
100
+ SUBJECT_FACET = Field.new :subject_facet, :facetable
101
+ SUBSERIES_FACET = Field.new :subseries_facet, :facetable
102
+ TARGET_ID = Field.new :target_id, :symbol
103
+ TECHMD_COLOR_SPACE = Field.new :techmd_color_space, :symbol
104
+ TECHMD_CREATING_APPLICATION = Field.new :techmd_creating_application, :symbol
105
+ TECHMD_CREATION_TIME = Field.new :techmd_creation_time, :stored_searchable, type: :date
106
+ TECHMD_FILE_SIZE = Field.new :techmd_file_size, solr_name: "techmd_file_size_lsi"
107
+ TECHMD_FITS_VERSION = Field.new :techmd_fits_version, :stored_sortable
108
+ TECHMD_FITS_DATETIME = Field.new :techmd_fits_datetime, :stored_sortable, type: :date
109
+ TECHMD_FORMAT_LABEL = Field.new :techmd_format_label, :symbol
110
+ TECHMD_FORMAT_VERSION = Field.new :techmd_format_version, :symbol
111
+ TECHMD_ICC_PROFILE_NAME = Field.new :techmd_icc_profile_name, :symbol
112
+ TECHMD_ICC_PROFILE_VERSION = Field.new :techmd_icc_profile_version, :symbol
113
+ TECHMD_IMAGE_HEIGHT = Field.new :techmd_image_height, :stored_searchable, type: :integer
114
+ TECHMD_IMAGE_WIDTH = Field.new :techmd_image_width, :stored_searchable, type: :integer
115
+ TECHMD_MD5 = Field.new :techmd_md5, :stored_sortable
116
+ TECHMD_MEDIA_TYPE = Field.new :techmd_media_type, :symbol
117
+ TECHMD_MODIFICATION_TIME = Field.new :techmd_modification_time, :stored_searchable, type: :date
118
+ TECHMD_PRONOM_IDENTIFIER = Field.new :techmd_pronom_identifier, :symbol
119
+ TECHMD_VALID = Field.new :techmd_valid, :symbol
120
+ TECHMD_WELL_FORMED = Field.new :techmd_well_formed, :symbol
121
+ TEMPORAL_FACET = Field.new :temporal_facet, :facetable
122
+ TITLE = Field.new :title, :stored_sortable
123
+ TONE_FACET = Field.new :tone_facet, :facetable
124
+ TYPE_FACET = Field.new :type_facet, :facetable
125
+ VOLUME_FACET = Field.new :volume_facet, :facetable
126
+ WORKFLOW_STATE = Field.new :workflow_state, :stored_sortable
127
+ YEAR_FACET = Field.new :year_facet, solr_name: "year_facet_iim"
128
+
129
+ def self.get(name)
130
+ const_get(name.to_s.upcase, false)
131
+ end
132
+
133
+ def self.techmd
134
+ @techmd ||= constants(false).select { |c| c =~ /\ATECHMD_/ }.map { |c| const_get(c) }.freeze
135
+ end
136
+
137
+ def self.descmd
138
+ @descmd ||= Ddr::Describable.term_names.map do |term_name|
139
+ Field.new term_name, *Ddr::Describable.indexers_for(term_name)
140
+ end.freeze
141
+ end
142
+
143
+ def self.adminmd
144
+ @adminmd ||= Ddr::HasAdminMetadata.term_names.map do |term_name|
145
+ begin
146
+ get(term_name)
147
+ rescue NameError
148
+ Field.new term_name
149
+ end
150
+ end.freeze
151
+ end
152
+
153
+ end
154
+ end
@@ -0,0 +1,139 @@
1
+ require "forwardable"
2
+ require "virtus"
3
+
4
+ module Ddr::Index
5
+ class Filter
6
+ include Virtus.model
7
+
8
+ attribute :clauses, Array, default: [ ]
9
+
10
+ def ==(other)
11
+ other.instance_of?(self.class) && (other.clauses == self.clauses)
12
+ end
13
+
14
+ module Api
15
+ def raw(*clauses)
16
+ self.clauses += clauses
17
+ self
18
+ end
19
+
20
+ def term(conditions)
21
+ self.clauses += conditions.map { |f, v| QueryClause.term(f, v) }
22
+ self
23
+ end
24
+
25
+ def where(conditions)
26
+ self.clauses += conditions.map { |f, v| QueryClause.where(f, v) }
27
+ self
28
+ end
29
+
30
+ def where_not(conditions)
31
+ self.clauses += conditions.map do |field, v|
32
+ Array(v).map { |value| QueryClause.negative(field, value) }
33
+ end.flatten
34
+ self
35
+ end
36
+
37
+ def absent(field)
38
+ self.clauses << QueryClause.absent(field)
39
+ self
40
+ end
41
+
42
+ def present(field)
43
+ self.clauses << QueryClause.present(field)
44
+ self
45
+ end
46
+
47
+ def negative(field, value)
48
+ self.clauses << QueryClause.negative(field, value)
49
+ self
50
+ end
51
+
52
+ def before(field, value)
53
+ self.clauses << QueryClause.before(field, value)
54
+ self
55
+ end
56
+
57
+ def before_days(field, value)
58
+ self.clauses << QueryClause.before_days(field, value)
59
+ self
60
+ end
61
+
62
+ def join(**args)
63
+ self.clauses << QueryClause.join(**args)
64
+ self
65
+ end
66
+
67
+ def regexp(field, value)
68
+ self.clauses << QueryClause.regexp(field, value)
69
+ self
70
+ end
71
+ end
72
+
73
+ module ClassMethods
74
+ extend Forwardable
75
+
76
+ delegate Api.public_instance_methods => :new_filter
77
+
78
+ def has_content
79
+ model "Ddr::Component", "Ddr::Attachment", "Ddr::Target"
80
+ end
81
+
82
+ def is_governed_by(arg)
83
+ term admin_policy_id: get_join_id(arg)
84
+ end
85
+
86
+ def is_member_of_collection(arg)
87
+ term is_member_of_collection: get_id(arg)
88
+ end
89
+
90
+ def is_part_of(arg)
91
+ term is_part_of: get_id(arg)
92
+ end
93
+
94
+ def model(*models)
95
+ namespaced_models = models.map{ |model| model.starts_with?("Ddr::") ? model : "Ddr::#{model}" }
96
+ where resource_model: namespaced_models
97
+ end
98
+
99
+ private
100
+
101
+ # def get_uri(arg)
102
+ # case arg
103
+ # when ActiveFedora::Base
104
+ # arg.internal_uri
105
+ # when String
106
+ # arg.start_with?("info:fedora/") ? arg : "info:fedora/#{arg}"
107
+ # else
108
+ # raise TypeError, "Argument must be a String or ActiveFedora::Base instance: #{arg.class}"
109
+ # end
110
+ # end
111
+
112
+ def get_id(arg)
113
+ case arg
114
+ when Ddr::Resource
115
+ arg.id.to_s
116
+ when Valkyrie::ID
117
+ arg.to_s
118
+ when String
119
+ arg
120
+ else
121
+ raise TypeError, "Argument must be a String or Ddr::Resource or Valkyrie::ID instance: #{arg.class}"
122
+ end
123
+ end
124
+
125
+ def get_join_id(arg)
126
+ "id-#{get_id(arg)}"
127
+ end
128
+
129
+ def new_filter
130
+ Filter.new
131
+ end
132
+
133
+ end
134
+
135
+ include Api
136
+ extend ClassMethods
137
+
138
+ end
139
+ end