Compare commits

..

13 Commits

Author SHA1 Message Date
Martin Kutter
84b53d9261 import SOAP-WSDL 2.00_24 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_24
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_24.tar.gz
2009-12-12 19:48:10 -08:00
Martin Kutter
b955c5ad79 import SOAP-WSDL 2.00_23 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_23
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_23.tar.gz
2009-12-12 19:48:07 -08:00
Martin Kutter
080b211e4e import SOAP-WSDL 2.00_22 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_22
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_22.tar.gz
2009-12-12 19:48:06 -08:00
Martin Kutter
fa4d5dd884 import SOAP-WSDL 2.00_20 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_20
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_20.tar.gz
2009-12-12 19:48:05 -08:00
Martin Kutter
3d11524449 import SOAP-WSDL 2.00_19 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_19
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_19.tar.gz
2009-12-12 19:48:04 -08:00
Martin Kutter
21efa286af import SOAP-WSDL 2.00_18 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_18
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_18.tar.gz
2009-12-12 19:48:03 -08:00
Martin Kutter
008d06b72a import SOAP-WSDL 2.00_17 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_17
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_17.tar.gz
2009-12-12 19:48:02 -08:00
Martin Kutter
c6a48ba84b import SOAP-WSDL 1.26 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  1.26
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-1.26.tar.gz
2009-12-12 19:48:00 -08:00
Martin Kutter
30be0da3dc import SOAP-WSDL 2.00_16 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_16
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_16.tar.gz
2009-12-12 19:47:59 -08:00
Martin Kutter
2347a88353 import SOAP-WSDL 1.25 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  1.25
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-1.25.tar.gz
2009-12-12 19:47:57 -08:00
Martin Kutter
9e85f63aa0 import SOAP-WSDL 1.24 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  1.24
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-1.24.tar.gz
2009-12-12 19:47:56 -08:00
Martin Kutter
7ba2f93e44 import SOAP-WSDL 2.00_15 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_15
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_15.tar.gz
2009-12-12 19:47:55 -08:00
Martin Kutter
099c83b6bc import SOAP-WSDL 2.00_14 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00_14
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00_14.tar.gz
2009-12-12 19:47:53 -08:00
299 changed files with 10279 additions and 8951 deletions

View File

@@ -1,41 +1,55 @@
use Module::Build;
Module::Build->new(
$build = Module::Build->new(
dist_author => 'Martin Kutter <martin.kutter@fen-net.de>',
create_makefile_pl => 'passthrough',
dist_abstract => 'SOAP with WSDL support',
dist_name => 'SOAP-WSDL',
dist_version => '2.00_13',
dist_version => '2.00_24',
module_name => 'SOAP::WSDL',
license => 'artistic',
requires => {
'Class::Std' => q/v0.0.8/,
# 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' => '5.8.0',
'Class::Std' => q/v0.0.8/,
'Class::Std::Storable' => 0,
'Data::Dumper' => 0,
'Date::Parse' => 0,
'Date::Format' => 0,
'LWP::UserAgent' => 0,
'List::Util' => 0,
'File::Basename' => 0,
'File::Path' => 0,
'XML::Parser::Expat' => 0,
'Template' => 0,
'Getopt::Long' => 0,
'List::Util' => 0,
'LWP::UserAgent' => 0,
'Template' => 0,
'Term::ReadKey' => 0,
'XML::Parser::Expat' => 0,
},
buildrequires => {
'Date::Parse' => 0,
'Date::Format' => 0,
'Test::More' => 0,
'Class::Std' => q/v0.0.8/,
'Class::Std::Storable' => 0,
'Cwd' => 0,
'Date::Parse' => 0,
'Date::Format' => 0,
'Getopt::Long' => 0,
'List::Util' => 0,
'LWP::UserAgent' => 0,
'File::Basename' => 0,
'File::Path' => 0,
'XML::Parser::Expat' => 0,
'Template' => 0,
'Getopt::Long' => 0,
'Cwd' => 0,
'File::Find' => 0,
'File::Spec' => 0,
'Storable' => 0,
'Test::More' => 0,
'Template' => 0,
'XML::Parser::Expat' => 0,
},
recursive_test_files => 1,
)->create_build_script;
meta_add => {
no_index => {
directory => 'lib/SOAP/WSDL/Generator/Template/XSD/',
},
}
);
$build->add_build_element('tt');
$build->create_build_script;

172
CHANGES
View File

@@ -1,172 +0,0 @@
Release notes for SOAP::WSDL 2.00_12
-------
I'm very happy to present a new pre-release version of SOAP::WSDL.
SOAP::WSDL is a toolkit for creating SOAP 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. SOAP::WSDL is much easier to use than SOAP::Lite.
o Automatically encodes perl data structures as message data
o Automatically sets HTTP headers right
* 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
The following changes have been made:
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 mad:
* 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 <wsdl:documentation> 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).

455
Changes Normal file
View File

@@ -0,0 +1,455 @@
Release notes for SOAP::WSDL 2.00_24
-------
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_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 <wsdl:documentation> 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).

134
HACKING
View File

@@ -1,3 +1,6 @@
HACKING
=======
Development of SOAP::WSDL takes place on sourceforge.net.
There's a svn repository available at
@@ -11,35 +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.* Development of the 1.* tree has stopped - I won't get past 1.2x anymore...
2.* WSDL -> Perl Class factory with offline WSDL processing
SOAP-WSDL CODING GUIDELINES
===========================
2.01
- WSDL support for the most common type definitions
- Online-facility (SOAP::WSDL) using WSDL object tree directly
- usable code generator
- full namespace support when processing WSDL
- high performance when parsing WSDL messages - get nearly as fast as
XML::Simple...
DESIGN PRINCIPLES
-----------------
2.02
- Support for Apache-SOAP datatypes
- support for embedded atomic simpleType/complexType definitions
- Caching of WSDL object tree + generated code (when using SOAP::WSDL).
- Online-facility (SOAP::WSDL) using code generator via cache directory
SOAP-WSDL is designed for the following principles:
Somewhere on the TODO list (in no particular order):
1. SPEED
A SOAP toolkit is useless, if it's not fast enough. Therefore SOAP::WSDL aims
at always being fast enough.
- validation
- typemaps for use with the type="tns:MyComplexType" XML attribute
- external entities support when parsing WSDL
- support all these XML Schema variants
- support creating XML Schmema definitions via SOAP::WSDL::XSD::* ('minimal conformant')
- support other Schema definition languages than XML::Schema (maybe RelaxNG?)
- factor out SOAP::WSDL::XSD into it's own namespace (maybe just XSD ?)
Please benchmark any contributions - if they slow down SOAP-WSDL (especially
the XML parsing part), you should have good reasons.
July 2007,
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 uthor tests are 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
* 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

1
MAINFEST Normal file
View File

@@ -0,0 +1 @@

172
MANIFEST
View File

@@ -4,10 +4,12 @@ benchmark/XSD/02_anySimpleType.t
benchmark/XSD/03_string.t
bin/wsdl2perl.pl
Build.PL
CHANGES
Changes
example/fortune.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
@@ -20,14 +22,14 @@ example/lib/MyElements/int.pm
example/lib/MyElements/readNodeCount.pm
example/lib/MyElements/readNodeCountResponse.pm
example/lib/MyElements/string.pm
example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie.pm
example/lib/MyInterfaces/GlobalWeather.pm
example/lib/MyInterfaces/FullerData_x0020_Fortune_x0020_Cookie/FullerData_x0020_Fortune_x0020_CookieSoap.pm
example/lib/MyInterfaces/GlobalWeather/GlobalWeatherSoap.pm
example/lib/MyTypemaps/FullerData_x0020_Fortune_x0020_Cookie.pm
example/lib/MyTypemaps/GlobalWeather.pm
example/visitor/visitor.pl
example/weather.pl
example/weather_wsdl.pl
example/wsdl/FortuneCookie.xml
example/wsdl/genericbarcode.xml
example/wsdl/globalweather.xml
HACKING
lib/SOAP/WSDL.pm
@@ -36,33 +38,82 @@ 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/SOAP11.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/MessageSubParser.pm
lib/SOAP/WSDL/Expat/SubParser.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/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/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/Parser.pod
lib/SOAP/WSDL/Part.pm
lib/SOAP/WSDL/Port.pm
lib/SOAP/WSDL/PortType.pm
lib/SOAP/WSDL/SAX/MessageHandler.pm
lib/SOAP/WSDL/SAX/WSDLHandler.pm
lib/SOAP/WSDL/Serializer/SOAP11.pm
lib/SOAP/WSDL/Serializer/XSD.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/SoapOperation.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/Builtin.pm
@@ -122,19 +173,16 @@ lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
lib/SOAP/WSDL/XSD/Typelib/Element.pm
lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
LICENSE
MAINFEST
Makefile.PL
MANIFEST This list of files
MANIFEST
META.yml
README
t/001_use.t
t/002_parse_wsdl.t
t/002_sax.t
t/003_sax_serializer.t
t/003_wsdl_based_serializer.t
t/004_parse_wsdl.t
t/004_sax_wsdl.t
t/005_parse_contributed.t
t/005_sax_contributed_wsdl.t
t/006_client.t
t/007_envelope.t
t/008_client_wsdl_complexType.t
@@ -142,17 +190,13 @@ t/009_data_classes.t
t/011_simpleType.t
t/012_element.t
t/013_complexType.t
t/014_sax_typelib.t
t/015_to_typemap.t
t/016_client_object.t
t/017_generator_expat.t
t/017_generator_libxml.t
t/018_generator_expat.t
t/018_generator_libxml.t
t/017_generator.t
t/018_compat_2_00_15-generator.t
t/020_storable.t
t/021_generator_element_ref_expat.t
t/021_generator_element_ref_libxml.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
@@ -178,13 +222,21 @@ t/acceptance/wsdl/contributed/Axis.wsdl
t/acceptance/wsdl/contributed/ETest.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_unsupported_test.wsdl
t/acceptance/wsdl/message_gateway.wsdl
t/contributed.wsdl
t/Expat/01_expat.t
t/Expat/02_sub_parser.t
t/Expat/03_wsdl.t
t/lib/MyComplexType.pm
t/lib/MyElement.pm
t/lib/MyElements/GetWeather.pm
t/lib/MyElements/GetWeatherResponse.pm
t/lib/MyInterfaces/GlobalWeather.pm
t/lib/MySimpleType.pm
t/lib/MyTypemaps/GlobalWeather.pm
t/lib/Test/SOAPMessage.pm
t/lib/Typelib/Base.pm
t/lib/Typelib/TEnqueueMessage.pm
@@ -204,11 +256,67 @@ 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.pl
t/SOAP/WSDL/XSD/Typelib/Builtin/001_string.t
t/SOAP/WSDL/XSD/Typelib/Builtin/002_dateTime.t
t/SOAP/WSDL/XSD/Typelib/Builtin/003_date.t
t/SOAP/WSDL/XSD/Typelib/Builtin/004_time.t
t/test.pl
t/SOAP/WSDL/12_binding.t
t/SOAP/WSDL/Deserializer/Hash.t
t/SOAP/WSDL/Deserializer/SOM.t
t/SOAP/WSDL/Deserializer/XSD.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_unsupported.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/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/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/test.wsdl
TEST_COVERAGE
TODO

458
META.yml
View File

@@ -1,200 +1,258 @@
---
name: SOAP-WSDL
version: 2.00_13
author:
abstract: SOAP with WSDL support
license: artistic
requires:
Class::Std: v0.0.8
Class::Std::Storable: 0
Date::Format: 0
Date::Parse: 0
File::Basename: 0
File::Path: 0
Getopt::Long: 0
LWP::UserAgent: 0
List::Util: 0
Template: 0
XML::Parser::Expat: 0
generated_by: Module::Build version 0.2808
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.2.html
version: 1.2
provides:
SOAP::WSDL:
file: lib/SOAP/WSDL.pm
version: 2.00_13
SOAP::WSDL::Base:
file: lib/SOAP/WSDL/Base.pm
SOAP::WSDL::Binding:
file: lib/SOAP/WSDL/Binding.pm
SOAP::WSDL::Client:
file: lib/SOAP/WSDL/Client.pm
version: 2.00_13
SOAP::WSDL::Client::Base:
file: lib/SOAP/WSDL/Client/Base.pm
SOAP::WSDL::Definitions:
file: lib/SOAP/WSDL/Definitions.pm
SOAP::WSDL::Deserializer::SOAP11:
file: lib/SOAP/WSDL/Deserializer/SOAP11.pm
version: 2.00_13
SOAP::WSDL::Deserializer::SOM:
file: lib/SOAP/WSDL/Deserializer/SOM.pm
version: 2.00_13
SOAP::WSDL::Expat::MessageParser:
file: lib/SOAP/WSDL/Expat/MessageParser.pm
SOAP::WSDL::Expat::MessageStreamParser:
file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm
SOAP::WSDL::Expat::MessageSubParser:
file: lib/SOAP/WSDL/Expat/MessageSubParser.pm
SOAP::WSDL::Factory::Deserializer:
file: lib/SOAP/WSDL/Factory/Deserializer.pm
SOAP::WSDL::Factory::Serializer:
file: lib/SOAP/WSDL/Factory/Serializer.pm
SOAP::WSDL::Factory::Transport:
file: lib/SOAP/WSDL/Factory/Transport.pm
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::SAX::MessageHandler:
file: lib/SOAP/WSDL/SAX/MessageHandler.pm
SOAP::WSDL::SOAP::Typelib::Fault11:
file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
SOAP::WSDL::Serializer::SOAP11:
file: lib/SOAP/WSDL/Serializer/SOAP11.pm
version: 2.00_13
SOAP::WSDL::Service:
file: lib/SOAP/WSDL/Service.pm
SOAP::WSDL::SoapOperation:
file: lib/SOAP/WSDL/SoapOperation.pm
SOAP::WSDL::Transport::HTTP:
file: lib/SOAP/WSDL/Transport/HTTP.pm
SOAP::WSDL::TypeLookup:
file: lib/SOAP/WSDL/TypeLookup.pm
SOAP::WSDL::Types:
file: lib/SOAP/WSDL/Types.pm
SOAP::WSDL::XSD::Builtin:
file: lib/SOAP/WSDL/XSD/Builtin.pm
SOAP::WSDL::XSD::ComplexType:
file: lib/SOAP/WSDL/XSD/ComplexType.pm
SOAP::WSDL::XSD::Element:
file: lib/SOAP/WSDL/XSD/Element.pm
SOAP::WSDL::XSD::Schema:
file: lib/SOAP/WSDL/XSD/Schema.pm
SOAP::WSDL::XSD::Schema::Builtin:
file: lib/SOAP/WSDL/XSD/Schema/Builtin.pm
SOAP::WSDL::XSD::SimpleType:
file: lib/SOAP/WSDL/XSD/SimpleType.pm
SOAP::WSDL::XSD::Typelib::Builtin:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
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
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
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
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
SOAP::WSDL::XSD::Typelib::Element:
file: lib/SOAP/WSDL/XSD/Typelib/Element.pm
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
resources:
license: http://opensource.org/licenses/artistic-license.php
---
name: SOAP-WSDL
version: 2.00_24
author:
- 'Martin Kutter <martin.kutter@fen-net.de>'
abstract: SOAP with WSDL support
license: artistic
resources:
license: http://opensource.org/licenses/artistic-license.php
requires:
Class::Std: v0.0.8
Class::Std::Storable: 0
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: 2.00_17
SOAP::WSDL::Base:
file: lib/SOAP/WSDL/Base.pm
version: 2.00_17
SOAP::WSDL::Binding:
file: lib/SOAP/WSDL/Binding.pm
SOAP::WSDL::Client:
file: lib/SOAP/WSDL/Client.pm
version: 2.00_17
SOAP::WSDL::Client::Base:
file: lib/SOAP/WSDL/Client/Base.pm
version: 2.00_24
SOAP::WSDL::Definitions:
file: lib/SOAP/WSDL/Definitions.pm
version: 2.00_17
SOAP::WSDL::Deserializer::Hash:
file: lib/SOAP/WSDL/Deserializer/Hash.pm
version: 2.00_24
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_24
SOAP::WSDL::Expat::Base:
file: lib/SOAP/WSDL/Expat/Base.pm
version: 2.00_24
SOAP::WSDL::Expat::Message2Hash:
file: lib/SOAP/WSDL/Expat/Message2Hash.pm
version: 2.00_24
SOAP::WSDL::Expat::MessageParser:
file: lib/SOAP/WSDL/Expat/MessageParser.pm
version: 2.00_24
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_17
SOAP::WSDL::Generator::Template:
file: lib/SOAP/WSDL/Generator/Template.pm
version: 2.00_17
SOAP::WSDL::Generator::Template::XSD:
file: lib/SOAP/WSDL/Generator/Template/XSD.pm
SOAP::WSDL::Generator::Visitor:
file: lib/SOAP/WSDL/Generator/Visitor.pm
version: 2.00_17
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
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_17
SOAP::WSDL::SOAP::Typelib::Fault11:
file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
version: 2.00_17
SOAP::WSDL::Serializer::XSD:
file: lib/SOAP/WSDL/Serializer/XSD.pm
version: 2.00_24
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_17
SOAP::WSDL::Transport::Test:
file: lib/SOAP/WSDL/Transport/Test.pm
version: 2.00_14
SOAP::WSDL::TypeLookup:
file: lib/SOAP/WSDL/TypeLookup.pm
SOAP::WSDL::Types:
file: lib/SOAP/WSDL/Types.pm
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_17
SOAP::WSDL::XSD::Element:
file: lib/SOAP/WSDL/XSD/Element.pm
version: 2.00_22
SOAP::WSDL::XSD::Schema:
file: lib/SOAP/WSDL/XSD/Schema.pm
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_17
SOAP::WSDL::XSD::Typelib::Builtin:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
version: 2.00_17
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
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_17
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_18
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_24
SOAP::WSDL::XSD::Typelib::Element:
file: lib/SOAP/WSDL/XSD/Typelib/Element.pm
version: 2.00_24
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/

View File

@@ -1,31 +1,31 @@
# Note: this file was auto-generated by Module::Build::Compat version 0.03
unless (eval "use Module::Build::Compat 0.02; 1" ) {
print "This module requires Module::Build to install itself.\n";
require ExtUtils::MakeMaker;
my $yn = ExtUtils::MakeMaker::prompt
(' Install Module::Build now from CPAN?', 'y');
unless ($yn =~ /^y/i) {
die " *** Cannot install without Module::Build. Exiting ...\n";
}
require Cwd;
require File::Spec;
require CPAN;
# Save this 'cause CPAN will chdir all over the place.
my $cwd = Cwd::cwd();
CPAN::Shell->install('Module::Build::Compat');
CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
or die "Couldn't install Module::Build, giving up.\n";
chdir $cwd or die "Cannot chdir() back to $cwd: $!";
}
eval "use Module::Build::Compat 0.02; 1" or die $@;
Module::Build::Compat->run_build_pl(args => \@ARGV);
require Module::Build;
Module::Build::Compat->write_makefile(build_class => 'Module::Build');
# Note: this file was auto-generated by Module::Build::Compat version 0.03
unless (eval "use Module::Build::Compat 0.02; 1" ) {
print "This module requires Module::Build to install itself.\n";
require ExtUtils::MakeMaker;
my $yn = ExtUtils::MakeMaker::prompt
(' Install Module::Build now from CPAN?', 'y');
unless ($yn =~ /^y/i) {
die " *** Cannot install without Module::Build. Exiting ...\n";
}
require Cwd;
require File::Spec;
require CPAN;
# Save this 'cause CPAN will chdir all over the place.
my $cwd = Cwd::cwd();
CPAN::Shell->install('Module::Build::Compat');
CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
or die "Couldn't install Module::Build, giving up.\n";
chdir $cwd or die "Cannot chdir() back to $cwd: $!";
}
eval "use Module::Build::Compat 0.02; 1" or die $@;
Module::Build::Compat->run_build_pl(args => \@ARGV);
require Module::Build;
Module::Build::Compat->write_makefile(build_class => 'Module::Build');

11
TEST_COVERAGE Normal file
View File

@@ -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"

28
TODO
View File

@@ -2,35 +2,23 @@ TODO list for SOAP::WSDL
2.00 Pre-releases
--------
* SOAP Header support (#1764845)
* Implement a interface similar to SOAP::Schema (#1783639)
* Check & probably fix simpleType support.
The WS at http://www.webservicex.net/genericbarcode.asmx?wsdl should
make up a good example for simpleType definitions.
* Remove benchmarks from test. Create benchmark/ directory to store benchmarks.
* write inheritance Test for all XSD::Typelib::Builtin::* classes
* support embedded atomic types (#1761532)
Implement by including a second (and third and fourth)
package type_prefix::complex_type::element_name;
element package.
Maybe even allow unlimited depth? What does the specs say?
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
* Act as SOAP Server
3.0 release
--------
We're not thinking that far ahead right now.
We're not thinking that far ahead right now.

View File

@@ -1,13 +1,16 @@
#!/usr/bin/perl -w
%DB::packages=(SOAP::WSDL::Expat::MessageParser => 1);
%DB::packages=(SOAP::WSDL::Expat::MessageParser => 1);
use strict;
use warnings;
use lib '../lib';
use lib 'lib';
use lib '../t/lib';
use SOAP::WSDL::SAX::MessageHandler;
# use SOAP::WSDL::SAX::MessageHandler;
use Benchmark;
use Benchmark qw(cmpthese timethese);
use SOAP::WSDL::Expat::MessageParser;
use SOAP::WSDL::Expat::Message2Hash;
use XML::Simple;
use XML::LibXML;
use MyComplexType;
@@ -16,43 +19,100 @@ use MySimpleType;
my $xml = q{<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body><MyAtomicComplexTypeElement xmlns="urn:Test" >
<test>Test</test>
<SOAP-ENV:Body>
<MyAtomicComplexTypeElement xmlns="urn:Test" >
<test>
<test2 >Test2</test2>
</MyAtomicComplexTypeElement></SOAP-ENV:Body></SOAP-ENV:Envelope>};
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test55</test2>
</test>
</MyAtomicComplexTypeElement>
</SOAP-ENV:Body></SOAP-ENV:Envelope>};
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'FakeResolver'
});
my $hash_parser = SOAP::WSDL::Expat::Message2Hash->new();
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
my $libxml = XML::LibXML->new();
print "xml length: ${ \length $xml } bytes\n";
timethese 1000,
{
'SOAP::WSDL' => sub { $parser->parse( $xml ) },
#'XML::Simple (Hash)' => sub { XMLin $xml },
'XML::LibXML (DOM)' => sub { my $dom = $libxml->parse_string( $xml ) },
my $libxml = XML::LibXML->new();
$libxml->keep_blanks(0);
my @data;
sub libxml_test {
my $dom = $libxml->parse_string( $xml );
push @data, dom2hash( $dom->firstChild );
};
use Test::More tests => 1;
is $parser->get_data(), q{<MyAtomicComplexTypeElement xmlns="urn:Test" >}
. q{<test >Test</test><test2 >Test2</test2></MyAtomicComplexTypeElement>}
, 'Content comparison';
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];
}
$parser->class_resolver( 'FakeResolver2' );
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,
};
# for (1..10000) { push @data, $parser->parse( $xml ) };
# data classes reside in t/lib/Typelib/
BEGIN {
package FakeResolver;
{
my %class_list = (
'MyAtomicComplexTypeElement' => 'MyAtomicComplexTypeElement',
'MyAtomicComplexTypeElement/test' => 'MyTestElement',
'MyAtomicComplexTypeElement/test2' => 'MyTestElement2',
'MyAtomicComplexTypeElement/test' => 'MyAtomicComplexTypeElement',
'MyAtomicComplexTypeElement/test/test2' => 'MyTestElement2',
);
sub get_map { return \%class_list };

View File

@@ -8,14 +8,5 @@ my $obj = SOAP::WSDL::XSD::Typelib::Builtin::anyType->new();
timethese 10000, {
'new' => sub { SOAP::WSDL::XSD::Typelib::Builtin::anyType->new() },
'new with params' => sub { SOAP::WSDL::XSD::Typelib::Builtin::anyType->new({
xmlns => 'urn:Test'
}) },
'set_FOO' => sub { $obj->set_xmlns('Test') },
};
my $data;
timethese 1000000, {
'set_FOO' => sub { $obj->set_xmlns('Test') },
'get_FOO' => sub { $data = $obj->get_xmlns() },
};

View File

@@ -9,14 +9,13 @@ 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({
xmlns => 'urn:Test',
value => 'Teststring'
}) },
'set_FOO' => sub { $obj->set_xmlns('Test') },
'set_FOO' => sub { $obj->set_value('Test') },
};
my $data;
timethese 1000000, {
'set_FOO' => sub { $obj->set_xmlns('Test') },
'get_FOO' => sub { $data = $obj->get_xmlns() },
'set_FOO' => sub { $obj->set_value('Test') },
'get_FOO' => sub { $data = $obj->get_value() },
};

View File

@@ -6,17 +6,20 @@ use SOAP::WSDL::XSD::Typelib::Builtin::string;
my $obj = SOAP::WSDL::XSD::Typelib::Builtin::string->new();
timethese 10000, {
timethese 20000, {
'new' => sub { SOAP::WSDL::XSD::Typelib::Builtin::string->new() },
'new + params' => sub { SOAP::WSDL::XSD::Typelib::Builtin::string->new({
xmlns => 'urn:Test',
value => 'Teststring'
}) },
'set_FOO' => sub { $obj->set_xmlns('Test') },
};
$obj->set_value('Foobar');
timethese 20000, {
serialize => sub { $obj->serialize() }
};
my $data;
timethese 1000000, {
'set_FOO' => sub { $obj->set_xmlns('Test') },
'get_FOO' => sub { $data = $obj->get_xmlns() },
'set_FOO' => sub { $obj->set_value('Test') },
'get_FOO' => sub { $data = $obj->get_value() },
};

View File

@@ -5,29 +5,60 @@ 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::',
type_prefix => 'MyTypes',
element_prefix => 'MyElements',
typemap_prefix => 'MyTypemaps',
interface_prefix => 'MyInterfaces',
base_path => 'lib/',
proxy => undef
proxy => undef,
generator => 'XSD',
);
{ # 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(
url|u=s
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
)
);
@@ -39,23 +70,52 @@ pod2usage( -exit => 1 , verbose => 1 ) if not ($url);
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
local $ENV{HTTP_PROXY} = $opt{proxy} if $opt{proxy};
my $lwp = LWP::UserAgent->new();
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 $wsdl = $parser->parse_string( $xml );
my $definitions = $parser->parse_string( $xml );
my %typemap = ();
if ($opt{typemap_include}) {
open my $fh , $opt{typemap_include}
or die "cannot open typemap_include file $opt{typemap_include}\n";
$opt{custom_types} .= join q{}, <$fh>;
close $fh;
delete $opt{typemap_include};
die "$opt{typemap_include} not found " if not -f $opt{typemap_include};
%typemap = do $opt{typemap_include};
}
$wsdl->create({ %opt });
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();
__END__
=pod
@@ -73,17 +133,26 @@ wsdl2perl.pl - create perl bindings for SOAP webservices.
NAME SHORT DESCRITPION
----------------------------------------------------------------------------
prefix p Prefix for both type and element classes.
type_prefix t Prefix for type classes. Should end with '::'
Default: MyTypes::
element_prefix e Prefix for element classes. Should end with '::'
Default: MyElements::
typemap_prefix m Prefix for typemap classes. Should end with '::'
Default: MyTypemaps::
interface_prefix i Prefix for interface classes. Should end with '::'
Default: MyInterfaces::
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: ./lib
typemap_include mi File to include in typemap.
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
help h Show help content
=head1 DESCRIPTION
@@ -95,7 +164,7 @@ The following classes are created:
=over
=item * A interface class for every service
=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.
@@ -116,10 +185,34 @@ typemap_include (mi) option.
You may need to write additional type classes if your WSDL is incomplete.
For writing your own lib classes, see L<SOAP::WSDL::XSD::Typelib::Element>,
L<SOAP::WSDL::XSD::Typelib::ComplexType> and L<SOAP::WSDL::XSD::Typelib::SimpleType>.
L<SOAP::WSDL::XSD::Typelib::ComplexType>
and L<SOAP::WSDL::XSD::Typelib::SimpleType>.
=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.

View File

@@ -10,21 +10,21 @@
# Eigene Dateien/Martin/SOAP-WSDL/trunk/bin/FortuneCookie.xml"
use lib 'lib/';
use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie;
my $cookieService = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie->new();
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";
print $cookie->get_GetFortuneCookieResult()->get_value, "\n\n";
$cookie = $cookieService->GetSpecificCookie({ index => 23 })
or die "$cookie";
print $cookie->get_GetSpecificCookieResult(), "\n";
print $cookie;
# print $cookie;
=for demo:

View File

@@ -1,29 +1,8 @@
package MyElements::CountCookies;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="CountCookies"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
__PACKAGE__->_factory(
[ qw() ],
{
},
{
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -31,41 +10,45 @@ __PACKAGE__->__set_name('CountCookies');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::CountCookies
=head1 NAME
=head1 SYNOPSIS
MyElements::CountCookies
=head1 DESCRIPTION
Type class for the XML element CountCookies.
Perl data type class for the XML Schema defined element
CountCookies from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
my $element = MyElements::CountCookies->new($data);
Constructor. The following data structure may be passed to new():
=head1 Object structure
=head1 AUTHOR
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
Generated by SOAP::WSDL
=cut

View File

@@ -1,37 +1,8 @@
package MyElements::CountCookiesResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="CountCookiesResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %CountCookiesResult_of :ATTR(:get<CountCookiesResult>);
__PACKAGE__->_factory(
[ qw(
CountCookiesResult
) ],
{
CountCookiesResult => \%CountCookiesResult_of,
},
{
CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -39,47 +10,70 @@ __PACKAGE__->__set_name('CountCookiesResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %CountCookiesResult_of :ATTR(:get<CountCookiesResult>);
__PACKAGE__->_factory(
[ qw(
CountCookiesResult
) ],
{
CountCookiesResult => \%CountCookiesResult_of,
},
{
CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::CountCookiesResponse
=head1 NAME
=head1 SYNOPSIS
MyElements::CountCookiesResponse
=head1 DESCRIPTION
Type class for the XML element CountCookiesResponse.
Perl data type class for the XML Schema defined element
CountCookiesResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
CountCookiesResult
my $element = MyElements::CountCookiesResponse->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
CountCookiesResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
{
CountCookiesResult => $some_value, # int
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'CountCookiesResponse'=> {
'CountCookiesResult' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -0,0 +1,102 @@
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::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %BarCodeParam_of :ATTR(:get<BarCodeParam>);
my %BarCodeText_of :ATTR(:get<BarCodeText>);
__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

View File

@@ -0,0 +1,79 @@
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::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %GenerateBarCodeResult_of :ATTR(:get<GenerateBarCodeResult>);
__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

View File

@@ -1,38 +1,8 @@
package MyElements::GetCitiesByCountry;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetCitiesByCountry"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %CountryName_of :ATTR(:get<CountryName>);
__PACKAGE__->_factory(
[ qw(
CountryName
) ],
{
CountryName => \%CountryName_of,
},
{
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.webserviceX.NET' }
@@ -40,54 +10,70 @@ __PACKAGE__->__set_name('GetCitiesByCountry');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %CountryName_of :ATTR(:get<CountryName>);
__PACKAGE__->_factory(
[ qw(
CountryName
) ],
{
CountryName => \%CountryName_of,
},
{
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME
=head1 NAME
MyElements::GetCitiesByCountry
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetCitiesByCountry.
Perl data type class for the XML Schema defined element
GetCitiesByCountry from the namespace http://www.webserviceX.NET.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
CountryName
my $element = MyElements::GetCitiesByCountry->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
{
CountryName => $some_value, # string
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetCitiesByCountry'=> {
'CountryName' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,38 +1,8 @@
package MyElements::GetCitiesByCountryResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetCitiesByCountryResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetCitiesByCountryResult_of :ATTR(:get<GetCitiesByCountryResult>);
__PACKAGE__->_factory(
[ qw(
GetCitiesByCountryResult
) ],
{
GetCitiesByCountryResult => \%GetCitiesByCountryResult_of,
},
{
GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.webserviceX.NET' }
@@ -40,54 +10,70 @@ __PACKAGE__->__set_name('GetCitiesByCountryResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %GetCitiesByCountryResult_of :ATTR(:get<GetCitiesByCountryResult>);
__PACKAGE__->_factory(
[ qw(
GetCitiesByCountryResult
) ],
{
GetCitiesByCountryResult => \%GetCitiesByCountryResult_of,
},
{
GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME
=head1 NAME
MyElements::GetCitiesByCountryResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetCitiesByCountryResponse.
Perl data type class for the XML Schema defined element
GetCitiesByCountryResponse from the namespace http://www.webserviceX.NET.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
GetCitiesByCountryResult
my $element = MyElements::GetCitiesByCountryResponse->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
{
GetCitiesByCountryResult => $some_value, # string
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetCitiesByCountryResponse'=> {
'GetCitiesByCountryResult' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,29 +1,8 @@
package MyElements::GetFortuneCookie;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetFortuneCookie"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
__PACKAGE__->_factory(
[ qw() ],
{
},
{
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -31,41 +10,45 @@ __PACKAGE__->__set_name('GetFortuneCookie');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::GetFortuneCookie
=head1 NAME
=head1 SYNOPSIS
MyElements::GetFortuneCookie
=head1 DESCRIPTION
Type class for the XML element GetFortuneCookie.
Perl data type class for the XML Schema defined element
GetFortuneCookie from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
my $element = MyElements::GetFortuneCookie->new($data);
Constructor. The following data structure may be passed to new():
=head1 Object structure
=head1 AUTHOR
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
Generated by SOAP::WSDL
=cut

View File

@@ -1,37 +1,8 @@
package MyElements::GetFortuneCookieResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetFortuneCookieResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetFortuneCookieResult_of :ATTR(:get<GetFortuneCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetFortuneCookieResult
) ],
{
GetFortuneCookieResult => \%GetFortuneCookieResult_of,
},
{
GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -39,47 +10,70 @@ __PACKAGE__->__set_name('GetFortuneCookieResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %GetFortuneCookieResult_of :ATTR(:get<GetFortuneCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetFortuneCookieResult
) ],
{
GetFortuneCookieResult => \%GetFortuneCookieResult_of,
},
{
GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::GetFortuneCookieResponse
=head1 NAME
=head1 SYNOPSIS
MyElements::GetFortuneCookieResponse
=head1 DESCRIPTION
Type class for the XML element GetFortuneCookieResponse.
Perl data type class for the XML Schema defined element
GetFortuneCookieResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
GetFortuneCookieResult
my $element = MyElements::GetFortuneCookieResponse->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
GetFortuneCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
{
GetFortuneCookieResult => $some_value, # string
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetFortuneCookieResponse'=> {
'GetFortuneCookieResult' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,37 +1,8 @@
package MyElements::GetSpecificCookie;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetSpecificCookie"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %index_of :ATTR(:get<index>);
__PACKAGE__->_factory(
[ qw(
index
) ],
{
index => \%index_of,
},
{
index => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -39,47 +10,70 @@ __PACKAGE__->__set_name('GetSpecificCookie');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %index_of :ATTR(:get<index>);
__PACKAGE__->_factory(
[ qw(
index
) ],
{
index => \%index_of,
},
{
index => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::GetSpecificCookie
=head1 NAME
=head1 SYNOPSIS
MyElements::GetSpecificCookie
=head1 DESCRIPTION
Type class for the XML element GetSpecificCookie.
Perl data type class for the XML Schema defined element
GetSpecificCookie from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
index
my $element = MyElements::GetSpecificCookie->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
index => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
{
index => $some_value, # int
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetSpecificCookie'=> {
'index' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,37 +1,8 @@
package MyElements::GetSpecificCookieResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetSpecificCookieResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetSpecificCookieResult_of :ATTR(:get<GetSpecificCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetSpecificCookieResult
) ],
{
GetSpecificCookieResult => \%GetSpecificCookieResult_of,
},
{
GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -39,47 +10,70 @@ __PACKAGE__->__set_name('GetSpecificCookieResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %GetSpecificCookieResult_of :ATTR(:get<GetSpecificCookieResult>);
__PACKAGE__->_factory(
[ qw(
GetSpecificCookieResult
) ],
{
GetSpecificCookieResult => \%GetSpecificCookieResult_of,
},
{
GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::GetSpecificCookieResponse
=head1 NAME
=head1 SYNOPSIS
MyElements::GetSpecificCookieResponse
=head1 DESCRIPTION
Type class for the XML element GetSpecificCookieResponse.
Perl data type class for the XML Schema defined element
GetSpecificCookieResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
GetSpecificCookieResult
my $element = MyElements::GetSpecificCookieResponse->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
GetSpecificCookieResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
{
GetSpecificCookieResult => $some_value, # string
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetSpecificCookieResponse'=> {
'GetSpecificCookieResult' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,46 +1,8 @@
package MyElements::GetWeather;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetWeather"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %CityName_of :ATTR(:get<CityName>);
my %CountryName_of :ATTR(:get<CountryName>);
__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',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.webserviceX.NET' }
@@ -48,58 +10,75 @@ __PACKAGE__->__set_name('GetWeather');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %CityName_of :ATTR(:get<CityName>);
my %CountryName_of :ATTR(:get<CountryName>);
__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__
# __END__
=pod
=head1 NAME
=head1 NAME
MyElements::GetWeather
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetWeather.
Perl data type class for the XML Schema defined element
GetWeather from the namespace http://www.webserviceX.NET.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
CityName
CountryName
my $element = MyElements::GetWeather->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
CityName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
{
CityName => $some_value, # string
CountryName => $some_value, # string
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetWeather'=> {
'CityName' => $someValue,
'CountryName' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,38 +1,8 @@
package MyElements::GetWeatherResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="GetWeatherResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %GetWeatherResult_of :ATTR(:get<GetWeatherResult>);
__PACKAGE__->_factory(
[ qw(
GetWeatherResult
) ],
{
GetWeatherResult => \%GetWeatherResult_of,
},
{
GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.webserviceX.NET' }
@@ -40,54 +10,70 @@ __PACKAGE__->__set_name('GetWeatherResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %GetWeatherResult_of :ATTR(:get<GetWeatherResult>);
__PACKAGE__->_factory(
[ qw(
GetWeatherResult
) ],
{
GetWeatherResult => \%GetWeatherResult_of,
},
{
GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME
=head1 NAME
MyElements::GetWeatherResponse
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element GetWeatherResponse.
Perl data type class for the XML Schema defined element
GetWeatherResponse from the namespace http://www.webserviceX.NET.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
GetWeatherResult
my $element = MyElements::GetWeatherResponse->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
{
GetWeatherResult => $some_value, # string
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'GetWeatherResponse'=> {
'GetWeatherResult' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,17 +1,8 @@
package MyElements::int;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
#
# <element name="int" type="s:int"/> definition
#
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::int
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -19,42 +10,43 @@ __PACKAGE__->__set_name('int');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::int
);
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::int
=head1 NAME
=head1 SYNOPSIS
MyElements::int
=head1 DESCRIPTION
Type class for the XML element int.
Perl data type class for the XML Schema defined element
int from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
my $element = MyElements::int->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
$some_value, # int
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'int' => $someValue,
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,29 +1,8 @@
package MyElements::readNodeCount;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="readNodeCount"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
__PACKAGE__->_factory(
[ qw() ],
{
},
{
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -31,41 +10,45 @@ __PACKAGE__->__set_name('readNodeCount');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::readNodeCount
=head1 NAME
=head1 SYNOPSIS
MyElements::readNodeCount
=head1 DESCRIPTION
Type class for the XML element readNodeCount.
Perl data type class for the XML Schema defined element
readNodeCount from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
my $element = MyElements::readNodeCount->new($data);
Constructor. The following data structure may be passed to new():
=head1 Object structure
=head1 AUTHOR
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
Generated by SOAP::WSDL
=cut

View File

@@ -1,37 +1,8 @@
package MyElements::readNodeCountResponse;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
# atomic complexType
# <element name="readNodeCountResponse"><complexType> definition
use SOAP::WSDL::XSD::Typelib::ComplexType;
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
my %readNodeCountResult_of :ATTR(:get<readNodeCountResult>);
__PACKAGE__->_factory(
[ qw(
readNodeCountResult
) ],
{
readNodeCountResult => \%readNodeCountResult_of,
},
{
readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }
@@ -39,47 +10,70 @@ __PACKAGE__->__set_name('readNodeCountResponse');
__PACKAGE__->__set_nillable();
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
my %readNodeCountResult_of :ATTR(:get<readNodeCountResult>);
__PACKAGE__->_factory(
[ qw(
readNodeCountResult
) ],
{
readNodeCountResult => \%readNodeCountResult_of,
},
{
readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
}
);
} # end BLOCK
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME MyElements::readNodeCountResponse
=head1 NAME
=head1 SYNOPSIS
MyElements::readNodeCountResponse
=head1 DESCRIPTION
Type class for the XML element readNodeCountResponse.
Perl data type class for the XML Schema defined element
readNodeCountResponse from the namespace http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
readNodeCountResult
my $element = MyElements::readNodeCountResponse->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
readNodeCountResult => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
{
readNodeCountResult => $some_value, # int
}
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'readNodeCountResponse'=> {
'readNodeCountResult' => $someValue,
},
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,18 +1,8 @@
package MyElements::string;
use strict;
use Class::Std::Storable;
use SOAP::WSDL::XSD::Typelib::Element;
#
# <element name="string" type="s:string"/> definition
#
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::string
);
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { 'http://www.webserviceX.NET' }
@@ -20,49 +10,43 @@ __PACKAGE__->__set_name('string');
__PACKAGE__->__set_nillable(true);
__PACKAGE__->__set_minOccurs();
__PACKAGE__->__set_maxOccurs();
__PACKAGE__->__set_ref('');
__PACKAGE__->__set_ref();
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::Builtin::string
);
} # end of BLOCK
1;
__END__
# __END__
=pod
=head1 NAME
=head1 NAME
MyElements::string
=head1 SYNOPSIS
=head1 DESCRIPTION
Type class for the XML element string.
Perl data type class for the XML Schema defined element
string from the namespace http://www.webserviceX.NET.
=head1 PROPERTIES
=head1 METHODS
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
=head2 new
my $element = MyElements::string->new($data);
=head1 Object structure
Constructor. The following data structure may be passed to new():
$some_value, # string
Structure as perl hash:
The object structure is displayed as hash below though this is not correct.
Complex hash elements actually are objects of their corresponding classes
(look for classes of the same name in your typleib).
new() will accept a hash structure like this, but transform it to a object
tree.
'string' => $someValue,
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -1,327 +0,0 @@
package MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie;
use strict;
use warnings;
use MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie;
use base 'SOAP::WSDL::Client::Base';
sub new {
my $class = shift;
my $arg_ref = shift || {};
my $self = $class->SUPER::new({
class_resolver => 'MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie',
proxy => 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx',
%{ $arg_ref }
});
return bless $self, $class;
}
__PACKAGE__->__create_methods(
GetSpecificCookie => [ 'MyElements::GetSpecificCookie', ],
CountCookies => [ 'MyElements::CountCookies', ],
readNodeCount => [ 'MyElements::readNodeCount', ],
GetFortuneCookie => [ 'MyElements::GetFortuneCookie', ],
);
1;
__END__
=pod
=head1 NAME
MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie - SOAP interface to FullerData_x0020_Fortune_x0020_Cookie at
http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx
=head1 SYNOPSIS
my $interface = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie->new();
my $CountCookies = $interface->CountCookies();
=head1 Service FullerData_x0020_Fortune_x0020_Cookie
=head2 Service information:
Port name: FullerData_x0020_Fortune_x0020_CookieSoap
Binding: tns:FullerData_x0020_Fortune_x0020_CookieSoap
Location: http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 readNodeCount
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetFortuneCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 CountCookies
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetSpecificCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head2 Service information:
Port name: FullerData_x0020_Fortune_x0020_CookieHttpGet
Binding: tns:FullerData_x0020_Fortune_x0020_CookieHttpGet
Location:
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 readNodeCount
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetFortuneCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 CountCookies
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetSpecificCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head2 Service information:
Port name: FullerData_x0020_Fortune_x0020_CookieHttpPost
Binding: tns:FullerData_x0020_Fortune_x0020_CookieHttpPost
Location:
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
=head3 readNodeCount
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetFortuneCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 CountCookies
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=head3 GetSpecificCookie
B<Input Message:>
{
}
B<Output Message:>
{
}
B<Fault:>
=cut

View File

@@ -0,0 +1,191 @@
package MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie::FullerData_x0020_Fortune_x0020_CookieSoap;
use strict;
use warnings;
use Class::Std::Storable;
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) = @_;
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) = @_;
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) = @_;
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) = @_;
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 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<SOAP::WSDL::Client|SOAP::WSDL::Client>.
=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 Tue Nov 6 20:56:46 2007
=pod

View File

@@ -0,0 +1,136 @@
package MyInterfaces::GlobalWeather::GlobalWeatherSoap;
use strict;
use warnings;
use Class::Std::Storable;
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) = @_;
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) = @_;
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 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<SOAP::WSDL::Client|SOAP::WSDL::Client>.
=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 Tue Nov 6 21:00:30 2007
=pod

View File

@@ -2,48 +2,47 @@ package MyTypemaps::FullerData_x0020_Fortune_x0020_Cookie;
use strict;
use warnings;
my %typemap = (
'readNodeCount' => 'MyElements::readNodeCount',
'readNodeCountResponse' => 'MyElements::readNodeCountResponse',
# atomic complex type (sequence)
'readNodeCountResponse/readNodeCountResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
# end atomic complex type (sequence)
'GetFortuneCookie' => 'MyElements::GetFortuneCookie',
'GetFortuneCookieResponse' => 'MyElements::GetFortuneCookieResponse',
# atomic complex type (sequence)
'GetFortuneCookieResponse/GetFortuneCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'CountCookies' => 'MyElements::CountCookies',
'CountCookiesResponse' => 'MyElements::CountCookiesResponse',
# atomic complex type (sequence)
'CountCookiesResponse/CountCookiesResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
# end atomic complex type (sequence)
'GetSpecificCookie' => 'MyElements::GetSpecificCookie',
# atomic complex type (sequence)
'GetSpecificCookie/index' => 'SOAP::WSDL::XSD::Typelib::Builtin::int',
# end atomic complex type (sequence)
'GetSpecificCookieResponse' => 'MyElements::GetSpecificCookieResponse',
# atomic complex type (sequence)
'GetSpecificCookieResponse/GetSpecificCookieResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
);
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{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap{ $name };
exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap_1->{ $name };
}
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

View File

@@ -2,49 +2,43 @@ package MyTypemaps::GlobalWeather;
use strict;
use warnings;
my %typemap = (
# SOAP 1.1 fault typemap
'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11',
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN',
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# generated typemap
'GetWeather' => 'MyElements::GetWeather',
# atomic complex type (sequence)
'GetWeather/CityName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'GetWeather/CountryName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'GetWeatherResponse' => 'MyElements::GetWeatherResponse',
# atomic complex type (sequence)
'GetWeatherResponse/GetWeatherResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'GetCitiesByCountry' => 'MyElements::GetCitiesByCountry',
# atomic complex type (sequence)
'GetCitiesByCountry/CountryName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
'GetCitiesByCountryResponse' => 'MyElements::GetCitiesByCountryResponse',
# atomic complex type (sequence)
'GetCitiesByCountryResponse/GetCitiesByCountryResult' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# end atomic complex type (sequence)
);
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{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap{ $name };
exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap_1->{ $name };
}
1;
__END__
=pod
=head1 NAME
MyTypemaps::GlobalWeather; - typemap for ::GlobalWeather;
=head1 DESCRIPTION
Typemap created by SOAP::WSDL for map-based SOAP message parsers.
=cut

View File

@@ -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<name> :default<anonymous>);
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);
}

View File

@@ -10,11 +10,13 @@
# This script demonstrates the use of a interface generated by wsdl2perl.pl
use lib 'lib/';
use MyInterfaces::GlobalWeather;
my $weather = MyInterfaces::GlobalWeather->new();
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);
print $result->get_GetWeatherResult()->get_value() , "\n";
# The result is a XML string
# use get_value to avoid automatic entity encoding
print $result->get_GetWeatherResult()->get_value , "\n";

View File

@@ -30,10 +30,10 @@ print $som->result();
# 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;
my $soap = SOAP::Lite->new()->on_action( sub { join'/', @_ } )
use SOAP::Lite +trace;
$soap = SOAP::Lite->new()->on_action( sub { join'/', @_ } )
->proxy("http://www.webservicex.net/globalweather.asmx"); # from WSDL
my $som = $soap->call(
$som = $soap->call(
SOAP::Data->name('GetWeather')
->attr({ xmlns => 'http://www.webserviceX.NET' }), # from WSDL
SOAP::Data->name('CountryName')->value('Germany'),

View File

@@ -1,153 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.webservicex.net/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://www.webservicex.net/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.webservicex.net/">
<s:element name="GenerateBarCode">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="BarCodeParam" type="tns:BarCodeData" />
<s:element minOccurs="0" maxOccurs="1" name="BarCodeText" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="BarCodeData">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="Height" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Width" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Angle" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Ratio" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Module" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Left" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="Top" type="s:int" />
<s:element minOccurs="1" maxOccurs="1" name="CheckSum" type="s:boolean" />
<s:element minOccurs="0" maxOccurs="1" name="FontName" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="BarColor" type="s:string" />
<s:element minOccurs="0" maxOccurs="1" name="BGColor" type="s:string" />
<s:element minOccurs="1" maxOccurs="1" name="FontSize" type="s:float" />
<s:element minOccurs="1" maxOccurs="1" name="barcodeOption" type="tns:BarcodeOption" />
<s:element minOccurs="1" maxOccurs="1" name="barcodeType" type="tns:BarcodeType" />
<s:element minOccurs="1" maxOccurs="1" name="checkSumMethod" type="tns:CheckSumMethod" />
<s:element minOccurs="1" maxOccurs="1" name="showTextPosition" type="tns:ShowTextPosition" />
<s:element minOccurs="1" maxOccurs="1" name="BarCodeImageFormat" type="tns:ImageFormats" />
</s:sequence>
</s:complexType>
<s:simpleType name="BarcodeOption">
<s:restriction base="s:string">
<s:enumeration value="None" />
<s:enumeration value="Code" />
<s:enumeration value="Typ" />
<s:enumeration value="Both" />
</s:restriction>
</s:simpleType>
<s:simpleType name="BarcodeType">
<s:restriction base="s:string">
<s:enumeration value="Code_2_5_interleaved" />
<s:enumeration value="Code_2_5_industrial" />
<s:enumeration value="Code_2_5_matrix" />
<s:enumeration value="Code39" />
<s:enumeration value="Code39Extended" />
<s:enumeration value="Code128A" />
<s:enumeration value="Code128B" />
<s:enumeration value="Code128C" />
<s:enumeration value="Code93" />
<s:enumeration value="Code93Extended" />
<s:enumeration value="CodeMSI" />
<s:enumeration value="CodePostNet" />
<s:enumeration value="CodeCodabar" />
<s:enumeration value="CodeEAN8" />
<s:enumeration value="CodeEAN13" />
<s:enumeration value="CodeUPC_A" />
<s:enumeration value="CodeUPC_E0" />
<s:enumeration value="CodeUPC_E1" />
<s:enumeration value="CodeUPC_Supp2" />
<s:enumeration value="CodeUPC_Supp5" />
<s:enumeration value="CodeEAN128A" />
<s:enumeration value="CodeEAN128B" />
<s:enumeration value="CodeEAN128C" />
</s:restriction>
</s:simpleType>
<s:simpleType name="CheckSumMethod">
<s:restriction base="s:string">
<s:enumeration value="None" />
<s:enumeration value="Modulo10" />
</s:restriction>
</s:simpleType>
<s:simpleType name="ShowTextPosition">
<s:restriction base="s:string">
<s:enumeration value="TopLeft" />
<s:enumeration value="TopRight" />
<s:enumeration value="TopCenter" />
<s:enumeration value="BottomLeft" />
<s:enumeration value="BottomRight" />
<s:enumeration value="BottomCenter" />
</s:restriction>
</s:simpleType>
<s:simpleType name="ImageFormats">
<s:restriction base="s:string">
<s:enumeration value="BMP" />
<s:enumeration value="EMF" />
<s:enumeration value="EXIF" />
<s:enumeration value="GIF" />
<s:enumeration value="ICON" />
<s:enumeration value="JPEG" />
<s:enumeration value="MemoryBMP" />
<s:enumeration value="PNG" />
<s:enumeration value="TIFF" />
<s:enumeration value="WMF" />
</s:restriction>
</s:simpleType>
<s:element name="GenerateBarCodeResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GenerateBarCodeResult" type="s:base64Binary" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="GenerateBarCodeSoapIn">
<wsdl:part name="parameters" element="tns:GenerateBarCode" />
</wsdl:message>
<wsdl:message name="GenerateBarCodeSoapOut">
<wsdl:part name="parameters" element="tns:GenerateBarCodeResponse" />
</wsdl:message>
<wsdl:portType name="BarCodeSoap">
<wsdl:operation name="GenerateBarCode">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">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.</documentation>
<wsdl:input message="tns:GenerateBarCodeSoapIn" />
<wsdl:output message="tns:GenerateBarCodeSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="BarCodeHttpGet" />
<wsdl:portType name="BarCodeHttpPost" />
<wsdl:binding name="BarCodeSoap" type="tns:BarCodeSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="GenerateBarCode">
<soap:operation soapAction="http://www.webservicex.net/GenerateBarCode" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="BarCodeHttpGet" type="tns:BarCodeHttpGet">
<http:binding verb="GET" />
</wsdl:binding>
<wsdl:binding name="BarCodeHttpPost" type="tns:BarCodeHttpPost">
<http:binding verb="POST" />
</wsdl:binding>
<wsdl:service name="BarCode">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/">Barcode generator</documentation>
<wsdl:port name="BarCodeSoap" binding="tns:BarCodeSoap">
<soap:address location="http://www.webservicex.net/genericbarcode.asmx" />
</wsdl:port>
<wsdl:port name="BarCodeHttpGet" binding="tns:BarCodeHttpGet">
<http:address location="http://www.webservicex.net/genericbarcode.asmx" />
</wsdl:port>
<wsdl:port name="BarCodeHttpPost" binding="tns:BarCodeHttpPost">
<http:address location="http://www.webservicex.net/genericbarcode.asmx" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

View File

@@ -10,12 +10,11 @@ use Class::Std;
use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
use LWP::UserAgent;
our $VERSION='2.00_13';
our $VERSION='2.00_17';
my %no_dispatch_of :ATTR(:name<no_dispatch>);
my %wsdl_of :ATTR(:name<wsdl>);
my %proxy_of :ATTR(:name<proxy>);
my %readable_of :ATTR(:name<readable>);
my %autotype_of :ATTR(:name<autotype>);
my %outputxml_of :ATTR(:name<outputxml> :default<0>);
my %outputtree_of :ATTR(:name<outputtree>);
@@ -31,29 +30,39 @@ my %binding_of :ATTR(:default<()>);
my %service_of :ATTR(:default<()>);
my %definitions_of :ATTR(:get<definitions> :default<()>);
my %serialize_options_of :ATTR(:default<()>);
my %explain_options_of :ATTR(:default<()>);
my %client_of :ATTR(:name<client> :default<()>);
my %keep_alive_of :ATTR(:name<keep_alive> :default<0> );
my %LOOKUP = (
no_dispatch => \%no_dispatch_of,
class_resolver => \%class_resolver_of,
wsdl => \%wsdl_of,
proxy => \%proxy_of,
readable => \%readable_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;
}
sub set_readable; *set_readable = \&readable;
for my $method (keys %LOOKUP ) {
no strict qw(refs);
no strict qw(refs); ## no critic (ProhibitNoStrict)
*{ $method } = sub {
my $self = shift;
my $ident = ident $self;
my $ident = ident $self;
if (@_) {
$LOOKUP{ $method }->{ $ident } = shift;
return $self;
@@ -62,51 +71,54 @@ for my $method (keys %LOOKUP ) {
};
}
{
{ # just a BLOCK for scoping warnings.
# we need to roll our own for supporting
# SOAP::WSDL->new( key => value ) syntax,
# like SOAP::Lite does
no warnings qw(redefine);
# 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 new {
my $class = shift;
my %args_from = @_;
my ($class, %args_from) = @_;
my $self = \do { my $foo = undef };
bless $self, $class;
for (keys %args_from) {
my $method = $self->can("set_$_")
or croak "unknown parameter $_ passed to new";
$method->($self, $args_from{$_});
}
my $ident = ident $self;
my $ident = ident $self;
$self->wsdlinit() if ($wsdl_of{ $ident });
$client_of{ $ident } = SOAP::WSDL::Client->new();
return $self;
}
}
sub wsdlinit {
my $self = shift;
my ($self, %opt) = @_;
my $ident = ident $self;
my %opt = @_;
my $lwp = LWP::UserAgent->new();
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);
# TODO: Port parser to expat and remove XML::LibXML dependency
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
$parser->parse_string( $response->content() );
my $wsdl_definitions = $parser->get_data();
# sanity checks
my $wsdl_definitions = $parser->get_data() or die "unable to parse WSDL";
my $types = $wsdl_definitions->first_types()
or die "unable to extract schema from WSDL";
or croak "unable to extract schema from WSDL";
my $ns = $wsdl_definitions->get_xmlns()
or die "unable to extract XML Namespaces" . $wsdl_definitions->to_string;
( %{ $ns } ) or die "unable to extract XML Namespaces";
or croak "unable to extract XML Namespaces" . $wsdl_definitions->to_string;
( %{ $ns } ) or croak "unable to extract XML Namespaces";
# setup lookup variables
$definitions_of{ $ident } = $wsdl_definitions;
@@ -115,12 +127,6 @@ sub wsdlinit {
typelib => $types,
namespace => $ns,
};
$explain_options_of{ $ident } = {
readable => $self->readable(),
wsdl => $wsdl_definitions,
namespace => $ns,
typelib => $types,
};
$servicename_of{ $ident } = $opt{servicename} if $opt{servicename};
$portname_of{ $ident } = $opt{portname} if $opt{portname};
@@ -130,7 +136,7 @@ sub wsdlinit {
sub _wsdl_get_service :PRIVATE {
my $ident = ident shift;
my $wsdl = $definitions_of{ $ident };
return $service_of{ $ident } = $servicename_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
@@ -142,28 +148,25 @@ sub _wsdl_get_port :PRIVATE {
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 = $port_of{ $ident } || $self->_wsdl_get_port();
$binding_of{ $ident } = $wsdl->find_binding( $wsdl->_expand( $port->get_binding() ) )
or die "no binding found for ", $port->get_binding();
$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 = $binding_of{ $ident } || $self->_wsdl_get_binding();
$porttype_of{ $ident } = $wsdl->find_portType( $wsdl->_expand( $binding->get_type() ) )
or die "cannot find portType for " . $binding->get_type();
$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;
@@ -173,7 +176,7 @@ sub _wsdl_init_methods :PRIVATE {
# get bindings, portType, message, part(s) - use private methods for clear separation...
$self->_wsdl_get_service if not ($service_of{ $ident });
my $binding = $binding_of{ $ident } || $self->_wsdl_get_binding()
|| die "Can't find binding";
|| croak "Can't find binding";
my $portType = $porttype_of{ $ident } || $self->_wsdl_get_portType();
$method_info_of{ $ident } = {};
@@ -194,21 +197,34 @@ sub _wsdl_init_methods :PRIVATE {
$binding_operation->get_name() );
# 2. get input message name
my ( $prefix, $localname ) = split /:/,
my ( $prefix, $localname ) = split /:/xm,
$operation->first_input()->get_message();
# 3. get input message
my $message = $wsdl->find_message( $ns, $localname )
or die "Message {$ns}$localname not found in WSDL definition";
$method->{ parts } = $message->get_part();
or croak "Message {$ns}$localname not found in WSDL definition";
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();
# 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->get_namespace() : undef;
$method->{ namespace } = $binding_operation
? do {
my $input = $binding_operation->first_input();
$input ? $input->first_body()->get_namespace() : undef;
}
: undef;
@@ -222,9 +238,9 @@ sub call {
my ($self, $method, @data_from) = @_;
my $ident = ident $self;
my ($data, $header) = ref $data_from[0]
? ($data_from[0], $data_from[1] )
: (@data_from>1)
my ($data, $header) = ref $data_from[0]
? ($data_from[0], $data_from[1] )
: (@data_from>1)
? ( { @data_from }, undef )
: ( $data_from[0], undef );
@@ -232,16 +248,23 @@ sub call {
$self->_wsdl_init_methods() if not ($method_info_of{ $ident });
my $client = $client_of{ $ident };
$client->set_proxy( $proxy_of{ $ident } || $port_of{ $ident }->get_location() );
$client->set_no_dispatch( $no_dispatch_of{ $ident } );
# 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) : (),
);
$client->set_no_dispatch( $no_dispatch_of{ $ident } );
$client->set_outputxml( $outputxml_of{ $ident } ? 1 : 0 );
# maybe we should introduce something like $output{ $ident } with a fixed
# 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 } ) ) {
&& ( ! $outputhash_of{ $ident } )
&& ( ! $outputxml_of{ $ident } )
&& ( ! $no_dispatch_of{ $ident } ) ) {
require SOAP::WSDL::Deserializer::SOM;
$client->set_deserializer( SOAP::WSDL::Deserializer::SOM->new() );
};
@@ -249,19 +272,19 @@ sub call {
my $method_info = $method_info_of{ $ident }->{ $method };
# TODO serialize both header and body, not only header
my $response = (blessed $data)
my (@response) = (blessed $data)
? $client->call( {
operation => $method,
soap_action => $method_info->{ soap_action },
}, $data )
: do {
my $content = '';
my $content = q{};
# TODO support RPC-encoding: Top-Level element + namespace...
foreach my $part ( @{ $method_info->{ parts } } ) {
$content .= $part->serialize( $method, $data,
$content .= $part->serialize( $method, $data,
{
%{ $serialize_options_of{ $ident } },
readable => $readable_of{ $ident },
%{ $serialize_options_of{ $ident } }
} );
}
$client->call(
@@ -269,27 +292,20 @@ sub call {
operation => $method,
soap_action => $method_info->{ soap_action }
},
# absolutely stupid, but we need a reference which
# 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 unless defined $response; # nothing to do for one-ways
return $response;
}
sub explain {
my $ident = ident shift;
my $opt = $explain_options_of{ $ident };
return $definitions_of{ $ident }->explain( $opt );
}
return if not @response; # nothing to do for one-ways
return wantarray ? @response : $response[0];
}
1;
__END__
@@ -305,23 +321,22 @@ SOAP::WSDL - SOAP with WSDL support
For creating Perl classes instrumenting a web service with a WSDL definition,
read L<SOAP::WSDL::Manual>.
For using an interpreting (thus slow and somewhat troublesome) WSDL based
For using an interpreting (thus slow and somewhat troublesome) WSDL based
SOAP client, which mimics L<SOAP::Lite|SOAP::Lite>'s API, read on.
=head1 SYNOPSIS
my $soap = SOAP::WSDL->new(
wsdl => 'file://bla.wsdl',
readable => 1,
);
my $result = $soap->call('MyMethod', %data);
=head1 DESCRIPTION
SOAP::WSDL provides easy access to Web Services with WSDL descriptions.
The WSDL is parsed and stored in memory.
The WSDL is parsed and stored in memory.
Your data is serialized according to the rules in the WSDL.
@@ -336,7 +351,7 @@ Constructor. All parameters passed are passed to the corresponding methods.
=head2 call
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
a hash reference (with outputhash), plain XML (with outputxml) or a SOAP::SOM
object (with neither of the above set).
call() can be called in different ways:
@@ -353,9 +368,16 @@ Does not support SOAP header data.
my $result = $soap->call('method', $body_ref, $header_ref );
Does support SOAP header data. $body_ref and $header ref may either be
Does support SOAP header data. $body_ref and $header ref may either be
hash refs or SOAP::WSDL::XSD::Typelib::* derived objects.
Result headers are accessible via the result SOAP::SOM object.
If outputtree or outputhash are set, you may also use the following to
access response header data:
my ($body, $header) = $soap->call('method', $body_ref, $header_ref );
=back
=head2 wsdlinit
@@ -368,34 +390,34 @@ Is called automatically from call() if not called directly before.
portname
call
You may set servicename and portname by passing them as attributes to
You may set servicename and portname by passing them as attributes to
wsdlinit:
$soap->wsdlinit(
servicename => 'MyService',
portname => 'MyPort'
portname => 'MyPort',
);
=head1 CONFIGURATION METHODS
=head2 outputtree
When outputtree is set, SOAP::WSDL will return an object tree instead of a
When outputtree is set, SOAP::WSDL will return an object tree instead of a
SOAP::SOM object.
You have to specify a class_resolver for this to work. See
<class_resolver|class_resolver>
You have to specify a class_resolver for this to work. See
L<class_resolver|class_resolver>
=head2 class_resolver
Set the class resolver class (or object).
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
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.
Class resolvers are typically generated by using the to_typemap method on a
SOAP::WSDL::Definitions objects.
Class resolvers are typically generated by using the generate_typemap method
of a SOAP::WSDL::Generator subclass.
Example:
@@ -414,18 +436,18 @@ Class resolver
'Person/Name' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Person/FirstName' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
);
sub get_class { return $typemap{ $_[1] } };
1;
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.
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.
=head2 servicename
$soap->servicename('Name');
Sets the service to operate on. If no service is set via servicename, the
Sets the service to operate on. If no service is set via servicename, the
first service found is used.
Returns the soap object, so you can chain calls like
@@ -436,7 +458,7 @@ Returns the soap object, so you can chain calls like
$soap->portname('Name');
Sets the port to operate on. If no port is set via portname, the
Sets the port to operate on. If no port is set via portname, the
first port found is used.
Returns the soap object, so you can chain calls like
@@ -445,54 +467,45 @@ Returns the soap object, so you can chain calls like
=head2 no_dispatch
When set, call() returns the plain request XML instead of dispatching the
When set, call() returns the plain request XML instead of dispatching the
SOAP call to the SOAP service. Handy for testing/debugging.
=head1 ACCESS TO SOAP::WSDL's internals
=head2 get_client / set_client
Returns the SOAP client implementation used (normally a SOAP::WSDL::Client
Returns the SOAP client implementation used (normally a SOAP::WSDL::Client
object).
Useful for enabling tracing:
# enable tracing via 'warn'
$soap->get_client->set_trace(1);
# enable tracing via a custom facility -
# Log::Log4perl in this case...
$soap->get_client->set_trace(sub { Log::Log4perl->get_logger->info(@_) } );
=head1 EXAMPLES
See the examples/ directory.
=head1 Differences to previous versions
=over
=over
=item * WSDL handling
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
SAX filter for parsing the WSDL and building up a object tree representing
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.
The object tree has two main functions: It knows how to serialize data passed
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.
Yup your're right, there's a builting code generation facility. Read
Yup your're right, there's a builting code generation facility. Read
L<SOAP::WSDL::Manual> for using it.
=item * no_dispatch
=item * no_dispatch
call() with outputtxml set to true now returns the complete SOAP
call() with no_dispatch set to true now returns the complete SOAP request
envelope, not only the body's content.
=item * outputxml
call() with outputxml set to true now returns the complete SOAP
call() with outputxml set to true now returns the complete SOAP response
envelope, not only the body's content.
=item * servicename/portname
@@ -505,15 +518,23 @@ You may pass the servicename and portname as attributes to wsdlinit, though.
=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
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.
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.
@@ -529,13 +550,13 @@ 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.
This is the recommended output format.
You need a class resolver (typemap) for outputting object trees.
See L<class_resolver|class_resolver> above.
=item * Hash refs
This is for convnience: A single hash ref containing the content of the
This is for convnience: A single hash ref containing the content of the
SOAP body.
=item * xml
@@ -549,7 +570,7 @@ See below.
SOAP::Lite returns only the content of the SOAP body when outputxml is set
to true. SOAP::WSDL returns the complete XML response.
=head3 Auto-Dispatching
=head2 Auto-Dispatching
SOAP::WSDL does B<does not> support auto-dispatching.
@@ -561,25 +582,26 @@ SOAP::WSDL::Client and implementing something like
$soap_wsdl_client->call( mySoapMethod, @_);
}
You may even do this in a class factory - see L<wsdl2perl.pl> for creating
You may even do this in a class factory - see L<wsdl2perl.pl> for creating
such interfaces.
=head3 Debugging / Tracing
=head2 Debugging / Tracing
While SOAP::Lite features a global tracing facility, SOAP::WSDL
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<get_client|get_client> for an example and L<SOAP::WSDL::Client> for
This has to be done in the SOAP client used by SOAP::WSDL - see
L<get_client|get_client> for an example and L<SOAP::WSDL::Client> for
details.
=head1 Bugs and Limitations
=head1 BUGS AND LIMITATIONS
=over
=over
=item * SOAP Headers are not supported
=item * perl 5.8.0 or higher required
There's no way to use SOAP Headers with SOAP::WSDL yet.
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
@@ -587,26 +609,31 @@ 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 * outputhash
=item * Incomplete XML Schema definitions support
outputhash is not implemented yet.
XML Schema attribute definitions are not supported yet.
=item * Unsupported XML Schema definitions
Importing external definitions is not supported yet.
The following XML Schema definitions are not supported:
The following XML Schema definitions varieties are not supported:
choice
group
union
simpleContent
complexContent
The following XML Schema definition content model is only partially
supported:
complexContent - only restriction variety supported
See L<SOAP::WSDL::Manual::XSD> for details.
=item * Serialization of hash refs dos not work for ambiguos values
If you have list elements with multiple occurences allowed, SOAP::WSDL
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
Passing in item => [1,2,3] could serialize to
<item>1 2</item><item>3</item>
<item>1</item><item>2 3</item>
@@ -615,7 +642,7 @@ 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
Almost no XML schema facets are implemented yet. The only facets
currently implemented are:
fixed
@@ -644,20 +671,20 @@ The following facets have no influence yet:
Full featured SOAP-library, little WSDL support. Supports rpc-encoded style only. Many protocols supported.
=item * <XML::Compile::WSDL|XML::Compile::WSDL>
=item * L<XML::Compile::WSDL|XML::Compile::WSDL> / L<XML::Compile::SOAP|XML::Compile::SOAP>
A promising-looking approach derived from a cool functional DOM-based XML schema parser.
Will support encoding/decoding of SOAP messages based on WSDL definitions.
Not yet finished at the time of writing - but you may wish to give it a try, especially
if you need to adhere very closely to the XML Schema / WSDL specs.
Not yet finished at the time of writing - but you may wish to give it a try, especially
if you need to adhere very closely to the XML Schema / WSDL specs.
=back
=head2 Sources of documentation
=over
=over
=item * SOAP::WSDL homepage at sourceforge.net
@@ -671,27 +698,30 @@ L<http://www.cpanforum.com/dist/SOAP-WSDL>
=head1 ACKNOWLEDGMENTS
There are many people out there who fostered SOAP::WSDL's developement.
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)
Giovanni S. Fois wrote a improved version of SOAP::WSDL (which eventually
became v1.23)
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.
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 'ACID' Specht constantly asked for better performance.
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.
Paul Kulchenko and Byrne Reese wrote and maintained SOAP::Lite and
thus provided a base (and counterpart) for SOAP::WSDL.
=head1 LICENSE
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
@@ -700,10 +730,10 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 218 $
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: WSDL.pm 218 2007-09-10 16:19:23Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $
$Id: WSDL.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $
=cut

View File

@@ -1,9 +1,11 @@
package SOAP::WSDL::Base;
use strict;
use warnings;
use Carp;
use Class::Std::Storable;
use List::Util qw(first);
use Carp qw(croak carp confess);
our $VERSION='2.00_17';
my %id_of :ATTR(:name<id> :default<()>);
my %name_of :ATTR(:name<name> :default<()>);
@@ -16,6 +18,7 @@ sub DEMOLISH {
my $self = shift;
# delete upward references
delete $parent_of{ ident $self };
return;
}
sub STORABLE_freeze_pre :CUMULATIVE {};
@@ -23,6 +26,16 @@ 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...
#
@@ -34,15 +47,13 @@ sub AUTOMETHOD {
if ($subname =~s{^push_}{}xms) {
my $getter = "get_$subname";
my $setter = "set_$subname";
## Checking here is paranoid - will fail fatally if
## 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...
# croak "no set accessor found for push_$subname"
# if not ($self->can( $setter ));
return sub {
no strict qw(refs);
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;
@@ -54,6 +65,7 @@ sub AUTOMETHOD {
# 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] &&
@@ -70,17 +82,16 @@ sub AUTOMETHOD {
return $result_ref->[0];
};
}
croak "$subname not found in class " . (ref $self || $self);
confess "$subname not found in class " . (ref $self || $self) ;
}
sub init {
my $self = shift;
my @args = @_;
my ($self, @args) = @_;
foreach my $value (@args)
{
die @args if (not defined ($value->{ Name }));
croak @args if (not defined ($value->{ Name }));
if ($value->{ Name } =~m{^xmlns\:}xms) {
die $xmlns_of{ ident $self }
croak $xmlns_of{ ident $self }
if ref $xmlns_of{ ident $self } ne 'HASH';
# add namespaces
@@ -94,80 +105,37 @@ sub init {
# TODO handle xmlns correctly - maybe via setting a prefix ?
next;
}
my $name = $value->{ LocalName };
my $method = "set_$name";
$self->$method( $value->{ Value } ) if ( $method );
my $name = $value->{ LocalName };
my $method = "set_$name";
$self->$method( $value->{ Value } );
}
return $self;
}
sub add_namespace {
my ($self, $uri, $prefix ) = @_;
return unless $uri;
$self->{ namespace } ||= {};
$self->{ namespace }->{ $uri } = $prefix;
}
sub expand {
my ($self, , $qname) = @_;
my ($prefix, $localname) = split /:/x, $qname;
my %ns_map = reverse %{ $self->get_xmlns() };
return ($ns_map{ $prefix }, $localname) if ($ns_map{ $prefix });
sub to_typemap {
warn "to_typemap";
return q{};
}
sub toClass {
my $self = shift;
warn 'toClass is deprecated and will be removed before reaching 2.01 - '
. 'use to_class instead (' . caller() . ')';
$self->to_class(@_);
}
sub to_class {
my $self = shift;
my $opt = shift;
my $template = shift;
$opt->{ base_path } ||= '.';
my $element_prefix = $opt->{ element_prefix } || $opt->{ prefix };
my $type_prefix = $opt->{ type_prefix } || $opt->{ prefix };
if (($type_prefix) && ($type_prefix !~m{ :: $ }xms ) ) {
warn 'type_prefix should end with "::"';
$type_prefix .= '::';
if (my $parent = $self->get_parent()) {
return $parent->expand($qname);
}
if (($element_prefix) && ($element_prefix !~m{ :: $ }xms) ) {
warn 'element_prefix should end with "::"';
$element_prefix .= '::';
}
# Be careful: a Element may be ComplexType, too
# (but not vice versa)
my $prefix = $self->isa('SOAP::WSDL::XSD::Element')
? $element_prefix
: $type_prefix;
die 'No prefix specified' if not $prefix;
my $filename = $prefix . $self->get_name() . '.pm';
$filename =~s{::}{/}xmsg;
my $output = $opt->{ output } || $filename;
require Template;
my $tt = Template->new(
RELATIVE => 1,
OUTPUT_PATH => $opt->{ base_path },
);
my $code = $tt->process( \$template, {
element_prefix => $element_prefix,
type_prefix => $type_prefix,
self => $self,
nsmap => { reverse %{ $opt->{ wsdl }->get_xmlns() } },
structure => $self->explain( { wsdl => $opt->{ wsdl } } ),
},
$output
)
or die $tt->error();
confess "unbound prefix $prefix found for $prefix:$localname";
}
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 $
#

View File

@@ -10,106 +10,4 @@ my %type_of :ATTR(:name<type> :default<()>);
my %transport_of :ATTR(:name<transport> :default<()>);
my %style_of :ATTR(:name<style> :default<()>);
sub explain {
my $self = shift;
my $opt = shift;
my $name = $self->get_name();
die 'required atribute wsdl missing' if not $opt->{ wsdl };
my $portType = $opt->{ wsdl }->find_portType(
$opt->{ wsdl }->_expand( $self->get_type() )
) or die 'portType not found: ' . $self->get_type();
my $txt = <<"EOT";
=head2 SOAP Operations
B<Note:>
Input, output and fault messages are stated as perl hash refs.
These are only for informational purposes - the actual implementation
normally uses object trees, not hash refs, though the input messages
may be passed to the respective methods as hash refs and will be
converted to object trees automatically.
EOT
foreach my $operation (@{ $self->get_operation() }) {
my $operation_name = $operation->get_name();
my $operation_style = $operation->get_style() || q{};
my $port_operation = first { $_->get_name eq $operation_name }
@{ $portType->get_operation() }
or die "operation not found:" . $operation->get_name();
# TODO rename lexical $input to "message"
my $input_message = do {
my $input = $port_operation->first_input();
$input ? $input->explain($opt) : q{};
};
my $output_message = do {
my $input = $port_operation->first_output();
$input ? $input->explain($opt) : q{};
};
my $fault_message = do {
my $input = $port_operation->first_fault();
$input ? $input->explain($opt) : q{};
};
$txt .= <<"EOT";
=head3 $operation_name
B<Input Message:>
$input_message
B<Output Message:>
$output_message
B<Fault:>
$fault_message
EOT
}
return $txt;
}
sub to_typemap {
my ($self, $opt) = @_;
my $name = $self->get_name();
my $portType = $opt->{ wsdl }->find_portType(
$opt->{ wsdl }->_expand( $self->get_type )
) or die 'portType not found: ' . $self->get_type;
my $txt = q{};
foreach my $operation (@{ $self->get_operation() })
{
my $operation_name = $operation->get_name();
my $operation_style = $operation->get_style() || q{};
my ($port_operation) = grep { $_->get_name eq $operation_name }
@{ $portType->get_operation() }
or die "operation not found:" . $operation->get_name();
no strict qw(refs);
$txt .= join q{},
map {
my $message = $port_operation->$_;
$message
? $message->to_typemap($opt)
: q{}
} qw(first_input first_output first_fault);
}
return $txt;
}
1;

View File

@@ -4,8 +4,6 @@ use warnings;
use Carp;
use Class::Std::Storable;
use LWP::UserAgent;
use HTTP::Request;
use Scalar::Util qw(blessed);
use SOAP::WSDL::Factory::Deserializer;
@@ -13,11 +11,7 @@ use SOAP::WSDL::Factory::Serializer;
use SOAP::WSDL::Factory::Transport;
use SOAP::WSDL::Expat::MessageParser;
our $VERSION='2.00_13';
# Package global for speed and memory savings.
# But should be factored out into serializer/deserializer...
my $PARSER;
our $VERSION = '2.00_17';
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
my %no_dispatch_of :ATTR(:name<no_dispatch> :default<()>);
@@ -27,16 +21,11 @@ my %endpoint_of :ATTR(:name<endpoint> :default<()>);
my %soap_version_of :ATTR(:get<soap_version> :init_attr<soap_version> :default<'1.1'>);
my %trace_of :ATTR(:set<trace> :init_arg<trace> :default<()> );
my %on_action_of :ATTR(:name<on_action> :default<()>);
my %content_type_of :ATTR(:name<content_type> :default<text/xml; charset=utf8>); #/#trick editors
my %serializer_of :ATTR(:name<serializer> :default<()>);
my %deserializer_of :ATTR(:name<deserializer> :default<()>);
# TODO remove when preparing 2.01
sub outputtree { warn 'outputtree is deprecated and'
. 'will be removed before reaching v2.01 !' }
sub BUILD {
my ($self, $ident, $attrs_of_ref) = @_;
@@ -44,24 +33,15 @@ sub BUILD {
$self->set_proxy( $attrs_of_ref->{ proxy } );
delete $attrs_of_ref->{ proxy };
}
return;
}
sub get_trace {
my $ident = ident $_[0];
return $trace_of{ $ident }
? ref $trace_of{ $ident } eq 'CODE'
? $trace_of{ $ident }
: sub { warn @_ }
: ()
}
sub get_proxy {
sub get_proxy { ## no critic RequireArgUnpacking
return $_[0]->get_transport();
}
sub set_proxy {
my ($self, @args_from) = @_;
my ($self, @args_from) = @_;
my $ident = ident $self;
# remember old value to return it later - Class::Std does so, too
@@ -69,7 +49,7 @@ sub set_proxy {
# accept both list and list ref args
@args_from = @{ $args_from[0] } if ref $args_from[0];
# remember endpoint
$endpoint_of{ $ident } = $args_from[0];
@@ -86,23 +66,22 @@ sub set_soap_version {
# remember old value to return it later - Class::Std does so, too
my $soap_version = $soap_version_of{ $ident };
# re-setting the soap version invalidates the
# re-setting the soap version invalidates the
# serializer object
delete $serializer_of{ $ident };
delete $deserializer_of{ $ident };
delete $transport_of{ $ident };
$soap_version_of{ $ident } = shift;
$soap_version_of{ $ident } = shift;
return $soap_version;
}
# Mimic SOAP::Lite's behaviour for getter/setter routines
SUBFACTORY: {
no strict qw(refs);
for (qw(class_resolver no_dispatch outputxml proxy)) {
my $setter = "set_$_";
my $getter = "get_$_";
no strict qw(refs); ## no critic ProhibitNoStrict
*{ $_ } = sub { my $self = shift;
if (@_) {
$self->$setter(@_);
@@ -117,33 +96,32 @@ sub call {
my ($self, $method, @data_from) = @_;
my $ident = ident $self;
# the only valid idiom for calling a method with both a header and a body
# the only valid idiom for calling a method with both a header and a body
# is
# ->call($method, $body_ref, $header_ref);
#
# These other idioms all assume an empty header:
# ->call($method, %body_of); # %body_of is a hash
# ->call($method, $body); # $body is a scalar
my ($data, $header) = ref $data_from[0]
? ($data_from[0], $data_from[1] )
: (@data_from>1)
my ($data, $header) = ref $data_from[0]
? ($data_from[0], $data_from[1] )
: (@data_from>1)
? ( { @data_from }, undef )
: ( $data_from[0], undef );
# get operation name and soap_action
my ($operation, $soap_action) = (ref $method eq 'HASH')
my ($operation, $soap_action) = (ref $method eq 'HASH')
? ( $method->{ operation }, $method->{ soap_action } )
: (blessed $data
: (blessed $data
&& $data->isa('SOAP::WSDL::XSD::Typelib::Builtin::anyType'))
? ( $method , (join '/', $data->get_xmlns(), $method) )
? ( $method , (join q{/}, $data->get_xmlns(), $method) )
: ( $method, q{} );
$serializer_of{ $ident } ||= SOAP::WSDL::Factory::Serializer->get_serializer({
soap_version => $self->get_soap_version(),
});
my $envelope = $serializer_of{ $ident }->serialize({
method => $operation,
method => $operation,
body => $data,
header => $header,
});
@@ -152,7 +130,7 @@ sub call {
# always quote SOAPAction header.
# WS-I BP 1.0 R1109
if ($soap_action) {
if ($soap_action) {
$soap_action =~s{\A(:?"|')?}{"}xms;
$soap_action =~s{(:?"|')?\Z}{"}xms;
}
@@ -161,18 +139,15 @@ sub call {
}
# get response via transport layer.
# Normally, SOAP::Lite's transport layer is used, though users
# Normally, SOAP::Lite's transport layer is used, though users
# may provide their own.
my $transport = $self->get_transport();
my $transport = $self->get_transport();
my $response = $transport->send_receive(
endpoint => $self->get_endpoint(),
content_type => $content_type_of{ $ident },
envelope => $envelope,
action => $soap_action,
on_receive_chunk => sub {} # optional, may be used for parsing large responses as they arrive.
# might not be supported by all transport layers...
# and, of course, only is of interest for chunk parsers -
# namely ExpatNB and XML::LibXML's Push parser interface...
# on_receive_chunk => sub {} # optional, may be used for parsing large responses as they arrive.
);
return $response if ($outputxml_of{ $ident } );
@@ -183,16 +158,20 @@ sub call {
});
# set class resolver if serializer supports it
$deserializer_of{ $ident }->class_resolver( $class_resolver_of{ $ident } )
if ( $deserializer_of{ $ident }->can('class_resolver') );
my $result;
$deserializer_of{ $ident }->set_class_resolver( $class_resolver_of{ $ident } )
if ( $deserializer_of{ $ident }->can('set_class_resolver') );
# Try deserializing response - there may be some,
# even if transport did not succeed (got a 500 response)
if ( $response ) {
eval { $result = $deserializer_of{ $ident }->deserialize( $response ); };
return $result if (not $@);
my ($result_body, $result_header) = eval {
$deserializer_of{ $ident }->deserialize( $response );
};
if (not $@) {
return wantarray
? ($result_body, $result_header)
: $result_body;
}
return $deserializer_of{ $ident }->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
@@ -218,18 +197,28 @@ sub call {
1;
__END__
=pod
=head1 NAME
SOAP::WSDL::Client - SOAP::WSDL's SOAP Client
=head1 SYNOPSIS
use SOAP::WSDL::Client;
my $soap = SOAP::WSDL::Client->new({
proxy => 'http://www.example.org/webservice/test'
});
$soap->call( \%method, $body, $header);
=head1 METHODS
=head2 call
$soap->call( \%method, \@parts );
%method is a hash with the following keys:
Name Description
@@ -237,7 +226,7 @@ SOAP::WSDL::Client - SOAP::WSDL's SOAP Client
operation operation name
soap_action SOAPAction HTTP header to use
style Operation style. One of (document|rpc)
use SOAP body encoding. One of (literal|encoded)
use SOAP body encoding. One of (literal|encoded)
The style and use keys have no influence yet.
@@ -247,12 +236,11 @@ For backward compatibility, call may also be called as below:
$soap->call( $method, \@parts );
In this case, $method is the SOAP operation name, and the SOAPAction header
is guessed from the first part's namespace and the operation name (which is
mostly correct, but may fail). Operation style and body encoding are assumed to
In this case, $method is the SOAP operation name, and the SOAPAction header
is guessed from the first part's namespace and the operation name (which is
mostly correct, but may fail). Operation style and body encoding are assumed to
be document/literal
=head2 Configuration methods
=head3 outputxml
@@ -261,17 +249,17 @@ be document/literal
When set, call() returns the raw XML of the SOAP Envelope.
=head3 set_content_type
=head3 set_content_type
$soap->set_content_type('application/xml; charset: utf8');
Sets the content type and character encoding.
Sets the content type and character encoding.
You probably should not use a character encoding different from utf8:
SOAP::WSDL::Client will not convert the request into a different encoding
You probably should not use a character encoding different from utf8:
SOAP::WSDL::Client will not convert the request into a different encoding
(yet).
To leave out the encoding, just set the content type without appendet charset
To leave out the encoding, just set the content type without appendet charset
like in
text/xml
@@ -287,8 +275,8 @@ Default:
When set to a true value, tracing (via warn) is enabled.
When set to a code reference, this function will be called on every
trace call, making it really easy for you to set up log4perl logging
When set to a code reference, this function will be called on every
trace call, making it really easy for you to set up log4perl logging
or whatever you need.
=head2 Features different from SOAP::Lite
@@ -354,22 +342,28 @@ SOAP::WSDL::Client and implementing something like
$soap_wsdl_client->call( mySoapMethod, @_);
}
You may even do this in a class factory - see L<wsdl2perl.pl> for creating
You may even do this in a class factory - see L<wsdl2perl.pl> for creating
such interfaces.
=head3 Debugging / Tracing
=head1 TROUBLESHOOTING
While SOAP::Lite features a global tracing facility, SOAP::WSDL::Client
allows to switch tracing on/of on a per-object base.
=head2 Accessing protected web services
See L<set_trace|set_trace> on how to enable tracing.
Accessing protected web services is very specific for the transport
backend used.
=head1 LICENSE
In general, you may pass additional arguments to the set_proxy method (or
a list ref of the web service address and any additional arguments to the
new method's I<proxy> argument).
Refer to the appropriate transport module for documentation.
=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
This file is part of SOAP-WSDL. You may distribute/modify it under the same
terms as perl itself
=head1 AUTHOR
@@ -377,10 +371,10 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 218 $
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Client.pm 218 2007-09-10 16:19:23Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
$Id: Client.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
=cut

View File

@@ -2,54 +2,59 @@ package SOAP::WSDL::Client::Base;
use strict;
use warnings;
use base 'SOAP::WSDL::Client';
use Scalar::Util qw(blessed);
sub __create_new {
my ($package, %args_of) = @_;
no strict qw(refs);
*{ "$package\::new" } = sub {
my $class = shift;
my $self = $class->SUPER::new({
proxy => $args_of{ proxy },
class_resolver => $args_of{ class_resolver }
});
bless $self, $class;
return $self;
}
our $VERSION = '2.00_24';
sub call {
my ($self, $method, $body, $header) = @_;
if (not blessed $body) {
$body = {} if not defined $body;
my $class = $method->{ body }->{ parts }->[0];
eval "require $class" || die $@;
$body = $class->new($body);
}
# if we have a header
if (%{ $method->{ header } }) {
if (not blessed $header) {
my $class = $method->{ header }->{ parts }->[0];
eval "require $class" || die $@;
$header = $class->new($header);
}
}
return $self->SUPER::call($method, $body, $header);
}
sub __create_methods {
my ($package, %info_of) = @_;
no strict qw(refs);
for my $method (keys %info_of){
my ($soap_action, @parts);
# up to 2.00_10 we had list refs...
if (ref $info_of{ $method }eq 'HASH') {
@parts = @{ $info_of{ $method }->{ parts } };
$soap_action = $info_of{ $method }->{ soap_action };
}
else {
@parts = @{ $info_of{ $method } };
$soap_action = ();
}
*{ "$package\::$method" } = sub {
my $self = shift;
my @param = map {
my ($package, %info_of) = @_;
no strict qw(refs);
no warnings qw(redefine);
for my $method (keys %info_of){
my ($soap_action, @parts);
# up to 2.00_10 we had list refs...
if (ref $info_of{ $method }eq 'HASH') {
@parts = @{ $info_of{ $method }->{ parts } };
$soap_action = $info_of{ $method }->{ soap_action };
}
else {
die "Pre-v2.00_10 Interfaces are no longer supported. Please re-generate your interface.";
}
*{ "$package\::$method" } = sub {
my $self = shift;
my @param = map {
my $data = shift || {};
eval "require $_";
$_->new( $data );
} @parts;
return $self->SUPER::call( {
operation => $method,
soap_action => $soap_action,
}, @param );
} @parts;
return $self->SUPER::call( {
operation => $method,
soap_action => $soap_action,
}, @param );
}
}
}
@@ -68,24 +73,20 @@ SOAP::WSDL::Client::Base - Factory class for WSDL-based SOAP access
package MySoapInterface;
use SOAP::WSDL::Client::Base;
__PACKAGE__->__create_new(
proxy => 'http://somewhere.over.the.rainbow',
class_resolver => 'Typemap::MySoapInterface'
);
__PACKAGE__->__create_methods( qw(one two three) );
1;
=head1 DESCRIPTION
Factory class for creating interface classes. Should probably be renamed to
Factory class for creating interface classes. Should probably be renamed to
SOAP::WSDL::Factory::Interface...
=head1 LICENSE
=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
This file is part of SOAP-WSDL. You may distribute/modify it under the same
terms as perl itself
=head1 AUTHOR
@@ -93,9 +94,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 214 $
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Base.pm 214 2007-09-10 15:54:52Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client/Base.pm $
$Id: Base.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client/Base.pm $
=cut

View File

@@ -9,6 +9,8 @@ use List::Util qw(first);
use Class::Std::Storable;
use base qw(SOAP::WSDL::Base);
our $VERSION='2.00_17';
my %types_of :ATTR(:name<types> :default<[]>);
my %message_of :ATTR(:name<message> :default<()>);
my %portType_of :ATTR(:name<portType> :default<()>);
@@ -17,7 +19,7 @@ my %service_of :ATTR(:name<service> :default<()>);
my %namespace_of :ATTR(:name<namespace> :default<()>);
# must be attr for Class::Std::Storable
my %attributes_of :ATTR();
my %attributes_of :ATTR();
%attributes_of = (
binding => \%binding_of,
message => \%message_of,
@@ -27,292 +29,21 @@ my %attributes_of :ATTR();
# Function factory - we could be writing this method for all %attribute
# keys, too, but that's just C&P (eehm, Copy & Paste...)
BLOCK: {
no strict qw/refs/;
BLOCK: {
foreach my $method(keys %attributes_of ) {
no strict qw/refs/; ## no critic ProhibitNoStrict
*{ "find_$method" } = sub {
my ($self, @args) = @_;
return first {
$_->get_targetNamespace() eq $args[0]
&& $_->get_name() eq $args[1]
my ($self, @args_from) = @_;
@args_from = @{ $args_from[0] } if ref $args_from[0] eq 'ARRAY';
return first {
$_->get_targetNamespace() eq $args_from[0]
&& $_->get_name() eq $args_from[1]
}
@{ $attributes_of{ $method }->{ ident $self } };
};
}
}
sub explain {
my $self = shift;
my $opt = shift;
$opt->{ wsdl } ||= $self;
$opt->{ namespace } ||= $self->get_xmlns() || {};
my $txt = '';
for my $service (@{ $self->get_service() }) {
$txt .= $service->explain( $opt ) . "\n";
}
return $txt;
}
sub _expand {
my ($self, $prefix, $localname) = ($_[0], split /:/, $_[1]);
my %ns_map = reverse %{ $self->get_xmlns() };
return ($ns_map{ $prefix }, $localname);
}
sub to_typemap {
my $self = shift;
my $opt = shift;
$opt->{ prefix } ||= q{};
$opt->{ wsdl } ||= $self;
$opt->{ type_prefix } ||= $opt->{ prefix };
$opt->{ element_prefix } ||= $opt->{ prefix };
return join "\n",
map { $_->to_typemap( $opt ) } @{ $service_of{ ident $self } };
}
sub create {
my $self = shift;
my $opt = shift;
my $base_path = $opt->{ base_path }
or croak "missing or empty argument base_path";
$opt->{ prefix } ||= q{};
$opt->{ type_prefix } ||= $opt->{ prefix };
$opt->{ element_prefix } ||= $opt->{ prefix };
$opt->{ typemap_prefix } or die 'Required argument typemap_prefix missing';
mkpath $base_path;
for my $service (@{ $service_of{ ident $self } }) {
warn "creating typemap $opt->{ typemap_prefix }". $service->get_name() . "\n";
$self->_create_typemap({ %{ $opt }, service => $service });
$self->_create_interface({ %{ $opt }, service => $service });
}
my @schema = @{ $self->first_types()->get_schema() };
for my $type (map { @{ $_->get_type() } , @{ $_->get_element() } } @schema[1..$#schema] ) {
warn 'creating class for '. $type->get_name() . "\n";
$type->to_class( { %$opt, wsdl => $self } );
}
}
sub _create_interface {
my $self = shift;
my $opt = shift;
my $service_name = $opt->{ service }->get_name();
$service_name =~s{\.}{\:\:}xmsg;
# TODO: iterate over ports.
# - ignore non-SOAP ports
# - generate interface for all SOAP ports...
my $binding = $self->find_binding( $self->_expand( $opt->{ service }->first_port()->get_binding() ) );
my $porttype = $self->find_portType( $self->_expand( $binding->get_type() ) );
my $port_operation_ref = $porttype->get_operation();
my $operation_ref = $binding->get_operation();
# make up operations map - name => [ part types / elements class names ]
#
my %operations = ();
for my $operation ( @{ $operation_ref } ) {
my $operation_name = $operation->get_name();
my $soap_operation = $operation->first_operation();
$operations{ $operation_name }->{ style } = $soap_operation
? $soap_operation->get_style()
: undef;
$operations{ $operation_name }->{ soap_action } = $soap_operation
? $soap_operation->get_soapAction()
: undef;
my $port_op = first { $_->get_name() eq $operation_name } @{ $port_operation_ref };
$operations{ $operation_name }->{ documentation } = $port_op->get_documentation();
my %msg_from = (
'input' => ($port_op->first_input() ) ? $port_op->first_input()->get_message() : undef,
'output' => ($port_op->first_output()) ? $port_op->first_output()->get_message(): undef,
'fault' => ($port_op->first_fault()) ? $port_op->first_fault()->get_message() : undef,
);
for my $msg (keys %msg_from) {
next if not $msg_from{ $msg };
for my $part (@{ $self->find_message( $self->_expand( $msg_from{$msg} ) )->get_part }) {
my $name;
if (my $element_name = $part->get_element() ) {
$name = $element_name;
push @{ $operations{ $operation_name }->{$msg}->{ types } },
$self->first_types()->find_element( $self->_expand( $element_name ) )
->explain({ wsdl => $self , anonymous => 1 });
}
elsif (my $type_name = $part->get_element() ) {
push @{ $operations{ $operation_name }->{$msg}->{ types } },
$self->first_types()->find_type( $self->_expand( $element_name ) )
->explain({ wsdl => $self });
$name = $type_name;
}
my ($prefix, $localname) = split m{:}xms , $name;
push @{ $operations{ $operation_name }->{$msg}->{ class } },
"$opt->{ element_prefix }$localname";
}
}
}
my $template = <<'EOT';
package [% interface_prefix %][% service.get_name.replace('\.', '::') %];
use strict;
use warnings;
use [% typemap_prefix %][% service.get_name %];
use base 'SOAP::WSDL::Client::Base';
sub new {
my $class = shift;
my $arg_ref = shift || {};
my $self = $class->SUPER::new({
class_resolver => '[% typemap_prefix %][% service.get_name.replace('\.', '::') %]',
proxy => '[% service.first_port.get_location %]',
%{ $arg_ref }
});
return bless $self, $class;
}
__PACKAGE__->__create_methods(
[% FOREACH name = operations.keys -%]
[% name %] => {
parts => [ [% FOREACH class = operations.$name.input.class %]'[% class %]', [% END %]],
soap_action => '[% operations.$name.soap_action %]',
style => '[% operations.$name.style %]',
# use => '', # use not implemented yet
},
[% END %]
);
1;
__END__
[% MACRO pod BLOCK %]=pod[% END %]
[% MACRO cut BLOCK %]=pod[% END %]
[% MACRO head1 BLOCK %]=head1[% END %]
[% MACRO head2 BLOCK %]=head2[% END %]
[% pod %]
[% head1 %] NAME
[% interface_prefix %][% service.get_name %] - SOAP interface to [% service.get_name %] at
[% service.first_port.get_location %]
[% head1 %] SYNOPSIS
my $interface = [% interface_prefix %][% service.get_name %]->new();
my $[% operations.keys.1 %] = $interface->[% operations.keys.1 %]();
[% head1 %] METHODS
[% FOREACH name=operations.keys;
operation=operations.$name;
%]
[% head2 %] [% name %]
[% operation.documentation %]
SYNOPSIS:
$service->[% name %]({
[% FOREACH type = operation.input.types; type; END %] });
[% END %]
[% cut %]
EOT
require Template;
my $file_name = "$opt->{ base_path }/$opt->{ interface_prefix }/$service_name.pm";
$file_name =~s{::}{/}gms;
my $path = dirname $file_name;
my $name = basename $file_name;
my $tt = Template->new(
OUTPUT_PATH => $path,
);
$tt->process(\$template,
{ %{ $opt }, operations => \%operations, binding => $binding, wsdl => $self },
$name,
binmode => ':utf8'
)
or die $tt->error();
return 1;
}
sub _create_typemap {
my $self = shift;
my $opt = shift;
my $service_name = $opt->{ service }->get_name();
$service_name =~s{\.}{\:\:}xmsg;
my $file_name = "$opt->{ base_path }/$opt->{ typemap_prefix }/$service_name.pm";
$file_name =~s{::}{/}gms;
my $path = dirname $file_name;
my $name = basename $file_name;
my $typemap = $opt->{ service }->to_typemap( { %{ $opt }, wsdl => $self } );
my $template = <<'EOT';
package [% typemap_prefix %][% service.get_name.replace('\.', '::') %];
use strict;
use warnings;
my %typemap = (
# SOAP 1.1 fault typemap
'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11',
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN',
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
# generated typemap
[% typemap %]
[% custom_types %]
);
sub get_class {
my $name = join '/', @{ $_[1] };
exists $typemap{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap{ $name };
}
1;
__END__
EOT
require Template;
my $tt = Template->new(
OUTPUT_PATH => $path,
);
$tt->process(\$template,
{ %{ $opt }, typemap => $typemap },
$name,
binmode => ':utf8',
)
or die $tt->error();
}
sub listify {
my $data = shift;
return if not defined $data;
return [ $data ] if not ref $data;
return [ $data ] if not ref $data eq 'ARRAY';
return $data;
}
1;
=pod
@@ -327,7 +58,7 @@ SOAP::WSDL::Definitions - model a WSDL E<gt>definitionsE<lt> element
=head2 first_service get_service set_service push_service
Accessors/Mutators for accessing / setting the E<gt>serviceE<lt> child
Accessors/Mutators for accessing / setting the E<gt>serviceE<lt> child
element(s).
=head2 find_service
@@ -338,7 +69,7 @@ Returns the service matching the namespace/localname pair passed as arguments.
=head2 first_binding get_binding set_binding push_binding
Accessors/Mutators for accessing / setting the E<gt>bindingE<lt> child
Accessors/Mutators for accessing / setting the E<gt>bindingE<lt> child
element(s).
=head2 find_service
@@ -349,7 +80,7 @@ Returns the binding matching the namespace/localname pair passed as arguments.
=head2 first_portType get_portType set_portType push_portType
Accessors/Mutators for accessing / setting the E<gt>portTypeE<lt> child
Accessors/Mutators for accessing / setting the E<gt>portTypeE<lt> child
element(s).
=head2 find_portType
@@ -360,7 +91,7 @@ Returns the portType matching the namespace/localname pair passed as arguments.
=head2 first_message get_message set_message push_message
Accessors/Mutators for accessing / setting the E<gt>messageE<lt> child
Accessors/Mutators for accessing / setting the E<gt>messageE<lt> child
element(s).
=head2 find_service
@@ -371,155 +102,26 @@ Returns the message matching the namespace/localname pair passed as arguments.
=head2 first_types get_types set_types push_types
Accessors/Mutators for accessing / setting the E<gt>typesE<lt> child
Accessors/Mutators for accessing / setting the E<gt>typesE<lt> child
element(s).
=head2 explain
Returns a POD string describing how to call the methods of the service(s)
described in the WSDL.
=head2 to_typemap
Creates a typemap for use with a generated type class library.
Options:
NAME DESCRIPTION
-------------------------------------------------------------------------
prefix Prefix to use for all classes
type_prefix Prefix to use for all (Complex/Simple)Type classes
element_prefix Prefix to use for all Element classes (with atomic types)
As some webservices tend to use globally unique type definitions, but
locally unique elements with atomic types, type and element classes may
be separated by specifying type_prefix and element_prefix instead of
prefix.
The typemap is plain text which can be used as snipped for building a
SOAP::WSDL class_resolver perl class.
Try something like this for creating typemap classes:
my $parser = XML::LibXML->new();
my $handler = SOAP::WSDL::SAX::WSDLHandler->new()
$parser->set_handler( $handler );
$parser->parse_url('file:///path/to/wsdl');
my $wsdl = $handler->get_data();
my $typemap = $wsdl->to_typemap();
print <<"EOT"
package MyTypemap;
my \%typemap = (
$typemap
);
sub get_class { return \$typemap{\$_[1] } };
1;
"EOT"
=head2 create_interface
Creates a typemap class, classes for all types and elements, and interface
classes for every service.
See L<CODE GENERATOR|CODE GENERATOR> below.
Options:
Name Description
----------------------------------------------------------------------------
prefix Prefix to use for types and elements. Should end with '::'.
element_prefix Prefix to use for element packages. Should end with '::'.
Must be specified if prefix is not given.
type_prefix Prefix to use for type packages. Should end with '::'.
Must be specified if prefix is not given.
typemap_prefix Prefix to use for type packages. Should end with '::'.
Mandatory.
custom_types A perl source code snippet defining custom types for the
class resolver (typemap).
Must look like this:
q{
'path/to/my/element' => 'My::Element',
'path/to/my/element/prop' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'path/to/my/element/prop2' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
};
=head2 _expand
Expands a qualified name into a list consisting of namespace URI and
localname by using the definition's xmlns table.
Used internally by SOAP::WSDL::* classes.
=head1 CODE GENERATOR
TODO: move somewhere else - maybe SOAP::WSDL::Client ?
SOAP::WSDL::Definitions features a code generation facility for generating
perl classes (packages) from a WSDL definition.
The following classes are generated:
=over
=item * Typemaps
A typemap class is created for every service.
Typemaps are basically lookup classes. They allow the
SOAP::WSDL::SAX::MessageHandler to find out which class a XML element
in a SOAP message shoud be processed as.
Typemaps are passed to SOAP::WSDL::Client via the class_resolver
method.
=item * Interfaces
TODO: Implement Interface generation
Interface classes are just convenience shortcuts for accessing web
service methods. They define a method for every web service method,
dispatching the request to SOAP::WSDL::Client.
=item * Type and Element classes
For every top-level E<lt>elementE<gt>, E<lt>complexTypeE<gt> and
E<lt>simpleTypeE<gt> definition in the WSDL's schema, a perl class is
created.
Classes for E<lt>complexTypeE<gt> and E<lt>simpleTypeE<gt> definitions
are prefixed by the C<type_prefix> argument passed to
L<create_interface|create_interface>, classes for E<lt>elementE<gt>
definitions are prefixed by the C<element_prefix> passed to
L<create_interface|create_interface>. If the specific prefixes are not
specified, the C<prefix> argument is used instead.
If your web service is part of a bigger framework which defines types
globally, you probably do well always using the same C<type_prefix>:
This reduces the number of classes generated (provided types
are re-used by more than one service).
You probably should use different element prefixes, though -
E<lt>elementE<gt> definitions tend to be unique in the defining WSDL
only, especially when using document/literal style/encoding.
If not, you probably want to specify just C<prefix> (and use a
different one for every web service).
=back
=head1 LICENSE
=head1 LICENSE and COPYRIGHT
Copyright 2004-2007 Martin Kutter.
This file is part of SOAP-WSDL. You may distribute/modify it under
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Definitions.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Definitions.pm $
=cut

View File

@@ -0,0 +1,160 @@
package SOAP::WSDL::Deserializer::Hash;
use strict;
use warnings;
use Class::Std::Storable;
use SOAP::WSDL::SOAP::Typelib::Fault11;
use SOAP::WSDL::Expat::Message2Hash;
use SOAP::WSDL::Factory::Deserializer;
SOAP::WSDL::Factory::Deserializer->register( '1.1', __PACKAGE__ );
our $VERSION='2.00_24';
sub BUILD {
my ($self, $ident, $args_of_ref) = @_;
# ignore all options
for (keys %{ $args_of_ref }) {
delete $args_of_ref->{ $_ }
}
}
sub deserialize {
my ($self, $content) = @_;
my $parser = SOAP::WSDL::Expat::Message2Hash->new();
eval { $parser->parse_string( $content ) };
if ($@) {
die $self->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
message => "Error deserializing message: $@. \n"
. "Message was: \n$content"
});
}
return $parser->get_data();
}
sub generate_fault {
my ($self, $args_from_ref) = @_;
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => $args_from_ref->{ code } || 'soap:Client',
faultactor => $args_from_ref->{ role } || 'urn:localhost',
faultstring => $args_from_ref->{ message } || "Unknown error"
});
}
1;
=head1 NAME
SOAP::WSDL::Deserializer::Hash - Deserializer SOAP messages into perl hash refs
=head1 SYNOPSIS
use SOAP::WSDL;
use SOAP::WSDL::Deserializer::Hash;
=head1 DESCRIPTION
Deserializer for creating perl hash refs as result of a SOAP call.
=head2 Output structure
The XML structure is converted into a perl data structure consisting of
hash and or list references. List references are used for holding array data.
SOAP::WSDL::Deserializer::Hash creates list references always at the maximum
depth possible.
Examples:
XML:
<MyDataArray>
<MyData>1</MyData>
<MyData>1</MyData>
</MyDataArray>
Perl:
{
MyDataArray => {
MyData => [ 1, 1 ]
}
}
XML:
<DeepArray>
<MyData><int>1<int>/MyData>
<MyData><int>1<int>/MyData>
</DeepArray>
Perl:
{
MyDataArray => {
MyData => [
{ int => 1 },
{ int => 1 }
]
}
}
List reference creation is triggered by the second occurance of an element.
XML Array types with one element only will not be represented as list
references.
=head1 USAGE
All you need to do is to use SOAP::WSDL::Deserializer::Hash.
SOAP::WSDL::Deserializer::Hash autoregisters itself for SOAP1.1 messages
You may register SOAP::WSDLDeserializer::Hash for other SOAP Versions by
calling
SOAP::Factory::Deserializer->register('1.2',
SOAP::WSDL::Deserializer::Hash)
=head1 Limitations
=over
=item * Namespaces
All namespaces are ignored.
=item * XML attributes
All XML attributes are ignored.
=back
=head2 Differences from other SOAP::WSDL::Deserializer classes
=over
=item * generate_fault
SOAP::WSDL::Deserializer::Hash will die with a SOAP::WSDL::Fault11 object when
a parse error appears
=back
=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 E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Hash.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/Hash.pm $
=cut

View File

@@ -1,49 +0,0 @@
package SOAP::WSDL::Deserializer::SOAP11;
use strict;
use warnings;
use Class::Std::Storable;
use SOAP::WSDL::SOAP::Typelib::Fault11;
our $VERSION='2.00_13';
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
sub BUILD {
my ($self, $ident, $args_of_ref) = @_;
# ignore all options except 'class_resolver'
for (keys %{ $args_of_ref }) {
delete $args_of_ref->{ $_ } if $_ ne 'class_resolver';
}
}
sub deserialize {
my ($self, $content) = @_;
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => $class_resolver_of{ ident $self },
});
eval { $parser->parse_string( $content ) };
if ($@) {
return $self->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
message => "Error deserializing message: $@. \n"
. "Message was: \n$content"
});
}
return $parser->get_data();
}
sub generate_fault {
my ($self, $args_from_ref) = @_;
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => $args_from_ref->{ code } || 'soap:Client',
faultactor => $args_from_ref->{ role } || 'urn:localhost',
faultstring => $args_from_ref->{ message } || "Unknown error"
});
}
1;

View File

@@ -1,24 +1,17 @@
package SOAP::WSDL::Deserializer::SOM;
use strict;
use warnings;
use Class::Std::Storable;
use SOAP::Lite;
our $VERSION='2.00_13';
our $VERSION = '2.00_24';
our @ISA;
sub BUILD {
my ($self, $ident, $args_of_ref) = @_;
# ignore all options
for (keys %{ $args_of_ref }) {
delete $args_of_ref->{ $_ };
}
}
sub deserialize {
my ($self, $content) = @_;
return SOAP::Deserializer->new()->deserialize( $content );
eval {
require SOAP::Lite;
push @ISA, 'SOAP::Deserializer';
}
or die "Cannot load SOAP::Lite.
Cannot deserialize to SOM object without SOAP::Lite.
Please install SOAP::Lite.";
sub generate_fault {
my ($self, $args_from_ref) = @_;
@@ -49,13 +42,42 @@ SOAP::WSDL::Deserializer::SOM - Deserializer SOAP messages into SOM objects
Deserializer for creating SOAP::Lite's SOM object as result of a SOAP call.
This package is mainly here for compatibility reasons: You don't have to
change the rest of your SOAP::Lite based app when switching to SOAP::WSDL,
but can just use SOAP::WSDL::Deserializer::SOM to get back the same objects
as you were used to.
This package is here for two reasons:
SOAP::WSDL::Deserializer will not auroregister itself - just use the lines
from the L</SYNOPSIS> to register it as deserializer for SOAP::WSDL.
=over
=item * Compatibility
You don't have to change the rest of your SOAP::Lite based app when switching
to SOAP::WSDL, but can just use SOAP::WSDL::Deserializer::SOM to get back the
same objects as you were used to.
=item * Completeness
SOAP::Lite covers much more of the SOAP specification than SOAP::WSDL.
SOAP::WSDL::Deserializer::SOM can be used for content which cannot be
deserialized by L<SOAP::WSDL::Deserializer::SOAP11|SOAP::WSDL::Deserializer::SOAP11>.
This may be XML including mixed content, attachements and other XML data not
(yet) handled by L<SOAP::WSDL::Deserializer::SOAP11|SOAP::WSDL::Deserializer::SOAP11>.
=back
SOAP::WSDL::Deserializer::SOM is a subclass of L<SOAP::Deserializer|SOAP::Deserializer>
from the L<SOAP::Lite|SOAP::Lite> package.
=head1 USAGE
SOAP::WSDL::Deserializer will not auroregister itself - to use it for a particular
SOAP version just use the following lines:
my $soap_version = '1.1'; # or '1.2', further versions may appear.
use SOAP::WSDL::Deserializer::SOM;
use SOAP::WSDL::Factory::Deserializer;
SOAP::WSDL::Factory::Deserializer->register( $soap_version, __PACKAGE__ );
=head1 DIFFERENCES FROM OTHER CLASSES
=head2 Differences from SOAP::Lite
@@ -63,7 +85,7 @@ from the L</SYNOPSIS> to register it as deserializer for SOAP::WSDL.
=item * No on_fault handler
You cannot specify what to do when an error occurs - SOAP::WSDL will die
You cannot specify what to do when an error occurs - SOAP::WSDL will die
with a SOAP::Fault object on transport errors.
=back
@@ -74,17 +96,17 @@ with a SOAP::Fault object on transport errors.
=item * generate_fault
SOAP::WSDL::Deserializer::SOM will die with a SOAP::Fault object on calls
SOAP::WSDL::Deserializer::SOM will die with a SOAP::Fault object on calls
to generate_fault.
=back
=head1 LICENSE
=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
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself.
=head1 AUTHOR
@@ -92,9 +114,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 176 $
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Serializer.pm 176 2007-08-31 15:28:29Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
$Id: SOM.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/SOM.pm $
=cut

View File

@@ -0,0 +1,106 @@
package SOAP::WSDL::Deserializer::XSD;
use strict;
use warnings;
use Class::Std::Storable;
use SOAP::WSDL::SOAP::Typelib::Fault11;
use SOAP::WSDL::Expat::MessageParser;
our $VERSION='2.00_24';
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
sub BUILD {
my ($self, $ident, $args_of_ref) = @_;
# ignore all options except 'class_resolver'
for (keys %{ $args_of_ref }) {
delete $args_of_ref->{ $_ } if $_ ne 'class_resolver';
}
}
sub deserialize {
my ($self, $content) = @_;
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => $class_resolver_of{ ident $self },
});
eval { $parser->parse_string( $content ) };
if ($@) {
return $self->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
message => "Error deserializing message: $@. \n"
. "Message was: \n$content"
});
}
return ( $parser->get_data(), $parser->get_header() );
}
sub generate_fault {
my ($self, $args_from_ref) = @_;
return SOAP::WSDL::SOAP::Typelib::Fault11->new({
faultcode => $args_from_ref->{ code } || 'soap:Client',
faultactor => $args_from_ref->{ role } || 'urn:localhost',
faultstring => $args_from_ref->{ message } || "Unknown error"
});
}
1;
__END__
=head1 NAME
SOAP::WSDL::Deserializer::XSD - Deserializer SOAP messages into SOAP::WSDL::XSD::Typelib:: objects
=head1 DESCRIPTION
Default deserializer for SOAP::WSDL::Client and interface classes generated by
SOAP::WSDL. Converts SOAP messages to SOAP::WSDL::XSD::Typlib:: based objects.
Needs a class_resolver typemap either passed by the generated interface
or user-provided.
SOAP::WSDL::Deserializer classes implement the API described in
L<SOAP::WSDL::Factory::Deserializer>.
=head1 USAGE
Usually you don't need to do anything to use this package - it's the default
deserializer for SOAP::WSDL::Client and interface classes generated by
SOAP::WSDL.
Is you want to use the XSD serializer from SOAP::WSDL, set the outputtree()
property and provide a class_resolver.
=head1 METHODS
=head2 deserialize
Deserializes the message.
=head2 generate_fault
Generates a L<SOAP::WSDL::SOAP::Typelib::Fault11|SOAP::WSDL::SOAP::Typelib::Fault11>
object and returns it.
=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 E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: XSD.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/XSD.pm $
=cut

View File

@@ -0,0 +1,44 @@
package SOAP::WSDL::Expat::Base;
use strict;
use warnings;
use XML::Parser::Expat;
our $VERSION = '2.00_24';
sub new {
my ($class, $args) = @_;
my $self = {};
bless $self, $class;
return $self;
}
sub parse {
eval {
$_[0]->_initialize( XML::Parser::Expat->new( Namespaces => 1 ) )->parse( $_[1] );
$_[0]->{ parser }->release();
};
$_[0]->{ parser }->xpcroak( $@ ) if $@;
return $_[0]->{ data };
}
sub parsefile {
eval {
$_[0]->_initialize( XML::Parser::Expat->new(Namespaces => 1) )->parsefile( $_[1] );
$_[0]->{ parser }->release();
};
$_[0]->{ parser }->xpcroak( $@ ) if $@;
return $_[0]->{ data };
}
# SAX-like aliases
sub parse_string;
*parse_string = \&parse;
sub parse_file;
*parse_file = \&parsefile;
sub get_data {
return $_[0]->{ data };
}
1;

View File

@@ -0,0 +1,129 @@
#!/usr/bin/perl
package SOAP::WSDL::Expat::Message2Hash;
use strict;
use warnings;
use base qw(SOAP::WSDL::Expat::Base);
our $VERSION = '2.00_24';
sub _initialize {
my ($self, $parser) = @_;
$self->{ parser } = $parser;
delete $self->{ data }; # remove potential old results
my $characters;
my $current = {};
my $list = []; # node list
my $current_part = q{}; # are we in header or body ?
$self->{ data } = $current;
# use "globals" for speed
my ($_element, $_method,
$_class, $_parser, %_attrs) = ();
no strict qw(refs);
$parser->setHandlers(
Start => sub {
push @$list, $current;
#If our element exists and is a list ref, add to it
if ( exists $current->{ $_[1] }
&& ( ref ($current->{ $_[1] }) eq 'ARRAY')
) {
push @{ $current->{ $_[1] } }, {};
$current = $current->{ $_[1] }->[-1];
}
elsif ( exists $current->{ $_[1] } )
{
$current->{ $_[1] } = [ $current->{ $_[1] }, {} ];
$current = $current->{ $_[1] }->[-1];
}
else {
$current->{ $_[1] } = {};
$current = $current->{ $_[1] };
}
return;
},
Char => sub {
$characters .= $_[1] if $_[1] !~m{ \A \s* \z}xms;
return;
},
End => sub {
$_element = $_[1];
# This one easily handles ignores for us, too...
# return if not ref $$list[-1];
if (length $characters) {
if (ref $list->[-1]->{ $_element } eq 'ARRAY') {
$list->[-1]->{ $_element }->[-1] = $characters ;
}
else {
$list->[-1]->{ $_element } = $characters;
}
}
$characters = q{};
$current = pop @$list; # step up in object hierarchy...
return;
}
);
return $parser;
}
1;
=pod
=head1 NAME
SOAP::WSDL::Expat::Message2Hash - Convert SOAP messages to perl hash refs
=head1 SYNOPSIS
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'My::Resolver'
});
$parser->parse( $xml );
my $obj = $parser->get_data();
=head1 DESCRIPTION
Real fast expat based SOAP message parser.
See L<SOAP::WSDL::Manual::Parser> for details.
=head1 Bugs and Limitations
=over
=item * Ignores all namespaces
=item * Ignores all attributes
=item * Does not handle mixed content
=item * The SOAP header is ignored
=back
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 COPYING
This module may be used under the same terms as perl itself.
=head1 Repository information
$ID: $
$LastChangedDate: 2007-09-10 18:19:23 +0200 (Mo, 10 Sep 2007) $
$LastChangedRevision: 218 $
$LastChangedBy: kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $

View File

@@ -3,12 +3,15 @@ package SOAP::WSDL::Expat::MessageParser;
use strict;
use warnings;
use SOAP::WSDL::XSD::Typelib::Builtin;
use XML::Parser::Expat;
use base qw(SOAP::WSDL::Expat::Base);
our $VERSION = '2.00_24';
sub new {
my ($class, $args) = @_;
my $self = {
class_resolver => $args->{ class_resolver },
strict => exists $args->{ strict } ? $args->{ strict } : 1,
};
bless $self, $class;
return $self;
@@ -16,151 +19,164 @@ sub new {
sub class_resolver {
my $self = shift;
$self->{ class_resolver } = shift;
$self->{ class_resolver } = shift if @_;
return $self->{ class_resolver };
}
sub _initialize {
my ($self, $parser) = @_;
$self->{ parser } = $parser;
delete $self->{ data }; # remove potential old results
delete $self->{ header };
my $characters;
#my @characters_from = ();
my $current = undef;
my $ignore = [ 'Envelope', 'Body' ]; # top level elements to ignore
my $list = []; # node list
my $path = []; # current path
my $skip = 0; # skip elements
my $list = []; # node list
my $path = []; # current path
my $skip = 0; # skip elements
my $current_part = q{}; # are we in header or body ?
my $depth = 0;
my %content_check = $self->{strict}
? (
0 => sub {
die "Bad top node $_[1]" if $_[1] ne 'Envelope';
die "Bad namespace for SOAP envelope: " . $_[0]->recognized_string()
if $_[0]->namespace($_[1]) ne 'http://schemas.xmlsoap.org/soap/envelope/';
$depth++;
return;
},
1 => sub {
$depth++;
if ($_[1] eq 'Body') {
if (exists $self->{ data }) { # there was header data
$self->{ header } = $self->{ data };
delete $self->{ data };
$list = [];
$path = [];
undef $current;
}
}
return;
}
)
: ();
my $char_handler = sub {
# push @characters_from, $_[1] if $_[1] =~m{ [^s] }xms;
$characters .= $_[1] if $_[1] =~m{ [^\s] }xms;
return;
};
# use "globals" for speed
my ($_prefix, $_localname, $_element, $_method,
$_class, $_parser, %_attrs) = ();
my ($_prefix, $_method,
$_class) = ();
no strict qw(refs);
no strict qw(refs);
$parser->setHandlers(
Start => sub {
($_parser, $_element, %_attrs) = @_;
($_prefix, $_localname) = split m{:}xms , $_element;
# my ($parser, $element, %_attrs) = @_;
# $depth = $parser->depth();
$_localname ||= $_element; # for non-prefixed elements
# ignore top level elements
if (@{ $ignore } && $_localname eq $ignore->[0]) {
CHECK_ENVELOPE: {
last CHECK_ENVELOPE if $_localname ne 'Envelope';
last CHECK_ENVELOPE if exists $_attrs{ 'xmlns' }
&& $_attrs{ 'xmlns' } eq 'http://schemas.xmlsoap.org/soap/envelope/';
last CHECK_ENVELOPE if $_attrs{ "xmlns:$_prefix"}
eq 'http://schemas.xmlsoap.org/soap/envelope/';
die "Bad namespace for SOAP envelope: " . $parser->recognized_string();
}
shift @{ $ignore };
return;
}
# call methods without using their parameter stack
# That's slightly faster than $content_check{ $depth }->()
# and we don't have to pass $_[1] to the method.
# Yup, that's dirty.
return &{$content_check{ $depth }} if exists $content_check{ $depth };
push @{ $path }, $_localname; # step down in path
return if $skip; # skip inside __SKIP__
push @{ $path }, $_[1]; # step down in path
return if $skip; # skip inside __SKIP__
# resolve class of this element
$_class = $self->{ class_resolver }->get_class( $path )
or die "Cannot resolve class for "
. join('/', @{ $path }) . " via " . $self->{ class_resolver };
# maybe write as "return $skip = join ... if (...)" ?
# would save a BLOCK...
return $skip = join('/', @{ $path }) if ($_class eq '__SKIP__');
push @$list, $current; # step down in tree ()remember current)
$characters = q{}; # empty characters
# Check whether we have a primitive - we implement them as classes
if ($_class eq '__SKIP__') {
$skip = join('/', @{ $path });
$_[0]->setHandlers( Char => undef );
return;
}
push @$list, $current; # step down in tree (remember current)
$characters = q(); # empty characters
# Check whether we have a builtin - we implement them as classes
# We could replace this with UNIVERSAL->isa() - but it's slow...
# match is a bit faster if the string does not match, but WAY slower
# if $class matches...
if (index $_class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
# match is a bit faster if the string does not match, but WAY slower
# if $class matches. We hope to match often...
if (index $_class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
# check wheter there is a non-empty ARRAY reference for $_class::ISA
# or a "new" method
# If not, require it - all classes required here MUST
# define new()
# This is not exactly the same as $class->can('new'), but it's way faster
# This is not exactly the same as $class->can('new'), but it's way faster
defined *{ "$_class\::new" }{ CODE }
or scalar @{ *{ "$_class\::ISA" }{ ARRAY } }
or eval "require $_class" ## no critic qw(ProhibitStringyEval)
or die $@;
or die $@;
}
$current = $_class->new({ %_attrs }); # set new current object
$current = $_class->new({ @_[2..$#_] }); # set new current object
# remember top level element
exists $self->{ data }
or ($self->{ data } = $current);
exists $self->{ data }
or ($self->{ data } = $current);
$depth++;
return;
},
Char => sub {
return if $skip;
$characters .= $_[1];
},
End => sub {
$_element = $_[1];
($_prefix, $_localname) = split m{:}xms , $_element;
$_localname ||= $_element; # for non-prefixed elements
Char => $char_handler,
End => sub {
pop @{ $path }; # step up in path
if ($skip) {
return if $skip ne join '/', @{ $path }, $_localname;
return if $skip ne join '/', @{ $path }, $_[1];
$skip = 0;
$_[0]->setHandlers( Char => $char_handler );
return;
}
$depth--;
# This one easily handles ignores for us, too...
return if not ref $$list[-1];
return if not ref $list->[-1];
# set characters in current if we are a simple type
# we may have characters in complexTypes with simpleContent,
# too - maybe we should rely on the presence of characters ?
# may get a speedup by defining a ident method in anySimpleType
# may get a speedup by defining a ident method in anySimpleType
# and looking it up via exists &$class::ident;
if ( $current->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ) {
$current->set_value( $characters );
}
# currently doesn't work, as anyType does not implement value -
# if ( $current->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ) {
# $current->set_value( $characters );
# }
# currently doesn't work, as anyType does not implement value -
# maybe change ?
# $current->set_value( $characters ) if ($characters);
$current->set_value( $characters ) if (length $characters);
#$current->set_value( join @characters_from ) if (@characters_from);
$characters = q{};
# undef @characters_from;
# set appropriate attribute in last element
# multiple values must be implemented in base class
$_method = "add_$_localname";
$$list[-1]->$_method( $current );
#$_method = "add_$_localname";
$_method = "add_$_[1]";
$list->[-1]->$_method( $current );
$current = pop @$list; # step up in object hierarchy...
return;
}
);
return $parser;
}
sub parse {
$_[0]->_initialize( XML::Parser::Expat->new() )->parse( $_[1] );
return $_[0]->{ data };
}
sub parsefile {
$_[0]->_initialize( XML::Parser::Expat->new() )->parsefile( $_[1] );
return $_[0]->{ data };
}
# SAX-like aliases
sub parse_string;
*parse_string = \&parse;
sub parse_file;
*parse_file = \&parsefile;
sub get_data {
return $_[0]->{ data };
sub get_header {
return $_[0]->{ header };
}
1;
@@ -174,7 +190,7 @@ SOAP::WSDL::Expat::MessageParser - Convert SOAP messages to custom object trees
=head1 SYNOPSIS
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'My::Resolver'
class_resolver => 'My::Resolver'
});
$parser->parse( $xml );
my $obj = $parser->get_data();
@@ -183,14 +199,14 @@ SOAP::WSDL::Expat::MessageParser - Convert SOAP messages to custom object trees
Real fast expat based SOAP message parser.
See L<SOAP::WSDL::Parser> for details.
See L<SOAP::WSDL::Manual::Parser> for details.
=head2 Skipping unwanted items
Sometimes there's unneccessary information transported in SOAP messages.
To skip XML nodes (including all child nodes), just edit the type map for
the message and set the type map entry to '__SKIP__'.
To skip XML nodes (including all child nodes), just edit the type map for
the message and set the type map entry to '__SKIP__'.
=head1 Bugs and Limitations
@@ -204,23 +220,22 @@ the message and set the type map entry to '__SKIP__'.
=back
=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
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
=head1 COPYING
This module may be used under the same terms as perl itself.
=head1 Repository information
$ID: $
$LastChangedDate: 2007-09-10 18:19:23 +0200 (Mo, 10 Sep 2007) $
$LastChangedRevision: 218 $
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: MessageParser.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $
=cut

View File

@@ -6,9 +6,11 @@ use XML::Parser::Expat;
use SOAP::WSDL::Expat::MessageParser;
use base qw(SOAP::WSDL::Expat::MessageParser);
our $VERSION = '2.00_24';
sub parse_start {
my $self = shift;
$self->{ parser } = $_[0]->_initialize( XML::Parser::ExpatNB->new() );
$self->{ parser } = $_[0]->_initialize( XML::Parser::ExpatNB->new( Namespaces => 1 ) );
}
sub init;
*init = \&parse_start;
@@ -19,6 +21,7 @@ sub parse_more {
sub parse_done {
$_[0]->{ parser }->parse_done();
$_[0]->{ parser }->release();
}
1;
@@ -34,7 +37,7 @@ SOAP::WSDL::Expat::MessageStreamParser - Convert SOAP messages to custom object
my $lwp = LWP::UserAgent->new();
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'My::Resolver'
class_resolver => 'My::Resolver'
});
my $chunk_parser = $parser->init();
# process response while it comes in, trying to read 32k chunks.
@@ -47,29 +50,28 @@ SOAP::WSDL::Expat::MessageStreamParser - Convert SOAP messages to custom object
ExpatNB based parser for parsing huge documents.
See L<SOAP::WSDL::Parser> for details.
See L<SOAP::WSDL::Manual::Parser> for details.
=head1 Bugs and Limitations
See SOAP::WSDL::Expat::MessageParser
=head1 LICENSE AND COPYRIGHT
Copyright 2007 Martin Kutter. All rights reserved.
This file is part of SOAP-WSDL. You may distribte/modify it under
the same terms as perl itself
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
=head1 COPYING
This module may be used under the same terms as perl itself.
=head1 Repository information
$ID: $
$LastChangedDate: 2007-09-10 17:54:52 +0200 (Mo, 10 Sep 2007) $
$LastChangedRevision: 214 $
$Rev: 391 $
$LastChangedBy: kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $
$Id: MessageStreamParser.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $
=cut

View File

@@ -1,213 +0,0 @@
#!/usr/bin/perl
package SOAP::WSDL::Expat::MessageSubParser;
use strict;
use warnings;
use SOAP::WSDL::XSD::Typelib::Builtin;
use XML::Parser::Expat;
sub new {
my ($class, $args) = @_;
my $self = {};
bless $self, $class;
return $self;
}
# create handlers via currying - XML::Compiled is a good teacher...
#
# A handler has to know
# - the order of it's child elements
# - the classes for these child elements
# - the handlers for these child elements (sub refs)
# order is checked if provided
sub start_tag {
my $self = shift;
my $arg_ref = shift;
my $CHILD_ORDER = $arg_ref->{ order } || [];
my $CHILD_CLASS = $arg_ref->{ class_of } || {};
my $CHILD_HANDLER = $arg_ref->{ handler_of };
my $CHILD_OCCURS = $arg_ref->{ occurs_of } || {};
my $CHILD_INDEX = 0;
return sub {
# parser, element, attrs
my ($prefix, $localname) = split m{:}xms , $_[1];
$localname ||= $_[1];
=pod
# # implement better checks...
# if (@{ $CHILD_ORDER }) {
# if ($CHILD_ORDER->[$CHILD_INDEX] ne $localname) {
# if (! $CHILD_ORDER->[++$CHILD_INDEX]
# || $CHILD_ORDER->[$CHILD_INDEX] ne $localname) {
# die "misplaced xml element " . $parser->recognized_string()
# . " at line "
# . $parser->current_line()
# . " column " . $parser->current_column() , "\n"
# , "Element order: " . join(',' , @{ $CHILD_ORDER }), "\n"
# }
# }
# }
#
# if (%{ $CHILD_OCCURS }) {
# die "too many occurances of $localname at line "
# . $parser->current_line()
# . " column " . $parser->current_column() , "\n"
# if (not --$CHILD_OCCURS->{ $localname }->{ max });
#
# # min must be checked in end_element !
# $CHILD_OCCURS->{ $localname }->{ min }--
# if ($CHILD_OCCURS->{ $localname }->{ min });
# }
=cut
# remove this some day
return if ($localname eq 'Envelope');
return if ($localname eq 'Body');
# step down in tree (remember current)
push @{ $self->{ list } }, $self->{ current };
$self->{ current } = $CHILD_CLASS->{ $localname }->new({ @_[2..$#_] });
# Set (and remember) next state
push @{ $self->{ handlers } }, $CHILD_HANDLER->{ $localname };
$_[0]->setHandlers( %{ $CHILD_HANDLER->{ $localname } } );
};
}
# characters is a good candidate for replacement when not needed -
# expat calls it for those whitespaces in non-mixed-content-elements, too
sub characters {
my $self = shift;
return sub { $self->{ characters } .= $_[1] };
}
# end_tag is a somewhat generic thingy - don't know whether we should
# curry it, and whether this will speed us up...
sub end_tag {
my $self = shift;
return sub {
# step down handler hierarchy
pop @{ $self->{ handlers } };
# restore state: set handler to last handler
$_[0]->setHandlers( %{ $self->{ handlers }->[ -1 ] } );
my ($prefix, $localname) = split m{:}xms , $_[1];
$localname ||= $_[1]; # for non-prefixed elements
# we only have characters if we need them - if not Char handler
# has to be set to undef
$self->{ current }->set_value( $self->{ characters } )
if ($self->{ characters });
# empty temp characters
undef $self->{ characters };
# return if we're top node
# This one easily handles ignores for us, too...
#
# Hmm... could be replaced by something else, maybe ???
# Maybe by defining an empty end_tag handler for the top node ?
# Can we do this ???
return if not defined $self->{ list }->[-1];
# set appropriate attribute in last element
# multiple values must be implemented in base class
my $method = "add_$localname";
$self->{ list }->[-1]->$method( $self->{ current } );
# step up in object hierarchy...
$self->{ current } = pop @{ $self->{ list } };
};
}
sub end_top_tag {
my $self = shift;
return sub {};
}
sub initialize {
my ($self, $handler_of_ref, $parser ) = @_;
$parser ||= XML::Parser::Expat->new();
$self->{ list } = undef;
$self->{ current } = undef;
$self->{ characters } = q{}; # empty characters
$self->{ handlers } = [ $handler_of_ref ];
$parser->setHandlers( %$handler_of_ref );
return $parser;
}
sub get_data {
return $_[0]->{ current };
}
1;
=pod
=head1 NAME
SOAP::WSDL::Expat::MessageParser - Convert SOAP messages to custom object trees
=head1 SYNOPSIS
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'My::Resolver'
});
$parser->parse( $xml );
my $obj = $parser->get_data();
=head1 DESCRIPTION
Real fast expat based SOAP message parser.
See L<SOAP::WSDL::Parser> for details.
=head2 Skipping unwanted items
Sometimes there's unneccessary information transported in SOAP messages.
To skip XML nodes (including all child nodes), just edit the type map for
the message and set the type map entry to '__SKIP__'.
=head1 Bugs and Limitations
=over
=item * Ignores all namespaces
=item * Does not handle mixed content
=item * The SOAP header is ignored
=back
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 COPYING
This module may be used under the same terms as perl itself.
=head1 Repository information
$ID: $
$LastChangedDate: 2007-09-10 17:54:52 +0200 (Mo, 10 Sep 2007) $
$LastChangedRevision: 214 $
$LastChangedBy: kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageSubParser.pm $

View File

@@ -1,219 +0,0 @@
#!/usr/bin/perl
package SOAP::WSDL::Expat::MessageSubParser;
use strict;
use warnings;
use SOAP::WSDL::XSD::Typelib::Builtin;
use XML::Parser::Expat;
sub new {
my ($class, $args) = @_;
my $self = {
class_resolver => $args->{ class_resolver }
};
bless $self, $class;
return $self;
}
sub class_resolver {
my $self = shift;
$self->{ class_resolver } = shift;
}
sub _start;
sub _initialize {
my ($self, $parser) = @_;
delete $self->{ data };
my $characters;
my $current = undef;
my $ignore = [ 'Envelope', 'Body' ]; # top level elements to ignore
my $list = []; # node list
my $path = []; # current path (without
# number)
my $skip = 0; # skip elements
# use "globals" for speed
my ($_prefix, $_localname, $_element, $_method,
$_class, $_parser, %_attrs) = ();
no strict qw(refs);
my $start_sub = sub {
($_parser, $_element, %_attrs) = @_;
($_prefix, $_localname) = split m{:}xms , $_element;
# $parser->setHandlers( Start => \&_start );
$_localname ||= $_element; # for non-prefixed elements
# ignore top level elements
if (@{ $ignore } && $_localname eq $ignore->[0]) {
shift @{ $ignore };
return;
}
push @{ $path }, $_localname; # step down in path
return if $skip; # skip inside __SKIP__
# resolve class of this element
$_class = $self->{ class_resolver }->get_class( $path )
or die "Cannot resolve class for "
. join('/', @{ $path }) . " via $self->{ class_resolver }";
# maybe write as "return $skip = join ... if (...)" ?
# would save a BLOCK...
return $skip = join('/', @{ $path }) if ($_class eq '__SKIP__');
push @$list, $current; # step down in tree ()remember current)
$characters = q{}; # empty characters
# Check whether we have a primitive - we implement them as classes
# We could replace this with UNIVERSAL->isa() - but it's slow...
# match is a bit faster if the string does not match, but WAY slower
# if $class matches...
if (index $_class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
# check wheter there is a CODE reference for $class::new.
# If not, require it - all classes required here MUST
# define new()
# This is the same as $class->can('new'), but it's way faster
*{ "$_class\::new" }{ CODE }
or eval "require $_class" ## no critic qw(ProhibitStringyEval)
or die $@;
}
$current = $_class->new({ %_attrs }); # set new current object
# remember top level element
defined $self->{ data }
or ($self->{ data } = $current);
};
my $char_sub = sub {
return if $skip;
$characters .= $_[1];
};
my $end_sub = sub {
$_element = $_[1];
($_prefix, $_localname) = split m{:}xms , $_element;
$_localname ||= $_element; # for non-prefixed elements
pop @{ $path }; # step up in path
if ($skip) {
return if $skip ne join '/', @{ $path }, $_localname;
$skip = 0;
return;
}
# This one easily handles ignores for us, too...
return if not ref $$list[-1];
# set characters in current if we are a simple type
# we may have characters in complexTypes with simpleContent,
# too - maybe we should rely on the presence of characters ?
# may get a speedup by defining a ident method in anySimpleType
# and looking it up via exists &$class::ident;
if ( $current->isa('SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType') ) {
$current->set_value( $characters );
}
# set appropriate attribute in last element
# multiple values must be implemented in base class
$_method = "add_$_localname";
$$list[-1]->$_method( $current );
$current = pop @$list; # step up in object hierarchy...
};
$parser->setHandlers(
Start => sub {
$_[0]->setHandlers( Start => $start_sub );
$start_sub->(@_) },
Char => $char_sub,
End => $end_sub,
);
return $parser;
}
sub parse {
$_[0]->_initialize( XML::Parser::Expat->new() )->parse( $_[1] );
return $_[0]->{ data };
}
sub parsefile {
$_[0]->_initialize( XML::Parser::Expat->new() )->parsefile( $_[1] );
return $_[0]->{ data };
}
sub get_data {
return $_[0]->{ data };
}
1;
=pod
=head1 NAME
SOAP::WSDL::Expat::MessageParser - Convert SOAP messages to custom object trees
=head1 SYNOPSIS
my $parser = SOAP::WSDL::Expat::MessageParser->new({
class_resolver => 'My::Resolver'
});
$parser->parse( $xml );
my $obj = $parser->get_data();
=head1 DESCRIPTION
Real fast expat based SOAP message parser.
See L<SOAP::WSDL::Parser> for details.
=head2 Skipping unwanted items
Sometimes there's unneccessary information transported in SOAP messages.
To skip XML nodes (including all child nodes), just edit the type map for
the message and set the type map entry to '__SKIP__'.
=head1 Bugs and Limitations
=over
=item * Ignores all namespaces
=item * Does not handle mixed content
=item * The SOAP header is ignored
=back
=head1 AUTHOR
Replace the whitespace by @ for E-Mail Address.
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 COPYING
This module may be used under the same terms as perl itself.
=head1 Repository information
$ID: $
$LastChangedDate: 2007-09-10 17:54:52 +0200 (Mo, 10 Sep 2007) $
$LastChangedRevision: 214 $
$LastChangedBy: kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/SubParser.pm $

View File

@@ -3,14 +3,7 @@ use strict;
use warnings;
use Carp;
use SOAP::WSDL::TypeLookup;
use XML::Parser::Expat;
sub new {
my ($class, $args) = @_;
my $self = {};
bless $self, $class;
return $self;
}
use base qw(SOAP::WSDL::Expat::Base);
sub _initialize {
my ($self, $parser) = @_;
@@ -18,43 +11,43 @@ sub _initialize {
# init object data
$self->{ parser } = $parser;
delete $self->{ data };
# setup local variables for keeping temp data
my $characters = undef;
my $current = undef;
my $list = []; # node list
# TODO skip non-XML Schema namespace tags
$parser->setHandlers(
Start => sub {
my ($parser, $localname, %attrs) = @_;
$characters = q{};
my $action = SOAP::WSDL::TypeLookup->lookup(
$parser->namespace($localname),
$localname
);
return if not $action;
if ($action->{ type } eq 'CLASS') {
eval "require $action->{ class }";
croak $@ if ($@);
my $obj = $action->{ class }->new({ parent => $current })
->init( _fixup_attrs( $parser, %attrs ) );
if ($current) {
# inherit namespace, but don't override
$obj->set_targetNamespace( $current->get_targetNamespace() )
if not $obj->get_targetNamespace();
# push on parent's element/type list
my $method = "push_$localname";
no strict qw(refs);
$current->$method( $obj );
# remember element for stepping back
push @{ $list }, $current;
}
@@ -69,7 +62,7 @@ sub _initialize {
}
elsif ($action->{ type } eq 'METHOD') {
my $method = $action->{ method } || $localname;
no strict qw(refs);
# call method with
# - default value ($action->{ value } if defined,
@@ -81,24 +74,26 @@ sub _initialize {
? ref $action->{ value }
? @{ $action->{ value } }
: ($action->{ value })
: _fixup_attrs($parser, %attrs)
: _fixup_attrs($parser, %attrs)
);
}
return;
},
Char => sub { $characters .= $_[1] },
End => sub {
Char => sub { $characters .= $_[1]; return; },
End => sub {
my ($parser, $localname) = @_;
my $action = SOAP::WSDL::TypeLookup->lookup(
$parser->namespace( $localname ),
$localname
) || {};
return if not ($action->{ type });
if ( $action->{ type } eq 'CLASS' ) {
$current = pop @{ $list };
if ( $action->{ type } eq 'CLASS' ) {
$current = pop @{ $list };
}
elsif ($action->{ type } eq 'CONTENT' ) {
my $method = $action->{ method };
@@ -110,6 +105,7 @@ sub _initialize {
no strict qw(refs);
$current->$method( $characters );
}
return;
}
);
return $parser;
@@ -118,24 +114,24 @@ sub _initialize {
# make attrs SAX style
sub _fixup_attrs {
my ($parser, %attrs_of) = @_;
my @attrs_from = map { $_ =
my @attrs_from = map { $_ =
{
Name => $_,
Value => $attrs_of{ $_ },
LocalName => $_
}
Name => $_,
Value => $attrs_of{ $_ },
LocalName => $_
}
} keys %attrs_of;
# add xmlns: attrs. expat eats them.
push @attrs_from, map {
# ignore xmlns=FOO namespaces - must be XML schema
# add xmlns: attrs. expat eats them.
push @attrs_from, map {
# ignore xmlns=FOO namespaces - must be XML schema
# Other nodes should be ignored somewhere else
($_ eq '#default')
? ()
? ()
:
{
Name => "xmlns:$_",
{
Name => "xmlns:$_",
Value => $parser->expand_ns_prefix( $_ ),
LocalName => $_
}
@@ -143,33 +139,5 @@ sub _fixup_attrs {
return @attrs_from;
}
sub parse {
$_[0]->_initialize( XML::Parser::Expat->new(
Namespaces => 1
) )->parse( $_[1] );
$_[0]->{ parser }->release();
return $_[0]->{ data };
}
sub parsefile {
$_[0]->_initialize( XML::Parser::Expat->new(
Namespaces => 1
) )->parsefile( $_[1] );
$_[0]->{ parser }->release();
return $_[0]->{ data };
}
# aliases to make it more SAX-like
sub parse_file;
*parse_file = \&parsefile;
sub parse_string;
*parse_string = \&parse;
sub get_data {
return $_[0]->{ data };
}
1;

View File

@@ -2,8 +2,10 @@ package SOAP::WSDL::Factory::Deserializer;
use strict;
use warnings;
our $VERSION = '2.00_24';
my %DESERIALIZER = (
'1.1' => 'SOAP::WSDL::Deserializer::SOAP11',
'1.1' => 'SOAP::WSDL::Deserializer::XSD',
);
# class method
@@ -14,7 +16,15 @@ sub register {
sub get_deserializer {
my ($self, $args_of_ref) = @_;
eval "require $DESERIALIZER{ $args_of_ref->{ soap_version } }" or die $@;
# sanity check
die "no deserializer registered for SOAP version $args_of_ref->{ soap_version }"
if not exists ($DESERIALIZER{ $args_of_ref->{ soap_version } });
# load module
eval "require $DESERIALIZER{ $args_of_ref->{ soap_version } }"
or die "Cannot load serializer $DESERIALIZER{ $args_of_ref->{ soap_version } }", $@;
return $DESERIALIZER{ $args_of_ref->{ soap_version } }->new($args_of_ref);
}
@@ -24,41 +34,48 @@ sub get_deserializer {
=head1 NAME
SOAP::WSDL::Factory::Deserializer - factory for retrieving Deserializer objects
SOAP::WSDL::Factory::Deserializer - Factory for retrieving Deserializer objects
=head1 SYNOPSIS
# from SOAP::WSDL::Client:
$deserializer = SOAP::WSDL::Factory::Serializer->get_deserializer({
$deserializer = SOAP::WSDL::Factory::Deserializer->get_deserializer({
soap_version => $soap_version,
class_resolver => $class_resolver,
});
# in serializer class:
package MyWickedSerializer;
# in deserializer class:
package MyWickedDeserializer;
use SOAP::WSDL::Factory::Deserializer;
# u don't know the SOAP 1.2 recommendation? poor boy...
# register class as deserializer for SOAP1.2 messages
SOAP::WSDL::Factory::Deserializer->register( '1.2' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Factory::Deserializer serves as factory for retrieving
SOAP::WSDL::Factory::Deserializer serves as factory for retrieving
deserializer objects for SOAP::WSDL.
The actual work is done by specific deserializer classes.
SOAP::WSDL::Deserializer tries to load one of the following classes:
a) the class registered for the scheme via register()
=over
=item * The class registered for the scheme via register()
=back
By default, L<SOAP::WSDL::Deserializer::XSD|SOAP::WSDL::Deserializer::XSD>
is registered for SOAP1.1 messages.
=head1 METHODS
=head2 register
SOAP::WSDL::Serializer->register('1.1', 'MyWickedSerializer');
SOAP::WSDL::Deserializer->register('1.1', 'MyWickedDeserializer');
Globally registers a class for use as serializer class.
Globally registers a class for use as deserializer class.
=head2 get_deserializer
@@ -66,27 +83,29 @@ Returns an object of the deserializer class for this endpoint.
=head1 WRITING YOUR OWN DESERIALIZER CLASS
Deserializer classes may register with
SOAP::WSDL::Factory::Deserializer.
Deserializer classes may register with SOAP::WSDL::Factory::Deserializer.
Registering a deserializer class with
SOAP::WSDL::Factory::Deserializer is done by executing the
following code where $version is the SOAP version the class should
be used for, and $class is the class
name.
=head2 Registering a deserializer
Registering a deserializer class with SOAP::WSDL::Factory::Deserializer
is done by executing the following code where $version is the SOAP version
the class should be used for, and $class is the class name.
SOAP::WSDL::Factory::Deserializer->register( $version, $class);
To auto-register your transport class on loading, execute register()
To auto-register your transport class on loading, execute register()
in your tranport class (see L<SYNOPSIS|SYNOPSIS> above).
Deserializer modules must be named equal to the deserializer
class they contain. There can only be one deserializer class per
deserializer module.
=head2 Deserializer package layout
Deserializer modules must be named equal to the deserializer class they
contain. There can only be one deserializer class per deserializer module.
=head2 Methods to implement
Deserializer classes must implement the following methods:
=over
=over
=item * new
@@ -94,33 +113,31 @@ Constructor.
=item * deserialize
Deserialize data from XML to arbitrary formats.
Deserialize data from XML to arbitrary formats.
deserialize() must return a fault indicating that deserializing
failed if any error is encountered during the process of
deserializing the XML message.
deserialize() must return a fault indicating that deserializing failed if
any error is encountered during the process of deserializing the XML message.
The following
positional parameters are passed to the deserialize method:
The following positional parameters are passed to the deserialize method:
$content - the xml message
$content - the xml message
=item * generate_fault
Generate a fault in the supported format. The following named
parameters are passed as a single hash ref:
Generate a fault in the supported format. The following named parameters are
passed as a single hash ref:
code - The fault code, e.g. 'soap:Server' or the like
role - The fault role (actor in SOAP1.1)
role - The fault role (actor in SOAP1.1)
message - The fault message (faultstring in SOAP1.1)
=back
=head1 LICENSE
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
Copyright 2007 Martin Kutter. All rights reserved.
This file is part of SOAP-WSDL. You may distribute/modify it under
This file is part of SOAP-WSDL. You may distribte/modify it under
the same terms as perl itself
=head1 AUTHOR

View File

@@ -0,0 +1,172 @@
package SOAP::WSDL::Factory::Generator;
use strict;
use warnings;
our $VERSION='2.00_24';
my %GENERATOR = (
'XSD' => 'SOAP::WSDL::Generator::Template::XSD',
);
# class method
sub register {
my ($class, $ref_type, $package) = @_;
$GENERATOR{ $ref_type } = $package;
}
sub get_generator {
my ($self, $args_of_ref) = @_;
# sanity check
# die "no generator registered for generation method $args_of_ref->{ type }"
#
my $generator_class = (exists ($GENERATOR{ $args_of_ref->{ type } }))
? $GENERATOR{ $args_of_ref->{ type } }
: $args_of_ref->{ type };
# load module
eval "require $generator_class"
or die "Cannot load generator $generator_class", $@;
return $generator_class->new();
}
1;
=pod
=head1 NAME
SOAP::WSDL::Factory:Generator - Factory for retrieving generator objects
=head1 SYNOPSIS
# from SOAP::WSDL::Client:
$generator = SOAP::WSDL::Factory::Generator->get_generator({
soap_version => $soap_version,
});
# in generator class:
package MyWickedGenerator;
use SOAP::WSDL::Factory::Generator;
# register as generator for SOAP1.2 messages
SOAP::WSDL::Factory::Generator->register( '1.2' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Factory::Generator serves as factory for retrieving
generator objects for SOAP::WSDL.
The actual work is done by specific generator classes.
SOAP::WSDL::Generator tries to load one of the following classes:
=over
=item * the class registered for the scheme via register()
=back
=head1 METHODS
=head2 register
SOAP::WSDL::Generator->register('Lite', 'MyWickedGenerator');
Globally registers a class for use as generator class.
=head2 get_generator
Returns an object of the generator class for this endpoint.
=head1 WRITING YOUR OWN GENERATOR CLASS
=head2 Registering a generator
Generator classes may register with SOAP::WSDL::Factory::Generator.
Registering a generator class with SOAP::WSDL::Factory::Generator is done
by executing the following code where $version is the SOAP version the
class should be used for, and $class is the class name.
SOAP::WSDL::Factory::Generator->register( $version, $class);
To auto-register your transport class on loading, execute register() in
your generator class (see L<SYNOPSIS|SYNOPSIS> above).
=head2 Generator package layout
Generator modules must be named equal to the generator class they contain.
There can only be one generator class per generator module.
=head2 Methods to implement
Generator classes must implement the following methods:
=over
=item * new
Constructor.
=item * generate
Generate SOAP interface
=back
Generators may implements one or more of the following configuration
methods. All of them are tried via can() by wsdl2perl.
=over
=item * set_wsdl
Set the raw WSDL XML. Implement if you have your own WSDL parser.
=item * set_definitions
Sets the (parsed) SOAP::WSDL::Definitions object.
=item * set_type_prefix
Sets the prefix for XML Schema type classes
=item * set_element_prefix
Sets the prefix for XML Schema element classes
=item * set_typemap_prefix
Sets the prefix for typemap classes (class resolvers).
=item * set_interface_prefix
Sets the prefix for interface classes
=item * set_typemap
Set user-defined typemap snippet
=back
=head1 LICENSE AND COPYRIGHT
Copyright 2007 Martin Kutter. All rights reserved.
This file is part of SOAP-WSDL. You may distribte/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 176 $
$LastChangedBy: kutterma $
$Id: Serializer.pm 176 2007-08-31 15:28:29Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
=cut

View File

@@ -2,8 +2,10 @@ package SOAP::WSDL::Factory::Serializer;
use strict;
use warnings;
our $VERSION='2.00_24';
my %SERIALIZER = (
'1.1' => 'SOAP::WSDL::Serializer::SOAP11',
'1.1' => 'SOAP::WSDL::Serializer::XSD',
);
# class method
@@ -14,7 +16,15 @@ sub register {
sub get_serializer {
my ($self, $args_of_ref) = @_;
eval "require $SERIALIZER{ $args_of_ref->{ soap_version } }" or die $@;
# sanity check
die "no serializer registered for SOAP version $args_of_ref->{ soap_version }"
if not exists ($SERIALIZER{ $args_of_ref->{ soap_version } });
# load module
eval "require $SERIALIZER{ $args_of_ref->{ soap_version } }"
or die "Cannot load serializer $SERIALIZER{ $args_of_ref->{ soap_version } }", $@;
return $SERIALIZER{ $args_of_ref->{ soap_version } }->new();
}
@@ -24,7 +34,7 @@ sub get_serializer {
=head1 NAME
SOAP::WSDL::Factory::Serializer - factory for retrieving serializer objects
SOAP::WSDL::Factory::Serializer - Factory for retrieving serializer objects
=head1 SYNOPSIS
@@ -37,19 +47,23 @@ SOAP::WSDL::Factory::Serializer - factory for retrieving serializer objects
package MyWickedSerializer;
use SOAP::WSDL::Factory::Serializer;
# u don't know the SOAP 1.2 recommendation? poor boy...
# register as serializer for SOAP1.2 messages
SOAP::WSDL::Factory::Serializer->register( '1.2' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Factory::Serializer serves as factory for retrieving
SOAP::WSDL::Factory::Serializer serves as factory for retrieving
serializer objects for SOAP::WSDL.
The actual work is done by specific serializer classes.
SOAP::WSDL::Serializer tries to load one of the following classes:
a) the class registered for the scheme via register()
=over
=item * the class registered for the scheme via register()
=back
=head1 METHODS
@@ -65,30 +79,34 @@ Returns an object of the serializer class for this endpoint.
=head1 WRITING YOUR OWN SERIALIZER CLASS
=head2 Registering a deserializer
Serializer classes may register with SOAP::WSDL::Factory::Serializer.
Serializer objects may also be passed directly to SOAP::WSDL::Client
by using the set_serializer method. Note that serializers objects set
via SOAP::WSDL::Client's set_serializer method are discarded when the
SOAP version is changed via set_soap_version.
Serializer objects may also be passed directly to SOAP::WSDL::Client by
using the set_serializer method. Note that serializers objects set via
SOAP::WSDL::Client's set_serializer method are discarded when the SOAP
version is changed via set_soap_version.
Registering a serializer class with SOAP::WSDL::Factory::Serializer
is done by executing the following code where $version is the
SOAP version the class should be used for, and $class is the class
name.
Registering a serializer class with SOAP::WSDL::Factory::Serializer is done
by executing the following code where $version is the SOAP version the
class should be used for, and $class is the class name.
SOAP::WSDL::Factory::Serializer->register( $version, $class);
To auto-register your transport class on loading, execute register()
in your tranport class (see L<SYNOPSIS|SYNOPSIS> above).
To auto-register your transport class on loading, execute register() in
your tranport class (see L</SYNOPSIS> above).
Serializer modules must be named equal to the serializer
class they contain. There can only be one serializer class per
serializer module.
=head2 Serializer package layout
Serializer class must implement the following methods:
Serializer modules must be named equal to the serializer class they contain.
There can only be one serializer class per serializer module.
=over
=head2 Methods to implement
Serializer classes must implement the following methods:
=over
=item * new
@@ -96,8 +114,8 @@ Constructor.
=item * serialize
Serializes data to XML. The following named parameters are passed to
the serialize method in a anonymous hash ref:
Serializes data to XML. The following named parameters are passed to the
serialize method in a anonymous hash ref:
{
method => $operation_name,
@@ -107,12 +125,12 @@ the serialize method in a anonymous hash ref:
=back
=head1 LICENSE
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
Copyright 2004-2007 Martin Kutter. All rights reserved.
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself.
=head1 AUTHOR
@@ -120,9 +138,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 218 $
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Serializer.pm 218 2007-09-10 16:19:23Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
$Id: Serializer.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
=cut

View File

@@ -2,6 +2,8 @@ package SOAP::WSDL::Factory::Transport;
use strict;
use warnings;
our $VERSION='2.00_17';
# class data
my %registered_transport_of = ();
@@ -14,12 +16,12 @@ my %SOAP_LITE_TRANSPORT_OF = (
mailto => 'SOAP::Transport::MAILTO',
'local' => 'SOAP::Transport::LOCAL',
jabber => 'SOAP::Transport::JABBER',
mq => 'SOAP::Transport::MQ',
mq => 'SOAP::Transport::MQ',
);
my %SOAP_WSDL_TRANSPORT_OF = (
http => 'SOAP::WSDL::Transport::HTTP',
https => 'SOAP::WSDL::Transport::HTTP',
https => 'SOAP::WSDL::Transport::HTTP',
);
# class methods only
@@ -33,24 +35,25 @@ sub get_transport {
my ($class, $scheme, %attrs) = @_;
$scheme =~s{ \A ([^\:]+) \: .+ }{$1}smx;
if (exists $registered_transport_of{ $scheme }) {
eval "require $registered_transport_of{ $scheme }" or die $@;
# try "foo::Client" class first - SOAP::Tranport always requires
if ($registered_transport_of{ $scheme }) {
eval "require $registered_transport_of{ $scheme }"
or die "Cannot load transport class $registered_transport_of{ $scheme } : $@";
# try "foo::Client" class first - SOAP::Tranport always requires
# a package withoug the ::Client appended, and then
# instantiates a ::Client object...
# ... pretty weird ...
# ... must be from some time when the max number of files was a
# ... must be from some time when the max number of files was a
# sparse resource ...
# ... but we've decided to mimic SOAP::Lite...
my $protocol_class = $SOAP_LITE_TRANSPORT_OF{ $scheme } . '::Client';
my $transport;
eval {
$transport = $protocol_class->new( %attrs );
};
return $transport if not $@;
# my $protocol_class = $SOAP_LITE_TRANSPORT_OF{ $scheme } . '::Client';
# my $transport;
# eval {
# $transport = $protocol_class->new( %attrs );
# };
# return $transport if not $@;
return $registered_transport_of{ $scheme }->new( %attrs );
}
@@ -65,7 +68,8 @@ sub get_transport {
}
if (exists $SOAP_WSDL_TRANSPORT_OF{ $scheme }) {
eval "require $SOAP_WSDL_TRANSPORT_OF{ $scheme }" or die $@;
eval "require $SOAP_WSDL_TRANSPORT_OF{ $scheme }"
or die "Cannot load transport class $SOAP_WSDL_TRANSPORT_OF{ $scheme } : $@";
return $SOAP_WSDL_TRANSPORT_OF{ $scheme }->new( %attrs );
}
@@ -78,7 +82,7 @@ sub get_transport {
=head1 NAME
SOAP::WSDL::Factory::Transport - factory for retrieving transport objects
SOAP::WSDL::Factory::Transport - Factory for retrieving transport objects
=head1 SYNOPSIS
@@ -89,22 +93,29 @@ SOAP::WSDL::Factory::Transport - factory for retrieving transport objects
package MyWickedTransport;
use SOAP::WSDL::Factory::Transport;
# u don't know the httpr protocol? poor boy...
# register class as transport module for httpr and https
# (httpr is "reliable http", a protocol developed by IBM).
SOAP::WSDL::Factory::Transport->register( 'httpr' , __PACKAGE__ );
SOAP::WSDL::Factory::Transport->register( 'https' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Transport serves as factory for retrieving
transport objects for SOAP::WSDL.
SOAP::WSDL::Transport serves as factory for retrieving transport objects for
SOAP::WSDL.
The actual work is done by specific transport classes.
SOAP::WSDL::Transport tries to load one of the following classes:
a) the class registered for the scheme via register()
b) the SOAP::Lite class matching the scheme
c) the SOAP::WSDL class matching the scheme
=over
=item * the class registered for the scheme via register()
=item * the SOAP::Lite class matching the scheme
=item * the SOAP::WSDL class matching the scheme
=back
=head1 METHODS
@@ -118,7 +129,7 @@ Globally registers a class for use as transport class.
$trans->proxy('http://soap-wsdl.sourceforge.net');
Sets the proxy (endpoint).
Sets the proxy (endpoint).
Returns the transport for this protocol.
@@ -132,33 +143,36 @@ Gets the current transport object.
=head1 WRITING YOUR OWN TRANSPORT CLASS
Transport classes must be registered with SOAP::WSDL::Factory::Transport.
=head2 Registering a transport class
This is done by executing the following code where $scheme is the
URL scheme the class should be used for, and $module is the class'
module name.
Transport classes must be registered with SOAP::WSDL::Factory::Transport.
This is done by executing the following code where $scheme is the URL scheme
the class should be used for, and $module is the class' module name.
SOAP::WSDL::Factory::Transport->register( $scheme, $module);
To auto-register your transport class on loading, execute register()
in your tranport class (see L<SYNOPSIS|SYNOPSIS> above).
To auto-register your transport class on loading, execute register() in your
tranport class (see L<SYNOPSIS|SYNOPSIS> above).
Multiple protocols ore multiple classes are registered by multiple calls to
Multiple protocols ore multiple classes are registered by multiple calls to
register().
You may only use transport classes whose name is either
=head2 Transport plugin package layout
You may only use transport classes whose name is either
the module name or the module name with '::Client' appended.
Transport classes must implement the interface required for
SOAP::Lite transport classes.
=head2 Methods to implement
See L<SOAP::Lite::Transport> for details,
L<SOAP::WSDL::Transport::HTTP|SOAP::WSDL::Transport::HTTP>
for an example.
Transport classes must implement the interface required for SOAP::Lite
transport classes (see L<SOAP::Lite::Transport> for details,
L<SOAP::WSDL::Transport::HTTP|SOAP::WSDL::Transport::HTTP> for an example).
Transport modules must implement the following methods:
To provide this interface, transport modules must implement the following
methods:
=over
=over
=item * new
@@ -184,12 +198,12 @@ Returns true after a send_receive was successful, false if it was not.
=back
SOAP::Lite requires transport modules to pack client and server
SOAP::Lite requires transport modules to pack client and server
classes in one file, and to follow this naming scheme:
Module name:
Module name:
"SOAP::Transport::" . uc($scheme)
Client class (additional package in module):
"SOAP::Transport::" . uc($scheme) . "::Client"
@@ -200,21 +214,20 @@ SOAP::WSDL does not require you to follow these restrictions.
There is only one restriction in SOAP::WSDL:
You may only use transport classes whose name is either
the module name or the module name with '::Client' appended.
You may only use transport classes whose name is either the module name or
the module name with '::Client' appended.
SOAP::WSDL will try to instantiate an object of your
transport class with '::Client' appended to allow using transport
classes written for SOAP::Lite.
SOAP::WSDL will try to instantiate an object of your transport class with
'::Client' appended to allow using transport classes written for SOAP::Lite.
This may lead to errors when a different module with the name
of your transport module suffixed with ::Client is also loaded.
This may lead to errors when a different module with the name of your
transport module suffixed with ::Client is also loaded.
=head1 LICENSE
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2007 Martin Kutter.
Copyright 2004-2007 Martin Kutter. All rights reserved.
This file is part of SOAP-WSDL. You may distribute/modify it under
This file is part of SOAP-WSDL. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
@@ -223,9 +236,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 218 $
$Rev: 391 $
$LastChangedBy: kutterma $
$Id: Transport.pm 218 2007-09-10 16:19:23Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Transport.pm $
$Id: Transport.pm 391 2007-11-17 21:56:13Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Transport.pm $
=cut

View File

@@ -0,0 +1,48 @@
package SOAP::WSDL::Generator::Template;
use strict;
use Template;
use Class::Std::Storable;
our $VERSION='2.00_17';
my %tt_of :ATTR(:get<tt>);
my %definitions_of :ATTR(:name<definitions> :default<()>);
my %interface_prefix_of :ATTR(:name<interface_prefix> :default<MyInterfaces>);
my %typemap_prefix_of :ATTR(:name<typemap_prefix> :default<MyTypemaps>);
my %type_prefix_of :ATTR(:name<type_prefix> :default<MyTypes>);
my %element_prefix_of :ATTR(:name<element_prefix> :default<MyElements>);
my %INCLUDE_PATH_of :ATTR(:name<INCLUDE_PATH> :default<()>);
my %EVAL_PERL_of :ATTR(:name<EVAL_PERL> :default<0>);
my %RECURSION_of :ATTR(:name<RECURSION> :default<0>);
my %OUTPUT_PATH_of :ATTR(:name<OUTPUT_PATH> :default<.>);
sub START {
my ($self, $ident, $arg_ref) = @_;
}
sub _process :PROTECTED {
my ($self, $template, $arg_ref, $output) = @_;
my $ident = ident $self;
my $tt = $tt_of{$ident} ||= Template->new(
DEBUG => 1,
EVAL_PERL => $EVAL_PERL_of{ $ident },
RECURSION => $RECURSION_of{ $ident },
INCLUDE_PATH => $INCLUDE_PATH_of{ $ident },
OUTPUT_PATH => $OUTPUT_PATH_of{ $ident },
);
$tt->process( $template,
{
definitions => $self->get_definitions,
interface_prefix => $self->get_interface_prefix,
type_prefix => $self->get_type_prefix,
typemap_prefix => $self->get_typemap_prefix,
TYPE_PREFIX => $self->get_type_prefix,
element_prefix => $self->get_element_prefix,
NO_POD => delete $arg_ref->{ NO_POD } ? 1 : 0 ,
%{ $arg_ref }
},
$output)
or die $INCLUDE_PATH_of{ $ident }, '\\', $template, ' ', $tt->error();
}
1;

View File

@@ -0,0 +1,162 @@
package SOAP::WSDL::Generator::Template::XSD;
use strict;
use Template;
use Class::Std::Storable;
use File::Basename;
use File::Spec;
use SOAP::WSDL::Generator::Visitor::Typemap;
use SOAP::WSDL::Generator::Visitor::Typelib;
use base qw(SOAP::WSDL::Generator::Template);
my %output_of :ATTR(:name<output> :default<()>);
my %typemap_of :ATTR(:name<typemap> :default<({})>);
sub BUILD {
my ($self, $ident, $arg_ref) = @_;
$self->set_EVAL_PERL(1);
$self->set_RECURSION(1);
$self->set_INCLUDE_PATH( exists $arg_ref->{INCLUDE_PATH}
? $arg_ref->{INCLUDE_PATH}
: do {
# ignore uninitialized warnings - File::Spec warns about
# uninitialized values, probably because we have no filename
local $SIG{__WARN__} = sub {
return if ($_[0]=~m{\buninitialized\b});
CORE::warn @_;
};
# makeup path for the OS we're running on
my ($volume, $dir, $file) = File::Spec->splitpath(
File::Spec->rel2abs( dirname __FILE__ )
);
$dir = File::Spec->catdir($dir, $file, 'XSD');
# return path put together...
my $path = File::Spec->catpath( $volume, $dir );
# Fixup path for windows - / works fine, \ does
# not...
if ( eval { &Win32::BuildNumber } ) {
$path =~s{\\}{/}g;
}
$path;
}
);
}
sub generate {
my $self = shift;
my $opt = shift;
$self->generate_typelib( $opt );
$self->generate_interface( $opt );
$self->generate_typemap( $opt );
}
sub generate_typelib {
my ($self) = @_;
# $output_of{ ident $self } = "";
my @schema = @{ $self->get_definitions()->first_types()->get_schema() };
for my $type (map { @{ $_->get_type() } , @{ $_->get_element() } } @schema[1..$#schema] ) {
$type->_accept( $self );
}
# return $output_of{ ident $self };
return;
}
sub generate_interface {
my $self = shift;
my $ident = ident $self;
my $arg_ref = shift;
my $tt = $self->get_tt();
for my $service (@{ $self->get_definitions->get_service }) {
for my $port (@{ $service->get_port() }) {
# Skip ports without (known) address
next if not $port->first_address;
next if not $port->first_address->isa('SOAP::WSDL::SOAP::Address');
my $port_name = $port->get_name;
$port_name =~s{ \A .+\. }{}xms;
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename(
$self->get_interface_prefix(),
$service->get_name(),
$port_name,
);
print "Creating interface class $output\n";
$self->_process('Interface.tt',
{
service => $service,
port => $port,
NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 ,
},
$output, binmode => ':utf8');
}
}
}
sub generate_typemap {
my ($self, $arg_ref) = @_;
my $visitor = SOAP::WSDL::Generator::Visitor::Typemap->new({
type_prefix => $self->get_type_prefix(),
element_prefix => $self->get_element_prefix(),
definitions => $self->get_definitions(),
typemap => {
'Fault' => 'SOAP::WSDL::SOAP::Typelib::Fault11',
'Fault/faultcode' => 'SOAP::WSDL::XSD::Typelib::Builtin::anyURI',
'Fault/faultactor' => 'SOAP::WSDL::XSD::Typelib::Builtin::TOKEN',
'Fault/faultstring' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
%{ $typemap_of{ident $self }},
}
});
for my $service (@{ $self->get_definitions->get_service }) {
$visitor->visit_Service( $service );
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename( $self->get_typemap_prefix(), $service->get_name() );
print "Creating typemap class $output\n";
$self->_process('Typemap.tt',
{
service => $service,
typemap => $visitor->get_typemap(),
NO_POD => $arg_ref->{ NO_POD } ? 1 : 0 ,
},
$output);
}
}
sub _generate_filename :PRIVATE {
my ($self, @parts) = @_;
my $name = join '::', @parts;
$name =~s{ \. }{::}xmsg;
$name =~s{ :: }{/}xmsg;
return "$name.pm";
}
sub visit_XSD_Element {
my ($self, $element) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_element_prefix(), $element->get_name() );
$self->_process('element.tt', { element => $element } , $output);
}
sub visit_XSD_SimpleType {
my ($self, $type) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_type_prefix(), $type->get_name() );
$self->_process('simpleType.tt', { simpleType => $type } , $output);
}
sub visit_XSD_ComplexType {
my ($self, $type) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_type_prefix(), $type->get_name() );
$self->_process('complexType.tt', { complexType => $type } , $output);
}
1;

View File

@@ -0,0 +1,86 @@
package [% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('^.+\.','') %];
use strict;
use warnings;
use Class::Std::Storable;
use Scalar::Util qw(blessed);
use base qw(SOAP::WSDL::Client::Base);
# only load if it hasn't been loaded before
require [% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]
if not [% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]->can('get_class');
sub START {
$_[0]->set_proxy('[% port.first_address.get_location %]') if not $_[2]->{proxy};
$_[0]->set_class_resolver('[% typemap_prefix %]::[% service.get_name.replace('\.', '::') %]')
if not $_[2]->{class_resolver};
}
[% binding = definitions.find_binding( port.expand( port.get_binding ) );
FOREACH operation = binding.get_operation;
%][% INCLUDE Interface/Operation.tt %]
[%
END;
%]
1;
[% IF NO_POD; STOP; END %]
__END__
=pod
=head1 NAME
[% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('\.', '::') %] - SOAP Interface for the [% service.get_name %] Web Service
=head1 SYNOPSIS
use [% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('\.', '::') %];
my $interface = [% interface_prefix %]::[% service.get_name.replace('\.', '::') %]::[% port.get_name.replace('\.', '::') %]->new();
my $response;
[% FOREACH operation = binding.get_operation;
%] $response = $interface->[% operation.get_name %]();
[% END %]
=head1 DESCRIPTION
SOAP Interface for the [% service.get_name %] web service
located at [% port.first_address.get_location %].
=head1 SERVICE [% service.get_name %]
[% service.get_documentation %]
=head2 Port [% port.get_name %]
[% port.get_documentation %]
=head1 METHODS
=head2 General methods
=head3 new
Constructor.
All arguments are forwarded to L<SOAP::WSDL::Client|SOAP::WSDL::Client>.
=head2 SOAP Service methods
[% INCLUDE Interface/POD/method_info.tt %]
[% FOREACH operation = binding.get_operation;
%][% INCLUDE Interface/POD/Operation.tt %]
[% END %]
=head1 AUTHOR
Generated by SOAP::WSDL on [% PERL %]print scalar localtime() [% END %]
=pod

View File

@@ -0,0 +1,64 @@
[% RETURN IF NOT item;
type = definitions.find_portType( binding.expand( binding.get_type ) );
port_op = type.find_operation( definitions.get_targetNamespace, operation.get_name );
message = definitions.find_message( port_op.first_input.expand( port_op.first_input.get_message ) );
part_from = message.get_part;
PERL %]
my $item = $stash->{ item };
my $def = $stash->{ definitions };
my $part_from = $stash->{ part_from };
my $type_prefix = $stash->{ type_prefix };
my $element_prefix = $stash->{ element_prefix };
my @body_part_from = split m{\s}, $item->get_parts;
my @parts;
if (@body_part_from) {
@parts = map {
my $part = $_;
(grep {
my ($ns, $lname) = $def->expand( $_ );
($lname eq $part->get_name)
} @body_part_from
)
? do {
my $name;
($name = $part->get_element)
? do {
$name =~s{ ^[^:]+: }{}xms;
$element_prefix . '::' . $name;
}
: ($name = $part->get_type)
? do {
$name =~s{ ^[^:]+: }{}xms;
$type_prefix . '::' . $name;
}
: die "input must have either type or element"
}
: ()
} @{ $part_from };
}
else {
@parts = map {
my $part = $_;
my $name;
($name = $part->get_element)
? do {
$name =~s{ ^[^:]+: }{}xms;
"$element_prefix\::$name"
}
: ($name = $part->get_type)
? do {
$name =~s{ ^[^:]+: }{}xms;
"$type_prefix\::$name"
}
: die "input must have either type or element";
} @{ $part_from };
}
$stash->{ parts } = \@parts;
[% END %]
'use' => '[% item.get_use %]',
namespace => '[% item.get_namespace %]',
encodingStyle => '[% item.get_encodingStyle %]',
parts => [qw( [% parts.join(' ') %] )],

View File

@@ -0,0 +1,38 @@
[%
RETURN IF NOT item;
message_name = item.get_message;
IF NOT message_name;
THROW BAD_WSDL "missing <message> attribute in header for operation ${operation.get_name}";
END;
message = definitions.find_message( item.expand( message_name ) );
PERL %]
my $message = $stash->{ message };
my $item = $stash->{ item };
my $def = $stash->{ definitions };
my $type_prefix = $stash->{ type_prefix };
my $element_prefix = $stash->{ element_prefix };
my ($ns, $lname) = $def->expand( $item->get_part() );
my ($part) = grep {
$_->get_name eq $lname
&& $_->get_targetNamespace eq $ns } @{ $message->get_part( ) };
my $part_class = do {
my $name;
($name = $part->get_element)
? do {
$name =~s{ ^[^:]+: }{}xms;
$element_prefix . '::' . $name;
}
: ($name = $part->get_type)
? do {
$name =~s{ ^[^:]+: }{}xms;
$type_prefix . '::' . $name;
}
: die "input must have either type or element"
};
$stash->{ part_class } = $part_class;
[% END;
%]
'use' => '[% item.get_use %]',
namespace => '[% item.get_namespace %]',
encodingStyle => '[% item.get_encodingStyle %]',
parts => [qw( [% part_class %] )],

View File

@@ -0,0 +1,18 @@
sub [% operation.get_name %] {
my ($self, $body, $header) = @_;
die "[% operation.get_name %] must be called as object method (\$self is <$self>)" if not blessed($self);
return $self->SUPER::call({
operation => '[% operation.get_name %]',
soap_action => '[% operation.first_operation.get_soapAction %]',
style => '[% operation.get_style || binding.get_style %]',
body => {
[% INCLUDE Interface/Body.tt( item = operation.first_input.first_body ); %]
},
header => {
[% INCLUDE Interface/Header.tt( item = operation.first_input.first_header ); %]
},
headerfault => {
[% INCLUDE Interface/Header.tt( item = operation.first_input.first_headerfault ); %]
}
}, $body, $header);
}

View File

@@ -0,0 +1,13 @@
[% INDENT; %][% element.get_name %] => [%-
IF (element.get_ref);
element = element.get_ref();
END;
IF (type_name = element.get_type);
INCLUDE Interface/POD/Type.tt(type = definitions.first_types.find_type( element.expand(type_name) ) );
ELSIF (type = element.first_complexType);
INCLUDE Interface/POD/Type.tt(type = type );
ELSIF (type = element.first_simpleType);
INCLUDE Interface/POD/Type.tt(type = type );
END;
%]

View File

@@ -0,0 +1,9 @@
[%
message_name = port_op.first_input.get_message();
# message_name;
part_from = definitions.find_message( port_op.first_input.expand( message_name ) ).get_part;
FOREACH part = part_from;
INCLUDE Interface/POD/Part.tt(part = part);
END;
%]

View File

@@ -0,0 +1,8 @@
=head3 [% operation.get_name %]
[% type = definitions.find_portType( binding.expand( binding.get_type ) );
port_op = type.find_operation( definitions.get_targetNamespace, operation.get_name );
port_op.get_documentation %]
$interface->[% operation.get_name %]([% INCLUDE Interface/POD/Message.tt %] );

View File

@@ -0,0 +1,7 @@
[% element = definitions.first_types.find_element( part.expand( part.get_element ) );
#element.get_name();
#element;
#STOP;
type = element.first_complexType || element.first_simpleType || definitions.first_types.find_type(
element.expand( element.get_type ) );
INCLUDE Interface/POD/Type.tt;%],

View File

@@ -0,0 +1,7 @@
[%- indent = ' ';
IF type.isa('SOAP::WSDL::XSD::ComplexType');
INCLUDE complexType/POD/structure.tt(complexType = type);
ELSE;
INCLUDE simpleType/POD/structure.tt(simpleType = type);
END;
indent.replace('\s{2}$',''); %]

View File

@@ -0,0 +1,7 @@
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.

View File

@@ -0,0 +1,28 @@
package [% typemap_prefix %]::[% service.get_name.replace('\.','::') %];
use strict;
use warnings;
our [% USE Dumper(varname = 'typemap_'); Dumper.dump( typemap ) %];
sub get_class {
my $name = join '/', @{ $_[1] };
exists $typemap_1->{ $name } or die "Cannot resolve $name via " . __PACKAGE__;
return $typemap_1->{ $name };
}
1;
__END__
=pod
=head1 NAME
[% typemap_prefix %]::[% service.get_name.replace('\.','::') %]; - typemap for ::[% service.get_name %];
=head1 DESCRIPTION
Typemap created by SOAP::WSDL for map-based SOAP message parsers.
=cut

View File

@@ -0,0 +1,6 @@
[% type_name = node.expand( type );
IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%]
SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %]
[% ELSE -%]
[% type_prefix %]::[% type_name.1 %]
[% END -%]

View File

@@ -0,0 +1,44 @@
package [% type_prefix %]::[% complexType.get_name %];
use strict;
use warnings;
[% INCLUDE complexType/contentModel.tt %]
[%#
# Don't include any perl source here - there may be sub-packages...
#-%]
1;
=pod
=head1 NAME
[% type_prefix %]::[% complexType.get_name %]
=head1 DESCRIPTION
Perl data type class for the XML Schema defined complextype
[% complexType.get_name %] from the namespace [% complexType.get_targetNamespace %].
=head2 PROPERTIES
The following properties may be accessed using get_PROPERTY / set_PROPERTY
methods:
[% FOREACH element = complexType.get_element -%]
[% element.get_name %]
[% END %]
=head1 METHODS
=head2 new
Constructor. The following data structure may be passed to new():
[% indent = ' '; INCLUDE complexType/POD/structure.tt %]
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -0,0 +1,7 @@
[% indent %]{
[%- IF complexType.get_name %] # [% type_prefix %]::[% complexType.get_name %][% END %]
[%- indent = indent _ ' ';
FOREACH element = complexType.get_element %]
[% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%]
[% END %]
[% indent.replace('\s{2}$', ''); %]}

View File

@@ -0,0 +1,9 @@
[% indent %]{
[%- IF complexType.get_name %] # [% type_prefix %]::[% complexType.get_name %][% END %]
[%- indent = indent _ ' ' %]
[% indent %]# One of the following elements.
[% indent %]# No occurance checks yet, so be sure to pass just one...
[%- FOREACH element = complexType.get_element %]
[% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%]
[% END %]
[% indent.replace('\s{2}$', ''); %]}

View File

@@ -0,0 +1,9 @@
[% IF (complexType.get_variety == 'restriction');
INCLUDE complexType/POD/restriction.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'sequence');
THROW NOT_IMPLEMENTED, "${ complexType.get_name } - complexType complexContent extension not implemented yet";
ELSE;
THROW UNKNOWN, "unknown variety ${ complexType.get_variety }";
END;
%]

View File

@@ -0,0 +1,7 @@
[% indent %]{
[%- IF complexType.get_name %] # [% type_prefix %]::[% complexType.get_name %][% END %]
[%- indent = indent _ ' ';
FOREACH element = complexType.get_element %]
[% indent %][% element.get_name %] => [% INCLUDE element/POD/structure.tt -%]
[% END %]
[% indent.replace('\s{2}$', ''); %]}

View File

@@ -0,0 +1,13 @@
[% IF (complexType.get_variety == 'all');
INCLUDE complexType/POD/all.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'sequence');
INCLUDE complexType/POD/all.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'group');
THROW NOT_IMPLEMENTED, "${ element.get_name } - complexType group not implemented yet";
ELSIF (complexType.get_variety == 'choice');
INCLUDE complexType/POD/choice.tt(complexType = complexType);
ELSIF (complexType.get_contentModel == 'simpleContent');
THROW NOT_IMPLEMENTED, "${ element.get_name } - complexType simpleContent not implemented yet";
ELSIF (complexType.get_contentModel == 'complexContent');
INCLUDE complexType/POD/complexContent.tt(complexType = complexType);
END %],

View File

@@ -0,0 +1,47 @@
use Class::Std::Storable;
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
{ # BLOCK to scope variables
[%
atomic_types = {};
FOREACH element = complexType.get_element %]
my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
[%- END %]
__PACKAGE__->_factory(
[ qw([% FOREACH element = complexType.get_element %]
[% element.get_name -%]
[% END %]
) ],
{
[% FOREACH element = complexType.get_element -%]
[% element.get_name %] => \%[% element.get_name %]_of,
[% END -%]
},
{
[% FOREACH element = complexType.get_element;
IF (type = element.get_type);
element_type = complexType.expand( type );
IF (element_type.0 == 'http://www.w3.org/2001/XMLSchema'); -%]
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% element_type.1 %]',
[% ELSE -%]
[% element.get_name %] => '[% type_prefix %]::[% element_type.1 %]',
[% END;
ELSE;
IF (element.first_simpleType);
atomic_types.${ element.get_name } = element.first_simpleType;
ELSIF (element.first_complexType);
atomic_types.${ element.get_name } = element.first_complexType;
ELSE;
THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type - don't know what to do with it";
END; %]
[% element.get_name %] => '[% type_prefix %]::[% complexType.get_name %]::_[% element.get_name %]',
[% END;
END -%]
}
);
} # end BLOCK
[% INCLUDE complexType/atomicTypes.tt(atomic_types = atomic_types) %]

View File

@@ -0,0 +1,19 @@
[% FOREACH type IN atomic_types; %]
package [% type_prefix %]::[% complexType.get_name %]::_[% type.key %];
use strict;
use warnings;
{
[% IF ( type.value.isa('SOAP::WSDL::XSD::ComplexType') );
INCLUDE complexType/contentModel.tt(complexType = type.value );
ELSIF ( type.value.isa('SOAP::WSDL::XSD::SimpleType') );
INCLUDE simpleType/contentModel.tt(simpleType = type.value );
ELSE;
PERL; %] die $stash->{ type } [% END;
THROW UNKNOWN, "neither complex nor simple type - don't know what to do";
END
%]
}
[% END %]

View File

@@ -0,0 +1,8 @@
[% IF (complexType.get_variety == 'restriction');
INCLUDE complexType/restriction.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'sequence');
INCLUDE complexType/extension.tt(complexType = complexType);
ELSE;
THROW UNKNOWN, "unknown variety ${ complexType.get_variety }";
END;
%]

View File

@@ -0,0 +1,7 @@
[% IF (complexType.get_contentModel == 'simpleContent');
THROW NOT_IMPLEMENTED, "${ element.get_name } - complexType simpleContent not implemented yet";
ELSIF (complexType.get_contentModel == 'complexContent');
INCLUDE complexType/complexContent.tt(complexType = complexType);
ELSE;
INCLUDE complexType/variety.tt(complexType = complexType);
END %]

View File

@@ -0,0 +1,24 @@
[%
base_name=complexType.expand( complexType.get_base);
base_type = definitions.first_types.find_type( base_name );
element_from = complexType.get_element;
#
# Sanity check: All original elements must be noted first
#
FOREACH element = base_type.get_element;
IF element_from.${ loop.index }.get_name != element.get_name;
THROW WSDL "${element.get_name} not found at position ${ loop.index } in extension type ${ complexType.get_name }";
END;
END;
-%]
use base qw([% type_prefix %]::[% base_name.1.replace('\.', '::') %]);
[%
INCLUDE complexType/variety.tt(complexType = complexType);
%]

View File

@@ -0,0 +1,8 @@
[% IF (base=complexType.get_base);
base_name=complexType.expand(base);
-%]
use base qw([% type_prefix %]::[% base_name.1.replace('\.', '::') %]);
[%
ELSE;
THROW NOT_IMPLEMENTED, "restriction without base not supported";
END %]

View File

@@ -0,0 +1,15 @@
[%
IF (complexType.get_variety == 'all');
INCLUDE complexType/all.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'sequence');
INCLUDE complexType/all.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'group');
THROW NOT_IMPLEMENTED, "${ element.get_name } - complexType group not implemented yet";
ELSIF (complexType.get_variety == 'choice');
INCLUDE complexType/all.tt(complexType = complexType);
ELSIF (complexType.get_variety);
THROW NOT_IMPLEMENTED, "Unknown variety ${ complexType.get_variety } in ${ complexType.get_name } (${ element.get_name })";
ELSE;
# There's no variety - might be empty complexType
END;
%]

View File

@@ -0,0 +1,71 @@
package [% element_prefix %]::[% element.get_name %];
use strict;
use warnings;
{ # BLOCK to scope variables
sub get_xmlns { '[% element.get_targetNamespace %]' }
__PACKAGE__->__set_name('[% element.get_name %]');
__PACKAGE__->__set_nillable([% element.get_nillable %]);
__PACKAGE__->__set_minOccurs([% element.get_minOccurs %]);
__PACKAGE__->__set_maxOccurs([% element.get_maxOccurs %]);
__PACKAGE__->__set_ref([% IF element.get_ref; %]'[% element.get_ref %]'[% END %]);
[%- IF (type = element.get_type); -%]
use base qw(
SOAP::WSDL::XSD::Typelib::Element
[% INCLUDE _type_class.tt( type = type, node = element ) %]
);
[%- ELSIF (ref = element.get_ref); -%]
# element ref="[% ref %]"
use base qw(
[% element_prefix %]::[% ref.split(':').1 %]
);
[%- ELSIF (simpleType = element.first_simpleType) %]
# atomic simpleType: <element><simpleType
use base qw(
SOAP::WSDL::XSD::Typelib::Element
);
[% INCLUDE simpleType/contentModel.tt %]
[% ELSIF (complexType = element.first_complexType) %]
use base qw(
SOAP::WSDL::XSD::Typelib::Element
SOAP::WSDL::XSD::Typelib::ComplexType
);
[% INCLUDE complexType/contentModel.tt;
END %]
} # end of BLOCK
1;
# __END__
=pod
=head1 NAME
[% element_prefix %]::[% element.get_name %]
=head1 DESCRIPTION
Perl data type class for the XML Schema defined element
[% element.get_name %] from the namespace [% element.get_targetNamespace %].
=head1 METHODS
=head2 new
my $element = [% element_prefix %]::[% element.get_name %]->new($data);
Constructor. The following data structure may be passed to new():
[% indent = ' '; INCLUDE element/POD/structure.tt; %]
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -0,0 +1,30 @@
[%- IF (name = element.get_type);
type_name = element.expand(name);
IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%]
$some_value, # [% type_name.1 %]
[%-
RETURN;
ELSIF (type = definitions.first_types.find_type( type_name ));
IF (type.isa('SOAP::WSDL::XSD::ComplexType') );
INCLUDE complexType/POD/structure.tt(complexType = type);
RETURN;
ELSE;
INCLUDE simpleType/POD/structure.tt(simpleType = type);
END;
RETURN;
END;
THROW NOT_FOUND, "no type found for {${type_name.0}}${type_name.1}";
ELSIF (ref = element.get_ref);
ref_element = definitions.first_types.find_element( element.expand( ref ) );
INCLUDE element/POD/structure.tt(element = ref_element);
RETURN;
ELSIF (type = element.first_simpleType);
INCLUDE simpleType/POD/structure.tt(simpleType = type);
RETURN;
ELSIF (type = element.first_complexType);
INCLUDE complexType/POD/structure.tt(complexType = type);
ELSE;
THROW NOT_FOUND, "no type found for ${element.get_name}";
%]
NO TYPE FOUND FOR ELEMENT [% element.get_name %]
[% END -%]

View File

@@ -0,0 +1,56 @@
package [% type_prefix %]::[% simpleType.get_name %];
use strict;
use warnings;
sub get_xmlns { '[% simpleType.get_targetNamespace %]'};
[% INCLUDE simpleType/contentModel.tt %]
[%#
# Don't include any perl source here - there may be sub-packages...
#-%]
1;
=pod
=head1 [% type_prefix %]::[% simpleType.get_name %]
=head1 DESCRIPTION
Perl data type class for the XML Schema defined simpleType
[% simpleType.get_name %] from the namespace [% simpleType.get_targetNamespace %].
[% IF (simpleType.get_variety == 'list');
INCLUDE simpleType/POD/list.tt;
ELSIF (simpleType.get_variety == 'restriction');
INCLUDE simpleType/POD/restriction.tt;
ELSE;
THROW NOT_IMPLEMENTED "simpleType union not implemented yet in $simpleType.get_name";
END %]
=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<SOAP::WSDL::XSD::Typelib::Builtin> for more information.
=head1 AUTHOR
Generated by SOAP::WSDL
=cut

View File

@@ -0,0 +1,20 @@
This clase is derived from
[%-
IF (name = simpleType.get_itemType);
type_name = simpleType.expand( name );
IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%]
SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %]
[% ELSE -%]
[% type_prefix %]::[% type_name.1 %]
[% END;
ELSE;
# THROW NOT_IMPLEMENTED "atomic simpleType list not implemented yet in $simpleType.get_name";
%] a atomic base type. Unfortunately there's no documenatation generation for atomic base types yet. [%
END -%].
You may pass the following structure to new():
[ $value_1, .. $value_n ]
All elements of the list must be of the class' base type (or valid arguments
to it's constructor).

View File

@@ -0,0 +1,16 @@
This clase is derived from [%-
IF (name = simpleType.get_base);
type_name = simpleType.expand( name );
IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%]
SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %]
[% ELSE -%]
[% type_prefix %]::[% type_name.1 %]
[% END;
ELSE;
# THROW NOT_IMPLEMENTED "atomic simpleType restriction not implemented yet in $simpleType.get_name";
%] a atomic base type. Unfortunately there's no documenatation generation for atomic base types yet. [%
END -%]
. 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.

View File

@@ -0,0 +1 @@
$some_value, # [% IF (simpleType.get_name); simpleType.get_name; ELSE %]atomic[% END %]

View File

@@ -0,0 +1,3 @@
# atomic simple type.
[% INCLUDE simpleType/contentModel.tt(simpleType = type ); %]

View File

@@ -0,0 +1,7 @@
[% IF (simpleType.get_variety == 'list');
INCLUDE simpleType/list.tt(simpleType = simpleType);
ELSIF (simpleType.get_variety == 'restriction');
INCLUDE simpleType/restriction.tt(type = simpleType);
ELSE;
THROW NOT_IMPLEMENTED "${ element.get_name } - ${ simpleType.get_variety } not supported yet";
END %]

View File

@@ -0,0 +1,21 @@
# list derivation
use base qw(
SOAP::WSDL::XSD::Typelib::Builtin::list
[%
IF (name = simpleType.get_itemType);
type_name = simpleType.expand( name );
IF (type_name.0 == 'http://www.w3.org/2001/XMLSchema'); -%]
SOAP::WSDL::XSD::Typelib::Builtin::[% type_name.1 %]
);
[% ELSE -%]
[% type_prefix %]::[% type_name.1 %]
);
[% END;
ELSIF (type = simpleType.first_simpleType); %]
);
[% INCLUDE simpleType/atomicType.tt(type = type);
ELSE; PERL %]die $stash->{simpleType}._DUMP [% END;
THROW UNKNOWN , "No list itemTape and no atomic simpleType - don't know what to do";
END %]

View File

@@ -0,0 +1,9 @@
# derivation by restriction
[% IF (base = simpleType.get_base) -%]
use base qw(
[% INCLUDE _type_class.tt(type = base, node=simpleType) %]);
[% ELSIF (type = simpleType.first_simpleType() );
INCLUDE simpleType/atomicType.tt(type = type);
ELSE;
THROW "neither base nor atomic type - don't know what to do" %]
[% END %]

View File

@@ -0,0 +1,315 @@
package SOAP::WSDL::Generator::Visitor;
use strict;
use warnings;
use Class::Std::Storable;
our $VERSION = '2.00_17';
my %definitions_of :ATTR(:name<definitions> :default<()>);
my %type_prefix_of :ATTR(:name<type_prefix> :default<()>);
my %element_prefix_of :ATTR(:name<element_prefix> :default<()>);
sub START {
my ($self, $ident, $arg_ref) = @_;
$type_prefix_of{ $ident } = 'MyType' if not exists
$arg_ref->{ 'type_prefix' };
$element_prefix_of{ $ident } = 'MyElement' if not exists
$arg_ref->{ 'element_prefix' };
}
# WSDL stuff
sub visit_Definitions {}
sub visit_Binding {}
sub visit_Message {}
sub visit_Operation {}
sub visit_OpMessage {}
sub visit_Part {}
sub visit_Port {}
sub visit_PortType {}
sub visit_Service {}
sub visit_SoapOperation {}
sub visit_Types {}
# XML Schema stuff
sub visit_XSD_Schema {}
sub visit_XSD_ComplexType {}
sub visit_XSD_Element {}
sub visit_XSD_SimpleType {}
1;
__END__
=head1 NAME
SOAP::WSDL::Generator::Visitor - SOAP::WSDL's Visitor-based Code Generator
=head1 DESCRIPTION
SOAP::WSDL featores a code generating facility. This code generation facility
(in fact there are several of them) is implemented as Visitor to
SOAP::WSDL::Base-derived objects.
=head2 The Visitor Pattern
The Visitor design pattern is one of the object oriented design pattern
described by [GHJV1995].
A Visitor is an object implementing some behaviour for a fixed set of classes,
whose implementation would otherwise need to be scattered accross those
classes' implementations.
Visitors are usually combined with Iterators for traversing either a list or
tree of objects.
A Visitor's methods are called using the so-called double dispatch technique.
To allow double dispatching, the Visitor implements one method for every class
ro be handled, whereas every class implements just one method (commonly named
"access"), which does nothing more than calling a method on the reference
given, with the self object as parameter.
If all this sounds strange, maybe an example helps. Imagine you had a list of
person objects and wanted to print out a list of their names (or address
stamps or everything elseyou like). This can easily be implemented with a
Visitor:
package PersonVisitor;
use Class::Std; # handles all basic stuff like constructors etc.
sub visit_Person {
my ( $self, $object ) = @_;
print "Person name is ", $object->get_name(), "\n";
}
package Person;
use Class::Std;
my %name : ATTR(:name<name> :default<anonymous>);
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);
}
# will print
Person name is Gamma
Person name is Helm
Person name is Johnson
Person name is Vlissides
While using this pattern for just printing a list may look a bit over-sized,
but it may become handy if you need multiple output formats and different
classes to operate on.
The main benefits using visitors are:
=over
=item * Grouping related behaviour in one class
Related behaviour for several classes can be grouped together in the Visitor
class. The behaviour can easily be changed by changing the code in one class,
instead of having to change all the visited classes.
=item * Cleaning up the data classes' implementations
If classes holding data also implement several different output formats or
other (otherwise unrelated) behaviour, they tend to get bloated.
=item * Adding behaviour is easy
Swapping out the visitor class allows easy alterations of behaviour. So on a
list of Persons, one Visitor may print address stamps, while another one prints
out a phone number list.
=back
Of course, there are also drawbacks in the visitor pattern:
=over
=item * Changes in the visited classes are expensive
If one of the visited classes changes (or is added), all visitors must be
updated to reflect this change. This may be rather expensive if classes change
often.
=item * The visited classes must expose all data required
Visitors may need to use the internals of a class. This may result in fidelling
with a object's internals, or a bloated interface in the visited class.
=back
Visitors are usually accompanied by a Iterator. The Iterator may be implemented
in the visited classes, in the Visitor, or somewhere else (in the example it
was somewhere else).
The Iterator decides which object to visit next.
=head2 Why SOAP::WSDL uses the Visitor pattern for Code Generation
Code generation in SOAP::WSDL means generating various artefacts:
=over
=item * Typemaps
For every WSDL definition, a Typemap is created. The Typemap is used later as
an aid in parsing the SOAP XML messages.
=item * Type Classes
For every type defined in the WSDL's schema, a Type Class is generated.
These classes are instantiated later as a result of parsing SOAP XML messages.
=item * Interface Classes
For every service, a interface class is generated. This class is later used by
programmers accessing the service
=item * Documentation
Both Type Classes and Interface Classes include documentation. Additional
documentation may be generated as a hint for programmers, or later for
mimicing .NET's .asmx example pages.
=back
All these behaviours could well (and has historically been) implemented in the
classes holding the WSDL data. This made these classes rather bloated, and
made it hard to change behaviour (like, supporting SOAP Headers,
supporting atomic types and other features which were missing from early
versions of SOAP::WSDL).
Implementing these behaviours in Visitor classes eases adding new behaviours,
and reducing the incompletenesses still inherent in SOAP::WSDL's WSDL and XML
schema implementation.
=head2 Implementation
=head3 accept
SOAP::WSDL::Base defines an accept method which expects a Visitor as only
parameter.
The method visit_Foo_Bar is called on the visitor, whith the self object as
parameter.
The actual method name is constructed this way:
=over
=item * SOAP::WSDL is stripped from the class name
=item * All remaining :: s are replaced by _
=back
Example:
When visiting a SOAP::WSDL::XSD::ComplexType object, the method
visit_XSD_ComplexType is called on the visitor.
=head2 Writing your own visitor
SOAP::WSDL eases writing your own visitor. This might be required if you need
some special output format from a WSDL file, or want to feed your own
serializer/deserializer pair with custom configuration data. Or maybe you want
to generate C# code from it...
To write your own code generating visitor, you should subclass
SOAP::WSDL::Generator::Visitor. It implements (empty) default methods for all
SOAP::WSDL data classes:
=over
=item * visit_Definitions
=item * visit_Binding
=item * visit_Message
=item * visit_Operation
=item * visit_OpMessage
=item * visit_Part
=item * visit_Port
=item * visit_PortType
=item * visit_Service
=item * visit_SoapOperation
=item * visit_Types
=item * visit_XSD_Schema
=item * visit_XSD_ComplexType
=item * visit_XSD_Element
=item * visit_XSD_SimpleType
=back
In your Visitor, you must implement visit_Foo methods for all classes you wish
to visit.
Currently, all SOAP::WSDL::Generator::Visitor implementations include their own
Iterator (which means they know how to find the next objects to visit). You
may or may not choose to implement a separate Iterator.
Letting a visitor implementing it's own Iterator visit a WSDL definition is as
easy as writing something like this:
my $visitor = MyVisitor->new();
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
my $definitions = $parser->parse_file('my.wsdl'):
$definitions->_accept( $visitor );
=head1 REFERENCES
=over
=item * [GHJV1995]
Erich Gamma, Richard Helm, Ralph E. Johnson, John Vlissides, (1995):
Design Patterns. Elements of Reusable Object-Oriented Software.
Addison-Wesley Longman, Amsterdam.
=back
=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 E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 239 $
$LastChangedBy: kutterma $
$Id: Client.pm 239 2007-09-11 09:45:42Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
=cut

Some files were not shown because too many files have changed in this diff Show More