view Lib/IMPL/Config.pm @ 171:59e5fcb59d86

Исправления, изменена концепция веб-форм
author sourcer
date Mon, 06 Jun 2011 03:30:36 +0400
parents b88b7fe60aa3
children b3d91ff7aea9
line wrap: on
line source

package IMPL::Config;
use strict;
use warnings;

use parent qw(IMPL::Object::Accessor IMPL::Object::Serializable IMPL::Object::Autofill);

__PACKAGE__->PassThroughArgs;

use File::Spec();

use IMPL::Class::Member;
use IMPL::Class::PropertyInfo;
use IMPL::Exception;

use IMPL::Serialization;
use IMPL::Serialization::XmlFormatter;

our $ConfigBase ||= '';

sub LoadXMLFile {
    my ($self,$file) = @_;
    
    my $class = ref $self || $self;
    
    my $serializer = new IMPL::Serializer(
        Formatter => new IMPL::Serialization::XmlFormatter(
            IdentOutput => 1,
            SkipWhitespace => 1
        )
    );
    
    open my $hFile,'<',$file or die new IMPL::Exception("Failed to open file",$file,$!);
    
    my $obj;
    eval {
        $obj = $serializer->Deserialize($hFile);
    };
    
    if ($@) {
        my $e=$@;
        die new IMPL::Exception("Can't load the configuration file",$file,$e);
    }
    return $obj;
}

sub SaveXMLFile {
    my ($this,$file) = @_;
    
    my $serializer = new IMPL::Serializer(
        Formatter => new IMPL::Serialization::XmlFormatter(
            IdentOutput => 1,
            SkipWhitespace => 1
        )
    );
    
    open my $hFile,'>',$file or die new IMPL::Exception("Failed to open file",$file,$!);
    
    $serializer->Serialize($hFile, $this);
}

sub xml {
    my $this = shift;
    my $serializer = new IMPL::Serializer(
        Formatter => new IMPL::Serialization::XmlFormatter(
            IdentOutput => 1,
            SkipWhitespace => 1
        )
    );
    my $str = '';
    open my $hFile,'>',\$str or die new IMPL::Exception("Failed to open stream",$!);
    
    $serializer->Serialize($hFile, $this);
    
    undef $hFile;
    
    return $str;
}

sub save {
    my ($this,$ctx) = @_;
    
    my $val;

    $val = $this->rawGet($_) and $ctx->AddVar($_ => $val) foreach map $_->Name, $this->get_meta(
    	'IMPL::Class::PropertyInfo',
    	sub {
    		$_->Access == IMPL::Class::Member::MOD_PUBLIC and
    		$_->canGet;
    	},
    	1);    
}

sub spawn {
	my ($this,$file) = @_;
	return $this->LoadXMLFile( File::Spec->catfile($ConfigBase,$file) );
}

sub get {
	my $this = shift;
	
	if (@_ == 1) {
		my $obj = $this->SUPER::get(@_);
		return UNIVERSAL::isa($obj,'IMPL::Config::Activator') ? $obj->activate : $obj;
	} else {
		my @objs = $this->SUPER::get(@_);	
		return map UNIVERSAL::isa($_,'IMPL::Config::Activator') ? $_->activate : $_, @objs ;	
	}
}

sub rawGet {
	my $this = shift;
	return $this->SUPER::get(@_);
}

sub Exists {
	$_[0]->SUPER::get($_[1]) ? 1 : 0;
}

1;
__END__

=pod

=head1 NAME

C<IMPL::Config> -     .

=head1 SYNOPSIS

=begin code

# define application

package MyApp;
use parent qw(IMPL::Config);

use IMPL::Class::Property;
use IMPL::Config::Class;

BEGIN {
    public property SimpleString => prop_all;
    public property DataSource => prop_all; 
}

sub CTOR {
    my $this = shift;
    
    $this->DataSource(
    	new IMPL::Config::Activator(
    		factory => 'MyDataSource',
    		parameters=>{
    			host => 'localhost',
    			user => 'dbuser'
    		}
    	)
    ) unless $this->Exists('DataSource');
}

# using application object

my $app = spawn MyApp('default.xml');

$app->Run();

=end code

    C<default.xml>   

=begin code xml

<app type='MyApp'>
	<SimpleString>The application</SimpleString>
	<DataSource type='IMPL::Config::Activator'>
		<factory>MyDataSourceClass</factory>
		<parameters type='HASH'>
			<host>localhost</host>
			<user>dbuser</user>
		</parameters>
	</DataSource>
</app>

=end code xml

=head1 DESCRIPTION

C<[Serializable]>

C<[Autofill]>

C<use parent IMPL::Object::Accessor>

   .  ,  
 ,     ,
  - .

     ( ) 
  XML .     C<IMPL::Serialization>.
    C<IMPL::Serialization::XmlFormatter> C<IdentOutput> 
C<SkipWhitespace>       .

       
  ,       
 ,     . ,   
      ,   .

       C<IMPL::Config::Activator>.

    ,    C<IMPL::Config::Activator>, 
     ,     
C<< IMPL::Config::Activator->activate() >>      .
      ,  
 . 

=head1 MEMBERS

=over

=item C<[static] LoadXMLFile($fileName) >

  XML  C<$fileName>  

=item C<SaveXMLFile($fileName)>

    C<$fileName>

=item C<[get] xml >

    XML .

=item C<[static,operator] spawn($file)>

  C<LoadXMLFile>,    .

=item C<rawGet($propname,...)>

     .    
    C<IMPL::Config::Activator>.

=back

=cut