Bio-BioVeL

 view release on metacpan or  search on metacpan

lib/Bio/BioVeL/Service.pm  view on Meta::CPAN

package Bio::BioVeL::Service;
use strict;
use warnings;
use Getopt::Long;
use CGI;
use YAML qw(Dump Load DumpFile LoadFile);
use Apache2::Request;
use Apache2::RequestRec ();
use Apache2::RequestIO ();
use Apache2::Const -compile => qw(OK);
use LWP::UserAgent;
use Bio::Phylo::Util::Logger ':levels';

# this increments the verbosity in the concrete service classes
# we've implemented so far. in production systems this should
# probably be set to WARN instead to prevent flooding apache's
# /var/log/apache2/error_log (or wherever it is located).
my $log = Bio::Phylo::Util::Logger->new(
	'-level' => INFO,
	'-class' => [ 
		'Bio::BioVeL::Service::NeXMLMerger', 
		'Bio::BioVeL::Service::NeXMLExtractor' 
	]
);
our $AUTOLOAD;

=head1 NAME

Bio::BioVeL::Service - base class for synchronous web services

=head1 DESCRIPTION

The BioVeL API makes a distinction between "synchronised" and "asynchronous" services.
Synchronised services produce their final result within a single HTTP request/response
cycle by generating a response_body that is returned to the client at the end of the
cycle. Asynchronous services produce a result at the end of a longer running, forked 
process, which needs to be tracked between request/response cycles.

All concrete service classes need to inherit from either one of these service type 
superclasses (L<Bio::BioVeL::Service> or L<Bio::BioVeL::AsynchronousService>) so that
all the bookkeeping (processing request parameters, managing forked processes) is 
taken care of and the concrete child class only needs to worry about producing its
result.

=head1 METHODS

=over

=item new

The constructor takes at least one named argument, C<parameters>, whose value is an
array reference of names. The constructor then tries to obtain the values for these
named parameters. It does in a number of ways: 1. by probing the @ARGV command line
argument array, 2. by probing the apache request object (if provided), 3. by 
instantiating and querying a L<CGI> object. Once the constructor returns, the object
will have properties whose values are available to the child class for constructing
its response body.

=cut

sub new {
	my $class = shift;
	my %args  = @_;
	my $self  = { '_params' => {} };
	bless $self, $class;
	my $params = delete $args{'parameters'};
	if ( $params ) {
		if ( @ARGV ) {
			my %getopt;
			for my $p ( @{ $params } ) {
				$getopt{"${p}=s"} = sub {
					my $value = pop;
					$self->{'_params'}->{$p} = $value;
				};
			}
			GetOptions(%getopt);			
		}
		elsif ( my $req = delete $args{'request'} ) {
			for my $p ( @{ $params } ) {
				$self->{'_params'}->{$p} = $req->param($p);
			}		
		}
		else {
			my $cgi = CGI->new;
			for my $p ( @{ $params } ) {
				$self->{'_params'}->{$p} = $cgi->param($p);
			}
		}
	}
	for my $key ( keys %args ) {
		$self->$key( $args{$key} );
	}	
	return $self;
}

# the AUTOLOAD method traps all undefined method calls that child classes might
# make on themselves. the method names are turned into keys inside the object's
# '_params' hash, whose values are returned (and optionally updated, if an argument
# was provided.



( run in 1.563 second using v1.01-cache-2.11-cpan-39bf76dae61 )