diff --git a/Build.PL b/Build.PL index 76bdf82..c1b82ee 100644 --- a/Build.PL +++ b/Build.PL @@ -5,7 +5,7 @@ $build = Module::Build->new( create_makefile_pl => 'small', dist_abstract => 'SOAP with WSDL support', dist_name => 'SOAP-WSDL', - dist_version => '2.00.04', + dist_version => '2.00.05', module_name => 'SOAP::WSDL', license => 'artistic', requires => { diff --git a/Changes b/Changes index 985e2ff..fa25727 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,4 @@ -Release notes for SOAP::WSDL 2.00.04 +Release notes for SOAP::WSDL 2.00.05 ------- I'm proud to present a new release of SOAP::WSDL. @@ -36,6 +36,26 @@ Features: The following changes have been made: +2.00.05 + +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/). + + * [ 2014482 ] Big-O memory hole when parsing WSDL + SOAP::WSDL still leaks memory when using SOAP::Lite's transport backend + This is to be fixed in 0.710.08 in SOAP::Lite + * #36865 wsdl2perl.pl fails on Expat error + Resolved by dropping a note for Solaris in README + * [ 2005693 ] causes error + The >fixed< attribute is now recognized (but has no effect yet) + +The following uncategorized improvements have been made: + + * added missing Class::Std::Storable::Fast import flags to + SOAP::WSDL::XSD::Typelib::Builtin::IDREFS + * some code cleanup + 2.00.04 The following bugs have been fixed (the numbers in square brackets are the @@ -77,6 +97,7 @@ 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/). + * [ 1963613 ] ComplexTypes die on ->can('FOOBAR'); * [ 1943667 ] Error parsing complexType/extension * [ 1960650 ] multi-level inheritance of complexTypes fails * [ 1960319 ] ComplexType as_hash_ref returns objects on maximum depth diff --git a/MANIFEST b/MANIFEST index b27b64d..6a862ff 100644 --- a/MANIFEST +++ b/MANIFEST @@ -13,6 +13,8 @@ benchmark/XSD/strftime.pl bin/wsdl2perl.pl Build.PL Changes +covered_by.pl +covering.pl example/cgi-bin/helloworld.pl example/cgi-bin/person.pl example/fortune.pl @@ -20,6 +22,9 @@ example/genericbarcode.pl example/hello.pl example/hello_compile.pl example/hello_lite.pl +example/leaktest/hello_wsdl.pl +example/leaktest/leak.pl +example/leaktest/parse.pl example/lib/MyElements/CountCookies.pm example/lib/MyElements/CountCookiesResponse.pm example/lib/MyElements/GenerateBarCode.pm @@ -270,8 +275,6 @@ MANIFEST This list of files META.yml MIGRATING README -SOAP-WSDL-2.00.01.ppd -SOAP-WSDL-2.00.01.zip t/002_parse_wsdl.t t/003_wsdl_based_serializer.t t/006_client.t @@ -281,6 +284,7 @@ t/011_simpleType.t t/012_element.t t/013_complexType.t t/016_client_object.t +t/094_cpan_meta.t t/095_copying.t t/096_characters.t t/097_kwalitee.t @@ -332,9 +336,6 @@ t/acceptance/wsdl/WSDLParser/imported.xsd t/acceptance/wsdl/WSDLParser/xsd_import_no_location.wsdl t/acceptance/wsdl/WSDLParser_import_loop.wsdl t/contributed.wsdl -t/covered-by.txt -t/covered.txt -t/covered/covered-0.01.db t/lib/Mod_Perl2Test.pm t/lib/MyComplexType.pm t/lib/MyElement.pm @@ -364,6 +365,7 @@ t/SOAP/WSDL/05_simpleType-union.t t/SOAP/WSDL/06_keep_alive.t t/SOAP/WSDL/11_helloworld.NET.t t/SOAP/WSDL/12_binding.t +t/SOAP/WSDL/Base.t t/SOAP/WSDL/Client.t t/SOAP/WSDL/Client/Base.t t/SOAP/WSDL/Definitions.t @@ -461,4 +463,5 @@ t/SOAP/WSDL_NO_MESSAGE.wsdl t/SOAP/WSDL_NO_PORTTYPE.wsdl t/test.wsdl TEST_COVERAGE +test_html.pl TODO diff --git a/META.yml b/META.yml index 4bb94e8..523a406 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- name: SOAP-WSDL -version: 2.00.04 +version: 2.00.05 author: - 'Martin Kutter ' abstract: SOAP with WSDL support @@ -41,220 +41,220 @@ build_requires: provides: SOAP::WSDL: file: lib/SOAP/WSDL.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Base: file: lib/SOAP/WSDL/Base.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Binding: file: lib/SOAP/WSDL/Binding.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Client: file: lib/SOAP/WSDL/Client.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Client::Base: file: lib/SOAP/WSDL/Client/Base.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Definitions: file: lib/SOAP/WSDL/Definitions.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Deserializer::Hash: file: lib/SOAP/WSDL/Deserializer/Hash.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Deserializer::SOM: file: lib/SOAP/WSDL/Deserializer/SOM.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Deserializer::XSD: file: lib/SOAP/WSDL/Deserializer/XSD.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Expat::Base: file: lib/SOAP/WSDL/Expat/Base.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Expat::Message2Hash: file: lib/SOAP/WSDL/Expat/Message2Hash.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Expat::MessageParser: file: lib/SOAP/WSDL/Expat/MessageParser.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Expat::MessageStreamParser: file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Expat::WSDLParser: file: lib/SOAP/WSDL/Expat/WSDLParser.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Factory::Deserializer: file: lib/SOAP/WSDL/Factory/Deserializer.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Factory::Generator: file: lib/SOAP/WSDL/Factory/Generator.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Factory::Serializer: file: lib/SOAP/WSDL/Factory/Serializer.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Factory::Transport: file: lib/SOAP/WSDL/Factory/Transport.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Generator::Iterator::WSDL11: file: lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Generator::PrefixResolver: file: lib/SOAP/WSDL/Generator/PrefixResolver.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Generator::Template: file: lib/SOAP/WSDL/Generator/Template.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Generator::Template::Plugin::XSD: file: lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Generator::Template::XSD: file: lib/SOAP/WSDL/Generator/Template/XSD.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Generator::Visitor: file: lib/SOAP/WSDL/Generator/Visitor.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Generator::Visitor::Typelib: file: lib/SOAP/WSDL/Generator/Visitor/Typelib.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Generator::Visitor::Typemap: file: lib/SOAP/WSDL/Generator/Visitor/Typemap.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Message: file: lib/SOAP/WSDL/Message.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::OpMessage: file: lib/SOAP/WSDL/OpMessage.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Operation: file: lib/SOAP/WSDL/Operation.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Part: file: lib/SOAP/WSDL/Part.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Port: file: lib/SOAP/WSDL/Port.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::PortType: file: lib/SOAP/WSDL/PortType.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::SOAP::Address: file: lib/SOAP/WSDL/SOAP/Address.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::SOAP::Body: file: lib/SOAP/WSDL/SOAP/Body.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::SOAP::Header: file: lib/SOAP/WSDL/SOAP/Header.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::SOAP::HeaderFault: file: lib/SOAP/WSDL/SOAP/HeaderFault.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::SOAP::Operation: file: lib/SOAP/WSDL/SOAP/Operation.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::SOAP::Typelib::Fault11: file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Serializer::XSD: file: lib/SOAP/WSDL/Serializer/XSD.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Server: file: lib/SOAP/WSDL/Server.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Server::CGI: file: lib/SOAP/WSDL/Server/CGI.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Server::Mod_Perl2: file: lib/SOAP/WSDL/Server/Mod_Perl2.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Service: file: lib/SOAP/WSDL/Service.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Transport::HTTP: file: lib/SOAP/WSDL/Transport/HTTP.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Transport::Loopback: file: lib/SOAP/WSDL/Transport/Loopback.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::Transport::Test: file: lib/SOAP/WSDL/Transport/Test.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::TypeLookup: file: lib/SOAP/WSDL/TypeLookup.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::Types: file: lib/SOAP/WSDL/Types.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Annotation: file: lib/SOAP/WSDL/XSD/Annotation.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Attribute: file: lib/SOAP/WSDL/XSD/Attribute.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::AttributeGroup: file: lib/SOAP/WSDL/XSD/AttributeGroup.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Builtin: file: lib/SOAP/WSDL/XSD/Builtin.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::ComplexType: file: lib/SOAP/WSDL/XSD/ComplexType.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Element: file: lib/SOAP/WSDL/XSD/Element.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Enumeration: file: lib/SOAP/WSDL/XSD/Enumeration.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::FractionDigits: file: lib/SOAP/WSDL/XSD/FractionDigits.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Group: file: lib/SOAP/WSDL/XSD/Group.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Length: file: lib/SOAP/WSDL/XSD/Length.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::MaxExclusive: file: lib/SOAP/WSDL/XSD/MaxExclusive.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::MaxInclusive: file: lib/SOAP/WSDL/XSD/MaxInclusive.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::MaxLength: file: lib/SOAP/WSDL/XSD/MaxLength.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::MinExclusive: file: lib/SOAP/WSDL/XSD/MinExclusive.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::MinInclusive: file: lib/SOAP/WSDL/XSD/MinInclusive.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::MinLength: file: lib/SOAP/WSDL/XSD/MinLength.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Pattern: file: lib/SOAP/WSDL/XSD/Pattern.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Schema: file: lib/SOAP/WSDL/XSD/Schema.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Schema::Builtin: file: lib/SOAP/WSDL/XSD/Schema/Builtin.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::SimpleType: file: lib/SOAP/WSDL/XSD/SimpleType.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::TotalDigits: file: lib/SOAP/WSDL/XSD/TotalDigits.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::Attribute: file: lib/SOAP/WSDL/XSD/Typelib/Attribute.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::AttributeSet: file: lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::Builtin: file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::Builtin::ENTITY: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm SOAP::WSDL::XSD::Typelib::Builtin::ID: @@ -279,14 +279,14 @@ provides: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm SOAP::WSDL::XSD::Typelib::Builtin::anyType: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::Builtin::anyURI: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm SOAP::WSDL::XSD::Typelib::Builtin::base64Binary: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm SOAP::WSDL::XSD::Typelib::Builtin::boolean: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::Builtin::byte: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm SOAP::WSDL::XSD::Typelib::Builtin::date: @@ -339,7 +339,7 @@ provides: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm SOAP::WSDL::XSD::Typelib::Builtin::time: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::Builtin::token: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte: @@ -352,19 +352,19 @@ provides: file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm SOAP::WSDL::XSD::Typelib::ComplexType: file: lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm - version: 2.1.0 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::Element: file: lib/SOAP/WSDL/XSD/Typelib/Element.pm - version: 2.00.04 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::SimpleType: file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::Typelib::SimpleType::restriction: file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm - version: 2.00.03 + version: 2.00.05 SOAP::WSDL::XSD::WhiteSpace: file: lib/SOAP/WSDL/XSD/WhiteSpace.pm - version: 2.00.04 + version: 2.00.05 generated_by: Module::Build version 0.2808 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html diff --git a/README b/README index 77ac657..59cff57 100644 --- a/README +++ b/README @@ -41,4 +41,13 @@ If you don't have Module::Build installed, you may also use make install Note that Module::Build is the recommended installer - make will not run -all tests provided with SOAP-WSDL. \ No newline at end of file +all tests provided with SOAP-WSDL. + +SOLARIS INSTALLATION NOTES +-------------------------- +According to a CPAN RT report http://rt.cpan.org/Ticket/Display.html?id=36865 +it may be necessary to check (and possibly update) the expat libraries +required by XML::Parser. + +SOAP::WSDL's metadata includes XML::Parser, but it seems that the expat +libraries XML::Parser depends on may slip through missing or outdated. \ No newline at end of file diff --git a/SOAP-WSDL-2.00.01.ppd b/SOAP-WSDL-2.00.01.ppd deleted file mode 100644 index 488f5a3..0000000 --- a/SOAP-WSDL-2.00.01.ppd +++ /dev/null @@ -1,16 +0,0 @@ - - - SOAP-WSDL-2.00.01 - SOAP with WSDL support - Martin Kutter <martin.kutter@fen-net.de> - - - - - - - - - - - diff --git a/SOAP-WSDL-2.00.01.zip b/SOAP-WSDL-2.00.01.zip deleted file mode 100644 index f7b0d3b..0000000 Binary files a/SOAP-WSDL-2.00.01.zip and /dev/null differ diff --git a/TEST_COVERAGE b/TEST_COVERAGE index 88897ab..8e6ad76 100644 --- a/TEST_COVERAGE +++ b/TEST_COVERAGE @@ -6,12 +6,18 @@ # Note that this shell script requires Devel::CoverX::Covered - if you # don't have it, comment out the line noted below # -cd t/ -cover -delete -find . -type f -name '*.t' | xargs -n 1 /usr/bin/perl -MDevel::Cover=-silent,1,-summary,0 -I../lib > /dev/null + +perl -It/lib -MTAP::Harness -MFile::Find::Rule -e ' + local $ENV{TEST_VERBOSE} = 1; + TAP::Harness->new({ + merge => 1, + lib => [ q{t/lib}, q{lib} ], + switches => [ q{-MDevel::Cover=-ignore,.,-select,^lib/.+,-coverage,statement,-coverage,subroutine,-coverage,condition,-coverage,branch} ], + })->runtests( sort { $a cmp $b } File::Find::Rule->file()->name( q{*.t} )->in( q{t/} ) ); +' # Devel::CoverX::Covered covered runs -cover -ignore_re \.t$ -ignore_re ^lib -coverage="statement" -coverage=condition -coverage=subroutine -coverage="branch" +cover -coverage="statement" -coverage=condition -coverage=subroutine -coverage="branch" diff --git a/covered_by.pl b/covered_by.pl new file mode 100644 index 0000000..dadb146 --- /dev/null +++ b/covered_by.pl @@ -0,0 +1,20 @@ +use Getopt::Long; +use Pod::Usage; +use File::Basename; +use POSIX; +use Data::Dumper; +use Path::Class; + +use Devel::CoverX::Covered::Db; +my $db = Devel::CoverX::Covered::Db->new( + dir => dir('./cover_db')->absolute(), +); + +print( "* Covered *\nVersion: " . Devel::CoverX::Covered->VERSION . "\n" ); + +my @test_file_from = $db->test_files(); +for my $test_file (sort @test_file_from) { + print "$test_file\n"; + print( "\t", join("\n\t", $db->source_files_covered_by($test_file)) , "\n\n" ); +} + diff --git a/covering.pl b/covering.pl new file mode 100644 index 0000000..2c3d427 --- /dev/null +++ b/covering.pl @@ -0,0 +1,58 @@ +use strict; +use Getopt::Long; +use Pod::Usage; +use File::Basename; +use POSIX; +use Data::Dumper; +use Path::Class; + +use Devel::CoverX::Covered::Db; +my $db = Devel::CoverX::Covered::Db->new( + dir => dir('./cover_db')->absolute(), +); + +sub covered_subs { + my $db = shift; + my ($covered_file_name, $calling_file_name) = @_; + + my %sub_covered; + map { push @{ $sub_covered{ $_->[1] } }, $_->[0] } $db->db->query( + qq{ + SELECT ccm.covered_row, ccm.covered_sub_name + FROM covered_calling_metric ccm, file f_covered, file f_calling + WHERE + f_covered.name = ? + AND f_calling.name = ? + AND ccm.calling_file_id = f_calling.file_id + AND ccm.covered_file_id = f_covered.file_id + AND ccm.metric_type_id = ? + GROUP BY ccm.covered_row + ORDER by ccm.covered_sub_name + }, + $covered_file_name, + $calling_file_name, + $db->get_metric_type_id("subroutine"), + )->arrays; + + return \%sub_covered; +} + +print( "* Covered *\nVersion: " . Devel::CoverX::Covered->VERSION . "\n" ); + +my @covered_files = sort { $a cmp $b } $db->covered_files(); +for my $covered_file (sort @covered_files) { + next if $covered_file =~m{\.t$}x; + print "$covered_file\n"; +# print( "\t", join("\n\t", $db->test_files_covering($covered_file)) , "\n\n" ); + + my @test_files = $db->test_files_covering($covered_file); + for my $test_file (@test_files) { + print "\t$test_file\n"; + + my $covered_subs_of_ref = covered_subs($db, $covered_file, $test_file); + for my $covered_sub (sort keys %{ $covered_subs_of_ref }) { + print "\t\t$covered_sub (line ", join(q{, }, @{ $covered_subs_of_ref->{ $covered_sub } }), ")\n"; + } + } +} + diff --git a/example/leaktest/hello_wsdl.pl b/example/leaktest/hello_wsdl.pl new file mode 100644 index 0000000..b07fd7b --- /dev/null +++ b/example/leaktest/hello_wsdl.pl @@ -0,0 +1,45 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +# use SOAP::Lite 'trace'; +use Devel::Leak; +use Devel::Cycle; +use SOAP::WSDL; +my $path = `pwd`; chomp $path; +# I have to lookup the URL from the WSDL + +use SOAP::WSDL::Factory::Transport; +SOAP::WSDL::Factory::Transport->register('http' => 'SOAP::WSDL::Transport::HTTP'); + +my $table; +my $count = Devel::Leak::NoteSV($table); + +for (1..10) { + my $soap; + $soap = SOAP::WSDL->new( + wsdl => "file://$path/../wsdl/11_helloworld.wsdl", + ); + $count = Devel::Leak::NoteSV($table); + print "SVs: $count\n"; + + $soap->wsdlinit(); + # $count = Devel::Leak::NoteSV($table); + # print "SVs: $count\n"; + # $soap->autotype(0); + +my $som = $soap->call( + "sayHello", + 'sayHello', => { 'name' => 'Your Name', + 'givenName' => 'Your given name', + } +); + +die $som->fault->{ faultstring } if ($som->fault); + +print $som->result, "\n"; + undef $som; +# $count = Devel::Leak::NoteSV($table); +# print "SVs: $count\n"; +} +#} +sleep 500; diff --git a/example/leaktest/leak.pl b/example/leaktest/leak.pl new file mode 100644 index 0000000..0ccb953 --- /dev/null +++ b/example/leaktest/leak.pl @@ -0,0 +1,28 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +# use SOAP::Lite 'trace'; +use Devel::Leak; +use SOAP::WSDL; +use SOAP::WSDL::Definitions; +use SOAP::WSDL::Binding; +my $path = `pwd`; chomp $path; +# I have to lookup the URL from the WSDL + +my $table; +my $count = Devel::Leak::NoteSV($table); +for (1..3) { +print "SVs: $count\n"; +my $definitions = SOAP::WSDL::Definitions->new({ + annotation => 'Foo', +}); + +$definitions->set_binding( + SOAP::WSDL::Binding->new({ parent => $definitions }) +); + +undef $definitions; +$count = Devel::Leak::NoteSV($table); +} +print "SVs: $count\n"; + diff --git a/example/leaktest/parse.pl b/example/leaktest/parse.pl new file mode 100644 index 0000000..b9fc6d7 --- /dev/null +++ b/example/leaktest/parse.pl @@ -0,0 +1,16 @@ +use SOAP::WSDL::Expat::WSDLParser; +use Devel::Leak; +my $xml = `cat ../wsdl/11_helloworld.wsdl`; + +my ($table, $count); + + +for (1..5) { + $count = Devel::Leak::NoteSV($table); + print "SV: $count \n"; + my $parser = SOAP::WSDL::Expat::WSDLParser->new(); + $parser->parse_string($xml); + my $data = $parser->get_data(); + undef $parser; + undef $data; +} diff --git a/lib/SOAP/WSDL.pm b/lib/SOAP/WSDL.pm index e514260..25262d4 100644 --- a/lib/SOAP/WSDL.pm +++ b/lib/SOAP/WSDL.pm @@ -14,7 +14,7 @@ use Class::Std::Fast constructor => 'none'; use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; use LWP::UserAgent; -use version; our $VERSION= qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %no_dispatch_of :ATTR(:name); my %wsdl_of :ATTR(:name); @@ -270,7 +270,7 @@ sub _wsdl_init_methods :PRIVATE { # on_action is a no-op and just here for compatibility reasons. # It returns the first parameter to allow method chaining. -sub on_action { return shift }; +sub on_action { return shift } sub call { my ($self, $method, @data_from) = @_; @@ -299,7 +299,7 @@ sub call { && ( ! $no_dispatch_of{ $ident } ) ) { require SOAP::WSDL::Deserializer::SOM; $client->set_deserializer( SOAP::WSDL::Deserializer::SOM->new() ); - }; + } my $method_info = $method_info_of{ $ident }->{ $method }; @@ -830,9 +830,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 694 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: WSDL.pm 694 2008-05-25 21:06:56Z kutterma $ + $Id: WSDL.pm 728 2008-07-13 19:28:50Z 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 7b074ce..0da82eb 100644 --- a/lib/SOAP/WSDL/Base.pm +++ b/lib/SOAP/WSDL/Base.pm @@ -1,11 +1,11 @@ package SOAP::WSDL::Base; -use strict; -use warnings; +use strict; use warnings; use Class::Std::Fast::Storable; -use List::Util qw(first); +use List::Util; +use Scalar::Util; use Carp qw(croak carp confess); -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %id_of :ATTR(:name :default<()>); my %lang_of :ATTR(:name :default<()>); @@ -15,7 +15,7 @@ my %documentation_of :ATTR(:name :default<()>); my %annotation_of :ATTR(:name :default<()>); my %targetNamespace_of :ATTR(:name :default<()>); my %xmlns_of :ATTR(:name :default<{}>); -my %parent_of :ATTR(:name :default<()>); +my %parent_of :ATTR(:get :default<()>); my %namespaces_of :ATTR(:default<{}>); @@ -23,34 +23,42 @@ sub namespaces { return shift->get_xmlns(); } +sub BUILD { + my ($self, $ident, $arg_ref) = @_; + if (defined $arg_ref->{ parent }) { + $parent_of{ $ident } = delete $arg_ref->{ parent }, + Scalar::Util::weaken($parent_of{ $ident }); + } +} + sub START { my ($self, $ident, $arg_ref) = @_; $xmlns_of{ $ident }->{ 'xml' } = 'http://www.w3.org/XML/1998/namespace'; $namespaces_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' }; $namespaces_of{ $ident }->{ 'xml' } = 'http://www.w3.org/XML/1998/namespace'; - -} - -sub DEMOLISH { - my $self = shift; - # delete upward references - delete $parent_of{ ${ $self } }; - return; } # -#sub STORABLE_freeze_pre :CUMULATIVE {}; -#sub STORABLE_freeze_post :CUMULATIVE {}; -#sub STORABLE_thaw_pre :CUMULATIVE {}; -#sub STORABLE_thaw_post :CUMULATIVE { return $_[0] }; +# set_parent is hand-implemented to break up (weaken) the circular reference +# between an object and it's parent +# +sub set_parent { + $parent_of{ ${ $_[0]} } = $_[1]; + Scalar::Util::weaken($parent_of{ ${ $_[0]} }); +} +# _accept is here to be called by visitor. +# The visitor pattern is a level of indirection - here the visitor calls +# $object->_accept($visitor) on each object, which in turn calls +# $visitor->visit_$class( $object ) where $class is the object's class. +# sub _accept { my $self = shift; my $class = ref $self; $class =~ s{ \A SOAP::WSDL:: }{}xms; $class =~ s{ (:? :: ) }{_}gxms; my $method = "visit_$class"; - no strict qw(refs); ## no critic ProhibitNoStrict + no strict qw(refs); return shift->$method( $self ); } @@ -65,13 +73,12 @@ sub AUTOMETHOD { if ($subname =~s{^push_}{}xms) { my $getter = "get_$subname"; my $setter = "set_$subname"; - ## Checking here is paranoid - will fail fatally if - ## there is no setter... - ## And we would have to check getters, too. - ## Maybe do it the Conway way via the Symbol table... - ## ... can is way slow... + # Checking here is paranoid - will fail fatally if there is no setter. + # And we would have to check getters, too. + # Maybe do it the Conway way via the Symbol table... + # ... can is way slow... return sub { - no strict qw(refs); ## no critic ProhibitNoStrict + no strict qw(refs); my $old_value = $self->$getter(); # Listify if not a list ref $old_value = $old_value ? [ $old_value ] : [] if not ref $old_value; @@ -85,7 +92,7 @@ sub AUTOMETHOD { elsif ($subname =~s {^find_}{get_}xms) { @values = @{ $values[0] } if ref $values[0] eq 'ARRAY'; return sub { - return first { + return List::Util::first { $_->get_targetNamespace() eq $values[0] && $_->get_name() eq $values[1] } @@ -101,10 +108,6 @@ sub AUTOMETHOD { }; } - # return if called from can(); - my @caller = caller(2); - return if ($caller[3] eq 'Class::Std::Fast::__ANON__'); - # confess "$subname not found in class " . ref $self; return; } diff --git a/lib/SOAP/WSDL/Binding.pm b/lib/SOAP/WSDL/Binding.pm index aab6078..71f7cfe 100644 --- a/lib/SOAP/WSDL/Binding.pm +++ b/lib/SOAP/WSDL/Binding.pm @@ -2,10 +2,10 @@ package SOAP::WSDL::Binding; use strict; use warnings; use Class::Std::Fast::Storable; -use List::Util qw(first); + use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %operation_of :ATTR(:name :default<()>); my %type_of :ATTR(:name :default<()>); diff --git a/lib/SOAP/WSDL/Client.pm b/lib/SOAP/WSDL/Client.pm index 67ff891..58f5368 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; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %class_resolver_of :ATTR(:name :default<()>); my %no_dispatch_of :ATTR(:name :default<()>); @@ -20,7 +20,7 @@ my %outputxml_of :ATTR(:name :default<()>); my %transport_of :ATTR(:name :default<()>); my %endpoint_of :ATTR(:name :default<()>); -my %soap_version_of :ATTR(:get :init_attr :default<'1.1'>); +my %soap_version_of :ATTR(:get :init_attr :default<1.1>); my %on_action_of :ATTR(:name :default<()>); my %content_type_of :ATTR(:name :default); #/#trick editors @@ -395,9 +395,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 677 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: Client.pm 677 2008-05-18 20:17:56Z kutterma $ + $Id: Client.pm 728 2008-07-13 19:28:50Z 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 029df98..2b19241 100644 --- a/lib/SOAP/WSDL/Client/Base.pm +++ b/lib/SOAP/WSDL/Client/Base.pm @@ -4,7 +4,7 @@ use warnings; use base 'SOAP::WSDL::Client'; use Scalar::Util qw(blessed); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); sub call { my ($self, $method, $body, $header) = @_; @@ -22,7 +22,7 @@ sub call { # parameters given my @part_from = (); foreach my $class (@{ $method->{ body }->{ parts } }) { - eval "require $class" || die $@; + eval "require $class" || die $@; ## no critic (ProhibitStringyEval) push @part_from, $class->new(shift(@body_from) || {}); } @@ -33,10 +33,10 @@ sub call { # if we have a header if (%{ $method->{ header } }) { - # trat non object special - as above, but only for one + # treat non object special - as above, but only for one if (not blessed $header) { my $class = $method->{ header }->{ parts }->[0]; - eval "require $class" || die $@; + eval "require $class" || die $@; ## no critic (ProhibitStringyEval) $header = $class->new($header); } } @@ -85,9 +85,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 689 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: Base.pm 689 2008-05-23 22:11:46Z kutterma $ + $Id: Base.pm 728 2008-07-13 19:28:50Z 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/Definitions.pm b/lib/SOAP/WSDL/Definitions.pm index 0b29796..8dcb26f 100644 --- a/lib/SOAP/WSDL/Definitions.pm +++ b/lib/SOAP/WSDL/Definitions.pm @@ -1,26 +1,22 @@ package SOAP::WSDL::Definitions; -use utf8; use strict; use warnings; -use Carp; -use File::Basename; -use File::Path; use List::Util qw(first); use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %types_of :ATTR(:name :default<[]>); my %message_of :ATTR(:name :default<[]>); my %portType_of :ATTR(:name :default<[]>); my %binding_of :ATTR(:name :default<[]>); my %service_of :ATTR(:name :default<[]>); -my %namespace_of :ATTR(:name :default<()>); +my %namespace_of :ATTR(:name :default<()>); # must be attr for Class::Std::Fast::Storable -my %attributes_of :ATTR(); -%attributes_of = ( +#my %attributes_of :ATTR(); +my %attributes_of = ( binding => \%binding_of, message => \%message_of, portType => \%portType_of, @@ -44,6 +40,7 @@ BLOCK: { } } + 1; =pod @@ -118,9 +115,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 689 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: Definitions.pm 689 2008-05-23 22:11:46Z kutterma $ + $Id: Definitions.pm 728 2008-07-13 19:28:50Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Definitions.pm $ =cut diff --git a/lib/SOAP/WSDL/Deserializer/Hash.pm b/lib/SOAP/WSDL/Deserializer/Hash.pm index 850d1e5..7dbc826 100644 --- a/lib/SOAP/WSDL/Deserializer/Hash.pm +++ b/lib/SOAP/WSDL/Deserializer/Hash.pm @@ -8,7 +8,7 @@ use SOAP::WSDL::Expat::Message2Hash; use SOAP::WSDL::Factory::Deserializer; SOAP::WSDL::Factory::Deserializer->register( '1.1', __PACKAGE__ ); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); sub BUILD { my ($self, $ident, $args_of_ref) = @_; @@ -163,9 +163,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 689 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: Hash.pm 689 2008-05-23 22:11:46Z kutterma $ + $Id: Hash.pm 728 2008-07-13 19:28:50Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/Hash.pm $ =cut diff --git a/lib/SOAP/WSDL/Deserializer/SOM.pm b/lib/SOAP/WSDL/Deserializer/SOM.pm index 6d312d1..67c27a6 100644 --- a/lib/SOAP/WSDL/Deserializer/SOM.pm +++ b/lib/SOAP/WSDL/Deserializer/SOM.pm @@ -2,7 +2,7 @@ package SOAP::WSDL::Deserializer::SOM; use strict; use warnings; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); our @ISA; eval { @@ -13,6 +13,18 @@ or die "Cannot load SOAP::Lite. Cannot deserialize to SOM object without SOAP::Lite. Please install SOAP::Lite."; +sub deserialize { + my $self = shift; + my $result = eval { $self->SUPER::deserialize(@_) }; + if ($@) { + return SOAP::Fault->new( + faultactor => 'soap:Server', + faultstring => $@, + ); + } + return $result; +} + sub generate_fault { my ($self, $args_from_ref) = @_; # code, message, detail, actor @@ -66,6 +78,17 @@ This may be XML including mixed content, attachements and other XML data not SOAP::WSDL::Deserializer::SOM is a subclass of L from the L package. +=head1 METHODS + +=head2 deserialize + +Deserializes a XML sting into a SOAP::SOM object. Returns a SOAP::Fault object +on deserialization errors. + +=head2 generate_fault + +Dies with a SOAP::Fault object. + =head1 USAGE SOAP::WSDL::Deserializer will not autoregister itself - to use it for a particular @@ -85,8 +108,8 @@ SOAP version just use the following lines: =item * No on_fault handler -You cannot specify what to do when an error occurs - SOAP::WSDL will die -with a SOAP::Fault object on transport errors. +You cannot specify what to do when an error occurs - SOAP::WSDL will return +a SOAP::Fault object on transport errors. =back @@ -99,6 +122,9 @@ with a SOAP::Fault object on transport errors. SOAP::WSDL::Deserializer::SOM will die with a SOAP::Fault object on calls to generate_fault. +This also means that a SOAP::Fault may be thrown as exception when using + + =back =head1 LICENSE AND COPYRIGHT @@ -114,9 +140,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 677 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: SOM.pm 677 2008-05-18 20:17:56Z kutterma $ + $Id: SOM.pm 728 2008-07-13 19:28:50Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/SOM.pm $ =cut diff --git a/lib/SOAP/WSDL/Deserializer/XSD.pm b/lib/SOAP/WSDL/Deserializer/XSD.pm index 6c3ce9b..84b63f3 100644 --- a/lib/SOAP/WSDL/Deserializer/XSD.pm +++ b/lib/SOAP/WSDL/Deserializer/XSD.pm @@ -5,7 +5,7 @@ use Class::Std::Fast::Storable; use SOAP::WSDL::SOAP::Typelib::Fault11; use SOAP::WSDL::Expat::MessageParser; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %class_resolver_of :ATTR(:name :default<()>); @@ -99,9 +99,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 677 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: XSD.pm 677 2008-05-18 20:17:56Z kutterma $ + $Id: XSD.pm 728 2008-07-13 19:28:50Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/XSD.pm $ =cut diff --git a/lib/SOAP/WSDL/Expat/Base.pm b/lib/SOAP/WSDL/Expat/Base.pm index 0346f5b..703364e 100644 --- a/lib/SOAP/WSDL/Expat/Base.pm +++ b/lib/SOAP/WSDL/Expat/Base.pm @@ -6,7 +6,7 @@ use XML::Parser::Expat; # TODO: convert to Class::Std::Fast based class - hash based classes suck. -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); sub new { my ($class, $arg_ref) = @_; @@ -35,17 +35,23 @@ sub get_uri { return $_[0]->{ uri }; } sub set_user_agent { $_[0]->{ user_agent } = $_[1]; } sub get_user_agent { return $_[0]->{ user_agent }; } +# Mark a URI as "already parsed" sub set_parsed { my ($self, $uri) = @_; $self->{ parsed }->{ $uri } = 1; return; } + +# returns true if a specific URI has already been parsed sub is_parsed { my ($self, $uri) = @_; return exists $self->{ parsed }->{ $uri }; } + +# parse a URI. This is the preferred parsing method for WSDL files, as it's +# the only one allowing automatic import resolution sub parse_uri { my $self = shift; my $uri = shift; @@ -74,6 +80,7 @@ sub parse { $_[0]->{ parser }->release(); }; $_[0]->{ parser }->xpcroak( $@ ) if $@; + delete $_[0]->{ parser }; return $_[0]->{ data }; } @@ -83,6 +90,7 @@ sub parsefile { $_[0]->{ parser }->release(); }; $_[0]->{ parser }->xpcroak( $@ ) if $@; + delete $_[0]->{ parser }; return $_[0]->{ data }; } diff --git a/lib/SOAP/WSDL/Expat/Message2Hash.pm b/lib/SOAP/WSDL/Expat/Message2Hash.pm index b8386ff..e8ef7dd 100644 --- a/lib/SOAP/WSDL/Expat/Message2Hash.pm +++ b/lib/SOAP/WSDL/Expat/Message2Hash.pm @@ -4,7 +4,7 @@ use strict; use warnings; use base qw(SOAP::WSDL::Expat::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); sub _initialize { my ($self, $parser) = @_; diff --git a/lib/SOAP/WSDL/Expat/MessageParser.pm b/lib/SOAP/WSDL/Expat/MessageParser.pm index 4711335..cb798b1 100644 --- a/lib/SOAP/WSDL/Expat/MessageParser.pm +++ b/lib/SOAP/WSDL/Expat/MessageParser.pm @@ -1,19 +1,20 @@ #!/usr/bin/perl package SOAP::WSDL::Expat::MessageParser; -use strict; -use warnings; -use Carp qw(croak confess); - -use version; our $VERSION = qv('2.00.03'); +use strict; use warnings; use SOAP::WSDL::XSD::Typelib::Builtin; use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; use base qw(SOAP::WSDL::Expat::Base); -require Class::Std::Fast; +BEGIN { require Class::Std::Fast }; + +use version; our $VERSION = qv('2.00.05'); + +# GLOBALS my $OBJECT_CACHE_REF = Class::Std::Fast::OBJECT_CACHE_REF(); +# keep track of classes loaded my %LOADED_OF = (); sub new { @@ -46,7 +47,10 @@ sub class_resolver { sub load_classes { my $self = shift; - for (values %{ $self->{ class_resolver }->get_typemap }) { + return if $LOADED_OF{ $self->{ class_resolver } }; + + # requires sorting to make sub-packages load after their parent + for (sort values %{ $self->{ class_resolver }->get_typemap }) { no strict qw(refs); my $class = $_; @@ -54,9 +58,10 @@ sub load_classes { next if $class eq '__SKIP__'; next if defined *{ "$class\::" }; # check if namespace exists + # Require takes a bareword or a file name - we have to take + # the filname road here... $class =~s{ :: }{/}xmsg; - $class .= '.pm'; - require $class; + require "$class.pm"; ## no critic (RequireBarewordIncludes) } $LOADED_OF{ $self->{ class_resolver } } = 1; } @@ -106,16 +111,12 @@ sub _initialize { : (); # use "globals" for speed - my ($_prefix, $_method, - $_class, $_leaf) = (); + my ($_prefix, $_method, $_class, $_leaf) = (); my $char_handler = sub { - return if (!$_leaf); # we only want characters in leaf nodes - - $characters .= $_[1]; -# if $_[1] =~m{ [^\s] }xms; - - return; + return if (!$_leaf); # we only want characters in leaf nodes + $characters .= $_[1]; # add to characters + return; # return void }; no strict qw(refs); @@ -194,6 +195,9 @@ sub _initialize { } } $depth++; + + # TODO: Skip content of anyType / any stuff + return; }, @@ -319,10 +323,10 @@ the same terms as perl itself =head1 Repository information - $Id: MessageParser.pm 677 2008-05-18 20:17:56Z kutterma $ + $Id: MessageParser.pm 728 2008-07-13 19:28:50Z kutterma $ - $LastChangedDate: 2008-05-18 22:17:56 +0200 (So, 18 Mai 2008) $ - $LastChangedRevision: 677 $ + $LastChangedDate: 2008-07-13 21:28:50 +0200 (So, 13 Jul 2008) $ + $LastChangedRevision: 728 $ $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/MessageStreamParser.pm b/lib/SOAP/WSDL/Expat/MessageStreamParser.pm index 2c1f363..c64c21f 100644 --- a/lib/SOAP/WSDL/Expat/MessageStreamParser.pm +++ b/lib/SOAP/WSDL/Expat/MessageStreamParser.pm @@ -6,7 +6,7 @@ use XML::Parser::Expat; use SOAP::WSDL::Expat::MessageParser; use base qw(SOAP::WSDL::Expat::MessageParser); -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); sub parse_start { my $self = shift; @@ -69,9 +69,9 @@ the same terms as perl itself =head1 REPOSITORY INFORMATION - $Rev: 701 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: MessageStreamParser.pm 701 2008-06-05 19:19:16Z kutterma $ + $Id: MessageStreamParser.pm 728 2008-07-13 19:28:50Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $ =cut diff --git a/lib/SOAP/WSDL/Expat/WSDLParser.pm b/lib/SOAP/WSDL/Expat/WSDLParser.pm index 7a7a745..9836114 100644 --- a/lib/SOAP/WSDL/Expat/WSDLParser.pm +++ b/lib/SOAP/WSDL/Expat/WSDLParser.pm @@ -5,7 +5,17 @@ use Carp; use SOAP::WSDL::TypeLookup; use base qw(SOAP::WSDL::Expat::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); + +# +# Import child elements of a WSDL / XML Schema tree into the current tree +# +# Set the targetNamespace of the imported nodes to $import_namespace +# +# SYNOPSIS +# +# $self->_import_children($name, $imported, $imported, $import_namespace) +# sub _import_children { my ($self, $name, $imported, $importer, $import_namespace) = @_; @@ -140,6 +150,8 @@ sub _initialize { # TODO skip non-XML Schema namespace tags $parser->setHandlers( Start => sub { + # handle attrs as list - expat uses dual-vars for looking + # up namespace information, and hash keys don't allow dual vars... my ($parser, $localname, @attrs) = @_; $characters = q{}; @@ -174,9 +186,7 @@ sub _initialize { # remember element for stepping back push @{ $list }, $current; } - else { - $self->{ data } = $obj; - } + # set new element (step down) $current = $obj; } @@ -228,6 +238,11 @@ sub _initialize { $localname ) || {}; + if (! defined $list->[-1]) { + $self->{ data } = $current; + return; + } + return if not ($action->{ type }); if ( $action->{ type } eq 'CLASS' ) { $current = pop @{ $list }; @@ -275,7 +290,6 @@ sub _fixup_attrs { } $parser->new_ns_prefixes(); push @attrs_from, map { - $_ = { Name => defined $parser->namespace($_) ? $parser->namespace($_) . '|' . $_ @@ -322,10 +336,10 @@ the same terms as perl itself =head1 Repository information - $Id: WSDLParser.pm 688 2008-05-23 21:01:54Z kutterma $ + $Id: WSDLParser.pm 728 2008-07-13 19:28:50Z kutterma $ - $LastChangedDate: 2008-05-23 23:01:54 +0200 (Fr, 23 Mai 2008) $ - $LastChangedRevision: 688 $ + $LastChangedDate: 2008-07-13 21:28:50 +0200 (So, 13 Jul 2008) $ + $LastChangedRevision: 728 $ $LastChangedBy: kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $ diff --git a/lib/SOAP/WSDL/Factory/Deserializer.pm b/lib/SOAP/WSDL/Factory/Deserializer.pm index 68ae3d2..e49a324 100644 --- a/lib/SOAP/WSDL/Factory/Deserializer.pm +++ b/lib/SOAP/WSDL/Factory/Deserializer.pm @@ -2,7 +2,7 @@ package SOAP::WSDL::Factory::Deserializer; use strict; use warnings; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %DESERIALIZER = ( '1.1' => 'SOAP::WSDL::Deserializer::XSD', diff --git a/lib/SOAP/WSDL/Factory/Generator.pm b/lib/SOAP/WSDL/Factory/Generator.pm index 2ce842b..e82df35 100644 --- a/lib/SOAP/WSDL/Factory/Generator.pm +++ b/lib/SOAP/WSDL/Factory/Generator.pm @@ -2,7 +2,7 @@ package SOAP::WSDL::Factory::Generator; use strict; use warnings; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %GENERATOR = ( 'XSD' => 'SOAP::WSDL::Generator::Template::XSD', diff --git a/lib/SOAP/WSDL/Factory/Serializer.pm b/lib/SOAP/WSDL/Factory/Serializer.pm index 750bead..cec461b 100644 --- a/lib/SOAP/WSDL/Factory/Serializer.pm +++ b/lib/SOAP/WSDL/Factory/Serializer.pm @@ -2,7 +2,7 @@ package SOAP::WSDL::Factory::Serializer; use strict; use warnings; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %SERIALIZER = ( '1.1' => 'SOAP::WSDL::Serializer::XSD', @@ -138,9 +138,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 677 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: Serializer.pm 677 2008-05-18 20:17:56Z kutterma $ + $Id: Serializer.pm 728 2008-07-13 19:28:50Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $ =cut diff --git a/lib/SOAP/WSDL/Factory/Transport.pm b/lib/SOAP/WSDL/Factory/Transport.pm index 6ff8d59..e61545d 100644 --- a/lib/SOAP/WSDL/Factory/Transport.pm +++ b/lib/SOAP/WSDL/Factory/Transport.pm @@ -1,7 +1,7 @@ package SOAP::WSDL::Factory::Transport; use strict; use warnings; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %registered_transport_of = (); @@ -243,9 +243,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 679 $ + $Rev: 728 $ $LastChangedBy: kutterma $ - $Id: Transport.pm 679 2008-05-18 21:18:03Z kutterma $ + $Id: Transport.pm 728 2008-07-13 19:28:50Z 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/Iterator/WSDL11.pm b/lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm index 958c4c3..c0ea2d6 100644 --- a/lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm +++ b/lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm @@ -2,7 +2,7 @@ package SOAP::WSDL::Generator::Iterator::WSDL11; use strict; use warnings; use Class::Std::Fast; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %definitions_of :ATTR(:name :default<[]>); my %nodes_of :ATTR(:name :default<[]>); @@ -74,7 +74,8 @@ my %METHOD_OF = ( ? do { die "unsupported global type <" . $node->get_type . "> found in part ". $node->get_name(); - $types->find_type( $node->expand($node->get_type) ) + ## use this once we can auto-generate an element for RPC bindings + # $types->find_type( $node->expand($node->get_type) ) } : (), $node->get_element() diff --git a/lib/SOAP/WSDL/Generator/PrefixResolver.pm b/lib/SOAP/WSDL/Generator/PrefixResolver.pm index c497c1f..9a8f89f 100644 --- a/lib/SOAP/WSDL/Generator/PrefixResolver.pm +++ b/lib/SOAP/WSDL/Generator/PrefixResolver.pm @@ -3,7 +3,7 @@ use strict; use warnings; use Class::Std::Fast::Storable; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %namespace_prefix_map_of :ATTR(:name :default<{}>); my %namespace_map_of :ATTR(:name :default<{}>); diff --git a/lib/SOAP/WSDL/Generator/Template.pm b/lib/SOAP/WSDL/Generator/Template.pm index 37dd9e4..bacbf04 100644 --- a/lib/SOAP/WSDL/Generator/Template.pm +++ b/lib/SOAP/WSDL/Generator/Template.pm @@ -1,11 +1,11 @@ package SOAP::WSDL::Generator::Template; -use strict; +use strict; use warnings; use Template; use Class::Std::Fast::Storable; use Carp; use SOAP::WSDL::Generator::PrefixResolver; -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %tt_of :ATTR(:get); my %definitions_of :ATTR(:name :default<()>); @@ -39,7 +39,8 @@ sub _process :PROTECTED { INCLUDE_PATH => $INCLUDE_PATH_of{ $ident }, OUTPUT_PATH => $OUTPUT_PATH_of{ $ident }, PLUGIN_BASE => 'SOAP::WSDL::Generator::Template::Plugin', - ); + ) + or die Template->error(); $tt->process( $template, { @@ -68,4 +69,4 @@ sub _process :PROTECTED { or croak $INCLUDE_PATH_of{ $ident }, '\\', $template, ' ', $tt->error(); } -1; \ No newline at end of file +1; diff --git a/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm b/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm index 02f5607..0e95bc0 100644 --- a/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm +++ b/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm @@ -4,7 +4,7 @@ use warnings; use Carp qw(confess); use Class::Std::Fast::Storable constructor => 'none'; -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %namespace_prefix_map_of :ATTR(:name :default<{}>); my %namespace_map_of :ATTR(:name :default<{}>); diff --git a/lib/SOAP/WSDL/Generator/Template/XSD.pm b/lib/SOAP/WSDL/Generator/Template/XSD.pm index c99f9c8..1404e08 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD.pm +++ b/lib/SOAP/WSDL/Generator/Template/XSD.pm @@ -1,11 +1,11 @@ package SOAP::WSDL::Generator::Template::XSD; -use strict; +use strict; use warnings; use Template; use Class::Std::Fast::Storable; use File::Basename; use File::Spec; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); use SOAP::WSDL::Generator::Visitor::Typemap; use SOAP::WSDL::Generator::Visitor::Typelib; diff --git a/lib/SOAP/WSDL/Generator/Visitor.pm b/lib/SOAP/WSDL/Generator/Visitor.pm index 1470558..8914bd6 100644 --- a/lib/SOAP/WSDL/Generator/Visitor.pm +++ b/lib/SOAP/WSDL/Generator/Visitor.pm @@ -3,7 +3,7 @@ use strict; use warnings; use Class::Std::Fast::Storable; -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %definitions_of :ATTR(:name :default<()>); my %type_prefix_of :ATTR(:name :default<()>); diff --git a/lib/SOAP/WSDL/Generator/Visitor/Typelib.pm b/lib/SOAP/WSDL/Generator/Visitor/Typelib.pm index 7c1a3a2..3ecdd41 100644 --- a/lib/SOAP/WSDL/Generator/Visitor/Typelib.pm +++ b/lib/SOAP/WSDL/Generator/Visitor/Typelib.pm @@ -5,7 +5,7 @@ use base qw(SOAP::WSDL::Generator::Visitor SOAP::WSDL::Generator::Template ); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); 1; diff --git a/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm b/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm index d22fe00..ad87e52 100644 --- a/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm +++ b/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm @@ -5,7 +5,7 @@ use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Generator::Visitor); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %path_of :ATTR(:name :default<[]>); my %typemap_of :ATTR(:name :default<()>); diff --git a/lib/SOAP/WSDL/Manual/Cookbook.pod b/lib/SOAP/WSDL/Manual/Cookbook.pod index 7329d35..b76eaf9 100644 --- a/lib/SOAP/WSDL/Manual/Cookbook.pod +++ b/lib/SOAP/WSDL/Manual/Cookbook.pod @@ -32,6 +32,15 @@ this backend: =head3 Accessing HTTP(S) webservices protected by NTLM authentication +You need the L distribution installed to access webservices protected +by NTLM authentication. More specifically, you need the Authen::NTLM module +from this distribution. Note that this is different from the Authen::NTML +distribution by Yee Man Chan also available from CPAN. + +Your user credentials usually need to include the windows domain like this: + + testdomain\testuser + Besides passing user credentials as when accessing a web service protected by basic or digest authentication, you also need to enforce connection keep_alive on the transport backens. @@ -130,4 +139,4 @@ Martin Kutter Emartin.kutter fen-net.deE $Id: $ $HeadURL: $ -=cut \ No newline at end of file +=cut diff --git a/lib/SOAP/WSDL/Manual/XSD.pod b/lib/SOAP/WSDL/Manual/XSD.pod index 4638527..d67ce4a 100644 --- a/lib/SOAP/WSDL/Manual/XSD.pod +++ b/lib/SOAP/WSDL/Manual/XSD.pod @@ -90,10 +90,8 @@ can just say Of course this will only work if MyTypes::NewType has a superset of the old object class' elements. -. -Future versions will restrict the data returned to the child element's data - -you should not expect XML attributes to be returned through hash refs. +Note that XML attribute data is not included in the hash ref output yet. =head1 HOW IT WORKS @@ -405,7 +403,7 @@ supported (yet). =item * import -The import includion element requires the schemaLocation attribute for +The import inclusion element requires the schemaLocation attribute for resolving the XML schema to import. Support for the import element is implemented in L, so alternative parsers may or may not support the import element. diff --git a/lib/SOAP/WSDL/Message.pm b/lib/SOAP/WSDL/Message.pm index 48892bd..1124a38 100644 --- a/lib/SOAP/WSDL/Message.pm +++ b/lib/SOAP/WSDL/Message.pm @@ -4,7 +4,7 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %part_of :ATTR(:name :default<[]>); diff --git a/lib/SOAP/WSDL/OpMessage.pm b/lib/SOAP/WSDL/OpMessage.pm index 2ea24b3..1a098d1 100644 --- a/lib/SOAP/WSDL/OpMessage.pm +++ b/lib/SOAP/WSDL/OpMessage.pm @@ -4,7 +4,7 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %body_of :ATTR(:name :default<[]>); my %header_of :ATTR(:name
:default<[]>); diff --git a/lib/SOAP/WSDL/Operation.pm b/lib/SOAP/WSDL/Operation.pm index f6655c8..76d86b7 100644 --- a/lib/SOAP/WSDL/Operation.pm +++ b/lib/SOAP/WSDL/Operation.pm @@ -4,7 +4,7 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %operation_of :ATTR(:name :default<()>); my %input_of :ATTR(:name :default<[]>); diff --git a/lib/SOAP/WSDL/Part.pm b/lib/SOAP/WSDL/Part.pm index 4799327..e32a4f5 100644 --- a/lib/SOAP/WSDL/Part.pm +++ b/lib/SOAP/WSDL/Part.pm @@ -6,7 +6,7 @@ use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %element_of :ATTR(:name :default<()>); my %type_of :ATTR(:name :default<()>); diff --git a/lib/SOAP/WSDL/Port.pm b/lib/SOAP/WSDL/Port.pm index 0e23d65..60ec970 100644 --- a/lib/SOAP/WSDL/Port.pm +++ b/lib/SOAP/WSDL/Port.pm @@ -4,7 +4,7 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %binding_of :ATTR(:name :default<()>); my %address_of :ATTR(:name
:default<()>); diff --git a/lib/SOAP/WSDL/PortType.pm b/lib/SOAP/WSDL/PortType.pm index 2f25959..1d2c10d 100644 --- a/lib/SOAP/WSDL/PortType.pm +++ b/lib/SOAP/WSDL/PortType.pm @@ -2,33 +2,26 @@ package SOAP::WSDL::PortType; use strict; use warnings; use Class::Std::Fast::Storable; +use List::Util; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %operation_of :ATTR(:name :default<()>); -my %attributes_of :ATTR(); +# +#=head2 find_operation +# +#$port_type->find_operation($namespace, $name) +# +#Returns the PortType's operation object matching the given namespace and +#name +# -%attributes_of = ( - operation => \%operation_of, -); - -# Function factory - we could be writing this method for all %attribute -# keys, too, but that's just C&P (eehm, Copy & Paste...) -foreach my $method(keys %attributes_of ) { - no strict qw(refs); ## no critic ProhibitNoStrict - - # ... btw, we mean this method here... - *{ "find_$method" } = sub { - my ($self, @args) = @_; - my @found_at = grep { - $_->get_targetNamespace() eq $args[0] && - $_->get_name() eq $args[1] - } - @{ $attributes_of{ $method }->{ ident $self } }; - return $found_at[0]; - }; -} +sub find_operation { + return List::Util::first { + ( $_->get_targetNamespace() eq $_[1] ) && ( $_->get_name() eq $_[2] ) + } @{ $operation_of{ ${ $_[0] } } }; +}; 1; diff --git a/lib/SOAP/WSDL/SOAP/Address.pm b/lib/SOAP/WSDL/SOAP/Address.pm index 4126885..7a0ee16 100644 --- a/lib/SOAP/WSDL/SOAP/Address.pm +++ b/lib/SOAP/WSDL/SOAP/Address.pm @@ -4,7 +4,7 @@ use warnings; use base qw(SOAP::WSDL::Base); use Class::Std::Fast::Storable; -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %location :ATTR(:name :default<()>); 1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/SOAP/Body.pm b/lib/SOAP/WSDL/SOAP/Body.pm index 4ac3847..176e0c6 100644 --- a/lib/SOAP/WSDL/SOAP/Body.pm +++ b/lib/SOAP/WSDL/SOAP/Body.pm @@ -4,7 +4,7 @@ use warnings; use base qw(SOAP::WSDL::Base); use Class::Std::Fast::Storable; -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); my %use_of :ATTR(:name :default); my %namespace_of :ATTR(:name :default); diff --git a/lib/SOAP/WSDL/SOAP/Header.pm b/lib/SOAP/WSDL/SOAP/Header.pm index aadac6e..5460c2c 100644 --- a/lib/SOAP/WSDL/SOAP/Header.pm +++ b/lib/SOAP/WSDL/SOAP/Header.pm @@ -4,7 +4,7 @@ use warnings; use base qw(SOAP::WSDL::Base); use Class::Std::Fast::Storable; -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %use_of :ATTR(:name :default); my %namespace_of :ATTR(:name :default); diff --git a/lib/SOAP/WSDL/SOAP/HeaderFault.pm b/lib/SOAP/WSDL/SOAP/HeaderFault.pm index f641ab0..5e12ff1 100644 --- a/lib/SOAP/WSDL/SOAP/HeaderFault.pm +++ b/lib/SOAP/WSDL/SOAP/HeaderFault.pm @@ -3,6 +3,6 @@ use strict; use warnings; use base qw(SOAP::WSDL::Header); -use version; our $VERSION = qv('2.00.04'); +use version; our $VERSION = qv('2.00.05'); 1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/SOAP/Operation.pm b/lib/SOAP/WSDL/SOAP/Operation.pm index 1ae0599..ab77c87 100644 --- a/lib/SOAP/WSDL/SOAP/Operation.pm +++ b/lib/SOAP/WSDL/SOAP/Operation.pm @@ -4,7 +4,7 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -use version; our $VERSION = qv('2.00.03'); +use version; our $VERSION = qv('2.00.05'); my %style_of :ATTR(:name