Class: Puppet::Pops::Binder::Injector::Private::InjectorImpl Private
- Defined in:
- lib/puppet/pops/binder/injector.rb
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Defined Under Namespace
Classes: NotFound
Instance Attribute Summary collapse
- #binder ⇒ Object readonly private
-
#entries ⇒ Object
readonly
private
Hash of key => InjectorEntry.
- #key_factory ⇒ Object readonly private
- #type_calculator ⇒ Object readonly private
Instance Method Summary collapse
-
#assistable_injected_class(key) ⇒ Object
private
Produces an injectable class given a key, or nil if key does not represent an injectable class.
-
#data_key(name) ⇒ Object
private
Produces a key for a PDataType/name combination.
- #format_binding(b) ⇒ Object private
-
#get_contributions(scope, contributions_key) ⇒ Object
private
Returns contributions to a multibind in precedence order; highest first.
-
#get_entry(key) ⇒ Object
private
Should be used to get entries as it converts missing entries to NotFound entries or AssistedInject entries.
-
#initialize(configured_binder, parent_injector = nil) ⇒ InjectorImpl
constructor
private
A new instance of InjectorImpl.
- #lookup(scope, *args, &block) ⇒ Object private
- #lookup_key(scope, key) ⇒ Object private
- #lookup_producer(scope, *args, &block) ⇒ Object private
- #lookup_producer_key(scope, key) ⇒ Object private
- #lookup_producer_type(scope, type, name = '') ⇒ Object private
- #lookup_type(scope, type, name = '') ⇒ Object private
- #make_producer(clazz, descriptor, scope, entry, options) ⇒ Object private
- #merge_producer_options(binding, options) ⇒ Object private
- #named_arguments_to_hash(named_args) ⇒ Object private
-
#named_key(type, name) ⇒ Object
private
Produces a key for a type/name combination.
-
#produce(scope, entry) ⇒ Object
private
Returns the produced instance.
-
#producer(scope, entry, use) ⇒ Puppet::Pops::Binder::Producers::Producer
private
Returns the producer for the entry.
- #singleton?(descriptor) ⇒ Boolean private
- #singleton_wrapped(descriptor, scope, entry, producer) ⇒ Object private
- #transform(producer_descriptor, scope, entry) ⇒ Object private
- #transform_ArrayMultibindProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_ConstantProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_EvaluatingProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_FirstFoundProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_HashLookupProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_HashMultibindProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_InstanceProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_LookupProducerDescriptor(descriptor, scope, entry) ⇒ Object private
-
#transform_NilClass(descriptor, scope, entry) ⇒ Object
private
Handles a missing producer (which is valid for a Multibinding where one is selected automatically).
- #transform_NonCachingProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #transform_ProducerProducerDescriptor(descriptor, scope, entry) ⇒ Object private
- #type_error_detail(expected, actual) ⇒ Object private
Constructor Details
#initialize(configured_binder, parent_injector = nil) ⇒ InjectorImpl
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of InjectorImpl.
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/puppet/pops/binder/injector.rb', line 421 def initialize(configured_binder, parent_injector = nil) @binder = configured_binder @parent = parent_injector # TODO: Different error message raise ArgumentError, "Given Binder is not configured" unless configured_binder #&& configured_binder.configured?() @entries = configured_binder.injector_entries() # It is essential that the injector uses the same key factory as the binder since keys must be # represented the same (but still opaque) way. # @key_factory = configured_binder.key_factory() @type_calculator = key_factory.type_calculator() @@transform_visitor ||= Puppet::Pops::Visitor.new(nil,"transform", 2, 2) @recursion_lock = [ ] end |
Instance Attribute Details
#binder ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
419 420 421 |
# File 'lib/puppet/pops/binder/injector.rb', line 419 def binder @binder end |
#entries ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Hash of key => InjectorEntry
413 414 415 |
# File 'lib/puppet/pops/binder/injector.rb', line 413 def entries @entries end |
#key_factory ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
415 416 417 |
# File 'lib/puppet/pops/binder/injector.rb', line 415 def key_factory @key_factory end |
#type_calculator ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
417 418 419 |
# File 'lib/puppet/pops/binder/injector.rb', line 417 def type_calculator @type_calculator end |
Instance Method Details
#assistable_injected_class(key) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Produces an injectable class given a key, or nil if key does not represent an injectable class
563 564 565 566 567 |
# File 'lib/puppet/pops/binder/injector.rb', line 563 def assistable_injected_class(key) kt = key_factory.get_type(key) return nil unless kt.is_a?(Puppet::Pops::Types::PRuntimeType) && kt.runtime == :ruby && !key_factory.is_named?(key) type_calculator.injectable_class(kt) end |
#data_key(name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Produces a key for a PDataType/name combination
479 480 481 |
# File 'lib/puppet/pops/binder/injector.rb', line 479 def data_key(name) key_factory.data_key(name) end |
#format_binding(b) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
663 664 665 |
# File 'lib/puppet/pops/binder/injector.rb', line 663 def format_binding(b) Puppet::Pops::Binder::Binder.format_binding(b) end |
#get_contributions(scope, contributions_key) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns contributions to a multibind in precedence order; highest first. Returns an Array on the form [ [key, entry], [key, entry]] where the key is intended to be used to lookup the value (or a producer) for that entry.
552 553 554 555 556 557 558 |
# File 'lib/puppet/pops/binder/injector.rb', line 552 def get_contributions(scope, contributions_key) result = {} return [] unless contributions = lookup_key(scope, contributions_key) contributions.each { |k| result[k] = get_entry(k) } result.sort {|a, b| a[0] <=> b[0] } #result.sort_by {|key, entry| entry } end |
#get_entry(key) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Should be used to get entries as it converts missing entries to NotFound entries or AssistedInject entries
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 |
# File 'lib/puppet/pops/binder/injector.rb', line 531 def get_entry(key) case entry = entries[ key ] when NilClass # not found, is this an assisted inject? if clazz = assistable_injected_class(key) entry = Producers::AssistedInjectProducer.new(self, clazz) entries[ key ] = entry else entries[ key ] = NotFound.new() entry = nil end when NotFound entry = nil end entry end |
#lookup(scope, *args, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 |
# File 'lib/puppet/pops/binder/injector.rb', line 439 def lookup(scope, *args, &block) raise ArgumentError, "lookup should be called with two or three arguments, got: #{args.size()+1}" unless args.size.between?(1,2) val = case args[ 0 ] when Puppet::Pops::Types::PAnyType lookup_type(scope, *args) when String raise ArgumentError, "lookup of name should only pass the name" unless args.size == 1 lookup_key(scope, key_factory.data_key(args[ 0 ])) else raise ArgumentError, 'lookup using a key should only pass a single key' unless args.size == 1 lookup_key(scope, args[ 0 ]) end # call block with result if given if block case block.arity when 1 block.call(val) when 2 block.call(scope, val) else raise ArgumentError, "The block should have arity 1 or 2" end else val end end |
#lookup_key(scope, key) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 |
# File 'lib/puppet/pops/binder/injector.rb', line 500 def lookup_key(scope, key) if @recursion_lock.include?(key) raise ArgumentError, "Lookup loop detected for key: #{key}" end begin @recursion_lock.push(key) case entry = get_entry(key) when NilClass @parent ? @parent.lookup_key(scope, key) : nil when Puppet::Pops::Binder::InjectorEntry val = produce(scope, entry) return nil if val.nil? unless key_factory.type_calculator.instance?(entry.binding.type, val) raise "Type error: incompatible type returned by producer, #{type_error_detail(entry.binding.type, val)}" end val when Producers::AssistedInjectProducer entry.produce(scope) else # internal, direct entries entry end ensure @recursion_lock.pop() end end |
#lookup_producer(scope, *args, &block) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
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 |
# File 'lib/puppet/pops/binder/injector.rb', line 569 def lookup_producer(scope, *args, &block) raise ArgumentError, "lookup_producer should be called with two or three arguments, got: #{args.size()+1}" unless args.size <= 2 p = case args[ 0 ] when Puppet::Pops::Types::PAnyType lookup_producer_type(scope, *args) when String raise ArgumentError, "lookup_producer of name should only pass the name" unless args.size == 1 lookup_producer_key(scope, key_factory.data_key(args[ 0 ])) else raise ArgumentError, "lookup_producer using a key should only pass a single key" unless args.size == 1 lookup_producer_key(scope, args[ 0 ]) end # call block with result if given if block case block.arity when 1 block.call(p) when 2 block.call(scope, p) else raise ArgumentError, "The block should have arity 1 or 2" end else p end end |
#lookup_producer_key(scope, key) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
601 602 603 604 605 606 607 608 609 610 611 |
# File 'lib/puppet/pops/binder/injector.rb', line 601 def lookup_producer_key(scope, key) if @recursion_lock.include?(key) raise ArgumentError, "Lookup loop detected for key: #{key}" end begin @recursion_lock.push(key) producer(scope, get_entry(key), :multiple_use) ensure @recursion_lock.pop() end end |
#lookup_producer_type(scope, type, name = '') ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
614 615 616 |
# File 'lib/puppet/pops/binder/injector.rb', line 614 def lookup_producer_type(scope, type, name='') lookup_producer_key(scope, named_key(type, name)) end |
#lookup_type(scope, type, name = '') ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
484 485 486 487 488 489 490 491 |
# File 'lib/puppet/pops/binder/injector.rb', line 484 def lookup_type(scope, type, name='') val = lookup_key(scope, named_key(type, name)) return nil if val.nil? unless key_factory.type_calculator.instance?(type, val) raise ArgumentError, "Type error: incompatible type, #{type_error_detail(type, val)}" end val end |
#make_producer(clazz, descriptor, scope, entry, options) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
713 714 715 |
# File 'lib/puppet/pops/binder/injector.rb', line 713 def make_producer(clazz, descriptor, scope, entry, ) singleton_wrapped(descriptor, scope, entry, clazz.new(self, entry.binding, scope, )) end |
#merge_producer_options(binding, options) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
658 659 660 |
# File 'lib/puppet/pops/binder/injector.rb', line 658 def (binding, ) named_arguments_to_hash(binding.producer_args).merge() end |
#named_arguments_to_hash(named_args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
650 651 652 653 654 655 |
# File 'lib/puppet/pops/binder/injector.rb', line 650 def named_arguments_to_hash(named_args) nb = named_args.nil? ? [] : named_args result = {} nb.each {|arg| result[ :"#{arg.name}" ] = arg.value } result end |
#named_key(type, name) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Produces a key for a type/name combination.
473 474 475 |
# File 'lib/puppet/pops/binder/injector.rb', line 473 def named_key(type, name) key_factory.named_key(type, name) end |
#produce(scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the produced instance
644 645 646 647 |
# File 'lib/puppet/pops/binder/injector.rb', line 644 def produce(scope, entry) return nil unless entry # not found producer(scope, entry, :single_use).produce(scope) end |
#producer(scope, entry, use) ⇒ Puppet::Pops::Binder::Producers::Producer
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns the producer for the entry
623 624 625 626 627 628 629 630 631 632 633 |
# File 'lib/puppet/pops/binder/injector.rb', line 623 def producer(scope, entry, use) return nil unless entry # not found return entry.producer(scope) if entry.is_a?(Producers::AssistedInjectProducer) unless entry.cached_producer entry.cached_producer = transform(entry.binding.producer, scope, entry) end unless entry.cached_producer raise ArgumentError, "Injector entry without a producer #{format_binding(entry.binding)}" end entry.cached_producer.producer(scope) end |
#singleton?(descriptor) ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
757 758 759 |
# File 'lib/puppet/pops/binder/injector.rb', line 757 def singleton?(descriptor) ! descriptor.eContainer().is_a?(Puppet::Pops::Binder::Bindings::NonCachingProducerDescriptor) end |
#singleton_wrapped(descriptor, scope, entry, producer) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
718 719 720 721 722 |
# File 'lib/puppet/pops/binder/injector.rb', line 718 def singleton_wrapped(descriptor, scope, entry, producer) return producer unless singleton?(descriptor) Producers::SingletonProducer.new(self, entry.binding, scope, (entry.binding, {:value => producer.produce(scope)})) end |
#transform(producer_descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
636 637 638 |
# File 'lib/puppet/pops/binder/injector.rb', line 636 def transform(producer_descriptor, scope, entry) @@transform_visitor.visit_this_2(self, producer_descriptor, scope, entry) end |
#transform_ArrayMultibindProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
685 686 687 |
# File 'lib/puppet/pops/binder/injector.rb', line 685 def transform_ArrayMultibindProducerDescriptor(descriptor, scope, entry) make_producer(Producers::ArrayMultibindProducer, descriptor, scope, entry, named_arguments_to_hash(entry.binding.producer_args)) end |
#transform_ConstantProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
695 696 697 698 |
# File 'lib/puppet/pops/binder/injector.rb', line 695 def transform_ConstantProducerDescriptor(descriptor, scope, entry) producer_class = singleton?(descriptor) ? Producers::SingletonProducer : Producers::DeepCloningProducer producer_class.new(self, entry.binding, scope, (entry.binding, {:value => descriptor.value})) end |
#transform_EvaluatingProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
707 708 709 710 |
# File 'lib/puppet/pops/binder/injector.rb', line 707 def transform_EvaluatingProducerDescriptor(descriptor, scope, entry) make_producer(Producers::EvaluatingProducer, descriptor, scope, entry, (entry.binding, {:expression => descriptor.expression})) end |
#transform_FirstFoundProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
751 752 753 754 |
# File 'lib/puppet/pops/binder/injector.rb', line 751 def transform_FirstFoundProducerDescriptor(descriptor, scope, entry) make_producer(Producers::FirstFoundProducer, descriptor, scope, entry, (entry.binding, {:producers => descriptor.producers.collect {|p| transform(p, scope, entry) }})) end |
#transform_HashLookupProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
739 740 741 742 |
# File 'lib/puppet/pops/binder/injector.rb', line 739 def transform_HashLookupProducerDescriptor(descriptor, scope, entry) make_producer(Producers::LookupKeyProducer, descriptor, scope, entry, (entry.binding, {:type => descriptor.type, :name => descriptor.name, :key => descriptor.key})) end |
#transform_HashMultibindProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
690 691 692 |
# File 'lib/puppet/pops/binder/injector.rb', line 690 def transform_HashMultibindProducerDescriptor(descriptor, scope, entry) make_producer(Producers::HashMultibindProducer, descriptor, scope, entry, named_arguments_to_hash(entry.binding.producer_args)) end |
#transform_InstanceProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
701 702 703 704 |
# File 'lib/puppet/pops/binder/injector.rb', line 701 def transform_InstanceProducerDescriptor(descriptor, scope, entry) make_producer(Producers::InstantiatingProducer, descriptor, scope, entry, (entry.binding, {:class_name => descriptor.class_name, :init_args => descriptor.arguments})) end |
#transform_LookupProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
733 734 735 736 |
# File 'lib/puppet/pops/binder/injector.rb', line 733 def transform_LookupProducerDescriptor(descriptor, scope, entry) make_producer(Producers::LookupProducer, descriptor, scope, entry, (entry.binding, {:type => descriptor.type, :name => descriptor.name})) end |
#transform_NilClass(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Handles a missing producer (which is valid for a Multibinding where one is selected automatically)
670 671 672 673 674 675 676 677 678 679 680 681 682 |
# File 'lib/puppet/pops/binder/injector.rb', line 670 def transform_NilClass(descriptor, scope, entry) unless entry.binding.is_a?(Puppet::Pops::Binder::Bindings::Multibinding) raise ArgumentError, "Binding without producer detected, #{format_binding(entry.binding)}" end case entry.binding.type when Puppet::Pops::Types::PArrayType transform(Puppet::Pops::Binder::Bindings::ArrayMultibindProducerDescriptor.new(), scope, entry) when Puppet::Pops::Types::PHashType transform(Puppet::Pops::Binder::Bindings::HashMultibindProducerDescriptor.new(), scope, entry) else raise ArgumentError, "Unsupported multibind type, must be an array or hash type, #{format_binding(entry.binding)}" end end |
#transform_NonCachingProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
745 746 747 748 |
# File 'lib/puppet/pops/binder/injector.rb', line 745 def transform_NonCachingProducerDescriptor(descriptor, scope, entry) # simply delegates to the wrapped producer transform(descriptor.producer, scope, entry) end |
#transform_ProducerProducerDescriptor(descriptor, scope, entry) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
725 726 727 728 729 730 |
# File 'lib/puppet/pops/binder/injector.rb', line 725 def transform_ProducerProducerDescriptor(descriptor, scope, entry) p = transform(descriptor.producer, scope, entry) clazz = singleton?(descriptor) ? Producers::SingletonProducerProducer : Producers::ProducerProducer clazz.new(self, entry.binding, scope, (entry.binding, (entry.binding, { :producer_producer => p }))) end |
#type_error_detail(expected, actual) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
494 495 496 497 |
# File 'lib/puppet/pops/binder/injector.rb', line 494 def type_error_detail(expected, actual) actual_t = type_calculator.infer(actual) "expected: #{type_calculator.string(expected)}, got: #{type_calculator.string(actual_t)}" end |