class Arachni::Platform::List

Represents a collection of applicable platforms.

@author Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>

Public Class Methods

new( valid_platforms ) click to toggle source

@param [Array<String, Symbol>] valid_platforms

Valid platforms for this list.
# File lib/arachni/platform/list.rb, line 21
def initialize( valid_platforms )
    @valid_platforms = normalize!( valid_platforms )
    @platforms       = []
end
normalize( platforms ) click to toggle source
# File lib/arachni/platform/list.rb, line 217
def self.normalize( platforms )
    case platforms
        when self.class, Symbol
            platforms
        when String
            platforms.to_sym
        when Hash
            platforms.my_symbolize_keys
        when Enumerable, Array
            platforms.to_a.flatten.map( &:to_sym ).uniq.sort
    end
end

Public Instance Methods

+( enum )
Alias for: merge
<<( platform ) click to toggle source

@param [Symbol, String] platform

Platform to add to the list.

@return [Platform] ‘self`

@raise [Error::Invalid]

On {#invalid?} platforms.
# File lib/arachni/platform/list.rb, line 132
def <<( platform )
    @platforms |= [normalize( platform )]
    self
end
any?() click to toggle source

@return [Boolean]

`true` if there are applicable platforms, `false` otherwise.
# File lib/arachni/platform/list.rb, line 121
def any?
    !empty?
end
clear() click to toggle source

Clears platforms.

# File lib/arachni/platform/list.rb, line 201
def clear
    @platforms.clear
end
dup() click to toggle source

@return [Platform]

Copy of `self`.
# File lib/arachni/platform/list.rb, line 207
def dup
    self.class.new( @valid_platforms ).tap { |p| p.platforms = @platforms }
end
each( &block ) click to toggle source

@param [Block] block

Block to be passed each platform.

@return [Enumerator, Platform]

`Enumerator` if no `block` is given, `self` otherwise.
# File lib/arachni/platform/list.rb, line 169
def each( &block )
    return enum_for( __method__ ) if !block_given?
    @platforms.each( &block )
    self
end
empty?() click to toggle source

@return [Boolean]

`true` if there are no applicable platforms, `false` otherwise.
# File lib/arachni/platform/list.rb, line 115
def empty?
    @platforms.empty?
end
hierarchical?() click to toggle source

@return [Boolean]

`true` if the list has a hierarchy, `false` otherwise.
# File lib/arachni/platform/list.rb, line 213
def hierarchical?
    @valid_platforms.is_a? Hash
end
include?( platform ) click to toggle source

@param [Symbol, String] platform

Platform to check.

@return [Boolean]

`true` if `platform` applies to the given resource, `false` otherwise.

@raise [Error::Invalid]

On {#invalid?} `platforms`.
# File lib/arachni/platform/list.rb, line 183
def include?( platform )
    @platforms.include? normalize( platform )
end
include_any?( platforms ) click to toggle source

@param [Array<Symbol, String>] platforms

Platform to check.

@return [Boolean]

`true` if any platform in `platforms` applies to the given resource,
`false` otherwise.

@raise [Error::Invalid]

On {#invalid?} `platforms`.
# File lib/arachni/platform/list.rb, line 196
def include_any?( platforms )
    (@platforms & normalize( platforms )).any?
end
invalid?( platforms ) click to toggle source

@param [Array<Symbol, String> Symbol, String] platforms

Platform(s) to check.

@return [Boolean]

`true` if platforms are invalid (i.e. not in {#valid}), `false` otherwise.

@see valid?

# File lib/arachni/platform/list.rb, line 109
def invalid?( platforms )
    !valid?( platforms )
end
merge( enum ) click to toggle source

@param [Platform, Enumerable] enum

Enumerable object containing platforms.
New {Platform} built by merging `self` and the elements of the
given enumerable object.

@raise [Error::Invalid]

On {#invalid?} platforms.
# File lib/arachni/platform/list.rb, line 144
def merge( enum )
    dup.merge!( enum )
end
Also aliased as: +, |
merge!( enum ) click to toggle source

@param [Enumerable] enum

Enumerable object containing platforms.

@return [Platform]

Updated `self`.

@raise [Error::Invalid]

On {#invalid?} platforms.
# File lib/arachni/platform/list.rb, line 158
def merge!( enum )
    @platforms |= normalize( enum )
    self
end
Also aliased as: update
pick( data_per_platform ) click to toggle source

Selects appropriate data depending on the applicable platforms from ‘data_per_platform`.

@param [Hash{<Symbol, String> => Object}] data_per_platform

Hash with platform names as keys and arbitrary data as values.

@return [Hash]

`data_per_platform` with non-applicable entries removed.

@raise [Error::Invalid]

On {#invalid?} platforms.
# File lib/arachni/platform/list.rb, line 43
def pick( data_per_platform )
    orig_data_per_platform = data_per_platform.dup
    data_per_platform      = data_per_platform.dup

    data_per_platform.select! { |k, v| include? k }

    # Bail out if the valid platforms are just a flat array, without hierarchy.
    return data_per_platform if !hierarchical?

    # Keep track of parents which will be removed due to the existence of
    # their children.
    specified_parents = []

    # Remove parents if we have children.
    data_per_platform.keys.each do |platform|
        specified_parents |= parents = find_parents( platform )
        data_per_platform.reject! { |k, _| parents.include? k }
    end

    # Include all of the parents' children if parents are specified but no
    # children for them.

    children = {}
    children_for = valid & @platforms.to_a
    children_for.each do |platform|
        next if specified_parents.include? platform
        c = find_children( platform )
        children.merge! orig_data_per_platform.select { |k, _| c.include? k }
    end

    data_per_platform.merge! children

    # Include the nearest parent data there is a child platform but there
    # are no data for it.

    ignore = data_per_platform.keys | specified_parents
    orig_data_per_platform.each do |platform, data|
        next if ignore.include?( platform ) ||
            !include_any?( find_children( platform ) )
        data_per_platform[platform] = data
    end

    data_per_platform
end
update( enum )
Alias for: merge!
valid() click to toggle source

@return [Array<Symbol>]

Supported platforms.
# File lib/arachni/platform/list.rb, line 28
def valid
    hierarchical? ? @valid_platforms.find_symbol_keys_recursively : @valid_platforms
end
valid?( platforms ) click to toggle source

@param [Array<Symbol, String> Symbol, String] platforms

Platform(s) to check.

@return [Boolean]

`true` if platforms are valid (i.e. in {#valid}), `false` otherwise.

@see invalid?

# File lib/arachni/platform/list.rb, line 95
def valid?( platforms )
    normalize( platforms )
    true
rescue
    false
end
|( enum )
Alias for: merge

Protected Instance Methods

platforms=( enum ) click to toggle source
# File lib/arachni/platform/list.rb, line 232
def platforms=( enum )
    @platforms = enum.to_a
end

Private Instance Methods

find_children( platform, hash = @valid_platforms ) click to toggle source
# File lib/arachni/platform/list.rb, line 238
def find_children( platform, hash = @valid_platforms )
    return [] if hash.empty?

    children = []
    hash.each do |k, v|
        if k == platform
            children |= v.find_symbol_keys_recursively
        elsif v.is_a? Hash
            children |= find_children( platform, v )
        end

    end
    children
end
find_parents( platform, hash = @valid_platforms ) click to toggle source
# File lib/arachni/platform/list.rb, line 253
def find_parents( platform, hash = @valid_platforms )
    return [] if hash.empty?

    parents = []
    hash.each do |k, v|
        if v.include?( platform )
            parents << k
        elsif v.is_a? Hash
            parents |= find_parents( platform, v )
        end
    end
    parents
end
normalize( platforms ) click to toggle source
# File lib/arachni/platform/list.rb, line 267
def normalize( platforms )
    return platforms if platforms.is_a? self.class

    if platforms.is_a?( Symbol ) || platforms.is_a?( String )
        platform = normalize!( platforms )
        if !valid.include?( platform )
            fail Error::Invalid, "Invalid platform: #{platform}"
        end

        return platform
    end

    platforms = normalize!( platforms )
    invalid   = (valid + platforms) - valid

    if invalid.any?
        fail Error::Invalid, "Invalid platforms: #{invalid.to_a.join( ', ' )}"
    end

    platforms
end
normalize!( platforms ) click to toggle source
# File lib/arachni/platform/list.rb, line 289
def normalize!( platforms )
    self.class.normalize( platforms )
end