gyro 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/gyro ADDED
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ Copyright 2016 - Niji
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ if RUBY_VERSION < '2.0.0'
20
+ abort 'error: gyro requires Ruby 2 or higher.'
21
+ end
22
+
23
+ require 'gyro'
24
+ require 'optparse'
25
+
26
+ dir = Dir.pwd
27
+ options = {
28
+ :model => nil,
29
+ :android_dir => nil,
30
+ :package => nil,
31
+ :ios_dir => nil,
32
+ :ios_json => false,
33
+ :ios_framework => false,
34
+ :ios_swift => false
35
+ }
36
+
37
+ OptionParser.new do |opts|
38
+ opts.banner = 'Usage: gyro [options]'
39
+ opts.on('-m PATH', '--model PATH', %q(Specify Interface Builder .xcdatamodel file)) do |path|
40
+ options[:model] = path
41
+ end
42
+ opts.on('-a PATH', '--android PATH', %q(Specify Android Realm model classes dir)) do |path|
43
+ options[:android_dir] = path
44
+ end
45
+ opts.on('-p PATH', '--package PATH', %q(Specify Android Realm model classes package name)) do |path|
46
+ options[:package] = path
47
+ end
48
+ opts.on('-i PATH', '--ios PATH', %q(Specify iOS Realm model classes dir)) do |path|
49
+ options[:ios_dir] = path
50
+ end
51
+ opts.on('-j', '--json', %q(Additionally generate Realm-JSON categories (Objective-C) or ObjectMapper artifacts (Swift))) do
52
+ options[:ios_json] = true
53
+ end
54
+ opts.on('-f', '--framework', %q(If you use CocoaPods Frameworks instead of static libraries)) do
55
+ options[:ios_framework] = true
56
+ end
57
+ opts.on('-s', '--swift', %q(If you use Swift as iOS language)) do
58
+ options[:ios_swift] = true
59
+ end
60
+ opts.on('-n', '--nsnumber', %q(To generate NSNumbers instead of Int/BOOL/Float types)) do
61
+ options[:wrappers] = true
62
+ end
63
+ opts.on('-w', '--wrappers', %q(To generate Java primitive wrappers for optional fields instead of primitive types)) do
64
+ options[:wrappers] = true
65
+ end
66
+ opts.on('-x', '--annotations', %q(To tag code with Android support annotations according to optional/non optional fields)) do
67
+ options[:annotations] = true
68
+ end
69
+ opts.on_tail('-h', '--help', %q(Show this message)) { puts opts; exit 1 }
70
+ opts.on_tail('-v', '--version', 'Show version') { puts Gyro::VERSION; exit }
71
+ opts.parse!
72
+ end
73
+
74
+ if options[:model].nil?
75
+ Gyro::Log::info('No model provided, trying to find one in the local directory…')
76
+ options[:model] = Gyro.find_xcdatamodel(dir)
77
+ Gyro::Log::info("Unable to find any .xcdatamodel in #{dir}") if options[:model].nil?
78
+ end
79
+
80
+ if options[:model].nil?
81
+ Gyro.exit_with_error('You need to specify .xcdatamodel path using --model option (see --help for more info)')
82
+ else
83
+ basename = File.basename(options[:model])
84
+ dirname = File.dirname(options[:model])
85
+ Gyro::Log::success("Using #{basename} in #{dirname}")
86
+ end
87
+
88
+ # Android
89
+ if options[:android_dir].nil?
90
+ Gyro::Log::info('You need to specify a dir using --android option to generate Android Realm model classes (see --help for more info)')
91
+ else
92
+ if Dir.exist?(options[:android_dir])
93
+ if options[:package].nil?
94
+ Gyro::Log::info('You need to specify an Android package name using --package option (see --help for more info)')
95
+ else
96
+ xcdatamodel = Gyro::XCDataModel::Parser::XCDataModel.new(options[:model])
97
+ Gyro::Realm::Java::Generator.new(options[:android_dir], options[:package], xcdatamodel, options[:wrappers], options[:annotations])
98
+ end
99
+ else
100
+ Gyro::Log::info('You need to specify a valid Android Realm model classes dir')
101
+ end
102
+ end
103
+
104
+ # iOS
105
+ if options[:ios_dir].nil?
106
+ Gyro::Log::info('You need to specify a dir using --ios option to generate iOS Realm model classes (see --help for more info)')
107
+ else
108
+ if Dir.exist?(options[:ios_dir])
109
+ xcdatamodel = Gyro::XCDataModel::Parser::XCDataModel.new(options[:model])
110
+ if options[:ios_swift]
111
+ Gyro::Realm::Swift::Generator.new(options[:ios_dir], xcdatamodel, options[:ios_json])
112
+ else
113
+ Gyro::Realm::ObjC::Generator.new(options[:ios_dir], xcdatamodel, options[:ios_json], options[:ios_framework], options[:wrappers])
114
+ end
115
+ else
116
+ Gyro::Log::info('You need to specify a valid iOS Realm model classes dir')
117
+ end
118
+ end
data/lib/gyro.rb ADDED
@@ -0,0 +1,32 @@
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('gyro/xcdatamodel/parser/xcdatamodel', File.dirname(__FILE__))
18
+ require File.expand_path('gyro/realm/java/generator', File.dirname(__FILE__))
19
+ require File.expand_path('gyro/realm/objc/generator', File.dirname(__FILE__))
20
+ require File.expand_path('gyro/realm/swift/generator', File.dirname(__FILE__))
21
+ require File.expand_path('gyro/utils/log', File.dirname(__FILE__))
22
+ require File.expand_path('gyro/utils/file_utils', File.dirname(__FILE__))
23
+
24
+ module Gyro
25
+ VERSION = '0.4.0'
26
+
27
+ def self.exit_with_error(message)
28
+ Gyro::Log::error message
29
+ exit 1
30
+ end
31
+
32
+ end
@@ -0,0 +1,63 @@
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 Java
20
+ module Converter
21
+
22
+ TYPES = {
23
+ :integer_16 => 'short',
24
+ :integer_32 => 'int',
25
+ :integer_64 => 'long',
26
+ :decimal => 'double',
27
+ :double => 'double',
28
+ :float => 'float',
29
+ :string => 'String',
30
+ :boolean => 'boolean',
31
+ :date => 'Date',
32
+ :binary => 'byte[]'
33
+ }
34
+
35
+ WRAPPER_TYPES = {
36
+ :integer_16 => 'Short',
37
+ :integer_32 => 'Integer',
38
+ :integer_64 => 'Long',
39
+ :decimal => 'Double',
40
+ :double => 'Double',
41
+ :float => 'Float',
42
+ :string => 'String',
43
+ :boolean => 'Boolean',
44
+ :date => 'Date',
45
+ :binary => 'Byte[]'
46
+ }
47
+
48
+ def convert_type(type, useWrapperClass)
49
+ if (useWrapperClass)
50
+ WRAPPER_TYPES[type]
51
+ else
52
+ TYPES[type]
53
+ end
54
+ end
55
+
56
+ def is_primitive(type_str)
57
+ TYPES.has_value?(type_str) and type_str != "String" and type_str != "Date"
58
+ end
59
+
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,128 @@
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 Java
24
+ module EnumGenerator
25
+
26
+ # INCLUDES #############################################################
27
+ include Templates
28
+
29
+ # PUBLIC METHODS #######################################################
30
+
31
+ def generate_enums(path, package, attributes, support_annotations = false)
32
+ enums = Array.new
33
+ attributes.each do |_, attribute|
34
+ if attribute.enum? and !enums.include?(attribute.enum_type)
35
+ enum_type = attribute.enum_type.delete_objc_prefix
36
+ enums.push(enum_type)
37
+ generate_enum(path, package, enum_type, attribute.enum_values, attribute.json_values, support_annotations)
38
+ end
39
+ end
40
+ end
41
+
42
+ def generate_enum_getter_and_setter(enum_type, attribute_name, support_annotations)
43
+ getter = String.new
44
+ setter = String.new
45
+ getter << ' ' + '@android.support.annotation.Nullable' + "\n" if support_annotations
46
+ getter << ' public ' + enum_type + ' get'+ attribute_name.capitalize_first_letter + 'Enum() {' + "\n" +
47
+ ' ' + 'return '+ enum_type + '.get(get' + attribute_name.capitalize_first_letter + '());' + "\n" +
48
+ ' ' + '}' + "\n"
49
+ setter << ' ' + 'public void set'+ attribute_name.capitalize_first_letter + 'Enum('
50
+ setter << '@android.support.annotation.NonNull ' if support_annotations
51
+ setter << 'final ' + enum_type + ' ' + attribute_name +') {' + "\n" +
52
+ ' ' + 'this.' + attribute_name + ' = ' + attribute_name + '.getJsonValue();' + "\n" +
53
+ ' ' + '}' + "\n"
54
+ getter + "\n" + setter
55
+ end
56
+
57
+ private #################################################################
58
+
59
+ def generate_enum(path, package, enum_name, enum_values, json_values, support_annotations)
60
+ enum_file = String.new
61
+ enum_file << PACKAGE_TEMPLATE%[package] + "\n\n"
62
+ enum_file << GENERATED_MESSAGE + "\n\n"
63
+ enum_file << ENUM_TEMPLATE%[enum_name] + "\n\n"
64
+ json_values = get_json_values(enum_values, json_values)
65
+ if enum_values.length != 0
66
+ (0..enum_values.length - 1).each { |idx|
67
+ gson_value = json_values[idx]
68
+ enum_value = generate_enum_string(enum_values[idx], gson_value)
69
+ enum_file << (idx != enum_values.length - 1 ? enum_value + ",\n" : enum_value + ";\n")
70
+ }
71
+ enum_file << "\n" ' ' + FINAL_ATTRIBUTE_TEMPLATE%%w(String jsonValue) + "\n\n"
72
+ enum_file << generate_enum_gson_constructor(enum_name) + "\n"
73
+ enum_file << generate_static_gson_getter(enum_name, support_annotations) + "\n"
74
+ enum_file << generate_gson_getter(support_annotations)
75
+ enum_file << '}' + "\n"
76
+ Gyro.write_file_with_name(path, JAVA_FILE_TEMPLATE%[enum_name], enum_file)
77
+ end
78
+ end
79
+
80
+ def generate_enum_string(enum_value, gson_value)
81
+ enum_value = enum_value.delete_objc_prefix.camel_case
82
+ gson_annotation = gson_value.empty? ? '' : ENUM_JSON_VALUE%[gson_value]
83
+ ' ' + enum_value + gson_annotation
84
+ end
85
+
86
+ def generate_enum_gson_constructor(enum_name)
87
+ ' ' + enum_name +'(final String jsonValue) {' + "\n" +
88
+ ' ' + 'this.jsonValue = jsonValue;' + "\n" +
89
+ ' ' + '}' + "\n"
90
+ end
91
+
92
+ # Methods to bypass enum restriction in Realm
93
+ def generate_static_gson_getter(enum_name, support_annotations)
94
+ getter = String.new
95
+ getter << ' @android.support.annotation.Nullable' + "\n" if support_annotations
96
+ getter << ' public static ' + enum_name + ' get(final String jsonValue) {' + "\n" +
97
+ ' ' + 'for (final ' + enum_name + ' type : ' + enum_name + '.values()) {' + "\n" +
98
+ ' ' + 'if (type.getJsonValue().equals(jsonValue)) {' + "\n" +
99
+ ' ' + 'return type;' + "\n" +
100
+ ' ' + '}'+ "\n" +
101
+ ' ' + '}' + "\n" +
102
+ ' ' + 'return null;' + "\n" +
103
+ ' ' + '}' + "\n"
104
+ getter
105
+ end
106
+
107
+ def generate_gson_getter(support_annotations)
108
+ getter = String.new
109
+ getter << ' @android.support.annotation.NonNull' + "\n" if support_annotations
110
+ getter << ' ' + 'public String getJsonValue() {' + "\n" +
111
+ ' ' + 'return jsonValue;' + "\n" +
112
+ ' ' + '}' + "\n"
113
+ getter
114
+ end
115
+
116
+ def get_json_values(enum_values, json_values)
117
+ if json_values.empty?
118
+ enum_values.each { |value|
119
+ json_values << value.delete_objc_prefix.underscore
120
+ }
121
+ end
122
+ json_values
123
+ end
124
+
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,183 @@
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('../../utils/log', 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
+ require File.expand_path('../../xcdatamodel/parser/relationship', File.dirname(__FILE__))
21
+ require File.expand_path('converter', File.dirname(__FILE__))
22
+ require File.expand_path('enum_generator', File.dirname(__FILE__))
23
+ require File.expand_path('templates', File.dirname(__FILE__))
24
+
25
+ module Gyro
26
+ module Realm
27
+ module Java
28
+
29
+ class Generator
30
+
31
+ # INCLUDES #############################################################
32
+
33
+ include Gyro::XCDataModel::Parser
34
+ include Converter
35
+ include EnumGenerator
36
+ include Templates
37
+
38
+ # PUBLIC METHODS #######################################################
39
+
40
+ def initialize(path, package_name, xcdatamodel, use_wrappers = false, support_annotations = false)
41
+ puts "\n"
42
+ Gyro::Log::title('Android Realm')
43
+ xcdatamodel.entities.each do |_, entity|
44
+ unless entity.abstract?
45
+ Gyro::Log::success("Generating entity #{entity.name}...")
46
+ generate_class(path, package_name, entity, use_wrappers, support_annotations)
47
+ end
48
+ end
49
+ end
50
+
51
+ private ################################################################
52
+
53
+ def generate_class(path, package, entity, use_wrappers, support_annotations)
54
+ class_file = String.new
55
+ entity.name = entity.name.delete_objc_prefix
56
+ generate_header(class_file, package, entity)
57
+ generate_attributes(class_file, entity.attributes, entity.relationships, entity.identity_attribute, use_wrappers, support_annotations)
58
+ generate_footer(class_file)
59
+ Gyro.write_file_with_name(path, JAVA_FILE_TEMPLATE%[entity.name], class_file)
60
+ generate_enums(path, package, entity.attributes, support_annotations)
61
+ end
62
+
63
+ def generate_header(class_file, package, entity)
64
+ class_file << PACKAGE_TEMPLATE%[package] + "\n\n"
65
+ class_file << IMPORT_GSON + "\n\n" if entity.has_json_key_path?
66
+ class_file << IMPORT_DATE + "\n" if entity.has_date_attribute?
67
+ class_file << IMPORT_LIST + "\n" if entity.has_list_relationship?
68
+ class_file << "\n" if entity.has_date_attribute? or entity.has_list_relationship?
69
+ class_file << IMPORT_REALM_LIST + "\n" if entity.has_list_attributes?
70
+ class_file << IMPORT_REALM_OBJECT + "\n"
71
+ class_file << IMPORT_REALM_IGNORE + "\n" if entity.has_ignored? or entity.has_enum_attributes?
72
+ class_file << IMPORT_REALM_INDEX + "\n" if entity.has_indexed_attributes?
73
+ class_file << IMPORT_REALM_PRIMARY_KEY + "\n" if entity.has_primary_key?
74
+ class_file << "\n" if class_file != PACKAGE_TEMPLATE%[package]
75
+ class_file << GENERATED_MESSAGE + "\n\n"
76
+ class_file << CLASS_COMMENT_TEMPLATE%[entity.comment] + "\n" unless entity.comment.empty?
77
+ class_file << CLASS_TEMPLATE%[entity.name] + "\n\n"
78
+ class_file << generate_constants(entity)
79
+ end
80
+
81
+ def generate_constants(entity)
82
+ attribute_constants = String.new
83
+ unless entity.attributes.empty?
84
+ attribute_constants << ' ' + ATTRIBUTE_CONSTANTS + "\n"
85
+ entity.attributes.each do |_, attribute|
86
+ unless attribute.realm_ignored? or attribute.read_only?
87
+ attribute_constants << ' ' + ATTRIBUTE_COMMENT_TEMPLATE%[attribute.comment] + "\n" unless attribute.comment.empty?
88
+ attribute_constants << ' ' + CONSTANT_TEMPLATE%[attribute.name.underscore.upcase, attribute.name] + "\n"
89
+ end
90
+ end
91
+ attribute_constants << ' ' + '}'+ "\n\n"
92
+ end
93
+ relationship_constants = String.new
94
+ if not entity.relationships.empty? and not entity.has_only_inverse?
95
+ relationship_constants << ' ' + RELATIONSHIP_CONSTANTS + "\n"
96
+ entity.relationships.each do |_, relationship|
97
+ relationship_constants << ' ' + CONSTANT_TEMPLATE%[relationship.name.underscore.upcase, relationship.name] + "\n" unless relationship.inverse?
98
+ end
99
+ relationship_constants << ' ' + '}'+ "\n\n"
100
+ end
101
+ attribute_constants + relationship_constants
102
+ end
103
+
104
+ def generate_footer(class_file)
105
+ class_file << '}' + "\n"
106
+ end
107
+
108
+ def generate_attributes(class_file, attributes, relationships, primary_key, use_wrappers, support_annotations)
109
+ # "NORMAL" ATTRIBUTES
110
+ (attributes_string, getters_and_setters_string) = write_attributes(attributes, primary_key, use_wrappers, support_annotations)
111
+ # "RELATIONSHIP" ATTRIBUTES
112
+ relationships.each do |_, relationship|
113
+ unless relationship.inverse?
114
+ if relationship.destination.empty?
115
+ type_without_prefix = relationship.inverse_type.delete_objc_prefix
116
+ type = relationship.type == :to_many ? REALM_LIST_TEMPLATE%[type_without_prefix] : type_without_prefix
117
+ name = relationship.name
118
+ else
119
+ type = LIST_TEMPLATE%[relationship.destination]
120
+ name = relationship.name
121
+ end
122
+ attributes_string << ' ' + IGNORED_ANNOTATION + "\n" if relationship.realm_ignored?
123
+ attributes_string << ' ' + GSON_ANNOTATION%[relationship.json_key_path]+ "\n" unless relationship.json_key_path.empty?
124
+ attributes_string << ' ' + ATTRIBUTE_TEMPLATE%[type, name] + "\n"
125
+ getters_and_setters_string << "\n" unless getters_and_setters_string.empty?
126
+ getters_and_setters_string << generate_getter_and_setter(type, name, (support_annotations and relationship.optional), (support_annotations and !relationship.optional), relationship.support_annotation)
127
+ end
128
+ end
129
+ class_file << attributes_string + "\n" + getters_and_setters_string
130
+ end
131
+
132
+ def write_attributes(attributes, primary_key, use_wrappers, support_annotations)
133
+ attributes_string = String.new
134
+ getters_and_setters_string = String.new
135
+ attributes.each_with_index do |(_, attribute), idx|
136
+ unless attribute.read_only?
137
+ name = attribute.name
138
+ type = attribute.enum? ? 'String' : convert_type(attribute.type, (use_wrappers and attribute.optional))
139
+ if type
140
+ # Realm annotations
141
+ attributes_string << ' ' + PRIMARY_KEY_ANNOTATION + "\n" if name == primary_key
142
+ attributes_string << ' ' + INDEXED_ANNOTATION + "\n" if attribute.indexed
143
+ attributes_string << ' ' + IGNORED_ANNOTATION + "\n" if attribute.realm_ignored? or attribute.enum?
144
+ if attribute.enum?
145
+ ignored_type = attribute.enum? ? attribute.enum_type.delete_objc_prefix : type
146
+ ignored_name = attribute.enum? ? name + 'Enum' : name
147
+ attributes_string << ' ' + ATTRIBUTE_TEMPLATE%[ignored_type, ignored_name] + "\n"
148
+ end
149
+ attributes_string << ' ' + GSON_ANNOTATION%[attribute.json_key_path]+ "\n" unless attribute.json_key_path.empty?
150
+ attributes_string << ' ' + SUPPORT_ANNOTATION%[attribute.support_annotation] + "\n" unless attribute.support_annotation.empty?
151
+ attributes_string << ' ' + ATTRIBUTE_TEMPLATE%[type, name] + "\n"
152
+ end
153
+ getters_and_setters_string << generate_getter_and_setter(type, name, (support_annotations and ((use_wrappers and attribute.optional) or (attribute.enum? and attribute.optional))), (support_annotations and ((!is_primitive(type) and !attribute.optional) or (attribute.enum? and !attribute.optional))), attribute.support_annotation)
154
+ getters_and_setters_string << "\n" + generate_enum_getter_and_setter(attribute.enum_type.delete_objc_prefix, name, support_annotations) if attribute.enum?
155
+ getters_and_setters_string << "\n" if idx != attributes.count - 1
156
+ end
157
+ end
158
+ return attributes_string, getters_and_setters_string
159
+ end
160
+
161
+ def generate_getter_and_setter(type, name, nullable, nonnull, support_annotation)
162
+ getter_setter = String.new
163
+ getter_setter << ' ' + SUPPORT_ANNOTATION%['Nullable'] + "\n" if nullable
164
+ getter_setter << ' ' + SUPPORT_ANNOTATION%['NonNull'] + "\n" if nonnull
165
+ getter_setter << ' ' + SUPPORT_ANNOTATION%[support_annotation] + "\n" unless support_annotation.empty?
166
+ getter_setter << ' ' + 'public ' + type + ' get' + name.capitalize_first_letter + '() {' + "\n"
167
+ getter_setter << ' ' + 'return '+ name + ';' + "\n"
168
+ getter_setter << ' ' + '}' + "\n\n"
169
+ getter_setter << ' ' + 'public void set' + name.capitalize_first_letter + '('
170
+ getter_setter << SUPPORT_ANNOTATION%['Nullable'] + ' ' if nullable
171
+ getter_setter << SUPPORT_ANNOTATION%['NonNull'] + ' ' if nonnull
172
+ getter_setter << SUPPORT_ANNOTATION%[support_annotation] + ' ' unless support_annotation.empty?
173
+ getter_setter << 'final ' + type + ' ' + name + ') {' + "\n"
174
+ getter_setter << ' ' + 'this.' + name + ' = ' + name + ';' + "\n"
175
+ getter_setter << ' ' + '}' + "\n"
176
+ getter_setter
177
+ end
178
+
179
+ end
180
+
181
+ end
182
+ end
183
+ end