shale 0.2.1 → 0.3.1
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 +24 -0
- data/README.md +274 -7
- data/exe/shaleb +75 -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 +1 -1
- data/lib/shale/error.rb +6 -0
- data/lib/shale/mapper.rb +11 -11
- 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/base.rb +41 -0
- data/lib/shale/schema/json/boolean.rb +23 -0
- data/lib/shale/schema/json/collection.rb +39 -0
- data/lib/shale/schema/json/date.rb +23 -0
- data/lib/shale/schema/json/float.rb +23 -0
- data/lib/shale/schema/json/integer.rb +23 -0
- data/lib/shale/schema/json/object.rb +37 -0
- data/lib/shale/schema/json/ref.rb +28 -0
- data/lib/shale/schema/json/schema.rb +57 -0
- data/lib/shale/schema/json/string.rb +23 -0
- data/lib/shale/schema/json/time.rb +23 -0
- data/lib/shale/schema/json.rb +165 -0
- data/lib/shale/schema/xml/attribute.rb +41 -0
- data/lib/shale/schema/xml/complex_type.rb +67 -0
- data/lib/shale/schema/xml/element.rb +55 -0
- data/lib/shale/schema/xml/import.rb +46 -0
- data/lib/shale/schema/xml/ref_attribute.rb +37 -0
- data/lib/shale/schema/xml/ref_element.rb +39 -0
- data/lib/shale/schema/xml/schema.rb +121 -0
- data/lib/shale/schema/xml/typed_attribute.rb +46 -0
- data/lib/shale/schema/xml/typed_element.rb +46 -0
- data/lib/shale/schema/xml.rb +316 -0
- data/lib/shale/schema.rb +47 -0
- data/lib/shale/type/boolean.rb +2 -2
- data/lib/shale/type/composite.rb +67 -56
- 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 +41 -13
- data/lib/shale/mapping/base.rb +0 -32
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'element'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
class XML
|
8
|
+
# Class representing XML Schema <element ref=""> element
|
9
|
+
# with a reference
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
class RefElement < Element
|
13
|
+
# Initialize RefElement object
|
14
|
+
#
|
15
|
+
# @param [String] ref
|
16
|
+
# @param [String, nil] default
|
17
|
+
# @param [true, false] collection
|
18
|
+
# @param [true, false] required
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
def initialize(ref:, default: nil, collection: false, required: false)
|
22
|
+
super(default, collection, required)
|
23
|
+
@ref = ref
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# Return attributes as Ruby Hash
|
29
|
+
#
|
30
|
+
# @return [Hash]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
def attributes
|
34
|
+
{ 'ref' => @ref }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../../shale'
|
4
|
+
require_relative 'complex_type'
|
5
|
+
|
6
|
+
module Shale
|
7
|
+
module Schema
|
8
|
+
class XML
|
9
|
+
class Schema
|
10
|
+
# XML Schema namespace
|
11
|
+
# @api private
|
12
|
+
NAMESPACE_NAME = 'http://www.w3.org/2001/XMLSchema'
|
13
|
+
|
14
|
+
# Return name
|
15
|
+
#
|
16
|
+
# @return [String]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
attr_reader :name
|
20
|
+
|
21
|
+
# Initialize Schema object
|
22
|
+
#
|
23
|
+
# @param [String] name
|
24
|
+
# @param [String, nil] target_namespace
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def initialize(name, target_namespace)
|
28
|
+
@name = name
|
29
|
+
@target_namespace = target_namespace
|
30
|
+
@namespaces = []
|
31
|
+
@children = []
|
32
|
+
end
|
33
|
+
|
34
|
+
# Add namespace to XML Schema
|
35
|
+
#
|
36
|
+
# @param [String] prefix
|
37
|
+
# @param [String] name
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def add_namespace(prefix, name)
|
41
|
+
@namespaces << { prefix: prefix, name: name }
|
42
|
+
end
|
43
|
+
|
44
|
+
# Add child element to XML Schema
|
45
|
+
#
|
46
|
+
# @param [Shale::Schema::XML::Import,
|
47
|
+
# Shale::Schema::XML::Element,
|
48
|
+
# Shale::Schema::XML::Attribute,
|
49
|
+
# Shale::Schema::XML::ComplesType] child
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
def add_child(child)
|
53
|
+
@children << child
|
54
|
+
end
|
55
|
+
|
56
|
+
# Append element to the XML document
|
57
|
+
#
|
58
|
+
# @param [Shale::Adapter::<XML adapter>::Document] doc
|
59
|
+
#
|
60
|
+
# @return [Shale::Adapter::REXML::Document,
|
61
|
+
# Shale::Adapter::Nokogiri::Document,
|
62
|
+
# Shale::Adapter::Ox::Document]
|
63
|
+
#
|
64
|
+
# @api private
|
65
|
+
def as_xml
|
66
|
+
doc = Shale.xml_adapter.create_document
|
67
|
+
doc.add_namespace('xs', NAMESPACE_NAME)
|
68
|
+
|
69
|
+
@namespaces.uniq.each do |namespace|
|
70
|
+
doc.add_namespace(namespace[:prefix], namespace[:name])
|
71
|
+
end
|
72
|
+
|
73
|
+
schema = doc.create_element('xs:schema')
|
74
|
+
doc.add_element(doc.doc, schema)
|
75
|
+
|
76
|
+
doc.add_attribute(schema, 'elementFormDefault', 'qualified')
|
77
|
+
doc.add_attribute(schema, 'attributeFormDefault', 'qualified')
|
78
|
+
|
79
|
+
unless @target_namespace.nil?
|
80
|
+
doc.add_attribute(schema, 'targetNamespace', @target_namespace)
|
81
|
+
end
|
82
|
+
|
83
|
+
imports = @children
|
84
|
+
.select { |e| e.is_a?(Import) }
|
85
|
+
.uniq(&:namespace)
|
86
|
+
.sort { |a, b| (a.namespace || '') <=> (b.namespace || '') }
|
87
|
+
|
88
|
+
elements = @children
|
89
|
+
.select { |e| e.is_a?(Element) }
|
90
|
+
.sort { |a, b| a.name <=> b.name }
|
91
|
+
|
92
|
+
attributes = @children
|
93
|
+
.select { |e| e.is_a?(Attribute) }
|
94
|
+
.sort { |a, b| a.name <=> b.name }
|
95
|
+
|
96
|
+
complex_types = @children
|
97
|
+
.select { |e| e.is_a?(ComplexType) }
|
98
|
+
.sort { |a, b| a.name <=> b.name }
|
99
|
+
|
100
|
+
imports.each do |import|
|
101
|
+
doc.add_element(schema, import.as_xml(doc))
|
102
|
+
end
|
103
|
+
|
104
|
+
elements.each do |element|
|
105
|
+
doc.add_element(schema, element.as_xml(doc))
|
106
|
+
end
|
107
|
+
|
108
|
+
attributes.each do |attribute|
|
109
|
+
doc.add_element(schema, attribute.as_xml(doc))
|
110
|
+
end
|
111
|
+
|
112
|
+
complex_types.each do |complex_type|
|
113
|
+
doc.add_element(schema, complex_type.as_xml(doc))
|
114
|
+
end
|
115
|
+
|
116
|
+
doc.doc
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'attribute'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
class XML
|
8
|
+
# Class representing XML Schema <attribute name="" type=""> element
|
9
|
+
# with a name and a type
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
class TypedAttribute < Attribute
|
13
|
+
# Return name
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
attr_reader :name
|
19
|
+
|
20
|
+
# Initialize TypedAttribute object
|
21
|
+
#
|
22
|
+
# @param [String] name
|
23
|
+
# @param [String] type
|
24
|
+
# @param [String, nil] default
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def initialize(name:, type:, default: nil)
|
28
|
+
super(default)
|
29
|
+
@name = name
|
30
|
+
@type = type
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Return attributes as Ruby Hash
|
36
|
+
#
|
37
|
+
# @return [Hash]
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def attributes
|
41
|
+
{ 'name' => @name, 'type' => @type }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'element'
|
4
|
+
|
5
|
+
module Shale
|
6
|
+
module Schema
|
7
|
+
class XML
|
8
|
+
# Class representing XML Schema <element mame="" type=""> element
|
9
|
+
# with a name and a type
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
class TypedElement < Element
|
13
|
+
# Return name
|
14
|
+
#
|
15
|
+
# @return [String]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
attr_reader :name
|
19
|
+
|
20
|
+
# Initialize TypedElement object
|
21
|
+
#
|
22
|
+
# @param [String] name
|
23
|
+
# @param [String] type
|
24
|
+
# @param [String, nil] default
|
25
|
+
# @param [true, false] collection
|
26
|
+
# @param [true, false] required
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
def initialize(name:, type:, default: nil, collection: false, required: false)
|
30
|
+
super(default, collection, required)
|
31
|
+
@name = name
|
32
|
+
@type = type
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return attributes as Ruby Hash
|
36
|
+
#
|
37
|
+
# @return [Hash]
|
38
|
+
#
|
39
|
+
# @api private
|
40
|
+
def attributes
|
41
|
+
{ 'name' => @name, 'type' => @type }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,316 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../shale'
|
4
|
+
require_relative 'xml/complex_type'
|
5
|
+
require_relative 'xml/import'
|
6
|
+
require_relative 'xml/ref_attribute'
|
7
|
+
require_relative 'xml/ref_element'
|
8
|
+
require_relative 'xml/schema'
|
9
|
+
require_relative 'xml/typed_attribute'
|
10
|
+
require_relative 'xml/typed_element'
|
11
|
+
|
12
|
+
module Shale
|
13
|
+
module Schema
|
14
|
+
# Class for handling XML schema
|
15
|
+
#
|
16
|
+
# @api public
|
17
|
+
class XML
|
18
|
+
# XML Schema default name
|
19
|
+
# @api private
|
20
|
+
DEFAULT_SCHEMA_NAME = 'schema'
|
21
|
+
|
22
|
+
@xml_types = Hash.new('string')
|
23
|
+
|
24
|
+
# Register Shale to XML type mapping
|
25
|
+
#
|
26
|
+
# @param [Shale::Type::Value] shale_type
|
27
|
+
# @param [String] xml_type
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# Shale::Schema::XML.register_xml_type(Shale::Type::String, 'myType')
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def self.register_xml_type(shale_type, xml_type)
|
34
|
+
@xml_types[shale_type] = xml_type
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return XML type for given Shale type
|
38
|
+
#
|
39
|
+
# @param [Shale::Type::Value] shale_type
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# Shale::Schema::XML.get_xml_type(Shale::Type::String)
|
45
|
+
# # => 'string'
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
def self.get_xml_type(shale_type)
|
49
|
+
@xml_types[shale_type]
|
50
|
+
end
|
51
|
+
|
52
|
+
register_xml_type(Shale::Type::Boolean, 'boolean')
|
53
|
+
register_xml_type(Shale::Type::Date, 'date')
|
54
|
+
register_xml_type(Shale::Type::Float, 'decimal')
|
55
|
+
register_xml_type(Shale::Type::Integer, 'integer')
|
56
|
+
register_xml_type(Shale::Type::Time, 'dateTime')
|
57
|
+
|
58
|
+
# Generate XML Schema from Shale model and return
|
59
|
+
# it as a Shale::Schema::XML::Schema array
|
60
|
+
#
|
61
|
+
# @param [Shale::Mapper] klass
|
62
|
+
# @param [String, nil] base_name
|
63
|
+
#
|
64
|
+
# @raise [NotAShaleMapperError] when attribute is not a Shale model
|
65
|
+
#
|
66
|
+
# @return [Array<Shale::Schema::XML::Schema>]
|
67
|
+
#
|
68
|
+
# @example
|
69
|
+
# Shale::Schema::XML.new.as_schemas(Person)
|
70
|
+
#
|
71
|
+
# @api public
|
72
|
+
def as_schemas(klass, base_name = nil)
|
73
|
+
unless mapper_type?(klass)
|
74
|
+
raise NotAShaleMapperError, "XML Shema can't be generated for '#{klass}' type"
|
75
|
+
end
|
76
|
+
|
77
|
+
schemas = Hash.new do |hash, key|
|
78
|
+
name = "#{base_name || DEFAULT_SCHEMA_NAME}#{hash.keys.length}.xsd"
|
79
|
+
hash[key] = Schema.new(name, key)
|
80
|
+
end
|
81
|
+
|
82
|
+
default_namespace = klass.xml_mapping.default_namespace
|
83
|
+
|
84
|
+
root_element = TypedElement.new(
|
85
|
+
name: klass.xml_mapping.unprefixed_root,
|
86
|
+
type: [default_namespace.prefix, schematize(klass.name)].compact.join(':'),
|
87
|
+
required: true
|
88
|
+
)
|
89
|
+
|
90
|
+
schemas[default_namespace.name].add_namespace(
|
91
|
+
default_namespace.prefix,
|
92
|
+
default_namespace.name
|
93
|
+
)
|
94
|
+
schemas[default_namespace.name].add_child(root_element)
|
95
|
+
|
96
|
+
composites = collect_composite_types(klass, klass.xml_mapping.default_namespace.name)
|
97
|
+
|
98
|
+
composites.each do |composite|
|
99
|
+
type = composite[:type]
|
100
|
+
namespace = composite[:namespace]
|
101
|
+
children = []
|
102
|
+
|
103
|
+
type.xml_mapping.elements.values.each do |mapping|
|
104
|
+
attribute = type.attributes[mapping.attribute]
|
105
|
+
next unless attribute
|
106
|
+
|
107
|
+
xml_type = get_xml_type_for_attribute(attribute.type, mapping.namespace)
|
108
|
+
default = get_default_for_attribute(attribute)
|
109
|
+
|
110
|
+
if namespace == mapping.namespace.name
|
111
|
+
children << TypedElement.new(
|
112
|
+
name: mapping.name,
|
113
|
+
type: xml_type,
|
114
|
+
collection: attribute.collection?,
|
115
|
+
default: default
|
116
|
+
)
|
117
|
+
else
|
118
|
+
target_namespace = mapping.namespace
|
119
|
+
target_schema = schemas[target_namespace.name]
|
120
|
+
|
121
|
+
children << RefElement.new(
|
122
|
+
ref: mapping.prefixed_name,
|
123
|
+
collection: attribute.collection?,
|
124
|
+
default: default
|
125
|
+
)
|
126
|
+
|
127
|
+
target_element = TypedElement.new(
|
128
|
+
name: mapping.name,
|
129
|
+
type: xml_type,
|
130
|
+
required: true
|
131
|
+
)
|
132
|
+
|
133
|
+
import_element = Import.new(
|
134
|
+
target_namespace.name,
|
135
|
+
target_schema.name
|
136
|
+
)
|
137
|
+
|
138
|
+
target_schema.add_namespace(
|
139
|
+
target_namespace.prefix,
|
140
|
+
target_namespace.name
|
141
|
+
)
|
142
|
+
target_schema.add_child(target_element)
|
143
|
+
|
144
|
+
schemas[namespace].add_namespace(
|
145
|
+
target_namespace.prefix,
|
146
|
+
target_namespace.name
|
147
|
+
)
|
148
|
+
schemas[namespace].add_child(import_element)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
type.xml_mapping.attributes.values.each do |mapping|
|
153
|
+
attribute = type.attributes[mapping.attribute]
|
154
|
+
next unless attribute
|
155
|
+
|
156
|
+
xml_type = get_xml_type_for_attribute(attribute.type, mapping.namespace)
|
157
|
+
default = get_default_for_attribute(attribute)
|
158
|
+
|
159
|
+
if namespace == mapping.namespace.name
|
160
|
+
children << TypedAttribute.new(
|
161
|
+
name: mapping.name,
|
162
|
+
type: xml_type,
|
163
|
+
default: default
|
164
|
+
)
|
165
|
+
else
|
166
|
+
target_namespace = mapping.namespace
|
167
|
+
target_schema = schemas[target_namespace.name]
|
168
|
+
|
169
|
+
children << RefAttribute.new(
|
170
|
+
ref: mapping.prefixed_name,
|
171
|
+
default: default
|
172
|
+
)
|
173
|
+
|
174
|
+
target_element = TypedAttribute.new(name: mapping.name, type: xml_type)
|
175
|
+
|
176
|
+
import_element = Import.new(
|
177
|
+
target_namespace.name,
|
178
|
+
target_schema.name
|
179
|
+
)
|
180
|
+
|
181
|
+
target_schema.add_namespace(
|
182
|
+
target_namespace.prefix,
|
183
|
+
target_namespace.name
|
184
|
+
)
|
185
|
+
target_schema.add_child(target_element)
|
186
|
+
|
187
|
+
schemas[namespace].add_namespace(
|
188
|
+
target_namespace.prefix,
|
189
|
+
target_namespace.name
|
190
|
+
)
|
191
|
+
schemas[namespace].add_child(import_element)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
complex = ComplexType.new(
|
196
|
+
schematize(type.name),
|
197
|
+
children,
|
198
|
+
mixed: !type.xml_mapping.content.nil?
|
199
|
+
)
|
200
|
+
|
201
|
+
schemas[namespace].add_child(complex)
|
202
|
+
end
|
203
|
+
|
204
|
+
schemas.values
|
205
|
+
end
|
206
|
+
|
207
|
+
# Generate XML Schema from Shale model
|
208
|
+
#
|
209
|
+
# @param [Shale::Mapper] klass
|
210
|
+
# @param [String, nil] base_name
|
211
|
+
# @param [true, false] pretty
|
212
|
+
# @param [true, false] declaration
|
213
|
+
#
|
214
|
+
# @return [Hash<String, String>]
|
215
|
+
#
|
216
|
+
# @example
|
217
|
+
# Shale::Schema::XML.new.to_schemas(Person)
|
218
|
+
#
|
219
|
+
# @api public
|
220
|
+
def to_schemas(klass, base_name = nil, pretty: false, declaration: false)
|
221
|
+
schemas = as_schemas(klass, base_name)
|
222
|
+
|
223
|
+
options = [
|
224
|
+
pretty ? :pretty : nil,
|
225
|
+
declaration ? :declaration : nil,
|
226
|
+
]
|
227
|
+
|
228
|
+
schemas.to_h do |schema|
|
229
|
+
[schema.name, Shale.xml_adapter.dump(schema.as_xml, *options)]
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
private
|
234
|
+
|
235
|
+
# Check it type inherits from Shale::Mapper
|
236
|
+
#
|
237
|
+
# @param [Class] type
|
238
|
+
#
|
239
|
+
# @return [true, false]
|
240
|
+
#
|
241
|
+
# @api private
|
242
|
+
def mapper_type?(type)
|
243
|
+
type < Shale::Mapper
|
244
|
+
end
|
245
|
+
|
246
|
+
# Collect recursively Shale::Mapper types
|
247
|
+
#
|
248
|
+
# @param [Shale::Mapper] type
|
249
|
+
# @param [String, nil] namespace
|
250
|
+
#
|
251
|
+
# @return [Array<Hash<Symbol, String>>]
|
252
|
+
#
|
253
|
+
# @api private
|
254
|
+
def collect_composite_types(type, namespace)
|
255
|
+
types = [{ type: type, namespace: namespace }]
|
256
|
+
|
257
|
+
type.xml_mapping.elements.values.each do |mapping|
|
258
|
+
attribute = type.attributes[mapping.attribute]
|
259
|
+
next unless attribute
|
260
|
+
|
261
|
+
is_mapper = mapper_type?(attribute.type)
|
262
|
+
is_included = types.include?({ type: attribute.type, namespace: namespace })
|
263
|
+
|
264
|
+
if is_mapper && !is_included
|
265
|
+
types += collect_composite_types(attribute.type, mapping.namespace.name)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
types.uniq
|
270
|
+
end
|
271
|
+
|
272
|
+
# Convert Ruby class name to XML Schema name
|
273
|
+
#
|
274
|
+
# @param [String] word
|
275
|
+
#
|
276
|
+
# @return [String]
|
277
|
+
#
|
278
|
+
# @api private
|
279
|
+
def schematize(word)
|
280
|
+
word.gsub('::', '_')
|
281
|
+
end
|
282
|
+
|
283
|
+
# Return XML Schema type for given Shale::Type::Value
|
284
|
+
#
|
285
|
+
# @param [Shale::Type::Value] type
|
286
|
+
# @param [String] namespace
|
287
|
+
#
|
288
|
+
# @return [String]
|
289
|
+
#
|
290
|
+
# @api private
|
291
|
+
def get_xml_type_for_attribute(type, namespace)
|
292
|
+
if mapper_type?(type)
|
293
|
+
[namespace.prefix, schematize(type.name)].compact.join(':')
|
294
|
+
else
|
295
|
+
"xs:#{self.class.get_xml_type(type)}"
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# Return default value for given Shale::Attribute
|
300
|
+
#
|
301
|
+
# @param [Shale::Attribute] attribute
|
302
|
+
#
|
303
|
+
# @return [String, nil]
|
304
|
+
#
|
305
|
+
# @api private
|
306
|
+
def get_default_for_attribute(attribute)
|
307
|
+
return unless attribute.default
|
308
|
+
return if attribute.collection?
|
309
|
+
return if mapper_type?(attribute.type)
|
310
|
+
|
311
|
+
value = attribute.type.cast(attribute.default.call)
|
312
|
+
attribute.type.as_xml_value(value)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
data/lib/shale/schema.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'schema/json'
|
4
|
+
require_relative 'schema/xml'
|
5
|
+
|
6
|
+
module Shale
|
7
|
+
# Module for handling JSON and XML schema
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
module Schema
|
11
|
+
# Generate JSON Schema from Shale model
|
12
|
+
#
|
13
|
+
# @param [Shale::Mapper] klass
|
14
|
+
# @param [String, nil] id
|
15
|
+
# @param [String, nil] description
|
16
|
+
# @param [true, false] pretty
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# Shale::Schema.to_json(Person, id: 'My ID', description: 'My description', pretty: true)
|
22
|
+
# # => JSON schema
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
def self.to_json(klass, id: nil, description: nil, pretty: false)
|
26
|
+
JSON.new.to_schema(klass, id: id, description: description, pretty: pretty)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Generate XML Schema from Shale model
|
30
|
+
#
|
31
|
+
# @param [Shale::Mapper] klass
|
32
|
+
# @param [String, nil] base_name
|
33
|
+
# @param [true, false] pretty
|
34
|
+
# @param [true, false] declaration
|
35
|
+
#
|
36
|
+
# @return [Hash<String, String>]
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
# Shale::Schema.to_xml(Person, pretty: true, declaration: true)
|
40
|
+
# # => { 'schema0.xsd' => <JSON schema>, 'schema1.xsd' => <JSON schema> }
|
41
|
+
#
|
42
|
+
# @api public
|
43
|
+
def self.to_xml(klass, base_name = nil, pretty: false, declaration: false)
|
44
|
+
XML.new.to_schemas(klass, base_name, pretty: pretty, declaration: declaration)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/shale/type/boolean.rb
CHANGED