gyro 0.4.0
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 +7 -0
- data/LICENSE +201 -0
- data/README.md +840 -0
- data/bin/gyro +118 -0
- data/lib/gyro.rb +32 -0
- data/lib/gyro/realm/java/converter.rb +63 -0
- data/lib/gyro/realm/java/enum_generator.rb +128 -0
- data/lib/gyro/realm/java/generator.rb +183 -0
- data/lib/gyro/realm/java/templates.rb +67 -0
- data/lib/gyro/realm/objc/converter.rb +63 -0
- data/lib/gyro/realm/objc/enum_generator.rb +86 -0
- data/lib/gyro/realm/objc/generator.rb +373 -0
- data/lib/gyro/realm/objc/json_category_generator.rb +172 -0
- data/lib/gyro/realm/objc/protocol_generator.rb +59 -0
- data/lib/gyro/realm/objc/templates.rb +100 -0
- data/lib/gyro/realm/swift/converter.rb +74 -0
- data/lib/gyro/realm/swift/enum_generator.rb +73 -0
- data/lib/gyro/realm/swift/generator.rb +265 -0
- data/lib/gyro/realm/swift/object_mapper_generator.rb +124 -0
- data/lib/gyro/realm/swift/templates.rb +64 -0
- data/lib/gyro/utils/file_utils.rb +31 -0
- data/lib/gyro/utils/log.rb +68 -0
- data/lib/gyro/utils/raise.rb +23 -0
- data/lib/gyro/utils/string_xcdatamodel.rb +58 -0
- data/lib/gyro/xcdatamodel/parser/attribute.rb +98 -0
- data/lib/gyro/xcdatamodel/parser/entity.rb +234 -0
- data/lib/gyro/xcdatamodel/parser/relationship.rb +70 -0
- data/lib/gyro/xcdatamodel/parser/xcdatamodel.rb +59 -0
- metadata +77 -0
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
|