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.
- data/AUTHORS +1 -0
- data/COPYING +165 -0
- data/INSTALL +24 -0
- data/README.rdoc +2 -0
- data/Rakefile +17 -0
- data/TODO +17 -0
- data/contrib/riddl.jpg +0 -0
- data/contrib/riddl.png +0 -0
- data/contrib/riddl.svg +138 -0
- data/lib/riddl/client.rb +423 -0
- data/lib/riddl/commonlogger.rb +16 -0
- data/lib/riddl/constants.rb +5 -0
- data/lib/riddl/error.rb +8 -0
- data/lib/riddl/handlers.rb +14 -0
- data/lib/riddl/handlers/oauth.rb +19 -0
- data/lib/riddl/handlers/plain-type.rb +21 -0
- data/lib/riddl/handlers/relaxng.rb +16 -0
- data/lib/riddl/handlers/xmlschema.rb +16 -0
- data/lib/riddl/header.rb +9 -0
- data/lib/riddl/implementation.rb +57 -0
- data/lib/riddl/ns/common-patterns/addon-security/request.xml +25 -0
- data/lib/riddl/ns/common-patterns/addon-security/response.xml +25 -0
- data/lib/riddl/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
- data/lib/riddl/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
- data/lib/riddl/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
- data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
- data/lib/riddl/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
- data/lib/riddl/ns/common-patterns/properties/1.0/properties.xml +150 -0
- data/lib/riddl/ns/common/datatypes-1_0.rng +79 -0
- data/lib/riddl/ns/common/relaxng-modular.rng +330 -0
- data/lib/riddl/ns/common/relaxng.rng +10 -0
- data/lib/riddl/ns/declaration/1.0/declaration.rng +114 -0
- data/lib/riddl/ns/description/1.0/description.rng +302 -0
- data/lib/riddl/option.rb +9 -0
- data/lib/riddl/parameter.rb +54 -0
- data/lib/riddl/protocols/http/generator.rb +121 -0
- data/lib/riddl/protocols/http/parser.rb +199 -0
- data/lib/riddl/protocols/websocket.rb +103 -0
- data/lib/riddl/protocols/xmpp/generator.rb +176 -0
- data/lib/riddl/protocols/xmpp/parser.rb +118 -0
- data/lib/riddl/roles.rb +15 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Faccess_token.rb +30 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Fon_behalf.rb +22 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0%2Frequest_token.rb +30 -0
- data/lib/riddl/roles/http%3A%2F%2Foauth.net%2F1.0/base.rb +67 -0
- data/lib/riddl/server.rb +519 -0
- data/lib/riddl/utils/description.rb +29 -0
- data/lib/riddl/utils/downloadify.rb +14 -0
- data/lib/riddl/utils/erbserve.rb +23 -0
- data/lib/riddl/utils/fileserve.rb +31 -0
- data/lib/riddl/utils/notifications_producer.rb +310 -0
- data/lib/riddl/utils/properties.rb +474 -0
- data/lib/riddl/utils/xsloverlay.rb +21 -0
- data/lib/riddl/wrapper.rb +280 -0
- data/lib/riddl/wrapper/declaration.rb +103 -0
- data/lib/riddl/wrapper/declaration/facade.rb +94 -0
- data/lib/riddl/wrapper/declaration/interface.rb +34 -0
- data/lib/riddl/wrapper/declaration/tile.rb +107 -0
- data/lib/riddl/wrapper/description.rb +69 -0
- data/lib/riddl/wrapper/description/access.rb +108 -0
- data/lib/riddl/wrapper/description/message_and_transformation.rb +131 -0
- data/lib/riddl/wrapper/description/resource.rb +271 -0
- data/lib/riddl/wrapper/layerchecker.rb +33 -0
- data/lib/riddl/wrapper/messageparser.rb +221 -0
- data/lib/riddl/wrapper/resourcechecker.rb +98 -0
- data/ns/common-patterns/addon-security/request.xml +25 -0
- data/ns/common-patterns/addon-security/response.xml +25 -0
- data/ns/common-patterns/downloadify/1.0/downloadify.xml +18 -0
- data/ns/common-patterns/notifications-consumer/1.0/consumer.xml +100 -0
- data/ns/common-patterns/notifications-producer/1.0/producer.xml +204 -0
- data/ns/common-patterns/properties/1.0/properties.schema.schema +140 -0
- data/ns/common-patterns/properties/1.0/properties.schema.xsl +89 -0
- data/ns/common-patterns/properties/1.0/properties.xml +150 -0
- data/ns/common/datatypes-1_0.rng +79 -0
- data/ns/common/relaxng-modular.rng +330 -0
- data/ns/common/relaxng.rng +10 -0
- data/ns/declaration/1.0/declaration.rng +114 -0
- data/ns/description/1.0/description.rng +302 -0
- data/riddl.gemspec +33 -0
- data/test/smartrunner.rb +48 -0
- data/test/tc_declaration-distributed.rb +79 -0
- data/test/tc_declaration-hybrid.rb +71 -0
- data/test/tc_declaration-local.rb +47 -0
- data/test/tc_helloworld.rb +17 -0
- data/test/tc_producer.rb +54 -0
- data/test/tc_properties.rb +72 -0
- data/tools/flash-policy-server.rb +12 -0
- data/tools/riddlcheck +36 -0
- data/tools/riddlcheck-1_0 +36 -0
- data/tools/riddlprocess +51 -0
- data/tools/riddlprocess-1_0 +51 -0
- metadata +291 -0
@@ -0,0 +1,271 @@
|
|
1
|
+
module Riddl
|
2
|
+
class Wrapper
|
3
|
+
class Description < WrapperUtils
|
4
|
+
|
5
|
+
class Resource
|
6
|
+
def initialize(path=nil,recursive=false)
|
7
|
+
#{{{
|
8
|
+
@path = path
|
9
|
+
@role = nil
|
10
|
+
@resources = {}
|
11
|
+
@access_methods = {}
|
12
|
+
@composition = {}
|
13
|
+
@recursive = recursive
|
14
|
+
#}}}
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_access_methods(des,desres,index,interface)
|
18
|
+
#{{{
|
19
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @in and not(@in='*')]").each do |m|
|
20
|
+
method = m.attributes['method'] || m.qname.name
|
21
|
+
add_request_in_out(index,interface,des,method,m.attributes['in'],m.attributes['out'])
|
22
|
+
end
|
23
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @pass and not(@pass='*')]").each do |m|
|
24
|
+
method = m.attributes['method'] || m.qname.name
|
25
|
+
add_request_in_out(index,interface,des,method,m.attributes['pass'],m.attributes['pass'])
|
26
|
+
end
|
27
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @transformation]").each do |m|
|
28
|
+
method = m.attributes['method'] || m.qname.name
|
29
|
+
add_request_transform(index,interface,des,method,m.attributes['transformation'])
|
30
|
+
end
|
31
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @in and @in='*']").each do |m|
|
32
|
+
method = m.attributes['method'] || m.qname.name
|
33
|
+
add_request_star_out(index,interface,des,method,m.attributes['out'])
|
34
|
+
end
|
35
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and not(@in)]").each do |m|
|
36
|
+
method = m.attributes['method'] || m.qname.name
|
37
|
+
add_request_star_out(index,interface,des,method,m.attributes['out'])
|
38
|
+
end
|
39
|
+
desres.find("des:*[not(name()='resource') and not(name()='websocket') and @pass and @pass='*']").each do |m|
|
40
|
+
method = m.attributes['method'] || m.qname.name
|
41
|
+
add_request_pass(index,interface,method)
|
42
|
+
end
|
43
|
+
desres.find("des:*[not(name()='resource') and name()='websocket']").each do |m|
|
44
|
+
add_websocket(index,interface)
|
45
|
+
end
|
46
|
+
@role = desres.find("string(@role)")
|
47
|
+
@role = nil if @role.strip == ''
|
48
|
+
#}}}
|
49
|
+
end
|
50
|
+
|
51
|
+
# TODO add websockets
|
52
|
+
|
53
|
+
def remove_access_methods(des,filter)
|
54
|
+
#{{{
|
55
|
+
freq = if filter['in'] && filter['in'] != '*'
|
56
|
+
t = [RequestInOut,Riddl::Wrapper::Description::Message.new(des,filter['in'])]
|
57
|
+
t << (filter['out'] ? Riddl::Wrapper::Description::Message.new(des,filter['out']) : nil)
|
58
|
+
elsif filter['pass'] && filter['pass'] != '*'
|
59
|
+
[RequestInOut,Riddl::Wrapper::Description::Message.new(des,filter['pass']),Riddl::Wrapper::Description::Message.new(des,filter['pass'])]
|
60
|
+
elsif filter['in'] && filter['in'] == '*'
|
61
|
+
t = [RequestStarOut]
|
62
|
+
t << (filter['out'] ? Riddl::Wrapper::Description::Message.new(des,filter['out']) : nil)
|
63
|
+
elsif filter['transformation']
|
64
|
+
[RequestTransformation,Riddl::Wrapper::Description::Transformation.new(des,filter['transformation'])]
|
65
|
+
elsif filter['pass'] && filter['pass'] == '*'
|
66
|
+
[RequestPass]
|
67
|
+
end
|
68
|
+
raise BlockError, "blocking #{filter.inspect} not possible" if freq.nil?
|
69
|
+
|
70
|
+
if reqs = @access_methods[filter['method']]
|
71
|
+
reqs = reqs.last # current layer
|
72
|
+
reqs.delete_if do |req|
|
73
|
+
if req.class == freq[0]
|
74
|
+
if req.class == RequestInOut
|
75
|
+
if freq[1] && freq[1].hash == req.in.hash && freq[2] && req.out && freq[2].hash == req.out.hash
|
76
|
+
true
|
77
|
+
elsif freq[1] && freq[1].hash == req.in.hash && !freq[2]
|
78
|
+
true
|
79
|
+
end
|
80
|
+
elsif req.class == RequestStarOut
|
81
|
+
true if freq[1] && req.out && freq[1].hash == req.out.hash
|
82
|
+
elsif req.class == RequestTransformation
|
83
|
+
true if freq[1] && freq[1].hash == req.trans.hash
|
84
|
+
elsif req.class == RequestPass
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
#}}}
|
91
|
+
end
|
92
|
+
|
93
|
+
def compose!
|
94
|
+
#{{{
|
95
|
+
@access_methods.each do |k,v|
|
96
|
+
### remove all emtpy layers
|
97
|
+
v.compact!
|
98
|
+
case v.size
|
99
|
+
when 0
|
100
|
+
when 1
|
101
|
+
@composition[k] = compose_plain(v[0])
|
102
|
+
else
|
103
|
+
@composition[k] = compose_layers(k,v)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
#}}}
|
107
|
+
end
|
108
|
+
|
109
|
+
def compose_layers(k,layers)
|
110
|
+
#{{{
|
111
|
+
routes = []
|
112
|
+
layers[0].find_all{|l|l.class==RequestInOut}.each do |r|
|
113
|
+
traverse_layers(container = [[r]],container[0],layers,1) unless r.used?
|
114
|
+
routes += container unless container.nil?
|
115
|
+
end
|
116
|
+
layers[0].find_all{|l|l.class==RequestTransformation}.each do |r|
|
117
|
+
traverse_layers(container = [[r]],container[0],layers,1) unless r.used?
|
118
|
+
routes += container unless container.nil?
|
119
|
+
end
|
120
|
+
layers[0].find_all{|l|l.class==RequestStarOut}.each do |r|
|
121
|
+
traverse_layers(container = [[r]],container[0],layers,1) unless r.used?
|
122
|
+
routes += container unless container.nil?
|
123
|
+
end
|
124
|
+
layers[0].find_all{|l|l.class==RequestPass}.each do |r|
|
125
|
+
traverse_layers(container = [[r]],container[0],layers,1) unless r.used?
|
126
|
+
routes += container unless container.nil?
|
127
|
+
end
|
128
|
+
routes.map do |r|
|
129
|
+
ret = nil
|
130
|
+
teh_last = r.last
|
131
|
+
begin
|
132
|
+
success = true
|
133
|
+
if r.first.respond_to?(:in) && teh_last.respond_to?(:out)
|
134
|
+
#1: responds first in + last out -> new InOut
|
135
|
+
ret = RequestInOut.new_from_message(r.first.in,teh_last.out)
|
136
|
+
elsif r.first.class == RequestTransformation && teh_last.class == RequestTransformation && teh_last.out.nil?
|
137
|
+
#2: first transform + last transform -> merge transformations
|
138
|
+
ret = RequestTransformation.new_from_transformation(r.first.trans,teh_last.trans)
|
139
|
+
elsif teh_last.respond_to?(:out)
|
140
|
+
#3: responds last out only -> new StarOut
|
141
|
+
ret = RequestStarOut.new_from_message(teh_last.out)
|
142
|
+
elsif teh_last.class == RequestPass
|
143
|
+
#4: last pass -> remove last until #1 or #2 or #3 or size == 1
|
144
|
+
if r.size > 1
|
145
|
+
teh_last = r[-2]
|
146
|
+
success = false
|
147
|
+
else
|
148
|
+
ret = teh_last
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end while !success
|
152
|
+
Composition.new(r,ret)
|
153
|
+
end
|
154
|
+
#}}}
|
155
|
+
end
|
156
|
+
private :compose_layers
|
157
|
+
|
158
|
+
def compose_plain(access_method)
|
159
|
+
#{{{
|
160
|
+
access_method.map do |ret|
|
161
|
+
Composition.new(nil,ret)
|
162
|
+
end
|
163
|
+
#}}}
|
164
|
+
end
|
165
|
+
private :compose_plain
|
166
|
+
|
167
|
+
def traverse_layers(container,path,layers,layer)
|
168
|
+
#{{{
|
169
|
+
return if layers.count <= layer
|
170
|
+
current = path.last
|
171
|
+
current_path = path.dup
|
172
|
+
|
173
|
+
# messages RequestInOut and RequestStarOut with no out are not processed
|
174
|
+
return if ((current.class == RequestInOut || current.class == RequestStarOut) && current.out.nil?)
|
175
|
+
|
176
|
+
if current.class == RequestInOut ||
|
177
|
+
(current.class == RequestTransformation && !current.out.nil?) ||
|
178
|
+
current.class == RequestStarOut
|
179
|
+
# Find all where "in" matches
|
180
|
+
layers[layer].find_all{ |l| (l.class == RequestInOut && l.in.traverse?(current.out) && !l.used?) }.each do |r|
|
181
|
+
path << r
|
182
|
+
path.last.used = true
|
183
|
+
traverse_layers(container,path,layers,layer+1)
|
184
|
+
return
|
185
|
+
end
|
186
|
+
# Find all possible transformations and apply them
|
187
|
+
layers[layer].find_all{ |l| l.class == RequestTransformation }.each_with_index do |r,num|
|
188
|
+
if num > 0
|
189
|
+
path = current_path.dup
|
190
|
+
container << path
|
191
|
+
end
|
192
|
+
path << r.transform(current)
|
193
|
+
r.used = true
|
194
|
+
traverse_layers(container,path,layers,layer+1)
|
195
|
+
end
|
196
|
+
# Find all in=* matches, they are all potential matches, even when used
|
197
|
+
layers[layer].find_all{ |l| l.class == RequestPass || l.class == RequestStarOut }.each_with_index do |r,num|
|
198
|
+
add_to_path_and_split(container,path,layers,layer,num,current_path,r)
|
199
|
+
end
|
200
|
+
return
|
201
|
+
end
|
202
|
+
|
203
|
+
if (current.class == RequestTransformation && current.out.nil?) ||
|
204
|
+
current.class == RequestPass
|
205
|
+
# all unused RequestInOut and all others (even if used)
|
206
|
+
layers[layer].find_all{|l| (l.class == RequestInOut && !l.used?) || (l.class != RequestInOut) }.each_with_index do |r,num|
|
207
|
+
add_to_path_and_split(container,path,layers,layer,num,current_path,r)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
#}}}
|
211
|
+
end
|
212
|
+
private :traverse_layers
|
213
|
+
|
214
|
+
def add_to_path_and_split(container,path,layers,layer,num,current_path,r)
|
215
|
+
#{{{
|
216
|
+
if num > 0
|
217
|
+
path = current_path.dup
|
218
|
+
container << path
|
219
|
+
end
|
220
|
+
path << r
|
221
|
+
path.last.used = true
|
222
|
+
traverse_layers(container,path,layers,layer+1)
|
223
|
+
#}}}
|
224
|
+
end
|
225
|
+
private :add_to_path_and_split
|
226
|
+
|
227
|
+
# add requests helper methods
|
228
|
+
#{{{
|
229
|
+
def add_request_in_out(index,interface,des,method,min,mout)
|
230
|
+
@access_methods[method] ||= []
|
231
|
+
@access_methods[method][index] ||= []
|
232
|
+
@access_methods[method][index] << RequestInOut.new(des,min,mout,interface)
|
233
|
+
end
|
234
|
+
private :add_request_in_out
|
235
|
+
|
236
|
+
def add_request_transform(index,interface,des,method,mtrans)
|
237
|
+
@access_methods[method] ||= []
|
238
|
+
@access_methods[method][index] ||= []
|
239
|
+
@access_methods[method][index] << RequestTransformation.new(des,mtrans,interface)
|
240
|
+
end
|
241
|
+
private :add_request_transform
|
242
|
+
|
243
|
+
def add_request_star_out(index,interface,des,method,mout)
|
244
|
+
@access_methods[method] ||= []
|
245
|
+
@access_methods[method][index] ||= []
|
246
|
+
@access_methods[method][index] << RequestStarOut.new(des,mout,interface)
|
247
|
+
end
|
248
|
+
private :add_request_star_out
|
249
|
+
|
250
|
+
def add_request_pass(index,interface,method)
|
251
|
+
@access_methods[method] ||= []
|
252
|
+
@access_methods[method][index] ||= []
|
253
|
+
@access_methods[method][index] << RequestPass.new(interface)
|
254
|
+
end
|
255
|
+
private :add_request_pass
|
256
|
+
|
257
|
+
def add_websocket(index,interface)
|
258
|
+
@access_methods['websocket'] ||= []
|
259
|
+
@access_methods['websocket'][index] ||= []
|
260
|
+
@access_methods['websocket'][index] << WebSocket.new(interface)
|
261
|
+
end
|
262
|
+
private :add_request_pass
|
263
|
+
#}}}
|
264
|
+
|
265
|
+
attr_reader :resources,:path,:access_methods,:composition,:recursive,:role
|
266
|
+
end
|
267
|
+
|
268
|
+
Composition = Struct.new(:route,:result)
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Riddl
|
2
|
+
class Wrapper
|
3
|
+
class LayerChecker
|
4
|
+
def initialize(doc)
|
5
|
+
@doc = doc
|
6
|
+
end
|
7
|
+
|
8
|
+
def check
|
9
|
+
check_layers(@doc.find("/dec:declaration/dec:facade/dec:tile/dec:layer"))
|
10
|
+
end
|
11
|
+
|
12
|
+
def check_layers(res)
|
13
|
+
#{{{
|
14
|
+
messages = []
|
15
|
+
res.each do |res|
|
16
|
+
messages += check_field(res.attributes['name'],res.parent.attributes['relative'] || '/')
|
17
|
+
end
|
18
|
+
messages
|
19
|
+
#}}}
|
20
|
+
end
|
21
|
+
private :check_layers
|
22
|
+
|
23
|
+
def check_field(name,tile)
|
24
|
+
#{{{
|
25
|
+
if @doc.find("/dec:declaration/dec:interface[@name='#{name}']").empty?
|
26
|
+
["Tile '#{tile}': interface '#{name}' not found."]
|
27
|
+
end || []
|
28
|
+
#}}}
|
29
|
+
end
|
30
|
+
private :check_field
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
module Riddl
|
2
|
+
class Wrapper
|
3
|
+
class MessageParser
|
4
|
+
def initialize(params,headers)
|
5
|
+
#{{{
|
6
|
+
@mist = params
|
7
|
+
@mistp = 0
|
8
|
+
@headp = {}
|
9
|
+
headers.each do |k,v|
|
10
|
+
if v.nil?
|
11
|
+
@headp[k.name.upcase.gsub(/\-/,'_')] = k.value
|
12
|
+
else
|
13
|
+
@headp[k.upcase.gsub(/\-/,'_')] = v
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
@numparams = 0
|
18
|
+
#}}}
|
19
|
+
end
|
20
|
+
|
21
|
+
def check(what,ignore_name=false)
|
22
|
+
#{{{
|
23
|
+
# reset for subsequent calls
|
24
|
+
@mistp = 0
|
25
|
+
@numparams = 0
|
26
|
+
|
27
|
+
# out not available
|
28
|
+
return true if what.nil? && @mist.empty?
|
29
|
+
|
30
|
+
# do it
|
31
|
+
m = what.content.root
|
32
|
+
|
33
|
+
m.find("des:header").each do |h|
|
34
|
+
return false unless header h
|
35
|
+
end
|
36
|
+
|
37
|
+
if ignore_name
|
38
|
+
# if only one parameter, ignore the name
|
39
|
+
@numparams = m.find("count(//des:parameter)").to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
m.find("des:*[not(name()='header')]").each do |p|
|
43
|
+
return false unless send p.qname.to_s, p
|
44
|
+
end
|
45
|
+
|
46
|
+
@mist.count == @mistp
|
47
|
+
#}}}
|
48
|
+
end
|
49
|
+
|
50
|
+
def parameter(a)
|
51
|
+
#{{{
|
52
|
+
return false if @mistp >= @mist.length
|
53
|
+
b = @mist[@mistp]
|
54
|
+
|
55
|
+
if b.class == Riddl::Parameter::Simple && (a.attributes['fixed'] || a.attributes['type'])
|
56
|
+
b.name = a.attributes['name'] if @numparams == 1
|
57
|
+
if (b.name == a.attributes['name'] || a.attributes['name'] == '*')
|
58
|
+
@mistp += 1
|
59
|
+
return match_simple(a,b.value)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
if b.class == Riddl::Parameter::Complex && a.attributes['mimetype']
|
63
|
+
b.name = a.attributes['name'] if @numparams == 1
|
64
|
+
if (b.name == a.attributes['name'] || a.attributes['name'] == '*') && match_mimetype(a,b)
|
65
|
+
if a.attributes['handler']
|
66
|
+
if Riddl::Handlers::handlers[a.attributes['handler']]
|
67
|
+
success = Riddl::Handlers::handlers[a.attributes['handler']].handle(b.value,a.children.map{|e|e.dump}.join)
|
68
|
+
b.value.rewind if b.value.respond_to?(:rewind)
|
69
|
+
if success
|
70
|
+
@mistp += 1
|
71
|
+
return true
|
72
|
+
end
|
73
|
+
else
|
74
|
+
# handler not found leads to an error
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
else
|
78
|
+
@mistp += 1
|
79
|
+
return true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
false
|
84
|
+
#}}}
|
85
|
+
end
|
86
|
+
private :parameter
|
87
|
+
|
88
|
+
def oneOrMore(a)
|
89
|
+
#{{{
|
90
|
+
tistp = @mistp
|
91
|
+
ncounter = 0
|
92
|
+
begin
|
93
|
+
counter,length = traverse_simple(a,true)
|
94
|
+
ncounter += 1 if counter == length
|
95
|
+
end while counter == length && @mistp < @mist.length
|
96
|
+
if ncounter > 0
|
97
|
+
true
|
98
|
+
else
|
99
|
+
@mistp = tistp
|
100
|
+
false
|
101
|
+
end
|
102
|
+
#}}}
|
103
|
+
end
|
104
|
+
|
105
|
+
def zeroOrMore(a)
|
106
|
+
#{{{
|
107
|
+
begin
|
108
|
+
counter,length = traverse_simple(a,true)
|
109
|
+
end while counter == length && @mistp < @mist.length
|
110
|
+
true
|
111
|
+
#}}}
|
112
|
+
end
|
113
|
+
|
114
|
+
def choice(a)
|
115
|
+
#{{{
|
116
|
+
a.find("des:*").each do |p|
|
117
|
+
return true if send p.qname.to_s, p
|
118
|
+
end
|
119
|
+
false
|
120
|
+
#}}}
|
121
|
+
end
|
122
|
+
|
123
|
+
def group(a)
|
124
|
+
#{{{
|
125
|
+
tistp = @mistp
|
126
|
+
success = true
|
127
|
+
a.find("des:*").each do |p|
|
128
|
+
unless send p.qname.to_s, p
|
129
|
+
success = false
|
130
|
+
break
|
131
|
+
end
|
132
|
+
end
|
133
|
+
if success
|
134
|
+
true
|
135
|
+
else
|
136
|
+
@mistp = tistp
|
137
|
+
false
|
138
|
+
end
|
139
|
+
#}}}
|
140
|
+
end
|
141
|
+
|
142
|
+
def optional(a)
|
143
|
+
#{{{
|
144
|
+
return true if @mistp >= @mist.length
|
145
|
+
|
146
|
+
tistp = @mistp
|
147
|
+
counter, length = traverse_simple(a,true)
|
148
|
+
|
149
|
+
if counter == 0 || counter == length
|
150
|
+
true
|
151
|
+
else
|
152
|
+
@mistp = tistp
|
153
|
+
false
|
154
|
+
end
|
155
|
+
#}}}
|
156
|
+
end
|
157
|
+
|
158
|
+
def header(a)
|
159
|
+
#{{{
|
160
|
+
name = a.attributes['name'].upcase.sub(/\-/,'_')
|
161
|
+
if @headp[name]
|
162
|
+
return match_simple(a,@headp[name])
|
163
|
+
end
|
164
|
+
false
|
165
|
+
#}}}
|
166
|
+
end
|
167
|
+
private :header
|
168
|
+
|
169
|
+
def traverse_simple(a,single_optional_protection=false)
|
170
|
+
#{{{
|
171
|
+
tistp = @mistp
|
172
|
+
nodes = a.find("des:*")
|
173
|
+
counter = 0
|
174
|
+
lastname = ''
|
175
|
+
nodes.each do |p|
|
176
|
+
lastname = p.qname.to_s
|
177
|
+
counter += 1 if send lastname, p
|
178
|
+
end
|
179
|
+
if single_optional_protection && lastname == 'optional' && tistp == @mistp
|
180
|
+
[0,-1]
|
181
|
+
else
|
182
|
+
[counter,nodes.length]
|
183
|
+
end
|
184
|
+
#}}}
|
185
|
+
end
|
186
|
+
|
187
|
+
def match_simple(a,b)
|
188
|
+
#{{{
|
189
|
+
if a.attributes['fixed']
|
190
|
+
a.attributes['fixed'] == b
|
191
|
+
else
|
192
|
+
value = XML::Smart::string("<check/>")
|
193
|
+
value.root.text = b
|
194
|
+
type = XML::Smart::string(CHECK)
|
195
|
+
data = type.root.children[0]
|
196
|
+
data.attributes['type'] = a.attributes['type']
|
197
|
+
data.add a.children
|
198
|
+
value.validate_against type
|
199
|
+
end
|
200
|
+
#}}}
|
201
|
+
end
|
202
|
+
private :match_simple
|
203
|
+
|
204
|
+
def match_mimetype(a,b)
|
205
|
+
if (a.attributes['mimetype'] == '*' || b.mimetype == a.attributes['mimetype'])
|
206
|
+
true
|
207
|
+
else
|
208
|
+
ma = a.attributes['mimetype'].split('/')
|
209
|
+
mb = b.mimetype.split('/')
|
210
|
+
if ma.length == 2 && mb.length == 2 && ((ma[0] == mb[0] && ma[1] == '*') || (ma[1] == mb[1] && ma[0] == '*'))
|
211
|
+
true
|
212
|
+
else
|
213
|
+
false
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
private :match_mimetype
|
218
|
+
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|