roundtrip_xml 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/roundtrip_xml/base_cleanroom.rb +13 -6
- data/lib/roundtrip_xml/dsl_runtime.rb +35 -15
- data/lib/roundtrip_xml/extractor.rb +97 -56
- data/lib/roundtrip_xml/extractor2.rb +88 -0
- data/lib/roundtrip_xml/plain_accessors.rb +5 -1
- data/lib/roundtrip_xml/root_cleanroom.rb +2 -1
- data/lib/roundtrip_xml/sexp_dsl_builder.rb +21 -43
- data/lib/roundtrip_xml/utils.rb +26 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8be8e12666739bebd81cc31be68c2707004172cb
|
4
|
+
data.tar.gz: 89c888102932ba9719a7b57a89ba58ca5c736c1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a95e401af921c46d3d7a36d8248a776230729a6b81630890c6496062e1d05431f916d89f9895e017f3abf0adb9db1496daf814c99ac919403468ab167d6afb71
|
7
|
+
data.tar.gz: fd001af3052e83f90617fee528178bd6065f1b43cbafbf9716fc24e6cf3eb358c5ae57f368a249dc94b968a18ffdbd338cfeb7decb9697454110379e158d4843
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'cleanroom'
|
2
|
+
require 'roundtrip_xml/utils'
|
2
3
|
# Generates cleanroom methods corresponding to all the xml_accessors and plain_accessors of @el
|
3
4
|
class BaseCleanroom
|
4
5
|
include Cleanroom
|
@@ -6,7 +7,9 @@ class BaseCleanroom
|
|
6
7
|
@el
|
7
8
|
end
|
8
9
|
|
9
|
-
|
10
|
+
attr_reader :show_undefined_params
|
11
|
+
def initialize(el, runtime, show_undefined_params = false)
|
12
|
+
@show_undefined_params = show_undefined_params
|
10
13
|
@runtime = runtime
|
11
14
|
@el = el
|
12
15
|
get_el.attributes.each do |attr|
|
@@ -39,8 +42,13 @@ class BaseCleanroom
|
|
39
42
|
def expose_attr_accessors()
|
40
43
|
get_el.class.plain_accessors.each do |a|
|
41
44
|
create_method(a) do |value = nil|
|
42
|
-
|
43
|
-
|
45
|
+
if value
|
46
|
+
get_el.send("#{a}=".to_sym, value) if value
|
47
|
+
elsif !value && show_undefined_params
|
48
|
+
return get_el.send(a) || Utils::UndefinedParam.new(a)
|
49
|
+
else
|
50
|
+
return get_el.send(a)
|
51
|
+
end
|
44
52
|
end
|
45
53
|
self.class.send(:expose, a)
|
46
54
|
end
|
@@ -51,10 +59,9 @@ class BaseCleanroom
|
|
51
59
|
|
52
60
|
def expand(clazz, &block)
|
53
61
|
plain_accessors = @el.class.plain_accessors
|
54
|
-
hash = {}
|
55
62
|
@value_holder ||= {}
|
56
|
-
hash = plain_accessors.inject({}) {|h, a| h[a] = @el.send(a); h}
|
57
|
-
child = @runtime.create_cleanroom(clazz)
|
63
|
+
hash = plain_accessors.inject({}) {|h, a| h[a] = @el.send(a) || Utils::UndefinedParam.new(a); h}
|
64
|
+
child = @runtime.create_cleanroom(clazz, @show_undefined_params)
|
58
65
|
child.inherit_properties hash.merge(@value_holder)
|
59
66
|
|
60
67
|
child.evaluate &block
|
@@ -15,34 +15,54 @@ class DslRuntime
|
|
15
15
|
@classes = {}
|
16
16
|
@root_classes = Set.new
|
17
17
|
end
|
18
|
-
def populate(files
|
19
|
-
files.map {|f| populate_from_file f
|
18
|
+
def populate(files)
|
19
|
+
files.map {|f| populate_from_file f }
|
20
20
|
end
|
21
21
|
|
22
|
-
def populate_from_file (file
|
23
|
-
populate_raw File.read(file)
|
22
|
+
def populate_from_file (file)
|
23
|
+
populate_raw File.read(file)
|
24
24
|
|
25
25
|
end
|
26
26
|
|
27
27
|
##
|
28
28
|
# @param root_method Symbol The method of the ROXML object to access its children
|
29
|
-
def populate_raw (raw
|
29
|
+
def populate_raw (raw)
|
30
30
|
builder = RoxmlBuilder.new (Nokogiri::XML(raw).root), @classes
|
31
31
|
new_classes = builder.build_classes
|
32
32
|
@root_classes << builder.root_class_name
|
33
33
|
@classes.merge! new_classes
|
34
|
-
|
35
|
-
roxml_root = fetch(builder.root_class_name).from_xml raw
|
34
|
+
end
|
36
35
|
|
37
|
-
|
36
|
+
# @param block Proc This proc is passed each health rule and must return a string value which specifies the partition for it
|
37
|
+
def write_dsl(xml, root_class_name, root_method, helpers = '', &block)
|
38
|
+
roxml_root = fetch(root_class_name).from_xml xml
|
38
39
|
|
39
|
-
|
40
|
-
subclasses = extractor.subclasses
|
41
|
-
roxml_root.send("#{root_method}=", new_objs)
|
42
|
-
builder = SexpDslBuilder.new [roxml_root], subclasses, self
|
40
|
+
extractor = Extractor.new roxml_root.send(root_method), self, root_class_name, helpers
|
43
41
|
|
44
|
-
|
42
|
+
new_objs = extractor.convert_roxml_objs
|
43
|
+
if block_given?
|
44
|
+
partitions = {}
|
45
|
+
new_objs.each do |obj|
|
46
|
+
partition = yield obj
|
47
|
+
partitions[partition] ||= []
|
48
|
+
partitions[partition] << obj
|
49
|
+
end
|
50
|
+
partitions
|
51
|
+
partitions.inject({}) do |out, (partition, objs)|
|
52
|
+
out[partition] = write_dsl_helper roxml_root, root_method, objs
|
53
|
+
out
|
54
|
+
end
|
55
|
+
else
|
56
|
+
write_dsl_helper roxml_root, root_method, new_objs
|
45
57
|
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def write_dsl_helper(root, root_method, objs)
|
62
|
+
root.send("#{root_method}=", objs)
|
63
|
+
builder = SexpDslBuilder.new root, self
|
64
|
+
|
65
|
+
builder.write_full_dsl root_method
|
46
66
|
end
|
47
67
|
|
48
68
|
def fetch(class_name)
|
@@ -73,8 +93,8 @@ class DslRuntime
|
|
73
93
|
BaseCleanroom.new(fetch(root_class).new, self)
|
74
94
|
end
|
75
95
|
|
76
|
-
def create_cleanroom(root_class)
|
77
|
-
BaseCleanroom.new(root_class.new, self)
|
96
|
+
def create_cleanroom(root_class, show_undefined_params = false)
|
97
|
+
BaseCleanroom.new(root_class.new, self, show_undefined_params)
|
78
98
|
end
|
79
99
|
|
80
100
|
def marshal_dump
|
@@ -8,80 +8,121 @@ require 'multiset'
|
|
8
8
|
require 'roundtrip_xml/roxml_subclass_helpers.rb'
|
9
9
|
|
10
10
|
class Extractor
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(roxml_objs, runtime)
|
11
|
+
|
12
|
+
def initialize(roxml_objs, runtime, root_class, definitions = nil, &block)
|
14
13
|
@roxml_objs = roxml_objs
|
15
|
-
@hashes = @roxml_objs.map { |obj| obj.to_hash }
|
16
14
|
@runtime = runtime
|
17
|
-
@
|
18
|
-
|
15
|
+
@root_class = root_class
|
16
|
+
if block_given?
|
17
|
+
@definitions = eval_definitions root_class, &block
|
18
|
+
else
|
19
|
+
@definitions = eval_definitions root_class, definitions
|
20
|
+
end
|
19
21
|
end
|
20
|
-
def list_diffs
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
def eval_definitions(root_class, str = nil, &block)
|
24
|
+
old_names = @runtime.instance_variable_get(:@classes).keys
|
25
|
+
if block_given?
|
26
|
+
@runtime.evaluate_raw '', root_class, &block
|
27
|
+
else
|
28
|
+
@runtime.evaluate_raw str, root_class
|
29
|
+
end
|
30
|
+
new_names = @runtime.instance_variable_get(:@classes).keys
|
31
|
+
def_names = new_names - old_names
|
32
|
+
def_names.inject({}) do |out, name|
|
33
|
+
clazz = @runtime.fetch(name)
|
34
|
+
parent = get_root_class clazz
|
35
|
+
obj = clazz.new
|
36
|
+
cleanroom = @runtime.create_cleanroom clazz, true
|
37
|
+
cleanroom.get_el.process.each { |p| cleanroom.evaluate &p }
|
38
|
+
out[parent] ||= []
|
39
|
+
out[parent] << cleanroom.get_el
|
40
|
+
out
|
41
|
+
end
|
26
42
|
end
|
27
43
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
compared[hash_2].add hash_1
|
37
|
-
|
38
|
-
diffs = HashDiff.diff(hash_1, hash_2).map do |diff|
|
39
|
-
diff[1].match(/(\w+)\.?/)[1]
|
40
|
-
end
|
44
|
+
def get_root_class(clazz)
|
45
|
+
super_clazz = @runtime.fetch clazz.superclass.class_name
|
46
|
+
if super_clazz.subclass?
|
47
|
+
get_root_class super_clazz
|
48
|
+
else
|
49
|
+
super_clazz.class_name
|
50
|
+
end
|
51
|
+
end
|
41
52
|
|
42
|
-
|
43
|
-
|
53
|
+
def diff_definition(defin, obj)
|
54
|
+
def_hash = defin.to_hash
|
55
|
+
obj_hash = obj.to_hash
|
56
|
+
[def_hash, obj_hash].each do |h|
|
57
|
+
h.delete '__class'
|
44
58
|
end
|
45
|
-
|
46
|
-
|
47
|
-
hash[key] = @hashes[0][key]
|
48
|
-
hash
|
59
|
+
diffs = HashDiff.diff(obj_hash, def_hash).map do |diff|
|
60
|
+
ROXMLDiff.new diff[1], from_hash(diff[2]), diff[3]
|
49
61
|
end
|
50
|
-
|
62
|
+
|
63
|
+
diffs
|
51
64
|
end
|
52
65
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
include RoxmlSubclassHelpers
|
58
|
-
end
|
59
|
-
clazz.defaults = keys
|
60
|
-
@runtime.add_class name, clazz
|
61
|
-
@subclasses << clazz
|
62
|
-
name
|
66
|
+
def from_hash(hash)
|
67
|
+
return hash unless hash.is_a? Hash
|
68
|
+
@runtime.fetch(hash['__class']).from_hash @runtime, hash
|
69
|
+
|
63
70
|
end
|
64
71
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
old_accessor = new_accessor.to_s.gsub(VAR_SUFIX, '').to_sym
|
70
|
-
new.send "#{new_accessor}=", obj.send(old_accessor)
|
72
|
+
def convert_roxml_objs
|
73
|
+
def_names = @definitions.keys
|
74
|
+
@roxml_objs.map do |obj|
|
75
|
+
convert_roxml_obj obj
|
71
76
|
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def convert_roxml_obj (obj)
|
80
|
+
name = obj.class.class_name
|
81
|
+
defs = @definitions[name]
|
82
|
+
|
83
|
+
defs.each do |defin|
|
84
|
+
diffs = diff_definition(defin, obj)
|
85
|
+
if diffs.all? {|diff| diff.template_val.is_a?(Utils::UndefinedParam) || diff.template_val == nil }
|
86
|
+
new_obj = defin.class.new
|
87
|
+
param_values = diffs.inject({}) do |values, diff|
|
88
|
+
name = diff.template_val ? diff.template_val.name : diff.key
|
89
|
+
values[name] = diff.obj_val
|
90
|
+
values
|
91
|
+
end
|
92
|
+
set_attributes new_obj, param_values
|
93
|
+
# return convert_roxml_obj new_obj
|
94
|
+
obj = new_obj
|
95
|
+
end
|
96
|
+
end if defs
|
72
97
|
|
73
|
-
|
74
|
-
|
98
|
+
obj.class.roxml_attrs.each do |a|
|
99
|
+
if a.array?
|
100
|
+
elements = obj.send(a.accessor).map {|el| convert_roxml_obj el}
|
101
|
+
obj.send a.setter.to_sym, elements
|
102
|
+
elsif a.sought_type.class == Class
|
103
|
+
current_value = obj.send(a.accessor)
|
104
|
+
obj.send a.setter.to_sym, convert_roxml_obj(current_value) if current_value
|
105
|
+
end
|
75
106
|
end
|
76
|
-
|
107
|
+
obj
|
77
108
|
end
|
78
109
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
convert_roxml roxml, diff_keys, name
|
110
|
+
def set_attributes(obj, params)
|
111
|
+
params.each do |param, val|
|
112
|
+
methods = param.to_s.split '.'
|
113
|
+
# set_deep_attribute obj, methods, val
|
114
|
+
obj.send "#{param}=", val
|
85
115
|
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
class ROXMLDiff
|
122
|
+
attr_reader :key, :obj_val, :template_val
|
123
|
+
def initialize(key, obj_val, template_val)
|
124
|
+
@key = key.to_sym
|
125
|
+
@obj_val = obj_val
|
126
|
+
@template_val = template_val
|
86
127
|
end
|
87
128
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'roxml'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'roundtrip_xml/utils'
|
4
|
+
require 'hashdiff'
|
5
|
+
require 'set'
|
6
|
+
require 'roundtrip_xml/utils'
|
7
|
+
require 'multiset'
|
8
|
+
require 'roundtrip_xml/roxml_subclass_helpers.rb'
|
9
|
+
|
10
|
+
# extracts duplicate attributes from ROXML objects
|
11
|
+
class Extractor2
|
12
|
+
include Utils
|
13
|
+
attr_reader :subclasses
|
14
|
+
def initialize(roxml_objs, runtime)
|
15
|
+
@roxml_objs = roxml_objs
|
16
|
+
@hashes = @roxml_objs.map { |obj| obj.to_hash }
|
17
|
+
@runtime = runtime
|
18
|
+
@subclass_names = Multiset.new
|
19
|
+
@subclasses = []
|
20
|
+
end
|
21
|
+
def list_diffs
|
22
|
+
|
23
|
+
HashDiff.best_diff(@hashes[0], @hashes[6]).sort_by do |diff|
|
24
|
+
m = diff[1].match(/\./)
|
25
|
+
m ? m.size : 0
|
26
|
+
end.map {|diff| diff[1]}
|
27
|
+
end
|
28
|
+
|
29
|
+
def similar_fields
|
30
|
+
keys = Set.new @hashes[0].keys
|
31
|
+
diff_keys = Set.new
|
32
|
+
compared = {}
|
33
|
+
@hashes.each do |hash_1|
|
34
|
+
@hashes.each do |hash_2|
|
35
|
+
compared[hash_2] ||= Set.new
|
36
|
+
next if hash_1 == hash_2 || compared[hash_1].include?(hash_2)
|
37
|
+
compared[hash_2].add hash_1
|
38
|
+
|
39
|
+
diffs = HashDiff.diff(hash_1, hash_2).map do |diff|
|
40
|
+
diff[1].match(/(\w+)\.?/)[1]
|
41
|
+
end
|
42
|
+
|
43
|
+
diff_keys.merge diffs
|
44
|
+
end
|
45
|
+
end
|
46
|
+
keys = keys - diff_keys
|
47
|
+
key_hash = keys.inject({}) do |hash, key|
|
48
|
+
hash[key] = @hashes[0][key]
|
49
|
+
hash
|
50
|
+
end
|
51
|
+
[key_hash, diff_keys]
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_romxl_class(keys, parent)
|
55
|
+
@subclass_names << parent
|
56
|
+
name = "#{parent.to_s}#{@subclass_names.count(parent)}"
|
57
|
+
clazz = new_roxml_class name, @runtime.fetch(parent) do
|
58
|
+
include RoxmlSubclassHelpers
|
59
|
+
end
|
60
|
+
clazz.defaults = keys
|
61
|
+
@runtime.add_class name, clazz
|
62
|
+
@subclasses << clazz
|
63
|
+
name
|
64
|
+
end
|
65
|
+
|
66
|
+
def convert_roxml(obj, keys, class_name)
|
67
|
+
parent = @runtime.fetch(class_name)
|
68
|
+
new = parent.new
|
69
|
+
parent.plain_accessors.each do |new_accessor|
|
70
|
+
old_accessor = new_accessor.to_s.gsub(VAR_SUFIX, '').to_sym
|
71
|
+
new.send "#{new_accessor}=", obj.send(old_accessor)
|
72
|
+
end
|
73
|
+
|
74
|
+
keys.each do |accessor|
|
75
|
+
new.send "#{accessor}=", obj.send(accessor)
|
76
|
+
end
|
77
|
+
new
|
78
|
+
end
|
79
|
+
|
80
|
+
def convert_roxml_objs
|
81
|
+
fields, diff_keys = similar_fields
|
82
|
+
parent_name = @roxml_objs[0].class.class_name
|
83
|
+
name = create_romxl_class fields, parent_name
|
84
|
+
@roxml_objs.map do |roxml|
|
85
|
+
convert_roxml roxml, diff_keys, name
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'roundtrip_xml/utils'
|
1
2
|
module PlainAccessors
|
2
3
|
def self.included(base)
|
3
4
|
base.extend ClassMethods
|
@@ -9,7 +10,10 @@ module PlainAccessors
|
|
9
10
|
@plain_accessors[name] = default
|
10
11
|
attr_writer name
|
11
12
|
define_method(name) do
|
12
|
-
instance_variable_get "@#{name}"
|
13
|
+
val = instance_variable_get "@#{name}"
|
14
|
+
val
|
15
|
+
# @plain_accessors is actually nil here
|
16
|
+
# val.nil? ? @plain_accessors[name] : val
|
13
17
|
end
|
14
18
|
end
|
15
19
|
|
@@ -10,6 +10,7 @@ class RootCleanroom < BaseCleanroom
|
|
10
10
|
# simply using @@params is referring to `AContainer`
|
11
11
|
# hash = self.class_variable_defined?(:@@block) ? self.class_variable_get(:@@block) : {}
|
12
12
|
# hash[name] = block
|
13
|
+
self.instance_variable_set :@is_subclass, true
|
13
14
|
self.instance_variable_set(:@block, block)
|
14
15
|
params.each do |param|
|
15
16
|
plain_accessor param
|
@@ -34,8 +35,8 @@ class RootCleanroom < BaseCleanroom
|
|
34
35
|
else
|
35
36
|
[proc]
|
36
37
|
end
|
37
|
-
|
38
38
|
end
|
39
|
+
|
39
40
|
end
|
40
41
|
@runtime.add_class name, new_class
|
41
42
|
end
|
@@ -30,48 +30,36 @@ EOF
|
|
30
30
|
s
|
31
31
|
end
|
32
32
|
|
33
|
-
attr_accessor :roxml_objs, :
|
34
|
-
def initialize(
|
35
|
-
|
36
|
-
self.subclasses = subclasses
|
33
|
+
attr_accessor :roxml_objs, :runtime
|
34
|
+
def initialize(roxml_obj, runtime)
|
35
|
+
@roxml_obj = roxml_obj
|
37
36
|
self.runtime = runtime
|
38
37
|
end
|
39
38
|
|
40
|
-
def write_def_classes
|
41
|
-
arr = []
|
42
|
-
subclasses.each do |clazz|
|
43
|
-
defaults = clazz.defaults.map do |accessor, default|
|
44
|
-
[:call, nil, accessor, [:str, default]]
|
45
|
-
end
|
46
|
-
arr = [:iter,
|
47
|
-
[:call, nil, :define,
|
48
|
-
[:lit, clazz.class_name],
|
49
|
-
[:lit, clazz.superclass.class_name]
|
50
|
-
], 0, [:block, *defaults]]
|
51
|
-
end
|
52
|
-
|
53
|
-
sexp = Sexp.from_array arr
|
54
|
-
processor = Ruby2Ruby.new
|
55
|
-
processor.process(sexp)
|
56
|
-
end
|
57
|
-
|
58
39
|
def create_sexp_for_roxml_obj(obj, root_method = nil)
|
59
|
-
is_subclass = obj.class.
|
60
|
-
subclass_value =
|
40
|
+
is_subclass = obj.class.subclass?
|
41
|
+
subclass_value = is_subclass ? [:lit, obj.class.class_name] : nil
|
61
42
|
accessors = []
|
62
43
|
obj.attributes.each do |attr|
|
63
44
|
val = obj.send attr.accessor
|
64
|
-
|
65
|
-
|
66
|
-
|
45
|
+
next unless val
|
46
|
+
# if !val || (is_subclass && obj.class.defaults.keys.include?(attr.accessor))
|
47
|
+
# next
|
48
|
+
# end
|
67
49
|
if attr.sought_type.class == Symbol
|
68
|
-
accessors << [:call, nil, attr.accessor, [:str, val
|
50
|
+
accessors << [:call, nil, attr.accessor, [:str, val]]
|
69
51
|
elsif val.class == Array
|
70
52
|
val.each { |v| accessors << create_sexp_for_roxml_obj(v, attr.accessor) }
|
71
53
|
else
|
72
54
|
accessors << create_sexp_for_roxml_obj(val, attr.accessor) if val
|
73
55
|
end
|
74
56
|
end.compact
|
57
|
+
# plain accessors
|
58
|
+
obj.class.plain_accessors.each do |a|
|
59
|
+
val = obj.send a
|
60
|
+
next unless val
|
61
|
+
accessors << [:call, nil, a, [:str, val]]
|
62
|
+
end
|
75
63
|
root_call = [:call, nil, root_method]
|
76
64
|
root_call << subclass_value if subclass_value
|
77
65
|
if root_method
|
@@ -83,28 +71,18 @@ EOF
|
|
83
71
|
[:block,
|
84
72
|
*accessors]
|
85
73
|
end
|
86
|
-
|
87
|
-
|
88
74
|
end
|
89
75
|
|
90
|
-
def write_roxml_obj(obj
|
91
|
-
s = create_sexp_for_roxml_obj obj
|
76
|
+
def write_roxml_obj(obj)
|
77
|
+
s = create_sexp_for_roxml_obj obj
|
92
78
|
|
93
79
|
sexp = Sexp.from_array s
|
94
80
|
processor = Ruby2Ruby.new
|
95
|
-
processor.process(sexp).gsub
|
96
|
-
end
|
97
|
-
|
98
|
-
def write_roxml_objs(root_method = nil)
|
99
|
-
roxml_objs.inject('') do |out, obj|
|
100
|
-
out += write_roxml_obj obj, root_method
|
101
|
-
out += "\n\n"
|
102
|
-
out
|
103
|
-
end
|
81
|
+
processor.process(sexp).gsub("\"", "'").gsub(/[\(\)]/, ' ')
|
104
82
|
end
|
105
83
|
|
106
|
-
def write_full_dsl()
|
107
|
-
|
84
|
+
def write_full_dsl(root_method)
|
85
|
+
write_roxml_obj @roxml_obj
|
108
86
|
end
|
109
87
|
|
110
88
|
end
|
data/lib/roundtrip_xml/utils.rb
CHANGED
@@ -7,6 +7,13 @@ def name_to_sym_helper(name, lower_case = false)
|
|
7
7
|
new_name.to_sym
|
8
8
|
end
|
9
9
|
module Utils
|
10
|
+
# UNDEFINED_PARAM = 'UNDEFINED_PARAM_VALUE'
|
11
|
+
class UndefinedParam
|
12
|
+
attr_reader :name
|
13
|
+
def initialize(name)
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
end
|
10
17
|
|
11
18
|
VAR_SUFIX = '_v'.freeze
|
12
19
|
def self.included(base)
|
@@ -20,12 +27,17 @@ module Utils
|
|
20
27
|
include PlainAccessors
|
21
28
|
xml_convention :dasherize
|
22
29
|
xml_name name
|
30
|
+
|
31
|
+
# by default a ROXML class isn't a sub class
|
32
|
+
def self.subclass?
|
33
|
+
@is_subclass || false
|
34
|
+
end
|
23
35
|
def attributes
|
24
36
|
self.class.roxml_attrs
|
25
37
|
end
|
26
38
|
|
27
39
|
def self.class_name
|
28
|
-
|
40
|
+
self.tag_name.is_a?(Symbol) ? self.tag_name : name_to_sym_helper(self.tag_name)
|
29
41
|
end
|
30
42
|
|
31
43
|
def to_hash
|
@@ -34,9 +46,22 @@ module Utils
|
|
34
46
|
value = value.to_hash if value.respond_to? :to_hash
|
35
47
|
|
36
48
|
hash[a.accessor] = value
|
49
|
+
hash['__class'] = self.class.class_name
|
37
50
|
hash
|
38
51
|
end
|
39
52
|
end
|
53
|
+
|
54
|
+
def self.from_hash(runtime, hash)
|
55
|
+
hash.delete '__class'
|
56
|
+
obj = self.new
|
57
|
+
hash.each do |k, val|
|
58
|
+
if val.is_a? Hash
|
59
|
+
val = runtime.fetch(val['__class']).from_hash(runtime, val)
|
60
|
+
end
|
61
|
+
obj.send "#{k}=", val
|
62
|
+
end
|
63
|
+
obj
|
64
|
+
end
|
40
65
|
def self.unique_parent_accessors
|
41
66
|
plain = Set.new(plain_accessors.map {|accessor| accessor.to_s.gsub(VAR_SUFIX, '').to_sym})
|
42
67
|
parent_accessors = Set.new(roxml_attrs.map { |attr| attr.accessor })
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roundtrip_xml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Usick
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- lib/roundtrip_xml/dsl_builder.rb
|
149
149
|
- lib/roundtrip_xml/dsl_runtime.rb
|
150
150
|
- lib/roundtrip_xml/extractor.rb
|
151
|
+
- lib/roundtrip_xml/extractor2.rb
|
151
152
|
- lib/roundtrip_xml/plain_accessors.rb
|
152
153
|
- lib/roundtrip_xml/root_cleanroom.rb
|
153
154
|
- lib/roundtrip_xml/roxml_builder.rb
|