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