rubyang 0.1.2.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,35 +1,35 @@
1
1
  # coding: utf-8
2
+ # vim: et ts=2 sw=2
2
3
 
3
4
  require 'bundler/setup'
4
-
5
5
  require 'fileutils'
6
6
  require 'drb/drb'
7
7
 
8
8
  module Rubyang
9
- module Component
10
- class Base
11
- include DRb::DRbUndumped
9
+ module Component
10
+ class Base
11
+ include DRb::DRbUndumped
12
12
 
13
- def initialize
14
- @rubyang_sock_file = "/tmp/rubyang/server/Example.sock"
15
- @db = DRbObject.new_with_uri( "drbunix:#{@rubyang_sock_file}" )
13
+ def initialize
14
+ @rubyang_sock_file = "/tmp/rubyang/server/Example.sock"
15
+ @db = DRbObject.new_with_uri( "drbunix:#{@rubyang_sock_file}" )
16
16
 
17
- #@pid = Process.pid
18
- @sock_dir = "/tmp/rubyang/component"
19
- #@sock_file = "#{@sock_dir}/#{self.class}.#{pid}.sock"
20
- @sock_file = "#{@sock_dir}/#{self.class}.sock"
17
+ #@pid = Process.pid
18
+ @sock_dir = "/tmp/rubyang/component"
19
+ #@sock_file = "#{@sock_dir}/#{self.class}.#{pid}.sock"
20
+ @sock_file = "#{@sock_dir}/#{self.class}.sock"
21
21
 
22
- FileUtils.mkdir_p @sock_dir
22
+ FileUtils.mkdir_p @sock_dir
23
23
 
24
- DRb.start_service( "drbunix:#{@sock_file}", self )
25
- DRb.thread.join
26
- end
24
+ DRb.start_service( "drbunix:#{@sock_file}", self )
25
+ DRb.thread.join
26
+ end
27
27
 
28
- def run
29
- end
28
+ def run
29
+ end
30
30
 
31
- def finish
32
- end
33
- end
34
- end
31
+ def finish
32
+ end
33
+ end
34
+ end
35
35
  end
@@ -1,14 +1,15 @@
1
1
  # coding: utf-8
2
+ # vim: et ts=2 sw=2
2
3
 
3
- require_relative 'base'
4
+ require 'rubyang/component/base'
4
5
 
5
6
  class Example < Rubyang::Component::Base
6
- def run
7
- config = @db.configure
8
- File.open( '/tmp/rubyang_component_example.txt', 'w' ){ |fo|
9
- fo.puts config.to_xml( pretty: true )
10
- }
11
- end
7
+ def run
8
+ config = @db.configure
9
+ File.open( '/tmp/rubyang_component_example.txt', 'w' ){ |fo|
10
+ fo.puts config.to_xml( pretty: true )
11
+ }
12
+ end
12
13
  end
13
14
 
14
15
  example = Example.new
@@ -1,39 +1,50 @@
1
1
  # coding: utf-8
2
+ # vim: et ts=2 sw=2
2
3
 
3
- require_relative 'model'
4
- require_relative 'xpath'
5
-
6
- require_relative 'database/schema_tree'
7
- require_relative 'database/data_tree'
4
+ require 'rubyang/model'
5
+ require 'rubyang/xpath'
6
+ require 'rubyang/database/logger'
7
+ require 'rubyang/database/schema_tree'
8
+ require 'rubyang/database/data_tree'
8
9
 
9
10
  module Rubyang
10
- class Database
11
- def initialize
12
- @yangs = Array.new
13
- @schema_tree = SchemaTree.new @yangs
14
- @data_tree = DataTree.new @schema_tree
15
- end
16
-
17
- def to_s parent=true
18
- head, vars, tail = "#<#{self.class.to_s}:0x#{(self.object_id << 1).to_s(16).rjust(14,'0')} ", Array.new, ">"
19
- if parent
20
- vars.push "@yangs=#{@yangs.to_s}"
21
- vars.push "@schema_tree=#{@schema_tree.to_s( false )}"
22
- vars.push "@data_tree=#{@data_tree.to_s( false )}"
23
- end
24
- head + vars.join(', ') + tail
25
- end
26
-
27
- def load_model model
28
- @schema_tree.load model
29
- end
30
-
31
- def configure
32
- @data_tree.root
33
- end
34
-
35
- def configuration
36
- @data_tree.root
37
- end
38
- end
11
+ class Database
12
+ def initialize
13
+ @yangs = Array.new
14
+ @schema_tree = SchemaTree.new @yangs
15
+ @config_tree = DataTree.new @schema_tree, Rubyang::Database::DataTree::Mode::CONFIG
16
+ @oper_tree = DataTree.new @schema_tree, Rubyang::Database::DataTree::Mode::OPER
17
+ end
18
+
19
+ def to_s parent=true
20
+ head, vars, tail = "#<#{self.class.to_s}:0x#{(self.object_id << 1).to_s(16).rjust(14,'0')} ", Array.new, ">"
21
+ if parent
22
+ vars.push "@yangs=#{@yangs.to_s}"
23
+ vars.push "@schema_tree=#{@schema_tree.to_s( false )}"
24
+ vars.push "@config_tree=#{@config_tree.to_s( false )}"
25
+ vars.push "@oper_tree=#{@oper_tree.to_s( false )}"
26
+ end
27
+ head + vars.join(', ') + tail
28
+ end
29
+
30
+ def load_model model
31
+ @schema_tree.load model
32
+ end
33
+
34
+ def configure
35
+ @config_tree.root
36
+ end
37
+
38
+ def configuration
39
+ @config_tree.root
40
+ end
41
+
42
+ def oper
43
+ @oper_tree.root
44
+ end
45
+
46
+ def operational
47
+ @oper_tree.root
48
+ end
49
+ end
39
50
  end
@@ -1,77 +1,77 @@
1
1
  # coding: utf-8
2
+ # vim: et ts=2 sw=2
2
3
 
3
4
  require 'open3'
4
5
  require 'drb/drb'
5
-
6
- require_relative '../../rubyang'
6
+ require 'rubyang'
7
7
 
8
8
  module Rubyang
9
- class Database
10
- class ComponentManager
11
- class Component
12
- attr_reader :name, :hook, :path, :sock, :thread, :instance
9
+ class Database
10
+ class ComponentManager
11
+ class Component
12
+ attr_reader :name, :hook, :path, :sock, :thread, :instance
13
13
 
14
- def initialize name, hook, path
15
- @name = name
16
- @hook = hook
17
- @path = path
18
- @sock = "/tmp/rubyang/component/#{@name}.sock"
19
- end
14
+ def initialize name, hook, path
15
+ @name = name
16
+ @hook = hook
17
+ @path = path
18
+ @sock = "/tmp/rubyang/component/#{@name}.sock"
19
+ end
20
20
 
21
- def start
22
- begin
23
- @thread = Thread.new( @path ) do |path|
24
- stdout, stderr, status = Open3.capture3( "#{RUBY_ENGINE} #{path}" )
25
- end
26
- 10.times{ |i|
27
- break if File.socket? @sock
28
- sleep 1
29
- raise "Load failed: #{@name} : #{@path}" if i == 9
30
- }
31
- @instance = DRbObject.new_with_uri( "drbunix:#{@sock}" )
32
- rescue => e
33
- puts "Error: #{e}"
34
- end
35
- end
21
+ def start
22
+ begin
23
+ @thread = Thread.new( @path ) do |path|
24
+ stdout, stderr, status = Open3.capture3( "#{RUBY_ENGINE} #{path}" )
25
+ end
26
+ 10.times{ |i|
27
+ break if File.socket? @sock
28
+ sleep 1
29
+ raise "Load failed: #{@name} : #{@path}" if i == 9
30
+ }
31
+ @instance = DRbObject.new_with_uri( "drbunix:#{@sock}" )
32
+ rescue => e
33
+ puts "Error: #{e}"
34
+ end
35
+ end
36
36
 
37
- def run
38
- begin
39
- @instance.run
40
- rescue => e
41
- puts "Error: #{e}"
42
- end
43
- end
44
- end
37
+ def run
38
+ begin
39
+ @instance.run
40
+ rescue => e
41
+ puts "Error: #{e}"
42
+ end
43
+ end
44
+ end
45
45
 
46
- def initialize
47
- @components = Array.new
48
- end
46
+ def initialize
47
+ @components = Array.new
48
+ end
49
49
 
50
- def update components
51
- current_component_names = @components.map{ |c| c.name }
52
- new_component_names = components.map{ |c| c[0] }
53
- unloading_component_names = current_component_names - new_component_names
54
- loading_component_names = new_component_names - current_component_names
55
- puts "Load: #{loading_component_names}"
56
- puts "Unload: #{unloading_component_names}"
57
- unloading_component_names.each{ |n|
58
- component = @components.find{ |c| c.name == n }
59
- component.thread.kill
60
- @components.delete_if{ |c| c.name == n }
61
- }
62
- loading_component_names.each{ |n|
63
- name, hook, path = components.find{ |c| c[0] == n }
64
- component = Component.new name, hook, path
65
- component.start
66
- @components.push component
67
- }
68
- end
50
+ def update components
51
+ current_component_names = @components.map{ |c| c.name }
52
+ new_component_names = components.map{ |c| c[0] }
53
+ unloading_component_names = current_component_names - new_component_names
54
+ loading_component_names = new_component_names - current_component_names
55
+ puts "Load: #{loading_component_names}"
56
+ puts "Unload: #{unloading_component_names}"
57
+ unloading_component_names.each{ |n|
58
+ component = @components.find{ |c| c.name == n }
59
+ component.thread.kill
60
+ @components.delete_if{ |c| c.name == n }
61
+ }
62
+ loading_component_names.each{ |n|
63
+ name, hook, path = components.find{ |c| c[0] == n }
64
+ component = Component.new name, hook, path
65
+ component.start
66
+ @components.push component
67
+ }
68
+ end
69
69
 
70
- def run hook
71
- @components.select{ |c| c.hook == hook }.each{ |c|
72
- c.run
73
- }
74
- end
75
- end
76
- end
70
+ def run hook
71
+ @components.select{ |c| c.hook == hook }.each{ |c|
72
+ c.run
73
+ }
74
+ end
75
+ end
76
+ end
77
77
  end
@@ -1,1109 +1,1142 @@
1
1
  # coding: utf-8
2
+ # vim: et ts=2 sw=2
2
3
 
3
4
  require 'drb/drb'
4
5
  require 'rexml/document'
5
6
  require 'rexml/formatters/pretty'
6
7
  require 'json'
7
-
8
- require_relative '../xpath'
9
- require_relative 'helper'
10
- require_relative 'component_manager'
8
+ require 'yaml'
9
+ require 'rubyang/xpath'
10
+ require 'rubyang/database/helper'
11
+ require 'rubyang/database/component_manager'
11
12
 
12
13
  module Rubyang
13
- class Database
14
- class DataTree
15
- include DRb::DRbUndumped
14
+ class Database
15
+ class DataTree
16
+ include DRb::DRbUndumped
16
17
 
17
- class Node
18
- attr_reader :parent, :schema_tree, :schema, :children
19
- def initialize parent, schema_tree, schema
20
- @parent = parent
21
- @schema_tree = schema_tree
22
- @schema = schema
23
- @children = []
24
- @logger = Rubyang::Logger.instance
25
- end
26
- def to_s parent=true
27
- head, vars, tail = "#<#{self.class.to_s}:0x#{(self.object_id << 1).to_s(16).rjust(14,'0')} ", Array.new, ">"
28
- if parent
29
- vars.push "@parent=#{@parent.to_s(false)}"
30
- vars.push "@schema_tree=#{@schema_tree.to_s(false)}"
31
- vars.push "@schema=#{@schema.to_s(true)}"
32
- vars.push "@children=#{@children.to_s}"
33
- end
34
- head + vars.join(', ') + tail
35
- end
36
- def to_xml pretty: false
37
- doc = REXML::Document.new
38
- self.to_xml_recursive doc, ''
39
- if pretty
40
- pretty_formatter = REXML::Formatters::Pretty.new( 2 )
41
- pretty_formatter.compact = true
42
- output = ''
43
- pretty_formatter.write( doc, output )
44
- output
45
- else
46
- doc.to_s
47
- end
48
- end
49
- def to_json pretty: false
50
- hash = Hash.new
51
- self.to_json_recursive hash
52
- if pretty
53
- JSON.pretty_generate( hash )
54
- else
55
- JSON.generate( hash )
56
- end
57
- end
58
- def valid? current=true
59
- result = if current
60
- self.root.valid?
61
- else
62
- case self
63
- when Rubyang::Database::DataTree::Container
64
- @children.inject(self.evaluate_musts){ |r, c|
65
- r.and c.valid?( false )
66
- }
67
- when Rubyang::Database::DataTree::LeafList, Rubyang::Database::DataTree::List
68
- tmp = Rubyang::Xpath::BasicType::Boolean.new( self.evaluate_min_elements )
69
- tmp.and Rubyang::Xpath::BasicType::Boolean.new( self.evaluate_max_elements )
70
- else
71
- Rubyang::Xpath::BasicType::Boolean.new true
72
- end
73
- end
74
- @logger.debug "#{self.class}#valid?: return: #{result} #{result.value}"
75
- result
76
- end
77
- def load_merge_xml_recursive doc_xml
78
- doc_xml.each_element{ |e|
79
- child = edit( e.name )
80
- unless e.has_elements?
81
- if e.has_text?
82
- classes_have_set = [
83
- Rubyang::Database::DataTree::Leaf,
84
- Rubyang::Database::DataTree::LeafList,
85
- ]
86
- if classes_have_set.include?(child.class)
87
- child.set e.text
88
- end
89
- end
90
- end
91
- child.load_merge_xml_recursive e
92
- }
93
- end
94
- def root
95
- case @parent
96
- when Rubyang::Database::DataTree::Root
97
- @parent
98
- else
99
- @parent.root
100
- end
101
- end
18
+ module Mode
19
+ CONFIG = :config
20
+ OPER = :oper
21
+ end
102
22
 
103
- # when start
104
- def evaluate_whens
105
- @schema.whens.inject( Rubyang::Xpath::BasicType::Boolean.new true ){ |r, w|
106
- puts
107
- puts 'evaluate whens:'
108
- puts 'r:'
109
- puts r.value
110
- puts 'w:'
111
- puts w.arg
112
- _when = r.and self.evaluate_xpath( w.xpath, self )
113
- puts '_when:'
114
- require 'yaml'
115
- puts _when.to_yaml
116
- puts 'evaluate whens done'
117
- puts
118
- r.and self.evaluate_xpath( w.xpath, self )
119
- }
120
- end
121
- # end
23
+ class Node
24
+ attr_reader :parent, :schema_tree, :schema, :children
25
+ def initialize parent, schema_tree, schema, db_mode, ctx_mode
26
+ @logger = Logger.new(self.class.name)
27
+ @parent = parent
28
+ @schema_tree = schema_tree
29
+ @schema = schema
30
+ @db_mode = db_mode
31
+ @ctx_mode = ctx_mode
32
+ @children = []
33
+ end
34
+ def to_s parent=true
35
+ head, vars, tail = "#<#{self.class.to_s}:0x#{(self.object_id << 1).to_s(16).rjust(14,'0')} ", Array.new, ">"
36
+ if parent
37
+ vars.push "@parent=#{@parent.to_s(false)}"
38
+ vars.push "@schema_tree=#{@schema_tree.to_s(false)}"
39
+ vars.push "@schema=#{@schema.to_s(true)}"
40
+ vars.push "@children=#{@children.to_s}"
41
+ end
42
+ head + vars.join(', ') + tail
43
+ end
44
+ def to_xml pretty: false
45
+ doc = REXML::Document.new
46
+ self.to_xml_recursive doc, ''
47
+ if pretty
48
+ pretty_formatter = REXML::Formatters::Pretty.new( 2 )
49
+ pretty_formatter.compact = true
50
+ output = ''
51
+ pretty_formatter.write( doc, output )
52
+ output
53
+ else
54
+ doc.to_s
55
+ end
56
+ end
57
+ def to_json pretty: false
58
+ hash = Hash.new
59
+ self.to_json_recursive hash
60
+ if pretty
61
+ JSON.pretty_generate( hash )
62
+ else
63
+ JSON.generate( hash )
64
+ end
65
+ end
66
+ def valid? current=true
67
+ result = if current
68
+ self.root.valid?
69
+ else
70
+ case self
71
+ when Rubyang::Database::DataTree::Container
72
+ @children.inject(self.evaluate_musts){ |r, c|
73
+ r.and c.valid?( false )
74
+ }
75
+ when Rubyang::Database::DataTree::LeafList, Rubyang::Database::DataTree::List
76
+ tmp = Rubyang::Xpath::BasicType::Boolean.new( self.evaluate_min_elements )
77
+ tmp.and Rubyang::Xpath::BasicType::Boolean.new( self.evaluate_max_elements )
78
+ else
79
+ Rubyang::Xpath::BasicType::Boolean.new true
80
+ end
81
+ end
82
+ @logger.debug { "#{self.class}#valid?: return: #{result} #{result.value}" }
83
+ result
84
+ end
85
+ def load_merge_xml_recursive doc_xml
86
+ doc_xml.each_element{ |e|
87
+ child = edit( e.name )
88
+ unless e.has_elements?
89
+ if e.has_text?
90
+ classes_have_set = [
91
+ Rubyang::Database::DataTree::Leaf,
92
+ Rubyang::Database::DataTree::LeafList,
93
+ ]
94
+ if classes_have_set.include?(child.class)
95
+ child.set e.text
96
+ end
97
+ end
98
+ end
99
+ child.load_merge_xml_recursive e
100
+ }
101
+ end
102
+ def root
103
+ case @parent
104
+ when Rubyang::Database::DataTree::Root
105
+ @parent
106
+ else
107
+ @parent.root
108
+ end
109
+ end
122
110
 
123
- # must start
124
- def evaluate_musts
125
- @schema.musts.inject( Rubyang::Xpath::BasicType::Boolean.new true ){ |r, w|
126
- puts
127
- puts 'evaluate musts:'
128
- puts 'r:'
129
- puts r.value
130
- puts 'w:'
131
- puts w.arg
132
- must = r.and self.evaluate_xpath( w.xpath, self )
133
- puts 'must:'
134
- require 'yaml'
135
- puts must.to_yaml
136
- puts 'evaluate musts done'
137
- puts
138
- r.and self.evaluate_xpath( w.xpath, self )
139
- }
140
- end
141
- # end
111
+ # when start
112
+ def evaluate_whens
113
+ @schema.whens.inject( Rubyang::Xpath::BasicType::Boolean.new true ){ |r, w|
114
+ @logger.debug { 'evaluate whens:' }
115
+ @logger.debug { 'r:' }
116
+ @logger.debug { r.value }
117
+ @logger.debug { 'w:' }
118
+ @logger.debug { w.arg }
119
+ _when = r.and self.evaluate_xpath( w.xpath, self )
120
+ @logger.debug { '_when:' }
121
+ @logger.debug { _when.to_yaml }
122
+ @logger.debug { 'evaluate whens done' }
123
+ r.and self.evaluate_xpath( w.xpath, self )
124
+ }
125
+ end
126
+ # end
142
127
 
143
- # min-elements start
144
- def evaluate_min_elements
145
- if @schema.min_elements.size > 0
146
- @logger.debug "#{self.class}#evaluate_min_elements: @schema.min_elements.first.arg: #{@schema.min_elements.first.arg}"
147
- if @children.size >= @schema.min_elements.first.arg.to_i then true else false end
148
- else
149
- true
150
- end
151
- end
152
- # end
128
+ # must start
129
+ def evaluate_musts
130
+ @schema.musts.inject( Rubyang::Xpath::BasicType::Boolean.new true ){ |r, w|
131
+ @logger.debug { 'evaluate musts:' }
132
+ @logger.debug { 'r:' }
133
+ @logger.debug { r.value }
134
+ @logger.debug { 'w:' }
135
+ @logger.debug { w.arg }
136
+ must = r.and self.evaluate_xpath( w.xpath, self )
137
+ @logger.debug { 'must:' }
138
+ require 'yaml'
139
+ @logger.debug { must.to_yaml }
140
+ @logger.debug { 'evaluate musts done' }
141
+ r.and self.evaluate_xpath( w.xpath, self )
142
+ }
143
+ end
144
+ # end
153
145
 
154
- # min-elements start
155
- def evaluate_max_elements
156
- if @schema.max_elements.size > 0
157
- @logger.debug "#{self.class}#evaluate_max_elements: @schema.max_elements.first.arg: #{@schema.max_elements.first.arg}"
158
- if @children.size <= @schema.max_elements.first.arg.to_i then true else false end
159
- else
160
- true
161
- end
162
- end
163
- # end
146
+ # min-elements start
147
+ def evaluate_min_elements
148
+ if @schema.min_elements.size > 0
149
+ @logger.debug { "#{self.class}#evaluate_min_elements: @schema.min_elements.first.arg: #{@schema.min_elements.first.arg}" }
150
+ if @children.size >= @schema.min_elements.first.arg.to_i then true else false end
151
+ else
152
+ true
153
+ end
154
+ end
155
+ # end
164
156
 
165
- def evaluate_xpath xpath, current=self
166
- if Rubyang::Xpath::Parser::DEBUG
167
- require 'yaml'
168
- puts
169
- puts 'in evaluate_xpath:'
170
- puts
171
- puts 'xpath:'
172
- puts xpath.to_yaml
173
- puts
174
- puts 'self:'
175
- puts self.class
176
- puts self.schema.arg
177
- puts self.schema.value rescue ''
178
- puts 'current:'
179
- puts current.class
180
- puts current.schema.arg
181
- puts current.schema.value rescue ''
182
- puts
183
- end
184
- evaluate_xpath_expr xpath, current
185
- end
157
+ # min-elements start
158
+ def evaluate_max_elements
159
+ if @schema.max_elements.size > 0
160
+ @logger.debug { "#{self.class}#evaluate_max_elements: @schema.max_elements.first.arg: #{@schema.max_elements.first.arg}" }
161
+ if @children.size <= @schema.max_elements.first.arg.to_i then true else false end
162
+ else
163
+ true
164
+ end
165
+ end
166
+ # end
186
167
 
187
- def evaluate_xpath_path location_path, current
188
- if Rubyang::Xpath::Parser::DEBUG
189
- require 'yaml'
190
- puts
191
- puts 'in evaluate_xpath_path:'
192
- puts
193
- puts 'location_path:'
194
- puts location_path.to_yaml
195
- puts
196
- puts 'self:'
197
- puts self.class
198
- puts self.schema.arg
199
- puts self.schema.value rescue ''
200
- puts 'current:'
201
- puts current.class
202
- puts current.schema.arg
203
- puts current.schema.value rescue ''
204
- puts
205
- end
206
- first_location_step = location_path.location_step_sequence.first
207
- if Rubyang::Xpath::Parser::DEBUG
208
- require 'yaml'
209
- puts
210
- puts 'first_location_step:'
211
- puts first_location_step.to_yaml
212
- end
213
- candidates_by_axis = self.evaluate_xpath_axis( first_location_step, current )
214
- if Rubyang::Xpath::Parser::DEBUG
215
- require 'yaml'
216
- puts
217
- puts 'candidates_by_axis:'
218
- puts candidates_by_axis.to_yaml
219
- end
220
- candidates_by_node_test = Rubyang::Xpath::BasicType::NodeSet.new candidates_by_axis.value.inject([]){ |cs, c| cs + c.evaluate_xpath_node_test( first_location_step, current ) }
221
- if Rubyang::Xpath::Parser::DEBUG
222
- require 'yaml'
223
- puts
224
- puts 'candidates_by_node_test:'
225
- puts candidates_by_node_test.to_yaml
226
- end
227
- candidates_by_predicates = Rubyang::Xpath::BasicType::NodeSet.new candidates_by_node_test.value.inject([]){ |cs, c| cs + c.evaluate_xpath_predicates( first_location_step, current ) }
228
- if Rubyang::Xpath::Parser::DEBUG
229
- require 'yaml'
230
- puts
231
- puts 'candidates_by_predicates:'
232
- puts candidates_by_predicates.to_yaml
233
- end
234
- if location_path.location_step_sequence[1..-1].size == 0
235
- candidates_by_predicates
236
- else
237
- Rubyang::Xpath::BasicType::NodeSet.new candidates_by_predicates.value.inject([]){ |cs, c|
238
- following_location_path = Rubyang::Xpath::LocationPath.new *(location_path.location_step_sequence[1..-1])
239
- if Rubyang::Xpath::Parser::DEBUG
240
- puts
241
- puts 'following_location_path:'
242
- puts following_location_path.to_yaml
243
- puts
244
- end
245
- cs + c.evaluate_xpath_path( following_location_path, current ).value
246
- }
247
- end
248
- end
168
+ def evaluate_xpath xpath, current=self
169
+ @logger.debug { 'in evaluate_xpath:' }
170
+ @logger.debug { 'xpath:' }
171
+ @logger.debug { xpath.to_yaml }
172
+ @logger.debug { 'self:' }
173
+ @logger.debug { self.class }
174
+ @logger.debug { self.schema.arg }
175
+ @logger.debug { self.schema.value rescue '' }
176
+ @logger.debug { 'current:' }
177
+ @logger.debug { current.class }
178
+ @logger.debug { current.schema.arg }
179
+ @logger.debug { current.schema.value rescue '' }
180
+ evaluate_xpath_expr xpath, current
181
+ end
249
182
 
250
- def evaluate_xpath_axis location_step, current
251
- if Rubyang::Xpath::Parser::DEBUG
252
- require 'yaml'
253
- puts
254
- puts 'in evaluate_xpath_axis:'
255
- puts
256
- puts 'location_step:'
257
- puts location_step.to_yaml
258
- puts
259
- puts 'self:'
260
- puts self.class
261
- puts self.schema.arg
262
- puts self.schema.value rescue ''
263
- puts 'current:'
264
- puts current.class
265
- puts current.schema.arg
266
- puts current.schema.value rescue ''
267
- puts
268
- end
269
- case location_step.axis.name
270
- when Rubyang::Xpath::Axis::SELF
271
- Rubyang::Xpath::BasicType::NodeSet.new [self]
272
- when Rubyang::Xpath::Axis::PARENT
273
- Rubyang::Xpath::BasicType::NodeSet.new [@parent]
274
- when Rubyang::Xpath::Axis::CHILD
275
- Rubyang::Xpath::BasicType::NodeSet.new @children.inject([]){ |cs, c|
276
- cs + case c
277
- when Rubyang::Database::DataTree::ListElement
278
- c.children
279
- else
280
- [c]
281
- end
282
- }
283
- else
284
- raise "location_step.axis.name: #{location_step.axis.name} NOT implemented"
285
- end
286
- end
183
+ def evaluate_xpath_path location_path, current
184
+ @logger.debug { 'in evaluate_xpath_path:' }
185
+ @logger.debug { 'location_path:' }
186
+ @logger.debug { location_path.to_yaml }
187
+ @logger.debug { 'self:' }
188
+ @logger.debug { self.class }
189
+ @logger.debug { self.schema.arg }
190
+ @logger.debug { self.schema.value rescue '' }
191
+ @logger.debug { 'current:' }
192
+ @logger.debug { current.class }
193
+ @logger.debug { current.schema.arg }
194
+ @logger.debug { current.schema.value rescue '' }
195
+ first_location_step = location_path.location_step_sequence.first
196
+ @logger.debug { 'first_location_step:' }
197
+ @logger.debug { first_location_step.to_yaml }
198
+ candidates_by_axis = self.evaluate_xpath_axis( first_location_step, current )
199
+ @logger.debug { 'candidates_by_axis:' }
200
+ @logger.debug { candidates_by_axis.to_yaml }
201
+ candidates_by_node_test = Rubyang::Xpath::BasicType::NodeSet.new candidates_by_axis.value.inject([]){ |cs, c| cs + c.evaluate_xpath_node_test( first_location_step, current ) }
202
+ @logger.debug { 'candidates_by_node_test:' }
203
+ @logger.debug { candidates_by_node_test.to_yaml }
204
+ candidates_by_predicates = Rubyang::Xpath::BasicType::NodeSet.new candidates_by_node_test.value.inject([]){ |cs, c| cs + c.evaluate_xpath_predicates( first_location_step, current ) }
205
+ @logger.debug { 'candidates_by_predicates:' }
206
+ @logger.debug { candidates_by_predicates.to_yaml }
207
+ if location_path.location_step_sequence[1..-1].size == 0
208
+ candidates_by_predicates
209
+ else
210
+ Rubyang::Xpath::BasicType::NodeSet.new candidates_by_predicates.value.inject([]){ |cs, c|
211
+ following_location_path = Rubyang::Xpath::LocationPath.new *(location_path.location_step_sequence[1..-1])
212
+ @logger.debug { 'following_location_path:' }
213
+ @logger.debug { following_location_path.to_yaml }
214
+ cs + c.evaluate_xpath_path( following_location_path, current ).value
215
+ }
216
+ end
217
+ end
287
218
 
288
- def evaluate_xpath_node_test location_step, current
289
- puts
290
- p 'in node_test'
291
- p self.class
292
- p self.schema.arg
293
- p self.value rescue ''
294
- puts
295
- case location_step.node_test.node_test_type
296
- when Rubyang::Xpath::NodeTest::NodeTestType::NAME_TEST
297
- if "/" == location_step.node_test.node_test
298
- [self.root]
299
- elsif self.schema.model.arg == location_step.node_test.node_test
300
- case self
301
- when Rubyang::Database::DataTree::List
302
- self.children
303
- else
304
- [self]
305
- end
306
- else
307
- []
308
- end
309
- when Rubyang::Xpath::NodeTest::NodeTestType::NODE_TYPE
310
- case location_step.node_test.node_test
311
- when Rubyang::Xpath::NodeTest::NodeType::COMMENT
312
- raise "node-type: comment is not implemented"
313
- when Rubyang::Xpath::NodeTest::NodeType::TEXT
314
- raise "node-type: text is not implemented"
315
- when Rubyang::Xpath::NodeTest::NodeType::NODE
316
- [self]
317
- else
318
- raise "node-type not match to comment or text or node"
319
- end
320
- when Rubyang::Xpath::NodeTest::NodeTestType::PROCESSING_INSTRUCTION
321
- raise "processing-instruction is not implemented"
322
- else
323
- raise ""
324
- end
325
- end
219
+ def evaluate_xpath_axis location_step, current
220
+ @logger.debug { 'in evaluate_xpath_axis:' }
221
+ @logger.debug { 'location_step:' }
222
+ @logger.debug { location_step.to_yaml }
223
+ @logger.debug { 'self:' }
224
+ @logger.debug { self.class }
225
+ @logger.debug { self.schema.arg }
226
+ @logger.debug { self.schema.value rescue '' }
227
+ @logger.debug { 'current:' }
228
+ @logger.debug { current.class }
229
+ @logger.debug { current.schema.arg }
230
+ @logger.debug { current.schema.value rescue '' }
231
+ case location_step.axis.name
232
+ when Rubyang::Xpath::Axis::SELF
233
+ Rubyang::Xpath::BasicType::NodeSet.new [self]
234
+ when Rubyang::Xpath::Axis::PARENT
235
+ Rubyang::Xpath::BasicType::NodeSet.new [@parent]
236
+ when Rubyang::Xpath::Axis::CHILD
237
+ Rubyang::Xpath::BasicType::NodeSet.new @children.inject([]){ |cs, c|
238
+ cs + case c
239
+ when Rubyang::Database::DataTree::ListElement
240
+ c.children
241
+ else
242
+ [c]
243
+ end
244
+ }
245
+ else
246
+ raise "location_step.axis.name: #{location_step.axis.name} NOT implemented"
247
+ end
248
+ end
326
249
 
327
- def evaluate_xpath_predicates location_step, current
328
- case location_step.predicates.size
329
- when 0
330
- [self]
331
- else
332
- location_step.predicates.inject([self]){ |cs, predicate|
333
- p 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa'
334
- p self.class
335
- if cs.size > 0
336
- result = cs[0].evaluate_xpath_expr predicate.expr, current
337
- case result
338
- when Rubyang::Xpath::BasicType::NodeSet
339
- raise
340
- when Rubyang::Xpath::BasicType::Boolean
341
- if result.value == true then cs else [] end
342
- when Rubyang::Xpath::BasicType::Number
343
- raise
344
- when Rubyang::Xpath::BasicType::String
345
- raise
346
- end
347
- else
348
- []
349
- end
350
- }
351
- end
352
- end
250
+ def evaluate_xpath_node_test location_step, current
251
+ @logger.debug { 'in node_test' }
252
+ @logger.debug { self.class }
253
+ @logger.debug { self.schema.arg }
254
+ @logger.debug { self.value rescue '' }
255
+ case location_step.node_test.node_test_type
256
+ when Rubyang::Xpath::NodeTest::NodeTestType::NAME_TEST
257
+ if "/" == location_step.node_test.node_test
258
+ [self.root]
259
+ elsif self.schema.model.arg == location_step.node_test.node_test
260
+ case self
261
+ when Rubyang::Database::DataTree::List
262
+ self.children
263
+ else
264
+ [self]
265
+ end
266
+ else
267
+ []
268
+ end
269
+ when Rubyang::Xpath::NodeTest::NodeTestType::NODE_TYPE
270
+ case location_step.node_test.node_test
271
+ when Rubyang::Xpath::NodeTest::NodeType::COMMENT
272
+ raise "node-type: comment is not implemented"
273
+ when Rubyang::Xpath::NodeTest::NodeType::TEXT
274
+ raise "node-type: text is not implemented"
275
+ when Rubyang::Xpath::NodeTest::NodeType::NODE
276
+ [self]
277
+ else
278
+ raise "node-type not match to comment or text or node"
279
+ end
280
+ when Rubyang::Xpath::NodeTest::NodeTestType::PROCESSING_INSTRUCTION
281
+ raise "processing-instruction is not implemented"
282
+ else
283
+ raise ""
284
+ end
285
+ end
353
286
 
354
- def evaluate_xpath_expr expr, current=self
355
- case expr
356
- when Rubyang::Xpath::Expr
357
- if Rubyang::Xpath::Parser::DEBUG
358
- puts
359
- puts "in Expr"
360
- puts "op: #{expr.op}"
361
- puts
362
- end
363
- op = expr.op
364
- op_result = self.evaluate_xpath_expr( op, current )
365
- when Rubyang::Xpath::OrExpr
366
- if Rubyang::Xpath::Parser::DEBUG
367
- puts
368
- puts "in OrExpr"
369
- puts "op1: #{expr.op1}"
370
- puts "op2: #{expr.op2}"
371
- puts
372
- end
373
- op1 = expr.op1
374
- op2 = expr.op2
375
- op1_result = self.evaluate_xpath_expr( op1, current )
376
- if op2 == nil
377
- op1_result
378
- else
379
- op2_result = self.evaluate_xpath_expr( op2, current )
380
- if op1_result.class == Rubyang::Xpath::BasicType::NodeSet && op2_result.class == Rubyang::Xpath::BasicType::NodeSet
381
- if op1_result.empty? && op2_result.empty?
382
- Rubyang::Xpath::BasicType::Boolean.new false
383
- else
384
- Rubyang::Xpath::BasicType::Boolean.new true
385
- end
386
- else
387
- Rubyang::Xpath::BasicType::Boolean.new true
388
- end
389
- end
390
- when Rubyang::Xpath::AndExpr
391
- if Rubyang::Xpath::Parser::DEBUG
392
- puts
393
- puts "in AndExpr"
394
- puts "op1: #{expr.op1}"
395
- puts "op2: #{expr.op2}"
396
- puts
397
- end
398
- op1 = expr.op1
399
- op2 = expr.op2
400
- op1_result = self.evaluate_xpath_expr( op1, current )
401
- if op2 == nil
402
- op1_result
403
- else
404
- op2_result = self.evaluate_xpath_expr( op2, current )
405
- if op1_result.class == Rubyang::Xpath::BasicType::NodeSet
406
- Rubyang::Xpath::BasicType::Boolean.new false if op1_result.empty?
407
- elsif op2_result.class == Rubyang::Xpath::BasicType::NodeSet
408
- Rubyang::Xpath::BasicType::Boolean.new false if op2_result.empty?
409
- else
410
- Rubyang::Xpath::BasicType::Boolean.new true
411
- end
412
- end
413
- when Rubyang::Xpath::EqualityExpr
414
- if Rubyang::Xpath::Parser::DEBUG
415
- puts
416
- puts "in EqualityExpr"
417
- puts "op1: #{expr.op1}"
418
- puts "op2: #{expr.op2}"
419
- puts "operator: #{expr.operator}"
420
- puts
421
- end
422
- op1 = expr.op1
423
- op2 = expr.op2
424
- operator = expr.operator
425
- op1_result = self.evaluate_xpath_expr( op1, current )
426
- if op2 == nil
427
- op1_result
428
- else
429
- op2_result = self.evaluate_xpath_expr( op2, current )
430
- if Rubyang::Xpath::Parser::DEBUG
431
- require 'yaml'
432
- puts
433
- puts "in EqualityExpr else:"
434
- puts "op1_result: #{op1_result.to_yaml}"
435
- puts "op2_result: #{op2_result.to_yaml}"
436
- puts
437
- end
438
- if op1_result.class == Rubyang::Xpath::BasicType::NodeSet && op2_result.class == Rubyang::Xpath::BasicType::String
439
- case operator
440
- when /^\=$/
441
- #op1_result.select{ |a| op2_result.map{ |b| b.value }.include? a.value }.map{ |c| c.parent }
442
- op1_result == op2_result
443
- when /^\!\=$/
444
- raise "Equality Expr: '!=' not implemented"
445
- else
446
- raise "Equality Expr: other than '=' and '!=' not implemented"
447
- end
448
- elsif op1_result.class == Rubyang::Xpath::BasicType::String && op2_result.class == Rubyang::Xpath::BasicType::NodeSet
449
- case operator
450
- when /^\=$/
451
- op2_result.select{ |a| op1_result.map{ |b| b.value }.include? a.value }.map{ |c| c.parent }
452
- when /^\!\=$/
453
- raise "Equality Expr: '!=' not implemented"
454
- else
455
- raise "Equality Expr: other than '=' and '!=' not implemented"
456
- end
457
- elsif op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
458
- case operator
459
- when /^\=$/
460
- op1_result == op2_result
461
- when /^\!\=$/
462
- op1_result != op2_result
463
- else
464
- raise "Equality Expr: other than '=' and '!=' not implemented"
465
- end
466
- elsif op1_result.class == Rubyang::Xpath::BasicType::String && op2_result.class == Rubyang::Xpath::BasicType::String
467
- case operator
468
- when /^\=$/
469
- op1_result == op2_result
470
- when /^\!\=$/
471
- op1_result != op2_result
472
- else
473
- raise "Equality Expr: other than '=' and '!=' not implemented"
474
- end
475
- elsif op1_result.class == Rubyang::Xpath::BasicType::NodeSet && op2_result.class == Rubyang::Xpath::BasicType::NodeSet
476
- case operator
477
- when /^\=$/
478
- op1_result == op2_result
479
- when /^\!\=$/
480
- op1_result != op2_result
481
- else
482
- raise "Equality Expr: other than '=' and '!=' not implemented"
483
- end
484
- else
485
- Rubyang::Xpath::BasicType::Boolean.new false
486
- end
487
- end
488
- when Rubyang::Xpath::RelationalExpr
489
- if Rubyang::Xpath::Parser::DEBUG
490
- puts
491
- puts "in RelationalExpr"
492
- puts "op1: #{expr.op1}"
493
- puts "op2: #{expr.op2}"
494
- puts "operator: #{expr.operator}"
495
- puts
496
- end
497
- op1 = expr.op1
498
- op2 = expr.op2
499
- operator = expr.operator
500
- op1_result = self.evaluate_xpath_expr( op1, current )
501
- if op2 == nil
502
- op1_result
503
- else
504
- op2_result = self.evaluate_xpath_expr( op2, current )
505
- if op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
506
- case operator
507
- when /^\>$/
508
- op1_result > op2_result
509
- when /^\<$/
510
- op1_result < op2_result
511
- when /^\>\=$/
512
- op1_result >= op2_result
513
- when /^\<\=$/
514
- op1_result <= op2_result
515
- else
516
- raise "Relational Expr: other than '>', '<', '>=' and '<=' not valid"
517
- end
518
- else
519
- Rubyang::Xpath::BasicType::Boolean.new false
520
- end
521
- end
522
- when Rubyang::Xpath::AdditiveExpr
523
- if Rubyang::Xpath::Parser::DEBUG
524
- puts
525
- puts "in AdditiveExpr"
526
- puts "op1: #{expr.op1}"
527
- puts "op2: #{expr.op2}"
528
- puts "operator: #{expr.operator}"
529
- puts
530
- end
531
- op1 = expr.op1
532
- op2 = expr.op2
533
- operator = expr.operator
534
- op1_result = self.evaluate_xpath_expr( op1, current )
535
- if op2 == nil
536
- op1_result
537
- else
538
- op2_result = self.evaluate_xpath_expr( op2, current )
539
- if op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
540
- case operator
541
- when /^\+$/
542
- op1_result + op2_result
543
- when /^\-$/
544
- op1_result - op2_result
545
- else
546
- raise "Additive Expr: other than '+' and '-' not valid"
547
- end
548
- else
549
- Rubyang::Xpath::BasicType::Number.new Float::NAN
550
- end
551
- end
552
- when Rubyang::Xpath::MultiplicativeExpr
553
- if Rubyang::Xpath::Parser::DEBUG
554
- puts
555
- puts "in MultiplicativeExpr"
556
- puts "op1: #{expr.op1}"
557
- puts "op2: #{expr.op2}"
558
- puts "operator: #{expr.operator}"
559
- puts
560
- end
561
- op1 = expr.op1
562
- op2 = expr.op2
563
- operator = expr.operator
564
- op1_result = self.evaluate_xpath_expr( op1, current )
565
- if op2 == nil
566
- op1_result
567
- else
568
- op2_result = self.evaluate_xpath_expr( op2, current )
569
- if op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
570
- case operator
571
- when /^\*$/
572
- op1_result * op2_result
573
- when /^\/$/
574
- op1_result / op2_result
575
- else
576
- raise "Multiplicative Expr: other than '*' and '/' not valid"
577
- end
578
- else
579
- Rubyang::Xpath::BasicType::Number.new Float::NAN
580
- end
581
- end
582
- when Rubyang::Xpath::UnaryExpr
583
- if Rubyang::Xpath::Parser::DEBUG
584
- puts
585
- puts "in UnaryExpr"
586
- puts "op1: #{expr.op1}"
587
- puts "operator: #{expr.operator}"
588
- puts
589
- end
590
- op1 = expr.op1
591
- operator = expr.operator
592
- op1_result = self.evaluate_xpath_expr( op1, current )
593
- case operator
594
- when nil
595
- op1_result
596
- when /^\-$/
597
- case op1_result
598
- when Rubyang::Xpath::BasicType::Number
599
- - op1_result
600
- else
601
- Rubyang::Xpath::BasicType::Number.new Float::NAN
602
- end
603
- else
604
- raise "Unary Expr: other than '-' not valid"
605
- end
606
- when Rubyang::Xpath::UnionExpr
607
- if Rubyang::Xpath::Parser::DEBUG
608
- puts
609
- puts "in UnionExpr"
610
- puts "op1: #{expr.op1}"
611
- puts "op2: #{expr.op2}"
612
- puts "operator: #{expr.operator}"
613
- puts
614
- end
615
- op1 = expr.op1
616
- op2 = expr.op2
617
- operator = expr.operator
618
- op1_result = self.evaluate_xpath_expr( op1, current )
619
- if op2 == nil
620
- op1_result
621
- else
622
- op2_result = self.evaluate_xpath_expr( op2, current )
623
- case operator
624
- when /^\|$/
625
- raise "Union Expr: '|' not implemented"
626
- else
627
- raise "Union Expr: other than '|' not implemented"
628
- end
629
- end
630
- when Rubyang::Xpath::PathExpr
631
- if Rubyang::Xpath::Parser::DEBUG
632
- puts
633
- puts "in PathExpr"
634
- puts "op1: #{expr.op1}"
635
- puts "op2: #{expr.op2}"
636
- puts "operator: #{expr.operator}"
637
- puts
638
- end
639
- op1 = expr.op1
640
- op2 = expr.op2
641
- operator = expr.operator
642
- op1_result = case op1
643
- when Rubyang::Xpath::LocationPath
644
- self.evaluate_xpath_path( op1, current )
645
- when Rubyang::Xpath::FilterExpr
646
- op1_result = self.evaluate_xpath_expr( op1, current )
647
- else
648
- raise "PathExpr: #{op1} not supported"
649
- end
650
- if op2 == nil
651
- op1_result
652
- else
653
- case operator
654
- when /^\/$/
655
- case op1_result
656
- when Rubyang::Database::DataTree::Node
657
- op1_result.evaluate_xpath_path op2, current
658
- when Rubyang::Xpath::LocationPath
659
- self.evaluate_xpath_path Rubyang::Xpath::LocationPath.new( *(op1_result.location_step_sequence + op2.location_step_sequence) ), current
660
- else
661
- raise
662
- end
663
- when /^\/\/$/
664
- raise "Path Expr: '//' not implemented"
665
- else
666
- raise "Path Expr: other than '/' and '//' not valid"
667
- end
668
- end
669
- when Rubyang::Xpath::FilterExpr
670
- if Rubyang::Xpath::Parser::DEBUG
671
- puts
672
- puts "in FilterExpr"
673
- puts "op1: #{expr.op1}"
674
- puts "op2: #{expr.op2}"
675
- puts
676
- end
677
- op1 = expr.op1
678
- op2 = expr.op2
679
- op1_result = self.evaluate_xpath_expr( op1, current )
680
- if op2 == nil
681
- op1_result
682
- else
683
- op2_result = self.evaluate_xpath_expr( op2.expr, current )
684
- Rubyang::Xpath::BasicType::NodeSet.new
685
- end
686
- when Rubyang::Xpath::PrimaryExpr
687
- if Rubyang::Xpath::Parser::DEBUG
688
- puts
689
- puts "in PrimaryExpr"
690
- puts "op1: #{expr.op1}"
691
- puts
692
- end
693
- op1 = expr.op1
694
- case op1
695
- when Rubyang::Xpath::VariableReference
696
- raise "Primary Expr: '#{op1}' not implemented"
697
- when Rubyang::Xpath::Expr
698
- op1_result = self.evaluate_xpath_expr( op1, current )
699
- when Rubyang::Xpath::Literal
700
- Rubyang::Xpath::BasicType::String.new op1.value
701
- when Rubyang::Xpath::Number
702
- Rubyang::Xpath::BasicType::Number.new op1.value
703
- when Rubyang::Xpath::FunctionCall
704
- op1_result = self.evaluate_xpath_expr( op1, current )
705
- else
706
- raise "Primary Expr: '#{op1}' not valid"
707
- end
708
- when Rubyang::Xpath::FunctionCall
709
- if Rubyang::Xpath::Parser::DEBUG
710
- puts
711
- puts "in FunctionCall"
712
- puts "name: #{expr.name}"
713
- puts "args: #{expr.args}"
714
- puts
715
- end
716
- name = expr.name
717
- case name
718
- when Rubyang::Xpath::FunctionCall::CURRENT
719
- current
720
- else
721
- raise "FunctionCall: #{name} not implemented"
722
- end
723
- else
724
- raise "Unrecognized Expr: #{expr}"
725
- end
726
- end
727
- end
287
+ def evaluate_xpath_predicates location_step, current
288
+ case location_step.predicates.size
289
+ when 0
290
+ [self]
291
+ else
292
+ location_step.predicates.inject([self]){ |cs, predicate|
293
+ if cs.size > 0
294
+ result = cs[0].evaluate_xpath_expr predicate.expr, current
295
+ case result
296
+ when Rubyang::Xpath::BasicType::NodeSet
297
+ raise
298
+ when Rubyang::Xpath::BasicType::Boolean
299
+ if result.value == true then cs else [] end
300
+ when Rubyang::Xpath::BasicType::Number
301
+ raise
302
+ when Rubyang::Xpath::BasicType::String
303
+ raise
304
+ end
305
+ else
306
+ []
307
+ end
308
+ }
309
+ end
310
+ end
728
311
 
729
- class InteriorNode < Node
730
- def to_xml_recursive _doc, current_namespace
731
- doc = _doc.add_element( @schema.model.arg )
732
- unless @schema.namespace == current_namespace
733
- current_namespace = @schema.namespace
734
- doc.add_namespace current_namespace
735
- end
736
- @children.each{ |c|
737
- c.to_xml_recursive doc, current_namespace
738
- }
739
- end
740
- def to_json_recursive( _hash )
741
- hash = Hash.new
742
- _hash[@schema.model.arg] = hash
743
- @children.each{ |c|
744
- c.to_json_recursive hash
745
- }
746
- end
747
- def find_child_schema schema, arg
748
- schema.children.map{ |c|
749
- case c
750
- when Rubyang::Database::SchemaTree::Choice
751
- find_child_schema c, arg
752
- when Rubyang::Database::SchemaTree::Case
753
- find_child_schema c, arg
754
- else
755
- if c.model.arg == arg
756
- c
757
- else
758
- nil
759
- end
760
- end
761
- }.find{ |c| c }
762
- end
763
- def delete_same_choice_other_case schema, arg, children
764
- child_schema = nil
765
- schema.children.each{ |c|
766
- case c
767
- when Rubyang::Database::SchemaTree::Choice
768
- child_schema = delete_same_choice_other_case c, arg, children
769
- when Rubyang::Database::SchemaTree::Case
770
- child_schema = delete_same_choice_other_case c, arg, children
771
- if Rubyang::Database::SchemaTree::Choice === schema
772
- other_schema_children = schema.children.select{ |c2| c2 != c }
773
- children.delete_if{ |c2|
774
- other_schema_children.find{ |sc|
775
- find_child_schema sc, c2.schema.model.arg or sc.model.arg == c2.schema.model.arg
776
- }
777
- }
778
- end
779
- else
780
- if c.model.arg == arg
781
- child_schema = c
782
- if Rubyang::Database::SchemaTree::Choice === schema
783
- other_schema_children = schema.children.select{ |c2| c2 != c }
784
- children.delete_if{ |c2|
785
- other_schema_children.find{ |sc|
786
- find_child_schema sc, c2.schema.model.arg or sc.model.arg == c2.schema.model.arg
787
- }
788
- }
789
- end
790
- else
791
- nil
792
- end
793
- end
794
- }
795
- child_schema
796
- end
797
- def edit arg
798
- child_schema = find_child_schema @schema, arg
799
- delete_same_choice_other_case @schema, arg, @children
800
- child_node = @children.find{ |c| c.schema == child_schema }
801
- unless child_node
802
- case child_schema.model
803
- when Rubyang::Model::Anyxml
804
- child_node = Anyxml.new( self, @schema_tree, child_schema )
805
- when Rubyang::Model::Container
806
- child_node = Container.new( self, @schema_tree, child_schema )
807
- # when start
808
- unless child_node.evaluate_whens.value
809
- raise "#{arg} is not valid because of 'when' conditions"
810
- end
811
- # end
812
- when Rubyang::Model::Leaf
813
- child_node = Leaf.new( self, @schema_tree, child_schema )
814
- when Rubyang::Model::List
815
- child_node = List.new( self, @schema_tree, child_schema )
816
- when Rubyang::Model::LeafList
817
- child_node = LeafList.new( self, @schema_tree, child_schema )
818
- else
819
- raise ArgumentError, "#{arg} NOT match"
820
- end
821
- @children.push child_node
822
- end
823
- child_node
824
- end
825
- def edit_xpath arg
826
- xpath = Rubyang::Xpath::Parser.parse arg
827
- candidates = self.evaluate_xpath( xpath )
828
- case candidates.value.size
829
- when 0
830
- raise "no such xpath: #{arg}"
831
- when 1
832
- candidates.value.first
833
- else
834
- raise "too many match to xpath: #{arg}"
835
- end
836
- end
837
- end
312
+ def evaluate_xpath_expr expr, current=self
313
+ case expr
314
+ when Rubyang::Xpath::Expr
315
+ @logger.debug { "in Expr" }
316
+ @logger.debug { "op: #{expr.op}" }
317
+ op = expr.op
318
+ op_result = self.evaluate_xpath_expr( op, current )
319
+ when Rubyang::Xpath::OrExpr
320
+ @logger.debug { "in OrExpr" }
321
+ @logger.debug { "op1: #{expr.op1}" }
322
+ @logger.debug { "op2: #{expr.op2}" }
323
+ op1 = expr.op1
324
+ op2 = expr.op2
325
+ op1_result = self.evaluate_xpath_expr( op1, current )
326
+ if op2 == nil
327
+ op1_result
328
+ else
329
+ op2_result = self.evaluate_xpath_expr( op2, current )
330
+ if op1_result.class == Rubyang::Xpath::BasicType::NodeSet && op2_result.class == Rubyang::Xpath::BasicType::NodeSet
331
+ if op1_result.empty? && op2_result.empty?
332
+ Rubyang::Xpath::BasicType::Boolean.new false
333
+ else
334
+ Rubyang::Xpath::BasicType::Boolean.new true
335
+ end
336
+ else
337
+ Rubyang::Xpath::BasicType::Boolean.new true
338
+ end
339
+ end
340
+ when Rubyang::Xpath::AndExpr
341
+ @logger.debug { "in AndExpr" }
342
+ @logger.debug { "op1: #{expr.op1}" }
343
+ @logger.debug { "op2: #{expr.op2}" }
344
+ op1 = expr.op1
345
+ op2 = expr.op2
346
+ op1_result = self.evaluate_xpath_expr( op1, current )
347
+ if op2 == nil
348
+ op1_result
349
+ else
350
+ op2_result = self.evaluate_xpath_expr( op2, current )
351
+ if op1_result.class == Rubyang::Xpath::BasicType::NodeSet
352
+ Rubyang::Xpath::BasicType::Boolean.new false if op1_result.empty?
353
+ elsif op2_result.class == Rubyang::Xpath::BasicType::NodeSet
354
+ Rubyang::Xpath::BasicType::Boolean.new false if op2_result.empty?
355
+ else
356
+ Rubyang::Xpath::BasicType::Boolean.new true
357
+ end
358
+ end
359
+ when Rubyang::Xpath::EqualityExpr
360
+ @logger.debug { "in EqualityExpr" }
361
+ @logger.debug { "op1: #{expr.op1}" }
362
+ @logger.debug { "op2: #{expr.op2}" }
363
+ @logger.debug { "operator: #{expr.operator}" }
364
+ op1 = expr.op1
365
+ op2 = expr.op2
366
+ operator = expr.operator
367
+ op1_result = self.evaluate_xpath_expr( op1, current )
368
+ if op2 == nil
369
+ op1_result
370
+ else
371
+ op2_result = self.evaluate_xpath_expr( op2, current )
372
+ @logger.debug { "in EqualityExpr else:" }
373
+ @logger.debug { "op1_result: #{op1_result.to_yaml}" }
374
+ @logger.debug { "op2_result: #{op2_result.to_yaml}" }
375
+ if op1_result.class == Rubyang::Xpath::BasicType::NodeSet && op2_result.class == Rubyang::Xpath::BasicType::String
376
+ case operator
377
+ when /^\=$/
378
+ #op1_result.select{ |a| op2_result.map{ |b| b.value }.include? a.value }.map{ |c| c.parent }
379
+ op1_result == op2_result
380
+ when /^\!\=$/
381
+ raise "Equality Expr: '!=' not implemented"
382
+ else
383
+ raise "Equality Expr: other than '=' and '!=' not implemented"
384
+ end
385
+ elsif op1_result.class == Rubyang::Xpath::BasicType::String && op2_result.class == Rubyang::Xpath::BasicType::NodeSet
386
+ case operator
387
+ when /^\=$/
388
+ op2_result.select{ |a| op1_result.map{ |b| b.value }.include? a.value }.map{ |c| c.parent }
389
+ when /^\!\=$/
390
+ raise "Equality Expr: '!=' not implemented"
391
+ else
392
+ raise "Equality Expr: other than '=' and '!=' not implemented"
393
+ end
394
+ elsif op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
395
+ case operator
396
+ when /^\=$/
397
+ op1_result == op2_result
398
+ when /^\!\=$/
399
+ op1_result != op2_result
400
+ else
401
+ raise "Equality Expr: other than '=' and '!=' not implemented"
402
+ end
403
+ elsif op1_result.class == Rubyang::Xpath::BasicType::String && op2_result.class == Rubyang::Xpath::BasicType::String
404
+ case operator
405
+ when /^\=$/
406
+ op1_result == op2_result
407
+ when /^\!\=$/
408
+ op1_result != op2_result
409
+ else
410
+ raise "Equality Expr: other than '=' and '!=' not implemented"
411
+ end
412
+ elsif op1_result.class == Rubyang::Xpath::BasicType::NodeSet && op2_result.class == Rubyang::Xpath::BasicType::NodeSet
413
+ case operator
414
+ when /^\=$/
415
+ op1_result == op2_result
416
+ when /^\!\=$/
417
+ op1_result != op2_result
418
+ else
419
+ raise "Equality Expr: other than '=' and '!=' not implemented"
420
+ end
421
+ else
422
+ Rubyang::Xpath::BasicType::Boolean.new false
423
+ end
424
+ end
425
+ when Rubyang::Xpath::RelationalExpr
426
+ @logger.debug { "in RelationalExpr" }
427
+ @logger.debug { "op1: #{expr.op1}" }
428
+ @logger.debug { "op2: #{expr.op2}" }
429
+ @logger.debug { "operator: #{expr.operator}" }
430
+ op1 = expr.op1
431
+ op2 = expr.op2
432
+ operator = expr.operator
433
+ op1_result = self.evaluate_xpath_expr( op1, current )
434
+ if op2 == nil
435
+ op1_result
436
+ else
437
+ op2_result = self.evaluate_xpath_expr( op2, current )
438
+ if op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
439
+ case operator
440
+ when /^\>$/
441
+ op1_result > op2_result
442
+ when /^\<$/
443
+ op1_result < op2_result
444
+ when /^\>\=$/
445
+ op1_result >= op2_result
446
+ when /^\<\=$/
447
+ op1_result <= op2_result
448
+ else
449
+ raise "Relational Expr: other than '>', '<', '>=' and '<=' not valid"
450
+ end
451
+ else
452
+ Rubyang::Xpath::BasicType::Boolean.new false
453
+ end
454
+ end
455
+ when Rubyang::Xpath::AdditiveExpr
456
+ @logger.debug { "in AdditiveExpr" }
457
+ @logger.debug { "op1: #{expr.op1}" }
458
+ @logger.debug { "op2: #{expr.op2}" }
459
+ @logger.debug { "operator: #{expr.operator}" }
460
+ op1 = expr.op1
461
+ op2 = expr.op2
462
+ operator = expr.operator
463
+ op1_result = self.evaluate_xpath_expr( op1, current )
464
+ if op2 == nil
465
+ op1_result
466
+ else
467
+ op2_result = self.evaluate_xpath_expr( op2, current )
468
+ if op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
469
+ case operator
470
+ when /^\+$/
471
+ op1_result + op2_result
472
+ when /^\-$/
473
+ op1_result - op2_result
474
+ else
475
+ raise "Additive Expr: other than '+' and '-' not valid"
476
+ end
477
+ else
478
+ Rubyang::Xpath::BasicType::Number.new Float::NAN
479
+ end
480
+ end
481
+ when Rubyang::Xpath::MultiplicativeExpr
482
+ @logger.debug { "in MultiplicativeExpr" }
483
+ @logger.debug { "op1: #{expr.op1}" }
484
+ @logger.debug { "op2: #{expr.op2}" }
485
+ @logger.debug { "operator: #{expr.operator}" }
486
+ op1 = expr.op1
487
+ op2 = expr.op2
488
+ operator = expr.operator
489
+ op1_result = self.evaluate_xpath_expr( op1, current )
490
+ if op2 == nil
491
+ op1_result
492
+ else
493
+ op2_result = self.evaluate_xpath_expr( op2, current )
494
+ if op1_result.class == Rubyang::Xpath::BasicType::Number && op2_result.class == Rubyang::Xpath::BasicType::Number
495
+ case operator
496
+ when /^\*$/
497
+ op1_result * op2_result
498
+ when /^\/$/
499
+ op1_result / op2_result
500
+ else
501
+ raise "Multiplicative Expr: other than '*' and '/' not valid"
502
+ end
503
+ else
504
+ Rubyang::Xpath::BasicType::Number.new Float::NAN
505
+ end
506
+ end
507
+ when Rubyang::Xpath::UnaryExpr
508
+ @logger.debug { "in UnaryExpr" }
509
+ @logger.debug { "op1: #{expr.op1}" }
510
+ @logger.debug { "operator: #{expr.operator}" }
511
+ op1 = expr.op1
512
+ operator = expr.operator
513
+ op1_result = self.evaluate_xpath_expr( op1, current )
514
+ case operator
515
+ when nil
516
+ op1_result
517
+ when /^\-$/
518
+ case op1_result
519
+ when Rubyang::Xpath::BasicType::Number
520
+ - op1_result
521
+ else
522
+ Rubyang::Xpath::BasicType::Number.new Float::NAN
523
+ end
524
+ else
525
+ raise "Unary Expr: other than '-' not valid"
526
+ end
527
+ when Rubyang::Xpath::UnionExpr
528
+ @logger.debug { "in UnionExpr" }
529
+ @logger.debug { "op1: #{expr.op1}" }
530
+ @logger.debug { "op2: #{expr.op2}" }
531
+ @logger.debug { "operator: #{expr.operator}" }
532
+ op1 = expr.op1
533
+ op2 = expr.op2
534
+ operator = expr.operator
535
+ op1_result = self.evaluate_xpath_expr( op1, current )
536
+ if op2 == nil
537
+ op1_result
538
+ else
539
+ op2_result = self.evaluate_xpath_expr( op2, current )
540
+ case operator
541
+ when /^\|$/
542
+ raise "Union Expr: '|' not implemented"
543
+ else
544
+ raise "Union Expr: other than '|' not implemented"
545
+ end
546
+ end
547
+ when Rubyang::Xpath::PathExpr
548
+ @logger.debug { "in PathExpr" }
549
+ @logger.debug { "op1: #{expr.op1}" }
550
+ @logger.debug { "op2: #{expr.op2}" }
551
+ @logger.debug { "operator: #{expr.operator}" }
552
+ op1 = expr.op1
553
+ op2 = expr.op2
554
+ operator = expr.operator
555
+ op1_result = case op1
556
+ when Rubyang::Xpath::LocationPath
557
+ self.evaluate_xpath_path( op1, current )
558
+ when Rubyang::Xpath::FilterExpr
559
+ op1_result = self.evaluate_xpath_expr( op1, current )
560
+ else
561
+ raise "PathExpr: #{op1} not supported"
562
+ end
563
+ if op2 == nil
564
+ op1_result
565
+ else
566
+ case operator
567
+ when /^\/$/
568
+ case op1_result
569
+ when Rubyang::Database::DataTree::Node
570
+ op1_result.evaluate_xpath_path op2, current
571
+ when Rubyang::Xpath::LocationPath
572
+ self.evaluate_xpath_path Rubyang::Xpath::LocationPath.new( *(op1_result.location_step_sequence + op2.location_step_sequence) ), current
573
+ else
574
+ raise
575
+ end
576
+ when /^\/\/$/
577
+ raise "Path Expr: '//' not implemented"
578
+ else
579
+ raise "Path Expr: other than '/' and '//' not valid"
580
+ end
581
+ end
582
+ when Rubyang::Xpath::FilterExpr
583
+ @logger.debug { "in FilterExpr" }
584
+ @logger.debug { "op1: #{expr.op1}" }
585
+ @logger.debug { "op2: #{expr.op2}" }
586
+ op1 = expr.op1
587
+ op2 = expr.op2
588
+ op1_result = self.evaluate_xpath_expr( op1, current )
589
+ if op2 == nil
590
+ op1_result
591
+ else
592
+ op2_result = self.evaluate_xpath_expr( op2.expr, current )
593
+ Rubyang::Xpath::BasicType::NodeSet.new
594
+ end
595
+ when Rubyang::Xpath::PrimaryExpr
596
+ @logger.debug { "in PrimaryExpr" }
597
+ @logger.debug { "op1: #{expr.op1}" }
598
+ op1 = expr.op1
599
+ case op1
600
+ when Rubyang::Xpath::VariableReference
601
+ raise "Primary Expr: '#{op1}' not implemented"
602
+ when Rubyang::Xpath::Expr
603
+ op1_result = self.evaluate_xpath_expr( op1, current )
604
+ when Rubyang::Xpath::Literal
605
+ Rubyang::Xpath::BasicType::String.new op1.value
606
+ when Rubyang::Xpath::Number
607
+ Rubyang::Xpath::BasicType::Number.new op1.value
608
+ when Rubyang::Xpath::FunctionCall
609
+ op1_result = self.evaluate_xpath_expr( op1, current )
610
+ else
611
+ raise "Primary Expr: '#{op1}' not valid"
612
+ end
613
+ when Rubyang::Xpath::FunctionCall
614
+ @logger.debug { "in FunctionCall" }
615
+ @logger.debug { "name: #{expr.name}" }
616
+ @logger.debug { "args: #{expr.args}" }
617
+ name = expr.name
618
+ case name
619
+ when Rubyang::Xpath::FunctionCall::CURRENT
620
+ current
621
+ else
622
+ raise "FunctionCall: #{name} not implemented"
623
+ end
624
+ else
625
+ raise "Unrecognized Expr: #{expr}"
626
+ end
627
+ end
628
+ end
838
629
 
839
- class LeafNode < Node
840
- end
630
+ class InteriorNode < Node
631
+ def to_xml_recursive _doc, current_namespace
632
+ doc = _doc.add_element( @schema.model.arg )
633
+ unless @schema.namespace == current_namespace
634
+ current_namespace = @schema.namespace
635
+ doc.add_namespace current_namespace
636
+ end
637
+ @children.each{ |c|
638
+ c.to_xml_recursive doc, current_namespace
639
+ }
640
+ end
641
+ def to_json_recursive( _hash )
642
+ hash = Hash.new
643
+ _hash[@schema.model.arg] = hash
644
+ @children.each{ |c|
645
+ c.to_json_recursive hash
646
+ }
647
+ end
648
+ def find_child_schema schema, arg
649
+ schema.children.map{ |c|
650
+ case c
651
+ when Database::SchemaTree::Choice
652
+ find_child_schema c, arg
653
+ when Database::SchemaTree::Case
654
+ find_child_schema c, arg
655
+ when Database::SchemaTree::Anyxml, Database::SchemaTree::Leaf, Database::SchemaTree::LeafList
656
+ if c.model.arg == arg
657
+ if @db_mode == Database::DataTree::Mode::CONFIG && @ctx_mode == Database::DataTree::Mode::CONFIG
658
+ if c.yang.substmt('config').any? && c.yang.substmt('config')[0].arg == 'false'
659
+ nil
660
+ else
661
+ c
662
+ end
663
+ elsif @db_mode == Database::DataTree::Mode::CONFIG && @ctx_mode == Database::DataTree::Mode::OPER
664
+ nil
665
+ elsif @db_mode == Database::DataTree::Mode::OPER && @ctx_mode == Database::DataTree::Mode::CONFIG
666
+ if c.yang.substmt('config').any? && c.yang.substmt('config')[0].arg == 'false'
667
+ c
668
+ else
669
+ nil
670
+ end
671
+ elsif @db_mode == Database::DataTree::Mode::OPER && @ctx_mode == Database::DataTree::Mode::OPER
672
+ if c.yang.substmt('config').any? && c.yang.substmt('config')[0].arg == 'true'
673
+ nil
674
+ else
675
+ c
676
+ end
677
+ end
678
+ else
679
+ nil
680
+ end
681
+ else
682
+ if c.model.arg == arg
683
+ if @db_mode == Database::DataTree::Mode::CONFIG && @ctx_mode == Database::DataTree::Mode::CONFIG
684
+ c
685
+ elsif @db_mode == Database::DataTree::Mode::CONFIG && @ctx_mode == Database::DataTree::Mode::OPER
686
+ c
687
+ elsif @db_mode == Database::DataTree::Mode::OPER && @ctx_mode == Database::DataTree::Mode::CONFIG
688
+ c
689
+ elsif @db_mode == Database::DataTree::Mode::OPER && @ctx_mode == Database::DataTree::Mode::OPER
690
+ if c.yang.substmt('config').any? && c.yang.substmt('config')[0].arg == 'true'
691
+ nil
692
+ else
693
+ c
694
+ end
695
+ end
696
+ else
697
+ nil
698
+ end
699
+ end
841
700
 
842
- class ListNode < Node
843
- end
701
+ =begin
702
+ case @db_mode
703
+ when Rubyang::Database::DataTree::Mode::CONFIG
704
+ case c
705
+ when Rubyang::Database::SchemaTree::Choice
706
+ find_child_schema c, arg
707
+ when Rubyang::Database::SchemaTree::Case
708
+ find_child_schema c, arg
709
+ when Rubyang::Database::SchemaTree::Leaf, Rubyang::Database::SchemaTree::LeafList
710
+ if c.model.arg == arg
711
+ c
712
+ else
713
+ nil
714
+ end
715
+ else
716
+ if c.model.arg == arg
717
+ if c.yang.substmt('config').any? && c.yang.substmt('config')[0].arg == 'false'
718
+ nil
719
+ else
720
+ c
721
+ end
722
+ else
723
+ nil
724
+ end
725
+ end
726
+ when Rubyang::Database::DataTree::Mode::OPER
727
+ case c
728
+ when Rubyang::Database::SchemaTree::Choice
729
+ find_child_schema c, arg
730
+ when Rubyang::Database::SchemaTree::Case
731
+ find_child_schema c, arg
732
+ when Rubyang::Database::SchemaTree::Leaf, Rubyang::Database::SchemaTree::LeafList
733
+ if c.model.arg == arg
734
+ if c.yang.substmt('config').any? && c.yang.substmt('config')[0].arg == 'false'
735
+ c
736
+ else
737
+ nil
738
+ end
739
+ else
740
+ nil
741
+ end
742
+ else
743
+ if c.model.arg == arg
744
+ c
745
+ else
746
+ nil
747
+ end
748
+ end
749
+ end
750
+ =end
751
+ }.find{ |c| c }
752
+ end
753
+ def delete_same_choice_other_case schema, arg, children
754
+ child_schema = nil
755
+ schema.children.each{ |c|
756
+ case c
757
+ when Rubyang::Database::SchemaTree::Choice
758
+ child_schema = delete_same_choice_other_case c, arg, children
759
+ when Rubyang::Database::SchemaTree::Case
760
+ child_schema = delete_same_choice_other_case c, arg, children
761
+ if Rubyang::Database::SchemaTree::Choice === schema
762
+ other_schema_children = schema.children.select{ |c2| c2 != c }
763
+ children.delete_if{ |c2|
764
+ other_schema_children.find{ |sc|
765
+ find_child_schema sc, c2.schema.model.arg or sc.model.arg == c2.schema.model.arg
766
+ }
767
+ }
768
+ end
769
+ else
770
+ if c.model.arg == arg
771
+ child_schema = c
772
+ if Rubyang::Database::SchemaTree::Choice === schema
773
+ other_schema_children = schema.children.select{ |c2| c2 != c }
774
+ children.delete_if{ |c2|
775
+ other_schema_children.find{ |sc|
776
+ find_child_schema sc, c2.schema.model.arg or sc.model.arg == c2.schema.model.arg
777
+ }
778
+ }
779
+ end
780
+ else
781
+ nil
782
+ end
783
+ end
784
+ }
785
+ child_schema
786
+ end
787
+ def edit arg
788
+ child_schema = find_child_schema @schema, arg
789
+ delete_same_choice_other_case @schema, arg, @children
790
+ child_node = @children.find{ |c| c.schema == child_schema }
791
+ unless child_node
792
+ begin
793
+ ctx_mode = if child_schema.yang.substmt('config').any?
794
+ case child_schema.yang.substmt('config')[0].arg
795
+ when 'true'
796
+ Rubyang::Database::DataTree::Mode::CONFIG
797
+ when 'false'
798
+ Rubyang::Database::DataTree::Mode::OPER
799
+ end
800
+ else
801
+ @ctx_mode
802
+ end
803
+ case child_schema.model
804
+ when Rubyang::Model::Anyxml
805
+ child_node = Anyxml.new( self, @schema_tree, child_schema, @db_mode, ctx_mode )
806
+ when Rubyang::Model::Container
807
+ child_node = Container.new( self, @schema_tree, child_schema, @db_mode, ctx_mode )
808
+ # when start
809
+ unless child_node.evaluate_whens.value
810
+ raise "#{arg} is not valid because of 'when' conditions"
811
+ end
812
+ # end
813
+ when Rubyang::Model::Leaf
814
+ child_node = Leaf.new( self, @schema_tree, child_schema, @db_mode, ctx_mode )
815
+ when Rubyang::Model::List
816
+ child_node = List.new( self, @schema_tree, child_schema, @db_mode, ctx_mode )
817
+ when Rubyang::Model::LeafList
818
+ child_node = LeafList.new( self, @schema_tree, child_schema, @db_mode, ctx_mode )
819
+ else
820
+ raise
821
+ end
822
+ rescue
823
+ raise ArgumentError, "#{arg} NOT match"
824
+ end
825
+ @children.push child_node
826
+ end
827
+ child_node
828
+ end
829
+ def edit_xpath arg
830
+ xpath = Rubyang::Xpath::Parser.parse arg
831
+ candidates = self.evaluate_xpath( xpath )
832
+ case candidates.value.size
833
+ when 0
834
+ raise "no such xpath: #{arg}"
835
+ when 1
836
+ candidates.value.first
837
+ else
838
+ raise "too many match to xpath: #{arg}"
839
+ end
840
+ end
841
+ def delete arg
842
+ child_schema = find_child_schema @schema, arg
843
+ child_node = @children.find{ |c| c.schema == child_schema }
844
+ @children.delete child_node
845
+ end
846
+ end
844
847
 
845
- class Root < InteriorNode
846
- def valid? current=true
847
- result = @children.inject(Rubyang::Xpath::BasicType::Boolean.new true){ |r, c|
848
- r.and c.valid?( false )
849
- }
850
- result.value
851
- end
852
- def commit
853
- begin
854
- components = self.edit( "rubyang" ).edit( "component" ).children.map{ |c|
855
- component = c.key_values.first
856
- hook = c.edit("hook").value
857
- file_path = c.edit("file-path").value
858
- [component, hook, file_path]
859
- }
860
- self.root.parent.component_manager.update components
861
- self.root.parent.component_manager.run "commit"
862
- rescue => e
863
- puts 'rescue in commit'
864
- puts e
865
- ensure
866
- backup = self.to_xml
867
- @parent.history.push backup
868
- end
869
- end
870
- def revert
871
- backup = @parent.history.pop
872
- if backup
873
- self.load_override_xml backup
874
- else
875
- self.load_override_xml self.new.to_xml
876
- end
877
- end
878
- def to_xml_recursive _doc, current_namespace=''
879
- doc = _doc.add_element( 'config' )
880
- current_namespace = @schema_tree.root.namespace
881
- doc.add_namespace( current_namespace )
882
- @children.each{ |c|
883
- c.to_xml_recursive doc, current_namespace
884
- }
885
- end
886
- def to_json_recursive _hash
887
- hash = Hash.new
888
- _hash['config'] = hash
889
- @children.each{ |c|
890
- c.to_json_recursive hash
891
- }
892
- end
893
- def load_xml xml_str
894
- doc_xml = REXML::Document.new( xml_str ).root
895
- self.load_merge_xml_recursive doc_xml
896
- end
897
- def load_merge_xml xml_str
898
- self.load_xml xml_str
899
- end
900
- def load_override_xml xml_str
901
- @children.clear
902
- self.load_xml xml_str
903
- end
904
- def load_merge_json json_str
905
- xml_str = json_to_xml( json_str )
906
- self.load_merge_xml xml_str
907
- end
908
- def load_override_json json_str
909
- xml_str = json_to_xml( json_str )
910
- self.load_override_xml xml_str
911
- end
912
- end
848
+ class LeafNode < Node
849
+ end
913
850
 
914
- class Anyxml < Node
915
- def set arg
916
- @value = REXML::Document.new( arg )
917
- end
918
- def value
919
- @value.to_s
920
- end
921
- def to_xml_recursive _doc, current_namespace
922
- doc = _doc.add_element @value
923
- unless @schema.namespace == current_namespace
924
- current_namespace = @schema.namespace
925
- doc.add_namespace current_namespace
926
- end
927
- end
928
- def to_json_recursive _hash
929
- raise "anyxml to json is not implemented"
930
- hash = _hash
931
- hash[@schema.model.arg] = @value.to_s
932
- end
933
- end
851
+ class ListNode < Node
852
+ end
934
853
 
935
- class Container < InteriorNode
936
- end
854
+ class Root < InteriorNode
855
+ def valid? current=true
856
+ result = @children.inject(Rubyang::Xpath::BasicType::Boolean.new true){ |r, c|
857
+ r.and c.valid?( false )
858
+ }
859
+ result.value
860
+ end
861
+ def commit
862
+ begin
863
+ components = self.edit( "rubyang" ).edit( "component" ).children.map{ |c|
864
+ component = c.key_values.first
865
+ hook = c.edit("hook").value
866
+ file_path = c.edit("file-path").value
867
+ [component, hook, file_path]
868
+ }
869
+ self.root.parent.component_manager.update components
870
+ self.root.parent.component_manager.run "commit"
871
+ rescue => e
872
+ @logger.debug { 'rescue in commit' }
873
+ @logger.debug { e }
874
+ ensure
875
+ backup = self.to_xml
876
+ @parent.history.push backup
877
+ end
878
+ end
879
+ def revert
880
+ backup = @parent.history.pop
881
+ if backup
882
+ self.load_override_xml backup
883
+ else
884
+ self.load_override_xml self.new.to_xml
885
+ end
886
+ end
887
+ def to_xml_recursive _doc, current_namespace=''
888
+ root_tag = case @db_mode
889
+ when Rubyang::Database::DataTree::Mode::CONFIG
890
+ 'config'
891
+ when Rubyang::Database::DataTree::Mode::OPER
892
+ 'oper'
893
+ end
894
+ doc = _doc.add_element( root_tag )
895
+ current_namespace = @schema_tree.root.namespace
896
+ doc.add_namespace( current_namespace )
897
+ @children.each{ |c|
898
+ c.to_xml_recursive doc, current_namespace
899
+ }
900
+ end
901
+ def to_json_recursive _hash
902
+ root_tag = case @db_mode
903
+ when Rubyang::Database::DataTree::Mode::CONFIG
904
+ 'config'
905
+ when Rubyang::Database::DataTree::Mode::OPER
906
+ 'oper'
907
+ end
908
+ hash = Hash.new
909
+ _hash[root_tag] = hash
910
+ @children.each{ |c|
911
+ c.to_json_recursive hash
912
+ }
913
+ end
914
+ def load_xml xml_str
915
+ doc_xml = REXML::Document.new( xml_str ).root
916
+ self.load_merge_xml_recursive doc_xml
917
+ end
918
+ def load_merge_xml xml_str
919
+ self.load_xml xml_str
920
+ end
921
+ def load_override_xml xml_str
922
+ @children.clear
923
+ self.load_xml xml_str
924
+ end
925
+ def load_merge_json json_str
926
+ xml_str = json_to_xml( json_str )
927
+ self.load_merge_xml xml_str
928
+ end
929
+ def load_override_json json_str
930
+ xml_str = json_to_xml( json_str )
931
+ self.load_override_xml xml_str
932
+ end
933
+ end
937
934
 
938
- class Leaf < LeafNode
939
- attr_accessor :value
940
- def set arg
941
- case @schema.type
942
- when SchemaTree::LeafrefType
943
- elements = self.evaluate_xpath( @schema.type.path )
944
- values = elements.inject([]){ |vs, v| vs + [v.value] }
945
- unless values.include? arg
946
- raise ArgumentError, "#{arg} is not valid for #{@schema.type.inspect}"
947
- end
948
- else
949
- unless @schema.type.valid? arg
950
- raise ArgumentError, "#{arg} is not valid for #{@schema.type.inspect}"
951
- end
952
- end
953
- self.value = arg
954
- end
955
- def has_value?
956
- if @value
957
- true
958
- else
959
- false
960
- end
961
- end
962
- def to_xml_recursive _doc, current_namespace
963
- doc = _doc.add_element( @schema.model.arg )
964
- unless @schema.namespace == current_namespace
965
- current_namespace = @schema.namespace
966
- doc.add_namespace current_namespace
967
- end
968
- doc.add_text( @value )
969
- end
970
- def to_json_recursive _hash
971
- hash = _hash
972
- hash[@schema.model.arg] = @value
973
- end
974
- end
935
+ class Anyxml < Node
936
+ def set arg
937
+ @value = REXML::Document.new( arg )
938
+ end
939
+ def value
940
+ @value.to_s
941
+ end
942
+ def to_xml_recursive _doc, current_namespace
943
+ doc = _doc.add_element @value
944
+ unless @schema.namespace == current_namespace
945
+ current_namespace = @schema.namespace
946
+ doc.add_namespace current_namespace
947
+ end
948
+ end
949
+ def to_json_recursive _hash
950
+ raise "anyxml to json is not implemented"
951
+ hash = _hash
952
+ hash[@schema.model.arg] = @value.to_s
953
+ end
954
+ end
975
955
 
976
- class List < ListNode
977
- def edit *args
978
- child_node = @children.find{ |c| c.key_values == args }
979
- unless child_node
980
- begin
981
- child_node = ListElement.new( self, @schema_tree, @schema, args )
982
- rescue
983
- raise ArgumentError, "#{args} NOT match"
984
- end
985
- @children.push child_node
986
- end
987
- child_node
988
- end
989
- def to_xml_recursive _doc, current_namespace
990
- doc = _doc
991
- @children.each{ |c|
992
- c.to_xml_recursive doc, current_namespace
993
- }
994
- end
995
- def to_json_recursive _hash
996
- array = Array.new
997
- _hash[@schema.model.arg] = array
998
- @children.each{ |c|
999
- c.to_json_recursive array
1000
- }
1001
- end
1002
- def load_merge_xml_recursive doc_xml
1003
- return if doc_xml.elements.size == 0
1004
- key_args = @schema.keys.map{ |k| doc_xml.elements[k].text }
1005
- child = edit( *key_args )
1006
- elements = REXML::Document.new('<tmp />')
1007
- doc_xml.each_element{ |e|
1008
- next if @schema.keys.include? e.name
1009
- elements.root.add_element e
1010
- }
1011
- child.load_merge_xml_recursive elements.root
1012
- end
1013
- end
956
+ class Container < InteriorNode
957
+ end
1014
958
 
1015
- class ListElement < InteriorNode
1016
- def initialize parent, schema_tree, schema, key_values
1017
- @parent = parent
1018
- @schema_tree = schema_tree
1019
- @schema = schema
1020
- @children = []
1021
- @key_values = key_values
1022
- @schema.keys.zip( key_values ).each{ |key, value|
1023
- self.edit( key, true ).set( value )
1024
- }
1025
- end
1026
- def key_values
1027
- @key_values
1028
- end
1029
- def edit arg, in_initialize=false
1030
- unless in_initialize
1031
- if @schema.model.substmt( 'key' ).find{ |s| s.arg == arg }
1032
- raise "#{arg} is key"
1033
- end
1034
- end
1035
- super arg
1036
- end
1037
- def to_json_recursive _array
1038
- hash = Hash.new
1039
- _array.push hash
1040
- @children.each{ |c|
1041
- c.to_json_recursive hash
1042
- }
1043
- end
1044
- end
959
+ class Leaf < LeafNode
960
+ attr_accessor :value
961
+ def set arg
962
+ case @schema.type
963
+ when SchemaTree::LeafrefType
964
+ elements = self.evaluate_xpath( @schema.type.path )
965
+ values = elements.inject([]){ |vs, v| vs + [v.value] }
966
+ unless values.include? arg
967
+ raise ArgumentError, "#{arg} is not valid for #{@schema.type.inspect}"
968
+ end
969
+ else
970
+ unless @schema.type.valid? arg
971
+ raise ArgumentError, "#{arg} is not valid for #{@schema.type.inspect}"
972
+ end
973
+ end
974
+ self.value = arg
975
+ end
976
+ def has_value?
977
+ if @value
978
+ true
979
+ else
980
+ false
981
+ end
982
+ end
983
+ def to_xml_recursive _doc, current_namespace
984
+ doc = _doc.add_element( @schema.model.arg )
985
+ unless @schema.namespace == current_namespace
986
+ current_namespace = @schema.namespace
987
+ doc.add_namespace current_namespace
988
+ end
989
+ doc.add_text( @value )
990
+ end
991
+ def to_json_recursive _hash
992
+ hash = _hash
993
+ hash[@schema.model.arg] = @value
994
+ end
995
+ end
1045
996
 
1046
- class LeafList < InteriorNode
1047
- def set arg
1048
- child_node = @children.find{ |c| c.value == arg }
1049
- unless child_node
1050
- begin
1051
- child_node = LeafListElement.new( self, @schema_tree, @schema, arg )
1052
- rescue
1053
- raise ArgumentError
1054
- end
1055
- @children.push child_node
1056
- end
1057
- child_node
1058
- end
1059
- def to_xml_recursive _doc, current_namespace
1060
- doc = _doc
1061
- @children.each{ |c|
1062
- c.to_xml_recursive doc, current_namespace
1063
- }
1064
- end
1065
- end
997
+ class List < ListNode
998
+ def edit *args
999
+ child_node = @children.find{ |c| c.key_values == args }
1000
+ unless child_node
1001
+ begin
1002
+ child_node = ListElement.new( self, @schema_tree, @schema, @db_mode, @ctx_mode, args )
1003
+ rescue
1004
+ raise ArgumentError, "#{args} NOT match"
1005
+ end
1006
+ @children.push child_node
1007
+ end
1008
+ child_node
1009
+ end
1010
+ def delete *args
1011
+ child_node = @children.find{ |c| c.key_values == args }
1012
+ @children.delete child_node
1013
+ end
1014
+ def to_xml_recursive _doc, current_namespace
1015
+ doc = _doc
1016
+ @children.each{ |c|
1017
+ c.to_xml_recursive doc, current_namespace
1018
+ }
1019
+ end
1020
+ def to_json_recursive _hash
1021
+ array = Array.new
1022
+ _hash[@schema.model.arg] = array
1023
+ @children.each{ |c|
1024
+ c.to_json_recursive array
1025
+ }
1026
+ end
1027
+ def load_merge_xml_recursive doc_xml
1028
+ return if doc_xml.elements.size == 0
1029
+ key_args = @schema.keys.map{ |k| doc_xml.elements[k].text }
1030
+ child = edit( *key_args )
1031
+ elements = REXML::Document.new('<tmp />')
1032
+ doc_xml.each_element{ |e|
1033
+ next if @schema.keys.include? e.name
1034
+ elements.root.add_element e
1035
+ }
1036
+ child.load_merge_xml_recursive elements.root
1037
+ end
1038
+ end
1066
1039
 
1067
- class LeafListElement < LeafNode
1068
- attr_accessor :value
1069
- def initialize parent, schema_tree, schema, value
1070
- @parent = parent
1071
- @schema_tree = schema_tree
1072
- @schema = schema
1073
- @value = value
1074
- end
1075
- def to_xml_recursive _doc, current_namespace
1076
- doc = _doc.add_element( @schema.model.arg )
1077
- unless @schema.namespace == current_namespace
1078
- current_namespace = @schema.namespace
1079
- doc.add_namespace current_namespace
1080
- end
1081
- doc.add_text( @value )
1082
- end
1083
- end
1040
+ class ListElement < InteriorNode
1041
+ def initialize parent, schema_tree, schema, db_mode, ctx_mode, key_values
1042
+ @logger = Logger.new(self.class.name)
1043
+ @parent = parent
1044
+ @schema_tree = schema_tree
1045
+ @schema = schema
1046
+ @db_mode = db_mode
1047
+ @ctx_mode = ctx_mode
1048
+ @children = []
1049
+ @key_values = key_values
1050
+ @schema.keys.zip( key_values ).each{ |key, value|
1051
+ self.edit( key, true ).set( value )
1052
+ }
1053
+ end
1054
+ def key_values
1055
+ @key_values
1056
+ end
1057
+ def edit arg, in_initialize=false
1058
+ unless in_initialize
1059
+ if @schema.model.substmt( 'key' ).find{ |s| s.arg == arg }
1060
+ raise "#{arg} is key"
1061
+ end
1062
+ end
1063
+ super arg
1064
+ end
1065
+ def to_json_recursive _array
1066
+ hash = Hash.new
1067
+ _array.push hash
1068
+ @children.each{ |c|
1069
+ c.to_json_recursive hash
1070
+ }
1071
+ end
1072
+ end
1084
1073
 
1085
- attr_accessor :component_manager
1086
- def initialize schema_tree
1087
- @root = Root.new( self, schema_tree, schema_tree.root )
1088
- @history = Array.new
1089
- @component_manager = Rubyang::Database::ComponentManager.new
1090
- end
1091
- def to_s parent=true
1092
- head, vars, tail = "#<#{self.class.to_s}:0x#{(self.object_id << 1).to_s(16).rjust(14,'0')} ", Array.new, ">"
1093
- if parent
1094
- vars.push "@yang=#{@root.to_s}"
1095
- vars.push "@history=#{@history.to_s}"
1096
- vars.push "@component_manager=#{@component_manager.to_s}"
1097
- end
1098
- head + vars.join(', ') + tail
1099
- end
1100
- def history
1101
- @history
1102
- end
1103
- def root
1104
- @root
1105
- end
1106
- end
1107
- end
1108
- end
1074
+ class LeafList < InteriorNode
1075
+ def set arg
1076
+ child_node = @children.find{ |c| c.value == arg }
1077
+ unless child_node
1078
+ begin
1079
+ child_node = LeafListElement.new( self, @schema_tree, @schema, @db_mode, @ctx_mode, arg )
1080
+ rescue
1081
+ raise ArgumentError
1082
+ end
1083
+ @children.push child_node
1084
+ end
1085
+ child_node
1086
+ end
1087
+ def to_xml_recursive _doc, current_namespace
1088
+ doc = _doc
1089
+ @children.each{ |c|
1090
+ c.to_xml_recursive doc, current_namespace
1091
+ }
1092
+ end
1093
+ end
1109
1094
 
1095
+ class LeafListElement < LeafNode
1096
+ attr_accessor :value
1097
+ def initialize parent, schema_tree, schema, db_mode, ctx_mode, value
1098
+ @logger = Logger.new(self.class.name)
1099
+ @parent = parent
1100
+ @schema_tree = schema_tree
1101
+ @schema = schema
1102
+ @db_mode = db_mode
1103
+ @ctx_mode = ctx_mode
1104
+ @value = value
1105
+ end
1106
+ def to_xml_recursive _doc, current_namespace
1107
+ doc = _doc.add_element( @schema.model.arg )
1108
+ unless @schema.namespace == current_namespace
1109
+ current_namespace = @schema.namespace
1110
+ doc.add_namespace current_namespace
1111
+ end
1112
+ doc.add_text( @value )
1113
+ end
1114
+ end
1115
+
1116
+ attr_accessor :component_manager
1117
+ def initialize schema_tree, mode=Rubyang::Database::DataTree::Mode::CONFIG
1118
+ @logger = Logger.new(self.class.name)
1119
+ @db_mode = mode
1120
+ @ctx_mode = Rubyang::Database::DataTree::Mode::CONFIG
1121
+ @root = Root.new( self, schema_tree, schema_tree.root, @db_mode, @ctx_mode )
1122
+ @history = Array.new
1123
+ @component_manager = Rubyang::Database::ComponentManager.new
1124
+ end
1125
+ def to_s parent=true
1126
+ head, vars, tail = "#<#{self.class.to_s}:0x#{(self.object_id << 1).to_s(16).rjust(14,'0')} ", Array.new, ">"
1127
+ if parent
1128
+ vars.push "@yang=#{@root.to_s}"
1129
+ vars.push "@history=#{@history.to_s}"
1130
+ vars.push "@component_manager=#{@component_manager.to_s}"
1131
+ end
1132
+ head + vars.join(', ') + tail
1133
+ end
1134
+ def history
1135
+ @history
1136
+ end
1137
+ def root
1138
+ @root
1139
+ end
1140
+ end
1141
+ end
1142
+ end