1# $Id$
2#
3# BioPerl module Bio::Tools::Run::AnalysisFactory::soap.pm
4#
5# Please direct questions and support issues to <bioperl-l@bioperl.org>
6#
7# Cared for by Martin Senger <martin.senger@gmail.com>
8# For copyright and disclaimer see below.
9
10# POD documentation - main docs before the code
11
12=head1 NAME
13
14Bio::Tools::Run::AnalysisFactory::soap - A SOAP-based access to the list of analysis tools
15
16=head1 SYNOPSIS
17
18Do not use this object directly, it is recommended to access it and use
19it through the I<Bio::Tools::Run::AnalysisFactory> module:
20
21  use Bio::Tools::Run::AnalysisFactory;
22  my $list = Bio::Tools::Run::AnalysisFactory->new(-access => 'soap')
23     ->available_analyses;
24  print join ("\n", @$list) . "\n";
25
26=head1 DESCRIPTION
27
28All public methods are documented in the interface module
29C<Bio::Factory::AnalysisI>.
30
31=head1 FEEDBACK
32
33=head2 Mailing Lists
34
35User feedback is an integral part of the evolution of this and other
36Bioperl modules. Send your comments and suggestions preferably to
37the Bioperl mailing list.  Your participation is much appreciated.
38
39  bioperl-l@bioperl.org                  - General discussion
40  http://bioperl.org/wiki/Mailing_lists  - About the mailing lists
41
42=head2 Support
43
44Please direct usage questions or support issues to the mailing list:
45
46I<bioperl-l@bioperl.org>
47
48rather than to the module maintainer directly. Many experienced and
49reponsive experts will be able look at the problem and quickly
50address it. Please include a thorough description of the problem
51with code and data examples if at all possible.
52
53=head2 Reporting Bugs
54
55Report bugs to the Bioperl bug tracking system to help us keep track
56of the bugs and their resolution. Bug reports can be submitted via the
57web:
58
59  http://redmine.open-bio.org/projects/bioperl/
60
61=head1 AUTHOR
62
63Martin Senger (martin.senger@gmail.com)
64
65=head1 COPYRIGHT
66
67Copyright (c) 2003, Martin Senger and EMBL-EBI.
68All Rights Reserved.
69
70This module is free software; you can redistribute it and/or modify
71it under the same terms as Perl itself.
72
73=head1 DISCLAIMER
74
75This software is provided "as is" without warranty of any kind.
76
77=head1 SEE ALSO
78
79=over
80
81=item *
82
83http://www.ebi.ac.uk/soaplab/Perl_Client.html
84
85=back
86
87=head1 BUGS AND LIMITATIONS
88
89None known at the time of writing this.
90
91=head1 APPENDIX
92
93The main documentation details are in
94C<Bio::Factory::AnalysisI>.
95
96=cut
97
98# Let the code begin...
99
100package Bio::Tools::Run::AnalysisFactory::soap;
101use vars qw(@ISA $Revision $DEFAULT_LOCATION @DEFAULT_DIR_SERVICE);
102use strict;
103
104use Bio::Tools::Run::AnalysisFactory;
105use Bio::Tools::Run::Analysis;
106use SOAP::Lite
107    on_fault => sub {
108	my $soap = shift;
109	my $res = shift;
110	my $msg =
111	    ref $res ?
112		"--- SOAP FAULT ---\n" .
113		'faultcode:   ' . $res->faultcode . "\n" .
114		'faultstring: ' . Bio::Tools::Run::AnalysisFactory::soap::_clean_msg ($res->faultstring)
115	      : "--- TRANSPORT ERROR ---\n" . $soap->transport->status . "\n$res\n";
116        Bio::Tools::Run::AnalysisFactory::soap->throw ($msg);
117    }
118;
119
120@ISA = qw(Bio::Tools::Run::AnalysisFactory);
121
122BEGIN {
123    $Revision = q[$Id$];
124
125    # where to go...
126    $DEFAULT_LOCATION = 'http://www.ebi.ac.uk/soaplab/services';
127
128    # ...and what to find there
129    # (this is a list of service names available from the given location;
130    #  those that do not exist are ignored; if none exists then only
131    #  location - without any service name appended - is used)
132    @DEFAULT_DIR_SERVICE = ('AnalysisFactory', 'GowlabFactory');
133}
134
135# -----------------------------------------------------------------------------
136
137=head2 _initialize
138
139 Usage   : my $factory = Bio::Tools::Run::AnalysisFactory->new(@args);
140           (_initialize is internally called from the 'new()' method)
141 Returns : nothing interesting
142 Args    : This module recognises and uses following arguments:
143             -location
144             -httpproxy
145             -soap
146	   Additionally, the main module Bio::Tools::Run::AnalysisFactory
147           recognises also:
148             -access
149
150It populates calling object with the given arguments, and then - for
151some attributes and only if they are not yet populated - it assigns
152some default values.
153
154This is an actual new() method (except for the real object creation
155and its blessing which is done in the parent class Bio::Root::Root in
156method _create_object).
157
158Note that this method is called always as an I<object> method (never as
159a I<class> method) - and that the object who calls this method may
160already be partly initiated (from Bio::Tools::Run::AnalysisFactory::new method);
161so if you need to do some tricks with the 'class invocation' you need to
162change Bio::Tools::Run::AnalysisFactory I<new> method, not this one.
163
164=over
165
166=item -location
167
168A URL (also called an I<endpoint>) defining where is located a Web Service
169functioning for this object.
170
171Default is C<http://www.ebi.ac.uk/soaplab/services> (a service running
172at European Bioinformatics Institute on top of most of the EMBOSS
173analyses, and on top of few others).
174
175For example, if you run your own Web Service using Java(TM) Apache Axis
176toolkit, the location might be something like
177C<http://localhost:8080/axis/services>.
178
179=item -httpproxy
180
181In addition to the I<location> parameter, you may need
182to specify also a location/URL of an HTTP proxy server
183(if your site requires one). The expected format is C<http://server:port>.
184There is no default value.
185
186=item -soap
187
188Defines your own SOAP::Lite object. Useful if you need finer-grained
189access to many features and attributes of the wonderful Paul Kulchenko's
190module.
191
192=back
193
194=cut
195
196# '
197
198sub _initialize {
199    my ($self, @args) = @_;
200
201    # make a hashtable from @args
202    my %param = @args;
203    @param { map { lc $_ } keys %param } = values %param; # lowercase keys
204
205    # copy all @args into this object (overwriting what may already be
206    # there) - changing '-key' into '_key'
207    my $new_key;
208    foreach my $key (keys %param) {
209	($new_key = $key) =~ s/^-/_/;
210	$self->{ $new_key } = $param { $key };
211    }
212
213    # finally add default values for those keys who have default value
214    # and who are not yet in the object
215    $self->{'_location'} = $DEFAULT_LOCATION unless $self->{'_location'};
216
217    # create a SOAP object which will do the main job
218    # ('uri' (representing a service name) will be added before each call)
219    unless ($self->{'_soap'}) {
220	if (defined $self->{'_httpproxy'}) {
221	    $self->{'_soap'} = SOAP::Lite
222		-> proxy ($self->{'_location'},
223			  proxy => ['http' => $self->{'_httpproxy'}]);
224	} else {
225	    $self->{'_soap'} = SOAP::Lite
226		-> proxy ($self->{'_location'});
227	}
228    }
229}
230
231sub _clean_msg {
232    my ($msg) = @_;
233    $msg =~ s/^org\.embl\.ebi\.SoaplabShare\.SoaplabException\:\s*//;
234    $msg;
235}
236
237# String[] getAvailableCategories()
238sub available_categories {
239    my ($self) = @_;
240    my $soap = $self->{'_soap'};
241
242    my @result = ();
243    my $okay = 0;
244    foreach my $service_name (@DEFAULT_DIR_SERVICE) {
245	$soap-> uri ($service_name);
246	eval {
247	    push (@result, @{ $soap->getAvailableCategories->result });
248	};
249	$okay = 1 unless $@;
250    }
251    return $soap->getAvailableCategories->result unless $okay;
252    \@result;
253}
254
255# String[] getAvailableAnalyses()
256# String[] getAvailableAnalysesInCategory (String categoryName)
257sub available_analyses {
258    my ($self, $category) = @_;
259    my $soap = $self->{'_soap'};
260
261    my @result = ();
262    my $okay = 0;
263
264    if (defined $category) {
265	foreach my $service_name (@DEFAULT_DIR_SERVICE) {
266	    $soap-> uri ($service_name);
267	    eval {
268		push (@result, @{ $soap->getAvailableAnalysesInCategory (SOAP::Data->type (string => $category))->result });
269	    };
270	    $okay = 1 unless $@;
271	}
272	return
273	    $soap->getAvailableAnalysesInCategory (SOAP::Data->type (string => $category))
274	    ->result unless $okay;
275	\@result;
276
277    } else {
278	foreach my $service_name (@DEFAULT_DIR_SERVICE) {
279	    $soap-> uri ($service_name);
280	    eval {
281		push (@result, @{ $soap->getAvailableAnalyses->result });
282	    };
283	    $okay = 1 unless $@;
284	}
285	return
286	    $soap->getAvailableAnalyses->result unless $okay;
287	\@result;
288    }
289}
290
291# String getServiceLocation (String analysisName)
292sub create_analysis {
293    my ($self, $name) = @_;
294
295    # service name
296    my @name  = ('-name', $name) if $name;
297
298    # ask for an endpoint
299    my $soap = $self->{'_soap'};
300    my $location;
301    foreach my $service_name (@DEFAULT_DIR_SERVICE) {
302	$soap-> uri ($service_name);
303	eval {
304	    $location = $soap->getServiceLocation (SOAP::Data->type (string => $name))->result;
305	};
306	last if defined $location;
307    }
308    unless (defined $location) {
309	$location = $soap->getServiceLocation (SOAP::Data->type (string => $name)) ->result;
310    }
311    my @location  = ('-location', $location) if $location;
312
313    # share some of my properties with the new Bio::Analysis object
314    my @access  = ('-access', $self->{'_access'}) if $self->{'_access'};
315    my @httpproxy = ('-httpproxy', $self->{'_httpproxy'}) if $self->{'_httpproxy'};
316
317    Bio::Tools::Run::Analysis->new(@name, @location, @httpproxy, @access);
318}
319
320
321
322=head2 VERSION and Revision
323
324 Usage   : print $Bio::Tools::Run::AnalysisFactory::soap::VERSION;
325           print $Bio::Tools::Run::AnalysisFactory::soap::Revision;
326
327=cut
328
329
3301;
331__END__
332