gyro 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,172 @@
1
+ =begin
2
+ Copyright 2016 - Niji
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ require File.expand_path('templates', File.dirname(__FILE__))
18
+ require File.expand_path('../../utils/file_utils', File.dirname(__FILE__))
19
+ require File.expand_path('../../utils/string_xcdatamodel', File.dirname(__FILE__))
20
+
21
+ module Gyro
22
+ module Realm
23
+ module ObjC
24
+ module JSONCategoryGenerator
25
+
26
+ # INCLUDES #############################################################
27
+
28
+ include Templates
29
+
30
+ # PUBLIC METHODS #######################################################
31
+
32
+ def generate_objc_categories(path, xcdatamodel, framework = false)
33
+ json_path = File.join(path, 'JSON')
34
+ Dir.mkdir(json_path) unless Dir.exists?(json_path)
35
+ xcdatamodel.entities.each do |_, entity|
36
+ generate_json_category_file(json_path, entity, framework)
37
+ end
38
+ end
39
+
40
+ private #################################################################
41
+
42
+ def generate_json_category_file(path, entity, framework)
43
+ if !entity.attributes.empty? || !entity.relationships.empty?
44
+ source_file = generate_source_category_file(entity)
45
+ header_file = generate_header_category_file(entity, framework)
46
+ file_name = JSON_CATEGORY_NAME%[entity.name]
47
+ Gyro.write_file_with_name(path, HEADER_TEMPLATE%[file_name], header_file) unless header_file.empty?
48
+ Gyro.write_file_with_name(path, SOURCE_TEMPLATE%[file_name], source_file) unless source_file.empty?
49
+ end
50
+ end
51
+
52
+ def generate_header_category_file(entity, framework)
53
+ header_file = String.new
54
+ header_file << GENERATED_MESSAGE + "\n"
55
+ header_file << "\n" + SEPARATOR + "\n\n"
56
+ header_file << PRAGMA_MARK_IMPORTS + "\n\n"
57
+ header_file << (framework ? IMPORT_REALM_JSON_FRAMEWORK : IMPORT_REALM_JSON_LIBRARY) + "\n"
58
+ header_file << IMPORT_HEADER%[entity.name] + "\n"
59
+ header_file << "\n" + SEPARATOR + "\n\n"
60
+ header_file << PRAGMA_MARK_INTERFACE + "\n\n"
61
+ header_file << JSON_CATEGORY_INTERFACE%[entity.name] + "\n\n"
62
+ header_file << END_CODE + "\n"
63
+ header_file
64
+ end
65
+
66
+ def generate_source_category_file(entity)
67
+ source_file = String.new
68
+ source_file << GENERATED_MESSAGE + "\n"
69
+ source_file << "\n" + SEPARATOR + "\n\n"
70
+ source_file << PRAGMA_MARK_IMPORTS + "\n\n"
71
+ source_file << IMPORT_HEADER%[JSON_CATEGORY_NAME%[entity.name]] + "\n"
72
+ source_file << IMPORT_HEADER%[ENUM_FILE_NAME] + "\n" if entity.has_enum_attributes?
73
+ entity.transformers.each do |name|
74
+ source_file << IMPORT_HEADER%[name]+"\n"
75
+ end
76
+ source_file << "\n" + SEPARATOR + "\n\n"
77
+ source_file << PRAGMA_MARK_IMPLEMENTATION + "\n\n"
78
+ source_file << JSON_CATEGORY_IMPLEMENTATION%[entity.name] + "\n\n"
79
+ source_file << generate_mapping(entity)
80
+ source_file << "\n" + generate_json_transformers(entity) if entity.need_transformer?
81
+ source_file << "\n" + END_CODE + "\n"
82
+ source_file
83
+ end
84
+
85
+ def generate_mapping(entity)
86
+ inbound_mapping_string = '+ (NSDictionary *)JSONInboundMappingDictionary' + "\n"
87
+ inbound_mapping_string << '{' + "\n"
88
+ inbound_mapping_string << ' ' + 'return @{' + "\n"
89
+ outbound_mapping_string = '+ (NSDictionary *)JSONOutboundMappingDictionary' + "\n"
90
+ outbound_mapping_string << '{' + "\n"
91
+ outbound_mapping_string << ' '+ 'return @{' + "\n"
92
+
93
+ entity.attributes.each do |_, attribute|
94
+ json_value = attribute.json_key_path.empty? ? attribute.name.add_quotes : attribute.json_key_path.add_quotes
95
+ inbound_mapping_string << ' ' + DICTIONARY_JSON%[json_value, attribute.name.add_quotes] + "\n"
96
+ outbound_mapping_string << ' ' + DICTIONARY_JSON%[attribute.name.add_quotes, json_value] + "\n"
97
+ end
98
+
99
+ entity.relationships.each do |_, relationship|
100
+ json_value = relationship.json_key_path.empty? ? relationship.name.add_quotes : relationship.json_key_path.add_quotes
101
+ inbound_mapping_string << ' ' + DICTIONARY_JSON%[json_value, relationship.name.add_quotes] + "\n"
102
+ outbound_mapping_string << ' ' + DICTIONARY_JSON%[relationship.name.add_quotes, json_value] + "\n"
103
+ end
104
+
105
+ #delete last coma
106
+ inbound_mapping_string = inbound_mapping_string[0..inbound_mapping_string.length - 3] + "\n"
107
+ inbound_mapping_string << ' ' +'};' + "\n"
108
+ inbound_mapping_string << '}' + "\n\n"
109
+ outbound_mapping_string = outbound_mapping_string[0..outbound_mapping_string.length - 3] + "\n"
110
+ outbound_mapping_string << ' ' + '};' + "\n"
111
+ outbound_mapping_string << '}' + "\n"
112
+ inbound_mapping_string + outbound_mapping_string
113
+ end
114
+
115
+ def generate_json_transformers(entity)
116
+ json_transformer_string = String.new
117
+ first_transformer = true
118
+ entity.attributes.each do |(_, attribute)|
119
+ if attribute.need_transformer?
120
+ json_transformer_string << "\n" unless first_transformer
121
+ first_transformer = false
122
+ json_transformer_string << JSON_TRANSFORMER_DEF%[attribute.name] + "\n"
123
+ json_transformer_string << '{'+ "\n"
124
+ if !attribute.enum_type.empty? or attribute.type == :boolean # Enum | Boolean
125
+ json_transformer_string << ' ' + 'return [MCJSONValueTransformer valueTransformerWithMappingDictionary:@{' + "\n"
126
+ if attribute.type == :boolean
127
+ json_values = TRANSFORMER_BOOL_JSON
128
+ model_values = TRANSFORMER_BOOL_MODEL
129
+ else
130
+ if attribute.json_values.empty?
131
+ Raise::error("The attribute \"%s\" from \"%s\" is enum without JSONValues - please fix it"%[attribute.name, attribute.entity_name])
132
+ end
133
+ json_values = TRANSFORMER_ENUM_JSON + attribute.json_values.map { |enum| '@' + enum.add_quotes }
134
+ enums = attribute.enum_values
135
+ if attribute.optional?
136
+ default = attribute.enum_type + 'None'
137
+ else
138
+ default = enums[attribute.default.to_i]
139
+ end
140
+ model_values = [default, default, default] + enums
141
+ model_values = [default, default, default, default] + enums
142
+ end
143
+ json_transformer_string << format_json_transformers(json_values, model_values)
144
+
145
+ # delete last coma
146
+ json_transformer_string = json_transformer_string[0..json_transformer_string.length - 3] + "\n"
147
+ json_transformer_string << ' ' + '}];' + "\n"
148
+ else # custom transformer, or a default one
149
+ transformer = attribute.transformer
150
+ transformer = 'ISO8601DateTransform' if transformer.empty? && attribute.type == :date # default one for dates if none provided
151
+ json_transformer_string << ' ' + TRANSFORMER%[transformer] + "\n" unless transformer.empty?
152
+ end
153
+ json_transformer_string << '}' + "\n"
154
+ end
155
+ end
156
+ json_transformer_string
157
+ end
158
+
159
+ def format_json_transformers(json_values, model_values)
160
+ json_transformer_string = String.new
161
+ (0..model_values.length - 1).each { |enum|
162
+ json_value = json_values[enum]
163
+ enum_value = model_values[enum].add_parentheses
164
+ json_transformer_string << ' ' + DICTIONARY_JSON_CATEGORY%[json_value, enum_value] + "\n"
165
+ }
166
+ json_transformer_string
167
+ end
168
+
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,59 @@
1
+ =begin
2
+ Copyright 2016 - Niji
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ require File.expand_path('templates', File.dirname(__FILE__))
18
+ require File.expand_path('converter', File.dirname(__FILE__))
19
+ require File.expand_path('../../utils/string_xcdatamodel', File.dirname(__FILE__))
20
+ require File.expand_path('../../utils/file_utils', File.dirname(__FILE__))
21
+
22
+ module Gyro
23
+ module Realm
24
+ module ObjC
25
+ module ProtocolGenerator
26
+
27
+ # INCLUDES #############################################################
28
+
29
+ include Templates
30
+ include Converter
31
+
32
+ # PUBLIC METHODS #######################################################
33
+
34
+ def generate_protocol_file(path, xcdatamodel)
35
+ content = String.new
36
+ xcdatamodel.entities.each do |_, entity|
37
+ unless entity.abstract?
38
+ if entity.used_as_list_by_other?(xcdatamodel.entities)
39
+ content << protocol_file_template if content.empty?
40
+ content << REALM_LIST_TYPE_TEMPLATE%[entity.name, entity.name] + "\n"
41
+ end
42
+ end
43
+ end
44
+ Gyro.write_file_with_name(path, HEADER_TEMPLATE%[PROTOCOL_FILE_NAME], content) unless content.empty?
45
+ end
46
+
47
+ private ################################################################
48
+
49
+ def protocol_file_template
50
+ content = String.new
51
+ content << GENERATED_MESSAGE + "\n"
52
+ content << "\n" + SEPARATOR + "\n\n"
53
+ content << PRAGMA_MARK_PROTOCOLS + "\n\n"
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,100 @@
1
+ =begin
2
+ Copyright 2016 - Niji
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ module Gyro
18
+ module Realm
19
+ module ObjC
20
+ module Templates
21
+
22
+ # IMPORTS
23
+ IMPORT_REALM = '#import <Realm/Realm.h>'
24
+ IMPORT_HEADER = '#import "%s.h"'
25
+ IMPORT_REALM_JSON_LIBRARY = '#import <Realm+JSON/RLMObject+JSON.h>'
26
+ IMPORT_REALM_JSON_FRAMEWORK = '#import "RLMObject+JSON.h"'
27
+
28
+
29
+ # PRAGMA
30
+ PRAGMA_MARK_IMPORTS = '#pragma mark - Imports'
31
+ PRAGMA_MARK_TYPES = '#pragma mark - Types'
32
+ PRAGMA_MARK_CONSTANTS = '#pragma mark - Defines & Constants'
33
+ PRAGMA_MARK_INTERFACE = '#pragma mark - Interface'
34
+ PRAGMA_MARK_PROPERTIES = '#pragma mark - Properties'
35
+ PRAGMA_MARK_PROTOCOLS = '#pragma mark - Protocols'
36
+ PRAGMA_MARK_IMPLEMENTATION = '#pragma mark - Implementation'
37
+ PRAGMA_MARK_NUMBER_ACCESSORS = '#pragma mark - NSNumber Convenience Accessors'
38
+ PRAGMA_MARK_SUPER = '#pragma mark - Superclass Overrides'
39
+
40
+ # COMMONS
41
+ GENERATED_MESSAGE = '// DO NOT EDIT | Generated by gyro'
42
+ END_CODE = '@end'
43
+ SEPARATOR = '////////////////////////////////////////////////////////////////////////////////'
44
+ DICTIONARY_JSON = '@%s : @%s,'
45
+ DICTIONARY_DEFAULT = '@%s : %s,'
46
+ DICTIONARY_JSON_CATEGORY = '%s : @%s,'
47
+
48
+ # HEADER
49
+ HEADER_TEMPLATE = '%s.h'
50
+ NUMBER_TRANSFORMER_FILE_NAME = 'NFNumberTransformer'
51
+ CLASS_COMMENT_TEMPLATE = "/**\n * %s\n */"
52
+ CLASS_TEMPLATE = '@class %s;'
53
+ INTERFACE_TEMPLATE = '@interface %s : RLMObject'
54
+ PROPERTY_COMMENT_TEMPLATE = '/** %s */'
55
+ SIMPLE_PROPERTY_TEMPLATE = '@property %s%s;'
56
+ OBJECT_PROPERTY_TEMPLATE = '@property %s *%s;'
57
+ NUMBER_ACCESSOR_DECL_TEMPLATES = "-(%s)%sValue;\n-(void)set%sValue:(%s)value;\n"
58
+ LIST_TEMPLATE = 'NSArray<%s>'
59
+ REALM_LIST_TYPE_TEMPLATE = "// This protocol enables typed collections. i.e.: RLMArray<%s>\nRLM_ARRAY_TYPE(%s)"
60
+ REALM_LIST_TEMPLATE = 'RLMArray<%s>'
61
+
62
+ # COMMONS
63
+ CONSTANT_ATTRIBUTES_NAME = '%sAttributes'
64
+ CONSTANT_RELATIONSHIPS_NAME = '%sRelationships'
65
+ CONSTANT_HEADER_ATTRIBUTES = 'extern const struct %s {'
66
+ CONSTANT_HEADER_RELATIONSHIPS = 'extern const struct %s {'
67
+ CONSTANT_HEADER_ITEM = '__unsafe_unretained NSString *%s;'
68
+ CONSTANT_SOURCE_ATTRIBUTES = 'const struct %s %s = {'
69
+ CONSTANT_SOURCE_RELATIONSHIPS = 'const struct %s %s = {'
70
+ CONSTANT_SOURCE_ITEM = '.%s = @"%s"'
71
+
72
+ # ENUM
73
+ ENUM_TYPEDEF_TEMPLATE = 'typedef NS_ENUM(%s, %s) {'
74
+ ENUM_FILE_NAME = 'RLMTypes'
75
+ PROTOCOL_FILE_NAME = 'RLMProtocols'
76
+
77
+ # SOURCE
78
+ SOURCE_TEMPLATE = '%s.m'
79
+ IMPLEMENTATION_TEMPLATE = '@implementation %s'
80
+ ARRAY_TEMPLATE ='@%s, '
81
+ READ_ONLY_DEF_TEMPLATE = '- (%s)%s'
82
+ NUMBER_ACCESSOR_SOURCE_TEMPLATES = "-(%s)%sValue\n{\n return [self.%s %s];\n}\n-(void)set%sValue:(%s)value\n{\n self.%s = @(value);\n}"
83
+ INVERSE_DEF_TEMPLATE = '- (%s *)%s'
84
+ INVERSE_MANY_TEMPLATE = 'return [self linkingObjectsOfClass:@"%s" forProperty:@"%s"];'
85
+ INVERSE_ONE_TEMPLATE = 'return [[self linkingObjectsOfClass:@"%s" forProperty:@"%s"] objectAtIndex:0];'
86
+
87
+ # JSON_CATEGORY
88
+ JSON_CATEGORY_NAME = '%s+JSON'
89
+ JSON_TRANSFORMER_DEF = '+ (NSValueTransformer *)%sJSONTransformer'
90
+ JSON_CATEGORY_IMPLEMENTATION = '@implementation %s (JSON)'
91
+ JSON_CATEGORY_INTERFACE = '@interface %s (JSON)'
92
+ TRANSFORMER_BOOL_JSON = ['@"null"', '[NSNull null]', '@"<null>"', '@"false"', '@"true"', '@(NO)', '@(YES)']
93
+ TRANSFORMER_BOOL_MODEL = %w(NO NO NO NO YES NO YES)
94
+ TRANSFORMER_ENUM_JSON = ['@"null"', '[NSNull null]', '@"<null>"', '@""']
95
+ TRANSFORMER = 'return [[%s alloc] init];'
96
+
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,74 @@
1
+ =begin
2
+ Copyright 2016 - Niji
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ module Gyro
18
+ module Realm
19
+ module Swift
20
+ module Converter
21
+
22
+ TYPES = {
23
+ :integer_16 => 'Int16',
24
+ :integer_32 => 'Int32',
25
+ :integer_64 => 'Int64',
26
+ :decimal => 'Double',
27
+ :double => 'Double',
28
+ :float => 'Float',
29
+ :string => 'String',
30
+ :boolean => 'Bool',
31
+ :date => 'NSDate',
32
+ :binary => 'NSData'
33
+ }
34
+
35
+ DEFAULTS = {
36
+ :integer_16 => '0',
37
+ :integer_32 => '0',
38
+ :integer_64 => '0',
39
+ :decimal => '0.0',
40
+ :double => '0.0',
41
+ :float => '0.0',
42
+ :string => '""',
43
+ :boolean => 'false',
44
+ :date => 'NSDate()',
45
+ :binary => 'NSData()'
46
+ }
47
+
48
+ def convert_type(type)
49
+ TYPES[type]
50
+ end
51
+
52
+ def convert_default(type, value = nil)
53
+ if value.nil?
54
+ return DEFAULTS[type]
55
+ end
56
+ # Do some conversions for some special types
57
+ case [type, value]
58
+ when [:boolean, 'YES']
59
+ return 'true'
60
+ when [:boolean, 'NO']
61
+ return 'false'
62
+ else
63
+ return value
64
+ end
65
+ end
66
+
67
+ def is_number?(type)
68
+ type != :string && type != :date && type != :binary
69
+ end
70
+
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,73 @@
1
+ =begin
2
+ Copyright 2016 - Niji
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ =end
16
+
17
+ require File.expand_path('templates', File.dirname(__FILE__))
18
+ require File.expand_path('../../utils/string_xcdatamodel', File.dirname(__FILE__))
19
+ require File.expand_path('../../utils/file_utils', File.dirname(__FILE__))
20
+
21
+ module Gyro
22
+ module Realm
23
+ module Swift
24
+ module EnumGenerator
25
+
26
+ # INCLUDES #############################################################
27
+
28
+ include Templates
29
+
30
+ # PUBLIC METHODS #######################################################
31
+
32
+ def generate_enums(path, attributes)
33
+ enums = Array.new
34
+ attributes.each do |_, attribute|
35
+ if attribute.enum? and !enums.include?(attribute.enum_type)
36
+ enum_type = attribute.enum_type.delete_objc_prefix
37
+ enums.push(enum_type)
38
+ generate_enum(path, enum_type, attribute.enum_values, attribute.json_values)
39
+ end
40
+ end
41
+ end
42
+
43
+ private ################################################################
44
+
45
+ def generate_enum(path, enum_name, enum_values, raw_values)
46
+ enum_file = String.new
47
+ enum_file << GENERATED_MESSAGE + "\n\n"
48
+ enum_file << ENUM_STRING_DEF_TEMPLATE%[enum_name] + "\n"
49
+ raw_values = raw_values(enum_values, raw_values)
50
+ if !enum_values.empty? and raw_values.length == enum_values.length
51
+ (0..enum_values.length - 1).each { |idx|
52
+ enum_value = enum_values[idx].delete_objc_prefix
53
+ raw_value = raw_values[idx]
54
+ enum_file << ' ' + ENUM_STRING_CASE_TEMPLATE%[enum_value, raw_value] + "\n"
55
+ }
56
+ enum_file << '}' + "\n"
57
+ Gyro.write_file_with_name(path, SWIFT_FILE_TEMPLATE%[enum_name], enum_file)
58
+ end
59
+ end
60
+
61
+ def raw_values(enum_values, raw_values)
62
+ if raw_values.empty?
63
+ raw_values = enum_values.map { |value|
64
+ value.delete_objc_prefix.underscore
65
+ }
66
+ end
67
+ raw_values
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+ end