class HaveAPI::Fs::Component

The basic building block of the file system. Every directory and file is represented by a subclass of this class.

Attributes

atime[RW]
children[RW]
context[RW]
ctime[RW]
mtime[RW]

Public Class Methods

children_reader(*args) click to toggle source

Define reader methods for child components.

# File lib/haveapi/fs/component.rb, line 50
def children_reader(*args)
  args.each do |arg|
    define_method(arg) { children[arg] }
  end
end
component(name = nil) click to toggle source

Set or get a component name. Component name is used for finding components within a {Context}.

@param [Symbol] name @return [nil] if name is set @return [Symbol] if name is nil

# File lib/haveapi/fs/component.rb, line 62
def component(name = nil)
  if name
    @component = name

  else
    @component
  end
end
inherited(subclass) click to toggle source

Pass component name to the subclass.

# File lib/haveapi/fs/component.rb, line 72
def inherited(subclass)
  subclass.component(@component)
end
new(bound: false) click to toggle source

@param [Boolean] bound

# File lib/haveapi/fs/component.rb, line 80
def initialize(bound: false)
  @bound = bound
  @atime = @mtime = @ctime = Time.now
end

Public Instance Methods

abspath() click to toggle source

@return [String] absolute path of this component from the system root

# File lib/haveapi/fs/component.rb, line 173
def abspath
  File.join(
      context.mountpoint,
      path
  )
end
bound=(b) click to toggle source
# File lib/haveapi/fs/component.rb, line 125
def bound=(b)
  @bound = b
end
bound?() click to toggle source
# File lib/haveapi/fs/component.rb, line 121
def bound?
  @bound
end
contents() click to toggle source
# File lib/haveapi/fs/component.rb, line 149
def contents
  raise NotImplementedError
end
directory?() click to toggle source
# File lib/haveapi/fs/component.rb, line 129
def directory?
  !file?
end
executable?() click to toggle source
# File lib/haveapi/fs/component.rb, line 145
def executable?
  false
end
file?() click to toggle source
# File lib/haveapi/fs/component.rb, line 133
def file?
  !directory?
end
find(name) click to toggle source

Attempt to find a child component with `name`.

@return [HaveAPI::Fs::Component] if found @return [nil] if not found

# File lib/haveapi/fs/component.rb, line 95
def find(name)
  return @children[name] if @children.has_key?(name)
  c = new_child(name)

  @children.set(name, Factory.create(context, name, *c)) if c
end
invalid?() click to toggle source
# File lib/haveapi/fs/component.rb, line 206
def invalid?
  @invalid
end
invalidate() click to toggle source

Mark the component and all its descendats as invalid. Invalid components can still be in the cache and are dropped on hit.

# File lib/haveapi/fs/component.rb, line 200
def invalidate
  @invalid = true

  children.each { |_, c| c.invalidate }
end
parent() click to toggle source
# File lib/haveapi/fs/component.rb, line 180
def parent
  context.object_path[-2][1]
end
path() click to toggle source

@return [String] path of this component in the tree without the leading /

# File lib/haveapi/fs/component.rb, line 168
def path
  context.file_path.join('/')
end
readable?() click to toggle source
# File lib/haveapi/fs/component.rb, line 137
def readable?
  true
end
reset() click to toggle source

Shortcut for {#drop_children} and {#setup}.

# File lib/haveapi/fs/component.rb, line 158
def reset
  drop_children
  setup
end
setup() click to toggle source

Called by {Factory} when the instance is prepared. Subclasses must call this method.

# File lib/haveapi/fs/component.rb, line 87
def setup
  @children = Children.new(context)
end
times() click to toggle source
# File lib/haveapi/fs/component.rb, line 153
def times
  [@atime, @mtime, @ctime]
end
title() click to toggle source
# File lib/haveapi/fs/component.rb, line 163
def title
  self.class.name
end
unsaved?(n = nil) click to toggle source

A component is unsaved if it or any of its descendants has been modified and not saved.

@param [Integer] n used to determine the result just once per the same `n` @return [Boolean]

# File lib/haveapi/fs/component.rb, line 189
def unsaved?(n = nil)
  return @is_unsaved if n && @last_unsaved == n

  child = @children.detect { |_, c| c.unsaved? }

  @last_unsaved = n
  @is_unsaved = !child.nil?
end
use(*names) click to toggle source

Attempt to find and use nested components with `names`. Each name is for the next descendant. If the target component is found, it and all components in its path will be bound. Bound components are not automatically deleted when not in use.

# File lib/haveapi/fs/component.rb, line 106
def use(*names)
  ret = self
  path = []

  names.each do |n|
    ret = ret.find(n)
    return if ret.nil?
    path << ret
  end

  path.each { |c| c.bound = true }

  ret
end
writable?() click to toggle source
# File lib/haveapi/fs/component.rb, line 141
def writable?
  false
end

Protected Instance Methods

changed() click to toggle source

Update the time of last modification.

# File lib/haveapi/fs/component.rb, line 233
def changed
  self.mtime = Time.now
end
drop_children() click to toggle source

Drop all children from the memory and clear them from the cache.

# File lib/haveapi/fs/component.rb, line 227
def drop_children
  @children.clear
  context.cache.drop_below(path)
end
new_child(name) click to toggle source

Called to create a component for a child with `name` if this child is not yet or not anymore in memory. All subclasses should extend this method to add their own custom contents.

@param [Symbol] name @return [Array] the array describes the new child to be created by

{Factory}. The first item is a class name and
the rest are arguments to its constructor.

@return [nil] if the child does not exist

# File lib/haveapi/fs/component.rb, line 222
def new_child(name)
  raise NotImplementedError
end