1# 2# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) 3# 4# $Id: utils.rb 36958 2012-09-13 02:22:10Z zzak $ 5# 6module XMLRPC # :nodoc: 7 8 9 # This module enables a user-class to be marshalled 10 # by XML-RPC for Ruby into a Hash, with one additional 11 # key/value pair <code>___class___ => ClassName</code> 12 # 13 module Marshallable 14 end 15 16 17 # Defines ParserWriterChooseMixin, which makes it possible to choose a 18 # different XMLWriter and/or XMLParser then the default one. 19 # 20 # The Mixin is used in client.rb (class XMLRPC::Client) 21 # and server.rb (class XMLRPC::BasicServer) 22 module ParserWriterChooseMixin 23 24 # Sets the XMLWriter to use for generating XML output. 25 # 26 # Should be an instance of a class from module XMLRPC::XMLWriter. 27 # 28 # If this method is not called, then XMLRPC::Config::DEFAULT_WRITER is used. 29 def set_writer(writer) 30 @create = Create.new(writer) 31 self 32 end 33 34 # Sets the XMLParser to use for parsing XML documents. 35 # 36 # Should be an instance of a class from module XMLRPC::XMLParser. 37 # 38 # If this method is not called, then XMLRPC::Config::DEFAULT_PARSER is used. 39 def set_parser(parser) 40 @parser = parser 41 self 42 end 43 44 private 45 46 def create 47 # if set_writer was not already called then call it now 48 if @create.nil? then 49 set_writer(Config::DEFAULT_WRITER.new) 50 end 51 @create 52 end 53 54 def parser 55 # if set_parser was not already called then call it now 56 if @parser.nil? then 57 set_parser(Config::DEFAULT_PARSER.new) 58 end 59 @parser 60 end 61 62 end # module ParserWriterChooseMixin 63 64 65 module Service 66 67 # Base class for XMLRPC::Service::Interface definitions, used 68 # by XMLRPC::BasicServer#add_handler 69 class BasicInterface 70 attr_reader :prefix, :methods 71 72 def initialize(prefix) 73 @prefix = prefix 74 @methods = [] 75 end 76 77 def add_method(sig, help=nil, meth_name=nil) 78 mname = nil 79 sig = [sig] if sig.kind_of? String 80 81 sig = sig.collect do |s| 82 name, si = parse_sig(s) 83 raise "Wrong signatures!" if mname != nil and name != mname 84 mname = name 85 si 86 end 87 88 @methods << [mname, meth_name || mname, sig, help] 89 end 90 91 private 92 93 def parse_sig(sig) 94 # sig is a String 95 if sig =~ /^\s*(\w+)\s+([^(]+)(\(([^)]*)\))?\s*$/ 96 params = [$1] 97 name = $2.strip 98 $4.split(",").each {|i| params << i.strip} if $4 != nil 99 return name, params 100 else 101 raise "Syntax error in signature" 102 end 103 end 104 105 end # class BasicInterface 106 107 # 108 # Class which wraps a XMLRPC::Service::Interface definition, used 109 # by XMLRPC::BasicServer#add_handler 110 # 111 class Interface < BasicInterface 112 def initialize(prefix, &p) 113 raise "No interface specified" if p.nil? 114 super(prefix) 115 instance_eval(&p) 116 end 117 118 def get_methods(obj, delim=".") 119 prefix = @prefix + delim 120 @methods.collect { |name, meth, sig, help| 121 [prefix + name.to_s, obj.method(meth).to_proc, sig, help] 122 } 123 end 124 125 private 126 127 def meth(*a) 128 add_method(*a) 129 end 130 131 end # class Interface 132 133 class PublicInstanceMethodsInterface < BasicInterface 134 def initialize(prefix) 135 super(prefix) 136 end 137 138 def get_methods(obj, delim=".") 139 prefix = @prefix + delim 140 obj.class.public_instance_methods(false).collect { |name| 141 [prefix + name.to_s, obj.method(name).to_proc, nil, nil] 142 } 143 end 144 end 145 146 147 end # module Service 148 149 150 # 151 # Short-form to create a XMLRPC::Service::Interface 152 # 153 def self.interface(prefix, &p) 154 Service::Interface.new(prefix, &p) 155 end 156 157 # Short-cut for creating a XMLRPC::Service::PublicInstanceMethodsInterface 158 def self.iPIMethods(prefix) 159 Service::PublicInstanceMethodsInterface.new(prefix) 160 end 161 162 163 module ParseContentType 164 def parse_content_type(str) 165 a, *b = str.split(";") 166 return a.strip.downcase, *b 167 end 168 end 169 170end # module XMLRPC 171 172