class Sfp::Runtime

Constants

ParentEliminator
ParentGenerator
SFPtoRubyValueConverter

Attributes

cloudfinder[R]
model[R]
root[R]

Public Class Methods

new(model) click to toggle source
# File lib/sfpagent/runtime.rb, line 6
def initialize(model)
        @mutex_procedure = Mutex.new
        @mutex_get_state = Mutex.new
        @root = nil
        @cloudfinder = Sfp::Helper::CloudFinder.new
        set_model(model)
end

Public Instance Methods

execute_action(action) click to toggle source
# File lib/sfpagent/runtime.rb, line 19
def execute_action(action)
        return false if !defined?(@root) or @root.nil?

        def normalise_parameters(params)
                p = {}
                params.each { |k,v| p[k[2,k.length-2]] = v }
                p
        end

        module_path, method_name = action['name'].pop_ref
        mod = @root.at?(module_path)[:_self]

        if mod.nil?
                raise Exception, "Module #{module_path} cannot be found!"

        elsif mod.is_a?(Sfp::Module::Shell)
                params = normalise_parameters(action['parameters'])
                mod.execute method_name, params

        elsif not mod.respond_to?(method_name)
                raise Exception, "Cannot execute #{action['name']}!"

        else
                params = normalise_parameters(action['parameters'])
                if mod.synchronized.rindex(method_name)
                        @mutex_procedure.synchronize {
                                mod.send method_name.to_sym, params
                        }
                else
                        mod.send method_name.to_sym, params
                end

        end

        # TODO - check post-execution state for verification
end
get_state(as_sfp=false) click to toggle source
# File lib/sfpagent/runtime.rb, line 72
def get_state(as_sfp=false)
        @mutex_get_state.synchronize {
                update_state(@root)
                get_object_state(@root, @model)
        }
end
normalise_parameters(params) click to toggle source
# File lib/sfpagent/runtime.rb, line 22
def normalise_parameters(params)
        p = {}
        params.each { |k,v| p[k[2,k.length-2]] = v }
        p
end
set_model(model) click to toggle source
# File lib/sfpagent/runtime.rb, line 56
def set_model(model)
        @mutex_get_state.synchronize {
                @model = model
                if @model.is_a?(Hash)
                        root_model = Sfp::Helper.deep_clone(@model)
                        root_model.accept(SFPtoRubyValueConverter)
                        root_model.accept(ParentEliminator)
                        @root = update_model(root_model, root_model, '$')
                        @root.accept(ParentGenerator)

                        @cloudfinder.clouds = []
                        @model.accept(@cloudfinder.reset)
                end
        }
end
whoami?() click to toggle source
# File lib/sfpagent/runtime.rb, line 14
def whoami?
        @model.each { |key,value| return key if key[0,1] != '_' and value['_context'] == 'object' } if !@model.nil?
        nil
end

Protected Instance Methods

get_object_state(object, model) click to toggle source
# File lib/sfpagent/runtime.rb, line 80
def get_object_state(object, model)
        # get object's state
        state = (object.has_key?(:_self) ? object[:_self].state : {})

        # add hidden attributes and procedures
        model.each { |k,v|
                state[k] = v if (k[0,1] == '_' and k != '_parent') or
                        (v.is_a?(Hash) and v['_context'] == 'procedure')
        }

        # accumulate children's state
        object.each { |name,child|
                next if name.to_s[0,1] == '_' #or state.has_key?(name)
                state[name] = get_object_state(child, model[name])
        }

        # set state=Sfp::Undefined for each attribute that exists in the model
        # but not covered by SFP object instants
        (model.keys - state.keys).each do |name|
                next if name[0,1] == '_'
                state[name] = Sfp::Undefined.new
        end

        state
end
instantiate_sfp_object(model, path) click to toggle source
# File lib/sfpagent/runtime.rb, line 133
def instantiate_sfp_object(model, path)
        ### get SFP schema's name
        schema = model['_isa'].sub(/^\$\./, '')
        object = nil

        if schema[0] =~ /[A-Z]/ and Sfp::Module.const_defined?(schema)
                ### create an instance of the schema
                object = Sfp::Module::const_get(schema).new

        elsif shell_module?(schema)
                ### get module's metadata
                metadata = Sfp::Agent.get_modules[schema]

                ### create module wrapper instance
                object = Sfp::Module::Shell.new(metadata)

        else
                # throw an exception if schema's implementation is not exist!
                raise Exception, "Implementation of schema #{schema} is not available!"

        end

        # initialize the instance
        object.init(model)
                
        # update list of synchronized procedures
        model.each { |k,v|
                next if k[0,1] == '_' or not (v.is_a?(Hash) and v['_context'] == 'procedure')
                object.synchronized << k if v['_synchronized']
        }

        # set object's path
        object.path = path

        object
end
shell_module?(schema) click to toggle source
# File lib/sfpagent/runtime.rb, line 126
def shell_module?(schema)
        Sfp::Agent.get_modules.each do |name,data|
                return true if schema == name and data[:type] == :shell
        end
        false
end
update_model(model, root, path) click to toggle source
# File lib/sfpagent/runtime.rb, line 111
def update_model(model, root, path)
        object = {}
        if model['_context'] == 'object' and model['_isa'].to_s.isref #and model['_isa'].to_s != '$.Object'
                object[:_self] = instantiate_sfp_object(model, path)
        end

        model.each do |key,child|
                if key[0,1] != '_' and child.is_a?(Hash) and child['_context'] == 'object' #and child['_isa'].to_s != '$.Object'
                        object[key] = update_model(child, root, path.push(key))
                end
        end

        object
end
update_state(object) click to toggle source
# File lib/sfpagent/runtime.rb, line 106
def update_state(object)
        object[:_self].update_state if not object[:_self].nil?
        object.each { |k,v| update_state(v) if k.to_s[0,1] != '_' }
end