duxml 0.8.8 → 0.8.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/validate_xml +30 -30
- data/lib/duxml.rb +76 -76
- data/lib/duxml/doc.rb +108 -91
- data/lib/duxml/doc/element.rb +250 -250
- data/lib/duxml/doc/lazy_ox.rb +167 -167
- data/lib/duxml/doc/node_set.rb +38 -38
- data/lib/duxml/meta.rb +72 -72
- data/lib/duxml/meta/grammar.rb +133 -133
- data/lib/duxml/meta/grammar/pattern.rb +111 -111
- data/lib/duxml/meta/grammar/pattern/attr_name_pattern.rb +36 -36
- data/lib/duxml/meta/grammar/pattern/attr_val_pattern.rb +36 -36
- data/lib/duxml/meta/grammar/pattern/child_pattern.rb +60 -60
- data/lib/duxml/meta/grammar/pattern/text_pattern.rb +31 -31
- data/lib/duxml/meta/grammar/pattern_maker.rb +68 -68
- data/lib/duxml/meta/grammar/relax_ng.rb +39 -39
- data/lib/duxml/meta/grammar/relax_ng/attrs_rule.rb +58 -58
- data/lib/duxml/meta/grammar/relax_ng/children_rule.rb +82 -82
- data/lib/duxml/meta/grammar/relax_ng/value_rule.rb +44 -44
- data/lib/duxml/meta/grammar/rule.rb +58 -58
- data/lib/duxml/meta/grammar/rule/attrs_rule.rb +77 -77
- data/lib/duxml/meta/grammar/rule/children_rule.rb +135 -135
- data/lib/duxml/meta/grammar/rule/text_rule.rb +39 -39
- data/lib/duxml/meta/grammar/rule/value_rule.rb +110 -110
- data/lib/duxml/meta/grammar/spreadsheet.rb +34 -34
- data/lib/duxml/meta/history.rb +88 -88
- data/lib/duxml/meta/history/add.rb +30 -30
- data/lib/duxml/meta/history/change.rb +70 -70
- data/lib/duxml/meta/history/change_attr.rb +33 -33
- data/lib/duxml/meta/history/change_text.rb +32 -32
- data/lib/duxml/meta/history/error.rb +24 -24
- data/lib/duxml/meta/history/new_attr.rb +32 -32
- data/lib/duxml/meta/history/new_text.rb +36 -36
- data/lib/duxml/meta/history/qualify_error.rb +21 -21
- data/lib/duxml/meta/history/remove.rb +27 -27
- data/lib/duxml/meta/history/undo.rb +23 -23
- data/lib/duxml/meta/history/validate_error.rb +20 -20
- data/lib/duxml/reportable.rb +28 -28
- data/lib/duxml/ruby_ext/fixnum.rb +55 -55
- data/lib/duxml/ruby_ext/module.rb +11 -11
- data/lib/duxml/ruby_ext/object.rb +13 -13
- data/lib/duxml/ruby_ext/regexp.rb +19 -19
- data/lib/duxml/ruby_ext/string.rb +37 -37
- data/lib/duxml/saxer.rb +75 -75
- metadata +12 -12
@@ -1,40 +1,40 @@
|
|
1
|
-
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
-
|
3
|
-
require File.expand_path(File.dirname(__FILE__) + '/../rule')
|
4
|
-
|
5
|
-
module Duxml
|
6
|
-
module TextRule; end
|
7
|
-
|
8
|
-
class TextRuleClass < RuleClass
|
9
|
-
include TextRule
|
10
|
-
end
|
11
|
-
|
12
|
-
module TextRule
|
13
|
-
# @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
|
14
|
-
# @return [Boolean] whether this rule does in fact apply
|
15
|
-
def applies_to?(change_or_pattern)
|
16
|
-
super(change_or_pattern) &&
|
17
|
-
change_or_pattern.respond_to?(:text)
|
18
|
-
end
|
19
|
-
|
20
|
-
# applies Regexp statement to text content of this node; returns false if content has XML
|
21
|
-
def qualify(change_or_pattern)
|
22
|
-
@object = change_or_pattern
|
23
|
-
result = pass
|
24
|
-
super change_or_pattern unless result
|
25
|
-
@object = nil
|
26
|
-
result
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def pass
|
32
|
-
return false unless object.text.is_a?(String)
|
33
|
-
get_scanner.match(object.text).to_s == object.text
|
34
|
-
end
|
35
|
-
|
36
|
-
def get_scanner
|
37
|
-
Regexp.new(statement)
|
38
|
-
end
|
39
|
-
end # module TextRule
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../rule')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module TextRule; end
|
7
|
+
|
8
|
+
class TextRuleClass < RuleClass
|
9
|
+
include TextRule
|
10
|
+
end
|
11
|
+
|
12
|
+
module TextRule
|
13
|
+
# @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
|
14
|
+
# @return [Boolean] whether this rule does in fact apply
|
15
|
+
def applies_to?(change_or_pattern)
|
16
|
+
super(change_or_pattern) &&
|
17
|
+
change_or_pattern.respond_to?(:text)
|
18
|
+
end
|
19
|
+
|
20
|
+
# applies Regexp statement to text content of this node; returns false if content has XML
|
21
|
+
def qualify(change_or_pattern)
|
22
|
+
@object = change_or_pattern
|
23
|
+
result = pass
|
24
|
+
super change_or_pattern unless result
|
25
|
+
@object = nil
|
26
|
+
result
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def pass
|
32
|
+
return false unless object.text.is_a?(String)
|
33
|
+
get_scanner.match(object.text).to_s == object.text
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_scanner
|
37
|
+
Regexp.new(statement)
|
38
|
+
end
|
39
|
+
end # module TextRule
|
40
40
|
end # module Duxml
|
@@ -1,111 +1,111 @@
|
|
1
|
-
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
-
|
3
|
-
require File.expand_path(File.dirname(__FILE__) + '/../rule')
|
4
|
-
|
5
|
-
module Duxml
|
6
|
-
module ValueRule; end
|
7
|
-
|
8
|
-
# rule that states what values a given attribute name is allowed to have
|
9
|
-
class ValueRuleClass < RuleClass
|
10
|
-
include ValueRule
|
11
|
-
|
12
|
-
# @param _attr_name [String] the attribute name
|
13
|
-
# @param _statement [String] data type or expression of the rule for the given attribute's value
|
14
|
-
def initialize(_attr_name, _statement)
|
15
|
-
@attr_name, @statement = _attr_name, _statement
|
16
|
-
end
|
17
|
-
|
18
|
-
attr_reader :attr_name
|
19
|
-
end
|
20
|
-
|
21
|
-
module ValueRule
|
22
|
-
CDATA_EXPR = /(\]\]>)/
|
23
|
-
ENTITY_EXPR = /(\b[\S]+\b)/
|
24
|
-
ID_EXPR = Regexp.nmtoken
|
25
|
-
NMTOKEN_EXPR = ID_EXPR
|
26
|
-
NOTATION_EXPR = //
|
27
|
-
|
28
|
-
# @return [true]
|
29
|
-
def abstract?
|
30
|
-
true
|
31
|
-
end
|
32
|
-
|
33
|
-
# @return [String] description of this rule
|
34
|
-
def description
|
35
|
-
%(#{relationship.capitalize} Rule that @#{attr_name}'s #{relationship} must match '#{statement}')
|
36
|
-
end
|
37
|
-
|
38
|
-
# @param change_or_pattern [Duxml::Pattern, Duxml::Change] change or pattern to be evaluated
|
39
|
-
# @return [Boolean] whether change_or_pattern#subject is allowed to have value of type #object
|
40
|
-
# if false, reports Error to History
|
41
|
-
def qualify(change_or_pattern)
|
42
|
-
value = change_or_pattern.value
|
43
|
-
s = change_or_pattern.subject
|
44
|
-
raise Exception if value.nil?
|
45
|
-
result = pass value
|
46
|
-
super change_or_pattern unless result
|
47
|
-
result
|
48
|
-
end
|
49
|
-
|
50
|
-
# @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
|
51
|
-
# @return [Boolean] whether this rule does in fact apply
|
52
|
-
def applies_to?(change_or_pattern)
|
53
|
-
return false unless change_or_pattern.respond_to?(:attr_name)
|
54
|
-
return false unless change_or_pattern.respond_to?(:value)
|
55
|
-
change_or_pattern.attr_name == attr_name
|
56
|
-
end
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
def pass(value)
|
61
|
-
matcher = find_method_or_expr
|
62
|
-
if matcher.respond_to?(:match)
|
63
|
-
matcher.match(value).to_s == value
|
64
|
-
else
|
65
|
-
matcher.call(value)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def find_method_or_expr
|
70
|
-
s = statement
|
71
|
-
case s
|
72
|
-
when 'CDATA' # unparsed character data e.g. '<not-xml>'; may not contain string ']]>'
|
73
|
-
proc do |val| val.match(CDATA_EXPR).nil? end
|
74
|
-
when 'ID' then ID_EXPR # does not check for uniqueness!
|
75
|
-
when 'IDREF' # id of another doc
|
76
|
-
proc do |val| val.match(ID_EXPR) && resolve_ref(val, subject.meta) end
|
77
|
-
when 'IDREFS' # ids of other elements
|
78
|
-
proc do |val|
|
79
|
-
separate_list val do |sub_val|
|
80
|
-
sub_val.match(ID_EXPR) && resolve_ref(sub_val, subject.meta)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
when 'NMTOKEN' then NMTOKEN_EXPR # valid XML name
|
84
|
-
when 'NMTOKENS' # a list of valid XML names
|
85
|
-
proc do |val|
|
86
|
-
separate_list val do |sub_val|
|
87
|
-
sub_val.match NMTOKEN_EXPR
|
88
|
-
end
|
89
|
-
end
|
90
|
-
when 'ENTITY' then ENTITY_EXPR # an entity
|
91
|
-
when 'ENTITIES' # list of entities
|
92
|
-
proc do |val|
|
93
|
-
separate_list val do |sub_val|
|
94
|
-
sub_val.match ENTITY_EXPR
|
95
|
-
end
|
96
|
-
end
|
97
|
-
when 'NOTATION' then // # TODO name of a notation
|
98
|
-
when 'xml:' then // # TODO predefined XML value
|
99
|
-
else # '|'-separated list of allowable values i.e. Regexp-style DTD declaration
|
100
|
-
Regexp.new(s)
|
101
|
-
end
|
102
|
-
end # def find_method_or_expr
|
103
|
-
|
104
|
-
def separate_list(spc_sep_vals, &block)
|
105
|
-
spc_sep_vals.split(' ').any? do |sub_val|
|
106
|
-
result = block.call sub_val
|
107
|
-
!result
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end # module ValueRule
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../rule')
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
module ValueRule; end
|
7
|
+
|
8
|
+
# rule that states what values a given attribute name is allowed to have
|
9
|
+
class ValueRuleClass < RuleClass
|
10
|
+
include ValueRule
|
11
|
+
|
12
|
+
# @param _attr_name [String] the attribute name
|
13
|
+
# @param _statement [String] data type or expression of the rule for the given attribute's value
|
14
|
+
def initialize(_attr_name, _statement)
|
15
|
+
@attr_name, @statement = _attr_name, _statement
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :attr_name
|
19
|
+
end
|
20
|
+
|
21
|
+
module ValueRule
|
22
|
+
CDATA_EXPR = /(\]\]>)/
|
23
|
+
ENTITY_EXPR = /(\b[\S]+\b)/
|
24
|
+
ID_EXPR = Regexp.nmtoken
|
25
|
+
NMTOKEN_EXPR = ID_EXPR
|
26
|
+
NOTATION_EXPR = //
|
27
|
+
|
28
|
+
# @return [true]
|
29
|
+
def abstract?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [String] description of this rule
|
34
|
+
def description
|
35
|
+
%(#{relationship.capitalize} Rule that @#{attr_name}'s #{relationship} must match '#{statement}')
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param change_or_pattern [Duxml::Pattern, Duxml::Change] change or pattern to be evaluated
|
39
|
+
# @return [Boolean] whether change_or_pattern#subject is allowed to have value of type #object
|
40
|
+
# if false, reports Error to History
|
41
|
+
def qualify(change_or_pattern)
|
42
|
+
value = change_or_pattern.value
|
43
|
+
s = change_or_pattern.subject
|
44
|
+
raise Exception if value.nil?
|
45
|
+
result = pass value
|
46
|
+
super change_or_pattern unless result
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param change_or_pattern [Duxml::Change, Duxml::Pattern] change or pattern that rule may apply to
|
51
|
+
# @return [Boolean] whether this rule does in fact apply
|
52
|
+
def applies_to?(change_or_pattern)
|
53
|
+
return false unless change_or_pattern.respond_to?(:attr_name)
|
54
|
+
return false unless change_or_pattern.respond_to?(:value)
|
55
|
+
change_or_pattern.attr_name == attr_name
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def pass(value)
|
61
|
+
matcher = find_method_or_expr
|
62
|
+
if matcher.respond_to?(:match)
|
63
|
+
matcher.match(value).to_s == value
|
64
|
+
else
|
65
|
+
matcher.call(value)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def find_method_or_expr
|
70
|
+
s = statement
|
71
|
+
case s
|
72
|
+
when 'CDATA' # unparsed character data e.g. '<not-xml>'; may not contain string ']]>'
|
73
|
+
proc do |val| val.match(CDATA_EXPR).nil? end
|
74
|
+
when 'ID' then ID_EXPR # does not check for uniqueness!
|
75
|
+
when 'IDREF' # id of another doc
|
76
|
+
proc do |val| val.match(ID_EXPR) && resolve_ref(val, subject.meta) end
|
77
|
+
when 'IDREFS' # ids of other elements
|
78
|
+
proc do |val|
|
79
|
+
separate_list val do |sub_val|
|
80
|
+
sub_val.match(ID_EXPR) && resolve_ref(sub_val, subject.meta)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
when 'NMTOKEN' then NMTOKEN_EXPR # valid XML name
|
84
|
+
when 'NMTOKENS' # a list of valid XML names
|
85
|
+
proc do |val|
|
86
|
+
separate_list val do |sub_val|
|
87
|
+
sub_val.match NMTOKEN_EXPR
|
88
|
+
end
|
89
|
+
end
|
90
|
+
when 'ENTITY' then ENTITY_EXPR # an entity
|
91
|
+
when 'ENTITIES' # list of entities
|
92
|
+
proc do |val|
|
93
|
+
separate_list val do |sub_val|
|
94
|
+
sub_val.match ENTITY_EXPR
|
95
|
+
end
|
96
|
+
end
|
97
|
+
when 'NOTATION' then // # TODO name of a notation
|
98
|
+
when 'xml:' then // # TODO predefined XML value
|
99
|
+
else # '|'-separated list of allowable values i.e. Regexp-style DTD declaration
|
100
|
+
Regexp.new(s)
|
101
|
+
end
|
102
|
+
end # def find_method_or_expr
|
103
|
+
|
104
|
+
def separate_list(spc_sep_vals, &block)
|
105
|
+
spc_sep_vals.split(' ').any? do |sub_val|
|
106
|
+
result = block.call sub_val
|
107
|
+
!result
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end # module ValueRule
|
111
111
|
end # module Duxml
|
@@ -1,35 +1,35 @@
|
|
1
|
-
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
-
|
3
|
-
require 'rubyXL'
|
4
|
-
|
5
|
-
module Duxml
|
6
|
-
# contains helper methods to convert spreadsheet of DTD rules into Duxml::Rules
|
7
|
-
module Spreadsheet
|
8
|
-
private
|
9
|
-
# @param path [String] spreadsheet file
|
10
|
-
def self.sheet_to_xml(path)
|
11
|
-
worksheet = RubyXL::Parser.parse(path)[0]
|
12
|
-
attr_val_rule_hash = {}
|
13
|
-
g = GrammarClass.new
|
14
|
-
worksheet.each_with_index do |row, index|
|
15
|
-
next if index == 0
|
16
|
-
break if row[3].nil? || row[4].nil?
|
17
|
-
element_name = row[3].value
|
18
|
-
statement_str = row[4].value
|
19
|
-
g << ChildrenRuleClass.new(element_name, statement_str)
|
20
|
-
attribute_rules = row[5].value.split(/\n/)
|
21
|
-
attribute_rules.each_with_index do |rule, i|
|
22
|
-
next if i == 0 or rule.empty?
|
23
|
-
attr_name, value_expr, attr_req = *rule.split
|
24
|
-
next if [attr_name, value_expr, attr_req].any? do |s| s.empty? or s.match(/\w/).nil? end
|
25
|
-
g << AttrsRuleClass.new(element_name, attr_name, attr_req)
|
26
|
-
unless attr_val_rule_hash[attr_name]
|
27
|
-
g << ValueRuleClass.new(attr_name, value_expr)
|
28
|
-
attr_val_rule_hash[attr_name] = true
|
29
|
-
end
|
30
|
-
end # attribute_rules.each_with_index
|
31
|
-
end # worksheet.each_with_index
|
32
|
-
g
|
33
|
-
end # def sheet_to_xml(path)
|
34
|
-
end # module Spreadsheet
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require 'rubyXL'
|
4
|
+
|
5
|
+
module Duxml
|
6
|
+
# contains helper methods to convert spreadsheet of DTD rules into Duxml::Rules
|
7
|
+
module Spreadsheet
|
8
|
+
private
|
9
|
+
# @param path [String] spreadsheet file
|
10
|
+
def self.sheet_to_xml(path)
|
11
|
+
worksheet = RubyXL::Parser.parse(path)[0]
|
12
|
+
attr_val_rule_hash = {}
|
13
|
+
g = GrammarClass.new
|
14
|
+
worksheet.each_with_index do |row, index|
|
15
|
+
next if index == 0
|
16
|
+
break if row[3].nil? || row[4].nil?
|
17
|
+
element_name = row[3].value
|
18
|
+
statement_str = row[4].value
|
19
|
+
g << ChildrenRuleClass.new(element_name, statement_str)
|
20
|
+
attribute_rules = row[5].value.split(/\n/)
|
21
|
+
attribute_rules.each_with_index do |rule, i|
|
22
|
+
next if i == 0 or rule.empty?
|
23
|
+
attr_name, value_expr, attr_req = *rule.split
|
24
|
+
next if [attr_name, value_expr, attr_req].any? do |s| s.empty? or s.match(/\w/).nil? end
|
25
|
+
g << AttrsRuleClass.new(element_name, attr_name, attr_req)
|
26
|
+
unless attr_val_rule_hash[attr_name]
|
27
|
+
g << ValueRuleClass.new(attr_name, value_expr)
|
28
|
+
attr_val_rule_hash[attr_name] = true
|
29
|
+
end
|
30
|
+
end # attribute_rules.each_with_index
|
31
|
+
end # worksheet.each_with_index
|
32
|
+
g
|
33
|
+
end # def sheet_to_xml(path)
|
34
|
+
end # module Spreadsheet
|
35
35
|
end # module Duxml
|
data/lib/duxml/meta/history.rb
CHANGED
@@ -1,89 +1,89 @@
|
|
1
|
-
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
-
|
3
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/add')
|
4
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/remove')
|
5
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/validate_error')
|
6
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/qualify_error')
|
7
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/new_attr')
|
8
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/change_attr')
|
9
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/new_text')
|
10
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/change_text')
|
11
|
-
require File.expand_path(File.dirname(__FILE__) + '/history/undo')
|
12
|
-
require File.expand_path(File.dirname(__FILE__) + '/../doc')
|
13
|
-
require 'forwardable'
|
14
|
-
|
15
|
-
module Duxml
|
16
|
-
# monitors XML Elements for changes and GrammarClass for errors, recording them and saving to Meta file
|
17
|
-
module History
|
18
|
-
include Duxml
|
19
|
-
include Reportable
|
20
|
-
end
|
21
|
-
|
22
|
-
# as an object, HistoryClass holds events latest first, earliest last
|
23
|
-
# it also has delegators that allow the use of Array-style notation e.g. '[]' and #each to search the history.
|
24
|
-
class HistoryClass
|
25
|
-
include History
|
26
|
-
extend Forwardable
|
27
|
-
|
28
|
-
def_delegators :@nodes, :[], :each
|
29
|
-
|
30
|
-
# @param strict_or_false [Boolean] by default strict i.e. true so that if this History detects an error it will raise an Exception; otherwise not
|
31
|
-
def initialize(strict_or_false = true)
|
32
|
-
@nodes = []
|
33
|
-
@strict = strict_or_false
|
34
|
-
end
|
35
|
-
|
36
|
-
attr_reader :nodes
|
37
|
-
alias_method :events, :nodes
|
38
|
-
end
|
39
|
-
|
40
|
-
module History
|
41
|
-
# used when creating a new metadata file for a static XML file
|
42
|
-
#
|
43
|
-
# @return [Doc] returns self as XML document
|
44
|
-
def xml
|
45
|
-
h = Element.new('history')
|
46
|
-
events.each do |event| h << event.xml end
|
47
|
-
h
|
48
|
-
end
|
49
|
-
|
50
|
-
# @return [Boolean] toggles (true by default) whether History will raise exception or tolerate qualify errors
|
51
|
-
def strict?(strict_or_false=nil)
|
52
|
-
@strict = strict_or_false.nil? ? @strict : strict_or_false
|
53
|
-
end
|
54
|
-
|
55
|
-
# @return [ChangeClass, ErrorClass] the latest event
|
56
|
-
def latest
|
57
|
-
events[0]
|
58
|
-
end
|
59
|
-
|
60
|
-
# @return [GrammarClass] grammar that is observing this history's events
|
61
|
-
def grammar
|
62
|
-
@observer_peers.first.first if @observer_peers and @observer_peers.any? and @observer_peers.first.any?
|
63
|
-
end
|
64
|
-
|
65
|
-
# @return [String] shortened self description for debugging
|
66
|
-
def inspect
|
67
|
-
"#<#{self.class.to_s} #{object_id}: @events=#{nodes.size}>"
|
68
|
-
end
|
69
|
-
|
70
|
-
# @return [String] returns entire history, calling #description on each event in chronological order
|
71
|
-
def description
|
72
|
-
"history follows: \n" +
|
73
|
-
events.reverse.collect do |change_or_error|
|
74
|
-
change_or_error.description
|
75
|
-
end.join("\n")
|
76
|
-
end
|
77
|
-
|
78
|
-
# @param type [Symbol] category i.e. class symbol of changes/errors reported
|
79
|
-
# @param *args [*several_variants] information needed to accurately log the event; varies by change/error class
|
80
|
-
def update(type, *args)
|
81
|
-
change_class = Duxml::const_get "#{type.to_s}Class".to_sym
|
82
|
-
change_comp = change_class.new *args
|
83
|
-
@nodes.unshift change_comp
|
84
|
-
changed
|
85
|
-
notify_observers(change_comp) unless change_comp.respond_to?(:error?)
|
86
|
-
raise(Exception, change_comp.description) if strict? && type == :QualifyError
|
87
|
-
end
|
88
|
-
end # module History
|
1
|
+
# Copyright (c) 2016 Freescale Semiconductor Inc.
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/add')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/remove')
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/validate_error')
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/qualify_error')
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/new_attr')
|
8
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/change_attr')
|
9
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/new_text')
|
10
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/change_text')
|
11
|
+
require File.expand_path(File.dirname(__FILE__) + '/history/undo')
|
12
|
+
require File.expand_path(File.dirname(__FILE__) + '/../doc')
|
13
|
+
require 'forwardable'
|
14
|
+
|
15
|
+
module Duxml
|
16
|
+
# monitors XML Elements for changes and GrammarClass for errors, recording them and saving to Meta file
|
17
|
+
module History
|
18
|
+
include Duxml
|
19
|
+
include Reportable
|
20
|
+
end
|
21
|
+
|
22
|
+
# as an object, HistoryClass holds events latest first, earliest last
|
23
|
+
# it also has delegators that allow the use of Array-style notation e.g. '[]' and #each to search the history.
|
24
|
+
class HistoryClass
|
25
|
+
include History
|
26
|
+
extend Forwardable
|
27
|
+
|
28
|
+
def_delegators :@nodes, :[], :each
|
29
|
+
|
30
|
+
# @param strict_or_false [Boolean] by default strict i.e. true so that if this History detects an error it will raise an Exception; otherwise not
|
31
|
+
def initialize(strict_or_false = true)
|
32
|
+
@nodes = []
|
33
|
+
@strict = strict_or_false
|
34
|
+
end
|
35
|
+
|
36
|
+
attr_reader :nodes
|
37
|
+
alias_method :events, :nodes
|
38
|
+
end
|
39
|
+
|
40
|
+
module History
|
41
|
+
# used when creating a new metadata file for a static XML file
|
42
|
+
#
|
43
|
+
# @return [Doc] returns self as XML document
|
44
|
+
def xml
|
45
|
+
h = Element.new('history')
|
46
|
+
events.each do |event| h << event.xml end
|
47
|
+
h
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Boolean] toggles (true by default) whether History will raise exception or tolerate qualify errors
|
51
|
+
def strict?(strict_or_false=nil)
|
52
|
+
@strict = strict_or_false.nil? ? @strict : strict_or_false
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [ChangeClass, ErrorClass] the latest event
|
56
|
+
def latest
|
57
|
+
events[0]
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [GrammarClass] grammar that is observing this history's events
|
61
|
+
def grammar
|
62
|
+
@observer_peers.first.first if @observer_peers and @observer_peers.any? and @observer_peers.first.any?
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [String] shortened self description for debugging
|
66
|
+
def inspect
|
67
|
+
"#<#{self.class.to_s} #{object_id}: @events=#{nodes.size}>"
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [String] returns entire history, calling #description on each event in chronological order
|
71
|
+
def description
|
72
|
+
"history follows: \n" +
|
73
|
+
events.reverse.collect do |change_or_error|
|
74
|
+
change_or_error.description
|
75
|
+
end.join("\n")
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param type [Symbol] category i.e. class symbol of changes/errors reported
|
79
|
+
# @param *args [*several_variants] information needed to accurately log the event; varies by change/error class
|
80
|
+
def update(type, *args)
|
81
|
+
change_class = Duxml::const_get "#{type.to_s}Class".to_sym
|
82
|
+
change_comp = change_class.new *args
|
83
|
+
@nodes.unshift change_comp
|
84
|
+
changed
|
85
|
+
notify_observers(change_comp) unless change_comp.respond_to?(:error?)
|
86
|
+
raise(Exception, change_comp.description) if strict? && type == :QualifyError
|
87
|
+
end
|
88
|
+
end # module History
|
89
89
|
end # module Duxml
|