require 'set' require 'locabulary' require 'locabulary/exceptions' require 'locabulary/item' require 'locabulary/facet_wrapper_for_item' require 'locabulary/hierarchy_processor' module Locabulary module Commands # Responsible for building a hierarchical tree from faceted items, and ordering the nodes as per the presentation sequence for the # associated predicate_name. class BuildOrderedHierarchicalTreeCommand # @api private # @since 0.5.0 # # @param options [Hash] # @option options [String] :predicate_name # @option options [Array<#hits, #value>] :faceted_items # @option options [String] :faceted_item_hierarchy_delimiter # For any given item in faceted_items how is the hierarchy encoded in the :value? # # @return [Array<FacetWrapperForItem>] def self.call(options = {}) new(options).call end def initialize(options = {}) @predicate_name = options.fetch(:predicate_name) @faceted_items = options.fetch(:faceted_items) @faceted_item_hierarchy_delimiter = options.fetch(:faceted_item_hierarchy_delimiter) @locabulary_item_class = Item.class_to_instantiate(predicate_name: predicate_name) end def call HierarchyProcessor.call( enumerator: faceted_items.method(:each), item_builder: method(:build_item), predicate_name: predicate_name ) end private attr_reader :locabulary_item_class, :predicate_name, :faceted_items, :faceted_item_hierarchy_delimiter def build_item(faceted_node) term_label = convert_faceted_node_value_to_term_label(faceted_node.value) locabulary_item = find_locabulary_item(predicate_name: predicate_name, term_label: term_label) if locabulary_item FacetWrapperForItem.build_for_faceted_node_and_locabulary_item(faceted_node: faceted_node, locabulary_item: locabulary_item) else FacetWrapperForItem.build_for_faceted_node(faceted_node: faceted_node, predicate_name: predicate_name, term_label: term_label) end end def find_locabulary_item(*args) Locabulary.item_for(*args) rescue Exceptions::ItemNotFoundError, Exceptions::MissingPredicateNameError # Either the predicate name didn't exist or the item didn't exist for the given predicate name # Given that we are building from an alternate source, this is an acceptable error. It is possible # that we want to consider a developer notification but not abort the whole process. nil end # Responsible for converting the hierarchy delimiter of the facet item to the hierarchy delimiter of the Locabulary::Item. def convert_faceted_node_value_to_term_label(value) value.split(faceted_item_hierarchy_delimiter).join(locabulary_item_class.hierarchy_delimiter) end end end end