shale 0.2.2 → 0.4.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 +33 -0
- data/README.md +366 -8
- data/exe/shaleb +123 -0
- data/lib/shale/adapter/json.rb +7 -2
- data/lib/shale/adapter/nokogiri.rb +48 -12
- data/lib/shale/adapter/ox.rb +28 -4
- data/lib/shale/adapter/rexml.rb +56 -13
- data/lib/shale/attribute.rb +7 -1
- data/lib/shale/error.rb +12 -0
- data/lib/shale/mapper.rb +17 -15
- data/lib/shale/mapping/descriptor/dict.rb +57 -0
- data/lib/shale/mapping/descriptor/xml.rb +43 -0
- data/lib/shale/mapping/descriptor/xml_namespace.rb +37 -0
- data/lib/shale/mapping/{key_value.rb → dict.rb} +8 -6
- data/lib/shale/mapping/validator.rb +51 -0
- data/lib/shale/mapping/xml.rb +86 -15
- data/lib/shale/schema/json_compiler/boolean.rb +21 -0
- data/lib/shale/schema/json_compiler/date.rb +21 -0
- data/lib/shale/schema/json_compiler/float.rb +21 -0
- data/lib/shale/schema/json_compiler/integer.rb +21 -0
- data/lib/shale/schema/json_compiler/object.rb +85 -0
- data/lib/shale/schema/json_compiler/property.rb +70 -0
- data/lib/shale/schema/json_compiler/string.rb +21 -0
- data/lib/shale/schema/json_compiler/time.rb +21 -0
- data/lib/shale/schema/json_compiler/utils.rb +52 -0
- data/lib/shale/schema/json_compiler/value.rb +13 -0
- data/lib/shale/schema/json_compiler.rb +333 -0
- data/lib/shale/schema/json_generator/base.rb +41 -0
- data/lib/shale/schema/json_generator/boolean.rb +23 -0
- data/lib/shale/schema/json_generator/collection.rb +39 -0
- data/lib/shale/schema/json_generator/date.rb +23 -0
- data/lib/shale/schema/json_generator/float.rb +23 -0
- data/lib/shale/schema/json_generator/integer.rb +23 -0
- data/lib/shale/schema/json_generator/object.rb +40 -0
- data/lib/shale/schema/json_generator/ref.rb +28 -0
- data/lib/shale/schema/json_generator/schema.rb +59 -0
- data/lib/shale/schema/json_generator/string.rb +23 -0
- data/lib/shale/schema/json_generator/time.rb +23 -0
- data/lib/shale/schema/json_generator/value.rb +23 -0
- data/lib/shale/schema/json_generator.rb +165 -0
- data/lib/shale/schema/xml_generator/attribute.rb +41 -0
- data/lib/shale/schema/xml_generator/complex_type.rb +70 -0
- data/lib/shale/schema/xml_generator/element.rb +55 -0
- data/lib/shale/schema/xml_generator/import.rb +46 -0
- data/lib/shale/schema/xml_generator/ref_attribute.rb +37 -0
- data/lib/shale/schema/xml_generator/ref_element.rb +39 -0
- data/lib/shale/schema/xml_generator/schema.rb +121 -0
- data/lib/shale/schema/xml_generator/typed_attribute.rb +46 -0
- data/lib/shale/schema/xml_generator/typed_element.rb +46 -0
- data/lib/shale/schema/xml_generator.rb +315 -0
- data/lib/shale/schema.rb +70 -0
- data/lib/shale/type/boolean.rb +2 -2
- data/lib/shale/type/composite.rb +78 -72
- data/lib/shale/type/date.rb +35 -2
- data/lib/shale/type/float.rb +2 -2
- data/lib/shale/type/integer.rb +2 -2
- data/lib/shale/type/string.rb +2 -2
- data/lib/shale/type/time.rb +35 -2
- data/lib/shale/type/{base.rb → value.rb} +18 -7
- data/lib/shale/utils.rb +18 -2
- data/lib/shale/version.rb +1 -1
- data/lib/shale.rb +10 -10
- data/shale.gemspec +6 -2
- metadata +53 -13
- data/lib/shale/mapping/base.rb +0 -32
data/lib/shale/mapping/xml.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'descriptor/xml'
|
4
|
+
require_relative 'descriptor/xml_namespace'
|
5
|
+
require_relative 'validator'
|
4
6
|
|
5
7
|
module Shale
|
6
8
|
module Mapping
|
7
|
-
class Xml
|
9
|
+
class Xml
|
8
10
|
# Return elements mapping hash
|
9
11
|
#
|
10
12
|
# @return [Hash]
|
@@ -26,6 +28,31 @@ module Shale
|
|
26
28
|
# @api private
|
27
29
|
attr_reader :content
|
28
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
|
+
|
29
56
|
# Initialize instance
|
30
57
|
#
|
31
58
|
# @api private
|
@@ -35,32 +62,65 @@ module Shale
|
|
35
62
|
@attributes = {}
|
36
63
|
@content = nil
|
37
64
|
@root = ''
|
65
|
+
@default_namespace = Descriptor::XmlNamespace.new
|
38
66
|
end
|
39
67
|
|
40
68
|
# Map element to attribute
|
41
69
|
#
|
42
70
|
# @param [String] element Document's element
|
43
|
-
# @param [Symbol] to Object's attribute
|
71
|
+
# @param [Symbol, nil] to Object's attribute
|
72
|
+
# @param [Hash, nil] using
|
73
|
+
# @param [String, nil] namespace
|
74
|
+
# @param [String, nil] prefix
|
44
75
|
#
|
45
76
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
46
77
|
#
|
47
78
|
# @api private
|
48
|
-
def map_element(element, to: nil, using: nil)
|
49
|
-
validate_arguments(element, to, using)
|
50
|
-
|
79
|
+
def map_element(element, to: nil, using: nil, namespace: :undefined, prefix: :undefined)
|
80
|
+
Validator.validate_arguments(element, to, using)
|
81
|
+
Validator.validate_namespace(element, namespace, prefix)
|
82
|
+
|
83
|
+
if namespace == :undefined && prefix == :undefined
|
84
|
+
nsp = default_namespace.name
|
85
|
+
pfx = default_namespace.prefix
|
86
|
+
else
|
87
|
+
nsp = namespace
|
88
|
+
pfx = prefix
|
89
|
+
end
|
90
|
+
|
91
|
+
namespaced_element = [nsp, element].compact.join(':')
|
92
|
+
|
93
|
+
@elements[namespaced_element] = Descriptor::Xml.new(
|
94
|
+
name: element,
|
95
|
+
attribute: to,
|
96
|
+
methods: using,
|
97
|
+
namespace: Descriptor::XmlNamespace.new(nsp, pfx)
|
98
|
+
)
|
51
99
|
end
|
52
100
|
|
53
101
|
# Map document's attribute to object's attribute
|
54
102
|
#
|
55
103
|
# @param [String] attribute Document's attribute
|
56
|
-
# @param [Symbol] to Object's attribute
|
104
|
+
# @param [Symbol, nil] to Object's attribute
|
105
|
+
# @param [Hash, nil] using
|
106
|
+
# @param [String, nil] namespace
|
107
|
+
# @param [String, nil] prefix
|
57
108
|
#
|
58
109
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
59
110
|
#
|
60
111
|
# @api private
|
61
|
-
def map_attribute(attribute, to: nil, using: nil)
|
62
|
-
validate_arguments(attribute, to, using)
|
63
|
-
|
112
|
+
def map_attribute(attribute, to: nil, using: nil, namespace: nil, prefix: nil)
|
113
|
+
Validator.validate_arguments(attribute, to, using)
|
114
|
+
Validator.validate_namespace(attribute, namespace, prefix)
|
115
|
+
|
116
|
+
namespaced_attribute = [namespace, attribute].compact.join(':')
|
117
|
+
|
118
|
+
@attributes[namespaced_attribute] = Descriptor::Xml.new(
|
119
|
+
name: attribute,
|
120
|
+
attribute: to,
|
121
|
+
methods: using,
|
122
|
+
namespace: Descriptor::XmlNamespace.new(namespace, prefix)
|
123
|
+
)
|
64
124
|
end
|
65
125
|
|
66
126
|
# Map document's content to object's attribute
|
@@ -72,15 +132,24 @@ module Shale
|
|
72
132
|
@content = to
|
73
133
|
end
|
74
134
|
|
75
|
-
#
|
135
|
+
# Set the name for root element
|
136
|
+
#
|
137
|
+
# @param [String] value root's name
|
76
138
|
#
|
77
|
-
# @
|
139
|
+
# @api private
|
140
|
+
def root(value)
|
141
|
+
@root = value
|
142
|
+
end
|
143
|
+
|
144
|
+
# Set default namespace for root element
|
78
145
|
#
|
79
|
-
# @
|
146
|
+
# @param [String] name
|
147
|
+
# @param [String] prefix
|
80
148
|
#
|
81
149
|
# @api private
|
82
|
-
def
|
83
|
-
|
150
|
+
def namespace(name, prefix)
|
151
|
+
@default_namespace.name = name
|
152
|
+
@default_namespace.prefix = prefix
|
84
153
|
end
|
85
154
|
|
86
155
|
# @api private
|
@@ -89,6 +158,8 @@ module Shale
|
|
89
158
|
@attributes = other.instance_variable_get('@attributes').dup
|
90
159
|
@content = other.instance_variable_get('@content').dup
|
91
160
|
@root = other.instance_variable_get('@root').dup
|
161
|
+
@default_namespace = other.instance_variable_get('@default_namespace').dup
|
162
|
+
|
92
163
|
super
|
93
164
|
end
|
94
165
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale Boolean type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Boolean
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::Boolean'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale Date type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Date
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::Date'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale Float type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Float
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::Float'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale Integer type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Integer
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::Integer'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'utils'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
class JSONCompiler
|
8
|
+
# Class representing Shale's comosite type
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Object
|
12
|
+
# Return id
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_reader :id
|
18
|
+
|
19
|
+
# Return properties
|
20
|
+
#
|
21
|
+
# @return [Array<Shale::Schema::JSONCompiler::Property>]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :properties
|
25
|
+
|
26
|
+
# Name setter
|
27
|
+
#
|
28
|
+
# @param [String] val
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
attr_writer :name
|
32
|
+
|
33
|
+
# Initialize object
|
34
|
+
#
|
35
|
+
# @param [String] id
|
36
|
+
# @param [String] name
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
def initialize(id, name)
|
40
|
+
@id = id
|
41
|
+
@name = name
|
42
|
+
@properties = []
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return name
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
#
|
49
|
+
# @api private
|
50
|
+
def name
|
51
|
+
Utils.classify(@name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return file name
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
#
|
58
|
+
# @api private
|
59
|
+
def file_name
|
60
|
+
Utils.snake_case(@name)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return references
|
64
|
+
#
|
65
|
+
# @return [Array<Shale::Schema::JSONCompiler::Property>]
|
66
|
+
#
|
67
|
+
# @api private
|
68
|
+
def references
|
69
|
+
@properties
|
70
|
+
.filter { |e| e.type.is_a?(self.class) && e.type != self }
|
71
|
+
.uniq { |e| e.type.id }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Add property to Object
|
75
|
+
#
|
76
|
+
# @param [Shale::Schema::JSONCompiler::Property] property
|
77
|
+
#
|
78
|
+
# @api private
|
79
|
+
def add_property(property)
|
80
|
+
@properties << property
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'utils'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
class JSONCompiler
|
8
|
+
# Class representing Shale's property
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class Property
|
12
|
+
# Return property's name
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_reader :property_name
|
18
|
+
|
19
|
+
# Return attribute's name
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :attribute_name
|
25
|
+
|
26
|
+
# Return types's name
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
attr_reader :type
|
32
|
+
|
33
|
+
# Initialize Property object
|
34
|
+
#
|
35
|
+
# @param [String] name
|
36
|
+
# @param [Shale::Schema::JsonCompiler::Type] type
|
37
|
+
# @param [true, false] collection
|
38
|
+
# @param [Object] default
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def initialize(name, type, collection, default)
|
42
|
+
@property_name = name
|
43
|
+
@attribute_name = Utils.snake_case(name)
|
44
|
+
@type = type
|
45
|
+
@collection = collection
|
46
|
+
@default = default
|
47
|
+
end
|
48
|
+
|
49
|
+
# Return whether property is a collection
|
50
|
+
#
|
51
|
+
# @return [true, false]
|
52
|
+
#
|
53
|
+
# @api private
|
54
|
+
def collection?
|
55
|
+
@collection
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return default value
|
59
|
+
#
|
60
|
+
# @return [nil, Object]
|
61
|
+
#
|
62
|
+
# @api private
|
63
|
+
def default
|
64
|
+
return if collection?
|
65
|
+
@default.is_a?(::String) ? @default.dump : @default
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale String type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class String
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::String'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Class that maps Schema type to Shale Time type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Time
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::Time'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
class JSONCompiler
|
6
|
+
# Module with utility functions
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
module Utils
|
10
|
+
# Convert string to Ruby's class naming convention
|
11
|
+
#
|
12
|
+
# @param [String] val
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# Shale::Schema::JSONCompiler.classify('foobar')
|
16
|
+
# # => 'Foobar'
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
def self.classify(str)
|
20
|
+
str = str.to_s.sub(/.*\./, '')
|
21
|
+
|
22
|
+
str = str.sub(/^[a-z\d]*/) { |match| match.capitalize || match }
|
23
|
+
|
24
|
+
str.gsub(%r{(?:_|(/))([a-z\d]*)}i) do
|
25
|
+
word = Regexp.last_match(2)
|
26
|
+
substituted = word.capitalize || word
|
27
|
+
Regexp.last_match(1) ? "::#{substituted}" : substituted
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Convert string to snake case
|
32
|
+
#
|
33
|
+
# @param [String] val
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# Shale::Schema::JSONCompiler.snake_case('FooBar')
|
37
|
+
# # => 'foo_bar'
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def self.snake_case(str)
|
41
|
+
return str.to_s unless /[A-Z-]|::/.match?(str)
|
42
|
+
word = str.to_s.gsub('::', '/')
|
43
|
+
word = word.gsub(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
|
44
|
+
"#{Regexp.last_match(1) || Regexp.last_match(2)}_"
|
45
|
+
end
|
46
|
+
word = word.tr('-', '_')
|
47
|
+
word.downcase
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|