qa 3.1.0 → 4.0.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 (95) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +16 -548
  3. data/app/controllers/qa/linked_data_terms_controller.rb +64 -42
  4. data/app/controllers/qa/terms_controller.rb +14 -6
  5. data/app/models/qa/iri_template/url_config.rb +47 -0
  6. data/app/models/qa/iri_template/variable_map.rb +62 -0
  7. data/app/models/qa/linked_data/config/context_map.rb +77 -0
  8. data/app/models/qa/linked_data/config/context_property_map.rb +144 -0
  9. data/app/models/qa/linked_data/config/helper.rb +34 -0
  10. data/app/services/qa/iri_template_service.rb +31 -0
  11. data/{lib/qa/authorities → app/services/qa}/linked_data/authority_service.rb +3 -4
  12. data/app/services/qa/linked_data/authority_url_service.rb +48 -0
  13. data/app/services/qa/linked_data/deep_sort_service.rb +238 -0
  14. data/app/services/qa/linked_data/graph_service.rb +106 -0
  15. data/app/services/qa/linked_data/language_service.rb +30 -0
  16. data/app/services/qa/linked_data/language_sort_service.rb +81 -0
  17. data/app/services/qa/linked_data/mapper/context_mapper_service.rb +59 -0
  18. data/app/services/qa/linked_data/mapper/graph_mapper_service.rb +40 -0
  19. data/app/services/qa/linked_data/mapper/search_results_mapper_service.rb +70 -0
  20. data/config/authorities/linked_data/loc.json +5 -2
  21. data/config/authorities/linked_data/oclc_fast.json +3 -2
  22. data/config/initializers/linked_data_authorities.rb +1 -1
  23. data/config/locales/qa.en.yml +9 -0
  24. data/lib/generators/qa/install/templates/config/initializers/qa.rb +4 -0
  25. data/lib/qa.rb +8 -0
  26. data/lib/qa/authorities/assign_fast/generic_authority.rb +1 -1
  27. data/lib/qa/authorities/base.rb +0 -11
  28. data/lib/qa/authorities/crossref/generic_authority.rb +1 -1
  29. data/lib/qa/authorities/geonames.rb +1 -1
  30. data/lib/qa/authorities/getty/aat.rb +7 -2
  31. data/lib/qa/authorities/getty/tgn.rb +7 -2
  32. data/lib/qa/authorities/getty/ulan.rb +7 -2
  33. data/lib/qa/authorities/linked_data.rb +0 -1
  34. data/lib/qa/authorities/linked_data/config.rb +29 -28
  35. data/lib/qa/authorities/linked_data/config/search_config.rb +21 -79
  36. data/lib/qa/authorities/linked_data/config/term_config.rb +7 -77
  37. data/lib/qa/authorities/linked_data/find_term.rb +25 -17
  38. data/lib/qa/authorities/linked_data/generic_authority.rb +6 -5
  39. data/lib/qa/authorities/linked_data/rdf_helper.rb +6 -73
  40. data/lib/qa/authorities/linked_data/search_query.rb +54 -101
  41. data/lib/qa/authorities/loc/generic_authority.rb +4 -4
  42. data/lib/qa/authorities/web_service_base.rb +1 -8
  43. data/lib/qa/configuration.rb +7 -0
  44. data/lib/qa/version.rb +1 -1
  45. data/lib/tasks/mesh.rake +19 -18
  46. data/spec/controllers/linked_data_terms_controller_spec.rb +51 -1
  47. data/spec/controllers/terms_controller_spec.rb +15 -15
  48. data/spec/fixtures/authorities/linked_data/lod_encoding_config.json +2 -1
  49. data/spec/fixtures/authorities/linked_data/lod_full_config.json +56 -2
  50. data/spec/fixtures/authorities/linked_data/lod_full_config_1_0.json +164 -0
  51. data/spec/fixtures/authorities/linked_data/lod_lang_defaults.json +5 -4
  52. data/spec/fixtures/authorities/linked_data/lod_lang_multi_defaults.json +3 -2
  53. data/spec/fixtures/authorities/linked_data/lod_lang_no_defaults.json +3 -2
  54. data/spec/fixtures/authorities/linked_data/lod_lang_param.json +3 -2
  55. data/spec/fixtures/authorities/linked_data/lod_min_config.json +3 -2
  56. data/spec/fixtures/authorities/linked_data/lod_search_only_config.json +2 -1
  57. data/spec/fixtures/authorities/linked_data/lod_sort.json +2 -1
  58. data/spec/fixtures/authorities/linked_data/lod_term_id_param_config.json +2 -1
  59. data/spec/fixtures/authorities/linked_data/lod_term_only_config.json +2 -1
  60. data/spec/fixtures/authorities/linked_data/lod_term_uri_param_config.json +2 -1
  61. data/spec/fixtures/getty-error-response.txt +10 -0
  62. data/spec/fixtures/lod_2_ranked_2_unranked.nt +17 -0
  63. data/spec/fixtures/lod_3_ranked_varying_preds.nt +16 -0
  64. data/spec/fixtures/lod_lang_search_filtering.nt +11 -0
  65. data/spec/fixtures/lod_search_with_blanknode_subjects.nt +18 -0
  66. data/spec/fixtures/lod_term_with_blanknode_objects.nt +8 -0
  67. data/spec/lib/authorities/assign_fast_spec.rb +1 -0
  68. data/spec/lib/authorities/getty/aat_spec.rb +14 -2
  69. data/spec/lib/authorities/getty/tgn_spec.rb +14 -2
  70. data/spec/lib/authorities/getty/ulan_spec.rb +14 -2
  71. data/spec/lib/authorities/linked_data/authority_service_spec.rb +2 -1
  72. data/spec/lib/authorities/linked_data/config_spec.rb +284 -5
  73. data/spec/lib/authorities/linked_data/find_term_spec.rb +3 -1
  74. data/spec/lib/authorities/linked_data/generic_authority_spec.rb +92 -42
  75. data/spec/lib/authorities/linked_data/search_config_spec.rb +67 -160
  76. data/spec/lib/authorities/linked_data/search_query_spec.rb +3 -127
  77. data/spec/lib/authorities/linked_data/term_config_spec.rb +6 -134
  78. data/spec/lib/authorities/loc_spec.rb +9 -9
  79. data/spec/lib/configuration_spec.rb +20 -7
  80. data/spec/lib/tasks/mesh.rake_spec.rb +2 -2
  81. data/spec/models/iri_template/url_config_spec.rb +102 -0
  82. data/spec/models/iri_template/variable_map_spec.rb +105 -0
  83. data/spec/models/linked_data/config/context_map_spec.rb +148 -0
  84. data/spec/models/linked_data/config/context_property_map_spec.rb +286 -0
  85. data/spec/services/iri_template_service_spec.rb +69 -0
  86. data/spec/services/linked_data/authority_url_service_spec.rb +107 -0
  87. data/spec/services/linked_data/deep_sort_service_spec.rb +260 -0
  88. data/spec/services/linked_data/graph_service_spec.rb +232 -0
  89. data/spec/services/linked_data/language_service_spec.rb +66 -0
  90. data/spec/services/linked_data/language_sort_service_spec.rb +58 -0
  91. data/spec/services/linked_data/mapper/context_mapper_service_spec.rb +137 -0
  92. data/spec/services/linked_data/mapper/graph_mapper_service_spec.rb +110 -0
  93. data/spec/services/linked_data/mapper/search_results_mapper_service_spec.rb +109 -0
  94. data/spec/spec_helper.rb +10 -2
  95. metadata +81 -11
@@ -7,7 +7,7 @@ module Qa::Authorities
7
7
  end
8
8
 
9
9
  def build_query_url(q)
10
- query = URI.escape(sparql(untaint(q)))
10
+ query = ERB::Util.url_encode(sparql(untaint(q)))
11
11
  # Replace ampersands, otherwise the query will fail
12
12
  # Gsub hack to convert the encoded regex in the REPLACE into a form Getty understands
13
13
  "http://vocab.getty.edu/sparql.json?query=#{query.gsub('&', '%26').gsub(',[%5E,]+,[%5E,]+$', '%2C[^%2C]%2B%2C[^%2C]%2B%24')}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
@@ -44,7 +44,7 @@ module Qa::Authorities
44
44
  end
45
45
 
46
46
  def find_url(id)
47
- "http://vocab.getty.edu/tgn/#{id}.json"
47
+ "http://vocab.getty.edu/download/json?uri=http://vocab.getty.edu/tgn/#{id}.json"
48
48
  end
49
49
 
50
50
  def request_options
@@ -59,6 +59,11 @@ module Qa::Authorities
59
59
  response['results']['bindings'].map do |result|
60
60
  { 'id' => result['s']['value'], 'label' => result['name']['value'] + ' (' + result['par']['value'].gsub(/\,[^\,]+\,[^\,]+$/, '') + ')' }
61
61
  end
62
+ rescue StandardError => e
63
+ cause = response.fetch('error', {}).fetch('cause', 'UNKNOWN')
64
+ cause = cause.present? ? cause : 'UNKNOWN'
65
+ Rails.logger.warn " ERROR fetching Getty response: #{e.message}; cause: #{cause}"
66
+ {}
62
67
  end
63
68
  end
64
69
  end
@@ -8,7 +8,7 @@ module Qa::Authorities
8
8
 
9
9
  # Replace ampersands, otherwise the query will fail
10
10
  def build_query_url(q)
11
- "http://vocab.getty.edu/sparql.json?query=#{URI.escape(sparql(q)).gsub('&', '%26')}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
11
+ "http://vocab.getty.edu/sparql.json?query=#{ERB::Util.url_encode(sparql(q)).gsub('&', '%26')}&_implicit=false&implicit=true&_equivalent=false&_form=%2Fsparql"
12
12
  end
13
13
 
14
14
  def sparql(q) # rubocop:disable Metrics/MethodLength
@@ -42,7 +42,7 @@ module Qa::Authorities
42
42
  end
43
43
 
44
44
  def find_url(id)
45
- "http://vocab.getty.edu/ulan/#{id}.json"
45
+ "http://vocab.getty.edu/download/json?uri=http://vocab.getty.edu/ulan/#{id}.json"
46
46
  end
47
47
 
48
48
  def request_options
@@ -57,6 +57,11 @@ module Qa::Authorities
57
57
  response['results']['bindings'].map do |result|
58
58
  { 'id' => result['s']['value'], 'label' => result['name']['value'] + ' (' + result['bio']['value'] + ')' }
59
59
  end
60
+ rescue StandardError => e
61
+ cause = response.fetch('error', {}).fetch('cause', 'UNKNOWN')
62
+ cause = cause.present? ? cause : 'UNKNOWN'
63
+ Rails.logger.warn " ERROR fetching Getty response: #{e.message}; cause: #{cause}"
64
+ {}
60
65
  end
61
66
  end
62
67
  end
@@ -3,7 +3,6 @@ module Qa::Authorities
3
3
  extend ActiveSupport::Autoload
4
4
  autoload :GenericAuthority
5
5
  autoload :RdfHelper
6
- autoload :AuthorityService
7
6
  autoload :SearchQuery
8
7
  autoload :FindTerm
9
8
  autoload :Config
@@ -1,7 +1,6 @@
1
1
  require 'qa/authorities/linked_data/config/term_config'.freeze
2
2
  require 'qa/authorities/linked_data/config/search_config'.freeze
3
3
  require 'json'
4
- require 'erb'
5
4
 
6
5
  # Provide attr_reader methods for linked data authority configurations. Some default configurations are provided for several
7
6
  # linked data authorities and can be found at /config/authorities/linked_data. You can add configurations for new authorities by
@@ -18,34 +17,42 @@ require 'erb'
18
17
  module Qa::Authorities
19
18
  module LinkedData
20
19
  class Config
21
- class << self
22
- include ERB::Util
23
- end
24
-
25
20
  attr_reader :authority_name
26
- attr_reader :authority_config
27
21
 
28
22
  # Initialize to hold the configuration for the specifed authority. Configurations are defined in config/authorities/linked_data. See README for more information.
29
23
  # @param [String] the name of the configuration file for the authority
30
24
  # @return [Qa::Authorities::LinkedData::Config] instance of this class
31
25
  def initialize(auth_name)
32
26
  @authority_name = auth_name
33
- auth_config
27
+ authority_config
34
28
  end
35
29
 
36
30
  def search
37
- @search ||= Qa::Authorities::LinkedData::SearchConfig.new(auth_config.fetch(:search))
31
+ @search ||= Qa::Authorities::LinkedData::SearchConfig.new(authority_config.fetch(:search), prefixes)
38
32
  end
39
33
 
40
34
  def term
41
- @term ||= Qa::Authorities::LinkedData::TermConfig.new(auth_config.fetch(:term))
35
+ @term ||= Qa::Authorities::LinkedData::TermConfig.new(authority_config.fetch(:term), prefixes)
36
+ end
37
+
38
+ def prefixes
39
+ @prefixes ||= authority_config.fetch(:prefixes, {})
40
+ end
41
+
42
+ def config_version
43
+ @config_version ||= authority_config.fetch(:QA_CONFIG_VERSION, '1.0')
44
+ end
45
+
46
+ def config_version?(version)
47
+ config_version == version
42
48
  end
43
49
 
44
50
  # Return the full configuration for an authority
45
51
  # @return [String] the authority configuration
46
- def auth_config
47
- @authority_config ||= Qa::Authorities::LinkedData::AuthorityService.authority_config(@authority_name)
52
+ def authority_config
53
+ @authority_config ||= Qa::LinkedData::AuthorityService.authority_config(@authority_name)
48
54
  raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data authority '#{@authority_name}'" if @authority_config.nil?
55
+ convert_1_0_to_2_0 if @authority_config.fetch(:QA_CONFIG_VERSION, '1.0') == '1.0'
49
56
  @authority_config
50
57
  end
51
58
 
@@ -61,26 +68,20 @@ module Qa::Authorities
61
68
  pred_uri
62
69
  end
63
70
 
64
- def self.replace_pattern(url, pattern, value, encode = false)
65
- value = url_encode(value).gsub(".", "%2E") if encode
66
- url.gsub("{?#{pattern}}", value)
67
- end
71
+ private
68
72
 
69
- def self.process_subauthority(url, subauth_pattern, subauthorities, subauth_key)
70
- pattern = subauth_pattern[:pattern]
71
- value = subauthorities[subauth_key] || subauth_pattern[:default]
72
- replace_pattern(url, pattern, value)
73
- end
73
+ def convert_1_0_to_2_0
74
+ convert_1_0_url_to_2_0_url(:search)
75
+ convert_1_0_url_to_2_0_url(:term)
76
+ end
74
77
 
75
- def self.apply_replacements(url, config, replacements = {})
76
- return url unless config.size.positive?
77
- config.each do |param_key, rep_pattern|
78
- s_param_key = param_key.to_s
79
- value = replacements[param_key] || replacements[s_param_key] || rep_pattern[:default]
80
- url = replace_pattern(url, param_key, value, rep_pattern[:encode])
78
+ # @deprecated Update to linked data config version 2.0 instead
79
+ def convert_1_0_url_to_2_0_url(action_key)
80
+ url_template = @authority_config.fetch(action_key, {}).fetch(:url, {}).fetch(:template, "")
81
+ return if url_template.blank?
82
+ warn "[DEPRECATED] #Linked data configuration #{authority_name} has 1.0 version format which is deprecated; update to version 2.0 configuration."
83
+ @authority_config[action_key][:url][:template] = url_template.gsub("{?", "{")
81
84
  end
82
- url
83
- end
84
85
  end
85
86
  end
86
87
  end
@@ -5,9 +5,12 @@
5
5
  module Qa::Authorities
6
6
  module LinkedData
7
7
  class SearchConfig
8
+ attr_reader :prefixes
9
+
8
10
  # @param [Hash] config the search portion of the config
9
- def initialize(config)
11
+ def initialize(config, prefixes = {})
10
12
  @search_config = config
13
+ @prefixes = prefixes
11
14
  end
12
15
 
13
16
  attr_reader :search_config
@@ -19,26 +22,10 @@ module Qa::Authorities
19
22
  search_config.present?
20
23
  end
21
24
 
22
- # Return search url encoding defined in the configuration for this authority
23
- # if it was provided
24
- # @return [Hash,NilClass] the configured search url
25
- def url
26
- search_config[:url]
27
- end
28
-
29
25
  # Return search url template defined in the configuration for this authority.
30
- # @return [String] the configured search url template
31
- def url_template
32
- url.fetch(:template)
33
- end
34
-
35
- # Return search url parameter mapping defined in the configuration for this authority.
36
- # @return [Hash] the configured search url parameter mappings with variable name as key
37
- def url_mappings
38
- return @url_mappings unless @url_mappings.nil?
39
- mappings = Config.config_value(url, :mapping)
40
- return {} if mappings.nil?
41
- Hash[*mappings.collect { |m| [m[:variable].to_sym, m] }.flatten]
26
+ # @return [Qa::IriTemplate::UrlConfig] the configured search url template
27
+ def url_config
28
+ @url_config ||= Qa::IriTemplate::UrlConfig.new(search_config[:url]) if supports_search?
42
29
  end
43
30
 
44
31
  # Return the preferred language for literal value selection for search query.
@@ -89,45 +76,24 @@ module Qa::Authorities
89
76
  Config.predicate_uri(results, :sort_predicate)
90
77
  end
91
78
 
92
- # Return parameters that are required for QA api
93
- # @return [Hash] the configured search url parameter mappings
94
- def qa_replacement_patterns
95
- search_config.fetch(:qa_replacement_patterns)
96
- end
97
-
98
- # Should the replacement pattern be encoded?
99
- # @return [Boolean] true, if the pattern should be encoded; otherwise, false
100
- def qa_replacement_encoded?(pattern_key)
101
- map_key = qa_replacement_patterns[pattern_key].to_sym
102
- replacement_encoded? map_key
103
- end
104
-
105
- # Are there replacement parameters configured for search query?
106
- # @return [True|False] true if there are replacement parameters configured for search query; otherwise, false
107
- def replacements?
108
- replacement_count.positive?
109
- end
110
-
111
- # Should the replacement parameter be encoded?
112
- # @return [True|False] true if the replacement parameter should be encoded; otherwise, false
113
- def replacement_encoded?(map_key)
114
- return false unless url_mappings[map_key].key? :encode
115
- url_mappings[map_key][:encode]
79
+ # Does this authority configuration support additional context in search results?
80
+ # @return [True|False] true if additional context in search results is supported; otherwise, false
81
+ def supports_context?
82
+ return true if context_map.present?
83
+ false
116
84
  end
117
85
 
118
- # Return the number of possible replacement values to make in the search URL
119
- # @return [Integer] the configured number of possible replacements in the search url
120
- def replacement_count
121
- replacements.size
86
+ # Return the context map if it is defined
87
+ # @return [Qa::LinkedData::Config::ContextMap] the context map
88
+ def context_map
89
+ return nil unless search_config.key?(:context)
90
+ @context_map ||= Qa::LinkedData::Config::ContextMap.new(search_config.fetch(:context), prefixes)
122
91
  end
123
92
 
124
- # Return the replacement configurations
125
- # @return [Hash] the configurations for search url replacements
126
- def replacements
127
- return @replacements unless @replacements.nil?
128
- @replacements = {}
129
- @replacements = url_mappings.select { |k, _v| !qa_replacement_patterns.include?(k) } unless search_config.nil? || url_mappings.nil?
130
- @replacements
93
+ # Return parameters that are required for QA api
94
+ # @return [Hash] the configured search url parameter mappings
95
+ def qa_replacement_patterns
96
+ search_config.fetch(:qa_replacement_patterns)
131
97
  end
132
98
 
133
99
  # Are there subauthorities configured for search query?
@@ -155,30 +121,6 @@ module Qa::Authorities
155
121
  @subauthorities ||= {} if search_config.nil? || !(search_config.key? :subauthorities)
156
122
  @subauthorities ||= search_config.fetch(:subauthorities)
157
123
  end
158
-
159
- # Return the replacement configurations
160
- # @return [Hash] the configurations for search url replacements
161
- def subauthority_replacement_pattern
162
- return {} unless subauthorities?
163
- @subauthority_replacement_pattern ||= {} if search_config.nil? || !subauthorities?
164
- pattern = qa_replacement_patterns[:subauth]
165
- default = url_mappings[pattern.to_sym][:default]
166
- @subauthority_replacement_pattern ||= { pattern: pattern, default: default }
167
- end
168
-
169
- # Build a linked data authority search url
170
- # @param [String] the query
171
- # @param [String] (optional) subauthority key
172
- # @param [Hash] (optional) replacement values with { pattern_name (defined in YAML config) => value }
173
- # @return [String] the search encoded url
174
- def url_with_replacements(query, sub_auth = nil, search_replacements = {})
175
- return nil unless supports_search?
176
- sub_auth = sub_auth.to_sym if sub_auth.present?
177
- url = Config.replace_pattern(url_template, qa_replacement_patterns[:query], query, qa_replacement_encoded?(:query))
178
- url = Config.process_subauthority(url, subauthority_replacement_pattern, subauthorities, sub_auth) if subauthorities?
179
- url = Config.apply_replacements(url, replacements, search_replacements) if replacements?
180
- url
181
- end
182
124
  end
183
125
  end
184
126
  end
@@ -6,8 +6,9 @@ module Qa::Authorities
6
6
  module LinkedData
7
7
  class TermConfig
8
8
  # @param [Hash] config the term portion of the config
9
- def initialize(config)
9
+ def initialize(config, prefixes = {})
10
10
  @term_config = config
11
+ @prefixes = prefixes
11
12
  end
12
13
 
13
14
  attr_reader :term_config
@@ -19,25 +20,10 @@ module Qa::Authorities
19
20
  term_config.present?
20
21
  end
21
22
 
22
- # Return term url encoding defined in the configuration for this authority.
23
- # @return [Hash] the configured term url
24
- def term_url
25
- Config.config_value(term_config, :url)
26
- end
27
-
28
23
  # Return term url template defined in the configuration for this authority.
29
- # @return [String] the configured term url template
30
- def term_url_template
31
- Config.config_value(term_url, :template)
32
- end
33
-
34
- # Return term url parameter mapping defined in the configuration for this authority.
35
- # @return [Hash] the configured term url parameter mappings with variable name as key
36
- def term_url_mappings
37
- return @term_url_mappings unless @term_url_mappings.nil?
38
- mappings = Config.config_value(term_url, :mapping)
39
- return {} if mappings.nil?
40
- Hash[*mappings.collect { |m| [m[:variable].to_sym, m] }.flatten]
24
+ # @return [Qa::IriTemplate::UrlConfig] the configured term url template
25
+ def url_config
26
+ @url_config ||= Qa::IriTemplate::UrlConfig.new(term_config[:url]) if supports_term?
41
27
  end
42
28
 
43
29
  # Is the term_id substitution expected to be a URI?
@@ -111,41 +97,7 @@ module Qa::Authorities
111
97
  def term_qa_replacement_patterns
112
98
  Config.config_value(term_config, :qa_replacement_patterns)
113
99
  end
114
-
115
- # Should the replacement pattern be encoded?
116
- # @return [Boolean] true, if the pattern should be encoded; otherwise, false
117
- def term_qa_replacement_encoded?(pattern_key)
118
- map_key = term_qa_replacement_patterns[pattern_key].to_sym
119
- term_replacement_encoded? map_key
120
- end
121
-
122
- # Are there replacement parameters configured for term fetch?
123
- # @return [Boolean] true if there are replacement parameters configured for term fetch; otherwise, false
124
- def term_replacements?
125
- term_replacement_count.positive?
126
- end
127
-
128
- # Should the replacement parameter be encoded?
129
- # @return [Boolean] true if the replacement parameter should be encoded; otherwise, false
130
- def term_replacement_encoded?(map_key)
131
- return false unless term_url_mappings[map_key].key? :encode
132
- term_url_mappings[map_key][:encode]
133
- end
134
-
135
- # Return the number of possible replacement values to make in the term URL
136
- # @return [Integer] the configured number of possible replacements in the term url
137
- def term_replacement_count
138
- term_replacements.size
139
- end
140
-
141
- # Return the replacement configurations
142
- # @return [Hash] the configurations for term url replacements
143
- def term_replacements
144
- return @term_replacements unless @term_replacements.nil?
145
- @term_replacements = {}
146
- @term_replacements = term_url_mappings.select { |k, _v| !term_qa_replacement_patterns.value?(k.to_s) } unless term_config.nil? || term_url_mappings.nil?
147
- @term_replacements
148
- end
100
+ alias qa_replacement_patterns term_qa_replacement_patterns
149
101
 
150
102
  # Are there subauthorities configured for term fetch?
151
103
  # @return [True|False] true if there are subauthorities configured term fetch; otherwise, false
@@ -172,29 +124,7 @@ module Qa::Authorities
172
124
  @term_subauthorities ||= {} if term_config.nil? || !(term_config.key? :subauthorities)
173
125
  @term_subauthorities ||= term_config[:subauthorities]
174
126
  end
175
-
176
- # Return the replacement configurations
177
- # @return [Hash] the configurations for term url replacements
178
- def term_subauthority_replacement_pattern
179
- return {} unless term_subauthorities?
180
- @term_subauthority_replacement_pattern ||= {} if term_config.nil? || !term_subauthorities?
181
- pattern = term_qa_replacement_patterns[:subauth]
182
- @term_subauthority_replacement_pattern ||= { pattern: pattern, default: term_url_mappings[pattern.to_sym][:default] }
183
- end
184
-
185
- # Build a linked data authority term url
186
- # @param [String] the id
187
- # @param [String] (optional) subauthority key
188
- # @param [Hash] (optional) replacement values with { pattern_name (defined in YAML config) => value }
189
- # @return [String] the term encoded url
190
- def term_url_with_replacements(id, sub_auth = nil, replacements = {})
191
- return nil unless supports_term?
192
- sub_auth = sub_auth.to_sym if sub_auth.is_a? String
193
- url = Config.replace_pattern(term_url_template, term_qa_replacement_patterns[:term_id], id, term_qa_replacement_encoded?(:term_id))
194
- url = Config.process_subauthority(url, term_subauthority_replacement_pattern, term_subauthorities, sub_auth) if term_subauthorities?
195
- url = Config.apply_replacements(url, term_replacements, replacements) if term_replacements?
196
- url
197
- end
127
+ alias subauthorities term_subauthorities
198
128
  end
199
129
  end
200
130
  end
@@ -10,7 +10,8 @@ module Qa::Authorities
10
10
  @term_config = term_config
11
11
  end
12
12
 
13
- attr_reader :term_config
13
+ attr_reader :term_config, :full_graph, :filtered_graph, :language
14
+ private :full_graph, :filtered_graph, :language
14
15
 
15
16
  delegate :term_subauthority?, to: :term_config
16
17
 
@@ -35,24 +36,31 @@ module Qa::Authorities
35
36
  # "http://schema.org/sameAs":["http://id.loc.gov/authorities/names/n79021621","https://viaf.org/viaf/126293486"] } }
36
37
  def find(id, language: nil, replacements: {}, subauth: nil, jsonld: false)
37
38
  raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data term sub-authority #{subauth}" unless subauth.nil? || term_subauthority?(subauth)
38
- language ||= term_config.term_language
39
- url = term_config.term_url_with_replacements(id, subauth, replacements)
39
+ @language = Qa::LinkedData::LanguageService.preferred_language(user_language: language, authority_language: term_config.term_language)
40
+ url = Qa::LinkedData::AuthorityUrlService.build_url(action_config: term_config, action: :term, action_request: id, substitutions: replacements, subauthority: subauth)
40
41
  Rails.logger.info "QA Linked Data term url: #{url}"
41
- graph = get_linked_data(url)
42
- return "{}" unless graph.size.positive?
43
- return graph.dump(:jsonld, standard_prefixes: true) if jsonld
44
- parse_term_authority_response(id, graph, language)
42
+ load_graph(url: url)
43
+ return "{}" unless full_graph.size.positive?
44
+ return full_graph.dump(:jsonld, standard_prefixes: true) if jsonld
45
+ parse_term_authority_response(id)
45
46
  end
46
47
 
47
48
  private
48
49
 
49
- def parse_term_authority_response(id, graph, language)
50
- graph = filter_language(graph, language) unless language.nil?
51
- results = extract_preds(graph, preds_for_term)
50
+ def load_graph(url:)
51
+ # @graph = Qa::LinkedData::GraphService.load_graph(url: url)
52
+ @full_graph = Qa::LinkedData::GraphService.load_graph(url: url)
53
+ return unless @full_graph.size.positive?
54
+ @filtered_graph = Qa::LinkedData::GraphService.deep_copy(graph: @full_graph)
55
+ @filtered_graph = Qa::LinkedData::GraphService.filter(graph: @filtered_graph, language: language) unless language.blank?
56
+ end
57
+
58
+ def parse_term_authority_response(id)
59
+ results = extract_preds(filtered_graph, preds_for_term)
52
60
  consolidated_results = consolidate_term_results(results)
53
61
  json_results = convert_term_to_json(consolidated_results)
54
62
  termhash = select_json_result_for_id(json_results, id)
55
- predicates_hash = predicates_with_subject_uri(graph, termhash[:uri])
63
+ predicates_hash = predicates_with_subject_uri(termhash[:uri])
56
64
  termhash['predicates'] = predicates_hash unless predicates_hash.length <= 0
57
65
  termhash
58
66
  end
@@ -124,22 +132,22 @@ module Qa::Authorities
124
132
  json_results.first
125
133
  end
126
134
 
127
- def predicates_with_subject_uri(graph, expected_uri) # rubocop:disable Metrics/MethodLength
135
+ def predicates_with_subject_uri(expected_uri) # rubocop:disable Metrics/MethodLength
128
136
  predicates_hash = {}
129
- graph.statements.each do |st|
137
+ @full_graph.statements.each do |st|
130
138
  subj = st.subject.to_s
131
139
  next unless subj == expected_uri
132
140
  pred = st.predicate.to_s
133
- obj = st.object.to_s
134
- next if blank_node? obj
141
+ obj = st.object
142
+ next if obj.anonymous?
135
143
  if predicates_hash.key?(pred)
136
144
  objs = predicates_hash[pred]
137
145
  objs = [] unless objs.is_a?(Array)
138
146
  objs << predicates_hash[pred] unless objs.length.positive?
139
- objs << obj
147
+ objs << obj.to_s
140
148
  predicates_hash[pred] = objs
141
149
  else
142
- predicates_hash[pred] = [obj]
150
+ predicates_hash[pred] = [obj.to_s]
143
151
  end
144
152
  end
145
153
  predicates_hash