gyro 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +42 -797
  3. data/bin/gyro +91 -84
  4. data/documentation/enum.png +0 -0
  5. data/documentation/enum_json.png +0 -0
  6. data/documentation/ignored.png +0 -0
  7. data/documentation/json.png +0 -0
  8. data/documentation/primary_key.png +0 -0
  9. data/documentation/read_only.png +0 -0
  10. data/documentation/simple_entity.png +0 -0
  11. data/documentation/support_annotation.png +0 -0
  12. data/documentation/transformer.png +0 -0
  13. data/documentation/transformers.png +0 -0
  14. data/lib/gyro.rb +18 -29
  15. data/lib/gyro/generator/json.rb +30 -0
  16. data/lib/gyro/generator/liquid.rb +22 -0
  17. data/lib/gyro/generator/liquid/filters.rb +53 -0
  18. data/lib/gyro/generator/liquid/liquid.rb +124 -0
  19. data/lib/gyro/generator/liquid/whitespace_patch.rb +61 -0
  20. data/lib/gyro/log.rb +46 -0
  21. data/lib/gyro/parser/xcdatamodel.rb +20 -0
  22. data/lib/gyro/parser/xcdatamodel/attribute.rb +129 -0
  23. data/lib/gyro/parser/xcdatamodel/entity.rb +195 -0
  24. data/lib/gyro/parser/xcdatamodel/relationship.rb +84 -0
  25. data/lib/gyro/parser/xcdatamodel/xcdatamodel.rb +65 -0
  26. data/lib/gyro/template.rb +68 -0
  27. data/lib/gyro/version.rb +19 -0
  28. data/lib/templates/android/README.md +164 -0
  29. data/lib/templates/android/entity.liquid +49 -0
  30. data/lib/templates/android/entity_filename.liquid +1 -0
  31. data/lib/templates/android/enum.liquid +44 -0
  32. data/lib/templates/android/enum_filename.liquid +1 -0
  33. data/lib/templates/android/inc/_attributes_enum.liquid +17 -0
  34. data/lib/templates/android/inc/_attributes_getter_setter.liquid +58 -0
  35. data/lib/templates/android/inc/_attributes_properties.liquid +35 -0
  36. data/lib/templates/android/inc/_enum_getter_setter.liquid +19 -0
  37. data/lib/templates/android/inc/_primitives.liquid +30 -0
  38. data/lib/templates/android/inc/_relationships_enum.liquid +14 -0
  39. data/lib/templates/android/inc/_relationships_getter_setter.liquid +47 -0
  40. data/lib/templates/android/inc/_relationships_properties.liquid +27 -0
  41. data/lib/templates/android/inc/_type_converter.liquid +22 -0
  42. data/lib/templates/android/inc/_wrapper_type_converter.liquid +22 -0
  43. data/lib/templates/decodable/README.md +34 -0
  44. data/lib/templates/decodable/entity.liquid +57 -0
  45. data/lib/templates/decodable/entity_filename.liquid +1 -0
  46. data/lib/templates/decodable/enum.liquid +0 -0
  47. data/lib/templates/decodable/enum_filename.liquid +0 -0
  48. data/lib/templates/object-mapper/README.md +40 -0
  49. data/lib/templates/object-mapper/entity.liquid +66 -0
  50. data/lib/templates/object-mapper/entity_filename.liquid +1 -0
  51. data/lib/templates/object-mapper/enum.liquid +0 -0
  52. data/lib/templates/object-mapper/enum_filename.liquid +0 -0
  53. data/lib/templates/swift3-variant/README.md +60 -0
  54. data/lib/templates/swift3-variant/entity.liquid +12 -0
  55. data/lib/templates/swift3-variant/entity_filename.liquid +1 -0
  56. data/lib/templates/swift3-variant/enum.liquid +15 -0
  57. data/lib/templates/swift3-variant/enum_filename.liquid +1 -0
  58. data/lib/templates/swift3-variant/inc/_attributes_enum.liquid +13 -0
  59. data/lib/templates/swift3-variant/inc/_attributes_properties.liquid +32 -0
  60. data/lib/templates/swift3-variant/inc/_default_value_converter.liquid +14 -0
  61. data/lib/templates/swift3-variant/inc/_enum_attribute_property.liquid +26 -0
  62. data/lib/templates/swift3-variant/inc/_ignored_properties.liquid +24 -0
  63. data/lib/templates/swift3-variant/inc/_indexed_properties.liquid +19 -0
  64. data/lib/templates/swift3-variant/inc/_inverse_properties.liquid +11 -0
  65. data/lib/templates/swift3-variant/inc/_optional_attribute_property.liquid +5 -0
  66. data/lib/templates/swift3-variant/inc/_primary_key.liquid +5 -0
  67. data/lib/templates/swift3-variant/inc/_relationship_properties.liquid +9 -0
  68. data/lib/templates/swift3-variant/inc/_relationships_enum.liquid +17 -0
  69. data/lib/templates/swift3-variant/inc/_type_converter.liquid +20 -0
  70. data/lib/templates/swift3/README.md +60 -0
  71. data/lib/templates/swift3/entity.liquid +12 -0
  72. data/lib/templates/swift3/entity_filename.liquid +1 -0
  73. data/lib/templates/swift3/enum.liquid +15 -0
  74. data/lib/templates/swift3/enum_filename.liquid +1 -0
  75. data/lib/templates/swift3/inc/_attributes_enum.liquid +13 -0
  76. data/lib/templates/swift3/inc/_attributes_properties.liquid +32 -0
  77. data/lib/templates/swift3/inc/_default_value_converter.liquid +14 -0
  78. data/lib/templates/swift3/inc/_enum_attribute_property.liquid +26 -0
  79. data/lib/templates/swift3/inc/_ignored_properties.liquid +24 -0
  80. data/lib/templates/swift3/inc/_indexed_properties.liquid +19 -0
  81. data/lib/templates/swift3/inc/_inverse_properties.liquid +11 -0
  82. data/lib/templates/swift3/inc/_optional_attribute_property.liquid +5 -0
  83. data/lib/templates/swift3/inc/_primary_key.liquid +5 -0
  84. data/lib/templates/swift3/inc/_relationship_properties.liquid +9 -0
  85. data/lib/templates/swift3/inc/_relationships_enum.liquid +17 -0
  86. data/lib/templates/swift3/inc/_type_converter.liquid +20 -0
  87. metadata +134 -31
  88. data/lib/gyro/realm/java/converter.rb +0 -63
  89. data/lib/gyro/realm/java/enum_generator.rb +0 -128
  90. data/lib/gyro/realm/java/generator.rb +0 -183
  91. data/lib/gyro/realm/java/templates.rb +0 -67
  92. data/lib/gyro/realm/objc/converter.rb +0 -63
  93. data/lib/gyro/realm/objc/enum_generator.rb +0 -86
  94. data/lib/gyro/realm/objc/generator.rb +0 -373
  95. data/lib/gyro/realm/objc/json_category_generator.rb +0 -172
  96. data/lib/gyro/realm/objc/protocol_generator.rb +0 -59
  97. data/lib/gyro/realm/objc/templates.rb +0 -100
  98. data/lib/gyro/realm/swift/converter.rb +0 -74
  99. data/lib/gyro/realm/swift/enum_generator.rb +0 -73
  100. data/lib/gyro/realm/swift/generator.rb +0 -265
  101. data/lib/gyro/realm/swift/object_mapper_generator.rb +0 -124
  102. data/lib/gyro/realm/swift/templates.rb +0 -64
  103. data/lib/gyro/utils/file_utils.rb +0 -31
  104. data/lib/gyro/utils/log.rb +0 -68
  105. data/lib/gyro/utils/raise.rb +0 -23
  106. data/lib/gyro/utils/string_xcdatamodel.rb +0 -58
  107. data/lib/gyro/xcdatamodel/parser/attribute.rb +0 -98
  108. data/lib/gyro/xcdatamodel/parser/entity.rb +0 -234
  109. data/lib/gyro/xcdatamodel/parser/relationship.rb +0 -70
  110. data/lib/gyro/xcdatamodel/parser/xcdatamodel.rb +0 -59
@@ -0,0 +1,61 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'liquid'
16
+
17
+ if Gem::Version.new(Liquid::VERSION) < Gem::Version.new('4.0.0')
18
+ module Gyro
19
+ module Generator
20
+ # This allows to support whitespace trimming (which is only supported in Liquid 4) when using Liquid 3.0
21
+ # It works by patching Liquid::Template using ruby's `Module#prepend` feature
22
+ # See http://stackoverflow.com/a/4471202/803787 for more info on Monkey-Patching in Ruby
23
+ #
24
+ module LiquidWhitespacePatch
25
+ # Patch for Liquid::Template class
26
+ #
27
+ module Template
28
+ def parse(source, options = {})
29
+ super(source.gsub(/\s*{%-/, "\v{%").gsub(/-%}\s*/, "%}\v"), options)
30
+ end
31
+
32
+ def render(*params)
33
+ super(*params).delete("\v")
34
+ end
35
+ end
36
+
37
+ # Patch for Liquid's String extension
38
+ #
39
+ module String
40
+ def to_liquid
41
+ super.delete("\v")
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ module Liquid
49
+ # Monkey-Patch Liquid::Template class
50
+ #
51
+ class Template
52
+ prepend Gyro::Generator::LiquidWhitespacePatch::Template
53
+ end
54
+ end
55
+
56
+ # Monkey-Patch String
57
+ #
58
+ class String
59
+ prepend Gyro::Generator::LiquidWhitespacePatch::String
60
+ end
61
+ end
data/lib/gyro/log.rb ADDED
@@ -0,0 +1,46 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Gyro
16
+ # Print nice and colored output for various error/success/title messages of Gyro
17
+ #
18
+ module Log
19
+ @quiet = false
20
+ def self.quiet=(value)
21
+ @quiet = value
22
+ end
23
+
24
+ def self.title(str) # bg yellow
25
+ puts "\n\e[44;37m#{str}\e[0m" unless @quiet
26
+ end
27
+
28
+ def self.error(str)
29
+ puts "\e[1;31m! #{str}\e[0m" unless @quiet
30
+ end
31
+
32
+ def self.info(str)
33
+ puts "\e[1;33m> #{str}\e[0m" unless @quiet
34
+ end
35
+
36
+ def self.success(str)
37
+ puts "\e[1;32m√ #{str}\e[0m" unless @quiet
38
+ end
39
+
40
+ def self.fail!(message, stacktrace: false)
41
+ Gyro::Log.error message
42
+ raise message if stacktrace
43
+ exit 1
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'nokogiri'
16
+
17
+ require 'gyro/parser/xcdatamodel/xcdatamodel'
18
+ require 'gyro/parser/xcdatamodel/attribute'
19
+ require 'gyro/parser/xcdatamodel/relationship'
20
+ require 'gyro/parser/xcdatamodel/entity'
@@ -0,0 +1,129 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Gyro
16
+ module Parser
17
+ module XCDataModel
18
+ # One Attribute in an Entity of the xcdatamodel
19
+ #
20
+ class Attribute
21
+ attr_accessor :entity_name, :name, :type, :optional, :indexed, :default
22
+ attr_accessor :realm_ignored, :realm_read_only, :enum_type, :enum_values
23
+ attr_accessor :json_key_path, :json_values, :transformer, :comment, :support_annotation
24
+
25
+ alias optional? optional
26
+ alias indexed? indexed
27
+ alias realm_ignored? realm_ignored
28
+
29
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
30
+ def initialize(attribute_xml, entity_name)
31
+ @entity_name = entity_name
32
+ @name = attribute_xml.xpath('@name').to_s
33
+ @optional = attribute_xml.xpath('@optional').to_s == 'YES'
34
+ @indexed = attribute_xml.xpath('@indexed').to_s == 'YES'
35
+ @default = attribute_xml.xpath('@defaultValueString').to_s
36
+ @type = attribute_xml.xpath('@attributeType').to_s.downcase.tr(' ', '_').to_sym
37
+ @realm_ignored = !Gyro::Parser::XCDataModel.user_info(attribute_xml, 'realmIgnored').empty?
38
+ @realm_read_only = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'realmReadOnly')
39
+ @enum_type = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'enumType')
40
+ @enum_values = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'enumValues').split(',')
41
+ @json_key_path = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'JSONKeyPath')
42
+ @json_values = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'JSONValues').split(',')
43
+ @transformer = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'transformer').strip
44
+ @comment = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'comment')
45
+ @support_annotation = Gyro::Parser::XCDataModel.user_info(attribute_xml, 'supportAnnotation')
46
+ search_for_error
47
+ end
48
+
49
+ def to_h
50
+ {
51
+ 'entity_name' => entity_name, 'name' => name,
52
+ 'type' => type.to_s,
53
+ 'optional' => optional,
54
+ 'indexed' => indexed,
55
+ 'default' => default,
56
+ 'realm_ignored' => realm_ignored, 'realm_read_only' => realm_read_only,
57
+ 'enum_type' => enum_type, 'enum_values' => enum_values,
58
+ 'json_key_path' => json_key_path, 'json_values' => json_values,
59
+ 'transformer' => transformer, 'need_transformer' => need_transformer?,
60
+ 'comment' => comment,
61
+ 'support_annotation' => support_annotation,
62
+ 'is_decimal' => decimal?, 'is_integer' => integer?, 'is_number' => number?, 'is_bool' => bool?
63
+ }
64
+ end
65
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
66
+
67
+ def enum?
68
+ !@enum_type.empty?
69
+ end
70
+
71
+ def read_only?
72
+ !@realm_read_only.empty?
73
+ end
74
+
75
+ def default?
76
+ !@default.empty?
77
+ end
78
+
79
+ def to_s
80
+ items = [
81
+ "name=#{@name}",
82
+ "type=#{@type}",
83
+ "optional=#{@optional}",
84
+ "default=#{@default}",
85
+ "indexed=#{@indexed}"
86
+ ]
87
+ "\tAttribute => " + items.join(' | ') + "\n"
88
+ end
89
+
90
+ def decimal?
91
+ (@type == :decimal) || (@type == :double) || (@type == :float)
92
+ end
93
+
94
+ def integer?
95
+ (@type == :integer_16) || (@type == :integer_32) || (@type == :integer_64)
96
+ end
97
+
98
+ def number?
99
+ decimal? || integer?
100
+ end
101
+
102
+ def bool?
103
+ @type == :boolean
104
+ end
105
+
106
+ def need_transformer?
107
+ !@enum_type.empty? || (@type == :boolean) || (@type == :date) || !@transformer.empty?
108
+ end
109
+
110
+ private ################################################################
111
+
112
+ def search_for_error
113
+ # rubocop:disable Style/GuardClause
114
+ if @type == :undefined || @type.empty?
115
+ msg = %(The attribute "#{@name}" from "#{@entity_name}" has no type - please fix it)
116
+ Gyro::Log.fail!(msg, stacktrace: true)
117
+ end
118
+ if !@json_key_path.empty? && !@enum_values.empty? && (@enum_values.size != @json_values.size)
119
+ message = %(The attribute "#{@name}" from "#{@entity_name}" is wrongly annotated:) +
120
+ %(when declaring an type with enum and JSONKeyPath, you must have the same number of items) +
121
+ %(in the 'enumValues' and 'JSONValues' annotations.)
122
+ Gyro::Log.fail!(message, stacktrace: true)
123
+ end
124
+ # rubocop:enable Style/GuardClause
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,195 @@
1
+ # Copyright 2016 - Niji
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Gyro
16
+ module Parser
17
+ module XCDataModel
18
+ # One Entity in the xcdatamodel
19
+ #
20
+ class Entity
21
+ attr_accessor :name, :parent, :abstract, :attributes, :relationships, :identity_attribute, :comment
22
+ alias abstract? abstract
23
+
24
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
25
+ def initialize(entity_xml)
26
+ @name = entity_xml.xpath('@name').to_s
27
+ @parent = entity_xml.xpath('@parentEntity').to_s
28
+ @abstract = entity_xml.xpath('@isAbstract').to_s == 'YES' ? true : false
29
+ @clean = false
30
+ @identity_attribute = Gyro::Parser::XCDataModel.user_info(entity_xml, 'identityAttribute')
31
+ @comment = Gyro::Parser::XCDataModel.user_info(entity_xml, 'comment')
32
+ @attributes = {}
33
+ @relationships = {}
34
+ load_entity(entity_xml)
35
+ end
36
+
37
+ def to_h
38
+ {
39
+ 'attributes' => attributes.values.map(&:to_h),
40
+ 'relationships' => relationships.values.map(&:to_h),
41
+ 'name' => name,
42
+ 'parent' => parent,
43
+ 'abstract' => abstract,
44
+ 'identity_attribute' => identity_attribute,
45
+ 'comment' => comment,
46
+ 'has_no_inverse_relationship' => no_inverse_relationship?,
47
+ 'has_ignored' => ignored_attributes_relationships?, 'has_required' => required_attributes?,
48
+ 'has_primary_key' => primary_key?, 'has_indexed_attributes' => indexed_attributes?,
49
+ 'has_json_key_path' => json_key_paths?, 'has_enum_attributes' => enum_attributes?,
50
+ 'has_custom_transformers' => custom_transformers?, 'need_transformer' => need_transformer?,
51
+ 'has_bool_attributes' => bool_attributes?,
52
+ 'has_number_attributes' => number_attributes?,
53
+ 'has_date_attribute' => date_attributes?,
54
+ 'has_list_relationship' => list_relationships?,
55
+ 'has_list_attributes' => list_attributes?,
56
+ 'has_only_inverse' => only_inverse_relationships?
57
+ }
58
+ end
59
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
60
+
61
+ def to_s
62
+ "\nEntity => #{@name}\n" +
63
+ @attributes.map { |_, attr| attr.to_s } +
64
+ @relationships.map { |_, rel| rel.to_s }
65
+ end
66
+
67
+ def used_as_list_by_other?(entities)
68
+ entities.any? do |_, entity|
69
+ entity.relationships.any? do |_, relationship|
70
+ (relationship.inverse_type == @name) && (relationship.type == :to_many)
71
+ end
72
+ end
73
+ end
74
+
75
+ def list_attributes?(include_inverse = false)
76
+ @relationships.any? do |_, relationship|
77
+ (relationship.type == :to_many) && (include_inverse ? true : !relationship.inverse?)
78
+ end
79
+ end
80
+
81
+ def no_inverse_relationship?
82
+ @relationships.none? { |_, relationship| relationship.inverse? }
83
+ end
84
+
85
+ def ignored_attributes?
86
+ @attributes.any? { |_, attribute| attribute.realm_ignored? }
87
+ end
88
+
89
+ def ignored_relationships?
90
+ @relationships.any? { |_, relationship| relationship.realm_ignored? }
91
+ end
92
+
93
+ def ignored_attributes_relationships?
94
+ ignored_attributes? || ignored_relationships?
95
+ end
96
+
97
+ def primary_key?
98
+ !@identity_attribute.empty?
99
+ end
100
+
101
+ def required_attributes?
102
+ @attributes.any? { |_, attribute| required?(attribute) }
103
+ end
104
+
105
+ def required?(attribute)
106
+ return false if attribute.optional?
107
+ return true unless primary_key?
108
+ return true if primary_key? && !attribute.name.eql?(identity_attribute)
109
+ end
110
+
111
+ def default_value?(attribute)
112
+ attribute.name != @identity_attribute
113
+ end
114
+
115
+ def indexed_attributes?
116
+ @attributes.any? { |_, attribute| attribute.indexed? }
117
+ end
118
+
119
+ def json_key_paths?
120
+ @attributes.any? do |_, attribute|
121
+ !attribute.json_key_path.empty?
122
+ end || @relationships.any? do |_, relationship|
123
+ !relationship.inverse? && !relationship.json_key_path.empty?
124
+ end
125
+ end
126
+
127
+ def enum_attributes?
128
+ @attributes.any? { |_, attribute| !attribute.enum_type.empty? }
129
+ end
130
+
131
+ def transformers
132
+ transformers = Set.new
133
+ @attributes.each do |_, attribute|
134
+ transformers.add attribute.transformer unless attribute.transformer.empty?
135
+ end
136
+ transformers
137
+ end
138
+
139
+ def custom_transformers?
140
+ @attributes.any? { |_, attribute| !attribute.transformer.empty? }
141
+ end
142
+
143
+ def need_transformer?
144
+ enum_attributes? || bool_attributes? || custom_transformers? || date_attributes?
145
+ end
146
+
147
+ def bool_attributes?
148
+ @attributes.any? { |_, attribute| attribute.type == :boolean }
149
+ end
150
+
151
+ NUMBER_TYPES = %i[integer_16 integer_32 integer_64 decimal double float].freeze
152
+ def number_attributes?
153
+ @attributes.any? do |_, attribute|
154
+ attribute.enum_type.empty? && NUMBER_TYPES.include?(attribute.type)
155
+ end
156
+ end
157
+
158
+ def date_attributes?
159
+ @attributes.any? { |_, attribute| attribute.type == :date }
160
+ end
161
+
162
+ def list_relationships?
163
+ @relationships.any? { |_, relationship| !relationship.destination.empty? }
164
+ end
165
+
166
+ def only_inverse_relationships?
167
+ @relationships.all? { |_, relationship| relationship.inverse? }
168
+ end
169
+
170
+ private ################################################################
171
+
172
+ def load_entity(entity_xml)
173
+ load_attributes(entity_xml)
174
+ load_relationships(entity_xml)
175
+ end
176
+
177
+ def load_attributes(entity_xml)
178
+ entity_xml.xpath('attribute').each do |node|
179
+ attribute = Attribute.new(node, @name)
180
+ if attribute.type != 'Transformable'
181
+ @attributes[attribute.name] = attribute
182
+ end
183
+ end
184
+ end
185
+
186
+ def load_relationships(entity_xml)
187
+ entity_xml.xpath('relationship').each do |node|
188
+ relationship = Relationship.new(node, @name)
189
+ @relationships[relationship.name] = relationship
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end