diff --git a/Build.PL b/Build.PL index 0ad9021..955aa9b 100644 --- a/Build.PL +++ b/Build.PL @@ -1,25 +1,53 @@ -#!/usr/bin/perl -w use Module::Build; - -Module::Build->new( - create_makefile_pl => 'passthrough', - dist_name => 'SOAP-WSDL', - dist_version => '1.27', - dist_abstract => 'WSDL support for SOAP::Lite', - module_name => 'SOAP::WSDL', - license => 'artistic', - requires => { - 'SOAP::Lite' => 0, - 'XML::XPath' => 0, - }, - buildrequires => { - 'Test::More' => 0, - 'SOAP::Lite' => 0, - 'XML::XPath' => 0, - 'Time::HiRes' => 0, - 'File::Spec' => 0, - 'File::Basename' => 0, - 'Cwd' => 0, - }, - -)->create_build_script; +use version; +$build = Module::Build->new( + dist_author => 'Martin Kutter ', + create_makefile_pl => 'passthrough', + dist_abstract => 'SOAP with WSDL support', + dist_name => 'SOAP-WSDL', + dist_version => '2.00_29', + module_name => 'SOAP::WSDL', + license => 'artistic', + requires => { + # 5.6.x is way too buggy and has no unicode support + # 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), + 'Data::Dumper' => 0, + 'Date::Parse' => 0, + 'Date::Format' => 0, + 'File::Basename' => 0, + 'File::Path' => 0, + 'Getopt::Long' => 0, + 'List::Util' => 0, + 'LWP::UserAgent' => 0, + 'Template' => 0, + 'Term::ReadKey' => 0, + 'XML::Parser::Expat' => 0, + }, + buildrequires => { + 'Class::Std::Fast' => qv(0.0.5), + 'Cwd' => 0, + 'Date::Parse' => 0, + 'Date::Format' => 0, + 'Getopt::Long' => 0, + 'List::Util' => 0, + 'LWP::UserAgent' => 0, + 'File::Basename' => 0, + 'File::Path' => 0, + 'File::Spec' => 0, + 'Storable' => 0, + 'Test::More' => 0, + 'Template' => 0, + 'XML::Parser::Expat' => 0, + }, + recursive_test_files => 1, + meta_add => { + no_index => { + directory => 'lib/SOAP/WSDL/Generator/Template/XSD/', + }, + } +); +$build->add_build_element('tt'); +$build->create_build_script; diff --git a/CHANGES b/CHANGES deleted file mode 100644 index 24f9c70..0000000 --- a/CHANGES +++ /dev/null @@ -1,170 +0,0 @@ -* v.1.27 -- fixed issue reported by Cominic Caffrey: SOAP::WSDL does not find XML -elements with multiple prefixes assigned to the schema's targetNamespace -* v1.26 2007/10/05 - bugfix -- fixed issue reported by T Alex Beamish: tests fail when unwrapped into /tmp -* v1.25 2007/09/24 - maintenance -- added Makefile.PL to ease installation - -* v1.24 2007/09/22 - bugfix -- fixes issue reported by David Bussenschutt: wsdlinit always uses new SOAP::Schema instance. - -* v1.23 2007/06/05 - bugfixes and optimizations -- fixes #27426: missing prereq XML::XPath -- fixed build_requires -- some doc fixes -- now performs some initializations on calling portname() - -* v1.22 2007/05/30 - auto-discover service and port again -- re-introduces auto-detecting of servicename and portname -- fixes #27325: Test fails with Test::Pod::Coverage v 1.06. -- Now build requires Test::More -- documentation update -- cosmetics - -2007/05/28 private methods made private and pod update - - added pod tests - - made encodeComplexType and method generators private - - updated pod - - fixed test scripts to work again from within/without t/ - - moved development repository to - https://svn.sourceforge.net/svnroot/soap-wsdl/ (finally !) - -2007/05/21 updated base version to customized version from Giovanni S Fois - - merged in doc changes, so that they don't refer to "customized version" - - changed build process to Build.PL - - changed repository layout to support new build process - -2006/11/06 only in the customized version - Added the support for default values in the wsdl file - -2006/11/04 only in the customized version - Changed the calling interface. Now it's driven by the by the service - and port names. - -2006/11/03 only in the customized version - Corrected the Check for the correct number of elements in complex types - - If a complex type is marked optional in a WSDL file, but sub-parts are marked as - required, SOAP::WSDL used to die if the complex type was found in the data. - Now, if a complex type has not data associated and is not strictly required, it - will not be encoded. - -A quick-and-dirty workaround is to turn off the check with - - $soap->wsdl_checkoccurs(0); - -2006/11/02 only in the customized version - - small changes for .Net compatibility when encoding complex types - - added some test cases to the test suite try perl t/3_varous.t for more details - - -2006/10/28 only in the customized version - - added a small support for the complexType restrictions of Arrays - -2006/10/02 only in the customized version - (Thanks to Dan Horne for having spotted so many bugs in a row) -- the xml prefix was used as the default wsdl namespace when looking for the complextype restrictions -- the module crashed when the operation had no part declaration -- the port name stated in the service definition was used as the portType -- the test suited failed when the module was unzipped in a t.* named directory - - - -2006/09/15 only in the customized version - (Thanks to Terje Kristensen for his support and twisted wsdl files :) -- cleaned up the code for readability -- cleaned up the code for "use warnings" and "use strict" -- added support for wsdl files with multiple schema declarations -- added supporto for some restriction on complexTypes - - - - -2006/07/10 only in the customized version - - added the support for SOAP::header calls - -2006/06/10 only in the customized version - - - removed the overload based on the type of the call's parameters - - - added an overloading support based on the unique name of the input message of the call. The input message must be provided by the calling script (sorry, the module has no mean to find this). - - - added a light support to the sympletypes. - - - added a light support to the imported namespaces in the types section. - - - added the support for the multiple SOAP bindings. The correct binding must be provided by the calling script (sorry, the module has no mean to find this). - - - the method will use his own soapAction if defined - - - the method will use his own namespace if defined - - - some other code cleaning - -2006/04/23 only in the customized version - - - corrected a bug related to the presence of the same method name on multiple - webservices - - - added an overloading support based on the type of the call's parameters - - - multiple extensions support added: a complextype can be an extension of a complextype which is an extension and so on - - - -Revision 1.7 2004/07/27 13:00:03 lsc -- added missing test file - -Revision 1.18 2004/07/16 07:43:05 lsc -fixed test scripts for windows - -Revision 1.17 2004/07/05 08:19:49 lsc -- added wsdl_checkoccurs - -Revision 1.16 2004/07/04 09:01:14 lsc -- change element lookup from find('/definitions') and find('wsdl:definitions') to find('/*[1]') to process arbitrary default (wsdl) namespaces correctly -- fixed test output in test 06 - -Revision 1.15 2004/07/02 12:28:31 lsc -- documentation update -- cosmetics - -Revision 1.14 2004/07/02 10:53:36 lsc -- API change: - - call now behaves (almost) like SOAP::Lite::call - - call() takes a list (hash) as second argument - - call does no longer support the "dispatch" option - - dispatching calls can be suppressed by passing - "no_dispatch => 1" to new() - - dispatching calls can be suppressed by calling - $soap->no_dispatch(1); - and re-enabled by calling - $soap->no_dispatch(0); -- Updated test skripts to reflect API change. - -Revision 1.13 2004/06/30 12:08:40 lsc -- added IServiceInstance (ecmed) to acceptance tests -- refined documentation - -Revision 1.12 2004/06/26 14:13:29 lsc -- refined file caching -- added descriptive output to test scripts - -Revision 1.11 2004/06/26 07:55:40 lsc -- fixed "freeze" caching bug -- improved test scripts to test file system caching (and show the difference) - -Revision 1.10 2004/06/26 06:30:33 lsc -- added filesystem caching using Cache::FileCache - -Revision 1.9 2004/06/24 12:27:23 lsc -Cleanup - -Revision 1.8 2004/06/11 19:49:15 lsc -- moved .t files to more self-describing names -- changed WSDL.pm to accept AXIS wsdl files -- implemented XPath query result caching on all absolute queries - -Revision 1.7 2004/06/07 13:01:16 lsc -added changelog to pod diff --git a/Changes b/Changes new file mode 100644 index 0000000..40cda63 --- /dev/null +++ b/Changes @@ -0,0 +1,573 @@ +Release notes for SOAP::WSDL 2.00_29 +------- + +I'm proud to present a new pre-release version of SOAP::WSDL. + +SOAP::WSDL is a toolkit for creating WSDL-based SOAP client interfaces in perl. + +Features: + + * WSDL based SOAP client + o SOAP1.1 support + o Supports document/literal message style/encoding + * Code generator for generating WSDL-based interface classes + o Generated code includes usage documentation for the web service interface + * Easy-to use API + o Automatically encodes perl data structures as message data + o Automatically sets HTTP headers right + * Efficient documentation + o SOAP::WSDL::Manual guides you at getting your work done, not at + the module's internals + * Thorough test suite + o SOAP::WSDL is heavily regression tested, with a test coverage of + over 95% (excluding documentation - you wouldn't want to read + through it all). + * SOAP::Lite like look and feel + o Where possible, SOAP::WSDL mimics SOAP::Lite's API to allow easy migrations + * XML schema based class library for creating data objects + * High-performance XML parser + * Plugin support. SOAP::WSDL can be extended through plugins in various aspects. + The following plugins are supported: + o Transport plugins via SOAP::WSDL::Factory::Transport + o Serializer plugins via SOAP::WSDL::Factory::Serializer + o Deserializer plugins via SOAP::WSDL::Factory::Serializer + +The following changes have been made: + +2.00_29 + +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/). + + * #32188: minor bug found and fixed in WSDL generation + * [ 1871175 ] Can't delete attributes from ComplexType objects + +The following uncategorized improvements have been made: + + * Updated SOAP::WSDL::Manual::XSD + * Removed pod directives from templates to avoid confusing CPAN's pod + viewer + * Initial (incomplete) XML attribute support + * Updated test suite + +2.00_28 + +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/). + + * #32062: minor doc fixes + * [ 1852988 ] Generated Interface POD is invalid + * [ 1855583 ] t/SOAP/WSDL/XSD/Typelib/ComplexType.t requires Test::Warn + +The following uncategorized improvements have been made: + + * Updated SOAP::WSDL::Manual::WS_I to reflect new Server modules + +2.00_27 + +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1850793 ] Add a to_hash_ref method + * [ 1844427 ] Support multiple parts in body + +The following bugs have been fixed (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660921): +The numbers with # are CPAN RT IDs (http://rt.cpan.org/). + + * [ 1850795 ] attributes referencing types in default namespace throw + * [ 1844458 ] Add warning when generating Interface with multiple parts + * [ 1843841 ] Grammar/typos in Manual.pod + * [ 1843799 ] ./Build test fails due to testcount mismatch not IO::Scalar + * [ 1845077 ] Top level simpleType elements don't serialize correctly + +The following uncategorized improvements have been made: + + * Fixed serializing complexType elements with no elements to empty element + * Enhanced test suite + * Documentation improvements + +2.00_26 + +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + +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/). + + * [ 1843195 ] t/013_complexType.t still requires Class::Std::Storable + * [ 1843590 ] Tests broken on Cygwin + +The following uncategorized improvements have been made: + + * Added examples + * Added Content-length header to CGI output + +2.00_25 +--- +WARNING: INCOMPATIBLE CHANGE: + + SOAP::WSDL now uses Class::Std::Fast. Read the MIGRATING guide for + upgrading from previous versions. + You probably need to re-generate all your interfaces. + +WARNING: INCOMPATIBLE CHANGE: + + SOAP::WSDL::XSD::Typelib::anySimpleType based objects no longer serialize + to their XML value on stringification. + This means that strings are no longer XML-escaped when the simpleType + containing the string is printed or used like this: + + my $value = "$simpleType"; + + Note that ComplexType objects still serialize to their XML on + stringification. This Change is due to the demands of applications + embedding SOAP::WSDL::XSD::Typelib objects in templates - it would mean + a nasty ->get_value for every (simple) value. + +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1837347 ] Use Class::Std::Fast + Class::Std::Fast allows optimizations which almost double SOAP::WSDL's + performance and reduce code size. Class::Std::Fast also opens the door + for even faster XS implementations. + * [ 1842436 ] Add SOAP Server + +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/). + + * [ 1842418 ] Message parser eats up whitespaces between entities + * [ 1839820 ] encoding parameter of Content-Type header set incorrectly + * [ 1839851 ] token in UPPERCASE in default typemap + * [ 1839690 ] Can't use two prefixes for namespace in WSDL + * [ 1839833 ] incorrect encoding/decoding of double-quote + +The following uncategorized improvements have been made: + + * Errors in typemap generation have been fixed + * XML parser speedups + * The test suite has been improved + +2.00_24 +--- +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1832998 ] Make interface methods complain when called as class method + * [ 1826833 ] listify all XSD type objects when called as @{} + +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/). + + * #30685: Error in MessageParser when using __SKIP__ in typemap + * [ 1831398 ] Badd class names for atomic typed elements + * [ 1828240 ] POD Defects + * [ 1792348 ] 006_client.t requires SOAP::Lite (again) + +The following uncategorized improvements have been made: + + * The test suite has been improved + * Documentation has been improved + +2.00_23 +--- + +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): + + * [ 1826382 ] nillable elements not serialized as xsi:nil + * [ 1826337 ] Second element in complexType gets eaten up + * [ 1792348 ] 006_client.t requires SOAP::Lite (again) + +The following uncategorized improvements have been made: + + * Test for complexType containing element with atomic simpleType added + +2.00_22 +---- + +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): + + * [ 1817697 ] Dots in service/port names lead to broken interfaces + * [ 1817699 ] Templates not found on all OS + +The following uncategorized improvements have been made: + + * Code cleanup. The XSD library has been cleaned up a bit. Should result + in a minor speedup in serializing and deserializing XML messages, + +2.00_21 - not released +---- +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): + + * [ 1810058 ] .tt's pod indexed on CPAN (again) + * [ 1809284 ] Rename SOAP::WSDL::Deserializer::SOAP11 to ::XSD + +The following uncategorized improvements have been made: + + * Requires at least perl 5.8.0. This is due to a bug in perls before - + see http://aspn.activestate.com/ASPN/Mail/Message/perl5-porters/929746 + +2.00_20 +---- +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1815646 ] Only include last part of port name in interface + * [ 1815648 ] Methods with empty body cannot be called as ->method() + * [ 1815651 ] Empty complexType definitions not supported + +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): + + * [ 1815643 ] ComplexTypes cannot be freezed/thawed + +The following uncategorized improvements have been made: + + * WSDL definitions are decoded into utf8 + * fixed tests to use correct path on windows + +2.00_19 +---- +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1810395 ] Implement complexType complexContent extension + +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): + + * [ 1813144 ] Typemap not used in interface class + * [ 1810058 ] .tt's pod indexed on CPAN + +The following uncategorized improvements have been made: + + * Documentation improvements + +2.00_18 +---- +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1790983 ] Create generator Plugin API + Generator factory is SOAP::WSDL::Factory::Generator + +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): + + * [ 1805252 ] t/SOAP/WSDL/XSD/Typelib/Builtin/004_time.t fails + The default timezone conversion has been fixed. + +The following uncategorized improvements have been made: + + * Documentation improvements + * Test updates + * readable() has been converted into a no-op, as it already had no effect + any more + +2.00_17 +---- +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + +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): + + * [ 1772617 ] SOAP Header not working + Added header support. Currently, SOAP headers are only supported with + the SOM or the XSD (SOAP11) serializer. + + * [ 1805238 ] Tests in t/SOAP/WSDL don't work when run from t/ + + * [ 1805241 ] explain() broken in SOAP::WSDL + explain has been removed from SOAP::WSDL + +The following uncategorized improvements have been made: + + * Added limited support for complexType complexContent content model with + restriction variety. + SOAP::WSDL now supports this XML Schema definition variant, although no + constraints are imposed on derived types yet. + Derived types do not serialize with a xsi:type attribute (and the xsi:type + attribute is not recognized by the XML parser), so you cannot use derived + types as a substitute for theri parent, yet. + + * Added support for complexType choice variety + complexType definitions using the choice variety are now supported, + even though the content is not checked (if you pass in invalid data, + invalid XML will be generated). + + * Added Loopback Transport backend. + SOAP::WSDL::Tranport::Loopback just returns the request as respons, but + allows testing the whole chain from user interface to transport backend. + + * Fixed SOAP::WSDL::Factory::Transport prefer user-registered + transport backend + + * Fixed set_soap_version method in SOAP::WSDL::Client. + Re-setting the SOAP version now invalidates (resets) serializer and + deserializer, but not the transport backend. + + * Fixed SOAP::WSDL::XSD::Typelib::Builtin::boolean to return false + when false and true when true. + + * SOAP::WSDL::XSD::Typelib::Builtin::normalizedString now replaces all + occurences of tab, newline and carriage return by whitespce on set_value. + + * Code cleanup + o Lots of orphan methods now replaced by the SOAP::WSDL::Generator + hierarchy have been removed. + o Unused (and unusable) readable option checking has been removed in + SOAP::WSDL::Serializer::SOAP11. + o Unused XML Schema facet attributes have been removed from XSD Builtin + classes + o Methods common to all expat parser classes have been factored out + into a common base class. + + * XML serialization speedup for SOAP::WSDL::XSD::* objects + + * Tests added to improve test coverage. + + * A few documentation errors have been fixed + + * Misspelled default Typemap and Interface prefixes have been corrected + +2.00_16 +---- +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1761532 ] Support embedded atomic types + SOAP::WSDL now supports a greater variety of XML Schema type definitions. + Note that XML Schema support is still incomplete, though. + + * [ 1797943 ] Create Perl Hash Deserializer + There's a new deserializer which outputs perl hashes as data structures. + Much like XML::Simple, but faster. No XML Attribute support, though. + + * [ 1797678 ] Move Code generator from WSDL::Definitions to separate class + + * [ 1803330 ] Create one interface per port + SOAP::WSDL now creates one interface per port, not one per service. + +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): + + * [ 1804441 ] parts from binding not regarded in SOAP::WSDL + SOAP::WSDL (interpreter mode) now respects the body parts specified in the + binding. + + * [ 1803763 ] nonNegativeInteger misspelled in Schema::Builtin + + * [ 1793965 ] _expand() does not work on non-root-node ns declarations + + * [ 1792348 ] 006_client.t requires SOAP::Lite in 2.00_15 + SOAP::WSDL no longer attempts to load SOAP::WSDL::Deserializer::SOM when + no_dispatch is set. + 006_client.t now sets outputxml(1), to be really sure. + +The following uncategorized improvements have been made: + + * Code generator only generates interface for the first port in a service + The code generator now generates interfaces for all ports. + Note: The naming scheme has changed. It is now + InterfacePrefix::Service::Port + + * XML Parser speedup + The XML parser has received a little speedup. + + * A number of errors in parsing / traversing WSDL documents have been + corrected. + + * Documentation has been improved + + * A number of (incorrect, but passing) tests have been fixed. + + * Code cleanup: The SOAP::WSDL::SAX* modules are no longer included, as they + are not supported any more. They can still be found in SOAP::WSDL's + subversion repository in the attic directory, though. + +2.00_15 +---- + +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): + + * [ 1792321 ] 2.00_14 requires SOAP::Lite for passing tests + +2.00_14 +---- + +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): + + * [ 1792235 ] SOAP::WSDL::Transport::Test missing from 2.00_13 + The package has been re-added + + * [ 1792221 ] class_resolver not set from ::Client in 2.00_13 + Changed to set class_resolver correctly. + +The following uncategorized improvements have been made: + + * The ::SOM deserializer has been simplified to be just a subclass + of SOAP::Deserializer from SOAP::Lite + * Factories now emit more useful error messages when no class is registered + for the protocol/soap_version requested + * Documentation has been improved + - refined ::Factory:: modules' documentation + * Several tests have been added + * XSD classes have been improved for testability + +2.00_13 +---- +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [ 1790619 ] Test transport backend + A test transport backend has been implemented (SOAP::WSDL::Transport::Test). + It returns the contents from a file and discards the response. + The filename is determined from the soap_action field. + + * [ 1785196 ] Replace outputsom(1) by deserializer plugin + outputsom(1) in SOAP::WSDL is now implemented via using the deserializer + plugin SOAP::WSDL::Deserializer::SOM. + + * [1785195] Support deserializer plugins + Deserializer plugin API added via SOAP::WSDL::Factory::Deserializer. + +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): + + * [1789581] Support ComplexType mixed + WSDL parser now supports using the mixed="true" attribute in complexType + definitions. Mixed content in messages is only supported via SOAP::SOM yet. + + * [1787975] 016_client_object.t fails due to testing XML as string + Removed string test. + + * [1787959] Test wsdl seems to be broken + Corrected typo. + + * [1787955] ::XSD::Typelib::date is broken + SOAP::WSDL::XSD::Typelib::Builtin::date now converts time-zoned dates properly, + and adds the local time zone if none is given. + + * [1785646] SOAPAction header not set from soap:operation soapAction + SOAP::WSDL now sets the SOAPAction header correctly. + +The following uncategorized improvements have been made: + + * Documentation improvements + +2.00_12 +---- + +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): + + * [1787146] SOAP::WSDL still uses XML::LibXML + The superficious usage of XML::LibXML has been removed. XML::LibXML with + sax filter has been replaced by SOAP::WSDL::Expat::WSDLParser. + + * [1787054] Test suite requires XML::LibXML in 2.00_11 + The test suite no longer requires XML::LibXML to pass. + + * [1785678] SOAP envelope not checked for namespace + The SOAP envelope is now checked for the correct namespace. + + * [1786644] SOAP::WSDL::Manual - doc error + Documentation improvements + +The following uncategorized improvements have been made + + * The SOAPAction header is now alway quoted (R1109 in WS-I BP 1.0). + +2.00_11 +---- + +The following features were added (the numbers in square brackets are the +tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924): + + * [1767963] Transport plugins via SOAP::WSDL::Factory::Transport. + SOAP::WSDL uses SOAP::Lite's tranport modules as default, with a + lightweight HTTP(S) transport plugin as fallback. + Custom transport modules can be registered via SOAP::WSDL::Factory::Transport. + + * [ 1772730 ] Serializer plugins via SOAP::WSDL::Factory::Serializer + The default serializer for SOAP1.1 is SOAP::WSDL::Serializer::SOAP11. + Custom serializers classes can be registered via + SOAP::WSDL::Factory::Serializer or set via SOAP::WSDL's set_serializer + method. + +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): + + * [ 1764854 ] Port WSDL parser to expat and remove XML::LibXML dependency + SOAP::WSDL now requires only XML::Parser to be installed. + XML::LibXML is not required any more, though XML::LibXML based modules still + exist. + +The following uncategorized improvements have been made + + * The number of dependencies has been reduced. SOAP::WSDL no longer requires the + following modules to be installed: + - XML::SAX::Base + - XML::SAX::ParserFactory + - Pod::Simple::Text + - XML::LibXML + + * The missing prerequisite Template has been added. + * Documentation has been improved: + - WS-I Compliance document added. + + +2.00_10 +---- + * Changed Makefile.PL to use Module::Build (passthrough mode) + * fixed element ref="" handling + +2.00_09 +---- + * SOAP::WSDL::XSD::Typelib::Builtin::boolean objects now return their numerical + value in bool context, not "true" or "false" (always true...) + * date/time test are now timezone-sensitive + * examples added + +2.00_08 +--- + * SOAP::WSDL::XSD::Typelib::ComplexType objects now check the class of their + child objects. + This provides early feedback to developers. + * SOAP message parser can skip unwanted parts of the message to improve parsing + speed - see SOAP::WSDL::Expat::MessageParser for details. + * HTTP Content-Type is configurable + * SOAP::WSDL::XSD::Typelib::ComplexType based objects accept any combination of + hash refs, list refs and objects as parameter to set_value() and new(). + * SOAP::WSDL::XSD::Typelib::Builtin::dateTime and ::date convert date + strings into XML date strings + * SOAP::WSDL::Definitions::create now + - converts '.' in service names to '::' (.NET class separator to perl class + separator) + - outputs Typemaps and Interface classes in UTF8 to allow proper inclusion + of UTF8 documentation from WSDL + * SOAP::WSDL::Definitions::create() includes doc in generated interface classes + * WSDLHandler now handles tags + * fixed explain in SimpleType, ComplexType and Element + +2.00_07 and below +--- + * Implemented a Code generator for creating SOAP interfaces based on WSDL definitions + * Implemented a high-speed stream based SOAP message parser + SOAP message parser returns a objects based on XML schema based class library + * Implemented a XML schema based class library + * Implemented a stream based WSDL parser. + Parses WSDL into objects. Objects can serialize data, and explain how to use the + service(s) they make up (output documentation). diff --git a/HACKING b/HACKING index add7d05..4ebb710 100644 --- a/HACKING +++ b/HACKING @@ -1,7 +1,10 @@ +HACKING +======= + Development of SOAP::WSDL takes place on sourceforge.net. There's a svn repository available at -https://svn.sourceforge.net/svnroot/soap-wsdl +https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl Engagement in the further development of this module is highly encouraged - many people have already contributed, and many more probably will. @@ -11,14 +14,118 @@ so if you feel your changes are urgent, please set up a sourceforge account and ask me for commit permissions on the repository - I will happily accept you as co-author. -The (my) current roadmap for SOAP::WSDL is: +TODO shows the current roadmap. -1.2*: Bugfixes and support for more XSD variants +SOAP-WSDL CODING GUIDELINES +=========================== -1.3: Bindings support +DESIGN PRINCIPLES +----------------- -2.*: WSDL -> Perl Class factory with offline WSDL processing +SOAP-WSDL is designed for the following principles: -May 2007, +1. SPEED +A SOAP toolkit is useless, if it's not fast enough. Therefore SOAP::WSDL aims +at always being fast enough. + +Please benchmark any contributions - if they slow down SOAP-WSDL (especially +the XML parsing part), you should have good reasons. + +2. USABILITY +SOAP-WSDL is designed user-friendly. It tells the user whether it's +capable of handling some WSDL or not, it gives friendly error messages, and +if a user happens to call a non-existant method on XSD objects, they croak +with a list of available methods to ease development. + +3. EXTENSIBILITY +If you plan an extension, look if the extension itself should be extensible, +and which extension points to use. + +Creating new extension points is highly appreciated. + +4. MAINTAINABILITY +SOAP::Lite unfortunately shows where a toolkit can go without focus on +maintainability. SOAP::WSDL tries to be highly maintainable and easy to +understand. + +CODING STYLE +------------ + +The principles above dictate a clear, but not too lengthy coding style. + +SOAP::WSDL's coding style in principle follows Perl Best Practices by +Damian Conway, but allows deviances for speed reasons + +The following guidelines apply: + +- Testing + * SOAP::WSDL has a test coverage of >95% and aims at 100%. Please write + a test first. + * Use author tests for testing guidelines. Disable author tests for + users - it's time consuming and of no use to have users run author tests. + +- Indentation and formatting + * indent with spaces. + * indent 4 characters per level + * use \n (LF) for newlines, not CRLF + * use blank lines to separate paragraphs + * Coding style is similar to K&R (opening brace on last line, closing + brace on new line. No cuddled else) + * No trailing spaces allowed (except to indicate a blank line in a POD + source block) + +- Flow control + * postfix if is allowed for single statements only. Preferably for flow + control only. + * postfix for, while, until are not allowed. + * unless is not allowed at all. Use if not. + * goto is only allowed for jumping into subs. Nothing else. + * redo, next, last etc. are preferred over goto. + +- Strictness and Warnings + * always use strict and warnings. Switch off for the smallest block + possible, but switch of if there's a reason (don't let tools like + perlcritic fool you: no strict qw(refs); is often required. + +- Naming + * variable names are lower case with _ separating words, except when + a XML Schema, SOAP, or WSDL name is name-giving (don't force portType to + become port_type) + * hashes should be named FOO_of, lists FOO_from, references FOO_ref. + * package names are CamelCase, except when a XML, SOAP or WSDL name is + name-giving (don't force 'int' to become 'Int'. However, simpleType + becomes SimpleType). + +- Subroutines + * Subroutines shouldn't be more than around 50 lines long + * @_ should be unpacked. Deviances are allowed for speed reasons. If + you're not unpacking @_ in a sub of say, 5 lines or more, please comment + what you're doing. + * Always return. Always return. A single "return" allows perl to execute + the subroutine in question in void context, which saves it from putting + it's result in a temporary variable. Always return. + +- POD and comments + * Comment extensively. Comments are the maintainer (and core developer's) + documentation - aid them where possible (your're probably doing yourself + a favor by adding extensive comments). + * Comment either in blocks or as hanging side comments (especially when + commenting @_ access). + Example: + + sub baz { + # @_ not unpacked for speed reasons. Read: + # my ($self, $something, %args_of) = @_; + + $_[0]->bar($_[1]); # read as $self->bar($something); + $_[0]->foo($_[2..$#]); # read as $self->foo(%args_of); + return; + } + * POD is located at end of file, preferably after __END__ + * Complete POD coverage is essential. However, if the package in question + is used internally only, it's better to omit the POD completely - too many + PODs to look at confuse the average CPAN user. + +July - November 2007, Martin Kutter \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fd6bcd3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +SOAP::WSDL is dual licensed under the same terms as +Perl itself. + +This means at your choice, either the Perl Artistic License, or +the GNU GPL version 1 or higher. + + diff --git a/MANIFEST b/MANIFEST index d16ff4e..9fa3564 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,18 +1,394 @@ +benchmark/01_expat.t +benchmark/hello.pl +benchmark/person.pl +benchmark/person.xml +benchmark/XSD/01_anyType.t +benchmark/XSD/02_anySimpleType.t +benchmark/XSD/03_string.t +bin/wsdl2perl.pl Build.PL -CHANGES +Changes +example/cgi-bin/helloworld.pl +example/cgi-bin/person.pl +example/fortune.pl +example/genericbarcode.pl +example/hello.pl +example/hello_compile.pl +example/hello_lite.pl +example/lib/MyElements/CountCookies.pm +example/lib/MyElements/CountCookiesResponse.pm +example/lib/MyElements/GenerateBarCode.pm +example/lib/MyElements/GenerateBarCodeResponse.pm +example/lib/MyElements/GetCitiesByCountry.pm +example/lib/MyElements/GetCitiesByCountryResponse.pm +example/lib/MyElements/GetFortuneCookie.pm +example/lib/MyElements/GetFortuneCookieResponse.pm +example/lib/MyElements/GetSpecificCookie.pm +example/lib/MyElements/GetSpecificCookieResponse.pm +example/lib/MyElements/GetWeather.pm +example/lib/MyElements/GetWeatherResponse.pm +example/lib/MyElements/int.pm +example/lib/MyElements/ListPerson.pm +example/lib/MyElements/ListPersonResponse.pm +example/lib/MyElements/readNodeCount.pm +example/lib/MyElements/readNodeCountResponse.pm +example/lib/MyElements/sayHello.pm +example/lib/MyElements/sayHelloResponse.pm +example/lib/MyElements/string.pm +example/lib/MyInterfaces/BarCode/BarCodeSoap.pm +example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm +example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm +example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm +example/lib/MyInterfaces/TestService/TestPort.pm +example/lib/MyServer/HelloWorld/HelloWorldSoap.pm +example/lib/MyServer/TestService/TestPort.pm +example/lib/MyTypemaps/BarCode.pm +example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm +example/lib/MyTypemaps/GlobalWeather.pm +example/lib/MyTypemaps/HelloWorld.pm +example/lib/MyTypemaps/TestService.pm +example/lib/MyTypes/Address.pm +example/lib/MyTypes/ArrayOfContract.pm +example/lib/MyTypes/ArrayOfPerson.pm +example/lib/MyTypes/BarCodeData.pm +example/lib/MyTypes/BarcodeOption.pm +example/lib/MyTypes/BarcodeType.pm +example/lib/MyTypes/CheckSumMethod.pm +example/lib/MyTypes/Contract.pm +example/lib/MyTypes/ImageFormats.pm +example/lib/MyTypes/Person.pm +example/lib/MyTypes/PersonID.pm +example/lib/MyTypes/PhoneNumber.pm +example/lib/MyTypes/ShowTextPosition.pm +example/lib/MyTypes/test2.pm +example/lib/MyTypes/testExtended.pm +example/person.pl +example/person_compile.pl +example/visitor/visitor.pl +example/weather.pl +example/weather_wsdl.pl +example/wsdl/11_helloworld.wsdl +example/wsdl/FortuneCookie.xml +example/wsdl/genericbarcode.xml +example/wsdl/globalweather.xml +example/wsdl/Person.wsdl HACKING lib/SOAP/WSDL.pm +lib/SOAP/WSDL/Base.pm +lib/SOAP/WSDL/Binding.pm +lib/SOAP/WSDL/Client.pm +lib/SOAP/WSDL/Client/Base.pm +lib/SOAP/WSDL/Definitions.pm +lib/SOAP/WSDL/Deserializer/Hash.pm +lib/SOAP/WSDL/Deserializer/SOM.pm +lib/SOAP/WSDL/Deserializer/XSD.pm +lib/SOAP/WSDL/Expat/Base.pm +lib/SOAP/WSDL/Expat/Message2Hash.pm +lib/SOAP/WSDL/Expat/MessageParser.pm +lib/SOAP/WSDL/Expat/MessageStreamParser.pm +lib/SOAP/WSDL/Expat/WSDLParser.pm +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/Template.pm +lib/SOAP/WSDL/Generator/Template/XSD.pm +lib/SOAP/WSDL/Generator/Template/XSD/_type_class.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 +lib/SOAP/WSDL/Generator/Template/XSD/complexType/attributeSet.tt +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/choice.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/complexContent.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/restriction.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/POD/structure.tt +lib/SOAP/WSDL/Generator/Template/XSD/complexType/restriction.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/structure.tt +lib/SOAP/WSDL/Generator/Template/XSD/Interface.tt +lib/SOAP/WSDL/Generator/Template/XSD/Interface/Body.tt +lib/SOAP/WSDL/Generator/Template/XSD/Interface/Header.tt +lib/SOAP/WSDL/Generator/Template/XSD/Interface/Operation.tt +lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Element.tt +lib/SOAP/WSDL/Generator/Template/XSD/Interface/POD/Message.tt +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/Server.tt +lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/Message.tt +lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/method_info.tt +lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/Operation.tt +lib/SOAP/WSDL/Generator/Template/XSD/Server/POD/OutPart.tt +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/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/restriction.tt +lib/SOAP/WSDL/Generator/Template/XSD/Typemap.tt +lib/SOAP/WSDL/Generator/Visitor.pm +lib/SOAP/WSDL/Generator/Visitor/Typelib.pm +lib/SOAP/WSDL/Generator/Visitor/Typemap.pm +lib/SOAP/WSDL/Manual.pod +lib/SOAP/WSDL/Manual/Deserializer.pod +lib/SOAP/WSDL/Manual/Glossary.pod +lib/SOAP/WSDL/Manual/Parser.pod +lib/SOAP/WSDL/Manual/Serializer.pod +lib/SOAP/WSDL/Manual/WS_I.pod +lib/SOAP/WSDL/Manual/XSD.pod +lib/SOAP/WSDL/Message.pm +lib/SOAP/WSDL/Operation.pm +lib/SOAP/WSDL/OpMessage.pm +lib/SOAP/WSDL/Part.pm +lib/SOAP/WSDL/Port.pm +lib/SOAP/WSDL/PortType.pm +lib/SOAP/WSDL/Serializer/XSD.pm +lib/SOAP/WSDL/Server.pm +lib/SOAP/WSDL/Server/CGI.pm +lib/SOAP/WSDL/Service.pm +lib/SOAP/WSDL/SOAP/Address.pm +lib/SOAP/WSDL/SOAP/Body.pm +lib/SOAP/WSDL/SOAP/Header.pm +lib/SOAP/WSDL/SOAP/HeaderFault.pm +lib/SOAP/WSDL/SOAP/Operation.pm +lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm +lib/SOAP/WSDL/Transport/HTTP.pm +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/Attribute.pm +lib/SOAP/WSDL/XSD/Builtin.pm +lib/SOAP/WSDL/XSD/ComplexType.pm +lib/SOAP/WSDL/XSD/Element.pm +lib/SOAP/WSDL/XSD/Schema.pm +lib/SOAP/WSDL/XSD/Schema/Builtin.pm +lib/SOAP/WSDL/XSD/SimpleType.pm +lib/SOAP/WSDL/XSD/Typelib/Attribute.pm +lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/date.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/decimal.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/double.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/duration.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/float.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/gDay.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonth.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonthDay.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/gYear.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/gYearMonth.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/ID.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREFS.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/int.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/integer.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/language.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/list.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/long.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/Name.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/NCName.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/negativeInteger.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/nonNegativeInteger.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/QName.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/short.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedByte.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedInt.pm +lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedLong.pm +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 +LICENSE Makefile.PL MANIFEST This list of files META.yml +MIGRATING +patches/Manual.diff README -t/1_performance.t -t/2_helloworld.NET.t -t/3_various.t -t/4_auto_set_port.t -t/5_same_transport.t -t/97_pod.t -t/98_pod_coverage.t -t/acceptance/helloworld.asmx.xml -t/acceptance/helloworld.xml -t/acceptance/test.wsdl.xml +t/001_use.t +t/002_parse_wsdl.t +t/003_wsdl_based_serializer.t +t/004_parse_wsdl.t +t/006_client.t +t/007_envelope.t +t/008_client_wsdl_complexType.t +t/009_data_classes.t +t/011_simpleType.t +t/012_element.t +t/013_complexType.t +t/016_client_object.t +t/017_generator.t +t/020_storable.t +t/095_copying.t +t/096_characters.t +t/097_kwalitee.t +t/098_pod.t +t/099_pod_coverage.t +t/acceptance/results/03_complexType-all.xml +t/acceptance/results/03_complexType-sequence.xml +t/acceptance/results/04_element-simpleType.xml +t/acceptance/results/04_element.xml +t/acceptance/results/05_simpleType-list.xml +t/acceptance/results/05_simpleType-restriction.xml +t/acceptance/results/05_simpleType-union.xml +t/acceptance/results/11_helloworld.xml +t/acceptance/wsdl/006_sax_client.wsdl +t/acceptance/wsdl/008_complexType.wsdl +t/acceptance/wsdl/02_port.wsdl +t/acceptance/wsdl/03_complexType-all.wsdl +t/acceptance/wsdl/03_complexType-element-ref.wsdl +t/acceptance/wsdl/03_complexType-sequence.wsdl +t/acceptance/wsdl/04_element-simpleType.wsdl +t/acceptance/wsdl/04_element.wsdl +t/acceptance/wsdl/05_simpleType-list.wsdl +t/acceptance/wsdl/05_simpleType-restriction.wsdl +t/acceptance/wsdl/05_simpleType-union.wsdl +t/acceptance/wsdl/10_helloworld.asmx.xml +t/acceptance/wsdl/11_helloworld.wsdl +t/acceptance/wsdl/contributed/Axis.wsdl +t/acceptance/wsdl/contributed/ETest.wsdl +t/acceptance/wsdl/contributed/gasquery.wsdl +t/acceptance/wsdl/contributed/OITest.wsdl +t/acceptance/wsdl/contributed/tools.wsdl +t/acceptance/wsdl/elementAtomicComplexType.xml +t/acceptance/wsdl/email_account.wsdl +t/acceptance/wsdl/generator_test.wsdl +t/acceptance/wsdl/generator_test_dot_names.wsdl +t/acceptance/wsdl/generator_unsupported_test.wsdl +t/acceptance/wsdl/message_gateway.wsdl +t/acceptance/wsdl/WSDLParser.wsdl +t/contributed.wsdl +t/Expat/03_wsdl.t +t/lib/MyComplexType.pm +t/lib/MyElement.pm +t/lib/MySimpleType.pm +t/lib/Test/SOAPMessage.pm +t/lib/Typelib/Base.pm +t/lib/Typelib/TEnqueueMessage.pm +t/lib/Typelib/TMessage.pm +t/SOAP/WSDL.t +t/SOAP/WSDL/01_use.t +t/SOAP/WSDL/02_port.t +t/SOAP/WSDL/03_complexType-all.t +t/SOAP/WSDL/03_complexType-choice.t +t/SOAP/WSDL/03_complexType-complexContent.t +t/SOAP/WSDL/03_complexType-element-ref.t +t/SOAP/WSDL/03_complexType-group.t +t/SOAP/WSDL/03_complexType-sequence.t +t/SOAP/WSDL/03_complexType-simpleContent.t +t/SOAP/WSDL/04_element-complexType.t +t/SOAP/WSDL/04_element-simpleType.t +t/SOAP/WSDL/04_element.t +t/SOAP/WSDL/05_simpleType-list.t +t/SOAP/WSDL/05_simpleType-restriction.t +t/SOAP/WSDL/05_simpleType-union.t +t/SOAP/WSDL/06_keep_alive.t +t/SOAP/WSDL/11_helloworld.NET.t +t/SOAP/WSDL/12_binding.t +t/SOAP/WSDL/Client.t +t/SOAP/WSDL/Client/Base.t +t/SOAP/WSDL/Deserializer/Hash.t +t/SOAP/WSDL/Deserializer/SOM.t +t/SOAP/WSDL/Deserializer/XSD.t +t/SOAP/WSDL/Expat/Base.t +t/SOAP/WSDL/Expat/MessageParser.t +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/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_unsupported.t +t/SOAP/WSDL/Part.t +t/SOAP/WSDL/Serializer/XSD.t +t/SOAP/WSDL/Server.t +t/SOAP/WSDL/Server/CGI.t +t/SOAP/WSDL/Transport/01_Test.t +t/SOAP/WSDL/Transport/02_HTTP.t +t/SOAP/WSDL/Transport/acceptance/test2.xml +t/SOAP/WSDL/Transport/acceptance/test3.xml +t/SOAP/WSDL/Typelib/Fault11.t +t/SOAP/WSDL/XSD/ComplexType.t +t/SOAP/WSDL/XSD/Element.t +t/SOAP/WSDL/XSD/SimpleType.t +t/SOAP/WSDL/XSD/Typelib/Attribute.t +t/SOAP/WSDL/XSD/Typelib/Builtin/01_constructors.t +t/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.t +t/SOAP/WSDL/XSD/Typelib/Builtin/anyType.t +t/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.t +t/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.t +t/SOAP/WSDL/XSD/Typelib/Builtin/boolean.t +t/SOAP/WSDL/XSD/Typelib/Builtin/byte.t +t/SOAP/WSDL/XSD/Typelib/Builtin/date.t +t/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.t +t/SOAP/WSDL/XSD/Typelib/Builtin/decimal.t +t/SOAP/WSDL/XSD/Typelib/Builtin/double.t +t/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.t +t/SOAP/WSDL/XSD/Typelib/Builtin/float.t +t/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.t +t/SOAP/WSDL/XSD/Typelib/Builtin/ID.t +t/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.t +t/SOAP/WSDL/XSD/Typelib/Builtin/IDREFS.t +t/SOAP/WSDL/XSD/Typelib/Builtin/int.t +t/SOAP/WSDL/XSD/Typelib/Builtin/integer.t +t/SOAP/WSDL/XSD/Typelib/Builtin/language.t +t/SOAP/WSDL/XSD/Typelib/Builtin/list.t +t/SOAP/WSDL/XSD/Typelib/Builtin/long.t +t/SOAP/WSDL/XSD/Typelib/Builtin/Name.t +t/SOAP/WSDL/XSD/Typelib/Builtin/NCName.t +t/SOAP/WSDL/XSD/Typelib/Builtin/negativeInteger.t +t/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.t +t/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.t +t/SOAP/WSDL/XSD/Typelib/Builtin/nonNegativeInteger.t +t/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.t +t/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.t +t/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.t +t/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.t +t/SOAP/WSDL/XSD/Typelib/Builtin/short.t +t/SOAP/WSDL/XSD/Typelib/Builtin/string.t +t/SOAP/WSDL/XSD/Typelib/Builtin/time.t +t/SOAP/WSDL/XSD/Typelib/Builtin/token.t +t/SOAP/WSDL/XSD/Typelib/Builtin/unsignedByte.t +t/SOAP/WSDL/XSD/Typelib/Builtin/unsignedInt.t +t/SOAP/WSDL/XSD/Typelib/Builtin/unsignedLong.t +t/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.t +t/SOAP/WSDL/XSD/Typelib/ComplexType.t +t/SOAP/WSDL/XSD/Typelib/Element.t +t/SOAP/WSDL_1.wsdl +t/SOAP/WSDL_EMPTY_DEFINITIONS.wsdl +t/SOAP/WSDL_NO_BINDING.wsdl +t/SOAP/WSDL_NO_MESSAGE.wsdl +t/SOAP/WSDL_NO_PORTTYPE.wsdl +t/test.wsdl +TEST_COVERAGE +TODO diff --git a/META.yml b/META.yml index c7dd95f..f06e077 100644 --- a/META.yml +++ b/META.yml @@ -1,19 +1,281 @@ --- name: SOAP-WSDL -version: 1.27 -author: [] -abstract: WSDL support for SOAP::Lite +version: 2.00_29 +author: + - 'Martin Kutter ' +abstract: SOAP with WSDL support license: artistic resources: license: http://opensource.org/licenses/artistic-license.php requires: - SOAP::Lite: 0 - XML::XPath: 0 + Class::Std::Fast: !!perl/hash:version + original: v0.0.5 + qv: 1 + version: + - 0 + - 0 + - 5 + Data::Dumper: 0 + Date::Format: 0 + Date::Parse: 0 + File::Basename: 0 + File::Path: 0 + Getopt::Long: 0 + LWP::UserAgent: 0 + List::Util: 0 + Template: 0 + Term::ReadKey: 0 + XML::Parser::Expat: 0 + perl: 5.8.0 provides: SOAP::WSDL: file: lib/SOAP/WSDL.pm - version: 1.27 + version: 2.00_25 + SOAP::WSDL::Base: + file: lib/SOAP/WSDL/Base.pm + version: 2.00_27 + SOAP::WSDL::Binding: + file: lib/SOAP/WSDL/Binding.pm + SOAP::WSDL::Client: + file: lib/SOAP/WSDL/Client.pm + version: 2.00_27 + SOAP::WSDL::Client::Base: + file: lib/SOAP/WSDL/Client/Base.pm + version: 2.00_25 + SOAP::WSDL::Definitions: + file: lib/SOAP/WSDL/Definitions.pm + version: 2.00_27 + SOAP::WSDL::Deserializer::Hash: + file: lib/SOAP/WSDL/Deserializer/Hash.pm + version: 2.00_25 + SOAP::WSDL::Deserializer::SOM: + file: lib/SOAP/WSDL/Deserializer/SOM.pm + version: 2.00_24 + SOAP::WSDL::Deserializer::XSD: + file: lib/SOAP/WSDL/Deserializer/XSD.pm + version: 2.00_25 + SOAP::WSDL::Expat::Base: + file: lib/SOAP/WSDL/Expat/Base.pm + version: 2.00_27 + SOAP::WSDL::Expat::Message2Hash: + file: lib/SOAP/WSDL/Expat/Message2Hash.pm + version: 2.00_27 + SOAP::WSDL::Expat::MessageParser: + file: lib/SOAP/WSDL/Expat/MessageParser.pm + version: 2.00_27 + SOAP::WSDL::Expat::MessageStreamParser: + file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm + version: 2.00_24 + SOAP::WSDL::Factory::Deserializer: + file: lib/SOAP/WSDL/Factory/Deserializer.pm + version: 2.00_24 + SOAP::WSDL::Factory::Generator: + file: lib/SOAP/WSDL/Factory/Generator.pm + version: 2.00_24 + SOAP::WSDL::Factory::Serializer: + file: lib/SOAP/WSDL/Factory/Serializer.pm + version: 2.00_24 + SOAP::WSDL::Factory::Transport: + file: lib/SOAP/WSDL/Factory/Transport.pm + version: 2.00_25 + SOAP::WSDL::Generator::Template: + file: lib/SOAP/WSDL/Generator/Template.pm + version: 2.00_25 + SOAP::WSDL::Generator::Template::XSD: + file: lib/SOAP/WSDL/Generator/Template/XSD.pm + version: 2.00_27 + SOAP::WSDL::Generator::Visitor: + file: lib/SOAP/WSDL/Generator/Visitor.pm + version: 2.00_25 + SOAP::WSDL::Generator::Visitor::Typelib: + file: lib/SOAP/WSDL/Generator/Visitor/Typelib.pm + SOAP::WSDL::Generator::Visitor::Typemap: + file: lib/SOAP/WSDL/Generator/Visitor/Typemap.pm + version: 2.00_25 + SOAP::WSDL::Message: + file: lib/SOAP/WSDL/Message.pm + SOAP::WSDL::OpMessage: + file: lib/SOAP/WSDL/OpMessage.pm + SOAP::WSDL::Operation: + file: lib/SOAP/WSDL/Operation.pm + SOAP::WSDL::Part: + file: lib/SOAP/WSDL/Part.pm + SOAP::WSDL::Port: + file: lib/SOAP/WSDL/Port.pm + SOAP::WSDL::PortType: + file: lib/SOAP/WSDL/PortType.pm + SOAP::WSDL::SOAP::Address: + file: lib/SOAP/WSDL/SOAP/Address.pm + SOAP::WSDL::SOAP::Body: + file: lib/SOAP/WSDL/SOAP/Body.pm + SOAP::WSDL::SOAP::Header: + file: lib/SOAP/WSDL/SOAP/Header.pm + SOAP::WSDL::SOAP::HeaderFault: + file: lib/SOAP/WSDL/SOAP/HeaderFault.pm + SOAP::WSDL::SOAP::Operation: + file: lib/SOAP/WSDL/SOAP/Operation.pm + version: 2.00_25 + SOAP::WSDL::SOAP::Typelib::Fault11: + file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm + version: 2.00_25 + SOAP::WSDL::Serializer::XSD: + file: lib/SOAP/WSDL/Serializer/XSD.pm + version: 2.00_27 + SOAP::WSDL::Server: + file: lib/SOAP/WSDL/Server.pm + version: 2.00_27 + SOAP::WSDL::Server::CGI: + file: lib/SOAP/WSDL/Server/CGI.pm + version: 2.00_27 + SOAP::WSDL::Service: + file: lib/SOAP/WSDL/Service.pm + SOAP::WSDL::Transport::HTTP: + file: lib/SOAP/WSDL/Transport/HTTP.pm + SOAP::WSDL::Transport::Loopback: + file: lib/SOAP/WSDL/Transport/Loopback.pm + version: 2.00_25 + SOAP::WSDL::Transport::Test: + file: lib/SOAP/WSDL/Transport/Test.pm + version: 2.00_25 + SOAP::WSDL::TypeLookup: + file: lib/SOAP/WSDL/TypeLookup.pm + version: 2.00_29 + SOAP::WSDL::Types: + file: lib/SOAP/WSDL/Types.pm + SOAP::WSDL::XSD::Attribute: + file: lib/SOAP/WSDL/XSD/Attribute.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_25 + SOAP::WSDL::XSD::Element: + file: lib/SOAP/WSDL/XSD/Element.pm + version: 2.00_25 + SOAP::WSDL::XSD::Schema: + file: lib/SOAP/WSDL/XSD/Schema.pm + version: 2.00_25 + 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::Typelib::Attribute: + file: lib/SOAP/WSDL/XSD/Typelib/Attribute.pm + SOAP::WSDL::XSD::Typelib::AttributeSet: + file: lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm + SOAP::WSDL::XSD::Typelib::Builtin: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm + version: 2.00_25 + SOAP::WSDL::XSD::Typelib::Builtin::ENTITY: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm + SOAP::WSDL::XSD::Typelib::Builtin::ID: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ID.pm + SOAP::WSDL::XSD::Typelib::Builtin::IDREF: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREF.pm + SOAP::WSDL::XSD::Typelib::Builtin::IDREFS: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/IDREFS.pm + SOAP::WSDL::XSD::Typelib::Builtin::NCName: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NCName.pm + SOAP::WSDL::XSD::Typelib::Builtin::NMTOKEN: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKEN.pm + SOAP::WSDL::XSD::Typelib::Builtin::NMTOKENS: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NMTOKENS.pm + SOAP::WSDL::XSD::Typelib::Builtin::NOTATION: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/NOTATION.pm + SOAP::WSDL::XSD::Typelib::Builtin::Name: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/Name.pm + SOAP::WSDL::XSD::Typelib::Builtin::QName: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/QName.pm + SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm + SOAP::WSDL::XSD::Typelib::Builtin::anyType: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm + version: 2.00_29 + SOAP::WSDL::XSD::Typelib::Builtin::anyURI: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm + SOAP::WSDL::XSD::Typelib::Builtin::base64Binary: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm + SOAP::WSDL::XSD::Typelib::Builtin::boolean: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm + version: 2.00_23 + SOAP::WSDL::XSD::Typelib::Builtin::byte: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm + SOAP::WSDL::XSD::Typelib::Builtin::date: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/date.pm + SOAP::WSDL::XSD::Typelib::Builtin::dateTime: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/dateTime.pm + SOAP::WSDL::XSD::Typelib::Builtin::decimal: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/decimal.pm + SOAP::WSDL::XSD::Typelib::Builtin::double: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/double.pm + SOAP::WSDL::XSD::Typelib::Builtin::duration: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/duration.pm + SOAP::WSDL::XSD::Typelib::Builtin::float: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/float.pm + SOAP::WSDL::XSD::Typelib::Builtin::gDay: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gDay.pm + SOAP::WSDL::XSD::Typelib::Builtin::gMonth: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonth.pm + SOAP::WSDL::XSD::Typelib::Builtin::gMonthDay: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gMonthDay.pm + SOAP::WSDL::XSD::Typelib::Builtin::gYear: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gYear.pm + SOAP::WSDL::XSD::Typelib::Builtin::gYearMonth: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/gYearMonth.pm + SOAP::WSDL::XSD::Typelib::Builtin::hexBinary: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/hexBinary.pm + SOAP::WSDL::XSD::Typelib::Builtin::int: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/int.pm + SOAP::WSDL::XSD::Typelib::Builtin::integer: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/integer.pm + SOAP::WSDL::XSD::Typelib::Builtin::language: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/language.pm + SOAP::WSDL::XSD::Typelib::Builtin::list: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/list.pm + SOAP::WSDL::XSD::Typelib::Builtin::long: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/long.pm + SOAP::WSDL::XSD::Typelib::Builtin::negativeInteger: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/negativeInteger.pm + SOAP::WSDL::XSD::Typelib::Builtin::nonNegativeInteger: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/nonNegativeInteger.pm + SOAP::WSDL::XSD::Typelib::Builtin::nonPositiveInteger: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/nonPositiveInteger.pm + SOAP::WSDL::XSD::Typelib::Builtin::normalizedString: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/normalizedString.pm + SOAP::WSDL::XSD::Typelib::Builtin::positiveInteger: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/positiveInteger.pm + SOAP::WSDL::XSD::Typelib::Builtin::short: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/short.pm + SOAP::WSDL::XSD::Typelib::Builtin::string: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm + SOAP::WSDL::XSD::Typelib::Builtin::time: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm + version: 2.00_25 + SOAP::WSDL::XSD::Typelib::Builtin::token: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm + SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedByte.pm + SOAP::WSDL::XSD::Typelib::Builtin::unsignedInt: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedInt.pm + SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong: + file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedLong.pm + SOAP::WSDL::XSD::Typelib::Builtin::unsignedShort: + 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_29 + SOAP::WSDL::XSD::Typelib::Element: + file: lib/SOAP/WSDL/XSD/Typelib/Element.pm + version: 2.00_29 + SOAP::WSDL::XSD::Typelib::SimpleType: + file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm + SOAP::WSDL::XSD::Typelib::SimpleType::restriction: + file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm generated_by: Module::Build version 0.2808 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.2.html version: 1.2 +no_index: + directory: lib/SOAP/WSDL/Generator/Template/XSD/ diff --git a/MIGRATING b/MIGRATING new file mode 100644 index 0000000..5b0095c --- /dev/null +++ b/MIGRATING @@ -0,0 +1,50 @@ +MIGRATING +--------- + +This document describes how to migrate from 2.00_24 and before versions to +2.00_25. + +Migrating from 2.00_xx +---------------------- + +Background + +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 +no need to change anything in your (handwritten) code. + +Generated interfaces + +SOAP::WSDL's internal structure has changed, and this change needs to +be reflected in all generated classes. + +This means you have to re-generate your interfaces (in case you use generated +interfaces) + +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 +will try to load all correspondent classes. + +Migrating from 1.xx +------------------- + +Background + +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. +SOAP::WSDL is the compatibility module for old interfaces. + +Overloading + +Message overloading (as introduced in 1.23) is not supported any more. + +Message overloading is prohibited by the WS-I basic profile, therefore +SOAP::WSDL does not implement it any more. \ No newline at end of file diff --git a/README b/README index 62407bf..d7e76c8 100644 --- a/README +++ b/README @@ -1,31 +1,26 @@ -SOAP::WSDL - a WSDL-driven message preprocessor for SOAP::Lite. - -DESCRIPTION - -See "perldoc SOAP::WSDL" (or "perldoc WSDL.pm") for details. - - -PREREQUISITES - -SOAP::WSDL requires the following perl modules: - -- SOAP::Lite -- XML::XPath - - -If you want to use file system caching (improves performance), you also -need the following packages: - -- Cache::Cache - -INSTALLING - -perl Build.PL -perl Build -perl Build test -perl Build install - -LICENSE - -This library is free software, you can distribute/modify it under the same -terms as perl itself. +INTRO +----- + +SOAP-WSDL provides a SOAP client with WSDL support. + +This is a developer release - everything may (and most things will) change. + +INSTALLING +---------- + +Use the following mantra: + + perl Build.PL + perl Build + perl Build test + perl Build install + +If you don't have Module::Build installed, you may also use + + perl Makefile.PL + make + make test + make install + +Note that Module::Build is the recommended installer - make will not run +all tests provided with SOAP-WSDL. \ No newline at end of file diff --git a/TEST_COVERAGE b/TEST_COVERAGE new file mode 100644 index 0000000..4e6bf73 --- /dev/null +++ b/TEST_COVERAGE @@ -0,0 +1,11 @@ +# Unfortunately, Build testcover reports test coverage wrong. +# +# To get a complete coverage report, just run this file as a shell script +# on a linux box (or execute the equivalent commands on another OS): + +cd t/ + +find . -type f -name '*.t' | xargs -n 1 /usr/bin/perl -MDevel::Cover=-silent,1,-summary,0 -I../lib + +cover -ignore_re \.t$ -ignore_re ^lib -coverage="statement" -coverage=condition -coverage=subroutine -coverage="branch" + diff --git a/TODO b/TODO new file mode 100644 index 0000000..2b94376 --- /dev/null +++ b/TODO @@ -0,0 +1,24 @@ +TODO list for SOAP::WSDL + +2.00 Pre-releases +-------- + +* Act as SOAP Server [ 1842436 ] + +2.1 release +-------- +* Support namespaces in SOAP message payload [ 1809057 ] + +* Support the xsi:type attribute on derived types on the wire [ 1809059 ] + +* SOAP1.2 support [ 1803331 ] + +2.2 release +-------- +* XML schema support ("minimal conformant") [ 1764845 ] + +* Support SOAP attachments + +3.0 release +-------- +We're not thinking that far ahead right now. diff --git a/benchmark/01_expat.t b/benchmark/01_expat.t new file mode 100644 index 0000000..5b833de --- /dev/null +++ b/benchmark/01_expat.t @@ -0,0 +1,130 @@ +#!/usr/bin/perl -w +%DB::packages=(SOAP::WSDL::Expat::MessageParser => 1); +use strict; +use warnings; +use lib '../lib'; +use lib '../../Class-Std-Fast/lib'; +use lib '../t/lib'; +# use SOAP::WSDL::SAX::MessageHandler; + +use Benchmark qw(cmpthese timethese); +use SOAP::WSDL::Expat::MessageParser; +use SOAP::WSDL::Expat::Message2Hash; +use SOAP::Lite; +use XML::Simple; +use XML::LibXML; +use MyComplexType; +use MyElement; +use MySimpleType; + +my $xml = q{ + + + + Test2 + Test2 + Test2 + Test2 + Test2 + Test2 + Test2 + Test2 + Test2 + Test2 + Test2 + Test2 + Test55 + + +}; + + + +my $parser = SOAP::WSDL::Expat::MessageParser->new({ + class_resolver => 'FakeResolver' +}); + +my $hash_parser = SOAP::WSDL::Expat::Message2Hash->new(); + +$XML::Simple::PREFERRED_PARSER = 'XML::Parser'; + +print "xml length: ${ \length $xml } bytes\n"; + +my $libxml = XML::LibXML->new(); +$libxml->keep_blanks(0); +my @data; + +my $deserializer = SOAP::Deserializer->new(); + +sub libxml_test { + my $dom = $libxml->parse_string( $xml ); + push @data, dom2hash( $dom->firstChild ); +}; + +sub dom2hash { + for ($_[0]->childNodes) { + if (exists $_[1]->{ $_->nodeName }) { + if (ref $_[1]->{ $_->nodeName } eq 'ARRAY') { + if ($_->nodeName eq '#text') { + push @{ $_[1] } ,$_->textContent; + } + else { + push @{ $_[1]->{ $_->nodeName } }, dom2hash( $_, {} ); + } + } + else { + if ($_->nodeName eq '#text') { + $_[1] = [ $_[1], $_->textContent() ]; + } + else { + $_[1]->{ $_->nodeName } = [ $_[1]->{ $_->nodeName } , + dom2hash( $_, {} ) ]; + } + } + } + else { + if ($_->nodeName eq '#text') { + $_[1] = $_->textContent(); + } + else { + $_[1]->{ $_->nodeName } = dom2hash( $_, {} ); + } + } + } + return $_[1]; +} + +cmpthese 5000, +{ + 'SOAP::WSDL (Hash)' => sub { push @data, $hash_parser->parse( $xml ) }, + 'SOAP::WSDL (XSD)' => sub { push @data, $parser->parse( $xml ) }, + 'XML::Simple (Hash)' => sub { push @data, XMLin $xml }, + 'XML::LibXML (DOM)' => sub { push @data, $libxml->parse_string( $xml ) }, + 'XML::LibXML (Hash)' => \&libxml_test, + 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( $xml ) }, +}; + +# data classes reside in t/lib/Typelib/ +BEGIN { + package FakeResolver; + { + my %class_list = ( + 'MyAtomicComplexTypeElement' => 'MyAtomicComplexTypeElement', + 'MyAtomicComplexTypeElement/test' => 'MyAtomicComplexTypeElement', + 'MyAtomicComplexTypeElement/test/test2' => 'MyTestElement2', + ); + + sub get_typemap { return \%class_list; }; + + sub get_map { return \%class_list }; + + sub new { return bless {}, 'FakeResolver' }; + + sub get_class { + my $name = join('/', @{ $_[1] }); + return ($class_list{ $name }) ? $class_list{ $name } + : warn "no class found for $name"; + }; + }; +}; diff --git a/benchmark/XSD/01_anyType.t b/benchmark/XSD/01_anyType.t new file mode 100644 index 0000000..a30ea14 --- /dev/null +++ b/benchmark/XSD/01_anyType.t @@ -0,0 +1,12 @@ +use strict; +use warnings; +use Benchmark; +use lib '../../lib'; +use SOAP::WSDL::XSD::Typelib::Builtin::anyType; + +my $obj = SOAP::WSDL::XSD::Typelib::Builtin::anyType->new(); + +timethese 10000, { + 'new' => sub { SOAP::WSDL::XSD::Typelib::Builtin::anyType->new() }, +}; + diff --git a/benchmark/XSD/02_anySimpleType.t b/benchmark/XSD/02_anySimpleType.t new file mode 100644 index 0000000..011b708 --- /dev/null +++ b/benchmark/XSD/02_anySimpleType.t @@ -0,0 +1,57 @@ +use strict; +use warnings; +use Benchmark; +use lib '../../lib'; +use lib '../../../Class-Std-Fast/lib'; + +use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; + +my $obj = SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new(); + +timethese 10000, { + 'new' => sub { SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new() }, + 'new + params' => sub { SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new({ + value => 'Teststring' + }) }, + 'set_FOO' => sub { $obj->set_value('Test') }, +}; + +my $data; +timethese 1000000, { + 'set_FOO' => sub { $obj->set_value('Test') }, + 'get_FOO' => sub { $data = $obj->get_value() }, +}; + +__END__ + +Benchmark: timing 10000 iterations of new, new + params, set_FOO... + new: 0 wallclock secs ( 0.83 usr + 0.00 sys = 0.83 CPU) @ 12048.19/s (n=10000) +new + params: 1 wallclock secs ( 0.58 usr + 0.00 sys = 0.58 CPU) @ 17241.38/s (n=10000) + set_FOO: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 1000000.00/s (n=10000) + (warning: too few iterations for a reliable count) +Benchmark: timing 1000000 iterations of get_FOO, set_FOO... + get_FOO: 1 wallclock secs ( 1.79 usr + 0.01 sys = 1.80 CPU) @ 555555.56/s (n=1000000) + set_FOO: 2 wallclock secs ( 1.44 usr + 0.03 sys = 1.47 CPU) @ 680272.11/s (n=1000000) + +## Fast: +Benchmark: timing 10000 iterations of new, new + params, set_FOO... + new: 1 wallclock secs ( 0.67 usr + 0.01 sys = 0.68 CPU) @ 14705.88/s (n=10000) +new + params: 1 wallclock secs ( 0.54 usr + 0.00 sys = 0.54 CPU) @ 18518.52/s (n=10000) + set_FOO: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 1000000.00/s (n=10000) + (warning: too few iterations for a reliable count) +Benchmark: timing 1000000 iterations of get_FOO, set_FOO... + get_FOO: 2 wallclock secs ( 1.11 usr + 0.00 sys = 1.11 CPU) @ 900900.90/s (n=1000000) + set_FOO: 2 wallclock secs ( 0.80 usr + 0.00 sys = 0.80 CPU) @ 1250000.00/s (n=1000000) + +## Fast qw(2); +Benchmark: timing 10000 iterations of new, new + params, set_FOO... + new: 1 wallclock secs ( 0.17 usr + 0.00 sys = 0.17 CPU) @ 58823.53/s (n=10000) + (warning: too few iterations for a reliable count) +new + params: 0 wallclock secs ( 0.19 usr + 0.00 sys = 0.19 CPU) @ 52631.58/s (n=10000) + (warning: too few iterations for a reliable count) + set_FOO: 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) @ 1000000.00/s (n=10000) + (warning: too few iterations for a reliable count) +Benchmark: timing 1000000 iterations of get_FOO, set_FOO... + get_FOO: 1 wallclock secs ( 1.12 usr + 0.00 sys = 1.12 CPU) @ 892857.14/s (n=1000000) + set_FOO: 0 wallclock secs ( 0.80 usr + 0.01 sys = 0.81 CPU) @ 1234567.90/s (n=1000000) + diff --git a/benchmark/XSD/03_string.t b/benchmark/XSD/03_string.t new file mode 100644 index 0000000..6f85b7b --- /dev/null +++ b/benchmark/XSD/03_string.t @@ -0,0 +1,56 @@ +use strict; +use warnings; +use Benchmark; +use lib '../../lib'; +use lib '../../../Class-Std-Fast/lib'; + +use SOAP::WSDL::XSD::Typelib::Builtin::string; + +my $obj = SOAP::WSDL::XSD::Typelib::Builtin::string->new(); + +timethese 20000, { + 'new' => sub { SOAP::WSDL::XSD::Typelib::Builtin::string->new() }, + 'new + params' => sub { SOAP::WSDL::XSD::Typelib::Builtin::string->new({ + value => 'Teststring' + }) }, +}; + +$obj->set_value('Foobar'); +timethese 20000, { + serialize => sub { $obj->serialize() } +}; + +my $data; +timethese 1000000, { + 'set_FOO' => sub { $obj->set_value('Test') }, + 'get_FOO' => sub { $data = $obj->get_value() }, +}; + + + +__END__ + +Benchmark: timing 20000 iterations of new, new + params... + new: 1 wallclock secs ( 0.41 usr + 0.00 sys = 0.41 CPU) @ 48780.49/s (n=20000) +new + params: 1 wallclock secs ( 0.53 usr + 0.01 sys = 0.54 CPU) @ 37037.04/s (n=20000) +Benchmark: timing 1000000 iterations of get_FOO, set_FOO... + get_FOO: 2 wallclock secs ( 1.43 usr + 0.01 sys = 1.44 CPU) @ 694444.44/s (n=1000000) + set_FOO: 0 wallclock secs ( 1.43 usr + 0.01 sys = 1.44 CPU) @ 694444.44/s (n=1000000) + + +::Fast +--- +Benchmark: timing 20000 iterations of new, new + params... + new: 0 wallclock secs ( 0.44 usr + 0.01 sys = 0.45 CPU) @ 44444.44/s (n=20000) +new + params: 1 wallclock secs ( 0.55 usr + 0.00 sys = 0.55 CPU) @ 36363.64/s (n=20000) +Benchmark: timing 1000000 iterations of get_FOO, set_FOO... + get_FOO: 0 wallclock secs ( 0.81 usr + 0.00 sys = 0.81 CPU) @ 1234567.90/s (n=1000000) + set_FOO: 2 wallclock secs ( 0.87 usr + 0.01 sys = 0.88 CPU) @ 1136363.64/s (n=1000000) + +::Fast with inlined ID +Benchmark: timing 20000 iterations of new, new + params... + new: 0 wallclock secs ( 0.41 usr + 0.00 sys = 0.41 CPU) @ 48780.49/s (n=20000) +new + params: 1 wallclock secs ( 0.52 usr + 0.00 sys = 0.52 CPU) @ 38461.54/s (n=20000) +Benchmark: timing 1000000 iterations of get_FOO, set_FOO... + get_FOO: 2 wallclock secs ( 0.80 usr + 0.00 sys = 0.80 CPU) @ 1250000.00/s (n=1000000) + set_FOO: 2 wallclock secs ( 0.89 usr + -0.01 sys = 0.88 CPU) @ 1136363.64/s (n=1000000) \ No newline at end of file diff --git a/benchmark/hello.pl b/benchmark/hello.pl new file mode 100644 index 0000000..328a904 --- /dev/null +++ b/benchmark/hello.pl @@ -0,0 +1,69 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +use lib '../example/lib'; +use lib '/home/martin/workspace/SOAP-WSDL-Fast_XS/blib/lib'; +use lib '/home/martin/workspace/SOAP-WSDL-Fast_XS/blib/arch'; +use SOAP::Lite; +use XML::Compile::WSDL11; +use XML::Compile::Transport::SOAPHTTP; +use MyInterfaces::HelloWorld::HelloWorldSoap; +use SOAP::WSDL::Deserializer::XSD_XS; +use Benchmark qw(cmpthese); + +my $lite = SOAP::Lite->new( + proxy => 'http://localhost:81/soap-wsdl-test/helloworld.pl' +); + +$lite->on_action( sub { "urn:HelloWorld#sayHello" }); +$lite->autotype(0); + +my $soap = MyInterfaces::HelloWorld::HelloWorldSoap->new(); + +my $soap_xs = MyInterfaces::HelloWorld::HelloWorldSoap->new(); +$soap_xs->set_deserializer( SOAP::WSDL::Deserializer::XSD_XS->new() ); + +my @result; + +sub wsdl_bench { + push @result, $soap->sayHello({ + name => $ARGV[1] || '"Your name"', + givenName => $ARGV[0] || '"Your given name"', + }); +} + +sub wsdl_xs_bench { + push @result, $soap_xs->sayHello({ + name => $ARGV[1] || '"Your name"', + givenName => $ARGV[0] || '"Your given name"', + }); +} + +my $wsdl = XML::Compile::WSDL11->new('../example/wsdl/11_helloworld.wsdl'); +my $call = $wsdl->compileClient('sayHello'); + +sub compile_bench { + push @result, $call->( + name => $ARGV[1] || '"Your name"', + givenName => $ARGV[0] || '"Your given name"', + ); +} + +sub lite_bench { + push @result, $lite->call( + SOAP::Data->name("sayHello") + ->attr({ xmlns => 'urn:HelloWorld' }), + SOAP::Data->name('name')->value( $ARGV[1] || '"Your name"'), + SOAP::Data->name('givenName')->value( $ARGV[0] || '"Your given name"'), + ); +} + +wsdl_bench(); +wsdl_xs_bench(); + +cmpthese 150, { + 'SOAP::WSDL' => \&wsdl_bench, + 'SOAP::WSDL_XS' => \&wsdl_xs_bench, + 'XML::Compile' => \&compile_bench, + # 'SOAP::Lite' => \&lite_bench, +} diff --git a/benchmark/person.pl b/benchmark/person.pl new file mode 100644 index 0000000..1e085b0 --- /dev/null +++ b/benchmark/person.pl @@ -0,0 +1,86 @@ +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 qw(cmpthese); + +use XML::Compile::Transport::SOAPHTTP(); +use XML::Compile::Util; +use XML::Compile::WSDL11; +use XML::Simple; + +use SOAP::WSDL::Deserializer::XSD_XS; +use SOAP::WSDL::Factory::Deserializer; + +$XML::Simple::PREFERRED_PARSER = 'XML::Parser'; +use SOAP::Lite; + +use MyInterfaces::TestService::TestPort; + +my $compile = XML::Compile::WSDL11->new('../example/wsdl/Person.wsdl'); +my $call = $compile->compileClient('ListPerson'); +$call->({ in => undef}); + +# Initialize SOAP::Lite +my $deserializer = SOAP::Deserializer->new(); + +# Initialize SOAP::WSDL interface +my $soap = MyInterfaces::TestService::TestPort->new(); +# Load all classes - XML::Compile has created everything before, too +$soap->ListPerson({}); + +my $lite = SOAP::Lite->new()->default_ns('http://www.example.org/benchmark/') + ->proxy('http://localhost:81/soap-wsdl-test/person.pl'); +$lite->on_action( sub { 'http://www.example.org/benchmark/ListPerson' } ); + +# # register for SOAP 1.1 +SOAP::WSDL::Factory::Deserializer->register('1.1' => 'SOAP::WSDL::Deserializer::XSD_XS' ); +my $wsdl_xs = MyInterfaces::TestService::TestPort->new(); + +# trigger loading of XML Data +my $count = 100; +my @data = (); +my $n = 0; +print "Benchmark conducted with +SOAP::Lite - $SOAP::Lite::VERSION +SOAP::WSDL - $SOAP::WSDL::Client::VERSION +SOAP::WSDL_XS - $SOAP::WSDL::Deserializer::XSD_XS::VERSION; +XML::Compile::SOAP - $XML::Compile::SOAP::VERSION + +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_XS' => sub { my $result = $wsdl_xs->ListPerson({}) }, +# 'SOAP::Lite' => sub { my $result = $deserializer->deserialize( MyData::xml() )}, + '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_XS' => sub { push @data, $wsdl_xs->ListPerson({}) }, +# 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )} + 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') }, +}; + +@data = (); +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_XS' => sub { push @data, $wsdl_xs->ListPerson({}) }, + 'XML::Compile' => sub { push @data, $call->() }, +# 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )} + 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') }, +}; + diff --git a/benchmark/person.xml b/benchmark/person.xml new file mode 100644 index 0000000..9a66877 --- /dev/null +++ b/benchmark/person.xml @@ -0,0 +1,437 @@ + + + + + + 1 + + Salutation0 + Name0 + Martin + 1970-01-01 + + Street 0 + 00000 + City0 + Country0 + ++499131123456 + ++49150123456 + + + Somestreet 23 + 12345 + SomeCity + Germany + ++499131123456 + ++49150123456 + + + + 100000 + SomeContract0 + + + 100001 + SomeContract1 + + + 100002 + SomeContract2 + + + 100003 + SomeContract3 + + + + + + 2 + + Salutation2 + Name2 + Martin2 + 1970-01-02 + + Street 2 + 00002 + City2 + Country2 + ++4900000002 + ++491700000002 + + + Somestreet 2 + 222222 + SomeCity2 + Germany + ++4920000002 + ++4920000002 + + + + 100002 + SomeContract2 + + + 100021 + SomeContract21 + + + 100022 + SomeContract22 + + + 1000023 + SomeContract23 + + + + + + 3 + + Salutation3 + Name3 + Martin3 + 1970-01-03 + + Street 3 + 00003 + City3 + Country3 + ++4900000003 + ++491700000003 + + + Somestreet 3 + 333333 + SomeCity3 + Germany + ++4930000003 + ++4930000003 + + + + 100003 + SomeContract3 + + + 100031 + SomeContract31 + + + 100033 + SomeContract33 + + + 1000033 + SomeContract33 + + + + + + 4 + + Salutation4 + Name4 + Martin4 + 1970-01-04 + + Street 4 + 00004 + City4 + Country4 + ++4900000004 + ++491700000004 + + + Somestreet 4 + 444444 + SomeCity4 + Germany + ++4940000004 + ++4940000004 + + + + 100004 + SomeContract4 + + + 100041 + SomeContract41 + + + 100044 + SomeContract44 + + + 1000044 + SomeContract44 + + + + + + 5 + + Salutation5 + Name5 + Martin5 + 1970-01-05 + + Street 5 + 00005 + City5 + Country5 + ++4900000005 + ++491700000005 + + + Somestreet 5 + 555555 + SomeCity5 + Germany + ++4950000005 + ++4950000005 + + + + 100005 + SomeContract5 + + + 100051 + SomeContract51 + + + 100055 + SomeContract55 + + + 1000053 + SomeContract53 + + + + + + 6 + + Salutation6 + Name6 + Martin6 + 1970-01-06 + + Street 6 + 00006 + City6 + Country6 + ++4900000006 + ++491700000006 + + + Somestreet 6 + 666666 + SomeCity6 + Germany + ++4960000006 + ++4960000006 + + + + 100006 + SomeContract6 + + + 100061 + SomeContract61 + + + 100066 + SomeContract66 + + + 1000063 + SomeContract63 + + + + + + 7 + + Salutation7 + Name7 + Martin7 + 1970-01-07 + + Street 7 + 00007 + City7 + Country7 + ++4900000007 + ++491700000007 + + + Somestreet 7 + 777777 + SomeCity7 + Germany + ++4970000007 + ++4970000007 + + + + 100007 + SomeContract7 + + + 100071 + SomeContract71 + + + 100077 + SomeContract77 + + + 1000073 + SomeContract73 + + + + + + 8 + + Salutation8 + Name8 + Martin8 + 1970-01-08 + + Street 8 + 00008 + City8 + Country8 + ++4900000008 + ++491700000008 + + + Somestreet 8 + 888888 + SomeCity8 + Germany + ++4980000008 + ++4980000008 + + + + 100008 + SomeContract8 + + + 100081 + SomeContract81 + + + 100088 + SomeContract88 + + + 1000083 + SomeContract83 + + + + + + 9 + + Salutation9 + Name9 + Martin9 + 1970-01-09 + + Street 9 + 00009 + City9 + Country9 + ++4900000009 + ++491700000009 + + + Somestreet 9 + 999999 + SomeCity9 + Germany + ++4990000009 + ++4990000009 + + + + 100009 + SomeContract9 + + + 100091 + SomeContract91 + + + 100099 + SomeContract99 + + + 1000093 + SomeContract93 + + + + + + 10 + + Salutation10 + Name10 + Martin10 + 1970-01-010 + + Street 10 + 000010 + City10 + Country10 + ++49000000010 + ++4917000000010 + + + Somestreet 10 + 101010101010 + SomeCity10 + Germany + ++491000000010 + ++491000000010 + + + + 1000010 + SomeContract10 + + + 1000101 + SomeContract101 + + + 10001010 + SomeContract1010 + + + 10000103 + SomeContract103 + + + + + + + diff --git a/bin/wsdl2perl.pl b/bin/wsdl2perl.pl new file mode 100644 index 0000000..a642a06 --- /dev/null +++ b/bin/wsdl2perl.pl @@ -0,0 +1,239 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +use Pod::Usage; +use Getopt::Long; +use LWP::UserAgent; +use SOAP::WSDL::Expat::WSDLParser; +use SOAP::WSDL::Factory::Generator; +use Term::ReadKey; + +my %opt = ( + url => '', + prefix => undef, + type_prefix => 'MyTypes', + element_prefix => 'MyElements', + typemap_prefix => 'MyTypemaps', + interface_prefix => 'MyInterfaces', + base_path => 'lib/', + proxy => undef, + generator => 'XSD', + server => 0, +); + +{ # a block just to scope "no warnings" + no warnings qw(redefine); + + *LWP::UserAgent::get_basic_credentials = sub { + my ($user, $password); + # remove user from option if called, to force prompting for a user + # name the next time + print "URL requires authorization.\n"; + if (not $user = delete $opt{user}) { + print 'User name:'; + ReadMode 1; + $user = ReadLine(); + ReadMode 0; + }; + if (not $password = delete $opt{password}) { + print 'Password:'; + ReadMode 2; + $user = ReadLine; + ReadMode 0; + }; + return ($user, $password); + }; +} + +GetOptions(\%opt, + qw( + prefix|p=s + type_prefix|t=s + element_prefix|e=s + typemap_prefix|m=s + interface_prefix|i=s + base_path|b=s + typemap_include|mi=s + help|h + proxy|x=s + keep_alive + user=s + password=s + generator=s + server + ) +); + +my $url = $ARGV[0]; + +pod2usage( -exit => 1 , verbose => 2 ) if ($opt{help}); +pod2usage( -exit => 1 , verbose => 1 ) if not ($url); + +my $parser = SOAP::WSDL::Expat::WSDLParser->new(); + +local $ENV{HTTP_PROXY} = $opt{proxy} if $opt{proxy}; +local $ENV{HTTPS_PROXY} = $opt{proxy} if $opt{proxy}; + +my $lwp = LWP::UserAgent->new( + $opt{keep_alive} + ? ( keep_alive => 1 ) + : () + ); +$lwp->env_proxy(); # get proxy from environment. Works for both http & https. + +my $response = $lwp->get($url); +die $response->message(), "\n" if $response->code != 200; + +my $xml = $response->content(); + +my $definitions = $parser->parse_string( $xml ); + +my %typemap = (); + +if ($opt{typemap_include}) { + die "$opt{typemap_include} not found " if not -f $opt{typemap_include}; + %typemap = do $opt{typemap_include}; +} + +my $generator = SOAP::WSDL::Factory::Generator->get_generator({ type => $opt{'generator'} }); + +if (%typemap) { + if ($generator->can('set_typemap')) { + $generator->set_typemap( \%typemap ); + } + else { + warn "Typemap snippet given, but generator does not support it\n"; + } +}; + +$generator->set_type_prefix( $opt{ type_prefix }) if $generator->can('set_type_prefix'); +$generator->set_typemap_prefix( $opt{ typemap_prefix }) if $generator->can('set_typemap_prefix'); +$generator->set_element_prefix($opt{ element_prefix }) if $generator->can('set_element_prefix'); +$generator->set_interface_prefix($opt{ interface_prefix }) if $generator->can('set_interface_prefix'); +$generator->set_OUTPUT_PATH($opt{ base_path }) if $generator->can('set_OUTPUT_PATH'); +$generator->set_definitions($definitions) if $generator->can('set_definitions'); +$generator->set_wsdl($xml) if $generator->can('set_wsdl'); + +# start with typelib, as errors will most likely occur here... +$generator->generate(); +$generator->generate_interface() if ! $opt{server}; +$generator->generate_server() if $opt{server}; +__END__ + +=pod + +=head1 NAME + +wsdl2perl.pl - create perl bindings for SOAP webservices. + +=head1 SYNOPSIS + + wsdl2perl.pl -t TYPE_PREFIX -e ELEMENT_PREFIX -m TYPEMAP_PREFIX \ + -i INTERFACE_PREFIX -b BASE_DIR URL + +=head1 OPTIONS + + NAME SHORT DESCRITPION + ---------------------------------------------------------------------------- + prefix p Prefix for both type and element classes. + type_prefix t Prefix for type classes. + Default: MyTypes + element_prefix e Prefix for element classes. + Default: MyElements + typemap_prefix m Prefix for typemap classes. + Default: MyTypemaps + interface_prefix i Prefix for interface classes. + Default: MyInterfaces + base_path b Path to create classes in. + Default: . + typemap_include mi File to include in typemap. Must eval() to a valid + perl hash (not a hash ref !). + proxy x HTTP(S) proxy to use (if any). wsdl2perl will also + use the proxy settings specified via the HTTP_PROXY + and HTTPS_PROXY environment variables. + keep_alive Use http keep_alive. + user Username for HTTP authentication + password Password. wsdl2perl will prompt if not given. + generator g Generator to use. + Default: XSD + server s Generate a server interface (currently only CGI + supported) + help h Show help content + +=head1 DESCRIPTION + +Generates a interface class for a SOAP web service described by a WSDL +definition. + +The following classes are created: + +=over + +=item * A interface class for every SOAP port in service + +Interface classes are what you will mainly deal with: They provide a method +for accessing every web service method. + +If you chose to generate Server interfaces, a class for every SOAP port in +every Web service. + +You'll have to implement a method for each of the implemented methods. You +may implement these methods in the CGI script / handler, or in any class +to dispatch calls to. + +=item * A typemap for every service + +Typemaps are used internally by SOAP::WSDL for parsing the SOAP message into +object trees. + +If the WSDL definition is incomplete, you may need to add some lines to +your typemap. Especially definitions for faults are sometimes left out. + +Additional typemap content may be included by passing a file name as +typemap_include (mi) option. + +=item * A type class for every element, complexType or simpleType definition + +You may need to write additional type classes if your WSDL is incomplete. + +For writing your own lib classes, see L, +L +and L. + +=back + +=head1 TROUBLESHOOTING + +=head2 Accessing HTTPS URLs + +You need Crypt::SSLeay installed for accessing HTTPS URLs. + +=head2 Accessing protected documents + +Use the -u option for specifying the user name. You will be prompted for a +password. + +Alternatively, you may specify a passowrd with --password on the command +line. + +=head2 Accessing documents protected by NTLM authentication + +Set the --keep_alive option. + +Note that accessing documents protected by NTLM authentication is currently +untested, because I have no access to a system using NTLM authentication. +If you try it, I would be glad if you could just drop me a note about +success or failure. + +=head1 LICENSE + +Copyright 2007 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 + +=cut diff --git a/example/cgi-bin/helloworld.pl b/example/cgi-bin/helloworld.pl new file mode 100755 index 0000000..50323f5 --- /dev/null +++ b/example/cgi-bin/helloworld.pl @@ -0,0 +1,56 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +use lib '../../lib'; +use lib '../lib'; +use MyServer::HelloWorld::HelloWorldSoap; + +my $soap = MyServer::HelloWorld::HelloWorldSoap->new({ + dispatch_to => 'main', +}); + +$soap->handle(); + +sub sayHello { + my ($self, $body, $header) = @_; + my $name = $body->get_name(); + my $givenName = $body->get_givenName(); + + return MyElements::sayHelloResponse->new({ + sayHelloResult => "Hello $givenName $name" + }) +} + +=pod + +=head1 NAME + +helloworld.pl - a simple CGI-based SOAP server implementing the service from +in examples/wsdl/helloworld.wsdl + +=head1 USAGE + +Before using this script, you should secure your webserver. The easiest way +to do so is to let it listen to 127.0.0.1 only. + +Then make a ScriptAlias named /soap-wsdl-test/ pointing at the directory +this file lies in. + +For my apache, it looks like this: + + ScriptAlias /soap-wsdl-test/ /home/martin/workspace/SOAP-WSDL/example/cgi-bin/ + + AllowOverride None + Options +ExecCGI -MultiViews + Order allow,deny + Allow from all + + +Then run the helloworld.pl from the examples directory. It should print + + Hello World + +=head1 DESCRIPTION + +=cut + diff --git a/example/cgi-bin/person.pl b/example/cgi-bin/person.pl new file mode 100755 index 0000000..6ef8588 --- /dev/null +++ b/example/cgi-bin/person.pl @@ -0,0 +1,84 @@ +#!/usr/bin/perl -w +package main; +use strict; +use warnings; +#use lib qw(../lib ../../lib); +use MyElements::ListPersonResponse; +use MyServer::TestService::TestPort; +my $server = MyServer::TestService::TestPort->new({ + dispatch_to => 'main', + transport_class => 'SOAP::WSDL::Server::CGI', # optional, default +}); +$server->handle(); + +sub ListPerson { + my ($self, $body, $header) = @_; + # body is a ??? object - sorry, POD not implemented yet + # header is a ??? object - sorry, POD not implemented yet + + # do something with body and header... + + my %person = ( + PersonID => { # MyTypes::PersonID + ID => 1, # int + }, + Salutation => 'Salutation0', # string + Name => 'Name0', # string + GivenName => 'Martin', # string + DateOfBirth => '1970-01-01', # date + HomeAddress => { # MyTypes::Address + Street => 'Street 0', # string + ZIP => '00000', # string + City => 'City0', # string + Country => 'Country0', # string + PhoneNumber => '++499131123456', # PhoneNumber + MobilePhoneNumber => '++49150123456', # PhoneNumber + }, + WorkAddress => { # MyTypes::Address + Street => 'Somestreet 23', # string + ZIP => '12345', # string + City => 'SomeCity', # string + Country => 'Germany', # string + PhoneNumber => '++499131123456', # PhoneNumber + MobilePhoneNumber => '++49150123456', # PhoneNumber + }, + Contracts => { # MyTypes::ArrayOfContract + Contract => [ + { # MyTypes::Contract + ContractID => 100000, # long + ContractName => 'SomeContract0', # string + }, + { # MyTypes::Contract + ContractID => 100001, # long + ContractName => 'SomeContract1', # string + }, + { # MyTypes::Contract + ContractID => 100002, # long + ContractName => 'SomeContract2', # string + }, + { # MyTypes::Contract + ContractID => 100003, # long + ContractName => 'SomeContract3', # string + }, + ], + }, + ); + + return MyElements::ListPersonResponse->new( { + out => { # MyTypes::ArrayOfPerson + NewElement => [ + { %person }, + { %person }, + { %person }, + { %person }, + { %person }, + { %person }, + { %person }, + { %person }, + { %person }, + { %person }, + ], + }, + } + ); + } diff --git a/example/fortune.pl b/example/fortune.pl new file mode 100644 index 0000000..86ba476 --- /dev/null +++ b/example/fortune.pl @@ -0,0 +1,47 @@ +# Accessing the fortune cookie service at +# www.fullerdata.com/FortuneCookie/FortuneCookie.asmx +# +# I have no connection to www.fullerdata.com +# +# Use this script at your own risk. + +# Run before: +# D:\Eigene Dateien\Martin\SOAP-WSDL\trunk>perl -I../lib wsdl2perl.pl "file:///D:/ +# Eigene Dateien/Martin/SOAP-WSDL/trunk/bin/FortuneCookie.xml" + +use lib 'lib/'; +use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap; +my $cookieService = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap->new(); + +my $cookie; +$cookie = $cookieService->GetFortuneCookie() + or die "$cookie"; + +print $cookie->get_GetFortuneCookieResult()->get_value, "\n\n"; + +$cookie = $cookieService->GetSpecificCookie({ index => 23 }) + or die "$cookie"; + +print $cookie->get_GetSpecificCookieResult(), "\n"; + +# print $cookie; + + +=for demo: + +# the same in SOAP lite (second call) +# + +use SOAP::Lite; + +my $lite = SOAP::Lite->new()->on_action(sub { join '/', @_ } ) + ->proxy('http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx'); + +$lite->call( + SOAP::Data->name('GetSpecificCookie') + ->attr({ 'xmlns', 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }), + SOAP::Data->name('index')->value(23) + ); + +die $soap->message() if ($soap->fault()); +print $soap->result(); \ No newline at end of file diff --git a/example/genericbarcode.pl b/example/genericbarcode.pl new file mode 100644 index 0000000..e874be3 --- /dev/null +++ b/example/genericbarcode.pl @@ -0,0 +1,29 @@ +use lib 'lib'; +use lib '../lib'; +use MyInterfaces::BarCode::BarCodeSoap; +my $interface = MyInterfaces::BarCode::BarCodeSoap->new(); +my $barcode = $interface->GenerateBarCode( { + BarCodeParam => { # MyTypes::BarCodeData + Height => 42, # int + Width => 120, # int + Angle => 90, # int + Ratio => 1, # int + Module => 1, # int + Left => 10, # int + Top => 10, # int + CheckSum => 0, # boolean + FontName => 'Arial', # string + BarColor => 'black', # string + BGColor => 'white', # string + FontSize => 6.25, # float + barcodeOption => 'Both', # BarcodeOption + barcodeType => 'CodeMSI', # BarcodeType + checkSumMethod => 'None', # CheckSumMethod + showTextPosition => 'TopLeft', # ShowTextPosition + BarCodeImageFormat => 'PNG', # ImageFormats + }, + BarCodeText => 'JustSomeText', # string + }, + ); +die $barcode if not ($barcode); +print $barcode; diff --git a/example/hello.pl b/example/hello.pl new file mode 100644 index 0000000..1fbdf07 --- /dev/null +++ b/example/hello.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +use lib 'lib'; # just needed because interface lies here + +# I have to generate the interface using wsdl2perl.pl before +use MyInterfaces::HelloWorld::HelloWorldSoap; + +# I instantiate a interface class. +my $soap = MyInterfaces::HelloWorld::HelloWorldSoap->new(); + +# I have to lookup the method and synopsis from the interface's pod +my $result = $soap->sayHello({ + name => $ARGV[1] || '"Your name"', + givenName => $ARGV[0] || '"Your given name"', +}); + +# SOAP::WSDL::SOAP::Typelib::Fault11 objects are false, but serialize to XML +die $result if not $result; + +# I have to lookup the output parameter from the interface's POD - or try: +# Will die on bad method names with a list of available methods +print $result->get_sayHelloResult(), "\n"; + diff --git a/example/hello_compile.pl b/example/hello_compile.pl new file mode 100644 index 0000000..349a4d3 --- /dev/null +++ b/example/hello_compile.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +use XML::Compile::WSDL11; +use XML::Compile::Transport::SOAPHTTP; + +# I need access to the WSDL around - or use Data::Dumper::Streamer +# for serializing the generated closures into (big) perl files +my $wsdl = XML::Compile::WSDL11->new('wsdl/11_helloworld.wsdl'); + +# I compile a interface method for a single SOAP method from the WSDL +# I have to lookup the method names from the WSDL +my $call = $wsdl->compileClient('sayHello'); + +# I have to lookup the parameters from the WSDL - can be quite tricky +my $result = $call->( + name => $ARGV[1] || '"Your name"', + givenName => $ARGV[0] || '"Your given name"', +); + +# XML::Compile::SOAP's client just returns undef in case of failure +die "Error calling soap method" if not defined $result; + +# I have to lookup the output parameters from the WSDL - or try Data::Dumper +print $result->{ parameters }->{ sayHelloResult }, "\n"; diff --git a/example/hello_lite.pl b/example/hello_lite.pl new file mode 100644 index 0000000..cb1d992 --- /dev/null +++ b/example/hello_lite.pl @@ -0,0 +1,29 @@ +#!/usr/bin/perl -w +#use strict; +use warnings; +use SOAP::Lite +trace; + +# I have to lookup the URL from the WSDL +my $soap = SOAP::Lite->new( + proxy => 'http://localhost:81/soap-wsdl-test/helloworld.pl' +); + +# I have to lookup the SOAPAction from the WSDL +$soap->on_action( sub { "urn:HelloWorld#sayHello" }); +$soap->autotype(0); + +# I have to lookup the top level element's namespace from the WSDL +$soap->default_ns('urn:HelloWorld'); + +# I have to encode all parameters as SOAP::Data objects +# I have to know the order of parameters +my $som = $soap->call( + "sayHello", + SOAP::Data->name('name')->value( $ARGV[1] || '"Your name"'), + SOAP::Data->name('givenName')->value( $ARGV[0] || '"Your given name"'), +); + +die $som->fault->{ faultstring } if ($som->fault); + +print $som->result, "\n"; + diff --git a/example/lib/MyElements/CountCookies.pm b/example/lib/MyElements/CountCookies.pm new file mode 100644 index 0000000..02bea8f --- /dev/null +++ b/example/lib/MyElements/CountCookies.pm @@ -0,0 +1,54 @@ +package MyElements::CountCookies; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('CountCookies'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::CountCookies + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +CountCookies from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::CountCookies->new($data); + +Constructor. The following data structure may be passed to new(): + +, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/CountCookiesResponse.pm b/example/lib/MyElements/CountCookiesResponse.pm new file mode 100644 index 0000000..630551a --- /dev/null +++ b/example/lib/MyElements/CountCookiesResponse.pm @@ -0,0 +1,81 @@ +package MyElements::CountCookiesResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('CountCookiesResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %CountCookiesResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + CountCookiesResult + ) ], + { + CountCookiesResult => \%CountCookiesResult_of, + }, + { + CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::CountCookiesResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +CountCookiesResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::CountCookiesResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + CountCookiesResult => $some_value, # int + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GenerateBarCode.pm b/example/lib/MyElements/GenerateBarCode.pm new file mode 100644 index 0000000..fe94f95 --- /dev/null +++ b/example/lib/MyElements/GenerateBarCode.pm @@ -0,0 +1,104 @@ +package MyElements::GenerateBarCode; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.webservicex.net/' } + +__PACKAGE__->__set_name('GenerateBarCode'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %BarCodeParam_of :ATTR(:get); +my %BarCodeText_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + BarCodeParam + BarCodeText + ) ], + { + BarCodeParam => \%BarCodeParam_of, + BarCodeText => \%BarCodeText_of, + }, + { + BarCodeParam => 'MyTypes::BarCodeData', + BarCodeText => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GenerateBarCode + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GenerateBarCode from the namespace http://www.webservicex.net/. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GenerateBarCode->new($data); + +Constructor. The following data structure may be passed to new(): + + { + BarCodeParam => { # MyTypes::BarCodeData + Height => $some_value, # int + Width => $some_value, # int + Angle => $some_value, # int + Ratio => $some_value, # int + Module => $some_value, # int + Left => $some_value, # int + Top => $some_value, # int + CheckSum => $some_value, # boolean + FontName => $some_value, # string + BarColor => $some_value, # string + BGColor => $some_value, # string + FontSize => $some_value, # float + barcodeOption => $some_value, # BarcodeOption + barcodeType => $some_value, # BarcodeType + checkSumMethod => $some_value, # CheckSumMethod + showTextPosition => $some_value, # ShowTextPosition + BarCodeImageFormat => $some_value, # ImageFormats + }, + BarCodeText => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GenerateBarCodeResponse.pm b/example/lib/MyElements/GenerateBarCodeResponse.pm new file mode 100644 index 0000000..35814c7 --- /dev/null +++ b/example/lib/MyElements/GenerateBarCodeResponse.pm @@ -0,0 +1,81 @@ +package MyElements::GenerateBarCodeResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.webservicex.net/' } + +__PACKAGE__->__set_name('GenerateBarCodeResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %GenerateBarCodeResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + GenerateBarCodeResult + ) ], + { + GenerateBarCodeResult => \%GenerateBarCodeResult_of, + }, + { + GenerateBarCodeResult => 'SOAP::WSDL::XSD::Typelib::Builtin::base64Binary', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GenerateBarCodeResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GenerateBarCodeResponse from the namespace http://www.webservicex.net/. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GenerateBarCodeResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + GenerateBarCodeResult => $some_value, # base64Binary + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetCitiesByCountry.pm b/example/lib/MyElements/GetCitiesByCountry.pm new file mode 100644 index 0000000..8630ea6 --- /dev/null +++ b/example/lib/MyElements/GetCitiesByCountry.pm @@ -0,0 +1,81 @@ +package MyElements::GetCitiesByCountry; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.webserviceX.NET' } + +__PACKAGE__->__set_name('GetCitiesByCountry'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %CountryName_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + CountryName + ) ], + { + CountryName => \%CountryName_of, + }, + { + CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetCitiesByCountry + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetCitiesByCountry from the namespace http://www.webserviceX.NET. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetCitiesByCountry->new($data); + +Constructor. The following data structure may be passed to new(): + + { + CountryName => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetCitiesByCountryResponse.pm b/example/lib/MyElements/GetCitiesByCountryResponse.pm new file mode 100644 index 0000000..1fedc5e --- /dev/null +++ b/example/lib/MyElements/GetCitiesByCountryResponse.pm @@ -0,0 +1,81 @@ +package MyElements::GetCitiesByCountryResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.webserviceX.NET' } + +__PACKAGE__->__set_name('GetCitiesByCountryResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %GetCitiesByCountryResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + GetCitiesByCountryResult + ) ], + { + GetCitiesByCountryResult => \%GetCitiesByCountryResult_of, + }, + { + GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetCitiesByCountryResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetCitiesByCountryResponse from the namespace http://www.webserviceX.NET. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetCitiesByCountryResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + GetCitiesByCountryResult => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetFortuneCookie.pm b/example/lib/MyElements/GetFortuneCookie.pm new file mode 100644 index 0000000..5914bc1 --- /dev/null +++ b/example/lib/MyElements/GetFortuneCookie.pm @@ -0,0 +1,54 @@ +package MyElements::GetFortuneCookie; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('GetFortuneCookie'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetFortuneCookie + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetFortuneCookie from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetFortuneCookie->new($data); + +Constructor. The following data structure may be passed to new(): + +, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetFortuneCookieResponse.pm b/example/lib/MyElements/GetFortuneCookieResponse.pm new file mode 100644 index 0000000..752c7f0 --- /dev/null +++ b/example/lib/MyElements/GetFortuneCookieResponse.pm @@ -0,0 +1,81 @@ +package MyElements::GetFortuneCookieResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('GetFortuneCookieResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %GetFortuneCookieResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + GetFortuneCookieResult + ) ], + { + GetFortuneCookieResult => \%GetFortuneCookieResult_of, + }, + { + GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetFortuneCookieResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetFortuneCookieResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetFortuneCookieResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + GetFortuneCookieResult => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetSpecificCookie.pm b/example/lib/MyElements/GetSpecificCookie.pm new file mode 100644 index 0000000..2b32f0e --- /dev/null +++ b/example/lib/MyElements/GetSpecificCookie.pm @@ -0,0 +1,81 @@ +package MyElements::GetSpecificCookie; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('GetSpecificCookie'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %index_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + index + ) ], + { + index => \%index_of, + }, + { + index => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetSpecificCookie + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetSpecificCookie from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetSpecificCookie->new($data); + +Constructor. The following data structure may be passed to new(): + + { + index => $some_value, # int + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetSpecificCookieResponse.pm b/example/lib/MyElements/GetSpecificCookieResponse.pm new file mode 100644 index 0000000..2405b3c --- /dev/null +++ b/example/lib/MyElements/GetSpecificCookieResponse.pm @@ -0,0 +1,81 @@ +package MyElements::GetSpecificCookieResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('GetSpecificCookieResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %GetSpecificCookieResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + GetSpecificCookieResult + ) ], + { + GetSpecificCookieResult => \%GetSpecificCookieResult_of, + }, + { + GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetSpecificCookieResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetSpecificCookieResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetSpecificCookieResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + GetSpecificCookieResult => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetWeather.pm b/example/lib/MyElements/GetWeather.pm new file mode 100644 index 0000000..d26c06c --- /dev/null +++ b/example/lib/MyElements/GetWeather.pm @@ -0,0 +1,86 @@ +package MyElements::GetWeather; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.webserviceX.NET' } + +__PACKAGE__->__set_name('GetWeather'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %CityName_of :ATTR(:get); +my %CountryName_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + CityName + CountryName + ) ], + { + CityName => \%CityName_of, + CountryName => \%CountryName_of, + }, + { + CityName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetWeather + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetWeather from the namespace http://www.webserviceX.NET. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetWeather->new($data); + +Constructor. The following data structure may be passed to new(): + + { + CityName => $some_value, # string + CountryName => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/GetWeatherResponse.pm b/example/lib/MyElements/GetWeatherResponse.pm new file mode 100644 index 0000000..d837315 --- /dev/null +++ b/example/lib/MyElements/GetWeatherResponse.pm @@ -0,0 +1,81 @@ +package MyElements::GetWeatherResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.webserviceX.NET' } + +__PACKAGE__->__set_name('GetWeatherResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %GetWeatherResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + GetWeatherResult + ) ], + { + GetWeatherResult => \%GetWeatherResult_of, + }, + { + GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::GetWeatherResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +GetWeatherResponse from the namespace http://www.webserviceX.NET. + +=head1 METHODS + +=head2 new + + my $element = MyElements::GetWeatherResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + GetWeatherResult => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/ListPerson.pm b/example/lib/MyElements/ListPerson.pm new file mode 100644 index 0000000..04ae689 --- /dev/null +++ b/example/lib/MyElements/ListPerson.pm @@ -0,0 +1,111 @@ +package MyElements::ListPerson; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.example.org/benchmark/' } + +__PACKAGE__->__set_name('ListPerson'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %in_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + in + ) ], + { + in => \%in_of, + }, + { + in => 'MyTypes::Person', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::ListPerson + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +ListPerson from the namespace http://www.example.org/benchmark/. + +=head1 METHODS + +=head2 new + + my $element = MyElements::ListPerson->new($data); + +Constructor. The following data structure may be passed to new(): + + { + in => { # MyTypes::Person + PersonID => { # MyTypes::PersonID + ID => $some_value, # int + }, + Salutation => $some_value, # string + Name => $some_value, # string + GivenName => $some_value, # string + DateOfBirth => $some_value, # date + HomeAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + WorkAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + Contracts => { # MyTypes::ArrayOfContract + Contract => { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + }, + }, + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/ListPersonResponse.pm b/example/lib/MyElements/ListPersonResponse.pm new file mode 100644 index 0000000..e66bd2d --- /dev/null +++ b/example/lib/MyElements/ListPersonResponse.pm @@ -0,0 +1,113 @@ +package MyElements::ListPersonResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.example.org/benchmark/' } + +__PACKAGE__->__set_name('ListPersonResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %out_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + out + ) ], + { + out => \%out_of, + }, + { + out => 'MyTypes::ArrayOfPerson', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::ListPersonResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +ListPersonResponse from the namespace http://www.example.org/benchmark/. + +=head1 METHODS + +=head2 new + + my $element = MyElements::ListPersonResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + out => { # MyTypes::ArrayOfPerson + NewElement => { # MyTypes::Person + PersonID => { # MyTypes::PersonID + ID => $some_value, # int + }, + Salutation => $some_value, # string + Name => $some_value, # string + GivenName => $some_value, # string + DateOfBirth => $some_value, # date + HomeAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + WorkAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + Contracts => { # MyTypes::ArrayOfContract + Contract => { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + }, + }, + }, + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/int.pm b/example/lib/MyElements/int.pm new file mode 100644 index 0000000..74cac71 --- /dev/null +++ b/example/lib/MyElements/int.pm @@ -0,0 +1,52 @@ +package MyElements::int; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('int'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::Builtin::int + +); + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::int + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +int from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::int->new($data); + +Constructor. The following data structure may be passed to new(): + + $some_value, # int + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/readNodeCount.pm b/example/lib/MyElements/readNodeCount.pm new file mode 100644 index 0000000..484bf70 --- /dev/null +++ b/example/lib/MyElements/readNodeCount.pm @@ -0,0 +1,54 @@ +package MyElements::readNodeCount; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('readNodeCount'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::readNodeCount + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +readNodeCount from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::readNodeCount->new($data); + +Constructor. The following data structure may be passed to new(): + +, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/readNodeCountResponse.pm b/example/lib/MyElements/readNodeCountResponse.pm new file mode 100644 index 0000000..d5ffeee --- /dev/null +++ b/example/lib/MyElements/readNodeCountResponse.pm @@ -0,0 +1,81 @@ +package MyElements::readNodeCountResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' } + +__PACKAGE__->__set_name('readNodeCountResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %readNodeCountResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + readNodeCountResult + ) ], + { + readNodeCountResult => \%readNodeCountResult_of, + }, + { + readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::readNodeCountResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +readNodeCountResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 METHODS + +=head2 new + + my $element = MyElements::readNodeCountResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + readNodeCountResult => $some_value, # int + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/sayHello.pm b/example/lib/MyElements/sayHello.pm new file mode 100644 index 0000000..9a0fb77 --- /dev/null +++ b/example/lib/MyElements/sayHello.pm @@ -0,0 +1,86 @@ +package MyElements::sayHello; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'urn:HelloWorld' } + +__PACKAGE__->__set_name('sayHello'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %name_of :ATTR(:get); +my %givenName_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + name + givenName + ) ], + { + name => \%name_of, + givenName => \%givenName_of, + }, + { + name => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + givenName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::sayHello + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +sayHello from the namespace urn:HelloWorld. + +=head1 METHODS + +=head2 new + + my $element = MyElements::sayHello->new($data); + +Constructor. The following data structure may be passed to new(): + + { + name => $some_value, # string + givenName => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/sayHelloResponse.pm b/example/lib/MyElements/sayHelloResponse.pm new file mode 100644 index 0000000..3d60631 --- /dev/null +++ b/example/lib/MyElements/sayHelloResponse.pm @@ -0,0 +1,81 @@ +package MyElements::sayHelloResponse; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'urn:HelloWorld' } + +__PACKAGE__->__set_name('sayHelloResponse'); +__PACKAGE__->__set_nillable(); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); + +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::ComplexType +); +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %sayHelloResult_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + sayHelloResult + ) ], + { + sayHelloResult => \%sayHelloResult_of, + }, + { + sayHelloResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::sayHelloResponse + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +sayHelloResponse from the namespace urn:HelloWorld. + +=head1 METHODS + +=head2 new + + my $element = MyElements::sayHelloResponse->new($data); + +Constructor. The following data structure may be passed to new(): + + { + sayHelloResult => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyElements/string.pm b/example/lib/MyElements/string.pm new file mode 100644 index 0000000..052f4a9 --- /dev/null +++ b/example/lib/MyElements/string.pm @@ -0,0 +1,52 @@ +package MyElements::string; +use strict; +use warnings; + +{ # BLOCK to scope variables + +sub get_xmlns { 'http://www.webserviceX.NET' } + +__PACKAGE__->__set_name('string'); +__PACKAGE__->__set_nillable(true); +__PACKAGE__->__set_minOccurs(); +__PACKAGE__->__set_maxOccurs(); +__PACKAGE__->__set_ref(); +use base qw( + SOAP::WSDL::XSD::Typelib::Element + SOAP::WSDL::XSD::Typelib::Builtin::string + +); + + +} # end of BLOCK +1; + +# __END__ + +=pod + +=head1 NAME + +MyElements::string + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined element +string from the namespace http://www.webserviceX.NET. + +=head1 METHODS + +=head2 new + + my $element = MyElements::string->new($data); + +Constructor. The following data structure may be passed to new(): + + $some_value, # string + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyInterfaces/BarCode/BarCodeSoap.pm b/example/lib/MyInterfaces/BarCode/BarCodeSoap.pm new file mode 100644 index 0000000..88be68a --- /dev/null +++ b/example/lib/MyInterfaces/BarCode/BarCodeSoap.pm @@ -0,0 +1,135 @@ +package MyInterfaces::BarCode::BarCodeSoap; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); +use base qw(SOAP::WSDL::Client::Base); + +# only load if it hasn't been loaded before +require MyTypemaps::BarCode + if not MyTypemaps::BarCode->can('get_class'); + +sub START { + $_[0]->set_proxy('http://www.webservicex.net/genericbarcode.asmx') if not $_[2]->{proxy}; + $_[0]->set_class_resolver('MyTypemaps::BarCode') + if not $_[2]->{class_resolver}; +} + +sub GenerateBarCode { + my ($self, $body, $header) = @_; + die "GenerateBarCode must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'GenerateBarCode', + soap_action => 'http://www.webservicex.net/GenerateBarCode', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::GenerateBarCode )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + + + +1; + + + +__END__ + +=pod + +=head1 NAME + + +MyInterfaces::BarCode::BarCodeSoap - SOAP Interface for the BarCode Web Service + +=head1 SYNOPSIS + + use MyInterfaces::BarCode::BarCodeSoap; + my $interface = MyInterfaces::BarCode::BarCodeSoap->new(); + + my $response; + $response = $interface->GenerateBarCode(); + + + +=head1 DESCRIPTION + +SOAP Interface for the BarCode web service +located at http://www.webservicex.net/genericbarcode.asmx. + +=head1 SERVICE BarCode + +Barcode generator + +=head2 Port BarCodeSoap + + + +=head1 METHODS + +=head2 General methods + +=head3 new + +Constructor. + +All arguments are forwarded to L. + +=head2 SOAP Service methods + +Method synopsis is displayed with hash refs as parameters. + +The commented class names in the method's parameters denote that objects +of the corresponding class can be passed instead of the marked hash ref. + +You may pass any combination of objects, hash and list refs to these +methods, as long as you meet the structure. + + + +=head3 GenerateBarCode + +WebserviceX.NET barcode library that provides the means to create barcodes for printing and display in any internet enabled applications. This web service supports Code 128, Industrial 2 of 5, Interleaved 2 of 5, Code 2 5 Matrix, Code 39, Code 39 Extended, Code 93, Code 93 Extended, Codabar, EAN13, EAN8, MSI, Postnet, Supp2, Supp5, UPC A, UPC E0 and UPC E1 barcode formats. This Barcodes returns byte image. It supports following image format JPEG, GIF, PNG, BMP, EMF, EXIF, ICON, MEMORY BMP, TIFF and WMF. + + $interface->GenerateBarCode( { + BarCodeParam => { # MyTypes::BarCodeData + Height => $some_value, # int + Width => $some_value, # int + Angle => $some_value, # int + Ratio => $some_value, # int + Module => $some_value, # int + Left => $some_value, # int + Top => $some_value, # int + CheckSum => $some_value, # boolean + FontName => $some_value, # string + BarColor => $some_value, # string + BGColor => $some_value, # string + FontSize => $some_value, # float + barcodeOption => $some_value, # BarcodeOption + barcodeType => $some_value, # BarcodeType + checkSumMethod => $some_value, # CheckSumMethod + showTextPosition => $some_value, # ShowTextPosition + BarCodeImageFormat => $some_value, # ImageFormats + }, + BarCodeText => $some_value, # string + },, + ); + + + +=head1 AUTHOR + +Generated by SOAP::WSDL on Sun Dec 16 20:10:20 2007 + +=pod \ No newline at end of file diff --git a/example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm b/example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm new file mode 100644 index 0000000..69a0a37 --- /dev/null +++ b/example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm @@ -0,0 +1,209 @@ +package MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); +use base qw(SOAP::WSDL::Client::Base); + +# only load if it hasn't been loaded before +require MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie + if not MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie->can('get_class'); + +sub START { + $_[0]->set_proxy('http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx') if not $_[2]->{proxy}; + $_[0]->set_class_resolver('MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie') + if not $_[2]->{class_resolver}; +} + +sub readNodeCount { + my ($self, $body, $header) = @_; + die "readNodeCount must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'readNodeCount', + soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/readNodeCount', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::readNodeCount )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + +sub GetFortuneCookie { + my ($self, $body, $header) = @_; + die "GetFortuneCookie must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'GetFortuneCookie', + soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/GetFortuneCookie', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::GetFortuneCookie )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + +sub CountCookies { + my ($self, $body, $header) = @_; + die "CountCookies must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'CountCookies', + soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/CountCookies', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::CountCookies )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + +sub GetSpecificCookie { + my ($self, $body, $header) = @_; + die "GetSpecificCookie must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'GetSpecificCookie', + soap_action => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx/GetSpecificCookie', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::GetSpecificCookie )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + + + +1; + + + +__END__ + +=pod + +=head1 NAME + + +MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap - SOAP Interface for the FullerData_x0020_Fortune_x0020_Cookie Web Service + +=head1 SYNOPSIS + + use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap; + my $interface = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap->new(); + + my $response; + $response = $interface->readNodeCount(); + $response = $interface->GetFortuneCookie(); + $response = $interface->CountCookies(); + $response = $interface->GetSpecificCookie(); + + + +=head1 DESCRIPTION + +SOAP Interface for the FullerData_x0020_Fortune_x0020_Cookie web service +located at http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx. + +=head1 SERVICE FullerData_x0020_Fortune_x0020_Cookie + +Simple XML-based fortune cookie + +=head2 Port FullerData_x0020_Fortune_x0020_CookieSoap + + + +=head1 METHODS + +=head2 General methods + +=head3 new + +Constructor. + +All arguments are forwarded to L. + +=head2 SOAP Service methods + +Method synopsis is displayed with hash refs as parameters. + +The commented class names in the method's parameters denote that objects +of the corresponding class can be passed instead of the marked hash ref. + +You may pass any combination of objects, hash and list refs to these +methods, as long as you meet the structure. + + + +=head3 readNodeCount + +Display the number of nodes specified in fortune XML document + + $interface->readNodeCount(,, + ); + +=head3 GetFortuneCookie + +Get a random fortune cookie from the XML document + + $interface->GetFortuneCookie(,, + ); + +=head3 CountCookies + +Count the actual number of nodes in the XML document of fortunes + + $interface->CountCookies(,, + ); + +=head3 GetSpecificCookie + +Get a specific cookie by the XML node number + + $interface->GetSpecificCookie( { + index => $some_value, # int + },, + ); + + + +=head1 AUTHOR + +Generated by SOAP::WSDL on Sun Dec 16 19:58:30 2007 + +=pod \ No newline at end of file diff --git a/example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm b/example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm new file mode 100644 index 0000000..caf6c23 --- /dev/null +++ b/example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm @@ -0,0 +1,150 @@ +package MyInterfaces::GlobalWeather::GlobalWeatherSoap; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); +use base qw(SOAP::WSDL::Client::Base); + +# only load if it hasn't been loaded before +require MyTypemaps::GlobalWeather + if not MyTypemaps::GlobalWeather->can('get_class'); + +sub START { + $_[0]->set_proxy('http://www.webservicex.net/globalweather.asmx') if not $_[2]->{proxy}; + $_[0]->set_class_resolver('MyTypemaps::GlobalWeather') + if not $_[2]->{class_resolver}; +} + +sub GetWeather { + my ($self, $body, $header) = @_; + die "GetWeather must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'GetWeather', + soap_action => 'http://www.webserviceX.NET/GetWeather', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::GetWeather )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + +sub GetCitiesByCountry { + my ($self, $body, $header) = @_; + die "GetCitiesByCountry must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'GetCitiesByCountry', + soap_action => 'http://www.webserviceX.NET/GetCitiesByCountry', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::GetCitiesByCountry )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + + + +1; + + + +__END__ + +=pod + +=head1 NAME + + +MyInterfaces::GlobalWeather::GlobalWeatherSoap - SOAP Interface for the GlobalWeather Web Service + +=head1 SYNOPSIS + + use MyInterfaces::GlobalWeather::GlobalWeatherSoap; + my $interface = MyInterfaces::GlobalWeather::GlobalWeatherSoap->new(); + + my $response; + $response = $interface->GetWeather(); + $response = $interface->GetCitiesByCountry(); + + + +=head1 DESCRIPTION + +SOAP Interface for the GlobalWeather web service +located at http://www.webservicex.net/globalweather.asmx. + +=head1 SERVICE GlobalWeather + + + +=head2 Port GlobalWeatherSoap + + + +=head1 METHODS + +=head2 General methods + +=head3 new + +Constructor. + +All arguments are forwarded to L. + +=head2 SOAP Service methods + +Method synopsis is displayed with hash refs as parameters. + +The commented class names in the method's parameters denote that objects +of the corresponding class can be passed instead of the marked hash ref. + +You may pass any combination of objects, hash and list refs to these +methods, as long as you meet the structure. + + + +=head3 GetWeather + +Get weather report for all major cities around the world. + + $interface->GetWeather( { + CityName => $some_value, # string + CountryName => $some_value, # string + },, + ); + +=head3 GetCitiesByCountry + +Get all major cities by country name(full / part). + + $interface->GetCitiesByCountry( { + CountryName => $some_value, # string + },, + ); + + + +=head1 AUTHOR + +Generated by SOAP::WSDL on Sun Dec 16 20:05:01 2007 + +=pod \ No newline at end of file diff --git a/example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm b/example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm new file mode 100644 index 0000000..e2a6ffc --- /dev/null +++ b/example/lib/MyInterfaces/HelloWorld/HelloWorldSoap.pm @@ -0,0 +1,113 @@ +package MyInterfaces::HelloWorld::HelloWorldSoap; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); +use base qw(SOAP::WSDL::Client::Base); + +# only load if it hasn't been loaded before +require MyTypemaps::HelloWorld + if not MyTypemaps::HelloWorld->can('get_class'); + +sub START { + $_[0]->set_proxy('http://localhost:81/soap-wsdl-test/helloworld.pl') if not $_[2]->{proxy}; + $_[0]->set_class_resolver('MyTypemaps::HelloWorld') + if not $_[2]->{class_resolver}; +} + +sub sayHello { + my ($self, $body, $header) = @_; + die "sayHello must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'sayHello', + soap_action => 'urn:HelloWorld#sayHello', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::sayHello )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + +1; + +__END__ + +=pod + +=head1 NAME + + +MyInterfaces::HelloWorld::HelloWorldSoap - SOAP Interface for the HelloWorld Web Service + +=head1 SYNOPSIS + + use MyInterfaces::HelloWorld::HelloWorldSoap; + my $interface = MyInterfaces::HelloWorld::HelloWorldSoap->new(); + + my $response; + $response = $interface->sayHello(); + + + +=head1 DESCRIPTION + +SOAP Interface for the HelloWorld web service +located at http://localhost:81/soap-wsdl-test/helloworld.pl. + +=head1 SERVICE HelloWorld + + + +=head2 Port HelloWorldSoap + + + +=head1 METHODS + +=head2 General methods + +=head3 new + +Constructor. + +All arguments are forwarded to L. + +=head2 SOAP Service methods + +Method synopsis is displayed with hash refs as parameters. + +The commented class names in the method's parameters denote that objects +of the corresponding class can be passed instead of the marked hash ref. + +You may pass any combination of objects, hash and list refs to these +methods, as long as you meet the structure. + + + +=head3 sayHello + + + + $interface->sayHello( { + name => $some_value, # string + givenName => $some_value, # string + },, + ); + + + +=head1 AUTHOR + +Generated by SOAP::WSDL on Sat Dec 1 19:51:31 2007 + +=pod \ No newline at end of file diff --git a/example/lib/MyInterfaces/TestService/TestPort.pm b/example/lib/MyInterfaces/TestService/TestPort.pm new file mode 100644 index 0000000..73217a8 --- /dev/null +++ b/example/lib/MyInterfaces/TestService/TestPort.pm @@ -0,0 +1,146 @@ +package MyInterfaces::TestService::TestPort; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); +use base qw(SOAP::WSDL::Client::Base); + +# only load if it hasn't been loaded before +require MyTypemaps::TestService + if not MyTypemaps::TestService->can('get_class'); + +sub START { + $_[0]->set_proxy('http://localhost:81/soap-wsdl-test/person.pl') if not $_[2]->{proxy}; + $_[0]->set_class_resolver('MyTypemaps::TestService') + if not $_[2]->{class_resolver}; +} + +sub ListPerson { + my ($self, $body, $header) = @_; + die "ListPerson must be called as object method (\$self is <$self>)" if not blessed($self); + return $self->SUPER::call({ + operation => 'ListPerson', + soap_action => 'http://www.example.org/benchmark/ListPerson', + style => 'document', + body => { + + 'use' => 'literal', + namespace => '', + encodingStyle => '', + parts => [qw( MyElements::ListPerson )], + }, + header => { + + }, + headerfault => { + + } + }, $body, $header); +} + + + +1; + + + +__END__ + +=pod + +=head1 NAME + + +MyInterfaces::TestService::TestPort - SOAP Interface for the TestService Web Service + +=head1 SYNOPSIS + + use MyInterfaces::TestService::TestPort; + my $interface = MyInterfaces::TestService::TestPort->new(); + + my $response; + $response = $interface->ListPerson(); + + + +=head1 DESCRIPTION + +SOAP Interface for the TestService web service +located at http://localhost:81/soap-wsdl-test/person.pl. + +=head1 SERVICE TestService + + + +=head2 Port TestPort + + + +=head1 METHODS + +=head2 General methods + +=head3 new + +Constructor. + +All arguments are forwarded to L. + +=head2 SOAP Service methods + +Method synopsis is displayed with hash refs as parameters. + +The commented class names in the method's parameters denote that objects +of the corresponding class can be passed instead of the marked hash ref. + +You may pass any combination of objects, hash and list refs to these +methods, as long as you meet the structure. + + + +=head3 ListPerson + + + + $interface->ListPerson( { + in => { # MyTypes::Person + PersonID => { # MyTypes::PersonID + ID => $some_value, # int + }, + Salutation => $some_value, # string + Name => $some_value, # string + GivenName => $some_value, # string + DateOfBirth => $some_value, # date + HomeAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + WorkAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + Contracts => { # MyTypes::ArrayOfContract + Contract => { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + }, + }, + },, + ); + + + +=head1 AUTHOR + +Generated by SOAP::WSDL on Mon Dec 3 22:20:49 2007 + +=pod \ No newline at end of file diff --git a/example/lib/MyServer/HelloWorld/HelloWorldSoap.pm b/example/lib/MyServer/HelloWorld/HelloWorldSoap.pm new file mode 100644 index 0000000..fdf839b --- /dev/null +++ b/example/lib/MyServer/HelloWorld/HelloWorldSoap.pm @@ -0,0 +1,113 @@ +package MyServer::HelloWorld::HelloWorldSoap; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); +use base qw(SOAP::WSDL::Client::Base); + +# only load if it hasn't been loaded before +require MyTypemaps::HelloWorld + if not MyTypemaps::HelloWorld->can('get_class'); + +my %transport_class_of :ATTR(:name :default); +my %transport_of :ATTR(:name :default<()>); +my %dispatch_to :ATTR(:name); + +my $action_map_ref = { + 'urn:HelloWorld#sayHello' => 'sayHello', + +}; + +sub START { + my ($self, $ident, $arg_ref) = @_; + eval "require $transport_class_of{ $ident }" + 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 => 'MyTypemaps::HelloWorld', + dispatch_to => $dispatch_to{ $ident }, + }); +} + +sub handle { + $transport_of{ ${ $_[0] } }->handle(); +} + +1; + + + +__END__ + +=pod + +=head1 NAME + +MyInterfaces::HelloWorld::HelloWorldSoap - SOAP Server Class for the HelloWorld Web Service + +=head1 SYNOPSIS + + use MyServer::HelloWorld::HelloWorldSoap; + my $server = MyServer::HelloWorld::HelloWorldSoap->new({ + dispatch_to => 'My::Handler::Class', + transport_class => 'SOAP::WSDL::Server::CGI', # optional, default + }); + $server->handle(); + + +=head1 DESCRIPTION + +SOAP Server handler for the HelloWorld web service +located at http://localhost:81/soap-wsdl-test/helloworld.pl. + +=head1 SERVICE HelloWorld + + + +=head2 Port HelloWorldSoap + + + +=head1 METHODS + +=head2 General methods + +=head3 new + +Constructor. + +The C argument is mandatory. It must be a class or object +implementing the SOAP Service methods listed below. + +=head2 SOAP Service methods + +Your dispatch_to class has to implement the following methods: + +The examples below serve as copy-and-paste prototypes to use in your +class. + +=head3 sayHello + + + + sub sayHello( + my ($self, $body, $header) = @_; + # body is a ??? object - sorry, POD not implemented yet + # header is a ??? object - sorry, POD not implemented yet + + # do something with body and header... + + return MyElements::sayHelloResponse->new( { + sayHelloResult => $some_value, # string + }, + ); + + } + + + +=head1 AUTHOR + +Generated by SOAP::WSDL on Sun Dec 2 01:20:36 2007 + +=pod \ No newline at end of file diff --git a/example/lib/MyServer/TestService/TestPort.pm b/example/lib/MyServer/TestService/TestPort.pm new file mode 100644 index 0000000..35ff18a --- /dev/null +++ b/example/lib/MyServer/TestService/TestPort.pm @@ -0,0 +1,145 @@ +package MyServer::TestService::TestPort; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use Scalar::Util qw(blessed); +use base qw(SOAP::WSDL::Client::Base); + +# only load if it hasn't been loaded before +require MyTypemaps::TestService + if not MyTypemaps::TestService->can('get_class'); + +my %transport_class_of :ATTR(:name :default); +my %transport_of :ATTR(:name :default<()>); +my %dispatch_to :ATTR(:name); + +my $action_map_ref = { + 'http://www.example.org/benchmark/ListPerson' => 'ListPerson', + +}; + +sub START { + my ($self, $ident, $arg_ref) = @_; + eval "require $transport_class_of{ $ident }" + 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 => 'MyTypemaps::TestService', + dispatch_to => $dispatch_to{ $ident }, + }); +} + +sub handle { + $transport_of{ ${ $_[0] } }->handle(); +} + +1; + + + +__END__ + +=pod + +=head1 NAME + +MyInterfaces::TestService::TestPort - SOAP Server Class for the TestService Web Service + +=head1 SYNOPSIS + + use MyServer::TestService::TestPort; + my $server = MyServer::TestService::TestPort->new({ + dispatch_to => 'My::Handler::Class', + transport_class => 'SOAP::WSDL::Server::CGI', # optional, default + }); + $server->handle(); + + +=head1 DESCRIPTION + +SOAP Server handler for the TestService web service +located at http://localhost:81/soap-wsdl-test/person.pl. + +=head1 SERVICE TestService + + + +=head2 Port TestPort + + + +=head1 METHODS + +=head2 General methods + +=head3 new + +Constructor. + +The C argument is mandatory. It must be a class or object +implementing the SOAP Service methods listed below. + +=head2 SOAP Service methods + +Your dispatch_to class has to implement the following methods: + +The examples below serve as copy-and-paste prototypes to use in your +class. + +=head3 ListPerson + + + + sub ListPerson { + my ($self, $body, $header) = @_; + # body is a ??? object - sorry, POD not implemented yet + # header is a ??? object - sorry, POD not implemented yet + + # do something with body and header... + + return MyElements::ListPersonResponse->new( { + out => { # MyTypes::ArrayOfPerson + NewElement => { # MyTypes::Person + PersonID => { # MyTypes::PersonID + ID => $some_value, # int + }, + Salutation => $some_value, # string + Name => $some_value, # string + GivenName => $some_value, # string + DateOfBirth => $some_value, # date + HomeAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + WorkAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + Contracts => { # MyTypes::ArrayOfContract + Contract => { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + }, + }, + }, + }, + ); + + } + + + +=head1 AUTHOR + +Generated by SOAP::WSDL on Mon Dec 3 22:20:32 2007 + +=pod \ No newline at end of file diff --git a/example/lib/MyTypemaps/BarCode.pm b/example/lib/MyTypemaps/BarCode.pm new file mode 100644 index 0000000..0765bea --- /dev/null +++ b/example/lib/MyTypemaps/BarCode.pm @@ -0,0 +1,61 @@ +package MyTypemaps::BarCode; +use strict; +use warnings; + +our $typemap_1 = { + 'GenerateBarCode/BarCodeText' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GenerateBarCode/BarCodeParam/BarColor' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GenerateBarCode/BarCodeParam/barcodeOption' => 'MyTypes::BarcodeOption', + 'GenerateBarCode/BarCodeParam/Left' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', + 'GenerateBarCode' => 'MyElements::GenerateBarCode', + 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GenerateBarCode/BarCodeParam/Angle' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'GenerateBarCode/BarCodeParam/Width' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', + 'GenerateBarCode/BarCodeParam/BarCodeImageFormat' => 'MyTypes::ImageFormats', + 'GenerateBarCode/BarCodeParam/BGColor' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GenerateBarCode/BarCodeParam/Ratio' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', + 'GenerateBarCode/BarCodeParam/Height' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'GenerateBarCode/BarCodeParam/CheckSum' => 'SOAP::WSDL::XSD::Typelib::Builtin::boolean', + 'GenerateBarCode/BarCodeParam/checkSumMethod' => 'MyTypes::CheckSumMethod', + 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GenerateBarCode/BarCodeParam/barcodeType' => 'MyTypes::BarcodeType', + 'GenerateBarCode/BarCodeParam/FontSize' => 'SOAP::WSDL::XSD::Typelib::Builtin::float', + 'GenerateBarCode/BarCodeParam/Top' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'GenerateBarCodeResponse/GenerateBarCodeResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::base64Binary', + 'GenerateBarCodeResponse' => 'MyElements::GenerateBarCodeResponse', + 'GenerateBarCode/BarCodeParam/Module' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'GenerateBarCode/BarCodeParam/showTextPosition' => 'MyTypes::ShowTextPosition', + 'GenerateBarCode/BarCodeParam' => 'MyTypes::BarCodeData', + 'GenerateBarCode/BarCodeParam/FontName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string' + }; +; + +sub get_class { + my $name = join '/', @{ $_[1] }; + exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; + return $typemap_1->{ $name }; +} + +sub get_typemap { + return $typemap_1; +} + +1; + +__END__ + +=pod + +=head1 NAME + +MyTypemaps::BarCode; - typemap for ::BarCode; + +=head1 DESCRIPTION + +Typemap created by SOAP::WSDL for map-based SOAP message parsers. + +=cut + diff --git a/example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm b/example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm new file mode 100644 index 0000000..5ac3313 --- /dev/null +++ b/example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm @@ -0,0 +1,52 @@ +package MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie; +use strict; +use warnings; + +our $typemap_1 = { + 'GetFortuneCookie' => 'MyElements::GetFortuneCookie', + 'CountCookiesResponse/CountCookiesResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', + 'readNodeCountResponse/readNodeCountResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'CountCookiesResponse' => 'MyElements::CountCookiesResponse', + 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GetSpecificCookieResponse' => 'MyElements::GetSpecificCookieResponse', + 'GetFortuneCookieResponse' => 'MyElements::GetFortuneCookieResponse', + 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', + 'GetSpecificCookie' => 'MyElements::GetSpecificCookie', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', + 'CountCookies' => 'MyElements::CountCookies', + 'GetSpecificCookie/index' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GetFortuneCookieResponse/GetFortuneCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GetSpecificCookieResponse/GetSpecificCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'readNodeCount' => 'MyElements::readNodeCount', + 'readNodeCountResponse' => 'MyElements::readNodeCountResponse' + }; +; + +sub get_class { + my $name = join '/', @{ $_[1] }; + exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; + return $typemap_1->{ $name }; +} + +sub get_typemap { + return $typemap_1; +} + +1; + +__END__ + +=pod + +=head1 NAME + +MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie; - typemap for ::FullerData_x0020_Fortune_x0020_Cookie; + +=head1 DESCRIPTION + +Typemap created by SOAP::WSDL for map-based SOAP message parsers. + +=cut + diff --git a/example/lib/MyTypemaps/GlobalWeather.pm b/example/lib/MyTypemaps/GlobalWeather.pm new file mode 100644 index 0000000..1cc863e --- /dev/null +++ b/example/lib/MyTypemaps/GlobalWeather.pm @@ -0,0 +1,48 @@ +package MyTypemaps::GlobalWeather; +use strict; +use warnings; + +our $typemap_1 = { + 'GetWeatherResponse/GetWeatherResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GetWeather' => 'MyElements::GetWeather', + 'GetCitiesByCountryResponse/GetCitiesByCountryResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', + 'GetWeatherResponse' => 'MyElements::GetWeatherResponse', + 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', + 'GetWeather/CityName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GetCitiesByCountry' => 'MyElements::GetCitiesByCountry', + 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GetCitiesByCountry/CountryName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'GetWeather/CountryName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', + 'GetCitiesByCountryResponse' => 'MyElements::GetCitiesByCountryResponse' + }; +; + +sub get_class { + my $name = join '/', @{ $_[1] }; + exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; + return $typemap_1->{ $name }; +} + +sub get_typemap { + return $typemap_1; +} + +1; + +__END__ + +=pod + +=head1 NAME + +MyTypemaps::GlobalWeather; - typemap for ::GlobalWeather; + +=head1 DESCRIPTION + +Typemap created by SOAP::WSDL for map-based SOAP message parsers. + +=cut + diff --git a/example/lib/MyTypemaps/HelloWorld.pm b/example/lib/MyTypemaps/HelloWorld.pm new file mode 100644 index 0000000..1a86e9e --- /dev/null +++ b/example/lib/MyTypemaps/HelloWorld.pm @@ -0,0 +1,44 @@ +package MyTypemaps::HelloWorld; +use strict; +use warnings; + +our $typemap_1 = { + 'sayHello/givenName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'sayHelloResponse' => 'MyElements::sayHelloResponse', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', + 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'sayHelloResponse/sayHelloResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', + 'sayHello' => 'MyElements::sayHello', + 'sayHello/name' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11' + }; +; + +sub get_class { + my $name = join '/', @{ $_[1] }; + exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; + return $typemap_1->{ $name }; +} + +sub get_typemap { + return $typemap_1; +} + +1; + +__END__ + +=pod + +=head1 NAME + +MyTypemaps::HelloWorld; - typemap for ::HelloWorld; + +=head1 DESCRIPTION + +Typemap created by SOAP::WSDL for map-based SOAP message parsers. + +=cut + diff --git a/example/lib/MyTypemaps/TestService.pm b/example/lib/MyTypemaps/TestService.pm new file mode 100644 index 0000000..de7c4f7 --- /dev/null +++ b/example/lib/MyTypemaps/TestService.pm @@ -0,0 +1,92 @@ +package MyTypemaps::TestService; +use strict; +use warnings; + +our $typemap_1 = { + 'ListPersonResponse/out/NewElement/WorkAddress/Street' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/Contracts' => 'MyTypes::ArrayOfContract', + 'ListPerson/in/HomeAddress/PhoneNumber' => 'MyTypes::PhoneNumber', + 'ListPersonResponse/out/NewElement/HomeAddress' => 'MyTypes::Address', + 'ListPersonResponse/out/NewElement/Contracts/Contract' => 'MyTypes::Contract', + 'ListPersonResponse/out/NewElement/HomeAddress/ZIP' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/WorkAddress/City' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/HomeAddress' => 'MyTypes::Address', + 'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI', + 'ListPerson/in/HomeAddress/City' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/WorkAddress/PhoneNumber' => 'MyTypes::PhoneNumber', + 'ListPerson/in/WorkAddress/ZIP' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/Contracts' => 'MyTypes::ArrayOfContract', + 'ListPerson/in/WorkAddress/Street' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in' => 'MyTypes::Person', + 'ListPersonResponse/out/NewElement/GivenName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/HomeAddress/PhoneNumber' => 'MyTypes::PhoneNumber', + 'ListPersonResponse/out/NewElement/HomeAddress/City' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement' => 'MyTypes::Person', + 'ListPerson/in/PersonID/ID' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'ListPerson/in/HomeAddress/Street' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/PersonID/ID' => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + 'ListPerson/in/HomeAddress/Country' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/GivenName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/HomeAddress/MobilePhoneNumber' => 'MyTypes::PhoneNumber', + 'ListPerson/in/Name' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/PersonID' => 'MyTypes::PersonID', + 'ListPersonResponse/out/NewElement/WorkAddress/MobilePhoneNumber' => 'MyTypes::PhoneNumber', + 'ListPersonResponse/out' => 'MyTypes::ArrayOfPerson', + 'ListPerson/in/Contracts/Contract' => 'MyTypes::Contract', + 'ListPersonResponse/out/NewElement/Name' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/WorkAddress/ZIP' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/DateOfBirth' => 'SOAP::WSDL::XSD::Typelib::Builtin::date', + 'ListPersonResponse/out/NewElement/HomeAddress/MobilePhoneNumber' => 'MyTypes::PhoneNumber', + 'ListPersonResponse/out/NewElement/HomeAddress/Country' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/HomeAddress/Street' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/Contracts/Contract/ContractName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11', + 'ListPerson/in/Contracts/Contract/ContractName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse' => 'MyElements::ListPersonResponse', + 'ListPersonResponse/out/NewElement/Salutation' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/WorkAddress/City' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::token', + 'ListPerson' => 'MyElements::ListPerson', + 'ListPerson/in/Salutation' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/WorkAddress/MobilePhoneNumber' => 'MyTypes::PhoneNumber', + 'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/WorkAddress/Country' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPerson/in/PersonID' => 'MyTypes::PersonID', + 'ListPerson/in/HomeAddress/ZIP' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/WorkAddress' => 'MyTypes::Address', + 'ListPersonResponse/out/NewElement/DateOfBirth' => 'SOAP::WSDL::XSD::Typelib::Builtin::date', + 'ListPerson/in/WorkAddress/PhoneNumber' => 'MyTypes::PhoneNumber', + 'ListPersonResponse/out/NewElement/WorkAddress/Country' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'ListPersonResponse/out/NewElement/Contracts/Contract/ContractID' => 'SOAP::WSDL::XSD::Typelib::Builtin::long', + 'ListPerson/in/Contracts/Contract/ContractID' => 'SOAP::WSDL::XSD::Typelib::Builtin::long', + 'ListPerson/in/WorkAddress' => 'MyTypes::Address' + }; +; + +sub get_class { + my $name = join '/', @{ $_[1] }; + exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__; + return $typemap_1->{ $name }; +} + +sub get_typemap { + return $typemap_1; +} + +1; + +__END__ + +=pod + +=head1 NAME + +MyTypemaps::TestService; - typemap for ::TestService; + +=head1 DESCRIPTION + +Typemap created by SOAP::WSDL for map-based SOAP message parsers. + +=cut + diff --git a/example/lib/MyTypes/Address.pm b/example/lib/MyTypes/Address.pm new file mode 100644 index 0000000..220f949 --- /dev/null +++ b/example/lib/MyTypes/Address.pm @@ -0,0 +1,98 @@ +package MyTypes::Address; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %Street_of :ATTR(:get); +my %ZIP_of :ATTR(:get); +my %City_of :ATTR(:get); +my %Country_of :ATTR(:get); +my %PhoneNumber_of :ATTR(:get); +my %MobilePhoneNumber_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + Street + ZIP + City + Country + PhoneNumber + MobilePhoneNumber + ) ], + { + Street => \%Street_of, + ZIP => \%ZIP_of, + City => \%City_of, + Country => \%Country_of, + PhoneNumber => \%PhoneNumber_of, + MobilePhoneNumber => \%MobilePhoneNumber_of, + }, + { + Street => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + ZIP => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + City => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + Country => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + PhoneNumber => 'MyTypes::PhoneNumber', + MobilePhoneNumber => 'MyTypes::PhoneNumber', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::Address + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +Address from the namespace http://www.example.org/benchmark/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + Street + ZIP + City + Country + PhoneNumber + MobilePhoneNumber + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/ArrayOfContract.pm b/example/lib/MyTypes/ArrayOfContract.pm new file mode 100644 index 0000000..5b2c0a9 --- /dev/null +++ b/example/lib/MyTypes/ArrayOfContract.pm @@ -0,0 +1,71 @@ +package MyTypes::ArrayOfContract; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %Contract_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + Contract + ) ], + { + Contract => \%Contract_of, + }, + { + Contract => 'MyTypes::Contract', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::ArrayOfContract + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +ArrayOfContract from the namespace http://www.example.org/benchmark/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + Contract + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::ArrayOfContract + Contract => { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/ArrayOfPerson.pm b/example/lib/MyTypes/ArrayOfPerson.pm new file mode 100644 index 0000000..9b6ae50 --- /dev/null +++ b/example/lib/MyTypes/ArrayOfPerson.pm @@ -0,0 +1,98 @@ +package MyTypes::ArrayOfPerson; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %NewElement_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + NewElement + ) ], + { + NewElement => \%NewElement_of, + }, + { + NewElement => 'MyTypes::Person', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::ArrayOfPerson + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +ArrayOfPerson from the namespace http://www.example.org/benchmark/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + NewElement + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::ArrayOfPerson + NewElement => { # MyTypes::Person + PersonID => { # MyTypes::PersonID + ID => $some_value, # int + }, + Salutation => $some_value, # string + Name => $some_value, # string + GivenName => $some_value, # string + DateOfBirth => $some_value, # date + HomeAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + WorkAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + Contracts => { # MyTypes::ArrayOfContract + Contract => { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + }, + }, + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/BarCodeData.pm b/example/lib/MyTypes/BarCodeData.pm new file mode 100644 index 0000000..aa742a1 --- /dev/null +++ b/example/lib/MyTypes/BarCodeData.pm @@ -0,0 +1,164 @@ +package MyTypes::BarCodeData; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %Height_of :ATTR(:get); +my %Width_of :ATTR(:get); +my %Angle_of :ATTR(:get); +my %Ratio_of :ATTR(:get); +my %Module_of :ATTR(:get); +my %Left_of :ATTR(:get); +my %Top_of :ATTR(:get); +my %CheckSum_of :ATTR(:get); +my %FontName_of :ATTR(:get); +my %BarColor_of :ATTR(:get); +my %BGColor_of :ATTR(:get); +my %FontSize_of :ATTR(:get); +my %barcodeOption_of :ATTR(:get); +my %barcodeType_of :ATTR(:get); +my %checkSumMethod_of :ATTR(:get); +my %showTextPosition_of :ATTR(:get); +my %BarCodeImageFormat_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + Height + Width + Angle + Ratio + Module + Left + Top + CheckSum + FontName + BarColor + BGColor + FontSize + barcodeOption + barcodeType + checkSumMethod + showTextPosition + BarCodeImageFormat + ) ], + { + Height => \%Height_of, + Width => \%Width_of, + Angle => \%Angle_of, + Ratio => \%Ratio_of, + Module => \%Module_of, + Left => \%Left_of, + Top => \%Top_of, + CheckSum => \%CheckSum_of, + FontName => \%FontName_of, + BarColor => \%BarColor_of, + BGColor => \%BGColor_of, + FontSize => \%FontSize_of, + barcodeOption => \%barcodeOption_of, + barcodeType => \%barcodeType_of, + checkSumMethod => \%checkSumMethod_of, + showTextPosition => \%showTextPosition_of, + BarCodeImageFormat => \%BarCodeImageFormat_of, + }, + { + Height => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Width => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Angle => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Ratio => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Module => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Left => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + Top => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + CheckSum => 'SOAP::WSDL::XSD::Typelib::Builtin::boolean', + FontName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + BarColor => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + BGColor => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + FontSize => 'SOAP::WSDL::XSD::Typelib::Builtin::float', + barcodeOption => 'MyTypes::BarcodeOption', + barcodeType => 'MyTypes::BarcodeType', + checkSumMethod => 'MyTypes::CheckSumMethod', + showTextPosition => 'MyTypes::ShowTextPosition', + BarCodeImageFormat => 'MyTypes::ImageFormats', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::BarCodeData + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +BarCodeData from the namespace http://www.webservicex.net/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + Height + Width + Angle + Ratio + Module + Left + Top + CheckSum + FontName + BarColor + BGColor + FontSize + barcodeOption + barcodeType + checkSumMethod + showTextPosition + BarCodeImageFormat + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::BarCodeData + Height => $some_value, # int + Width => $some_value, # int + Angle => $some_value, # int + Ratio => $some_value, # int + Module => $some_value, # int + Left => $some_value, # int + Top => $some_value, # int + CheckSum => $some_value, # boolean + FontName => $some_value, # string + BarColor => $some_value, # string + BGColor => $some_value, # string + FontSize => $some_value, # float + barcodeOption => $some_value, # BarcodeOption + barcodeType => $some_value, # BarcodeType + checkSumMethod => $some_value, # CheckSumMethod + showTextPosition => $some_value, # ShowTextPosition + BarCodeImageFormat => $some_value, # ImageFormats + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/BarcodeOption.pm b/example/lib/MyTypes/BarcodeOption.pm new file mode 100644 index 0000000..96c8aba --- /dev/null +++ b/example/lib/MyTypes/BarcodeOption.pm @@ -0,0 +1,56 @@ +package MyTypes::BarcodeOption; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::BarcodeOption + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +BarcodeOption from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/BarcodeType.pm b/example/lib/MyTypes/BarcodeType.pm new file mode 100644 index 0000000..b974c61 --- /dev/null +++ b/example/lib/MyTypes/BarcodeType.pm @@ -0,0 +1,56 @@ +package MyTypes::BarcodeType; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::BarcodeType + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +BarcodeType from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/CheckSumMethod.pm b/example/lib/MyTypes/CheckSumMethod.pm new file mode 100644 index 0000000..847228a --- /dev/null +++ b/example/lib/MyTypes/CheckSumMethod.pm @@ -0,0 +1,56 @@ +package MyTypes::CheckSumMethod; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::CheckSumMethod + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +CheckSumMethod from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/Contract.pm b/example/lib/MyTypes/Contract.pm new file mode 100644 index 0000000..4e0ead0 --- /dev/null +++ b/example/lib/MyTypes/Contract.pm @@ -0,0 +1,74 @@ +package MyTypes::Contract; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %ContractID_of :ATTR(:get); +my %ContractName_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + ContractID + ContractName + ) ], + { + ContractID => \%ContractID_of, + ContractName => \%ContractName_of, + }, + { + ContractID => 'SOAP::WSDL::XSD::Typelib::Builtin::long', + ContractName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::Contract + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +Contract from the namespace http://www.example.org/benchmark/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + ContractID + ContractName + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/ImageFormats.pm b/example/lib/MyTypes/ImageFormats.pm new file mode 100644 index 0000000..337184b --- /dev/null +++ b/example/lib/MyTypes/ImageFormats.pm @@ -0,0 +1,56 @@ +package MyTypes::ImageFormats; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::ImageFormats + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +ImageFormats from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/Person.pm b/example/lib/MyTypes/Person.pm new file mode 100644 index 0000000..fb0ea82 --- /dev/null +++ b/example/lib/MyTypes/Person.pm @@ -0,0 +1,131 @@ +package MyTypes::Person; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %PersonID_of :ATTR(:get); +my %Salutation_of :ATTR(:get); +my %Name_of :ATTR(:get); +my %GivenName_of :ATTR(:get); +my %DateOfBirth_of :ATTR(:get); +my %HomeAddress_of :ATTR(:get); +my %WorkAddress_of :ATTR(:get); +my %Contracts_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + PersonID + Salutation + Name + GivenName + DateOfBirth + HomeAddress + WorkAddress + Contracts + ) ], + { + PersonID => \%PersonID_of, + Salutation => \%Salutation_of, + Name => \%Name_of, + GivenName => \%GivenName_of, + DateOfBirth => \%DateOfBirth_of, + HomeAddress => \%HomeAddress_of, + WorkAddress => \%WorkAddress_of, + Contracts => \%Contracts_of, + }, + { + PersonID => 'MyTypes::PersonID', + Salutation => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + Name => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + GivenName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + DateOfBirth => 'SOAP::WSDL::XSD::Typelib::Builtin::date', + HomeAddress => 'MyTypes::Address', + WorkAddress => 'MyTypes::Address', + Contracts => 'MyTypes::ArrayOfContract', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::Person + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +Person from the namespace http://www.example.org/benchmark/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + PersonID + Salutation + Name + GivenName + DateOfBirth + HomeAddress + WorkAddress + Contracts + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::Person + PersonID => { # MyTypes::PersonID + ID => $some_value, # int + }, + Salutation => $some_value, # string + Name => $some_value, # string + GivenName => $some_value, # string + DateOfBirth => $some_value, # date + HomeAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + WorkAddress => { # MyTypes::Address + Street => $some_value, # string + ZIP => $some_value, # string + City => $some_value, # string + Country => $some_value, # string + PhoneNumber => $some_value, # PhoneNumber + MobilePhoneNumber => $some_value, # PhoneNumber + }, + Contracts => { # MyTypes::ArrayOfContract + Contract => { # MyTypes::Contract + ContractID => $some_value, # long + ContractName => $some_value, # string + }, + }, + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/PersonID.pm b/example/lib/MyTypes/PersonID.pm new file mode 100644 index 0000000..55ce4c3 --- /dev/null +++ b/example/lib/MyTypes/PersonID.pm @@ -0,0 +1,68 @@ +package MyTypes::PersonID; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %ID_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + ID + ) ], + { + ID => \%ID_of, + }, + { + ID => 'SOAP::WSDL::XSD::Typelib::Builtin::int', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::PersonID + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +PersonID from the namespace http://www.example.org/benchmark/. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + ID + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::PersonID + ID => $some_value, # int + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/PhoneNumber.pm b/example/lib/MyTypes/PhoneNumber.pm new file mode 100644 index 0000000..58bea0b --- /dev/null +++ b/example/lib/MyTypes/PhoneNumber.pm @@ -0,0 +1,56 @@ +package MyTypes::PhoneNumber; +use strict; +use warnings; + +sub get_xmlns { 'http://www.example.org/benchmark/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::PhoneNumber + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +PhoneNumber from the namespace http://www.example.org/benchmark/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/ShowTextPosition.pm b/example/lib/MyTypes/ShowTextPosition.pm new file mode 100644 index 0000000..42a8a1a --- /dev/null +++ b/example/lib/MyTypes/ShowTextPosition.pm @@ -0,0 +1,56 @@ +package MyTypes::ShowTextPosition; +use strict; +use warnings; + +sub get_xmlns { 'http://www.webservicex.net/'}; + +# derivation by restriction +use base qw( + SOAP::WSDL::XSD::Typelib::Builtin::string +); + + + +1; + +=pod + +=head1 MyTypes::ShowTextPosition + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined simpleType +ShowTextPosition from the namespace http://www.webservicex.net/. + +This clase is derived from SOAP::WSDL::XSD::Typelib::Builtin::string +. SOAP::WSDL's schema implementation does not validate data, so you can use it exactly +like it's base type. + +# Description of restrictions not implemented yet. + +=head1 METHODS + +=head2 new + +Constructor. + +=head2 get_value / set_value + +Getter and setter for the simpleType's value. + +=head1 OVERLOADING + +Depending on the simple type's base type, the following operations are overloaded + + Stringification + Numerification + Boolification + +Check L for more information. + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/test2.pm b/example/lib/MyTypes/test2.pm new file mode 100644 index 0000000..72366b8 --- /dev/null +++ b/example/lib/MyTypes/test2.pm @@ -0,0 +1,74 @@ +package MyTypes::test2; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %name_of :ATTR(:get); +my %givenName_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + name + givenName + ) ], + { + name => \%name_of, + givenName => \%givenName_of, + }, + { + name => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + givenName => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::test2 + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +test2 from the namespace urn:HelloWorld. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + name + givenName + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::test2 + name => $some_value, # string + givenName => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/lib/MyTypes/testExtended.pm b/example/lib/MyTypes/testExtended.pm new file mode 100644 index 0000000..5729a8a --- /dev/null +++ b/example/lib/MyTypes/testExtended.pm @@ -0,0 +1,68 @@ +package MyTypes::testExtended; +use strict; +use warnings; +use Class::Std::Fast::Storable constructor => 'none'; +use base qw(SOAP::WSDL::XSD::Typelib::ComplexType); + +Class::Std::initialize(); + +{ # BLOCK to scope variables + +my %extend_of :ATTR(:get); + +__PACKAGE__->_factory( + [ qw( + extend + ) ], + { + extend => \%extend_of, + }, + { + extend => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + } +); + +} # end BLOCK + + + + + + +1; + +=pod + +=head1 NAME + +MyTypes::testExtended + +=head1 DESCRIPTION + +Perl data type class for the XML Schema defined complextype +testExtended from the namespace urn:HelloWorld. + +=head2 PROPERTIES + +The following properties may be accessed using get_PROPERTY / set_PROPERTY +methods: + + extend + + +=head1 METHODS + +=head2 new + +Constructor. The following data structure may be passed to new(): + + { # MyTypes::testExtended + extend => $some_value, # string + }, + +=head1 AUTHOR + +Generated by SOAP::WSDL + +=cut + diff --git a/example/person.pl b/example/person.pl new file mode 100644 index 0000000..19ef578 --- /dev/null +++ b/example/person.pl @@ -0,0 +1,12 @@ +use strict; +use warnings; +use lib 'lib'; +use MyInterfaces::TestService::TestPort; + +my $soap = MyInterfaces::TestService::TestPort->new(); + +my $result = $soap->ListPerson({}) + or die "error calling SOAP method"; + +print "Found " . @{ $result->get_out()->get_NewElement } . " persons\n"; + diff --git a/example/person_compile.pl b/example/person_compile.pl new file mode 100644 index 0000000..df9f63b --- /dev/null +++ b/example/person_compile.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl -w +use strict; +use warnings; +use XML::Compile::WSDL11; +use XML::Compile::Transport::SOAPHTTP; + +my $wsdl = XML::Compile::WSDL11->new('wsdl/Person.wsdl'); + +# I have to lookup the methods from the WSDL +my $call = $wsdl->compileClient('ListPerson'); + +# I have to lookup the parameters from the WSDL +my $result = $call->({ in => undef}); + +die "Error calling soap method" if not defined $result; + +# I have to lookup the output parameters from the WSDL - or try Dumper +#use Data::Dumper; +#print Dumper $result; + +print "Found ", scalar @{ $result->{ parameters }->{ out }->{ seq_NewElement }->[0]->{ NewElement } } , " persons\n"; diff --git a/example/visitor/visitor.pl b/example/visitor/visitor.pl new file mode 100644 index 0000000..2918c56 --- /dev/null +++ b/example/visitor/visitor.pl @@ -0,0 +1,26 @@ +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); +} + + diff --git a/example/weather.pl b/example/weather.pl new file mode 100644 index 0000000..be8dd3a --- /dev/null +++ b/example/weather.pl @@ -0,0 +1,22 @@ +# Accessing the globalweather service at +# www.webservicex.net/GlobalWeather/GlobalWeather.asmx +# +# Note that the GlobalWeather web service returns a (quoted) XML structure - +# don't be surprised by the response's format. +# +# I have no connection to www.webservicex.net +# Use this script at your own risk. +# +# This script demonstrates the use of a interface generated by wsdl2perl.pl + +use lib 'lib/'; +use MyInterfaces::GlobalWeather::GlobalWeatherSoap; +my $weather = MyInterfaces::GlobalWeather::GlobalWeatherSoap->new(); +my $result = $weather->GetWeather({ CountryName => 'Germany', CityName => 'Munich' }); + +# boolean comparison overloaded +die $result->get_faultstring()->get_value() if not ($result); + +# The result is a XML string +# use get_value to avoid automatic entity encoding +print $result->get_GetWeatherResult()->get_value , "\n"; diff --git a/example/weather_wsdl.pl b/example/weather_wsdl.pl new file mode 100644 index 0000000..0053c46 --- /dev/null +++ b/example/weather_wsdl.pl @@ -0,0 +1,43 @@ +# Accessing the globalweather service at +# www.webservicex.net/GlobalWeather/GlobalWeather.asmx +# +# Note that the GlobalWeather web service returns a (quoted) XML structure - +# don't be surprised by the response's format. +# +# I have no connection to www.webservicex.net +# Use this script at your own risk. +# +# This script demonstrates the use of SOAP::WSDL in SOAP::Lite style. + +use lib 'lib/'; +use lib '../lib'; +use File::Basename qw(dirname); +use File::Spec; +my $path = File::Spec->rel2abs( dirname __FILE__); + +# SOAP::WSDL variant +use SOAP::WSDL; +my $soap = SOAP::WSDL->new(); +my $som = $soap->wsdl("file:///$path/wsdl/globalweather.xml") + ->call('GetWeather', GetWeather => + { CountryName => 'Germany', CityName => 'Munich' } +); + +die "Error" if $som->fault(); +print $som->result(); + +# SOAP::Lite variant: +# Note that you have to look both the proxy and the xmlns attribute +# set on the GetWeather SOAP::Data object from the WSDL. + +use SOAP::Lite +trace; +$soap = SOAP::Lite->new()->on_action( sub { join'/', @_ } ) + ->proxy("http://www.webservicex.net/globalweather.asmx"); # from WSDL +$som = $soap->call( + SOAP::Data->name('GetWeather') + ->attr({ xmlns => 'http://www.webserviceX.NET' }), # from WSDL + SOAP::Data->name('CountryName')->value('Germany'), + SOAP::Data->name('CityName')->value('Munich') +); +die "Error" if $som->fault(); +print $som->result(); diff --git a/example/wsdl/11_helloworld.wsdl b/example/wsdl/11_helloworld.wsdl new file mode 100644 index 0000000..6a170e9 --- /dev/null +++ b/example/wsdl/11_helloworld.wsdl @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/wsdl/FortuneCookie.xml b/example/wsdl/FortuneCookie.xml new file mode 100644 index 0000000..09afdc7 --- /dev/null +++ b/example/wsdl/FortuneCookie.xml @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Display the number of nodes specified in fortune XML document + + + + + Get a random fortune cookie from the XML document + + + + + Count the actual number of nodes in the XML document of fortunes + + + + + Get a specific cookie by the XML node number + + + + + + + Display the number of nodes specified in fortune XML document + + + + + Get a random fortune cookie from the XML document + + + + + Count the actual number of nodes in the XML document of fortunes + + + + + Get a specific cookie by the XML node number + + + + + + + Display the number of nodes specified in fortune XML document + + + + + Get a random fortune cookie from the XML document + + + + + Count the actual number of nodes in the XML document of fortunes + + + + + Get a specific cookie by the XML node number + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Simple XML-based fortune cookie + + + + + + + + + + + \ No newline at end of file diff --git a/example/wsdl/Person.wsdl b/example/wsdl/Person.wsdl new file mode 100644 index 0000000..26770b5 --- /dev/null +++ b/example/wsdl/Person.wsdl @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/wsdl/genericbarcode.xml b/example/wsdl/genericbarcode.xml new file mode 100644 index 0000000..6363039 --- /dev/null +++ b/example/wsdl/genericbarcode.xml @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WebserviceX.NET barcode library that provides the means to create barcodes for printing and display in any internet enabled applications. This web service supports Code 128, Industrial 2 of 5, Interleaved 2 of 5, Code 2 5 Matrix, Code 39, Code 39 Extended, Code 93, Code 93 Extended, Codabar, EAN13, EAN8, MSI, Postnet, Supp2, Supp5, UPC A, UPC E0 and UPC E1 barcode formats. This Barcodes returns byte image. It supports following image format JPEG, GIF, PNG, BMP, EMF, EXIF, ICON, MEMORY BMP, TIFF and WMF. + + + + + + + + + + + + + + + + + + + + + + + + + + Barcode generator + + + + + + + + + + + \ No newline at end of file diff --git a/example/wsdl/globalweather.xml b/example/wsdl/globalweather.xml new file mode 100644 index 0000000..b28974d --- /dev/null +++ b/example/wsdl/globalweather.xml @@ -0,0 +1,185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Get weather report for all major cities around the world. + + + + + Get all major cities by country name(full / part). + + + + + + + Get weather report for all major cities around the world. + + + + + Get all major cities by country name(full / part). + + + + + + + Get weather report for all major cities around the world. + + + + + Get all major cities by country name(full / part). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/SOAP/WSDL.pm b/lib/SOAP/WSDL.pm index e2b2f0f..5a53dfa 100644 --- a/lib/SOAP/WSDL.pm +++ b/lib/SOAP/WSDL.pm @@ -1,1001 +1,311 @@ -#!/usr/bin/perl -w package SOAP::WSDL; - -use SOAP::Lite; -use vars qw($VERSION @ISA); -use XML::XPath; -use Data::Dumper; - use strict; use warnings; -@ISA = qw(SOAP::Lite); - -$VERSION = "1.27"; - -# SOAP::Lite has changed the name for speciying a schema in 0.6? -# method before: schema -# method name after: schema_url -# -# Actually, we don't care which SOAP::Lite version there is, so we -# try to support whatever we find... -# -my $SCHEMA_URL = $SOAP::Lite::VERSION >= 0.6 ? 'schema_url' : 'schema'; - -sub wsdlinit -{ - my $self = shift; - my %opt = @_; - $self->{ _WSDL }->{ cache } = {}; - $self->{ _WSDL }->{ caching } = $opt{ caching }; - $self->{ _WSDL }->{ cache_directory } = $opt{ cache_directory } - if exists( $opt{ cache_directory } ); - $self->{ _WSDL }->{ checkoccurs } = 1 - unless defined( $self->{ _WSDL }->{ checkoccurs } ); - - if ( ( $self->{ _WSDL }->{ caching } ) - && ( !$self->{ _WSDL }->{ fileCache } ) ) - { - $self->wsdl_cache_init(); - } - - #makeup xpath document - my $xpath; - - # check cache - if ( $self->{ _WSDL }->{ fileCache } ) - { - - # get xpath from cache - $xpath = $self->{ _WSDL }->{ fileCache }->get( $self->wsdl ); - - # get in-memory cache from cache - if ( $self->{ _WSDL }->{ caching } ) - { - my $cache = - $self->{ _WSDL }->{ fileCache }->get( $self->wsdl . "_cache" ); - $self->{ _WSDL }->{ cache } = $cache || {}; - } ## end if ( $self->{ _WSDL }->... - } ## end if ( $self->{ _WSDL }->... - unless ( $xpath ) - { - no strict qw(refs); - $xpath = XML::XPath->new( - xml => $self->schema->$SCHEMA_URL( $self->wsdl() )->access ); - } ## end unless ( $xpath ) - - ( $xpath ) - || die "Error processing WSDL: Cannot create XPath object"; - - $self->_wsdl_xpath( $xpath ); - - # Get root element () and get - # default prefix (the root element's one). - my $definitions = undef; - $definitions = $xpath->find( '/*[1]' )->shift; - - my $prefix = $definitions->getPrefix; - $self->_wsdl_wsdlns( $prefix ? $prefix . ':' : '' ); - - # get the targetNamespace - my $tns = $definitions->getAttribute( 'targetNamespace' ) - || die - "Error processing WSDL: cannot get "; - - # look for schema namespace & prefix for targetNamespace - my ( $defaultNS, $schemaNS ) = ( '', '' ); - my @_ns_sub_list = (); - - my $nameSpaces = $definitions->getNamespaces - || die "Error processing WSDL: cannot get namespaces"; - my $nsHash = {}; - foreach my $ns ( @{ $nameSpaces } ) - { - $xpath->set_namespace( $ns->getPrefix, $ns->getData ); - if ( $ns->getData eq $tns ) - { - push @_ns_sub_list, $ns->getPrefix; - next; - } - - #------------------------------------------------------- - # Here we look for the default wsdl namespace which is used *only* - # when we are looking for the arrays restrictions. - # Originally the prefix was used for this, but sometimes the prefix - # can be omitted - #------------------------------------------------------- - $ns->getPrefix eq "#default" and next; - if ( $ns->getData eq "http://schemas.xmlsoap.org/wsdl/" ) - { - $self->_wsdl_wsdlExplicitNS( - $ns->getPrefix ? $ns->getPrefix . ":" : "" ); - } - - # the schema namespace is hardcoded in to the SOAP::Constants package, - # in the Lite.pm module - if ( defined $SOAP::Constants::XML_SCHEMAS{ $ns->getData } - and $SOAP::Constants::XML_SCHEMAS{ $ns->getData } =~ - /SOAP::XMLSchema\d+/ ) - { - $schemaNS = $ns->getPrefix; - } ## end if ( defined $SOAP::Constants::XML_SCHEMAS... - $nsHash->{ $ns->getData } = $ns->getPrefix . ':'; - } ## end foreach my $ns ( @{ $nameSpaces... - - $self->_wsdl_ns( $nsHash ); - $defaultNS = join( '|', @_ns_sub_list ); - - $self->_wsdl_tns( $defaultNS ); - $self->_wsdl_tns_uri( $tns ); - $self->_wsdl_schemans( $schemaNS ); - - #--- - #-- TBD: remove all the hardcoded urls - $self->_wsdl_soapns( - $self->_wsdl_ns->{ 'http://schemas.xmlsoap.org/wsdl/soap/' } ); - - #the default namespaces for types - $self->{ _WSDL }->{ _type_ns } = ""; - $self->_wsdl_schemans - and $self->{ _WSDL }->{ _type_ns } .= $self->_wsdl_schemans . ":|"; - - #TBD: the apache soap special case has to be handled elsewhere - $nsHash->{ 'http://xml.apache.org/xml-soap' } - and $self->{ _WSDL }->{ _type_ns } .= - $nsHash->{ 'http://xml.apache.org/xml-soap' } . "|"; - chop $self->{ _WSDL }->{ _type_ns }; - - $self->servicename( $opt{ servicename } ) if ( $opt{ servicename } ); - $self->portname( $opt{ portname } ) if ( $opt{ portname } ); - - # return something useful to ease testing... - return $self; - -} ## end sub wsdlinit - -sub _wsdl_init_port -{ - my $self = shift; - my $name = shift; - my $opt = shift; - my $xpath = $self->_wsdl_xpath; - my $tns = $self->_wsdl_tns; - - # Step one: get element - # - # This provides us with the address (enpoint/proxy), which we set here - # and the binding name. - - # Fetch _wsdl_wsdlns() - . 'definitions/' - . $self->_wsdl_wsdlns() .'service[@name="' . $self->servicename() - . '"]/' - . $self->_wsdl_wsdlns() . 'port[@name="' . $name . '"]/' - . $self->_wsdl_soapns() . 'address'; - - my $address = $xpath->find( $path )->shift - || die "Error processing WSDL file - no such port ($path)"; - my $endpoint = $address->getAttribute( 'location' ) - or die "No endpoint address found ($path)"; - - $self->proxy( $endpoint ); - - my $port = $address->getParentNode(); - my $binding_name = $port->getAttribute( 'binding' ); - - # Step two: get the correct element. - # This provides us with the portType name. - # Remember binding for later usage (in call() ) and - # - - # remove the default targetNamespace from messageName - $binding_name =~ s/^($tns)\:*//; - - $path = join( - $self->_wsdl_wsdlns, - ( - '/', - 'definitions/', - 'binding[@name="' . $binding_name . '"]', - ) - ); - - my $binding = $xpath->find( $path )->shift() - or die "no binding found ($path)"; - - $self->{ _WSDL }->{ binding } = $binding; - - my $portType_name = $binding->getAttribute( 'type' ); - - # remove the default targetNamespace from messageName - $portType_name =~ s/^($tns)\:*//; - - $path = join( - $self->_wsdl_wsdlns, - ( - '/', - 'definitions/', - 'portType[@name="' . $portType_name . '"]', - ) - ); - - # warn("looking for $path"); - my $portType = $xpath->find( $path )->shift() - or die "No portType found ($path)"; - $self->{ _WSDL }->{ portType } = $portType; - -} - -sub call -{ - my $self = shift; - my $method = shift; - my %data = @_; - - my $path; - my $location; - my $mode = 'input'; - - my $tns = $self->_wsdl_tns; - my $ns = $self->_wsdl_ns; - - my $xpath = $self->_wsdl_xpath; - - ( $xpath ) || do - { - $self->wsdlinit; - $xpath = $self->_wsdl_xpath - || die "Error processing WSDL: no wsdl object"; - }; - - # get the first port if none has been set... - $self->_get_first_port() if (not $self->portname() ); - - # initialize port if not done yet - $self->_wsdl_init_port( $self->portname() ) - if ( not $self->_wsdl_portType() ); - - my $portType = $self->_wsdl_portType(); - my $binding = $self->_wsdl_binding(); - - $path = join( - $self->_wsdl_wsdlns, - ( - # '/', - 'operation[@name="' . $method . '"]/', - $mode - ) - ); - - #overload: the user has provided a the input name for us - $data{ "wsdl_${mode}_name" } - and $path .= "[\@name='" . $data{ "wsdl_${mode}_name" } . "']"; - - # warn "Looking for operation $path"; - my $inputMessageName; - my $binding_operation_message = $binding->find( $path )->shift(); - if ($binding_operation_message) - { - my $binding_operation = $binding_operation_message->getParentNode(); - my $soapAction = $binding_operation->getAttribute( 'soapAction' ); - $self->on_action( sub { return "$soapAction" } ) if ($soapAction); - # warn "soapAction set to $soapAction\n"; - - #if defined, the input message name has to be the leading item - #in the SOAP call. If not defined, it has to be the operation - #name. In the case of overloaded calls, it *IS* the parameter passed - #by the calling script. So - - if ( $data{ "wsdl_${mode}_name" } ) - { - $inputMessageName = $data{ "wsdl_${mode}_name" }; - } - else - { - $inputMessageName = $binding_operation_message->getAttribute('name'); - } - - } - # just set it right if not set before: - $inputMessageName ||= $method; - - $path = join( - $self->_wsdl_wsdlns, - ( - '/', - 'definitions/', - 'binding[@name="' . $binding->getAttribute('name') . '"]/', - 'operation[@name="' . $method . '"]/', - "$mode/" - ) - ) - . $self->_wsdl_soapns . "body"; - - # warn "looking for $path..."; - my $callNamespace; - my $encodingStyle = q{}; - if (my $operation = $self->_wsdl_find( $path )->shift) - { - # warn "found operation:" . Dumper $operation; - #a call can have an associated, namespace - $callNamespace = $operation->getAttribute('namespace'); - #the encoding style is required when handling restricted complextypes - $encodingStyle = $operation->getAttribute( 'encodingStyle' ); - } - $callNamespace ||= $self->_wsdl_tns_uri; - - $self->wsdl_encoding( $self->_wsdl_ns->{ $encodingStyle } ) - if ($encodingStyle); - - $path = join( - $self->_wsdl_wsdlns, - ( - '/', 'definitions/', - 'portType[@name="' . $portType->getAttribute('name') . '"]/', - 'operation[@name="' . $method . '"]/', - $mode - ) - ); - - # overload: the calling script has to say wich overloading - # procedure call has to be encoded and forwarded to the server - - $data{ "wsdl_${mode}_name" } - and $path .= "[\@name='" . $data{ "wsdl_${mode}_name" } . "']"; - - $path .= "/\@message"; - my $messageName = $self->_wsdl_findvalue( $path, "dieIfError" ); - - $messageName =~ s/^($tns)\:*//; - - $path = join( - $self->_wsdl_wsdlns, - ( '/', 'definitions/', 'message[@name="' . $messageName . '"]/' - , 'part' ) - ); - - # warn "looking for $path..."; - - # An operation without parts is equivalent to a procedure - # call without parameters - # Though not very common, messages may have more than one part... - my $parts = $self->_wsdl_find( $path ); - - my @param = (); - while ( my $part = $parts->shift ) - { - my @enc = $self->encode( $part, \%data ); - push @param, @enc if ( @enc ); - } - - my $methodEncoded = - SOAP::Data->name( $inputMessageName ) - ->attr( { "xmlns" => $callNamespace } ); - unless ( $self->{ _WSDL }->{ no_dispatch } ) - { - return $self->SUPER::call( - $methodEncoded => @param, - @{ $data{ soap_headers } } - ); - } ## end unless ( $self->{ _WSDL }->... - else - { - return $methodEncoded, @param; - } -} ## end sub call - -# find the first servie and port for convenience - -sub _get_first_port -{ - my $self = shift; - my $url = shift; - my $xpath = $self->_wsdl_xpath(); - - # find /wsdl:definitions/wsdl:service/wsdl:port/soap:address - # use namespace prefixes from WSDL - they may differ... - # - # We head right for the address instead of just fetching the first - # port - we want to set the SOAP::Lite proxy, and accessing - # our parent is easier than running repeated XPath queries... - # - my $path = '/' . $self->_wsdl_wsdlns() . - 'definitions/' - . $self->_wsdl_wsdlns() .'service/' - . $self->_wsdl_wsdlns() . 'port/' - . $self->_wsdl_soapns() . 'address'; - - my @ports = $xpath->findnodes( $path ); - - return if ( not @ports ); - - my $address = shift @ports; - my $port = $address->getParentNode(); - my $service = $port->getParentNode(); - $self->servicename( $service->getAttribute( 'name' ) ); - $self->portname( $port->getAttribute( 'name' ) ); - - return $self; -} ## end sub _get_first_port - -sub DESTROY -{ - my $self = shift; - $self->wsdl_cache_store(); - return 1; -} - -#a sort of autoload for the store-and-return methods -sub _load_method -{ - my $method = shift; - my $param = shift; - no strict "refs"; - *$method = sub { - my $self = shift; - return ( @_ ) ? $self->{ _WSDL }->{ $param } = shift - : $self->{ _WSDL }->{ $param } ? $self->{ _WSDL }->{ $param } - : ""; - }; -} ## end sub _load_method - -sub portname { - my $self = shift; - if ( @_ ) - { - my $portname = shift; - if ( not defined($self->{ _WSDL }->{ portname }) - or ($portname ne ($self->{ _WSDL }->{ portname }) ) ) - { - $self->{ _WSDL }->{ portname } = $portname; - $self->_wsdl_init_port( $portname ); - } - } - if ($self->{ _WSDL }->{ 'portname' }) - { - return $self->{ _WSDL }->{ 'portname' } - }; +use 5.008; # require at least perl 5.8 + +use vars qw($AUTOLOAD); + +use Carp; +use Scalar::Util qw(blessed); +use SOAP::WSDL::Client; +use SOAP::WSDL::Expat::WSDLParser; +use Class::Std::Fast; +use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType; +use LWP::UserAgent; + +our $VERSION= '2.00_25'; + +my %no_dispatch_of :ATTR(:name); +my %wsdl_of :ATTR(:name); +my %proxy_of :ATTR(:name); +my %autotype_of :ATTR(:name); +my %outputxml_of :ATTR(:name :default<0>); +my %outputtree_of :ATTR(:name); +my %outputhash_of :ATTR(:name); +my %servicename_of :ATTR(:name); +my %portname_of :ATTR(:name); +my %class_resolver_of :ATTR(:name); + +my %method_info_of :ATTR(:default<()>); +my %port_of :ATTR(:default<()>); +my %porttype_of :ATTR(:default<()>); +my %binding_of :ATTR(:default<()>); +my %service_of :ATTR(:default<()>); +my %definitions_of :ATTR(:get :default<()>); +my %serialize_options_of :ATTR(:default<()>); + +my %client_of :ATTR(:name :default<()>); +my %keep_alive_of :ATTR(:name :default<0> ); + +my %LOOKUP = ( + no_dispatch => \%no_dispatch_of, + class_resolver => \%class_resolver_of, + wsdl => \%wsdl_of, + proxy => \%proxy_of, + autotype => \%autotype_of, + outputxml => \%outputxml_of, + outputtree => \%outputtree_of, + outputhash => \%outputhash_of, + portname => \%portname_of, + servicename => \%servicename_of, + keep_alive => \%keep_alive_of, +); + +sub readable { carp <<'EOT'; +'readable' has no effect any more. If you want formatted XML, +copy the debug output to your favorite XML editor and run the +source format command. +EOT return; } -&_load_method( "no_dispatch", "no_dispatch" ); -&_load_method( "wsdl", "wsdl" ); -&_load_method( "wsdl_checkoccurs", "checkoccurs" ); -&_load_method( "servicename", "servicename" ); -#&_load_method( "portname", "portname" ); -&_load_method( "wsdl_cache_directory", "cache_directory" ); -&_load_method( "wsdl_encoding", "wsdl_encoding" ); -&_load_method( "_wsdl_ns", "namespaces" ); -&_load_method( "_wsdl_xpath", "xpath" ); -&_load_method( "_wsdl_tns", "tns" ); -&_load_method( "_wsdl_tns_uri", "tns_uri" ); -&_load_method( "_wsdl_wsdlns", "wsdlns" ); -&_load_method( "_wsdl_schemans", "schemans" ); -&_load_method( "_wsdl_soapns", "soapns" ); -&_load_method( "_wsdl_wsdlExplicitNS", "wsdl_wsdlExplicitNS" ); -&_load_method( "_wsdl_binding", "binding" ); -&_load_method( "_wsdl_portType", "portType" ); +sub set_readable; *set_readable = \&readable; -#each call to make finder returns a wrapped version of the xpath calls. -#find, findvalue, findnodes and so on -#the cache checking part is hidden here -sub _make_finder() -{ - my ( $method, $call ) = @_; - no strict "refs"; - *$method = sub { - my $self = shift; - my ( $path, $dieIfError ) = @_; - my $data = ""; +for my $method (keys %LOOKUP ) { + no strict qw(refs); ## no critic (ProhibitNoStrict) + *{ $method } = sub { + my $self = shift; + my $ident = ident $self; + if (@_) { + $LOOKUP{ $method }->{ $ident } = shift; + return $self; + } + return $LOOKUP{ $method }->{ $ident }; + }; +} - $data = $self->{ _WSDL }->{ cache }->{ $path }; - unless ( $data ) - { - $data = $self->_wsdl_xpath->$call( $path ); - $self->{ _WSDL }->{ cache }->{ $path } = $data - if ( $self->{ _WSDL }->{ caching } ); - } ## end unless ( $data ) - if ( !$data ) - { - $dieIfError - and - print( "Error processing WSDL: can't find the path '$path'\n" ), - exit; - } ## end if ( !$data ) - return $data; - }; -} ## end sub _make_finder() +{ # just a BLOCK for scoping warnings. -&_make_finder( "_wsdl_find", "find" ); -&_make_finder( "_wsdl_findvalue", "findvalue" ); -&_make_finder( "_wsdl_findnodes", "findnodes" ); + # we need to roll our own for supporting + # SOAP::WSDL->new( key => value ) syntax, + # like SOAP::Lite does. Class::Std enforces a single hash ref as + # parameters to new() + no warnings qw(redefine); ## no critic ProhibitNoWarnings; -sub wsdl_cache_store -{ - my $self = shift; - if ( ( $self->{ _WSDL }->{ cache_directory } ) - && ( $self->{ _WSDL }->{ fileCache } ) ) - { - $self->{ _WSDL }->{ fileCache } - ->set( $self->wsdl, $self->{ _WSDL }->{ xpath } ); - $self->{ _WSDL }->{ fileCache } - ->set( $self->wsdl . "_cache", $self->{ _WSDL }->{ cache } ); - } ## end if ( ( $self->{ _WSDL ... -} ## end sub wsdl_cache_store + sub new { + my ($class, %args_from) = @_; + my $self = \do { my $foo = Class::Std::Fast::ID() }; + bless $self, $class; + for (keys %args_from) { + my $method = $self->can("set_$_") + or croak "unknown parameter $_ passed to new"; + $method->($self, $args_from{$_}); + } -sub wsdl_cache_init -{ - my $self = shift; - my $p = shift || {}; # get custom params - or none... - my $cache = undef; - eval { require Cache::FileCache; }; - if ( $@ ) - { - # warn about missing Cache::FileCache and set cache hadnle to undef - warn "File caching is enabled, but you do not have the " - . "Cache::FileCache module. Disabling Filesystem caching." - if ( $self->{ _WSDL }->{ cache_directory } ); - $self->{ _WSDL }->{ fileCache } = undef; - } ## end if ( $@ ) - else - { - # initialize cache from custom parameters if given - $p->{ cache_root } ||= $self->{ _WSDL }->{ cache_directory }; - $cache = Cache::FileCache->new( $p ); - } ## end else [ if ( $@ ) - $self->{ _WSDL }->{ fileCache } = $cache; -} ## end sub wsdl_cache_init + my $ident = ident $self; + $self->wsdlinit() if ($wsdl_of{ $ident }); + $client_of{ $ident } = SOAP::WSDL::Client->new(); + return $self; + } +} -sub encode -{ +sub wsdlinit { + my ($self, %opt) = @_; + my $ident = ident $self; - my $self = shift; - my $part = shift; - my $data = shift; + my $lwp = LWP::UserAgent->new( + $keep_alive_of{ $ident } + ? (keep_alive => 1) + : () + ); + my $response = $lwp->get( $wsdl_of{ $ident } ); + croak $response->message() if ($response->code != 200); - my $schemaNS = $self->_wsdl_schemans ? $self->_wsdl_schemans . ':' : ''; - my $defaultNS = $self->{ _WSDL }->{ tns }; + my $parser = SOAP::WSDL::Expat::WSDLParser->new(); + $parser->parse_string( $response->content() ); - my %nsHash = reverse %{ $self->_wsdl_ns }; - my %nsURIs = %{ $self->_wsdl_ns }; + my $wsdl_definitions = $parser->get_data(); - #TBD: Caching hook ? - my $p = { - name => $part->findvalue( '@name' )->value, - type => $part->findvalue( '@type' )->value, - element => $part->findvalue( '@element' )->value, - xmlns => $part->findvalue( '@targetNamespace' )->value, - nillable => $part->findvalue( '@nillable' )->value, - }; + # sanity checks + my $types = $wsdl_definitions->first_types() + or croak "unable to extract schema from WSDL"; + my $ns = $wsdl_definitions->get_xmlns(); - my $result = undef; - my $order = undef; - my $typeName = undef; - my $typeNS = ""; - my $type = ""; + # setup lookup variables + $definitions_of{ $ident } = $wsdl_definitions; + $serialize_options_of{ $ident } = { + autotype => 0, + typelib => $types, + namespace => $ns, + }; - my $default = $part->findvalue( '@default' )->value; - if ( $default eq "0" or $default ) - { - $p->{ default } = $default; - } + $servicename_of{ $ident } = $opt{servicename} if $opt{servicename}; + $portname_of{ $ident } = $opt{portname} if $opt{portname}; + return $self; +} ## end sub wsdlinit - if ( ( $p->{ type } ) ) - { - if ( $p->{ type } =~ m!($defaultNS):(.*)! ) - { - $typeName = $2; +sub _wsdl_get_service :PRIVATE { + my $ident = ident shift; + my $wsdl = $definitions_of{ $ident }; + return $service_of{ $ident } = $servicename_of{ $ident } + ? $wsdl->find_service( $wsdl->get_targetNamespace() , $servicename_of{ $ident } ) + : $service_of{ $ident } = $wsdl->get_service()->[ 0 ]; +} ## end sub _wsdl_get_service - #looking for type restrictions - my $path = join( $self->_wsdl_wsdlns, - '/', 'definitions/', "types/${schemaNS}schema/" ) - . "${schemaNS}simpleType[\@name='$typeName']/" - . "${schemaNS}restriction" . "|" - . join( $self->_wsdl_wsdlns, - '/', 'definitions/', "types/${schemaNS}schema/" ) - . "${schemaNS}complexType[\@name='$typeName']/${schemaNS}complexContent/" - . "${schemaNS}restriction"; +sub _wsdl_get_port :PRIVATE { + my $ident = ident shift; + my $wsdl = $definitions_of{ $ident }; + my $ns = $wsdl->get_targetNamespace(); + return $port_of{ $ident } = $portname_of{ $ident } + ? $service_of{ $ident }->get_port( $ns, $portname_of{ $ident } ) + : $port_of{ $ident } = $service_of{ $ident }->get_port()->[ 0 ]; +} +sub _wsdl_get_binding :PRIVATE { + my $self = shift; + my $ident = ident $self; + my $wsdl = $definitions_of{ $ident }; + my $port = $self->_wsdl_get_port(); + $binding_of{ $ident } = $wsdl->find_binding( $port->expand( $port->get_binding() ) ) + or croak "no binding found for ", $port->get_binding(); + return $binding_of{ $ident }; +} +sub _wsdl_get_portType :PRIVATE { + my $self = shift; + my $ident = ident $self; + my $wsdl = $definitions_of{ $ident }; + my $binding = $self->_wsdl_get_binding(); + $porttype_of{ $ident } = $wsdl->find_portType( $binding->expand( $binding->get_type() ) ) + or croak "cannot find portType for " . $binding->get_type(); + return $porttype_of{ $ident }; +} +sub _wsdl_init_methods :PRIVATE { + my $self = shift; + my $ident = ident $self; + my $wsdl = $definitions_of{ $ident }; + my $ns = $wsdl->get_targetNamespace(); - #usually there is only one restriction - #my $simpleType = $self->{_WSDL}->{xpath}->find($path)->shift; - my $simpleType = $self->_wsdl_find( $path, "" )->shift; - $simpleType - and my $baseType = $simpleType->findvalue( '@base' )->value; + # get bindings, portType, message, part(s) - use private methods for clear separation... + $self->_wsdl_get_service if not ($service_of{ $ident }); + $self->_wsdl_get_portType(); - #TBD: verify if the data matches the restrictions - #-- - #now we have (hopely) the base type - my $wsdl_encoding = $self->wsdl_encoding(); + $method_info_of{ $ident } = {}; - if ( defined( $baseType ) - and $baseType eq $wsdl_encoding . "Array" ) - { + foreach my $binding_operation (@{ $binding_of{ $ident }->get_operation() }) + { + my $method = {}; - #the type is an array restricted of something - #-- - $type = $baseType; - $type =~ s/^$schemaNS/xsd:/; + # get SOAP Action + # SOAP-Action is a required HTTP Header, so we need to look it up... + my $soap_binding_operation = $binding_operation->get_operation()->[0]; + $method->{ soap_action } = $soap_binding_operation ? + $soap_binding_operation->get_soapAction() : $method; - #-- + # get parts + # 1. get operation from port + my $operation = $porttype_of{ $ident }->find_operation( $ns, + $binding_operation->get_name() ); - #if the basetype is Array then we ask: Array of what? - #only complexTypes can be restricted to an Array - my $path = join( $self->_wsdl_wsdlns, - '/', 'definitions/', "types/${schemaNS}schema/" ) - . "${schemaNS}complexType[\@name='$typeName']/${schemaNS}complexContent/" - . "${schemaNS}restriction/" - . "${schemaNS}attribute"; + # 2. get input message name + my ( $prefix, $localname ) = split /:/xm, + $operation->first_input()->get_message(); - my $simpleType = - $self->{ _WSDL }->{ xpath }->find( $path )->shift; - $simpleType - and $baseType = - $simpleType->findvalue( - '@' . ( $self->_wsdl_wsdlExplicitNS ) . 'arrayType' ) - ->value; + # 3. get input message + my $message = $wsdl->find_message( $ns, $localname ) + or croak "Message {$ns}$localname not found in WSDL definition"; - #and now we have (eventually) the base type - $baseType =~ s/..$//; - } ## end if ( defined( $baseType... - $baseType and $p->{ type } = $baseType; - } ## end if ( $p->{ type } =~ m!($defaultNS):(.*)!... + if (my $body=$binding_operation->first_input()->first_body()) { + if ($body->get_parts()) { + $method->{ parts } = []; # make sure it's empty + my $message_part_ref = $message->get_part(); + for my $name ( split m{\s}xm , $body->get_parts() ) { + $name =~s{ \A [^:]+: }{}xm; # throw away ns prefix + # could probably made more efficient, but our lists are + # usually quite short + push @{ $method->{ parts } }, + grep { $_->get_name() eq $name } @{ $message_part_ref }; + } + } + } + $method->{ parts } ||= $message->get_part(); - #Now, we have p, and p has a type - #and the type of p is (eventually) extracted from some restriction + # rpc / encoded methods may have a namespace specified. + # look it up and set it... + $method->{ namespace } = $binding_operation + ? do { + my $input = $binding_operation->first_input(); + $input ? $input->first_body()->get_namespace() : undef; + } + : undef; - #In order to get the correct type, now we have to handle the imported - #namespaces. Some wsdl files have multiple schema declaration. - #And each declaration can have her own imported namespaces. - #Plainly: for each type check we have to check the schemas chain - #in order to get the imported namespaces for *that* schema + $method_info_of{ $ident }->{ $binding_operation->get_name() } = $method; + } - #- _type_ns contains the typical default namespaces - $typeNS = $self->{ _WSDL }->{ _type_ns }; + return $method_info_of{ $ident }; +} - $p->{ type } =~ /(.*:)(.*)/; - if ( $1 ne $schemaNS ) - { +sub call { + my ($self, $method, @data_from) = @_; + my $ident = ${ $self }; - #the type of p don't belongs to some default schema type - #first we look after the schema who owns our type - my $path = join( $self->_wsdl_wsdlns, - '/', 'definitions/', "types/${schemaNS}schema/" ) - . "*[\@name='$2']"; + my ($data, $header) = ref $data_from[0] + ? ($data_from[0], $data_from[1] ) + : (@data_from>1) + ? ( { @data_from }, undef ) + : ( $data_from[0], undef ); - my $schema = $self->_wsdl_find( "$path/..", "" )->shift; - my $nodeSet = - $self->_wsdl_find( - "$path/preceding-sibling::${schemaNS}import" ); - while ( my $node = $nodeSet->shift ) - { - no warnings; - $typeNS .= "|" - . $self->_wsdl_ns->{ $node->getAttribute( 'namespace' ) }; - } ## end while ( my $node = $nodeSet... + $self->wsdlinit() if not ($definitions_of{ $ident }); + $self->_wsdl_init_methods() if not ($method_info_of{ $ident }); -#if the schema has a default nameSpace, it has to be added to the added to dhe typeNs list + my $client = $client_of{ $ident }; - my $schemaTargetNS = $schema->findvalue( '@targetNamespace' ); - if ( $schemaTargetNS ) - { - defined $self->_wsdl_ns->{ $schemaTargetNS } - and $typeNS .= "|" . $self->_wsdl_ns->{ $schemaTargetNS }; - } - } ## end if ( $1 ne $schemaNS ) + # pass-through keep_alive if we need it... + $client->set_proxy( $proxy_of{ $ident } + || $port_of{ $ident }->first_address()->get_location(), + $keep_alive_of{ $ident } ? (keep_alive => 1) : (), + ); - if ( $p->{ type } =~ m/^$typeNS/ ) - { #it's a simple type + $client->set_no_dispatch( $no_dispatch_of{ $ident } ); + $client->set_outputxml( $outputxml_of{ $ident } ? 1 : 0 ); - #symple types can have default values - if ( !exists $data->{ $p->{ name } } - or !defined $data->{ $p->{ name } } ) - { - if ( defined $p->{ default } ) - { - $data->{ $p->{ name } } = $p->{ default }; - } - } ## end if ( !exists $data->{ ... + # only load ::Deserializer::SOM if we really need to deserialize to SOM. + # maybe we should introduce something like $output{ $ident } with a fixed + # set of values - m{^(TREE|HASH|XML|SOM)$}xms ? + if ( ( ! $outputtree_of{ $ident } ) + && ( ! $outputhash_of{ $ident } ) + && ( ! $outputxml_of{ $ident } ) + && ( ! $no_dispatch_of{ $ident } ) ) { + require SOAP::WSDL::Deserializer::SOM; + $client->set_deserializer( SOAP::WSDL::Deserializer::SOM->new() ); + }; - #-- this stuff is supposed to check the occurrences - my $count = -1; - if ( $self->{ _WSDL }->{ checkoccurs } ) - { - $count = - exists $data->{ $p->{ name } } - ? defined $data->{ $p->{ name } } - ? ref $data->{ $p->{ name } } eq 'ARRAY' - ? scalar @{ $data->{ $p->{ name } } } - : 1 - : 0 - : 0; + my $method_info = $method_info_of{ $ident }->{ $method }; - $order = $part->getParentNode()->getName; - $p->{ minOccurs } = $part->findvalue( '@minOccurs' )->value; - if ( ( !defined( $p->{ minOccurs } ) ) - || ( $p->{ minOccurs } eq "" ) ) - { - if ( $order eq 'sequence' ) - { - $p->{ minOccurs } = 1; - } - elsif ( $order eq 'all' ) - { - $p->{ minOccurs } = 0; - } - else - { - $p->{ minOccurs } = 0; - } - } ## end if ( ( !defined( $p->{... + # TODO serialize both header and body, not only header + my (@response) = (blessed $data) + ? $client->call( { + operation => $method, + soap_action => $method_info->{ soap_action }, + }, $data ) + : do { + my $content = q{}; + # TODO support RPC-encoding: Top-Level element + namespace... + foreach my $part ( @{ $method_info->{ parts } } ) { - $p->{ maxOccurs } = $part->findvalue( '@maxOccurs' )->value; - if ( ( !defined( $p->{ maxOccurs } ) ) - || ( $p->{ maxOccurs } eq "" ) ) - { - if ( $order eq 'sequence' ) { $p->{ maxOccurs } = 1 } - elsif ( $order eq 'all' ) { $p->{ maxOccurs } = 1 } - else { $p->{ maxOccurs } = undef } - } ## end if ( ( !defined( $p->{... - $p->{ maxOccurs } = undef - if ( defined( $p->{ maxOccurs } ) - && $p->{ maxOccurs } eq 'unbounded' ); - } ## end if ( $self->{ _WSDL }->... - - # check for ocurrence ? - # acceptable number of value ? - if ( - ( !$self->{ _WSDL }->{ checkoccurs } ) - || ( ( $p->{ minOccurs } <= $count ) - || ( $p->{ nillable } eq "true" ) ) - && ( ( !defined( $p->{ maxOccurs } ) ) - || ( $count <= $p->{ maxOccurs } ) ) - ) - { - - # not nillable - # empty value - ( !$p->{ nillable } ) - && ( ( !( exists $data->{ $p->{ name } } ) ) - || ( !( defined $data->{ $p->{ name } } ) ) ) - && do - { - return (); - }; - - # some value - - # SOAP::Lite uses the "xsd" prefix for specifying schema NS - my $type = $p->{ type }; - $type =~ s/^$schemaNS/xsd:/; - $result = SOAP::Data->new( name => $p->{ name } ); - $result->type( $type ) if ( $self->autotype ); - $result->attr( { xmlns => $p->{ xmlns } } ) if $p->{ xmlns }; - return ( $result->value( $data->{ $p->{ name } } ) ); - } ## end if ( ( !$self->{ _WSDL... - else - { - no warnings; - die "illegal number of elements ($count, min: " - . $p->{ minOccurs } - . ", max: ." - . $p->{ maxOccurs } - . ") for element '$p->{ name }' (may be sub-element) "; - } ## end else [ if ( ( !$self->{ _WSDL... - - } ## end if ( $p->{ type } =~ m/^$typeNS/... - else - { ### must be a complex type - ### get complex type - my $type = $p->{ type }; - $type =~ s/^($defaultNS)\://; # - $type =~ s/^(.+?\:)?//; - my $path; - { - no warnings; - - $path = '/' - . $self->_wsdl_wsdlns - . 'definitions/' - . $self->_wsdl_wsdlns - . "types/${schemaNS}schema/" - . "${schemaNS}complexType[\@name='$type']" . '|' . '/' - . $self->_wsdl_wsdlns - . 'definitions/' - . $self->_wsdl_wsdlns - . "types/schema[\@xmlns='" - . $nsHash{ $schemaNS } - . "' and \@targetNameSpace = '" - . $nsHash{ $1 } . "' ]/" - . "complexType[\@name='$type']"; - }; - - my $complexType = $self->_wsdl_find( $path, "dieIfError" )->shift; - - ### handles arrays of complex types - ### TBD: check for min /max number of elements - if ( ref $data->{ $p->{ name } } eq 'ARRAY' ) - { - - #$data says: look, in this position I have for you an array of stuff - my @resultArray = (); - foreach my $subdata ( @{ $data->{ $p->{ name } } } ) - { - $result = SOAP::Data->new( name => $p->{ name } ); - $result->type( $type ) if ( $self->autotype ); - $result->attr( { xmlns => $p->{ xmlns } } ) - if $p->{ xmlns }; - my $value = - $self->_encodeComplexType( $complexType, $subdata ); - push @resultArray, $result->value( $value ) - if ( defined( $value ) ); - } ## end foreach my $subdata ( @{ $data... - return ( @resultArray ) ? @resultArray : (); - } ## end if ( ref $data->{ $p->... - else - { - $result = SOAP::Data->new( name => $p->{ name } ); - - #.Net compatibility $result->type( $type ) if ($self->autotype); - $result->attr( { xmlns => $p->{ xmlns } } ) if $p->{ xmlns }; - my $value; - - # - if ( $data->{ $p->{ name } } ) - { #we have some data to encode - $value = - $self->_encodeComplexType( $complexType, - $data->{ $p->{ name } } ); - } ## end if ( $data->{ $p->{ name... - else - { - $p->{ minOccurs } = - $part->findvalue( '@minOccurs' )->value; - if ( $p->{ minOccurs } ne '' and $p->{ minOccurs } > 0 ) - { - - #this element is required, but we have no data to encode - #it's an error - die "illegal number of elements (0, min: " - . $p->{ minOccurs } - . ", for element '$p->{ name }' (may be sub-element) "; - } ## end if ( $p->{ minOccurs }... - } ## end else [ if ( $data->{ $p->{ name... - return () unless ( defined( $value ) ); - return ( $result->value( $value ) ); - } ## end else [ if ( ref $data->{ $p->... - } ## end else [ if ( $p->{ type } =~ m/^$typeNS/... - } ## end if ( ( $p->{ type } ) ... - elsif ( $p->{ element } ) - { - - #if p has no type, then must be an an element (or an error) - #which one? - my $elementPath = $p->{ element }; - - $elementPath =~ s/^(:?$defaultNS)\://; - - # there are two ways how schema are usually defined - my $path = '/' - . $self->_wsdl_wsdlns - . 'definitions/' - . $self->_wsdl_wsdlns - . 'types/' - . $schemaNS - . 'schema/' - . $schemaNS - . 'element[@name="' - . $elementPath . '"]/' - . $schemaNS - . 'complexType/' - . 'descendant::' - . $schemaNS - . 'element'; - - my $elements = $self->_wsdl_findnodes( $path, "dieIfError" ); - - my @resultArray = (); - while ( my $e = $elements->shift ) - { - my @enc; - @enc = $self->encode( $e, $data ); - push @resultArray, @enc if ( @enc ); - } ## end while ( my $e = $elements... - return ( @resultArray ) ? @resultArray : (); - } ## end elsif ( $p->{ element } ) - else - { - - #typical case when coping with .Net generated wsdl files - ( $p->{ name } eq "anyType" ) - and print -"Oops, have you defined an ArrayOfAnyType without the Type? Try type=[namespace]:anyType\n"; - die "illegal part definition\n"; - } ## end else [ if ( ( $p->{ type } ) ... - return (); # if we got here, something went wrong... -} ## end sub encode - -sub _encodeComplexType -{ - my $self = shift; - my $complexType = shift; - my $data = shift; - my @result = (); - my $schemaNS = $self->_wsdl_schemans ? $self->_wsdl_schemans . ':' : ''; - my $defaultNS = $self->_wsdl_tns; - my %nsHash = reverse %{ $self->_wsdl_ns }; - - #-- first we encode the local elements .... - my $path = './/' . $schemaNS . 'element'; - my $elements = $complexType->find( $path ); - while ( my $e = $elements->shift ) - { - my @enc; - @enc = $self->encode( $e, $data ); - push @result, @enc if ( @enc ); - } ## end while ( my $e = $elements... - - my $extension = undef; - ### check for extension -#%baseList avoids loops while looking at the extensions chain, just a flag holder - my %baseList = (); - - #... and then we cope with the chain of extensions - while ( $extension = - $complexType->find( './/' . $schemaNS . 'extension' )->shift ) - { - ### pull in extension base - my $base = $extension->findvalue( '@base' ); - $base =~ s/^$defaultNS\://; - $base =~ s/^(.+?\:)//; - - #- - last if ( $baseList{ $base } ); #got a loop - $baseList{ $base } = 1; - - #- - my $path; - { - no warnings; - - # there are two ways how schema are usually defined - $path = '/' - . $self->_wsdl_wsdlns - . 'definitions/' - . $self->_wsdl_wsdlns - . "types/" - . $schemaNS - . "schema/" - . $schemaNS - . "complexType[\@name='$base']" . '|' . '/' - . $self->_wsdl_wsdlns - . 'definitions/' - . $self->_wsdl_wsdlns - . "types/schema[\@xmlns='" - . $nsHash{ $schemaNS } - . "' and \@targetNameSpace = '" - . $nsHash{ $1 } . "' ]/" - . "complexType[\@name='$base']"; - } - - $complexType = $self->_wsdl_find( $path, "dieIfError" )->shift; - - #now we can find the elements - $path = ".//" . $schemaNS . "element|.//element"; - my $elements = $complexType->find( $path ) - || die "Error processing WSDL: '$path' not found"; - - while ( my $e = $elements->shift ) - { - my @enc; - @enc = $self->encode( $e, $data ); - push @result, @enc if ( @enc ); - } ## end while ( my $e = $elements... - } ## end while ( $extension = $complexType... - return ( @result ) ? \SOAP::Data->value( @result ) : (); -} ## end sub _encodeComplexType + $content .= $part->serialize( $method, $data, + { + %{ $serialize_options_of{ $ident } } + } ); + } + $client->call( + { + operation => $method, + soap_action => $method_info->{ soap_action } + }, + # absolutely stupid, but we need a reference which + # serializes to XML on stringification... + SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new({ + value => $content + }), + SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new({ + value => $header + }) + ); + }; + return if not @response; # nothing to do for one-ways + return wantarray ? @response : $response[0]; +} 1; __END__ @@ -1006,568 +316,424 @@ __END__ SOAP::WSDL - SOAP with WSDL support +=head1 Overview + +For creating Perl classes instrumenting a web service with a WSDL definition, +read L. + +For using an interpreting (thus slow and somewhat troublesome) WSDL based +SOAP client, which mimics L's API, read on. + =head1 SYNOPSIS - use SOAP::WSDL; - - my $soap = SOAP::WSDL->new( wsdl => 'http://server.com/ws.wsdl' ); - $soap->wsdlinit(); - $soap->servicename( 'myservice' ); - $soap->portname( 'myport' ); - - my $som = $soap->call( 'method' => ( - name => 'value' , - name => 'value' ) ); - + my $soap = SOAP::WSDL->new( + wsdl => 'file://bla.wsdl', + ); + + my $result = $soap->call('MyMethod', %data); =head1 DESCRIPTION -This is mainly a bugfix update to 1.22, which was a small update to 1.21 -- autodetection of servicename and portname have been -are re-introduced, so users of 1.20 have no need to change their scripts. +SOAP::WSDL provides easy access to Web Services with WSDL descriptions. -1.21 was a new version of SOAP::WSDL, mainly based on the work of -Giovanni S Fois. +The WSDL is parsed and stored in memory. -SOAP::WSDL provides WSDL support for SOAP::Lite. -It is built as a add-on to SOAP::Lite, and will sit on top of it, -forwarding all the actual request-response to SOAP::Lite - somewhat -like a pre-processor. +Your data is serialized according to the rules in the WSDL. -WSDL support means that you don't have to deal with those bitchy namespaces -some web services set on each and every method call parameter. +The only transport mechanisms currently supported are http and https. -It also means an end to that nasty +=head1 METHODS - SOAP::Data->name( 'Name' )->value( - SOAP::Data->name( 'Sub-Name')->value( 'Subvalue' ) - ); +=head2 new -encoding of complex data. (Another solution for this problem is just iterating -recursively over your data. But that doesn't work if you need more information -[e.g. namespaces etc] than just your data to encode your parameters). - -And it means that you can use ordinary hashes for your parameters - the -encording order will be derived from the WSDL and not from your (unordered) -data, thus the problem of unordered perl-hashes and WSDL EsequenceE -definitions is solved, too. (Another solution for the ordering problem is -tying your hash to a class that provides ordered hashes - Tie::IxHash is -one of them). - -=head2 Why should I use this ? - -SOAP::WSDL eases life for webservice developers who have to communicate with -lots of different web services using a reasonable big number of method calls. - -If you just want to call a hand full of methods of one web service, take -SOAP::Lite's stubmaker and modify the stuff by hand if it doesn't work right -from the start. The overhead SOAP::WSDL imposes on your calls is not worth -the time saving. - -If you need to access many web services offering zillions of methods to you, -this module should be your choice. It automatically encodes your perl data -structures correctly, based on the service's WSDL description, handling -even those complex types SOAP::Lite can't cope with. - -SOAP::WSDL also eliminates most perl E-E .NET interoperability -problems by qualifying method and parameters as they are specified in the -WSDL definition. - -=head1 USAGE - - my $soap=SOAP::WSDL->new( wsdl => 'http://server.com/ws.wsdl' ); - - # or - my $soap=SOAP::WSDL->new() - $soap->wsdl('http://server.com/ws.wsdl'); - - # or - # without dispatching calls to the WebService - # - # useful for testing - my $soap=SOAP::WSDL->new( wsdl => 'http://server.com/ws.wsdl', - no_dispatch => 1 ); - - # never forget to call this !in order to start the parsing procedure - $soap->wsdlinit(); - - # with caching enabled:don't forget the cache directory - $soap->wsdlinit( caching => 1, cache_directory =>"/tmp/cachedir"); - - # optional, set to a false value if you don't want your - # soap message elements to be typed - $soap->autotype(0); - - # you may specify a service and port - if not, SOAP::WSDL will search for - # the first one appearing in the WSDL - $soap->servicename('myservice'); - $soap->portname('myport'); - - my $som=$soap->call( 'method' , - name => 'value' , - name => 'value' ); - - - # with the method overloaded (got it from the standard) - my $som=$soap->call( 'method' , - wsdl_input_name => unique_input_message_name - name => 'value' , - name => 'value' ); - - # with headers (see the SOAP documentation) - - #first define your headers - @header = (SOAP::Header->name("FirstHeader")->value("FirstValue"), - SOAP::Header->name("SecontHeader")->value("SecondValue")); - - #and then do the call. please note the backslash - my $som=$soap->call( 'method' , - name => 'value' , - name => 'value' , - "soap_headers" => \@header); - - -=head1 How it works - -SOAP::WSDL takes the wsdl file specified and looks up the service and the -specified port. - -On calling a SOAP method, it looks up the message encoding and wraps all the -stuff around your data accordingly. - -Most pre-processing is done in I, the rest is done in I, which -overrides the same method from SOAP::Lite. - -=head2 wsdlinit - -SOAP::WSDL loads the wsdl file specified by the wsdl parameter / call using -SOAP::Lite's schema method. It sets up a XPath object of that wsdl file, and -subsequently queries it for namespaces, service, and port elements. - -SOAP::WSDL automatically uses the first service and port found in the WSDL. - -If you want to chose a different one, you can specify the service by calling - - $soap->servicename('ServiceToUse'); - $soap->portname('PortToUse'); +Constructor. All parameters passed are passed to the corresponding methods. =head2 call -The call method examines the wsdl file to find out how to encode the SOAP -message for your method. Lookups are done in real-time using XPath, so this -incorporates a small delay to your calls (see -L below. +Performs a SOAP call. The result is either an object tree (with outputtree), +a hash reference (with outputhash), plain XML (with outputxml) or a SOAP::SOM +object (with neither of the above set). -The SOAP message will include the types for each element, unless you have -set autotype to a false value by calling +call() can be called in different ways: - $soap->autotype(0); +=over -After wrapping your call into what is appropriate, SOAP::WSDL uses the -I method from SOAP::Lite to dispatch your call. +=item * Old-style idiom -call takes the method name as first argument, and the parameters passed to -that method as following arguments. + my $result = $soap->call('method', %data); -B +Does not support SOAP header data. - $som=$soap->call( "SomeMethod" , "test" => "testvalue" ); +=item * New-style idiom - $som=$soap->call( "SomeMethod" => %args ); + my $result = $soap->call('method', $body_ref, $header_ref ); -=head1 Caching +Does support SOAP header data. $body_ref and $header ref may either be +hash refs or SOAP::WSDL::XSD::Typelib::* derived objects. -SOAP::WSDL uses a two-stage caching mechanism to achieve best performance. +Result headers are accessible via the result SOAP::SOM object. -First, there's a pretty simple caching mechanisms for storing XPath query -results. +If outputtree or outputhash are set, you may also use the following to +access response header data: -They are just stored in a hash with the XPath path as key (until recently, -only results of "find" or "findnodes" are cached). I did not use the obvious -L or L module here, because these -use L to store complex objects and thus incorporate a -performance loss heavier than using no cache at all. + my ($body, $header) = $soap->call('method', $body_ref, $header_ref ); -Second, the XPath object and the XPath results cache are be stored on disk -using the L implementation. - -A filesystem cache is only used if you - - 1) enable caching - 2) set wsdl_cache_directory - -The cache directory must be, of course, read- and writeable. - -XPath result caching doubles performance, but increases memory consumption -- if you lack of memory, you should not enable caching (disabled by default). - -Filesystem caching triples performance for wsdlinit and doubles performance -for the first method call. - -The file system cache is written to disk when the SOAP::WSDL object is -destroyed. - -It may be written to disk any time by calling the L method. - -Using both filesystem and in-memory caching is recommended for best -performance and smallest startup costs. - -=head2 Sharing cache between applications - -Sharing a file system cache among applications accessing the same web -service is generally possible, but may under some circumstances reduce -performance, and under some special circumstances even lead to errors. -This is due to the cache key algorithm used. - -SOAP::WSDL uses the WSDL's URL to store the XML::XPath object of the -wsdl file. If you're using more than one WSDL definition on the same URL, -this may lead to errors when two or more applications using SOAP::WSDL -share a file system cache. - -SOAP::WSDL stores the XPath results in-memory-cache in the filesystem cache, -using the URL wsdl file with C<_cache> appended. Two applications sharing the -file system cache and accessing different methods of one web service could -overwrite each others in-memory-caches when dumping the XPath results to -disk, resulting in a slight performance drawback (even though this only -happens in the rare case of one app being started before the other one has -had a chance to write its cache to disk). - -=head2 Controlling the file system cache - -If you want full controll over the file system cache, you can use wsdl_init_cash to -initialize it. wsdl_init_cash will take the same parameters as Cache::FileCache->new(). -See L and L for details. - -=head2 Notes - -If you plan to write your own caching implementation, you should consider the following: - -The XPath results cache must not survive the XPath object SOAP::WSDL uses to -store the WSDL file in (this could cause memory holes - see -L for details). -This never happens during normal usage - but note that you have been warned -before trying to store and re-read SOAP::WSDL's internal cache. - -=head1 Methods - -=head2 Frequently used methods - -=head3 wsdl - - $soap->wsdl('http://my.web.service.com/wsdl'); - -Use this to specify the WSDL file to use. Must be a valid (and accessible !) -url. - -You must call this before calling L. - -For time saving's sake, this should be a local file - you never know how much -time your WebService needs for delivering a wsdl file. +=back =head2 wsdlinit - $soap->wsdlinit( caching => 1, - cache_directory => '/tmp/cache' ); +Reads the WSDL file and initializes SOAP::WSDL for working with it. -Initializes the WSDL document for usage. +Is called automatically from call() if not called directly before. -wsdlinit will die if it can't set up the WSDL file properly, so you might -want to eval{} it. + servicename + portname + call -On death, $@ will (hopefully) contain some error message like +You may set servicename and portname by passing them as attributes to +wsdlinit: - Error processing WSDL: no element found + $soap->wsdlinit( + servicename => 'MyService', + portname => 'MyPort', + ); -to give you a hint about what went wrong. +=head1 CONFIGURATION METHODS -wsdlinit will accept a hash of parameters with the following keys: +=head2 outputtree -=over 4 +When outputtree is set, SOAP::WSDL will return an object tree instead of a +SOAP::SOM object. -=item * caching +You have to specify a class_resolver for this to work. See +L -enables caching if true +=head2 class_resolver -=item * cache_directory +Set the class resolver class (or object). -The cache directory to use for FS caching +Class resolvers must implement the method get_class which has to return the +name of the class name for deserializing a XML node at the current XPath +location. -=item * url +Class resolvers are typically generated by using the generate_typemap method +of a SOAP::WSDL::Generator subclass. -URL to derive port and service name from. If url is given, wsdlinit will try -to find a matching service and port in the WSDL definition. +Example: -=item * servicename +XML structure (SOAP body content): -like setting the servicename directly. See below. + + Smith + John + -=item * portname +Class resolver -like setting the servicename directly. See below. + package MyResolver; + my %typemap = ( + 'Person' => 'MyPersonClass', + 'Person/Name' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + 'Person/FirstName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string', + ); + + sub get_class { return $typemap{ $_[1] } }; + 1; -=back +You'll need a MyPersonClass module in your search path for this to work - see +SOAP::WSDL::XSD::ComplexType on how to build / generate one. -=head3 call +=head2 servicename - $soap->call($method, %data); + $soap->servicename('Name'); -See above. +Sets the service to operate on. If no service is set via servicename, the +first service found is used. -call will die if it can't find required elements in the WSDL file or if your data -doesn't meet the WSDL definition's requirements, so you might want to eval{} it. -On death, $@ will (hopefully) contain some error message like +Returns the soap object, so you can chain calls like - Error processing WSDL: no element found + $soap->servicename->('Name')->portname('Port'); -to give you a hint about what went wrong. +=head2 portname -=head2 Configuration methods + $soap->portname('Name'); -=head3 servicename +Sets the port to operate on. If no port is set via portname, the +first port found is used. - $soap->servicename('Service1'); +Returns the soap object, so you can chain calls like -Use this to specify a service by name. -Your wsdl contains definitions for one or more services - hou have to tell -SOAP::WSDL which one to use. + $soap->portname('Port')->call('MyMethod', %data); -You can call it before each method call. +=head2 no_dispatch -=head3 portname +When set, call() returns the plain request XML instead of dispatching the +SOAP call to the SOAP service. Handy for testing/debugging. - $soap->portname('Port1'); +=head1 ACCESS TO SOAP::WSDL's internals -Your service can have one or many ports attached to it. -Each port has some operation defined in it trough a binding. -You have to tell which port of your service should be used for the -method you are calling. +=head2 get_client / set_client -You can call it before each method call. +Returns the SOAP client implementation used (normally a SOAP::WSDL::Client +object). -=head3 wsdl_checkoccurs +=head1 EXAMPLES -Enables/disables checks for correct number of -occurences of elements in WSDL types. The default is 1 (on). +See the examples/ directory. -Turning off occurance number checking results in a sligt performance gain. - -To turn off checking for correct number of elements, call - - $soap->wsdl_checkoccurs(0); - -=head3 wsdl_encoding - -The encoding style for the SOAP call. - -=head3 cache_directory - -enables filesystem caching (in the directory specified). The directory given must be -existant, read- and writeable. - -=head3 wsdl_cache_directory - - $soap->wsdl_cache_directory( '/tmp/cache' ); - -Sets the directory used for filesystem caching and enables filesystem caching. -Passing the I parameter to wsdlinit has the same effect. - -=head2 Seldomly used methods - -The following methods are mainly used internally in SOAP::WSDL, but may -be useful for debugging and some special purposes (like forcing a cache flush -on disk or custom cache initializations). - -=head3 no_dispatch - -Gets/Sets the I flag. If no_dispatch is set to true value, SOAP::WSDL -will not dispatch your calls to a remote server but return the SOAP::SOM object -containing the call instead. - -=head3 encode - - # this is how call uses encode - # $xpath contains a XPath object of the wsdl document - - my $def=$xpath->find("/definitions")->shift; - my $parts=$def->find("//message[\@name='$messageName']/part"); - - my @param=(); - - while (my $part=$parts->shift) { - my $enc=$self->encode($part, \%data); - push @param, $enc if defined $enc; - } - -Does the actual encoding. Expects a XPath::NodeSet as first, a hashref containing -your data as second parameter. The XPath nodeset must be a node specifying a WSDL -message part. - -You won't need to call I unless you plan to -override I or want to write a new SOAP server implementation. - -=head3 * wsdl_cache_init - -Initialize the WSDL file cache. Normally called from wsdlinit. For custom -cache initailization, you may pass the same parameters as to -Cache::FileCache->new(). - -=head3 wsdl_cache_store - - $soap->wsdl_cache_store(); - -Stores the content of the in-memory-cache (and the XML::XPath representation of -the WSDL file) to disk. This will not have any effect if cache_directory is not set. - -=head1 Notes - -=head2 Why another SOAP module ? - -SOAP::Lite provides only some rudimentary WSDL support. This lack is not just -something unimplemented, but an offspring of the SOAP::Schema -class design. SOAP::Schema uses some complicated format to store XML Schema information -(mostly a big hashref, containing arrays of SOAP::Data and a SOAP::Parser-derived -object). This data structure makes it pretty hard to improve SOAP::Lite's -WSDL support. - -SOAP::WSDL uses XPath for processing WSDL. XPath is a query language standard for -XML, and usually a good choice for XML transformations or XML template processing -(and what else is WSDL-based en-/decoding ?). Besides, there's an excellent XPath -module (L) available from CPAN, and as SOAP::Lite uses XPath to -access elements in SOAP::SOM objects, this seems like a natural choice. - -Fiddling the kind of WSDL support implemented here into SOAP::Lite would mean -a larger set of changes, so I decided to build something to use as add-on. - -=head2 Memory consumption and performance - -SOAP::WSDL uses around twice the memory (or even more) SOAP::Lite uses for the -same task (but remember: SOAP::WSDL does things for you SOAP::Lite can't). -It imposes a slight delay for initialization, and for every SOAP method call, too. - -On my 1.4 GHz Pentium mobile notebook, the init delay with a simple -WSDL file (containing just one operation and some complex types and elements) -was around 50 ms, the delay for the first call around 25 ms and for subsequent -calls to the same method around 7 ms without and around 6 ms with XPath result -caching (on caching, see above). XML::XPath must do some caching, too - -don't know where else the speedup should come from. - -Calling a method of a more complex WSDL file (defining around 10 methods and -numerous complex types on around 500 lines of XML), the delay for the first -call was around 100 ms for the first and 70 ms for subsequent method calls. -wsdlinit took around 150 ms to process the stuff. With XPath result caching enabled, -all but the first call take around 35 ms. - -Using SOAP::WSDL on an idiotically complex WSDL file with just one method, but around -100 parameters for that method, mostly made up by extensions of complex types -(the heaviest XPath operation) takes around 1.2 s for the first call (0.9 with caching) -and around 830 ms for subsequent calls (arount 570 ms with caching). - -The actual performance loss compared to SOAP::Lite should be around 10 % less -than the values above - SOAP::Lite encodes the data for you, too (or you do -it yourself) - and encoding in SOAP::WSDL is already covered by the pre-call -delay time mentioned above. - -If you have lots of WebService methods and call each of them from time to time, -this delay should not affect your perfomance too much. If you have just one method -and keep calling it ever & ever again, you should cosider hardcoding your data -encoding (maybe even with hardcoded XML templates - yes, this may be a BIG speedup). - - -=head1 CAVEATS - -=head2 API change between 1.20 and 1.21 - -Giovanni S. Fois has implemented a new calling convention, which allows to specify the -port type used by SOAP::WSDL. - -While this allows greater flexibillity (and helps around the still missing bindings support), -the following lines have to be added to existing code: - - $soap->servicename( $servicename); - $soap->portname( $porttype ); - -Both lines must appear after calling - - $soap->wsdlinit(); - -=head2 API change between 1.13 and 1.14 - -The SOAP::WSDL API changed significantly between versions 1.13 and 1.14. -From 1.14 on, B expects the following arguments: method name as scalar first, -method parameters as hash following. - -The B no longer recognizes the I option - to get the same behaviour, -pass C 1> to I or call - - $soap->no_dispatch(1); - -=head2 Unstable interface - -This is alpha software - everything may (and most things will) change. -But you don't have to be afraid too much - at least the I synopsis should -be stable from 1.14 on, and that is the part you'll use most frequently. - -=head1 BUGS +=head1 Differences to previous versions =over -=item * Arrays of complex types are not checked for the correct number of elements +=item * WSDL handling -Arrays of complex types are just encoded and not checked for correctness etc. -I don't know if I do this right yet, but output looks good. However, they are not -checked for the correct number of element (does the SOAP spec say how to -specify this ?). +SOAP::WSDL 2 is a complete rewrite. While SOAP::WSDL 1.x attempted to +process the WSDL file on the fly by using XPath queries, SOAP:WSDL 2 uses a +Expat handler for parsing the WSDL and building up a object tree representing +it's content. -=item * +trace (and other SOAP::Lite flags) don't work +The object tree has two main functions: It knows how to serialize data passed +as hash ref, and how to render the WSDL elements found into perl classes. -This may be an issue with older versions of the base module (before 2.?), or with -activestate's activeperl, which do -not call the base modules I method with the flags supplied to the parent. +Yup your're right, there's a builting code generation facility. Read +L for using it. -There's a simple workaround: +=item * no_dispatch - use SOAP::WSDL; - import SOAP::Lite +trace; +call() with no_dispatch set to true now returns the complete SOAP request +envelope, not only the body's content. -=item * nothing else known +=item * outputxml -But I'm sure there are some serious bugs lurking around somewhere. +call() with outputxml set to true now returns the complete SOAP response +envelope, not only the body's content. + +=item * servicename/portname + +Both servicename and portname can only be called B calling wsdlinit(). + +You may pass the servicename and portname as attributes to wsdlinit, though. =back -=head1 TODO +=head1 Differences to SOAP::Lite + +=head2 readable + +readable is a no-op in SOAP::WSDL. Actually, the XML output from SOAP::Lite +is hardly readable, either with readable switched on. + +If you need readable XML messages, I suggest using your favorite XML editor +for displaying and formatting. + +=head2 Message style/encoding + +While SOAP::Lite supports rpc/encoded style/encoding only, SOAP::WSDL currently +supports document/literal style/encoding. + +=head2 autotype / type information + +SOAP::Lite defaults to transmitting XML type information by default, where +SOAP::WSDL defaults to leaving it out. + +autotype(1) might even be broken in SOAP::WSDL - it's not well-tested, yet. + +=head2 Output formats + +In contrast to SOAP::Lite, SOAP::WSDL supports the following output formats: =over -=item Allow use of alternative XPath implementations +=item * SOAP::SOM objects. -XML::XPath is a great module, but it's not a race-winning one. -XML::LibXML offers a promising-looking XPath interface. SOAP::WSDL should -support both, defaulting to the faster one, and leaving the final choice -to the user. +This is the default. SOAP::Lite is required for outputting SOAP::SOM objects. + +=item * Object trees. + +This is the recommended output format. +You need a class resolver (typemap) for outputting object trees. +See L above. + +=item * Hash refs + +This is for convnience: A single hash ref containing the content of the +SOAP body. + +=item * xml + +See below. =back -=head1 CHANGES +=head2 outputxml -See CHANGES file. +SOAP::Lite returns only the content of the SOAP body when outputxml is set +to true. SOAP::WSDL returns the complete XML response. -=head1 COPYRIGHT +=head2 Auto-Dispatching -This library is free software, you can distribute / modify it under the same -terms as perl itself. +SOAP::WSDL does B support auto-dispatching. -=head1 AUTHOR> +This is on purpose: You may easily create interface classes by using +SOAP::WSDL::Client and implementing something like -Replace whitespace by '@' in E-Mail addresses. + sub mySoapMethod { + my $self = shift; + $soap_wsdl_client->call( mySoapMethod, @_); + } - Martin Kutter - Giovanni S. Fois +You may even do this in a class factory - see L for creating +such interfaces. -=head1 SVN information +=head2 Debugging / Tracing +While SOAP::Lite features a global tracing facility, SOAP::WSDL +allows to switch tracing on/of on a per-object base. + +This has to be done in the SOAP client used by SOAP::WSDL - see +L for an example and L for +details. + +=head1 BUGS AND LIMITATIONS + +=over + +=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 +before - see http://aspn.activestate.com/ASPN/Mail/Message/perl5-porters/929746 for details. + +=item * Apache SOAP datatypes are not supported + +You currently can't use SOAP::WSDL with Apache SOAP datatypes like map. + +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. + +Importing external definitions is not supported yet. + +The following XML Schema definitions varieties are not supported: + + group + union + simpleContent + +The following XML Schema definition content model is only partially +supported: + + complexContent - only restriction variety supported + +See L for details. + +=item * Serialization of hash refs dos not work for ambiguos values + +If you have list elements with multiple occurences allowed, SOAP::WSDL +has no means of finding out which variant you meant. + +Passing in item => [1,2,3] could serialize to + + 1 23 + 12 3 + +Ambiguos data can be avoided by providing data as objects. + +=item * XML Schema facets + +Almost no XML schema facets are implemented yet. The only facets +currently implemented are: + + fixed + default + +The following facets have no influence yet: + + minLength + maxLength + minInclusive + maxInclusive + minExclusive + maxExclusive + pattern + enumeration + +=back + +=head1 SEE ALSO + +=head2 Related projects + +=over + +=item * L + +Full featured SOAP-library, little WSDL support. Supports rpc-encoded style +only. Many protocols supported. + +=item * L / L + +Creates parser/generator functions for SOAP messages. Includes SOAP Client +and Server implementatios. + +You might want to give it a try, especially if you need to adhere very +closely to the XML Schema / WSDL specs. + +=back + +=head2 Sources of documentation + +=over + +=item * SOAP::WSDL homepage at sourceforge.net + +L + +=item * SOAP::WSDL forum at CPAN::Forum + +L + +=back + +=head1 ACKNOWLEDGMENTS + +There are many people out there who fostered SOAP::WSDL's developement. +I would like to thank them all (and apologize to all those I have forgotten). + +Giovanni S. Fois wrote a improved version of SOAP::WSDL (which eventually +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. + +Andreas 'ac0v' Specht constantly asked for better performance. + +JT Justman provided early feedback for the 2.xx pre-releases. + +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. + +=head1 LICENSE AND COPYRIGHT + +Copyright 2004-2007 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: 477 $ $LastChangedBy: kutterma $ - $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/branches/1.21/lib/SOAP/WSDL.pm $ - $Rev: 490 $ + $Id: WSDL.pm 477 2007-12-24 10:23:52Z 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 new file mode 100644 index 0000000..ff99ac1 --- /dev/null +++ b/lib/SOAP/WSDL/Base.pm @@ -0,0 +1,145 @@ +package SOAP::WSDL::Base; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use List::Util qw(first); +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<()>); + +sub START { + my ($self, $ident, $arg_ref) = @_; + $xmlns_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' }; +} + +sub DEMOLISH { + my $self = shift; + # delete upward references + delete $parent_of{ ident $self }; + return; +} + +sub STORABLE_freeze_pre :CUMULATIVE {}; +sub STORABLE_freeze_post :CUMULATIVE {}; +sub STORABLE_thaw_pre :CUMULATIVE {}; +sub STORABLE_thaw_post :CUMULATIVE { return $_[0] }; + +sub _accept { + my $self = shift; + my $class = ref $self; + $class =~ s{ \A SOAP::WSDL:: }{}xms; + $class =~ s{ (:? :: ) }{_}gxms; + my $method = "visit_$class"; + no strict qw(refs); ## no critic ProhibitNoStrict + return shift->$method( $self ); +} + +# unfortunately, AUTOMETHOD is SLOW. +# Re-implement in derived package wherever speed is an issue... +# +sub AUTOMETHOD { + my ($self, $ident, @values) = @_; + my $subname = $_; # Requested subroutine name is passed via $_ + + # we're called as $self->push_something(@values); + if ($subname =~s{^push_}{}xms) { + my $getter = "get_$subname"; + my $setter = "set_$subname"; + ## Checking here is paranoid - will fail fatally if + ## there is no setter... + ## And we would have to check getters, too. + ## Maybe do it the Conway way via the Symbol table... + ## ... can is way slow... + return sub { + no strict qw(refs); ## no critic ProhibitNoStrict + my $old_value = $self->$getter(); + # Listify if not a list ref + $old_value = $old_value ? [ $old_value ] : [] if not ref $old_value; + + push @$old_value , @values; + $self->$setter( $old_value ); + }; + } + + # we're called as $obj->find_something($ns, $key) + elsif ($subname =~s {^find_}{get_}xms) { + @values = @{ $values[0] } if ref $values[0] eq 'ARRAY'; + return sub { + return first { + $_->get_targetNamespace() eq $values[0] && + $_->get_name() eq $values[1] + } + @{ $self->$subname() }; + } + } + elsif ($subname =~s {^first_}{get_}xms) { + return sub { + my $result_ref = $self->$subname(); + return if not $result_ref; + return $result_ref if (not ref $result_ref eq 'ARRAY'); + return $result_ref->[0]; + }; + } + confess "$subname not found in class " . ref $self; +} + +sub init { + my ($self, @args) = @_; + foreach my $value (@args) + { + croak @args if (not defined ($value->{ Name })); + if ($value->{ Name } =~m{^xmlns\:}xms) { + # add namespaces + $xmlns_of{ ident $self }->{ $value->{ LocalName } } = $value->{ Value }; + next; + } + + my $name = $value->{ LocalName }; + my $method = "set_$name"; + $self->$method( $value->{ Value } ); + } + return $self; +} + +sub expand { + my ($self, , $qname) = @_; + my $ns_of = $self->get_xmlns(); + if (not $qname=~m{:}xm) { + die "un-prefixed element name <$qname> found, but no default namespace set\n" + if not defined $ns_of->{ '#default' }; + return $ns_of->{ '#default' }, $qname; + } + + my ($prefix, $localname) = split /:/x, $qname; + + + return ($ns_of->{ $prefix }, $localname) if ($ns_of->{ $prefix }); + + if (my $parent = $self->get_parent()) { + return $parent->expand($qname); + } + confess "unbound prefix $prefix found for $prefix:$localname. Bound prefixes are" + . join(', ', keys %{ $ns_of }); +} +sub _expand; +*_expand = \&expand; + +1; + +__END__ + +# REPOSITORY INFORMATION +# +# $Rev: 332 $ +# $LastChangedBy: kutterma $ +# $Id: WSDL.pm 332 2007-10-19 07:29:03Z kutterma $ +# $HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $ +# + diff --git a/lib/SOAP/WSDL/Binding.pm b/lib/SOAP/WSDL/Binding.pm new file mode 100644 index 0000000..059456e --- /dev/null +++ b/lib/SOAP/WSDL/Binding.pm @@ -0,0 +1,13 @@ +package SOAP::WSDL::Binding; +use strict; +use warnings; +use Class::Std::Fast::Storable; +use List::Util qw(first); +use base qw(SOAP::WSDL::Base); + +my %operation_of :ATTR(:name :default<()>); +my %type_of :ATTR(:name :default<()>); +my %transport_of :ATTR(:name :default<()>); +my %style_of :ATTR(:name