shale 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -0
  3. data/README.md +93 -7
  4. data/exe/shaleb +30 -6
  5. data/lib/shale/adapter/nokogiri/document.rb +87 -0
  6. data/lib/shale/adapter/nokogiri/node.rb +100 -0
  7. data/lib/shale/adapter/nokogiri.rb +11 -151
  8. data/lib/shale/adapter/ox/document.rb +80 -0
  9. data/lib/shale/adapter/ox/node.rb +88 -0
  10. data/lib/shale/adapter/ox.rb +9 -134
  11. data/lib/shale/adapter/rexml/document.rb +88 -0
  12. data/lib/shale/adapter/rexml/node.rb +99 -0
  13. data/lib/shale/adapter/rexml.rb +9 -150
  14. data/lib/shale/error.rb +35 -2
  15. data/lib/shale/mapper.rb +2 -2
  16. data/lib/shale/schema/{json_compiler → compiler}/boolean.rb +1 -1
  17. data/lib/shale/schema/{json_compiler/object.rb → compiler/complex.rb} +11 -8
  18. data/lib/shale/schema/{json_compiler → compiler}/date.rb +1 -1
  19. data/lib/shale/schema/{json_compiler → compiler}/float.rb +1 -1
  20. data/lib/shale/schema/{json_compiler → compiler}/integer.rb +1 -1
  21. data/lib/shale/schema/{json_compiler → compiler}/property.rb +6 -6
  22. data/lib/shale/schema/{json_compiler → compiler}/string.rb +1 -1
  23. data/lib/shale/schema/{json_compiler → compiler}/time.rb +1 -1
  24. data/lib/shale/schema/compiler/value.rb +21 -0
  25. data/lib/shale/schema/compiler/xml_complex.rb +50 -0
  26. data/lib/shale/schema/compiler/xml_property.rb +73 -0
  27. data/lib/shale/schema/json_compiler.rb +32 -34
  28. data/lib/shale/schema/json_generator.rb +3 -3
  29. data/lib/shale/schema/xml_compiler.rb +919 -0
  30. data/lib/shale/schema/xml_generator.rb +7 -7
  31. data/lib/shale/schema.rb +16 -0
  32. data/lib/shale/type/{composite.rb → complex.rb} +20 -2
  33. data/lib/shale/utils.rb +42 -7
  34. data/lib/shale/version.rb +1 -1
  35. data/lib/shale.rb +8 -19
  36. data/shale.gemspec +1 -1
  37. metadata +23 -15
  38. data/lib/shale/schema/json_compiler/utils.rb +0 -52
  39. 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
- class JSONCompiler
8
- # Class representing Shale's comosite type
7
+ module Compiler
8
+ # Class representing Shale's complex type
9
9
  #
10
10
  # @api private
11
- class Object
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::JSONCompiler::Property>]
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::JSONCompiler::Property>]
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::JSONCompiler::Property] property
77
+ # @param [Shale::Schema::Compiler::Property] property
77
78
  #
78
79
  # @api private
79
80
  def add_property(property)
80
- @properties << property
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
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Shale
4
4
  module Schema
5
- class JSONCompiler
5
+ module Compiler
6
6
  # Class that maps Schema type to Shale Date type
7
7
  #
8
8
  # @api private
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Shale
4
4
  module Schema
5
- class JSONCompiler
5
+ module Compiler
6
6
  # Class that maps Schema type to Shale Float type
7
7
  #
8
8
  # @api private
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Shale
4
4
  module Schema
5
- class JSONCompiler
5
+ module Compiler
6
6
  # Class that maps Schema type to Shale Integer type
7
7
  #
8
8
  # @api private
@@ -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
- class JSONCompiler
7
+ module Compiler
8
8
  # Class representing Shale's property
9
9
  #
10
10
  # @api private
11
11
  class Property
12
- # Return property's name
12
+ # Return mapping's name
13
13
  #
14
14
  # @return [String]
15
15
  #
16
16
  # @api private
17
- attr_reader :property_name
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::JsonCompiler::Type] type
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
- @property_name = name
42
+ @mapping_name = name
43
43
  @attribute_name = Utils.snake_case(name)
44
44
  @type = type
45
45
  @collection = collection
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Shale
4
4
  module Schema
5
- class JSONCompiler
5
+ module Compiler
6
6
  # Class that maps Schema type to Shale String type
7
7
  #
8
8
  # @api private
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Shale
4
4
  module Schema
5
- class JSONCompiler
5
+ module Compiler
6
6
  # Class that maps Schema type to Shale Time type
7
7
  #
8
8
  # @api private
@@ -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 'json_compiler/boolean'
8
- require_relative 'json_compiler/date'
9
- require_relative 'json_compiler/float'
10
- require_relative 'json_compiler/integer'
11
- require_relative 'json_compiler/object'
12
- require_relative 'json_compiler/property'
13
- require_relative 'json_compiler/string'
14
- require_relative 'json_compiler/time'
15
- require_relative 'json_compiler/value'
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.property_name %>', to: :<%= property.attribute_name %>
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 od objects
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 [JSONSchemaError] when JSON Schema has errors
58
+ # @raise [SchemaError] when JSON Schema has errors
59
59
  #
60
- # @return [Array<Shale::Schema::JSONCompiler::Object>]
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 [JSONSchemaError] when JSON Schema has errors
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 [JSONSchemaError] when ref can't be resolved
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 JSONSchemaError, "can't resolve reference '#{key}'"
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::JSONCompiler::Type]
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
- Object.new(id, name)
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 [JSONSchemaError] when there are problems with JSON schema
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 JSONSchemaError, "schema with id '#{pointer}' already exists"
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::JSONCompiler::Property, nil]
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?(Object) && !@types.include?(type)
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
- collect_composite_types(types, klass)
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 collect_composite_types(types, type)
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
- collect_composite_types(types, attribute.type)
159
+ collect_complex_types(types, attribute.type)
160
160
  end
161
161
  end
162
162
  end