rpcoder 0.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.
- data/Gemfile +16 -0
- data/Gemfile.lock +35 -0
- data/LICENSE +21 -0
- data/README.rdoc +21 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/lib/rpcoder.rb +92 -0
- data/lib/rpcoder/function.rb +41 -0
- data/lib/rpcoder/type.rb +49 -0
- data/lib/templates/API.erb +147 -0
- data/lib/templates/Type.erb +39 -0
- data/mock/build.xml +70 -0
- data/mock/lib/as3corelib.swc +0 -0
- data/mock/lib/flexUnitTasks-4.0.0.jar +0 -0
- data/mock/lib/flexunit-4.0.0.swc +0 -0
- data/mock/lib/flexunit-cilistener-4.0.0.swc +0 -0
- data/mock/lib/flexunit-flexcoverlistener-4.0.0.swc +0 -0
- data/mock/lib/flexunit-uilistener-4.0.0.swc +0 -0
- data/mock/lib/hamcrest-as3-1.1.1.swc +0 -0
- data/mock/lib/mockolate-0.9.3.swc +0 -0
- data/mock/mock_rpcoder.rb +46 -0
- data/mock/mock_server.rb +34 -0
- data/mock/src/Mock.mxml +62 -0
- data/mock/src_test/FlexUnitRunner.mxml +27 -0
- data/mock/src_test/TestSuite.as +10 -0
- data/mock/src_test/com/oneup/rpcoder/test/APITest.as +76 -0
- data/mock/src_test/com/oneup/rpcoder/test/TypeTest.as +25 -0
- data/rpcoder.gemspec +92 -0
- data/spec/fixtures/foo/bar/API.as +139 -0
- data/spec/fixtures/foo/bar/Mail.as +34 -0
- data/spec/rpcoder/function_spec.rb +52 -0
- data/spec/rpcoder_spec.rb +46 -0
- data/spec/spec_helper.rb +12 -0
- metadata +158 -0
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "rspec", ">= 0"
|
10
|
+
gem "bundler", "~> 1.0.0"
|
11
|
+
gem "jeweler", "~> 1.5.2"
|
12
|
+
gem "rcov", ">= 0"
|
13
|
+
gem "rake", ">= 0"
|
14
|
+
end
|
15
|
+
|
16
|
+
gem "sinatra"
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.2)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.5.2)
|
7
|
+
bundler (~> 1.0.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rack (1.2.2)
|
11
|
+
rake (0.8.7)
|
12
|
+
rcov (0.9.9)
|
13
|
+
rspec (2.5.0)
|
14
|
+
rspec-core (~> 2.5.0)
|
15
|
+
rspec-expectations (~> 2.5.0)
|
16
|
+
rspec-mocks (~> 2.5.0)
|
17
|
+
rspec-core (2.5.1)
|
18
|
+
rspec-expectations (2.5.0)
|
19
|
+
diff-lcs (~> 1.1.2)
|
20
|
+
rspec-mocks (2.5.0)
|
21
|
+
sinatra (1.2.3)
|
22
|
+
rack (~> 1.1)
|
23
|
+
tilt (< 2.0, >= 1.2.2)
|
24
|
+
tilt (1.2.2)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
bundler (~> 1.0.0)
|
31
|
+
jeweler (~> 1.5.2)
|
32
|
+
rake
|
33
|
+
rcov
|
34
|
+
rspec
|
35
|
+
sinatra
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2009 jugyo
|
2
|
+
Copyright (c) 2011 tosik
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= rpcoder
|
2
|
+
|
3
|
+
mock/mock_rpcoder.rb を見ると使い方がなんとなくわかると思います。
|
4
|
+
|
5
|
+
== Mock API の作成
|
6
|
+
|
7
|
+
$ ruby mock/mock_rpcoder.rb
|
8
|
+
|
9
|
+
== Mock swf のビルド
|
10
|
+
|
11
|
+
$ cd mock
|
12
|
+
$ ant
|
13
|
+
|
14
|
+
== Mock Server の起動
|
15
|
+
|
16
|
+
$ ruby mock/mock_server.rb
|
17
|
+
|
18
|
+
== as3 のテストの実行
|
19
|
+
|
20
|
+
$ cd spec
|
21
|
+
$ ant
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "rpcoder"
|
16
|
+
gem.homepage = "http://github.com/one-up/rpcoder"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Simple RPC generator for as3}
|
19
|
+
gem.description = %Q{Simple RPC generator for as3}
|
20
|
+
gem.email = "toshi.hirooka@gmail.com"
|
21
|
+
gem.authors = ["jugyo", "Toshiyuki Hirooka"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "rpcoder #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/lib/rpcoder.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
require 'rpcoder/function'
|
5
|
+
require 'rpcoder/type'
|
6
|
+
|
7
|
+
module RPCoder
|
8
|
+
class << self
|
9
|
+
def name_space=(name_space)
|
10
|
+
@name_space = name_space
|
11
|
+
end
|
12
|
+
|
13
|
+
def name_space
|
14
|
+
@name_space
|
15
|
+
end
|
16
|
+
|
17
|
+
def api_class_name=(name)
|
18
|
+
@api_class_name = name
|
19
|
+
end
|
20
|
+
|
21
|
+
def api_class_name
|
22
|
+
@api_class_name
|
23
|
+
end
|
24
|
+
|
25
|
+
def types
|
26
|
+
@types ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def type(name)
|
30
|
+
type = Type.new
|
31
|
+
type.name = name
|
32
|
+
yield type
|
33
|
+
types << type
|
34
|
+
type
|
35
|
+
end
|
36
|
+
|
37
|
+
def functions
|
38
|
+
@functions ||= []
|
39
|
+
end
|
40
|
+
|
41
|
+
def function(name)
|
42
|
+
func = Function.new
|
43
|
+
func.name = name
|
44
|
+
yield func
|
45
|
+
functions << func
|
46
|
+
func
|
47
|
+
end
|
48
|
+
|
49
|
+
def export(dir)
|
50
|
+
class_dir = dir_to_export_classes(dir)
|
51
|
+
FileUtils.mkdir_p(class_dir)
|
52
|
+
|
53
|
+
export_functions(File.join(class_dir, api_class_name.split('.').last + ".as"))
|
54
|
+
types.each { |type| export_type(type, File.join(class_dir, "#{type.name}.as")) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def export_functions(path)
|
58
|
+
puts "API: #{path}"
|
59
|
+
File.open(path, "w") { |file| file << render_functions }
|
60
|
+
end
|
61
|
+
|
62
|
+
def render_functions
|
63
|
+
render_erb('API.erb', binding)
|
64
|
+
end
|
65
|
+
|
66
|
+
def export_type(type, path)
|
67
|
+
puts "Type: #{path}"
|
68
|
+
File.open(path, "w") { |file| file << render_type(type) }
|
69
|
+
end
|
70
|
+
|
71
|
+
def render_type(type)
|
72
|
+
render_erb('Type.erb', binding)
|
73
|
+
end
|
74
|
+
|
75
|
+
def render_erb(template, _binding)
|
76
|
+
ERB.new(File.read(template_path(template)), nil, '-').result(_binding)
|
77
|
+
end
|
78
|
+
|
79
|
+
def template_path(name)
|
80
|
+
File.join File.dirname(__FILE__), 'templates', name
|
81
|
+
end
|
82
|
+
|
83
|
+
def dir_to_export_classes(dir)
|
84
|
+
File.join(dir, *name_space.split('.'))
|
85
|
+
end
|
86
|
+
|
87
|
+
def clear
|
88
|
+
functions.clear
|
89
|
+
types.clear
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RPCoder
|
2
|
+
class Function
|
3
|
+
PARAMS_IN_URL_RE = /:[\w\d]+/
|
4
|
+
attr_accessor :name, :description, :path, :method, :return_type
|
5
|
+
|
6
|
+
def params
|
7
|
+
@params ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_param(name, type, options = {})
|
11
|
+
params << Param.new(name, type, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def path_parts
|
15
|
+
raise "path must starts with `/`: #{path}" unless path =~ /^\//
|
16
|
+
|
17
|
+
path_strs = path.split(PARAMS_IN_URL_RE)
|
18
|
+
params = path.scan(PARAMS_IN_URL_RE)
|
19
|
+
parts = []
|
20
|
+
([path_strs.size, params.size].max).times do |variable|
|
21
|
+
parts << %Q{"#{path_strs.shift}"}
|
22
|
+
parts << params.shift.sub(/^:/, '') rescue nil
|
23
|
+
end
|
24
|
+
parts
|
25
|
+
end
|
26
|
+
|
27
|
+
def query_params
|
28
|
+
param_strs = path.scan(PARAMS_IN_URL_RE).map { |i| i.sub(/^:/, '') }
|
29
|
+
params.select { |i| !param_strs.include?(i.name.to_s) }
|
30
|
+
end
|
31
|
+
|
32
|
+
class Param
|
33
|
+
attr_accessor :name, :type, :options
|
34
|
+
def initialize(name, type, options = {})
|
35
|
+
@name = name
|
36
|
+
@type = type
|
37
|
+
@options = options
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/rpcoder/type.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module RPCoder
|
2
|
+
class Type
|
3
|
+
attr_accessor :name, :description
|
4
|
+
|
5
|
+
def fields
|
6
|
+
@fields ||= []
|
7
|
+
end
|
8
|
+
|
9
|
+
def add_field(name, type, options = {})
|
10
|
+
fields << Field.new(name, type, options)
|
11
|
+
end
|
12
|
+
|
13
|
+
class Field
|
14
|
+
attr_accessor :name, :type, :options
|
15
|
+
def initialize(name, type, options = {})
|
16
|
+
@name = name
|
17
|
+
@type = type
|
18
|
+
@options = options
|
19
|
+
end
|
20
|
+
|
21
|
+
def original_type?
|
22
|
+
original_types.include?(@type.to_sym)
|
23
|
+
end
|
24
|
+
|
25
|
+
def array?
|
26
|
+
@type.to_sym == :Array
|
27
|
+
end
|
28
|
+
|
29
|
+
def array_field
|
30
|
+
Field.new(name, options[:array_type])
|
31
|
+
end
|
32
|
+
|
33
|
+
def original_types
|
34
|
+
[:int, :String, :Boolean, :Array]
|
35
|
+
end
|
36
|
+
|
37
|
+
def instance_creator(elem = nil, options = {})
|
38
|
+
elem = name if elem.nil?
|
39
|
+
if original_type?
|
40
|
+
"object['#{name}']"
|
41
|
+
elsif options[:direct]
|
42
|
+
"new #{type}(#{elem})"
|
43
|
+
else
|
44
|
+
"new #{type}(object['#{elem}'])"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
/* generated by rpcoder */
|
2
|
+
|
3
|
+
package <%= name_space %>
|
4
|
+
{
|
5
|
+
import mx.rpc.AsyncResponder;
|
6
|
+
import mx.rpc.AsyncToken;
|
7
|
+
import mx.rpc.events.ResultEvent;
|
8
|
+
import mx.rpc.events.FaultEvent;
|
9
|
+
import mx.rpc.http.HTTPService;
|
10
|
+
import com.adobe.serialization.json.JSON;
|
11
|
+
|
12
|
+
public class <%= api_class_name %>
|
13
|
+
{
|
14
|
+
public static const CONTINUE :int = 100;
|
15
|
+
public static const SWITCHING_PROTOCOLS :int = 101;
|
16
|
+
public static const PROCESSING :int = 102;
|
17
|
+
public static const OK :int = 200;
|
18
|
+
public static const CREATED :int = 201;
|
19
|
+
public static const ACCEPTED :int = 202;
|
20
|
+
public static const NON_AUTHORITATIVE_INFORMATION :int = 203;
|
21
|
+
public static const NO_CONTENT :int = 204;
|
22
|
+
public static const RESET_CONTENT :int = 205;
|
23
|
+
public static const PARTIAL_CONTENT :int = 206;
|
24
|
+
public static const MULTI_STATUS :int = 207;
|
25
|
+
public static const IM_USED :int = 226;
|
26
|
+
public static const MULTIPLE_CHOICES :int = 300;
|
27
|
+
public static const MOVED_PERMANENTLY :int = 301;
|
28
|
+
public static const FOUND :int = 302;
|
29
|
+
public static const SEE_OTHER :int = 303;
|
30
|
+
public static const NOT_MODIFIED :int = 304;
|
31
|
+
public static const USE_PROXY :int = 305;
|
32
|
+
public static const RESERVED :int = 306;
|
33
|
+
public static const TEMPORARY_REDIRECT :int = 307;
|
34
|
+
public static const BAD_REQUEST :int = 400;
|
35
|
+
public static const UNAUTHORIZED :int = 401;
|
36
|
+
public static const PAYMENT_REQUIRED :int = 402;
|
37
|
+
public static const FORBIDDEN :int = 403;
|
38
|
+
public static const NOT_FOUND :int = 404;
|
39
|
+
public static const METHOD_NOT_ALLOWED :int = 405;
|
40
|
+
public static const NOT_ACCEPTABLE :int = 406;
|
41
|
+
public static const PROXY_AUTHENTICATION_REQUIRED :int = 407;
|
42
|
+
public static const REQUEST_TIMEOUT :int = 408;
|
43
|
+
public static const CONFLICT :int = 409;
|
44
|
+
public static const GONE :int = 410;
|
45
|
+
public static const LENGTH_REQUIRED :int = 411;
|
46
|
+
public static const PRECONDITION_FAILED :int = 412;
|
47
|
+
public static const REQUEST_ENTITY_TOO_LARGE :int = 413;
|
48
|
+
public static const REQUEST_URI_TOO_LONG :int = 414;
|
49
|
+
public static const UNSUPPORTED_MEDIA_TYPE :int = 415;
|
50
|
+
public static const REQUESTED_RANGE_NOT_SATISFIABLE :int = 416;
|
51
|
+
public static const EXPECTATION_FAILED :int = 417;
|
52
|
+
public static const UNPROCESSABLE_ENTITY :int = 422;
|
53
|
+
public static const LOCKED :int = 423;
|
54
|
+
public static const FAILED_DEPENDENCY :int = 424;
|
55
|
+
public static const UPGRADE_REQUIRED :int = 426;
|
56
|
+
public static const INTERNAL_SERVER_ERROR :int = 500;
|
57
|
+
public static const NOT_IMPLEMENTED :int = 501;
|
58
|
+
public static const BAD_GATEWAY :int = 502;
|
59
|
+
public static const SERVICE_UNAVAILABLE :int = 503;
|
60
|
+
public static const GATEWAY_TIMEOUT :int = 504;
|
61
|
+
public static const HTTP_VERSION_NOT_SUPPORTED :int = 505;
|
62
|
+
public static const VARIANT_ALSO_NEGOTIATES :int = 506;
|
63
|
+
public static const INSUFFICIENT_STORAGE :int = 507;
|
64
|
+
public static const NOT_EXTENDED :int = 510;
|
65
|
+
|
66
|
+
private var _baseUrl:String;
|
67
|
+
private var _errorHandler : Function;
|
68
|
+
|
69
|
+
public function <%= api_class_name %>(baseUrl:String)
|
70
|
+
{
|
71
|
+
this._baseUrl = baseUrl;
|
72
|
+
}
|
73
|
+
|
74
|
+
public function get baseUrl():String
|
75
|
+
{
|
76
|
+
return this._baseUrl;
|
77
|
+
}
|
78
|
+
|
79
|
+
public function set errorHandler(handler : Function):void
|
80
|
+
{
|
81
|
+
this._errorHandler = handler;
|
82
|
+
}
|
83
|
+
|
84
|
+
public function get errorHandler():Function
|
85
|
+
{
|
86
|
+
return this._errorHandler;
|
87
|
+
}
|
88
|
+
|
89
|
+
<%- functions.each do |func| -%>
|
90
|
+
/**
|
91
|
+
* <%= func.description %>
|
92
|
+
*
|
93
|
+
<%- func.params.each do |param| -%>
|
94
|
+
* @<%= param.name %>:<%= param.type %> <%= param.options[:expect] %> <%= param.options[:description] %>
|
95
|
+
<%- end -%>
|
96
|
+
* @success:Function
|
97
|
+
* @error:Function
|
98
|
+
*/
|
99
|
+
<%-
|
100
|
+
params = func.params.map{|i| [i.name, i.type].join(':') } + ['success:Function', 'error:Function']
|
101
|
+
-%>
|
102
|
+
public function <%= func.name %>(<%= params.join(', ') %>):void
|
103
|
+
{
|
104
|
+
var params:Object = {<%= func.query_params.map { |i| "\"#{i.name}\":#{i.name}" }.join(', ') %>};
|
105
|
+
request("<%= func.method %>", <%= func.path_parts.join(' + ') %>, params,
|
106
|
+
function(e:ResultEvent, t:Object):void {
|
107
|
+
t = t; // FIXME: for removing warning
|
108
|
+
<%- if func.return_type && func.return_type != 'void' -%>
|
109
|
+
success(new <%= func.return_type %>(JSON.decode(e.result as String)));
|
110
|
+
<%- else -%>
|
111
|
+
success();
|
112
|
+
<%- end -%>
|
113
|
+
},
|
114
|
+
function(e:FaultEvent, t:Object):void {
|
115
|
+
t = t; // FIXME: for removing warning
|
116
|
+
error(e);
|
117
|
+
}
|
118
|
+
);
|
119
|
+
}
|
120
|
+
|
121
|
+
<%- end -%>
|
122
|
+
public function request(method:String, path:String, params:Object, success:Function, error:Function):void
|
123
|
+
{
|
124
|
+
var service:HTTPService = createHttpService(this.baseUrl);
|
125
|
+
service.method = method;
|
126
|
+
service.url = path;
|
127
|
+
service.request = params;
|
128
|
+
service.resultFormat = 'text';
|
129
|
+
var token:AsyncToken = service.send();
|
130
|
+
token.addResponder(new AsyncResponder(
|
131
|
+
success,
|
132
|
+
function(e:FaultEvent, t:Object):void {
|
133
|
+
if (_errorHandler !== null && e.statusCode >= 500) {
|
134
|
+
_errorHandler(e, t);
|
135
|
+
} else {
|
136
|
+
error(e, t);
|
137
|
+
}
|
138
|
+
}
|
139
|
+
));
|
140
|
+
}
|
141
|
+
|
142
|
+
public function createHttpService(baseUrl:String) : HTTPService
|
143
|
+
{
|
144
|
+
return new HTTPService(baseUrl);
|
145
|
+
}
|
146
|
+
}
|
147
|
+
}
|