diff --git a/Build.PL b/Build.PL index 26505e3..75bc1e7 100644 --- a/Build.PL +++ b/Build.PL @@ -5,7 +5,7 @@ $build = Module::Build->new( create_makefile_pl => 'passthrough', dist_abstract => 'SOAP with WSDL support', dist_name => 'SOAP-WSDL', - dist_version => '2.00_26', + dist_version => '2.00_27', module_name => 'SOAP::WSDL', license => 'artistic', requires => { diff --git a/Changes b/Changes index 5e02d8b..3e6a80c 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,4 @@ -Release notes for SOAP::WSDL 2.00_26 +Release notes for SOAP::WSDL 2.00_27 ------- I'm proud to present a new pre-release version of SOAP::WSDL. @@ -34,6 +34,30 @@ Features: The following changes have been made: +2.00_27 + +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1850793 ] Add a to_hash_ref method + * [ 1844427 ] Support multiple parts in body + +The following bugs have been fixed (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660921): +The numbers with # are CPAN RT IDs (http://rt.cpan.org/). + + * [ 1850795 ] attributes referencing types in default namespace throw + * [ 1844458 ] Add warning when generating Interface with multiple parts + * [ 1843841 ] Grammar/typos in Manual.pod + * [ 1843799 ] ./Build test fails due to testcount mismatch not IO::Scalar + * [ 1845077 ] Top level simpleType elements don't serialize correctly + +The following uncategorized improvements have been made: + + * Fixed serializing complexType elements with no elements to empty element + * Enhanced test suite + * Documentation improvements + 2.00_26 The following features were added (the numbers in square brackets are the diff --git a/MANIFEST b/MANIFEST index dfcda35..e70e32e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -50,10 +50,16 @@ example/lib/MyTypemaps/TestService.pm example/lib/MyTypes/Address.pm example/lib/MyTypes/ArrayOfContract.pm example/lib/MyTypes/ArrayOfPerson.pm +example/lib/MyTypes/BarCodeData.pm +example/lib/MyTypes/BarcodeOption.pm +example/lib/MyTypes/BarcodeType.pm +example/lib/MyTypes/CheckSumMethod.pm example/lib/MyTypes/Contract.pm +example/lib/MyTypes/ImageFormats.pm example/lib/MyTypes/Person.pm example/lib/MyTypes/PersonID.pm example/lib/MyTypes/PhoneNumber.pm +example/lib/MyTypes/ShowTextPosition.pm example/lib/MyTypes/test2.pm example/lib/MyTypes/testExtended.pm example/person.pl @@ -311,6 +317,8 @@ t/SOAP/WSDL/Generator/Visitor/Typemap.t t/SOAP/WSDL/Generator/XCS.t t/SOAP/WSDL/Generator/XSD.t t/SOAP/WSDL/Generator/XSD_unsupported.t +t/SOAP/WSDL/Part.t +t/SOAP/WSDL/Serializer/XSD.t t/SOAP/WSDL/Server.t t/SOAP/WSDL/Server/CGI.t t/SOAP/WSDL/Transport/01_Test.t @@ -318,6 +326,9 @@ t/SOAP/WSDL/Transport/02_HTTP.t t/SOAP/WSDL/Transport/acceptance/test2.xml t/SOAP/WSDL/Transport/acceptance/test3.xml t/SOAP/WSDL/Typelib/Fault11.t +t/SOAP/WSDL/XSD/ComplexType.t +t/SOAP/WSDL/XSD/Element.t +t/SOAP/WSDL/XSD/SimpleType.t t/SOAP/WSDL/XSD/Typelib/Builtin/01_constructors.t t/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.t t/SOAP/WSDL/XSD/Typelib/Builtin/anyType.t diff --git a/META.yml b/META.yml index 39d67c5..3ebbb16 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- name: SOAP-WSDL -version: 2.00_26 +version: 2.00_27 author: - 'Martin Kutter ' abstract: SOAP with WSDL support @@ -33,12 +33,12 @@ provides: version: 2.00_25 SOAP::WSDL::Base: file: lib/SOAP/WSDL/Base.pm - version: 2.00_25 + version: 2.00_27 SOAP::WSDL::Binding: file: lib/SOAP/WSDL/Binding.pm SOAP::WSDL::Client: file: lib/SOAP/WSDL/Client.pm - version: 2.00_25 + version: 2.00_27 SOAP::WSDL::Client::Base: file: lib/SOAP/WSDL/Client/Base.pm version: 2.00_25 diff --git a/TODO b/TODO index a3f0426..2b94376 100644 --- a/TODO +++ b/TODO @@ -3,22 +3,22 @@ TODO list for SOAP::WSDL 2.00 Pre-releases -------- +* Act as SOAP Server [ 1842436 ] + 2.1 release -------- -* Support namespaces in SOAP message payload(#1809057) +* Support namespaces in SOAP message payload [ 1809057 ] -* Support the xsi:type attribute on derived types on the wire(#1809059) +* Support the xsi:type attribute on derived types on the wire [ 1809059 ] -* SOAP1.2 support (#1803331) +* SOAP1.2 support [ 1803331 ] 2.2 release -------- -* XML schema support ("minimal conformant") (#1764845) +* XML schema support ("minimal conformant") [ 1764845 ] * Support SOAP attachments -* Act as SOAP Server - 3.0 release -------- We're not thinking that far ahead right now. diff --git a/benchmark/person.pl b/benchmark/person.pl index 12366c8..5253801 100644 --- a/benchmark/person.pl +++ b/benchmark/person.pl @@ -1,12 +1,14 @@ use lib '../lib'; use lib '../example/lib'; +use lib '../../SOAP-WSDL_XS/blib/lib'; +use lib '../../SOAP-WSDL_XS/blib/arch'; use strict; package MyData; my $XML; sub xml { return $XML if ($XML); - + open my $fh, 'person.xml' or die 'cannot open data file'; $XML = join '', <$fh>; close $fh; @@ -17,12 +19,10 @@ package MyTransport; use SOAP::WSDL::Factory::Transport; SOAP::WSDL::Factory::Transport->register( http => __PACKAGE__ ); sub send_receive { - # warn MyData::xml; return MyData::xml(); } sub new { return bless {}, 'MyTransport' }; - package main; use Benchmark qw(cmpthese); @@ -34,68 +34,80 @@ use XML::Compile::Util;#use Data::Dumper; #print Dumper $result; use XML::Compile::WSDL11; use XML::Simple; + +use SOAP::WSDL::Deserializer::XSD_XS; +use SOAP::WSDL::Factory::Deserializer; + $XML::Simple::PREFERRED_PARSER = 'XML::Parser'; use SOAP::Lite; use MyInterfaces::TestService::TestPort; my $tester = XML::Compile::SOAP::Tester->new(); - my $action = pack_type 'http://example.org', 'ListPerson'; -sub ListPerson(@) { MyData::xml }; my $compile = XML::Compile::WSDL11->new('../example/wsdl/Person.wsdl'); -# $tester->fromWSDL($wsdl); -$tester->actionCallback($action, \&ListPerson); -# I have to lookup the methods from the WSDL +$tester->actionCallback($action, \&MyData::xml); + my $call = $compile->compileClient('ListPerson'); - -# I have to lookup the parameters from the WSDL my $result = $call->({ in => undef}); -#use Data::Dumper; -#print Dumper $result; +# Initialize SOAP::Lite my $deserializer = SOAP::Deserializer->new(); +# Initialize SOAP::WSDL interface my $soap = MyInterfaces::TestService::TestPort->new(); +# Load all classes - XML::Compile has created everything before, too +$soap->ListPerson({}); -$result = $soap->ListPerson({}); -#print $result; -#exit; +# # register for SOAP 1.1 +SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' ); + +my $wsdl_xs = MyInterfaces::TestService::TestPort->new(); + +# trigger loading of XML Data +{ + use bytes; + print "XML length (bytes): " . length( MyData::xml() ), "\n"; +} my @data = (); my $n = 0; print "Benchmark conducted with SOAP::Lite - $SOAP::Lite::VERSION SOAP::WSDL - $SOAP::WSDL::Client::VERSION +SOAP::WSDL_XS - $SOAP::WSDL::Deserializer::XSD_XS::VERSION; XML::Compile::SOAP - $XML::Compile::SOAP::VERSION XML::Simple - $XML::Simple::VERSION -Benchmark $n: Push result on list +Benchmark $n: Store result in private variable and destroy it "; $n++; -print "Benchmark $n: Store result in private variable and destroy it\n"; -cmpthese 100, { +cmpthese 300, { 'XML::Simple' => sub { my $result = XMLin( MyData::xml() )}, 'SOAP::WSDL' => sub { my $result = $soap->ListPerson({}) }, 'XML::Compile::SOAP' => sub { my $result = $call->() }, + 'SOAP::WSDL_XS' => sub { my $result = @data, $wsdl_xs->ListPerson({}) }, 'SOAP::Lite' => sub { my $result = $deserializer->deserialize( MyData::xml() )} }; +print "Benchmark $n: Push result on list\n"; $n++; -cmpthese 100, { +cmpthese 500, { 'XML::Simple' => sub { push @data, XMLin( MyData::xml() )}, 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) }, 'XML::Compile::SOAP' => sub { push @data, $call->() }, + 'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) }, 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )} }; @data = (); print "Benchmark $n: Play it again, Sam\n"; -cmpthese 100, { +cmpthese 500, { 'XML::Simple' => sub { push @data, XMLin( MyData::xml() )}, 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) }, + 'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) }, 'XML::Compile::SOAP' => sub { push @data, $call->() }, 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )} }; diff --git a/example/cgi-bin/helloworld.pl b/example/cgi-bin/helloworld.pl index 5aa1536..50323f5 100755 --- a/example/cgi-bin/helloworld.pl +++ b/example/cgi-bin/helloworld.pl @@ -52,4 +52,5 @@ Then run the helloworld.pl from the examples directory. It should print =head1 DESCRIPTION -=cut \ No newline at end of file +=cut + diff --git a/example/hello.pl b/example/hello.pl index 1725719..b810b58 100644 --- a/example/hello.pl +++ b/example/hello.pl @@ -1,11 +1,12 @@ #!/usr/bin/perl -w use strict; use warnings; -use lib 'lib'; +use lib 'lib'; # just needed because interface lies here # I have to generate the interface using wsdl2perl.pl before use MyInterfaces::HelloWorld::HelloWorldSoap; +# I instantiate a interface class. my $soap = MyInterfaces::HelloWorld::HelloWorldSoap->new(); # I have to lookup the method and synopsis from the interface's pod @@ -14,8 +15,9 @@ my $result = $soap->sayHello({ givenName => $ARGV[0] || '"Your given name"', }); +# SOAP::WSDL::SOAP::Typelib::Fault11 objects are false, but serialize to XML die $result if not $result; # I have to lookup the output parameter from the interface's POD - or try: -# Bad method names will die with a list of available methods -print $result->get_sayHelloResult(), "\n"; \ No newline at end of file +# Will die on bad method names with a list of available methods +print $result->get_sayHelloResult(), "\n"; diff --git a/example/hello_compile.pl b/example/hello_compile.pl index 94edeed..349a4d3 100644 --- a/example/hello_compile.pl +++ b/example/hello_compile.pl @@ -4,18 +4,22 @@ use warnings; use XML::Compile::WSDL11; use XML::Compile::Transport::SOAPHTTP; +# I need access to the WSDL around - or use Data::Dumper::Streamer +# for serializing the generated closures into (big) perl files my $wsdl = XML::Compile::WSDL11->new('wsdl/11_helloworld.wsdl'); -# I have to lookup the methods from the WSDL +# I compile a interface method for a single SOAP method from the WSDL +# I have to lookup the method names from the WSDL my $call = $wsdl->compileClient('sayHello'); -# I have to lookup the parameters from the WSDL +# I have to lookup the parameters from the WSDL - can be quite tricky my $result = $call->( name => $ARGV[1] || '"Your name"', givenName => $ARGV[0] || '"Your given name"', ); +# XML::Compile::SOAP's client just returns undef in case of failure die "Error calling soap method" if not defined $result; -# I have to lookup the output parameters from the WSDL - or try Dumper -print $result->{ parameters }->{ sayHelloResult }, "\n"; \ No newline at end of file +# I have to lookup the output parameters from the WSDL - or try Data::Dumper +print $result->{ parameters }->{ sayHelloResult }, "\n"; diff --git a/example/lib/MyElements/CountCookies.pm b/example/lib/MyElements/CountCookies.pm index 2c022d1..02bea8f 100644 --- a/example/lib/MyElements/CountCookies.pm +++ b/example/lib/MyElements/CountCookies.pm @@ -13,8 +13,8 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); @@ -44,7 +44,7 @@ CountCookies from the namespace http://www.fullerdata.com/FortuneCookie/FortuneC Constructor. The following data structure may be passed to new(): - +, =head1 AUTHOR diff --git a/example/lib/MyElements/CountCookiesResponse.pm b/example/lib/MyElements/CountCookiesResponse.pm index 745dd5f..630551a 100644 --- a/example/lib/MyElements/CountCookiesResponse.pm +++ b/example/lib/MyElements/CountCookiesResponse.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %CountCookiesResult_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( CountCookiesResult ) ], - { - CountCookiesResult => \%CountCookiesResult_of, + { + CountCookiesResult => \%CountCookiesResult_of, }, { CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { CountCookiesResult => $some_value, # int - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/GenerateBarCode.pm b/example/lib/MyElements/GenerateBarCode.pm index 3a8187c..fe94f95 100644 --- a/example/lib/MyElements/GenerateBarCode.pm +++ b/example/lib/MyElements/GenerateBarCode.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %BarCodeParam_of :ATTR(:get); @@ -29,9 +31,9 @@ __PACKAGE__->_factory( BarCodeParam BarCodeText ) ], - { - BarCodeParam => \%BarCodeParam_of, - BarCodeText => \%BarCodeText_of, + { + BarCodeParam => \%BarCodeParam_of, + BarCodeText => \%BarCodeText_of, }, { BarCodeParam => 'MyTypes::BarCodeData', diff --git a/example/lib/MyElements/GenerateBarCodeResponse.pm b/example/lib/MyElements/GenerateBarCodeResponse.pm index bd9e2dc..35814c7 100644 --- a/example/lib/MyElements/GenerateBarCodeResponse.pm +++ b/example/lib/MyElements/GenerateBarCodeResponse.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %GenerateBarCodeResult_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( GenerateBarCodeResult ) ], - { - GenerateBarCodeResult => \%GenerateBarCodeResult_of, + { + GenerateBarCodeResult => \%GenerateBarCodeResult_of, }, { GenerateBarCodeResult => 'SOAP::WSDL::XSD::Typelib::Builtin::base64Binary', diff --git a/example/lib/MyElements/GetCitiesByCountry.pm b/example/lib/MyElements/GetCitiesByCountry.pm index 25ae700..8630ea6 100644 --- a/example/lib/MyElements/GetCitiesByCountry.pm +++ b/example/lib/MyElements/GetCitiesByCountry.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %CountryName_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( CountryName ) ], - { - CountryName => \%CountryName_of, + { + CountryName => \%CountryName_of, }, { CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { CountryName => $some_value, # string - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/GetCitiesByCountryResponse.pm b/example/lib/MyElements/GetCitiesByCountryResponse.pm index fe3b874..1fedc5e 100644 --- a/example/lib/MyElements/GetCitiesByCountryResponse.pm +++ b/example/lib/MyElements/GetCitiesByCountryResponse.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %GetCitiesByCountryResult_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( GetCitiesByCountryResult ) ], - { - GetCitiesByCountryResult => \%GetCitiesByCountryResult_of, + { + GetCitiesByCountryResult => \%GetCitiesByCountryResult_of, }, { GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { GetCitiesByCountryResult => $some_value, # string - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/GetFortuneCookie.pm b/example/lib/MyElements/GetFortuneCookie.pm index 116c0b5..5914bc1 100644 --- a/example/lib/MyElements/GetFortuneCookie.pm +++ b/example/lib/MyElements/GetFortuneCookie.pm @@ -13,8 +13,8 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); @@ -44,7 +44,7 @@ GetFortuneCookie from the namespace http://www.fullerdata.com/FortuneCookie/Fort Constructor. The following data structure may be passed to new(): - +, =head1 AUTHOR diff --git a/example/lib/MyElements/GetFortuneCookieResponse.pm b/example/lib/MyElements/GetFortuneCookieResponse.pm index a3868f8..752c7f0 100644 --- a/example/lib/MyElements/GetFortuneCookieResponse.pm +++ b/example/lib/MyElements/GetFortuneCookieResponse.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %GetFortuneCookieResult_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( GetFortuneCookieResult ) ], - { - GetFortuneCookieResult => \%GetFortuneCookieResult_of, + { + GetFortuneCookieResult => \%GetFortuneCookieResult_of, }, { GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { GetFortuneCookieResult => $some_value, # string - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/GetSpecificCookie.pm b/example/lib/MyElements/GetSpecificCookie.pm index 8b9dd3d..2b32f0e 100644 --- a/example/lib/MyElements/GetSpecificCookie.pm +++ b/example/lib/MyElements/GetSpecificCookie.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %index_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( index ) ], - { - index => \%index_of, + { + index => \%index_of, }, { index => 'SOAP::WSDL::XSD::Typelib::Builtin::int', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { index => $some_value, # int - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/GetSpecificCookieResponse.pm b/example/lib/MyElements/GetSpecificCookieResponse.pm index a6c4778..2405b3c 100644 --- a/example/lib/MyElements/GetSpecificCookieResponse.pm +++ b/example/lib/MyElements/GetSpecificCookieResponse.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %GetSpecificCookieResult_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( GetSpecificCookieResult ) ], - { - GetSpecificCookieResult => \%GetSpecificCookieResult_of, + { + GetSpecificCookieResult => \%GetSpecificCookieResult_of, }, { GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { GetSpecificCookieResult => $some_value, # string - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/GetWeather.pm b/example/lib/MyElements/GetWeather.pm index 04b4320..d26c06c 100644 --- a/example/lib/MyElements/GetWeather.pm +++ b/example/lib/MyElements/GetWeather.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %CityName_of :ATTR(:get); @@ -29,9 +31,9 @@ __PACKAGE__->_factory( CityName CountryName ) ], - { - CityName => \%CityName_of, - CountryName => \%CountryName_of, + { + CityName => \%CityName_of, + CountryName => \%CountryName_of, }, { CityName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', @@ -74,7 +76,7 @@ Constructor. The following data structure may be passed to new(): { CityName => $some_value, # string CountryName => $some_value, # string - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/GetWeatherResponse.pm b/example/lib/MyElements/GetWeatherResponse.pm index 287395c..d837315 100644 --- a/example/lib/MyElements/GetWeatherResponse.pm +++ b/example/lib/MyElements/GetWeatherResponse.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %GetWeatherResult_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( GetWeatherResult ) ], - { - GetWeatherResult => \%GetWeatherResult_of, + { + GetWeatherResult => \%GetWeatherResult_of, }, { GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { GetWeatherResult => $some_value, # string - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/int.pm b/example/lib/MyElements/int.pm index eccf137..74cac71 100644 --- a/example/lib/MyElements/int.pm +++ b/example/lib/MyElements/int.pm @@ -12,8 +12,8 @@ __PACKAGE__->__set_minOccurs(); __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::Builtin::int + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::Builtin::int ); diff --git a/example/lib/MyElements/readNodeCount.pm b/example/lib/MyElements/readNodeCount.pm index 3a52485..484bf70 100644 --- a/example/lib/MyElements/readNodeCount.pm +++ b/example/lib/MyElements/readNodeCount.pm @@ -13,8 +13,8 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); @@ -44,7 +44,7 @@ readNodeCount from the namespace http://www.fullerdata.com/FortuneCookie/Fortune Constructor. The following data structure may be passed to new(): - +, =head1 AUTHOR diff --git a/example/lib/MyElements/readNodeCountResponse.pm b/example/lib/MyElements/readNodeCountResponse.pm index f4ac6e9..d5ffeee 100644 --- a/example/lib/MyElements/readNodeCountResponse.pm +++ b/example/lib/MyElements/readNodeCountResponse.pm @@ -13,12 +13,14 @@ __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType ); -use Class::Std::Storable; +use Class::Std::Fast::Storable constructor => 'none'; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +Class::Std::initialize(); + { # BLOCK to scope variables my %readNodeCountResult_of :ATTR(:get); @@ -27,8 +29,8 @@ __PACKAGE__->_factory( [ qw( readNodeCountResult ) ], - { - readNodeCountResult => \%readNodeCountResult_of, + { + readNodeCountResult => \%readNodeCountResult_of, }, { readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int', @@ -69,7 +71,7 @@ Constructor. The following data structure may be passed to new(): { readNodeCountResult => $some_value, # int - } + }, =head1 AUTHOR diff --git a/example/lib/MyElements/string.pm b/example/lib/MyElements/string.pm index 044fa2a..052f4a9 100644 --- a/example/lib/MyElements/string.pm +++ b/example/lib/MyElements/string.pm @@ -12,8 +12,8 @@ __PACKAGE__->__set_minOccurs(); __PACKAGE__->__set_maxOccurs(); __PACKAGE__->__set_ref(); use base qw( - SOAP::WSDL::XSD::Typelib::Element - SOAP::WSDL::XSD::Typelib::Builtin::string + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::Builtin::string ); diff --git a/example/lib/MyInterfaces/BarCode/BarCodeSoap.pm b/example/lib/MyInterfaces/BarCode/BarCodeSoap.pm index facf9ff..88be68a 100644 --- a/example/lib/MyInterfaces/BarCode/BarCodeSoap.pm +++ b/example/lib/MyInterfaces/BarCode/BarCodeSoap.pm @@ -1,12 +1,13 @@ package MyInterfaces::BarCode::BarCodeSoap; use strict; use warnings; -use Class::Std::Storable; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); use base qw(SOAP::WSDL::Client::Base); # only load if it hasn't been loaded before require MyTypemaps::BarCode - if not MyTypemaps::BarCode->can('get_class'); + if not MyTypemaps::BarCode->can('get_class'); sub START { $_[0]->set_proxy('http://www.webservicex.net/genericbarcode.asmx') if not $_[2]->{proxy}; @@ -16,11 +17,12 @@ sub START { sub GenerateBarCode { my ($self, $body, $header) = @_; + die "GenerateBarCode must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ - operation => 'GenerateBarCode', + operation => 'GenerateBarCode', soap_action => 'http://www.webservicex.net/GenerateBarCode', style => 'document', - body => { + body => { 'use' => 'literal', namespace => '', @@ -58,12 +60,12 @@ MyInterfaces::BarCode::BarCodeSoap - SOAP Interface for the BarCode Web Service my $response; $response = $interface->GenerateBarCode(); - + =head1 DESCRIPTION -SOAP Interface for the BarCode web service +SOAP Interface for the BarCode web service located at http://www.webservicex.net/genericbarcode.asmx. =head1 SERVICE BarCode @@ -86,12 +88,12 @@ All arguments are forwarded to L. =head2 SOAP Service methods -Method synopsis is displayed with hash refs as parameters. +Method synopsis is displayed with hash refs as parameters. -The commented class names in the method's parameters denote that objects +The commented class names in the method's parameters denote that objects of the corresponding class can be passed instead of the marked hash ref. -You may pass any combination of objects, hash and list refs to these +You may pass any combination of objects, hash and list refs to these methods, as long as you meet the structure. @@ -124,10 +126,10 @@ WebserviceX.NET barcode library that provides the means to create barcodes for p },, ); - + =head1 AUTHOR -Generated by SOAP::WSDL on Fri Nov 9 00:18:35 2007 +Generated by SOAP::WSDL on Sun Dec 16 20:10:20 2007 =pod \ No newline at end of file diff --git a/example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm b/example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm index 12eade0..69a0a37 100644 --- a/example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm +++ b/example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm @@ -1,12 +1,13 @@ package MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap; use strict; use warnings; -use Class::Std::Storable; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); use base qw(SOAP::WSDL::Client::Base); # only load if it hasn't been loaded before require MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie - if not MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie->can('get_class'); + if not MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie->can('get_class'); sub START { $_[0]->set_proxy('http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx') if not $_[2]->{proxy}; @@ -16,11 +17,12 @@ sub START { sub readNodeCount { my ($self, $body, $header) = @_; + die "readNodeCount must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ - operation => 'readNodeCount', + operation => 'readNodeCount', soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/readNodeCount', style => 'document', - body => { + body => { 'use' => 'literal', namespace => '', @@ -38,11 +40,12 @@ sub readNodeCount { sub GetFortuneCookie { my ($self, $body, $header) = @_; + die "GetFortuneCookie must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ - operation => 'GetFortuneCookie', + operation => 'GetFortuneCookie', soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/GetFortuneCookie', style => 'document', - body => { + body => { 'use' => 'literal', namespace => '', @@ -60,11 +63,12 @@ sub GetFortuneCookie { sub CountCookies { my ($self, $body, $header) = @_; + die "CountCookies must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ - operation => 'CountCookies', + operation => 'CountCookies', soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/CountCookies', style => 'document', - body => { + body => { 'use' => 'literal', namespace => '', @@ -82,11 +86,12 @@ sub CountCookies { sub GetSpecificCookie { my ($self, $body, $header) = @_; + die "GetSpecificCookie must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ - operation => 'GetSpecificCookie', + operation => 'GetSpecificCookie', soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/GetSpecificCookie', style => 'document', - body => { + body => { 'use' => 'literal', namespace => '', @@ -117,9 +122,22 @@ __END__ MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap - SOAP Interface for the FullerData_x0020_Fortune_x0020_Cookie Web Service +=head1 SYNOPSIS + + use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap; + my $interface = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap->new(); + + my $response; + $response = $interface->readNodeCount(); + $response = $interface->GetFortuneCookie(); + $response = $interface->CountCookies(); + $response = $interface->GetSpecificCookie(); + + + =head1 DESCRIPTION -SOAP Interface for the FullerData_x0020_Fortune_x0020_Cookie web service +SOAP Interface for the FullerData_x0020_Fortune_x0020_Cookie web service located at http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. =head1 SERVICE FullerData_x0020_Fortune_x0020_Cookie @@ -142,12 +160,12 @@ All arguments are forwarded to L. =head2 SOAP Service methods -Method synopsis is displayed with hash refs as parameters. +Method synopsis is displayed with hash refs as parameters. -The commented class names in the method's parameters denote that objects +The commented class names in the method's parameters denote that objects of the corresponding class can be passed instead of the marked hash ref. -You may pass any combination of objects, hash and list refs to these +You may pass any combination of objects, hash and list refs to these methods, as long as you meet the structure. @@ -156,21 +174,21 @@ methods, as long as you meet the structure. Display the number of nodes specified in fortune XML document - $interface->readNodeCount(, + $interface->readNodeCount(,, ); =head3 GetFortuneCookie Get a random fortune cookie from the XML document - $interface->GetFortuneCookie(, + $interface->GetFortuneCookie(,, ); =head3 CountCookies Count the actual number of nodes in the XML document of fortunes - $interface->CountCookies(, + $interface->CountCookies(,, ); =head3 GetSpecificCookie @@ -179,13 +197,13 @@ Get a specific cookie by the XML node number $interface->GetSpecificCookie( { index => $some_value, # int - }, + },, ); - + =head1 AUTHOR -Generated by SOAP::WSDL on Tue Nov 6 20:56:46 2007 +Generated by SOAP::WSDL on Sun Dec 16 19:58:30 2007 =pod \ No newline at end of file diff --git a/example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm b/example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm index 65c8100..caf6c23 100644 --- a/example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm +++ b/example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm @@ -1,12 +1,13 @@ package MyInterfaces::GlobalWeather::GlobalWeatherSoap; use strict; use warnings; -use Class::Std::Storable; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); use base qw(SOAP::WSDL::Client::Base); # only load if it hasn't been loaded before require MyTypemaps::GlobalWeather - if not MyTypemaps::GlobalWeather->can('get_class'); + if not MyTypemaps::GlobalWeather->can('get_class'); sub START { $_[0]->set_proxy('http://www.webservicex.net/globalweather.asmx') if not $_[2]->{proxy}; @@ -16,11 +17,12 @@ sub START { sub GetWeather { my ($self, $body, $header) = @_; + die "GetWeather must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ - operation => 'GetWeather', + operation => 'GetWeather', soap_action => 'http://www.webserviceX.NET/GetWeather', style => 'document', - body => { + body => { 'use' => 'literal', namespace => '', @@ -38,11 +40,12 @@ sub GetWeather { sub GetCitiesByCountry { my ($self, $body, $header) = @_; + die "GetCitiesByCountry must be called as object method (\$self is <$self>)" if not blessed($self); return $self->SUPER::call({ - operation => 'GetCitiesByCountry', + operation => 'GetCitiesByCountry', soap_action => 'http://www.webserviceX.NET/GetCitiesByCountry', style => 'document', - body => { + body => { 'use' => 'literal', namespace => '', @@ -73,9 +76,20 @@ __END__ MyInterfaces::GlobalWeather::GlobalWeatherSoap - SOAP Interface for the GlobalWeather Web Service +=head1 SYNOPSIS + + use MyInterfaces::GlobalWeather::GlobalWeatherSoap; + my $interface = MyInterfaces::GlobalWeather::GlobalWeatherSoap->new(); + + my $response; + $response = $interface->GetWeather(); + $response = $interface->GetCitiesByCountry(); + + + =head1 DESCRIPTION -SOAP Interface for the GlobalWeather web service +SOAP Interface for the GlobalWeather web service located at http://www.webservicex.net/globalweather.asmx. =head1 SERVICE GlobalWeather @@ -98,12 +112,12 @@ All arguments are forwarded to L. =head2 SOAP Service methods -Method synopsis is displayed with hash refs as parameters. +Method synopsis is displayed with hash refs as parameters. -The commented class names in the method's parameters denote that objects +The commented class names in the method's parameters denote that objects of the corresponding class can be passed instead of the marked hash ref. -You may pass any combination of objects, hash and list refs to these +You may pass any combination of objects, hash and list refs to these methods, as long as you meet the structure. @@ -115,7 +129,7 @@ Get weather report for all major cities around the world. $interface->GetWeather( { CityName => $some_value, # string CountryName => $some_value, # string - }, + },, ); =head3 GetCitiesByCountry @@ -124,13 +138,13 @@ Get all major cities by country name(full / part). $interface->GetCitiesByCountry( { CountryName => $some_value, # string - }, + },, ); - + =head1 AUTHOR -Generated by SOAP::WSDL on Tue Nov 6 21:00:30 2007 +Generated by SOAP::WSDL on Sun Dec 16 20:05:01 2007 =pod \ No newline at end of file diff --git a/example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm b/example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm index fc9e814..e2a6ffc 100644 --- a/example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm +++ b/example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm @@ -38,12 +38,8 @@ sub sayHello { }, $body, $header); } - - 1; - - __END__ =pod diff --git a/example/lib/MyTypemaps/BarCode.pm b/example/lib/MyTypemaps/BarCode.pm index eac7c8b..0765bea 100644 --- a/example/lib/MyTypemaps/BarCode.pm +++ b/example/lib/MyTypemaps/BarCode.pm @@ -10,13 +10,13 @@ our $typemap_1 = { 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', 'GenerateBarCode' => 'MyElements::GenerateBarCode', 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', - 'GenerateBarCode/BarCodeParam/Width' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', 'GenerateBarCode/BarCodeParam/Angle' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'GenerateBarCode/BarCodeParam/Width' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', 'GenerateBarCode/BarCodeParam/BarCodeImageFormat' => 'MyTypes::ImageFormats', 'GenerateBarCode/BarCodeParam/BGColor' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', 'GenerateBarCode/BarCodeParam/Ratio' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', - 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', 'GenerateBarCode/BarCodeParam/Height' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', 'GenerateBarCode/BarCodeParam/CheckSum' => 'SOAP::WSDL::XSD::Typelib::Builtin::boolean', 'GenerateBarCode/BarCodeParam/checkSumMethod' => 'MyTypes::CheckSumMethod', @@ -27,18 +27,22 @@ our $typemap_1 = { 'GenerateBarCodeResponse/GenerateBarCodeResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::base64Binary', 'GenerateBarCodeResponse' => 'MyElements::GenerateBarCodeResponse', 'GenerateBarCode/BarCodeParam/Module' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', - 'GenerateBarCode/BarCodeParam' => 'MyTypes::BarCodeData', 'GenerateBarCode/BarCodeParam/showTextPosition' => 'MyTypes::ShowTextPosition', + 'GenerateBarCode/BarCodeParam' => 'MyTypes::BarCodeData', 'GenerateBarCode/BarCodeParam/FontName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string' }; ; -sub get_class { +sub get_class { my $name = join '/', @{ $_[1] }; exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; return $typemap_1->{ $name }; } +sub get_typemap { + return $typemap_1; +} + 1; __END__ diff --git a/example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm b/example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm index 821a84b..5ac3313 100644 --- a/example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm +++ b/example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm @@ -13,7 +13,7 @@ our $typemap_1 = { 'GetFortuneCookieResponse' => 'MyElements::GetFortuneCookieResponse', 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', 'GetSpecificCookie' => 'MyElements::GetSpecificCookie', - 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', 'CountCookies' => 'MyElements::CountCookies', 'GetSpecificCookie/index' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', @@ -24,12 +24,16 @@ our $typemap_1 = { }; ; -sub get_class { +sub get_class { my $name = join '/', @{ $_[1] }; exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; return $typemap_1->{ $name }; } +sub get_typemap { + return $typemap_1; +} + 1; __END__ diff --git a/example/lib/MyTypemaps/GlobalWeather.pm b/example/lib/MyTypemaps/GlobalWeather.pm index 0958b34..1cc863e 100644 --- a/example/lib/MyTypemaps/GlobalWeather.pm +++ b/example/lib/MyTypemaps/GlobalWeather.pm @@ -6,7 +6,7 @@ our $typemap_1 = { 'GetWeatherResponse/GetWeatherResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', 'GetWeather' => 'MyElements::GetWeather', 'GetCitiesByCountryResponse/GetCitiesByCountryResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', - 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', 'GetWeatherResponse' => 'MyElements::GetWeatherResponse', 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', @@ -20,12 +20,16 @@ our $typemap_1 = { }; ; -sub get_class { +sub get_class { my $name = join '/', @{ $_[1] }; exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; return $typemap_1->{ $name }; } +sub get_typemap { + return $typemap_1; +} + 1; __END__ diff --git a/example/lib/MyTypes/BarCodeData.pm b/example/lib/MyTypes/BarCodeData.pm new file mode 100644 index 0000000..aa742a1 --- /dev/null +++ b/example/lib/MyTypes/BarCodeData.pm @@ -0,0 +1,164 @@ +package MyTypes::BarCodeData; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %Height_of :ATTR(:get); +my %Width_of :ATTR(:get); +my %Angle_of :ATTR(:get); +my %Ratio_of :ATTR(:get); +my %Module_of :ATTR(:get); +my %Left_of :ATTR(:get); +my %Top_of :ATTR(:get); +my %CheckSum_of :ATTR(:get); +my %FontName_of :ATTR(:get); +my %BarColor_of :ATTR(:get); +my %BGColor_of :ATTR(:get); +my %FontSize_of :ATTR(:get); +my %barcodeOption_of :ATTR(:get); +my %barcodeType_of :ATTR(:get); +my %checkSumMethod_of :ATTR(:get); +my %showTextPosition_of :ATTR(:get); +my %BarCodeImageFormat_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + Height + Width + Angle + Ratio + Module + Left + Top + CheckSum + FontName + BarColor + BGColor + FontSize + barcodeOption + barcodeType + checkSumMethod + showTextPosition + BarCodeImageFormat + ) ], + { + Height => \%Height_of, + Width => \%Width_of, + Angle => \%Angle_of, + Ratio => \%Ratio_of, + Module => \%Module_of, + Left => \%Left_of, + Top => \%Top_of, + CheckSum => \%CheckSum_of, + FontName => \%FontName_of, + BarColor => \%BarColor_of, + BGColor => \%BGColor_of, + FontSize => \%FontSize_of, + barcodeOption => \%barcodeOption_of, + barcodeType => \%barcodeType_of, + checkSumMethod => \%checkSumMethod_of, + showTextPosition => \%showTextPosition_of, + BarCodeImageFormat => \%BarCodeImageFormat_of, + }, + { + Height => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Width => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Angle => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Ratio => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Module => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Left => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Top => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + CheckSum => 'SOAP::WSDL::XSD::Typelib::Builtin::boolean', + FontName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + BarColor => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + BGColor => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + FontSize => 'SOAP::WSDL::XSD::Typelib::Builtin::float', + barcodeOption => 'MyTypes::BarcodeOption', + barcodeType => 'MyTypes::BarcodeType', + checkSumMethod => 'MyTypes::CheckSumMethod', + showTextPosition => 'MyTypes::ShowTextPosition', + BarCodeImageFormat => 'MyTypes::ImageFormats', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::BarCodeData + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +BarCodeData from the namespace http://www.webservicex.net/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + Height + Width + Angle + Ratio + Module + Left + Top + CheckSum + FontName + BarColor + BGColor + FontSize + barcodeOption + barcodeType + checkSumMethod + showTextPosition + BarCodeImageFormat + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::BarCodeData + Height => $some_value, # int + Width => $some_value, # int + Angle => $some_value, # int + Ratio => $some_value, # int + Module => $some_value, # int + Left => $some_value, # int + Top => $some_value, # int + CheckSum => $some_value, # boolean + FontName => $some_value, # string + BarColor => $some_value, # string + BGColor => $some_value, # string + FontSize => $some_value, # float + barcodeOption => $some_value, # BarcodeOption + barcodeType => $some_value, # BarcodeType + checkSumMethod => $some_value, # CheckSumMethod + showTextPosition => $some_value, # ShowTextPosition + BarCodeImageFormat => $some_value, # ImageFormats + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/BarcodeOption.pm b/example/lib/MyTypes/BarcodeOption.pm new file mode 100644 index 0000000..96c8aba --- /dev/null +++ b/example/lib/MyTypes/BarcodeOption.pm @@ -0,0 +1,56 @@ +package MyTypes::BarcodeOption; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::BarcodeOption + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +BarcodeOption from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/BarcodeType.pm b/example/lib/MyTypes/BarcodeType.pm new file mode 100644 index 0000000..b974c61 --- /dev/null +++ b/example/lib/MyTypes/BarcodeType.pm @@ -0,0 +1,56 @@ +package MyTypes::BarcodeType; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::BarcodeType + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +BarcodeType from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/CheckSumMethod.pm b/example/lib/MyTypes/CheckSumMethod.pm new file mode 100644 index 0000000..847228a --- /dev/null +++ b/example/lib/MyTypes/CheckSumMethod.pm @@ -0,0 +1,56 @@ +package MyTypes::CheckSumMethod; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::CheckSumMethod + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +CheckSumMethod from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/ImageFormats.pm b/example/lib/MyTypes/ImageFormats.pm new file mode 100644 index 0000000..337184b --- /dev/null +++ b/example/lib/MyTypes/ImageFormats.pm @@ -0,0 +1,56 @@ +package MyTypes::ImageFormats; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::ImageFormats + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +ImageFormats from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/ShowTextPosition.pm b/example/lib/MyTypes/ShowTextPosition.pm new file mode 100644 index 0000000..42a8a1a --- /dev/null +++ b/example/lib/MyTypes/ShowTextPosition.pm @@ -0,0 +1,56 @@ +package MyTypes::ShowTextPosition; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::ShowTextPosition + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +ShowTextPosition from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/lib/SOAP/WSDL.pm b/lib/SOAP/WSDL.pm index c70758f..23987d6 100644 --- a/lib/SOAP/WSDL.pm +++ b/lib/SOAP/WSDL.pm @@ -669,16 +669,16 @@ The following facets have no influence yet: =item * L -Full featured SOAP-library, little WSDL support. Supports rpc-encoded style only. Many protocols supported. +Full featured SOAP-library, little WSDL support. Supports rpc-encoded style +only. Many protocols supported. =item * L / L -A promising-looking approach derived from a cool functional DOM-based XML schema parser. +Creates parser/generator functions for SOAP messages. Includes SOAP Client +and Server implementatios. -Will support encoding/decoding of SOAP messages based on WSDL definitions. - -Not yet finished at the time of writing - but you may wish to give it a try, especially -if you need to adhere very closely to the XML Schema / WSDL specs. +You might want to give it a try, especially if you need to adhere very +closely to the XML Schema / WSDL specs. =back @@ -730,9 +730,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 427 $ + $Rev: 457 $ $LastChangedBy: kutterma $ - $Id: WSDL.pm 427 2007-12-02 22:20:24Z kutterma $ + $Id: WSDL.pm 457 2007-12-16 08:02:06Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $ =cut diff --git a/lib/SOAP/WSDL/Base.pm b/lib/SOAP/WSDL/Base.pm index 517892a..ff99ac1 100644 --- a/lib/SOAP/WSDL/Base.pm +++ b/lib/SOAP/WSDL/Base.pm @@ -5,7 +5,7 @@ use Class::Std::Fast::Storable; use List::Util qw(first); use Carp qw(croak carp confess); -our $VERSION='2.00_25'; +our $VERSION='2.00_27'; my %id_of :ATTR(:name :default<()>); my %name_of :ATTR(:name :default<()>); @@ -14,6 +14,11 @@ my %targetNamespace_of :ATTR(:name :default<()>); my %xmlns_of :ATTR(:name :default<{}>); my %parent_of :ATTR(:name :default<()>); +sub START { + my ($self, $ident, $arg_ref) = @_; + $xmlns_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' }; +} + sub DEMOLISH { my $self = shift; # delete upward references @@ -82,7 +87,7 @@ sub AUTOMETHOD { return $result_ref->[0]; }; } - confess "$subname not found in class " . (ref $self || $self) ; + confess "$subname not found in class " . ref $self; } sub init { @@ -95,11 +100,6 @@ sub init { $xmlns_of{ ident $self }->{ $value->{ LocalName } } = $value->{ Value }; next; } - elsif ($value->{ Name } =~m{^xmlns$}xms) { - # just ignore xmlns = for now - # TODO handle xmlns correctly - maybe via setting a prefix ? - next; - } my $name = $value->{ LocalName }; my $method = "set_$name"; @@ -110,16 +110,23 @@ sub init { sub expand { my ($self, , $qname) = @_; + my $ns_of = $self->get_xmlns(); + if (not $qname=~m{:}xm) { + die "un-prefixed element name <$qname> found, but no default namespace set\n" + if not defined $ns_of->{ '#default' }; + return $ns_of->{ '#default' }, $qname; + } + my ($prefix, $localname) = split /:/x, $qname; - # my %ns_map = reverse %{ $self->get_xmlns() }; - my %ns_map = %{ $self->get_xmlns() }; - return ($ns_map{ $prefix }, $localname) if ($ns_map{ $prefix }); + + + return ($ns_of->{ $prefix }, $localname) if ($ns_of->{ $prefix }); if (my $parent = $self->get_parent()) { return $parent->expand($qname); } confess "unbound prefix $prefix found for $prefix:$localname. Bound prefixes are" - . join(', ', keys %ns_map); + . join(', ', keys %{ $ns_of }); } sub _expand; *_expand = \&expand; diff --git a/lib/SOAP/WSDL/Client.pm b/lib/SOAP/WSDL/Client.pm index 6b5595f..f8a32b2 100644 --- a/lib/SOAP/WSDL/Client.pm +++ b/lib/SOAP/WSDL/Client.pm @@ -11,7 +11,7 @@ use SOAP::WSDL::Factory::Serializer; use SOAP::WSDL::Factory::Transport; use SOAP::WSDL::Expat::MessageParser; -our $VERSION = '2.00_25'; +our $VERSION = '2.00_27'; my %class_resolver_of :ATTR(:name :default<()>); my %no_dispatch_of :ATTR(:name :default<()>); @@ -268,17 +268,6 @@ Default: text/xml; charset: utf8 -=head3 set_trace - - $soap->set_trace(1); - $soap->set_trace( sub { Log::Log4perl::get_logger()->debug( @_ ) } ); - -When set to a true value, tracing (via warn) is enabled. - -When set to a code reference, this function will be called on every -trace call, making it really easy for you to set up log4perl logging -or whatever you need. - =head2 Features different from SOAP::Lite SOAP::WSDL does not aim to be a complete replacement for SOAP::Lite - the @@ -371,9 +360,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 427 $ + $Rev: 455 $ $LastChangedBy: kutterma $ - $Id: Client.pm 427 2007-12-02 22:20:24Z kutterma $ + $Id: Client.pm 455 2007-12-14 15:50:16Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $ =cut diff --git a/lib/SOAP/WSDL/Client/Base.pm b/lib/SOAP/WSDL/Client/Base.pm index c18a07b..777faab 100644 --- a/lib/SOAP/WSDL/Client/Base.pm +++ b/lib/SOAP/WSDL/Client/Base.pm @@ -10,9 +10,16 @@ sub call { my ($self, $method, $body, $header) = @_; if (not blessed $body) { $body = {} if not defined $body; - my $class = $method->{ body }->{ parts }->[0]; - eval "require $class" || die $@; - $body = $class->new($body); + $body = ref $body eq 'ARRAY' ? $body : [ $body ]; + my $index = 0; + my @part_from; + foreach my $part (@{ $body }) { + my $class = $method->{ body }->{ parts }->[$index]; + eval "require $class" || die $@; + push @part_from, $class->new($part); + $index++; + } + $body = $#part_from ? \@part_from : $part_from[0]; } # if we have a header @@ -94,9 +101,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 427 $ + $Rev: 440 $ $LastChangedBy: kutterma $ - $Id: Base.pm 427 2007-12-02 22:20:24Z kutterma $ + $Id: Base.pm 440 2007-12-04 22:24:33Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client/Base.pm $ =cut diff --git a/lib/SOAP/WSDL/Expat/MessageParser.pm b/lib/SOAP/WSDL/Expat/MessageParser.pm index 3b8852a..d7ca217 100644 --- a/lib/SOAP/WSDL/Expat/MessageParser.pm +++ b/lib/SOAP/WSDL/Expat/MessageParser.pm @@ -48,7 +48,7 @@ sub load_classes { # a bad test - do you know a better one? next if $class eq '__SKIP__'; - next if defined @{ "$class\::ISA"}; # check if namespace exists + next if defined *{ "$class\::" }; # check if namespace exists $class =~s{ :: }{/}xmsg; $class .= '.pm'; @@ -289,8 +289,8 @@ This module may be used under the same terms as perl itself. $ID: $ - $LastChangedDate: 2007-12-02 23:20:24 +0100 (So, 02 Dez 2007) $ - $LastChangedRevision: 427 $ + $LastChangedDate: 2007-12-07 21:04:06 +0100 (Fr, 07 Dez 2007) $ + $LastChangedRevision: 444 $ $LastChangedBy: kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $ diff --git a/lib/SOAP/WSDL/Expat/WSDLParser.pm b/lib/SOAP/WSDL/Expat/WSDLParser.pm index 5e45ae8..0555fe5 100644 --- a/lib/SOAP/WSDL/Expat/WSDLParser.pm +++ b/lib/SOAP/WSDL/Expat/WSDLParser.pm @@ -5,7 +5,7 @@ use Carp; use SOAP::WSDL::TypeLookup; use base qw(SOAP::WSDL::Expat::Base); -our $VERSION = q{2.00_25}; +our $VERSION = q{2.00_27}; sub _initialize { my ($self, $parser) = @_; @@ -36,7 +36,9 @@ sub _initialize { eval "require $action->{ class }"; croak $@ if ($@); - my $obj = $action->{ class }->new({ parent => $current }) + my $obj = $action->{ class }->new({ parent => $current, + xmlns => { '#default' => $parser->namespace($localname) } + }) ->init( _fixup_attrs( $parser, %attrs ) ); if ($current) { diff --git a/lib/SOAP/WSDL/Factory/Transport.pm b/lib/SOAP/WSDL/Factory/Transport.pm index b427509..b13a3fa 100644 --- a/lib/SOAP/WSDL/Factory/Transport.pm +++ b/lib/SOAP/WSDL/Factory/Transport.pm @@ -38,7 +38,7 @@ sub get_transport { if ($registered_transport_of{ $scheme }) { no strict qw(refs); - *{ $registered_transport_of{ $scheme } . '::' }{ CODE } + defined %{ "$registered_transport_of{ $scheme }::" } or eval "require $registered_transport_of{ $scheme }" or die "Cannot load transport class $registered_transport_of{ $scheme } : $@"; @@ -71,7 +71,7 @@ sub get_transport { if (exists $SOAP_WSDL_TRANSPORT_OF{ $scheme }) { no strict qw(refs); - *{ $SOAP_WSDL_TRANSPORT_OF{ $scheme } . '::' }{ CODE } + defined %{ "$SOAP_WSDL_TRANSPORT_OF{ $scheme }::" } or eval "require $SOAP_WSDL_TRANSPORT_OF{ $scheme }" or die "Cannot load transport class $SOAP_WSDL_TRANSPORT_OF{ $scheme } : $@"; return $SOAP_WSDL_TRANSPORT_OF{ $scheme }->new( %attrs ); @@ -240,9 +240,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 435 $ + $Rev: 459 $ $LastChangedBy: kutterma $ - $Id: Transport.pm 435 2007-12-03 22:31:00Z kutterma $ + $Id: Transport.pm 459 2007-12-16 16:00:14Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Transport.pm $ =cut diff --git a/lib/SOAP/WSDL/Generator/Template/XSD.pm b/lib/SOAP/WSDL/Generator/Template/XSD.pm index d447651..be8163d 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD.pm +++ b/lib/SOAP/WSDL/Generator/Template/XSD.pm @@ -55,9 +55,11 @@ sub generate { } sub generate_typelib { - my ($self) = @_; + my ($self, $arg_ref) = @_; # $output_of{ ident $self } = ""; - my @schema = @{ $self->get_definitions()->first_types()->get_schema() }; + my @schema = exists $arg_ref->{ schema } + ? @{ $arg_ref->{schema} } + : @{ $self->get_definitions()->first_types()->get_schema() }; for my $type (map { @{ $_->get_type() } , @{ $_->get_element() } } @schema[1..$#schema] ) { $type->_accept( $self ); } @@ -164,6 +166,7 @@ sub _generate_filename :PRIVATE { my ($self, @parts) = @_; my $name = join '::', @parts; $name =~s{ \. }{::}xmsg; + $name =~s{ \- }{_}xmsg; $name =~s{ :: }{/}xmsg; return "$name.pm"; } diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt index e2ccb06..4cb5b42 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt @@ -1,4 +1,4 @@ -package [% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('^.+\.','') %]; +package [% interface_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]::[% port.get_name.replace('^.+\.','').replace('-', '_') %]; use strict; use warnings; use Class::Std::Fast::Storable; @@ -6,12 +6,12 @@ use Scalar::Util qw(blessed); use base qw(SOAP::WSDL::Client::Base); # only load if it hasn't been loaded before -require [% typemap_prefix %]::[% service.get_name.replace('\.', '::') %] - if not [% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]->can('get_class'); +require [% typemap_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %] + if not [% typemap_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]->can('get_class'); sub START { $_[0]->set_proxy('[% port.first_address.get_location %]') if not $_[2]->{proxy}; - $_[0]->set_class_resolver('[% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]') + $_[0]->set_class_resolver('[% typemap_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]') if not $_[2]->{class_resolver}; } @@ -34,12 +34,12 @@ __END__ =head1 NAME -[% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('\.', '::') %] - SOAP Interface for the [% service.get_name %] Web Service +[% interface_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]::[% port.get_name.replace('\.', '::').replace('-', '_') %] - SOAP Interface for the [% service.get_name %] Web Service =head1 SYNOPSIS - use [% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('\.', '::') %]; - my $interface = [% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('\.', '::') %]->new(); + use [% interface_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]::[% port.get_name.replace('\.', '::').replace('-', '_') %]; + my $interface = [% interface_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]::[% port.get_name.replace('\.', '::').replace('-', '_') %]->new(); my $response; [% FOREACH operation = binding.get_operation; diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt index 70f7bf6..2ce2ce2 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt @@ -55,6 +55,11 @@ : die "input must have either type or element"; } @{ $part_from }; } + + warn "Multiple parts detected in message " . $stash->{ message }->get_name() . ".\n", + "WS-I BP demands 0 to 1 parts in message body\n" + if (@parts > 1); + $stash->{ parts } = \@parts; [% END %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt index 8595d1f..9f93a68 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt @@ -22,7 +22,7 @@ __END__ =head1 NAME -[% typemap_prefix %]::[% service.get_name.replace('\.','::') %]; - typemap for ::[% service.get_name %]; +[% typemap_prefix %]::[% service.get_name.replace('\.','::').replace('-', '_') %]; - typemap for ::[% service.get_name %]; =head1 DESCRIPTION diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt index c4074d8..af224c7 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt @@ -1,4 +1,4 @@ -package [% type_prefix %]::[% complexType.get_name %]; +package [% type_prefix %]::[% complexType.get_name.replace('\.','::').replace('-','_') %]; use strict; use warnings; [% INCLUDE complexType/contentModel.tt %] @@ -12,7 +12,7 @@ use warnings; =head1 NAME -[% type_prefix %]::[% complexType.get_name %] +[% type_prefix %]::[% complexType.get_name.replace('\.','::').replace('-','_') %] =head1 DESCRIPTION diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt index 4067616..5ed7cb3 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt @@ -1,6 +1,6 @@ [% -base_name=complexType.expand( complexType.get_base); +base_name=complexType.expand( complexType.get_base ); base_type = definitions.first_types.find_type( base_name ); element_from = complexType.get_element; @@ -9,14 +9,15 @@ element_from = complexType.get_element; # Sanity check: All original elements must be noted first # element_list = base_type.get_element; -FOREACH element = base_type.get_element; - IF element_from.${ loop.index }.get_name != element.get_name; -# element_list.push( element ); - THROW WSDL "${element.get_name} not found at position ${ loop.index } in extension type ${ complexType.get_name }"; + +FOREACH element = element_from; + IF element_list.${ loop.index }.get_name != element.get_name; + element_list.push( element ); +# THROW WSDL "${element.get_name} not found at position ${ loop.index } in extension type ${ complexType.get_name }"; END; END; -#complexType.set_element( element_list ); +complexType.set_element( element_list ); -%] use base qw([% type_prefix %]::[% base_name.1.replace('\.', '::') %]); diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/element.tt b/lib/SOAP/WSDL/Generator/Template/XSD/element.tt index 9d5282b..d19bb11 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/element.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/element.tt @@ -1,4 +1,4 @@ -package [% element_prefix %]::[% element.get_name %]; +package [% element_prefix %]::[% element.get_name.replace('\.','::') %]; use strict; use warnings; diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt index 09ef52c..215c8e4 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt @@ -1,4 +1,4 @@ -package [% type_prefix %]::[% simpleType.get_name %]; +package [% type_prefix %]::[% simpleType.get_name.replace('\.','::').replace('-','_') %]; use strict; use warnings; @@ -13,7 +13,7 @@ sub get_xmlns { '[% simpleType.get_targetNamespace %]'}; =pod -=head1 [% type_prefix %]::[% simpleType.get_name %] +=head1 [% type_prefix %]::[% simpleType.get_name.replace('\.','::').replace('-','_') %] =head1 DESCRIPTION diff --git a/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm b/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm index b046bc3..657716e 100644 --- a/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm +++ b/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm @@ -211,6 +211,8 @@ sub visit_XSD_Element { # for atomic and complex types , and ref elements my $typeclass = join q{::}, $element_prefix_of{$ident}, $element->get_name(); + $typeclass =~s{\.}{::}g; + $typeclass =~s{\-}{_}g; $self->set_typemap_entry($typeclass); $self->process_atomic_type( $element->first_complexType() @@ -225,6 +227,8 @@ sub visit_XSD_Element { if (not defined($parent)) { # for atomic and complex types , and ref elements my $typeclass = join q{::}, $element_prefix_of{$ident}, $element->get_name(); + $typeclass =~s{\.}{::}g; + $typeclass =~s{\-}{_}g; $self->set_typemap_entry($typeclass); } diff --git a/lib/SOAP/WSDL/Manual.pod b/lib/SOAP/WSDL/Manual.pod index 7825e9b..e396d19 100644 --- a/lib/SOAP/WSDL/Manual.pod +++ b/lib/SOAP/WSDL/Manual.pod @@ -12,7 +12,7 @@ SOAP::WSDL::Manual - Accessing WSDL based web services =item * Create WSDL bindings - perl wsdl2perl.pl -b base_dir URL + perl wsdl2perl.pl -b base_dir URL =item * Look what has been generated @@ -37,7 +37,7 @@ The results of all calls to your service object's methods (except new) are objects based on SOAP::WSDL's XML schema implementation. To access the object's properties use get_NAME / set_NAME getter/setter -methods whith NAME corresponding to the XML tag name / the hash structure as +methods with NAME corresponding to the XML tag name / the hash structure as showed in the generated pod. =item * Run script @@ -91,7 +91,7 @@ and you may even want to add custom typemap elements. There should be a bunch of classes for types (in the MyTypes:: namespace by default), elements (in MyElements::), and at least one typemap (in -MyTypemaps::) and one ore more interface classes (in MyInterfaces::). +MyTypemaps::) and one or more interface classes (in MyInterfaces::). If you don't already know the details of the web service you're going to instrument, it's now time to read the perldoc of the generated interface @@ -111,7 +111,7 @@ included perldoc will be, too - if not, blame the web service author. print $result; The above handling of errors ("die $result if not $result") may look a bit -strange - it is due to the nature of +strange - it is due to the nature of the L objects SOAP::WSDL uses for signalling failure. @@ -144,12 +144,12 @@ generated classes - while generated classes may be many, you probably will only implement a few by hand. These (precious) few classes may get lost in the mass of (cheap) generated ones. Just imagine one of your co-workers (or even yourself) deleting the whole bunch and re-generating everything - oops -- almost everything. You got the point. +- almost everything. You get the point. For simplicity, you probably just want to use builtin types wherever possible - you are probably not interested in whether a fault detail's error code is presented to you as a simpleType ranging from 1 to 10 (which you have to -write) or as a int (which is a builtin type ready to use). +write) or as an int (which is a builtin type ready to use). Using builtin types for simpleType definitions may greatly reduce the number of additional classes you need to implement. @@ -230,6 +230,17 @@ L will tell you how to create a typemap class. =back +=head1 Creating a SOAP Server + +Creating a SOAP server works just like creating a client - just add the +C<--server> or C<-s> option to the call to C. + + perl wsdl2perl.pl -s -b BASE_DIR URL + +Note that SOAP::WSDL only includes a basic CGI based SOAP servers by now - +while more advanced servers (like standalone or mod_perl based) are no big +deal, no base implementation is included yet. + =head1 Troubleshooting =head2 Accessing HTTPS webservices diff --git a/lib/SOAP/WSDL/Serializer/XSD.pm b/lib/SOAP/WSDL/Serializer/XSD.pm index 7d09651..a6b4457 100644 --- a/lib/SOAP/WSDL/Serializer/XSD.pm +++ b/lib/SOAP/WSDL/Serializer/XSD.pm @@ -3,7 +3,7 @@ package SOAP::WSDL::Serializer::XSD; use strict; use warnings; use Class::Std::Fast::Storable; - +use Scalar::Util qw(blessed); our $VERSION=q{2.00_25}; my $SOAP_NS = 'http://schemas.xmlsoap.org/soap/envelope/'; @@ -49,7 +49,7 @@ sub serialize_header { return q{} if not $data; return join ( q{}, "<$opt->{ namespace }->{ $SOAP_NS }\:Header>", - "$data", + blessed $data ? $data->serialize_qualified : (), "{ namespace }->{ $SOAP_NS }\:Header>", ); } @@ -61,7 +61,13 @@ sub serialize_body { # if we have no data. return join ( q{}, "<$opt->{ namespace }->{ $SOAP_NS }\:Body>", - defined $data ? "$data" : (), + defined $data + ? ref $data eq 'ARRAY' + ? join q{}, map { blessed $_ ? $_->serialize_qualified() : () } @{ $data } + : blessed $data + ? $data->serialize_qualified + : () + : (), "{ namespace }->{ $SOAP_NS }\:Body>", ); } @@ -113,9 +119,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 427 $ + $Rev: 444 $ $LastChangedBy: kutterma $ - $Id: XSD.pm 427 2007-12-02 22:20:24Z kutterma $ + $Id: XSD.pm 444 2007-12-07 20:04:06Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Serializer/XSD.pm $ =cut diff --git a/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm b/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm index 77aee4e..1a862c3 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm @@ -7,9 +7,12 @@ sub get_xmlns { 'http://www.w3.org/2001/XMLSchema' }; # use $_[1] for performance sub start_tag { - my $opt = $_[1] ||= {}; - return '<' . $opt->{name} . ' >' if $opt->{ name }; - return q{} + return q{} if not $#_; # return if no second argument ($opt) + if ($_[1]->{ name }) { + return "<$_[1]->{name} />" if $_[1]->{ empty }; + return "<$_[1]->{name} >"; + } + return q{}; } # use $_[1] for performance diff --git a/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm b/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm index dfabfe6..9d739f1 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm @@ -39,6 +39,34 @@ sub AUTOMETHOD { . "\n" } +sub as_hash_ref { + my $self = shift; + my $attributes_ref = $ATTRIBUTES_OF{ ref $self }; + my $ident = ident $self; + + my $hash_of_ref = {}; + foreach my $attribute (keys %{ $attributes_ref }) { + next if not defined $attributes_ref->{ $attribute }->{ $ident }; + my $value = $attributes_ref->{ $attribute }->{ $ident }; + + $hash_of_ref->{ $attribute } = blessed $value + ? $value->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') + ? $value + : $value->as_hash_ref() + : ref $value eq 'ARRAY' + ? [ + map { + $_->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') + ? $_ + : $_->as_hash_ref() + } @{ $value } + ] + : die "Neither blessed obj nor list ref"; + }; + + return $hash_of_ref; +} + # we store per-class elements. # call as __PACKAGE__->_factory sub _factory { @@ -352,6 +380,10 @@ This means you may set element properties by passing Examples are similar to the examples provided for new() above. +=head2 as_hash_ref + +Returns a hash ref representation of the complexType object + =head1 Bugs and limitations =over @@ -391,9 +423,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 412 $ + $Rev: 452 $ $LastChangedBy: kutterma $ - $Id: ComplexType.pm 412 2007-11-27 22:57:52Z kutterma $ + $Id: ComplexType.pm 452 2007-12-12 14:46:54Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm $ =cut diff --git a/t/SOAP/WSDL/Generator/XSD.t b/t/SOAP/WSDL/Generator/XSD.t index 9761ce8..ca9b740 100644 --- a/t/SOAP/WSDL/Generator/XSD.t +++ b/t/SOAP/WSDL/Generator/XSD.t @@ -1,4 +1,4 @@ -use Test::More tests => 37; +use Test::More tests => 38; use File::Basename qw(dirname); use File::Spec; use File::Path; @@ -11,6 +11,7 @@ use_ok qw(SOAP::WSDL::Generator::Template::XSD); use SOAP::WSDL::Expat::WSDLParser; my $parser = SOAP::WSDL::Expat::WSDLParser->new(); + my $definitions = $parser->parse_file( "$path/../../../acceptance/wsdl/generator_test.wsdl" #"$path/../../../acceptance/wsdl/elementAtomicComplexType.xml" @@ -34,6 +35,7 @@ $generator->generate_typelib(); } # print $code; + $generator->set_type_prefix('MyTypes'); $generator->set_element_prefix('MyElements'); $generator->set_typemap_prefix('MyTypemaps'); @@ -43,7 +45,15 @@ $generator->set_output(undef); $generator->generate(); #$generator->generate_typelib(); #$generator->generate_typemap(); -$generator->generate_interface(); + +if (eval { require Test::Warn; }) { + Test::Warn::warning_like( sub { $generator->generate_interface() }, + qr{\A Multiple \s parts \s detected \s in \s message \s testMultiPartWarning}xms); +} +else { + $generator->generate_interface(); + SKIP: { skip 'Cannot test warnings without Test::Warn', 1 }; +} $generator->generate_server(); diff --git a/t/SOAP/WSDL/Part.t b/t/SOAP/WSDL/Part.t new file mode 100644 index 0000000..1304a28 --- /dev/null +++ b/t/SOAP/WSDL/Part.t @@ -0,0 +1,44 @@ +package MyTypelib; +use strict; +use warnings; + + +sub find_element {}; +sub find_type {}; + +package main; + +use strict; +use warnings; +use Test::More tests => 5; + +use_ok qw(SOAP::WSDL::Part); + +my $typelib = {}; + +eval { SOAP::WSDL::Part->serialize() }; +like $@, qr{No typelib}; + +my $opt = { + typelib => 'MyTypelib', + namespace => { foo => 'bar'} +}; + +my $data = {}; + +my $part = SOAP::WSDL::Part->new(); + +eval { $part->serialize('name', $data, $opt ) }; +like $@, qr{Neither type nor element}; + +$part->set_type('foo:Foo'); + +eval { $part->serialize('name', $data, $opt ) }; +like $@, qr{type foo:Foo}; + +$part->set_type(undef); + +$part->set_element('foo:Foo'); + +eval { $part->serialize('name', $data, $opt ) }; +like $@, qr{element foo:Foo}; diff --git a/t/SOAP/WSDL/Serializer/XSD.t b/t/SOAP/WSDL/Serializer/XSD.t new file mode 100644 index 0000000..ecbc56f --- /dev/null +++ b/t/SOAP/WSDL/Serializer/XSD.t @@ -0,0 +1,13 @@ +use strict; +use warnings; +use Test::More qw(no_plan); + +use_ok qw(SOAP::WSDL::Serializer::XSD); + +my $serializer = SOAP::WSDL::Serializer::XSD->new(); + +like $serializer->serialize(), qr{}, 'empty body'; +like $serializer->serialize({ body => {} }), qr{}, 'empty body'; +like $serializer->serialize({ body => [] }), qr{}, 'empty body'; +like $serializer->serialize({ header => {}, body => [] }), + qr{}, 'empty header and body'; \ No newline at end of file diff --git a/t/SOAP/WSDL/Server/CGI.t b/t/SOAP/WSDL/Server/CGI.t index 5f7eddd..326b5c8 100644 --- a/t/SOAP/WSDL/Server/CGI.t +++ b/t/SOAP/WSDL/Server/CGI.t @@ -7,7 +7,11 @@ sub bar { return "Verdammte Axt"; } package main; -use Test::More tests => 4; +use Test::More; +eval "require IO::Scalar" + or plan skip_all => 'IO::Scalar required for testing...'; + +plan tests => 8; use_ok(SOAP::WSDL::Server); use_ok(SOAP::WSDL::Server::CGI); @@ -19,8 +23,6 @@ $server->set_action_map_ref({ 'testaction' => 'testmethod', }); -eval "require IO::Scalar" - or exit 0; { no warnings qw(once); *IO::Scalar::BINMODE = sub {}; @@ -48,17 +50,31 @@ $server->set_action_map_ref({ $server->set_dispatch_to( 'HandlerClass' ); $server->handle(); +like $output, qr{no \s element \s found}xms; +$output = q{}; -print "\n"; - -$ENV{HTTP_SOAPAction} = 'test'; +$ENV{REQUEST_METHOD} = 'POST'; +$ENV{HTTP_SOAPACTION} = 'test'; $server->handle(); +like $output, qr{no \s element \s found}xms; +$output = q{}; -print "\n"; +delete $ENV{HTTP_SOAPACTION}; +$ENV{EXPECT} = 'Foo'; $ENV{HTTP_SOAPAction} = 'foo'; $server->handle(); +like $output, qr{no \s element \s found}xms; +$output = q{}; + +$ENV{EXPECT} = '100-Continue'; +$ENV{HTTP_SOAPAction} = 'foo'; +$server->handle(); +like $output, qr{100 \s Continue}xms; +$output = q{}; + + *STDOUT = $stdout; # print $output; \ No newline at end of file diff --git a/t/SOAP/WSDL/XSD/ComplexType.t b/t/SOAP/WSDL/XSD/ComplexType.t new file mode 100644 index 0000000..4a1e84f --- /dev/null +++ b/t/SOAP/WSDL/XSD/ComplexType.t @@ -0,0 +1,11 @@ +use strict; +use warnings; +use Test::More tests => 2; #qw(no_plan); + +use_ok qw(SOAP::WSDL::XSD::ComplexType); + +my $obj = SOAP::WSDL::XSD::ComplexType->new(); +$obj->set_flavor('extension'); + +eval { $obj->serialize('foo') }; +like $@, qr{sorry, \s we \s just}xsm; \ No newline at end of file diff --git a/t/SOAP/WSDL/XSD/Element.t b/t/SOAP/WSDL/XSD/Element.t new file mode 100644 index 0000000..a8837a6 --- /dev/null +++ b/t/SOAP/WSDL/XSD/Element.t @@ -0,0 +1,43 @@ +package Foo; +sub serialize { + return "serialized $_[1] $_[2]"; +} +package main; +use strict; +use warnings; +use Test::More tests => 12; + +use_ok qw(SOAP::WSDL::XSD::Element); + +my $element = SOAP::WSDL::XSD::Element->new(); + +is $element->first_simpleType(), undef; + +$element->set_simpleType('Foo'); +is $element->first_simpleType(), 'Foo'; + +$element->set_simpleType( [ 'Foo', 'Bar' ]); +is $element->first_simpleType(), 'Foo'; + +is $element->first_complexType(), undef; + +$element->set_complexType('Foo'); +is $element->first_complexType(), 'Foo'; + +$element->set_complexType( [ 'Foo', 'Bar' ]); +is $element->first_complexType(), 'Foo'; + +$element->set_default('Foo'); +is $element->serialize('Foobar', undef, { namespace => {} } ), 'serialized Foobar Foo'; + +$element->set_name('Bar'); +is $element->serialize(undef, undef, { namespace => {} } ), 'serialized Bar Foo'; + +$element->set_fixed('Foobar'); +is $element->serialize(undef, undef, { namespace => {} } ), 'serialized Bar Foobar'; + +$element->set_abstract('1'); +is $element->serialize('Bar', undef, { namespace => {} } ), 'serialized Bar Foobar'; + +eval { $element->serialize(undef, undef, { namespace => {} } ) }; +like $@, qr{cannot \s serialize \s abstract}xms; \ No newline at end of file diff --git a/t/SOAP/WSDL/XSD/SimpleType.t b/t/SOAP/WSDL/XSD/SimpleType.t new file mode 100644 index 0000000..d318b94 --- /dev/null +++ b/t/SOAP/WSDL/XSD/SimpleType.t @@ -0,0 +1,33 @@ +use strict; +use warnings; +use Test::More tests => 11; + +use_ok qw(SOAP::WSDL::XSD::SimpleType); + +my $obj = SOAP::WSDL::XSD::SimpleType->new(); + +$obj->set_list({ LocalName => 'foo', Value => 'bar'}, + { LocalName => 'itemType', Value => 'xsd:int'} ); +is $obj->get_flavor(), 'list'; +is $obj->get_itemType(), 'xsd:int'; + +is $obj->serialize('Foo', ['Foo', 'Bar']), 'Foo Bar'; + +$obj->set_union({ LocalName => 'foo', Value => 'bar'}, + { LocalName => 'memberTypes', Value => 'xsd:int'} ); +is $obj->get_flavor(), 'union'; +is $obj->get_base()->[0], 'xsd:int'; + +$obj->set_union({ LocalName => 'foo', Value => 'bar'}, + { LocalName => 'memberTypes', Value => 'xsd:int xsd:string'} ); +is $obj->get_flavor(), 'union'; +is $obj->get_base()->[1], 'xsd:string'; + +is $obj->serialize('Foo', 'Foobar'), 'Foobar'; + +$obj->set_flavor('enumeration'); +is $obj->serialize('Foo', 'Foobar'), 'Foobar'; + +# TODO die on non-serializable content... +$obj->set_flavor(''); +is $obj->serialize('Foo', 'Foobar'), ''; \ No newline at end of file diff --git a/t/SOAP/WSDL/XSD/Typelib/ComplexType.t b/t/SOAP/WSDL/XSD/Typelib/ComplexType.t index ca618de..e72a8c9 100644 --- a/t/SOAP/WSDL/XSD/Typelib/ComplexType.t +++ b/t/SOAP/WSDL/XSD/Typelib/ComplexType.t @@ -1,6 +1,14 @@ use strict; use warnings; +package MyEmptyType; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +__PACKAGE__->_factory([],{},{}); + +package MyEmptyType2; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); +__PACKAGE__->_factory(); + package MyType; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); @@ -34,15 +42,34 @@ __PACKAGE__->_factory( ); package main; -use Test::More tests => 89; -use Data::Dumper; +use Test::More tests => 100; use Storable; + +my $have_warn = eval { use Test::Warn; 1; }; + my $obj; +$obj = MyEmptyType->new(); +is $obj->serialize, ''; +is $obj->serialize({ name => 'test'}), ''; + +$obj = MyEmptyType2->new(); +is $obj->serialize, ''; +is $obj->serialize({ name => 'test'}), ''; + + $obj = MyType->new({}); isa_ok $obj, 'MyType'; is $obj->get_test, undef, 'undefined element content'; +my $hash_of_ref = $obj->as_hash_ref(); +is scalar keys %{ $hash_of_ref }, 0; + +SKIP: { + skip 'Cannot test warnings without Test::Warn', 1 if not $have_warn; + warning_is { $obj->add_test() } 'attempting to add empty value to MyType'; +} + $obj = MyType->new({ test => 'Test1'}); isa_ok $obj, 'MyType'; isa_ok $obj->get_test, 'SOAP::WSDL::XSD::Typelib::Builtin::string'; @@ -64,6 +91,9 @@ isa_ok $obj, 'MyType'; isa_ok $obj->get_test, 'SOAP::WSDL::XSD::Typelib::Builtin::string'; is $obj->get_test, 'Test2', 'element content'; +$hash_of_ref = $obj->as_hash_ref(); +is $hash_of_ref->{ test }, 'Test2'; + $obj = MyType->new({ test => [ SOAP::WSDL::XSD::Typelib::Builtin::string->new({ @@ -80,6 +110,10 @@ isa_ok $obj->get_test, 'ARRAY'; is $obj->get_test()->[0], 'Test', 'element content (list content [0])'; is $obj->get_test()->[1], 'Test2', 'element content (list content [1])'; +$hash_of_ref = $obj->as_hash_ref(); +is $hash_of_ref->{ test }->[0], 'Test'; +is $hash_of_ref->{ test }->[1], 'Test2'; + my $nested = MyType2->new({ test => $obj, }); @@ -106,6 +140,10 @@ $nested = MyType2->new({ }); +$hash_of_ref = $nested->as_hash_ref(); +is $hash_of_ref->{ test }->{ test }->[1], 'Test2'; + + # isnt $nested->get_test->[0], $obj, 'element identity'; $obj = MyType->new(); @@ -203,6 +241,14 @@ eval { like $@, qr{cannot \s use \s CODE}xms; +eval { + $obj = MyType->new({ + foobar => 'fubar' + }); +}; +like $@, qr{unknown \s field \s foobar \s in \s MyType }xms; + + eval { $obj->set_FOO(42) }; like $@, qr{Can't \s locate \s object \s method}x; diff --git a/t/acceptance/wsdl/generator_test.wsdl b/t/acceptance/wsdl/generator_test.wsdl index 1ee660e..6a08fa5 100644 --- a/t/acceptance/wsdl/generator_test.wsdl +++ b/t/acceptance/wsdl/generator_test.wsdl @@ -161,7 +161,7 @@ (Inclusive constraints) - + @@ -204,6 +204,10 @@ + + + + @@ -233,6 +237,14 @@ + + + Test-Methode + + + + + @@ -257,15 +269,25 @@ - + - - - - - + + + + + + + + + + + + + + +