1package SOAP::XML::Client::Generic;
2$SOAP::XML::Client::Generic::VERSION = '2.8';
3use strict;
4use Carp;
5
6use base qw(SOAP::XML::Client);
7
8# Actually do the call
9sub _call {
10    my ( $self, $method ) = @_;
11
12    my @params = ( $self->{sdb}->to_soap_data() );
13    unshift( @params, $self->header() ) if $self->header();
14
15    my $caller
16        = $self->{soap}->uri( $self->uri() )
17        ->proxy( $self->proxy(), timeout => $self->timeout() )
18        ->soapversion( $self->soapversion() )->encoding( $self->encoding );
19
20    my $res = $caller->$method(@params);
21    return $res, $caller->transport;
22}
23
241;
25__END__
26
27=head1 NAME
28
29SOAP::XML::Client::Generic - talk with 'generic' webservices, e.g. not .net
30
31=head1 DESCRIPTION
32
33This package helps in talking with SOAP webservers, it just needs
34a bit of XML thrown at it and you get some XML back.
35It's designed to be REALLY simple to use, it doesn't try to
36be cleaver in any way (patches for 'cleaverness' welcome).
37
38The major difference to SOAP::XML::Client::DotNet is it will submit as:
39
40SOAPAction: "http://www.yourdomain.com/services#GetSellerActivity"
41
42and namesp<X> will be added to the XML submitted, including for
43the xmlns.
44
45=head1 SYNOPSIS
46
47  If your service looks like this:
48
49  <?xml version="1.0" encoding="utf-8"?>
50  <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
51    <soap:Body>
52      <GetActivity xmlns="http://www.yourdomain.com/services">
53        <userId>long</userId>
54      </GetActivity>
55    </soap:Body>
56  </soap:Envelope>
57
58
59  # Create an object with basic SOAP::Lite config stuff
60  my $soap_client = SOAP::XML::Client::Generic->new({
61    uri 		=> 'http://www.yourdomain.com/services',
62    proxy 		=> 'http://www.yourproxy.com/services',
63    xmlns 		=> 'http://www.yourdomain.com/services',
64    soapversion 	=> '1.1', # defaults to 1.1
65    timeout		=> '30', # detauls to 30 seconds
66    strip_default_xmlns => 1, # defaults to 1
67  });
68
69
70  # Create the following XML:
71
72  my $user_id = '900109';
73  my $xml = "<userId _value_type='long'>$user_id</userId>";
74
75  ###########
76  # Warning: you might have to supply data types (using _value_type)
77  # for each field, depending on the service you are talking to
78  ###########
79
80  # Actually do the call
81  if( $soap_client->fetch({
82                         'method' => 'GetActivity',
83                         'xml' => $xml,
84                     }) ) {
85		      # Get result as a string
86		      my $xml_string = $soap_client->result();
87
88		      # Get result as a XML::LibXML object
89		      my $xml_libxml_object = $soap_client->result_xml();
90
91  } else {
92    # Got an error
93    print "Problem using service:" . $soap_client->error();
94
95  }
96
97=head1 methods
98
99=head2 new()
100
101  my $soap_client = SOAP::XML::Client::Generic->new({
102    uri 	=> 'http://www.yourdomain.com/services',
103    proxy 	=> 'http://www.yourproxy.com/services',
104    xmlns 	=> 'http://www.yourdomain.com/services',
105    soapversion => '1.1', # defaults to 1.1
106    timeout	=> '30', # detauls to 30 seconds
107    strip_default_xmlns => 1, # defaults to 1
108  });
109
110This constructor requires uri, proxy and xmlns to be
111supplied, otherwise it will croak.
112
113strip_default_xmlns is used to remove xmlns="http://.../"
114from returned XML, it will NOT alter xmlns:FOO="http//.../"
115set to '0' if you do not wish for this to happen.
116
117=head2 header()
118
119   my $header = SOAP::Header->name(
120          SomeDomain => {
121              Username => "a_user",
122              Password => 'xxxxx',
123          }
124      )->uri('http://www.thedomain.com/')->prefix('');
125
126    $soap_client->header($header);
127
128Add a soap header to the soap call, probably useful if there is
129credential based authenditcation
130
131=head2 fetch()
132
133  # Generate the required XML (you don't need the SOAP wrapper or method part of the XML
134  my $user_id = '900109';
135  my $xml = "<userId _value_type='long'>$user_id</userId>";
136
137  if($soap_client->fetch({ method => 'GetActivity', xml => $xml }) {
138      # Get result as a string
139      my $xml_string = $soap_client->result();
140
141      # Get result as a XML::LibXML object
142      my $xml_libxml_object = $soap_client->result_xml();
143
144  } else {
145      # There was some sort of error
146      print $soap_client->error() . "\n";
147  }
148
149This method actually calls the web service, it takes a method name
150and an xml string. If there is a problem with either the XML or
151the SOAP transport (e.g. web server error/could not connect etc)
152undef will be returned and the error() will be set.
153
154Each node in the XML supplied (either by string or from a filename)
155can have _value_type defined or the submitted format may
156default to 'string' (depending on SOAP::Data::Builder).
157
158You can supply 'filename' rather than 'xml' and it will read in from
159the file.
160
161We check for Fault/faultstring in the returned XML,
162anything else you'll need to check for yourself.
163
164
165=cut
166
167=head2 error()
168
169  $soap_client->error();
170
171If fetch returns undef then check this method, it will either be that the filename you
172supplied couldn't be read, the XML you supplied was not correctly formatted (XML::LibXML
173could not parse it), there was a transport error with the web service or Fault/faultstring
174was found in the XML returned.
175
176=head2 results();
177
178  my $results = $soap_client->results();
179
180Can be called after fetch() to get the raw XML, if fetch was sucessful.
181
182=head2 results_xml();
183
184  my $results_as_xml = $soap_client->results_xml();
185
186Can be called after fetch() to get the XML::LibXML Document element of the returned
187xml, as long as fetch was sucessful.
188
189=cut
190
191=head1 HOW TO DEBUG
192
193At the top of your script, before 'use SOAP::XML::Client::Generic' add:
194
195use SOAP::Lite (  +trace => 'all',
196                  readable => 1,
197                  outputxml => 1,
198               );
199
200It may or may not help, not all services don't give you helpful error messages!
201At least you can see what's being submitted and returned. It can be the
202smallest thing that causes a problem, mis-typed data (see _value_type in xml),
203or typo in xmlns line.
204
205=head1 BUGS
206
207This is only designed to work with generic services, it may work
208 with others. I haven't found any open webservices which I can use
209to test against, but as far as I'm aware it all works - web services
210are all standard.. right.. :) ?
211
212=head1 AUTHOR
213
214Leo Lapworth <LLAP@cuckoo.org>
215
216=head1 COPYRIGHT
217
218(c) 2005 Leo Lapworth
219
220This library is free software, you can use it under the same
221terms as perl itself.
222
223=head1 SEE ALSO
224
225  <SOAP::XML::Client::DotNet>, <SOAP::XML::Client>
226
227=cut
228
2291;
230