Class: ActiveFedora::Indexing::DescendantFetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/active_fedora/indexing/descendant_fetcher.rb

Overview

Finds all descendent URIs of a given repo URI (usually the base URI).

This is a slow and non-performant thing to do, we need to fetch every single object from the repo.

The DescendantFetcher is also capable of partitioning the URIs into “priority” URIs that will be first in the returned list. These prioritized URIs belong to objects with certain hasModel models. This feature is used in some samvera apps that need to index ‘permissions’ objects before other objects to have the solr indexing work right. And so by default, the prioritized class names are the ones form Hydra::AccessControls, but you can alter the prioritized model name list, or set it to the empty array.

DescendantFetcher.new(ActiveFedora.fedora.base_uri).descendent_and_self_uris
#=> array including self uri and descendent uris with "prioritized" (by default)
    Hydra::AccessControls permissions) objects FIRST.

Change the default prioritized hasModel names:

ActiveFedora::Indexing::DescendantFetcher.default_priority_models = []

Constant Summary collapse

HAS_MODEL_PREDICATE =
ActiveFedora::RDF::Fcrepo::Model.hasModel

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, priority_models: self.class.default_priority_models, exclude_self: false) ⇒ DescendantFetcher

Returns a new instance of DescendantFetcher.



30
31
32
33
34
35
# File 'lib/active_fedora/indexing/descendant_fetcher.rb', line 30

def initialize(uri,
               priority_models: self.class.default_priority_models, exclude_self: false)
  @uri = uri
  @priority_models = priority_models
  @exclude_self = exclude_self
end

Instance Attribute Details

#priority_modelsObject (readonly)

Returns the value of attribute priority_models.



28
29
30
# File 'lib/active_fedora/indexing/descendant_fetcher.rb', line 28

def priority_models
  @priority_models
end

#uriObject (readonly)

Returns the value of attribute uri.



28
29
30
# File 'lib/active_fedora/indexing/descendant_fetcher.rb', line 28

def uri
  @uri
end

Instance Method Details

#descendant_and_self_urisArray<String>

Returns uris starting with priority models.

Returns:

  • (Array<String>)

    uris starting with priority models



38
39
40
41
# File 'lib/active_fedora/indexing/descendant_fetcher.rb', line 38

def descendant_and_self_uris
  partitioned = descendant_and_self_uris_partitioned
  partitioned[:priority] + partitioned[:other]
end

#descendant_and_self_uris_partitionedHash<String, Array<String>>

returns a hash where key :priority is an array of all prioritized type objects, key :other is an array of the rest.

Returns:

  • (Hash<String, Array<String>>)

    uris sorted into :priority and :other



46
47
48
49
50
# File 'lib/active_fedora/indexing/descendant_fetcher.rb', line 46

def descendant_and_self_uris_partitioned
  model_partitioned = descendant_and_self_uris_partitioned_by_model
  { priority: model_partitioned.slice(*priority_models).values.flatten,
    other: model_partitioned.slice(*(model_partitioned.keys - priority_models)).values.flatten }
end

#descendant_and_self_uris_partitioned_by_modelHash<String, Array<String>>

Returns a hash where keys are model names This is useful if you need to action on certain models and want finer grainularity than priority/other

Returns:

  • (Hash<String, Array<String>>)

    uris sorted by model names



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/active_fedora/indexing/descendant_fetcher.rb', line 55

def descendant_and_self_uris_partitioned_by_model
  # GET could be slow if it's a big resource, we're using HEAD to avoid this problem,
  # but this causes more requests to Fedora.
  return partitioned_uris unless rdf_resource.head.rdf_source?

  add_self_to_partitioned_uris unless @exclude_self

  immediate_descendant_uris = rdf_graph.query(predicate: ::RDF::Vocab::LDP.contains).map { |descendant| descendant.object.to_s }
  immediate_descendant_uris.each do |descendant_uri|
    self.class.new(
      descendant_uri,
      priority_models: priority_models
    ).descendant_and_self_uris_partitioned_by_model.tap do |descendant_partitioned|
      descendant_partitioned.keys.each do |k|
        partitioned_uris[k] ||= []
        partitioned_uris[k].concat descendant_partitioned[k]
      end
    end
  end
  partitioned_uris
end