junoser 0.3.12 → 0.4.2
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG.md +95 -42
- data/Gemfile.lock +12 -10
- data/LICENSE.txt +1 -1
- data/README.md +47 -11
- data/Rakefile +12 -3
- data/example/get-schema.xml +19 -0
- data/example/junos-18.1R3-S9.rb +102366 -0
- data/example/mx-19.3R3-S1.3.rb +118283 -0
- data/example/vmx-17.2R1.13.rb +2287 -2272
- data/example/vsrx-18.3R1.9.rb +1305 -1305
- data/junoser.gemspec +1 -1
- data/lib/junoser/display/structure.rb +1 -1
- data/lib/junoser/js_ruler.rb +20 -21
- data/lib/junoser/parser.rb +40788 -22351
- data/lib/junoser/ruler.rb +137 -84
- data/lib/junoser/version.rb +1 -1
- data/lib/junoser/xsd/base.rb +9 -6
- data/lib/junoser/xsd/choice.rb +6 -2
- data/lib/junoser/xsd/complex_type.rb +3 -3
- data/lib/junoser/xsd/element.rb +7 -3
- data/lib/junoser/xsd/restriction.rb +2 -2
- data/lib/junoser/xsd/sequence.rb +11 -3
- data/lib/junoser/xsd/simple_content.rb +1 -1
- data/lib/junoser/xsd/simple_type.rb +2 -2
- data/lib/junoser/xsd/union.rb +1 -1
- metadata +11 -8
data/lib/junoser/ruler.rb
CHANGED
|
@@ -14,10 +14,9 @@ module Junoser
|
|
|
14
14
|
str = @rule.read
|
|
15
15
|
str = remove_comments(str)
|
|
16
16
|
str = process_reserved_element(str)
|
|
17
|
-
str = str.split(/\n/).map {|l| format(process_line(l)) }.join("\n")
|
|
17
|
+
str = str.split(/\n/).map { |l| format(process_line(l)) }.join("\n")
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
|
|
21
20
|
private
|
|
22
21
|
|
|
23
22
|
def remove_comments(str)
|
|
@@ -27,16 +26,16 @@ module Junoser
|
|
|
27
26
|
def process_line(str)
|
|
28
27
|
return str if str =~ /^(.* do|end)$/
|
|
29
28
|
|
|
30
|
-
str.gsub!(/("[^"]+")/) { "str(#$1)" }
|
|
29
|
+
str.gsub!(/("[^"]+")/) { "str(#$1)" } # "foo" -> str("foo")
|
|
31
30
|
|
|
32
|
-
str.gsub!(/^(\s*)arg(\.as\(:\S+\))? \($/) { "#{$1}b(arg#$2," }
|
|
33
|
-
str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+)(\.as\(:\S+\))?(,?)$/) { "#{$1}a(#$2, #$3)#$4#$5" }
|
|
34
|
-
str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\)(,?)$/) { "#{$1}a(#$2, #$3#$4)#$5" }
|
|
31
|
+
str.gsub!(/^(\s*)arg(\.as\(:\S+\))? \($/) { "#{$1}b(arg#$2," } # arg ( -> b(arg,
|
|
32
|
+
str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+)(\.as\(:\S+\))?(,?)$/) { "#{$1}a(#$2, #$3)#$4#$5" } # str("foo") bar -> a(str("foo"), bar)
|
|
33
|
+
str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\)(,?)$/) { "#{$1}a(#$2, #$3#$4)#$5" } # str("foo") (a | b) -> a(str("foo"), a | b)
|
|
35
34
|
|
|
36
|
-
str.gsub!(/^(\s*)(str\(\S+\)) \($/) { "#{$1}b(#$2," }
|
|
37
|
-
str.gsub!(/^(\s*)(enum)?(\(.*\))(\.as\(:\S\))? \($/) { "#{$1}b(#$2#$3#$4," }
|
|
38
|
-
str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+) \($/) { "#{$1}b(a(#$2, #$3)," }
|
|
39
|
-
str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\) \($/) { "#{$1}a(#$2, #$3#$4," }
|
|
35
|
+
str.gsub!(/^(\s*)(str\(\S+\)) \($/) { "#{$1}b(#$2," } # str("foo") ( -> b(str("foo"),
|
|
36
|
+
str.gsub!(/^(\s*)(enum)?(\(.*\))(\.as\(:\S\))? \($/) { "#{$1}b(#$2#$3#$4," } # (a | b) ( -> b((a | b),
|
|
37
|
+
str.gsub!(/^(\s*)(str\(\S+\)) ([^ \t\n\r\f\(|,]+) \($/) { "#{$1}b(a(#$2, #$3)," } # str("foo") bar ( -> b(a(str("foo"), bar),
|
|
38
|
+
str.gsub!(/^(\s*)(str\(\S+\)) (enum)?\((.*)\) \($/) { "#{$1}a(#$2, #$3#$4," } # str("foo") (a | b) ( -> a(str("foo"), a | b,
|
|
40
39
|
|
|
41
40
|
str
|
|
42
41
|
end
|
|
@@ -46,64 +45,106 @@ module Junoser
|
|
|
46
45
|
|
|
47
46
|
str.gsub! /"groups" \(\s*s\(\s*any\s*\)\s*\)/, 'a("groups", arg, configuration)'
|
|
48
47
|
|
|
49
|
-
%w[as-number confederation-as metric-value limit-threshold filename filter-name class-name classifier-name link-subscription per-traffic-class-bandwidth template-name].each do |key|
|
|
50
|
-
str.gsub! %["#{key}" arg], 'arg'
|
|
51
|
-
end
|
|
52
|
-
|
|
53
48
|
str.gsub! '"equal-literal"', '"="'
|
|
54
49
|
str.gsub! '"plus-literal"', '"+"'
|
|
55
50
|
str.gsub! '"minus-literal"', '"-"'
|
|
56
51
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
#
|
|
53
|
+
# Statements can be quoted
|
|
54
|
+
#
|
|
60
55
|
str.gsub!(/("ssh-\S+") arg/) { "#$1 (quote | arg)" }
|
|
56
|
+
str.gsub! '"message" arg', '"message" (quote | arg)'
|
|
61
57
|
str.gsub! '"description" arg', '"description" (quote | arg)'
|
|
62
58
|
str.gsub! '"as-path-prepend" arg', '"as-path-prepend" (quote | arg)'
|
|
63
|
-
str.gsub!(/arg \| (".*")/) { "#$1 | arg" }
|
|
64
|
-
str.gsub! '"dhcp-service" (', '("dhcp-service" | "dhcp") ('
|
|
65
59
|
|
|
66
|
-
str.gsub!(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
str.gsub!(/"snmp"(.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
|
|
71
|
-
%w[ccc ethernet-over-atm tcc vpls bridge].each do |encap|
|
|
72
|
-
str.gsub!(/"ethernet"(.*)"ethernet-#{encap}"/) { %["ethernet-#{encap}"#$1"ethernet"] }
|
|
60
|
+
str.gsub!(/^(\s*)"as-path" arg \(\s*c\(\s*arg/) do
|
|
61
|
+
format(['"as-path" arg (',
|
|
62
|
+
' c(',
|
|
63
|
+
' quote | arg'], $1)
|
|
73
64
|
end
|
|
74
|
-
str.gsub! '"icmp6" |', '"icmp6" | "icmpv6" |'
|
|
75
|
-
str.gsub!(/"cspf"(.*)"cspf-link"/) { %["cspf-link"#$1"cspf"] }
|
|
76
|
-
str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
|
|
77
|
-
str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
|
|
78
65
|
|
|
79
|
-
|
|
80
|
-
|
|
66
|
+
str.gsub!(/^rule\(:regular_expression\) do\s*((?!end).)*\s*end/) do
|
|
67
|
+
<<~EOS
|
|
68
|
+
rule(:regular_expression) do
|
|
69
|
+
(quote | arg).as(:arg)
|
|
70
|
+
end
|
|
71
|
+
EOS
|
|
81
72
|
end
|
|
82
|
-
|
|
83
|
-
|
|
73
|
+
|
|
74
|
+
str.gsub!(/^rule\(:login_user_object\) do\s*arg\.as\(:arg\) \(\s*c\(\s*"full-name" arg,/) do
|
|
75
|
+
<<~EOS
|
|
76
|
+
rule(:login_user_object) do
|
|
77
|
+
arg.as(:arg) (
|
|
78
|
+
sc(
|
|
79
|
+
"full-name" (quote | arg),
|
|
80
|
+
EOS
|
|
84
81
|
end
|
|
85
|
-
|
|
86
|
-
|
|
82
|
+
|
|
83
|
+
str.gsub!(/^(\s*)"location" arg,\s*"contact" arg,/) do
|
|
84
|
+
format(['"location" (quote | arg),',
|
|
85
|
+
'"contact" (quote | arg),'], $1)
|
|
87
86
|
end
|
|
88
87
|
|
|
88
|
+
str.gsub!(/^(\s*)"as-path" \(\s*c\(\s*"path" arg/) do
|
|
89
|
+
format(['"as-path" (',
|
|
90
|
+
' c(',
|
|
91
|
+
' "path" (quote | arg)'], $1)
|
|
92
|
+
end
|
|
89
93
|
|
|
90
|
-
str.gsub!(/^(\s*)
|
|
91
|
-
format(['"
|
|
92
|
-
'
|
|
93
|
-
' "lacp" (',
|
|
94
|
-
' c(',
|
|
95
|
-
' "force-up",'], $1)
|
|
94
|
+
str.gsub!(/^(\s*)prefix_list_items,\s*"apply-path" arg/) do
|
|
95
|
+
format(['"apply-path" (quote | arg),',
|
|
96
|
+
'prefix_list_items'], $1)
|
|
96
97
|
end
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
|
|
99
|
+
#
|
|
100
|
+
# "arg" matches anything so move to the end
|
|
101
|
+
#
|
|
102
|
+
str.gsub!(/arg \| (".*")/) { "#$1 | arg" }
|
|
103
|
+
str.gsub!(/^(\s*)c\(\s*arg,$/) { "#{$1}ca(" }
|
|
104
|
+
str.gsub!(/(rule\(:control_route_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
|
|
105
|
+
str.gsub!(/(rule\(:control_source_address_filter_type\) do\s*)s\(\s*arg,/) { "#{$1}b(" }
|
|
106
|
+
str.gsub!(/^(rule\(:trace_file_type\) do\s*)ca\(/) { "#{$1}sca(" }
|
|
107
|
+
|
|
108
|
+
str.gsub!(/^(rule\(:archive_object\) do\s*)c\(/) { "#{$1}sc(" }
|
|
109
|
+
str.gsub!(/^(rule\(:server_group_type\) do\s*)c\(\s*c\(\s*arg\s*\)\s*\)/) { "#{$1}s(arg, arg)" }
|
|
110
|
+
|
|
111
|
+
str.gsub!(/^(rule\(:rib_group_inet_type\) do)\s*c\(\s*arg/) do
|
|
112
|
+
format([$1,
|
|
113
|
+
' ca(',
|
|
114
|
+
' a(arg, arg)'], '')
|
|
101
115
|
end
|
|
102
|
-
|
|
116
|
+
|
|
117
|
+
# Fix overkill
|
|
118
|
+
str.gsub!(/^(\s*)"priority" \(\s*ca\(\s*arg\s*\)/) do
|
|
103
119
|
format(['"priority" (',
|
|
104
120
|
' a(arg, arg)', $1])
|
|
105
121
|
end
|
|
106
|
-
|
|
122
|
+
|
|
123
|
+
#
|
|
124
|
+
# Longer pattern first
|
|
125
|
+
#
|
|
126
|
+
# covers:
|
|
127
|
+
# "inet" | "inet6"
|
|
128
|
+
#
|
|
129
|
+
# and even
|
|
130
|
+
#
|
|
131
|
+
# "inet",
|
|
132
|
+
# "inet6"
|
|
133
|
+
str.gsub!(/"cspf"(.*\s*.*)"cspf-link"/) { %["cspf-link"#$1"cspf"] }
|
|
134
|
+
str.gsub!(/"http"(.*\s*.*)"https"/) { %["https"#$1"http"] }
|
|
135
|
+
str.gsub!(/"inet"(.*\s*.*)"inet6"/) { %["inet6"#$1"inet"] }
|
|
136
|
+
str.gsub!(/"icmp"(.*\s*.*)"icmp6"/) { %["icmp6"#$1"icmp"] }
|
|
137
|
+
str.gsub!(/"icmp"(.*\s*.*)"icmpv6"/) { %["icmpv6"#$1"icmp"] }
|
|
138
|
+
str.gsub!(/"snmp"(.*\s*.*)"snmptrap"/) { %["snmptrap"#$1"snmp"] }
|
|
139
|
+
str.gsub!(/"ospf"(.*\s*.*)"ospf3"/) { %["ospf3"#$1"ospf"] }
|
|
140
|
+
str.gsub! '"tls1" | "tls11" | "tls12"', '"tls11" | "tls12" | "tls1"'
|
|
141
|
+
str.gsub!(/("group1" \| "group2" \| "group5") \| ([^\)]+)/) { "#{$2} | #{$1}"}
|
|
142
|
+
|
|
143
|
+
%w[ccc ethernet-over-atm tcc vpls bridge].each do |encap|
|
|
144
|
+
str.gsub!(/"ethernet"(.*)"ethernet-#{encap}"/) { %["ethernet-#{encap}"#$1"ethernet"] }
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
str.gsub!(/^(\s*)"path" arg \(\s*c\(\s*sc\(\s*"abstract",\s*c\(\s*"loose",\s*"loose-link",\s*"strict"\s*\)\s*\)\.as\(:oneline\)/) do
|
|
107
148
|
format(['"path" arg (',
|
|
108
149
|
' c(',
|
|
109
150
|
' b(',
|
|
@@ -119,63 +160,75 @@ module Junoser
|
|
|
119
160
|
' )', $1])
|
|
120
161
|
end
|
|
121
162
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
163
|
+
#
|
|
164
|
+
# Fix .xsd: Elements without "nokeyword" flag
|
|
165
|
+
#
|
|
166
|
+
str.gsub!(/\((.*) \| "name"\)/) { "(#$1 | arg)" }
|
|
167
|
+
str.gsub! '"vlan" ("all" | "vlan-name")', '"vlan" ("all" | arg)'
|
|
168
|
+
str.gsub!(/\((.*) \| "vlan-id"\)/) { "(#$1 | arg)" }
|
|
127
169
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
' (quote | arg).as(:arg)',
|
|
131
|
-
'end'])
|
|
132
|
-
end
|
|
133
|
-
str.gsub!(/^rule\(:login_user_object\) do\s*arg\.as\(:arg\) \(\s*c\(\s*"full-name" arg,/) do
|
|
134
|
-
format(['rule(:login_user_object) do',
|
|
135
|
-
' arg.as(:arg) (',
|
|
136
|
-
' sc(',
|
|
137
|
-
' "full-name" (quote | arg),'])
|
|
170
|
+
%w[filename].each do |key|
|
|
171
|
+
str.gsub! %["#{key}" arg], 'arg'
|
|
138
172
|
end
|
|
139
173
|
|
|
140
|
-
|
|
141
|
-
str.gsub!(
|
|
142
|
-
str.gsub!(/^(rule\(:trace_file_type\) do\s*)c\(\s*arg,/) { "#{$1}sca(" }
|
|
143
|
-
str.gsub!(/^(rule\(:archive_object\) do\s*)c\(/) { "#{$1}sc(" }
|
|
144
|
-
str.gsub!(/^(rule\(:server_group_type\) do\s*)c\(\s*c\(\s*arg\s*\)\s*\)/) { "#{$1}s(arg, arg)" }
|
|
145
|
-
str.gsub!(/^(rule\(:rib_group_inet_type\) do)\s*c\(\s*arg/) do
|
|
146
|
-
format([$1,
|
|
147
|
-
' ca(',
|
|
148
|
-
' a(arg, arg)'], '')
|
|
149
|
-
end
|
|
174
|
+
# "filename" fix above leaves "arg". Move to the end
|
|
175
|
+
str.gsub!(/^(rule\(:esp_trace_file_type\) do\s*)c\(\s*arg,/) { "#{$1}ca(" }
|
|
150
176
|
|
|
151
|
-
|
|
177
|
+
# Fix .xsd: system processes dhcp is valid on some platforms
|
|
178
|
+
str.gsub! '"dhcp-service" (', '("dhcp-service" | "dhcp") ('
|
|
152
179
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
180
|
+
# Fix .xsd: "icmpv6" is also acceptable
|
|
181
|
+
str.gsub! '"icmp6" |', '"icmp6" | "icmpv6" |'
|
|
182
|
+
|
|
183
|
+
#
|
|
184
|
+
# Fix .xsd: "arg" is missing
|
|
185
|
+
#
|
|
186
|
+
str.gsub!(/"route-filter" (\(\s*control_route_filter_type\s*\))/) { %["route-filter" arg #{$1}.as(:oneline)] }
|
|
187
|
+
str.gsub!(/"source-address-filter" (\(\s*control_source_address_filter_type\s*\))/) { %["source-adress-filter" arg #{$1}.as(:oneline)] }
|
|
188
|
+
%w[file].each do |key|
|
|
189
|
+
str.gsub!(/^(\s*"#{key}" \(\s*)c\(\s*arg,/) { "#{$1}sca(" }
|
|
156
190
|
end
|
|
157
191
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
' "path" (quote | arg)'], $1)
|
|
192
|
+
# Fix .xsd: Unnecessary "arg" is added
|
|
193
|
+
%w[exact longer orlonger].each do |key|
|
|
194
|
+
str.gsub!(/^(\s*"#{key}") arg/) { "#{$1}" }
|
|
162
195
|
end
|
|
163
196
|
|
|
197
|
+
# Fix .xsd: "ieee-802.3ad" is invalid
|
|
198
|
+
str.gsub! '"ieee-802.3ad"', '"802.3ad"'
|
|
199
|
+
|
|
200
|
+
# Fix .xsd: "class-of-service interfaces all unit * classifiers exp foo"
|
|
201
|
+
str.gsub!(/^(\s*)sc\(\s*\("default"\)\s*\)/) do
|
|
202
|
+
format(['c(',
|
|
203
|
+
' ("default" | arg)',
|
|
204
|
+
')'], $1)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Fix .xsd: "from-zone" arg is also required
|
|
164
208
|
str.gsub!(/^(\s*)"policy" \(\s*s\(\s*arg,\s*"to-zone-name" arg,\s*c\(\s*"policy" \(\s*policy_type\s*\)\s*\)/) do
|
|
165
209
|
format(['b(s("from-zone", arg, "to-zone", arg),',
|
|
166
210
|
' b("policy", policy_type',
|
|
167
211
|
], $1)
|
|
168
212
|
end
|
|
169
213
|
|
|
214
|
+
# Fix .xsd: "members" accepts [ foo bar ]
|
|
215
|
+
str.gsub! '"members" arg', '"members" any'
|
|
216
|
+
|
|
217
|
+
# Fix .xsd: "term_object" accepts multiple conditions
|
|
218
|
+
str.gsub!(/^(rule\(:term_object\) do\s*arg\.as\(:arg\) \(\s*)c\(/) { "#{$1}sc(" }
|
|
219
|
+
|
|
220
|
+
# Fix .xsd: keywords "dest-nat-rule-match", "src-nat-rule-match", "static-nat-rule-match" are wrong
|
|
221
|
+
str.gsub!(/"(dest|src|static)-nat-rule-match"/) { '"match"' }
|
|
222
|
+
|
|
170
223
|
str
|
|
171
224
|
end
|
|
172
225
|
|
|
173
|
-
def format(str, offset=OFFSET)
|
|
226
|
+
def format(str, offset = OFFSET)
|
|
174
227
|
case str
|
|
175
228
|
when String
|
|
176
229
|
str.empty? ? '' : offset + str
|
|
177
230
|
when Array
|
|
178
|
-
str.map {|s| s.empty? ? '' : offset + s.to_s }.join("\n")
|
|
231
|
+
str.map { |s| s.empty? ? '' : offset + s.to_s }.join("\n")
|
|
179
232
|
end
|
|
180
233
|
end
|
|
181
234
|
|
|
@@ -206,7 +259,7 @@ module Junoser
|
|
|
206
259
|
|
|
207
260
|
begin
|
|
208
261
|
# .xsd doesn't include "apply-groups"
|
|
209
|
-
if line =~ /(.*)\\s+apply-groups
|
|
262
|
+
if line =~ /(.*)\\s+apply-groups(-except)?\\s+(\\S+|\\[.*\\])$/
|
|
210
263
|
return \$1 == 'set' ? true : parse(\$1)
|
|
211
264
|
end
|
|
212
265
|
|
data/lib/junoser/version.rb
CHANGED
data/lib/junoser/xsd/base.rb
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
module Junoser
|
|
2
2
|
module Xsd
|
|
3
3
|
module Base
|
|
4
|
-
attr_reader :xml
|
|
4
|
+
attr_reader :xml, :parent
|
|
5
5
|
|
|
6
6
|
OFFSET = ' '
|
|
7
7
|
|
|
8
8
|
def initialize(xml, options={})
|
|
9
9
|
@xml = xml
|
|
10
10
|
@depth = options[:depth] || 0
|
|
11
|
+
@parent = options[:parent]
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
def config
|
|
@@ -32,15 +33,17 @@ module Junoser
|
|
|
32
33
|
']>'].join("\n#{OFFSET*(@depth+1)}")
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
36
|
def oneliner?
|
|
39
|
-
|
|
37
|
+
# don't use "/flag" as xsd manipulation automatically add "xsd:" prefix
|
|
38
|
+
@oneliner ||= !xml.xpath('./xsd:annotation/xsd:appinfo/*[local-name()="flag" and text()="oneliner"]').empty?
|
|
40
39
|
end
|
|
41
40
|
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
42
44
|
def nokeyword?
|
|
43
|
-
|
|
45
|
+
# don't use "/flag" as xsd manipulation automatically add "xsd:" prefix
|
|
46
|
+
@nokeyword ||= !xml.xpath('./xsd:annotation/xsd:appinfo/*[local-name()="flag" and text()="nokeyword"]').empty?
|
|
44
47
|
end
|
|
45
48
|
|
|
46
49
|
def has_single_child_of?(klass)
|
data/lib/junoser/xsd/choice.rb
CHANGED
|
@@ -10,9 +10,9 @@ module Junoser
|
|
|
10
10
|
@config ||= children.map {|child|
|
|
11
11
|
case child.name
|
|
12
12
|
when 'element'
|
|
13
|
-
Junoser::Xsd::Element.new(child, depth: @depth+1)
|
|
13
|
+
Junoser::Xsd::Element.new(child, depth: @depth+1, parent: self)
|
|
14
14
|
when 'choice'
|
|
15
|
-
Junoser::Xsd::Choice.new(child, depth: @depth+1)
|
|
15
|
+
Junoser::Xsd::Choice.new(child, depth: @depth+1, parent: self)
|
|
16
16
|
else
|
|
17
17
|
raise "ERROR: unknown element: #{child.name}"
|
|
18
18
|
end
|
|
@@ -29,6 +29,10 @@ module Junoser
|
|
|
29
29
|
format('c(', config.map(&:to_s).join(",\n"), ')')
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
|
+
|
|
33
|
+
def unbounded?
|
|
34
|
+
xml['maxOccurs'] == 'unbounded'
|
|
35
|
+
end
|
|
32
36
|
end
|
|
33
37
|
end
|
|
34
38
|
end
|
|
@@ -18,9 +18,9 @@ module Junoser
|
|
|
18
18
|
@config ||= children.map {|child|
|
|
19
19
|
case child.name
|
|
20
20
|
when 'sequence'
|
|
21
|
-
Junoser::Xsd::Sequence.new(child, depth: @depth+1)
|
|
21
|
+
Junoser::Xsd::Sequence.new(child, depth: @depth+1, parent: self)
|
|
22
22
|
when 'simpleContent'
|
|
23
|
-
Junoser::Xsd::SimpleContent.new(child, depth: @depth+1)
|
|
23
|
+
Junoser::Xsd::SimpleContent.new(child, depth: @depth+1, parent: self)
|
|
24
24
|
when 'attribute'
|
|
25
25
|
'arg'
|
|
26
26
|
else
|
|
@@ -52,7 +52,7 @@ module Junoser
|
|
|
52
52
|
def argument
|
|
53
53
|
return unless @argument
|
|
54
54
|
|
|
55
|
-
arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1).config
|
|
55
|
+
arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1, parent: self).config
|
|
56
56
|
raise "ERROR: argument shouldn't consist of multiple elements" if arg.size > 1
|
|
57
57
|
|
|
58
58
|
if root?
|
data/lib/junoser/xsd/element.rb
CHANGED
|
@@ -16,9 +16,9 @@ module Junoser
|
|
|
16
16
|
@config ||= children.map {|child|
|
|
17
17
|
case child.name
|
|
18
18
|
when 'complexType'
|
|
19
|
-
Junoser::Xsd::ComplexType.new(child, depth: @depth+1)
|
|
19
|
+
Junoser::Xsd::ComplexType.new(child, depth: @depth+1, parent: self)
|
|
20
20
|
when 'simpleType'
|
|
21
|
-
Junoser::Xsd::SimpleType.new(child, depth: @depth+1)
|
|
21
|
+
Junoser::Xsd::SimpleType.new(child, depth: @depth+1, parent: self)
|
|
22
22
|
else
|
|
23
23
|
raise "ERROR: unknown element: #{child.name}"
|
|
24
24
|
end
|
|
@@ -70,7 +70,7 @@ module Junoser
|
|
|
70
70
|
when @argument.name == 'simpleType'
|
|
71
71
|
'arg'
|
|
72
72
|
else
|
|
73
|
-
arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1).config
|
|
73
|
+
arg = Junoser::Xsd::Element.new(@argument, depth: @depth+1, parent: self).config
|
|
74
74
|
raise "ERROR: argument shouldn't consist of multiple elements" if arg.size > 1
|
|
75
75
|
arg.first.to_s.strip
|
|
76
76
|
end
|
|
@@ -97,6 +97,10 @@ module Junoser
|
|
|
97
97
|
|
|
98
98
|
def documentation
|
|
99
99
|
@documentation ||= xml.xpath('./xsd:annotation/xsd:documentation').text
|
|
100
|
+
|
|
101
|
+
# Translate multiline documentation into a single line to make it parsable in further processes
|
|
102
|
+
@documentation.gsub! /\n\s*/, ' '
|
|
103
|
+
|
|
100
104
|
@documentation.empty? ? nil : @documentation
|
|
101
105
|
end
|
|
102
106
|
end
|
|
@@ -17,9 +17,9 @@ module Junoser
|
|
|
17
17
|
@config ||= children.map {|child|
|
|
18
18
|
case child.name
|
|
19
19
|
when 'enumeration'
|
|
20
|
-
Junoser::Xsd::Enumeration.new(child, depth: @depth+1)
|
|
20
|
+
Junoser::Xsd::Enumeration.new(child, depth: @depth+1, parent: self)
|
|
21
21
|
when 'simpleType'
|
|
22
|
-
Junoser::Xsd::SimpleType.new(child, depth: @depth+1)
|
|
22
|
+
Junoser::Xsd::SimpleType.new(child, depth: @depth+1, parent: self)
|
|
23
23
|
when 'attribute'
|
|
24
24
|
else
|
|
25
25
|
raise "ERROR: unknown element: #{child.name}"
|
data/lib/junoser/xsd/sequence.rb
CHANGED
|
@@ -11,9 +11,9 @@ module Junoser
|
|
|
11
11
|
@config ||= children.map {|child|
|
|
12
12
|
case child.name
|
|
13
13
|
when 'choice'
|
|
14
|
-
Junoser::Xsd::Choice.new(child, depth: @depth+1)
|
|
14
|
+
Junoser::Xsd::Choice.new(child, depth: @depth+1, parent: self)
|
|
15
15
|
when 'element'
|
|
16
|
-
Junoser::Xsd::Element.new(child, depth: @depth+1)
|
|
16
|
+
Junoser::Xsd::Element.new(child, depth: @depth+1, parent: self)
|
|
17
17
|
when 'any'
|
|
18
18
|
'any'
|
|
19
19
|
else
|
|
@@ -28,7 +28,15 @@ module Junoser
|
|
|
28
28
|
when has_single_child_of?(Junoser::Xsd::Choice)
|
|
29
29
|
child = config.first
|
|
30
30
|
str = child.config.map(&:to_s).reject(&:empty?).join(",\n")
|
|
31
|
-
|
|
31
|
+
|
|
32
|
+
return if str.empty?
|
|
33
|
+
|
|
34
|
+
# Assuming that <xsd:sequence> always has <xsd:complexType> as the parent
|
|
35
|
+
if parent.parent&.oneliner? && config.first.unbounded?
|
|
36
|
+
format('sc(', str, ')')
|
|
37
|
+
else
|
|
38
|
+
format('c(', str, ')')
|
|
39
|
+
end
|
|
32
40
|
else
|
|
33
41
|
str = config.map {|c| c.is_a?(String) ? format(OFFSET + c) : c.to_s }.reject(&:empty?).join(",\n")
|
|
34
42
|
format('s(', str, ')')
|