soybean 1.0.0 → 2.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/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
|