shale 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|