roundtrip_xml 0.1.6 → 0.2.0
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/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
|