rubywbem 0.1.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.
@@ -0,0 +1,23 @@
1
+ #
2
+ # Copyright 2006, Red Hat, Inc
3
+ # Scott Seago <sseago@redhat.com>
4
+ #
5
+ # derived from pywbem, written by Tim Potter <tpot@hp.com>, Martin Pool <mbp@hp.com>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15
+ #
16
+ require "wbem/cim_constants"
17
+ require "wbem/cim_http"
18
+ require "wbem/cim_obj"
19
+ require "wbem/cim_types"
20
+ require "wbem/cim_operations"
21
+ require "wbem/cim_xml"
22
+ require "wbem/tupleparse"
23
+ require "wbem/tupletree"
@@ -0,0 +1,50 @@
1
+ #
2
+ # Copyright 2006, Red Hat, Inc
3
+ # Scott Seago <sseago@redhat.com>
4
+ #
5
+ # derived from pywbem, written by Tim Potter <tpot@hp.com>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15
+ #
16
+ #"""Useful CIM constants."""
17
+
18
+ module WBEM
19
+
20
+ # CIMError error code constants
21
+
22
+ CIM_ERR_FAILED = 1 # A general error occurred
23
+ CIM_ERR_ACCESS_DENIED = 2 # Resource not available
24
+ CIM_ERR_INVALID_NAMESPACE = 3 # The target namespace does not exist
25
+ CIM_ERR_INVALID_PARAMETER = 4 # Parameter value(s) invalid
26
+ CIM_ERR_INVALID_CLASS = 5 # The specified Class does not exist
27
+ CIM_ERR_NOT_FOUND = 6 # Requested object could not be found
28
+ CIM_ERR_NOT_SUPPORTED = 7 # Operation not supported
29
+ CIM_ERR_CLASS_HAS_CHILDREN = 8 # Class has subclasses
30
+ CIM_ERR_CLASS_HAS_INSTANCES = 9 # Class has instances
31
+ CIM_ERR_INVALID_SUPERCLASS = 10 # Superclass does not exist
32
+ CIM_ERR_ALREADY_EXISTS = 11 # Object already exists
33
+ CIM_ERR_NO_SUCH_PROPERTY = 12 # Property does not exist
34
+ CIM_ERR_TYPE_MISMATCH = 13 # Value incompatible with type
35
+ CIM_ERR_QUERY_LANGUAGE_NOT_SUPPORTED = 14 # Query language not supported
36
+ CIM_ERR_INVALID_QUERY = 15 # Query not valid
37
+ CIM_ERR_METHOD_NOT_AVAILABLE = 16 # Extrinsic method not executed
38
+ CIM_ERR_METHOD_NOT_FOUND = 17 # Extrinsic method does not exist
39
+
40
+ # Provider types
41
+
42
+ PROVIDERTYPE_CLASS = 1
43
+ PROVIDERTYPE_INSTANCE = 2
44
+ PROVIDERTYPE_ASSOCIATION = 3
45
+ PROVIDERTYPE_INDICATION = 4
46
+ PROVIDERTYPE_METHOD = 5
47
+ PROVIDERTYPE_CONSUMER = 6 # Indication consumer
48
+ PROVIDERTYPE_QUERY = 7
49
+
50
+ end
@@ -0,0 +1,137 @@
1
+ #
2
+ # Copyright 2006, Red Hat, Inc
3
+ # Scott Seago <sseago@redhat.com>
4
+ #
5
+ # derived from pywbem, written by Tim Potter <tpot@hp.com>, Martin Pool <mbp@hp.com>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15
+ #
16
+
17
+ #'''
18
+ #This module implements CIM operations over HTTP.
19
+ #
20
+ #This module should not know anything about the fact that the data
21
+ #being transferred is XML. It is up to the caller to format the input
22
+ #data and interpret the result.
23
+ #'''
24
+
25
+ require "wbem/cim_obj"
26
+ require "net/https"
27
+
28
+ module WBEM
29
+ class CIMHttpError < Exception
30
+ # """This exception is raised when a transport error occurs."""
31
+ end
32
+ class AuthError < StandardError
33
+ #"""This exception is raised when an authentication error (401) occurs."""
34
+ end
35
+
36
+ def WBEM.parse_url(url)
37
+ #"""Return an array of (host, port, ssl, credentials) from the URL parameter.
38
+ #The returned port defaults to 5988 if not specified. SSL supports
39
+ #defaults to False if not specified. Credentials are optional
40
+ #as they may be specified as a separate parameter to
41
+ #wbem_request. """
42
+
43
+ host = url.sub(%r{^https?://}, "") # Eat protocol name
44
+ port = 5988
45
+ ssl = false
46
+
47
+ if /^https/.match(url) # Set SSL if specified
48
+ ssl = true
49
+ port = 5989
50
+ end
51
+
52
+ s = host.split("@") # parse creds if specified
53
+ if (s.length > 1 )
54
+ creds = s[0].split(":")
55
+ host = s[1]
56
+ end
57
+ s = host.split(":") # Set port number
58
+ if (s.length > 1 )
59
+ host = s[0]
60
+ port = s[1].to_i
61
+ end
62
+ # STDOUT << "host: #{host}, port: #{port}, ssl: #{ssl}, creds: #{creds}\n"
63
+ return host, port, ssl, creds
64
+ end
65
+
66
+ def WBEM.wbem_request(url, data, creds, headers = [], debug = 0, x509 = nil)
67
+ #"""Send XML data over HTTP to the specified url. Return the
68
+ #response in XML. Uses Python's build-in httplib. x509 may be a
69
+ #dictionary containing the location of the SSL certificate and key
70
+ #files."""
71
+
72
+ host, port, ssl, urlcreds = WBEM.parse_url(url)
73
+ creds = urlcreds unless creds
74
+ h = Net::HTTP.new(host, port)
75
+ if (ssl)
76
+ if x509
77
+ cert_file = x509.get("cert_file")
78
+ key_file = x509.get("key_file", cert_file)
79
+ else
80
+ cert_file = nil
81
+ key_file = nil
82
+ end
83
+ h.use_ssl = true
84
+ # key_file, cert_file ???
85
+ end
86
+ data = "<?xml version='1.0' encoding='utf-8' ?>\n" + data
87
+ response = nil
88
+ h.start do |http|
89
+ request = Net::HTTP::Post.new("/cimom")
90
+ request.basic_auth creds[0], creds[1]
91
+ request.content_type = "application/xml"
92
+ request.content_length = data.length
93
+ headers.each do |header|
94
+ s = header.split(":", 2).collect { |x| x.strip }
95
+ request.add_field(URI.escape(s[0]), URI.escape(s[1]))
96
+ end
97
+ # STDOUT << "request: #{data}\n"
98
+ response = http.request(request, data)
99
+ # STDOUT << "response: #{response.body}\n"
100
+ end
101
+ unless response.kind_of?(Net::HTTPSuccess)
102
+ if (response.kind_of?(NET::HTTPUnauthorized))
103
+ raise AuthError, response.reason
104
+ elsif (response.fetch("CIMError", []) or response.fetch("PGErrorDetail", []))
105
+ raise CIMHttpError, "CIMError: #{response.fetch('CIMError',[])}: #{response.fetch('PGErrorDetail',[])}"
106
+ end
107
+ raise CIMHttpError, "HTTP error: #{response.reason}"
108
+ end
109
+ # TODO: do we need more error checking here?
110
+
111
+ response.body
112
+ end
113
+
114
+ def WBEM.get_object_header(obj)
115
+ #"""Return the HTTP header required to make a CIM operation request
116
+ #using the given object. Return None if the object does not need
117
+ #to have a header."""
118
+
119
+ # Local namespacepath
120
+
121
+ if obj.kind_of?(String)
122
+ return "CIMObject: #{obj}"
123
+ end
124
+
125
+ # CIMLocalClassPath
126
+
127
+ if obj.kind_of?(CIMLocalClassPath)
128
+ return "CIMObject: #{obj.localnamespacepath}:#{obj.classname}"
129
+ end
130
+ # CIMInstanceName with namespace
131
+
132
+ if obj.kind_of?(CIMInstanceName) && !obj.namespace.nil?
133
+ return 'CIMObject: %s' % obj
134
+ end
135
+ raise CIMHttpError, "Don\'t know how to generate HTTP headers for #{obj}"
136
+ end
137
+ end
@@ -0,0 +1,1148 @@
1
+ #
2
+ # Copyright 2006, Red Hat, Inc
3
+ # Scott Seago <sseago@redhat.com>
4
+ #
5
+ # derived from pywbem, written by Tim Potter <tpot@hp.com>, Martin Pool <mbp@hp.com>
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, write to the Free Software
14
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15
+ #
16
+
17
+ require "wbem/cim_types"
18
+ require "wbem/cim_xml"
19
+ require "date"
20
+
21
+ #"""
22
+ #Representations of CIM Objects.
23
+ #
24
+ #In general we try to map CIM objects directly into standard Ruby types,
25
+ #except when that is not possible or would be ambiguous. For example,
26
+ #CIM Class names are simply strings, but a ClassPath is
27
+ #represented as a special object.
28
+ #
29
+ #These objects can also be mapped back into XML, by the toxml() method
30
+ #which returns a string.
31
+ #"""
32
+
33
+ #
34
+ # Base objects
35
+ #
36
+
37
+ module WBEM
38
+
39
+ class NocaseHash < Hash
40
+
41
+ def initialize(initial_values = {})
42
+ super()
43
+ initial_values = initial_values.to_a if initial_values.is_a?(Hash)
44
+ if initial_values.is_a?(Array)
45
+ initial_values.each do |item|
46
+ self[item[0]] = item[1] if item.is_a?(Array)
47
+ end
48
+ end
49
+ end
50
+
51
+ def get_key(key)
52
+ key.is_a?(String) ? key.downcase : key
53
+ end
54
+ def [](key)
55
+ v = super(get_key(key))
56
+ v[1] unless v.nil?
57
+ end
58
+ def []=(key, value)
59
+ unless key.is_a?(String)
60
+ raise IndexError, "Key must be a String"
61
+ end
62
+ super(get_key(key),[key, value])
63
+ end
64
+ alias rawkeys keys
65
+ alias rawvalues values
66
+ alias rawarray to_a
67
+ def keys
68
+ rawvalues.collect { |v| v[0] }
69
+ end
70
+ def values
71
+ super.collect { |v| v[1] }
72
+ end
73
+ def to_a
74
+ super.collect { |k,v| [v[0], v[1]] }
75
+ end
76
+ def each(&block)
77
+ to_a.each(&block)
78
+ end
79
+ def sort
80
+ rawarray.sort.collect { |k,v| [v[0], v[1]] }
81
+ end
82
+ def ==(other)
83
+ self.each do |key, value|
84
+ return false unless (other.include?(key) and other[key] == value)
85
+ end
86
+ return self.length == other.length
87
+ end
88
+
89
+ def delete(key)
90
+ super(get_key(key))
91
+ end
92
+ def fetch(key)
93
+ super(get_key(key))[1]
94
+ end
95
+ def has_key?(key)
96
+ super(get_key(key))
97
+ end
98
+ def include?(key)
99
+ super(get_key(key))
100
+ end
101
+ def update(otherHash)
102
+ otherHash.to_a.each { |key, value| self[key] = value }
103
+ end
104
+ def clone
105
+ return NocaseHash.new(self)
106
+ end
107
+ alias copy clone
108
+ end
109
+
110
+ class XMLObject
111
+ #"""Base class for objects that produce cim_xml document fragments."""
112
+
113
+ def toxml
114
+ #"""Return the XML string representation of ourselves."""
115
+ ret = ""
116
+ self.tocimxml().write(ret)
117
+ return ret
118
+ end
119
+ def hash
120
+ self.toxml().hash
121
+ end
122
+ # probably not the best equality method, as trivial
123
+ # differences such as attribute order will affect the results,
124
+ # but better than the default eql? method defined in object --
125
+ # subclasses can define this in a better way
126
+ def eql?(other)
127
+ (self.toxml == other.toxml)
128
+ end
129
+
130
+ def nilcmp(obj1, obj2)
131
+ cmpname(obj1, obj2, false)
132
+ end
133
+
134
+ def cmpname(name1, name2, downcase_strings = true)
135
+ #"""Compare to CIM names. The comparison is done
136
+ #case-insensitvely, and one or both of the names may be None."""
137
+
138
+ if name1.nil? and name2.nil?
139
+ return 0
140
+ end
141
+ unless (name1 || name2)
142
+ return 0
143
+ end
144
+
145
+ if name1.nil?
146
+ return -1
147
+ end
148
+
149
+ if name2.nil?
150
+ return 1
151
+ end
152
+ if (downcase_strings)
153
+ name1.downcase <=> name2.downcase
154
+ elsif (name2.is_a?(Boolean))
155
+ (name2 <=> name1)*-1
156
+ elsif (!name1.methods.include?("<=>"))
157
+ (name1 == name2) ? 0 : 1
158
+ elsif ((name1.nil? || name1 == false) &&
159
+ (name2.nil? || name2 == false))
160
+ return 0
161
+ else
162
+ name1 <=> name2
163
+ end
164
+ end
165
+ end
166
+
167
+ #
168
+ # Object location classes
169
+ #
170
+
171
+ #
172
+ # It turns out that most of the object location elements can be
173
+ # represented easily using one base class which roughly corresponds to
174
+ # the OBJECTPATH element.
175
+ #
176
+ # Element Name (host, namespace, classname, instancename)
177
+ # ---------------------------------------------------------------------------
178
+ # CLASSNAME (None, None, 'CIM_Foo', None)
179
+ # LOCALNAMESPACEPATH (None, 'root/cimv2', None, None)
180
+ # NAMESPACEPATH ('leonardo', 'root/cimv2', None, None)
181
+ # LOCALCLASSPATH (None, 'root/cimv2', 'CIM_Foo', None)
182
+ # CLASSPATH ('leonardo', 'root/cimv2', 'CIM_Foo', None)
183
+ # LOCALINSTANCEPATH (None, 'root/cimv2', None, InstanceName)
184
+ # INSTANCEPATH ('leonardo', 'root/cimv2', None, InstanceName)
185
+ #
186
+ # These guys also have string representations similar to the output
187
+ # produced by the Pegasus::CIMObjectPath.toString() method:
188
+ #
189
+ # Element Name Python Class String representation
190
+ # ---------------------------------------------------------------------------
191
+ # CLASSNAME CIMClassName CIM_Foo
192
+ # LOCALNAMESPACEPATH String root/cimv2:
193
+ # NAMESPACEPATH CIMNamespacePath //leo/root/cimv2:
194
+ # LOCALCLASSPATH CIMLocalClassPath root/cimv2:CIM_Foo
195
+ # CLASSPATH CIMClassPath //leo/root/cimv2:CIM_Foo
196
+ # INSTANCENAME CIMInstanceName CIM_Foo.Foo="Bar"
197
+ # LOCALINSTANCEPATH CIMLocalInstancePath root/cimv2:CIM_Foo.Foo="Bar"
198
+ # INSTANCEPATH CIMInstancePath //leo/root/cimv2:CIM_Foo.Foo="Bar"
199
+ #
200
+
201
+ class CIMObjectLocation < XMLObject
202
+ include Comparable
203
+ #"""A base class that can name any CIM object."""
204
+
205
+ attr_writer :host, :localnamespacepath, :classname, :instancename
206
+ attr_reader :host, :localnamespacepath, :classname, :instancename
207
+
208
+ def initialize(host = nil, localnamespacepath = nil,
209
+ classname = nil, instancename = nil)
210
+ @host = host
211
+ @localnamespacepath = localnamespacepath
212
+ @classname = classname
213
+ @instancename = instancename
214
+ end
215
+
216
+ def HOST
217
+ HOST.new(@host)
218
+ end
219
+
220
+ def CLASSNAME
221
+ CLASSNAME.new(@classname)
222
+ end
223
+
224
+ def LOCALNAMESPACEPATH
225
+ nsArray = @localnamespacepath.split("/").collect { |name| NAMESPACE.new(name) }
226
+ LOCALNAMESPACEPATH.new(nsArray)
227
+ end
228
+
229
+ def NAMESPACEPATH
230
+ NAMESPACEPATH.new(self.HOST, self.LOCALNAMESPACEPATH)
231
+ end
232
+
233
+ def eql?(other)
234
+ (self <=> other) == 0
235
+ end
236
+ def hash
237
+ self.host.hash + self.localnamespacepath.hash + self.classname.hash + self.instancename.hash
238
+ end
239
+ def <=>(other)
240
+ if equal?(other)
241
+ return 0
242
+ elsif (!other.kind_of?(CIMObjectLocation))
243
+ return 1
244
+ end
245
+ ret_val = cmpname(self.host, other.host)
246
+ ret_val = nilcmp(self.localnamespacepath, other.localnamespacepath) if (ret_val == 0)
247
+ ret_val = cmpname(lclassname, lOclassname) if (ret_val == 0)
248
+ ret_val = nilcmp(self.instancename, other.instancename) if (ret_val == 0)
249
+ ret_val
250
+ end
251
+ end
252
+
253
+ class CIMClassName < CIMObjectLocation
254
+ def initialize(classname)
255
+ unless classname.kind_of?(String)
256
+ raise TypeError, "classname argument must be a string"
257
+ end
258
+
259
+ # TODO: There are some odd restrictions on what a CIM
260
+ # classname can look like (i.e must start with a
261
+ # non-underscore and only one underscore per classname).
262
+ super()
263
+ self.classname=classname
264
+ end
265
+
266
+ def tocimxml
267
+ self.CLASSNAME
268
+ end
269
+
270
+ def to_s
271
+ self.classname
272
+ end
273
+
274
+ end
275
+
276
+ class CIMNamespacePath < CIMObjectLocation
277
+ def initialize(host, localnamespacepath)
278
+ unless host.kind_of?(String)
279
+ raise TypeError, "host argument must be a string"
280
+ end
281
+ unless localnamespacepath.kind_of?(String)
282
+ raise TypeError, "localnamespacepath argument must be a string"
283
+ end
284
+
285
+ super()
286
+ self.host=host
287
+ self.localnamespacepath=localnamespacepath
288
+ end
289
+
290
+ def tocimxml
291
+ self.NAMESPACEPATH
292
+ end
293
+
294
+ def to_s
295
+ "//#{self.host}/#{self.localnamespacepath}"
296
+ end
297
+ end
298
+
299
+ class CIMLocalClassPath < CIMObjectLocation
300
+ def initialize(localnamespacepath, classname)
301
+ unless localnamespacepath.kind_of?(String)
302
+ raise TypeError, "localnamespacepath argument must be a string"
303
+ end
304
+ unless classname.kind_of?(String)
305
+ raise TypeError, "classname argument must be a string"
306
+ end
307
+
308
+ super()
309
+ self.classname=classname
310
+ self.localnamespacepath=localnamespacepath
311
+ end
312
+
313
+ def tocimxml
314
+ LOCALCLASSPATH.new(self.LOCALNAMESPACEPATH, self.CLASSNAME)
315
+ end
316
+
317
+ def to_s
318
+ "#{self.localnamespacepath}:#{self.classname}"
319
+ end
320
+ end
321
+
322
+ class CIMClassPath < CIMObjectLocation
323
+ def initialize(localnamespacepath, classname)
324
+ unless host.kind_of?(String)
325
+ raise TypeError, "host argument must be a string"
326
+ end
327
+ unless localnamespacepath.kind_of?(String)
328
+ raise TypeError, "localnamespacepath argument must be a string"
329
+ end
330
+ unless classname.kind_of?(String)
331
+ raise TypeError, "classname argument must be a string"
332
+ end
333
+
334
+ super()
335
+ self.host=host
336
+ self.classname=classname
337
+ self.localnamespacepath=localnamespacepath
338
+ end
339
+
340
+ def tocimxml
341
+ CLASSPATH.new(self.NAMESPACEPATH, self.CLASSNAME)
342
+ end
343
+
344
+ def to_s
345
+ "//#{self.host}/#{self.localnamespacepath}:#{self.classname}"
346
+ end
347
+ end
348
+
349
+ # Object value elements
350
+
351
+ class CIMProperty < XMLObject
352
+ include Comparable
353
+ #"""A property of a CIMInstance.
354
+
355
+ #Property objects represent both properties on particular instances,
356
+ #and the property defined in a class. In the first case, the property
357
+ #will have a Value and in the second it will not.
358
+
359
+ #The property may hold an array value, in which case it is encoded
360
+ #in XML to PROPERTY.ARRAY containing VALUE.ARRAY.
361
+
362
+ #Properties holding references are handled specially as
363
+ #CIMPropertyReference."""
364
+
365
+ attr_writer :name, :prop_type, :class_origin, :propagated, :value, :is_array, :reference_class, :array_size
366
+ attr_reader :name, :prop_type, :class_origin, :propagated, :value, :is_array, :qualifiers, :reference_class, :array_size
367
+
368
+ def initialize(name, value, type=nil, class_origin=nil, propagated=nil,
369
+ is_array = false, qualifiers = {},
370
+ reference_class = nil, array_size = nil)
371
+ #"""Construct a new CIMProperty
372
+ #Either the type or the value must be given. If the value is not
373
+ #given, it is left as nil. If the type is not given, it is implied
374
+ #from the value."""
375
+ unless name.kind_of?(String)
376
+ raise TypeError, "name argument must be a string"
377
+ end
378
+ unless (class_origin.nil? or class_origin.kind_of?(String))
379
+ raise TypeError, "class_origin argument must be a string"
380
+ end
381
+
382
+ @name = name
383
+ @value = value
384
+ @prop_type = type
385
+ @class_origin = class_origin
386
+ @propagated = propagated
387
+ @qualifiers = NocaseHash.new(qualifiers)
388
+ @is_array = is_array
389
+ @array_size = array_size
390
+ @reference_class = reference_class
391
+
392
+ if type.nil?
393
+ if (value.nil?)
394
+ raise TypeError, "value argument must not be nil if type is missing"
395
+ end
396
+ if (value.is_a?(Array))
397
+ if (value.empty?)
398
+ raise TypeError, "Empty property array #{name} must have a type"
399
+ end
400
+ @is_array = true
401
+ @prop_type = WBEM.cimtype(value[0])
402
+ else
403
+ @prop_type = WBEM.cimtype(value)
404
+ end
405
+ else
406
+ @is_array = true if (value.is_a?(Array))
407
+ @prop_type = type
408
+ end
409
+ @value = value
410
+ end
411
+
412
+ def qualifiers=(qualifiers)
413
+ @qualifiers = NocaseHash.new(qualifiers)
414
+ end
415
+
416
+ def clone
417
+ return CIMProperty.new(self.name,
418
+ self.value,
419
+ self.prop_type,
420
+ self.class_origin,
421
+ self.propagated,
422
+ self.is_array,
423
+ self.qualifiers,
424
+ self.reference_class,
425
+ self.array_size)
426
+ end
427
+
428
+ def to_s
429
+ r = "#{self.class}(name=#{self.name}, type=#{self.prop_type}"
430
+ r += ", class_origin=#{self.class_origin}" if self.class_origin
431
+ r += ", propagated=#{self.propagated}" if self.propagated
432
+ r += ", value=#{self.value}" if self.value
433
+ r += ", qualifiers=#{self.qualifiers}" if self.qualifiers
434
+ r += ", is_array=#{self.is_array}"
435
+ r += ")"
436
+ end
437
+
438
+ def <=>(other)
439
+ if equal?(other)
440
+ ret_val = 0
441
+ elsif (!other.kind_of?(CIMProperty ))
442
+ ret_val = 1
443
+ else
444
+ ret_val = cmpname(self.name, other.name)
445
+ ret_val = nilcmp(self.value, other.value) if (ret_val == 0)
446
+ ret_val = nilcmp(self.prop_type, other.prop_type) if (ret_val == 0)
447
+ ret_val = nilcmp(self.class_origin, other.class_origin) if (ret_val == 0)
448
+ ret_val = nilcmp(self.propagated, other.propagated) if (ret_val == 0)
449
+ ret_val = nilcmp(self.qualifiers, other.qualifiers) if (ret_val == 0)
450
+ ret_val = nilcmp(self.is_array, other.is_array) if (ret_val == 0)
451
+ ret_val = cmpname(self.reference_class, other.reference_class) if (ret_val == 0)
452
+ end
453
+ ret_val
454
+ end
455
+
456
+ def tocimxml
457
+ if self.is_array
458
+ return PROPERTY_ARRAY.new(self.name,
459
+ self.prop_type,
460
+ WBEM.tocimxml(self.value),
461
+ self.array_size,
462
+ self.class_origin,
463
+ self.propagated,
464
+ self.qualifiers.values.collect { |q| q.tocimxml})
465
+ elsif self.prop_type == 'reference'
466
+ return PROPERTY_REFERENCE.new(self.name,
467
+ WBEM.tocimxml(self.value, true),
468
+ self.reference_class,
469
+ self.class_origin,
470
+ self.propagated,
471
+ self.qualifiers.values.collect { |q| q.tocimxml})
472
+ else
473
+ return PROPERTY.new(self.name,
474
+ self.prop_type,
475
+ WBEM.tocimxml(self.value),
476
+ self.class_origin,
477
+ self.propagated,
478
+ self.qualifiers.values.collect { |q| q.tocimxml})
479
+ end
480
+ end
481
+ end
482
+
483
+ class CIMInstanceName < XMLObject
484
+ include Comparable
485
+ #"""Name (keys) identifying an instance.
486
+
487
+ #This may be treated as a hash to retrieve the keys."""
488
+ # qualifiers removed?
489
+ attr_reader :classname, :keybindings, :host, :namespace
490
+ attr_writer :classname, :keybindings, :host, :namespace
491
+ def initialize(classname, keybindings = {}, host = nil, namespace = nil)
492
+ @classname = classname
493
+ @keybindings = NocaseHash.new(keybindings)
494
+ @host = host
495
+ @namespace = namespace
496
+ end
497
+
498
+ def clone
499
+ CIMInstanceName.new(@classname, @keybindings, @host, @namespace)
500
+ end
501
+
502
+ def <=>(other)
503
+ if equal?(other)
504
+ ret_val = 0
505
+ elsif (!other.kind_of?(CIMInstanceName ))
506
+ ret_val = 1
507
+ else
508
+ ## TODO: Allow for the type to be null as long as the values
509
+ ## are the same and non-null?
510
+ ret_val = cmpname(self.classname, other.classname)
511
+ ret_val = nilcmp(self.keybindings, other.keybindings) if (ret_val == 0)
512
+ ret_val = cmpname(self.host, other.host) if (ret_val == 0)
513
+ ret_val = cmpname(self.namespace, other.namespace) if (ret_val == 0)
514
+ end
515
+ ret_val
516
+ end
517
+
518
+ def keybindings=(keybindings)
519
+ @keybindings = NocaseHash.new(keybindings)
520
+ end
521
+
522
+ def to_s
523
+ s = ''
524
+
525
+ unless self.host.nil?
526
+ s += '//%s/' % self.host
527
+ end
528
+ unless self.namespace.nil?
529
+ s += '%s:' % self.namespace
530
+ end
531
+ s += '%s.' % self.classname
532
+
533
+ self.keybindings.to_a.each do |key, value|
534
+
535
+ s += "#{key}="
536
+
537
+ if value.kind_of?(Integer)
538
+ s += value.to_s
539
+ else
540
+ s += '"%s"' % value
541
+ end
542
+ s += ","
543
+ end
544
+ return s[0..-2]
545
+ end
546
+ # A whole bunch of dictionary methods that map to the equivalent
547
+ # operation on self.keybindings.
548
+
549
+ def fetch(key)
550
+ return self.keybindings.fetch(key)
551
+ end
552
+ def [](key)
553
+ return self.keybindings[key]
554
+ end
555
+ def []=(key, value)
556
+ return self.keybindings[key] = value
557
+ end
558
+ def delete(key)
559
+ self.keybindings.delete(key)
560
+ end
561
+ def length
562
+ return self.keybindings.length
563
+ end
564
+ def has_key?(key)
565
+ return self.keybindings.has_key?(key)
566
+ end
567
+ def keys
568
+ return self.keybindings.keys()
569
+ end
570
+ def values
571
+ return self.keybindings.values()
572
+ end
573
+ def to_a
574
+ return self.keybindings.to_a()
575
+ end
576
+
577
+ def tocimxml
578
+ # Generate an XML representation of the instance classname and
579
+ # keybindings.
580
+
581
+ if (self.keybindings.kind_of?(String))
582
+ # Class with single key string property
583
+ instancename_xml = INSTANCENAME.new(self.classname,
584
+ KEYVALUE.new(self.keybindings, "string"))
585
+
586
+ elsif (self.keybindings.kind_of?(Integer))
587
+ # Class with single key numeric property
588
+ instancename_xml = INSTANCENAME.new(self.classname,
589
+ KEYVALUE.new(self.keybindings.to_s, "numeric"))
590
+
591
+ elsif (self.keybindings.kind_of?(NocaseHash))
592
+ # Dictionary of keybindings
593
+ kbs = []
594
+ self.keybindings.to_a.each do |kb|
595
+ # Keybindings can be integers, booleans, strings or
596
+ # value references.
597
+ if (kb[1].methods.include?("tocimxml"))
598
+ kbs << KEYBINDING.new(kb[0], VALUE_REFERENCE.new(kb[1].tocimxml()))
599
+ next
600
+ end
601
+
602
+ if (kb[1].kind_of?(Integer) or kb[1].kind_of?(CIMInt))
603
+ _type = "numeric"
604
+ value = kb[1].to_s
605
+ elsif (kb[1] == true or kb[1] == false)
606
+ _type = "boolean"
607
+ if kb[1]
608
+ value = "TRUE"
609
+ else
610
+ value = "FALSE"
611
+ end
612
+ elsif (kb[1].kind_of?(String )) # unicode?
613
+ _type = "string"
614
+ value = kb[1]
615
+ else
616
+ raise TypeError, "Invalid keybinding type #{kb[1]}(#{kb[1].class}) for keybinding #{kb[0]}"
617
+ end
618
+
619
+ kbs << KEYBINDING.new(kb[0], KEYVALUE.new(value, _type))
620
+
621
+ end
622
+ instancename_xml = INSTANCENAME.new(self.classname, kbs)
623
+
624
+ else
625
+ # Value reference
626
+
627
+ return instancename_xml = INSTANCENAME.new(self.classname, self.keybindings.nil? ? nil : VALUE_REFERENCE.new(self.keybindings.tocimxml()))
628
+ end
629
+ # Instance name plus namespace = LOCALINSTANCEPATH
630
+
631
+ if (self.host.nil? && !self.namespace.nil?)
632
+ return LOCALINSTANCEPATH.new(
633
+ LOCALNAMESPACEPATH.new(
634
+ self.namespace.split('/').collect { |ns| NAMESPACE.new(ns)}),
635
+ instancename_xml)
636
+ end
637
+
638
+ # Instance name plus host and namespace = INSTANCEPATH
639
+ if (!self.host.nil? && !self.namespace.nil?)
640
+ return INSTANCEPATH.new(
641
+ NAMESPACEPATH.new(
642
+ HOST.new(self.host),
643
+ LOCALNAMESPACEPATH.new(
644
+ self.namespace.split('/').collect { |ns| NAMESPACE.new(ns)})),
645
+ instancename_xml)
646
+ end
647
+
648
+ # Just a regular INSTANCENAME
649
+ return instancename_xml
650
+ end
651
+ end
652
+
653
+ class CIMInstance < XMLObject
654
+ include Comparable
655
+ #"""Instance of a CIM Object.
656
+
657
+ #Has a classname (string), and named arrays of properties and qualifiers.
658
+
659
+ #The properties is indexed by name and points to CIMProperty
660
+ #instances."""
661
+
662
+ attr_reader :classname, :properties, :qualifiers, :path
663
+ attr_writer :classname, :path
664
+ def initialize(classname, properties = {}, qualifiers = {},
665
+ path = nil)
666
+ #"""Create CIMInstance.
667
+
668
+ @classname = classname
669
+ @qualifiers = NocaseHash.new(qualifiers)
670
+ @path = path
671
+ @properties = NocaseHash.new
672
+ properties.each do |k, v|
673
+ self[k]=v
674
+ end
675
+ end
676
+
677
+ def clone
678
+ CIMInstance.new(@classname, @properties, @qualifiers, @path)
679
+ end
680
+
681
+ def properties=(properties)
682
+ @properties = NocaseHash.new
683
+ properties.each do |k, v|
684
+ self[k]=v
685
+ end
686
+ end
687
+
688
+ def qualifiers=(qualifiers)
689
+ @qualifiers = NocaseHash.new(qualifiers)
690
+ end
691
+
692
+ def <=>(other)
693
+ if equal?(other)
694
+ return 0
695
+ elsif (!other.kind_of?(CIMInstance))
696
+ return 1
697
+ end
698
+ ## TODO: Allow for the type to be null as long as the values
699
+ ## are the same and non-null?
700
+ ret_val = cmpname(self.classname, other.classname)
701
+ ret_val = nilcmp(self.path, other.path) if (ret_val == 0)
702
+ ret_val = nilcmp(self.properties, other.properties) if (ret_val == 0)
703
+ ret_val = nilcmp(self.qualifiers, other.qualifiers) if (ret_val == 0)
704
+ ret_val
705
+ end
706
+
707
+ def to_s
708
+ # Don't show all the properties and qualifiers because they're
709
+ # just too big
710
+ "#{self.class}(classname=#{self.classname} ...)"
711
+ end
712
+
713
+ # A whole bunch of dictionary methods that map to the equivalent
714
+ # operation on self.properties.
715
+
716
+ def fetch(key)
717
+ return self.properties.fetch(key)
718
+ end
719
+ def [](key)
720
+ ret = self.properties[key]
721
+ ret = ret.value unless ret.nil?
722
+ end
723
+ def delete(key)
724
+ self.properties.delete(key)
725
+ end
726
+ def length
727
+ self.properties.length
728
+ end
729
+ def has_key?(key)
730
+ self.properties.has_key?(key)
731
+ end
732
+ def keys
733
+ self.properties.keys()
734
+ end
735
+ def values
736
+ self.properties.values.collect { |v| v.value }
737
+ end
738
+ def to_a
739
+ self.properties.to_a.collect { |k, v| [k, v.value] }
740
+ end
741
+ #def iterkeys(self): return self.properties.iterkeys()
742
+ #def itervalues(self): return self.properties.itervalues()
743
+ #def iteritems(self): return self.properties.iteritems()
744
+
745
+ def []=(key, value)
746
+
747
+ # Don't let anyone set integer or float values. You must use
748
+ # a subclass from the cim_type module.
749
+
750
+ unless (value.is_a?(CIMProperty))
751
+ unless WBEM.valid_cimtype?(value)
752
+ raise TypeError, "Must use a CIM type assigning numeric values."
753
+ end
754
+ value = CIMProperty.new(key, value)
755
+ end
756
+ self.properties[key] = value
757
+ end
758
+
759
+ def tocimxml
760
+ props = []
761
+ self.properties.each do |key, prop|
762
+ if (prop.is_a?(CIMProperty))
763
+ props << prop
764
+ else
765
+ props << CIMProperty.new(key, prop)
766
+ end
767
+ end
768
+ instance_xml = INSTANCE.new(self.classname,
769
+ props.collect { |p| p.tocimxml},
770
+ self.qualifiers.values.collect { |q| q.tocimxml})
771
+ if self.path.nil?
772
+ return instance_xml
773
+ end
774
+ return VALUE_NAMEDINSTANCE.new(self.path.tocimxml,
775
+ instance_xml)
776
+ end
777
+ end
778
+
779
+ class CIMClass < XMLObject
780
+ #"""Class, including a description of properties, methods and qualifiers.
781
+ #superclass may be None."""
782
+ include Comparable
783
+ attr_reader :classname, :properties, :qualifiers, :cim_methods, :superclass
784
+ attr_writer :classname, :superclass
785
+ def initialize(classname, properties = {}, qualifiers = {},
786
+ methods = {}, superclass = nil)
787
+ unless (classname.kind_of?(String))
788
+ raise TypeError, "classname must be a String"
789
+ end
790
+ @classname = classname
791
+ @properties = NocaseHash.new
792
+ unless properties.nil?
793
+ properties.each do |k, v|
794
+ @properties[k]=v
795
+ end
796
+ end
797
+ @qualifiers = NocaseHash.new(qualifiers)
798
+ @cim_methods = NocaseHash.new(methods)
799
+ @superclass = superclass
800
+ end
801
+
802
+ def clone
803
+ return CIMClass.new(@classname, @properties, @qualifiers,
804
+ @cim_methods, @superclass)
805
+ end
806
+
807
+ def properties=(properties)
808
+ @properties = NocaseHash.new
809
+ unless properties.nil?
810
+ properties.each do |k, v|
811
+ @properties[k]=v
812
+ end
813
+ end
814
+ end
815
+
816
+ def qualifiers=(qualifiers)
817
+ @qualifiers = NocaseHash.new(qualifiers)
818
+ end
819
+
820
+ def cim_methods=(cim_methods)
821
+ @cim_methods = NocaseHash.new(cim_methods)
822
+ end
823
+
824
+ def to_s
825
+ "#{self.class}(#{self.classname}, ...)"
826
+ end
827
+
828
+ def <=>(other)
829
+ if equal?(other)
830
+ return 0
831
+ elsif (!other.kind_of?(CIMClass))
832
+ return 1
833
+ end
834
+ ret_val = cmpname(self.classname, other.classname)
835
+ ret_val = cmpname(self.superclass, other.superclass) if (ret_val == 0)
836
+ ret_val = nilcmp(self.properties, other.properties) if (ret_val == 0)
837
+ ret_val = nilcmp(self.qualifiers, other.qualifiers) if (ret_val == 0)
838
+ ret_val = nilcmp(self.cim_methods, other.cim_methods) if (ret_val == 0)
839
+ ret_val
840
+ end
841
+
842
+ def tocimxml
843
+ return CLASS.new(self.classname,
844
+ self.properties.values.collect {|p| p.tocimxml()},
845
+ self.cim_methods.values.collect {|m| m.tocimxml()},
846
+ self.qualifiers.values.collect {|q| q.tocimxml()},
847
+ self.superclass)
848
+ end
849
+ end
850
+
851
+ class CIMMethod < XMLObject
852
+ include Comparable
853
+
854
+ attr_reader :name, :parameters, :qualifiers, :class_origin, :return_type, :propagated
855
+ attr_writer :name, :class_origin, :return_type, :propagated
856
+ def initialize(methodname, return_type = nil, parameters = {}, class_origin = nil, propagated = false, qualifiers = {} )
857
+ @name = methodname
858
+ @return_type = return_type
859
+ @parameters = NocaseHash.new(parameters)
860
+ @class_origin = class_origin
861
+ @propagated = propagated
862
+ @qualifiers = NocaseHash.new(qualifiers)
863
+ end
864
+
865
+ def clone
866
+ return CIMMethod.new(@name, @return_type, @parameters,
867
+ @class_origin, @propagated, @qualifiers)
868
+ end
869
+
870
+ def parameters=(parameters)
871
+ @parameters = NocaseHash.new(parameters)
872
+ end
873
+
874
+ def qualifiers=(qualifiers)
875
+ @qualifiers = NocaseHash.new(qualifiers)
876
+ end
877
+
878
+ def tocimxml
879
+ METHOD.new(self.name,
880
+ self.parameters.values.collect {|p| p.tocimxml()},
881
+ self.return_type,
882
+ self.class_origin,
883
+ self.propagated,
884
+ self.qualifiers.values.collect {|q| q.tocimxml()})
885
+ end
886
+
887
+ def <=>(other)
888
+ ret_val = 0
889
+ if equal?(other)
890
+ return 0
891
+ elsif (!other.kind_of?(CIMMethod))
892
+ return 1
893
+ end
894
+ ret_val = cmpname(self.name, other.name)
895
+ ret_val = nilcmp(self.parameters, other.parameters) if (ret_val == 0)
896
+ ret_val = nilcmp(self.qualifiers, other.qualifiers) if (ret_val == 0)
897
+ ret_val = nilcmp(self.class_origin, other.class_origin) if (ret_val == 0)
898
+ ret_val = nilcmp(self.propagated, other.propagated) if (ret_val == 0)
899
+ ret_val = nilcmp(self.return_type, other.return_type) if (ret_val == 0)
900
+ ret_val
901
+ end
902
+
903
+ def to_s
904
+ "#{self.class}(name=#{self.name}, return_type=#{self.return_type}...)"
905
+ end
906
+ end
907
+
908
+ class CIMParameter < XMLObject
909
+ include Comparable
910
+
911
+ attr_writer :name, :param_type, :is_array, :reference_class, :array_size
912
+ attr_reader :name, :param_type, :is_array, :qualifiers, :reference_class, :array_size
913
+
914
+ def initialize(name, type, reference_class=nil, is_array = nil,
915
+ array_size = nil, qualifiers = {})
916
+ @name = name
917
+ @param_type = type
918
+ @reference_class = reference_class
919
+ @is_array = is_array
920
+ @array_size = array_size
921
+ @qualifiers = NocaseHash.new(qualifiers)
922
+ end
923
+
924
+ def clone
925
+ return CIMParameter.new(@name, @param_type, @reference_class,
926
+ @is_array, @array_size, @qualifiers)
927
+ end
928
+
929
+ def qualifiers=(qualifiers)
930
+ @qualifiers = NocaseHash.new(qualifiers)
931
+ end
932
+
933
+ def to_s
934
+ "#{self.class}(name=#{self.name}, type=#{self.param_type}, is_array=#{self.is_array})"
935
+ end
936
+
937
+ def <=>(other)
938
+ if equal?(other)
939
+ return 0
940
+ elsif (!other.kind_of?(CIMParameter ))
941
+ return 1
942
+ end
943
+ ret_val = cmpname(self.name, other.name)
944
+ ret_val = nilcmp(self.param_type, other.param_type) if (ret_val == 0)
945
+ ret_val = cmpname(self.reference_class, other.reference_class) if (ret_val == 0)
946
+ ret_val = nilcmp(self.is_array, other.is_array) if (ret_val == 0)
947
+ ret_val = nilcmp(self.array_size, other.array_size) if (ret_val == 0)
948
+ ret_val = nilcmp(self.qualifiers, other.qualifiers) if (ret_val == 0)
949
+ ret_val
950
+ end
951
+
952
+ def tocimxml
953
+ if self.param_type == 'reference'
954
+ if self.is_array
955
+ return PARAMETER_REFARRAY.new(self.name,
956
+ self.reference_class,
957
+ array_size.nil? ? nil : self.array_size.to_s,
958
+ self.qualifiers.values.collect {|q| q.tocimxml()})
959
+ else
960
+ return PARAMETER_REFERENCE.new(self.name,
961
+ self.reference_class,
962
+ self.qualifiers.values.collect {|q| q.tocimxml()})
963
+ end
964
+ elsif self.is_array
965
+ return PARAMETER_ARRAY.new(self.name,
966
+ self.param_type,
967
+ array_size.nil? ? nil : self.array_size.to_s,
968
+ self.qualifiers.values.collect { |q| q.tocimxml})
969
+ else
970
+ return PARAMETER.new(self.name,
971
+ self.param_type,
972
+ self.qualifiers.values.collect { |q| q.tocimxml})
973
+ end
974
+ end
975
+ end
976
+
977
+ class CIMQualifier < XMLObject
978
+ include Comparable
979
+ #"""Represents static annotations of a class, method, property, etc.
980
+
981
+ #Includes information such as a documentation string and whether a property
982
+ #is a key."""
983
+
984
+ attr_reader :name, :qual_type, :value, :overridable, :propagated, :toinstance, :tosubclass, :translatable
985
+ attr_writer :name, :qual_type, :value, :overridable, :propagated, :toinstance, :tosubclass, :translatable
986
+ def initialize(name, value, propagated=nil, overridable=nil,
987
+ tosubclass=nil, toinstance=nil, translatable=nil)
988
+ @name = name
989
+ @value = value
990
+ @overridable = overridable
991
+ @propagated = propagated
992
+ @toinstance = toinstance
993
+ @tosubclass = tosubclass
994
+ @translatable = translatable
995
+ @qual_type = WBEM.cimtype(value)
996
+ end
997
+
998
+ def clone
999
+ CIMQualifier.new(@name, @value, @propagated, @overridable,
1000
+ @tosubclass, @toinstance, @translatable)
1001
+ end
1002
+
1003
+ def to_s
1004
+ "#{self.class}(#{self.name}, #{self.value}, ...)"
1005
+ end
1006
+
1007
+ def <=>(other)
1008
+ ret_val = 0
1009
+ if equal?(other)
1010
+ return 0
1011
+ elsif (!other.kind_of?(CIMQualifier))
1012
+ return 1
1013
+ end
1014
+ ret_val = cmpname(self.name, other.name)
1015
+ ret_val = nilcmp(self.value, other.value) if (ret_val == 0)
1016
+ ret_val = nilcmp(self.propagated, other.propagated) if (ret_val == 0)
1017
+ ret_val = nilcmp(self.overridable, other.overridable) if (ret_val == 0)
1018
+ ret_val = nilcmp(self.tosubclass, other.tosubclass) if (ret_val == 0)
1019
+ ret_val = nilcmp(self.toinstance, other.toinstance) if (ret_val == 0)
1020
+ ret_val = nilcmp(self.translatable, other.translatable) if (ret_val == 0)
1021
+ ret_val
1022
+ end
1023
+ def tocimxml
1024
+ QUALIFIER.new(self.name,
1025
+ self.qual_type,
1026
+ WBEM.tocimxml(self.value),
1027
+ self.propagated,
1028
+ self.overridable,
1029
+ self.tosubclass,
1030
+ self.toinstance,
1031
+ self.translatable)
1032
+ end
1033
+ end
1034
+
1035
+ def WBEM.tocimxml(value, wrap_references = false)
1036
+ #"""Convert an arbitrary object to CIM xml. Works with cim_obj
1037
+ #objects and builtin types."""
1038
+
1039
+
1040
+ # CIMType or builtin type
1041
+
1042
+ if ([CIMType, String, Integer, DateTime, TimeDelta, TrueClass, FalseClass].any? do |item|
1043
+ value.is_a?(item)
1044
+ end)
1045
+ return VALUE.new(WBEM.atomic_to_cim_xml(value))
1046
+ elsif (wrap_references and (value.is_a?(CIMInstanceName) or
1047
+ value.is_a?(CIMClassName) or
1048
+ value.is_a?(CIMLocalClassPath)))
1049
+ return VALUE_REFERENCE.new(WBEM.atomic_to_cim_xml(value))
1050
+ elsif (value.methods.include?("tocimxml"))
1051
+ return value.tocimxml()
1052
+ elsif (value.is_a?(Array))
1053
+ if (wrap_references and (value[0].is_a?(CIMInstanceName) or
1054
+ value[0].is_a?(CIMClassName) or
1055
+ value.is_a?(CIMLocalClassPath)))
1056
+ return VALUE_REFARRAY.new(value.collect {|val| WBEM.tocimxml(val, wrap_references)})
1057
+ else
1058
+ return VALUE_ARRAY.new(value.collect {|val| WBEM.tocimxml(val, wrap_references)})
1059
+ end
1060
+ elsif (value.nil?)
1061
+ return value
1062
+ end
1063
+ raise TypeError, "Can't convert #{value} (#{value.class}) to CIM XML"
1064
+ end
1065
+
1066
+ def WBEM.tocimobj(_type, value)
1067
+ #"""Convert a CIM type and a string value into an appropriate
1068
+ #builtin type."""
1069
+
1070
+ # Lists of values
1071
+
1072
+ if value.is_a?(Array)
1073
+ return value.collect { |val| WBEM.tocimobj(_type, val) }
1074
+ end
1075
+
1076
+ case _type
1077
+ # Boolean type
1078
+ when "boolean"
1079
+ return Boolean.new(value)
1080
+ # String type
1081
+ when "string"
1082
+ return value
1083
+ # Integer types
1084
+ when "uint8"
1085
+ return Uint8.new(value)
1086
+ when "sint8"
1087
+ return Sint8.new(value)
1088
+ when "uint16"
1089
+ return Uint16.new(value)
1090
+ when "sint16"
1091
+ return Sint16.new(value)
1092
+ when "uint32"
1093
+ return Uint32.new(value)
1094
+ when "sint32"
1095
+ return Sint32.new(value)
1096
+ when "uint64"
1097
+ return Uint64.new(value)
1098
+ when "sint64"
1099
+ return Sint64.new(value)
1100
+ # Real types
1101
+ when "real32"
1102
+ return Real32.new(value)
1103
+ when "real64"
1104
+ return Real64.new(value)
1105
+ # Char16
1106
+ when "char16"
1107
+ raise TypeError, "CIMType char16 not handled"
1108
+ # Datetime
1109
+ when "datetime"
1110
+ if (value.nil?)
1111
+ return nil
1112
+ end
1113
+ tv_pattern = /^(\d{8})(\d{2})(\d{2})(\d{2})\.(\d{6})(:)(\d{3})/
1114
+ date_pattern = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\.(\d{6})([+|-])(\d{3})/
1115
+ s = tv_pattern.match(value)
1116
+ if (s.nil?)
1117
+ if ((s = date_pattern.match(value)).nil?)
1118
+ raise TypeError, "Invalid Datetime format #{value}"
1119
+ end
1120
+ return DateTime.new(s[1].to_i,s[2].to_i,s[3].to_i,s[4].to_i,s[5].to_i,s[6].to_i+Rational(s[7].to_i,1000000))
1121
+ else
1122
+ # returning a rational num for the #days rather than a python timedelta
1123
+ return TimeDelta.new(s[1].to_i, s[2].to_i, s[3].to_i, s[4].to_i, s[5].to_i)
1124
+ end
1125
+ return value
1126
+ else
1127
+ return nil if _type.nil?
1128
+ raise TypeError, "Invalid CIM type #{_type}"
1129
+ end
1130
+ end
1131
+ def WBEM.byname(nlist)
1132
+ #"""Convert a list of named objects into a map indexed by name"""
1133
+ hash = Hash.new
1134
+ nlist.each { |x| hash[x.name] = x }
1135
+ return hash
1136
+ end
1137
+ class TimeDelta
1138
+ attr_reader :days, :hours, :minutes, :seconds, :microseconds
1139
+ attr_writer :days, :hours, :minutes, :seconds, :microseconds
1140
+ def initialize(days=0, hours=0, minutes=0, seconds=0, microseconds=0)
1141
+ @days = days
1142
+ @hours = hours
1143
+ @minutes = minutes
1144
+ @seconds = seconds
1145
+ @microseconds = microseconds
1146
+ end
1147
+ end
1148
+ end