riddl 0.99.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. data/AUTHORS +1 -0
  2. data/COPYING +165 -0
  3. data/INSTALL +24 -0
  4. data/README.rdoc +2 -0
  5. data/Rakefile +17 -0
  6. data/TODO +17 -0
  7. data/contrib/riddl.jpg +0 -0
  8. data/contrib/riddl.png +0 -0
  9. data/contrib/riddl.svg +138 -0
  10. data/lib/riddl/client.rb +423 -0
  11. data/lib/riddl/commonlogger.rb +16 -0
  12. data/lib/riddl/constants.rb +5 -0
  13. data/lib/riddl/error.rb +8 -0
  14. data/lib/riddl/handlers.rb +14 -0
  15. data/lib/riddl/handlers/oauth.rb +19 -0
  16. data/lib/riddl/handlers/plain-type.rb +21 -0
  17. data/lib/riddl/handlers/relaxng.rb +16 -0
  18. data/lib/riddl/handlers/xmlschema.rb +16 -0
  19. data/lib/riddl/header.rb +9 -0
  20. data/lib/riddl/implementation.rb +57 -0
  21. data/lib/riddl/ns/common-patterns/addon-security/request.xml +25 -0
  22. data/lib/riddl/ns/common-patterns/addon-security/response.xml +25 -0
  23. data/lib/riddl/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
  24. data/lib/riddl/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
  25. data/lib/riddl/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
  26. data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
  27. data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
  28. data/lib/riddl/ns/common-patterns/properties/1.0/properties.xml +150 -0
  29. data/lib/riddl/ns/common/datatypes-1_0.rng +79 -0
  30. data/lib/riddl/ns/common/relaxng-modular.rng +330 -0
  31. data/lib/riddl/ns/common/relaxng.rng +10 -0
  32. data/lib/riddl/ns/declaration/1.0/declaration.rng +114 -0
  33. data/lib/riddl/ns/description/1.0/description.rng +302 -0
  34. data/lib/riddl/option.rb +9 -0
  35. data/lib/riddl/parameter.rb +54 -0
  36. data/lib/riddl/protocols/http/generator.rb +121 -0
  37. data/lib/riddl/protocols/http/parser.rb +199 -0
  38. data/lib/riddl/protocols/websocket.rb +103 -0
  39. data/lib/riddl/protocols/xmpp/generator.rb +176 -0
  40. data/lib/riddl/protocols/xmpp/parser.rb +118 -0
  41. data/lib/riddl/roles.rb +15 -0
  42. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Faccess_token.rb +30 -0
  43. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Fon_behalf.rb +22 -0
  44. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Frequest_token.rb +30 -0
  45. data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0/base.rb +67 -0
  46. data/lib/riddl/server.rb +519 -0
  47. data/lib/riddl/utils/description.rb +29 -0
  48. data/lib/riddl/utils/downloadify.rb +14 -0
  49. data/lib/riddl/utils/erbserve.rb +23 -0
  50. data/lib/riddl/utils/fileserve.rb +31 -0
  51. data/lib/riddl/utils/notifications_producer.rb +310 -0
  52. data/lib/riddl/utils/properties.rb +474 -0
  53. data/lib/riddl/utils/xsloverlay.rb +21 -0
  54. data/lib/riddl/wrapper.rb +280 -0
  55. data/lib/riddl/wrapper/declaration.rb +103 -0
  56. data/lib/riddl/wrapper/declaration/facade.rb +94 -0
  57. data/lib/riddl/wrapper/declaration/interface.rb +34 -0
  58. data/lib/riddl/wrapper/declaration/tile.rb +107 -0
  59. data/lib/riddl/wrapper/description.rb +69 -0
  60. data/lib/riddl/wrapper/description/access.rb +108 -0
  61. data/lib/riddl/wrapper/description/message_and_transformation.rb +131 -0
  62. data/lib/riddl/wrapper/description/resource.rb +271 -0
  63. data/lib/riddl/wrapper/layerchecker.rb +33 -0
  64. data/lib/riddl/wrapper/messageparser.rb +221 -0
  65. data/lib/riddl/wrapper/resourcechecker.rb +98 -0
  66. data/ns/common-patterns/addon-security/request.xml +25 -0
  67. data/ns/common-patterns/addon-security/response.xml +25 -0
  68. data/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
  69. data/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
  70. data/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
  71. data/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
  72. data/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
  73. data/ns/common-patterns/properties/1.0/properties.xml +150 -0
  74. data/ns/common/datatypes-1_0.rng +79 -0
  75. data/ns/common/relaxng-modular.rng +330 -0
  76. data/ns/common/relaxng.rng +10 -0
  77. data/ns/declaration/1.0/declaration.rng +114 -0
  78. data/ns/description/1.0/description.rng +302 -0
  79. data/riddl.gemspec +33 -0
  80. data/test/smartrunner.rb +48 -0
  81. data/test/tc_declaration-distributed.rb +79 -0
  82. data/test/tc_declaration-hybrid.rb +71 -0
  83. data/test/tc_declaration-local.rb +47 -0
  84. data/test/tc_helloworld.rb +17 -0
  85. data/test/tc_producer.rb +54 -0
  86. data/test/tc_properties.rb +72 -0
  87. data/tools/flash-policy-server.rb +12 -0
  88. data/tools/riddlcheck +36 -0
  89. data/tools/riddlcheck-1_0 +36 -0
  90. data/tools/riddlprocess +51 -0
  91. data/tools/riddlprocess-1_0 +51 -0
  92. metadata +291 -0
@@ -0,0 +1,21 @@
1
+ module Riddl
2
+ module Utils
3
+
4
+ class XSLOverlay < Riddl::Implementation
5
+ def response
6
+ doc = if @p[0].value.class == String
7
+ XML::Smart::string(@p[0].value)
8
+ elsif @p[0].value.respond_to?(:read)
9
+ XML::Smart::string(@p[0].value.read)
10
+ else
11
+ nil
12
+ end
13
+ unless doc.nil?
14
+ doc.root.add_before "?xml-stylesheet", "href='#{@a[0]}' type='text/xsl'"
15
+ Riddl::Parameter::Complex.new("content",@p[0].mimetype,doc.to_s)
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,280 @@
1
+ require 'rubygems'
2
+ require 'open-uri'
3
+ gem 'xml-smart', '>= 0.3.0'
4
+ require 'xml/smart'
5
+
6
+ module Riddl
7
+ class Wrapper
8
+ class WrapperUtils
9
+ def get_resource_deep(path,pres)
10
+ #{{{
11
+ path.split('/').each do |pa|
12
+ next if pa == ""
13
+ if pres.resources.has_key?(pa)
14
+ pres = pres.resources[pa]
15
+ else
16
+ return nil
17
+ end
18
+ end
19
+ pres
20
+ #}}}
21
+ end
22
+ def rpaths(res,what)
23
+ #{{{
24
+ what += what == '' ? '/' : res.path
25
+ ret = [[what,res.recursive]]
26
+ res.resources.each do |name,r|
27
+ ret += rpaths(r,what == '/' ? what : what + '/')
28
+ end
29
+ ret.sort!
30
+ ret
31
+ #}}}
32
+ end
33
+ protected :rpaths, :get_resource_deep
34
+ end
35
+ end
36
+ end
37
+
38
+ require File.expand_path(File.dirname(__FILE__) + '/wrapper/description')
39
+ require File.expand_path(File.dirname(__FILE__) + '/wrapper/declaration')
40
+ require File.expand_path(File.dirname(__FILE__) + '/wrapper/messageparser')
41
+ require File.expand_path(File.dirname(__FILE__) + '/wrapper/resourcechecker')
42
+ require File.expand_path(File.dirname(__FILE__) + '/wrapper/layerchecker')
43
+ require File.expand_path(File.dirname(__FILE__) + '/error')
44
+ require File.expand_path(File.dirname(__FILE__) + '/handlers')
45
+ require File.expand_path(File.dirname(__FILE__) + '/roles')
46
+
47
+ module Riddl
48
+ class Wrapper
49
+ #{{{
50
+ VERSION_MAJOR = 1
51
+ VERSION_MINOR = 0
52
+ VERSION = "#{VERSION_MAJOR}.#{VERSION_MINOR}"
53
+ DESCRIPTION = "http://riddl.org/ns/description/#{VERSION}"
54
+ DECLARATION = "http://riddl.org/ns/declaration/#{VERSION}"
55
+ XINCLUDE = "http://www.w3.org/2001/XInclude"
56
+ DESCRIPTION_FILE = "#{File.dirname(__FILE__)}/ns/description/#{VERSION_MAJOR}.#{VERSION_MINOR}/description.rng"
57
+ DECLARATION_FILE = "#{File.dirname(__FILE__)}/ns/declaration/#{VERSION_MAJOR}.#{VERSION_MINOR}/declaration.rng"
58
+ COMMON = "datatypeLibrary=\"http://www.w3.org/2001/XMLSchema-datatypes\" xmlns=\"#{DESCRIPTION}\" xmlns:xi=\"http://www.w3.org/2001/XInclude\""
59
+ CHECK = "<element name=\"check\" datatypeLibrary=\"http://www.w3.org/2001/XMLSchema-datatypes\" xmlns=\"http://relaxng.org/ns/structure/1.0\"><data/></element>"
60
+ #}}}
61
+
62
+ def initialize(name,get_description=false)
63
+ #{{{
64
+ @doc = nil
65
+
66
+ fpath = nil
67
+ if name.is_a?(XML::Smart::Dom)
68
+ @doc = name
69
+ else
70
+ begin
71
+ fh = name.respond_to?(:read) ? name : open(name)
72
+ @doc = XML::Smart.string(fh.read)
73
+ fh.close
74
+ fpath = File.dirname(fh.path) if fh.is_a?(File) || fh.is_a?(Tempfile)
75
+ rescue
76
+ begin
77
+ @doc = XML::Smart.string(name)
78
+ rescue
79
+ raise SpecificationError, "#{name.inspect} is no RIDDL description or declaration (neither a file, url or string)."
80
+ end
81
+ end
82
+ end
83
+ @doc.register_namespace 'x', XINCLUDE
84
+ @doc.find('//x:include/@href').each do |i|
85
+ if i.value =~ /^http:\/\/(www\.)?riddl\.org(\/ns\/common-patterns\/.*)/
86
+ t = File.expand_path(File.dirname(__FILE__)) + $2
87
+ i.value = t if File.exists?(t)
88
+ end
89
+ end
90
+ fpath.nil? ? @doc.xinclude! : @doc.xinclude!(fpath)
91
+ @doc.register_namespace 'des', DESCRIPTION
92
+ @doc.register_namespace 'dec', DECLARATION
93
+ qname = @doc.root.qname
94
+ @is_description = qname.href == DESCRIPTION && qname.name == 'description'
95
+ @is_declaration = qname.href == DECLARATION && qname.name == 'declaration'
96
+
97
+ if @is_description && get_description
98
+ n = @doc.root.children
99
+ if n.empty?
100
+ @doc.root.add("message",:name=>"riddl-description-request").add("parameter",:name=>"riddl-description",:type=>"string")
101
+ @doc.root.add("message",:name=>"riddl-description-response").add("parameter",:name=>"riddl-description",:mimetype=>"text/xml")
102
+ else
103
+ n.first.add_before("message",:name=>"riddl-description-response").add("parameter",:name=>"riddl-description",:mimetype=>"text/xml")
104
+ n.first.add_before("message",:name=>"riddl-description-request").add("parameter",:name=>"riddl-description",:type=>"string")
105
+ end
106
+
107
+ r = @doc.find("/des:description/des:resource")
108
+ unless r.empty?
109
+ n = r.first.children
110
+ if n.empty?
111
+ r.add("get",:in=>'riddl-description-request',:out=>'riddl-description-response')
112
+ else
113
+ n.first.add_before("get",:in=>'riddl-description-request',:out=>'riddl-description-response')
114
+ end
115
+ end
116
+ end
117
+ @declaration = @description = nil
118
+ #}}}
119
+ end
120
+
121
+ def declaration
122
+ #{{{
123
+ if @is_declaration
124
+ @declaration = Riddl::Wrapper::Declaration.new(@doc)
125
+ end
126
+ @declaration
127
+ #}}}
128
+ end
129
+
130
+ def description
131
+ #{{{
132
+ if @is_description
133
+ @description = Riddl::Wrapper::Description.new(@doc)
134
+ end
135
+ @description
136
+ #}}}
137
+ end
138
+
139
+ def role(path) #{{{
140
+ description
141
+ declaration
142
+ return @description.get_resource(path).role if @is_description
143
+ return @declaration.get_resource(path).role if @is_declaration
144
+ nil
145
+ end #}}}
146
+
147
+ def io_messages(path,operation,params,headers)
148
+ #{{{
149
+ description
150
+ declaration
151
+
152
+ req = @description.get_resource(path).access_methods if @is_description
153
+ req = @declaration.get_resource(path).composition if @is_declaration
154
+
155
+ mp = MessageParser.new(params,headers)
156
+ if req.has_key?(operation)
157
+ if @is_description
158
+ r = req[operation][0]
159
+ r.select{|o|o.class==Riddl::Wrapper::Description::RequestInOut}.each do |o|
160
+ return IOMessages.new(o.in, o.out) if mp.check(o.in)
161
+ end
162
+ r.select{|o|o.class==Riddl::Wrapper::Description::RequestTransformation}.each do |o|
163
+ # TODO guess structure from input, create new output structure
164
+ return IOMessages.new(Riddl::Wrapper::Description::Star.new, Riddl::Wrapper::Description::Star.new)
165
+ end
166
+ r.select{|o|o.class==Riddl::Wrapper::Description::RequestStarOut}.each do |o|
167
+ return IOMessages.new(Riddl::Wrapper::Description::Star.new, o.out)
168
+ end
169
+ r.select{|o|o.class==Riddl::Wrapper::Description::RequestPass}.each do |o|
170
+ return IOMessages.new(Riddl::Wrapper::Description::Star.new, Riddl::Wrapper::Description::Star.new)
171
+ end
172
+ r.select{|o|o.class==Riddl::Wrapper::Description::WebSocket}.each do |o|
173
+ return IOMessages.new(nil,nil,nil,o.result.interface)
174
+ end
175
+ end
176
+ if @is_declaration
177
+ r = req[operation]
178
+ r.select{|o|o.result.class==Riddl::Wrapper::Description::RequestInOut}.each do |o|
179
+ return IOMessages.new(o.result.in, o.result.out, o.route, o.result.interface) if mp.check(o.result.in)
180
+ end
181
+ r.select{|o|o.result.class==Riddl::Wrapper::Description::RequestTransformation}.each do |o|
182
+ # TODO guess structure from input, create new output structure
183
+ return IOMessages.new(Riddl::Wrapper::Description::Star.new, Riddl::Wrapper::Description::Star.new, o.route, o.result.interface)
184
+ end
185
+ r.select{|o|o.result.class==Riddl::Wrapper::Description::RequestStarOut}.each do |o|
186
+ return IOMessages.new(Riddl::Wrapper::Description::Star.new, o.result.out, o.route, o.result.interface)
187
+ end
188
+ r.select{|o|o.result.class==Riddl::Wrapper::Description::RequestPass}.each do |o|
189
+ return IOMessages.new(Riddl::Wrapper::Description::Star.new, Riddl::Wrapper::Description::Star.new, o.route, o.result.interface)
190
+ end
191
+ r.select{|o|o.result.class==Riddl::Wrapper::Description::WebSocket}.each do |o|
192
+ return IOMessages.new(nil,nil,nil,o.result.interface)
193
+ end
194
+ end
195
+ end
196
+ return nil
197
+ #}}}
198
+ end
199
+
200
+ def check_message(params,headers,message)
201
+ description
202
+ declaration
203
+ #{{{
204
+ return true if message.class == Riddl::Wrapper::Description::Star
205
+ return true if message.nil? && params == []
206
+ mp = MessageParser.new(params,headers)
207
+ mp.check(message,true)
208
+ #}}}
209
+ end
210
+
211
+ def validate!
212
+ #{{{
213
+ if @is_description
214
+ xval = @doc.validate_against(XML::Smart.open_unprotected(DESCRIPTION_FILE))
215
+ xchk = ResourceChecker.new(@doc).check
216
+ puts xchk.join("\n") unless xchk.empty?
217
+ return xval && xchk.empty?
218
+ end
219
+ if @is_declaration
220
+ xval = @doc.validate_against(XML::Smart.open_unprotected(DECLARATION_FILE))
221
+ xchk = LayerChecker.new(@doc).check
222
+ puts xchk.join("\n") unless xchk.empty?
223
+ return xval && xchk.empty?
224
+ end
225
+ nil
226
+ #}}}
227
+ end
228
+
229
+ def load_necessary_handlers!
230
+ #{{{
231
+ @doc.find("//des:parameter/@handler").map{|h|h.to_s}.uniq.each do |h|
232
+ if File.exists?(File.dirname(__FILE__) + '/handlers/' + File.basename(h) + ".rb")
233
+ require File.expand_path(File.dirname(__FILE__) + '/handlers/' + File.basename(h))
234
+ end
235
+ end
236
+ #}}}
237
+ end
238
+ def load_necessary_roles!
239
+ #{{{
240
+ @doc.find("//des:resource/@role").map{|h|h.to_s}.uniq.each do |h|
241
+ h = Protocols::HTTP::Generator::escape(h)
242
+ if File.exists?(File.dirname(__FILE__) + '/roles/' + h + '.rb')
243
+ require File.expand_path(File.dirname(__FILE__) + '/roles/' + h)
244
+ end
245
+ end
246
+ #}}}
247
+ end
248
+
249
+ def paths
250
+ #{{{
251
+ description
252
+ declaration
253
+ tmp = []
254
+ tmp = @description.paths if @is_description
255
+ tmp = @declaration.paths if @is_declaration
256
+ tmp.map do |t|
257
+ [t[0],Regexp.new("^" + t[0].gsub(/\{\}/,"[^/]+") + (t[1] ? '\/?' : '\/?$'))]
258
+ end
259
+ #}}}
260
+ end
261
+
262
+ class IOMessages
263
+ #{{{
264
+ def initialize(min,mout,route=nil,interface=nil)
265
+ @in = min
266
+ @out = mout
267
+ @route = route
268
+ @interface = interface
269
+ end
270
+ def route?
271
+ !(route.nil? || route.empty?)
272
+ end
273
+ attr_reader :in, :out, :route, :interface
274
+ #}}}
275
+ end
276
+
277
+ def declaration?; @is_declaration; end
278
+ def description?; @is_description; end
279
+ end
280
+ end
@@ -0,0 +1,103 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/description')
2
+ require File.expand_path(File.dirname(__FILE__) + '/declaration/tile')
3
+ require File.expand_path(File.dirname(__FILE__) + '/declaration/facade')
4
+ require File.expand_path(File.dirname(__FILE__) + '/declaration/interface')
5
+
6
+ module Riddl
7
+ class Wrapper
8
+ class Declaration < WrapperUtils
9
+
10
+ def get_resource(path)
11
+ get_resource_deep(path,@facade.resource)
12
+ end
13
+ def paths
14
+ rpaths(@facade.resource,'')
15
+ end
16
+
17
+ def description_xml
18
+ @facade.description_xml
19
+ end
20
+
21
+ def description
22
+ Riddl::Wrapper.new(@facade.description_xml)
23
+ end
24
+
25
+ def visualize_tiles_and_layers
26
+ #{{{
27
+ @tiles.each_with_index do |til,index|
28
+ puts "### Tile #{index} " + ("#" * 60)
29
+ til.visualize :layers
30
+ end
31
+ #}}}
32
+ end
33
+ def visualize_tiles_and_compositions
34
+ #{{{
35
+ @tiles.each_with_index do |til,index|
36
+ puts "### Tile #{index} " + ("#" * 60)
37
+ til.visualize :composition
38
+ end
39
+ #}}}
40
+ end
41
+ def visualize_facade(res=@facade.resource,what='')
42
+ #{{{
43
+ what += res.path
44
+ puts what
45
+ res.composition.each do |k,v|
46
+ puts " #{k.to_s.upcase}:"
47
+ v.each do |r|
48
+ puts " #{r.result.class.name.gsub(/[^\:]+::/,'')}: #{r.result.visualize}"
49
+ r.route.each do |ritem|
50
+ puts " #{ritem.class.name.gsub(/[^\:]+::/,'')}: #{ritem.visualize}"
51
+ end unless r.route.nil?
52
+ end
53
+ end
54
+ res.resources.each do |key,r|
55
+ visualize_facade(r,what + (what == '/' ? '' : '/'))
56
+ end
57
+ #}}}
58
+ end
59
+
60
+ def initialize(riddl)
61
+ @facade = Riddl::Wrapper::Declaration::Facade.new
62
+ #{{{
63
+ ### create single tiles
64
+ @tiles = []
65
+ @interfaces = {}
66
+ riddl.find("/dec:declaration/dec:interface").each do |int|
67
+ @interfaces[int.attributes['name']] = [int.attributes['location'],int.find("des:description").first]
68
+ end
69
+ riddl.find("/dec:declaration/dec:facade/dec:tile").each do |tile|
70
+ @tiles << (til = Tile.new)
71
+ res = til.base_path(tile.attributes['path'] || '/')
72
+ # res.clean! # for overlapping tiles, each tile gets an empty path TODO
73
+ tile.find("dec:layer").each_with_index do |layer,index|
74
+ apply_to = layer.find("dec:apply-to")
75
+ block = layer.find("dec:block")
76
+
77
+ lname = layer.attributes['name']
78
+ lpath, des = @interfaces[lname]
79
+ desres = des.find("des:resource").first
80
+ if apply_to.empty?
81
+ int = Interface.new(lname,"/",lpath,"/",des)
82
+ rec = desres.attributes['recursive']
83
+ til.add_description(des,desres,"/",index,int,block,rec)
84
+ else
85
+ apply_to.each do |at|
86
+ int = Interface.new(lname,at.to_s,lpath,"/",des)
87
+ til.add_description(des,desres,at.to_s,index,int,block)
88
+ end
89
+ end
90
+ end
91
+ til.compose!
92
+ end
93
+
94
+ ### merge tiles into a facade
95
+ @tiles.each do |til|
96
+ @facade.merge_tiles(til.resource)
97
+ end
98
+ #}}}
99
+ end
100
+
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,94 @@
1
+ module Riddl
2
+ class Wrapper
3
+ class Declaration < WrapperUtils
4
+
5
+ class Facade
6
+ def initialize
7
+ @resource = Riddl::Wrapper::Description::Resource.new("/")
8
+ end
9
+
10
+ def description_xml
11
+ #{{{
12
+ result = ""
13
+ messages = {}
14
+ names = []
15
+ messages_result = ""
16
+ description_result = ""
17
+ description_xml_priv(result,messages,0)
18
+ messages.each do |hash,mess|
19
+ t = mess.content.dup
20
+ name = mess.name
21
+ name += '_' while names.include?(name)
22
+ t.root.attributes['name'] = name
23
+ messages_result << t.root.dump + "\n"
24
+ end
25
+ XML::Smart.string("<description #{Riddl::Wrapper::COMMON}>\n\n" + description_result + messages_result.gsub(/^/,' ') + "\n" + result + "\n</description>").to_s
26
+ #}}}
27
+ end
28
+ def description_xml_priv(result,messages,level,res=@resource)
29
+ #{{{
30
+ s = " " * (level + 1)
31
+ t = " " * (level + 2)
32
+ result << s + "<resource#{res.path != '/' && res.path != '{}' ? " relative=\"#{res.path}\"" : ''}#{res.recursive ? " recursive=\"true\"" : ''}>\n"
33
+ res.composition.each do |k,v|
34
+ v.each do |m|
35
+ m = m.result
36
+ if %w{get post put delete websocket}.include?(k)
37
+ result << t + "<#{k} "
38
+ else
39
+ result << t + "<request method=\"#{k}\" "
40
+ end
41
+ case m
42
+ when Riddl::Wrapper::Description::RequestInOut
43
+ messages[m.in.hash] ||= m.in
44
+ result << "in=\"#{messages[m.in.hash].name}\""
45
+ unless m.out.nil?
46
+ messages[m.out.hash] ||= m.out
47
+ result << " out=\"#{messages[m.out.hash].name}\""
48
+ end
49
+ when Riddl::Wrapper::Description::RequestStarOut
50
+ result << "in=\"*\""
51
+ unless m.out.nil?
52
+ messages[m.out.hash] ||= m.out
53
+ result << " out=\"#{messages[m.out.hash].name}\""
54
+ end
55
+ when Riddl::Wrapper::Description::RequestPass
56
+ messages[m.pass.hash] ||= m.pass
57
+ result << "pass=\"#{messages[m.pass.hash].name}\""
58
+ when Riddl::Wrapper::Description::RequestTransformation
59
+ messages[m.trans.hash] ||= m.trans
60
+ result << "transformation=\"#{messages[m.trans.hash].name}\""
61
+ end
62
+ result << "/>\n"
63
+ end
64
+ end
65
+ res.resources.each do |k,v|
66
+ description_xml_priv(result,messages,level+1,v)
67
+ end
68
+ ""
69
+ result << s + "</resource>\n"
70
+ #}}}
71
+ end
72
+ private :description_xml_priv
73
+
74
+ def merge_tiles(res,fac=@resource)
75
+ #{{{
76
+ res.composition.each do |method,s|
77
+ fac.composition[method] ||= []
78
+ fac.composition[method] += s
79
+ end
80
+ res.resources.each do |path,r|
81
+ unless fac.resources.has_key?(path)
82
+ fac.resources[path] = Riddl::Wrapper::Description::Resource.new(path,r.recursive)
83
+ end
84
+ merge_tiles(r,fac.resources[path])
85
+ end
86
+ #}}}
87
+ end
88
+
89
+ attr_reader :resource
90
+ end
91
+
92
+ end
93
+ end
94
+ end