source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/xmlrpc/create.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 6.0 KB
Line 
1#
2# Creates XML-RPC call/response documents
3#
4# Copyright (C) 2001, 2002, 2003 by Michael Neumann ([email protected])
5#
6# $Id: create.rb 11820 2007-02-23 03:47:59Z knu $
7#
8
9require "date"
10require "xmlrpc/base64"
11
12module XMLRPC
13
14 module XMLWriter
15
16 class Abstract
17 def ele(name, *children)
18 element(name, nil, *children)
19 end
20
21 def tag(name, txt)
22 element(name, nil, text(txt))
23 end
24 end
25
26
27 class Simple < Abstract
28
29 def document_to_str(doc)
30 doc
31 end
32
33 def document(*params)
34 params.join("")
35 end
36
37 def pi(name, *params)
38 "<?#{name} " + params.join(" ") + " ?>"
39 end
40
41 def element(name, attrs, *children)
42 raise "attributes not yet implemented" unless attrs.nil?
43 if children.empty?
44 "<#{name}/>"
45 else
46 "<#{name}>" + children.join("") + "</#{name}>"
47 end
48 end
49
50 def text(txt)
51 cleaned = txt.dup
52 cleaned.gsub!(/&/, '&amp;')
53 cleaned.gsub!(/</, '&lt;')
54 cleaned.gsub!(/>/, '&gt;')
55 cleaned
56 end
57
58 end # class Simple
59
60
61 class XMLParser < Abstract
62
63 def initialize
64 require "xmltreebuilder"
65 end
66
67 def document_to_str(doc)
68 doc.to_s
69 end
70
71 def document(*params)
72 XML::SimpleTree::Document.new(*params)
73 end
74
75 def pi(name, *params)
76 XML::SimpleTree::ProcessingInstruction.new(name, *params)
77 end
78
79 def element(name, attrs, *children)
80 XML::SimpleTree::Element.new(name, attrs, *children)
81 end
82
83 def text(txt)
84 XML::SimpleTree::Text.new(txt)
85 end
86
87 end # class XMLParser
88
89 Classes = [Simple, XMLParser]
90
91 # yields an instance of each installed XML writer
92 def self.each_installed_writer
93 XMLRPC::XMLWriter::Classes.each do |klass|
94 begin
95 yield klass.new
96 rescue LoadError
97 end
98 end
99 end
100
101 end # module XMLWriter
102
103 class Create
104
105 def initialize(xml_writer = nil)
106 @writer = xml_writer || Config::DEFAULT_WRITER.new
107 end
108
109
110 def methodCall(name, *params)
111 name = name.to_s
112
113 if name !~ /[a-zA-Z0-9_.:\/]+/
114 raise ArgumentError, "Wrong XML-RPC method-name"
115 end
116
117 parameter = params.collect do |param|
118 @writer.ele("param", conv2value(param))
119 end
120
121 tree = @writer.document(
122 @writer.pi("xml", 'version="1.0"'),
123 @writer.ele("methodCall",
124 @writer.tag("methodName", name),
125 @writer.ele("params", *parameter)
126 )
127 )
128
129 @writer.document_to_str(tree) + "\n"
130 end
131
132
133
134 #
135 # generates a XML-RPC methodResponse document
136 #
137 # if is_ret == false then the params array must
138 # contain only one element, which is a structure
139 # of a fault return-value.
140 #
141 # if is_ret == true then a normal
142 # return-value of all the given params is created.
143 #
144 def methodResponse(is_ret, *params)
145
146 if is_ret
147 resp = params.collect do |param|
148 @writer.ele("param", conv2value(param))
149 end
150
151 resp = [@writer.ele("params", *resp)]
152 else
153 if params.size != 1 or params[0] === XMLRPC::FaultException
154 raise ArgumentError, "no valid fault-structure given"
155 end
156 resp = @writer.ele("fault", conv2value(params[0].to_h))
157 end
158
159
160 tree = @writer.document(
161 @writer.pi("xml", 'version="1.0"'),
162 @writer.ele("methodResponse", resp)
163 )
164
165 @writer.document_to_str(tree) + "\n"
166 end
167
168
169
170 #####################################
171 private
172 #####################################
173
174 #
175 # converts a Ruby object into
176 # a XML-RPC <value> tag
177 #
178 def conv2value(param)
179
180 val = case param
181 when Fixnum
182 @writer.tag("i4", param.to_s)
183
184 when Bignum
185 if Config::ENABLE_BIGINT
186 @writer.tag("i4", param.to_s)
187 else
188 if param >= -(2**31) and param <= (2**31-1)
189 @writer.tag("i4", param.to_s)
190 else
191 raise "Bignum is too big! Must be signed 32-bit integer!"
192 end
193 end
194 when TrueClass, FalseClass
195 @writer.tag("boolean", param ? "1" : "0")
196
197 when String
198 @writer.tag("string", param)
199
200 when Symbol
201 @writer.tag("string", param.to_s)
202
203 when NilClass
204 if Config::ENABLE_NIL_CREATE
205 @writer.ele("nil")
206 else
207 raise "Wrong type NilClass. Not allowed!"
208 end
209
210 when Float
211 @writer.tag("double", param.to_s)
212
213 when Struct
214 h = param.members.collect do |key|
215 value = param[key]
216 @writer.ele("member",
217 @writer.tag("name", key.to_s),
218 conv2value(value)
219 )
220 end
221
222 @writer.ele("struct", *h)
223
224 when Hash
225 # TODO: can a Hash be empty?
226
227 h = param.collect do |key, value|
228 @writer.ele("member",
229 @writer.tag("name", key.to_s),
230 conv2value(value)
231 )
232 end
233
234 @writer.ele("struct", *h)
235
236 when Array
237 # TODO: can an Array be empty?
238 a = param.collect {|v| conv2value(v) }
239
240 @writer.ele("array",
241 @writer.ele("data", *a)
242 )
243
244 when Time, Date, ::DateTime
245 @writer.tag("dateTime.iso8601", param.strftime("%Y%m%dT%H:%M:%S"))
246
247 when XMLRPC::DateTime
248 @writer.tag("dateTime.iso8601",
249 format("%.4d%02d%02dT%02d:%02d:%02d", *param.to_a))
250
251 when XMLRPC::Base64
252 @writer.tag("base64", param.encoded)
253
254 else
255 if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable
256 # convert Ruby object into Hash
257 ret = {"___class___" => param.class.name}
258 param.instance_variables.each {|v|
259 name = v[1..-1]
260 val = param.instance_variable_get(v)
261
262 if val.nil?
263 ret[name] = val if Config::ENABLE_NIL_CREATE
264 else
265 ret[name] = val
266 end
267 }
268 return conv2value(ret)
269 else
270 ok, pa = wrong_type(param)
271 if ok
272 return conv2value(pa)
273 else
274 raise "Wrong type!"
275 end
276 end
277 end
278
279 @writer.ele("value", val)
280 end
281
282 def wrong_type(value)
283 false
284 end
285
286
287 end # class Create
288
289end # module XMLRPC
290
Note: See TracBrowser for help on using the repository browser.