Raw content of Bio::EnsEMBL::Analysis::Tools::ConfigUtils package Bio::EnsEMBL::Analysis::Tools::ConfigUtils; use strict; use FindBin ; use lib "$FindBin::Bin" ; use Data::Dumper; use Bio::EnsEMBL::Utils::Exception qw(verbose throw warning); use Bio::EnsEMBL::Utils::Argument qw( rearrange ); #use Module::Load; use Data::Dumper ; use Bio::EnsEMBL::Analysis::Tools::Stashes qw( package_stash ) ; use PPI; use vars qw(@ISA) ; @ISA = qw(); sub new { my ($class,@args) = @_; my $self = bless {},$class; my ($config_module) = rearrange (['CONFIG'], @args); $self->config_module($config_module) if $config_module ; $self->{_doc}= PPI::Document->new($self->file) ; #print $self->config_module() . "\n" ; #$self->file() ; #print join("\n" , @{$self->get_Block}); #for my $element ( @{$self->get_X}) { # print ref($element) . "\t$element\n" ; #} # #my $a = $self->get_subroutine("import") ; # print join("\n" , @{$self->get_package_statement}); # print join("\n" , @{$self->get_Pod}); # print join("\n" , @{$self->get_Variables}); # print join("\n" , @{$self->get_Comments}); # for my $symbol ( @{$self->get_all_symbols}){ # print $symbol ."\t:". $symbol->raw_type . "\t".$symbol->symbol_type ."\n" ; # } # Create a tokenizer for a file, array or string #my $Tokenizer = PPI::Tokenizer->new( $self->file ); #my $tokens = $Tokenizer->all_tokens; #while ( my $Token = $Tokenizer->get_token ) { # print ref($Token) . "\t:$Token\n" ; #} # my $c = $self->get_config_hash; # # # this is the braced config object %Config = ( ........ ) # my @lists= @{$c->find("PPI::Structure::List")} ; # throw("there should be only one braced obj in conf...\n") if scalar(@lists) >1; # # my $list = $lists[0]; # my @l; # for my $s (@{$list->find("PPI::Statement::Expression")}) { # #for my $s (@{$list->find("PPI::Structure::Block")}) { # # my @elements = $s->tokens; # for ( @elements ) { # print ref($_) . "\t" . $_ . "\n" ; # } # } # return $self; } =head2 write_config Example : $self->write_config() Description: writes new config file to disk package statement, pod and import-method are read out of old config file and transferred to new config file the comments in the Config hash section will be lost =cut sub write_config { my ($self) = @_ ; print "backing up old config file if it exists...\n"; $self->backup_existing_config() if ( -e $self->file ) ; my @content; push @content, "\n\n", @{$self->get_Pod},"\n\n", @{$self->get_package_statement}; push @content, "\n\n" , $self->print; push @content, "\n\n",$self->get_subroutine("import"),"\n\n1;"; my $f = $self->file ; open (I,">$f") || die "Can't acess file ".$self->file()."\n"; print I join("\n" ,@content) ; close(I); } =head2 backup_existing_config Example : $self->backup_existing_config() Description: tests if the original config file exists, if the file exists it copies it to a new file and extends the filename by ".bak.X" Returntype : true/false =cut sub backup_existing_config { my ($self) = @_ ; my $backuped_file = $self->file; my $count = 0 ; while ( -e $backuped_file ) { #print "file exists : $backuped_file \n" ; $backuped_file = $self->file.".bak.$count" ; $count++; } my $old_file = $self->file; #my $cmd = "cp " . $self->file ." $backuped_file"; #`$cmd`; open(OLD,"$old_file") || throw(" could not read old config $old_file\n"); my @conf= <OLD> ; close(OLD) ; my $backup_time = `date +%a","%d" "%B" "%T`; unshift (@conf, "\#\n\# this file was backuped on $backup_time\#\n\n"); open(NEW,">$backuped_file") || throw "Could not write to file $backuped_file\n" ; print NEW join("", @conf ) ; close(NEW) ; print "file $old_file backuped + modified to :\n$backuped_file\n" ; } sub get_config_hash { my ($self) = @_ ; my $rs ; my $v = $self->varname ; for my $s ( @{$self->get_all_statements} ) { if ($s->first_token=~m/$v/ && $s->first_token->isa("PPI::Token::Symbol")) { # config_hash found : %Config %Databases ... throw("statement appears twice in config - error!\n") if $rs ; $rs=$s; } } return $rs ; } sub get_all_statements{ my ($self) = @_ ; my @rs; for my $s (@{$self->{_doc}->find("PPI::Statement")}) { push @rs,$s unless ref($s)=~m/PPI::Statement::/; } return \@rs ; } sub get_X{ my ($self) = @_ ; #return $self->{_doc}->find("PPI::Structure::Constructor"); return $self->{_doc}->find("PPI::Node"); #return $self->{_doc}->find("PPI::Element"); #return $self->{_doc}->find("PPI::Structure::List"); } sub get_Block{ my ($self) = @_ ; return $self->{_doc}->find("PPI::Structure::List"); } sub get_all_symbols { my ($self) = @_ ; return $self->{_doc}->find("PPI::Token::Symbol"); } sub get_Comments{ my ($self) = @_ ; return $self->{_doc}->find("PPI::Token::Comment"); } sub get_Variables { my ($self) = @_ ; return $self->{_doc}->find("PPI::Statement::Variable"); } sub get_Pod { my ($self) = @_ ; return $self->{_doc}->find("PPI::Token::Pod"); } sub get_package_statement { my ($self) = @_ ; return $self->{_doc}->find("PPI::Statement::Package"); } sub get_include_statements { my ($self) = @_ ; return $self->{_doc}->find("PPI::Statement::Include"); } # hands back subroutine with $name out of config file sub get_subroutine { my ($self,$name) = @_ ; my @subs = @{$self->{_doc}->find("PPI::Statement::Sub")}; for my $s ( @subs ) { return $s if ($s->name eq $name); } return undef; } =head2 append_href Arg [1] : Hashref Arg [2] : opt. String Example : Description: appends a new config value (href, aref) to the configuration hash if Arg[2] is given the new key will be placed in this level / section Returntype : Exceptions : none =cut sub append_href{ my ($self, $href_to_append, $section, $logic_name) = @_ ; warning("$logic_name already exists in config file") if ($self->exists_in_config($logic_name)); # now walk trough hash and replace at the !!correct!! level # but how to we get the correct level ? ? ? my %new_config = %{ $self->configuration } ; $new_config{$section}{$logic_name} = $href_to_append ; $self->configuration(\%new_config) ; } sub get_config_by_name { my ($self, $name, $config_href) = @_ ; # this method can either be called on an object itself # $self->get_config_by_name as well as # in a non oo style for recuriveness # get_config_by_name( $obj, $name ) my %tmp ; unless ( $config_href ) { %tmp = %{$self->configuration} ; } else { %tmp = %$config_href ; } my $result ; KEY: foreach my $key ( keys %tmp ) { next KEY unless $tmp{$key}; if ( $key eq $name ) { $self->result($tmp{$key}) ; $result = $tmp{$key} ; return $result; } if (ref($tmp{$key}) =~m/HASH/ ){ $self->get_config_by_name($name, $tmp{$key}); } } return $result ; } sub result { my ($self, $r) = @_ ; $self->{_result} = $r if $r ; return $self->{_result}; } sub get_all_keys { my ($self) = @_ ; my @keys ; my %tmp = %{$self->configuration}; my @ak = @{print_keys (\%tmp)} ; my %hc ; @hc{@ak} =1 ; return [keys %hc] ; } # returns list of all keys which hold an anonymous hash in config sub print_keys { my ($t) = @_ ; my %tmp= %{$t}; my @ak ; KEY: foreach my $key ( %tmp ) { next KEY unless $key ; if (ref($tmp{$key}) =~m/HASH/ ){ push @ak, @{print_keys($tmp{$key})}; } push @ak , $key if (ref($tmp{$key}) =~m/HASH/) ; } return \@ak; } sub get_config_section { my ($self,$section) = @_ ; my %tmp = %{$self->configuration} ; foreach my $k ( keys %tmp ) { print " get_config_section : $k\tval $tmp{$k}\n" ; if ($k eq $section){ print "found $k\n" ; return $tmp{$k} ; } } } sub exists_in_config{ my ($self, $name) = @_; $self->check(); my @to_check = @{$self->get_all_keys() } ; my %hc ; @hc{@to_check} = 1 ; return 1 if ( exists $hc{$name} ) ; return 0 ; } sub check { my ($self) = @_ ; throw ( " you need to hand over a Bio::EnsEMBL::Analysis::Tools::ConfigUtils object") unless ( $self->isa("Bio::EnsEMBL::Analysis::Tools::ConfigUtils")) ; } =head2 config_module Arg [1] : String describing Class name of config Example : $config->config_module("Bio::EnsEMBL::Analysis::Config::Exonerate2Genes"); Description: getter/setter for config name Returntype : string Exceptions : none =cut sub config_module{ my ($self, $c) =@_ ; if ( $c ) { $self->{_config} = $c; # setenv PERL5LIB /nfs/acari/jhv/lib:${PERL5LIB} # load $c; # # we could use self->file here my $d = $c ; $c.=".pm" ; $c=~ s{::}{/}g; require $c; my ($config_href, $varname ) = @{package_stash("$d")}; $self->configuration($config_href) ; $self->varname($varname) ; } return $self->{_config} ; } sub print { my ($self) = @_ ; my $var_name = $self->varname; my $d = Data::Dumper->new([$self->configuration],[( "*var_name" )]); # $d->Purity(1); # $d->Terse(1); $d->Indent(1); $d->Deepcopy(1); my $rep = $d->Dump() ; $rep=~s/\%var_name/\%$var_name/; return $rep ; } =head2 varname Arg [1] : String Example : $config->varname($string) Description: getter/setter for hash-name of the variable used in the config file Returntype : String Exceptions : none =cut sub varname{ my ($self, $c) =@_ ; $self->{_varname} = $c if $c ; return $self->{_varname} ; } =head2 configuration Arg [1] : Hashref Example : $config->configuration(\%config) Description: getter/setter for the configuration hash exported by config module Returntype : Hashref Exceptions : none =cut sub configuration { my ($self, $c) =@_ ; $self->{_configuration} = $c if $c ; return $self->{_configuration} ; } =head2 file Arg [1] : none Example : $config->file; print $rf->name(); Description: Returns absolute path to config file Returntype : string Exceptions : none =cut sub file { my ( $self ) = @_ ; (my $path = $self->config_module) =~s/\:\:/\//g; $path.=".pm"; return $INC{$path} ; } 1;