shale 0.6.0 → 0.8.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/CHANGELOG.md +27 -0
- data/LICENSE.txt +1 -1
- data/README.md +222 -30
- data/lib/shale/adapter/json.rb +3 -3
- data/lib/shale/adapter/nokogiri.rb +6 -5
- data/lib/shale/adapter/ox.rb +5 -4
- data/lib/shale/adapter/rexml/document.rb +1 -1
- data/lib/shale/adapter/rexml.rb +5 -4
- data/lib/shale/error.rb +8 -3
- data/lib/shale/mapper.rb +5 -1
- data/lib/shale/mapping/descriptor/dict.rb +21 -1
- data/lib/shale/mapping/descriptor/xml.rb +20 -2
- data/lib/shale/mapping/dict.rb +14 -40
- data/lib/shale/mapping/dict_base.rb +73 -0
- data/lib/shale/mapping/dict_group.rb +41 -0
- data/lib/shale/mapping/group/dict.rb +55 -0
- data/lib/shale/mapping/group/dict_grouping.rb +41 -0
- data/lib/shale/mapping/group/xml.rb +43 -0
- data/lib/shale/mapping/group/xml_grouping.rb +27 -0
- data/lib/shale/mapping/xml.rb +53 -154
- data/lib/shale/mapping/xml_base.rb +227 -0
- data/lib/shale/mapping/xml_group.rb +70 -0
- data/lib/shale/schema/json_generator.rb +1 -3
- data/lib/shale/schema/xml_generator/import.rb +2 -2
- data/lib/shale/schema/xml_generator.rb +4 -6
- data/lib/shale/type/complex.rb +469 -84
- data/lib/shale/type/date.rb +2 -2
- data/lib/shale/type/time.rb +2 -2
- data/lib/shale/type/value.rb +10 -10
- data/lib/shale/version.rb +1 -1
- data/shale.gemspec +1 -1
- metadata +11 -3
data/lib/shale/mapping/dict.rb
CHANGED
@@ -1,65 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
3
|
+
require_relative 'dict_base'
|
4
|
+
require_relative 'dict_group'
|
5
5
|
|
6
6
|
module Shale
|
7
7
|
module Mapping
|
8
8
|
# Mapping for dictionary serialization formats (Hash/JSON/YAML)
|
9
9
|
#
|
10
10
|
# @api private
|
11
|
-
class Dict
|
12
|
-
# Return keys mapping hash
|
13
|
-
#
|
14
|
-
# @return [Hash]
|
15
|
-
#
|
16
|
-
# @api private
|
17
|
-
attr_reader :keys
|
18
|
-
|
19
|
-
# Initialize instance
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
def initialize
|
23
|
-
super
|
24
|
-
@keys = {}
|
25
|
-
@finalized = false
|
26
|
-
end
|
27
|
-
|
11
|
+
class Dict < DictBase
|
28
12
|
# Map key to attribute
|
29
13
|
#
|
30
14
|
# @param [String] key Document's key
|
31
15
|
# @param [Symbol, nil] to Object's attribute
|
32
16
|
# @param [Hash, nil] using
|
17
|
+
# @param [true, false] render_nil
|
33
18
|
#
|
34
19
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
35
20
|
#
|
36
21
|
# @api private
|
37
|
-
def map(key, to: nil, using: nil)
|
38
|
-
|
39
|
-
@keys[key] = Descriptor::Dict.new(name: key, attribute: to, methods: using)
|
22
|
+
def map(key, to: nil, using: nil, render_nil: false)
|
23
|
+
super(key, to: to, using: using, render_nil: render_nil)
|
40
24
|
end
|
41
25
|
|
42
|
-
#
|
26
|
+
# Map group of keys to mapping methods
|
43
27
|
#
|
44
|
-
# @
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
# Query the "finalized" instance variable
|
50
|
-
#
|
51
|
-
# @return [truem false]
|
28
|
+
# @param [Symbol] from
|
29
|
+
# @param [Symbol] to
|
30
|
+
# @param [Proc] block
|
52
31
|
#
|
53
32
|
# @api private
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# @api private
|
59
|
-
def initialize_dup(other)
|
60
|
-
@keys = other.instance_variable_get('@keys').dup
|
61
|
-
@finalized = false
|
62
|
-
super
|
33
|
+
def group(from:, to:, &block)
|
34
|
+
group = DictGroup.new(from, to)
|
35
|
+
group.instance_eval(&block)
|
36
|
+
@keys.merge!(group.keys)
|
63
37
|
end
|
64
38
|
end
|
65
39
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'descriptor/dict'
|
4
|
+
require_relative 'validator'
|
5
|
+
|
6
|
+
module Shale
|
7
|
+
module Mapping
|
8
|
+
# Base class for Mapping dictionary serialization formats (Hash/JSON/YAML)
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class DictBase
|
12
|
+
# Return keys mapping hash
|
13
|
+
#
|
14
|
+
# @return [Hash]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_reader :keys
|
18
|
+
|
19
|
+
# Initialize instance
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
def initialize
|
23
|
+
@keys = {}
|
24
|
+
@finalized = false
|
25
|
+
end
|
26
|
+
|
27
|
+
# Map key to attribute
|
28
|
+
#
|
29
|
+
# @param [String] key
|
30
|
+
# @param [Symbol, nil] to
|
31
|
+
# @param [Hash, nil] using
|
32
|
+
# @param [String, nil] group
|
33
|
+
# @param [true, false] render_nil
|
34
|
+
#
|
35
|
+
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
def map(key, to: nil, using: nil, group: nil, render_nil: false)
|
39
|
+
Validator.validate_arguments(key, to, using)
|
40
|
+
@keys[key] = Descriptor::Dict.new(
|
41
|
+
name: key,
|
42
|
+
attribute: to,
|
43
|
+
methods: using,
|
44
|
+
group: group,
|
45
|
+
render_nil: render_nil
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Set the "finalized" instance variable to true
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
def finalize!
|
53
|
+
@finalized = true
|
54
|
+
end
|
55
|
+
|
56
|
+
# Query the "finalized" instance variable
|
57
|
+
#
|
58
|
+
# @return [truem false]
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
def finalized?
|
62
|
+
@finalized
|
63
|
+
end
|
64
|
+
|
65
|
+
# @api private
|
66
|
+
def initialize_dup(other)
|
67
|
+
@keys = other.instance_variable_get('@keys').dup
|
68
|
+
@finalized = false
|
69
|
+
super
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'dict_base'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Mapping
|
7
|
+
# Group for dictionary serialization formats (Hash/JSON/YAML)
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class DictGroup < DictBase
|
11
|
+
# Return name of the group
|
12
|
+
#
|
13
|
+
# @return [String]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
attr_reader :name
|
17
|
+
|
18
|
+
# Initialize instance
|
19
|
+
#
|
20
|
+
# @param [Symbol] from
|
21
|
+
# @param [Symbol] to
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
def initialize(from, to)
|
25
|
+
super()
|
26
|
+
@from = from
|
27
|
+
@to = to
|
28
|
+
@name = "group_#{hash}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Map key to attribute
|
32
|
+
#
|
33
|
+
# @param [String] key
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
def map(key)
|
37
|
+
super(key, using: { from: @from, to: @to }, group: @name)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Mapping
|
5
|
+
module Group
|
6
|
+
# Dict group descriptor
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Dict
|
10
|
+
# Return method_from
|
11
|
+
#
|
12
|
+
# @return [Symbol]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
attr_reader :method_from
|
16
|
+
|
17
|
+
# Return method_to
|
18
|
+
#
|
19
|
+
# @return [Symbol]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
attr_reader :method_to
|
23
|
+
|
24
|
+
# Return dict hash
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
attr_reader :dict
|
30
|
+
|
31
|
+
# Initialize instance
|
32
|
+
#
|
33
|
+
# @param [Symbol] method_from
|
34
|
+
# @param [Symbol] method_to
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
def initialize(method_from, method_to)
|
38
|
+
@method_from = method_from
|
39
|
+
@method_to = method_to
|
40
|
+
@dict = {}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Add key-value pair to a group
|
44
|
+
#
|
45
|
+
# @param [String] key
|
46
|
+
# @param [any] value
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
def add(key, value)
|
50
|
+
@dict[key] = value
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'dict'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Mapping
|
7
|
+
module Group
|
8
|
+
# Class representing mapping group for JSON/YAML/TOML
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class DictGrouping
|
12
|
+
# Initialize instance
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def initialize
|
16
|
+
@groups = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
# Add a value to a group
|
20
|
+
#
|
21
|
+
# @param [Shale::Mapping::Descriptor::Dict] mapping
|
22
|
+
# @param [any] value
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
def add(mapping, value)
|
26
|
+
group = @groups[mapping.group] ||= Dict.new(mapping.method_from, mapping.method_to)
|
27
|
+
group.add(mapping.name, value)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Iterate over groups
|
31
|
+
#
|
32
|
+
# @param [Proc] block
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
def each(&block)
|
36
|
+
@groups.values.each(&block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'dict'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Mapping
|
7
|
+
module Group
|
8
|
+
# Xml group descriptor
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Xml < Dict
|
12
|
+
# Initialize instance
|
13
|
+
#
|
14
|
+
# @param [Symbol] method_from
|
15
|
+
# @param [Symbol] method_to
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
def initialize(method_from, method_to)
|
19
|
+
super(method_from, method_to)
|
20
|
+
@dict = { content: nil, attributes: {}, elements: {} }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Add key-value pair to a group
|
24
|
+
#
|
25
|
+
# @param [Symbol] kind
|
26
|
+
# @param [String] key
|
27
|
+
# @param [any] value
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
def add(kind, key, value)
|
31
|
+
case kind
|
32
|
+
when :content
|
33
|
+
@dict[:content] = value
|
34
|
+
when :attribute
|
35
|
+
@dict[:attributes][key] = value
|
36
|
+
when :element
|
37
|
+
@dict[:elements][key] = value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'dict_grouping'
|
4
|
+
require_relative 'xml'
|
5
|
+
|
6
|
+
module Shale
|
7
|
+
module Mapping
|
8
|
+
module Group
|
9
|
+
# Class representing mapping group for XML
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
class XmlGrouping < DictGrouping
|
13
|
+
# Add a value to a group
|
14
|
+
#
|
15
|
+
# @param [Shale::Mapping::Descriptor::Dict] mapping
|
16
|
+
# @param [Symbol] kind
|
17
|
+
# @param [any] value
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
def add(mapping, kind, value)
|
21
|
+
group = @groups[mapping.group] ||= Xml.new(mapping.method_from, mapping.method_to)
|
22
|
+
group.add(kind, mapping.namespaced_name, value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/shale/mapping/xml.rb
CHANGED
@@ -1,80 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative 'validator'
|
3
|
+
require_relative 'xml_base'
|
4
|
+
require_relative 'xml_group'
|
6
5
|
|
7
6
|
module Shale
|
8
7
|
module Mapping
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
# @api private
|
15
|
-
attr_reader :elements
|
16
|
-
|
17
|
-
# Return attributes mapping hash
|
18
|
-
#
|
19
|
-
# @return [Hash]
|
20
|
-
#
|
21
|
-
# @api private
|
22
|
-
attr_reader :attributes
|
23
|
-
|
24
|
-
# Return content mapping
|
25
|
-
#
|
26
|
-
# @return [Symbol]
|
27
|
-
#
|
28
|
-
# @api private
|
29
|
-
attr_reader :content
|
30
|
-
|
31
|
-
# Return default namespace
|
32
|
-
#
|
33
|
-
# @return [Shale::Mapping::Descriptor::XmlNamespace]
|
34
|
-
#
|
35
|
-
# @api private
|
36
|
-
attr_reader :default_namespace
|
37
|
-
|
38
|
-
# Return unprefixed root
|
39
|
-
#
|
40
|
-
# @return [String]
|
41
|
-
#
|
42
|
-
# @api private
|
43
|
-
def unprefixed_root
|
44
|
-
@root
|
45
|
-
end
|
46
|
-
|
47
|
-
# Return prefixed root
|
48
|
-
#
|
49
|
-
# @return [String]
|
50
|
-
#
|
51
|
-
# @api private
|
52
|
-
def prefixed_root
|
53
|
-
[default_namespace.prefix, @root].compact.join(':')
|
54
|
-
end
|
55
|
-
|
56
|
-
# Initialize instance
|
57
|
-
#
|
58
|
-
# @api private
|
59
|
-
def initialize
|
60
|
-
super
|
61
|
-
@elements = {}
|
62
|
-
@attributes = {}
|
63
|
-
@content = nil
|
64
|
-
@root = ''
|
65
|
-
@default_namespace = Descriptor::XmlNamespace.new
|
66
|
-
@finalized = false
|
67
|
-
end
|
68
|
-
|
8
|
+
# Mapping for XML serialization format
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Xml < XmlBase
|
69
12
|
# Map element to attribute
|
70
13
|
#
|
71
|
-
# @param [String] element
|
72
|
-
# @param [Symbol, nil] to
|
14
|
+
# @param [String] element
|
15
|
+
# @param [Symbol, nil] to
|
73
16
|
# @param [Hash, nil] using
|
74
17
|
# @param [String, nil] namespace
|
75
18
|
# @param [String, nil] prefix
|
76
|
-
#
|
77
|
-
# @
|
19
|
+
# @param [true, false] cdata
|
20
|
+
# @param [true, false] render_nil
|
78
21
|
#
|
79
22
|
# @api private
|
80
23
|
def map_element(
|
@@ -83,119 +26,75 @@ module Shale
|
|
83
26
|
using: nil,
|
84
27
|
namespace: :undefined,
|
85
28
|
prefix: :undefined,
|
86
|
-
cdata: false
|
29
|
+
cdata: false,
|
30
|
+
render_nil: false
|
87
31
|
)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
pfx = prefix
|
97
|
-
end
|
98
|
-
|
99
|
-
namespaced_element = [nsp, element].compact.join(':')
|
100
|
-
|
101
|
-
@elements[namespaced_element] = Descriptor::Xml.new(
|
102
|
-
name: element,
|
103
|
-
attribute: to,
|
104
|
-
methods: using,
|
105
|
-
namespace: Descriptor::XmlNamespace.new(nsp, pfx),
|
106
|
-
cdata: cdata
|
32
|
+
super(
|
33
|
+
element,
|
34
|
+
to: to,
|
35
|
+
using: using,
|
36
|
+
namespace: namespace,
|
37
|
+
prefix: prefix,
|
38
|
+
cdata: cdata,
|
39
|
+
render_nil: render_nil
|
107
40
|
)
|
108
41
|
end
|
109
42
|
|
110
43
|
# Map document's attribute to object's attribute
|
111
44
|
#
|
112
|
-
# @param [String] attribute
|
113
|
-
# @param [Symbol, nil] to
|
45
|
+
# @param [String] attribute
|
46
|
+
# @param [Symbol, nil] to
|
114
47
|
# @param [Hash, nil] using
|
115
48
|
# @param [String, nil] namespace
|
116
49
|
# @param [String, nil] prefix
|
117
|
-
#
|
118
|
-
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
50
|
+
# @param [true, false] render_nil
|
119
51
|
#
|
120
52
|
# @api private
|
121
|
-
def map_attribute(
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
53
|
+
def map_attribute(
|
54
|
+
attribute,
|
55
|
+
to: nil,
|
56
|
+
using: nil,
|
57
|
+
namespace: nil,
|
58
|
+
prefix: nil,
|
59
|
+
render_nil: false
|
60
|
+
)
|
61
|
+
super(
|
62
|
+
attribute,
|
63
|
+
to: to,
|
64
|
+
using: using,
|
65
|
+
namespace: namespace,
|
66
|
+
prefix: prefix,
|
67
|
+
render_nil: render_nil
|
133
68
|
)
|
134
69
|
end
|
135
70
|
|
136
71
|
# Map document's content to object's attribute
|
137
72
|
#
|
138
|
-
# @param [Symbol] to
|
73
|
+
# @param [Symbol] to
|
74
|
+
# @param [Hash, nil] using
|
75
|
+
# @param [true, false] cdata
|
139
76
|
#
|
140
77
|
# @api private
|
141
78
|
def map_content(to: nil, using: nil, cdata: false)
|
142
|
-
|
143
|
-
|
144
|
-
@content = Descriptor::Xml.new(
|
145
|
-
name: nil,
|
146
|
-
attribute: to,
|
147
|
-
methods: using,
|
148
|
-
namespace: nil,
|
149
|
-
cdata: cdata
|
150
|
-
)
|
79
|
+
super(to: to, using: using, cdata: cdata)
|
151
80
|
end
|
152
81
|
|
153
|
-
#
|
82
|
+
# Map group of nodes to mapping methods
|
154
83
|
#
|
155
|
-
# @param [
|
84
|
+
# @param [Symbol] from
|
85
|
+
# @param [Symbol] to
|
86
|
+
# @param [Proc] block
|
156
87
|
#
|
157
88
|
# @api private
|
158
|
-
def
|
159
|
-
|
160
|
-
end
|
89
|
+
def group(from:, to:, &block)
|
90
|
+
group = XmlGroup.new(from, to)
|
161
91
|
|
162
|
-
|
163
|
-
|
164
|
-
# @param [String] name
|
165
|
-
# @param [String] prefix
|
166
|
-
#
|
167
|
-
# @api private
|
168
|
-
def namespace(name, prefix)
|
169
|
-
@default_namespace.name = name
|
170
|
-
@default_namespace.prefix = prefix
|
171
|
-
end
|
172
|
-
|
173
|
-
# Set the "finalized" instance variable to true
|
174
|
-
#
|
175
|
-
# @api private
|
176
|
-
def finalize!
|
177
|
-
@finalized = true
|
178
|
-
end
|
179
|
-
|
180
|
-
# Query the "finalized" instance variable
|
181
|
-
#
|
182
|
-
# @return [truem false]
|
183
|
-
#
|
184
|
-
# @api private
|
185
|
-
def finalized?
|
186
|
-
@finalized
|
187
|
-
end
|
188
|
-
|
189
|
-
# @api private
|
190
|
-
def initialize_dup(other)
|
191
|
-
@elements = other.instance_variable_get('@elements').dup
|
192
|
-
@attributes = other.instance_variable_get('@attributes').dup
|
193
|
-
@content = other.instance_variable_get('@content').dup
|
194
|
-
@root = other.instance_variable_get('@root').dup
|
195
|
-
@default_namespace = other.instance_variable_get('@default_namespace').dup
|
196
|
-
@finalized = false
|
92
|
+
group.namespace(default_namespace.name, default_namespace.prefix)
|
93
|
+
group.instance_eval(&block)
|
197
94
|
|
198
|
-
|
95
|
+
@elements.merge!(group.elements)
|
96
|
+
@attributes.merge!(group.attributes)
|
97
|
+
@content = group.content if group.content
|
199
98
|
end
|
200
99
|
end
|
201
100
|
end
|