class ActiveFedora::Orders::OrderedList

Ruby object representation of an ORE doubly linked list.

Attributes

graph[R]
head[W]
head_subject[R]
node_cache[R]
tail[W]
tail_subject[R]

Public Class Methods

new(graph, head_subject, tail_subject, node_cache: NodeCache.new) click to toggle source

@param [::RDF::Enumerable] graph Enumerable where ORE statements are

stored.

@param [::RDF::URI] head_subject URI of head node in list. @param [::RDF::URI] tail_subject URI of tail node in list.

# File lib/active_fedora/orders/ordered_list.rb, line 15
def initialize(graph, head_subject, tail_subject, node_cache: NodeCache.new)
  @graph = if graph.respond_to?(:graph)
             graph.graph.data
           else
             graph
           end
  @head_subject = head_subject
  @tail_subject = tail_subject
  @node_cache = node_cache
  @changed = false
  tail
end

Public Instance Methods

-(other) click to toggle source

@param [Array<ListNode>] Nodes to remove. @return [OrderedList] List with node removed.

# File lib/active_fedora/orders/ordered_list.rb, line 63
def -(other)
  other.each do |node|
    delete_node(node)
  end
  self
end
[](key) click to toggle source

@param [Integer] key Position of the proxy @return [ListNode] Node for the proxy at the given position

# File lib/active_fedora/orders/ordered_list.rb, line 47
def [](key)
  list = ordered_reader.take(key + 1)
  list[key]
end
append_target(target, proxy_in: nil) click to toggle source

@param [ActiveFedora::Base] target Target to append to list. @option [::RDF::URI, ActiveFedora::Base] :proxy_in Proxy in to

assert on the created node.
# File lib/active_fedora/orders/ordered_list.rb, line 78
def append_target(target, proxy_in: nil)
  node = build_node(new_node_subject)
  node.target = target
  node.proxy_in = proxy_in
  append_to(node, tail.prev)
end
changed?() click to toggle source

@return [Boolean] Whether this list was changed since instantiation.

# File lib/active_fedora/orders/ordered_list.rb, line 139
def changed?
  @changed
end
changes_committed!() click to toggle source

Marks this list as not changed.

# File lib/active_fedora/orders/ordered_list.rb, line 160
def changes_committed!
  @changed = false
end
delete_at(loc) click to toggle source

@param [Integer] loc Index of node to delete.

# File lib/active_fedora/orders/ordered_list.rb, line 125
def delete_at(loc)
  return nil if loc.nil?
  arr = ordered_reader.take(loc + 1)
  delete_node(arr.last) if arr.length == loc + 1
end
delete_node(node) click to toggle source

@param [ListNode] node Node to delete

# File lib/active_fedora/orders/ordered_list.rb, line 112
def delete_node(node)
  node = ordered_reader.find { |x| x == node }
  return unless node

  prev_node = node.prev
  next_node = node.next
  node.prev.next = next_node
  node.next.prev = prev_node
  @changed = true
  node
end
delete_target(obj) click to toggle source

@param obj target of node to delete.

# File lib/active_fedora/orders/ordered_list.rb, line 132
def delete_target(obj)
  nodes_to_remove = ordered_reader.select { |list_node| obj.id == list_node.target_id }
  nodes_to_remove.each { |list_node| delete_node(list_node) }
  nodes_to_remove.last.try(:target)
end
empty?() click to toggle source

@return [Boolean]

# File lib/active_fedora/orders/ordered_list.rb, line 71
def empty?
  head.next == tail
end
head() click to toggle source

@return [HeadSentinel] Sentinel for the top of the list. If not empty,

head.next is the first element.
# File lib/active_fedora/orders/ordered_list.rb, line 30
def head
  @head ||= HeadSentinel.new(self, next_node: build_node(head_subject))
end
insert_at(loc, target, proxy_in: nil) click to toggle source

@param [Integer] loc Location to insert target at @param [ActiveFedora::Base] target Target to insert

# File lib/active_fedora/orders/ordered_list.rb, line 87
def insert_at(loc, target, proxy_in: nil)
  node = build_node(new_node_subject)
  node.target = target
  node.proxy_in = proxy_in
  if loc.zero?
    append_to(node, head)
  else
    append_to(node, ordered_reader.take(loc).last)
  end
end
insert_proxy_for_at(loc, proxy_for, proxy_in: nil) click to toggle source

@param [Integer] loc Location to insert target at @param [String] proxy_for proxyFor to add

# File lib/active_fedora/orders/ordered_list.rb, line 100
def insert_proxy_for_at(loc, proxy_for, proxy_in: nil)
  node = build_node(new_node_subject)
  node.proxy_for = proxy_for
  node.proxy_in = proxy_in
  if loc.zero?
    append_to(node, head)
  else
    append_to(node, ordered_reader.take(loc).last)
  end
end
last() click to toggle source

@return [ListNode] Last node in the list.

# File lib/active_fedora/orders/ordered_list.rb, line 53
def last
  if empty?
    nil
  else
    tail.prev
  end
end
order_will_change!() click to toggle source

Marks this ordered list as about to change. Useful for when changing proxies individually.

# File lib/active_fedora/orders/ordered_list.rb, line 145
def order_will_change!
  @changed = true
end
proxy_in() click to toggle source

@return The node all proxies are a proxy in. @note If there are multiple proxy_ins this will log a warning and return

the first.
# File lib/active_fedora/orders/ordered_list.rb, line 172
def proxy_in
  proxies = to_a.map(&:proxy_in_id).compact.uniq
  ActiveFedora::Base.logger.warn "WARNING: List contains nodes aggregated under different URIs. Returning only the first." if proxies.length > 1
  proxies.first
end
tail() click to toggle source

@return [TailSentinel] Sentinel for the bottom of the list. If not

empty, tail.prev is the first element.
# File lib/active_fedora/orders/ordered_list.rb, line 36
def tail
  @tail ||=
    if tail_subject
      TailSentinel.new(self, prev_node: build_node(tail_subject))
    else
      head.next
    end
end
target_ids() click to toggle source

@return IDs of all ordered targets, in order

# File lib/active_fedora/orders/ordered_list.rb, line 165
def target_ids
  to_a.map(&:target_id)
end
to_graph() click to toggle source

@return [::RDF::Graph] Graph representation of this list.

# File lib/active_fedora/orders/ordered_list.rb, line 150
def to_graph
  ::RDF::Graph.new.tap do |g|
    array = to_a
    array.map(&:to_graph).each do |resource_graph|
      g << resource_graph
    end
  end
end

Private Instance Methods

append_to(source, append_node) click to toggle source
# File lib/active_fedora/orders/ordered_list.rb, line 182
def append_to(source, append_node)
  source.prev = append_node
  if append_node.next
    append_node.next.prev = source
    source.next = append_node.next
  else
    self.tail = source
  end
  append_node.next = source
  @changed = true
end
build_node(subject = nil) click to toggle source
# File lib/active_fedora/orders/ordered_list.rb, line 198
def build_node(subject = nil)
  return nil unless subject
  node_cache.fetch(subject) do
    ActiveFedora::Orders::ListNode.new(node_cache, subject, graph)
  end
end
new_node_subject() click to toggle source
# File lib/active_fedora/orders/ordered_list.rb, line 205
def new_node_subject
  node = ::RDF::URI("##{::RDF::Node.new.id}")
  node = ::RDF::URI("##{::RDF::Node.new.id}") while node_cache.key?(node)
  node
end
ordered_reader() click to toggle source
# File lib/active_fedora/orders/ordered_list.rb, line 194
def ordered_reader
  ActiveFedora::Aggregation::OrderedReader.new(self)
end