genio 1.0.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.
@@ -0,0 +1,30 @@
1
+ #
2
+ # Copyright 2013 PayPal Inc.
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
+ #
16
+ #
17
+ require 'logger'
18
+
19
+ module Genio
20
+ class << self
21
+ attr_accessor :logger
22
+ end
23
+ self.logger = Logger.new(STDERR)
24
+
25
+ module Logging
26
+ def logger
27
+ Genio.logger
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,246 @@
1
+ #
2
+ # Copyright 2013 PayPal Inc.
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
+ #
16
+ #
17
+ require "genio"
18
+ require "thor"
19
+ require "json"
20
+ require "uri"
21
+ require "genio/parser"
22
+ require "pp"
23
+
24
+ module Genio
25
+ class Tasks < Thor
26
+ include Thor::Actions
27
+ include Template
28
+
29
+ class_option :force, :type => :boolean, :default => false, :desc => "Overwrite files that already exist"
30
+ class_option :skip, :type => :boolean, :default => false, :desc => "Skip files that already exist"
31
+
32
+ # Schema path
33
+ class_option :json_schema, :type => :string, :desc => "JSON Schema path"
34
+ class_option :wsdl, :type => :string, :desc => "WSDL path"
35
+ class_option :wadl, :type => :string, :desc => "WADL path"
36
+ class_option :schema, :type => :string, :desc => "Any schema path"
37
+
38
+ class_option :output_path, :type => :string, :default => "output/stubs/"
39
+ class_option :namespace, :type => :string, :desc => "Dot separated package name"
40
+ class_option :gen_deprecated_methods, :type => :boolean, :default => false, :desc => "Generate deprecated version of methods using AccessToken parameter"
41
+
42
+
43
+ desc "java", "Generate rest java stubs"
44
+ method_option :mandate_oauth, :type => :boolean, :default => true,
45
+ :desc => "Force APIContext object to include oauth token"
46
+ def java
47
+ if schema.is_a? Parser::Format::Wsdl
48
+ java_with_wsdl
49
+ else
50
+ java_with_json_schema
51
+ end
52
+ end
53
+
54
+ desc "php", "Generate rest php stubs"
55
+ def php
56
+ if schema.is_a? Parser::Format::Wsdl
57
+ php_with_wsdl
58
+ else
59
+ php_with_json_schema
60
+ end
61
+ end
62
+
63
+ desc "dotnet", "Generate rest dotnet stubs"
64
+ method_option :mandate_oauth, :type => :boolean, :default => true,
65
+ :desc => "Force APIContext object to include oauth token"
66
+ def dotnet
67
+ if schema.is_a? Parser::Format::Wsdl
68
+ dotnet_with_wsdl
69
+ else
70
+ dotnet_with_json_schema
71
+ end
72
+ end
73
+
74
+ desc "iodocs", "Generate iodocs"
75
+ method_option :output_file, :type => :string, :default => "iodocs.json"
76
+ def iodocs
77
+ file = File.join(options[:output_path], options[:output_file])
78
+ create_file(file, JSON.pretty_generate(schema.to_iodocs))
79
+ end
80
+
81
+ private
82
+
83
+ def java_with_json_schema
84
+ folder = options[:output_path]
85
+ schema.data_types.each do|name, data_type|
86
+ package = options[:namespace] || convert_ns_to_package(data_type.package || schema.endpoint);
87
+ render("templates/sdk.rest_java.erb",
88
+ :data_type => data_type,
89
+ :classname => name,
90
+ :schema => schema,
91
+ :package => package,
92
+ :helper => Helper::Java,
93
+ :gen_deprecated_methods => options[:gen_deprecated_methods],
94
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{validate_file_name(name)}.java"))
95
+ end
96
+ render("templates/sdk.rest_version_java.erb",
97
+ :create_file => File.join(folder, "com/paypal/sdk/info/SDKVersionImpl.java"))
98
+ end
99
+
100
+ def java_with_wsdl
101
+ folder = options[:output_path]
102
+
103
+ # emit datatypes
104
+ schema.data_types.each do|name, data_type|
105
+ package = options[:namespace] || convert_ns_to_package(data_type.package)
106
+ render("templates/sdk.wsdl_java.erb",
107
+ :package => package,
108
+ :classname => name,
109
+ :schema => schema,
110
+ :data_type => data_type,
111
+ :helper => Helper::Java,
112
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{validate_file_name(name)}.java"))
113
+ end
114
+
115
+ # emit enumtypes
116
+ schema.enum_types.each do|name, definition|
117
+ package = options[:namespace] || convert_ns_to_package(definition.package)
118
+ render("templates/sdk.wsdlenum_java.erb",
119
+ :package => package,
120
+ :classname => name,
121
+ :definition => definition,
122
+ :helper => Helper::Java,
123
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{validate_file_name(name)}.java"))
124
+ end
125
+
126
+ # emit service
127
+ schema.services.each do|name, service|
128
+ package = options[:namespace] || convert_ns_to_package(service.package)
129
+ render("templates/sdk.wsdlservice_java.erb",
130
+ :package => package,
131
+ :classname => name,
132
+ :schema => schema,
133
+ :service => service,
134
+ :helper => Helper::Java,
135
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{validate_file_name(name)}.java"))
136
+ end
137
+ end
138
+
139
+ def php_with_json_schema
140
+ folder = options[:output_path]
141
+ schema.data_types.each do|name, data_type|
142
+ package = get_slashed_package_name(capitalize_package(remove_tld_in_package(convert_ns_to_package(options[:namespace] || data_type.package || schema.endpoint))))
143
+ render("templates/sdk.rest_php.erb",
144
+ :data_type => data_type,
145
+ :classname => name,
146
+ :schema => schema,
147
+ :package => package,
148
+ :helper => Helper::PHP,
149
+ :gen_deprecated_methods => options[:gen_deprecated_methods],
150
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{name}.php"))
151
+ end
152
+ end
153
+
154
+ def php_with_wsdl
155
+ folder = options[:output_path]
156
+ schema.data_types.each do|name, data_type|
157
+ package = get_slashed_package_name(capitalize_package(remove_tld_in_package(convert_ns_to_package(options[:namespace] || data_type.package || schema.endpoint))))
158
+ render("templates/sdk.wsdl_php.erb",
159
+ :data_type => data_type,
160
+ :classname => name,
161
+ :schema => schema,
162
+ :package => package,
163
+ :helper => Helper::PHP,
164
+ :gen_deprecated_methods => options[:gen_deprecated_methods],
165
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{name}.php"))
166
+ end
167
+
168
+ # emit service
169
+ schema.services.each do|name, service|
170
+ package = get_slashed_package_name(capitalize_package(remove_tld_in_package(convert_ns_to_package(options[:namespace] || service.package || schema.endpoint))))
171
+ render("templates/sdk.wsdlservice_php.erb",
172
+ :package => package,
173
+ :classname => name,
174
+ :schema => schema,
175
+ :service => service,
176
+ :helper => Helper::PHP,
177
+ :gen_deprecated_methods => options[:gen_deprecated_methods],
178
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{name}.php"))
179
+ end
180
+ end
181
+
182
+ def dotnet_with_json_schema
183
+ folder = options[:output_path]
184
+ schema.data_types.each do|name, data_type|
185
+ package = capitalize_package(remove_tld_in_package(convert_ns_to_package(options[:namespace] || data_type.package || schema.endpoint)))
186
+ render("templates/sdk.rest_dotnet.erb",
187
+ :data_type => data_type,
188
+ :classname => name,
189
+ :schema => schema,
190
+ :package => package,
191
+ :helper => Helper::DotNet,
192
+ :gen_deprecated_methods => options[:gen_deprecated_methods],
193
+ :create_file => File.join(folder, "#{get_package_folder(package, true)}/#{validate_file_name(name)}.cs"))
194
+ end
195
+ render("templates/sdk.rest_version_dotnet.erb",
196
+ :create_file => File.join(folder, "PayPal/Sdk/Info/SDKVersionImpl.cs"))
197
+ end
198
+
199
+ def dotnet_with_wsdl
200
+ folder = options[:output_path]
201
+
202
+ # emit datatypes
203
+ schema.data_types.each do|name, data_type|
204
+ package = capitalize_package(remove_tld_in_package(convert_ns_to_package(options[:namespace] || data_type.package)))
205
+ render("templates/sdk.wsdl_dotnet.erb",
206
+ :package => package,
207
+ :classname => name,
208
+ :schema => schema,
209
+ :data_type => data_type,
210
+ :helper => Helper::DotNet,
211
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{validate_file_name(name)}.cs"))
212
+ end
213
+
214
+ # emit enumtypes
215
+ schema.enum_types.each do|name, definition|
216
+ package = capitalize_package(remove_tld_in_package(convert_ns_to_package(options[:namespace] || definition.package)))
217
+ render("templates/sdk.wsdlenum_dotnet.erb",
218
+ :package => package,
219
+ :classname => name,
220
+ :definition => definition,
221
+ :helper => Helper::DotNet,
222
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{validate_file_name(name)}.cs"))
223
+ end
224
+
225
+ # emit service
226
+ schema.services.each do|name, service|
227
+ package = capitalize_package(remove_tld_in_package(convert_ns_to_package(options[:namespace] || service.package)))
228
+ render("templates/sdk.wsdlservice_dotnet.erb",
229
+ :package => package,
230
+ :classname => name,
231
+ :schema => schema,
232
+ :service => service,
233
+ :helper => Helper::DotNet,
234
+ :create_file => File.join(folder, "#{get_package_folder(package)}/#{validate_file_name(name)}.cs"))
235
+ end
236
+ end
237
+
238
+ # load the schema by choosing an appropriate parser
239
+ def schema
240
+ @schema ||= get_parser(options)
241
+ end
242
+
243
+ include Util::NamespaceHelper
244
+ include Util::SchemaHelper
245
+ end
246
+ end
@@ -0,0 +1,65 @@
1
+ #
2
+ # Copyright 2013 PayPal Inc.
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
+ #
16
+ #
17
+ require 'tilt'
18
+ require "thor"
19
+
20
+ module Genio
21
+ module Template
22
+ include Thor::Shell
23
+ include Thor::Actions
24
+
25
+ def render_values
26
+ @render_values ||= [{}]
27
+ end
28
+
29
+ def render(template, values = {})
30
+ values = { :create_file => nil }.merge(values)
31
+ values = render_values.last.merge(values)
32
+ values[:scope] ||= generate_scope(values)
33
+ render_values.push(values)
34
+ content = parse_erb(template, values)
35
+ render_values.pop
36
+ create_file(values[:create_file], content) if values[:create_file]
37
+ content
38
+ end
39
+
40
+ def generate_scope(values)
41
+ Class.new do
42
+ include values[:helper] if values[:helper]
43
+
44
+ def initialize(klass)
45
+ @klass = klass
46
+ end
47
+
48
+ def method_missing(name, *args)
49
+ @klass.send(name, *args)
50
+ end
51
+ end.new(self)
52
+ end
53
+
54
+ def parse_erb(template, values)
55
+ filename = File.absolute_path(template, template_path)
56
+ template = Tilt::ErubisTemplate.new(Dir["#{filename}*"].first || template)
57
+ template.render(values[:scope] || self, values)
58
+ end
59
+
60
+ def template_path
61
+ @template_path ||= File.expand_path("../../../", __FILE__)
62
+ end
63
+
64
+ end
65
+ end
@@ -0,0 +1,93 @@
1
+ #
2
+ # Copyright 2013 PayPal Inc.
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
+ #
16
+ #
17
+ module Genio
18
+ module Util
19
+ module NamespaceHelper
20
+
21
+ # Checks the format of the namespace as uri or urn,
22
+ # and converts the namespace to package name ('.' seperated)
23
+ # eg: http://github.paypal.com/payments/sale is changed to
24
+ # com.paypal.github.payments.sale
25
+ # eg: urn:ebay:apis:eBLBaseComponents is changed to
26
+ # urn.ebay.apis.eBLBaseComponents
27
+ # any numbers occuring as a part of path in the uri
28
+ # based namespaces is removed
29
+ def convert_ns_to_package(ns)
30
+ if is_urn_ns(ns)
31
+ packagename = ns.gsub(/:/, "\.")
32
+ else
33
+ hostname = URI.parse(ns)
34
+ packagename = hostname.host.sub(/^www./, "").split(".").reverse.join(".")
35
+ packagename << hostname.path.to_s.gsub(/[\d-]+/, "").sub(/\/+$/,'').gsub(/-/, '_').gsub(/\/+/, ".")
36
+ end
37
+ packagename
38
+ end
39
+
40
+ # Strips a package name off any
41
+ # Top Level Domains (TLD)s; com, co, org, gov, de, us, in
42
+ # eg: com.paypal.github.payments.sale is converted to
43
+ # paypal.github.payments.sale
44
+ def remove_tld_in_package(packagename)
45
+ packagename.sub(/^(com|co|org|gov|de|us|in)\./, "")
46
+ end
47
+
48
+ # Lowercases parts of a package name
49
+ # eg: Paypal.Github.Payments.Sale is converted to
50
+ # paypal.github.payments.sale
51
+ def lowercase_package(packagename)
52
+ packagename.gsub(/([^\.]+[\.]?)/){ |match| $1.camelcase(:lower) }
53
+ end
54
+
55
+ # Capitalizes parts of a package name
56
+ # eg: paypal.github.payments.sale is converted to
57
+ # Paypal.Github.Payments.Sale
58
+ def capitalize_package(packagename)
59
+ packagename.gsub(/([^\.]+[\.]?)/){ |match| $1.camelcase }
60
+ end
61
+
62
+ # Returns a folder path corresponding to the
63
+ # packagename; setting capitalize_folder true returns
64
+ # folder names that are captialized
65
+ def get_package_folder(packagename, capitalize_folder = false)
66
+ if (capitalize_folder)
67
+ capitalize_package(packagename).gsub(/\.|\\/, '/')
68
+ else
69
+ packagename.gsub(/\.|\\/, '/')
70
+ end
71
+ end
72
+
73
+ # Returns a namespace path with '\' corresponding to the
74
+ # packagename; setting capitalizefolder true returns
75
+ # names that are captialized
76
+ def get_slashed_package_name(packagename, capitalizefolder = false)
77
+ if (capitalizefolder)
78
+ capitalize_package(packagename).gsub(/\./, '\\')
79
+ else
80
+ packagename.gsub(/\./, '\\')
81
+ end
82
+ end
83
+
84
+ # Checks if the uri starts with protocol
85
+ # schemes and returns true, else treats
86
+ # the namespace as a Uniform Resource Name
87
+ def is_urn_ns(ns)
88
+ !ns.start_with?('http:','https:')
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,65 @@
1
+ require 'thor/error'
2
+
3
+ module Genio
4
+ module Util
5
+ module SchemaHelper
6
+
7
+ # Decide on a parser from the passed in URI and
8
+ # return the parser after loading the definition
9
+ # from the URI
10
+ def get_parser(options)
11
+ if options[:wsdl]
12
+ load_wsdl(options[:wsdl])
13
+ elsif options[:wadl]
14
+ load_wadl(options[:wadl])
15
+ elsif options[:json_schema]
16
+ load_json_schema(options[:json_schema])
17
+ elsif options[:schema]
18
+ get_parser_with_uri(options[:schema])
19
+ else
20
+ raise Thor::RequiredArgumentMissingError, "No value provided for required options '--json-schema' or '--wsdl' or '--wadl'"
21
+ end
22
+ end
23
+
24
+ def get_parser_with_uri(uri)
25
+ if (uri.end_with?('wadl'))
26
+ load_wadl(uri)
27
+ elsif (uri.end_with?('wsdl'))
28
+ load_wsdl(uri)
29
+ else
30
+ load_json_schema(uri)
31
+ end
32
+ end
33
+
34
+ def load_wsdl(path)
35
+ schema = Parser::Format::Wsdl.new
36
+ load_schema_uri(schema, path)
37
+ schema
38
+ end
39
+
40
+ def load_wadl(path)
41
+ schema = Parser::Format::Wadl.new
42
+ load_schema_uri(schema, path)
43
+ schema
44
+ end
45
+
46
+ def load_json_schema(path)
47
+ schema = Parser::Format::JsonSchema.new
48
+ load_schema_uri(schema, path)
49
+ schema.fix_unknown_service
50
+ schema
51
+ end
52
+
53
+ def load_schema_uri(parser, uri)
54
+ uri.split(/,/).each do |path|
55
+ parser.load(path)
56
+ end
57
+ end
58
+
59
+ # Replaces '-' with '_' and CamelCase(s)
60
+ def validate_file_name(name)
61
+ name.gsub(/-/, "_").camelcase
62
+ end
63
+ end
64
+ end
65
+ end