soybean 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bin/soybean +12 -4
- data/lib/soybean.rb +7 -4
- data/lib/soybean/complex_type.rb +46 -0
- data/lib/soybean/encoded_mapping_registry_creator.rb +32 -0
- data/lib/soybean/generators/base_generator.rb +11 -0
- data/lib/soybean/generators/class_generator.rb +100 -0
- data/lib/soybean/generators/interface_generator.rb +31 -0
- data/lib/soybean/generators/mapping_generator.rb +105 -0
- data/lib/soybean/generators/model_generator.rb +23 -0
- data/lib/soybean/generators/service_generator.rb +48 -0
- data/lib/soybean/generators/types_generator.rb +202 -0
- data/lib/soybean/literal_mapping_registry_creator.rb +32 -0
- data/soybean.gemspec +18 -4
- data/spec/services/interfaces/get_registrars_interface.rb +16 -0
- data/spec/services/mappings/base.rb +2328 -0
- data/spec/services/mappings/get_registrars.rb +62 -0
- data/spec/services/models/get_registrars_service.rb +2 -0
- data/spec/services/types/get_registrars.rb +19 -0
- data/spec/services/types/type.rb +947 -0
- data/vendor/soap4r/soap/rpc/element.rb +2 -2
- data/vendor/soap4r/wsdl/soap/wsdl2ruby.rb +178 -178
- data/vendor/soap4r/xsd/codegen/classdef.rb +2 -2
- metadata +35 -21
- data/bin/xsd2ruby +0 -90
- data/lib/soybean/actions/generate_classes.rb +0 -33
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
2.0.0
|
data/bin/soybean
CHANGED
@@ -10,13 +10,21 @@ require 'soybean'
|
|
10
10
|
class Soybean::CLI < Thor
|
11
11
|
include Thor::Actions
|
12
12
|
|
13
|
-
desc "
|
13
|
+
desc "types file_path.xsd", "Generate Ruby classes for xsd-schema from file_path.xsd"
|
14
14
|
method_options :quiet => :boolean, :force => :boolean
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
def types(location, destination = '.')
|
16
|
+
Soybean::Generators::TypesGenerator.new(URI.parse(location)).generate do |filename, content|
|
17
|
+
create_file File.join(destination, filename), content, options
|
18
|
+
end
|
18
19
|
end
|
19
20
|
|
21
|
+
desc "service [PATH_TO_WSDL] [DESTINATION_DIR]", "Generate Ruby classes from WSDL"
|
22
|
+
method_options :quiet => :boolean, :force => :boolean
|
23
|
+
def service(wsdl, destination_dir)
|
24
|
+
Soybean::Generators::ServiceGenerator.new(destination_dir, wsdl).generate do |filename, content|
|
25
|
+
create_file filename, content, options
|
26
|
+
end
|
27
|
+
end
|
20
28
|
end
|
21
29
|
|
22
30
|
Soybean::CLI.start
|
data/lib/soybean.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
require 'active_support/hash_with_indifferent_access'
|
3
|
+
require 'active_support/core_ext/class'
|
4
|
+
require 'active_support/core_ext/array/grouping'
|
1
5
|
require 'active_support/deprecation'
|
2
6
|
require 'active_support/dependencies'
|
7
|
+
require 'active_support/dependencies/autoload'
|
8
|
+
|
3
9
|
ActiveSupport::Dependencies.autoload_paths << File.absolute_path(File.join(File.dirname(__FILE__), '..', 'vendor/soap4r'))
|
4
10
|
ActiveSupport::Dependencies.autoload_paths << File.absolute_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
11
|
|
6
12
|
module Soybean
|
7
|
-
|
8
|
-
module Actions
|
9
|
-
autoload :GenerateClasses, 'soybean/actions/generate_classes'
|
10
|
-
end
|
13
|
+
extend ActiveSupport::Autoload
|
11
14
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Soybean
|
2
|
+
class ComplexType
|
3
|
+
class_attribute :attributes, :instance_reader => true, :instance_writer => true
|
4
|
+
self.attributes = []
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def attr_accessor(*attrs)
|
8
|
+
self.attributes += attrs
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
hash = args.extract_options!
|
15
|
+
if args.empty?
|
16
|
+
init_from_hash(hash)
|
17
|
+
else
|
18
|
+
init_from_array(args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# @param hash [Hash]
|
25
|
+
def init_from_hash(hash)
|
26
|
+
check_arguments_number!(hash)
|
27
|
+
hash.each do |key, val|
|
28
|
+
self.send key.to_sym, val
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param arry [Array]
|
33
|
+
def init_from_array(arry)
|
34
|
+
check_arguments_number! arry
|
35
|
+
attributes.each_with_index do |key, i|
|
36
|
+
self.send "#{key}=".to_sym, arry.at(i)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_arguments_number!(args)
|
41
|
+
if args.size != attributes.size
|
42
|
+
raise ArgumentError, "wrong number of arguments(#{args.size} for #{attributes.size})"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Soybean
|
2
|
+
class EncodedMappingRegistryCreator < WSDL::SOAP::EncodedMappingRegistryCreator
|
3
|
+
|
4
|
+
def initialize(definitions, name_creator, modulepath, defined_const, cache)
|
5
|
+
@cache = cache
|
6
|
+
super(definitions, name_creator, modulepath, defined_const)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def dump_entry(regname, var)
|
12
|
+
if @cache.key?(var[:class])
|
13
|
+
''
|
14
|
+
else
|
15
|
+
@cache[var[:class]] = true
|
16
|
+
"#{regname}.register(\n " +
|
17
|
+
[
|
18
|
+
dump_entry_item(var, :class),
|
19
|
+
dump_entry_item(var, :soap_class),
|
20
|
+
dump_entry_item(var, :schema_name, :qname),
|
21
|
+
dump_entry_item(var, :schema_type, :qname),
|
22
|
+
dump_entry_item(var, :is_anonymous),
|
23
|
+
dump_entry_item(var, :schema_basetype, :qname),
|
24
|
+
dump_entry_item(var, :schema_qualified),
|
25
|
+
dump_entry_item(var, :schema_element),
|
26
|
+
dump_entry_item(var, :schema_attribute)
|
27
|
+
].compact.join(",\n ") +
|
28
|
+
"\n)\n"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Soybean
|
2
|
+
module Generators
|
3
|
+
class ClassGenerator < XSD::CodeGen::ClassDef
|
4
|
+
|
5
|
+
def def_attr(attrname, writable = true, varname = nil)
|
6
|
+
unless safevarname?(varname || attrname)
|
7
|
+
raise ArgumentError.new("#{varname || attrname} seems to be unsafe")
|
8
|
+
end
|
9
|
+
@attrdef << [attrname.underscore, writable, varname.underscore]
|
10
|
+
end
|
11
|
+
|
12
|
+
def def_classvar(var, value)
|
13
|
+
var = var.sub(/\A@@/, "")
|
14
|
+
unless safevarname?(var)
|
15
|
+
raise ArgumentError.new("#{var} seems to be unsafe")
|
16
|
+
end
|
17
|
+
@classvar << [var.underscore, value]
|
18
|
+
end
|
19
|
+
|
20
|
+
def def_method(name, *params)
|
21
|
+
return if name == 'initialize'
|
22
|
+
super name.underscore, *params.map(&:underscore)
|
23
|
+
end
|
24
|
+
|
25
|
+
def dump
|
26
|
+
buf = ""
|
27
|
+
unless @requirepath.empty?
|
28
|
+
buf << dump_requirepath
|
29
|
+
end
|
30
|
+
buf << dump_emptyline unless buf.empty?
|
31
|
+
package = @name.split(/::/)[0..-2]
|
32
|
+
buf << dump_package_def(package) unless package.empty?
|
33
|
+
#buf << dump_comment if @comment
|
34
|
+
buf << dump_class_def
|
35
|
+
spacer = false
|
36
|
+
unless @classvar.empty?
|
37
|
+
spacer = true
|
38
|
+
buf << dump_classvar
|
39
|
+
end
|
40
|
+
unless @const.empty?
|
41
|
+
buf << dump_emptyline if spacer
|
42
|
+
spacer = true
|
43
|
+
buf << dump_const
|
44
|
+
end
|
45
|
+
unless @innermodule.empty?
|
46
|
+
buf << dump_emptyline # always add 1 empty line
|
47
|
+
spacer = true
|
48
|
+
buf << dump_innermodule
|
49
|
+
end
|
50
|
+
unless @code.empty?
|
51
|
+
buf << dump_emptyline if spacer
|
52
|
+
spacer = true
|
53
|
+
buf << dump_code
|
54
|
+
end
|
55
|
+
unless @attrdef.empty?
|
56
|
+
buf << dump_emptyline if spacer
|
57
|
+
spacer = true
|
58
|
+
buf << dump_attributes
|
59
|
+
end
|
60
|
+
buf << accessors
|
61
|
+
unless @methoddef.empty?
|
62
|
+
buf << dump_emptyline if spacer
|
63
|
+
spacer = true
|
64
|
+
buf << dump_methods
|
65
|
+
end
|
66
|
+
buf << dump_class_def_end
|
67
|
+
buf << dump_package_def_end(package) unless package.empty?
|
68
|
+
buf.gsub(/^\s+$/, '')
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def dump_class_def
|
74
|
+
name = @name.to_s.split(/::/)
|
75
|
+
if @baseclass
|
76
|
+
"class #{name.last} < #{@baseclass}\n"
|
77
|
+
else
|
78
|
+
"class #{name.last} < Soybean::ComplexType\n"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def accessors
|
83
|
+
@attrdef.map do |attrname, *|
|
84
|
+
format("attr_accessor #{attrname.to_sym.inspect}\n", 2)
|
85
|
+
end.join
|
86
|
+
end
|
87
|
+
|
88
|
+
def dump_attribute(attrname, writable, varname)
|
89
|
+
""
|
90
|
+
end
|
91
|
+
|
92
|
+
def dump_attributes
|
93
|
+
""
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'wsdl/soap/servant_skelton_creator'
|
2
|
+
|
3
|
+
module Soybean
|
4
|
+
module Generators
|
5
|
+
class InterfaceGenerator
|
6
|
+
class InterfaceCreator < WSDL::SOAP::ServantSkeltonCreator
|
7
|
+
def mapped_class_basename(*)
|
8
|
+
(@definitions.name.name.gsub(/Service$/, 'Interface') rescue 'BaseInterface')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
include BaseGenerator
|
13
|
+
|
14
|
+
attr_reader :name
|
15
|
+
|
16
|
+
def initialize(wsdl)
|
17
|
+
@wsdl = wsdl
|
18
|
+
@name = (wsdl.name.name.underscore.gsub(/_service$/, '_interface') rescue 'base_interface')
|
19
|
+
end
|
20
|
+
|
21
|
+
def dir
|
22
|
+
'interfaces'
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate
|
26
|
+
InterfaceCreator.new(@wsdl, WSDL::SOAP::ClassNameCreator.new).dump
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Soybean
|
2
|
+
module Generators
|
3
|
+
class MappingGenerator
|
4
|
+
class_attribute :mapping_cache, :instance_reader => true, :instance_writer => true
|
5
|
+
self.mapping_cache = Hash.new { |hash, key| hash[key] = {} }
|
6
|
+
|
7
|
+
include BaseGenerator
|
8
|
+
include WSDL::SOAP::ClassDefCreatorSupport
|
9
|
+
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
def initialize(schema)
|
13
|
+
@schema = schema
|
14
|
+
@name = name_from_namespace(schema.targetnamespace)
|
15
|
+
@name_creator = WSDL::SOAP::ClassNameCreator.new
|
16
|
+
@defined_const = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def dir
|
20
|
+
'mappings'
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate
|
24
|
+
m = ModuleDef.new("#{@name.camelize}")
|
25
|
+
|
26
|
+
varname = 'EncodedRegistry'
|
27
|
+
m.def_code(encoded_creator.dump(varname))
|
28
|
+
|
29
|
+
varname = 'LiteralRegistry'
|
30
|
+
m.def_code(literal_creator.dump(varname))
|
31
|
+
|
32
|
+
@defined_const.each do |ns, tag|
|
33
|
+
m.def_const(tag, dq(ns))
|
34
|
+
end
|
35
|
+
|
36
|
+
registry = ModuleDef.new("Mappings", [m])
|
37
|
+
registry.def_require("soap/mapping")
|
38
|
+
registry.def_code('EncodedRegistry ||= ::SOAP::Mapping::EncodedRegistry.new')
|
39
|
+
registry.def_code('LiteralRegistry ||= ::SOAP::Mapping::LiteralRegistry.new')
|
40
|
+
|
41
|
+
if block_given?
|
42
|
+
yield File.join(dir, filename), registry.dump
|
43
|
+
else
|
44
|
+
registry.dump
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def literal_creator
|
49
|
+
LiteralMappingRegistryCreator.new(@schema, @name_creator, 'Types', @defined_const, mapping_cache[:literal])
|
50
|
+
end
|
51
|
+
|
52
|
+
def encoded_creator
|
53
|
+
EncodedMappingRegistryCreator.new(@schema, @name_creator, 'Types', @defined_const, mapping_cache[:encoded])
|
54
|
+
end
|
55
|
+
|
56
|
+
def name_from_namespace(ns)
|
57
|
+
name = URI.parse(ns).path.split('/').delete_if { |part| part.empty? || part == 'type' }.last
|
58
|
+
(name || 'base').underscore.gsub(/_service$/, '')
|
59
|
+
end
|
60
|
+
|
61
|
+
class ModuleDef < XSD::CodeGen::ModuleDef
|
62
|
+
def initialize(name, modules = [])
|
63
|
+
super(name)
|
64
|
+
@innermodule = modules
|
65
|
+
end
|
66
|
+
|
67
|
+
def dump
|
68
|
+
buf = ""
|
69
|
+
unless @requirepath.empty?
|
70
|
+
buf << dump_requirepath
|
71
|
+
end
|
72
|
+
buf << dump_emptyline unless buf.empty?
|
73
|
+
package = @name.split(/::/)[0..-2]
|
74
|
+
buf << dump_package_def(package) unless package.empty?
|
75
|
+
buf << dump_comment if @comment
|
76
|
+
buf << dump_module_def
|
77
|
+
spacer = false
|
78
|
+
unless @const.empty?
|
79
|
+
buf << dump_emptyline if spacer
|
80
|
+
spacer = true
|
81
|
+
buf << dump_const
|
82
|
+
end
|
83
|
+
unless @code.empty?
|
84
|
+
buf << dump_emptyline if spacer
|
85
|
+
spacer = true
|
86
|
+
buf << dump_code
|
87
|
+
end
|
88
|
+
unless @innermodule.empty?
|
89
|
+
buf << dump_emptyline # always add 1 empty line
|
90
|
+
spacer = true
|
91
|
+
buf << dump_innermodule
|
92
|
+
end
|
93
|
+
unless @methoddef.empty?
|
94
|
+
buf << dump_emptyline if spacer
|
95
|
+
spacer = true
|
96
|
+
buf << dump_methods
|
97
|
+
end
|
98
|
+
buf << dump_module_def_end
|
99
|
+
buf << dump_package_def_end(package) unless package.empty?
|
100
|
+
buf.gsub(/^\s+$/, '')
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Soybean
|
2
|
+
module Generators
|
3
|
+
class ModelGenerator
|
4
|
+
include BaseGenerator
|
5
|
+
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(wsdl)
|
9
|
+
@wsdl = wsdl
|
10
|
+
@name = (wsdl.name.name.underscore rescue 'base')
|
11
|
+
end
|
12
|
+
|
13
|
+
def dir
|
14
|
+
'models'
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
"class %s < %sInterface\nend" % [@name.camelize, @name.camelize.gsub(/Service$/,'')]
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Soybean
|
2
|
+
module Generators
|
3
|
+
class ServiceGenerator
|
4
|
+
attr_reader :path, :wsdl_location, :wsdl
|
5
|
+
|
6
|
+
def initialize(path, wsdl)
|
7
|
+
@path, @wsdl_location = Pathname.new(path), wsdl
|
8
|
+
@wsdl = import_wsdl
|
9
|
+
@schemes = @wsdl.importedschema.keys
|
10
|
+
end
|
11
|
+
|
12
|
+
def schemes
|
13
|
+
@schemes.map { |url| TypesGenerator.new(url) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate
|
17
|
+
(schemes + mappings + interface + model).map do |generator|
|
18
|
+
yield path.join(generator.dir, generator.filename), generator.generate
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def mappings
|
23
|
+
schemes.map { |gen| MappingGenerator.new(gen.xsd) }
|
24
|
+
end
|
25
|
+
|
26
|
+
def interface
|
27
|
+
[InterfaceGenerator.new(@wsdl)]
|
28
|
+
end
|
29
|
+
|
30
|
+
def model
|
31
|
+
[ModelGenerator.new(@wsdl)]
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def dirs
|
37
|
+
@dirs ||= %w{types mappings models interfaces}.inject(HashWithIndifferentAccess.new) do |dirs, dir|
|
38
|
+
dirs[dir.singularize] = Pathname.new @base.empty_directory(File.join(destination_dir, dir))
|
39
|
+
dirs
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def import_wsdl
|
44
|
+
WSDL::Importer.import(@wsdl_location)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|