ruby_vim_sdk 0.0.2
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/README +1 -0
- data/Rakefile +51 -0
- data/lib/ruby_vim_sdk.rb +48 -0
- data/lib/ruby_vim_sdk/base_type.rb +15 -0
- data/lib/ruby_vim_sdk/const.rb +32 -0
- data/lib/ruby_vim_sdk/core_types.rb +68 -0
- data/lib/ruby_vim_sdk/data_type.rb +14 -0
- data/lib/ruby_vim_sdk/enum_type.rb +12 -0
- data/lib/ruby_vim_sdk/ext.rb +9 -0
- data/lib/ruby_vim_sdk/managed_type.rb +12 -0
- data/lib/ruby_vim_sdk/method.rb +37 -0
- data/lib/ruby_vim_sdk/missing_types.rb +11 -0
- data/lib/ruby_vim_sdk/property.rb +49 -0
- data/lib/ruby_vim_sdk/server_objects.rb +2718 -0
- data/lib/ruby_vim_sdk/soap/deserializer.rb +301 -0
- data/lib/ruby_vim_sdk/soap/serializer.rb +225 -0
- data/lib/ruby_vim_sdk/soap/stub_adapter.rb +123 -0
- data/lib/ruby_vim_sdk/soap_exception.rb +12 -0
- data/lib/ruby_vim_sdk/typed_array.rb +9 -0
- data/lib/ruby_vim_sdk/types.rb +22 -0
- data/lib/ruby_vim_sdk/version.rb +5 -0
- data/lib/ruby_vim_sdk/vmodl/data_object.rb +102 -0
- data/lib/ruby_vim_sdk/vmodl/managed_object.rb +78 -0
- data/lib/ruby_vim_sdk/vmodl/method_name.rb +7 -0
- data/lib/ruby_vim_sdk/vmodl/property_path.rb +7 -0
- data/lib/ruby_vim_sdk/vmodl/type_name.rb +7 -0
- data/lib/ruby_vim_sdk/vmodl_helper.rb +33 -0
- data/lib/ruby_vim_sdk/vmomi_support.rb +280 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/unit/soap/deserializer_spec.rb +206 -0
- data/spec/unit/soap/serializer_spec.rb +261 -0
- data/spec/unit/soap/stub_adapter_spec.rb +9 -0
- data/spec/unit/vmodl/data_object_spec.rb +9 -0
- data/spec/unit/vmodl/managed_object_spec.rb +9 -0
- data/spec/unit/vmodl_helper_spec.rb +36 -0
- data/spec/unit/vmomi_support_spec.rb +33 -0
- metadata +121 -0
@@ -0,0 +1,123 @@
|
|
1
|
+
module VimSdk
|
2
|
+
module Soap
|
3
|
+
|
4
|
+
class StubAdapter
|
5
|
+
PC = Vmodl::Query::PropertyCollector
|
6
|
+
|
7
|
+
attr_reader :version
|
8
|
+
|
9
|
+
def initialize(uri, version, http_client)
|
10
|
+
@uri = URI.parse(uri)
|
11
|
+
@version = version
|
12
|
+
@version_id = compute_version_id(version)
|
13
|
+
@http_client = http_client
|
14
|
+
@cookie = ""
|
15
|
+
@property_collector = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def cookie
|
19
|
+
@http_client.cookie_manager.find(@uri)
|
20
|
+
end
|
21
|
+
|
22
|
+
def invoke_method(managed_object, method_info, arguments, outer_stub = nil)
|
23
|
+
outer_stub = self if outer_stub.nil?
|
24
|
+
headers = {"SOAPAction" => @version_id,
|
25
|
+
"Accept-Encoding" => "gzip, deflate",
|
26
|
+
"Content-Type" => "text/xml; charset=#{XML_ENCODING}"}
|
27
|
+
|
28
|
+
request = serialize_request(managed_object, method_info, arguments)
|
29
|
+
response = @http_client.post(@uri, request, headers)
|
30
|
+
|
31
|
+
status = response.code
|
32
|
+
if status == 200 || status == 500
|
33
|
+
object = SoapResponseDeserializer.new(outer_stub).deserialize(response.content, method_info.result_type)
|
34
|
+
if outer_stub != self
|
35
|
+
result = [status, object]
|
36
|
+
elsif status == 200
|
37
|
+
result = object
|
38
|
+
elsif object.kind_of?(Vmodl::MethodFault)
|
39
|
+
raise SoapException.new(object.msg, object)
|
40
|
+
else
|
41
|
+
raise SoapException.new("Unknown SOAP fault", object)
|
42
|
+
end
|
43
|
+
else
|
44
|
+
raise Net::HTTPError.new("#{status}", nil)
|
45
|
+
end
|
46
|
+
result
|
47
|
+
end
|
48
|
+
|
49
|
+
def invoke_property(managed_object, property_info)
|
50
|
+
filter_spec = PC::FilterSpec.new(
|
51
|
+
:object_set => [PC::ObjectSpec.new(:obj => managed_object, :skip => false)],
|
52
|
+
:prop_set => [PC::PropertySpec.new(:all => false, :type => managed_object.class,
|
53
|
+
:path_set => [property_info.wsdl_name])])
|
54
|
+
|
55
|
+
if @property_collector.nil?
|
56
|
+
service_instance = Vim::ServiceInstance.new("ServiceInstance", self)
|
57
|
+
@property_collector = service_instance.retrieve_content.property_collector
|
58
|
+
end
|
59
|
+
|
60
|
+
@property_collector.retrieve_contents([filter_spec]).first.prop_set.first.val
|
61
|
+
end
|
62
|
+
|
63
|
+
def compute_version_id(version)
|
64
|
+
version_ns = VmomiSupport.version_namespace(version)
|
65
|
+
if version_ns.index("/")
|
66
|
+
"\"urn:#{version_ns}\""
|
67
|
+
else
|
68
|
+
""
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def serialize_request(managed_object, info, arguments)
|
73
|
+
if !VmomiSupport.is_child_version(@version, info.version)
|
74
|
+
fault = Vmodl::Fault::MethodNotFound.new
|
75
|
+
fault.receiver = managed_object
|
76
|
+
fault.method = info.name
|
77
|
+
raise SoapException(fault)
|
78
|
+
end
|
79
|
+
|
80
|
+
namespace_map = SOAP_NAMESPACE_MAP.dup
|
81
|
+
default_namespace = VmomiSupport.wsdl_namespace(@version)
|
82
|
+
namespace_map[default_namespace] = ""
|
83
|
+
|
84
|
+
result = [XML_HEADER, "\n", SOAP_ENVELOPE_START]
|
85
|
+
result << SOAP_BODY_START
|
86
|
+
result << "<#{info.wsdl_name} xmlns=\"#{default_namespace}\">"
|
87
|
+
property = Property.new("_this", "Vmodl.ManagedObject", @version)
|
88
|
+
property.type = Vmodl::ManagedObject
|
89
|
+
result << serialize(managed_object, property, @version, namespace_map)
|
90
|
+
|
91
|
+
info.arguments.zip(arguments).each do |parameter, argument|
|
92
|
+
result << serialize(argument, parameter, @version, namespace_map)
|
93
|
+
end
|
94
|
+
|
95
|
+
result << "</#{info.wsdl_name}>"
|
96
|
+
result << SOAP_BODY_END
|
97
|
+
result << SOAP_ENVELOPE_END
|
98
|
+
|
99
|
+
result.join("")
|
100
|
+
end
|
101
|
+
|
102
|
+
def serialize(object, info, version, namespace_map)
|
103
|
+
if version.nil?
|
104
|
+
if object.kind_of?(Array)
|
105
|
+
item_type = object.class.type_info
|
106
|
+
version = item_type.version
|
107
|
+
else
|
108
|
+
if object.nil?
|
109
|
+
return ""
|
110
|
+
end
|
111
|
+
version = object.class.type_info.version
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
writer = StringIO.new
|
116
|
+
SoapSerializer.new(writer, version, namespace_map).serialize(object, info)
|
117
|
+
writer.string
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module VimSdk
|
2
|
+
|
3
|
+
class SoapBinary < String; end
|
4
|
+
|
5
|
+
class SoapBoolean
|
6
|
+
attr_accessor :value
|
7
|
+
def initialize(value)
|
8
|
+
@value = value
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class SoapFloat < DelegateClass(Float); end
|
13
|
+
class SoapInteger < DelegateClass(Integer); end
|
14
|
+
|
15
|
+
class SoapByte < SoapInteger; end
|
16
|
+
class SoapDouble < SoapFloat; end
|
17
|
+
class SoapLong < SoapInteger; end
|
18
|
+
class SoapShort < SoapInteger; end
|
19
|
+
class SoapURI < String; end
|
20
|
+
class SoapEnum; end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module VimSdk
|
2
|
+
module Vmodl
|
3
|
+
class DataObject
|
4
|
+
@type_info = DataType.new("vmodl.DataObject", "DataObject", nil, VimSdk::BASE_VERSION, [])
|
5
|
+
@resolved_properties = nil
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_reader :type_info
|
9
|
+
|
10
|
+
[:name, :wsdl_name, :version, :properties].each do |name|
|
11
|
+
define_method(name) { @type_info.send(name) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def property_list(include_base_class_props = true)
|
15
|
+
return properties unless include_base_class_props
|
16
|
+
return @resolved_properties unless @resolved_properties.nil?
|
17
|
+
|
18
|
+
result = []
|
19
|
+
property_names = Set.new
|
20
|
+
|
21
|
+
current_class = self
|
22
|
+
while current_class != DataObject
|
23
|
+
properties = current_class.type_info.properties
|
24
|
+
if properties
|
25
|
+
properties.reverse.each do |property|
|
26
|
+
unless property_names.include?(property.name)
|
27
|
+
result.unshift(property)
|
28
|
+
property_names << property.name
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
current_class = current_class.superclass
|
33
|
+
end
|
34
|
+
|
35
|
+
@resolved_properties = result
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_property_indices
|
39
|
+
@property_by_name = {}
|
40
|
+
@property_by_wsdl_name = {}
|
41
|
+
property_list.each do |property|
|
42
|
+
@property_by_name[property.name] = property
|
43
|
+
@property_by_wsdl_name[property.wsdl_name] = property
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def property(options = {})
|
48
|
+
if options[:name]
|
49
|
+
@property_by_name[options[:name]]
|
50
|
+
elsif options[:wsdl_name]
|
51
|
+
@property_by_wsdl_name[options[:wsdl_name]]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def finalize
|
56
|
+
build_property_indices
|
57
|
+
@type_info.properties.each do |property|
|
58
|
+
property.type = VmomiSupport.loaded_type(property.type) if property.type.kind_of?(String)
|
59
|
+
self.instance_eval do
|
60
|
+
attr_accessor(property.name)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize(properties = {})
|
68
|
+
|
69
|
+
self.class.property_list.each do |property|
|
70
|
+
subclasses = Set.new(property.type.ancestors)
|
71
|
+
if subclasses.include?(Array)
|
72
|
+
default_value = property.type.new
|
73
|
+
elsif property.optional?
|
74
|
+
default_value = nil
|
75
|
+
elsif property.type == SoapBoolean
|
76
|
+
default_value = false
|
77
|
+
elsif subclasses.include?(SoapEnum)
|
78
|
+
default_value = nil
|
79
|
+
elsif subclasses.include?(String)
|
80
|
+
default_value = ""
|
81
|
+
elsif [SoapByte, SoapShort, SoapLong, SoapInteger].include?(property.type)
|
82
|
+
default_value = 0
|
83
|
+
elsif [SoapFloat, SoapDouble].include?(property.type)
|
84
|
+
default_value = 0.0
|
85
|
+
else
|
86
|
+
default_value = nil
|
87
|
+
end
|
88
|
+
instance_variable_set("@#{property.name}", default_value)
|
89
|
+
end
|
90
|
+
|
91
|
+
properties.each do |key, value|
|
92
|
+
if self.class.property(:name => key.to_s)
|
93
|
+
instance_variable_set("@#{key}", value)
|
94
|
+
else
|
95
|
+
raise "Invalid property: #{key}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module VimSdk
|
2
|
+
module Vmodl
|
3
|
+
class ManagedObject < DataObject
|
4
|
+
@type_info = ManagedType.new("vmodl.ManagedObject", "ManagedObject", nil, VimSdk::BASE_VERSION, [], [])
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
[:managed_methods].each do |name|
|
9
|
+
define_method(name) { @type_info.send(name) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def invoke_method(object, managed_method, *args)
|
13
|
+
object.__stub__.invoke_method(object, managed_method, args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def invoke_property(object, property)
|
17
|
+
object.__stub__.invoke_property(object, property)
|
18
|
+
end
|
19
|
+
|
20
|
+
def finalize
|
21
|
+
build_property_indices
|
22
|
+
|
23
|
+
@type_info.properties.each do |property|
|
24
|
+
property.type = VmomiSupport.loaded_type(property.type) if property.type.kind_of?(String)
|
25
|
+
self.instance_eval do
|
26
|
+
define_method(property.name) do |*args|
|
27
|
+
if args.length != 0
|
28
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for 0)"
|
29
|
+
end
|
30
|
+
self.class.invoke_property(self, property)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
@type_info.managed_methods.each do |method|
|
36
|
+
method.result_type = VmomiSupport.loaded_type(method.result_type) if method.result_type.kind_of?(String)
|
37
|
+
method.arguments.each do |argument|
|
38
|
+
argument.type = VmomiSupport.loaded_type(argument.type) if argument.type.kind_of?(String)
|
39
|
+
end
|
40
|
+
self.instance_eval do
|
41
|
+
define_method(method.name) do |*args|
|
42
|
+
if args.length != method.arguments.length
|
43
|
+
raise ArgumentError, "wrong number of arguments (#{args.length} for #{method.arguments.length})"
|
44
|
+
end
|
45
|
+
self.class.invoke_method(self, method, *args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
attr_accessor :__mo_id__
|
53
|
+
attr_accessor :__stub__
|
54
|
+
|
55
|
+
def initialize(mo_id, stub = nil)
|
56
|
+
@__mo_id__ = mo_id
|
57
|
+
@__stub__ = stub
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_s
|
61
|
+
"<[#{self.class.name}] #{@__mo_id__}>"
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_str
|
65
|
+
@__mo_id__
|
66
|
+
end
|
67
|
+
|
68
|
+
def hash
|
69
|
+
__mo_id__.hash
|
70
|
+
end
|
71
|
+
|
72
|
+
def eql?(other)
|
73
|
+
@__mo_id__ == other.__mo_id__
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module VimSdk::VmodlHelper
|
2
|
+
UNDERSCORE_EXCEPTIONS = {
|
3
|
+
"numCPUs" => "num_cpus",
|
4
|
+
"importVApp" => "import_vapp"
|
5
|
+
}
|
6
|
+
|
7
|
+
# Borrowed mostly from activesupport
|
8
|
+
def camelize(word)
|
9
|
+
word.gsub(/(?:^|_)(.)/) { $1.upcase }
|
10
|
+
end
|
11
|
+
|
12
|
+
# Borrowed mostly from activesupport
|
13
|
+
def underscore(word)
|
14
|
+
exception = UNDERSCORE_EXCEPTIONS[word]
|
15
|
+
return exception if exception
|
16
|
+
|
17
|
+
word = word.dup
|
18
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
19
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
20
|
+
word.downcase!
|
21
|
+
word
|
22
|
+
end
|
23
|
+
|
24
|
+
def vmodl_type_to_ruby(name)
|
25
|
+
name.split(".").collect { |part| camelize(part) }.join(".")
|
26
|
+
end
|
27
|
+
|
28
|
+
def vmodl_property_to_ruby(name)
|
29
|
+
underscore(name)
|
30
|
+
end
|
31
|
+
|
32
|
+
module_function :camelize, :underscore, :vmodl_type_to_ruby, :vmodl_property_to_ruby
|
33
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
module VimSdk
|
2
|
+
|
3
|
+
module VmomiSupport
|
4
|
+
|
5
|
+
@logger = Logger.new(STDOUT)
|
6
|
+
|
7
|
+
@type_info = {}
|
8
|
+
@wsdl_type_info = {}
|
9
|
+
|
10
|
+
@versions = {}
|
11
|
+
@version_ids = {}
|
12
|
+
@version_parents = {}
|
13
|
+
@version_namespaces = {}
|
14
|
+
@service_version_namespaces = {BASE_VERSION => XMLNS_VMODL_BASE.split(":").last}
|
15
|
+
|
16
|
+
@wsdl_types = {
|
17
|
+
[XMLNS_XSD, "void"] => NilClass,
|
18
|
+
[XMLNS_XSD, "anyType"] => Object,
|
19
|
+
[XMLNS_XSD, "boolean"] => SoapBoolean,
|
20
|
+
[XMLNS_XSD, "byte"] => SoapByte,
|
21
|
+
[XMLNS_XSD, "short"] => SoapShort,
|
22
|
+
[XMLNS_XSD, "int"] => SoapInteger,
|
23
|
+
[XMLNS_XSD, "long"] => SoapLong,
|
24
|
+
[XMLNS_XSD, "float"] => SoapFloat,
|
25
|
+
[XMLNS_XSD, "double"] => SoapDouble,
|
26
|
+
[XMLNS_XSD, "string"] => String,
|
27
|
+
[XMLNS_XSD, "anyURI"] => SoapURI,
|
28
|
+
[XMLNS_XSD, "base64Binary"] => SoapBinary,
|
29
|
+
[XMLNS_XSD, "dateTime"] => Time,
|
30
|
+
[XMLNS_VMODL_BASE, "DataObject"] => Vmodl::DataObject,
|
31
|
+
[XMLNS_VMODL_BASE, "ManagedObject"] => Vmodl::ManagedObject,
|
32
|
+
[XMLNS_VMODL_BASE, "MethodName"] => Vmodl::MethodName,
|
33
|
+
[XMLNS_VMODL_BASE, "PropertyPath"] => Vmodl::PropertyPath,
|
34
|
+
[XMLNS_VMODL_BASE, "TypeName"] => Vmodl::TypeName
|
35
|
+
}
|
36
|
+
@wsdl_names = @wsdl_types.invert
|
37
|
+
@wsdl_type_namespaces = Set.new
|
38
|
+
|
39
|
+
@wsdl_types.dup.each do |namespaced_name, type|
|
40
|
+
namespace, name = namespaced_name
|
41
|
+
vmodl_name = namespace == XMLNS_VMODL_BASE ? "Vmodl.#{name}" : name
|
42
|
+
if type != NilClass
|
43
|
+
@wsdl_type_namespaces << namespace
|
44
|
+
array_type = Class.new(TypedArray) { @item = type }
|
45
|
+
type.const_set(:TypedArray, array_type)
|
46
|
+
array_name = "ArrayOf#{VmodlHelper.camelize(name)}"
|
47
|
+
array_namespace = XMLNS_VMODL_BASE
|
48
|
+
@wsdl_types[[array_namespace, array_name]] = array_type
|
49
|
+
@wsdl_names[array_type] = [array_namespace, array_name]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
@wsdl_names[Class] = [XMLNS_XSD, "TypeName"]
|
54
|
+
@wsdl_names[FalseClass] = [XMLNS_XSD, "boolean"]
|
55
|
+
@wsdl_names[TrueClass] = [XMLNS_XSD, "boolean"]
|
56
|
+
@wsdl_names[Fixnum] = [XMLNS_XSD, "int"]
|
57
|
+
@wsdl_names[Float] = [XMLNS_XSD, "float"]
|
58
|
+
|
59
|
+
@types = {
|
60
|
+
"Void" => @wsdl_types[[XMLNS_XSD, "void"]],
|
61
|
+
"AnyType"=> @wsdl_types[[XMLNS_XSD, "anyType"]],
|
62
|
+
"String" => @wsdl_types[[XMLNS_XSD, "string"]],
|
63
|
+
"Bool" => @wsdl_types[[XMLNS_XSD, "boolean"]],
|
64
|
+
"Boolean"=> @wsdl_types[[XMLNS_XSD, "boolean"]],
|
65
|
+
"Byte" => @wsdl_types[[XMLNS_XSD, "byte"]],
|
66
|
+
"Short" => @wsdl_types[[XMLNS_XSD, "short"]],
|
67
|
+
"Int" => @wsdl_types[[XMLNS_XSD, "int"]],
|
68
|
+
"Long" => @wsdl_types[[XMLNS_XSD, "long"]],
|
69
|
+
"Float" => @wsdl_types[[XMLNS_XSD, "float"]],
|
70
|
+
"Double" => @wsdl_types[[XMLNS_XSD, "double"]],
|
71
|
+
"Vmodl.URI" => @wsdl_types[[XMLNS_XSD, "anyURI"]],
|
72
|
+
"Vmodl.Binary" => @wsdl_types[[XMLNS_XSD, "base64Binary"]],
|
73
|
+
"Vmodl.DateTime" => @wsdl_types[[XMLNS_XSD, "dateTime"]],
|
74
|
+
"Vmodl.TypeName" => @wsdl_types[[XMLNS_VMODL_BASE, "TypeName"]],
|
75
|
+
"Vmodl.MethodName" => @wsdl_types[[XMLNS_VMODL_BASE, "MethodName"]],
|
76
|
+
"Vmodl.DataObject" => @wsdl_types[[XMLNS_VMODL_BASE, "DataObject"]],
|
77
|
+
"Vmodl.ManagedObject" => @wsdl_types[[XMLNS_VMODL_BASE, "ManagedObject"]],
|
78
|
+
"Vmodl.PropertyPath" => @wsdl_types[[XMLNS_VMODL_BASE, "PropertyPath"]]
|
79
|
+
}
|
80
|
+
|
81
|
+
@types.dup.each do |name, type|
|
82
|
+
if type != NilClass
|
83
|
+
array_type = type.const_get(:TypedArray)
|
84
|
+
array_name = "#{name}[]"
|
85
|
+
@types[array_name] = array_type
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
class << self
|
90
|
+
|
91
|
+
attr_reader :logger
|
92
|
+
|
93
|
+
def add_version(version, ns, version_id, is_legacy, service_ns)
|
94
|
+
unless @version_parents.has_key?(version)
|
95
|
+
@version_namespaces[version] = ns
|
96
|
+
@versions["#{ns}/#{version_id}"] = version unless version_id.empty?
|
97
|
+
@versions[ns] = version if is_legacy || ns.empty?
|
98
|
+
@version_ids[version] = version_id
|
99
|
+
service_ns = ns if service_ns.nil?
|
100
|
+
@service_version_namespaces[version] = service_ns
|
101
|
+
@version_parents[version] = {}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_version_parent(version, parent)
|
106
|
+
@version_parents[version][parent] = true
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_data_type(*args)
|
110
|
+
add_type(DataType.new(*args))
|
111
|
+
end
|
112
|
+
|
113
|
+
def create_enum_type(*args)
|
114
|
+
add_type(EnumType.new(*args))
|
115
|
+
end
|
116
|
+
|
117
|
+
def create_managed_type(*args)
|
118
|
+
add_type(ManagedType.new(*args))
|
119
|
+
end
|
120
|
+
|
121
|
+
def version_namespace(version)
|
122
|
+
namespace = @version_namespaces[version]
|
123
|
+
version_id = @version_ids[version]
|
124
|
+
|
125
|
+
if version_id
|
126
|
+
"#{namespace}/#{version_id}"
|
127
|
+
else
|
128
|
+
namespace
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_type(type)
|
133
|
+
@type_info[type.name] = type
|
134
|
+
namespace = wsdl_namespace(type.version)
|
135
|
+
@wsdl_type_namespaces << namespace
|
136
|
+
|
137
|
+
if @wsdl_type_info.has_key?([namespace, type.wsdl_name])
|
138
|
+
raise "Duplicate wsdl type #{type.wsdl_name} (already in typemap)" if @wsdl_type_info[namespace, type.wsdl_name] != type
|
139
|
+
else
|
140
|
+
@wsdl_type_info[[namespace, type.wsdl_name]] = type
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def wsdl_namespace(version)
|
145
|
+
"urn:#{@service_version_namespaces[version]}"
|
146
|
+
end
|
147
|
+
|
148
|
+
def is_child_version(a, b)
|
149
|
+
a == b || (@version_parents[a] && @version_parents[a][b])
|
150
|
+
end
|
151
|
+
|
152
|
+
def compatible_type(type, version)
|
153
|
+
if type.respond_to?(:version)
|
154
|
+
type = type.superclass until is_child_version(version, type.version)
|
155
|
+
end
|
156
|
+
type
|
157
|
+
end
|
158
|
+
|
159
|
+
def guess_wsdl_type(name)
|
160
|
+
@wsdl_type_namespaces.each do |namespace|
|
161
|
+
type = @wsdl_types[[namespace, name]]
|
162
|
+
return type if type
|
163
|
+
end
|
164
|
+
raise "Couldn't guess type for #{name}"
|
165
|
+
end
|
166
|
+
|
167
|
+
def load_types
|
168
|
+
@type_info.each_value do |type|
|
169
|
+
load_type(type) unless @types.has_key?(type.name)
|
170
|
+
end
|
171
|
+
|
172
|
+
@types.each_value do |clazz|
|
173
|
+
type_info = clazz.instance_eval { @type_info }
|
174
|
+
if type_info
|
175
|
+
if type_info.kind_of?(DataType)
|
176
|
+
clazz.finalize
|
177
|
+
elsif type_info.class == EnumType
|
178
|
+
type_info.values.each do |value|
|
179
|
+
clazz.const_set(VmodlHelper.underscore(value).upcase, value)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def load_type(type)
|
187
|
+
if type.respond_to?(:parent)
|
188
|
+
parent = type.parent
|
189
|
+
else
|
190
|
+
parent = nil
|
191
|
+
end
|
192
|
+
|
193
|
+
unless parent.nil? || @types.has_key?(type.parent)
|
194
|
+
load_type(@type_info[type.parent])
|
195
|
+
end
|
196
|
+
|
197
|
+
names = type.name.split(".")
|
198
|
+
|
199
|
+
current_name = ""
|
200
|
+
current_module = VimSdk
|
201
|
+
|
202
|
+
names[0..-2].each do |name|
|
203
|
+
if current_name.empty?
|
204
|
+
current_name = name
|
205
|
+
else
|
206
|
+
current_name = "#{current_name}.#{name}"
|
207
|
+
end
|
208
|
+
|
209
|
+
module_name = name.to_sym
|
210
|
+
unless current_module.const_defined?(module_name)
|
211
|
+
if @type_info.has_key?(current_name)
|
212
|
+
load_type(@type_info[current_name])
|
213
|
+
else
|
214
|
+
current_module.const_set(module_name, Module.new)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
current_module = current_module.const_get(module_name)
|
218
|
+
end
|
219
|
+
|
220
|
+
if type.kind_of?(EnumType)
|
221
|
+
super_class = SoapEnum
|
222
|
+
else
|
223
|
+
super_class = @types[type.parent]
|
224
|
+
end
|
225
|
+
|
226
|
+
clazz = Class.new(super_class) do
|
227
|
+
@type_info = type
|
228
|
+
end
|
229
|
+
current_module.const_set(names.last, clazz)
|
230
|
+
|
231
|
+
array_clazz = Class.new(TypedArray) do
|
232
|
+
@item = clazz
|
233
|
+
end
|
234
|
+
clazz.const_set(:TypedArray, array_clazz)
|
235
|
+
|
236
|
+
@types[type.name] = clazz
|
237
|
+
@types["#{type.name}[]"] = array_clazz
|
238
|
+
@wsdl_types[[wsdl_namespace(type.version), type.wsdl_name]] = clazz
|
239
|
+
@wsdl_types[[wsdl_namespace(type.version), "ArrayOf#{type.wsdl_name}"]] = array_clazz
|
240
|
+
end
|
241
|
+
|
242
|
+
def loaded_type(type_name)
|
243
|
+
raise "Can't find #{type_name}" unless @types[type_name]
|
244
|
+
@types[type_name]
|
245
|
+
end
|
246
|
+
|
247
|
+
def loaded_wsdl_type(namespace, name)
|
248
|
+
raise "Can't find #{namespace}/#{name}" unless @wsdl_types[[namespace, name]]
|
249
|
+
@wsdl_types[[namespace, name]]
|
250
|
+
end
|
251
|
+
|
252
|
+
def qualified_wsdl_name(type)
|
253
|
+
result = @wsdl_names[type]
|
254
|
+
if result
|
255
|
+
result
|
256
|
+
else
|
257
|
+
if type.ancestors.include?(Array)
|
258
|
+
type_info = type.class.type_info
|
259
|
+
[type_info.version, "ArrayOf#{type_info.wsdl_name}"]
|
260
|
+
else
|
261
|
+
namespace = wsdl_namespace(type.version)
|
262
|
+
[namespace, type.type_info.wsdl_name]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def wsdl_name(type)
|
268
|
+
qualified_wsdl_name(type).last
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
require "ruby_vim_sdk/missing_types"
|
273
|
+
require "ruby_vim_sdk/core_types"
|
274
|
+
require "ruby_vim_sdk/server_objects"
|
275
|
+
|
276
|
+
load_types
|
277
|
+
end
|
278
|
+
|
279
|
+
DYNAMIC_TYPES = Set.new([Class, Vmodl::TypeName, Vmodl::MethodName, Vmodl::PropertyPath])
|
280
|
+
end
|