Class: Genprovider::Provider
- Inherits:
-
Object
- Object
- Genprovider::Provider
- Defined in:
- lib/genprovider/provider.rb
Constant Summary collapse
- LOG =
“@log.info”
"@trace_file.puts"
Instance Method Summary collapse
-
#bounds(property, *args) ⇒ Object
Find bounds for property values.
-
#default_for_type(type) ⇒ Object
Return reasonable default for type.
- #explain_args(args, text) ⇒ Object
-
#features(predicate, filter) ⇒ Object
iterate features internal predicate: feature predicate symbol, like :property? filter: :keys # keys only :nokeys # non-keys only :all # all.
-
#initialize(c, name, out) ⇒ Provider
constructor
generate provider code for class ‘c’.
-
#make_valuemap(property) ⇒ Object
make_valuemap make one ValueMap class.
- #make_valuemap_header ⇒ Object
-
#methods(&block) ⇒ Object
iterate methods.
- #mkargs(args, name) ⇒ Object
- #mkassociations ⇒ Object
-
#mkbaseinstance ⇒ Object
base instance callbacks use by association and instance providers.
-
#mkcleanup ⇒ Object
Generate cleanup.
-
#mkcreate ⇒ Object
Generate create_instance.
-
#mkdelete_instance ⇒ Object
Generate delete_instance.
-
#mkeach ⇒ Object
Class#each.
-
#mkenum_instance_names ⇒ Object
Generate enum_instance_names.
-
#mkenum_instances ⇒ Object
Generate enum_instances.
-
#mkget_instance ⇒ Object
Generate get_instance.
- #mkindications ⇒ Object
- #mkinstance ⇒ Object
- #mkmethods ⇒ Object
-
#mknew ⇒ Object
Generate Class#initialize.
-
#mkquery ⇒ Object
Generate exec_query.
-
#mkset_instance ⇒ Object
Generate set_instance.
- #mktypemap ⇒ Object
-
#mkvaluemaps ⇒ Object
Generate valuemap classes.
-
#properties(filter, &block) ⇒ Object
iterate properties filter: :keys # keys only :nokeys # non-keys only :all # all.
-
#property_setter_line(property, klass, result_name = "result") ⇒ Object
generate line to set a property i.e.
- #providertypes ⇒ Object
Constructor Details
#initialize(c, name, out) ⇒ Provider
generate provider code for class ‘c’
returns providername
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 |
# File 'lib/genprovider/provider.rb', line 668 def initialize c, name, out @klass = c @out = out if name[0,1] == name[0,1].downcase raise "Provider name (#{name}) must start with upper case" end @name = name # # Header: class name, provider name (Class qualifier 'provider') # @out.comment @out.comment "Provider #{name} for class #{@klass.name}:#{@klass.class}" @out.comment @out.puts("require 'syslog'").puts @out.puts("require 'cmpi/provider'").puts @out.puts("module Cmpi").inc Genprovider::Class.mkdescription @out, @klass if @klass.parent Genprovider::Class.mkdescription @out, @klass.parent end p,mask = providertypes @out.puts("class #{name} < #{p.shift}").inc @out.puts p.each do |t| @out.puts "include #{t}IF" end mknew @out.puts mkcleanup @out.puts mktypemap @out.puts if (mask & METHOD_MASK) != 0 STDERR.puts " Generating Method provider" mkmethods @out.puts end if (mask & ASSOCIATION_MASK) != 0 STDERR.puts " Generating Association provider" mkbaseinstance mkassociations end if (mask & INDICATION_MASK) != 0 STDERR.puts " Generating Indication provider" mkindications @out.puts end if (mask & INSTANCE_MASK) != 0 STDERR.puts " Generating Instance provider" mkinstance @out.puts end mkvaluemaps @out.end # class @out.end # module end |
Instance Method Details
#bounds(property, *args) ⇒ Object
Find bounds for property values
Usage:
bounds property, :MaxLen, :Max, :Min
140 141 142 143 144 145 146 147 |
# File 'lib/genprovider/provider.rb', line 140 def bounds property, *args s = "" args.each do |n| v = property.send(n) s << "#{n} #{v} " if v end s end |
#default_for_type(type) ⇒ Object
Return reasonable default for type
152 153 154 155 156 157 |
# File 'lib/genprovider/provider.rb', line 152 def default_for_type type if type.array? then "[]" elsif type == :boolean then "false" else "nil" end end |
#explain_args(args, text) ⇒ Object
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
# File 'lib/genprovider/provider.rb', line 490 def explain_args args, text @out.comment "#{text} args" if args.empty? @out.comment " - none -" end args.each do |arg| @out.comment "#{arg.name} : #{arg.type}", 1 d = arg.description @out.comment("#{d}", 3) if d valuemap = arg.valuemap # values might be nil, then only ValueMap given if valuemap @out.comment "Value can be one of", 3 valuemap = valuemap values = arg.values if values values = values loop do s = values.shift v = valuemap.shift break unless v && s @out.comment "#{s}: #{v}", 5 end else valuemap.each do |v| @out.comment v, 5 end end end end @out.comment end |
#features(predicate, filter) ⇒ Object
iterate features internal
predicate: feature predicate symbol, like :property?
filter: :keys # keys only
:nokeys # non-keys only
:all # all
yields { |feature, klass| } if block_given? returns Array of [feature,klass] pairs else
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/genprovider/provider.rb', line 65 def features predicate, filter result = nil # # We start to iterate features from the child class and # climb up the parent chain # overrides = { name => features } # collects information about overridden features along # the parent chain overrides = {} # climb up parent chain klass = @klass while klass klass.features.each do |feature| next unless feature.send(predicate) # overriden in child class ? f_override = overrides[feature.name] if f_override # Y: f_override = overriding feature # copy qualifiers from overridden to overriding feature feature.qualifiers.each do |q| unless f_override.qualifiers[q.name] # non-overridden qualifier f_override.qualifiers << q end end next # skip this feature end # does this feature override a parent feature ? overrides[feature.name] = feature if feature.override if feature.key? next if filter == :nokeys else next if filter == :keys end if block_given? yield feature, klass else result ||= Array.new result << [feature,klass] end end klass = klass.parent end result end |
#make_valuemap(property) ⇒ Object
make_valuemap make one ValueMap class
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
# File 'lib/genprovider/provider.rb', line 398 def make_valuemap property t = property.type # get the Values and ValueMap qualifiers valuemap = property.ValueMap return unless valuemap make_valuemap_header values = property.Values @out.puts @out.puts("class #{property.name} < Cmpi::ValueMap").inc @out.def "self.map" @out.puts("{").inc # get to the array valuemap = valuemap # values might be nil, then only ValueMap given if values values = values elsif !t.matches?(String) raise "ValueMap missing Values for property #{property.name} with non-string type #{t}" end loop do val = values.shift if values map = valuemap.shift if val.nil? && values # have values but its empty break unless map # ok, both nil raise "#{property.name}: Values empty, ValueMap #{map}" end unless map break unless val # ok, both nil raise "#{property.name}: Values #{val}, ValueMap empty" end if val if map =~ /\.\./ @out.comment "#{val.inspect} => #{map}," else @out.puts "#{val.inspect} => #{map}," end else @out.puts "#{map.inspect} => #{map.to_sym.inspect}," end end @out.dec.puts "}" @out.end @out.end end |
#make_valuemap_header ⇒ Object
387 388 389 390 391 392 393 |
# File 'lib/genprovider/provider.rb', line 387 def make_valuemap_header return if @valuemap_headers_done @out.comment @out.comment "----------------- valuemaps following, don't touch -----------------" @out.comment @valuemap_headers_done = true end |
#methods(&block) ⇒ Object
iterate methods
accepts optional block
128 129 130 |
# File 'lib/genprovider/provider.rb', line 128 def methods &block features :method?, :all, &block end |
#mkargs(args, name) ⇒ Object
480 481 482 483 484 485 486 487 488 |
# File 'lib/genprovider/provider.rb', line 480 def mkargs args, name s = "" args.each do |arg| s << ", " unless s.empty? s << arg.name.inspect s << ", #{arg.type.to_cmpi}" end s end |
#mkassociations ⇒ Object
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 |
# File 'lib/genprovider/provider.rb', line 617 def mkassociations @out.comment "Associations" @out.def "associator_names", "context", "result", "reference", "assoc_class", "result_class", "role", "result_role" @out.puts "#{LOG} \"#{@name}.associator_names \#{context}, \#{result}, \#{reference}, \#{assoc_class}, \#{result_class}, \#{role}, \#{result_role}\"" @out.end @out.puts @out.def "associators", "context", "result", "reference", "assoc_class", "result_class", "role", "result_role", "properties" @out.puts "#{LOG} \"#{@name}.associators \#{context}, \#{result}, \#{reference}, \#{assoc_class}, \#{result_class}, \#{role}, \#{result_role}, \#{properties}\"" @out.end @out.puts @out.def "reference_names", "context", "result", "reference", "result_class", "role" @out.puts "#{LOG} \"#{@name}.reference_names \#{context}, \#{result}, \#{reference}, \#{result_class}, \#{role}\"" @out.puts("each(context, reference) do |ref|").inc @out.puts "result.return_objectpath ref" @out.end @out.puts "result.done" @out.puts "true" @out.end @out.puts @out.def "references", "context", "result", "reference", "result_class", "role", "properties" @out.puts "#{LOG} \"#{@name}.references \#{context}, \#{result}, \#{reference}, \#{result_class}, \#{role}, \#{properties}\"" @out.puts("each(context, reference, properties, true) do |instance|").inc @out.puts "result.return_instance instance" @out.end @out.puts "result.done" @out.puts "true" @out.end end |
#mkbaseinstance ⇒ Object
base instance callbacks use by association and instance providers
458 459 460 461 462 463 464 465 466 467 |
# File 'lib/genprovider/provider.rb', line 458 def mkbaseinstance mkeach @out.puts mkenum_instance_names @out.puts mkenum_instances @out.puts mkget_instance @out.puts end |
#mkcleanup ⇒ Object
Generate cleanup
352 353 354 355 356 357 |
# File 'lib/genprovider/provider.rb', line 352 def mkcleanup @out.def "cleanup", "context", "terminating" @out.puts "#{LOG} \"#{@name}.cleanup terminating? \#{terminating}\"" @out.puts "true" @out.end end |
#mkcreate ⇒ Object
Generate create_instance
240 241 242 243 244 245 246 247 248 |
# File 'lib/genprovider/provider.rb', line 240 def mkcreate @out.def "create_instance", "context", "result", "reference", "newinst" @out.puts "#{LOG} \"#{@name}.create_instance ref \#{reference}, newinst \#{newinst.inspect}\"" @out.comment "Create instance according to reference and newinst" @out.puts "result.return_objectpath reference" @out.puts "result.done" @out.puts "true" @out.end end |
#mkdelete_instance ⇒ Object
Generate delete_instance
314 315 316 317 318 319 320 |
# File 'lib/genprovider/provider.rb', line 314 def mkdelete_instance @out.def "delete_instance", "context", "result", "reference" @out.puts "#{LOG} \"#{@name}.delete_instance ref \#{reference}\"" @out.puts "result.done" @out.puts "true" @out.end end |
#mkeach ⇒ Object
Class#each
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/genprovider/provider.rb', line 183 def mkeach @out.puts "private" @out.comment @out.comment "Iterator for names and instances" @out.comment " yields references matching reference and properties" @out.comment @out.def "each", "context", "reference", "properties = nil", "want_instance = false" @out.puts "result = Cmpi::CMPIObjectPath.new reference.namespace, #{@klass.name.inspect}" @out.puts("if want_instance").inc @out.puts "result = Cmpi::CMPIInstance.new result" @out.puts "result.set_property_filter(properties) if properties" @out.end @out.puts @out.comment "Set key properties" @out.puts properties :keys do |prop, klass| @out.puts(property_setter_line prop, klass) end @out.puts("unless want_instance").inc @out.puts "yield result" @out.puts "return" @out.end @out.puts @out.comment "Instance: Set non-key properties" @out.puts properties :nokeys do |prop, klass| deprecated = prop.deprecated required = prop.required if required @out.comment "Required !" @out.puts "#{property_setter_line prop, klass}" else @out.comment "Deprecated !" if deprecated # using @out.comment would break the line at col 72 @out.puts "# #{property_setter_line prop, klass}" end end @out.puts "yield result" @out.end @out.puts "public" end |
#mkenum_instance_names ⇒ Object
Generate enum_instance_names
253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/genprovider/provider.rb', line 253 def mkenum_instance_names @out.def "enum_instance_names", "context", "result", "reference" @out.puts "#{LOG} \"#{@name}.enum_instance_names ref \#{reference}\"" @out.puts("each(context, reference) do |ref|").inc @out.puts "#{LOG} \"ref \#{ref}\"" @out.puts "result.return_objectpath ref" @out.end @out.puts "result.done" @out.puts "true" @out.end end |
#mkenum_instances ⇒ Object
Generate enum_instances
268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/genprovider/provider.rb', line 268 def mkenum_instances @out.def "enum_instances", "context", "result", "reference", "properties" @out.puts "#{LOG} \"#{@name}.enum_instances ref \#{reference}, props \#{properties.inspect}\"" @out.puts("each(context, reference, properties, true) do |instance|").inc @out.puts "#{LOG} \"instance \#{instance}\"" @out.puts "result.return_instance instance" @out.end @out.puts "result.done" @out.puts "true" @out.end end |
#mkget_instance ⇒ Object
Generate get_instance
283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/genprovider/provider.rb', line 283 def mkget_instance @out.def "get_instance", "context", "result", "reference", "properties" @out.puts "#{LOG} \"#{@name}.get_instance ref \#{reference}, props \#{properties.inspect}\"" @out.puts("each(context, reference, properties, true) do |instance|").inc @out.puts "#{LOG} \"instance \#{instance}\"" @out.puts "result.return_instance instance" @out.puts "break # only return first instance" @out.end @out.puts "result.done" @out.puts "true" @out.end end |
#mkindications ⇒ Object
647 648 649 |
# File 'lib/genprovider/provider.rb', line 647 def mkindications @out.comment "Indications" end |
#mkinstance ⇒ Object
469 470 471 472 473 474 475 476 477 478 |
# File 'lib/genprovider/provider.rb', line 469 def mkinstance mkbaseinstance mkcreate @out.puts mkset_instance @out.puts mkdelete_instance @out.puts mkquery end |
#mkmethods ⇒ Object
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 |
# File 'lib/genprovider/provider.rb', line 523 def mkmethods @out.comment "Methods" @out.puts methods do |method, klass| next if method.deprecated @out.comment "#{klass.name}: #{method.type} #{method.name}(...)" @out.comment input = [] output = [] method.parameters.each do |p| input << p if p.in? output << p if p.out? STDERR.puts "#{p.name} is IN and OUT" if p.in? && p.out? STDERR.puts "#{p.name} is neither IN nor OUT" unless p.in? || p.out? end name = method.name decam = name.decamelize # type and argument information # must be array since order here is order of args passed to function # first element is list of input args (alternating name and type) # second is list of output args (starting with return type, then name and type of additional out args) # -> used by cmpi_bindings ! @out.comment "type information for #{name}(...)" @out.comment "Array of 2 arrys. First array is input arguments as [<in_name1>, <in_type1>, ...]" @out.comment " Second array is [<return type>, <out_name1>, <out_type1>, <out_name2>, <out_type2>, ...]" @out.puts "def #{decam}_args; [[#{mkargs(input, decam)}],[#{method.type.to_cmpi}, #{mkargs(output, decam)}]] end" @out.comment d = method.description.value rescue nil if d @out.comment "#{d}" @out.comment end v = method.values default_return_value = default_for_type method.type if v @out.comment "See class #{method.name} for return values" @out.comment firstval = v[0] if firstval.to_s =~ /\s/ firstval = "send(#{firstval.to_sym.inspect})" end default_return_value = "#{name}.#{firstval}" end explain_args input, "Input" explain_args output, "Additional output" args = ["#{decam}", "context", "reference"] input.each do |arg| args << arg.name.decamelize end @out.def *args args.shift log = "" args.each do |arg| log << ", " unless log.empty? log << "\#{#{arg}}" end @out.puts "#{LOG} \"#{decam} #{log}\"" # Empty arrays are not transferred by sfcc/cimxml, end up as nil input.each do |arg| next unless arg.type.array? @out.puts "#{arg.name.decamelize} ||= []" end args = [ "method_return_value" ] @out.puts "method_return_value = #{default_return_value} # #{method.type}" if output.size > 0 @out.puts @out.comment "Output arguments" output.each do |arg| name = arg.name.decamelize @out.puts "#{name} = nil # #{arg.type}" args << name end end @out.puts @out.comment " function body goes here" @out.puts if args.size > 1 @out.puts "return [#{args.join(', ')}]" else @out.puts "return #{args[0]}" end @out.end @out.puts end # @out.puts # @out.def "invoke_method", "context", "result", "reference", "method", "argsin", "argsout" # @out.comment "method names and parameter names are case-insensitive !" # @out.puts "#{LOG} \"invoke_method \#{context}, \#{result}, \#{reference}, \#{method}, \#{argsin}, \#{argsout}\"" # @out.end end |
#mknew ⇒ Object
Generate Class#initialize
227 228 229 230 231 232 233 234 235 |
# File 'lib/genprovider/provider.rb', line 227 def mknew @out.comment @out.comment "Provider initialization" @out.comment @out.def "initialize", "name", "broker", "context" @out.puts "@trace_file = STDERR" @out.puts "super broker" @out.end end |
#mkquery ⇒ Object
Generate exec_query
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/genprovider/provider.rb', line 325 def mkquery @out.comment "query : String" @out.comment "lang : String" @out.def "exec_query", "context", "result", "reference", "query", "lang" @out.puts "#{LOG} \"#{@name}.exec_query ref \#{reference}, query \#{query}, lang \#{lang}\"" @out.printf "keys = [" first = true properties :keys do |property, klass| @out.write ", " unless first first = false @out.write "\"#{property.name}\"" end @out.puts "]" @out.puts "expr = CMPISelectExp.new query, lang, keys" @out.puts("each(context, reference, expr.filter, true) do |instance|").inc @out.puts( "if expr.match(instance)").inc @out.puts "result.return_instance instance" @out.end @out.end @out.puts "result.done" @out.puts "true" @out.end end |
#mkset_instance ⇒ Object
Generate set_instance
299 300 301 302 303 304 305 306 307 308 309 |
# File 'lib/genprovider/provider.rb', line 299 def mkset_instance @out.def "set_instance", "context", "result", "reference", "newinst", "properties" @out.puts "#{LOG} \"#{@name}.set_instance ref \#{reference}, newinst \#{newinst.inspect}, props \#{properties.inspect}\"" @out.puts("properties.each do |prop|").inc @out.puts "newinst.send \"\#{prop.name}=\".to_sym, FIXME" @out.end @out.puts "result.return_instance newinst" @out.puts "result.done" @out.puts "true" @out.end end |
#mktypemap ⇒ Object
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
# File 'lib/genprovider/provider.rb', line 359 def mktypemap @out.def("self.typemap") @out.puts("{").inc properties :all do |property, klass| t = property.type s = t.to_cmpi if t == CIM::ReferenceType # use t.name to stay Ruby-compatible. t.to_s would print MOF syntax @out.comment t.to_s elsif t == :string # check for Embedded{Instance,Object} if property. s = "Cmpi::embedded_instance" elsif property. s = "Cmpi::embedded_object" end elsif t == :stringA # check for Embedded{Instance,Object} if property. s = "Cmpi::embedded_instanceA" elsif property. s = "Cmpi::embedded_objectA" end end @out.puts "#{property.name.inspect} => #{s}," end @out.dec.puts "}" @out.end end |
#mkvaluemaps ⇒ Object
Generate valuemap classes
447 448 449 450 451 452 453 454 |
# File 'lib/genprovider/provider.rb', line 447 def mkvaluemaps properties :all do |property, klass| make_valuemap property end methods do |method, klass| make_valuemap method end end |
#properties(filter, &block) ⇒ Object
iterate properties
filter: :keys # keys only
:nokeys # non-keys only
:all # all
accepts optional block
120 121 122 |
# File 'lib/genprovider/provider.rb', line 120 def properties filter, &block features :property?, filter, &block end |
#property_setter_line(property, klass, result_name = "result") ⇒ Object
generate line to set a property i.e. result.Property = nil # property_type + valuemap
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/genprovider/provider.rb', line 163 def property_setter_line property, klass, result_name = "result" valuemap = property.ValueMap values = property.Values type = property.type if valuemap firstval = values ? values[0] : valuemap[0] if firstval.to_s =~ /\s/ firstval = "send(#{firstval.to_sym.inspect})" end default = "#{property.name}.#{firstval}" default = "[#{default}]" if type.array? else default = default_for_type type end bounds = bounds property, :MaxLen, :Max, :Min "#{result_name}.#{property.name} = #{default} # #{type} #{bounds} (-> #{klass.name})" end |
#providertypes ⇒ Object
651 652 653 654 655 656 657 658 659 660 |
# File 'lib/genprovider/provider.rb', line 651 def providertypes mask = Genprovider.classmask @klass res = [] res << "MethodProvider" if (mask & METHOD_MASK) != 0 res << "AssociationProvider" if (mask & ASSOCIATION_MASK) != 0 res << "IndicationProvider" if (mask & INDICATION_MASK) != 0 res << "InstanceProvider" if (mask & INSTANCE_MASK) != 0 [res, mask] end |