rubyang 0.1.2.1 → 0.1.3

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.
@@ -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