diff --git a/Build.PL b/Build.PL index f9c6514..e344043 100644 --- a/Build.PL +++ b/Build.PL @@ -2,10 +2,10 @@ use Module::Build; use version; $build = Module::Build->new( dist_author => 'Martin Kutter ', - create_makefile_pl => 'passthrough', + create_makefile_pl => 'small', dist_abstract => 'SOAP with WSDL support', dist_name => 'SOAP-WSDL', - dist_version => '2.00_32', + dist_version => '2.00_33', module_name => 'SOAP::WSDL', license => 'artistic', requires => { @@ -13,7 +13,7 @@ $build = Module::Build->new( # for us. SOAP-WSDL relies on unicode (WS-I demands it) # and triggers several 5.6 bugs... 'perl' => q(5.8.0), - 'Class::Std::Fast' => qv(0.0.5), + 'Class::Std::Fast' => q(0.0.5), 'Data::Dumper' => 0, 'Date::Parse' => 0, 'Date::Format' => 0, @@ -27,14 +27,15 @@ $build = Module::Build->new( 'URI' => 0, 'XML::Parser::Expat' => 0, }, - buildrequires => { - 'Class::Std::Fast' => qv(0.0.5), + build_requires => { + 'Class::Std::Fast' => q(0.0.5), 'Cwd' => 0, 'Date::Parse' => 0, 'Date::Format' => 0, 'Getopt::Long' => 0, 'List::Util' => 0, 'LWP::UserAgent' => 0, + 'Module::Build' => 0, 'File::Basename' => 0, 'File::Path' => 0, 'File::Spec' => 0, diff --git a/Changes b/Changes index fc2fde8..5d29f66 100644 --- a/Changes +++ b/Changes @@ -1,4 +1,4 @@ -Release notes for SOAP::WSDL 2.00_32 +Release notes for SOAP::WSDL 2.00_33 ------- I'm proud to present a new pre-release version of SOAP::WSDL. @@ -34,7 +34,41 @@ Features: The following changes have been made: -2.00_32 +2.00_33 - Mar 30 2008 + +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1925336 ] Create a Prefix Resolver Plugin Interface for Code Generator + * [ 1898591 ] object stringify returns undef + * [ 1906753 ] Hypens in MyTypes/* cause runtime syntax errors + Hypens and dots in variable and method names are now replaced by _ + +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/). + + * #33616: Bugs in the META.yml file + * [ 1892895 ] Test failures on RHEL4 + * [ 1844956 ] t/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS fails test on OS X + * #33376: HTTP Authentication (not implemented or not documented) + +The following uncategorized improvements have been made: + + * Some minor performance improvements have been made + * The XSD generator now asserts the soap:operation style is "document" + * and now import namespace declarations, too + * The XSD generator now uses the relevant 's + targetNamespace for finding operation messages, not the + element's targetNamespace + * Attribute handling has been improved so it could possibly work. + Attributes from different namespaces are probably still broken. + * Attribute ref handling has been added (though probably broken on + ref cascades). + * elements are now parsed, but have no effect yet. + * elements are now parsed, but have no effect yet. + +2.00_32 - Feb 14 2008 The following features were added (the numbers in square brackets are the tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): diff --git a/MANIFEST b/MANIFEST index 0659c65..2fda1aa 100644 --- a/MANIFEST +++ b/MANIFEST @@ -3,6 +3,7 @@ benchmark/hello.pl benchmark/person.pl benchmark/person.xml benchmark/person_profile.pl +benchmark/person_single.pl benchmark/XSD/01_anyType.t benchmark/XSD/02_anySimpleType.t benchmark/XSD/03_string.t @@ -92,10 +93,12 @@ lib/SOAP/WSDL/Factory/Deserializer.pm lib/SOAP/WSDL/Factory/Generator.pm lib/SOAP/WSDL/Factory/Serializer.pm lib/SOAP/WSDL/Factory/Transport.pm +lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm +lib/SOAP/WSDL/Generator/PrefixResolver.pm lib/SOAP/WSDL/Generator/Template.pm lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm lib/SOAP/WSDL/Generator/Template/XSD.pm -lib/SOAP/WSDL/Generator/Template/XSD/_type_class.tt +lib/SOAP/WSDL/Generator/Template/XSD/attribute.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/all.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/atomicTypes.tt @@ -104,15 +107,23 @@ lib/SOAP/WSDL/Generator/Template/XSD/complexType/complexContent.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/contentModel.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/all.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/attributeSet.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/choice.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/complexContent.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/content_model.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/extension.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/restriction.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/restriction.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/simpleContent.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent/extension.tt lib/SOAP/WSDL/Generator/Template/XSD/complexType/variety.tt lib/SOAP/WSDL/Generator/Template/XSD/element.tt +lib/SOAP/WSDL/Generator/Template/XSD/element/POD/contentModel.tt lib/SOAP/WSDL/Generator/Template/XSD/element/POD/structure.tt lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt @@ -124,6 +135,7 @@ lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/method_info.tt lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Operation.tt lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Part.tt lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Type.tt +lib/SOAP/WSDL/Generator/Template/XSD/POD/annotation.tt lib/SOAP/WSDL/Generator/Template/XSD/Server.tt lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/Message.tt lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/method_info.tt @@ -133,10 +145,13 @@ lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt lib/SOAP/WSDL/Generator/Template/XSD/simpleType/atomicType.tt lib/SOAP/WSDL/Generator/Template/XSD/simpleType/contentModel.tt lib/SOAP/WSDL/Generator/Template/XSD/simpleType/list.tt +lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/contentModel.tt lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/list.tt lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/restriction.tt lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/structure.tt +lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/union.tt lib/SOAP/WSDL/Generator/Template/XSD/simpleType/restriction.tt +lib/SOAP/WSDL/Generator/Template/XSD/simpleType/union.tt lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt lib/SOAP/WSDL/Generator/Visitor.pm lib/SOAP/WSDL/Generator/Visitor/Typelib.pm @@ -169,13 +184,27 @@ lib/SOAP/WSDL/Transport/Loopback.pm lib/SOAP/WSDL/Transport/Test.pm lib/SOAP/WSDL/TypeLookup.pm lib/SOAP/WSDL/Types.pm +lib/SOAP/WSDL/XSD/Annotation.pm lib/SOAP/WSDL/XSD/Attribute.pm +lib/SOAP/WSDL/XSD/AttributeGroup.pm lib/SOAP/WSDL/XSD/Builtin.pm lib/SOAP/WSDL/XSD/ComplexType.pm lib/SOAP/WSDL/XSD/Element.pm +lib/SOAP/WSDL/XSD/Enumeration.pm +lib/SOAP/WSDL/XSD/FractionDigits.pm +lib/SOAP/WSDL/XSD/Group.pm +lib/SOAP/WSDL/XSD/Length.pm +lib/SOAP/WSDL/XSD/MaxExclusive.pm +lib/SOAP/WSDL/XSD/MaxInclusive.pm +lib/SOAP/WSDL/XSD/MaxLength.pm +lib/SOAP/WSDL/XSD/MinExclusive.pm +lib/SOAP/WSDL/XSD/MinInclusive.pm +lib/SOAP/WSDL/XSD/MinLength.pm +lib/SOAP/WSDL/XSD/Pattern.pm lib/SOAP/WSDL/XSD/Schema.pm lib/SOAP/WSDL/XSD/Schema/Builtin.pm lib/SOAP/WSDL/XSD/SimpleType.pm +lib/SOAP/WSDL/XSD/TotalDigits.pm lib/SOAP/WSDL/XSD/Typelib/Attribute.pm lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm lib/SOAP/WSDL/XSD/Typelib/Builtin.pm @@ -228,12 +257,14 @@ lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm lib/SOAP/WSDL/XSD/Typelib/Element.pm lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm +lib/SOAP/WSDL/XSD/WhiteSpace.pm LICENSE Makefile.PL MANIFEST This list of files META.yml MIGRATING README +SOAP-WSDL-2.00_32.tar t/001_use.t t/002_parse_wsdl.t t/003_wsdl_based_serializer.t @@ -287,6 +318,7 @@ t/acceptance/wsdl/generator_unsupported_test.wsdl t/acceptance/wsdl/import.xsd t/acceptance/wsdl/import_loop.xsd t/acceptance/wsdl/message_gateway.wsdl +t/acceptance/wsdl/nested_complextype.wsdl t/acceptance/wsdl/WSDLParser-import.wsdl t/acceptance/wsdl/WSDLParser-imported.wsdl t/acceptance/wsdl/WSDLParser.wsdl @@ -296,7 +328,10 @@ t/Expat/03_wsdl.t t/lib/MyComplexType.pm t/lib/MyElement.pm t/lib/MySimpleType.pm -t/lib/Test/SOAPMessage.pm +t/lib/Test/SOAP/WSDL/Expat/WSDLParser.pm +t/lib/Test/SOAP/WSDL/Generator/Iterator/WSDL11.pm +t/lib/Test/SOAP/WSDL/Generator/Visitor/Typemap.pm +t/lib/Test/SOAP/WSDL/Tester.pm t/lib/Typelib/Base.pm t/lib/Typelib/TEnqueueMessage.pm t/lib/Typelib/TMessage.pm @@ -331,12 +366,13 @@ t/SOAP/WSDL/Expat/WSDLParser.t t/SOAP/WSDL/Factory/Deserializer.t t/SOAP/WSDL/Factory/Serializer.t t/SOAP/WSDL/Factory/Transport.t +t/SOAP/WSDL/Generator/attr.pl t/SOAP/WSDL/Generator/Template.t t/SOAP/WSDL/Generator/Visitor.t t/SOAP/WSDL/Generator/Visitor/Typemap.t -t/SOAP/WSDL/Generator/XCS.t t/SOAP/WSDL/Generator/XSD.t t/SOAP/WSDL/Generator/XSD_dot_names.t +t/SOAP/WSDL/Generator/XSD_nested_complextype.t t/SOAP/WSDL/Generator/XSD_unsupported.t t/SOAP/WSDL/Part.t t/SOAP/WSDL/PortType.t @@ -348,9 +384,13 @@ 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/Types.t t/SOAP/WSDL/XSD/Attribute.t +t/SOAP/WSDL/XSD/AttributeGroup.t +t/SOAP/WSDL/XSD/Builtin.t t/SOAP/WSDL/XSD/ComplexType.t t/SOAP/WSDL/XSD/Element.t +t/SOAP/WSDL/XSD/Enumeration.t t/SOAP/WSDL/XSD/Schema.t t/SOAP/WSDL/XSD/SimpleType.t t/SOAP/WSDL/XSD/Typelib/Attribute.t diff --git a/META.yml b/META.yml index 5c8c07f..9580def 100644 --- a/META.yml +++ b/META.yml @@ -1,6 +1,6 @@ --- name: SOAP-WSDL -version: 2.00_32 +version: 2.00_33 author: - 'Martin Kutter ' abstract: SOAP with WSDL support @@ -8,13 +8,7 @@ license: artistic resources: license: http://opensource.org/licenses/artistic-license.php requires: - Class::Std::Fast: !!perl/hash:version - original: v0.0.5 - qv: 1 - version: - - 0 - - 0 - - 5 + Class::Std::Fast: 0.0.5 Data::Dumper: 0 Date::Format: 0 Date::Parse: 0 @@ -28,10 +22,26 @@ requires: URI: 0 XML::Parser::Expat: 0 perl: 5.8.0 +build_requires: + Class::Std::Fast: 0.0.5 + Cwd: 0 + Date::Format: 0 + Date::Parse: 0 + File::Basename: 0 + File::Path: 0 + File::Spec: 0 + Getopt::Long: 0 + LWP::UserAgent: 0 + List::Util: 0 + Module::Build: 0 + Storable: 0 + Template: 0 + Test::More: 0 + XML::Parser::Expat: 0 provides: SOAP::WSDL: file: lib/SOAP/WSDL.pm - version: 2.00_32 + version: 2.00_33 SOAP::WSDL::Base: file: lib/SOAP/WSDL/Base.pm version: 2.00_27 @@ -42,10 +52,10 @@ provides: version: 2.00_27 SOAP::WSDL::Client::Base: file: lib/SOAP/WSDL/Client/Base.pm - version: 2.00_25 + version: 2.00_33 SOAP::WSDL::Definitions: file: lib/SOAP/WSDL/Definitions.pm - version: 2.00_27 + version: 2.00_33 SOAP::WSDL::Deserializer::Hash: file: lib/SOAP/WSDL/Deserializer/Hash.pm version: 2.00_25 @@ -78,10 +88,14 @@ provides: version: 2.00_24 SOAP::WSDL::Factory::Transport: file: lib/SOAP/WSDL/Factory/Transport.pm - version: 2.00_31 + version: 2.00_33 + SOAP::WSDL::Generator::Iterator::WSDL11: + file: lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm + SOAP::WSDL::Generator::PrefixResolver: + file: lib/SOAP/WSDL/Generator/PrefixResolver.pm SOAP::WSDL::Generator::Template: file: lib/SOAP/WSDL/Generator/Template.pm - version: 2.00_25 + version: v2.0033 SOAP::WSDL::Generator::Template::Plugin::XSD: file: lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm SOAP::WSDL::Generator::Template::XSD: @@ -129,7 +143,7 @@ provides: version: 2.00_27 SOAP::WSDL::Server::CGI: file: lib/SOAP/WSDL/Server/CGI.pm - version: 2.00_27 + version: 2.00_33 SOAP::WSDL::Service: file: lib/SOAP/WSDL/Service.pm SOAP::WSDL::Transport::HTTP: @@ -145,25 +159,64 @@ provides: version: 2.00_31 SOAP::WSDL::Types: file: lib/SOAP/WSDL/Types.pm + SOAP::WSDL::XSD::Annotation: + file: lib/SOAP/WSDL/XSD/Annotation.pm + version: 2.00_33 SOAP::WSDL::XSD::Attribute: file: lib/SOAP/WSDL/XSD/Attribute.pm version: 2.00_29 + SOAP::WSDL::XSD::AttributeGroup: + file: lib/SOAP/WSDL/XSD/AttributeGroup.pm + version: 2.00_29 SOAP::WSDL::XSD::Builtin: file: lib/SOAP/WSDL/XSD/Builtin.pm SOAP::WSDL::XSD::ComplexType: file: lib/SOAP/WSDL/XSD/ComplexType.pm - version: 2.00_29 + version: 2.00_33 SOAP::WSDL::XSD::Element: file: lib/SOAP/WSDL/XSD/Element.pm version: 2.00_25 + SOAP::WSDL::XSD::Enumeration: + file: lib/SOAP/WSDL/XSD/Enumeration.pm + version: 2.00_33 + SOAP::WSDL::XSD::Group: + file: lib/SOAP/WSDL/XSD/Group.pm + version: 2.00_33 + SOAP::WSDL::XSD::Length: + file: lib/SOAP/WSDL/XSD/Length.pm + version: 2.00_33 + SOAP::WSDL::XSD::MaxExclusive: + file: lib/SOAP/WSDL/XSD/MaxExclusive.pm + version: 2.00_33 + SOAP::WSDL::XSD::MaxInclusive: + file: lib/SOAP/WSDL/XSD/MaxInclusive.pm + version: 2.00_33 + SOAP::WSDL::XSD::MaxLength: + file: lib/SOAP/WSDL/XSD/MaxLength.pm + version: 2.00_33 + SOAP::WSDL::XSD::MinExclusive: + file: lib/SOAP/WSDL/XSD/MinExclusive.pm + version: 2.00_33 + SOAP::WSDL::XSD::MinInclusive: + file: lib/SOAP/WSDL/XSD/MinInclusive.pm + version: 2.00_33 + SOAP::WSDL::XSD::MinLength: + file: lib/SOAP/WSDL/XSD/MinLength.pm + version: 2.00_33 + SOAP::WSDL::XSD::Pattern: + file: lib/SOAP/WSDL/XSD/Pattern.pm + version: 2.00_33 SOAP::WSDL::XSD::Schema: file: lib/SOAP/WSDL/XSD/Schema.pm - version: 2.00_25 + version: 2.00_33 SOAP::WSDL::XSD::Schema::Builtin: file: lib/SOAP/WSDL/XSD/Schema/Builtin.pm SOAP::WSDL::XSD::SimpleType: file: lib/SOAP/WSDL/XSD/SimpleType.pm version: 2.00_25 + SOAP::WSDL::XSD::TotalDigits: + file: lib/SOAP/WSDL/XSD/TotalDigits.pm + version: 2.00_33 SOAP::WSDL::XSD::Typelib::Attribute: file: lib/SOAP/WSDL/XSD/Typelib/Attribute.pm version: 2.00_29 @@ -270,7 +323,7 @@ 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.00_31 + version: 2.00_33 SOAP::WSDL::XSD::Typelib::Element: file: lib/SOAP/WSDL/XSD/Typelib/Element.pm version: 2.00_29 @@ -278,6 +331,9 @@ provides: file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm SOAP::WSDL::XSD::Typelib::SimpleType::restriction: file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm + SOAP::WSDL::XSD::WhiteSpace: + file: lib/SOAP/WSDL/XSD/WhiteSpace.pm + version: 2.00_33 generated_by: Module::Build version 0.2808 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html diff --git a/MIGRATING b/MIGRATING index 13fb2ad..51daac5 100644 --- a/MIGRATING +++ b/MIGRATING @@ -1,5 +1,18 @@ MIGRATING --------- +MIGRATING FROM PRE-2.00_33 +-------------------------- +The handling of stringification of SOAP::WSDL::XSD simpleType objects with +undef values changed in 2.00_33. + +While 2.00_32 and before returned undef on stringification of a undef value, +>=2.00_33 now returns an empty string. + +This is due to common usage in templates or the like, where undef is likely +to produce a warning, and the unreliable behavior of + $obj eq undef +which behaves differently in different versions of perl. + MIGRATING FROM PRE-2.00_29 -------------------------- @@ -9,7 +22,7 @@ require the class SOAP::WSDL::XSD::Typelib::Attribute introduced in the same pre-release. While interfaces generated with pre-releases back to 2.00_25 work without -change, this does not hold true vice versa: Interfaces generated with +change, this does not hold true vice versa: Interfaces generated with 2.00_29 and above won't work with older pre-releases. You'll have to update SOAP::WSDL on all your machines. @@ -17,7 +30,7 @@ You'll have to update SOAP::WSDL on all your machines. MIGRATING FROM PRE-2.00_24 -------------------------- -This section describes how to migrate from 2.00_24 and before versions to +This section describes how to migrate from 2.00_24 and before versions to 2.00_25. Migrating from 2.00_xx @@ -25,9 +38,9 @@ Migrating from 2.00_xx Background -SOAP::WSDL 2.00_xx has used Class::Std as base for its inside out objects +SOAP::WSDL 2.00_xx has used Class::Std as base for its inside out objects up to 2.00_24. For performance reasons, now Class::Std::Fast is used. -As Class::Std::Fast is a drop-in replacement for Class::Std, there should be +As Class::Std::Fast is a drop-in replacement for Class::Std, there should be no need to change anything in your (handwritten) code. Generated interfaces @@ -42,8 +55,8 @@ Typemaps SOAP::WSDL now tries to load all typemap classes at once from 2.00_25 on. -If you use __SKIP__ in your typemaps, you'll have to comment out all -path deeper than the path marked with __SKIP__ - if you don't, SOAP::WSDL +If you use __SKIP__ in your typemaps, you'll have to comment out all +paths deeper than the path marked with __SKIP__ - if you don't, SOAP::WSDL will try to load all correspondent classes. Migrating from 1.xx @@ -55,7 +68,7 @@ SOAP::WSDL uses a custom WSDL parser and serializer. It does not rely on XPath for on the fly WSDL processing, nor does it use SOAP::Data objects for encoding any more. -You should be able to use your wxisting code under most circumstances. +You should be able to use your existing code under most circumstances. SOAP::WSDL is the compatibility module for old interfaces. Overloading diff --git a/Makefile.PL b/Makefile.PL index 192903a..2d25812 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,30 +1,5 @@ # Note: this file was auto-generated by Module::Build::Compat version 0.03 - - unless (eval "use Module::Build::Compat 0.02; 1" ) { - print "This module requires Module::Build to install itself.\n"; - - require ExtUtils::MakeMaker; - my $yn = ExtUtils::MakeMaker::prompt - (' Install Module::Build now from CPAN?', 'y'); - - unless ($yn =~ /^y/i) { - die " *** Cannot install without Module::Build. Exiting ...\n"; - } - - require Cwd; - require File::Spec; - require CPAN; - - # Save this 'cause CPAN will chdir all over the place. - my $cwd = Cwd::cwd(); - - CPAN::Shell->install('Module::Build::Compat'); - CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate - or die "Couldn't install Module::Build, giving up.\n"; - - chdir $cwd or die "Cannot chdir() back to $cwd: $!"; - } - eval "use Module::Build::Compat 0.02; 1" or die $@; + use Module::Build::Compat 0.02; Module::Build::Compat->run_build_pl(args => \@ARGV); require Module::Build; diff --git a/README b/README index d7e76c8..77ac657 100644 --- a/README +++ b/README @@ -3,7 +3,25 @@ INTRO SOAP-WSDL provides a SOAP client with WSDL support. -This is a developer release - everything may (and most things will) change. +SUBCLASSING +----------- + +SOAP-WSDL is still under very active development. Please don't build +applications using the following modules directly: + + - SOAP::WSDL::Definitions + - SOAP::WSDL::Port + - SOAP::WSDL::PortType + - SOAP::WSDL::Binding + - SOAP::WSDL::Message + - SOAP::WSDL::Operation + - SOAP::WSDL::OpMessage + - SOAP::WSDL::Part + - SOAP::WSDL::Service + - SOAP::WSDL::Types + - SOAP::WSDL::XSD::Schema + +Those will be replaced some time in the future. INSTALLING ---------- @@ -15,12 +33,12 @@ Use the following mantra: perl Build test perl Build install -If you don't have Module::Build installed, you may also use +If you don't have Module::Build installed, you may also use perl Makefile.PL - make + make make test make install -Note that Module::Build is the recommended installer - make will not run +Note that Module::Build is the recommended installer - make will not run all tests provided with SOAP-WSDL. \ No newline at end of file diff --git a/SOAP-WSDL-2.00_32.tar b/SOAP-WSDL-2.00_32.tar new file mode 100644 index 0000000..943f12b Binary files /dev/null and b/SOAP-WSDL-2.00_32.tar differ diff --git a/benchmark/person.pl b/benchmark/person.pl index 1e085b0..6742af3 100644 --- a/benchmark/person.pl +++ b/benchmark/person.pl @@ -39,8 +39,7 @@ $lite->on_action( sub { 'http://www.example.org/benchmark/ListPerson' } ); SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' ); my $wsdl_xs = MyInterfaces::TestService::TestPort->new(); -# trigger loading of XML Data -my $count = 100; +my $count = 70; my @data = (); my $n = 0; print "Benchmark conducted with @@ -54,22 +53,22 @@ Benchmark $n: Store result in private variable and destroy it $n++; cmpthese $count, { # 'XML::Simple' => sub { my $result = XMLin( MyData::xml() )}, - 'SOAP::WSDL' => sub { my $result = $soap->ListPerson({}) }, - 'XML::Compile' => sub { my $result = $call->() }, +# 'SOAP::WSDL' => sub { my $result = $soap->ListPerson({}) }, +# 'XML::Compile' => sub { my $result = $call->() }, 'SOAP::WSDL_XS' => sub { my $result = $wsdl_xs->ListPerson({}) }, # 'SOAP::Lite' => sub { my $result = $deserializer->deserialize( MyData::xml() )}, - 'SOAP::Lite' => sub { my $som = $lite->call('ListPerson') }, +# 'SOAP::Lite' => sub { my $som = $lite->call('ListPerson') }, }; print "\nBenchmark $n: Push result on list\n"; $n++; cmpthese $count, { # 'XML::Simple' => sub { push @data, XMLin( MyData::xml() )}, - 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) }, - 'XML::Compile' => sub { push @data, $call->() }, +# 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) }, +# 'XML::Compile' => sub { push @data, $call->() }, 'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) }, # 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )} - 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') }, +# 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') }, }; @data = (); @@ -77,10 +76,10 @@ print "\nBenchmark $n: Play it again, Sam\n"; cmpthese $count, { # 'XML::Simple' => sub { push @data, XMLin( MyData::xml() )}, - 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) }, +# 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) }, 'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) }, - 'XML::Compile' => sub { push @data, $call->() }, +# 'XML::Compile' => sub { push @data, $call->() }, # 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )} - 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') }, +# 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') }, }; diff --git a/benchmark/person_profile.pl b/benchmark/person_profile.pl index db35420..af39c40 100644 --- a/benchmark/person_profile.pl +++ b/benchmark/person_profile.pl @@ -3,9 +3,17 @@ use lib '../example/lib'; use lib '../../SOAP-WSDL_XS/blib/lib'; use lib '../../SOAP-WSDL_XS/blib/arch'; use strict; +# use Benchmark; +use SOAP::WSDL::Deserializer::XSD_XS; +use SOAP::WSDL::Factory::Deserializer; +# # register for SOAP 1.1 +SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' ); use MyInterfaces::TestService::TestPort; my $soap = MyInterfaces::TestService::TestPort->new(); # Load all classes - XML::Compile has created everything before, too -for (1..100) { $soap->ListPerson({}) }; +if (@ARGV) { print $soap->ListPerson({}) } +else { + $soap->ListPerson({}) +} diff --git a/benchmark/person_single.pl b/benchmark/person_single.pl new file mode 100644 index 0000000..1b4e7cb --- /dev/null +++ b/benchmark/person_single.pl @@ -0,0 +1,41 @@ +use lib '../lib'; +use lib '../example/lib'; +use lib '../../SOAP-WSDL_XS/blib/lib'; +use lib '../../SOAP-WSDL_XS/blib/arch'; +use strict; +use Benchmark; +#use SOAP::WSDL::Deserializer::XSD_XS; +use SOAP::WSDL::Factory::Deserializer; +# # register for SOAP 1.1 +SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' ); +SOAP::WSDL::Factory::Transport->register('http' => 'Transport'); + +use MyInterfaces::TestService::TestPort; +my @data = (); +my $soap = MyInterfaces::TestService::TestPort->new(); + +# Load all classes - XML::Compile has created everything before, too +timethis 100, sub { $soap->ListPerson({}) }; +#timethis 50, sub { push @data, $soap->ListPerson({}) }; +#@data = (); +# timethis 50, sub { push @data, $soap->ListPerson({}) }; + +# for (1..50) { push @data, $soap->ListPerson({}) }; +#print $soap->ListPerson({}); + +package Transport; +use Class::Std::Fast; +sub send_receive { +return <<'EOT'; + + + +1Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract31Salutation0Name0Martin1970-01-01Street 000000City0Country0++499131123456++49150123456Somestreet 2312345SomeCityGermany++499131123456++49150123456100000SomeContract0100001SomeContract1100002SomeContract2100003SomeContract3}; + + +EOT +} diff --git a/bin/wsdl2perl.pl b/bin/wsdl2perl.pl index 1369096..5911659 100644 --- a/bin/wsdl2perl.pl +++ b/bin/wsdl2perl.pl @@ -19,6 +19,7 @@ my %opt = ( proxy => undef, generator => 'XSD', server => 0, + namespace => 0, ); { # a block just to scope "no warnings" @@ -34,12 +35,14 @@ my %opt = ( ReadMode 1; $user = ReadLine(); ReadMode 0; + chomp $user; }; if (not $password = delete $opt{password}) { print 'Password:'; ReadMode 2; - $user = ReadLine; + $password = ReadLine; ReadMode 0; + chomp $password; }; return ($user, $password); }; @@ -61,6 +64,7 @@ GetOptions(\%opt, password=s generator=s server + namespaces|n ) ); diff --git a/example/cgi-bin/person.pl b/example/cgi-bin/person.pl index 6ef8588..8527825 100755 --- a/example/cgi-bin/person.pl +++ b/example/cgi-bin/person.pl @@ -2,7 +2,7 @@ package main; use strict; use warnings; -#use lib qw(../lib ../../lib); +use lib qw(../lib ../../lib); use MyElements::ListPersonResponse; use MyServer::TestService::TestPort; my $server = MyServer::TestService::TestPort->new({ diff --git a/lib/SOAP/WSDL.pm b/lib/SOAP/WSDL.pm index a34135d..370ea37 100644 --- a/lib/SOAP/WSDL.pm +++ b/lib/SOAP/WSDL.pm @@ -14,7 +14,7 @@ use Class::Std::Fast; use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; use LWP::UserAgent; -our $VERSION= '2.00_32'; +our $VERSION= '2.00_33'; my %no_dispatch_of :ATTR(:name); my %wsdl_of :ATTR(:name); @@ -330,6 +330,17 @@ read L. For using an interpreting (thus slow and somewhat troublesome) WSDL based SOAP client, which mimics L's API, read on. +Creating Interface classes is the recommended usage. + +Did I say you should create interface classes following the steps in +L? + +If you're migrating from earlier versions of SOAP::WSDL, you should read the +MIGRATING documentation. + +The stuff below is for users of the 1.2x SOAP::WSDL series. All others, +please refer to L + =head1 SYNOPSIS my $soap = SOAP::WSDL->new( @@ -522,6 +533,28 @@ You may pass the servicename and portname as attributes to wsdlinit, though. =back +=head1 Differences to previous versions + +The following functionality is no longer supported: + +=head2 Operation overloading + +The SOAP standard allows operation overloading - that is, you may specify +SOAP operations with more than one message. The client/server than can +choose which message to send. This SOAP feature is usually used similar +to the use of methods with different argument lists in C++. + +Operation overloading is no longer supported. The WS-I Basic profile does +not operation overloading. The same functionality as operation overloading +can be obtained by using a choice declaration in the XML Schema. + +=head2 readable + +Readable has no effect any more. If you need readable debug output, copy the +SOAP message to your favorite XML editor and run the source format command. +Outputting readable XML requires lots of programming for little use: The +resulting XMl is still quite unreadable. + =head1 Differences to SOAP::Lite =head2 readable @@ -604,6 +637,18 @@ details. =over +=item * $obj == undef does not work in perl 5.8.6 and perl 5.8.7 + +Due to some strange behaviour in perl 5.8.6 and perl 5.8.7, stringification +overloading is not triggered during comparison with undef. + +While this is probably harmless in most cases, it's important to know that +you need to do + + defined( $obj->get_value() ) + +to check for undef values in simpleType objects. + =item * perl 5.8.0 or higher required SOAP::WSDL needs perl 5.8.0 or higher. This is due to a bug in perls @@ -617,14 +662,16 @@ If you want this changed, email me a copy of the specs, please. =item * Incomplete XML Schema definitions support -XML Schema attribute definitions are not supported yet. +This section describes the limitations of SOAP::WSDL, that is the interpreting +SOAP client. For limitations of L generated +SOAP clients, see L. -Importing external definitions is not supported yet. +XML Schema attribute definitions are not supported in interpreting mode. -The following XML Schema definitions varieties are not supported: +The following XML Schema definitions varieties are not supported in +interpreting mod: group - union simpleContent The following XML Schema definition content model is only partially @@ -712,20 +759,29 @@ became v1.23) David Bussenschutt, Damian A. Martinez Gelabert, Dennis S. Hennen, Dan Horne, Peter Orvos, Mark Overmeer, Jon Robens, Isidro Vila Verde and Glenn Wood -spotted bugs and/or suggested improvements in the 1.2x releases. +(in alphabetical order) spotted bugs and/or suggested improvements in +the 1.2x releases. Andreas 'ac0v' Specht constantly asked for better performance. -JT Justman provided early feedback for the 2.xx pre-releases. +JT Justman and Noah Robin provided early feedback and bug reports for +the 2.xx pre-releases. + +Adam Kennedy checked and suggested improvements on metadata and dependencies +in the 2.xx pre-releases. + +CPAN Testers have provided most valuable (automated) feedback. Thanks. Numerous people sent me their real-world WSDL files for testing. Thank you. Paul Kulchenko and Byrne Reese wrote and maintained SOAP::Lite and thus provided a base (and counterpart) for SOAP::WSDL. +Mark Overmeer wrote XML::Compile::SOAP - competition is good for business. + =head1 LICENSE AND COPYRIGHT -Copyright 2004-2007 Martin Kutter. +Copyright 2004-2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself @@ -736,10 +792,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 534 $ + $Rev: 583 $ $LastChangedBy: kutterma $ - $Id: WSDL.pm 534 2008-02-14 17:07:18Z kutterma $ + $Id: WSDL.pm 583 2008-03-24 07:44: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 ff99ac1..2ff5726 100644 --- a/lib/SOAP/WSDL/Base.pm +++ b/lib/SOAP/WSDL/Base.pm @@ -7,16 +7,28 @@ use Carp qw(croak carp confess); our $VERSION='2.00_27'; -my %id_of :ATTR(:name :default<()>); -my %name_of :ATTR(:name :default<()>); -my %documentation_of :ATTR(:name :default<()>); -my %targetNamespace_of :ATTR(:name :default<()>); -my %xmlns_of :ATTR(:name :default<{}>); -my %parent_of :ATTR(:name :default<()>); +my %id_of :ATTR(:name :default<()>); +my %lang_of :ATTR(:name :default<()>); +my %name_of :ATTR(:name :default<()>); +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 %namespaces_of :ATTR(:default<{}>); + +sub namespaces { + return shift->get_xmlns(); +} sub START { my ($self, $ident, $arg_ref) = @_; $xmlns_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' }; + $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 { @@ -87,7 +99,12 @@ sub AUTOMETHOD { return $result_ref->[0]; }; } - confess "$subname not found in class " . ref $self; + + # 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; } sub init { @@ -109,8 +126,8 @@ sub init { } sub expand { - my ($self, , $qname) = @_; - my $ns_of = $self->get_xmlns(); + my ($self, $qname) = @_; + my $ns_of = $self->namespaces(); if (not $qname=~m{:}xm) { die "un-prefixed element name <$qname> found, but no default namespace set\n" if not defined $ns_of->{ '#default' }; diff --git a/lib/SOAP/WSDL/Client/Base.pm b/lib/SOAP/WSDL/Client/Base.pm index ccf31e0..8e1f201 100644 --- a/lib/SOAP/WSDL/Client/Base.pm +++ b/lib/SOAP/WSDL/Client/Base.pm @@ -4,21 +4,21 @@ use warnings; use base 'SOAP::WSDL::Client'; use Scalar::Util qw(blessed); -our $VERSION = '2.00_25'; +our $VERSION = '2.00_33'; sub call { my ($self, $method, $body, $header) = @_; # Treat non-objects special if (not blessed $body) { - + # make sure there's something sensible in our body data $body = {} if not defined $body; $body = ref $body eq 'ARRAY' ? $body : [ $body ]; my @body_from = @{ $body }; # make a copy - # build list of parts as objects initialized with + # build list of parts as objects initialized with # parameters given my @part_from = (); foreach my $class (@{ $method->{ body }->{ parts } }) { @@ -78,9 +78,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 501 $ + $Rev: 542 $ $LastChangedBy: kutterma $ - $Id: Base.pm 501 2008-01-26 20:23:32Z kutterma $ + $Id: Base.pm 542 2008-02-18 09:38:06Z 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 3a8305f..3fa94ee 100644 --- a/lib/SOAP/WSDL/Definitions.pm +++ b/lib/SOAP/WSDL/Definitions.pm @@ -9,22 +9,22 @@ use List::Util qw(first); use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -our $VERSION='2.00_27'; +our $VERSION='2.00_33'; -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 %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<()>); # must be attr for Class::Std::Fast::Storable my %attributes_of :ATTR(); %attributes_of = ( - binding => \%binding_of, - message => \%message_of, - portType => \%portType_of, - service => \%service_of, + binding => \%binding_of, + message => \%message_of, + portType => \%portType_of, + service => \%service_of, ); # Function factory - we could be writing this method for all %attribute @@ -118,9 +118,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 477 $ + $Rev: 549 $ $LastChangedBy: kutterma $ - $Id: Definitions.pm 477 2007-12-24 10:23:52Z kutterma $ + $Id: Definitions.pm 549 2008-02-20 10:14:26Z 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/Expat/Base.pm b/lib/SOAP/WSDL/Expat/Base.pm index 9713da9..47114de 100644 --- a/lib/SOAP/WSDL/Expat/Base.pm +++ b/lib/SOAP/WSDL/Expat/Base.pm @@ -10,7 +10,9 @@ our $VERSION = '2.00_32'; sub new { my ($class, $arg_ref) = @_; - my $self = {}; + my $self = { + data => undef, + }; bless $self, $class; $self->set_user_agent($arg_ref->{ user_agent }) diff --git a/lib/SOAP/WSDL/Expat/MessageParser.pm b/lib/SOAP/WSDL/Expat/MessageParser.pm index c482d4e..7fe0815 100644 --- a/lib/SOAP/WSDL/Expat/MessageParser.pm +++ b/lib/SOAP/WSDL/Expat/MessageParser.pm @@ -24,7 +24,8 @@ sub new { }; bless $self, $class; - $self->load_classes() if ($args->{ class_resolver }); + $self->load_classes() if ($args->{ class_resolver }) + && ! exists $LOADED_OF{ $self->{ class_resolver } }; return $self; } @@ -32,7 +33,8 @@ sub class_resolver { my $self = shift; if (@_) { $self->{ class_resolver } = shift; - $self->load_classes(); + $self->load_classes() + if ! exists $LOADED_OF{ $self->{ class_resolver } }; } return $self->{ class_resolver }; } @@ -40,8 +42,6 @@ sub class_resolver { sub load_classes { my $self = shift; - return if $LOADED_OF{ $self->{ class_resolver } }; - for (values %{ $self->{ class_resolver }->get_typemap }) { no strict qw(refs); my $class = $_; @@ -295,8 +295,8 @@ the same terms as perl itself $Id: $ - $LastChangedDate: 2008-02-02 10:19:45 +0100 (Sa, 02 Feb 2008) $ - $LastChangedRevision: 516 $ + $LastChangedDate: 2008-03-29 22:38:55 +0100 (Sa, 29 Mrz 2008) $ + $LastChangedRevision: 585 $ $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 cdf76d7..b696876 100644 --- a/lib/SOAP/WSDL/Expat/WSDLParser.pm +++ b/lib/SOAP/WSDL/Expat/WSDLParser.pm @@ -17,6 +17,9 @@ sub _import_children { no strict qw(refs); my $value_ref = $imported->$get_method(); if ($value_ref) { + #print $self->get_uri(), "\n"; + #use Data::Dumper; + #print Data::Dumper::Dumper $value_ref; $value_ref = [ $value_ref ] if (not ref $value_ref eq 'ARRAY'); # set xmlns - can be different from parent for (@{ $value_ref }) { @@ -25,9 +28,25 @@ sub _import_children { if ( ($import_namespace ne $targetNamespace) && ! $_->get_targetNamespace); # update parent... $_->set_parent( $importer ); + $importer->$push_method($_); } # push elements into importing WSDL - $importer->$push_method(@{ $value_ref }); + #$importer->$push_method(@{ $value_ref }) + # if @{ $value_ref }; + } +} + +sub _import_namespace_definitions { + my $self = shift; + my $arg_ref = shift; + my $importer = $arg_ref->{ importer }; + my $imported = $arg_ref->{ imported }; + + # import namespace definitions, too + my $importer_ns_of = $importer->get_xmlns(); + my %xmlns_of = %{ $imported->get_xmlns() }; + while (my ($prefix, $url) = each %xmlns_of) { + $importer_ns_of->{ $prefix } = $url; } } @@ -38,10 +57,18 @@ sub xml_schema_import { my %attr_of = @_; my $import_namespace = $attr_of{ namespace }; my $uri = URI->new_abs($attr_of{schemaLocation}, $self->get_uri() ); - my $import = $parser->parse_uri($uri); + my $imported = $parser->parse_uri($uri); - for my $name ( qw(type element group) ) { - $self->_import_children( $name, $import, $schema, $import_namespace); + # might already be imported - parse_uri just returns in this case + return if not defined $imported; + + $self->_import_namespace_definitions({ + importer => $schema, + imported => $imported, + }); + + for my $name ( qw(type element group attribute attributeGroup) ) { + $self->_import_children( $name, $imported, $schema, $import_namespace); } } @@ -53,9 +80,18 @@ sub wsdl_import { my $import_namespace = $attr_of{ namespace }; my $uri = URI->new_abs($attr_of{location}, $self->get_uri() ); - my $import = $parser->parse_uri($uri); + my $imported = $parser->parse_uri($uri); + + # might already be imported - parse_uri just returns in this case + return if not defined $imported; + + $self->_import_namespace_definitions({ + importer => $definitions, + imported => $imported, + }); + for my $name ( qw(types message binding portType service) ) { - $self->_import_children( $name, $import, $definitions, $import_namespace); + $self->_import_children( $name, $imported, $definitions, $import_namespace); } } @@ -243,10 +279,10 @@ the same terms as perl itself =head1 Repository information - $Id: $ + $Id: WSDLParser.pm 549 2008-02-20 10:14:26Z kutterma $ - $LastChangedDate: 2008-02-14 18:07:18 +0100 (Do, 14 Feb 2008) $ - $LastChangedRevision: 534 $ + $LastChangedDate: 2008-02-20 11:14:26 +0100 (Mi, 20 Feb 2008) $ + $LastChangedRevision: 549 $ $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/Transport.pm b/lib/SOAP/WSDL/Factory/Transport.pm index 176a235..ca050ac 100644 --- a/lib/SOAP/WSDL/Factory/Transport.pm +++ b/lib/SOAP/WSDL/Factory/Transport.pm @@ -2,7 +2,7 @@ package SOAP::WSDL::Factory::Transport; use strict; use warnings; -our $VERSION='2.00_31'; +our $VERSION='2.00_33'; # class data my %registered_transport_of = (); @@ -12,7 +12,7 @@ my %registered_transport_of = (); my %SOAP_LITE_TRANSPORT_OF = ( ftp => 'SOAP::Transport::FTP', http => 'SOAP::Transport::HTTP', - https => 'SOAP::Transport::HTTPS', + https => 'SOAP::Transport::HTTP', mailto => 'SOAP::Transport::MAILTO', 'local' => 'SOAP::Transport::LOCAL', jabber => 'SOAP::Transport::JABBER', @@ -240,9 +240,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 524 $ + $Rev: 579 $ $LastChangedBy: kutterma $ - $Id: Transport.pm 524 2008-02-10 23:24:43Z kutterma $ + $Id: Transport.pm 579 2008-03-09 18:39:24Z 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 new file mode 100644 index 0000000..5ed801f --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm @@ -0,0 +1,268 @@ +package SOAP::WSDL::Generator::Iterator::WSDL11; +use strict; use warnings; +use Class::Std::Fast; + +my %definitions_of :ATTR(:name :default<[]>); +my %nodes_of :ATTR(:name :default<[]>); + +# memoization attributes +my %portType_of :ATTR(); +my %types_of :ATTR(); + +my %METHOD_OF = ( + 'SOAP::WSDL::Definitions' => 'get_service', + 'SOAP::WSDL::Service' => 'get_port', + 'SOAP::WSDL::Port' => sub { + my ($self, $node) = @_; + return if ! $node->first_address() + or ! $node->first_address()->isa('SOAP::WSDL::SOAP::Address'); + + return [ $self->get_definitions() + ->find_binding( $node->expand( $node->get_binding() ) ) || () ]; + }, + + 'SOAP::WSDL::Binding' => sub { + my ($self, $node) = @_; + + # remember referenced portType + $portType_of{ ident $self } = $self->get_definitions() + ->find_portType( $node->expand( $node->get_type ) ) + or return []; + + return $node->get_operation(); + }, + + 'SOAP::WSDL::Operation' => sub { + my ($self, $node) = @_; + + my $name = $node->get_name(); + + # get the equally named operation from the portType + my ($op) = grep { $_->get_name() eq $name } + @{ $portType_of{ ident $self }->get_operation() } + or return []; + + return [ @{ $op->get_input }, @{ $op->get_output }, @{ $op->get_fault } ] + }, + + 'SOAP::WSDL::OpMessage' => sub { + my ($self, $node) = @_; + return if ( ref $node->get_parent() eq 'SOAP::WSDL::Binding' ); # we're in binding + + # TODO maybe allow more messages && overloading by specifying name + + return [ $self->get_definitions()->find_message( + $node->expand( $node->get_message() ) + ) || () ]; + }, + + 'SOAP::WSDL::Message' => 'get_part', + + 'SOAP::WSDL::Part' => sub { + my ($self, $node) = @_; + my $ident = ident $self; + my $types = $types_of{ $ident } = $definitions_of{ $ident }->get_types()->[0] + or return []; + return [ + # If we have a type, this type is to be used in document/literal + # as global type. However this is forbidden, at least by WS-I. + # We should store the style/encoding somewhere, and regard it. + # TODO: auto-generate element for RPC bindings + $node->get_type() + ? do { + die "unsupported global type <" + . $node->get_type . "> found in part ". $node->get_name(); + $types->find_type( $node->expand($node->get_type) ) + } + : (), + $node->get_element() + ? $types->find_element( $node->expand($node->get_element) ) + : (), + ]; + }, +); + +sub init { + my ($self, $arg_of) = @_; + my $ident = ident $self; + undef $portType_of{ $ident }; + undef $types_of{ $ident }; + $nodes_of{ $ident } = [ + exists($arg_of->{ node }) + ? $arg_of->{ node } + : $definitions_of{ ident $self } + ]; +} + +sub get_next { + my $self = shift; + my $ident = ident $self; + + my $node = shift @{ $nodes_of{ $ident }}; + return if ! defined $node; + + unshift @{ $nodes_of{ $ident }}, @{ $self->get_nextNodes( $node ) || [] }; + + return $node; +} + +sub get_nextNodes { + my ($self, $node) = @_; + + my $method = $METHOD_OF{ ref $node } + or return []; + + return (ref($method) eq 'CODE') + ? $method->( $self, $node ) + : $node->can($method)->( $node ); +} + +1; + +__END__ + +=pod + +=head1 NAME + +SOAP::WSDL::Generator::Iterator::WSDL11 - WSDL 1.1 Iterator + +=head1 SYNOPSIS + + my $iter = SOAP::WSDL::Generator::Iterator::WSDL11->new({ + definitions => $wsdl + }); + $iter->init(); + while (my $node = $iter->get_next()) { + # do something with node - possibly call _accept with a visitor on it... + } + +=head1 DESCRIPTION + +Iterator for walking a WSDL 1.1 definition. + +The iterator performs a depth-first search along the following path: + + service + port + binding + operation + input/output/fault of operation in portType + message + part + type/element in XML schema + +If you wonder about this path: This is how to look up which XML Schema element +is associated with a operation from a service/port. + +=head2 Example + +The nodes are returned in the order denoted in the following example: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +You should not rely too much on this order - it may change. Even though, the +current order will probably remain, but the nodes currently skipped might +be returned somewhere along the path. + + +=head1 LICENSE AND COPYRIGHT + +Copyright 2004-2008 Martin Kutter. + +This file is part of SOAP-WSDL. You may distribute/modify it under +the same terms as perl itself + +=head1 AUTHOR + +Martin Kutter Emartin.kutter fen-net.deE + +=head1 REPOSITORY INFORMATION + + $Rev: 239 $ + $LastChangedBy: kutterma $ + $Id: Client.pm 239 2007-09-11 09:45:42Z kutterma $ + $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $ + +=cut diff --git a/lib/SOAP/WSDL/Generator/PrefixResolver.pm b/lib/SOAP/WSDL/Generator/PrefixResolver.pm new file mode 100644 index 0000000..26dda45 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/PrefixResolver.pm @@ -0,0 +1,113 @@ +package SOAP::WSDL::Generator::PrefixResolver; +use strict; use warnings; + +use Class::Std::Fast::Storable; + +my %namespace_prefix_map_of :ATTR(:name :default<{}>); +my %namespace_map_of :ATTR(:name :default<{}>); +my %prefix_of :ATTR(:name :default<{}>); + +sub resolve_prefix { + my ($self, $type, $namespace, $element) = @_; + return $prefix_of{ $$self }->{ $type } + if not defined($namespace); + return $namespace_prefix_map_of{ $$self }->{ $namespace } + || ( ($namespace_map_of{ $$self }->{ $namespace }) + ? join ('::', $prefix_of{ $$self }->{ $type }, $namespace_map_of{ $$self }->{ $namespace }) + : $prefix_of{ $$self }->{ $type } + ); + +} + +1; + +__END__ + +=pod + +=head1 NAME + +SOAP::WSDL::Generator::PrefixResolver - prefixes for different classes + +=head1 SYNOPSIS + +If you want to create your custom prefix resolver: + + package MyPrefixResolver; + use strict; use warnings; + use base qw(SOAP::WSDL::Generator::PrefixResolver); + + sub resolve_prefix { + my ($self, $type, $namespace, $node) = @_; + # return something special + return $self->SUPER::resolve_prefix($type, $namespace, $node); + } + +When generating code: + + use MyPrefixResolver; + use SOAP::WSDL::Generator::XSD; + my $generator = SOAP::WSDL::Generator::Template::XSD->new({ + prefix_resolver_class => 'MyPrefixResolver', + }); + +=head1 DESCRIPTION + +Prefix resolver class for SOAP::WSDL's code generator. You may subclass it to +apply some custom prefix resolving logic. + +Subclasses must implement the following methods: + +=over + +=item * resolve_prefix + + sub resolve_prefix { + my ($self, $namespace, $node) = @_; + # ... + } + +resolve_prefix is expected to return a (perl class) prefis. It is called with +the following parameters: + + NAME DESCRIPTION + ----------------------------------------------------------------------------- + type One of (server|interface|typemap|type|element|attribute) + namespace The targetNamespace of the node to generate a prefix for. + node The node to generate a prefix for + +You usually just need type and namespace for prefix resolving. node is +provided for rather funky setups, where you have to choose different prefixes +based on type names or whatever. + +Note that node may be of any of the following classes: + + SOAP::WSDL::Service + SOAP::WSDL::XSD::Attribute + SOAP::WSDL::XSD::Element + SOAP::WSDL::XSD::Type + +Note that both namespace and node may be undef - you should test for +definedness before doing anything fancy with them. + +=back + +=head1 LICENSE AND COPYRIGHT + +Copyright 2008 Martin Kutter. + +This library is free software. You may distribute/modify it under +the same terms as perl itself + +=head1 AUTHOR + +Martin Kutter Emartin.kutter fen-net.deE + +=head1 REPOSITORY INFORMATION + + $Rev: 583 $ + $LastChangedBy: kutterma $ + $Id: $ + $HeadURL: $ + +=cut diff --git a/lib/SOAP/WSDL/Generator/Template.pm b/lib/SOAP/WSDL/Generator/Template.pm index 006389d..bc41fd8 100644 --- a/lib/SOAP/WSDL/Generator/Template.pm +++ b/lib/SOAP/WSDL/Generator/Template.pm @@ -2,20 +2,25 @@ package SOAP::WSDL::Generator::Template; use strict; use Template; use Class::Std::Fast::Storable; +use Carp; +use SOAP::WSDL::Generator::PrefixResolver; -our $VERSION=q{2.00_25}; +use version; our $VERSION = qv(2.00_33); my %tt_of :ATTR(:get); -my %definitions_of :ATTR(:name :default<()>); -my %server_prefix_of :ATTR(:name :default); -my %interface_prefix_of :ATTR(:name :default); -my %typemap_prefix_of :ATTR(:name :default); -my %type_prefix_of :ATTR(:name :default); -my %element_prefix_of :ATTR(:name :default); -my %INCLUDE_PATH_of :ATTR(:name :default<()>); -my %EVAL_PERL_of :ATTR(:name :default<0>); -my %RECURSION_of :ATTR(:name :default<0>); -my %OUTPUT_PATH_of :ATTR(:name :default<.>); +my %definitions_of :ATTR(:name :default<()>); +my %server_prefix_of :ATTR(:name :default); +my %interface_prefix_of :ATTR(:name :default); +my %typemap_prefix_of :ATTR(:name :default); +my %type_prefix_of :ATTR(:name :default); +my %element_prefix_of :ATTR(:name :default); +my %attribute_prefix_of :ATTR(:name :default); +my %INCLUDE_PATH_of :ATTR(:name :default<()>); +my %EVAL_PERL_of :ATTR(:name :default<0>); +my %RECURSION_of :ATTR(:name :default<0>); +my %OUTPUT_PATH_of :ATTR(:name :default<.>); + +my %prefix_resolver_class_of :ATTR(:name :default); sub START { my ($self, $ident, $arg_ref) = @_; @@ -39,31 +44,28 @@ sub _process :PROTECTED { $tt->process( $template, { context => { - namespace_prefix_map => { - 'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin', - }, - namespace_map => { - }, - prefix => { - interface => $self->get_interface_prefix, - element => $self->get_element_prefix, - server => $self->get_server_prefix, - type => $self->get_type_prefix, - typemap => $self->get_typemap_prefix, - } + prefix_resolver => $prefix_resolver_class_of{ $$self }->new({ + namespace_prefix_map => { + 'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin', + }, + namespace_map => { + }, + prefix => { + interface => $self->get_interface_prefix, + element => $self->get_element_prefix, + attribute => $self->get_attribute_prefix, + server => $self->get_server_prefix, + type => $self->get_type_prefix, + typemap => $self->get_typemap_prefix, + } + }), }, definitions => $self->get_definitions, - interface_prefix => $self->get_interface_prefix, - server_prefix => $self->get_server_prefix, - type_prefix => $self->get_type_prefix, - typemap_prefix => $self->get_typemap_prefix, - TYPE_PREFIX => $self->get_type_prefix, - element_prefix => $self->get_element_prefix, NO_POD => delete $arg_ref->{ NO_POD } ? 1 : 0 , %{ $arg_ref } }, $output) - or die $INCLUDE_PATH_of{ $ident }, '\\', $template, ' ', $tt->error(); + or croak $INCLUDE_PATH_of{ $ident }, '\\', $template, ' ', $tt->error(); } 1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm b/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm index dcfbbcc..3b5a7f1 100644 --- a/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm +++ b/lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm @@ -1,61 +1,196 @@ package SOAP::WSDL::Generator::Template::Plugin::XSD; use strict; use warnings; - +use Carp qw(confess); use Class::Std::Fast::Storable constructor => 'none'; -my %namespace_prefix_map_of :ATTR(:name :default<{}>); -my %namespace_map_of :ATTR(:name :default<{}>); -my %prefix_of :ATTR(:name :default<()>); +my %namespace_prefix_map_of :ATTR(:name :default<{}>); +my %namespace_map_of :ATTR(:name :default<{}>); +my %prefix_of :ATTR(:name :default<()>); +my %prefix_resolver_of :ATTR(:name :default<()>); # create a singleton sub load { # called as MyPlugin->load($context) my ($class, $context, @arg_from) = @_; my $stash = $context->stash(); my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class; - use Data::Dumper; - # die Data::Dumper::Dumper $stash->{ context }; - $self->set_namespace_map( $stash->{ context }->{ namespace_map }); - $self->set_namespace_prefix_map( $stash->{ context }->{ namespace_prefix_map }); - $self->set_prefix( $stash->{ context }->{ prefix }); +# $self->set_namespace_map( $stash->{ context }->{ namespace_map }); +# $self->set_namespace_prefix_map( $stash->{ context }->{ namespace_prefix_map }); +# $self->set_prefix( $stash->{ context }->{ prefix }); + $self->set_prefix_resolver( $stash->{ context }->{ prefix_resolver }); return $self; # returns 'MyPlugin' } sub new { - return shift; + return shift if ref $_[0]; + + my ($class, $arg_ref) = @_; + + my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class; +# $self->set_namespace_map( $arg_ref->{ namespace_map }); +# $self->set_namespace_prefix_map( $arg_ref->{ namespace_prefix_map }); +# $self->set_prefix( $arg_ref->{ prefix }); + $self->set_prefix_resolver( $arg_ref->{ prefix_resolver }); + return $self; # returns 'MyPlugin' } sub _get_prefix { - my ($self, $type, $namespace) = @_; - return $namespace_prefix_map_of{ $$self }->{ $namespace } - || ( ($namespace_map_of{ $$self }->{ $namespace }) - ? join ('::', $prefix_of{ $$self }->{ $type }, $namespace_map_of{ $$self }->{ $namespace }) - : $prefix_of{ $$self }->{ $type } - ) - || $prefix_of{ $$self }->{ $type }; + my ($self, $type, $node) = @_; + my $namespace = defined ($node) + ? ref($node) + ? $node->get_targetNamespace + : $node + : undef; + return $self->get_prefix_resolver->resolve_prefix( + $type, + $namespace, + ref($node) + ? $node + : undef + ); } -sub get_element_prefix { - shift->_get_prefix( 'element', shift ); +#sub _get_prefix { +# my ($self, $type, $namespace) = @_; +# return $prefix_of{ $$self }->{ $type } +# if not defined($namespace); +# return $namespace_prefix_map_of{ $$self }->{ $namespace } +# || ( ($namespace_map_of{ $$self }->{ $namespace }) +# ? join ('::', $prefix_of{ $$self }->{ $type }, $namespace_map_of{ $$self }->{ $namespace }) +# : $prefix_of{ $$self }->{ $type } +# ); +#} + +sub create_xsd_name { + my ($self,$element) = @_; + my $name = $self->_resolve_prefix($element) . '::' + . $element->get_name(); + return $self->perl_name( $name ); } -sub get_interface_prefix { - shift->_get_prefix( 'interface', shift ); +sub create_typemap_name { + my ($self, $node) = @_; + my $name = $self->_get_prefix('typemap') . '::' + . $node->get_name(); + return $self->perl_name( $name ); } -sub get_server_prefix { - shift->_get_prefix( 'server', shift ); +sub create_server_name { + my ($self, $server, $port) = @_; + my $port_name = $port->get_name(); + $port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x; + my $name = join('::', + $self->_get_prefix('server', $server), + $server->get_name(), + $port_name + ); + return $self->perl_name( $name ); } -sub get_type_prefix { - # die "WIX"; - shift->_get_prefix( 'type', shift ); +sub create_interface_name { + my ($self, $server, $port) = @_; + my $port_name = $port->get_name(); + $port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x; + my $name = join('::', + $self->_get_prefix('interface', $server), + $server->get_name(), + $port_name + ); + return $self->perl_name( $name ); } -sub get_typemap_prefix { - shift->_get_prefix( 'typemap', shift ); +sub _resolve_prefix { + my ($self, $node) = @_; + confess "no node" if not $node; + if ($node->isa('SOAP::WSDL::XSD::Builtin')) { + return $self->_get_prefix('type', $node) + } + if ( $node->isa('SOAP::WSDL::XSD::SimpleType') + or $node->isa('SOAP::WSDL::XSD::ComplexType') + ) { + return $self->_get_prefix('type', $node); + } + if ( $node->isa('SOAP::WSDL::XSD::Element') ) { + return $self->_get_prefix('element', $node); + } + if ( $node->isa('SOAP::WSDL::XSD::Attribute') ) { + return $self->_get_prefix('attribute', $node); + } +} + +sub perl_name { + my $self = shift; + my $name = shift; + $name =~s{[\-]}{_}xmsg; + $name =~s{[\.]}{::}xmsg; + return $name; +} + +sub create_subpackage_name { + my $self = shift; + my $arg_ref = shift; + my $type = ref $arg_ref eq 'HASH' ? $arg_ref->{ value } : $arg_ref; + + my @name_from = $type->get_name() || (); ; + my $parent = $type; + my $top_node = $parent; + if (! $parent->get_parent()->isa('SOAP::WSDL::XSD::Schema') ) { + NAMES: while ($parent = $parent->get_parent()) { + $top_node = $parent; + last NAMES if $parent->get_parent()->isa('SOAP::WSDL::XSD::Schema'); + # skip empty names - atomic types have no name... + unshift @name_from, $parent->get_name() + if $parent->get_name(); + } + } + # create name for top node + my $top_node_name = $self->create_xsd_name($top_node); + my $package_name = join('::_', $top_node_name , (@name_from) ? join('::', @name_from) : () ); + return $package_name; +} + +sub create_xmlattr_name { + return join '::', shift->create_subpackage_name(shift), 'XmlAttr'; } -sub error {} 1; +=pod + +=head1 NAME + +SOAP::WSDL::Generator::Template::Plugin::XSD - Template plugin for the XSD generator + +=head1 METHODS + +=head2 perl_name + + XSD.perl_name(element.get_name); + +Converts a XML name into a valid perl name (valid for subroutines, variables +or the like). + +perl_name takes a crude approach by just replacing . and - (dot and dash) +with a underscore. This may or may not be sufficient, and may or may not +provoke collisions in your XML names. + +=head1 LICENSE AND COPYRIGHT + +Copyright 2008 Martin Kutter. + +This file is part of SOAP-WSDL. You may distribute/modify it under the same +terms as perl itself + +=head1 AUTHOR + +Martin Kutter Emartin.kutter fen-net.deE + +=head1 REPOSITORY INFORMATION + + $Rev: 564 $ + $LastChangedBy: kutterma $ + $Id: ComplexType.pm 564 2008-02-23 13:31:39Z 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/lib/SOAP/WSDL/Generator/Template/XSD.pm b/lib/SOAP/WSDL/Generator/Template/XSD.pm index bb50cd2..f519527 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD.pm +++ b/lib/SOAP/WSDL/Generator/Template/XSD.pm @@ -9,10 +9,11 @@ our $VERSION = q{2.00_27}; use SOAP::WSDL::Generator::Visitor::Typemap; use SOAP::WSDL::Generator::Visitor::Typelib; +use SOAP::WSDL::Generator::Template::Plugin::XSD; use base qw(SOAP::WSDL::Generator::Template); -my %output_of :ATTR(:name :default<()>); -my %typemap_of :ATTR(:name :default<({})>); +my %output_of :ATTR(:name :default<()>); +my %typemap_of :ATTR(:name :default<({})>); sub BUILD { my ($self, $ident, $arg_ref) = @_; @@ -50,89 +51,76 @@ sub generate { my $self = shift; my $opt = shift; $self->generate_typelib( $opt ); -# $self->generate_interface( $opt ); $self->generate_typemap( $opt ); } sub generate_typelib { my ($self, $arg_ref) = @_; - # $output_of{ ident $self } = ""; 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] ) { + for my $type (map { + @{ $_->get_type() } , + @{ $_->get_element() }, + @{ $_->get_attribute() } + } @schema[1..$#schema] ) { $type->_accept( $self ); } - # return $output_of{ ident $self }; return; } +sub _generate_interface { + my $self = shift; + my $arg_ref = shift; + my $template_name = delete $arg_ref->{ template_name }; + my $prefix_method = delete $arg_ref->{ prefix_method }; + for my $service (@{ $self->get_definitions->get_service }) { + for my $port (@{ $service->get_port() }) { + # Skip ports without (known) address + next if not $port->first_address; + next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address'); + + my $port_name = $port->get_name; + $port_name =~s{ \A .+\. }{}xms; + my $output = $arg_ref->{ output } + ? $arg_ref->{ output } + : $self->_generate_filename( + $self->can($prefix_method)->($self), + $service->get_name(), + $port_name, + ); + print "Creating interface class $output\n"; + + $self->_process($template_name, + { + service => $service, + port => $port, + NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 , + }, + $output, binmode => ':utf8'); + } + } +} + sub generate_server { - my $self = shift; - my $ident = ident $self; - my $arg_ref = shift; - for my $service (@{ $self->get_definitions->get_service }) { - for my $port (@{ $service->get_port() }) { - # Skip ports without (known) address - next if not $port->first_address; - next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address'); - - my $port_name = $port->get_name; - $port_name =~s{ \A .+\. }{}xms; - my $output = $arg_ref->{ output } - ? $arg_ref->{ output } - : $self->_generate_filename( - $self->get_server_prefix(), - $service->get_name(), - $port_name, - ); - print "Creating interface class $output\n"; - - $self->_process('Server.tt', - { - service => $service, - port => $port, - NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 , - }, - $output, binmode => ':utf8'); - } - } + my ($self, $arg_ref) = @_; + $arg_ref->{ template_name } = 'Server.tt'; + $arg_ref->{ prefix_method } = 'get_server_prefix'; + $self->_generate_interface($arg_ref); } -sub generate_interface { - my $self = shift; - my $ident = ident $self; - my $arg_ref = shift; - for my $service (@{ $self->get_definitions->get_service }) { - for my $port (@{ $service->get_port() }) { - # Skip ports without (known) address - next if not $port->first_address; - next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address'); - - my $port_name = $port->get_name; - $port_name =~s{ \A .+\. }{}xms; - my $output = $arg_ref->{ output } - ? $arg_ref->{ output } - : $self->_generate_filename( - $self->get_interface_prefix(), - $service->get_name(), - $port_name, - ); - print "Creating interface class $output\n"; - - $self->_process('Interface.tt', - { - service => $service, - port => $port, - NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 , - }, - $output, binmode => ':utf8'); - } - } +sub generate_client { + my ($self, $arg_ref) = @_; + $arg_ref->{ template_name } = 'Interface.tt'; + $arg_ref->{ prefix_method } = 'get_interface_prefix'; + $self->_generate_interface($arg_ref); } +sub generate_interface; +*generate_interface = \&generate_client; sub generate_typemap { my ($self, $arg_ref) = @_; + my $visitor = SOAP::WSDL::Generator::Visitor::Typemap->new({ type_prefix => $self->get_type_prefix(), element_prefix => $self->get_element_prefix(), @@ -144,10 +132,35 @@ sub generate_typemap { 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', %{ $typemap_of{ident $self }}, - } + }, + resolver => SOAP::WSDL::Generator::Template::Plugin::XSD->new({ + prefix_resolver => $self->get_prefix_resolver_class()->new({ + namespace_prefix_map => { + 'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin', + }, + namespace_map => { + }, + prefix => { + interface => $self->get_interface_prefix, + element => $self->get_element_prefix, + server => $self->get_server_prefix, + type => $self->get_type_prefix, + typemap => $self->get_typemap_prefix, + } + }) + }), }); + + use SOAP::WSDL::Generator::Iterator::WSDL11; + my $iterator = SOAP::WSDL::Generator::Iterator::WSDL11->new({ + definitions => $self->get_definitions }); + for my $service (@{ $self->get_definitions->get_service }) { - $visitor->visit_Service( $service ); + $iterator->init({ node => $service }); + while (my $node = $iterator->get_next()) { + $node->_accept( $visitor ); + } + my $output = $arg_ref->{ output } ? $arg_ref->{ output } : $self->_generate_filename( $self->get_typemap_prefix(), $service->get_name() ); @@ -171,6 +184,14 @@ sub _generate_filename :PRIVATE { return "$name.pm"; } +sub visit_XSD_Attribute { + my ($self, $attribute) = @_; + my $output = defined $output_of{ ident $self } + ? $output_of{ ident $self } + : $self->_generate_filename( $self->get_attribute_prefix(), $attribute->get_name() ); + $self->_process('attribute.tt', { attribute => $attribute } , $output); +} + sub visit_XSD_Element { my ($self, $element) = @_; my $output = defined $output_of{ ident $self } diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt index c5334fa..f60bea7 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt @@ -1,8 +1,5 @@ [% USE XSD -%] -[% interface_name = interface_prefix _ '::' - _ service.get_name.replace('\.', '::') _ '::' - _ port.get_name.replace('^.+\.',''); -interface_name = interface_name.replace('-','_'); -%] +[% interface_name = XSD.create_interface_name(service, port) -%] package [% interface_name %]; use strict; use warnings; @@ -11,20 +8,20 @@ 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('\.', '::').replace('-', '_') %] - if not [% typemap_prefix %]::[% service.get_name.replace('\.', '::').replace('-', '_') %]->can('get_class'); +require [% XSD.create_typemap_name(service) %] + if not [% XSD.create_typemap_name(service) %]->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('\.', '::').replace('-', '_') %]') + $_[0]->set_class_resolver('[% XSD.create_typemap_name(service) %]') if not $_[2]->{class_resolver}; } [% binding = definitions.find_binding( port.expand( port.get_binding ) ); FOREACH operation = binding.get_operation; %][% INCLUDE Interface/Operation.tt %] -[% +[% END; %] @@ -83,7 +80,6 @@ All arguments are forwarded to L. [% INCLUDE Interface/POD/method_info.tt %] - [% FOREACH operation = binding.get_operation; %][% INCLUDE Interface/POD/Operation.tt %] [% END %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt index 2ce2ce2..ff80884 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt @@ -1,14 +1,12 @@ [% RETURN IF NOT item; type = definitions.find_portType( binding.expand( binding.get_type ) ); - port_op = type.find_operation( definitions.get_targetNamespace, operation.get_name ); + port_op = type.find_operation( type.get_targetNamespace, operation.get_name ); message = definitions.find_message( port_op.first_input.expand( port_op.first_input.get_message ) ); part_from = message.get_part; PERL %] my $item = $stash->{ item }; my $def = $stash->{ definitions }; - my $part_from = $stash->{ part_from }; - my $type_prefix = $stash->{ type_prefix }; - my $element_prefix = $stash->{ element_prefix }; + my $part_from = $stash->{ message }->get_part(); my @body_part_from = split m{\s}, $item->get_parts; @@ -25,14 +23,17 @@ my $name; ($name = $part->get_element) ? do { - $name =~s{ ^[^:]+: }{}xms; - $element_prefix . '::' . $name; - } + my $element = $def->first_types->find_element($part->expand($name)); + my $resolver = $context->plugin('XSD'); + $resolver->create_xsd_name($element); + + } : ($name = $part->get_type) ? do { - $name =~s{ ^[^:]+: }{}xms; - $type_prefix . '::' . $name; - } + my $element = $def->first_types->find_type($part->expand($name)); + my $resolver = $context->plugin('XSD'); + $resolver->create_xsd_name($element); + } : die "input must have either type or element" } : () @@ -44,13 +45,15 @@ my $name; ($name = $part->get_element) ? do { - $name =~s{ ^[^:]+: }{}xms; - "$element_prefix\::$name" - } + my $element = $def->first_types->find_element($part->expand($name)); + my $resolver = $context->plugin('XSD'); + $resolver->create_xsd_name($element); + } : ($name = $part->get_type) ? do { - $name =~s{ ^[^:]+: }{}xms; - "$type_prefix\::$name" + my $element = $def->first_types->find_type($part->expand($name)); + my $resolver = $context->plugin('XSD'); + $resolver->create_xsd_name($element); } : die "input must have either type or element"; } @{ $part_from }; @@ -63,7 +66,10 @@ $stash->{ parts } = \@parts; [% END %] - 'use' => '[% item.get_use %]', - namespace => '[% item.get_namespace %]', - encodingStyle => '[% item.get_encodingStyle %]', - parts => [qw( [% parts.join(' ') %] )], \ No newline at end of file +[% IF item.get_use != 'literal'; + THROW NOT_SUPPORTED "Body: SOAP::WSDL supports literal encoding only - ${ item.get_use } found"; +END %] + 'use' => '[% item.get_use %]', + namespace => '[% item.get_namespace %]', + encodingStyle => '[% item.get_encodingStyle %]', + parts => [qw( [% parts.join(' ') %] )], \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Header.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Header.tt index ff643d1..0b2c52d 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Header.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Header.tt @@ -19,19 +19,25 @@ my $name; ($name = $part->get_element) ? do { - $name =~s{ ^[^:]+: }{}xms; - $element_prefix . '::' . $name; + my $element = $def->first_types->find_element($part->expand($name)); + my $resolver = $context->plugin('XSD'); + $resolver->create_xsd_name($element); } : ($name = $part->get_type) ? do { - $name =~s{ ^[^:]+: }{}xms; - $type_prefix . '::' . $name; - } + my $element = $def->first_types->find_type($part->expand($name)); + my $resolver = $context->plugin('XSD'); + $resolver->create_xsd_name($element); + } : die "input must have either type or element" }; $stash->{ part_class } = $part_class; [% END; - %] +%] +[% IF item.get_use != 'literal'; + THROW NOT_SUPPORTED "Header: SOAP::WSDL supports literal encoding only - ${ item.get_use } found"; +END %] + 'use' => '[% item.get_use %]', namespace => '[% item.get_namespace %]', encodingStyle => '[% item.get_encodingStyle %]', diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Operation.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Operation.tt index 7a380e2..477c08e 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Operation.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/Operation.tt @@ -4,7 +4,12 @@ sub [% operation.get_name %] { return $self->SUPER::call({ operation => '[% operation.get_name %]', soap_action => '[% operation.first_operation.get_soapAction %]', - style => '[% operation.get_style || binding.get_style %]', + style => [% style = operation.first_operation.get_style || binding.get_style; + IF style != "document"; + THROW NOT_SUPPORTED "SOAP::WSDL supports document encoding only - $style found"; + END; +-%] +'[% style %]', body => { [% INCLUDE Interface/Body.tt( item = operation.first_input.first_body ); %] }, diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/method_info.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/method_info.tt index b4d1993..cf27836 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/method_info.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/method_info.tt @@ -5,3 +5,12 @@ 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 methods, as long as you meet the structure. + +List items (i.e. multiple occurences) are not displayed in the synopsis. +You may generally pass a list ref of hash refs (or objects) instead of a hash +ref - this may result in invalid XML if used improperly, though. Note that +SOAP::WSDL always expects list references at maximum depth position. + +XML attributes are not displayed in this synopsis and cannot be set using +hash refs. See the respective class' documentation for additional information. + diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/POD/annotation.tt b/lib/SOAP/WSDL/Generator/Template/XSD/POD/annotation.tt new file mode 100644 index 0000000..c3a93c1 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/POD/annotation.tt @@ -0,0 +1,2 @@ +[% node.get_annotation.0.get_documentation %] + diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Server.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Server.tt index 1e24d35..b5a5f24 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Server.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Server.tt @@ -1,7 +1,6 @@ -[% server_name = server_prefix _ '::' - _ service.get_name.replace('\.', '::') _ '::' - _ port.get_name.replace('^.+\.',''); -server_name = server_name.replace('-','_'); -%] +[% USE XSD; +server_name = XSD.create_server_name(service, port); +-%] package [% server_name %]; use strict; use warnings; @@ -10,8 +9,8 @@ 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 [% XSD.create_typemap_name(service) %] + if not [% XSD.create_typemap_name(service) %]->can('get_class'); my %transport_class_of :ATTR(:name :default); my %transport_of :ATTR(:name :default<()>); @@ -31,13 +30,13 @@ sub START { or die "Cannot load transport class $transport_class_of{ $ident }: $@"; $transport_of{ $ident } = $transport_class_of{ $ident }->new({ action_map_ref => $action_map_ref, - class_resolver => '[% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]', + class_resolver => '[% XSD.create_typemap_name(service) %]', dispatch_to => $dispatch_to{ $ident }, }); } sub handle { - $transport_of{ ${ $_[0] } }->handle(); + $transport_of{ ${ shift @_ } }->handle(@_); } 1; diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/OutPart.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/OutPart.tt index 50b5c97..6e1e51c 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/OutPart.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/OutPart.tt @@ -3,7 +3,7 @@ #element; #STOP; -%] - [% element_prefix %]::[% element.get_name.replace('\.', '::') %]->new([% + [% XSD.create_xsd_name(element) %]->new([% type = element.first_complexType || element.first_simpleType || definitions.first_types.find_type( element.expand( element.get_type ) ); INCLUDE Interface/POD/Type.tt; %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt b/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt index afa43f2..14f3332 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt @@ -1,4 +1,5 @@ -package [% typemap_prefix %]::[% service.get_name.replace('\.','::') %]; +[% USE XSD %] +package [% XSD.create_typemap_name(service) %]; use strict; use warnings; @@ -27,7 +28,7 @@ __END__ [% head1 %] NAME -[% typemap_prefix %]::[% service.get_name.replace('\.','::').replace('-', '_') %]; - typemap for ::[% service.get_name %]; +[% XSD.create_typemap_name(service) %] - typemap for [% service.get_name %] [% head1 %] DESCRIPTION diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/_type_class.tt b/lib/SOAP/WSDL/Generator/Template/XSD/_type_class.tt deleted file mode 100644 index f4118c2..0000000 --- a/lib/SOAP/WSDL/Generator/Template/XSD/_type_class.tt +++ /dev/null @@ -1,6 +0,0 @@ -[% type_name = node.expand( type ); - IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%] -SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %] -[% ELSE -%] -[% type_prefix %]::[% type_name.1 %] -[% END -%] \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/attribute.tt b/lib/SOAP/WSDL/Generator/Template/XSD/attribute.tt new file mode 100644 index 0000000..88b9531 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/attribute.tt @@ -0,0 +1,83 @@ +[% USE XSD(context) %] +package [% XSD.create_xsd_name(attribute) %]; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { '[% attribute.get_targetNamespace %]' } + +__PACKAGE__->__set_name('[% attribute.get_name %]'); +__PACKAGE__->__set_ref([% IF attribute.get_ref; %]'[% attribute.get_ref %]'[% END %]); + +[%- IF (type_name = attribute.get_type); -%] +use base qw( + SOAP::WSDL::XSD::Typelib::Attribute + [% type = definitions.get_types.0.find_type(attribute.expand(type_name)); + IF ! type; + THROW NOT_FOUND "type " _ type_name _ " not found in attribute " _ attribute.get_name; + END; + XSD.create_xsd_name(type) %] +); + +} +[%- ELSIF (ref = attribute.get_ref); + ref_from = ref.split(':'); +-%] +# attribute ref="[% ref %]" +use base qw( + [% ref_element = definitions.get_types.0.find_attribute(attribute.expand(ref)); + XSD.create_xsd_name( ref_element ); %] +); + +} +[%- ELSIF (simpleType = attribute.first_simpleType) %] +# atomic simpleType: new($data); + +Constructor. The following data structure may be passed to new(): + + { value => $value } + +[% head1 %] AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt index 0c07ada..76b3b42 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType.tt @@ -1,13 +1,15 @@ -[% USE XSD(context) -%] -package [% type_prefix %]::[% complexType.get_name.replace('\.','::').replace('-','_') %]; +[% USE XSD -%] +package [% XSD.create_xsd_name(complexType) %]; use strict; use warnings; -[% INCLUDE complexType/contentModel.tt %] + [%# -# Don't include any perl source here - there may be sub-packages... +# Don't include any perl source for this package below this line - there +# may be sub-packages... #-%] -[% INCLUDE complexType/attributeSet.tt %] +[% INCLUDE complexType/contentModel.tt %] + 1; [%# work around for CPAN's indexer, which gets disturbed by pod in templates -%] @@ -20,22 +22,35 @@ use warnings; [% head1 %] NAME -[% type_prefix %]::[% complexType.get_name.replace('\.','::').replace('-','_') %] +[% XSD.create_xsd_name(complexType) %] [% head1 %] DESCRIPTION -Perl data type class for the XML Schema defined complextype +Perl data type class for the XML Schema defined complexType [% complexType.get_name %] from the namespace [% complexType.get_targetNamespace %]. +[% INCLUDE POD/annotation.tt(node = complexType) %] + +[% IF (complexType.get_element); %] [% head2 %] PROPERTIES The following properties may be accessed using get_PROPERTY / set_PROPERTY methods: +=over + [% FOREACH element = complexType.get_element -%] - [% element.get_name %] +=item * [% element.get_name %] + +[% IF element.get_annotation.get_documentation; %] +[% element.get_annotation.get_documentation %] +[% END -%] [% END %] +=back + +[% END -%] + [% head1 %] METHODS [% head2 %] new @@ -44,6 +59,8 @@ Constructor. The following data structure may be passed to new(): [% indent = ' '; INCLUDE complexType/POD/structure.tt %] +[% INCLUDE complexType/POD/attributeSet.tt %] + [% head1 %] AUTHOR Generated by SOAP::WSDL diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/all.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/all.tt index 4ee4c7c..e23cedb 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/all.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/all.tt @@ -1,5 +1,5 @@ -[% indent %]{ -[%- IF complexType.get_name %] # [% XSD.get_type_prefix(complexType.get_targetNamespace) %]::[% complexType.get_name %][% END %] + { +[%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] [%- indent = indent _ ' '; FOREACH element = complexType.get_element %] [% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/attributeSet.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/attributeSet.tt new file mode 100644 index 0000000..d6e63f3 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/attributeSet.tt @@ -0,0 +1,34 @@ +[% head2 = BLOCK %]=head2[% END -%] +[% IF (complexType.get_attribute.size) %] + +[% head2 %] attr + +NOTE: Attribute documentation is experimental, and may be inaccurate. +See the correspondent WSDL/XML Schema if in question. + +This class has additional attributes, accessibly via the C method. + +attr() returns an object of the class [% XSD.create_xmlattr_name(complexType) %]. + +The following attributes can be accessed on this object via the corresponding +get_/set_ methods: + +=over + +[% FOREACH element = complexType.get_attribute -%] +=item * [% element.get_name %] + +[%- IF (element.get_annotation && element.get_annotation.0.get_documentation) %] + [% element.get_annotation.0.get_documentation %] +[% END; %] + +[% IF (type_name=element.get_type); + type = definitions.get_types.0.find_type(element.expand(type_name)); + IF (! type); + THROW NOT_FOUND "type " _ type_name _ " for attribute " _ element.get_name _ " not found"; + END; %] +This attribute is of type L<[% XSD.create_xsd_name(type) %]|[% XSD.create_xsd_name(type) %]>. +[% END %] + +[%- END -%] +[% END %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/choice.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/choice.tt index 7bee878..85cf9e5 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/choice.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/choice.tt @@ -1,5 +1,5 @@ [% indent %]{ -[%- IF complexType.get_name %] # [% XSD.get_type_prefix(complexType.get_targetNamespace) %]::[% complexType.get_name %][% END %] +[%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] [%- indent = indent _ ' ' %] [% indent %]# One of the following elements. [% indent %]# No occurance checks yet, so be sure to pass just one... diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/content_model.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/content_model.tt new file mode 100644 index 0000000..e69de29 diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt index 4ee4c7c..73b667f 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt @@ -1,5 +1,5 @@ [% indent %]{ -[%- IF complexType.get_name %] # [% XSD.get_type_prefix(complexType.get_targetNamespace) %]::[% complexType.get_name %][% END %] +[%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] [%- indent = indent _ ' '; FOREACH element = complexType.get_element %] [% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent.tt index cf80c48..c7bd31d 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent.tt @@ -1,10 +1,7 @@ [% IF (complexType.get_variety == 'restriction'); - INCLUDE complexType/POD/restriction.tt(complexType = complexType); + INCLUDE complexType/POD/simpleContent/restriction.tt(complexType = complexType); ELSIF (complexType.get_variety == 'extension'); - #THROW NOT_IMPLEMENTED, "${ complexType.get_name } - complexType complexContent extension not implemented yet"; -%] - # No documentation generated for complexContent / extension yet -[% + INCLUDE complexType/POD/simpleContent/restriction.tt(complexType = complexType); ELSE; THROW UNKNOWN, "unknown variety ${ complexType.get_variety }"; END; diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/extension.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/extension.tt new file mode 100644 index 0000000..cc4b94f --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/extension.tt @@ -0,0 +1 @@ +# No documentation generated for simpleContent / extension yet \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/restriction.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/restriction.tt new file mode 100644 index 0000000..b730bd4 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/simpleContent/restriction.tt @@ -0,0 +1,46 @@ + { + value => $some_value, # simple perl scalar. See below for restrictions + } + +NOTE: This type is derived by restriction as complexType with simpleContent. +Documentation generation for this derivation method is experimental and may +be erroneous/incomplete. + +This clase is derived from [%- +IF (name = complexType.get_base); +# type_name = complexType.expand( name ); +-%] +[% XSD.create_xsd_name(complexType) %] +[% ELSE; + %] an atomic base type. Unfortunately there's no documentation generated +on atomic base types' base type yet.[% +END -%] + +SOAP::WSDL's schema implementation does not validate data yet - however, the +following restrictions apply for this type's value: + +[%- FOREACH facet = [ + 'length', + 'minLength', + 'maxLength', + 'totalDigits', + 'fractionDigits', + 'minInclusive', + 'maxInclusive', + 'minExclusive', + 'maxExclusive', + 'pattern', + 'enumeration' + ]; + IF (facet_method = complexType.can( "get_" _ facet )); + facet_value = facet_method( complexType ); + IF (facet_value.size()); +%] + [% IF (facet == 'enumeration'); + %]valid values (enumeration) +[%- ELSE; + facet; + END -%]:[% FOREACH value = facet_value %] [% value.get_value; END -%] +[% END; + END; +END %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt index 3cd54f6..9a443ca 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt @@ -7,7 +7,7 @@ ELSIF (complexType.get_variety == 'group'); ELSIF (complexType.get_variety == 'choice'); INCLUDE complexType/POD/choice.tt(complexType = complexType); ELSIF (complexType.get_contentModel == 'simpleContent'); - INCLUDE complexType/POD/simpleContent.tt(complexType = complexType); + INCLUDE complexType/POD/structure/simpleContent.tt(complexType = complexType); ELSIF (complexType.get_contentModel == 'complexContent'); INCLUDE complexType/POD/complexContent.tt(complexType = complexType); -END %], \ No newline at end of file +END -%], \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/restriction.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/restriction.tt new file mode 100644 index 0000000..589efde --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/restriction.tt @@ -0,0 +1,7 @@ +{ +[%- IF complexType.get_name %] # [% XSD.create_xsd_name(complexType) %][% END %] +[%- indent = indent _ ' '; +FOREACH element = complexType.get_element %] +[% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%] +[% END %] +[% indent.replace('\s{2}$', ''); %]} \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/simpleContent.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/simpleContent.tt new file mode 100644 index 0000000..868261a --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure/simpleContent.tt @@ -0,0 +1 @@ + { value => $some_value } \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/all.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/all.tt index 8a3b986..9711549 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/all.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/all.tt @@ -8,7 +8,7 @@ Class::Std::initialize(); atomic_types = {}; FOREACH element = complexType.get_element %] -my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>); +my %[% XSD.perl_name(element.get_name) %]_of :ATTR(:get<[% XSD.perl_name(element.get_name) %]>); [%- END %] __PACKAGE__->_factory( @@ -18,23 +18,23 @@ __PACKAGE__->_factory( ) ], { [% FOREACH element = complexType.get_element -%] - [% element.get_name %] => \%[% element.get_name %]_of, + '[% element.get_name %]' => \%[% XSD.perl_name(element.get_name) %]_of, [% END -%] }, { [% FOREACH element = complexType.get_element; IF (type = element.get_type); - element_type = complexType.expand( type ); -%] - [% element.get_name %] => '[% XSD.get_type_prefix(element_type.0) %]::[% element_type.1 %]', + element_type = definitions.first_types.find_type(complexType.expand( type )); -%] + '[% element.get_name %]' => '[% XSD.create_xsd_name(element_type) %]', [% ELSE; IF (element.first_simpleType); atomic_types.${ element.get_name } = element.first_simpleType; ELSIF (element.first_complexType); atomic_types.${ element.get_name } = element.first_complexType; ELSE; - THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type - don't know what to do with it"; + THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type for element ${ element.get_name } - don't know what to do with it"; END; %] - [% element.get_name %] => '[% XSD.get_type_prefix(complexType.get_targetNamespace) %]::[% complexType.get_name %]::_[% element.get_name %]', + '[% element.get_name %]' => '[% XSD.create_subpackage_name({ value => element }) %]', [% END; END -%] } diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/atomicTypes.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/atomicTypes.tt index 053e865..298a913 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/atomicTypes.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/atomicTypes.tt @@ -1,7 +1,7 @@ [% FOREACH type IN atomic_types; %] - -package [% XSD.get_type_prefix(complexType.get_targetNamespace) %]::[% complexType.get_name %]::_[% type.key %]; +[%# TODO generate name create_name method %] +package [% XSD.create_subpackage_name(type); %]; use strict; use warnings; { diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/attributeSet.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/attributeSet.tt index 182bbf0..90401e8 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/attributeSet.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/attributeSet.tt @@ -1,16 +1,15 @@ -[% IF (complexType.get_attribute.size) %] -package [% XSD.get_type_prefix(complexType.get_targetNamespace) %]::[% complexType.get_name.replace('\.','::').replace('-','_') %]::_ATTR; +[% IF (complexType.get_attribute.size) -%] +package [% XSD.create_xmlattr_name(complexType) %]; use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet); { # BLOCK to scope variables -[% - -FOREACH element = complexType.get_attribute %] +[% FOREACH element = complexType.get_attribute %] my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>); [%- END %] __PACKAGE__->_factory( - [ qw([% FOREACH element = complexType.get_attribute %] + [ qw( +[%- FOREACH element = complexType.get_attribute %] [% element.get_name -%] [% END %] ) ], @@ -22,23 +21,24 @@ __PACKAGE__->_factory( { [% FOREACH element = complexType.get_attribute; IF (type = element.get_type); - element_type = complexType.expand( type ); + element_type = definitions.first_types.find_type(complexType.expand( type )); -%] - [% element.get_name %] => '[% XSD.get_type_prefix(element_type.0) %]::[% element_type.1 %]', + [% element.get_name %] => '[% XSD.create_xsd_name(element_type) %]', [% - ELSE; - IF (element.first_simpleType); + ELSIF (ref = element.get_ref); + attribute = definitions.first_types.find_attribute( complexType.expand(ref) ); + # element_type = definitions.get_types.0.find_type(complexType.expand( attribute.get_type )); +%] + [% attribute.get_name %] => '[% XSD.create_xsd_name(attribute) %]', +[% ELSIF (element.first_simpleType); THROW NOT_IMPLEMENTED , "Attributes with atomic simpleType definition are not implemented yet"; atomic_types.${ element.get_name } = element.first_simpleType; - ELSE; - THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type - don't know what to do with it"; - END; %] - [% element.get_name %] => '[% XSD.get_type_prefix(complexType.get_targetNamespace) %]::[% complexType.get_name %]::_[% element.get_name %]', -[% END; + ELSE; + THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type for attribute ${ element.get_name } in ${ complexType.get_name } - don't know what to do with it"; + END; END -%] } ); } # end BLOCK - [% END %] \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/contentModel.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/contentModel.tt index ebfbc22..ebfd679 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/contentModel.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/contentModel.tt @@ -1,7 +1,19 @@ +[% IF (complexType.get_attribute.size) -%] +our $XML_ATTRIBUTE_CLASS = '[% XSD.create_xmlattr_name(complexType) %]'; +[% ELSE -%] +our $XML_ATTRIBUTE_CLASS; +undef $XML_ATTRIBUTE_CLASS; +[% END %] +sub __get_attr_class { + return $XML_ATTRIBUTE_CLASS; +} + [% IF (complexType.get_contentModel == 'simpleContent'); INCLUDE complexType/simpleContent.tt(complexType = complexType); ELSIF (complexType.get_contentModel == 'complexContent'); INCLUDE complexType/complexContent.tt(complexType = complexType); ELSE; INCLUDE complexType/variety.tt(complexType = complexType); -END %] +END -%] + +[% INCLUDE complexType/attributeSet.tt %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt index e705bc8..125529f 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/extension.tt @@ -20,7 +20,7 @@ END; complexType.set_element( element_list ); -%] -use base qw([% XSD.get_type_prefix(base_name.0) %]::[% base_name.1.replace('\.', '::') %]); +use base qw([% XSD.create_xsd_name( base_type ) %]); [% INCLUDE complexType/variety.tt(complexType = complexType); diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.tt index f6a7f2d..899faf8 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.tt @@ -1,7 +1,7 @@ [% IF (base=complexType.get_base); - base_name=complexType.expand(base); + base_type=definitions.get_types.0.find_type(complexType.expand(base)); -%] -use base qw([% XSD.get_type_prefix(base_name.0) %]::[% base_name.1.replace('\.', '::') %]); +use base qw([% XSD.create_xsd_type(base_type) %]); [% ELSE; THROW NOT_IMPLEMENTED, "restriction without base not supported"; diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent.tt index a92faa7..414abb1 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent.tt @@ -1,8 +1,9 @@ [% IF (complexType.get_variety == 'restriction'); INCLUDE complexType/restriction.tt(complexType = complexType); ELSIF (complexType.get_variety == 'extension'); - THROW NOT_IMPLEMENTED, "${ complexType.get_name } - complexType simpleContent extension not implemented yet"; + INCLUDE complexType/simpleContent/extension.tt(complexType = complexType); + # THROW NOT_IMPLEMENTED, "${ complexType.get_name } - complexType simpleContent extension not implemented yet"; ELSE; - THROW UNKNOWN, "unknown variety ${ complexType.get_variety }"; + THROW UNKNOWN, "unknown variety ${ complexType.get_variety } in complexType name='${complexType.get_name}'"; END; %] \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent/extension.tt b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent/extension.tt new file mode 100644 index 0000000..f263f88 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/complexType/simpleContent/extension.tt @@ -0,0 +1,11 @@ +[% IF (base=complexType.get_base); + base_type=definitions.get_types.0.find_type(complexType.expand(base)); +-%] +use base qw( + SOAP::WSDL::XSD::Typelib::ComplexType + [% XSD.create_xsd_name(base_type) %] +); +[% +ELSE; + THROW NOT_IMPLEMENTED, "extension without base not supported"; +END %] \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/element.tt b/lib/SOAP/WSDL/Generator/Template/XSD/element.tt index 0c59c10..c2af3c2 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/element.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/element.tt @@ -1,5 +1,5 @@ [% USE XSD(context) %] -package [% XSD.get_element_prefix(element.get_targetNamespace) %]::[% element.get_name.replace('\.','::') %]; +package [% XSD.create_xsd_name(element) %]; use strict; use warnings; @@ -13,17 +13,21 @@ __PACKAGE__->__set_minOccurs([% element.get_minOccurs %]); __PACKAGE__->__set_maxOccurs([% element.get_maxOccurs %]); __PACKAGE__->__set_ref([% IF element.get_ref; %]'[% element.get_ref %]'[% END %]); -[%- IF (type = element.get_type); -%] +[%- IF (type_name = element.get_type); -%] use base qw( SOAP::WSDL::XSD::Typelib::Element - [% INCLUDE _type_class.tt( type = type, node = element ) %] + [% type = definitions.get_types.0.find_type(element.expand(type_name)); + XSD.create_xsd_name(type) %] ); } -[%- ELSIF (ref = element.get_ref); -%] +[%- ELSIF (ref = element.get_ref); + ref_from = ref.split(':'); +-%] # element ref="[% ref %]" use base qw( - [% element_prefix %]::[% ref.split(':').1 %] + [% ref_element = definitions.get_types.0.find_element(element.expand(ref)); + XSD.create_xsd_name( ref_element ); %] ); } @@ -41,16 +45,9 @@ use base qw( SOAP::WSDL::XSD::Typelib::Element SOAP::WSDL::XSD::Typelib::ComplexType ); + [% INCLUDE complexType/contentModel.tt -%] -} - -package [% XSD.get_element_prefix(element.get_targetNamespace) %]::[% element.get_name.replace('\.','::').replace('-','_') %]::_ATTR; -use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet); -[% INCLUDE complexType/attributeSet.tt %] - -[% ELSE %] - } # end of BLOCK [% END %] @@ -67,18 +64,20 @@ use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet); [% head1 %] NAME -[% XSD.get_element_prefix(element.get_targetNamespace) %]::[% element.get_name %] +[% XSD.create_xsd_name(element) %] [% head1 %] DESCRIPTION Perl data type class for the XML Schema defined element [% element.get_name %] from the namespace [% element.get_targetNamespace %]. +[% INCLUDE POD/annotation.tt(node = element) %] + [% head1 %] METHODS [% head2 %] new - my $element = [% XSD.get_element_prefix(element.get_targetNamespace) %]::[% element.get_name %]->new($data); + my $element = [% XSD.create_xsd_name(element) %]->new($data); Constructor. The following data structure may be passed to new(): diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/element/POD/contentModel.tt b/lib/SOAP/WSDL/Generator/Template/XSD/element/POD/contentModel.tt new file mode 100644 index 0000000..bdb111b --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/element/POD/contentModel.tt @@ -0,0 +1,8 @@ +[% IF (type = element.get_type); +ELSIF (simpleType = element.get_simpleType) %] +This XML element type class has a atomic simpleType as it's base: +[% + INCLUDE simpleType/POD/contentModel.tt(simpleType = simpleType); +ELSIF (simpleType = element.get_complexType); +ELSIF (ref_element = element.get_ref); +END %] \ No newline at end of file diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt index 2716f04..72f73e2 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType.tt @@ -1,5 +1,5 @@ [% USE XSD(context) -%] -package [% XSD.get_type_prefix(simpleType.get_targetNamespace) %]::[% simpleType.get_name.replace('\.','::').replace('-','_') %]; +package [% XSD.create_xsd_name(simpleType) %]; use strict; use warnings; @@ -21,20 +21,18 @@ __END__ [% pod %] -[% head1 %] [% XSD.get_type_prefix(simpleType.get_targetNamespace) %]::[% simpleType.get_name.replace('\.','::').replace('-','_') %] +[% head1 %] NAME + +[% XSD.create_name(simpleType) %] [% head1 %] DESCRIPTION Perl data type class for the XML Schema defined simpleType [% simpleType.get_name %] from the namespace [% simpleType.get_targetNamespace %]. -[% IF (simpleType.get_variety == 'list'); - INCLUDE simpleType/POD/list.tt; -ELSIF (simpleType.get_variety == 'restriction'); - INCLUDE simpleType/POD/restriction.tt; -ELSE; - THROW NOT_IMPLEMENTED "simpleType union not implemented yet in $simpleType.get_name"; -END %] +[% INCLUDE POD/annotation.tt(node = simpleType) %] + +[% INCLUDE simpleType/POD/contentModel.tt(simpleType = simpleType) %] [% head1 %] METHODS diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/contentModel.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/contentModel.tt new file mode 100644 index 0000000..92b2fd4 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/contentModel.tt @@ -0,0 +1,9 @@ +[% IF (simpleType.get_variety == 'list'); + INCLUDE simpleType/POD/list.tt; +ELSIF (simpleType.get_variety == 'restriction'); + INCLUDE simpleType/POD/restriction.tt; +ELSIF (simpleType.get_variety == 'union'); + INCLUDE simpleType/POD/union.tt; +ELSE; + # THROW NOT_IMPLEMENTED "simpleType " _ simpleType.get_variety _ "not implemented yet in $simpleType.get_name"; +END %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/list.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/list.tt index 68562ba..caa2d27 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/list.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/list.tt @@ -1,13 +1,9 @@ This clase is derived from [%- IF (name = simpleType.get_itemType); - type_name = simpleType.expand( name ); - IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%] -SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %] -[% ELSE -%] - [% type_prefix %]::[% type_name.1 %] -[% END; -ELSE; + type = definitions.get_types.0.find_type(simpleType.expand( name )); %] + [% XSD.create_xsd_name(type) %] +[% ELSE; # THROW NOT_IMPLEMENTED "atomic simpleType list not implemented yet in $simpleType.get_name"; %] a atomic base type. Unfortunately there's no documenatation generation for atomic base types yet. [% END -%]. diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/restriction.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/restriction.tt index db52e67..577c33c 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/restriction.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/restriction.tt @@ -1,12 +1,8 @@ This clase is derived from [%- IF (name = simpleType.get_base); - type_name = simpleType.expand( name ); - IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%] -SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %] -[% ELSE -%] - [% type_prefix %]::[% type_name.1 %] -[% END; -ELSE; + type = definitions.get_types.0.find_type(simpleType.expand(name)); %] + [% XSD.create_xsd_name(type); %] +[% ELSE; # THROW NOT_IMPLEMENTED "atomic simpleType restriction not implemented yet in $simpleType.get_name"; %] a atomic base type. Unfortunately there's no documenatation generation for atomic base types yet. [% END -%] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/union.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/union.tt new file mode 100644 index 0000000..04d73d5 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/POD/union.tt @@ -0,0 +1,8 @@ +This type class is derived by union. + +Derivation by union is not fully supported yet - value space constraints are +not checked yet. + +The current implementation of union resorts to inheriting from the base type, +which means (quoted from the XML Schema specs): "If the or +alternative is chosen, then the simple ur-type definition·." diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/contentModel.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/contentModel.tt index 63f9691..6754b42 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/contentModel.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/contentModel.tt @@ -2,6 +2,8 @@ INCLUDE simpleType/list.tt(simpleType = simpleType); ELSIF (simpleType.get_variety == 'restriction'); INCLUDE simpleType/restriction.tt(type = simpleType); +ELSIF (simpleType.get_variety == 'union'); + INCLUDE simpleType/union.tt(type = simpleType); ELSE; THROW NOT_IMPLEMENTED "${ element.get_name } - ${ simpleType.get_variety } not supported yet"; END %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/list.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/list.tt index e51a228..08b507c 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/list.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/list.tt @@ -1,17 +1,13 @@ +[% USE XSD %] # list derivation use base qw( SOAP::WSDL::XSD::Typelib::Builtin::list [% IF (name = simpleType.get_itemType); - type_name = simpleType.expand( name ); - IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%] - SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %] + type = definitions.get_types.0.find_type(simpleType.expand( name )); -%] + [% XSD.create_xsd_name(type) %] ); -[% ELSE -%] - [% type_prefix %]::[% type_name.1 %] -); -[% END; -ELSIF (type = simpleType.first_simpleType); %] +[% ELSIF (type = simpleType.first_simpleType); %] ); [% INCLUDE simpleType/atomicType.tt(type = type); diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/restriction.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/restriction.tt index 33d4360..f75a7c9 100644 --- a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/restriction.tt +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/restriction.tt @@ -1,9 +1,14 @@ # derivation by restriction [% IF (base = simpleType.get_base) -%] use base qw( - [% INCLUDE _type_class.tt(type = base, node=simpleType) %]); + [% + base_type = definitions.get_types.0.find_type(simpleType.expand(base)); + IF ! base_type; + THROW NOT_FOUND "No base type in " _ simpleType.get_parent.get_name; + END; + XSD.create_xsd_name(base_type) %]); [% ELSIF (type = simpleType.first_simpleType() ); INCLUDE simpleType/atomicType.tt(type = type); ELSE; THROW "neither base nor atomic type - don't know what to do" %] -[% END %] \ No newline at end of file +[% END %] diff --git a/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/union.tt b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/union.tt new file mode 100644 index 0000000..968f856 --- /dev/null +++ b/lib/SOAP/WSDL/Generator/Template/XSD/simpleType/union.tt @@ -0,0 +1,11 @@ +# derivation by union +# union is not fully supported yet - value space constraints are not +# checked yet. +# This implementation of union resorts to the simplest possible base, which +# is: "If the or alternative is chosen, then the +# simple ur-type definition·." +# + +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType +); diff --git a/lib/SOAP/WSDL/Generator/Visitor.pm b/lib/SOAP/WSDL/Generator/Visitor.pm index 04150db..634928e 100644 --- a/lib/SOAP/WSDL/Generator/Visitor.pm +++ b/lib/SOAP/WSDL/Generator/Visitor.pm @@ -77,24 +77,24 @@ Visitor: package PersonVisitor; use Class::Std; # handles all basic stuff like constructors etc. - + sub visit_Person { my ( $self, $object ) = @_; print "Person name is ", $object->get_name(), "\n"; } - + package Person; use Class::Std; my %name : ATTR(:name :default); - + sub accept { $_[1]->visit_Person( $_[0] ) } - + package main; my @person_from = (); for (qw(Gamma Helm Johnson Vlissides)) { push @person_from, Person->new( { name => $_ } ); } - + my $visitor = PersonVisitor->new(); for (@person_from) { $_->accept($visitor); @@ -269,7 +269,7 @@ SOAP::WSDL data classes: In your Visitor, you must implement visit_Foo methods for all classes you wish to visit. -Currently, all SOAP::WSDL::Generator::Visitor implementations include their own +The SOAP::WSDL::Generator::Visitor implementations include part of their own Iterator (which means they know how to find the next objects to visit). You may or may not choose to implement a separate Iterator. @@ -279,9 +279,12 @@ easy as writing something like this: my $visitor = MyVisitor->new(); my $parser = SOAP::WSDL::Expat::WSDLParser->new(); my $definitions = $parser->parse_file('my.wsdl'): - + $definitions->_accept( $visitor ); +If you need an iterator following the somewhat crude path of dependencies in +a WSDL1.1 definition, you might want to look at L. + =head1 REFERENCES =over @@ -296,10 +299,10 @@ Addison-Wesley Longman, Amsterdam. =head1 LICENSE AND COPYRIGHT -Copyright 2004-2007 Martin Kutter. +Copyright 2004-2008 Martin Kutter. -This file is part of SOAP-WSDL. You may distribute/modify it under -the same terms as perl itself +This file is part of SOAP-WSDL. You may distribute/modify it under the same +terms as perl itself =head1 AUTHOR @@ -307,9 +310,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 239 $ + $Rev: 391 $ $LastChangedBy: kutterma $ - $Id: Client.pm 239 2007-09-11 09:45:42Z kutterma $ + $Id: Client.pm 391 2007-11-17 21:56:13Z kutterma $ $HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $ =cut diff --git a/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm b/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm index 95aa640..1223a8e 100644 --- a/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm +++ b/lib/SOAP/WSDL/Generator/Visitor/Typemap.pm @@ -9,13 +9,11 @@ our $VERSION = q{2.00_25}; my %path_of :ATTR(:name :default<[]>); my %typemap_of :ATTR(:name :default<()>); -my %type_prefix_of :ATTR(:name :default<()>); -my %element_prefix_of :ATTR(:name :default<()>); +my %resolver_of :ATTR(:name :default<()>); sub START { my ($self, $ident, $arg_ref) = @_; - $type_prefix_of{ $ident } ||= 'MyTypes'; - $element_prefix_of{ $ident } ||= 'MyElements'; + $resolver_of { $ident } = $arg_ref->{ resolver }; } sub set_typemap_entry { @@ -41,105 +39,6 @@ sub add_element_path { # . $element->get_name(); } -sub visit_Definitions { - my ( $self, $ident, $definitions ) = ( $_[0], ident $_[0], $_[1] ); - - $self->set_definitions( $definitions ); - - for ( @{ $definitions->get_service() } ){ - $_->_accept($self); - } -} - -sub visit_Service { - my ( $self, $service ) = ( $_[0], $_[1] ); - - for ( @{ $service->get_port() } ) { $_->_accept($self); } -} - -sub visit_Port { - my ( $self, $ident, $port ) = ( $_[0], ident $_[0], $_[1] ); - - # This is a false assumption - typemaps may be valid for non-soap - # bindings as well. - # TODO check and correct - return if not $port->first_address(); - return if not $port->first_address()->isa('SOAP::WSDL::SOAP::Address'); - - my $binding = $self->get_definitions() - ->find_binding( $port->expand( $port->get_binding() ) ) - or die 'binding ' . $port->get_binding() . ' not found!'; - - $binding->_accept($self); -} - -sub visit_Binding { - my ( $self, $ident, $binding ) = ( $_[0], ident $_[0], $_[1] ); - - my $portType = $self->get_definitions() - ->find_portType( $binding->expand( $binding->get_type ) ) - or die 'portType not found: ' . $binding->binding_type; - - for my $operation ( @{ $binding->get_operation() } ) { - my $name = $operation->get_name(); - - # get the equally named operation from the portType - my ($op) = grep { $_->get_name eq $name } - @{ $portType->get_operation() } - or die "operation <$name> not found"; - - # visit every input, output and fault message... - for ( @{ $op->get_input }, @{ $op->get_output }, @{ $op->get_fault } ) { - $_->_accept($self); - } - } -} - -sub visit_OpMessage { - my ( $self, $ident, $operation_message ) = ( $_[0], ident $_[0], $_[1] ); - return if not( $operation_message->get_message() ); # we're in binding - - # TODO maybe allow more messages && overloading by specifying name - - # find message referenced in operation - my $message = $self->get_definitions()->find_message( - $operation_message->expand( $operation_message->get_message() ) ); - - for my $part ( @{ $message->get_part() } ) { - $part->_accept($self); - } -} - -sub visit_Part { - my ( $self, $ident, $part ) = ( $_[0], ident $_[0], $_[1] ); - - my $types_ref = $self->get_definitions()->first_types() - or warn "Empty part" . $part->get_name(); - - # resolve type - # If we have a type, this type is to be used in document/literal - # as global type. However this is forbidden, at least by WS-I. - # We should store the style/encoding somewhere, and regard it. - # TODO: auto-generate element for RPC bindings - if ( my $type_name = $part->get_type ) { - # FIXME support RPC-style calls - die "unsupported global type <$type_name> found in part ". $part->get_name(); - } - - # TODO factor out iterator or replace by lookup (probably better) - if ( my $element_name = $part->get_element() ) { - my $element = $types_ref->find_element( - $part->expand($element_name) ) - || die "no element $element_name found for part " . $part->get_name(); - $element->_accept($self); - return; - } - - warn 'neither type nor element - do not know what to do for part ' - . $part->get_name(); - return; -} - sub process_referenced_type { my ( $self, $ns, $localname ) = @_; return if not $localname; @@ -149,18 +48,13 @@ sub process_referenced_type { # Caveat: visits type if it's a referenced type from the # a ? b : c operation. my ($type, $typeclass); - if ( $ns eq 'http://www.w3.org/2001/XMLSchema' ) { - $typeclass = "SOAP::WSDL::XSD::Typelib::Builtin::$localname"; - } - else { - $type = $self->get_definitions()->first_types()->find_type( $ns, $localname ); - $typeclass = join( q{::}, $type_prefix_of{$ident}, $type->get_name() ); - } + $type = $self->get_definitions()->first_types()->find_type( $ns, $localname ); + $typeclass = $self->get_resolver()->create_xsd_name($type); # set before to allow it to be used from inside _accept $self->set_typemap_entry($typeclass); - $type->_accept($self) if ($type); + $type->_accept($self) if ($ns ne 'http://www.w3.org/2001/XMLSchema'); # set afterwards again (just to be sure...) $self->set_typemap_entry($typeclass); @@ -202,17 +96,21 @@ sub visit_XSD_Element { if ($element->get_simpleType()) { # warn "simpleType " . $element->get_name(); my @path = @{ $path_of{ ${ $self } } }; - my $typeclass = defined ($parent) - ? join '::_', $parent , $element->get_name() - : join q{::}, $element_prefix_of{$ident}, $element->get_name(); + my $typeclass = $self->get_resolver()->create_subpackage_name($element); +# my $typeclass = defined ($parent) +# ? join q{::_}, $parent , $element->get_name() +# : join q{::}, $self->resolver()->get_element_prefix( $element->get_targetNamespace), $element->get_name(); $self->set_typemap_entry($typeclass); + $typeclass =~s{\.}{::}g; + $typeclass =~s{\-}{_}g; last SWITCH; } # 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; + my $typeclass = $self->get_resolver()->create_subpackage_name($element); +# my $typeclass = join q{::}, $self->get_resolver()->get_element_prefix( $element->get_targetNamespace), $element->get_name(); +# $typeclass =~s{\.}{::}g; +# $typeclass =~s{\-}{_}g; $self->set_typemap_entry($typeclass); $self->process_atomic_type( $element->first_complexType() @@ -226,9 +124,10 @@ sub visit_XSD_Element { # a normal (not atomic) type, we just override it here 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; + my $typeclass = $self->get_resolver()->create_xsd_name($element); +# my $typeclass = join q{::}, $self->get_resolver()->get_element_prefix($element->get_targetNamespace), $element->get_name(); +# $typeclass =~s{\.}{::}g; +# $typeclass =~s{\-}{_}g; $self->set_typemap_entry($typeclass); } @@ -238,11 +137,12 @@ sub visit_XSD_Element { sub visit_XSD_ComplexType { my ($self, $ident, $type) = ($_[0], ident $_[0], $_[1] ); - my $content_model = $type->get_flavor(); - # TODO is this allowed ? or should we better die ? - return if not $content_model; # empty complexType + my $variety = $type->get_variety(); + my $content_model = $type->get_contentModel; + return if not $variety; # empty complexType + return if ($content_model eq 'simpleContent'); - if ( grep { $_ eq $content_model} qw(all sequence choice) ) + if ( grep { $_ eq $variety} qw(all sequence choice) ) { # visit child elements for (@{ $type->get_element() || [] }) { @@ -251,7 +151,21 @@ sub visit_XSD_ComplexType { return; } - warn "unsupported content model $content_model found in " + if (grep { $_ eq $variety } qw(restriction extension) ) { + # resolve base / get atomic type and run on elements + if (my $type_name = $type->get_base()) { + my $subtype = $self->get_definitions() + ->first_types()->find_type( $type->expand($type_name) ); + # visit child elements + for (@{ $subtype->get_element() || [] }) { + $_->_accept( $self ); + } + # that's all for restriction + return if ($variety eq 'restriction'); + } + } + + warn "unsupported content model $variety found in " . "complex type " . $type->get_name() . " - typemap may be incomplete"; } diff --git a/lib/SOAP/WSDL/Manual.pod b/lib/SOAP/WSDL/Manual.pod index e11020a..1a2da7d 100644 --- a/lib/SOAP/WSDL/Manual.pod +++ b/lib/SOAP/WSDL/Manual.pod @@ -22,15 +22,15 @@ service). =item * Write script - use MyInterface::SERVICE_NAME::PORT_NAME; - my $service = MyInterface::SERVICE_NAME::PORT_NAME->new(); - + use MyInterfaces::SERVICE_NAME::PORT_NAME; + my $service = MyInterfaces::SERVICE_NAME::PORT_NAME->new(); + my $result = $service->SERVICE_METHOD(); die $result if not $result; - + print $result; -C should give you some overview +C should give you some overview about the service's interface structure. The results of all calls to your service object's methods (except new) are @@ -103,9 +103,9 @@ included perldoc will be, too - if not, blame the web service author. =item * Write a perl script (or module) accessing the web service. - use MyInterface::SERVICE_NAME; - my $service = MyInterface::SERVICE_NAME->new(); - + use MyInterfaces::SERVICE_NAME::PORT_NAME; + my $service = MyInterfaces::SERVICE_NAME::PORT_NAME->new(); + my $result = $service->SERVICE_METHOD(); die $result if not $result; print $result; @@ -264,7 +264,7 @@ method called "get_basic_credentials" to SOAP::WSDL::Transport::HTTP: When using SOAP::Transport::HTTP (SOAP::Lite is installed), do the same to this backend: - *SOAP::Transport::HTTP::get_basic_credentials = sub { + *SOAP::Transport::HTTP::Client::get_basic_credentials = sub { return ($user, $password); }; diff --git a/lib/SOAP/WSDL/Manual/WS_I.pod b/lib/SOAP/WSDL/Manual/WS_I.pod index 4af8c2d..cdd31f5 100644 --- a/lib/SOAP/WSDL/Manual/WS_I.pod +++ b/lib/SOAP/WSDL/Manual/WS_I.pod @@ -430,7 +430,7 @@ TODO support rpc-literal bindings. The wsdl:import element imports the referenced WSDL definition. This is rather hard-wired and does not allow to specify a wsdl:import without -a resolvable location. +a resolvable location in SOAP::WSDL. =head2 R4002 @@ -681,7 +681,7 @@ is Schema valid. WSDL description. SOAP::WSDL (partially) supports the wsdl:import statement. The wsdl:include -statement is not supported (yet). +statement is not supported. It's the responsibility of the WSDL author to use only the wsdl:import statement for importing WSDL descriptions. @@ -1252,9 +1252,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 514 $ + $Rev: 562 $ $LastChangedBy: kutterma $ - $Id: WS_I.pod 514 2008-01-31 19:57:52Z kutterma $ + $Id: WS_I.pod 562 2008-02-22 20:32:17Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Manual/WS_I.pod $ =cut diff --git a/lib/SOAP/WSDL/Manual/XSD.pod b/lib/SOAP/WSDL/Manual/XSD.pod index 58e38cc..4638527 100644 --- a/lib/SOAP/WSDL/Manual/XSD.pod +++ b/lib/SOAP/WSDL/Manual/XSD.pod @@ -305,18 +305,17 @@ XML Schema facets are not implemented yet. They will probably implemented some day by putting constant methods into the correspondent classes. -=head1 ATTRIBUTES - -XML attributes are not implemented yet. The documentation below sketches -how XML attributes will be implemented in the future. - -All XML attributes are derived from SOAP::WSDL::XSD::Typelib::Attribute. +=head2 Attributes The attribute set for a XML element (derived from anySimpleType or complexType) is implemented as a sub-package of the element derived from SOAP::WSDL::XSD::Typelib::AttributeSet. -The sub-package is named as the top package, suffixed with C<_ATTR>. +The sub-package is named as the corresponding type or element package, +suffixed with C. The suffix "XmlAttr" has carefully been chosen to +avoid potential naming clashes: The name XmlAttr cannot be included as +element or type name in XML schemas - the XML standard bans the use of names +starting with "xml" (case-insensitive). All XML attributes for a XML element are set- and retrievable via the method C. The name is chosen to allow mimicing SOAP::Lite's behaviour, which @@ -336,6 +335,28 @@ get_FOO methods. The C method provides auto-vivification: An xml object's attribute set is instantiated when accessed. +Auto-vivification is only triggered if there actually B a set of +attributes for the class/object in question, so you may want to test +whether the result of ->attr is defined: + + my $attr = $unknownObject->attr(); + if (defined($attr)) { + $unknownObject->attr({ + some => 'value', + }); + } + +=head2 group + +CAVEAT: Group resolution is not implemented yet. + +XML Schema Group definitions are just treated as aliases that can be +inserted in complexType definitions by referencing them. That is, there's +no difference between a complexType with simpleContent and a sequence of +three elements, and a complexType with simpleContent referencing a group +containing the same sequence of elements. + + =head1 CAVEATS =over @@ -364,70 +385,153 @@ The constructors of all SOAP::WSDL::XSD::Typelib:: classes don't ! The following XML Schema declaration elements are not supported yet: +=head2 XML Schema elements partially supported + +=head3 Type definition elements + =over -=item * Declaration elements +=item * simpleContent - attribute - notation - -=item * Type definition elements - - simpleContent - union - -=item * Content model definition elements - - any - anyAttribute - attributeGroup - group - -=item * Identity definition elements - - field - key - keyref - selector - unique - -=item * Inclusion elements - - import - include - redefine +simpleContent is only supported with a restriction or extension with a C +attribute. simpleContent declarations deriving from a atomic type are not +supported (yet). =back -The following XML Schema declaration elements are supported, but have no -effect yet: +=head3 Inclusion elements =over -=item * Factes +=item * import - enumeration - fractionDigits - lenght - maxExclusive - maxInclusiove - maxLength - minExclusive - minInclusive - minLength - pattern - totalDigits - whitespace +The import includion 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. -=item * Documentation elements +L keeps track of +included schemas and prevents import loops. - appinfo +=back + +=head3 Facets + +The following XML Schema declaration elements are supported, but have no +effect yet. + +=over + +=item * enumeration + +=item * fractionDigits + +=item * lenght + +=item * maxExclusive + +=item * maxInclusiove + +=item * maxLength + +=item * minExclusive + +=item * minInclusive + +=item * minLength + +=item * pattern + +=item * totalDigits + +=item * whitespace + +=back + + +=head2 XML Schema elements not implemented + +=head3 Declaration elements + +=over + +=item * notation + +=back + +=head3 Content model definition elements + +=over + +=item * any + +The horror of each XML schema implementation: Just anything... + +C declarations are not supported yet. + +=item * anyAttribute + +=item * attributeGroup + +C declarations actually just are macros for XML Schema +writers: Including an attributeGroup in a declaration has the same effect +as including all attributes in the group. + +Just not implemented yet. + +=item * group + +The group definition element is not supported yet. + +=back + +=head3 Identity definition elements + +These declaration elements don't declare XML elements, but apply identity +constraints. They have no effect yet. + +=over + +=item * field + +=item * key + +=item * keyref + +=item * selector + +=item * unique + +=back + +=head3 Inclusion elements + +=over + +=item * include + +Use of the include inclusion element is forbidden by the WS-I basic profile. +It is not supported (yet). + +=item * redefine + +Not supported (yet). + +=back + +=head3 * Documentation elements + +=over + +=item * appinfo + +The appinfo documentation element is ignored. =back =head1 LICENSE -Copyright 2007 Martin Kutter. +Copyright 2007,2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself diff --git a/lib/SOAP/WSDL/OpMessage.pm b/lib/SOAP/WSDL/OpMessage.pm index 65caea0..9d8083d 100644 --- a/lib/SOAP/WSDL/OpMessage.pm +++ b/lib/SOAP/WSDL/OpMessage.pm @@ -4,9 +4,9 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -my %body_of :ATTR(:name :default<[]>); -my %header_of :ATTR(:name
:default<[]>); -my %headerfault_of :ATTR(:name :default<[]>); -my %message_of :ATTR(:name :default<()>); +my %body_of :ATTR(:name :default<[]>); +my %header_of :ATTR(:name
:default<[]>); +my %headerfault_of :ATTR(:name :default<[]>); +my %message_of :ATTR(:name :default<()>); 1; diff --git a/lib/SOAP/WSDL/Server.pm b/lib/SOAP/WSDL/Server.pm index f61aba8..0d57a32 100644 --- a/lib/SOAP/WSDL/Server.pm +++ b/lib/SOAP/WSDL/Server.pm @@ -162,7 +162,7 @@ hash keys. =head1 LICENSE AND COPYRIGHT -Copyright 2004-2007 Martin Kutter. +Copyright 2004-2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself diff --git a/lib/SOAP/WSDL/Server/CGI.pm b/lib/SOAP/WSDL/Server/CGI.pm index ef26da1..511b8fa 100644 --- a/lib/SOAP/WSDL/Server/CGI.pm +++ b/lib/SOAP/WSDL/Server/CGI.pm @@ -12,7 +12,7 @@ use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Server); -our $VERSION=q{2.00_27}; +our $VERSION=q{2.00_33}; # mostly copied from SOAP::Lite. Unfortunately we can't use SOAP::Lite's CGI # server directly - we would have to swap out it's base class... @@ -38,6 +38,8 @@ sub handle { my $content = q{}; my $buffer; + + # do wen need to use bytes; here ? binmode(STDIN); while (read(STDIN,$buffer,$length - length($content))) { $content .= $buffer; @@ -113,11 +115,64 @@ SOAP::WSDL::Server::CGI - CGI based SOAP server =head1 SYNOPSIS + use MyServer::TestService::TestPort; + my $server = MyServer::TestService::TestPort->new({ + dispatch_to => 'main', + transport_class => 'SOAP::WSDL::Server::CGI', # optional, default + }); + $server->handle(); + +=head1 USAGE + +To use SOAP::WSDL::Server::CGI efficiently, you should first create a server +interface using L. + +SOAP::WSDL::Server dispatches all calls to appropriately named methods in the +class or object set via C. + +See the generated server class on details. + =head1 DESCRIPTION +Lightweight CGI based SOAP server. SOAP::WSDL::Server::CGI does not provide +the fancier things of CGI handling, like URL parsing, parameter extraction +or the like, but provides a basic SOAP server using SOAP::WSDL::Server. + +=head1 METHODS + +=head1 EXCEPTION HANDLING + +SOAP::WSDL::CGI handles the following errors: + +=over + +=item * XML parsing error + +=back + +The proper way to throw a exception is just to die - +SOAP::WSDL::Server::CGI catches the exception and sends a SOAP Fault +back to the client. + +If you want more control over the SOAP Fault sent to the client, you can +die with a SOAP::WSDL::SOAP::Fault11 object - or just let the +SOAP::Server's deserializer create one for you: + + my $soap = MyServer::SomeService->new(); + + die $soap->get_deserializer()->generate_fault({ + code => 'soap:Server', + role => 'urn:localhost', + message => "The error message to pas back", + detail => "Some details on the error", + }); + +You may use any other object as exception, provided it has a +serialize() method which returns the object's XML representation. + =head1 LICENSE AND COPYRIGHT -Copyright 2004-2007 Martin Kutter. +Copyright 2004-2008 Martin Kutter. This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself diff --git a/lib/SOAP/WSDL/Service.pm b/lib/SOAP/WSDL/Service.pm index 20fd48c..0cc240c 100644 --- a/lib/SOAP/WSDL/Service.pm +++ b/lib/SOAP/WSDL/Service.pm @@ -4,6 +4,6 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -my %port_of :ATTR(:name :default<()>); +my %port_of :ATTR(:name :default<[]>); 1; diff --git a/lib/SOAP/WSDL/TypeLookup.pm b/lib/SOAP/WSDL/TypeLookup.pm index d88a0f2..d5126c1 100644 --- a/lib/SOAP/WSDL/TypeLookup.pm +++ b/lib/SOAP/WSDL/TypeLookup.pm @@ -4,7 +4,7 @@ use warnings; our $VERSION=q{2.00_31}; -my %TYPES = ( +my %TYPE_FROM = ( # wsdl: 'http://schemas.xmlsoap.org/wsdl/' => { 'import' => { @@ -97,10 +97,11 @@ my %TYPES = ( }, attribute => { type => 'CLASS', - class => 'SOAP::WSDL::XSD::Attribute' # not implemented yet + class => 'SOAP::WSDL::XSD::Attribute', }, - attributeGroup => { - type => 'SKIP', # not implemented yet + attributeGroup => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::AttributeGroup', }, key => { type => 'SKIP', # not implemented yet @@ -115,7 +116,12 @@ my %TYPES = ( type => 'SKIP', # not implemented yet }, annotation => { - type => 'SKIP', # not implemented yet + type => 'CLASS', # not implemented yet + class => 'SOAP::WSDL::XSD::Annotation', + }, + documentation => { + type => 'CONTENT', + method => 'set_documentation', }, appinfo => { type => 'SKIP', # not implemented yet @@ -162,13 +168,12 @@ my %TYPES = ( method => 'set_union', }, enumeration => { - type => 'SKIP', - # method => 'push_enumeration', + type => 'CLASS', + class => 'SOAP::WSDL::XSD::Enumeration', }, group => { - type => 'METHOD', - method => 'set_variety', - value => 'group', + type => 'CLASS', + class => 'SOAP::WSDL::XSD::Group', }, all => { type => 'METHOD', @@ -185,14 +190,51 @@ my %TYPES = ( method => 'set_variety', value => 'sequence', }, + value => { + type => 'SKIP', + }, + minExclusive => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::MinExclusive', + }, + maxExclusive => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::MaxExclusive', + }, + minInclusive => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::MinInclusive', + }, + maxInclusive => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::MaxInclusive', + }, + maxLength => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::MaxLength', + }, + minLength => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::MinLength', + }, + totalDigits => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::TotalDigits', + }, + fractionDigits => { + type => 'CLASS', + class => 'SOAP::WSDL::XSD::FractionDigits', + }, }, ); +$TYPE_FROM{ 'http://www.w3.org/2000/10/XMLSchema' } = $TYPE_FROM{ 'http://www.w3.org/2001/XMLSchema' }; + sub lookup { my $self = shift; my $namespace = shift || 'http://schemas.xmlsoap.org/wsdl/'; my $name = shift; - return $TYPES{ $namespace }->{ $name }; + return $TYPE_FROM{ $namespace }->{ $name }; } 1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/Types.pm b/lib/SOAP/WSDL/Types.pm index 5757766..d90bd35 100644 --- a/lib/SOAP/WSDL/Types.pm +++ b/lib/SOAP/WSDL/Types.pm @@ -23,6 +23,16 @@ sub find_type { return; } +sub find_attribute { + my ($self, $ns, $name) = @_; + ($ns, $name) = @{ $ns } if ref $ns; # allow passing list refs + foreach my $schema (@{ $schema_of{ ident $self } }) { + my $type = $schema->find_attribute($ns, $name); + return $type if $type; + } + return; +} + sub find_element { my ($self, $ns, $name) = @_; ($ns, $name) = @{ $ns } if ref $ns; # allow passing list refs diff --git a/lib/SOAP/WSDL/XSD/Annotation.pm b/lib/SOAP/WSDL/XSD/Annotation.pm new file mode 100644 index 0000000..284f845 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/Annotation.pm @@ -0,0 +1,20 @@ +package SOAP::WSDL::XSD::Annotation; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %appinfo_of :ATTR(:name :default<()>); + +# documentation provided by Base + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/Attribute.pm b/lib/SOAP/WSDL/XSD/Attribute.pm index 3cdded8..b9aace5 100644 --- a/lib/SOAP/WSDL/XSD/Attribute.pm +++ b/lib/SOAP/WSDL/XSD/Attribute.pm @@ -19,14 +19,17 @@ our $VERSION=q{2.00_29}; # Content: (annotation?, (simpleType?)) # +# id provided by Base +# name provided by Base +# annotation provided by Base my %default_of :ATTR(:name :default<()>); my %fixed_of :ATTR(:name :default<()>); -my %form_of :ATTR(:name
:default<()>); -# id provided by Base -# name provided by Base +my %form_of :ATTR(:name :default<()>); + my %type_of :ATTR(:name :default<()>); -my %use_of :ATTR(:name :default<()>); +my %use_of :ATTR(:name :default<()>); +my %ref_of :ATTR(:name :default<()>); # may be defined as atomic simpleType my %simpleType_of :ATTR(:name :default<()>); diff --git a/lib/SOAP/WSDL/XSD/AttributeGroup.pm b/lib/SOAP/WSDL/XSD/AttributeGroup.pm new file mode 100644 index 0000000..1bdd543 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/AttributeGroup.pm @@ -0,0 +1,27 @@ +package SOAP::WSDL::XSD::AttributeGroup; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_29}; + +# +# Content: (annotation?, ((attribute | attributeGroup)*, anyAttribute?)) +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +my %ref_of :ATTR(:name :default<()>); + +# may be defined as atomic simpleType +my %attribute_of :ATTR(:name :default<()>); +my %attributeGroup_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/ComplexType.pm b/lib/SOAP/WSDL/XSD/ComplexType.pm index 6980b67..4157388 100644 --- a/lib/SOAP/WSDL/XSD/ComplexType.pm +++ b/lib/SOAP/WSDL/XSD/ComplexType.pm @@ -6,16 +6,28 @@ use Class::Std::Fast::Storable; use Scalar::Util qw(blessed); use base qw/SOAP::WSDL::Base/; -our $VERSION=q{2.00_29}; +our $VERSION=q{2.00_33}; + +my %length_of :ATTR(:name :default<[]>); +my %minLength_of :ATTR(:name :default<[]>); +my %maxLength_of :ATTR(:name :default<[]>); +my %pattern_of :ATTR(:name :default<[]>); +my %enumeration_of :ATTR(:name :default<[]>); +my %whiteSpace_of :ATTR(:name :default<[]>); +my %totalDigits_of :ATTR(:name :default<[]>); +my %fractionDigits_of :ATTR(:name :default<[]>); +my %minExclusive :ATTR(:name :default<[]>); +my %minInclusive :ATTR(:name :default<[]>); +my %maxExclusive :ATTR(:name :default<[]>); +my %maxInclusive :ATTR(:name :default<[]>); my %annotation_of :ATTR(:name :default<()>); my %attribute_of :ATTR(:name :default<()>); my %element_of :ATTR(:name :default<()>); -#my %flavor_of :ATTR(:name :default<()>); +my %group_of :ATTR(:name :default<()>); my %variety_of :ATTR(:name :default<()>); my %base_of :ATTR(:name :default<()>); my %itemType_of :ATTR(:name :default<()>); -my %enumeration_of :ATTR(:name :default<()>); my %abstract_of :ATTR(:name :default<()>); my %mixed_of :ATTR(:name :default<()>); # default is false diff --git a/lib/SOAP/WSDL/XSD/Enumeration.pm b/lib/SOAP/WSDL/XSD/Enumeration.pm new file mode 100644 index 0000000..4efc2e0 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/Enumeration.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::Enumeration; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/FractionDigits.pm b/lib/SOAP/WSDL/XSD/FractionDigits.pm new file mode 100644 index 0000000..4150db2 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/FractionDigits.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::Pattern; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/Group.pm b/lib/SOAP/WSDL/XSD/Group.pm new file mode 100644 index 0000000..afae716 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/Group.pm @@ -0,0 +1,38 @@ +package SOAP::WSDL::XSD::Group; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# +# +# +# . . . +# +# +# +# +# +# +# +# +# +# +# +# +# +# +# + +my %ref_of :ATTR(:name :default<()>); + +my %maxOccurs_of :ATTR(:name :default<()>); +my %minOccurs_of :ATTR(:name :default<()>); +my %annotation_of :ATTR(:name :default<()>); +my %element_of :ATTR(:name :default<()>); +my %group_of :ATTR(:name :default<()>); +my %variety_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/Length.pm b/lib/SOAP/WSDL/XSD/Length.pm new file mode 100644 index 0000000..9797554 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/Length.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::Length; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/MaxExclusive.pm b/lib/SOAP/WSDL/XSD/MaxExclusive.pm new file mode 100644 index 0000000..18425c0 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/MaxExclusive.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::MaxExclusive; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/MaxInclusive.pm b/lib/SOAP/WSDL/XSD/MaxInclusive.pm new file mode 100644 index 0000000..c805543 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/MaxInclusive.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::MaxInclusive; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/MaxLength.pm b/lib/SOAP/WSDL/XSD/MaxLength.pm new file mode 100644 index 0000000..301912d --- /dev/null +++ b/lib/SOAP/WSDL/XSD/MaxLength.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::MaxLength; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/MinExclusive.pm b/lib/SOAP/WSDL/XSD/MinExclusive.pm new file mode 100644 index 0000000..92772fc --- /dev/null +++ b/lib/SOAP/WSDL/XSD/MinExclusive.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::MinExclusive; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/MinInclusive.pm b/lib/SOAP/WSDL/XSD/MinInclusive.pm new file mode 100644 index 0000000..e3a1acc --- /dev/null +++ b/lib/SOAP/WSDL/XSD/MinInclusive.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::MinInclusive; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/MinLength.pm b/lib/SOAP/WSDL/XSD/MinLength.pm new file mode 100644 index 0000000..9f0a598 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/MinLength.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::MinLength; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/Pattern.pm b/lib/SOAP/WSDL/XSD/Pattern.pm new file mode 100644 index 0000000..4150db2 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/Pattern.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::Pattern; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/Schema.pm b/lib/SOAP/WSDL/XSD/Schema.pm index 7edf005..e6178d5 100644 --- a/lib/SOAP/WSDL/XSD/Schema.pm +++ b/lib/SOAP/WSDL/XSD/Schema.pm @@ -4,19 +4,21 @@ use warnings; use Class::Std::Fast::Storable; use base qw(SOAP::WSDL::Base); -our $VERSION=q{2.00_25}; +our $VERSION=q{2.00_33}; # child elements -my %type_of :ATTR(:name :default<[]>); -my %element_of :ATTR(:name :default<[]>); -my %group_of :ATTR(:name :default<[]>); +my %attributeGroup_of :ATTR(:name :default<[]>); +my %attribute_of :ATTR(:name :default<[]>); +my %element_of :ATTR(:name :default<[]>); +my %group_of :ATTR(:name :default<[]>); +my %type_of :ATTR(:name :default<[]>); # attributes my %attributeFormDefault_of :ATTR(:name :default<()>); -my %blockDefault_of :ATTR(:name :default<()>); -my %elementFormDefault_of :ATTR(:name :default<()>); -my %finalDefault_of :ATTR(:name :default<()>); -my %version_of :ATTR(:name :default<()>); +my %blockDefault_of :ATTR(:name :default<()>); +my %elementFormDefault_of :ATTR(:name :default<()>); +my %finalDefault_of :ATTR(:name :default<()>); +my %version_of :ATTR(:name :default<()>); # id # name diff --git a/lib/SOAP/WSDL/XSD/Schema/Builtin.pm b/lib/SOAP/WSDL/XSD/Schema/Builtin.pm index 60597d6..d049891 100644 --- a/lib/SOAP/WSDL/XSD/Schema/Builtin.pm +++ b/lib/SOAP/WSDL/XSD/Schema/Builtin.pm @@ -8,40 +8,48 @@ use base qw(SOAP::WSDL::XSD::Schema); # all builtin types - add validation (e.g. content restrictions) later... my %BUILTINS = ( - 'string' => {}, - 'boolean' => {}, - 'decimal' => {}, - 'dateTime' => {}, - 'float' => {}, - 'double' => {}, - 'duration' => {}, - 'time' => {}, - 'date' => {}, - 'gYearMonth' => {}, - 'gYear' => {}, - 'gMonthDay' => {}, - 'gDay' => {}, - 'gMonth' => {}, - 'hexBinary' => {}, - 'base64Binary' => {}, - 'anyURI' => {}, - 'QName' => {}, - 'NOTATION' => {}, - 'integer' => {}, + 'anyURI' => {}, + 'boolean' => {}, + 'base64Binary' => {}, + 'byte' => {}, + 'date' => {}, + 'dateTime' => {}, + 'decimal' => {}, + 'double' => {}, + 'duration' => {}, + 'ENTITY' => {}, + 'float' => {}, + 'gDay' => {}, + 'gMonth' => {}, + 'gMonthDay' => {}, + 'gYearMonth' => {}, + 'gYear' => {}, + 'hexBinary' => {}, + 'ID' => {}, + 'IDREF' => {}, + 'IDREFS' => {}, + 'int' => {}, + 'integer' => {}, + 'language' => {}, + 'long' => {}, + 'negativeInteger' => {}, 'nonPositiveInteger' => {}, 'nonNegativeInteger' => {}, - 'positiveInteger' => {}, - 'negativeInteger' => {}, - 'long' => {}, - 'int' => {}, - 'unsignedInt' => {}, - 'short' => {}, - 'unsignedShort' => {}, - 'byte' => {}, - 'unsignedByte' => {}, - 'normalizedString' => {}, - 'token' => {}, - 'NMTOKEN' => {}, + 'normalizedString' => {}, + 'Name' => {}, + 'NCName' => {}, + 'NMTOKEN' => {}, + 'NOTATION' => {}, + 'positiveInteger' => {}, + 'QName' => {}, + 'short' => {}, + 'string' => {}, + 'time' => {}, + 'token' => {}, + 'unsignedByte' => {}, + 'unsignedInt' => {}, + 'unsignedLong' => {}, + 'unsignedShort' => {}, ); sub START { @@ -88,10 +96,10 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 412 $ + $Rev: 583 $ $LastChangedBy: kutterma $ - $Id: Builtin.pm 412 2007-11-27 22:57:52Z kutterma $ + $Id: Builtin.pm 583 2008-03-24 07:44:06Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Schema/Builtin.pm $ - + =cut diff --git a/lib/SOAP/WSDL/XSD/SimpleType.pm b/lib/SOAP/WSDL/XSD/SimpleType.pm index b270aed..0e3ed69 100644 --- a/lib/SOAP/WSDL/XSD/SimpleType.pm +++ b/lib/SOAP/WSDL/XSD/SimpleType.pm @@ -6,13 +6,27 @@ use base qw(SOAP::WSDL::Base); our $VERSION=q{2.00_25}; -my %annotation_of :ATTR(:name :default<()>); -my %base_of :ATTR(:name :default<()>); -my %itemType_of :ATTR(:name :default<()>); -# is set to simpleContent/complexContent -# my %content_model_of :ATTR(:name :default<()>); +my %length_of :ATTR(:name :default<[]>); +my %minLength_of :ATTR(:name :default<[]>); +my %maxLength_of :ATTR(:name :default<[]>); +my %pattern_of :ATTR(:name :default<[]>); +my %enumeration_of :ATTR(:name :default<[]>); +my %whiteSpace_of :ATTR(:name :default<[]>); +my %totalDigits_of :ATTR(:name :default<[]>); +my %fractionDigits_of :ATTR(:name :default<[]>); +my %minExclusive :ATTR(:name :default<[]>); +my %minInclusive :ATTR(:name :default<[]>); +my %maxExclusive :ATTR(:name :default<[]>); +my %maxInclusive :ATTR(:name :default<[]>); -# TODO rename flavor to content_model to be consistent with the XML Schema +my %fixed :ATTR(:name :default<[]>); + +my %annotation_of :ATTR(:name :default<()>); +my %base_of :ATTR(:name :default<()>); +my %itemType_of :ATTR(:name :default<()>); + + +# TODO rename flavor to variety to be consistent with the XML Schema # specs - though flavor is the cooler name.. # set to restriction|list|union|enumeration my %flavor_of :ATTR(:name :default<()>); @@ -29,6 +43,7 @@ sub set_restriction { my $self = shift; my @attributes = @_; $self->set_flavor( 'restriction' ); + for (@attributes) { next if (not $_->{ LocalName } eq 'base'); $self->set_base( $_->{ Value } ); diff --git a/lib/SOAP/WSDL/XSD/TotalDigits.pm b/lib/SOAP/WSDL/XSD/TotalDigits.pm new file mode 100644 index 0000000..f285989 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/TotalDigits.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::TotalDigits; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/lib/SOAP/WSDL/XSD/Typelib/Attribute.pm b/lib/SOAP/WSDL/XSD/Typelib/Attribute.pm index 5963802..0c09a10 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Attribute.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Attribute.pm @@ -8,8 +8,8 @@ our $VERSION=q{2.00_29}; sub start_tag { # my ($self, $opt, $value) = @_; - return q{} if (@_ < 3); - return qq{ $_[1]->{ name }="} + return q{} if (@_ < 3); + return qq{ $_[1]->{ name }="}; } sub end_tag { diff --git a/lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm b/lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm index 66e658a..f8c5866 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm @@ -7,8 +7,7 @@ our $VERSION=q{2.00_29}; sub serialize { # we work on @_ for performance. - $_[1] ||= {}; # $option_ref - + # $_[1] ||= {}; # $option_ref return ${ $_[0]->_serialize({ attr => 1 }) }; } diff --git a/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm b/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm index 414572d..dd77d83 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm @@ -3,5 +3,5 @@ use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::token); - +Class::Std::initialize(); 1; diff --git a/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm b/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm index 5891e5f..8d7d976 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm @@ -2,7 +2,10 @@ package SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; + use base qw(SOAP::WSDL::XSD::Typelib::Builtin::list SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN); +Class::Std::initialize(); + 1; diff --git a/lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm b/lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm index c239969..e6bdc4b 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm @@ -2,6 +2,7 @@ package SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; use strict; use warnings; use Class::Std::Fast::Storable constructor => 'none', cache => 1; +use SOAP::WSDL::XSD::Typelib::Builtin::anyType; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType); my %value_of :ATTR(:get :init_arg :default<()>); @@ -13,6 +14,11 @@ our $___value = \%value_of; # and we don't need to return the last value... sub set_value { $value_of{ ${ $_[0] } } = $_[1] } +# Default attribute handling +# TODO add something for handling default attributes +sub attr { +} + # use $_[n] for speed. # This is less readable, but notably faster. # @@ -23,8 +29,10 @@ sub set_value { $value_of{ ${ $_[0] } } = $_[1] } # every little statement matters... sub serialize { - no warnings qw(uninitialized); - $_[1]->{ nil } = 1 if not defined $value_of{ ${$_[0]} }; + $_[1] ||= {}; + if (not defined $value_of{ ${$_[0]} }) { + return $_[0]->start_tag({ %{ $_[1] }, nil => 1 }, undef); + } return join q{} , $_[0]->start_tag($_[1], $value_of{ ${$_[0]} }) , $value_of{ ${$_[0]} } @@ -32,7 +40,7 @@ sub serialize { } sub as_string :STRINGIFY { - return $value_of { ${ $_[0] } }; + return defined($value_of { ${ $_[0] } }) ? $value_of { ${ $_[0] } } : q{}; } sub as_bool :BOOLIFY { @@ -51,6 +59,6 @@ sub new { return $self; } -Class::Std::Fast::initialize(); # make :BOOLIFY overloading serializable +Class::Std::initialize(); # make :BOOLIFY overloading serializable 1; diff --git a/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm b/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm index fcd6b47..17f9fd2 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm @@ -8,12 +8,34 @@ our $VERSION = q{2.00_29}; sub get_xmlns { 'http://www.w3.org/2001/XMLSchema' }; # use $_[1] for performance +#sub start_tag { +# return q{} if not $#_; # return if no second argument ($opt) +# if ($_[1]->{ name }) { +# return qq{ $_[1]->{name}="} if $_[1]->{ attr }; +# return "<$_[1]->{name}/>" if $_[1]->{ empty }; +# return "<$_[1]->{name}>"; +# } +# return q{}; +#} + sub start_tag { return q{} if not $#_; # return if no second argument ($opt) if ($_[1]->{ name }) { return qq{ $_[1]->{name}="} if $_[1]->{ attr }; - return "<$_[1]->{name}/>" if $_[1]->{ empty }; - return "<$_[1]->{name}>"; + my $ending = ($_[1]->{ empty }) ? '/>' : '>'; + my @attr_from = (); + if ($_[1]->{ nil }) { + push @attr_from, q{ xsi:nil="true"}; + $ending = '/>'; + } +# if (delete $_[1]->{qualified}) { +# push @attr_from, q{ xmlns="} . $_[0]->get_xmlns() . q{"}; +# } + push @attr_from, $_[0]->serialize_attr(); + + # do we need to check for name ? Element ref="" should have it's own + # start_tag. If we don't need to check, we can speed things up + return join q{}, "<$_[1]->{ name }" , @attr_from , $ending; } return q{}; } @@ -21,7 +43,7 @@ sub start_tag { # use $_[1] for performance sub end_tag { return $_[1] && defined $_[1]->{ name } - ? $_[1]->{ attr } + ? $_[1]->{ attr } ? q{"} : "{name}>" : q{}; @@ -29,7 +51,7 @@ sub end_tag { sub serialize_attr {}; -sub serialize { q{} }; +# sub serialize { q{} }; sub serialize_qualified :STRINGIFY { return $_[0]->serialize( { qualified => 1 } ); @@ -39,7 +61,7 @@ sub as_list :ARRAYIFY { return [ $_[0] ]; } -Class::Std::initialize(); # make :STRINGIFY overloading serializable +Class::Std::initialize(); # make :STRINGIFY overloading work 1; diff --git a/lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm b/lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm index 808c6ff..50a8b69 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm @@ -33,5 +33,5 @@ sub as_bool :BOOLIFY { return $_[0]->get_value(); } -Class::Std::initialize; +Class::Std::initialize(); 1; diff --git a/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm b/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm index b2f3186..82f09a1 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm @@ -4,19 +4,23 @@ use strict; use warnings; use Carp; use SOAP::WSDL::XSD::Typelib::Builtin; -use Scalar::Util qw(blessed refaddr); +use Scalar::Util qw(blessed); require Class::Std::Fast::Storable; use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType); -our $VERSION = '2.00_31'; +our $VERSION = '2.00_33'; my %ELEMENTS_FROM; my %ATTRIBUTES_OF; my %CLASSES_OF; +# XML Attribute handling +my %xml_attr_of :ATTR(); + # don't you ever dare to use this ! our $___attributes_of_ref = \%ATTRIBUTES_OF; +our $___xml_attribute_of_ref = \%xml_attr_of; # STORABLE_ methods for supporting Class::Std::Fast::Storable. # We could also handle them via AUTOMETHOD, @@ -39,28 +43,28 @@ sub AUTOMETHOD { . "\n" } -# Attribute handling -my %xml_attr_of :ATTR(); + sub attr { my $self = shift; - my $class = ref $self; + my $class = $self->__get_attr_class() + or return; # disable strictness - in perl 5.10 %{ "$foo\::_bar" } triggers a # symbolic reference error with strictness enabled no strict qw(refs); - die "$class has no attributes" if not defined %{ "$class\::_ATTR::"}; + # die "$class has no attributes" if not defined %{ "$class\::_ATTR::"}; if (@_) { # setter - return $xml_attr_of{ $$self } = "$class\::_ATTR"->new(@_); + return $xml_attr_of{ $$self } = $class->new(@_); } return $xml_attr_of{ $$self } if exists $xml_attr_of{ $$self }; - return $xml_attr_of{ $$self } = "$class\::_ATTR"->new(); + return $xml_attr_of{ $$self } = $class->new(); } sub serialize_attr { return q{} if not $xml_attr_of{ ${ $_[0] } }; - $_[0]->attr()->serialize(); + return $xml_attr_of{ ${ $_[0] } }->serialize(); } sub as_hash_ref { @@ -118,7 +122,7 @@ sub _factory { # it when the method was created. my $is_list = $type->isa('SOAP::WSDL::XSD::Typelib::Builtin::list'); - # The set_$name method below looks rather weird, + # The set_$name method below looks rather weird, # but is optimized for performance. # # We could use sub calls for sure, but these are much slower. And @@ -151,7 +155,11 @@ sub _factory { # d) we should also die for non-blessed non-ARRAY/HASH references in # lists but don't do yet - oh my ! - *{ "$class\::set_$name" } = sub { + # keep in sync with Generator::Template::Plugin::XSD - maybe use + # function to allow substituting via symbol table... + my $method_name = $name; + $method_name =~s{[\.\-]}{_}xmsg; + *{ "$class\::set_$method_name" } = sub { if (not $#_) { delete $attribute_ref->{ ${ $_[0] } }; return; @@ -173,7 +181,6 @@ sub _factory { ] : $is_ref eq 'HASH' ? $type->new( $_[1] ) - # neither ARRAY nor HASH - probably an object... : ($is_ref eq $type) # of required type ? ->isa would be a better test... ? $_[1] # use it @@ -184,7 +191,7 @@ sub _factory { return; }; - *{ "$class\::add_$name" } = sub { + *{ "$class\::add_$method_name" } = sub { warn "attempting to add empty value to " . ref $_[0] if not defined $_[1]; @@ -221,8 +228,13 @@ sub _factory { # and call set appropriate field in clase map { ($ATTRIBUTES_OF{ $class }->{ $_ }) ? do { - my $method = "set_$_"; - $self->$method( $_[1]->{ $_ } ); # ( $args_of->{ $_ } ); + my $method = "set_$_"; + + # keep in sync with Generator::Template::Plugin::XSD - maybe use + # function to allow substituting via symbol table... + $method =~s{[\.\-]}{_}xmsg; + + $self->$method( $_[1]->{ $_ } ); # ( $args_of->{ $_ } ); } : $_ =~ m{ \A # beginning of string xmlns # xmlns @@ -245,7 +257,7 @@ sub _factory { # Triggers XML attribute serialization if the options hash ref contains # a attr element with a true value. *{ "$class\::_serialize" } = sub { - my $ident = ${ $_[0]}; + my $ident = ${ $_[0] }; my $option_ref = $_[1]; # return concatenated return value of serialize call of all # elements retrieved from get_elements expanding list refs. @@ -261,13 +273,13 @@ sub _factory { # serialize element elements with their own serializer # but name them like they're named here. if ( $_->isa( 'SOAP::WSDL::XSD::Typelib::Element' ) ) { - $_->serialize( { name => $name } ); + $_->serialize({ name => $name }); } # serialize complextype elments (of other types) with their # serializer, but add element tags around. else { join q{}, $_->start_tag({ name => $name , %{ $option_ref } }) - , $_->serialize() + , $_->serialize($option_ref) , $_->end_tag({ name => $name , %{ $option_ref } }); } } @{ $element } @@ -277,9 +289,19 @@ sub _factory { } } (@{ $ELEMENTS_FROM{ $class } }); }; + + # put hidden complex serializer into class + # ... but not for AttributeSet classes + if ( ! $class->isa('SOAP::WSDL::XSD::Typelib::AttributeSet')) { + *{ "$class\::serialize" } = \&__serialize_complex; + }; } -sub serialize { +# just a fallback +sub __get_attr_class {}; + +# hidden complex serializer +sub __serialize_complex { # we work on @_ for performance. $_[1] ||= {}; # $option_ref @@ -459,9 +481,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 524 $ + $Rev: 583 $ $LastChangedBy: kutterma $ - $Id: ComplexType.pm 524 2008-02-10 23:24:43Z kutterma $ + $Id: ComplexType.pm 583 2008-03-24 07:44:06Z 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/lib/SOAP/WSDL/XSD/Typelib/Element.pm b/lib/SOAP/WSDL/XSD/Typelib/Element.pm index 74a27ad..4c769f1 100644 --- a/lib/SOAP/WSDL/XSD/Typelib/Element.pm +++ b/lib/SOAP/WSDL/XSD/Typelib/Element.pm @@ -51,7 +51,7 @@ sub start_tag { push @attr_from, q{ xsi:nil="true"}; $ending = '/>'; } - if ($_[1]->{qualified}) { + if (delete $_[1]->{qualified}) { push @attr_from, q{ xmlns="} . $_[0]->get_xmlns() . q{"}; } push @attr_from, $_[0]->serialize_attr(); @@ -111,7 +111,7 @@ This example creates a class for this XML schema definition: Now we create this XML schema definition type class: - + package MyElement2; use strict; use Class::Std::Fast::Storable constructor => 'none'; @@ -175,9 +175,9 @@ Martin Kutter Emartin.kutter fen-net.deE =head1 REPOSITORY INFORMATION - $Rev: 498 $ + $Rev: 564 $ $LastChangedBy: kutterma $ - $Id: Element.pm 498 2008-01-20 22:47:18Z kutterma $ + $Id: Element.pm 564 2008-02-23 13:31:39Z kutterma $ $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/XSD/Typelib/Element.pm $ =cut diff --git a/lib/SOAP/WSDL/XSD/WhiteSpace.pm b/lib/SOAP/WSDL/XSD/WhiteSpace.pm new file mode 100644 index 0000000..06015c6 --- /dev/null +++ b/lib/SOAP/WSDL/XSD/WhiteSpace.pm @@ -0,0 +1,18 @@ +package SOAP::WSDL::XSD::WhiteSpace; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::Base); + +our $VERSION=q{2.00_33}; + +# + +# id provided by Base +# name provided by Base +# annotation provided by Base + +# may be defined as atomic simpleType +my %value_of :ATTR(:name :default<()>); + +1; \ No newline at end of file diff --git a/t/009_data_classes.t b/t/009_data_classes.t index ab19752..34c75c4 100644 --- a/t/009_data_classes.t +++ b/t/009_data_classes.t @@ -20,7 +20,7 @@ my @dir_from = File::Spec->splitdir($dir); unshift @dir_from, $volume if $volume; my $url = join '/', @dir_from; -my $parser; +my $parser; ok $parser = SOAP::WSDL::Expat::MessageParser->new({ class_resolver => FakeResolver->new(), @@ -56,11 +56,13 @@ q{ + xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + > mailto:test@example.com TestContent for Message - TestContent for Message 2 + martin.kutter@example.com mailto:test@example.com }; diff --git a/t/017_generator.t b/t/017_generator.t index 98204f9..b88cfd4 100644 --- a/t/017_generator.t +++ b/t/017_generator.t @@ -89,7 +89,7 @@ ok $interface->EnqueueMessage( MMessageContent => 'content', MSubject => 'subject', MDeliveryReportRecipientURI => 'mailto:report.recipient@example.org', - } + } }), 'interface operation call (no_dispatch set)'; diff --git a/t/095_copying.t b/t/095_copying.t index 9b222f9..0cccba5 100644 --- a/t/095_copying.t +++ b/t/095_copying.t @@ -48,6 +48,24 @@ sub filelist { return if $File::Find::name =~m{SOAP/WSDL/XSD/SimpleType\.pm$}xms; return if $File::Find::name =~m{SOAP/WSDL/XSD/Element\.pm$}xms; return if $File::Find::name =~m{SOAP/WSDL/XSD/Schema\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Attribute\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Typelib/Attribute\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Typelib/AttributeSet\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Group\.pm$}xms; + + return if $File::Find::name =~m{SOAP/WSDL/XSD/TotalDigits\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Annotation\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/AttributeGroup\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Enumeration\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/FractionDigits\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Length\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/MaxExclusive\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/MaxInclusive\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/MaxLength\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/MinLength\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/MinInclusive\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/MinExclusive\.pm$}xms; + return if $File::Find::name =~m{SOAP/WSDL/XSD/Whitespace\.pm$}xms; push @filelist, $File::Find::name; } @@ -59,4 +77,4 @@ for my $file (sort @filelist) { \s SOAP-WSDL\. \s You \s may \s distribute/modify \s it \s under \s the \s same \s terms \s as \s perl \s itself }xms, "$file License notice"); -} \ No newline at end of file +} diff --git a/t/098_pod.t b/t/098_pod.t index 427904b..fa2d87c 100644 --- a/t/098_pod.t +++ b/t/098_pod.t @@ -2,18 +2,18 @@ use Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; -# perl Build test or make test run from top-level dir. -if ( -d '../t/' ) { - @directories = ('../lib/'); -} -else { - @directories = (); # empty - will work automatically +my @dir_from = (); +if (!$ENV{HARNESS_ACTIVE}) { + # perl Build test or make test run from top-level dir. + if ( -d '../t/' ) { + @dir_from = ('../lib/'); + } } -my @files = all_pod_files(@directories); +my @files = all_pod_files(@dir_from); plan tests => scalar(@files); foreach my $module (@files){ - pod_file_ok( $module ) -} \ No newline at end of file + pod_file_ok( $module ) +} diff --git a/t/099_pod_coverage.t b/t/099_pod_coverage.t index e660c9b..c5025de 100644 --- a/t/099_pod_coverage.t +++ b/t/099_pod_coverage.t @@ -12,11 +12,11 @@ plan skip_all => "Test::Pod::Coverage 1.00 required for testing POD" if $@; my @dirs = ( 'lib' ); if (-d '../t/') { # we are inside t/ @dirs = ('../lib'); -} +} else { # we are outside t/ - # add ./lib to include path if blib/lib is not there (e.g. we're not - # run from Build test or the like) - push @INC, './lib' if not grep { $_ eq 'blib/lib' } @INC; + # add ./lib to include path if blib/lib is not there (e.g. we're not + # run from Build test or the like) + push @INC, './lib' if not grep { $_ eq 'blib/lib' } @INC; } # Don't test Builtin XSD types - they're undocumented on purpose @@ -34,25 +34,29 @@ else { # we are outside t/ |SOAP::WSDL::Part |SOAP::WSDL::Operation |SOAP::WSDL::SOAP::[^:]+ + |SOAP::WSDL::XSD::Attribute |SOAP::WSDL::XSD::SimpleType |SOAP::WSDL::XSD::Element |SOAP::WSDL::XSD::ComplexType |SOAP::WSDL::XSD::Builtin |SOAP::WSDL::XSD::Schema - + |SOAP::WSDL::XSD::Group + |SOAP::WSDL::XSD::Typelib::Attribute + |SOAP::WSDL::XSD::Typelib::AttributeSet + ) \z }xms; } all_modules( @dirs ); plan tests => scalar @files; foreach (@files) { - pod_coverage_ok( $_ , - { - private => [ - qr/^_/, - qr/^BUILD$/, - qr/^START$/, - qr/^STORABLE/, - qr/^AUTOMETHOD$/, - qr/^DEMOLISH$/ - ] - }); + pod_coverage_ok( $_ , + { + private => [ + qr/^_/, + qr/^BUILD$/, + qr/^START$/, + qr/^STORABLE/, + qr/^AUTOMETHOD$/, + qr/^DEMOLISH$/ + ] + }); } \ No newline at end of file diff --git a/t/SOAP/WSDL/Client/Base.t b/t/SOAP/WSDL/Client/Base.t index e8c2be5..321fdda 100644 --- a/t/SOAP/WSDL/Client/Base.t +++ b/t/SOAP/WSDL/Client/Base.t @@ -91,7 +91,8 @@ isa_ok $result[1], 'SOAP::WSDL::XSD::Typelib::Builtin::string'; ); isa_ok $result[0], 'SOAP::WSDL::XSD::Typelib::Builtin::string'; -is $result[0], undef; +is $result[0], q{}; + is $result[1], 'Header2'; isa_ok $result[1], 'SOAP::WSDL::XSD::Typelib::Builtin::string'; @@ -116,7 +117,7 @@ isa_ok $result[1], 'SOAP::WSDL::XSD::Typelib::Builtin::string'; }); isa_ok $result[0], 'SOAP::WSDL::XSD::Typelib::Builtin::string'; -is $result[0], undef; +is $result[0], q{}; eval { $client->call({ operation => 'sayHello', @@ -139,7 +140,8 @@ eval { $client->call({ like $@, qr{ Can't \s locate }xms; isa_ok $result[0], 'SOAP::WSDL::XSD::Typelib::Builtin::string'; -is $result[0], undef; + +is $result[0], q{}; eval { $client->call({ operation => 'sayHello', @@ -161,4 +163,4 @@ eval { $client->call({ }) }; # die $@; -like $@, qr{ Can't \s locate }xms; \ No newline at end of file +like $@, qr{ Can't \s locate }xms; diff --git a/t/SOAP/WSDL/Expat/WSDLParser.t b/t/SOAP/WSDL/Expat/WSDLParser.t index b058c8e..6921d49 100644 --- a/t/SOAP/WSDL/Expat/WSDLParser.t +++ b/t/SOAP/WSDL/Expat/WSDLParser.t @@ -30,15 +30,6 @@ my $generator = SOAP::WSDL::Generator::Template::XSD->new({ OUTPUT_PATH => "$path/testlib", }); -#my $code = ""; -#$generator->set_output(\$code); -#$generator->generate_typelib(); -#{ -# eval $code; -# ok !$@; -# print $@ if $@; -#} - $definitions = $parser->parse_uri( "file://$path/../../../acceptance/wsdl/WSDLParser-import.wsdl" ); diff --git a/t/SOAP/WSDL/Factory/Deserializer.t b/t/SOAP/WSDL/Factory/Deserializer.t index 545ca4e..4345155 100644 --- a/t/SOAP/WSDL/Factory/Deserializer.t +++ b/t/SOAP/WSDL/Factory/Deserializer.t @@ -1,21 +1,22 @@ use strict; use warnings; -use Test::More tests => 3; +use Test::More tests => 4; -use SOAP::WSDL::Factory::Serializer; +use SOAP::WSDL::Factory::Deserializer; -eval { SOAP::WSDL::Factory::Serializer->get_serializer({ - soap_version => 'zumsl' +eval { SOAP::WSDL::Factory::Deserializer->get_deserializer({ + soap_version => 'zumsl' }) }; -like $@, qr{^no serializer}; +like $@, qr{^no deserializer}; -ok my $serializer = SOAP::WSDL::Factory::Serializer->get_serializer({ - soap_version => '1.1' +ok my $serializer = SOAP::WSDL::Factory::Deserializer->get_deserializer({ + soap_version => '1.1' }); +ok $serializer = SOAP::WSDL::Factory::Deserializer->get_deserializer({}); -SOAP::WSDL::Factory::Serializer->register('1.1', 'Hope_You_Have_No_Such_Package_Installed'); +SOAP::WSDL::Factory::Deserializer->register('1.1', 'Hope_You_Have_No_Such_Package_Installed'); -eval { SOAP::WSDL::Factory::Serializer->get_serializer({ - soap_version => '1.1' +eval { SOAP::WSDL::Factory::Deserializer->get_deserializer({ + soap_version => '1.1' }) }; like $@, qr{^Cannot load}; diff --git a/t/SOAP/WSDL/Factory/Serializer.t b/t/SOAP/WSDL/Factory/Serializer.t index 690ec54..602d4d2 100644 --- a/t/SOAP/WSDL/Factory/Serializer.t +++ b/t/SOAP/WSDL/Factory/Serializer.t @@ -1,21 +1,23 @@ use strict; use warnings; -use Test::More tests => 3; +use Test::More tests => 4; -use SOAP::WSDL::Factory::Deserializer; +use SOAP::WSDL::Factory::Serializer; -eval { SOAP::WSDL::Factory::Deserializer->get_deserializer({ - soap_version => 'zumsl' +eval { SOAP::WSDL::Factory::Serializer->get_serializer({ + soap_version => 'zumsl' }) }; -like $@, qr{^no deserializer}; +like $@, qr{^no serializer}; -ok my $serializer = SOAP::WSDL::Factory::Deserializer->get_deserializer({ - soap_version => '1.1' +ok my $serializer = SOAP::WSDL::Factory::Serializer->get_serializer({ + soap_version => '1.1' }); -SOAP::WSDL::Factory::Deserializer->register('1.1', 'Hope_You_Have_No_Such_Package_Installed'); +ok $serializer = SOAP::WSDL::Factory::Serializer->get_serializer({}); -eval { SOAP::WSDL::Factory::Deserializer->get_deserializer({ - soap_version => '1.1' +SOAP::WSDL::Factory::Serializer->register('1.1', 'Hope_You_Have_No_Such_Package_Installed'); + +eval { SOAP::WSDL::Factory::Serializer->get_serializer({ + soap_version => '1.1' }) }; like $@, qr{^Cannot load}; diff --git a/t/SOAP/WSDL/Generator/Template.t b/t/SOAP/WSDL/Generator/Template.t index 16f4c15..242468d 100644 --- a/t/SOAP/WSDL/Generator/Template.t +++ b/t/SOAP/WSDL/Generator/Template.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More qw(no_plan); +use Test::More tests => 2; use Template; use File::Basename; use File::Spec; diff --git a/t/SOAP/WSDL/Generator/Visitor/Typemap.t b/t/SOAP/WSDL/Generator/Visitor/Typemap.t index a1cd83e..b961625 100644 --- a/t/SOAP/WSDL/Generator/Visitor/Typemap.t +++ b/t/SOAP/WSDL/Generator/Visitor/Typemap.t @@ -4,11 +4,23 @@ use Test::More tests => 5; use File::Basename; use File::Spec; my $path = File::Spec->rel2abs( dirname __FILE__ ); - +use SOAP::WSDL::Generator::Template::Plugin::XSD; +use SOAP::WSDL::Generator::Iterator::WSDL11; +use SOAP::WSDL::Generator::PrefixResolver; use_ok qw(SOAP::WSDL::Generator::Visitor::Typemap); my $visitor; -ok $visitor = SOAP::WSDL::Generator::Visitor::Typemap->new(), 'constructor'; +ok $visitor = SOAP::WSDL::Generator::Visitor::Typemap->new({ + resolver => SOAP::WSDL::Generator::Template::Plugin::XSD->new({ + prefix_resolver=> SOAP::WSDL::Generator::PrefixResolver->new({ + prefix => { + type => 'TestTypes', + element => 'TestElements', + typemap => 'TestTypemap', + } + }), + }) +}), 'constructor'; use SOAP::WSDL::Expat::WSDLParser; @@ -24,12 +36,21 @@ $parser->parse_file( my $definitions = $parser->get_data(); -$definitions->_accept( $visitor ); +my $iter = SOAP::WSDL::Generator::Iterator::WSDL11->new({ + definitions => $definitions +}); +$visitor->set_definitions($definitions); +$iter->init(); +while (my $node = $iter->get_next()) { + $node->_accept( $visitor ); +}; my $typemap = $visitor->get_typemap(); -is $typemap->{'EnqueueMessage/MMessage/MKeepalive'}, 'MyTypes::TKeepalive', 'content'; -is $typemap->{'EnqueueMessageResponse'}, 'MyElements::EnqueueMessageResponse', 'content'; -is $typemap->{'KeepaliveMessageResponse'}, 'MyElements::KeepaliveMessageResponse', 'content'; +is $typemap->{'EnqueueMessage/MMessage/MKeepalive'}, 'TestTypes::TKeepalive', 'content'; +is $typemap->{'EnqueueMessageResponse'}, 'TestElements::EnqueueMessageResponse', 'content'; +is $typemap->{'KeepaliveMessageResponse'}, 'TestElements::KeepaliveMessageResponse', 'content'; +use Data::Dumper; +print Dumper $typemap; sub wsdl { q{ @@ -137,4 +158,4 @@ xmlns="http://schemas.xmlsoap.org/wsdl/"> } -} \ No newline at end of file +} diff --git a/t/SOAP/WSDL/Generator/XCS.t b/t/SOAP/WSDL/Generator/XCS.t deleted file mode 100644 index 77ffaae..0000000 --- a/t/SOAP/WSDL/Generator/XCS.t +++ /dev/null @@ -1,27 +0,0 @@ -use strict; -use warnings; -use Test::More; -use File::Spec; -use File::Basename; -eval { require XML::Compile::WSDL11 } - or plan skip_all => 'Cannot test without XML::Compile::WSDL11'; - -eval { require XML::LibXML } - or plan skip_all => 'Cannot test without XML::LibXML'; - -plan skip_all => 'XML::Compile::WSDL11 is not functional yet'; - -plan qw(no_plan); - -my $path = File::Spec->rel2abs( dirname __FILE__ ); - -my $libxml = XML::LibXML->new(); -my $xml = $libxml->parse_file("$path/../../../acceptance/wsdl/generator_test.wsdl"); - -my $wsdl = XML::Compile::WSDL11->new($xml); -my $schemas = $wsdl->schemas; -ok my $operation = $wsdl->operation('testHeader'); - -#die Dumper $operation; -# -#my $client = $operation->prepareClient(); diff --git a/t/SOAP/WSDL/Generator/XSD.t b/t/SOAP/WSDL/Generator/XSD.t index b8c4824..9dfe3b9 100644 --- a/t/SOAP/WSDL/Generator/XSD.t +++ b/t/SOAP/WSDL/Generator/XSD.t @@ -1,4 +1,4 @@ -use Test::More tests => 42; +use Test::More tests => 49; use File::Basename qw(dirname); use File::Spec; use File::Path; @@ -156,9 +156,40 @@ ok my $empty = MyElements::testElementCompletelyEmptyComplex->new(); is $empty->serialize_qualified(), '' , 'serialize empty'; - ok eval { require MyTypes::testComplexTypeSimpleRestriction; } , 'load MyTypes::testComplexTypeSimpleRestriction'; +ok eval { require MyTypes::testComplexTypeSequenceWithAttribute; } + , 'load MyTypes::testComplexTypeSequenceWithAttribute'; + +use_ok qw(MyElements::testElementComplexTypeSequenceWithAttribute); + +my $obj = MyElements::testElementComplexTypeSequenceWithAttribute->new({ + Test1 => 'foo', + Test2 => 'bar', +}); +$obj->attr({ testAttr => 'foobar' }); + +is $obj, q{foobar} + . q{} + , 'seralize complexType sequence with attribute'; + +use_ok qw(MyTypes::testSimpleContentExtension); + +ok $obj = MyTypes::testSimpleContentExtension->new({ value => 'foo' }); +$obj->attr({ testAttr => 'bar' }); + +is $obj->serialize({ name => 'baz'}), q{foo}; + +SKIP: { + eval { require Test::Pod::Content; } + or skip 'Cannot test pod content without Test::Pod::Content', 1; + Test::Pod::Content::pod_section_like( + 'MyTypes::testComplexTypeSequenceWithAttribute', + 'attr', + qr{Test \s Attribute \s good \s for \s nothing}x, + 'Attribute POD'); +} rmtree "$path/testlib"; diff --git a/t/SOAP/WSDL/Generator/XSD_dot_names.t b/t/SOAP/WSDL/Generator/XSD_dot_names.t index c3430f2..8444836 100644 --- a/t/SOAP/WSDL/Generator/XSD_dot_names.t +++ b/t/SOAP/WSDL/Generator/XSD_dot_names.t @@ -1,4 +1,4 @@ -use Test::More tests => 12; +use Test::More tests => 14; use File::Basename qw(dirname); use File::Spec; use File::Path; @@ -12,7 +12,7 @@ use SOAP::WSDL::Expat::WSDLParser; my $parser = SOAP::WSDL::Expat::WSDLParser->new(); -my $definitions = $parser->parse_file( +my $definitions = $parser->parse_file( "$path/../../../acceptance/wsdl/generator_test_dot_names.wsdl" #"$path/../../../acceptance/wsdl/elementAtomicComplexType.xml" ); @@ -26,7 +26,7 @@ my $generator = SOAP::WSDL::Generator::Template::XSD->new({ }); my $code = ""; -$generator->set_output(\$code); +$generator->set_output(\$code); $generator->generate_typelib(); { eval $code; @@ -47,9 +47,9 @@ $generator->generate(); #$generator->generate_typemap(); if (eval { require Test::Warn; }) { - Test::Warn::warning_like( sub { $generator->generate_interface() }, + 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 }; @@ -61,38 +61,40 @@ eval "use lib '$path/testlib'"; use_ok qw(MyInterfaces::My::SOAP::testService::testPort); use_ok qw(MyServer::My::SOAP::testService::testPort); +use_ok qw(MyTypes::testComplexTypeRestriction); +use_ok qw(MyTypes::testComplexTypeAll); SKIP: { eval { require Test::Pod::Content; } or skip 'Cannot test pod content without Test::Pod::Content', 6; Test::Pod::Content::pod_section_like( - 'MyInterfaces::My::SOAP::testService::testPort', - 'NAME', + 'MyInterfaces::My::SOAP::testService::testPort', + 'NAME', qr{^MyInterfaces::My::SOAP::testService::testPort \s - \s}xms, 'Pod NAME section'); Test::Pod::Content::pod_section_like( - 'MyInterfaces::My::SOAP::testService::testPort', - 'SYNOPSIS', + 'MyInterfaces::My::SOAP::testService::testPort', + 'SYNOPSIS', qr{use \s MyInterfaces::My::SOAP::testService::testPort}xms, 'Pod SYNOPSIS section'); Test::Pod::Content::pod_section_like( - 'MyInterfaces::My::SOAP::testService::testPort', - 'SYNOPSIS', + 'MyInterfaces::My::SOAP::testService::testPort', + 'SYNOPSIS', qr{\s MyInterfaces::My::SOAP::testService::testPort->new\(}xms, 'Pod SYNOPSIS section'); Test::Pod::Content::pod_section_like( - 'MyServer::My::SOAP::testService::testPort', - 'NAME', + 'MyServer::My::SOAP::testService::testPort', + 'NAME', qr{^MyServer::My::SOAP::testService::testPort \s - \s}xms, 'Pod NAME section'); Test::Pod::Content::pod_section_like( - 'MyServer::My::SOAP::testService::testPort', - 'SYNOPSIS', + 'MyServer::My::SOAP::testService::testPort', + 'SYNOPSIS', qr{use \s MyServer::My::SOAP::testService::testPort}xms, 'Pod SYNOPSIS section'); Test::Pod::Content::pod_section_like( - 'MyServer::My::SOAP::testService::testPort', - 'SYNOPSIS', + 'MyServer::My::SOAP::testService::testPort', + 'SYNOPSIS', qr{\s MyServer::My::SOAP::testService::testPort->new\(}xms, 'Pod SYNOPSIS section'); } diff --git a/t/SOAP/WSDL/Generator/XSD_nested_complextype.t b/t/SOAP/WSDL/Generator/XSD_nested_complextype.t new file mode 100644 index 0000000..a260564 --- /dev/null +++ b/t/SOAP/WSDL/Generator/XSD_nested_complextype.t @@ -0,0 +1,117 @@ +use Test::More tests => 14; +use File::Basename qw(dirname); +use File::Spec; +use File::Path; + +my $path = File::Spec->rel2abs( dirname __FILE__ ); + +use SOAP::WSDL::Expat::MessageParser; + +use_ok qw(SOAP::WSDL::Generator::Visitor::Typelib); +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/nested_complextype.wsdl" +); + +ok my $element = $definitions->get_types()->[0]->find_element("urn:HelloWorld", "sayHello") + , 'got element'; +ok my $sub_element = $element->get_complexType->[0]->find_element("urn:HelloWorld", "givenName"), + , 'atomic type element'; +ok $sub_element->get_complexType->[0]->find_element("urn:HelloWorld", "givenName"), + 'element in subtype'; + + +my $generator = SOAP::WSDL::Generator::Template::XSD->new({ + definitions => $definitions, + type_prefix => 'Bar', + element_prefix => 'BarElem', + typemap_prefix => 'Bar', + OUTPUT_PATH => "$path/testlib", +}); + + +my $code = ""; +$generator->set_output(\$code); +$generator->generate_typelib(); +{ + eval $code; + ok !$@, 'eval generated code'; + print $@ if $@; +} +# print $code; + +my %prefix_of = ( + type => 'FooType', + element => 'FooElement', + typemap => 'FooMap', +); + +while (my ($name, $value) = each %prefix_of ) { + $generator->can("set_$name\_prefix")->($generator, $value); +} + +$generator->set_output(undef); +$generator->generate(); +#$generator->generate_typelib(); +$generator->generate_typemap(); +$generator->generate_server(); + +eval "use lib '$path/testlib'"; + +use_ok qw(FooElement::sayHello); +eval { + FooElement::sayHello::_givenName->new({ + givenName => 'Foo', + middleInitial => 'Bar', + }); +}; +ok !$@, 'instantiate subpackage FooElement::sayHello::_givenName'; + +eval { + FooElement::sayHello::_givenName::XmlAttr->new({ + testAttr => 'Bar' + }); +}; +ok !$@, 'instantiate subpackage attribute class FooElement::sayHello::_givenName::XmlAttr'; + + +SKIP: { + eval { require Test::Pod::Content; } + or skip 'Cannot test pod content without Test::Pod::Content', 1; + Test::Pod::Content::pod_section_is( + 'FooElement::sayHello', + 'NAME', + 'FooElement::sayHello', + 'Pod NAME section'); +} + +#rmtree "$path/testlib"; +require FooMap::Service1; +my $message_parser = SOAP::WSDL::Expat::MessageParser->new({ + class_resolver => 'FooMap::Service1', +}); + +my $result = $message_parser->parse_string( xml() ); +is $result->get_name(), 'Kutter', 'content'; +is $result->get_givenName()->get_givenName, 'Martin', 'nested complexType content'; +is $result->get_givenName()->get_givenName, 'Martin', 'nested complexType content'; +is $result->get_givenName()->attr()->get_testAttr, 'Bar', 'nested complexType attr'; + +sub xml { + return q{ + + + Kutter + + Martin + A. + + + }; +} diff --git a/t/SOAP/WSDL/Generator/XSD_unsupported.t b/t/SOAP/WSDL/Generator/XSD_unsupported.t index 9f2f01b..55031b0 100644 --- a/t/SOAP/WSDL/Generator/XSD_unsupported.t +++ b/t/SOAP/WSDL/Generator/XSD_unsupported.t @@ -10,7 +10,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( +my $definitions = $parser->parse_file( "$path/../../../acceptance/wsdl/generator_unsupported_test.wsdl" ); @@ -21,4 +21,4 @@ my $generator = SOAP::WSDL::Generator::Template::XSD->new({ { eval { $generator->generate_typelib() }; } -ok $@; \ No newline at end of file +ok $@, $@; \ No newline at end of file diff --git a/t/SOAP/WSDL/Generator/attr.pl b/t/SOAP/WSDL/Generator/attr.pl new file mode 100644 index 0000000..1b46ec1 --- /dev/null +++ b/t/SOAP/WSDL/Generator/attr.pl @@ -0,0 +1,23 @@ +use Test::More qw(no_plan); +use lib 'testlib'; +#ok eval { require MyTypes::testComplexTypeSequenceWithAttribute; } +# , 'load MyTypes::testComplexTypeSequenceWithAttribute'; +# +#my $obj = MyTypes::testComplexTypeSequenceWithAttribute->new({ +# Test1 => 'foo', +# Test2 => 'bar', +#}); +#$obj->attr({ testAttr => 'foobar' }); +# +#print $obj->attr(); +# + +use_ok qw(MyElements::testElementComplexTypeSequenceWithAttribute); + +my $obj = MyElements::testElementComplexTypeSequenceWithAttribute->new({ + Test1 => 'foo', + Test2 => 'bar', +}); +$obj->attr({ testAttr => 'foobar' }); + +print $obj; diff --git a/t/SOAP/WSDL/Types.t b/t/SOAP/WSDL/Types.t new file mode 100644 index 0000000..50d3cdb --- /dev/null +++ b/t/SOAP/WSDL/Types.t @@ -0,0 +1,34 @@ +use strict; +use warnings; +use Test::More tests => 6; + +use SOAP::WSDL::XSD::Attribute; + +use SOAP::WSDL::XSD::Schema; +use_ok qw(SOAP::WSDL::Types); + +my $types = SOAP::WSDL::Types->new(); +$types->set_xmlns({ + foo => 'bar', +}); + +my $attr = SOAP::WSDL::XSD::Attribute->new({ + name => 'test', + targetNamespace => 'bar' +}); + +my $schema = SOAP::WSDL::XSD::Schema->new(); +$schema->push_attribute( $attr ); + +$types->push_schema( + $schema +); + +ok my $found_attr = $types->find_attribute('bar', 'test'); +is $found_attr, $attr; + +ok $types->find_attribute([ 'bar', 'test' ]); + +ok ! $types->find_attribute('foo', 'test'); + +ok ! $types->find_element('foo', 'test'); diff --git a/t/SOAP/WSDL/XSD/AttributeGroup.t b/t/SOAP/WSDL/XSD/AttributeGroup.t new file mode 100644 index 0000000..a3ca2d2 --- /dev/null +++ b/t/SOAP/WSDL/XSD/AttributeGroup.t @@ -0,0 +1,6 @@ +use strict; +use warnings; +use Test::More tests => 1; #qw(no_plan); + +use_ok qw(SOAP::WSDL::XSD::AttributeGroup); + diff --git a/t/SOAP/WSDL/XSD/Builtin.t b/t/SOAP/WSDL/XSD/Builtin.t new file mode 100644 index 0000000..481c5ff --- /dev/null +++ b/t/SOAP/WSDL/XSD/Builtin.t @@ -0,0 +1,16 @@ +use strict; +use warnings; +use Test::More tests => 2; #qw(no_plan); + +use_ok qw(SOAP::WSDL::XSD::Builtin); + +my $foo = SOAP::WSDL::XSD::Builtin->new(); +$foo->set_targetNamespace('bar'); + +eval { + $foo->serialize( + 'foo', 'bar', { autotype => 1 , namespace => {} } + ) +}; + +like $@, qr{^No \s prefix \s found \s for \s namespace \s bar}x; \ No newline at end of file diff --git a/t/SOAP/WSDL/XSD/ComplexType.t b/t/SOAP/WSDL/XSD/ComplexType.t index 98dfc63..e8f6e25 100644 --- a/t/SOAP/WSDL/XSD/ComplexType.t +++ b/t/SOAP/WSDL/XSD/ComplexType.t @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 2; #qw(no_plan); +use Test::More tests => 3; #qw(no_plan); use_ok qw(SOAP::WSDL::XSD::ComplexType); @@ -9,3 +9,13 @@ $obj->set_variety('extension'); eval { $obj->serialize('foo') }; like $@, qr{sorry, \s we \s just}xsm; + +$obj->set_targetNamespace('bar'); + +eval { + $obj->serialize( + 'foo', 'bar', { autotype => 1 , namespace => {} } + ) +}; + +like $@, qr{^No \s prefix \s found \s for \s namespace \s bar}x; \ No newline at end of file diff --git a/t/SOAP/WSDL/XSD/Enumeration.t b/t/SOAP/WSDL/XSD/Enumeration.t new file mode 100644 index 0000000..2dd1e55 --- /dev/null +++ b/t/SOAP/WSDL/XSD/Enumeration.t @@ -0,0 +1,30 @@ +use strict; +use warnings; +use Test::More tests => 3; #qw(no_plan); + +use_ok qw(SOAP::WSDL::XSD::Enumeration); + +use SOAP::WSDL::Expat::WSDLParser; +my $parser = SOAP::WSDL::Expat::WSDLParser->new(); + +my $xml = q{ + + + + + + foobar + + + + + +}; + +my $schema = $parser->parse($xml); + +is $schema->find_type('urn:HelloWorld', 'test') + ->get_enumeration()->[0]->get_value(), 'foo'; +is $schema->find_type('urn:HelloWorld', 'test') + ->get_enumeration()->[1]->get_value(), 'bar'; diff --git a/t/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.t b/t/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.t index a2a1e2d..1f6f174 100644 --- a/t/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.t +++ b/t/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.t @@ -1,21 +1,30 @@ -use Test::More tests => 9; +use Test::More tests => 8; use strict; use warnings; use SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS; my $NMTOKENS = SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS->new(); -is $NMTOKENS->get_value(), undef; +is $NMTOKENS->get_value(), undef, 'get undef value'; $NMTOKENS = SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS->new({}); -is $NMTOKENS->get_value(), undef; +is $NMTOKENS->get_value(), undef, 'get undef value after new with {}'; ok $NMTOKENS = SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS->new({ value => [ 127 , 'Test' ] }); -is $NMTOKENS->serialize, '127 Test', 'stringification'; +is $NMTOKENS->serialize(), '127 Test', 'stringification'; -ok $NMTOKENS = SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS->new({ value => 'Test' }); +ok $NMTOKENS = SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS->new({ value => 'Test' }) + , 'constructor'; is "$NMTOKENS", "Test", 'stringification'; $NMTOKENS = SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS->new({ value => undef }); -is $NMTOKENS, undef, 'stringification'; +#{ +# my $found = 0; +# local $SIG{__WARN__} = sub { +# # die $_[0]; +# $found++ if $_[0] =~m{Use \s of \s uninitialized \s value}x; +# }; +# ok ! "$NMTOKENS"; +# is $found, 1; +#} ok $NMTOKENS->isa('SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN'), 'inheritance'; -ok $NMTOKENS->isa('SOAP::WSDL::XSD::Typelib::Builtin::list'), 'inheritance'; \ No newline at end of file +ok $NMTOKENS->isa('SOAP::WSDL::XSD::Typelib::Builtin::list'), 'inheritance'; diff --git a/t/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.t b/t/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.t index a6877fd..ee8f4f0 100644 --- a/t/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.t +++ b/t/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.t @@ -54,7 +54,7 @@ is $obj->get_value(), 'test2', 'get_value on attr value'; $obj->set_value(undef); -is $obj->serialize({ name => 'foo' }), '' +is $obj->serialize({ name => 'foo' }), '' , 'serialize undef value with name'; is $obj->serialize(), q{}, 'serialize undef value without name'; diff --git a/t/SOAP/WSDL/XSD/Typelib/Builtin/anyType.t b/t/SOAP/WSDL/XSD/Typelib/Builtin/anyType.t index 319d2ab..5c4c9f8 100644 --- a/t/SOAP/WSDL/XSD/Typelib/Builtin/anyType.t +++ b/t/SOAP/WSDL/XSD/Typelib/Builtin/anyType.t @@ -1,12 +1,12 @@ use strict; use warnings; -use Test::More tests => 5; +use Test::More tests => 4; use Scalar::Util qw(blessed); use_ok qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType); is SOAP::WSDL::XSD::Typelib::Builtin::anyType->get_xmlns(), 'http://www.w3.org/2001/XMLSchema', 'get_xmlns'; -is SOAP::WSDL::XSD::Typelib::Builtin::anyType->serialize(), q{}, 'serialize to empty'; +#is SOAP::WSDL::XSD::Typelib::Builtin::anyType->serialize(), q{}, 'serialize to empty'; is SOAP::WSDL::XSD::Typelib::Builtin::anyType->start_tag(), q{}, 'serialize to empty'; is SOAP::WSDL::XSD::Typelib::Builtin::anyType->start_tag({ name => 'foo'}), q{}, 'serialize with name'; exit 0; diff --git a/t/SOAP/WSDL/XSD/Typelib/ComplexType.t b/t/SOAP/WSDL/XSD/Typelib/ComplexType.t index 819a38f..83ebe10 100644 --- a/t/SOAP/WSDL/XSD/Typelib/ComplexType.t +++ b/t/SOAP/WSDL/XSD/Typelib/ComplexType.t @@ -34,6 +34,8 @@ use base qw( __PACKAGE__->__set_name( 'MyElement' ); +sub __get_attr_class { 'MyElement::_ATTR' }; + package MyElement::_ATTR; use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet); { @@ -51,6 +53,7 @@ use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet); } ); } + package MyType2; use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); @@ -67,8 +70,19 @@ __PACKAGE__->_factory( } ); +package MyElementSimpleContent; +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType + SOAP::WSDL::XSD::Typelib::Builtin::string +); + +__PACKAGE__->__set_name( 'MyElementSimpleContent' ); + +sub __get_attr_class { 'MyElement::_ATTR' }; + package main; -use Test::More tests => 109; +use Test::More tests => 111; use Storable; my $have_warn = eval { require Test::Warn; import Test::Warn; 1; }; @@ -150,6 +164,12 @@ $nested = MyType2->new({ is $nested->get_test->[0], $obj; +# use Data::Dumper; +# print Data::Dumper::Dumper $nested->as_hash_ref(); + +is $nested->as_hash_ref()->{ test }->[ 0 ]->{ test }->[0], 'Test' + , 'as_hash_ref with nested elements'; + $nested = MyType2->new({ test => { test => [ @@ -194,10 +214,7 @@ $obj->set_test(); is $obj->get_test, (), 'removed element content'; $obj = MyEmptyType->new(); -eval { - isa_ok $obj->attr() , 'SOAP::WSDL::XSD::Typelib::AttributeSet'; -}; -like $@, qr{\s has \s no \s attributes}x; +is $obj->attr(), undef; $obj = MyElement->new(); isa_ok $obj->attr() , 'SOAP::WSDL::XSD::Typelib::AttributeSet'; @@ -324,3 +341,7 @@ eval { SOAP::WSDL::XSD::Typelib::ComplexType->_factory([], { test => {} }, { tes like $@, qr{ Can't \s locate \s HopeItDoesntExistOnYourSystem.pm }xms; # print Dumper + +$obj = MyElementSimpleContent->new({ value => 'foo' }); +$obj->attr({ test => 'foo', test2 => 'bar' }); +is $obj->serialize_qualified(), 'foo'; diff --git a/t/acceptance/wsdl/WSDLParser-imported.wsdl b/t/acceptance/wsdl/WSDLParser-imported.wsdl index f642126..a6e936f 100644 --- a/t/acceptance/wsdl/WSDLParser-imported.wsdl +++ b/t/acceptance/wsdl/WSDLParser-imported.wsdl @@ -1,51 +1,50 @@ - + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="urn:HelloWorld" + xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" + xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" + targetNamespace="urn:HelloWorld" + xmlns="http://schemas.xmlsoap.org/wsdl/"> + - + - - - + + + - - - + + + - - - + + + + + + - - - + + - - + + - - + + + - - - - - - - - - + + + + + diff --git a/t/acceptance/wsdl/WSDLParser.wsdl b/t/acceptance/wsdl/WSDLParser.wsdl index 1e06b56..830551c 100644 --- a/t/acceptance/wsdl/WSDLParser.wsdl +++ b/t/acceptance/wsdl/WSDLParser.wsdl @@ -1,77 +1,77 @@ - - - - - - - - - - - + xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" + xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:s0="urn:HelloWorld" + xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" + xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" + xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" + targetNamespace="urn:HelloWorld" + xmlns="http://schemas.xmlsoap.org/wsdl/"> + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - - + + + - - - - - + + + + + - - - - - + + + + + diff --git a/t/acceptance/wsdl/generator_test.wsdl b/t/acceptance/wsdl/generator_test.wsdl index 2d18f48..5461af2 100644 --- a/t/acceptance/wsdl/generator_test.wsdl +++ b/t/acceptance/wsdl/generator_test.wsdl @@ -88,35 +88,40 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - ComplexType Test + complexType with simpleContent test - - + + + + + + + + + - - complexType extension test - - - - - - - - - - - - - - - ComplexType Test - + complexType extension test + + + + + + + + + + + + + + + ComplexType choice test @@ -126,9 +131,7 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - - ComplexType Test - + ComplexType Test @@ -136,11 +139,24 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm + + + ComplexType Test + + + + + + + + Test Attribute good for nothing + + + + - - ComplexType Test - + ComplexType test @@ -148,6 +164,13 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm + + + + + + + @@ -155,7 +178,7 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - + @@ -180,30 +203,30 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - - - + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -226,7 +249,7 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - + @@ -259,19 +282,19 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - - Test-Methode - - - - - - - Test-Methode - - - - + + Test-Methode + + + + + + + Test-Methode + + + + Test-Methode @@ -284,34 +307,34 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - + - + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - - - + + + @@ -337,60 +360,60 @@ xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:http="http://schemas.xm - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/t/acceptance/wsdl/generator_test_dot_names.wsdl b/t/acceptance/wsdl/generator_test_dot_names.wsdl index d2f0a46..2537bba 100644 --- a/t/acceptance/wsdl/generator_test_dot_names.wsdl +++ b/t/acceptance/wsdl/generator_test_dot_names.wsdl @@ -1,5 +1,5 @@ - - + SimpleType: List with an integer (length 2) @@ -43,7 +43,7 @@ - + @@ -57,7 +57,7 @@ - + @@ -67,8 +67,8 @@ ComplexType Test - - + + @@ -78,8 +78,8 @@ - - + + @@ -139,17 +139,17 @@ - + - SimpleType: Integer between 1 and 9 + SimpleType: Integer between 1 and 9 (Inclusive constraints) - @@ -157,7 +157,7 @@ - SimpleType: Integer between 1 and 9 + SimpleType: Integer between 1 and 9 (Inclusive constraints) @@ -170,8 +170,8 @@ - - + + @@ -191,8 +191,8 @@ - - + + @@ -202,7 +202,7 @@ - + @@ -213,7 +213,7 @@ - + @@ -258,7 +258,7 @@ - + diff --git a/t/acceptance/wsdl/generator_unsupported_test.wsdl b/t/acceptance/wsdl/generator_unsupported_test.wsdl index f86a72f..47623a5 100644 --- a/t/acceptance/wsdl/generator_unsupported_test.wsdl +++ b/t/acceptance/wsdl/generator_unsupported_test.wsdl @@ -1,5 +1,5 @@ - - + SimpleType: List with an integer and a string - + - - - - SimpleType: List with an integer and a string - - - - - - - - - - - - - - - - - - - - - - - SimpleType: List with an integer and a string - - - - - - - - - SimpleType: List with an integer and a string - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SimpleType: Integer between 1 and 9 - (Inclusive constraints) - - - - - - - - - - - - - + - + diff --git a/t/acceptance/wsdl/nested_complextype.wsdl b/t/acceptance/wsdl/nested_complextype.wsdl new file mode 100644 index 0000000..657855f --- /dev/null +++ b/t/acceptance/wsdl/nested_complextype.wsdl @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/t/lib/MyElement.pm b/t/lib/MyElement.pm index d59a98d..c86f20c 100644 --- a/t/lib/MyElement.pm +++ b/t/lib/MyElement.pm @@ -66,8 +66,8 @@ my %test2_of :ATTR(:get); sub get_xmlns { 'urn:Test' }; -__PACKAGE__->_factory( - [ qw(test test2) ], +__PACKAGE__->_factory( + [ qw(test test2) ], { test => \%test_of, test2 => \%test2_of, @@ -99,11 +99,11 @@ use base ( { my %test_of :ATTR(:get); my %test2_of :ATTR(:get); - + sub get_xmlns { 'urn:Test' }; - - __PACKAGE__->_factory( - [ qw(test test2) ], + + __PACKAGE__->_factory( + [ qw(test test2) ], { test => \%test_of, test2 => \%test2_of, @@ -117,6 +117,8 @@ use base ( } __PACKAGE__->__set_name('MyElementAttrs'); +sub __get_attr_class { 'MyElementAttrs::_ATTR' }; + package MyElementAttrs::_ATTR; use strict; @@ -128,11 +130,11 @@ use base qw( { my %test_of :ATTR(:get); my %test2_of :ATTR(:get); - + sub get_xmlns { 'urn:Test' }; - - __PACKAGE__->_factory( - [ qw(test test2) ], + + __PACKAGE__->_factory( + [ qw(test test2) ], { test => \%test_of, test2 => \%test2_of, diff --git a/t/lib/Test/SOAP/WSDL/Expat/WSDLParser.pm b/t/lib/Test/SOAP/WSDL/Expat/WSDLParser.pm new file mode 100644 index 0000000..11cb0eb --- /dev/null +++ b/t/lib/Test/SOAP/WSDL/Expat/WSDLParser.pm @@ -0,0 +1,74 @@ +#!perl +package Test::SOAP::WSDL::Expat::WSDLParser; +use strict; +use warnings; +use Test::More; +use Test::SOAP::WSDL::Tester; +use base qw(Test::SOAP::WSDL::Tester); + +# It's a modulinho - it runs when executed... +if (! caller() ) { + __PACKAGE__->runtests(); +} + +sub parse_t_uri { + my $self = shift; + my $parser = SOAP::WSDL::Expat::WSDLParser->new(); + return $parser->parse_uri($self->t_url() . '/'. shift); +} + +sub parse_wsdl_schema :Test(1) { + my $self = shift; + ok my $wsdl = $self->parse_t_uri( "../imported/schema/wsdl11/wsdl.xsd"); +} + +sub parse_soap_binding :Test(1) { + my $self = shift; + ok my $wsdl = $self->parse_t_uri( "../imported/schema/wsdl11/soap_binding.xsd"); +} + +sub parse_http_binding :Test(1) { + my $self = shift; + ok my $wsdl = $self->parse_t_uri( "../imported/schema/wsdl11/http_binding.xsd"); +} + +sub parse_wsdl :Test(3) { + my $self = shift; + ok my $wsdl = $self->parse_t_uri( "acceptance/wsdl/WSDLParser.wsdl"); + my $schema = $wsdl->first_types()->get_schema()->[1]; + my $attr = $schema->get_element()->[0]->first_complexType->first_attribute(); + ok $attr->get_name('testAttribute'); + ok $attr->get_type('xs:string'); + +} + +sub parse_wsdl_with_import :Test(8) { + my $self = shift; + ok my $wsdl = $self->parse_t_uri( "acceptance/wsdl/WSDLParser-import.wsdl"); + + # Content checks + is $wsdl->get_service()->[0]->get_name(), 'Service1', 'found service name'; + is $wsdl->get_portType->[0]->get_name(), 'Service1Soap', 'found portType name'; + is $wsdl->get_types()->[0] + ->get_schema()->[1] + ->get_element()->[0]->get_name(), 'sayHello', 'found element name'; + ok my $schema_from_ref = $wsdl->get_types() + ->[0]->get_schema(), 'found schema'; + is @{ $schema_from_ref }, 2, 'got builtin and imported schema'; + ok @{ $schema_from_ref->[1]->get_element } > 0, 'found mi element in second schema'; + is $schema_from_ref->[1] + ->get_element->[0]->get_name(), 'sayHello', 'found element name'; +} + +sub parse_wsdl_with_import_loop :Test(1) { + my $self = shift; + SKIP: { + skip 'cannot test without Test::Warn', 1 if not $self->has_test_warn(); + my $wsdl; + Test::Warn::warning_like + { $wsdl = $self->parse_t_uri( "acceptance/wsdl/WSDLParser_import_loop.wsdl") } + qr{file:///home/martin/workspace/SOAP-WSDL/t/acceptance/wsdl/import_loop.xsd \s already \s imported. \s Ignoring \s it}x, + 'warn about duplicate import'; + } +} +1; \ No newline at end of file diff --git a/t/lib/Test/SOAP/WSDL/Generator/Iterator/WSDL11.pm b/t/lib/Test/SOAP/WSDL/Generator/Iterator/WSDL11.pm new file mode 100644 index 0000000..a1cf901 --- /dev/null +++ b/t/lib/Test/SOAP/WSDL/Generator/Iterator/WSDL11.pm @@ -0,0 +1,42 @@ +#!perl +package Test::SOAP::WSDL::Generator::Iterator::WSDL11; +use strict; +use warnings; +use Test::More; +use SOAP::WSDL::Expat::WSDLParser; +use base qw(Test::SOAP::WSDL::Tester); + +# It's a modulinho - it runs when executed... +if (! caller() ) { + __PACKAGE__->runtests(); +} +sub parse_t_uri { + my $self = shift; + my $parser = SOAP::WSDL::Expat::WSDLParser->new(); + return $parser->parse_uri($self->t_url() . '/'. shift); +} + +sub iterate :Test() { + my $self = shift; + my $iter = SOAP::WSDL::Generator::Iterator::WSDL11->new(); + $iter->set_definitions($self->parse_t_uri( "acceptance/wsdl/WSDLParser.wsdl")); + $iter->init(); + + while (my $node = $iter->get_next()) { + print $node, "\n"; + } +} + +sub iterate_init :Test() { + my $self = shift; + my $iter = SOAP::WSDL::Generator::Iterator::WSDL11->new(); + $iter->set_definitions($self->parse_t_uri( "acceptance/wsdl/WSDLParser.wsdl")); + $iter->init(); + + for my $service (@{ $iter->get_definitions()->get_service() }) { + while (my $node = $iter->get_next()) { + print $node, "\n"; + } + } +} + diff --git a/t/lib/Test/SOAP/WSDL/Generator/Visitor/Typemap.pm b/t/lib/Test/SOAP/WSDL/Generator/Visitor/Typemap.pm new file mode 100644 index 0000000..0a3daa8 --- /dev/null +++ b/t/lib/Test/SOAP/WSDL/Generator/Visitor/Typemap.pm @@ -0,0 +1,16 @@ +#!perl +package Test::SOAP::WSDL::Generator::Visitor::Typemap; +use strict; use warnings; +use Test::More; +use base qw(Test::SOAP::WSDL::Tester); + +# It's a modulinho - it runs when executed... +if (! caller() ) { + __PACKAGE__->runtests(); +} + +sub a_constructor : Test( 1 ) { + my $self = shift; + ok my $obj = $self->get_class->new() ; + $self->set_object( $self->get_class->new() ); +} diff --git a/t/lib/Test/SOAP/WSDL/Tester.pm b/t/lib/Test/SOAP/WSDL/Tester.pm new file mode 100644 index 0000000..11abb84 --- /dev/null +++ b/t/lib/Test/SOAP/WSDL/Tester.pm @@ -0,0 +1,56 @@ +package Test::SOAP::WSDL::Tester; +use strict; +use warnings; +use Test::Class; +use base qw(Test::Class); + +use File::Basename; +use File::Spec; + +use Test::More; + +use Scalar::Util qw(blessed); + +our $HAS_TEST_WARN; + +BEGIN { + $HAS_TEST_WARN = eval { require Test::Warn; import Test::Warn; 1 }; +} + +sub has_test_warn { + return $HAS_TEST_WARN; +} + +# object accessors +sub set_object { $_[0]->{ object } = $_[1] } +sub get_object { return shift->{ object } }; +# class accessors +sub set_class { $_[0]->{ class } = $_[1] } +sub get_class { return shift->{ class } }; + + +sub startup :Test(startup => 1) { + my $self = shift; + my $class = ref $self; + if ($class eq __PACKAGE__) { + ok __PACKAGE__; + return; + }; + $class =~s{^Test::}{}; + $self->set_class( $class ); + use_ok $class; +} + +sub t_url { + my $path = File::Spec->rel2abs( dirname __FILE__ ); + my ($volume, $dir) = File::Spec->splitpath($path, 1); + my @dir_from = File::Spec->splitdir($dir); + unshift @dir_from, $volume if $volume; + + my $url = 'file://' . join '/', @dir_from[0..$#dir_from - 4]; + # die $url; + return $url; + +} + +1; \ No newline at end of file diff --git a/t/lib/Test/SOAPMessage.pm b/t/lib/Test/SOAPMessage.pm deleted file mode 100644 index e79ca5e..0000000 --- a/t/lib/Test/SOAPMessage.pm +++ /dev/null @@ -1,64 +0,0 @@ -package Test::SOAPMessage; - -use strict; - -use SOAP::Lite; -use Test::Differences; -use Tie::IxHash; - -use base qw/Exporter/; - -our @EXPORT = qw/soap_eq_or_diff/; - -sub soap_eq_or_diff -{ - my $got = shift; - my $expected = shift; - my $message = shift; - my $soapGot = SOAP::Deserializer->deserialize( $got ); - my $soapExpected = SOAP::Deserializer->deserialize( $expected ); - - return eq_or_diff( - unlather( $soapGot ), - unlather( $soapExpected ), - $message - ); -} - -sub unlather -{ - my $som = shift; - my $path = shift || '/Envelope/Body/[1]'; - my $data = shift; - - unless ( $data ) - { - my %hashData = (); - tie (%hashData, q/Tie::IxHash/); - $data = \%hashData; - } - - my $value; - my $tag; - my $i = 1; - while( $som->match("$path/[$i]") ) - { - $tag = $som->dataof->name(); - $data ||= {}; - $value = unlather($som,$path.'/'. '[' . $i . ']' ) || $som->valueof("$path/[$i]"); - if ($data->{ $tag }) - { - $data->{ $tag } = [ $data->{ $tag } ] unless ( ref ( $data->{ $tag } ) eq 'ARRAY' ); - push @{ $data->{ $tag } }, $value; - } - else - { - $data->{ $tag } = $value; - } - $i++; - } - $data ||= $som->valueof($path); - return $data; -} - -1; \ No newline at end of file