view lib/IMPL/Config/YAMLConfig.pm @ 421:7798345304bc ref20150831

working on IMPL::Config, removed old stuff
author cin
date Sun, 16 Jul 2017 22:59:39 +0300
parents bbc4739c4d48
children b0481c071bea
line wrap: on
line source

package IMPL::Config::YAMLConfig;
use strict;

use IMPL::lang qw(:base);
use IMPL::Exception();
use YAML::XS();

use IMPL::declare {
    require => {
        ReferenceDescriptor => 'IMPL::Config::ReferenceDescriptor',
        ServiceDescriptor   => 'IMPL::Config::ServiceDescriptor',
        ValueDescriptor     => 'IMPL::Config::ValueDescriptor'
    },
    base => [
        'IMPL::Object' => undef
    ],
    props => [
        container => 'ro'
    ]
};

sub CTOR {
    my ( $this, $container ) = @_;
    die IMPL::InvalidArgumentException('container')
      unless $container;
    $this->container($container);
}

sub LoadConfiguration {
    my ( $this, $file ) = @_;

    $this->Configure(
          isscalar($file)
        ? YAML::XS::Load( ${$file} )
        : YAML::XS::LoadFile($file)
    );
}

sub Configure {
    my ( $this, $config ) = @_;

    die IMPL::InvalidArgumentException('config')
      unless ishash($config);

    my $container = $this->container;
    foreach my $item ( @{ $this->ParseServices( $config->{services} ) } ) {
        $container->Register( $item->{role}, $item->{descriptor} );
    }

    return $container;
}

sub ParseServices {
    my ( $this, $services ) = @_;

    return $services
      ? [
        map {
            {
                role       => delete $_->{name},
                descriptor => $this->ParseDescriptor($_)
            };
        } @$services
      ]
      : undef;
}

sub ParseDescriptor {
    my ( $this, $data ) = @_;

    my %opts = ( onwer => $this->container() );

    if ( my $type = $data->{'$type'} ) {
        $opts{services} = $this->ParseServices( $data->{services} );
        $opts{type}     = $type;
        $opts{args}     = $this->ParseDescriptor( $data->{params} )
          if $data->{params};
        $opts{norequire}  = $data->{norequire};
        $opts{activation} = $data->{activation};

        return ServiceDescriptor->new(%opts);
    }
    elsif ( my $dep = $data->{'$ref'} ) {
        $opts{services} = $this->ParseServices( $data->{services} );
        $opts{lazy}     = $data->{lazy};
        $opts{optional} = $data->{optional};
        $opts{default}  = $this->ParseDescriptor( $data->{default} )
          if exists $data->{default};

        return ReferenceDesriptor->new( $dep, %opts );
    }
    elsif ( my $value = $data->{'$value'} ) {
        my ( $parsed, $raw ) = $this->ParseValue($value);
        $opts{services} = $this->ParseServices( $data->{services} );
        $opts{raw}      = $raw;
        return ValueDescriptor->new( $parsed, %opts );
    }
    else {
        my ( $parsed, $raw ) = $this->ParseValue($value);
        $opts{raw} = $raw;
        return ValueDescriptor->new( $parsed, %opts );
    }
}

sub ParseValue {
    my ( $this, $value ) = @_;

    my $raw = 1;

    if ( ishash($value) ) {
        return ( $this->ParseDescriptor($value), 0 )
          if grep exists $value->{$_}, qw($type $ref $value);

        my %res;
        while ( my ( $k, $v ) = each %$value ) {
            my ( $parsed, $flag ) = $this->ParseValue($v);
            $res{$k} = $parsed;
            $raw &&= $flag;
        }
        return ( \%res, $raw );
    }
    elsif ( isarray($value) ) {
        return (
            [
                map {
                    my ( $parsed, $flag ) = $this->ParseValue($_);
                    $raw &&= $flag;
                    return $parsed;
                } @$value
            ],
            $raw
        );
    }
    else {
        return ($value, 1);
    }
}

1;

__END__

=pod

=head1 NAME

=head1 SYNOPSIS

=

=cut