Project

General

Profile

Download (3.66 KB) Statistics
| Branch: | Tag: | Revision:
#--
# CyborgHood, a distributed system management software.
# Copyright (c) 2009-2010 Marc Dequènes (Duck) <Duck@DuckCorp.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#++

require 'singleton'


module CyborgHood
module CyborgServerInterface
def self.included(base)
base.class_eval("include Singleton")
base.extend(ClassMethods)
end

module ClassMethods
def decompose_command(cmd)
object, method = cmd.split('.', 2)

if method
begin
klass = object.split('::').inject(self) {|scope, const_name| scope.const_get(const_name)}
rescue
return
end
else
if object.index("::")
return
else
klass = self
method = cmd
end
end

[klass, method]
end

def has_node?(cmd)
klass, method = self.decompose_command(cmd)
return false if klass.nil?
return true if method.nil?

inst = klass.instance
inst.api_methods.include?(method)
end

attr_accessor :exported_methods
attr_accessor :auto_export_public_instance_methods

def export_method(syms)
syms = [syms] unless syms.is_a? Array
self.exported_methods ||= []
self.exported_methods += syms.collect{|m| m.to_s }
end
end

def initialize
@config = Config.instance

self.class.exported_methods ||= []
self.class.auto_export_public_instance_methods = true
end

def api_modules
@modules ||= self.class.constants.select do |c|
cc = self.class.const_get(c)
cc.class == Class and cc.ancestors.include? CyborgServerInterface
end
end

def api_methods
methods = self.class.exported_methods
methods += self.class.public_instance_methods(false) if self.class.auto_export_public_instance_methods
methods & self.methods
end

# preliminary incoming message handling
def call(cmd, data)
klass, method = self.class.decompose_command(cmd)
return "551 unknown object" if klass.nil?

inst = klass.instance

unless inst.api_methods.include?(method)
return "551 this object has no such method"
end

if data.nil?
formated_data = []
else
begin
formated_data = YAML.load(data) unless data.nil?
rescue
return "552 unreadable data for arguments"
end

return "552 wrong format for arguments" unless formated_data.is_a? Array
end

begin
# preliminary outgoing message handling
inst.send(method, *formated_data).to_yaml
rescue
return "550 method call failed"
end
end
end

module CyborgServerDefaultInterface
PROTOCOL_VERSION = "0.1~"

def self.included(base)
list = self.public_instance_methods(false)
base.class_eval do
export_method list
end
end

def product_name
PRODUCT
end

def product_version
VERSION
end

def protocol_version
PROTOCOL_VERSION
end

def bot_name
@config.bot_name
end
end
end
(1-1/2)