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
562 563 564 565 566 |
# File 'lib/puppet/pops/binder/injector.rb', line 562 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.
662 663 664 |
# File 'lib/puppet/pops/binder/injector.rb', line 662 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 |
# 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] } 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.
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 |
# File 'lib/puppet/pops/binder/injector.rb', line 568 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.
600 601 602 603 604 605 606 607 608 609 610 |
# File 'lib/puppet/pops/binder/injector.rb', line 600 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.
613 614 615 |
# File 'lib/puppet/pops/binder/injector.rb', line 613 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.
712 713 714 |
# File 'lib/puppet/pops/binder/injector.rb', line 712 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.
657 658 659 |
# File 'lib/puppet/pops/binder/injector.rb', line 657 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.
649 650 651 652 653 654 |
# File 'lib/puppet/pops/binder/injector.rb', line 649 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
643 644 645 646 |
# File 'lib/puppet/pops/binder/injector.rb', line 643 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
622 623 624 625 626 627 628 629 630 631 632 |
# File 'lib/puppet/pops/binder/injector.rb', line 622 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.
756 757 758 |
# File 'lib/puppet/pops/binder/injector.rb', line 756 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.
717 718 719 720 721 |
# File 'lib/puppet/pops/binder/injector.rb', line 717 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.
635 636 637 |
# File 'lib/puppet/pops/binder/injector.rb', line 635 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.
684 685 686 |
# File 'lib/puppet/pops/binder/injector.rb', line 684 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.
694 695 696 697 |
# File 'lib/puppet/pops/binder/injector.rb', line 694 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.
706 707 708 709 |
# File 'lib/puppet/pops/binder/injector.rb', line 706 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.
750 751 752 753 |
# File 'lib/puppet/pops/binder/injector.rb', line 750 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.
738 739 740 741 |
# File 'lib/puppet/pops/binder/injector.rb', line 738 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.
689 690 691 |
# File 'lib/puppet/pops/binder/injector.rb', line 689 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.
700 701 702 703 |
# File 'lib/puppet/pops/binder/injector.rb', line 700 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.
732 733 734 735 |
# File 'lib/puppet/pops/binder/injector.rb', line 732 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)
669 670 671 672 673 674 675 676 677 678 679 680 681 |
# File 'lib/puppet/pops/binder/injector.rb', line 669 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.
744 745 746 747 |
# File 'lib/puppet/pops/binder/injector.rb', line 744 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.
724 725 726 727 728 729 |
# File 'lib/puppet/pops/binder/injector.rb', line 724 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 |