ruby_vim_sdk 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/README +1 -0
  2. data/Rakefile +51 -0
  3. data/lib/ruby_vim_sdk.rb +48 -0
  4. data/lib/ruby_vim_sdk/base_type.rb +15 -0
  5. data/lib/ruby_vim_sdk/const.rb +32 -0
  6. data/lib/ruby_vim_sdk/core_types.rb +68 -0
  7. data/lib/ruby_vim_sdk/data_type.rb +14 -0
  8. data/lib/ruby_vim_sdk/enum_type.rb +12 -0
  9. data/lib/ruby_vim_sdk/ext.rb +9 -0
  10. data/lib/ruby_vim_sdk/managed_type.rb +12 -0
  11. data/lib/ruby_vim_sdk/method.rb +37 -0
  12. data/lib/ruby_vim_sdk/missing_types.rb +11 -0
  13. data/lib/ruby_vim_sdk/property.rb +49 -0
  14. data/lib/ruby_vim_sdk/server_objects.rb +2718 -0
  15. data/lib/ruby_vim_sdk/soap/deserializer.rb +301 -0
  16. data/lib/ruby_vim_sdk/soap/serializer.rb +225 -0
  17. data/lib/ruby_vim_sdk/soap/stub_adapter.rb +123 -0
  18. data/lib/ruby_vim_sdk/soap_exception.rb +12 -0
  19. data/lib/ruby_vim_sdk/typed_array.rb +9 -0
  20. data/lib/ruby_vim_sdk/types.rb +22 -0
  21. data/lib/ruby_vim_sdk/version.rb +5 -0
  22. data/lib/ruby_vim_sdk/vmodl/data_object.rb +102 -0
  23. data/lib/ruby_vim_sdk/vmodl/managed_object.rb +78 -0
  24. data/lib/ruby_vim_sdk/vmodl/method_name.rb +7 -0
  25. data/lib/ruby_vim_sdk/vmodl/property_path.rb +7 -0
  26. data/lib/ruby_vim_sdk/vmodl/type_name.rb +7 -0
  27. data/lib/ruby_vim_sdk/vmodl_helper.rb +33 -0
  28. data/lib/ruby_vim_sdk/vmomi_support.rb +280 -0
  29. data/spec/spec_helper.rb +10 -0
  30. data/spec/unit/soap/deserializer_spec.rb +206 -0
  31. data/spec/unit/soap/serializer_spec.rb +261 -0
  32. data/spec/unit/soap/stub_adapter_spec.rb +9 -0
  33. data/spec/unit/vmodl/data_object_spec.rb +9 -0
  34. data/spec/unit/vmodl/managed_object_spec.rb +9 -0
  35. data/spec/unit/vmodl_helper_spec.rb +36 -0
  36. data/spec/unit/vmomi_support_spec.rb +33 -0
  37. 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,12 @@
1
+ module VimSdk
2
+ class SoapException < Exception
3
+
4
+ attr_reader :fault
5
+
6
+ def initialize(message, fault)
7
+ super(message)
8
+ @fault = fault
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,9 @@
1
+ module VimSdk
2
+
3
+ class TypedArray < Array
4
+ class << self
5
+ attr_accessor :item
6
+ end
7
+ end
8
+
9
+ 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,5 @@
1
+ # Copyright (c) 2009-2012 VMware, Inc.
2
+
3
+ module VimSdk
4
+ VERSION = "0.0.2"
5
+ 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,7 @@
1
+ module VimSdk
2
+ module Vmodl
3
+ class MethodName < String
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module VimSdk
2
+ module Vmodl
3
+ class PropertyPath < String
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module VimSdk
2
+ module Vmodl
3
+ class TypeName < String
4
+
5
+ end
6
+ end
7
+ 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