# Defines the external authority predicates used to extract additional context from the graph. require 'ldpath' module Qa module LinkedData module Config class ContextPropertyMap VALUE_ON_ERROR = [].freeze attr_reader :group_id, # id that identifies which group the property should be in :label attr_reader :property_map, :ldpath, :expansion_label_ldpath, :expansion_id_ldpath, :prefixes private :property_map, :ldpath, :expansion_label_ldpath, :expansion_id_ldpath, :prefixes # @param [Hash] property_map defining information to return to provide context # @option property_map [String] :group_id (optional) default label to use for a property (default: no label) # @option property_map [String] :property_label_i18n (optional) i18n key to use to get the label for a property (default: property_label_default OR no label if neither are defined) # @option property_map [String] :property_label_default (optional) default label to use for a property (default: no label) # @option property_map [String] :ldpath (required) identifies the values to extract from the graph (based on http://marmotta.apache.org/ldpath/language.html) # @option property_map [Boolean] :selectable (optional) if true, this property can selected as the value (default: false) # @option property_map [Boolean] :drillable (optional) if true, the label for this property can be used to execute a second query allowing navi (default: false) # @param [Hash] shortcut names for URI prefixes with key = part of predicate that is the same for all terms (e.g. { "madsrdf": "http://www.loc.gov/mads/rdf/v1#" }) # @example property_map example # { # "group_id": "dates", # "property_label_i18n": "qa.linked_data.authority.locnames_ld4l_cache.birth_date", # "property_label_default": "Birth", # "ldpath": "madsrdf:identifiesRWO/madsrdf:birthDate/schema:label", # "selectable": false, # "drillable": false # } def initialize(property_map = {}, prefixes = {}) @property_map = property_map @group_id = Qa::LinkedData::Config::Helper.fetch_symbol(property_map, :group_id, nil) @label = extract_label @ldpath = Qa::LinkedData::Config::Helper.fetch_required(property_map, :ldpath, false) @selectable = Qa::LinkedData::Config::Helper.fetch_boolean(property_map, :selectable, false) @drillable = Qa::LinkedData::Config::Helper.fetch_boolean(property_map, :drillable, false) @optional = Qa::LinkedData::Config::Helper.fetch_boolean(property_map, :optional, Qa.config.property_map_default_for_optional) @expansion_label_ldpath = Qa::LinkedData::Config::Helper.fetch(property_map, :expansion_label_ldpath, nil) @expansion_id_ldpath = Qa::LinkedData::Config::Helper.fetch(property_map, :expansion_id_ldpath, nil) @prefixes = prefixes end # Can this property be the selected value? # @return [Boolean] true if this property's value can be selected; otherwise, false def selectable? @selectable end # Can this property be used as a new query # @return [Boolean] true if this property's value can be used to drill up/down to another level; otherwise, false def drillable? @drillable end # Should this property always be included in the extended context or is it optional (i.e. only shown if it has a value) # @return [Boolean] true if this property is optional and will only be included in extended context if it has a value; otherwise, false def optional? @optional end def group? group_id.present? end # Should this URI value be expanded to include its label? # @return [Boolean] true if this property's value is expected to be a URI and its label should be included in the value; otherwise, false def expand_uri? expansion_label_ldpath.present? end # Values of this property for a specfic subject URI # @return [Array<String>] values for this property def values(graph, subject_uri) Qa::LinkedData::LdpathService.ldpath_evaluate(program: basic_program, graph: graph, subject_uri: subject_uri) end # Values of this property for a specfic subject URI with URI values expanded to include id and label. # @return [Array<Hash>] expanded values for this property # @example returned values # [{ # uri: "http://id.loc.gov/authorities/genreForms/gf2014026551", # id: "gf2014026551", # label: "Space operas" # }] def expanded_values(graph, subject_uri) values = values(graph, subject_uri) return values unless expand_uri? return values unless values.respond_to? :map! values.map! do |uri| { uri: uri, id: expansion_id(graph, uri), label: expansion_label(graph, uri) } end values end private def extract_label i18n_key = Qa::LinkedData::Config::Helper.fetch(property_map, :property_label_i18n, nil) default = Qa::LinkedData::Config::Helper.fetch(property_map, :property_label_default, nil) return I18n.t(i18n_key, default: default) if i18n_key.present? default end def basic_program @basic_program ||= Qa::LinkedData::LdpathService.ldpath_program(ldpath: ldpath, prefixes: prefixes) end def expansion_label_program @expansion_label_program ||= Qa::LinkedData::LdpathService.ldpath_program(ldpath: expansion_label_ldpath, prefixes: prefixes) end def expansion_id_program @expansion_id_program ||= Qa::LinkedData::LdpathService.ldpath_program(ldpath: expansion_id_ldpath, prefixes: prefixes) end def expansion_label(graph, uri) label = Qa::LinkedData::LdpathService.ldpath_evaluate(program: expansion_label_program, graph: graph, subject_uri: RDF::URI(uri)) label.size == 1 ? label.first : label end def expansion_id(graph, uri) return uri if expansion_id_ldpath.blank? id = Qa::LinkedData::LdpathService.ldpath_evaluate(program: expansion_id_program, graph: graph, subject_uri: RDF::URI(uri)) id.size == 1 ? id.first : id end end end end end