shale 0.4.0 → 0.5.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 +11 -0
- data/README.md +93 -7
- data/exe/shaleb +30 -6
- data/lib/shale/adapter/nokogiri/document.rb +87 -0
- data/lib/shale/adapter/nokogiri/node.rb +100 -0
- data/lib/shale/adapter/nokogiri.rb +11 -151
- data/lib/shale/adapter/ox/document.rb +80 -0
- data/lib/shale/adapter/ox/node.rb +88 -0
- data/lib/shale/adapter/ox.rb +9 -134
- data/lib/shale/adapter/rexml/document.rb +88 -0
- data/lib/shale/adapter/rexml/node.rb +99 -0
- data/lib/shale/adapter/rexml.rb +9 -150
- data/lib/shale/error.rb +35 -2
- data/lib/shale/mapper.rb +2 -2
- data/lib/shale/schema/{json_compiler → compiler}/boolean.rb +1 -1
- data/lib/shale/schema/{json_compiler/object.rb → compiler/complex.rb} +11 -8
- data/lib/shale/schema/{json_compiler → compiler}/date.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/float.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/integer.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/property.rb +6 -6
- data/lib/shale/schema/{json_compiler → compiler}/string.rb +1 -1
- data/lib/shale/schema/{json_compiler → compiler}/time.rb +1 -1
- data/lib/shale/schema/compiler/value.rb +21 -0
- data/lib/shale/schema/compiler/xml_complex.rb +50 -0
- data/lib/shale/schema/compiler/xml_property.rb +73 -0
- data/lib/shale/schema/json_compiler.rb +32 -34
- data/lib/shale/schema/json_generator.rb +3 -3
- data/lib/shale/schema/xml_compiler.rb +919 -0
- data/lib/shale/schema/xml_generator.rb +7 -7
- data/lib/shale/schema.rb +16 -0
- data/lib/shale/type/{composite.rb → complex.rb} +20 -2
- data/lib/shale/utils.rb +42 -7
- data/lib/shale/version.rb +1 -1
- data/lib/shale.rb +8 -19
- data/shale.gemspec +1 -1
- metadata +23 -15
- data/lib/shale/schema/json_compiler/utils.rb +0 -52
- data/lib/shale/schema/json_compiler/value.rb +0 -13
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'utils'
|
3
|
+
require_relative '../../utils'
|
4
4
|
|
5
5
|
module Shale
|
6
6
|
module Schema
|
7
|
-
|
8
|
-
# Class representing Shale's
|
7
|
+
module Compiler
|
8
|
+
# Class representing Shale's complex type
|
9
9
|
#
|
10
10
|
# @api private
|
11
|
-
class
|
11
|
+
class Complex
|
12
12
|
# Return id
|
13
13
|
#
|
14
14
|
# @return [String]
|
@@ -18,7 +18,7 @@ module Shale
|
|
18
18
|
|
19
19
|
# Return properties
|
20
20
|
#
|
21
|
-
# @return [Array<Shale::Schema::
|
21
|
+
# @return [Array<Shale::Schema::Compiler::Property>]
|
22
22
|
#
|
23
23
|
# @api private
|
24
24
|
attr_reader :properties
|
@@ -62,22 +62,25 @@ module Shale
|
|
62
62
|
|
63
63
|
# Return references
|
64
64
|
#
|
65
|
-
# @return [Array<Shale::Schema::
|
65
|
+
# @return [Array<Shale::Schema::Compiler::Property>]
|
66
66
|
#
|
67
67
|
# @api private
|
68
68
|
def references
|
69
69
|
@properties
|
70
70
|
.filter { |e| e.type.is_a?(self.class) && e.type != self }
|
71
71
|
.uniq { |e| e.type.id }
|
72
|
+
.sort { |a, b| a.type.file_name <=> b.type.file_name }
|
72
73
|
end
|
73
74
|
|
74
75
|
# Add property to Object
|
75
76
|
#
|
76
|
-
# @param [Shale::Schema::
|
77
|
+
# @param [Shale::Schema::Compiler::Property] property
|
77
78
|
#
|
78
79
|
# @api private
|
79
80
|
def add_property(property)
|
80
|
-
@properties
|
81
|
+
unless @properties.find { |e| e.mapping_name == property.mapping_name }
|
82
|
+
@properties << property
|
83
|
+
end
|
81
84
|
end
|
82
85
|
end
|
83
86
|
end
|
@@ -1,20 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative 'utils'
|
3
|
+
require_relative '../../utils'
|
4
4
|
|
5
5
|
module Shale
|
6
6
|
module Schema
|
7
|
-
|
7
|
+
module Compiler
|
8
8
|
# Class representing Shale's property
|
9
9
|
#
|
10
10
|
# @api private
|
11
11
|
class Property
|
12
|
-
# Return
|
12
|
+
# Return mapping's name
|
13
13
|
#
|
14
14
|
# @return [String]
|
15
15
|
#
|
16
16
|
# @api private
|
17
|
-
attr_reader :
|
17
|
+
attr_reader :mapping_name
|
18
18
|
|
19
19
|
# Return attribute's name
|
20
20
|
#
|
@@ -33,13 +33,13 @@ module Shale
|
|
33
33
|
# Initialize Property object
|
34
34
|
#
|
35
35
|
# @param [String] name
|
36
|
-
# @param [Shale::Schema::
|
36
|
+
# @param [Shale::Schema::Compiler::Type] type
|
37
37
|
# @param [true, false] collection
|
38
38
|
# @param [Object] default
|
39
39
|
#
|
40
40
|
# @api private
|
41
41
|
def initialize(name, type, collection, default)
|
42
|
-
@
|
42
|
+
@mapping_name = name
|
43
43
|
@attribute_name = Utils.snake_case(name)
|
44
44
|
@type = type
|
45
45
|
@collection = collection
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Shale
|
4
|
+
module Schema
|
5
|
+
module Compiler
|
6
|
+
# Class that maps Schema type to Shale Value type
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Value
|
10
|
+
# Return name of the Shale type
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
def name
|
16
|
+
'Shale::Type::Value'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'complex'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
module Compiler
|
8
|
+
# Class representing Shale's XML complex type
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class XMLComplex < Complex
|
12
|
+
# Accessor for root attribute
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_accessor :root
|
18
|
+
|
19
|
+
# Return namespace prefix
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :prefix
|
25
|
+
|
26
|
+
# Return namespace URI
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
attr_reader :namespace
|
32
|
+
|
33
|
+
# Initialize object
|
34
|
+
#
|
35
|
+
# @param [String] id
|
36
|
+
# @param [String] name
|
37
|
+
# @param [String] prefix
|
38
|
+
# @param [String] namespace
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def initialize(id, name, prefix, namespace)
|
42
|
+
super(id, name)
|
43
|
+
@root = name
|
44
|
+
@prefix = prefix
|
45
|
+
@namespace = namespace
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'property'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
module Compiler
|
8
|
+
# Class representing Shale's property
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
class XMLProperty < Property
|
12
|
+
# Return namespace URI
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
attr_reader :namespace
|
18
|
+
|
19
|
+
# Return namespace prefix
|
20
|
+
#
|
21
|
+
# @return [String]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :prefix
|
25
|
+
|
26
|
+
# Initialize object
|
27
|
+
#
|
28
|
+
# @param [String] name
|
29
|
+
# @param [Shale::Schema::Compiler::Type] type
|
30
|
+
# @param [true, false] collection
|
31
|
+
# @param [Object] default
|
32
|
+
# @param [String] prefix
|
33
|
+
# @param [String] namespace
|
34
|
+
# @param [Symbol] category
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
def initialize(name:, type:, collection:, default:, prefix:, namespace:, category:)
|
38
|
+
super(name, type, collection, default)
|
39
|
+
@prefix = prefix
|
40
|
+
@namespace = namespace
|
41
|
+
@category = category
|
42
|
+
end
|
43
|
+
|
44
|
+
# Check if property's category is content
|
45
|
+
#
|
46
|
+
# @return [true, false]
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
def content?
|
50
|
+
@category == :content
|
51
|
+
end
|
52
|
+
|
53
|
+
# Check if property's category is attribute
|
54
|
+
#
|
55
|
+
# @return [true, false]
|
56
|
+
#
|
57
|
+
# @api private
|
58
|
+
def attribute?
|
59
|
+
@category == :attribute
|
60
|
+
end
|
61
|
+
|
62
|
+
# Check if property's category is element
|
63
|
+
#
|
64
|
+
# @return [true, false]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
def element?
|
68
|
+
@category == :element
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -4,15 +4,15 @@ require 'erb'
|
|
4
4
|
require 'uri'
|
5
5
|
|
6
6
|
require_relative '../../shale'
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
9
|
-
require_relative '
|
10
|
-
require_relative '
|
11
|
-
require_relative '
|
12
|
-
require_relative '
|
13
|
-
require_relative '
|
14
|
-
require_relative '
|
15
|
-
require_relative '
|
7
|
+
require_relative 'compiler/boolean'
|
8
|
+
require_relative 'compiler/complex'
|
9
|
+
require_relative 'compiler/date'
|
10
|
+
require_relative 'compiler/float'
|
11
|
+
require_relative 'compiler/integer'
|
12
|
+
require_relative 'compiler/property'
|
13
|
+
require_relative 'compiler/string'
|
14
|
+
require_relative 'compiler/time'
|
15
|
+
require_relative 'compiler/value'
|
16
16
|
|
17
17
|
module Shale
|
18
18
|
module Schema
|
@@ -44,20 +44,20 @@ module Shale
|
|
44
44
|
|
45
45
|
json do
|
46
46
|
<%- type.properties.each do |property| -%>
|
47
|
-
map '<%= property.
|
47
|
+
map '<%= property.mapping_name %>', to: :<%= property.attribute_name %>
|
48
48
|
<%- end -%>
|
49
49
|
end
|
50
50
|
end
|
51
51
|
TEMPLATE
|
52
52
|
|
53
|
-
# Generate Shale models from JSON Schema and return them as a Ruby Array
|
53
|
+
# Generate Shale models from JSON Schema and return them as a Ruby Array of objects
|
54
54
|
#
|
55
55
|
# @param [Array<String>] schemas
|
56
56
|
# @param [String, nil] root_name
|
57
57
|
#
|
58
|
-
# @raise [
|
58
|
+
# @raise [SchemaError] when JSON Schema has errors
|
59
59
|
#
|
60
|
-
# @return [Array<Shale::Schema::
|
60
|
+
# @return [Array<Shale::Schema::Compiler::Complex>]
|
61
61
|
#
|
62
62
|
# @example
|
63
63
|
# Shale::Schema::JSONCompiler.new.as_models([schema1, schema2])
|
@@ -81,7 +81,6 @@ module Shale
|
|
81
81
|
total_duplicates = Hash.new(0)
|
82
82
|
duplicates = Hash.new(0)
|
83
83
|
|
84
|
-
# rubocop:disable Style/CombinableLoops
|
85
84
|
@types.each do |type|
|
86
85
|
total_duplicates[type.name] += 1
|
87
86
|
end
|
@@ -93,7 +92,6 @@ module Shale
|
|
93
92
|
type.name = format("#{type.name}%d", duplicates[type.name])
|
94
93
|
end
|
95
94
|
end
|
96
|
-
# rubocop:enable Style/CombinableLoops
|
97
95
|
|
98
96
|
@types.reverse
|
99
97
|
end
|
@@ -103,7 +101,7 @@ module Shale
|
|
103
101
|
# @param [Array<String>] schemas
|
104
102
|
# @param [String, nil] root_name
|
105
103
|
#
|
106
|
-
# @raise [
|
104
|
+
# @raise [SchemaError] when JSON Schema has errors
|
107
105
|
#
|
108
106
|
# @return [Hash<String, String>]
|
109
107
|
#
|
@@ -159,7 +157,7 @@ module Shale
|
|
159
157
|
# @param [String, nil] base_id
|
160
158
|
# @param [String, nil] ref
|
161
159
|
#
|
162
|
-
# @raise [
|
160
|
+
# @raise [SchemaError] when ref can't be resolved
|
163
161
|
#
|
164
162
|
# @return [Hash, true, false]
|
165
163
|
#
|
@@ -172,7 +170,7 @@ module Shale
|
|
172
170
|
entry = @schema_repository[key]
|
173
171
|
|
174
172
|
unless entry
|
175
|
-
raise
|
173
|
+
raise SchemaError, "can't resolve reference '#{key}'"
|
176
174
|
end
|
177
175
|
|
178
176
|
if entry[:schema].key?('$ref')
|
@@ -188,12 +186,12 @@ module Shale
|
|
188
186
|
# @param [String] id
|
189
187
|
# @param [String] name
|
190
188
|
#
|
191
|
-
# @return [Shale::Schema::
|
189
|
+
# @return [Shale::Schema::Compiler::Type]
|
192
190
|
#
|
193
191
|
# @api private
|
194
192
|
def infer_type(schema, id, name)
|
195
193
|
return unless schema
|
196
|
-
return Value.new if schema == true
|
194
|
+
return Compiler::Value.new if schema == true
|
197
195
|
|
198
196
|
type = schema['type']
|
199
197
|
format = schema['format']
|
@@ -202,28 +200,28 @@ module Shale
|
|
202
200
|
type -= ['null']
|
203
201
|
|
204
202
|
if type.length > 1
|
205
|
-
return Value.new
|
203
|
+
return Compiler::Value.new
|
206
204
|
else
|
207
205
|
type = type[0]
|
208
206
|
end
|
209
207
|
end
|
210
208
|
|
211
209
|
if type == 'object'
|
212
|
-
|
210
|
+
Compiler::Complex.new(id, name)
|
213
211
|
elsif type == 'string' && format == 'date'
|
214
|
-
Date.new
|
212
|
+
Compiler::Date.new
|
215
213
|
elsif type == 'string' && format == 'date-time'
|
216
|
-
Time.new
|
214
|
+
Compiler::Time.new
|
217
215
|
elsif type == 'string'
|
218
|
-
String.new
|
216
|
+
Compiler::String.new
|
219
217
|
elsif type == 'number'
|
220
|
-
Float.new
|
218
|
+
Compiler::Float.new
|
221
219
|
elsif type == 'integer'
|
222
|
-
Integer.new
|
220
|
+
Compiler::Integer.new
|
223
221
|
elsif type == 'boolean'
|
224
|
-
Boolean.new
|
222
|
+
Compiler::Boolean.new
|
225
223
|
else
|
226
|
-
Value.new
|
224
|
+
Compiler::Value.new
|
227
225
|
end
|
228
226
|
end
|
229
227
|
|
@@ -233,7 +231,7 @@ module Shale
|
|
233
231
|
# @param [Array<String>] fragment
|
234
232
|
# @param [String] base_id
|
235
233
|
#
|
236
|
-
# @raise [
|
234
|
+
# @raise [SchemaError] when there are problems with JSON schema
|
237
235
|
#
|
238
236
|
# @api private
|
239
237
|
def disassemble_schema(schema, fragment = [], base_id = '')
|
@@ -249,7 +247,7 @@ module Shale
|
|
249
247
|
pointer = build_pointer(id, fragment)
|
250
248
|
|
251
249
|
if @schema_repository.key?(pointer)
|
252
|
-
raise
|
250
|
+
raise SchemaError, "schema with id '#{pointer}' already exists"
|
253
251
|
else
|
254
252
|
@schema_repository[pointer] = {
|
255
253
|
id: pointer,
|
@@ -274,7 +272,7 @@ module Shale
|
|
274
272
|
# @param [String] base_id
|
275
273
|
# @param [Array<String>] fragment
|
276
274
|
#
|
277
|
-
# @return [Shale::Schema::
|
275
|
+
# @return [Shale::Schema::Compiler::Property, nil]
|
278
276
|
#
|
279
277
|
# @api private
|
280
278
|
def compile(schema, is_root, base_id = '', fragment = [])
|
@@ -317,7 +315,7 @@ module Shale
|
|
317
315
|
default = schema['default']
|
318
316
|
end
|
319
317
|
|
320
|
-
if type.is_a?(
|
318
|
+
if type.is_a?(Compiler::Complex) && !@types.include?(type)
|
321
319
|
@types << type
|
322
320
|
|
323
321
|
(schema['properties'] || {}).each do |subschema_key, subschema|
|
@@ -326,7 +324,7 @@ module Shale
|
|
326
324
|
end
|
327
325
|
end
|
328
326
|
|
329
|
-
Property.new(key, type, collection, default) if type
|
327
|
+
Compiler::Property.new(key, type, collection, default) if type
|
330
328
|
end
|
331
329
|
end
|
332
330
|
end
|
@@ -76,7 +76,7 @@ module Shale
|
|
76
76
|
end
|
77
77
|
|
78
78
|
types = []
|
79
|
-
|
79
|
+
collect_complex_types(types, klass)
|
80
80
|
objects = []
|
81
81
|
|
82
82
|
types.each do |type|
|
@@ -148,7 +148,7 @@ module Shale
|
|
148
148
|
# @param [Shale::Mapper] type
|
149
149
|
#
|
150
150
|
# @api private
|
151
|
-
def
|
151
|
+
def collect_complex_types(types, type)
|
152
152
|
types << type
|
153
153
|
|
154
154
|
type.json_mapping.keys.values.each do |mapping|
|
@@ -156,7 +156,7 @@ module Shale
|
|
156
156
|
next unless attribute
|
157
157
|
|
158
158
|
if mapper_type?(attribute.type) && !types.include?(attribute.type)
|
159
|
-
|
159
|
+
collect_complex_types(types, attribute.type)
|
160
160
|
end
|
161
161
|
end
|
162
162
|
end
|