[Bio] / FigKernelPackages / SSserver.pm Repository:
ViewVC logotype

View of /FigKernelPackages/SSserver.pm

Parent Directory Parent Directory | Revision Log Revision Log

Revision 1.10 - (download) (as text) (annotate)
Thu Aug 27 19:46:36 2009 UTC (10 years, 7 months ago) by parrello
Branch: MAIN
CVS Tags: rast_rel_2009_0925
Changes since 1.9: +161 -58 lines
Converted subsystem server to new technology.

package SSserver;

# This is a SAS Component

use LWP::UserAgent;
use YAML;

use strict;

=head1 Subsystem Server Helper Object

=head2 Description

This module is used to call the Subsystem Server, which is a special-purpose
server for manipulating subsystem data from the Sapling database. Each Subsystem
Server function corresponds to a method of this object.

This package deliberately uses no internal SEED packages or scripts, only common
PERL modules.

The fields in this object are as follows.

=over 4

=item server_url

The URL used to request data from the subsystem server.

=item ua

The user agent for communication with the server.

=item singleton

Indicates whether or not results are to be returned in singleton mode. In
singleton mode, if the return document is a hash reference with only one
entry, the entry value is returned rather than the hash.



=head3 new

    my $ss = SSserver->new(%options);

Construct a new SSserver object. The following options are supported.

=over 4

=item url

URL for the subsystem server. This option may be used to redirect requests to a
test version of the server, or to an older server script.

=item singleton

If TRUE, results from methods will be returned in singleton mode. In singleton
mode, if a single result comes back, it will come back as a scalar rather than
as a hash value accessible via an incoming ID.



sub new {
    # Get the parameters.
    my ($class, %options) = @_;
    # Get the options.
    my $url = $options{url} || "http://servers.nmpdr.org/subsystem/server.cgi";
    my $singleton = $options{singleton} || 0;
    # Create the fields of the object.
    my $server_url = $url;
    my $ua = LWP::UserAgent->new();
    # Create the SAPserver object.
    my $retVal = { 
                    server_url => $server_url,
                    ua => $ua,
                    singleton => $singleton,
    # Bless and return it.
    bless $retVal, $class;
    return $retVal;

=head2 Public Methods

All L<SS/Primary Methods> are also methods of this object.


    my $result = $ss->method(%args);

Call a function on the server. Any method call on this object (other than
the constructor) is translated into a request against the server. This
enables us to add new server functions without requiring an update to this
module. The parameters are specified as a hash, and the result is a scalar
or object reference. If an error occurred, we will throw an exception.


# This variable will contain the method name.

    # Get the parameters. We do some fancy dancing to allow the user to pass
    # in a hash, a list, or a hash reference.
    my $self = shift @_;
    my $args = $_[0];
    if (defined $args) {
        if (scalar @_ gt 1) {
            # Here we have multiple arguments. We check the first one for a
            # leading hyphen.
            if ($args =~ /^-/) {
                # This means we have hash-form parameters.
                my %args = @_;
                $args = \%args;
            } else {
                # This means we have list-form parameters.
                my @args = @_;
                $args = \@args;
        } else {
            # Here we have a single argument. If it's a scalar, we convert it
            # to a singleton list.
            if (! ref $args) {
                $args = [$args];
    # Declare the return variable.
    my $retVal;
    # Get the method name.
    my $function = $AUTOLOAD;
    # Strip off the stuff before the method name.
    $function =~ s/.+:://;
    # Compute the argument document.
    my $argString = YAML::Dump($args);
    # Get our user agent.
    my $ua = $self->{ua};
    # Request the function from the server.
    my $response = $ua->post($self->{server_url},
                             [function => $function, args => $argString,
                              source => __PACKAGE__ ]);
    # Get the response content.
    my $content = $response->content;
    if (! $response->is_success) {
        die "Server error " . $response->status_line . "\n$content";
    } else {
        $retVal = YAML::Load($content);
        # Figure out what we got back.
        my $returnType = ref $retVal;
        if ($returnType) {
            if ($returnType eq 'ErrorDocument') {
                # Here an error occurred, so we throw an exception using the
                # error message.
                die $retVal->{message};
            } elsif ($self->{singleton} && $returnType eq 'HASH' &&
                     scalar(keys %$retVal) <= 1) {
                # Here we're in singleton mode and we got a single result,
                # so we dereference a bit to make it easier for the user
                # to access it.
                ($retVal) = values %$retVal;
    # Return the result.
    return $retVal;

=head3 DESTROY


This method has no function. It's purpose is to keep the destructor from
being caught by the autoload processing.


sub DESTROY { }


MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3