view lib/IMPL/Config/Hierarchy.pm @ 412:30e8c6a74937 ref20150831

working on di container (role based registrations)
author cin
date Mon, 21 Sep 2015 19:54:10 +0300
parents
children af8d359ee4cc
line wrap: on
line source

package IMPL::Config::Hierarchy;
use strict;

use IMPL::Exception();
use IMPL::lang qw(:base);
use IMPL::clone;
use IMPL::declare {
	base => {
		'IMPL::Object' => undef
	},
	props => {
		roles  => '*rw',
		_cache => '*rw'
	}
};

sub CTOR {
	my ( $this, $roles ) = @_;

	if ( is( $roles, SELF ) ) {
		$this->roles( clone( $roles->roles ) );
	}
	elsif ( ishash($roles) ) {
		$this->roles($roles);
	}
	elsif ( isarray($roles) ) {
		$this->roles( { map { $_, 1 } @$roles } );
	}
	else {
		$this->roles( {} );
	}
}

sub AddRole {
	my ( $this, $role, $parent ) = @_;

	$parent = isarray($parent) ? $parent : [$parent]
	  if $parent;

	die IMPL::InvalidArgumentException->new('role') unless $role;

	$this->roles->{$role} = $parent;
}

sub GetLinearRoleHash {
	my ( $this, $role ) = @_;

	return [] unless $role;

	my $cache = $this->{$_cache}{$role};

	unless ($cache) {
		$cache = {};

		my @roles = ($role);

		while (my $r = shift @roles ) {
			next if $cache->{$r};
			
			$cache->{$r} = 1;
			if(my $parents = $this->{$roles}{$r}) {
				push @roles, @$parents;
			}
		}
		$this->{$_cache}{$role} = $cache;
	}
	
	return $cache;
}

1;