Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd0854e34a | ||
|
|
c2da74b5ae | ||
|
|
7ba1959888 | ||
|
|
a554e87f49 |
@@ -1,42 +1,40 @@
|
|||||||
use Module::Build;
|
use Module::Build;
|
||||||
|
|
||||||
Module::Build->new(
|
Module::Build->new(
|
||||||
dist_abstract => 'SOAP with WSDL support',
|
create_makefile_pl => 'passthrough',
|
||||||
dist_name => 'SOAP-WSDL',
|
dist_abstract => 'SOAP with WSDL support',
|
||||||
dist_version => '2.00_08',
|
dist_name => 'SOAP-WSDL',
|
||||||
module_name => 'SOAP::WSDL',
|
dist_version => '2.00_12',
|
||||||
license => 'artistic',
|
module_name => 'SOAP::WSDL',
|
||||||
requires => {
|
license => 'artistic',
|
||||||
'Class::Std' => q/v0.0.8/,
|
requires => {
|
||||||
'Class::Std::Storable' => 0,
|
'Class::Std' => q/v0.0.8/,
|
||||||
'Date::Parse' => 0,
|
'Class::Std::Storable' => 0,
|
||||||
'Date::Format' => 0,
|
'Date::Parse' => 0,
|
||||||
'LWP::UserAgent' => 0,
|
'Date::Format' => 0,
|
||||||
'List::Util' => 0,
|
'LWP::UserAgent' => 0,
|
||||||
'File::Basename' => 0,
|
'List::Util' => 0,
|
||||||
'File::Path' => 0,
|
'File::Basename' => 0,
|
||||||
'XML::LibXML' => 0,
|
'File::Path' => 0,
|
||||||
'XML::SAX::Base' => 0,
|
'XML::Parser::Expat' => 0,
|
||||||
'XML::SAX::ParserFactory' => 0,
|
'Template' => 0,
|
||||||
'XML::Parser::Expat' => 0,
|
'Getopt::Long' => 0,
|
||||||
},
|
},
|
||||||
buildrequires => {
|
buildrequires => {
|
||||||
'Date::Parse' => 0,
|
'Date::Parse' => 0,
|
||||||
'Date::Format' => 0,
|
'Date::Format' => 0,
|
||||||
'Benchmark' => 0,
|
'Test::More' => 0,
|
||||||
'Cwd' => 0,
|
'Class::Std' => q/v0.0.8/,
|
||||||
'Test::More' => 0,
|
'Class::Std::Storable' => 0,
|
||||||
'Class::Std' => 0.0.8,
|
'List::Util' => 0,
|
||||||
'Class::Std::Storable' => 0,
|
'LWP::UserAgent' => 0,
|
||||||
'List::Util' => 0,
|
'File::Basename' => 0,
|
||||||
'LWP::UserAgent' => 0,
|
'File::Path' => 0,
|
||||||
'File::Basename' => 0,
|
'XML::Parser::Expat' => 0,
|
||||||
'File::Path' => 0,
|
'Template' => 0,
|
||||||
'XML::Simple' => 0,
|
'Getopt::Long' => 0,
|
||||||
'XML::LibXML' => 0,
|
'Cwd' => 0,
|
||||||
'XML::Parser::Expat' => 0,
|
'File::Find' => 0,
|
||||||
'XML::SAX::Base' => 0,
|
|
||||||
'XML::SAX::ParserFactory' => 0,
|
|
||||||
'Pod::Simple::Text' => 0,
|
|
||||||
},
|
},
|
||||||
recursive_test_files => 1,
|
recursive_test_files => 1,
|
||||||
)->create_build_script;
|
)->create_build_script;
|
||||||
|
|||||||
@@ -1 +1,122 @@
|
|||||||
See perldoc SOAP::WSDL
|
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_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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
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).
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
benchmark/01_expat.t
|
||||||
bin/wsdl2perl.pl
|
bin/wsdl2perl.pl
|
||||||
Build.PL
|
Build.PL
|
||||||
CHANGES
|
CHANGES
|
||||||
@@ -32,11 +33,16 @@ lib/SOAP/WSDL/Binding.pm
|
|||||||
lib/SOAP/WSDL/Client.pm
|
lib/SOAP/WSDL/Client.pm
|
||||||
lib/SOAP/WSDL/Client/Base.pm
|
lib/SOAP/WSDL/Client/Base.pm
|
||||||
lib/SOAP/WSDL/Definitions.pm
|
lib/SOAP/WSDL/Definitions.pm
|
||||||
lib/SOAP/WSDL/Envelope.pm
|
|
||||||
lib/SOAP/WSDL/Expat/MessageParser.pm
|
lib/SOAP/WSDL/Expat/MessageParser.pm
|
||||||
lib/SOAP/WSDL/Expat/MessageStreamParser.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/Serializer.pm
|
||||||
|
lib/SOAP/WSDL/Factory/Transport.pm
|
||||||
lib/SOAP/WSDL/Manual.pod
|
lib/SOAP/WSDL/Manual.pod
|
||||||
lib/SOAP/WSDL/Manual/Glossary.pod
|
lib/SOAP/WSDL/Manual/Glossary.pod
|
||||||
|
lib/SOAP/WSDL/Manual/WS_I.pod
|
||||||
lib/SOAP/WSDL/Message.pm
|
lib/SOAP/WSDL/Message.pm
|
||||||
lib/SOAP/WSDL/Operation.pm
|
lib/SOAP/WSDL/Operation.pm
|
||||||
lib/SOAP/WSDL/OpMessage.pm
|
lib/SOAP/WSDL/OpMessage.pm
|
||||||
@@ -46,9 +52,11 @@ lib/SOAP/WSDL/Port.pm
|
|||||||
lib/SOAP/WSDL/PortType.pm
|
lib/SOAP/WSDL/PortType.pm
|
||||||
lib/SOAP/WSDL/SAX/MessageHandler.pm
|
lib/SOAP/WSDL/SAX/MessageHandler.pm
|
||||||
lib/SOAP/WSDL/SAX/WSDLHandler.pm
|
lib/SOAP/WSDL/SAX/WSDLHandler.pm
|
||||||
|
lib/SOAP/WSDL/Serializer/SOAP11.pm
|
||||||
lib/SOAP/WSDL/Service.pm
|
lib/SOAP/WSDL/Service.pm
|
||||||
lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
|
lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
|
||||||
lib/SOAP/WSDL/SoapOperation.pm
|
lib/SOAP/WSDL/SoapOperation.pm
|
||||||
|
lib/SOAP/WSDL/Transport/HTTP.pm
|
||||||
lib/SOAP/WSDL/TypeLookup.pm
|
lib/SOAP/WSDL/TypeLookup.pm
|
||||||
lib/SOAP/WSDL/Types.pm
|
lib/SOAP/WSDL/Types.pm
|
||||||
lib/SOAP/WSDL/XSD/Builtin.pm
|
lib/SOAP/WSDL/XSD/Builtin.pm
|
||||||
@@ -108,13 +116,18 @@ lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
|
|||||||
lib/SOAP/WSDL/XSD/Typelib/Element.pm
|
lib/SOAP/WSDL/XSD/Typelib/Element.pm
|
||||||
lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
|
lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
|
||||||
LICENSE
|
LICENSE
|
||||||
|
Makefile.PL
|
||||||
MANIFEST This list of files
|
MANIFEST This list of files
|
||||||
META.yml
|
META.yml
|
||||||
README
|
README
|
||||||
t/001_use.t
|
t/001_use.t
|
||||||
|
t/002_parse_wsdl.t
|
||||||
t/002_sax.t
|
t/002_sax.t
|
||||||
t/003_sax_serializer.t
|
t/003_sax_serializer.t
|
||||||
|
t/003_wsdl_based_serializer.t
|
||||||
|
t/004_parse_wsdl.t
|
||||||
t/004_sax_wsdl.t
|
t/004_sax_wsdl.t
|
||||||
|
t/005_parse_contributed.t
|
||||||
t/005_sax_contributed_wsdl.t
|
t/005_sax_contributed_wsdl.t
|
||||||
t/006_client.t
|
t/006_client.t
|
||||||
t/007_envelope.t
|
t/007_envelope.t
|
||||||
@@ -126,9 +139,13 @@ t/013_complexType.t
|
|||||||
t/014_sax_typelib.t
|
t/014_sax_typelib.t
|
||||||
t/015_to_typemap.t
|
t/015_to_typemap.t
|
||||||
t/016_client_object.t
|
t/016_client_object.t
|
||||||
t/017_generator.t
|
t/017_generator_expat.t
|
||||||
t/018_generator.t
|
t/017_generator_libxml.t
|
||||||
|
t/018_generator_expat.t
|
||||||
|
t/018_generator_libxml.t
|
||||||
t/020_storable.t
|
t/020_storable.t
|
||||||
|
t/021_generator_element_ref_expat.t
|
||||||
|
t/021_generator_element_ref_libxml.t
|
||||||
t/098_pod.t
|
t/098_pod.t
|
||||||
t/acceptance/results/03_complexType-all.xml
|
t/acceptance/results/03_complexType-all.xml
|
||||||
t/acceptance/results/03_complexType-sequence.xml
|
t/acceptance/results/03_complexType-sequence.xml
|
||||||
@@ -142,6 +159,7 @@ t/acceptance/wsdl/006_sax_client.wsdl
|
|||||||
t/acceptance/wsdl/008_complexType.wsdl
|
t/acceptance/wsdl/008_complexType.wsdl
|
||||||
t/acceptance/wsdl/02_port.wsdl
|
t/acceptance/wsdl/02_port.wsdl
|
||||||
t/acceptance/wsdl/03_complexType-all.wsdl
|
t/acceptance/wsdl/03_complexType-all.wsdl
|
||||||
|
t/acceptance/wsdl/03_complexType-element-ref.wsdl
|
||||||
t/acceptance/wsdl/03_complexType-sequence.wsdl
|
t/acceptance/wsdl/03_complexType-sequence.wsdl
|
||||||
t/acceptance/wsdl/04_element-simpleType.wsdl
|
t/acceptance/wsdl/04_element-simpleType.wsdl
|
||||||
t/acceptance/wsdl/04_element.wsdl
|
t/acceptance/wsdl/04_element.wsdl
|
||||||
@@ -156,6 +174,8 @@ t/acceptance/wsdl/contributed/OITest.wsdl
|
|||||||
t/acceptance/wsdl/contributed/tools.wsdl
|
t/acceptance/wsdl/contributed/tools.wsdl
|
||||||
t/acceptance/wsdl/email_account.wsdl
|
t/acceptance/wsdl/email_account.wsdl
|
||||||
t/Expat/01_expat.t
|
t/Expat/01_expat.t
|
||||||
|
t/Expat/02_sub_parser.t
|
||||||
|
t/Expat/03_wsdl.t
|
||||||
t/lib/MyComplexType.pm
|
t/lib/MyComplexType.pm
|
||||||
t/lib/MyElement.pm
|
t/lib/MyElement.pm
|
||||||
t/lib/MySimpleType.pm
|
t/lib/MySimpleType.pm
|
||||||
@@ -168,6 +188,7 @@ t/SOAP/WSDL/02_port.t
|
|||||||
t/SOAP/WSDL/03_complexType-all.t
|
t/SOAP/WSDL/03_complexType-all.t
|
||||||
t/SOAP/WSDL/03_complexType-choice.t
|
t/SOAP/WSDL/03_complexType-choice.t
|
||||||
t/SOAP/WSDL/03_complexType-complexContent.t
|
t/SOAP/WSDL/03_complexType-complexContent.t
|
||||||
|
t/SOAP/WSDL/03_complexType-element-ref.t
|
||||||
t/SOAP/WSDL/03_complexType-group.t
|
t/SOAP/WSDL/03_complexType-group.t
|
||||||
t/SOAP/WSDL/03_complexType-sequence.t
|
t/SOAP/WSDL/03_complexType-sequence.t
|
||||||
t/SOAP/WSDL/03_complexType-simpleContent.t
|
t/SOAP/WSDL/03_complexType-simpleContent.t
|
||||||
@@ -177,11 +198,9 @@ t/SOAP/WSDL/04_element.t
|
|||||||
t/SOAP/WSDL/05_simpleType-list.t
|
t/SOAP/WSDL/05_simpleType-list.t
|
||||||
t/SOAP/WSDL/05_simpleType-restriction.t
|
t/SOAP/WSDL/05_simpleType-restriction.t
|
||||||
t/SOAP/WSDL/05_simpleType-union.t
|
t/SOAP/WSDL/05_simpleType-union.t
|
||||||
t/SOAP/WSDL/10_performance.t
|
|
||||||
t/SOAP/WSDL/11_helloworld.NET.t
|
t/SOAP/WSDL/11_helloworld.NET.t
|
||||||
t/SOAP/WSDL/12_binding.pl
|
t/SOAP/WSDL/12_binding.pl
|
||||||
t/SOAP/WSDL/XSD/Typelib/Builtin/001_string.t
|
t/SOAP/WSDL/XSD/Typelib/Builtin/001_string.t
|
||||||
t/SOAP/WSDL/XSD/Typelib/Builtin/002_dateTime.t
|
t/SOAP/WSDL/XSD/Typelib/Builtin/002_dateTime.t
|
||||||
t/SOAP/WSDL/XSD/Typelib/Builtin/002_time.t
|
|
||||||
t/SOAP/WSDL/XSD/Typelib/Builtin/003_date.t
|
t/SOAP/WSDL/XSD/Typelib/Builtin/003_date.t
|
||||||
TODO
|
TODO
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: SOAP-WSDL
|
name: SOAP-WSDL
|
||||||
version: 2.00_08
|
version: 2.00_12
|
||||||
author:
|
author:
|
||||||
abstract: SOAP with WSDL support
|
abstract: SOAP with WSDL support
|
||||||
license: artistic
|
license: artistic
|
||||||
@@ -11,12 +11,11 @@ requires:
|
|||||||
Date::Parse: 0
|
Date::Parse: 0
|
||||||
File::Basename: 0
|
File::Basename: 0
|
||||||
File::Path: 0
|
File::Path: 0
|
||||||
|
Getopt::Long: 0
|
||||||
LWP::UserAgent: 0
|
LWP::UserAgent: 0
|
||||||
List::Util: 0
|
List::Util: 0
|
||||||
XML::LibXML: 0
|
Template: 0
|
||||||
XML::Parser::Expat: 0
|
XML::Parser::Expat: 0
|
||||||
XML::SAX::Base: 0
|
|
||||||
XML::SAX::ParserFactory: 0
|
|
||||||
generated_by: Module::Build version 0.2808
|
generated_by: Module::Build version 0.2808
|
||||||
meta-spec:
|
meta-spec:
|
||||||
url: http://module-build.sourceforge.net/META-spec-v1.2.html
|
url: http://module-build.sourceforge.net/META-spec-v1.2.html
|
||||||
@@ -24,23 +23,28 @@ meta-spec:
|
|||||||
provides:
|
provides:
|
||||||
SOAP::WSDL:
|
SOAP::WSDL:
|
||||||
file: lib/SOAP/WSDL.pm
|
file: lib/SOAP/WSDL.pm
|
||||||
version: 2.00_08
|
version: 2.00_12
|
||||||
SOAP::WSDL::Base:
|
SOAP::WSDL::Base:
|
||||||
file: lib/SOAP/WSDL/Base.pm
|
file: lib/SOAP/WSDL/Base.pm
|
||||||
SOAP::WSDL::Binding:
|
SOAP::WSDL::Binding:
|
||||||
file: lib/SOAP/WSDL/Binding.pm
|
file: lib/SOAP/WSDL/Binding.pm
|
||||||
SOAP::WSDL::Client:
|
SOAP::WSDL::Client:
|
||||||
file: lib/SOAP/WSDL/Client.pm
|
file: lib/SOAP/WSDL/Client.pm
|
||||||
|
version: 2.00_12
|
||||||
SOAP::WSDL::Client::Base:
|
SOAP::WSDL::Client::Base:
|
||||||
file: lib/SOAP/WSDL/Client/Base.pm
|
file: lib/SOAP/WSDL/Client/Base.pm
|
||||||
SOAP::WSDL::Definitions:
|
SOAP::WSDL::Definitions:
|
||||||
file: lib/SOAP/WSDL/Definitions.pm
|
file: lib/SOAP/WSDL/Definitions.pm
|
||||||
SOAP::WSDL::Envelope:
|
|
||||||
file: lib/SOAP/WSDL/Envelope.pm
|
|
||||||
SOAP::WSDL::Expat::MessageParser:
|
SOAP::WSDL::Expat::MessageParser:
|
||||||
file: lib/SOAP/WSDL/Expat/MessageParser.pm
|
file: lib/SOAP/WSDL/Expat/MessageParser.pm
|
||||||
SOAP::WSDL::Expat::MessageStreamParser:
|
SOAP::WSDL::Expat::MessageStreamParser:
|
||||||
file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm
|
file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm
|
||||||
|
SOAP::WSDL::Expat::MessageSubParser:
|
||||||
|
file: lib/SOAP/WSDL/Expat/MessageSubParser.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:
|
SOAP::WSDL::Message:
|
||||||
file: lib/SOAP/WSDL/Message.pm
|
file: lib/SOAP/WSDL/Message.pm
|
||||||
SOAP::WSDL::OpMessage:
|
SOAP::WSDL::OpMessage:
|
||||||
@@ -57,10 +61,14 @@ provides:
|
|||||||
file: lib/SOAP/WSDL/SAX/MessageHandler.pm
|
file: lib/SOAP/WSDL/SAX/MessageHandler.pm
|
||||||
SOAP::WSDL::SOAP::Typelib::Fault11:
|
SOAP::WSDL::SOAP::Typelib::Fault11:
|
||||||
file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
|
file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
|
||||||
|
SOAP::WSDL::Serializer::SOAP11:
|
||||||
|
file: lib/SOAP/WSDL/Serializer/SOAP11.pm
|
||||||
SOAP::WSDL::Service:
|
SOAP::WSDL::Service:
|
||||||
file: lib/SOAP/WSDL/Service.pm
|
file: lib/SOAP/WSDL/Service.pm
|
||||||
SOAP::WSDL::SoapOperation:
|
SOAP::WSDL::SoapOperation:
|
||||||
file: lib/SOAP/WSDL/SoapOperation.pm
|
file: lib/SOAP/WSDL/SoapOperation.pm
|
||||||
|
SOAP::WSDL::Transport::HTTP:
|
||||||
|
file: lib/SOAP/WSDL/Transport/HTTP.pm
|
||||||
SOAP::WSDL::TypeLookup:
|
SOAP::WSDL::TypeLookup:
|
||||||
file: lib/SOAP/WSDL/TypeLookup.pm
|
file: lib/SOAP/WSDL/TypeLookup.pm
|
||||||
SOAP::WSDL::Types:
|
SOAP::WSDL::Types:
|
||||||
|
|||||||
+31
@@ -0,0 +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');
|
||||||
@@ -1,2 +1,26 @@
|
|||||||
|
INTRO
|
||||||
|
-----
|
||||||
|
|
||||||
|
SOAP-WSDL provides a SOAP client with WSDL support.
|
||||||
|
|
||||||
This is a developer release - everything may (and most things will) change.
|
This is a developer release - everything may (and most things will) change.
|
||||||
|
|
||||||
|
INSTALLING
|
||||||
|
----------
|
||||||
|
|
||||||
|
Use the following mantra:
|
||||||
|
|
||||||
|
perl Build.PL
|
||||||
|
perl Build
|
||||||
|
perl Build test
|
||||||
|
perl Build install
|
||||||
|
|
||||||
|
If you don't have Module::Build installed, you may also use
|
||||||
|
|
||||||
|
perl Makefile.PL
|
||||||
|
make
|
||||||
|
make test
|
||||||
|
make install
|
||||||
|
|
||||||
|
Note that Module::Build is the recommended installer - make will not run
|
||||||
|
all tests provided with SOAP-WSDL.
|
||||||
@@ -1,36 +1,35 @@
|
|||||||
- support embedded atomic types by including a second (and third and fourth)
|
TODO list for SOAP::WSDL
|
||||||
package type_prefix::complex_type::element_name element package.
|
|
||||||
Allow unlimited depth (though this is rather wicked).
|
2.00 Pre-releases
|
||||||
- fixup generated pod so it looks nice in SOAP::WSDL::Definitions.
|
--------
|
||||||
- remove benchmarks from tests. Create benchmark/ directory and store benchmarks in.
|
* SOAP Header support (#1764845)
|
||||||
- add tests for SOAP::WSDL::Definitions::create
|
|
||||||
- test for correct creation
|
* Implement a interface similar to SOAP::Schema (#1783639)
|
||||||
- test against web service (fullerdata.com?)
|
|
||||||
- Improve docs
|
* (#1785195) Support deserializer plugins
|
||||||
- Partially DONE
|
* Support XML::Compiled as one serializer/deserializer
|
||||||
- Remove SOAP::Lite dependency - for now, just support HTTP(s) via LWP::UserAgent.
|
|
||||||
- Partially DONE. SOAP::WSDL still uses SOAP::Schema
|
* Check & probably fix simpleType support.
|
||||||
- write inheritance Test for all XSD::Typelib::Builtin::* classes
|
The WS at http://www.webservicex.net/genericbarcode.asmx?wsdl should
|
||||||
- Check & probably fix simpleType support.
|
make up a good example for simpleType definitions.
|
||||||
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.
|
||||||
- add default Fault11 typemap to generated typemaps
|
|
||||||
- DONE
|
* write inheritance Test for all XSD::Typelib::Builtin::* classes
|
||||||
- SOAP::WSDL::Definitions::create creates bad interface docs. Fix it.
|
|
||||||
- DONE
|
* support embedded atomic types (#1761532)
|
||||||
- update all Builtin Types to new constructor BEGIN block (Class::Std unfortunately is way slow)
|
Implement by including a second (and third and fourth)
|
||||||
- DONE.
|
|
||||||
- Remove useless (but on CPAN annoying) doc from Builtin::* classes
|
package type_prefix::complex_type::element_name;
|
||||||
- DONE
|
|
||||||
- add example WS scripts
|
element package.
|
||||||
- DONE.
|
Maybe even allow unlimited depth? What does the specs say?
|
||||||
- SOAP::WSDL::XSD::Typelib::Builtin::string does not unescape XML builtin entities on get_value()
|
|
||||||
- WONTFIX.
|
2.1 release
|
||||||
Entities are unescaped by XML parser.
|
--------
|
||||||
If you want the plain value, you have to use get_value, as XML conversion is overloaded on stringification.
|
|
||||||
- Make callin WS easier: implent WS-I-based SOAP::WSDL::Client::WSI
|
|
||||||
- WONTFIX - SOAP::WSDL::Base should behave equal
|
|
||||||
- add capability to create request objects based on input part definitions to SOAP::WSDL::Client::Base
|
|
||||||
- DONE.
|
|
||||||
|
|
||||||
|
|
||||||
|
Past 2.1 release
|
||||||
|
--------
|
||||||
|
* XML schema support ("minimal conformant") (#1764845)
|
||||||
|
* Support SOAP attachments
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use lib '../lib';
|
||||||
|
use lib 'lib';
|
||||||
|
use lib '../t/lib';
|
||||||
|
use SOAP::WSDL::SAX::MessageHandler;
|
||||||
|
|
||||||
|
use Benchmark;
|
||||||
|
use SOAP::WSDL::Expat::MessageParser;
|
||||||
|
use XML::Simple;
|
||||||
|
use XML::LibXML;
|
||||||
|
use MyComplexType;
|
||||||
|
use MyElement;
|
||||||
|
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>
|
||||||
|
<test2 >Test2</test2>
|
||||||
|
</MyAtomicComplexTypeElement></SOAP-ENV:Body></SOAP-ENV:Envelope>};
|
||||||
|
|
||||||
|
|
||||||
|
my $parser = SOAP::WSDL::Expat::MessageParser->new({
|
||||||
|
class_resolver => 'FakeResolver'
|
||||||
|
});
|
||||||
|
|
||||||
|
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
|
||||||
|
|
||||||
|
my $libxml = XML::LibXML->new();
|
||||||
|
|
||||||
|
timethese 1000,
|
||||||
|
{
|
||||||
|
'SOAP::WSDL' => sub { $parser->parse( $xml ) },
|
||||||
|
#'XML::Simple (Hash)' => sub { XMLin $xml },
|
||||||
|
'XML::LibXML (DOM)' => sub { my $dom = $libxml->parse_string( $xml ) },
|
||||||
|
};
|
||||||
|
|
||||||
|
use Test::More tests => 1;
|
||||||
|
is $parser->get_data(), q{<MyAtomicComplexTypeElement xmlns="urn:Test" >}
|
||||||
|
. q{<test >Test</test><test2 >Test2</test2></MyAtomicComplexTypeElement>}
|
||||||
|
, 'Content comparison';
|
||||||
|
|
||||||
|
$parser->class_resolver( 'FakeResolver2' );
|
||||||
|
|
||||||
|
|
||||||
|
# data classes reside in t/lib/Typelib/
|
||||||
|
BEGIN {
|
||||||
|
package FakeResolver;
|
||||||
|
{
|
||||||
|
my %class_list = (
|
||||||
|
'MyAtomicComplexTypeElement' => 'MyAtomicComplexTypeElement',
|
||||||
|
'MyAtomicComplexTypeElement/test' => 'MyTestElement',
|
||||||
|
'MyAtomicComplexTypeElement/test2' => 'MyTestElement2',
|
||||||
|
);
|
||||||
|
|
||||||
|
sub get_map { return \%class_list };
|
||||||
|
|
||||||
|
sub new { return bless {}, 'FakeResolver' };
|
||||||
|
|
||||||
|
sub get_class {
|
||||||
|
my $name = join('/', @{ $_[1] });
|
||||||
|
return ($class_list{ $name }) ? $class_list{ $name }
|
||||||
|
: warn "no class found for $name";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
+6
-13
@@ -1,13 +1,10 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Fcntl;
|
|
||||||
use IO::File;
|
|
||||||
use Pod::Usage;
|
use Pod::Usage;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
use LWP::UserAgent;
|
use LWP::UserAgent;
|
||||||
use SOAP::WSDL::SAX::WSDLHandler;
|
use SOAP::WSDL::Expat::WSDLParser;
|
||||||
use XML::LibXML;
|
|
||||||
|
|
||||||
my %opt = (
|
my %opt = (
|
||||||
url => '',
|
url => '',
|
||||||
@@ -39,8 +36,7 @@ my $url = $ARGV[0];
|
|||||||
pod2usage( -exit => 1 , verbose => 2 ) if ($opt{help});
|
pod2usage( -exit => 1 , verbose => 2 ) if ($opt{help});
|
||||||
pod2usage( -exit => 1 , verbose => 1 ) if not ($url);
|
pod2usage( -exit => 1 , verbose => 1 ) if not ($url);
|
||||||
|
|
||||||
my $handler = SOAP::WSDL::SAX::WSDLHandler->new();
|
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
|
||||||
my $parser = XML::LibXML->new();
|
|
||||||
|
|
||||||
local $ENV{HTTP_PROXY} = $opt{proxy} if $opt{proxy};
|
local $ENV{HTTP_PROXY} = $opt{proxy} if $opt{proxy};
|
||||||
my $lwp = LWP::UserAgent->new();
|
my $lwp = LWP::UserAgent->new();
|
||||||
@@ -49,16 +45,13 @@ die $response->message(), "\n" if $response->code != 200;
|
|||||||
|
|
||||||
my $xml = $response->content();
|
my $xml = $response->content();
|
||||||
|
|
||||||
$parser->set_handler( $handler );
|
my $wsdl = $parser->parse_string( $xml );
|
||||||
$parser->parse_string( $xml );
|
|
||||||
|
|
||||||
my $wsdl = $handler->get_data();
|
|
||||||
|
|
||||||
if ($opt{typemap_include}) {
|
if ($opt{typemap_include}) {
|
||||||
my $fh = IO::File->new($opt{typemap_include} , O_RDONLY)
|
open my $fh , $opt{typemap_include}
|
||||||
or die "cannot open typemap_include file $opt{typemap_include}\n";
|
or die "cannot open typemap_include file $opt{typemap_include}\n";
|
||||||
$opt{custom_types} = join q{}, $fh->getlines();
|
$opt{custom_types} .= join q{}, <$fh>;
|
||||||
$fh->close();
|
close $fh;
|
||||||
delete $opt{typemap_include};
|
delete $opt{typemap_include};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-16
@@ -11,23 +11,37 @@
|
|||||||
|
|
||||||
use lib 'lib/';
|
use lib 'lib/';
|
||||||
use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie;
|
use MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie;
|
||||||
use MyElements::GetFortuneCookie;
|
|
||||||
my $cookieService = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie->new();
|
my $cookieService = MyInterfaces::FullerData_x0020_Fortune_x0020_Cookie->new();
|
||||||
|
|
||||||
my $cookie = $cookieService->GetFortuneCookie();
|
my $cookie;
|
||||||
|
$cookie = $cookieService->GetFortuneCookie()
|
||||||
|
or die "$cookie";
|
||||||
|
|
||||||
if ($cookie) {
|
print $cookie; # ->get_GetFortuneCookieResult()->get_value, "\n";
|
||||||
print $cookie->get_GetFortuneCookieResult()->get_value, "\n";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
print $cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cookie = $cookieService->GetSpecificCookie({ index => 23 });
|
$cookie = $cookieService->GetSpecificCookie({ index => 23 })
|
||||||
if ($cookie) {
|
or die "$cookie";
|
||||||
print $cookie
|
|
||||||
->get_GetSpecificCookieResult(), "\n";
|
print $cookie->get_GetSpecificCookieResult(), "\n";
|
||||||
}
|
|
||||||
else {
|
print $cookie;
|
||||||
print $cookie;
|
|
||||||
}
|
|
||||||
|
=for demo:
|
||||||
|
|
||||||
|
# the same in SOAP lite (second call)
|
||||||
|
#
|
||||||
|
|
||||||
|
use SOAP::Lite;
|
||||||
|
|
||||||
|
my $lite = SOAP::Lite->new()->on_action(sub { join '/', @_ } )
|
||||||
|
->proxy('http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx');
|
||||||
|
|
||||||
|
$lite->call(
|
||||||
|
SOAP::Data->name('GetSpecificCookie')
|
||||||
|
->attr({ 'xmlns', 'http://www.fullerdata.com/FortuneCookie/FortuneCookie.asmx' }),
|
||||||
|
SOAP::Data->name('index')->value(23)
|
||||||
|
);
|
||||||
|
|
||||||
|
die $soap->message() if ($soap->fault());
|
||||||
|
print $soap->result();
|
||||||
@@ -3,6 +3,7 @@ use strict;
|
|||||||
use Class::Std::Storable;
|
use Class::Std::Storable;
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
|
||||||
|
|
||||||
# atomic complexType
|
# atomic complexType
|
||||||
# <element name="GetCitiesByCountry"><complexType> definition
|
# <element name="GetCitiesByCountry"><complexType> definition
|
||||||
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
@@ -16,7 +17,7 @@ my %CountryName_of :ATTR(:get<CountryName>);
|
|||||||
|
|
||||||
|
|
||||||
__PACKAGE__->_factory(
|
__PACKAGE__->_factory(
|
||||||
[ qw(
|
[ qw(
|
||||||
CountryName
|
CountryName
|
||||||
) ],
|
) ],
|
||||||
{
|
{
|
||||||
@@ -25,8 +26,8 @@ __PACKAGE__->_factory(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -46,9 +47,16 @@ __PACKAGE__->__set_ref('');
|
|||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
|
|
||||||
=head1 NAME MyElements::GetCitiesByCountry
|
=head1 NAME
|
||||||
|
|
||||||
|
MyElements::GetCitiesByCountry
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use strict;
|
|||||||
use Class::Std::Storable;
|
use Class::Std::Storable;
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
|
||||||
|
|
||||||
# atomic complexType
|
# atomic complexType
|
||||||
# <element name="GetCitiesByCountryResponse"><complexType> definition
|
# <element name="GetCitiesByCountryResponse"><complexType> definition
|
||||||
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
@@ -16,7 +17,7 @@ my %GetCitiesByCountryResult_of :ATTR(:get<GetCitiesByCountryResult>);
|
|||||||
|
|
||||||
|
|
||||||
__PACKAGE__->_factory(
|
__PACKAGE__->_factory(
|
||||||
[ qw(
|
[ qw(
|
||||||
GetCitiesByCountryResult
|
GetCitiesByCountryResult
|
||||||
) ],
|
) ],
|
||||||
{
|
{
|
||||||
@@ -25,8 +26,8 @@ __PACKAGE__->_factory(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
GetCitiesByCountryResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -46,9 +47,16 @@ __PACKAGE__->__set_ref('');
|
|||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
|
|
||||||
=head1 NAME MyElements::GetCitiesByCountryResponse
|
=head1 NAME
|
||||||
|
|
||||||
|
MyElements::GetCitiesByCountryResponse
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use strict;
|
|||||||
use Class::Std::Storable;
|
use Class::Std::Storable;
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
|
||||||
|
|
||||||
# atomic complexType
|
# atomic complexType
|
||||||
# <element name="GetWeather"><complexType> definition
|
# <element name="GetWeather"><complexType> definition
|
||||||
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
@@ -18,9 +19,9 @@ my %CountryName_of :ATTR(:get<CountryName>);
|
|||||||
|
|
||||||
|
|
||||||
__PACKAGE__->_factory(
|
__PACKAGE__->_factory(
|
||||||
[ qw(
|
[ qw(
|
||||||
CityName
|
CityName
|
||||||
|
|
||||||
CountryName
|
CountryName
|
||||||
) ],
|
) ],
|
||||||
{
|
{
|
||||||
@@ -30,11 +31,11 @@ __PACKAGE__->_factory(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
CityName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
CityName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
|
||||||
|
|
||||||
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
CountryName => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -54,9 +55,16 @@ __PACKAGE__->__set_ref('');
|
|||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
|
|
||||||
=head1 NAME MyElements::GetWeather
|
=head1 NAME
|
||||||
|
|
||||||
|
MyElements::GetWeather
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use strict;
|
|||||||
use Class::Std::Storable;
|
use Class::Std::Storable;
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
|
||||||
|
|
||||||
# atomic complexType
|
# atomic complexType
|
||||||
# <element name="GetWeatherResponse"><complexType> definition
|
# <element name="GetWeatherResponse"><complexType> definition
|
||||||
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
@@ -16,7 +17,7 @@ my %GetWeatherResult_of :ATTR(:get<GetWeatherResult>);
|
|||||||
|
|
||||||
|
|
||||||
__PACKAGE__->_factory(
|
__PACKAGE__->_factory(
|
||||||
[ qw(
|
[ qw(
|
||||||
GetWeatherResult
|
GetWeatherResult
|
||||||
) ],
|
) ],
|
||||||
{
|
{
|
||||||
@@ -25,8 +26,8 @@ __PACKAGE__->_factory(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
||||||
GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
GetWeatherResult => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -46,9 +47,16 @@ __PACKAGE__->__set_ref('');
|
|||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
|
|
||||||
=head1 NAME MyElements::GetWeatherResponse
|
=head1 NAME
|
||||||
|
|
||||||
|
MyElements::GetWeatherResponse
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use strict;
|
|||||||
use Class::Std::Storable;
|
use Class::Std::Storable;
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# <element name="string" type="s:string"/> definition
|
# <element name="string" type="s:string"/> definition
|
||||||
#
|
#
|
||||||
@@ -26,9 +27,16 @@ __PACKAGE__->__set_ref('');
|
|||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
|
|
||||||
=head1 NAME MyElements::string
|
=head1 NAME
|
||||||
|
|
||||||
|
MyElements::string
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
package MyInterfaces::GlobalWeather;
|
package MyInterfaces::GlobalWeather;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use MyTypemaps::GlobalWeather;
|
use MyTypemaps::GlobalWeather;
|
||||||
@@ -16,15 +17,29 @@ sub new {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__PACKAGE__->__create_methods(
|
__PACKAGE__->__create_methods(
|
||||||
GetWeather => [ 'MyElements::GetWeather', ],
|
GetWeather => {
|
||||||
GetCitiesByCountry => [ 'MyElements::GetCitiesByCountry', ],
|
parts => [ 'MyElements::GetWeather', ],
|
||||||
|
soap_action => 'http://www.webserviceX.NET/GetWeather',
|
||||||
|
style => 'document',
|
||||||
|
# use => '', # use not implemented yet
|
||||||
|
},
|
||||||
|
GetCitiesByCountry => {
|
||||||
|
parts => [ 'MyElements::GetCitiesByCountry', ],
|
||||||
|
soap_action => 'http://www.webserviceX.NET/GetCitiesByCountry',
|
||||||
|
style => 'document',
|
||||||
|
# use => '', # use not implemented yet
|
||||||
|
},
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
@@ -64,5 +79,5 @@ SYNOPSIS:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
=cut
|
=pod
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -14,6 +14,7 @@ use MyInterfaces::GlobalWeather;
|
|||||||
my $weather = MyInterfaces::GlobalWeather->new();
|
my $weather = MyInterfaces::GlobalWeather->new();
|
||||||
my $result = $weather->GetWeather({ CountryName => 'Germany', CityName => 'Munich' });
|
my $result = $weather->GetWeather({ CountryName => 'Germany', CityName => 'Munich' });
|
||||||
|
|
||||||
die $result->get_faultstring()->get_value() if not ($result); # boolean comparison overloaded
|
# boolean comparison overloaded
|
||||||
|
die $result->get_faultstring()->get_value() if not ($result);
|
||||||
|
|
||||||
print $result->get_GetWeatherResult()->get_value() "\n";
|
print $result->get_GetWeatherResult()->get_value() , "\n";
|
||||||
|
|||||||
@@ -23,3 +23,17 @@ my $som = $soap->wsdl("file:///$path/wsdl/globalweather.xml")
|
|||||||
die $som->message() if $som->fault();
|
die $som->message() if $som->fault();
|
||||||
|
|
||||||
print $som->result();
|
print $som->result();
|
||||||
|
|
||||||
|
|
||||||
|
# SOAP::Lite variant:
|
||||||
|
|
||||||
|
use SOAP::Lite;
|
||||||
|
my $soap = SOAP::Lite->new()->on_action( sub { join'/', @_ } )
|
||||||
|
->proxy("http://www.webservicex.net/globalweather.asmx");
|
||||||
|
my $som = $soap->call(
|
||||||
|
SOAP::Data->name('GetWeather')->attr({ xmlns => 'http://www.webserviceX.NET' }),
|
||||||
|
SOAP::Data->name('CountryName')->value('Germany'),
|
||||||
|
SOAP::Data->name('CityName')->value('Munich')
|
||||||
|
);
|
||||||
|
|
||||||
|
print $som->result();
|
||||||
|
|||||||
+71
-25
@@ -5,14 +5,11 @@ use vars qw($AUTOLOAD);
|
|||||||
use Carp;
|
use Carp;
|
||||||
use Scalar::Util qw(blessed);
|
use Scalar::Util qw(blessed);
|
||||||
use SOAP::WSDL::Client;
|
use SOAP::WSDL::Client;
|
||||||
use SOAP::WSDL::Envelope;
|
use SOAP::WSDL::Expat::WSDLParser;
|
||||||
use SOAP::WSDL::SAX::WSDLHandler;
|
|
||||||
use Class::Std;
|
use Class::Std;
|
||||||
use XML::LibXML;
|
|
||||||
|
|
||||||
use Data::Dumper;
|
|
||||||
use LWP::UserAgent;
|
use LWP::UserAgent;
|
||||||
our $VERSION='2.00_08';
|
|
||||||
|
our $VERSION='2.00_12';
|
||||||
|
|
||||||
my %no_dispatch_of :ATTR(:name<no_dispatch>);
|
my %no_dispatch_of :ATTR(:name<no_dispatch>);
|
||||||
my %wsdl_of :ATTR(:name<wsdl>);
|
my %wsdl_of :ATTR(:name<wsdl>);
|
||||||
@@ -64,8 +61,10 @@ for my $method (keys %LOOKUP ) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
# we need to roll our own for supporting
|
||||||
|
# SOAP::WSDL->new( key => value ) syntax,
|
||||||
|
# like SOAP::Lite does
|
||||||
no warnings qw(redefine);
|
no warnings qw(redefine);
|
||||||
sub new {
|
sub new {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
@@ -85,7 +84,6 @@ for my $method (keys %LOOKUP ) {
|
|||||||
|
|
||||||
return $self;
|
return $self;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub wsdlinit {
|
sub wsdlinit {
|
||||||
@@ -98,13 +96,11 @@ sub wsdlinit {
|
|||||||
croak $response->message() if ($response->code != 200);
|
croak $response->message() if ($response->code != 200);
|
||||||
|
|
||||||
# TODO: Port parser to expat and remove XML::LibXML dependency
|
# TODO: Port parser to expat and remove XML::LibXML dependency
|
||||||
my $parser = XML::LibXML->new();
|
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
|
||||||
my $filter = SOAP::WSDL::SAX::WSDLHandler->new();
|
|
||||||
$parser->set_handler( $filter );
|
|
||||||
$parser->parse_string( $response->content() );
|
$parser->parse_string( $response->content() );
|
||||||
|
|
||||||
# sanity checks
|
# sanity checks
|
||||||
my $wsdl_definitions = $filter->get_data() or die "unable to parse WSDL";
|
my $wsdl_definitions = $parser->get_data() or die "unable to parse WSDL";
|
||||||
my $types = $wsdl_definitions->first_types()
|
my $types = $wsdl_definitions->first_types()
|
||||||
or die "unable to extract schema from WSDL";
|
or die "unable to extract schema from WSDL";
|
||||||
my $ns = $wsdl_definitions->get_xmlns()
|
my $ns = $wsdl_definitions->get_xmlns()
|
||||||
@@ -145,7 +141,7 @@ sub _wsdl_get_port :PRIVATE {
|
|||||||
return $port_of{ $ident } = $portname_of{ $ident }
|
return $port_of{ $ident } = $portname_of{ $ident }
|
||||||
? $service_of{ $ident }->get_port( $ns, $portname_of{ $ident } )
|
? $service_of{ $ident }->get_port( $ns, $portname_of{ $ident } )
|
||||||
: $port_of{ $ident } = $service_of{ $ident }->get_port()->[ 0 ];
|
: $port_of{ $ident } = $service_of{ $ident }->get_port()->[ 0 ];
|
||||||
} ## end sub _wsdl_get_port
|
}
|
||||||
|
|
||||||
sub _wsdl_get_binding :PRIVATE {
|
sub _wsdl_get_binding :PRIVATE {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
@@ -155,7 +151,7 @@ sub _wsdl_get_binding :PRIVATE {
|
|||||||
$binding_of{ $ident } = $wsdl->find_binding( $wsdl->_expand( $port->get_binding() ) )
|
$binding_of{ $ident } = $wsdl->find_binding( $wsdl->_expand( $port->get_binding() ) )
|
||||||
or die "no binding found for ", $port->get_binding();
|
or die "no binding found for ", $port->get_binding();
|
||||||
return $binding_of{ $ident };
|
return $binding_of{ $ident };
|
||||||
} ## end sub _wsdl_get_binding
|
}
|
||||||
|
|
||||||
sub _wsdl_get_portType :PRIVATE {
|
sub _wsdl_get_portType :PRIVATE {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
@@ -165,8 +161,7 @@ sub _wsdl_get_portType :PRIVATE {
|
|||||||
$porttype_of{ $ident } = $wsdl->find_portType( $wsdl->_expand( $binding->get_type() ) )
|
$porttype_of{ $ident } = $wsdl->find_portType( $wsdl->_expand( $binding->get_type() ) )
|
||||||
or die "cannot find portType for " . $binding->get_type();
|
or die "cannot find portType for " . $binding->get_type();
|
||||||
return $porttype_of{ $ident };
|
return $porttype_of{ $ident };
|
||||||
} ## end sub _wsdl_get_portType
|
}
|
||||||
|
|
||||||
|
|
||||||
sub _wsdl_init_methods :PRIVATE {
|
sub _wsdl_init_methods :PRIVATE {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
@@ -174,9 +169,7 @@ sub _wsdl_init_methods :PRIVATE {
|
|||||||
my $wsdl = $definitions_of{ $ident };
|
my $wsdl = $definitions_of{ $ident };
|
||||||
my $ns = $wsdl->get_targetNamespace();
|
my $ns = $wsdl->get_targetNamespace();
|
||||||
|
|
||||||
# get bindings, portType, message, part(s)
|
# get bindings, portType, message, part(s) - use private methods for clear separation...
|
||||||
# - use cached values where possible for speed,
|
|
||||||
# private methods if not for clear separation...
|
|
||||||
$self->_wsdl_get_service if not ($service_of{ $ident });
|
$self->_wsdl_get_service if not ($service_of{ $ident });
|
||||||
my $binding = $binding_of{ $ident } || $self->_wsdl_get_binding()
|
my $binding = $binding_of{ $ident } || $self->_wsdl_get_binding()
|
||||||
|| die "Can't find binding";
|
|| die "Can't find binding";
|
||||||
@@ -241,7 +234,6 @@ sub call {
|
|||||||
my $response = (blessed $data)
|
my $response = (blessed $data)
|
||||||
? $client->call( $method, $data )
|
? $client->call( $method, $data )
|
||||||
: do {
|
: do {
|
||||||
|
|
||||||
my $content = '';
|
my $content = '';
|
||||||
# TODO support RPC-encoding: Top-Level element + namespace...
|
# TODO support RPC-encoding: Top-Level element + namespace...
|
||||||
foreach my $part ( @{ $method_info_of{ $ident }->{ $method }->{ parts } } ) {
|
foreach my $part ( @{ $method_info_of{ $ident }->{ $method }->{ parts } } ) {
|
||||||
@@ -471,7 +463,19 @@ You may pass the servicename and portname as attributes to wsdlinit, though.
|
|||||||
|
|
||||||
=head1 Differences to SOAP::Lite
|
=head1 Differences to SOAP::Lite
|
||||||
|
|
||||||
=head3 Output formats
|
=head2 Message style/encoding
|
||||||
|
|
||||||
|
While SOAP::Lite supports rpc/encoded style/encoding only, SOAP::WSDL currently
|
||||||
|
supports document/literal style/encoding.
|
||||||
|
|
||||||
|
=head2 autotype / type information
|
||||||
|
|
||||||
|
SOAP::Lite defaults to transmitting XML type information by default, where
|
||||||
|
SOAP::WSDL defaults to leaving it out.
|
||||||
|
|
||||||
|
autotype(1) might even be broken in SOAP::WSDL - it's not well-tested, yet.
|
||||||
|
|
||||||
|
=head2 Output formats
|
||||||
|
|
||||||
In contrast to SOAP::Lite, SOAP::WSDL supports the following output formats:
|
In contrast to SOAP::Lite, SOAP::WSDL supports the following output formats:
|
||||||
|
|
||||||
@@ -498,7 +502,7 @@ See below.
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head3 outputxml
|
=head2 outputxml
|
||||||
|
|
||||||
SOAP::Lite returns only the content of the SOAP body when outputxml is set
|
SOAP::Lite returns only the content of the SOAP body when outputxml is set
|
||||||
to true. SOAP::WSDL returns the complete XML response.
|
to true. SOAP::WSDL returns the complete XML response.
|
||||||
@@ -565,7 +569,7 @@ Passing in item => [1,2,3] could serialize to
|
|||||||
<item>1 2</item><item>3</item>
|
<item>1 2</item><item>3</item>
|
||||||
<item>1</item><item>2 3</item>
|
<item>1</item><item>2 3</item>
|
||||||
|
|
||||||
Ambiguos data can be avoided by passing an objects as data.
|
Ambiguos data can be avoided by providing data as objects.
|
||||||
|
|
||||||
=item * XML Schema facets
|
=item * XML Schema facets
|
||||||
|
|
||||||
@@ -588,6 +592,41 @@ The following facets have no influence yet:
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
=head2 Related projects
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item * L<SOAP::Lite|SOAP::Lite>
|
||||||
|
|
||||||
|
Full featured SOAP-library, little WSDL support. Supports rpc-encoded style only. Many protocols supported.
|
||||||
|
|
||||||
|
=item * <XML::Compile::WSDL|XML::Compile::WSDL>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head2 Sources of documentation
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item * SOAP::WSDL homepage at sourceforge.net
|
||||||
|
|
||||||
|
L<http://soap-wsdl.sourceforge.net>
|
||||||
|
|
||||||
|
=item * SOAP::WSDL forum at CPAN::Forum
|
||||||
|
|
||||||
|
L<http://www.cpanforum.com/dist/SOAP-WSDL>
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
=head1 ACKNOWLEDGMENTS
|
=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.
|
||||||
@@ -595,7 +634,7 @@ 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, Marc Overmeer,
|
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
|
Jon Robens, Isidro Vila Verde and Glenn Wood spotted bugs and/or
|
||||||
suggested improvements in the 1.2x releases.
|
suggested improvements in the 1.2x releases.
|
||||||
|
|
||||||
@@ -615,7 +654,14 @@ the same terms as perl itself
|
|||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
||||||
|
|
||||||
|
=head1 REPOSITORY INFORMATION
|
||||||
|
|
||||||
|
$Rev: 188 $
|
||||||
|
$LastChangedBy: kutterma $
|
||||||
|
$Id: WSDL.pm 188 2007-09-03 15:15:19Z kutterma $
|
||||||
|
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|||||||
@@ -78,12 +78,15 @@ sub init {
|
|||||||
my @args = @_;
|
my @args = @_;
|
||||||
foreach my $value (@args)
|
foreach my $value (@args)
|
||||||
{
|
{
|
||||||
die $value if (not defined ($value->{ Name }));
|
die @args if (not defined ($value->{ Name }));
|
||||||
if ($value->{ Name } =~m{^xmlns\:}xms) {
|
if ($value->{ Name } =~m{^xmlns\:}xms) {
|
||||||
die $xmlns_of{ ident $self }
|
die $xmlns_of{ ident $self }
|
||||||
if ref $xmlns_of{ ident $self } ne 'HASH';
|
if ref $xmlns_of{ ident $self } ne 'HASH';
|
||||||
|
|
||||||
|
# add namespaces
|
||||||
$xmlns_of{ ident $self }->{ $value->{ Value } } =
|
$xmlns_of{ ident $self }->{ $value->{ Value } } =
|
||||||
$value->{ LocalName };
|
$value->{ LocalName };
|
||||||
|
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
elsif ($value->{ Name } =~m{^xmlns$}xms) {
|
elsif ($value->{ Name } =~m{^xmlns$}xms) {
|
||||||
|
|||||||
+156
-54
@@ -8,28 +8,44 @@ use LWP::UserAgent;
|
|||||||
use HTTP::Request;
|
use HTTP::Request;
|
||||||
use Scalar::Util qw(blessed);
|
use Scalar::Util qw(blessed);
|
||||||
|
|
||||||
use SOAP::WSDL::Envelope;
|
use SOAP::WSDL::Factory::Serializer;
|
||||||
|
use SOAP::WSDL::Factory::Transport;
|
||||||
use SOAP::WSDL::Expat::MessageParser;
|
use SOAP::WSDL::Expat::MessageParser;
|
||||||
use SOAP::WSDL::SOAP::Typelib::Fault11;
|
use SOAP::WSDL::SOAP::Typelib::Fault11;
|
||||||
|
|
||||||
# Package globals for speed...
|
our $VERSION='2.00_12';
|
||||||
|
|
||||||
|
# Package global for speed and memory savings.
|
||||||
|
# But should be factored out into serializer/deserializer...
|
||||||
my $PARSER;
|
my $PARSER;
|
||||||
|
|
||||||
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
|
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
|
||||||
my %no_dispatch_of :ATTR(:name<no_dispatch> :default<()>);
|
my %no_dispatch_of :ATTR(:name<no_dispatch> :default<()>);
|
||||||
my %outputxml_of :ATTR(:name<outputxml> :default<()>);
|
my %outputxml_of :ATTR(:name<outputxml> :default<()>);
|
||||||
my %proxy_of :ATTR(:name<proxy> :default<()>);
|
my %transport_of :ATTR(:name<transport> :default<()>);
|
||||||
|
my %endpoint_of :ATTR(:name<endpoint> :default<()>);
|
||||||
|
|
||||||
|
my %soap_version_of :ATTR(:get<soap_version> :init_attr<soap_version> :default<'1.1'>);
|
||||||
|
|
||||||
my %fault_class_of :ATTR(:name<fault_class> :default<SOAP::WSDL::SOAP::Typelib::Fault11>);
|
my %fault_class_of :ATTR(:name<fault_class> :default<SOAP::WSDL::SOAP::Typelib::Fault11>);
|
||||||
my %trace_of :ATTR(:set<trace> :init_arg<trace> :default<()> );
|
my %trace_of :ATTR(:set<trace> :init_arg<trace> :default<()> );
|
||||||
my %on_action_of :ATTR(:name<on_action> :default<()>);
|
my %on_action_of :ATTR(:name<on_action> :default<()>);
|
||||||
my %content_type_of :ATTR(:name<content_type> :default<text/xml; charset=utf8>);
|
my %content_type_of :ATTR(:name<content_type> :default<text/xml; charset=utf8>); #/#trick editors
|
||||||
|
my %serializer_of :ATTR(:name<serializer> :default<()>);
|
||||||
#/#trick editors
|
|
||||||
|
|
||||||
# TODO remove when preparing 2.01
|
# TODO remove when preparing 2.01
|
||||||
sub outputtree { warn 'outputtree is deprecated and'
|
sub outputtree { warn 'outputtree is deprecated and'
|
||||||
. 'will be removed before reaching v2.01 !' }
|
. 'will be removed before reaching v2.01 !' }
|
||||||
|
|
||||||
|
sub BUILD {
|
||||||
|
my ($self, $ident, $attrs_of_ref) = @_;
|
||||||
|
|
||||||
|
if (exists $attrs_of_ref->{ proxy }) {
|
||||||
|
$self->set_proxy( $attrs_of_ref->{ proxy } );
|
||||||
|
delete $attrs_of_ref->{ proxy };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sub get_trace {
|
sub get_trace {
|
||||||
my $ident = ident $_[0];
|
my $ident = ident $_[0];
|
||||||
@@ -39,6 +55,44 @@ sub get_trace {
|
|||||||
: sub { warn @_ }
|
: sub { warn @_ }
|
||||||
: ()
|
: ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_proxy {
|
||||||
|
return $_[0]->get_transport();
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_proxy {
|
||||||
|
my ($self, @args_from) = @_;
|
||||||
|
my $ident = ident $self;
|
||||||
|
|
||||||
|
# remember old value to return it later - Class::Std does so, too
|
||||||
|
my $old_value = $transport_of{ $ident };
|
||||||
|
|
||||||
|
# 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];
|
||||||
|
|
||||||
|
# set transport - SOAP::Lite works similar...
|
||||||
|
$transport_of{ $ident } = SOAP::WSDL::Factory::Transport
|
||||||
|
->get_transport( @args_from );
|
||||||
|
|
||||||
|
return $old_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_soap_version {
|
||||||
|
my $ident = ident shift;
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# serializer object
|
||||||
|
delete $serializer_of{ $ident };
|
||||||
|
$soap_version_of{ $ident } = shift;
|
||||||
|
|
||||||
|
return $soap_version;
|
||||||
|
}
|
||||||
|
|
||||||
# Mimic SOAP::Lite's behaviour for getter/setter routines
|
# Mimic SOAP::Lite's behaviour for getter/setter routines
|
||||||
SUBFACTORY: {
|
SUBFACTORY: {
|
||||||
@@ -69,60 +123,79 @@ sub call {
|
|||||||
: (@_>1)
|
: (@_>1)
|
||||||
? { @_ }
|
? { @_ }
|
||||||
: $_[0];
|
: $_[0];
|
||||||
|
my $header = {};
|
||||||
|
|
||||||
my $soap_action;
|
my ($soap_action, $operation);
|
||||||
my $trace_sub = $self->get_trace();
|
my $trace_sub = $self->get_trace();
|
||||||
my $envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
|
|
||||||
|
if (ref $method eq 'HASH') {
|
||||||
if (blessed $data
|
$soap_action = $method->{ soap_action };
|
||||||
&& $data->isa('SOAP::WSDL::XSD::Typelib::Builtin::anyType'))
|
$operation = $method->{ operation }
|
||||||
{
|
}
|
||||||
# TODO replace by something derived from binding - this is just a
|
else {
|
||||||
# workaround...
|
$operation = $method;
|
||||||
$soap_action = join '/', $data->get_xmlns(), $method;
|
}
|
||||||
}
|
|
||||||
else {
|
|
||||||
$envelope = SOAP::WSDL::Envelope->serialize( $method, $data );
|
$serializer_of{ $ident } ||= SOAP::WSDL::Factory::Serializer->get_serializer({
|
||||||
# TODO add something like SOAP::Lite's on_action mechanism
|
soap_version => $self->get_soap_version(),
|
||||||
$soap_action = $on_action_of{$ident}->( $self, $method ) if ($on_action_of{$ident});
|
});
|
||||||
}
|
|
||||||
|
my $envelope = $serializer_of{ $ident }->serialize({
|
||||||
|
method => $operation,
|
||||||
|
body => $data,
|
||||||
|
header => $header,
|
||||||
|
});
|
||||||
|
|
||||||
return $envelope if $self->no_dispatch();
|
return $envelope if $self->no_dispatch();
|
||||||
|
|
||||||
# get response via transport layer
|
# try to guess soap_action if not given
|
||||||
# maybe we should return a result with the following methods:
|
if (not defined $soap_action) {
|
||||||
# - result: returns the result of the call (like SOAP::Lite, but as
|
$soap_action = (blessed $data
|
||||||
# object tree)
|
&& $data->isa('SOAP::WSDL::XSD::Typelib::Builtin::anyType'))
|
||||||
# - header: returns the content of the SOAP header
|
? $soap_action = join '/', $data->get_xmlns(), $operation
|
||||||
# - fault: returns the result of the call if a SOAP fault is sent back
|
: ($on_action_of{$ident})
|
||||||
# by the server. Retuns undef (nothing) if the call has been
|
? $soap_action = $on_action_of{$ident}->( $self, $operation )
|
||||||
# processed without errors.
|
: "";
|
||||||
my $ua = LWP::UserAgent->new();
|
}
|
||||||
my $request = HTTP::Request->new( 'POST',
|
|
||||||
$self->get_proxy(),
|
# always quote SOAPAction header.
|
||||||
[ 'Content-Type', $content_type_of{ $ident },
|
# WS-I BP 1.0 R1109
|
||||||
'Content-Length', length($envelope),
|
$soap_action =~s{\A(:?"|')?}{"}xms;
|
||||||
'SOAPAction', $soap_action,
|
$soap_action =~s{(:?"|')?\Z}{"}xms;
|
||||||
],
|
|
||||||
$envelope );
|
# get response via transport layer.
|
||||||
|
# Normally, SOAP::Lite's transport layer is used, though users
|
||||||
|
# may provide their own.
|
||||||
$trace_sub->( $request->as_string() ) if $trace_of{ $ident }; # if for speed
|
my $transport = $self->get_transport();
|
||||||
my $response = $ua->request( $request );
|
my $response = $transport->send_receive(
|
||||||
$trace_sub->( $response->as_string() ) if $trace_of{ $ident }; # if for speed
|
endpoint => $self->get_endpoint(),
|
||||||
|
content_type => $content_type_of{ $ident },
|
||||||
return $response->content() if ($self->outputxml() );
|
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...
|
||||||
|
);
|
||||||
|
|
||||||
|
return $response if ($self->outputxml() );
|
||||||
|
|
||||||
$PARSER->class_resolver( $self->get_class_resolver() );
|
$PARSER->class_resolver( $self->get_class_resolver() );
|
||||||
|
|
||||||
# if we had no success (Transport layer error status code)
|
# if we had no success (Transport layer error status code)
|
||||||
# or if transport layer failed
|
# or if transport layer failed
|
||||||
if ($response->code() != 200) {
|
if ( ! $transport->is_success() ) {
|
||||||
# Try deserializing response - there may be some
|
# Try deserializing response - there may be some
|
||||||
if ($response->content) {
|
if ( $response ) {
|
||||||
eval { $PARSER->parse( $response->content() ); };
|
eval { $PARSER->parse( $response ); };
|
||||||
return $PARSER->get_data() if (not $@);
|
return $PARSER->get_data() if (not $@);
|
||||||
warn "could not deserialize response: $@";
|
return $fault_class_of{$ident}->new({
|
||||||
|
faultcode => 'soap:Server',
|
||||||
|
faultactor => 'urn:localhost',
|
||||||
|
faultstring => "Error deserializing message: $@. \n"
|
||||||
|
. "Message was: \n$response"
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
# generate & return fault if we cannot serialize response
|
# generate & return fault if we cannot serialize response
|
||||||
@@ -131,11 +204,10 @@ sub call {
|
|||||||
faultcode => 'soap:Server',
|
faultcode => 'soap:Server',
|
||||||
faultactor => 'urn:localhost',
|
faultactor => 'urn:localhost',
|
||||||
faultstring => 'Error sending / receiving message: '
|
faultstring => 'Error sending / receiving message: '
|
||||||
. $response->message()
|
. $transport->message()
|
||||||
#$soap->transport->message()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
eval { $PARSER->parse( $response->content() ) };
|
eval { $PARSER->parse( $response ) };
|
||||||
|
|
||||||
# return fault if we cannot deserialize response
|
# return fault if we cannot deserialize response
|
||||||
if ($@) {
|
if ($@) {
|
||||||
@@ -161,6 +233,31 @@ SOAP::WSDL::Client - SOAP::WSDL's SOAP Client
|
|||||||
=head1 METHODS
|
=head1 METHODS
|
||||||
|
|
||||||
=head2 call
|
=head2 call
|
||||||
|
|
||||||
|
$soap->call( \%method, \@parts );
|
||||||
|
|
||||||
|
%method is a hash with the following keys:
|
||||||
|
|
||||||
|
Name Description
|
||||||
|
----------------------------------------------------
|
||||||
|
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)
|
||||||
|
|
||||||
|
The style and use keys have no influence yet.
|
||||||
|
|
||||||
|
@parts is a list containing the elements of the message parts.
|
||||||
|
|
||||||
|
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
|
||||||
|
be document/literal
|
||||||
|
|
||||||
|
|
||||||
=head2 Configuration methods
|
=head2 Configuration methods
|
||||||
|
|
||||||
@@ -284,7 +381,12 @@ the same terms as perl itself
|
|||||||
|
|
||||||
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
|
||||||
|
|
||||||
|
=head1 REPOSITORY INFORMATION
|
||||||
|
|
||||||
|
$Rev: 188 $
|
||||||
|
$LastChangedBy: kutterma $
|
||||||
|
$Id: Client.pm 188 2007-09-03 15:15:19Z kutterma $
|
||||||
|
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,23 +21,37 @@ sub __create_new {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub __create_methods {
|
sub __create_methods {
|
||||||
my ($package, %parts_of) = @_;
|
my ($package, %info_of) = @_;
|
||||||
|
|
||||||
no strict qw(refs);
|
no strict qw(refs);
|
||||||
|
|
||||||
for my $method (keys %parts_of){
|
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 {
|
*{ "$package\::$method" } = sub {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my @param = map {
|
my @param = map {
|
||||||
my $data = shift || {};
|
my $data = shift || {};
|
||||||
eval "require $_";
|
eval "require $_";
|
||||||
$_->new( $data );
|
$_->new( $data );
|
||||||
} @{ $parts_of{ $method } };
|
} @parts;
|
||||||
|
|
||||||
$self->call( $method, @param );
|
return $self->SUPER::call( {
|
||||||
|
operation => $method,
|
||||||
|
soap_action => $soap_action,
|
||||||
|
}, @param );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
@@ -48,13 +62,40 @@ __END__
|
|||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
SOAP::WSDL::Client::Base - Base client for WSDL-based SOAP access
|
SOAP::WSDL::Client::Base - Factory class for WSDL-based SOAP access
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
package MySoapClient;
|
package MySoapInterface;
|
||||||
use SOAP::WSDL::Client::Base;
|
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) );
|
__PACKAGE__->__create_methods( qw(one two three) );
|
||||||
1;
|
1;
|
||||||
|
|
||||||
=cut
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Factory class for creating interface classes. Should probably be renamed to
|
||||||
|
SOAP::WSDL::Factory::Interface...
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
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: 176 $
|
||||||
|
$LastChangedBy: kutterma $
|
||||||
|
$Id: Base.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/Client/Base.pm $
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use Carp;
|
use Carp;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use List::Util qw(first);
|
use List::Util qw(first);
|
||||||
use Class::Std::Storable;
|
use Class::Std::Storable;
|
||||||
use base qw(SOAP::WSDL::Base);
|
use base qw(SOAP::WSDL::Base);
|
||||||
@@ -116,7 +116,17 @@ sub _create_interface {
|
|||||||
#
|
#
|
||||||
my %operations = ();
|
my %operations = ();
|
||||||
for my $operation ( @{ $operation_ref } ) {
|
for my $operation ( @{ $operation_ref } ) {
|
||||||
my $operation_name = $operation->get_name();
|
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 };
|
my $port_op = first { $_->get_name() eq $operation_name } @{ $port_operation_ref };
|
||||||
|
|
||||||
$operations{ $operation_name }->{ documentation } = $port_op->get_documentation();
|
$operations{ $operation_name }->{ documentation } = $port_op->get_documentation();
|
||||||
@@ -151,9 +161,6 @@ sub _create_interface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# use Data::Dumper;
|
|
||||||
# die Dumper \%operations;
|
|
||||||
|
|
||||||
my $template = <<'EOT';
|
my $template = <<'EOT';
|
||||||
package [% interface_prefix %][% service.get_name.replace('\.', '::') %];
|
package [% interface_prefix %][% service.get_name.replace('\.', '::') %];
|
||||||
|
|
||||||
@@ -174,33 +181,42 @@ sub new {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__PACKAGE__->__create_methods(
|
__PACKAGE__->__create_methods(
|
||||||
[% FOREACH name = operations.keys -%]
|
[% FOREACH name = operations.keys -%]
|
||||||
[% name %] => [ [% FOREACH class = operations.$name.input.class %]'[% class %]', [% END %]],
|
[% name %] => {
|
||||||
[% END %]
|
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;
|
1;
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
=pod
|
[% MACRO pod BLOCK %]=pod[% END %]
|
||||||
|
[% MACRO cut BLOCK %]=pod[% END %]
|
||||||
|
[% MACRO head1 BLOCK %]=head1[% END %]
|
||||||
|
[% MACRO head2 BLOCK %]=head2[% END %]
|
||||||
|
[% pod %]
|
||||||
|
|
||||||
=head1 NAME
|
[% head1 %] NAME
|
||||||
|
|
||||||
[% interface_prefix %][% service.get_name %] - SOAP interface to [% service.get_name %] at
|
[% interface_prefix %][% service.get_name %] - SOAP interface to [% service.get_name %] at
|
||||||
[% service.first_port.get_location %]
|
[% service.first_port.get_location %]
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
[% head1 %] SYNOPSIS
|
||||||
|
|
||||||
my $interface = [% interface_prefix %][% service.get_name %]->new();
|
my $interface = [% interface_prefix %][% service.get_name %]->new();
|
||||||
my $[% operations.keys.1 %] = $interface->[% operations.keys.1 %]();
|
my $[% operations.keys.1 %] = $interface->[% operations.keys.1 %]();
|
||||||
|
|
||||||
|
|
||||||
=head1 METHODS
|
[% head1 %] METHODS
|
||||||
[% FOREACH name=operations.keys;
|
[% FOREACH name=operations.keys;
|
||||||
operation=operations.$name;
|
operation=operations.$name;
|
||||||
%]
|
%]
|
||||||
=head2 [% name %]
|
[% head2 %] [% name %]
|
||||||
|
|
||||||
[% operation.documentation %]
|
[% operation.documentation %]
|
||||||
|
|
||||||
@@ -211,7 +227,7 @@ SYNOPSIS:
|
|||||||
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
=cut
|
[% cut %]
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
|
|||||||
@@ -5,29 +5,10 @@ use warnings;
|
|||||||
use SOAP::WSDL::XSD::Typelib::Builtin;
|
use SOAP::WSDL::XSD::Typelib::Builtin;
|
||||||
use XML::Parser::Expat;
|
use XML::Parser::Expat;
|
||||||
|
|
||||||
=pod
|
|
||||||
|
|
||||||
=head2 new
|
|
||||||
|
|
||||||
=over
|
|
||||||
|
|
||||||
=item SYNOPSIS
|
|
||||||
|
|
||||||
my $obj = ->new();
|
|
||||||
|
|
||||||
=item DESCRIPTION
|
|
||||||
|
|
||||||
Constructor.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
sub new {
|
sub new {
|
||||||
my $class = shift;
|
my ($class, $args) = @_;
|
||||||
my $args = shift;
|
|
||||||
my $self = {
|
my $self = {
|
||||||
class_resolver => $args->{ class_resolver }
|
class_resolver => $args->{ class_resolver },
|
||||||
};
|
};
|
||||||
bless $self, $class;
|
bless $self, $class;
|
||||||
return $self;
|
return $self;
|
||||||
@@ -39,33 +20,39 @@ sub class_resolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub _initialize {
|
sub _initialize {
|
||||||
my $self = shift;
|
my ($self, $parser) = @_;
|
||||||
|
|
||||||
$self->{ data } = undef;
|
delete $self->{ data }; # remove potential old results
|
||||||
|
|
||||||
my $characters;
|
my $characters;
|
||||||
my $current = undef;
|
my $current = undef;
|
||||||
my $ignore = [ 'Envelope', 'Body' ]; # top level elements to ignore
|
my $ignore = [ 'Envelope', 'Body' ]; # top level elements to ignore
|
||||||
my $list = []; # node list
|
my $list = []; # node list
|
||||||
my $path = []; # current path (without
|
my $path = []; # current path
|
||||||
# number)
|
|
||||||
my $skip = 0; # skip elements
|
my $skip = 0; # skip elements
|
||||||
my $parser = XML::Parser::Expat->new();
|
|
||||||
|
|
||||||
# use "globals" for speed
|
# use "globals" for speed
|
||||||
my ($_prefix, $_localname, $_element, $_method,
|
my ($_prefix, $_localname, $_element, $_method,
|
||||||
$_class, $_parser, %_attrs) = ();
|
$_class, $_parser, %_attrs) = ();
|
||||||
|
|
||||||
no strict qw(refs);
|
no strict qw(refs);
|
||||||
$parser->setHandlers(
|
$parser->setHandlers(
|
||||||
Start => sub {
|
Start => sub {
|
||||||
($_parser, $_element, %_attrs) = @_;
|
($_parser, $_element, %_attrs) = @_;
|
||||||
($_prefix, $_localname) = split m{:}xms , $_element;
|
($_prefix, $_localname) = split m{:}xms , $_element;
|
||||||
|
|
||||||
$_localname ||= $_element; # for non-prefixed elements
|
$_localname ||= $_element; # for non-prefixed elements
|
||||||
|
|
||||||
# ignore top level elements
|
# ignore top level elements
|
||||||
if (@{ $ignore } && $_localname eq $ignore->[0]) {
|
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 };
|
shift @{ $ignore };
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -73,39 +60,40 @@ sub _initialize {
|
|||||||
push @{ $path }, $_localname; # step down in path
|
push @{ $path }, $_localname; # step down in path
|
||||||
return if $skip; # skip inside __SKIP__
|
return if $skip; # skip inside __SKIP__
|
||||||
|
|
||||||
# resolve class of this element
|
# resolve class of this element
|
||||||
$_class = $self->{ class_resolver }->get_class( $path )
|
$_class = $self->{ class_resolver }->get_class( $path )
|
||||||
or die "Cannot resolve class for "
|
or die "Cannot resolve class for "
|
||||||
. join('/', @{ $path }) . " via $self->{ class_resolver }";
|
. join('/', @{ $path }) . " via " . $self->{ class_resolver };
|
||||||
|
|
||||||
if ($_class eq '__SKIP__') {
|
# maybe write as "return $skip = join ... if (...)" ?
|
||||||
$skip = join '/', @{ $path };
|
# would save a BLOCK...
|
||||||
return;
|
return $skip = join('/', @{ $path }) if ($_class eq '__SKIP__');
|
||||||
}
|
|
||||||
|
|
||||||
push @$list, $current; # step down in tree ()remember current)
|
push @$list, $current; # step down in tree ()remember current)
|
||||||
|
|
||||||
$characters = q{}; # empty characters
|
$characters = q{}; # empty characters
|
||||||
|
|
||||||
# Check whether we have a primitive - we implement them as classes
|
# Check whether we have a primitive - we implement them as classes
|
||||||
# TODO replace with UNIVERSAL->isa()
|
# 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
|
# match is a bit faster if the string does not match, but WAY slower
|
||||||
# if $class matches...
|
# if $class matches...
|
||||||
|
|
||||||
if (index $_class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
|
if (index $_class, 'SOAP::WSDL::XSD::Typelib::Builtin', 0 < 0) {
|
||||||
# check wheter there is a CODE reference for $class::new.
|
# 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
|
# If not, require it - all classes required here MUST
|
||||||
# define new()
|
# define new()
|
||||||
# This is 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
|
||||||
*{ "$_class\::new" }{ CODE }
|
defined *{ "$_class\::new" }{ CODE }
|
||||||
|
or scalar @{ *{ "$_class\::ISA" }{ ARRAY } }
|
||||||
or eval "require $_class" ## no critic qw(ProhibitStringyEval)
|
or eval "require $_class" ## no critic qw(ProhibitStringyEval)
|
||||||
or die $@;
|
or die $@;
|
||||||
}
|
}
|
||||||
|
|
||||||
$current = $_class->new({ %_attrs }); # set new current object
|
$current = $_class->new({ %_attrs }); # set new current object
|
||||||
|
|
||||||
# remember top level element
|
# remember top level element
|
||||||
defined $self->{ data }
|
exists $self->{ data }
|
||||||
or ($self->{ data } = $current);
|
or ($self->{ data } = $current);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -146,8 +134,8 @@ sub _initialize {
|
|||||||
# set appropriate attribute in last element
|
# set appropriate attribute in last element
|
||||||
# multiple values must be implemented in base class
|
# multiple values must be implemented in base class
|
||||||
$_method = "add_$_localname";
|
$_method = "add_$_localname";
|
||||||
$$list[-1]->$_method( $current );
|
$$list[-1]->$_method( $current );
|
||||||
|
|
||||||
$current = pop @$list; # step up in object hierarchy...
|
$current = pop @$list; # step up in object hierarchy...
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -155,18 +143,24 @@ sub _initialize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub parse {
|
sub parse {
|
||||||
$_[0]->_initialize->parse( $_[1] );
|
$_[0]->_initialize( XML::Parser::Expat->new() )->parse( $_[1] );
|
||||||
return $_[0]->{ data };
|
return $_[0]->{ data };
|
||||||
}
|
}
|
||||||
|
|
||||||
sub parsefile {
|
sub parsefile {
|
||||||
$_[0]->_initialize->parsefile( $_[1] );
|
$_[0]->_initialize( XML::Parser::Expat->new() )->parsefile( $_[1] );
|
||||||
return $_[0]->{ data };
|
return $_[0]->{ data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# SAX-like aliases
|
||||||
|
sub parse_string;
|
||||||
|
*parse_string = \&parse;
|
||||||
|
|
||||||
|
sub parse_file;
|
||||||
|
*parse_file = \&parsefile;
|
||||||
|
|
||||||
sub get_data {
|
sub get_data {
|
||||||
my $self = shift;
|
return $_[0]->{ data };
|
||||||
return $self->{ data };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
@@ -224,9 +218,9 @@ This module may be used under the same terms as perl itself.
|
|||||||
|
|
||||||
$ID: $
|
$ID: $
|
||||||
|
|
||||||
$LastChangedDate: $
|
$LastChangedDate: 2007-09-02 21:05:18 +0200 (So, 02 Sep 2007) $
|
||||||
$LastChangedRevision: $
|
$LastChangedRevision: 184 $
|
||||||
$LastChangedBy: $
|
$LastChangedBy: kutterma $
|
||||||
|
|
||||||
$HeadURL: $
|
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $
|
||||||
|
|
||||||
|
|||||||
@@ -2,148 +2,25 @@
|
|||||||
package SOAP::WSDL::Expat::MessageStreamParser;
|
package SOAP::WSDL::Expat::MessageStreamParser;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use SOAP::WSDL::XSD::Typelib::Builtin;
|
|
||||||
use XML::Parser::Expat;
|
use XML::Parser::Expat;
|
||||||
|
use SOAP::WSDL::Expat::MessageParser;
|
||||||
|
use base qw(SOAP::WSDL::Expat::MessageParser);
|
||||||
|
|
||||||
=pod
|
sub parse_start {
|
||||||
|
|
||||||
=head2 new
|
|
||||||
|
|
||||||
=over
|
|
||||||
|
|
||||||
=item SYNOPSIS
|
|
||||||
|
|
||||||
my $obj = ->new();
|
|
||||||
|
|
||||||
=item DESCRIPTION
|
|
||||||
|
|
||||||
Constructor.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
sub new {
|
|
||||||
my $class = shift;
|
|
||||||
my $self = {
|
|
||||||
class_resolver => shift->{ class_resolver }
|
|
||||||
};
|
|
||||||
bless $self, $class;
|
|
||||||
return $self;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub class_resolver {
|
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
$self->{ class_resolver } = shift;
|
$self->{ parser } = $_[0]->_initialize( XML::Parser::ExpatNB->new() );
|
||||||
}
|
}
|
||||||
|
sub init;
|
||||||
sub init {
|
*init = \&parse_start;
|
||||||
my $self = shift;
|
|
||||||
my $xml = shift;
|
|
||||||
$self->{ data } = undef;
|
|
||||||
|
|
||||||
my $characters;
|
|
||||||
my $current = '__STOP__';
|
|
||||||
my $ignore = [ 'Envelope', 'Body' ];
|
|
||||||
my $list = [];
|
|
||||||
my $namespace = {};
|
|
||||||
my $path = [];
|
|
||||||
my $parser = XML::Parser::ExpatNB->new();
|
|
||||||
|
|
||||||
no strict qw(refs);
|
sub parse_more {
|
||||||
$parser->setHandlers(
|
$_[0]->{ parser }->parse_more( $_[1] );
|
||||||
Start => sub {
|
|
||||||
my ($parser, $element, %attrs) = @_;
|
|
||||||
my ($prefix, $localname) = split m{:}xms , $element;
|
|
||||||
# for non-prefixed elements
|
|
||||||
if (not $localname) {
|
|
||||||
$localname = $element;
|
|
||||||
$prefix = q{};
|
|
||||||
}
|
|
||||||
# ignore top level elements
|
|
||||||
if (@{ $ignore } && $localname eq $ignore->[0]) {
|
|
||||||
shift @{ $ignore };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
# empty characters
|
|
||||||
$characters = q{};
|
|
||||||
|
|
||||||
push @{ $path }, $localname; # step down...
|
|
||||||
push @{ $list }, $current; # remember current
|
|
||||||
|
|
||||||
# resolve class of this element
|
|
||||||
my $class = $self->{ class_resolver }->get_class( $path )
|
|
||||||
or die "Cannot resolve class for "
|
|
||||||
. join('/', @{ $path }) . " via $self->{ class_resolver }";
|
|
||||||
|
|
||||||
# Check whether we have a primitive - we implement them as classes
|
|
||||||
# TODO replace with UNIVERSAL->isa()
|
|
||||||
# match is a bit faster if the string does not match, but WAY slower
|
|
||||||
# if $class matches...
|
|
||||||
# if (not $class=~m{^SOAP::WSDL::XSD::Typelib::Builtin}xms) {
|
|
||||||
|
|
||||||
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 $@;
|
|
||||||
}
|
|
||||||
# create object
|
|
||||||
# set current object
|
|
||||||
$current = $class->new({ %attrs });
|
|
||||||
|
|
||||||
# remember top level element
|
|
||||||
defined $self->{ data }
|
|
||||||
or ($self->{ data } = $current);
|
|
||||||
},
|
|
||||||
Char => sub {
|
|
||||||
$characters .= $_[1];
|
|
||||||
},
|
|
||||||
End => sub {
|
|
||||||
my $element = $_[1];
|
|
||||||
|
|
||||||
my ($prefix, $localname) = split m{:}xms , $element;
|
|
||||||
# for non-prefixed elements
|
|
||||||
if (not $localname) {
|
|
||||||
$localname = $element;
|
|
||||||
$prefix = q{};
|
|
||||||
}
|
|
||||||
|
|
||||||
# This one easily handles ignores for us, too...
|
|
||||||
return if not ref $list->[-1];
|
|
||||||
|
|
||||||
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
|
|
||||||
my $method = "add_$localname";
|
|
||||||
|
|
||||||
$list->[-1]->$method( $current );
|
|
||||||
|
|
||||||
# step up in path
|
|
||||||
pop @{ $path };
|
|
||||||
|
|
||||||
# step up in object hierarchy...
|
|
||||||
$current = pop @{ $list };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return $parser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_data {
|
sub parse_done {
|
||||||
my $self = shift;
|
$_[0]->{ parser }->parse_done();
|
||||||
return $self->{ data };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
=pod
|
=pod
|
||||||
@@ -174,15 +51,7 @@ See L<SOAP::WSDL::Parser> for details.
|
|||||||
|
|
||||||
=head1 Bugs and Limitations
|
=head1 Bugs and Limitations
|
||||||
|
|
||||||
=over
|
See SOAP::WSDL::Expat::MessageParser
|
||||||
|
|
||||||
=item * Ignores all namespaces
|
|
||||||
|
|
||||||
=item * Does not handle mixed content
|
|
||||||
|
|
||||||
=item * The SOAP header is ignored
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
=head1 AUTHOR
|
||||||
|
|
||||||
@@ -198,9 +67,9 @@ This module may be used under the same terms as perl itself.
|
|||||||
|
|
||||||
$ID: $
|
$ID: $
|
||||||
|
|
||||||
$LastChangedDate: $
|
$LastChangedDate: 2007-08-31 17:28:29 +0200 (Fr, 31 Aug 2007) $
|
||||||
$LastChangedRevision: $
|
$LastChangedRevision: 176 $
|
||||||
$LastChangedBy: $
|
$LastChangedBy: kutterma $
|
||||||
|
|
||||||
$HeadURL: $
|
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,213 @@
|
|||||||
|
#!/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-08-31 17:28:29 +0200 (Fr, 31 Aug 2007) $
|
||||||
|
$LastChangedRevision: 176 $
|
||||||
|
$LastChangedBy: kutterma $
|
||||||
|
|
||||||
|
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageSubParser.pm $
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
#!/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-08-31 17:28:29 +0200 (Fr, 31 Aug 2007) $
|
||||||
|
$LastChangedRevision: 176 $
|
||||||
|
$LastChangedBy: kutterma $
|
||||||
|
|
||||||
|
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/SubParser.pm $
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
package SOAP::WSDL::Expat::WSDLParser;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _initialize {
|
||||||
|
my ($self, $parser) = @_;
|
||||||
|
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->{ data } = $obj;
|
||||||
|
}
|
||||||
|
# set new element (step down)
|
||||||
|
$current = $obj;
|
||||||
|
}
|
||||||
|
elsif ($action->{ type } eq 'PARENT') {
|
||||||
|
$current->init( _fixup_attrs($parser, %attrs) );
|
||||||
|
}
|
||||||
|
elsif ($action->{ type } eq 'METHOD') {
|
||||||
|
my $method = $action->{ method } || $localname;
|
||||||
|
|
||||||
|
no strict qw(refs);
|
||||||
|
# call method with
|
||||||
|
# - default value ($action->{ value } if defined,
|
||||||
|
# dereferencing lists
|
||||||
|
# - the values of the elements Attributes hash
|
||||||
|
# TODO: add namespaces declared to attributes.
|
||||||
|
# Expat consumes them, so we have to re-add them here.
|
||||||
|
$current->$method( defined $action->{ value }
|
||||||
|
? ref $action->{ value }
|
||||||
|
? @{ $action->{ value } }
|
||||||
|
: ($action->{ value })
|
||||||
|
: _fixup_attrs($parser, %attrs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Char => sub { $characters .= $_[1] },
|
||||||
|
|
||||||
|
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 };
|
||||||
|
}
|
||||||
|
elsif ($action->{ type } eq 'CONTENT' ) {
|
||||||
|
my $method = $action->{ method };
|
||||||
|
|
||||||
|
# normalize whitespace
|
||||||
|
$characters =~s{ ^ \s+ (.+) \s+ $ }{$1}xms;
|
||||||
|
$characters =~s{ \s+ }{ }xmsg;
|
||||||
|
|
||||||
|
no strict qw(refs);
|
||||||
|
$current->$method( $characters );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return $parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
# make attrs SAX style
|
||||||
|
sub _fixup_attrs {
|
||||||
|
my ($parser, %attrs_of) = @_;
|
||||||
|
|
||||||
|
my @attrs_from = map { $_ =
|
||||||
|
{
|
||||||
|
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
|
||||||
|
# Other nodes should be ignored somewhere else
|
||||||
|
($_ eq '#default')
|
||||||
|
? ()
|
||||||
|
:
|
||||||
|
{
|
||||||
|
Name => "xmlns:$_",
|
||||||
|
Value => $parser->expand_ns_prefix( $_ ),
|
||||||
|
LocalName => $_
|
||||||
|
}
|
||||||
|
} $parser->new_ns_prefixes();
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
package SOAP::WSDL::Factory::Serializer;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
my %SERIALIZER = (
|
||||||
|
'1.1' => 'SOAP::WSDL::Serializer::SOAP11',
|
||||||
|
);
|
||||||
|
|
||||||
|
# class method
|
||||||
|
sub register {
|
||||||
|
my ($class, $ref_type, $package) = @_;
|
||||||
|
$SERIALIZER{ $ref_type } = $package;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_serializer {
|
||||||
|
my ($self, $args_of_ref) = @_;
|
||||||
|
eval "require $SERIALIZER{ $args_of_ref->{ soap_version } }" or die $@;
|
||||||
|
return $SERIALIZER{ $args_of_ref->{ soap_version } }->new();
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
SOAP::WSDL::Factory::Serializer - factory for retrieving serializer objects
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
# from SOAP::WSDL::Client:
|
||||||
|
$serializer = SOAP::WSDL::Factory::Serializer->get_serializer({
|
||||||
|
soap_version => $soap_version,
|
||||||
|
});
|
||||||
|
|
||||||
|
# in serializer class:
|
||||||
|
package MyWickedSerializer;
|
||||||
|
use SOAP::WSDL::Factory::Serializer;
|
||||||
|
|
||||||
|
# u don't know the SOAP 1.2 recommendation? poor boy...
|
||||||
|
SOAP::WSDL::Factory::Serializer->register( '1.2' , __PACKAGE__ );
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
=head1 METHODS
|
||||||
|
|
||||||
|
=head2 register
|
||||||
|
|
||||||
|
SOAP::WSDL::Serializer->register('1.1', 'MyWickedSerializer');
|
||||||
|
|
||||||
|
Globally registers a class for use as serializer class.
|
||||||
|
|
||||||
|
=head2 get_serializer
|
||||||
|
|
||||||
|
Returns an object of the serializer class for this endpoint.
|
||||||
|
|
||||||
|
=head1 WRITING YOUR OWN SERIALIZER CLASS
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
Serializer modules must be named equal to the serializer
|
||||||
|
class they contain. There can only be one serializer class per
|
||||||
|
serializer module.
|
||||||
|
|
||||||
|
Serializer class must implement the following methods:
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item * new
|
||||||
|
|
||||||
|
Constructor.
|
||||||
|
|
||||||
|
=item * serialize
|
||||||
|
|
||||||
|
Serializes data to XML. The following named parameters are passed to
|
||||||
|
the serialize method in a anonymous hash ref:
|
||||||
|
|
||||||
|
{
|
||||||
|
method => $operation_name,
|
||||||
|
header => $header_data,
|
||||||
|
body => $body_data,
|
||||||
|
}
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
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: 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
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
package SOAP::WSDL::Factory::Transport;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
# class data
|
||||||
|
my %registered_transport_of = ();
|
||||||
|
|
||||||
|
# Local constants
|
||||||
|
# Could be made readonly, but that's just for the paranoid...
|
||||||
|
my %SOAP_LITE_TRANSPORT_OF = (
|
||||||
|
ftp => 'SOAP::Transport::FTP',
|
||||||
|
http => 'SOAP::Transport::HTTP',
|
||||||
|
https => 'SOAP::Transport::HTTPS',
|
||||||
|
mailto => 'SOAP::Transport::MAILTO',
|
||||||
|
'local' => 'SOAP::Transport::LOCAL',
|
||||||
|
jabber => 'SOAP::Transport::JABBER',
|
||||||
|
mq => 'SOAP::Transport::MQ',
|
||||||
|
);
|
||||||
|
|
||||||
|
my %SOAP_WSDL_TRANSPORT_OF = (
|
||||||
|
http => 'SOAP::WSDL::Transport::HTTP',
|
||||||
|
https => 'SOAP::WSDL::Transport::HTTP',
|
||||||
|
);
|
||||||
|
|
||||||
|
# class methods only
|
||||||
|
sub register {
|
||||||
|
my ($class, $scheme, $package) = @_;
|
||||||
|
$registered_transport_of{ $scheme } = $package;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
# 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
|
||||||
|
# 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 $@;
|
||||||
|
return $registered_transport_of{ $scheme }->new( %attrs );
|
||||||
|
}
|
||||||
|
|
||||||
|
# try SOAP::Lite's Transport module - just skip if not require'able
|
||||||
|
SOAP_Lite: {
|
||||||
|
if (exists $SOAP_LITE_TRANSPORT_OF{ $scheme }) {
|
||||||
|
eval "require $SOAP_LITE_TRANSPORT_OF{ $scheme }"
|
||||||
|
or last SOAP_Lite;
|
||||||
|
my $protocol_class = $SOAP_LITE_TRANSPORT_OF{ $scheme } . '::Client';
|
||||||
|
return $protocol_class->new( %attrs );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exists $SOAP_WSDL_TRANSPORT_OF{ $scheme }) {
|
||||||
|
eval "require $SOAP_WSDL_TRANSPORT_OF{ $scheme }" or die $@;
|
||||||
|
return $SOAP_WSDL_TRANSPORT_OF{ $scheme }->new( %attrs );
|
||||||
|
}
|
||||||
|
|
||||||
|
die "no transport class found for scheme <$scheme>";
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
SOAP::WSDL::Factory::Transport - factory for retrieving transport objects
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
# from SOAP::WSDL::Client:
|
||||||
|
$transport = SOAP::WSDL::Factory::Transport->get_transport( $url, @opt );
|
||||||
|
|
||||||
|
# in transport class:
|
||||||
|
package MyWickedTransport;
|
||||||
|
use SOAP::WSDL::Factory::Transport;
|
||||||
|
|
||||||
|
# u don't know the httpr protocol? poor boy...
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
=head1 METHODS
|
||||||
|
|
||||||
|
=head2 register
|
||||||
|
|
||||||
|
SOAP::WSDL::Transport->register('https', 'MyWickedTransport');
|
||||||
|
|
||||||
|
Globally registers a class for use as transport class.
|
||||||
|
|
||||||
|
=head2 proxy
|
||||||
|
|
||||||
|
$trans->proxy('http://soap-wsdl.sourceforge.net');
|
||||||
|
|
||||||
|
Sets the proxy (endpoint).
|
||||||
|
|
||||||
|
Returns the transport for this protocol.
|
||||||
|
|
||||||
|
=head2 set_transport
|
||||||
|
|
||||||
|
Sets the current transport object.
|
||||||
|
|
||||||
|
=head2 get_transport
|
||||||
|
|
||||||
|
Gets the current transport object.
|
||||||
|
|
||||||
|
=head1 WRITING YOUR OWN TRANSPORT CLASS
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
Multiple protocols ore multiple classes are registered by multiple calls to
|
||||||
|
register().
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item * new
|
||||||
|
|
||||||
|
=item * send_receive
|
||||||
|
|
||||||
|
Dispatches a request and returns the content of the response.
|
||||||
|
|
||||||
|
=item * code
|
||||||
|
|
||||||
|
Returns the status code of the last send_receive call (if any).
|
||||||
|
|
||||||
|
=item * message
|
||||||
|
|
||||||
|
Returns the status message of the last send_receive call (if any).
|
||||||
|
|
||||||
|
=item * status
|
||||||
|
|
||||||
|
Returns the status of the last send_receive call (if any).
|
||||||
|
|
||||||
|
=item * is_success
|
||||||
|
|
||||||
|
Returns true after a send_receive was successful, false if it was not.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
SOAP::Lite requires transport modules to pack client and server
|
||||||
|
classes in one file, and to follow this naming scheme:
|
||||||
|
|
||||||
|
Module name:
|
||||||
|
"SOAP::Transport::" . uc($scheme)
|
||||||
|
|
||||||
|
Client class (additional package in module):
|
||||||
|
"SOAP::Transport::" . uc($scheme) . "::Client"
|
||||||
|
|
||||||
|
Server class (additional package in module):
|
||||||
|
"SOAP::Transport::" . uc($scheme) . "::Client"
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
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: 176 $
|
||||||
|
$LastChangedBy: kutterma $
|
||||||
|
$Id: Transport.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/Transport.pm $
|
||||||
|
|
||||||
|
=cut
|
||||||
@@ -35,9 +35,6 @@ the service's interface structure.
|
|||||||
The results of all calls to your service object's methods (except new)
|
The results of all calls to your service object's methods (except new)
|
||||||
are objects based on SOAP::WSDL's XML schema implementation.
|
are objects based on SOAP::WSDL's XML schema implementation.
|
||||||
|
|
||||||
These objects are false in boolean context, and serialize to XML when
|
|
||||||
printed.
|
|
||||||
|
|
||||||
To access the object's properties use get_NAME / set_NAME getter/setter
|
To access the object's properties use get_NAME / set_NAME getter/setter
|
||||||
methods whith NAME corresponding to the XML tag name.
|
methods whith NAME corresponding to the XML tag name.
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ some internet protocol, typically via HTTP(S).
|
|||||||
|
|
||||||
=head2 SOAP
|
=head2 SOAP
|
||||||
|
|
||||||
SOAP (the Simple Object Access Protocol) is a specification for
|
SOAP is an acronym for Simple Object Access Protocol.
|
||||||
defining RPC interfaces, including (but not neccessarily limited to)
|
SOAP is a W3C recommendation. The latest version of the SOAP
|
||||||
web services.
|
specification may be found at L<http://www.w3.org/TR/soap/>.
|
||||||
|
|
||||||
|
SOAP defines a protocoll for message exchange between applications.
|
||||||
|
The most popular usage is to use SOAP for remote procedure calls (RPC).
|
||||||
|
|
||||||
While one of the constituting aspects of a web service is its
|
While one of the constituting aspects of a web service is its
|
||||||
reachability via some internet protocol, you might as well define
|
reachability via some internet protocol, you might as well define
|
||||||
@@ -26,15 +29,52 @@ carry your pet.
|
|||||||
|
|
||||||
=head2 WSDL
|
=head2 WSDL
|
||||||
|
|
||||||
WSDL (Web Service Definition Language) is a XML-based markup language
|
WSDL is an acronym for Web Services Description Language.
|
||||||
for defining web service interfaces.
|
WSDL is a W3C recommendation. The latest version of the WSDL specification
|
||||||
|
may be found at L<http://www.w3.org/TR/wsdl20/>.
|
||||||
|
|
||||||
|
WSDL defines a XML-based language for describing web service interfaces,
|
||||||
|
including SOAP interfaces.
|
||||||
|
|
||||||
=head2 WS-I
|
=head2 WS-I
|
||||||
|
|
||||||
WS-I (Web Service Interoperability) is a industry consortium dedicated
|
WS-I (Web Services Interoperability Organization) is an open industry
|
||||||
to finding interoperability rules for web services.
|
organisation chartered to promote Web service interoperability across
|
||||||
|
platforms, operating systems, and programming languages.
|
||||||
|
|
||||||
SOAP::WSDL aims to be a WS-I compliant SOAP client.
|
WS-I publishes profiles, which provide implementation guidelines for
|
||||||
|
how related Web services specifications should be used together for
|
||||||
|
best interoperability. To date, WS-I has finalized the Basic Profile,
|
||||||
|
Attachments Profile and Simple SOAP Binding Profile.
|
||||||
|
|
||||||
|
SOAP::WSDL aims at complying to the Basic Profile (but does not
|
||||||
|
implement full support yet).
|
||||||
|
|
||||||
|
=head2 SOAP message styles
|
||||||
|
|
||||||
|
=head3 rpc
|
||||||
|
|
||||||
|
Meant for transporting a RPC message. All contents of the SOAP body are
|
||||||
|
put into a top-level node named equal to the SOAP operation.
|
||||||
|
|
||||||
|
WS-I Basic Profile allows the use of rpc message style.
|
||||||
|
|
||||||
|
SOAP::WSDL does not support rpc message style yet.
|
||||||
|
|
||||||
|
SOAP::Lite supports rpc message style only.
|
||||||
|
|
||||||
|
=head3 document
|
||||||
|
|
||||||
|
Meant for transporting arbitrary content. No additional nodes are inserted
|
||||||
|
between the SOAP body and the actual content.
|
||||||
|
|
||||||
|
WS-I Basic Profile allows the use of document message style.
|
||||||
|
|
||||||
|
=head2 SOAP encoding styles
|
||||||
|
|
||||||
|
=head3 encoded
|
||||||
|
|
||||||
|
=head3 literal
|
||||||
|
|
||||||
=head1 LICENSE
|
=head1 LICENSE
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+59
-16
@@ -6,8 +6,8 @@ SOAP::WSDL::Parser - How SOAP::WSDL parses XML messages
|
|||||||
|
|
||||||
=head1 Which XML message does SOAP::WSDL parse ?
|
=head1 Which XML message does SOAP::WSDL parse ?
|
||||||
|
|
||||||
Naturally, there are two kinds of XMLdocuments (or messages) SOAP::WSDL
|
Naturally, there are two kinds of XML documents (or messages)
|
||||||
has to parse:
|
SOAP::WSDL has to parse:
|
||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
@@ -19,13 +19,55 @@ has to parse:
|
|||||||
|
|
||||||
=head1 Parser implementations
|
=head1 Parser implementations
|
||||||
|
|
||||||
There are different parser implementations available for SOAP messages -
|
There are different parser implementations available for SOAP messages
|
||||||
currently there's only one for WSDL definitions.
|
and WSDL definitions.
|
||||||
|
|
||||||
|
Historically, SOAP::WSDL used SAX for parsing XML. The SAX handlers
|
||||||
|
were implemented as L<XML::LibXML|XML::LibXML> handlers, which
|
||||||
|
also worked with L<XML::SAX::ParserFactory|XML::SAX::ParserFactory>.
|
||||||
|
|
||||||
|
The use of SAX and L<XML::LibXML|XML::LibXML> in SOAP::WSDL is
|
||||||
|
deprecated for the following reasons:
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item * Speed
|
||||||
|
|
||||||
|
L<XML::Parser::Expat|XML::Parser::Expat> is faster than
|
||||||
|
L<XML::LibXML|XML::LibXML> - at least when optimized for speed.
|
||||||
|
|
||||||
|
=item * Availability
|
||||||
|
|
||||||
|
L<XML::Parser|XML::Parser> is more popular than
|
||||||
|
L<XML::LibXML|XML::LibXML>.
|
||||||
|
|
||||||
|
=item * Stability
|
||||||
|
|
||||||
|
XML::LibXML is based on the libxml2 library. Several versions of
|
||||||
|
libxml2 are known to have specific bugs. As a workaround, there are
|
||||||
|
often several versions of libxml2 installed on one system. This may
|
||||||
|
lead to problems on operating systems which cannot load more than
|
||||||
|
one version of a shared library simultaneously.
|
||||||
|
|
||||||
|
=item * SOAP::Lite uses XML::Parser
|
||||||
|
|
||||||
|
L<SOAP::Lite|SOAP::Lite> uses L<XML::Parser|XML::Parser> if available.
|
||||||
|
SOAP::WSDL should not require users to install both L<XML::Parser|XML::Parser>
|
||||||
|
and L<XML::LibXML|XML::LibXML>.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
=head2 WSDL definitions parser
|
=head2 WSDL definitions parser
|
||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
|
=item * SOAP::WSDL::Expat::WSDLParser
|
||||||
|
|
||||||
|
A parser for WSDL definitions based on L<XML::Parser::Expat|XML::Parser::Expat>.
|
||||||
|
|
||||||
|
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
|
||||||
|
my $wsdl = $parser->parse_file( $filename );
|
||||||
|
|
||||||
=item * SOAP::WSDL::SAX::WSDLHandler
|
=item * SOAP::WSDL::SAX::WSDLHandler
|
||||||
|
|
||||||
This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL
|
This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL
|
||||||
@@ -132,6 +174,19 @@ L<SOAP::WSDL::XSD::Typelib::ComplexType> and L<SOAP::WSDL::XSD::Typelib::SimpleT
|
|||||||
|
|
||||||
=over
|
=over
|
||||||
|
|
||||||
|
=item * SOAP::WSDL::Expat::MessageParser
|
||||||
|
|
||||||
|
A L<XML::Parser::Expat|XML::Parser::Expat> based parser. This is the fastest
|
||||||
|
parser for most SOAP messages and the default for SOAP::WSDL::Client.
|
||||||
|
|
||||||
|
=item * SOAP::WSDL::Expat::MessageStreamParser
|
||||||
|
|
||||||
|
A XML::Parser::ExpatNB based parser. Useful for parsing huge HTTP responses,
|
||||||
|
as you don't need to keep everything in memory.
|
||||||
|
|
||||||
|
See L<SOAP::WSDL::Expat::MessageStreamParser|SOAP::WSDL::Expat::MessageStreamParser>
|
||||||
|
for details.
|
||||||
|
|
||||||
=item * SOAP::WSDL::SAX::MessageHandler
|
=item * SOAP::WSDL::SAX::MessageHandler
|
||||||
|
|
||||||
This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL
|
This is a SAX handler for parsing WSDL files into object trees SOAP::WSDL
|
||||||
@@ -144,18 +199,6 @@ Can be used for parsing both streams (chunks) and documents.
|
|||||||
|
|
||||||
See L<SOAP::WSDL::SAX::MessageHandler> for details.
|
See L<SOAP::WSDL::SAX::MessageHandler> for details.
|
||||||
|
|
||||||
=item * SOAP::WSDL::Expat::MessageParser
|
|
||||||
|
|
||||||
A L<XML::Parser::Expat|XML::Parser::Expat> based parser. This is the fastest
|
|
||||||
parser for most SOAP messages and the default for SOAP::WSDL::Client.
|
|
||||||
|
|
||||||
=item * SOAP::WSDL::Expat::MessageStreamParser
|
|
||||||
|
|
||||||
A XML::Parser::ExpatNB based parser. Useful for parsing huge HTTP responses,
|
|
||||||
as you don't need to keep everything in memory.
|
|
||||||
|
|
||||||
See L<SOAP::WSDL::Expat::MessageStreamParser|SOAP::WSDL::Expat::MessageStreamParser> for details.
|
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head3 Performance
|
=head3 Performance
|
||||||
|
|||||||
@@ -273,9 +273,9 @@ This module may be used under the same terms as perl itself.
|
|||||||
|
|
||||||
$ID: $
|
$ID: $
|
||||||
|
|
||||||
$LastChangedDate: $
|
$LastChangedDate: 2007-08-31 17:28:29 +0200 (Fr, 31 Aug 2007) $
|
||||||
$LastChangedRevision: $
|
$LastChangedRevision: 176 $
|
||||||
$LastChangedBy: $
|
$LastChangedBy: kutterma $
|
||||||
|
|
||||||
$HeadURL: $
|
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/SAX/MessageHandler.pm $
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
package SOAP::WSDL::Envelope;
|
package SOAP::WSDL::Serializer::SOAP11;
|
||||||
use strict;
|
use strict;
|
||||||
use base qw/SOAP::WSDL::Base/;
|
use warnings;
|
||||||
|
use Class::Std::Storable;
|
||||||
|
# use base qw/SOAP::WSDL::Base/;
|
||||||
|
|
||||||
my $SOAP_NS = 'http://schemas.xmlsoap.org/soap/envelope/';
|
my $SOAP_NS = 'http://schemas.xmlsoap.org/soap/envelope/';
|
||||||
my $XML_INSTANCE_NS = 'http://www.w3.org/2001/XMLSchema-instance';
|
my $XML_INSTANCE_NS = 'http://www.w3.org/2001/XMLSchema-instance';
|
||||||
|
|
||||||
sub serialize {
|
sub serialize {
|
||||||
my ($self, $name, $data, $opt) = @_;
|
my ($self, $args_of_ref) = @_;
|
||||||
|
|
||||||
|
my $opt = $args_of_ref->{ options };
|
||||||
|
|
||||||
if (not $opt->{ namespace }->{ $SOAP_NS })
|
if (not $opt->{ namespace }->{ $SOAP_NS })
|
||||||
{
|
{
|
||||||
@@ -32,8 +36,9 @@ sub serialize {
|
|||||||
|
|
||||||
# TODO insert encoding
|
# TODO insert encoding
|
||||||
$xml.='>';
|
$xml.='>';
|
||||||
$xml .= $self->serialize_header($name, $data, $opt);
|
$xml .= $self->serialize_header($args_of_ref->{ method }, $args_of_ref->{ header }, $opt);
|
||||||
$xml .= $self->serialize_body($name, $data, $opt);
|
$xml .= "\n" if ($opt->{ readable });
|
||||||
|
$xml .= $self->serialize_body($args_of_ref->{ method }, $args_of_ref->{ body }, $opt);
|
||||||
$xml .= "\n" if ($opt->{ readable });
|
$xml .= "\n" if ($opt->{ readable });
|
||||||
$xml .= '</' . $soap_prefix .':Envelope>';
|
$xml .= '</' . $soap_prefix .':Envelope>';
|
||||||
$xml .= "\n" if ($opt->{ readable });
|
$xml .= "\n" if ($opt->{ readable });
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
package SOAP::WSDL::Transport::HTTP;
|
||||||
|
use strict;
|
||||||
|
use base qw(LWP::UserAgent);
|
||||||
|
|
||||||
|
# create methods normally inherited from SOAP::Client
|
||||||
|
SUBFACTORY: {
|
||||||
|
no strict qw(refs);
|
||||||
|
foreach my $method ( qw(code message status is_success) ) {
|
||||||
|
*{ $method } = sub {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->{ $method } if not @_;
|
||||||
|
return $self->{ $method } = shift;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub send_receive {
|
||||||
|
my ($self, %parameters) = @_;
|
||||||
|
my ($envelope, $soap_action, $endpoint, $encoding, $content_type) =
|
||||||
|
@parameters{qw(envelope action endpoint encoding content_type)};
|
||||||
|
|
||||||
|
$encoding = defined($encoding)
|
||||||
|
? 'utf8'
|
||||||
|
: lc($encoding);
|
||||||
|
|
||||||
|
# TODO check whether we need this with current LWP::UserAgent - we're
|
||||||
|
# not here to fix LWP::UserAgent bugs...
|
||||||
|
#
|
||||||
|
# what's this all about?
|
||||||
|
# unfortunately combination of LWP and Perl 5.6.1 and later has bug
|
||||||
|
# in sending multibyte characters. LWP uses length() to calculate
|
||||||
|
# content-length header and starting 5.6.1 length() calculates chars
|
||||||
|
# instead of bytes. 'use bytes' in THIS file doesn't work, because
|
||||||
|
# it's lexically scoped. Unfortunately, content-length we calculate
|
||||||
|
# here doesn't work either, because LWP overwrites it with
|
||||||
|
# content-length it calculates (which is wrong) AND uses length()
|
||||||
|
# during syswrite/sysread, so we are in a bad shape anyway.
|
||||||
|
#
|
||||||
|
# what to do? we calculate proper content-length (using
|
||||||
|
# bytelength() function from SOAP::Utils) and then drop utf8 mark
|
||||||
|
# from string (doing pack with 'C0A*' modifier) if length and
|
||||||
|
# bytelength are not the same
|
||||||
|
|
||||||
|
# use bytes is lexically scoped
|
||||||
|
my $bytelength = do { use bytes; length $envelope };
|
||||||
|
$envelope = pack('C0A*', $envelope)
|
||||||
|
if length($envelope) != $bytelength;
|
||||||
|
|
||||||
|
# END TODO
|
||||||
|
|
||||||
|
my $request = HTTP::Request->new( 'POST',
|
||||||
|
$endpoint,
|
||||||
|
[ 'Content-Type', "$content_type; charset=$encoding",
|
||||||
|
'Content-Length', $bytelength,
|
||||||
|
'SOAPAction', $soap_action,
|
||||||
|
],
|
||||||
|
$envelope );
|
||||||
|
|
||||||
|
use Data::Dumper;
|
||||||
|
warn Dumper $request;
|
||||||
|
|
||||||
|
my $response = $self->request( $request );
|
||||||
|
|
||||||
|
warn Dumper $response;
|
||||||
|
|
||||||
|
|
||||||
|
$self->code( $response->code);
|
||||||
|
$self->message( $response->message);
|
||||||
|
$self->is_success($response->is_success);
|
||||||
|
$self->status($response->status_line);
|
||||||
|
|
||||||
|
return $response->content();
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
=pod
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
SOAP::WSDL::Transport::HTTP - Fallback http(s) transport class
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Provides a thin transport class used by SOAP::WSDL::Transport when
|
||||||
|
SOAP::Lite is not available.
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
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: 176 $
|
||||||
|
$LastChangedBy: kutterma $
|
||||||
|
$Id: HTTP.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/Transport/HTTP.pm $
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ sub to_class {
|
|||||||
my $template = <<'EOT';
|
my $template = <<'EOT';
|
||||||
package [% type_prefix %][% self.get_name %];
|
package [% type_prefix %][% self.get_name %];
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
use base qw(
|
use base qw(
|
||||||
SOAP::WSDL::XSD::Typelib::ComplexType
|
SOAP::WSDL::XSD::Typelib::ComplexType
|
||||||
@@ -192,17 +192,17 @@ my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
|
|||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
__PACKAGE__->_factory(
|
__PACKAGE__->_factory(
|
||||||
[ qw([% FOREACH element=self.get_element -%]
|
[ qw([% FOREACH element=self.get_element -%]
|
||||||
[% element.get_name %]
|
[% element.get_name %]
|
||||||
[% END %]) ],
|
[% END %]) ],
|
||||||
{
|
{
|
||||||
[% FOREACH element=self.get_element %][% element.get_name %] => \%[% element.get_name %]_of,
|
[% FOREACH element=self.get_element %][% element.get_name %] => \%[% element.get_name %]_of,
|
||||||
[% END %]
|
[% END %]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[%-
|
[%-
|
||||||
FOREACH element=self.get_element;
|
FOREACH element=self.get_element;
|
||||||
IF (element.get_type);
|
IF (element.get_type); # element type="..."
|
||||||
split_name = element.get_type.split(':');
|
split_name = element.get_type.split(':');
|
||||||
prefix = split_name.0;
|
prefix = split_name.0;
|
||||||
localname = split_name.1;
|
localname = split_name.1;
|
||||||
@@ -210,8 +210,13 @@ __PACKAGE__->_factory(
|
|||||||
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
|
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
|
||||||
[% ELSE -%]
|
[% ELSE -%]
|
||||||
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
||||||
[%- END;
|
[%- END;
|
||||||
ELSIF (simpleType = element.first_simpleType);
|
ELSIF (element.get_ref); # element ref="..."
|
||||||
|
split_name = element.get_ref.split(':');
|
||||||
|
prefix = split_name.0;
|
||||||
|
localname = split_name.1; %]
|
||||||
|
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
||||||
|
[% ELSIF (simpleType = element.first_simpleType);
|
||||||
base = simpleType.get_base();
|
base = simpleType.get_base();
|
||||||
%]
|
%]
|
||||||
# basic simple type handling: we treat atomic simple types
|
# basic simple type handling: we treat atomic simple types
|
||||||
@@ -237,18 +242,25 @@ sub get_xmlns { '[% self.get_targetNamespace %]' }
|
|||||||
1;
|
1;
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
[% MACRO pod BLOCK %]=pod[% END %]
|
||||||
|
[% MACRO cut BLOCK %]=cut[% END %]
|
||||||
|
[% MACRO head1 BLOCK %]=head1[% END %]
|
||||||
|
[% MACRO head2 BLOCK %]=head2[% END %]
|
||||||
|
|
||||||
|
[% pod %]
|
||||||
|
|
||||||
|
[% head1 %] NAME
|
||||||
|
|
||||||
|
[% type_prefix %][% self.get_name %]
|
||||||
|
|
||||||
=pod
|
[% head1 %] SYNOPSIS
|
||||||
|
|
||||||
=head1 NAME [% type_prefix %][% self.get_name %]
|
[% head1 %] DESCRIPTION
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
Type class for the XML type [% self.get_name %].
|
Type class for the XML type [% self.get_name %].
|
||||||
|
|
||||||
=head1 PROPERTIES
|
[% head1 %] PROPERTIES
|
||||||
|
|
||||||
The following properties may be accessed using get_PROPERTY / set_PROPERTY
|
The following properties may be accessed using get_PROPERTY / set_PROPERTY
|
||||||
methods:
|
methods:
|
||||||
@@ -257,7 +269,7 @@ methods:
|
|||||||
[% element.get_name -%]
|
[% element.get_name -%]
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
=head1 Object structure
|
[% head1 %] Object structure
|
||||||
|
|
||||||
[% FOREACH element=self.get_element;
|
[% FOREACH element=self.get_element;
|
||||||
IF (element.get_type);
|
IF (element.get_type);
|
||||||
@@ -269,7 +281,12 @@ methods:
|
|||||||
[% ELSE -%]
|
[% ELSE -%]
|
||||||
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
||||||
[%- END;
|
[%- END;
|
||||||
ELSIF (simpleType = element.first_simpleType);
|
ELSIF (element.get_ref); # element ref="..."
|
||||||
|
split_name = element.get_ref.split(':');
|
||||||
|
prefix = split_name.0;
|
||||||
|
localname = split_name.1; %]
|
||||||
|
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
||||||
|
[% ELSIF (simpleType = element.first_simpleType);
|
||||||
base = simpleType.get_base();
|
base = simpleType.get_base();
|
||||||
split_name = base.split(':');
|
split_name = base.split(':');
|
||||||
prefix = split_name.0;
|
prefix = split_name.0;
|
||||||
@@ -292,7 +309,7 @@ Structure as perl hash:
|
|||||||
|
|
||||||
[% structure %]
|
[% structure %]
|
||||||
|
|
||||||
=cut
|
[% cut %]
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
|
|||||||
@@ -90,8 +90,8 @@ sub serialize {
|
|||||||
elsif (my $ref_name = $ref_of{ $ident }) { # ref
|
elsif (my $ref_name = $ref_of{ $ident }) { # ref
|
||||||
my ($prefix, $localname) = split /:/ , $ref_name;
|
my ($prefix, $localname) = split /:/ , $ref_name;
|
||||||
my $ns = $ns_map{ $prefix };
|
my $ns = $ns_map{ $prefix };
|
||||||
$type = $typelib->find_type( $ns, $localname );
|
$type = $typelib->find_element( $ns, $localname );
|
||||||
die "no type for $prefix:$localname" if (not $type);
|
die "no element for ref $prefix:$localname" if (not $type);
|
||||||
return $type->serialize( $name, $value, $opt );
|
return $type->serialize( $name, $value, $opt );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +130,12 @@ sub explain {
|
|||||||
}
|
}
|
||||||
return $type->explain( $opt, $self->get_name() );
|
return $type->explain( $opt, $self->get_name() );
|
||||||
}
|
}
|
||||||
|
elsif (my $element_name = $self->get_ref() ) {
|
||||||
|
my $element = $opt->{ wsdl }->first_types()->find_element(
|
||||||
|
$opt->{ wsdl }->_expand( $element_name )
|
||||||
|
);
|
||||||
|
return $element->explain( $opt, $self->get_name() );
|
||||||
|
}
|
||||||
|
|
||||||
# return if it's not a derived type - we don't handle
|
# return if it's not a derived type - we don't handle
|
||||||
# other stuff yet.
|
# other stuff yet.
|
||||||
@@ -152,7 +158,7 @@ sub explain {
|
|||||||
delete $opt->{ anonymous };
|
delete $opt->{ anonymous };
|
||||||
return $text .= $type->explain( $opt, undef );
|
return $text .= $type->explain( $opt, undef );
|
||||||
}
|
}
|
||||||
return $text .= $type->explain( $opt, $self->get_name() );
|
return $text .= $type->explain( $opt, $name || $self->get_name() );
|
||||||
return 'ERROR: '. $@;
|
return 'ERROR: '. $@;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,8 +244,9 @@ sub to_class {
|
|||||||
my $template = <<'EOT';
|
my $template = <<'EOT';
|
||||||
package [% element_prefix %][% self.get_name %];
|
package [% element_prefix %][% self.get_name %];
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
|
||||||
[% IF (type = self.first_simpleType) %]
|
[% IF (type = self.first_simpleType) %]
|
||||||
# <element name="[% self.get_name %]"><simpleType> definition
|
# <element name="[% self.get_name %]"><simpleType> definition
|
||||||
use SOAP::WSDL::XSD::Typelib::SimpleType;
|
use SOAP::WSDL::XSD::Typelib::SimpleType;
|
||||||
@@ -249,6 +256,17 @@ use base qw(
|
|||||||
[% type.flavor_class %]
|
[% type.flavor_class %]
|
||||||
[% type.base_class($type_prefix) %]
|
[% type.base_class($type_prefix) %]
|
||||||
);
|
);
|
||||||
|
[% ELSIF (ref_name = self.get_ref);
|
||||||
|
split_name = ref_name.split(':');
|
||||||
|
prefix = split_name.0;
|
||||||
|
localname = split_name.1;
|
||||||
|
ref_class = element_prefix _ localname;
|
||||||
|
%]
|
||||||
|
# <element name="[% self.get_name %]" ref="[% ref_name %]"> definition
|
||||||
|
# use [% ref_class %];
|
||||||
|
use base qw(
|
||||||
|
[% ref_class %]
|
||||||
|
);
|
||||||
[% ELSIF (type = self.first_complexType) %]
|
[% ELSIF (type = self.first_complexType) %]
|
||||||
# atomic complexType
|
# atomic complexType
|
||||||
# <element name="[% self.get_name %]"><complexType> definition
|
# <element name="[% self.get_name %]"><complexType> definition
|
||||||
@@ -263,7 +281,7 @@ my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
|
|||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
__PACKAGE__->_factory(
|
__PACKAGE__->_factory(
|
||||||
[ qw([% FOREACH element = type.get_element %]
|
[ qw([% FOREACH element = type.get_element %]
|
||||||
[% element.get_name %]
|
[% element.get_name %]
|
||||||
[% END %]) ],
|
[% END %]) ],
|
||||||
{
|
{
|
||||||
@@ -276,10 +294,10 @@ __PACKAGE__->_factory(
|
|||||||
prefix = split_name.0;
|
prefix = split_name.0;
|
||||||
localname = split_name.1;
|
localname = split_name.1;
|
||||||
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' %]
|
IF nsmap.$prefix == 'http://www.w3.org/2001/XMLSchema' %]
|
||||||
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
|
[% element.get_name %] => 'SOAP::WSDL::XSD::Typelib::Builtin::[% localname %]',
|
||||||
[% ELSE %]
|
[% ELSE %]
|
||||||
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
[% element.get_name %] => '[% type_prefix %][% localname %]',
|
||||||
[% END %]
|
[% END %]
|
||||||
[% END %]
|
[% END %]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -304,10 +322,6 @@ use base qw(
|
|||||||
SOAP::WSDL::XSD::Typelib::Element
|
SOAP::WSDL::XSD::Typelib::Element
|
||||||
[% base_class %]
|
[% base_class %]
|
||||||
);
|
);
|
||||||
[% ELSIF (element = self.get_ref)
|
|
||||||
%]
|
|
||||||
# element ref"element" definition
|
|
||||||
# Sorry, we don't handle this yet...
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
sub get_xmlns { '[% self.get_targetNamespace %]' }
|
sub get_xmlns { '[% self.get_targetNamespace %]' }
|
||||||
@@ -322,18 +336,25 @@ __PACKAGE__->__set_ref('[% self.get_ref %]');
|
|||||||
|
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
|
||||||
|
[% MACRO pod BLOCK %]=pod[% END %]
|
||||||
|
[% MACRO cut BLOCK %]=cut[% END %]
|
||||||
|
[% MACRO head1 BLOCK %]=head1[% END %]
|
||||||
|
[% MACRO head2 BLOCK %]=head2[% END %]
|
||||||
|
|
||||||
|
[% pod %]
|
||||||
|
|
||||||
|
[% head1 %] NAME
|
||||||
|
|
||||||
=pod
|
[% element_prefix %][% self.get_name %]
|
||||||
|
|
||||||
=head1 NAME [% element_prefix %][% self.get_name %]
|
[% head1 %] SYNOPSIS
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
[% head1 %] DESCRIPTION
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
Type class for the XML element [% self.get_name %].
|
Type class for the XML element [% self.get_name %].
|
||||||
|
|
||||||
=head1 PROPERTIES
|
[% head1 %] PROPERTIES
|
||||||
|
|
||||||
The following properties may be accessed using get_PROPERTY / set_PROPERTY
|
The following properties may be accessed using get_PROPERTY / set_PROPERTY
|
||||||
methods:
|
methods:
|
||||||
@@ -344,7 +365,7 @@ methods:
|
|||||||
[% END;
|
[% END;
|
||||||
END %]
|
END %]
|
||||||
|
|
||||||
=head1 Object structure
|
[% head1 %] Object structure
|
||||||
|
|
||||||
[%- IF (type = self.first_complexType);
|
[%- IF (type = self.first_complexType);
|
||||||
FOREACH element = type.get_element;
|
FOREACH element = type.get_element;
|
||||||
@@ -368,8 +389,8 @@ Structure as perl hash:
|
|||||||
tree.
|
tree.
|
||||||
|
|
||||||
[% structure %]
|
[% structure %]
|
||||||
|
|
||||||
=cut
|
[% cut %]
|
||||||
|
|
||||||
EOT
|
EOT
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use base qw(SOAP::WSDL::Base);
|
|||||||
# child elements
|
# child elements
|
||||||
my %type_of :ATTR(:name<type> :default<[]>);
|
my %type_of :ATTR(:name<type> :default<[]>);
|
||||||
my %element_of :ATTR(:name<element> :default<[]>);
|
my %element_of :ATTR(:name<element> :default<[]>);
|
||||||
|
my %group_of :ATTR(:name<group> :default<[]>);
|
||||||
|
|
||||||
# attributes
|
# attributes
|
||||||
my %attributeFormDefault_of :ATTR(:name<attributeFormDefault> :default<()>);
|
my %attributeFormDefault_of :ATTR(:name<attributeFormDefault> :default<()>);
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ sub as_bool :BOOLIFY {
|
|||||||
return $value_of { ident $_[0] };
|
return $value_of { ident $_[0] };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _get_handlers {
|
||||||
|
my $parser = $_[1];
|
||||||
|
return {
|
||||||
|
Char => $parser->characters(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Class::Std::initialize(); # make :BOOLIFY overloading serializable
|
Class::Std::initialize(); # make :BOOLIFY overloading serializable
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package SOAP::WSDL::XSD::Typelib::Builtin::boolean;
|
package SOAP::WSDL::XSD::Typelib::Builtin::boolean;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use Class::Std::Storable;
|
||||||
|
|
||||||
my %pattern_of :ATTR(:name<pattern> :default<()>);
|
my %pattern_of :ATTR(:name<pattern> :default<()>);
|
||||||
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
|
my %whiteSpace_of :ATTR(:name<whiteSpace> :default<()>);
|
||||||
@@ -9,7 +10,7 @@ my %value_of :ATTR(:get<value> :init_attr<value> :default<()>);
|
|||||||
|
|
||||||
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
|
# Speed up. Class::Std::new is slow - and we don't need it's functionality...
|
||||||
BEGIN {
|
BEGIN {
|
||||||
use Class::Std::Storable;
|
# use Class::Std::Storable;
|
||||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType);
|
||||||
|
|
||||||
no warnings qw(redefine);
|
no warnings qw(redefine);
|
||||||
@@ -40,7 +41,7 @@ sub serialize {
|
|||||||
, $self->end_tag($opt);
|
, $self->end_tag($opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub as_num :NUMERIFY {
|
sub as_num :NUMERIFY :BOOLIFY {
|
||||||
return $_[0]->get_value();
|
return $_[0]->get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ BEGIN {
|
|||||||
|
|
||||||
sub set_value {
|
sub set_value {
|
||||||
# use set_value from base class if we have a XML-DateTime format
|
# use set_value from base class if we have a XML-DateTime format
|
||||||
#2037-12-31T00:00:00.0000000+01:00
|
#2037-12-31+01:00
|
||||||
if (
|
if (
|
||||||
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
|
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
|
||||||
(:? [\+\-] \d{2} \: \d{2} )?
|
(:? [\+\-] \d{2} \: \d{2} )?$
|
||||||
}xms
|
}xms
|
||||||
) {
|
) {
|
||||||
$_[0]->SUPER::set_value($_[1])
|
$_[0]->SUPER::set_value($_[1])
|
||||||
@@ -53,7 +53,9 @@ sub set_value {
|
|||||||
# We leave out the optional nanoseconds part, as it would always be empty.
|
# We leave out the optional nanoseconds part, as it would always be empty.
|
||||||
else {
|
else {
|
||||||
# strptime sets empty values to undef - and strftime doesn't like that...
|
# strptime sets empty values to undef - and strftime doesn't like that...
|
||||||
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
|
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
|
||||||
|
# use Data::Dumper;
|
||||||
|
# die Dumper \@time_from;
|
||||||
my $time_str = strftime( '%Y-%m-%d%z', @time_from );
|
my $time_str = strftime( '%Y-%m-%d%z', @time_from );
|
||||||
substr $time_str, -2, 0, ':';
|
substr $time_str, -2, 0, ':';
|
||||||
$_[0]->SUPER::set_value($time_str);
|
$_[0]->SUPER::set_value($time_str);
|
||||||
|
|||||||
@@ -37,26 +37,20 @@ BEGIN {
|
|||||||
sub set_value {
|
sub set_value {
|
||||||
# use set_value from base class if we have a XML-DateTime format
|
# use set_value from base class if we have a XML-DateTime format
|
||||||
#2037-12-31T00:00:00.0000000+01:00
|
#2037-12-31T00:00:00.0000000+01:00
|
||||||
if (
|
return $_[0]->SUPER::set_value($_[1]) if (
|
||||||
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
|
$_[1] =~ m{ ^\d{4} \- \d{2} \- \d{2}
|
||||||
T \d{2} \: \d{2} \: \d{2} (:? \. \d{1,7} )?
|
T \d{2} \: \d{2} \: \d{2} (:? \. \d{1,7} )?
|
||||||
[\+\-] \d{2} \: \d{2} $
|
[\+\-] \d{2} \: \d{2} $
|
||||||
}xms
|
}xms
|
||||||
) {
|
);
|
||||||
$_[0]->SUPER::set_value($_[1])
|
|
||||||
}
|
# strptime sets empty values to undef - and strftime doesn't like that...
|
||||||
# use a combination of strptime and strftime for converting the date
|
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
|
||||||
# Unfortunately, strftime outputs the time zone as [+-]0000, whereas XML
|
undef $time_from[-1];
|
||||||
# whants it as [+-]00:00
|
|
||||||
# We leave out the optional nanoseconds part, as it would always be empty.
|
my $time_str = strftime( '%Y-%m-%dT%H:%M:%S%z', @time_from );
|
||||||
else {
|
substr $time_str, -2, 0, ':';
|
||||||
# strptime sets empty values to undef - and strftime doesn't like that...
|
$_[0]->SUPER::set_value($time_str);
|
||||||
my @time_from = map { ! defined $_ ? 0 : $_ } strptime($_[1]);
|
|
||||||
my $time_str = strftime( '%Y-%m-%dT%H:%M:%S%z', @time_from );
|
|
||||||
substr $time_str, -2, 0, ':';
|
|
||||||
$_[0]->SUPER::set_value($time_str);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -22,26 +22,3 @@ BEGIN {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
1;
|
1;
|
||||||
|
|
||||||
__END__
|
|
||||||
|
|
||||||
=pod
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
SOAP::WSDL::XSD::Typelib::Builtin::unsignedLong - unsigned long integer objects
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
Subclass of nonNegativeInteger.
|
|
||||||
|
|
||||||
=head1 LICENSE
|
|
||||||
|
|
||||||
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>
|
|
||||||
|
|
||||||
=cut
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
package SOAP::WSDL::XSD::Typelib::ComplexType;
|
package SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
use strict;
|
use strict;
|
||||||
|
use warnings;
|
||||||
use Carp;
|
use Carp;
|
||||||
use SOAP::WSDL::XSD::Typelib::Builtin;
|
use SOAP::WSDL::XSD::Typelib::Builtin;
|
||||||
use Scalar::Util qw(blessed);
|
use Scalar::Util qw(blessed refaddr);
|
||||||
use Class::Std::Storable;
|
|
||||||
|
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
|
use Class::Std::Storable;
|
||||||
|
|
||||||
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType);
|
use base qw(SOAP::WSDL::XSD::Typelib::Builtin::anyType);
|
||||||
|
|
||||||
@@ -14,6 +14,32 @@ my %ELEMENTS_FROM;
|
|||||||
my %ATTRIBUTES_OF;
|
my %ATTRIBUTES_OF;
|
||||||
my %CLASSES_OF;
|
my %CLASSES_OF;
|
||||||
|
|
||||||
|
# STORABLE_ methods for supporting Class::Std::Storable.
|
||||||
|
# We could also handle them via AUTOMETHOD,
|
||||||
|
# but AUTOMETHOD should always croak...
|
||||||
|
sub STORABLE_freeze_pre {
|
||||||
|
}
|
||||||
|
|
||||||
|
sub STORABLE_freeze_post {
|
||||||
|
}
|
||||||
|
|
||||||
|
sub STORABLE_thaw_pre {
|
||||||
|
}
|
||||||
|
|
||||||
|
sub STORABLE_thaw_post {
|
||||||
|
}
|
||||||
|
|
||||||
|
# for error reporting. Eases working with data objects...
|
||||||
|
sub AUTOMETHOD {
|
||||||
|
my ($self, $ident, @args_from) = @_;
|
||||||
|
|
||||||
|
my $class = ref $self || $self;
|
||||||
|
confess "Can't locate object method \"$_\" via package \"$class\". \n"
|
||||||
|
. "Valid methods are: "
|
||||||
|
. join(', ', map { ("get_$_" , "set_$_") } keys %{ $ATTRIBUTES_OF{ $class } })
|
||||||
|
. "\n"
|
||||||
|
}
|
||||||
|
|
||||||
# we store per-class elements.
|
# we store per-class elements.
|
||||||
# call as __PACKAGE__->_factory
|
# call as __PACKAGE__->_factory
|
||||||
sub _factory {
|
sub _factory {
|
||||||
@@ -29,56 +55,50 @@ sub _factory {
|
|||||||
my $type = $CLASSES_OF{ $class }->{ $name }
|
my $type = $CLASSES_OF{ $class }->{ $name }
|
||||||
or die "No class given for $name";
|
or die "No class given for $name";
|
||||||
|
|
||||||
# require all types here - this is a slow check -
|
# require all types here
|
||||||
# TODO speedup
|
|
||||||
$type->isa('UNIVERSAL')
|
$type->isa('UNIVERSAL')
|
||||||
or eval "require $type"
|
or eval "require $type"
|
||||||
or croak $@;
|
or croak $@;
|
||||||
|
|
||||||
|
# check now, so we don't need to do it later...
|
||||||
my $is_list = $type->isa('SOAP::WSDL::XSD::Typelib::Builtin::list');
|
my $is_list = $type->isa('SOAP::WSDL::XSD::Typelib::Builtin::list');
|
||||||
|
|
||||||
*{ "$class\::set_$name" } = sub {
|
*{ "$class\::set_$name" } = sub {
|
||||||
my ($self, $value) = @_;
|
# my ($self, $value) = @_;
|
||||||
|
|
||||||
=pod
|
# The structure below looks rather weird, but is optimized for performance.
|
||||||
|
#
|
||||||
|
# We could use sub calls for sure, but these are much slower. And the logic
|
||||||
|
# is not that easy:
|
||||||
|
#
|
||||||
|
# we accept:
|
||||||
|
# a) objects
|
||||||
|
# b) scalars
|
||||||
|
# c) list refs
|
||||||
|
# d) hash refs
|
||||||
|
# e) mixed stuff of all of the above, so we have to set our element to
|
||||||
|
# a) value if it's an object
|
||||||
|
# b) New object of expected class with value for simple values
|
||||||
|
# c 1) New object with value for list values and list type
|
||||||
|
# c 2) List ref of new objects with value for list values and non-list type
|
||||||
|
# c + e 1) List ref of objects for list values (list of objects) and non-list type
|
||||||
|
# c + e 2) List ref of new objects for list values (list of hashes) and non-list type
|
||||||
|
# where the hash ref is passed to new as argument
|
||||||
|
# d) New object with values passed to new for HASH references
|
||||||
|
#
|
||||||
|
# We throw an error on
|
||||||
|
# a) list refs of list refs - don't know what to do with this (maybe use for lists of list types ?)
|
||||||
|
# b) wrong object types
|
||||||
|
# c) non-blessed non-ARRAY/HASH references - if you can define semantics
|
||||||
|
# for GLOB references, feel free to add them.
|
||||||
|
# d) we should also die for non-blessed non-ARRAY/HASH references in lists but don't do yet - oh my !
|
||||||
|
|
||||||
=for developers
|
my $is_ref = ref $_[1];
|
||||||
|
$attribute_ref->{ ident $_[0] } = ($is_ref)
|
||||||
The structure below looks rather weird, but is optimized for performance.
|
|
||||||
|
|
||||||
We could use sub calls for sure, but these are much slower. And the logic
|
|
||||||
is not that easy:
|
|
||||||
|
|
||||||
we accept:
|
|
||||||
a) objects
|
|
||||||
b) scalars
|
|
||||||
c) list refs
|
|
||||||
d) hash refs
|
|
||||||
e) mixed stuff of all of the above, so we have to set our element to
|
|
||||||
a) value if it's an object
|
|
||||||
b) New object of expected class with value for simple values
|
|
||||||
c 1) New object with value for list values and list type
|
|
||||||
c 2) List ref of new objects with value for list values and non-list type
|
|
||||||
c + e 1) List ref of objects for list values (list of objects) and non-list type
|
|
||||||
c + e 2) List ref of new objects for list values (list of hashes) and non-list type
|
|
||||||
where the hash ref is passed to new as argument
|
|
||||||
d) New object with values passed to new for HASH references
|
|
||||||
|
|
||||||
We throw an error on
|
|
||||||
a) list refs of list refs - don't know what to do with this (maybe use for lists of list types ?)
|
|
||||||
b) wrong object types
|
|
||||||
c) non-blessed non-ARRAY/HASH references - if you can define semantics
|
|
||||||
for GLOB references, feel free to add them.
|
|
||||||
d) we should also die for non-blessed non-ARRAY/HASH references in lists but don't do yet - oh my !
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
my $is_ref = ref $value;
|
|
||||||
$attribute_ref->{ ident $self } = ($is_ref)
|
|
||||||
? $is_ref eq 'ARRAY'
|
? $is_ref eq 'ARRAY'
|
||||||
? $is_list
|
? $is_list # remembered from outside closure
|
||||||
? $type->new({ value => $value })
|
? $type->new({ value => $_[1] }) # list element - can take list ref as value
|
||||||
: [ map {
|
: [ map {
|
||||||
ref $_
|
ref $_
|
||||||
? ref $_ eq 'HASH'
|
? ref $_ eq 'HASH'
|
||||||
? $type->new($_)
|
? $type->new($_)
|
||||||
@@ -86,98 +106,110 @@ is not that easy:
|
|||||||
? $_
|
? $_
|
||||||
: croak "cannot use " . ref($_) . " reference as value for $name - $type required"
|
: croak "cannot use " . ref($_) . " reference as value for $name - $type required"
|
||||||
: $type->new({ value => $_ })
|
: $type->new({ value => $_ })
|
||||||
} @{ $value }
|
} @{ $_[1] }
|
||||||
]
|
]
|
||||||
: $is_ref eq 'HASH'
|
: $is_ref eq 'HASH'
|
||||||
? $type->new( $value )
|
? $type->new( $_[1] )
|
||||||
: $is_ref eq $type
|
: $is_ref eq $type
|
||||||
? $value
|
? $_[1]
|
||||||
: die 'Cannot use non-ARRAY/HASH as data'
|
: die croak "cannot use $is_ref reference as value for $name - $type required"
|
||||||
: $type->new({ value => $value });
|
: $type->new({ value => $_[1] });
|
||||||
};
|
};
|
||||||
|
|
||||||
*{ "$class\::add_$name" } = sub {
|
*{ "$class\::add_$name" } = sub {
|
||||||
my ($self, $value) = @_;
|
my $ident = ident $_[0];
|
||||||
my $ident = ident $self;
|
warn "attempting to add empty value to " . ref $_[0]
|
||||||
if (not defined $value) {
|
if not defined $_[1];
|
||||||
warn "attempting to add empty value to " . ref $self;
|
|
||||||
}
|
# first call
|
||||||
|
return $attribute_ref->{ $ident } = $_[1]
|
||||||
return $attribute_ref->{ $ident } = $value
|
|
||||||
if not defined $attribute_ref->{ $ident };
|
if not defined $attribute_ref->{ $ident };
|
||||||
|
|
||||||
# listify previous value if it's no list
|
# second call: listify previous value if it's no list
|
||||||
$attribute_ref->{ $ident } = [ $attribute_ref->{ $ident } ]
|
$attribute_ref->{ $ident } = [ $attribute_ref->{ $ident } ]
|
||||||
if not ref $attribute_ref->{ $ident } eq 'ARRAY';
|
if not ref $attribute_ref->{ $ident } eq 'ARRAY';
|
||||||
|
|
||||||
# add to list
|
# second and following: add to list
|
||||||
return push @{ $attribute_ref->{ $ident } }, $value;
|
return push @{ $attribute_ref->{ $ident } }, $_[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
*{ "$class\::START" } = sub {
|
*{ "$class\::$name" } = *{ "$class\::add_$name" };
|
||||||
my ($self, $ident, $args_of) = @_;
|
|
||||||
|
|
||||||
# iterate over keys of arguments
|
|
||||||
# and call set appropriate field in clase
|
|
||||||
map { ($ATTRIBUTES_OF{ $class }->{ $_ })
|
|
||||||
? do {
|
|
||||||
my $method = "set_$_";
|
|
||||||
$self->$method( $args_of->{ $_ } );
|
|
||||||
}
|
|
||||||
: $_ =~ m{ \A # beginning of string
|
|
||||||
xmlns # xmlns
|
|
||||||
}xms
|
|
||||||
? do {}
|
|
||||||
: do { use Data::Dumper;
|
|
||||||
croak "unknown field $_ in $class. Valid fields are "
|
|
||||||
. join(', ', @{ $ELEMENTS_FROM{ $class } }) . "\n"
|
|
||||||
. Dumper @_ };
|
|
||||||
# TODO maybe only warn for unknown fields ?
|
|
||||||
|
|
||||||
} keys %$args_of;
|
|
||||||
};
|
|
||||||
|
|
||||||
# this serialize method works fine for <all> and <sequence>
|
|
||||||
# complextypes, as well as for <restriction><all> or
|
|
||||||
# <restriction><sequence>.
|
|
||||||
# But what about choice, group, extension ?
|
|
||||||
#
|
|
||||||
}
|
}
|
||||||
*{ "$class\::_serialize" } = sub {
|
|
||||||
my $ident = ident $_[0];
|
|
||||||
# my $class = ref $_[0];
|
|
||||||
|
|
||||||
# return concatenated return value of serialize call of all
|
*{ "$class\::new" } = sub {
|
||||||
# elements retrieved from get_elements expanding list refs.
|
my $self = bless \my ($o), $_[0];
|
||||||
# get_elements is inlined for performance.
|
$self->BUILD( ident $self, $_[1] ) if exists &BUILD;
|
||||||
return join q{} , map {
|
$self->_init( ident $self, $_[1] );
|
||||||
my $element = $ATTRIBUTES_OF{ $class }->{ $_ }->{ $ident };
|
$self->START( ident $self, $_[1] ) if exists &START;
|
||||||
|
return $self;
|
||||||
if (defined $element) {
|
};
|
||||||
$element = [ $element ]
|
|
||||||
if not ref $element eq 'ARRAY';
|
*{ "$class\::_init" } = sub {
|
||||||
my $name = $_;
|
# We're working on @_ for speed.
|
||||||
|
# Normally, the first line would look like this:
|
||||||
|
# my ($self, $ident, $args_of) = @_;
|
||||||
|
#
|
||||||
|
# The hanging side comment show you what would be there, then.
|
||||||
|
|
||||||
|
# iterate over keys of arguments
|
||||||
|
# and call set appropriate field in clase
|
||||||
|
map { ($ATTRIBUTES_OF{ $class }->{ $_ })
|
||||||
|
? do {
|
||||||
|
my $method = "set_$_";
|
||||||
|
$_[0]->$method( $_[2]->{ $_ } ); # ( $args_of->{ $_ } );
|
||||||
|
}
|
||||||
|
: $_ =~ m{ \A # beginning of string
|
||||||
|
xmlns # xmlns
|
||||||
|
}xms
|
||||||
|
? do {}
|
||||||
|
: do { use Data::Dumper;
|
||||||
|
croak "unknown field $_ in $class. Valid fields are:\n"
|
||||||
|
. join(', ', @{ $ELEMENTS_FROM{ $class } }) . "\n"
|
||||||
|
. "Structure given:\n" . Dumper @_ };
|
||||||
|
} keys %{ $_[2] }; # %$args_of;
|
||||||
|
return $_[0]; # $self;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
# this serialize method works fine for <all> and <sequence>
|
||||||
|
# complextypes, as well as for <restriction><all> or
|
||||||
|
# <restriction><sequence>.
|
||||||
|
# But what about choice, extension ?
|
||||||
|
*{ "$class\::_serialize" } = sub {
|
||||||
|
my $ident = ident $_[0];
|
||||||
|
# my $class = ref $_[0];
|
||||||
|
# return concatenated return value of serialize call of all
|
||||||
|
# elements retrieved from get_elements expanding list refs.
|
||||||
|
# get_elements is inlined for performance.
|
||||||
|
return join q{} , map {
|
||||||
|
my $element = $ATTRIBUTES_OF{ $class }->{ $_ }->{ $ident };
|
||||||
|
|
||||||
|
# do we have some content
|
||||||
|
if (defined $element) {
|
||||||
|
$element = [ $element ]
|
||||||
|
if not ref $element eq 'ARRAY';
|
||||||
|
my $name = $_;
|
||||||
|
|
||||||
map {
|
map {
|
||||||
# serialize element elements with their own serializer
|
# serialize element elements with their own serializer
|
||||||
# but name them like they're named here.
|
# but name them like they're named here.
|
||||||
if ( $_->isa( 'SOAP::WSDL::XSD::Typelib::Element' ) ) {
|
if ( $_->isa( 'SOAP::WSDL::XSD::Typelib::Element' ) ) {
|
||||||
$_->serialize( { name => $name } );
|
$_->serialize( { name => $name } );
|
||||||
}
|
}
|
||||||
# serialize complextype elments (of other types) with their
|
# serialize complextype elments (of other types) with their
|
||||||
# serializer, but add element tags around.
|
# serializer, but add element tags around.
|
||||||
else {
|
else {
|
||||||
join q{}, $_->start_tag({ name => $name })
|
join q{}, $_->start_tag({ name => $name })
|
||||||
, $_->serialize()
|
, $_->serialize()
|
||||||
, $_->end_tag({ name => $name });
|
, $_->end_tag({ name => $name });
|
||||||
}
|
}
|
||||||
} @{ $element }
|
} @{ $element }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
q{};
|
q{};
|
||||||
}
|
}
|
||||||
} (@{ $ELEMENTS_FROM{ $class } });
|
} (@{ $ELEMENTS_FROM{ $class } });
|
||||||
};
|
};
|
||||||
|
|
||||||
*{ "$class\::serialize" } = sub {
|
*{ "$class\::serialize" } = sub {
|
||||||
my ($self, $opt) = @_;
|
my ($self, $opt) = @_;
|
||||||
@@ -191,7 +223,7 @@ is not that easy:
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
@@ -202,6 +234,81 @@ __END__
|
|||||||
|
|
||||||
SOAP::WSDL::XSD::Typelib::ComplexType - complexType base class
|
SOAP::WSDL::XSD::Typelib::ComplexType - complexType base class
|
||||||
|
|
||||||
|
=head1 Subclassing
|
||||||
|
|
||||||
|
package MyComplexType;
|
||||||
|
use Class::Std::Storable
|
||||||
|
use base qw(SOAP::WSDL::XSD::Typelib::ComplexType);
|
||||||
|
|
||||||
|
__PACKAGE__->_factory(
|
||||||
|
\@elements_from,
|
||||||
|
\%attributes_of,
|
||||||
|
\%classes_of
|
||||||
|
);
|
||||||
|
|
||||||
|
When subclassing, the following methods are created in the subclass:
|
||||||
|
|
||||||
|
=head2 new
|
||||||
|
|
||||||
|
Constructor. For your convenience, new will accept data for the object's
|
||||||
|
properties in the following forms:
|
||||||
|
|
||||||
|
hash refs
|
||||||
|
1) of scalars
|
||||||
|
2) of list refs
|
||||||
|
3) of hash refs
|
||||||
|
4) of objects
|
||||||
|
5) mixed stuff of all of the above
|
||||||
|
|
||||||
|
new() will set the data via the set_FOO methods to the object's element
|
||||||
|
properties.
|
||||||
|
|
||||||
|
Data passed to new must comply to the object's structure or new() will
|
||||||
|
complain. Objects passed must be of the expected type, or new() will
|
||||||
|
complain, too.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
my $obj = MyClass->new({ MyName => $value });
|
||||||
|
|
||||||
|
my $obj = MyClass->new({
|
||||||
|
MyName => {
|
||||||
|
DeepName => $value
|
||||||
|
},
|
||||||
|
MySecondName => $value,
|
||||||
|
});
|
||||||
|
|
||||||
|
my $obj = MyClass->new({
|
||||||
|
MyName => [
|
||||||
|
{ DeepName => $value },
|
||||||
|
{ DeepName => $other_value },
|
||||||
|
],
|
||||||
|
MySecondName => $object,
|
||||||
|
MyThirdName => [ $object1, $object2 ],
|
||||||
|
});
|
||||||
|
|
||||||
|
To be correct, SOAP::WSDL::XSD::Typelib::ComplexType will create a START
|
||||||
|
method, not new() - but new() will be created from Class::Std::Storable and
|
||||||
|
behave like stated above.
|
||||||
|
|
||||||
|
=head2 set_FOO
|
||||||
|
|
||||||
|
A mutator method for every element property.
|
||||||
|
|
||||||
|
For your convenience, the set_FOO methods will accept all kind of data you
|
||||||
|
can think of (and all combinations of them) as input - with the exception
|
||||||
|
of GLOBS and filehandles.
|
||||||
|
|
||||||
|
This means you may set element properties by passing
|
||||||
|
|
||||||
|
a) objects
|
||||||
|
b) scalars
|
||||||
|
c) list refs
|
||||||
|
d) hash refs
|
||||||
|
e) mixed stuff of all of the above
|
||||||
|
|
||||||
|
Examples are similar to the examples provided for new() above.
|
||||||
|
|
||||||
=head1 Bugs and limitations
|
=head1 Bugs and limitations
|
||||||
|
|
||||||
=over
|
=over
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
package SOAP::WSDL::XSD::Typelib::Element;
|
package SOAP::WSDL::XSD::Typelib::Element;
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use Data::Dumper;
|
|
||||||
|
|
||||||
my %NAME;
|
my %NAME;
|
||||||
my %NILLABLE;
|
my %NILLABLE;
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ my @modules = qw(
|
|||||||
SOAP::WSDL::Port
|
SOAP::WSDL::Port
|
||||||
SOAP::WSDL::PortType
|
SOAP::WSDL::PortType
|
||||||
SOAP::WSDL::Types
|
SOAP::WSDL::Types
|
||||||
SOAP::WSDL::SAX::WSDLHandler
|
|
||||||
SOAP::WSDL::XSD::Builtin
|
SOAP::WSDL::XSD::Builtin
|
||||||
SOAP::WSDL::XSD::ComplexType
|
SOAP::WSDL::XSD::ComplexType
|
||||||
SOAP::WSDL::XSD::SimpleType
|
SOAP::WSDL::XSD::SimpleType
|
||||||
|
|||||||
@@ -0,0 +1,327 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 17;
|
||||||
|
use lib '../lib';
|
||||||
|
|
||||||
|
eval {
|
||||||
|
require Test::XML;
|
||||||
|
import Test::XML;
|
||||||
|
};
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL::Expat::WSDLParser/);
|
||||||
|
|
||||||
|
my $filter;
|
||||||
|
|
||||||
|
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
|
||||||
|
|
||||||
|
$parser->parse_string( xml() );
|
||||||
|
|
||||||
|
my $wsdl;
|
||||||
|
ok( $wsdl = $parser->get_data() , "get object tree");
|
||||||
|
|
||||||
|
my $types = $wsdl->first_types();
|
||||||
|
|
||||||
|
is $types->get_parent(), $wsdl , 'types parent';
|
||||||
|
|
||||||
|
my $serializer_options = {
|
||||||
|
readable => 1,
|
||||||
|
autotype => 1,
|
||||||
|
namespace => { 'urn:myNamespace' => 'tns',
|
||||||
|
"http://www.w3.org/2001/XMLSchema" => 'xsd' },
|
||||||
|
typelib => $wsdl->first_types(),
|
||||||
|
indent => "\t",
|
||||||
|
};
|
||||||
|
|
||||||
|
my $xml;
|
||||||
|
my $type = $types->find_type( 'urn:myNamespace', 'testSimpleType1' );
|
||||||
|
|
||||||
|
|
||||||
|
ok($xml = $type->serialize( 'test', 1 , $serializer_options ),
|
||||||
|
"serialize simple Type"
|
||||||
|
);
|
||||||
|
|
||||||
|
# print $xml;
|
||||||
|
|
||||||
|
SKIP: {
|
||||||
|
skip_without_test_xml();
|
||||||
|
is_xml( $xml, '<test type="tns:testSimpleType1">1</test>',
|
||||||
|
"content compare" );
|
||||||
|
};
|
||||||
|
|
||||||
|
$type = $types->find_type( 'urn:myNamespace', 'testSimpleList' );
|
||||||
|
ok($xml = $type->serialize( 'testList', [ 1, 2, 3 ] , $serializer_options ),
|
||||||
|
"serialize simple list type"
|
||||||
|
);
|
||||||
|
SKIP: {
|
||||||
|
skip_without_test_xml();
|
||||||
|
is_xml( $xml, '<testList type="tns:testSimpleList">1 2 3</testList>',
|
||||||
|
"content compare" );
|
||||||
|
};
|
||||||
|
|
||||||
|
$type = $types->find_element( 'urn:myNamespace', 'TestElement' );
|
||||||
|
|
||||||
|
ok($xml = $type->serialize( undef, 1 , $serializer_options ),
|
||||||
|
"serialize simple element");
|
||||||
|
SKIP: {
|
||||||
|
skip_without_test_xml();
|
||||||
|
is_xml( $xml, '<TestElement type="xsd:int">1</TestElement>',
|
||||||
|
"content compare" );
|
||||||
|
};
|
||||||
|
|
||||||
|
ok( $xml = $types->find_type( 'urn:myNamespace', 'length3')->serialize(
|
||||||
|
'TestComplex', { size => -13, unit => 'BLA' } ,
|
||||||
|
$serializer_options
|
||||||
|
),
|
||||||
|
"serialize complex type");
|
||||||
|
|
||||||
|
SKIP: {
|
||||||
|
skip_without_test_xml();
|
||||||
|
is_xml( $xml, q{
|
||||||
|
<TestComplex type="tns:length3">
|
||||||
|
<size type="xsd:non-positive-integer">-13</size>
|
||||||
|
<unit type="xsd:NMTOKEN">BLA</unit>
|
||||||
|
</TestComplex>},
|
||||||
|
"content compare" );
|
||||||
|
};
|
||||||
|
|
||||||
|
ok($xml = $types->find_element( 'urn:myNamespace', 'TestElementComplexType')
|
||||||
|
->serialize(
|
||||||
|
undef, { size => -13, unit => 'BLA' } , $serializer_options ),
|
||||||
|
"serialize element with complex type"
|
||||||
|
);
|
||||||
|
SKIP: {
|
||||||
|
skip_without_test_xml();
|
||||||
|
is_xml( $xml, q{
|
||||||
|
<TestElementComplexType type="tns:length3">
|
||||||
|
<size type="xsd:non-positive-integer">-13</size>
|
||||||
|
<unit type="xsd:NMTOKEN">BLA</unit>
|
||||||
|
</TestElementComplexType>
|
||||||
|
},
|
||||||
|
"content compare" );
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ok($xml = $types->find_type( 'urn:myNamespace', 'complex')->serialize(
|
||||||
|
'complexComplex',
|
||||||
|
{ 'length' => { size => -13, unit => 'BLA' }, 'int' => 1 },
|
||||||
|
$serializer_options ),
|
||||||
|
"serialize complex type with complex content"
|
||||||
|
);
|
||||||
|
SKIP: {
|
||||||
|
skip_without_test_xml();
|
||||||
|
is_xml( $xml, q{
|
||||||
|
<complexComplex type="tns:complex">
|
||||||
|
<length type="tns:length3">
|
||||||
|
<size type="xsd:non-positive-integer">-13</size>
|
||||||
|
<unit type="xsd:NMTOKEN">BLA</unit>
|
||||||
|
</length>
|
||||||
|
<int type="xsd:int">1</int>
|
||||||
|
</complexComplex>
|
||||||
|
},
|
||||||
|
"content compare" );
|
||||||
|
}
|
||||||
|
ok($xml = $wsdl->find_message('urn:myNamespace', 'testRequest')
|
||||||
|
->get_part()->[0]->serialize(
|
||||||
|
undef,
|
||||||
|
{ test => { length => { size => -13, unit => 'BLA' } , int => 3 } },
|
||||||
|
$serializer_options ),
|
||||||
|
"serialize part"
|
||||||
|
);
|
||||||
|
SKIP: {
|
||||||
|
skip_without_test_xml();
|
||||||
|
is_xml( $xml, q{
|
||||||
|
<test type="tns:complex">
|
||||||
|
<length type="tns:length3">
|
||||||
|
<size type="xsd:non-positive-integer">-13</size>
|
||||||
|
<unit type="xsd:NMTOKEN">BLA</unit>
|
||||||
|
</length>
|
||||||
|
<int type="xsd:int">3</int>
|
||||||
|
</test>
|
||||||
|
},
|
||||||
|
"content compare")
|
||||||
|
};
|
||||||
|
|
||||||
|
my $opt = {
|
||||||
|
typelib => $types,
|
||||||
|
readable => 1,
|
||||||
|
autotype => 0,
|
||||||
|
namespace => { 'urn:myNamespace' => 'tns',
|
||||||
|
'http://www.w3.org/2001/XMLSchema' => 'xsd',
|
||||||
|
'http://schemas.xmlsoap.org/wsdl/' => 'wsdl',
|
||||||
|
},
|
||||||
|
indent => "",
|
||||||
|
wsdl => $wsdl,
|
||||||
|
};
|
||||||
|
|
||||||
|
# ok $wsdl->explain($opt) =~ m/#optional/m;
|
||||||
|
|
||||||
|
sub skip_without_test_xml {
|
||||||
|
skip("Test::XML not available", 1) if (not $Test::XML::VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub xml
|
||||||
|
{
|
||||||
|
return q{<?xml version="1.0"?>
|
||||||
|
<definitions name="simpleType"
|
||||||
|
targetNamespace="urn:myNamespace"
|
||||||
|
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
xmlns:tns="urn:myNamespace"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||||
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
>
|
||||||
|
<types>
|
||||||
|
<xsd:schema targetNamespace="urn:myNamespace">
|
||||||
|
<xsd:complexType name="length3">
|
||||||
|
<xsd:all>
|
||||||
|
<xsd:element name="size" type="xsd:non-positive-integer"/>
|
||||||
|
<xsd:element name="unit" type="xsd:NMTOKEN"/>
|
||||||
|
</xsd:all>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="complex">
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="length" type="tns:length3"/>
|
||||||
|
<xsd:element name="int" type="xsd:int"/>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:element name="TestElement" type="xsd:int"/>
|
||||||
|
<xsd:element name="TestElementComplexType" type="tns:length3"/>
|
||||||
|
<xsd:simpleType name="testSimpleType1">
|
||||||
|
<xsd:restriction base="int">
|
||||||
|
<xsd:enumeration value="1"/>
|
||||||
|
<xsd:enumeration value="2"/>
|
||||||
|
<xsd:enumeration value="3"/>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
|
||||||
|
<xsd:simpleType name="testSimpleList">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
SimpleType Test
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:list itemType="int">
|
||||||
|
</xsd:list>
|
||||||
|
</xsd:simpleType>
|
||||||
|
<xsd:simpleType name="testSimpleUnion">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
SimpleType Union test
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:union memberTypes="int float">
|
||||||
|
</xsd:union>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:schema>
|
||||||
|
</types>
|
||||||
|
<message name="testRequest">
|
||||||
|
<part name="test" type="tns:complex"/>
|
||||||
|
</message>
|
||||||
|
<message name="testResponse">
|
||||||
|
<part name="test" type="tns:testSimpleType1"/>
|
||||||
|
</message>
|
||||||
|
<message name="testRequest2">
|
||||||
|
<part name="test" type="tns:testSimpleType1"/>
|
||||||
|
</message>
|
||||||
|
<message name="testResponse2">
|
||||||
|
<part name="test" type="tns:testSimpleType1"/>
|
||||||
|
</message>
|
||||||
|
<portType name="testPort">
|
||||||
|
<operation name="test">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
|
||||||
|
<input message="tns:testRequest"/>
|
||||||
|
<output message="tns:testResponse"/>
|
||||||
|
</operation>
|
||||||
|
<operation name="test2">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
|
||||||
|
<input message="tns:testRequest2"/>
|
||||||
|
<output message="tns:testResponse2"/>
|
||||||
|
</operation>
|
||||||
|
</portType>
|
||||||
|
<portType name="testPort2">
|
||||||
|
<operation name="test">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
|
||||||
|
<input message="tns:testRequest"/>
|
||||||
|
<output message="tns:testResponse"/>
|
||||||
|
</operation>
|
||||||
|
</portType>
|
||||||
|
<portType name="testPort3">
|
||||||
|
<operation name="test">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
<input message="tns:testRequest"/>
|
||||||
|
<output message="tns:testResponse"/>
|
||||||
|
</operation>
|
||||||
|
</portType>
|
||||||
|
|
||||||
|
<binding type="tns:testPort" name="testBinding">
|
||||||
|
<operation name="test">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
|
<soap:operation soapAction="test">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</operation>
|
||||||
|
</binding>
|
||||||
|
<binding type="tns:testPort2" name="testBinding2">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
|
<operation name="test">
|
||||||
|
<soap:operation soapAction="test">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</operation>
|
||||||
|
</binding>
|
||||||
|
<binding type="tns:testPort3" name="testBinding3">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
|
<operation name="test">
|
||||||
|
<soap:operation soapAction="test">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</operation>
|
||||||
|
</binding>
|
||||||
|
<service name="testService">
|
||||||
|
<port name="testPort" binding="tns:testBinding">
|
||||||
|
<soap:address location="http://127.0.0.1/testPort" />
|
||||||
|
</port>
|
||||||
|
<port name="testPort2" binding="tns:testBinding2">
|
||||||
|
<soap:address location="http://127.0.0.1/testPort2" />
|
||||||
|
</port>
|
||||||
|
</service>
|
||||||
|
<service name="testService2">
|
||||||
|
<port name="testPort3" binding="tns:testBinding3">
|
||||||
|
<soap:address location="http://127.0.0.1/testPort3" />
|
||||||
|
</port>
|
||||||
|
|
||||||
|
</service>
|
||||||
|
</definitions>
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+10
-6
@@ -1,9 +1,15 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Test::More tests => 18; # qw/no_plan/; # TODO: change to tests => N;
|
use Test::More;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::SAX::ParserFactory;
|
|
||||||
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 18;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
require Test::XML;
|
require Test::XML;
|
||||||
@@ -15,12 +21,10 @@ use_ok(qw/SOAP::WSDL::SAX::WSDLHandler/);
|
|||||||
my $filter;
|
my $filter;
|
||||||
|
|
||||||
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(
|
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(
|
||||||
{ base => 'XML::SAX::Base' }
|
|
||||||
), "Object creation");
|
), "Object creation");
|
||||||
|
|
||||||
my $parser = XML::SAX::ParserFactory->parser(
|
my $parser = XML::LibXML->new();
|
||||||
Handler => $filter
|
$parser->set_handler( $filter );
|
||||||
);
|
|
||||||
|
|
||||||
$parser->parse_string( xml() );
|
$parser->parse_string( xml() );
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
use Test::More tests => 11;
|
use Test::More;
|
||||||
use Data::Dumper;
|
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::LibXML;
|
|
||||||
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 11;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
use_ok(qw/SOAP::WSDL::SAX::WSDLHandler/);
|
use_ok(qw/SOAP::WSDL::SAX::WSDLHandler/);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,253 @@
|
|||||||
|
use Test::More tests => 11;
|
||||||
|
use Data::Dumper;
|
||||||
|
use lib '../lib';
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL::Expat::WSDLParser/);
|
||||||
|
|
||||||
|
my $filter;
|
||||||
|
|
||||||
|
my $parser;
|
||||||
|
|
||||||
|
ok($parser = SOAP::WSDL::Expat::WSDLParser->new() );
|
||||||
|
|
||||||
|
eval { $parser->parse_string( xml() ) };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
fail("parsing WSDL");
|
||||||
|
die "Can't test without parsed WSDL";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass("parsing XML");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $wsdl;
|
||||||
|
ok( $wsdl = $parser->get_data() , "get object tree");
|
||||||
|
|
||||||
|
my $schema = $wsdl->first_types();
|
||||||
|
|
||||||
|
my $opt = {
|
||||||
|
readable => 0,
|
||||||
|
autotype => 1,
|
||||||
|
namespace => $wsdl->get_xmlns(),
|
||||||
|
indent => "\t",
|
||||||
|
typelib => $schema,
|
||||||
|
};
|
||||||
|
|
||||||
|
is( $schema->find_type( 'myNamespace', 'testSimpleType1' )->serialize(
|
||||||
|
'test', 1 , $opt ),
|
||||||
|
q{<test type="tns:testSimpleType1">1</test>} , "serialize simple type");
|
||||||
|
|
||||||
|
is( $schema->find_type( 'myNamespace', 'testSimpleList' )->serialize(
|
||||||
|
'testList', [ 1, 2, 3 ] , $opt),
|
||||||
|
q{<testList type="tns:testSimpleList">1 2 3</testList>},
|
||||||
|
"serialize simple list type"
|
||||||
|
);
|
||||||
|
|
||||||
|
is( $schema->find_element( 'myNamespace', 'TestElement' )->serialize(
|
||||||
|
undef, 1 , $opt),
|
||||||
|
q{<TestElement type="xsd:int">1</TestElement>}, "Serialize element"
|
||||||
|
);
|
||||||
|
|
||||||
|
$opt->{ readable } = 0;
|
||||||
|
|
||||||
|
is( $schema->find_type( 'myNamespace', 'length3')->serialize(
|
||||||
|
'TestComplex', { size => -13, unit => 'BLA' } ,
|
||||||
|
$opt ),
|
||||||
|
q{<TestComplex type="tns:length3" >}
|
||||||
|
. q{<size type="xsd:non-positive-integer">-13</size>}
|
||||||
|
. q{<unit type="xsd:NMTOKEN">BLA</unit></TestComplex>}
|
||||||
|
, "serialize complex type" );
|
||||||
|
|
||||||
|
is( $schema->find_element( 'myNamespace', 'TestElementComplexType')->serialize(
|
||||||
|
undef, { size => -13, unit => 'BLA' } ,
|
||||||
|
$opt ),
|
||||||
|
q{<TestElementComplexType type="tns:length3" >}
|
||||||
|
. q{<size type="xsd:non-positive-integer">-13</size>}
|
||||||
|
. q{<unit type="xsd:NMTOKEN">BLA</unit></TestElementComplexType>},
|
||||||
|
"element with complex type"
|
||||||
|
);
|
||||||
|
|
||||||
|
is( $schema->find_type( 'myNamespace', 'complex')->serialize(
|
||||||
|
'complexComplex',
|
||||||
|
{ 'length' => { size => -13, unit => 'BLA' }, 'int' => 1 },
|
||||||
|
$opt ),
|
||||||
|
q{<complexComplex type="tns:complex" >}
|
||||||
|
. q{<length type="tns:length3" >}
|
||||||
|
. q{<size type="xsd:non-positive-integer">-13</size>}
|
||||||
|
. q{<unit type="xsd:NMTOKEN">BLA</unit></length>}
|
||||||
|
. q{<int type="xsd:int">1</int></complexComplex>},
|
||||||
|
"nested complex type"
|
||||||
|
);
|
||||||
|
|
||||||
|
is( $wsdl->find_message('myNamespace', 'testRequest')->first_part()->serialize(
|
||||||
|
undef, { test => { length => { size => -13, unit => 'BLA' } , int => 3 } },
|
||||||
|
$opt ),
|
||||||
|
q{<test type="tns:complex" >}
|
||||||
|
. q{<length type="tns:length3" >}
|
||||||
|
. q{<size type="xsd:non-positive-integer">-13</size>}
|
||||||
|
. q{<unit type="xsd:NMTOKEN">BLA</unit>}
|
||||||
|
. q{</length><int type="xsd:int">3</int></test>}
|
||||||
|
, "Message part"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
exit;
|
||||||
|
|
||||||
|
sub xml
|
||||||
|
{
|
||||||
|
return q{<?xml version="1.0"?>
|
||||||
|
<definitions name="simpleType"
|
||||||
|
targetNamespace="myNamespace"
|
||||||
|
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
xmlns:tns="myNamespace"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||||
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
>
|
||||||
|
<types>
|
||||||
|
<xsd:schema targetNamespace="myNamespace">
|
||||||
|
<xsd:complexType name="length3">
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="size" type="xsd:non-positive-integer"/>
|
||||||
|
<xsd:element name="unit" type="xsd:NMTOKEN"/>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="complex">
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="length" type="tns:length3"/>
|
||||||
|
<xsd:element name="int" type="xsd:int"/>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:element name="TestElement" type="xsd:int"/>
|
||||||
|
<xsd:element name="TestElementComplexType" type="tns:length3"/>
|
||||||
|
<xsd:simpleType name="testSimpleType1">
|
||||||
|
<xsd:restriction base="int">
|
||||||
|
<xsd:enumeration value="1"/>
|
||||||
|
<xsd:enumeration value="2"/>
|
||||||
|
<xsd:enumeration value="3"/>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
|
||||||
|
<xsd:simpleType name="testSimpleList">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
SimpleType Test
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:list itemType="int">
|
||||||
|
</xsd:list>
|
||||||
|
</xsd:simpleType>
|
||||||
|
<xsd:simpleType name="testSimpleUnion">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
SimpleType Union test
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:union memberTypes="int float">
|
||||||
|
</xsd:union>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:schema>
|
||||||
|
</types>
|
||||||
|
<message name="testRequest">
|
||||||
|
<part name="test" type="tns:complex"/>
|
||||||
|
</message>
|
||||||
|
<message name="testResponse">
|
||||||
|
<part name="test" type="tns:testSimpleType1"/>
|
||||||
|
</message>
|
||||||
|
<message name="testRequest2">
|
||||||
|
<part name="test" type="tns:testSimpleType1"/>
|
||||||
|
</message>
|
||||||
|
<message name="testResponse2">
|
||||||
|
<part name="test" type="tns:testSimpleType1"/>
|
||||||
|
</message>
|
||||||
|
<portType name="testPort">
|
||||||
|
<operation name="test">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
|
||||||
|
<input message="testRequest"/>
|
||||||
|
<output message="testResponse"/>
|
||||||
|
</operation>
|
||||||
|
<operation name="test2">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
|
||||||
|
<input message="testRequest2"/>
|
||||||
|
<output message="testResponse2"/>
|
||||||
|
</operation>
|
||||||
|
</portType>
|
||||||
|
<portType name="testPort2">
|
||||||
|
<operation name="test">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
|
||||||
|
<input message="testRequest"/>
|
||||||
|
<output message="testResponse"/>
|
||||||
|
</operation>
|
||||||
|
</portType>
|
||||||
|
<portType name="testPort3">
|
||||||
|
<operation name="test">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
<input message="testRequest"/>
|
||||||
|
<output message="testResponse"/>
|
||||||
|
</operation>
|
||||||
|
</portType>
|
||||||
|
|
||||||
|
<binding type="testPort" name="testBinding">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
|
<soap:operation soapAction="test">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</binding>
|
||||||
|
<binding type="testPort2" name="testBinding2">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
|
<soap:operation soapAction="test">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</binding>
|
||||||
|
<binding type="testPort3" name="testBinding3">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
|
<soap:operation soapAction="test">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</binding>
|
||||||
|
<service name="testService">
|
||||||
|
<port name="testPort" binding="testBinding">
|
||||||
|
<soap:address location="http://127.0.0.1/testPort" />
|
||||||
|
</port>
|
||||||
|
<port name="testPort2" binding="testBinding2">
|
||||||
|
<soap:address location="http://127.0.0.1/testPort2" />
|
||||||
|
</port>
|
||||||
|
<port name="testPort3" binding="testBinding3">
|
||||||
|
<soap:address location="http://127.0.0.1/testPort3" />
|
||||||
|
</port>
|
||||||
|
|
||||||
|
</service>
|
||||||
|
</definitions>
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,398 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 5;
|
||||||
|
use lib '../lib';
|
||||||
|
|
||||||
|
eval {
|
||||||
|
require Test::XML;
|
||||||
|
import Test::XML;
|
||||||
|
};
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL::Expat::WSDLParser/);
|
||||||
|
|
||||||
|
my $parser;
|
||||||
|
|
||||||
|
ok($parser = SOAP::WSDL::Expat::WSDLParser->new(), "Object creation");
|
||||||
|
|
||||||
|
eval { $parser->parse_string( xml() ) };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
fail("parsing WSDL");
|
||||||
|
die "Can't test without parsed WSDL: $@";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass("parsing XML");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $wsdl;
|
||||||
|
ok( $wsdl = $parser->get_data() , "get object tree");
|
||||||
|
|
||||||
|
my $schema = $wsdl->get_types()->[0]->get_schema()->[0] || die "No schema !";
|
||||||
|
|
||||||
|
my $opt = {
|
||||||
|
typelib => $wsdl->first_types,
|
||||||
|
readable => 1,
|
||||||
|
autotype => 0,
|
||||||
|
namespace => { 'http://www.example.org/MessageGateway2/' => 'tns',
|
||||||
|
'http://www.w3.org/2001/XMLSchema' => 'xsd',
|
||||||
|
'http://schemas.xmlsoap.org/wsdl/' => 'wsdl',
|
||||||
|
},
|
||||||
|
indent => "",
|
||||||
|
};
|
||||||
|
|
||||||
|
my $data = { EnqueueMessage => {
|
||||||
|
MMessage => {
|
||||||
|
MRecipientURI => 'anyURI',
|
||||||
|
MSenderAddress => 'a string',
|
||||||
|
MMessageContent => 'a string',
|
||||||
|
MSubject => 'a string',
|
||||||
|
MDeliveryReportRecipientURI => 'anyURI',
|
||||||
|
MKeepalive => {
|
||||||
|
MKeepaliveTimeout => 1234567,
|
||||||
|
MKeepaliveErrorPolicy => ' ( suppress | report ) ',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SKIP: { skip_without_test_xml();
|
||||||
|
is_xml( $wsdl->find_message(
|
||||||
|
"http://www.example.org/MessageGateway2/" ,'EnqueueMessageRequest'
|
||||||
|
)->first_part()->serialize( 'test', $data, $opt ),
|
||||||
|
xml_message()
|
||||||
|
, "Serialized message part"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub skip_without_test_xml {
|
||||||
|
skip("Test::XML not available", 1) if (not $Test::XML::VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub xml_message {
|
||||||
|
return
|
||||||
|
q{<EnqueueMessage xmlns="http://www.example.org/MessageGateway2/">
|
||||||
|
<MMessage>
|
||||||
|
<MRecipientURI>anyURI</MRecipientURI>
|
||||||
|
<MSenderAddress>a string</MSenderAddress>
|
||||||
|
<MMessageContent>a string</MMessageContent>
|
||||||
|
<MSubject>a string</MSubject>
|
||||||
|
<MDeliveryReportRecipientURI>anyURI</MDeliveryReportRecipientURI>
|
||||||
|
<MKeepalive>
|
||||||
|
<MKeepaliveTimeout>1234567</MKeepaliveTimeout>
|
||||||
|
<MKeepaliveErrorPolicy> ( suppress | report ) </MKeepaliveErrorPolicy>
|
||||||
|
</MKeepalive>
|
||||||
|
</MMessage>
|
||||||
|
</EnqueueMessage>
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub xml {
|
||||||
|
return q{<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wsdl:definitions name="MessageGateway"
|
||||||
|
targetNamespace="http://www.example.org/MessageGateway2/"
|
||||||
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
xmlns:tns="http://www.example.org/MessageGateway2/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
||||||
|
<wsdl:types>
|
||||||
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
targetNamespace="http://www.example.org/MessageGateway2/">
|
||||||
|
|
||||||
|
<xsd:element name="EnqueueMessage" type="tns:TEnqueueMessage"
|
||||||
|
xmlns:tns="http://www.example.org/MessageGateway2/">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Enqueue message request element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
<xsd:complexType name="TMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A type containing all elements of a message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MRecipientURI" type="xsd:anyURI" minOccurs="1"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:documentation>
|
||||||
|
The recipient in URI notaitions. Valid URI schemas are: mailto:, sms:,
|
||||||
|
phone:. Not all URI schemas need to be implemented at the current
|
||||||
|
implementation stage.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MSenderAddress" type="xsd:string" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
E-Mail sender address. Ignored for all but mailto: recipient URIs.
|
||||||
|
</xsd:documentation>
|
||||||
|
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MMessageContent" type="xsd:string" minOccurs="1"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Message Content.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MSubject" type="xsd:string" minOccurs="0" maxOccurs="1">
|
||||||
|
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Message Subject. Ignored for all but mailto: URIs
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MDeliveryReportRecipientURI" type="xsd:anyURI" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
|
||||||
|
URI to send a delivery report to. May be of one of the following schemes:
|
||||||
|
mailto:, http:, https:. Reports to mailto: URIs are sent as plaintext,
|
||||||
|
reports to http(s) URIs are sent as SOAP requests following the
|
||||||
|
MessageGatewayClient service definition.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MKeepalive" type="tns:TKeepalive" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Container for keepalive information. May be missing.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepalive">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Type containing keeplive information.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
|
||||||
|
<xsd:element name="MKeepaliveTimeout" type="xsd:double">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Keepalive timeout. The keepalive timeout spezifies how long the sending of
|
||||||
|
a message will be delayed waiting for keepalive updates. If a keepalive
|
||||||
|
update is received during this period, the timeout will be reset. If not,
|
||||||
|
the message will be sent after the timeout has expired.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MKeepaliveErrorPolicy" minOccurs="0" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:documentation>
|
||||||
|
Policy to comply to in case of system errors. Valid values are "suppress"
|
||||||
|
and "report". If the policy is set to "suppress", keepalive messages will
|
||||||
|
not be sent to their recipients in case of partial system failure, even if
|
||||||
|
the keepalive has expired. This may result in "false negatives", i.e.
|
||||||
|
messages may not be sent, even though their keepalive has expired. If the
|
||||||
|
value is "report", keepalive messages will be sent from any cluster node.
|
||||||
|
This may result in "false positive" alerts.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:string">
|
||||||
|
<xsd:enumeration value="suppress"></xsd:enumeration>
|
||||||
|
<xsd:enumeration value="report"></xsd:enumeration>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Type containing a message ID.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessageID" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepliveMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Type containing all elements of a keppalive update / remove request.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessageID" type="xsd:string" minOccurs="1" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
The ID for the message to update / remove
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
<xsd:element name="MAction" minOccurs="1" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
The action to perform. Valid values are: "remove", "update". On "remove",
|
||||||
|
the message with the ID specified will be removed from the queue, thus it
|
||||||
|
will never be sent, even if it's timeout expires. On "update" the
|
||||||
|
keepalive timeout of the corresponding message will be reset.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:string">
|
||||||
|
<xsd:enumeration value="remove"></xsd:enumeration>
|
||||||
|
<xsd:enumeration value="update"></xsd:enumeration>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
<xsd:element name="KeepaliveMessage" type="tns:TKeepaliveMessageRequest">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Keepalive message request element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="KeepaliveMessageResponse" type="tns:TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Response element for a keepalive request</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="EnqueueMessageResponse" type="tns:TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Enqueue message response element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="TEnqueueMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A complex type containing one element: The message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessage" type="tns:TMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Element containing a message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepaliveMessageRequest">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A complex type containing one element: The keepalive message to process.
|
||||||
|
</xsd:documentation>
|
||||||
|
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MKeepaliveMessage" type="tns:TKeepliveMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Element containing a keepalive message to process.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:schema>
|
||||||
|
</wsdl:types>
|
||||||
|
<wsdl:message name="EnqueueMessageRequest">
|
||||||
|
<wsdl:part name="parameters" element="tns:EnqueueMessage">
|
||||||
|
<wsdl:documentation>inputparameters for EnqueueMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="EnqueueMessageResponse">
|
||||||
|
<wsdl:part name="parameters" element="tns:EnqueueMessageResponse">
|
||||||
|
<wsdl:documentation>outputparameters for EnqueueMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="KeepaliveMessageRequest">
|
||||||
|
<wsdl:part name="parameters" element="tns:KeepaliveMessage">
|
||||||
|
|
||||||
|
<wsdl:documentation>input parameters for KeepaliveMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="KeepaliveMessageResponse">
|
||||||
|
<wsdl:part name="parameters" element="tns:KeepaliveMessageResponse">
|
||||||
|
<wsdl:documentation>output parameters for KeepaliveMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
|
||||||
|
<wsdl:portType name="MGWPortType">
|
||||||
|
<wsdl:documentation>
|
||||||
|
generic port type for all methods required for sending messages over the mosaic
|
||||||
|
message gatewa
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:operation name="EnqueueMessage">
|
||||||
|
<wsdl:documentation>
|
||||||
|
This method is used to enqueue a normal (immediate send) or a delayed message with
|
||||||
|
keepalive functionality.
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:input message="tns:EnqueueMessageRequest"></wsdl:input>
|
||||||
|
<wsdl:output message="tns:EnqueueMessageResponse"></wsdl:output>
|
||||||
|
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="KeepaliveMessage">
|
||||||
|
<wsdl:documentation>
|
||||||
|
This method is used to update or remove a
|
||||||
|
keepalive message.
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:input message="tns:KeepaliveMessageRequest"></wsdl:input>
|
||||||
|
<wsdl:output message="tns:KeepaliveMessageResponse"></wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:portType>
|
||||||
|
|
||||||
|
<wsdl:binding name="MGWBinding" type="tns:MGWPortType">
|
||||||
|
<wsdl:documentation>Generic binding for all (SOAP) port</wsdl:documentation>
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||||
|
<wsdl:operation name="EnqueueMessage">
|
||||||
|
<soap:operation soapAction="http://www.example.org/MessageGateway2/EnqueueMessage" />
|
||||||
|
<wsdl:input>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:input>
|
||||||
|
<wsdl:output>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="KeepaliveMessage">
|
||||||
|
<soap:operation
|
||||||
|
soapAction="http://www.example.org/MessageGateway2/KeepaliveMessage" />
|
||||||
|
<wsdl:input>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:input>
|
||||||
|
|
||||||
|
<wsdl:output>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:binding>
|
||||||
|
<wsdl:service name="MessageGateway">
|
||||||
|
<wsdl:documentation>
|
||||||
|
Web Service for sending messages over the mosaic message gatewa
|
||||||
|
</wsdl:documentation>
|
||||||
|
|
||||||
|
<wsdl:port name="HTTPPort" binding="tns:MGWBinding">
|
||||||
|
<wsdl:documentation>HTTP(S) port for the mosaic message gatewa</wsdl:documentation>
|
||||||
|
<soap:address location="https://www.example.org/MessageGateway/" />
|
||||||
|
</wsdl:port>
|
||||||
|
</wsdl:service>
|
||||||
|
</wsdl:definitions>};
|
||||||
|
}
|
||||||
+7
-4
@@ -1,11 +1,15 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Test::More tests => 5;
|
use Test::More;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::SAX::ParserFactory;
|
|
||||||
|
|
||||||
use diagnostics;
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 5;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
require Test::XML;
|
require Test::XML;
|
||||||
@@ -18,7 +22,6 @@ my $filter;
|
|||||||
|
|
||||||
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(), "Object creation");
|
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(), "Object creation");
|
||||||
|
|
||||||
use XML::LibXML;
|
|
||||||
my $parser = XML::LibXML->new();
|
my $parser = XML::LibXML->new();
|
||||||
$parser->set_handler( $filter );
|
$parser->set_handler( $filter );
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,249 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More qw/no_plan/; # TODO: change to tests => N;
|
||||||
|
use Data::Dumper;
|
||||||
|
use lib '../lib';
|
||||||
|
use diagnostics;
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL::Expat::WSDLParser/);
|
||||||
|
|
||||||
|
my $parser;
|
||||||
|
|
||||||
|
ok($parser = SOAP::WSDL::Expat::WSDLParser->new(), "Object creation");
|
||||||
|
eval { $parser->parse_string( xml() ) };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
fail("parsing WSDL");
|
||||||
|
die "Can't test without parsed WSDL: $@";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass("parsing XML");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $wsdl;
|
||||||
|
ok( $wsdl = $parser->get_data() , "get object tree");
|
||||||
|
|
||||||
|
my $opt = {
|
||||||
|
namespace => $wsdl->get_xmlns(),
|
||||||
|
style => 'perl',
|
||||||
|
wsdl => $wsdl,
|
||||||
|
readable => 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
my $txt;
|
||||||
|
ok( $txt = $wsdl->explain( $opt ) , "explain WSDL" );
|
||||||
|
|
||||||
|
# print $txt;
|
||||||
|
|
||||||
|
sub xml {
|
||||||
|
return q{<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wsdl:definitions targetNamespace="http://example.com/soap/services/ETest/impl"
|
||||||
|
xmlns="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
xmlns:apachesoap="http://xml.apache.org/xml-soap"
|
||||||
|
xmlns:impl="http://example.com/soap/services/ETest/impl"
|
||||||
|
xmlns:intf="http://example.com/soap/services/ETest"
|
||||||
|
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
|
xmlns:tns1="urn:ETest"
|
||||||
|
xmlns:tns2="urn:acquisition"
|
||||||
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
|
|
||||||
|
<wsdl:types>
|
||||||
|
<schema targetNamespace="urn:ETest" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||||
|
<complexType name="CreationBaseData">
|
||||||
|
<sequence>
|
||||||
|
<element name="createdBy" nillable="true" type="xsd:long" />
|
||||||
|
<element name="creationDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="updateDateCenter" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="updateDateLocal" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="updatedBy" nillable="true" type="xsd:long" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
<complexType name="CreationData">
|
||||||
|
<complexContent>
|
||||||
|
<extension base="tns1:CreationBaseData">
|
||||||
|
<sequence>
|
||||||
|
<element name="creatorFullName" nillable="true" type="xsd:string" />
|
||||||
|
<element name="modifierFullName" nillable="true" type="xsd:string" />
|
||||||
|
</sequence>
|
||||||
|
</extension>
|
||||||
|
</complexContent>
|
||||||
|
</complexType>
|
||||||
|
<complexType abstract="true" name="EProductData">
|
||||||
|
<sequence>
|
||||||
|
<element name="EStatus" nillable="true" type="xsd:string" />
|
||||||
|
<element name="EStatusUpdatedate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="SFXID" nillable="true" type="xsd:string" />
|
||||||
|
<element name="activationFromDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="activationToDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="activityStatusDateFrom" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="activityStatusDateTo" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="canEditSFXID" type="xsd:boolean" />
|
||||||
|
<element name="concurrentNumberOfUsers" nillable="true" type="xsd:int" />
|
||||||
|
<element name="creationData" nillable="true" type="tns1:CreationData" />
|
||||||
|
<element name="deleteable" type="xsd:boolean" />
|
||||||
|
<element name="ETestCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="id" nillable="true" type="xsd:long" />
|
||||||
|
<element name="instanceCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="mainContact" nillable="true" type="xsd:string" />
|
||||||
|
<element name="metaLibID" nillable="true" type="xsd:string" />
|
||||||
|
<element name="otherID" nillable="true" type="xsd:string" />
|
||||||
|
<element name="otherSource" nillable="true" type="xsd:string" />
|
||||||
|
<element name="privateNote" nillable="true" type="xsd:string" />
|
||||||
|
<element name="procurementStatus" nillable="true" type="xsd:string" />
|
||||||
|
<element name="procurementStatusUpdateDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="procurementStatusUpdatedate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="sourceInstanceCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="sponseringLibraryCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="sponseringLibraryName" nillable="true" type="xsd:string" />
|
||||||
|
<element name="updateTarget" nillable="true" type="xsd:string" />
|
||||||
|
<element name="workExpressionCode" nillable="true" type="xsd:string" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
<complexType name="EProductInformation">
|
||||||
|
<sequence>
|
||||||
|
<element name="acquisitions" nillable="true"
|
||||||
|
type="impl:ArrayOf_tns2_AcquisitionData" />
|
||||||
|
<element name="data" nillable="true" type="tns1:EProductData" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</schema>
|
||||||
|
<schema targetNamespace="urn:acquisition" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||||
|
<complexType name="AcquisitionCommonData">
|
||||||
|
<sequence>
|
||||||
|
<element name="budgets" nillable="true" type="xsd:string" />
|
||||||
|
<element name="campusCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="concurrentUsersNote" nillable="true" type="xsd:string" />
|
||||||
|
<element name="creationData" nillable="true" type="tns1:CreationData" />
|
||||||
|
<element name="id" nillable="true" type="xsd:long" />
|
||||||
|
<element name="instituteCode" nillable="true" type="xsd:string" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
<complexType name="AcquisitionData">
|
||||||
|
<sequence>
|
||||||
|
<element name="ILSSubscriptionNo" nillable="true" type="xsd:string" />
|
||||||
|
<element name="acquisitionCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="acquisitionCommonData" nillable="true"
|
||||||
|
type="tns2:AcquisitionCommonData" />
|
||||||
|
<element name="acquisitionMethod" nillable="true" type="xsd:string" />
|
||||||
|
<element name="acquisitionNumber" nillable="true" type="xsd:string" />
|
||||||
|
<element name="acquisitionStatus" nillable="true" type="xsd:string" />
|
||||||
|
<element name="acquisitionStatusDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="advanceNoticeDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="autoRenewal" nillable="true" type="xsd:boolean" />
|
||||||
|
<element name="consortialAgreement" type="xsd:boolean" />
|
||||||
|
<element name="discountOnPrice" nillable="true" type="xsd:int" />
|
||||||
|
<element name="id" nillable="true" type="xsd:long" />
|
||||||
|
<element name="instanceCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="materialType" nillable="true" type="xsd:string" />
|
||||||
|
<element name="noteForILS" nillable="true" type="xsd:string" />
|
||||||
|
<element name="noteForVendor" nillable="true" type="xsd:string" />
|
||||||
|
<element name="noticePeriodCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="numberOfCopies" nillable="true" type="xsd:int" />
|
||||||
|
<element name="orderDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="orderForm" nillable="true" type="xsd:string" />
|
||||||
|
<element name="orderSendMethod" nillable="true" type="xsd:string" />
|
||||||
|
<element name="pooledConcurrentUsers" nillable="true" type="xsd:int" />
|
||||||
|
<element name="price" nillable="true" type="xsd:double" />
|
||||||
|
<element name="pricingCap" nillable="true" type="xsd:int" />
|
||||||
|
<element name="pricingCapFrom" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="pricingCapTo" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="pricingModel" nillable="true" type="xsd:string" />
|
||||||
|
<element name="printCancellationNote" nillable="true" type="xsd:string" />
|
||||||
|
<element name="printCancellationRestriction" type="xsd:boolean" />
|
||||||
|
<element name="printPurchaseOrderNo" nillable="true" type="xsd:string" />
|
||||||
|
<element name="purchaseOrderNo" nillable="true" type="xsd:string" />
|
||||||
|
<element name="renewallOrCancellationDate" nillable="true" type="xsd:dateTime" />
|
||||||
|
<element name="renewallOrCancellationDescisionNote" nillable="true"
|
||||||
|
type="xsd:string" />
|
||||||
|
<element name="renewallOrCancellationNoteForILS" nillable="true"
|
||||||
|
type="xsd:string" />
|
||||||
|
<element name="renewallOrCancellationNoteForVendor" nillable="true"
|
||||||
|
type="xsd:string" />
|
||||||
|
<element name="subscriptionNotification" nillable="true" type="xsd:int" />
|
||||||
|
<element name="subscriptionPeriodCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="subscriptionType" nillable="true" type="xsd:string" />
|
||||||
|
<element name="subscriptionTypeNote" nillable="true" type="xsd:string" />
|
||||||
|
<element name="vendorAdvancedNotice" nillable="true" type="xsd:int" />
|
||||||
|
<element name="vendorAdvancedNoticeVal" nillable="true" type="xsd:string" />
|
||||||
|
<element name="vendorCode" nillable="true" type="xsd:string" />
|
||||||
|
<element name="vendorName" nillable="true" type="xsd:string" />
|
||||||
|
<element name="vendorSubscriptionCode" nillable="true" type="xsd:string" />
|
||||||
|
</sequence>
|
||||||
|
</complexType>
|
||||||
|
</schema>
|
||||||
|
<schema targetNamespace="http://example.com/soap/services/ETest/impl"
|
||||||
|
xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
|
||||||
|
<complexType name="ArrayOf_tns2_AcquisitionData">
|
||||||
|
<complexContent>
|
||||||
|
<restriction base="soapenc:Array">
|
||||||
|
<attribute ref="soapenc:arrayType" wsdl:arrayType="tns2:AcquisitionData[]" />
|
||||||
|
</restriction>
|
||||||
|
</complexContent>
|
||||||
|
</complexType>
|
||||||
|
</schema>
|
||||||
|
</wsdl:types>
|
||||||
|
<wsdl:message name="getETestResponse">
|
||||||
|
<wsdl:part name="getETestReturn" type="tns1:EProductInformation" />
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="getFixedETestResponse">
|
||||||
|
<wsdl:part name="getFixedETestReturn" type="tns1:EProductInformation" />
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="getFixedETestRequest"></wsdl:message>
|
||||||
|
<wsdl:message name="getETestRequest">
|
||||||
|
<wsdl:part name="indexName" type="xsd:string" />
|
||||||
|
<wsdl:part name="indexValue" type="xsd:string" />
|
||||||
|
<wsdl:part name="withStatus" type="xsd:string" />
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:portType name="ETestWeb">
|
||||||
|
<wsdl:operation name="getETest" parameterOrder="indexName indexValue withStatus">
|
||||||
|
<wsdl:input message="impl:getETestRequest" name="getETestRequest" />
|
||||||
|
<wsdl:output message="impl:getETestResponse" name="getETestResponse" />
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="getFixedETest">
|
||||||
|
<wsdl:input message="impl:getFixedETestRequest" name="getFixedETestRequest" />
|
||||||
|
<wsdl:output message="impl:getFixedETestResponse"
|
||||||
|
name="getFixedETestResponse" />
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:portType>
|
||||||
|
|
||||||
|
<wsdl:binding name="ETestSoapBinding" type="impl:ETestWeb">
|
||||||
|
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||||
|
<wsdl:operation name="getETest">
|
||||||
|
<wsdlsoap:operation soapAction="" />
|
||||||
|
<wsdl:input name="getETestRequest">
|
||||||
|
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
|
namespace="http://example.com/soap/services/ETest" use="encoded" />
|
||||||
|
</wsdl:input>
|
||||||
|
<wsdl:output name="getETestResponse">
|
||||||
|
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
|
namespace="http://example.com/soap/services/ETest" use="encoded" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="getFixedETest">
|
||||||
|
<wsdlsoap:operation soapAction="" />
|
||||||
|
<wsdl:input name="getFixedETestRequest">
|
||||||
|
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
|
namespace="http://example.com/soap/services/ETest" use="encoded" />
|
||||||
|
</wsdl:input>
|
||||||
|
<wsdl:output name="getFixedETestResponse">
|
||||||
|
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
|
namespace="http://example.com/soap/services/ETest" use="encoded" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:binding>
|
||||||
|
|
||||||
|
<wsdl:service name="ETestWebService">
|
||||||
|
<wsdl:port binding="impl:ETestSoapBinding" name="ETest">
|
||||||
|
<wsdlsoap:address location="http://example.com/soap/services/ETest" />
|
||||||
|
</wsdl:port>
|
||||||
|
</wsdl:service>
|
||||||
|
</wsdl:definitions>
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,10 +1,15 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Test::More qw/no_plan/; # TODO: change to tests => N;
|
use Test::More; # TODO: change to tests => N;
|
||||||
use Data::Dumper;
|
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::LibXML;
|
|
||||||
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 5;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
use diagnostics;
|
use diagnostics;
|
||||||
|
|
||||||
|
|||||||
+11
-10
@@ -1,10 +1,8 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Pod::Simple::Text;
|
|
||||||
use Test::More qw/no_plan/; # TODO: change to tests => N;
|
use Test::More qw/no_plan/; # TODO: change to tests => N;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::SAX::ParserFactory;
|
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
require Test::XML;
|
require Test::XML;
|
||||||
@@ -31,11 +29,17 @@ ok( $soap->no_dispatch( 1 ) , "Set no_dispatch" );
|
|||||||
ok( $soap->explain() );
|
ok( $soap->explain() );
|
||||||
|
|
||||||
|
|
||||||
my $pod = Pod::Simple::Text->new();
|
SKIP: {
|
||||||
my $output;
|
|
||||||
$pod->output_string( \$output );
|
if (not eval "require Pod::Simple::Text") {
|
||||||
$pod->parse_string_document( $soap->explain() );
|
skip "cannot test parsing pod without Pod::Test::Simple", 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
my $pod = Pod::Simple::Text->new();
|
||||||
|
my $output;
|
||||||
|
$pod->output_string( \$output );
|
||||||
|
ok $pod->parse_string_document( $soap->explain() ), 'parse explain pod';
|
||||||
|
}
|
||||||
# print $output;
|
# print $output;
|
||||||
|
|
||||||
SKIP: {
|
SKIP: {
|
||||||
@@ -60,6 +64,3 @@ sub skip_without_test_xml {
|
|||||||
my $number = shift || 1;
|
my $number = shift || 1;
|
||||||
skip("Test::XML not available", $number) if (not $Test::XML::VERSION);
|
skip("Test::XML not available", $number) if (not $Test::XML::VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
__END__
|
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -10,7 +10,7 @@ eval {
|
|||||||
import Test::XML;
|
import Test::XML;
|
||||||
};
|
};
|
||||||
|
|
||||||
use_ok qw/SOAP::WSDL::Envelope/;
|
use_ok qw/SOAP::WSDL::Serializer::SOAP11/;
|
||||||
|
|
||||||
my $opt = {
|
my $opt = {
|
||||||
readable => 1,
|
readable => 1,
|
||||||
@@ -18,7 +18,7 @@ my $opt = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
my $xml;
|
my $xml;
|
||||||
ok( $xml = SOAP::WSDL::Envelope->serialize(
|
ok( $xml = SOAP::WSDL::Serializer::SOAP11->serialize(
|
||||||
undef, undef, $opt
|
undef, undef, $opt
|
||||||
),
|
),
|
||||||
"serialize empty envelope"
|
"serialize empty envelope"
|
||||||
|
|||||||
+12
-15
@@ -1,13 +1,14 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
|
use warnings;
|
||||||
use Test::More tests => 5;
|
use Test::More tests => 5;
|
||||||
use lib 't/lib';
|
use lib 't/lib';
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use lib 'lib';
|
use lib 'lib';
|
||||||
use XML::Simple;
|
|
||||||
use SOAP::WSDL::SAX::WSDLHandler;
|
use SOAP::WSDL::SAX::WSDLHandler;
|
||||||
use Cwd;
|
use Cwd;
|
||||||
use XML::LibXML::SAX;
|
|
||||||
use_ok(qw/SOAP::WSDL::SAX::MessageHandler/);
|
use_ok(qw/SOAP::WSDL::SAX::MessageHandler/);
|
||||||
|
|
||||||
use SOAP::WSDL;
|
use SOAP::WSDL;
|
||||||
@@ -15,22 +16,18 @@ use SOAP::WSDL::XSD::Typelib::Builtin;
|
|||||||
my $path = cwd;
|
my $path = cwd;
|
||||||
$path =~s|\/t\/?$||; # allow running from t/ and above (Build test)
|
$path =~s|\/t\/?$||; # allow running from t/ and above (Build test)
|
||||||
|
|
||||||
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
|
|
||||||
|
|
||||||
my $filter;
|
my $parser;
|
||||||
ok($filter = SOAP::WSDL::SAX::MessageHandler->new( {
|
|
||||||
|
ok $parser = SOAP::WSDL::Expat::MessageParser->new({
|
||||||
class_resolver => FakeResolver->new(),
|
class_resolver => FakeResolver->new(),
|
||||||
} ), "Object creation");
|
}), "Object creation";
|
||||||
|
|
||||||
my $parser = XML::LibXML->new();
|
# TODO factor out into bool test
|
||||||
$parser->set_handler( $filter );
|
|
||||||
|
|
||||||
$parser->parse_string( xml() );
|
$parser->parse( xml() );
|
||||||
|
|
||||||
# print $filter->get_data();
|
if($parser->get_data()->get_MMessage()->get_MDeliveryReportRecipientURI()) {
|
||||||
# print $filter->get_data()->get_MMessage()->_DUMP();
|
|
||||||
|
|
||||||
if($filter->get_data()->get_MMessage()->get_MDeliveryReportRecipientURI()) {
|
|
||||||
pass "bool context overloading";
|
pass "bool context overloading";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -38,6 +35,8 @@ else
|
|||||||
fail "bool context overloading"
|
fail "bool context overloading"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO factor out into different test
|
||||||
|
|
||||||
my $soap = SOAP::WSDL->new(
|
my $soap = SOAP::WSDL->new(
|
||||||
readable => 1,
|
readable => 1,
|
||||||
wsdl => 'file:///' . $path .'/t/acceptance/wsdl/006_sax_client.wsdl',
|
wsdl => 'file:///' . $path .'/t/acceptance/wsdl/006_sax_client.wsdl',
|
||||||
@@ -86,6 +85,4 @@ BEGIN {
|
|||||||
: warn "no class found for $name";
|
: warn "no class found for $name";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
+9
-5
@@ -1,11 +1,15 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Test::More tests => 16;
|
use Test::More;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::SAX::ParserFactory;
|
|
||||||
|
|
||||||
use diagnostics;
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 16;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
require Test::XML;
|
require Test::XML;
|
||||||
@@ -18,7 +22,6 @@ my $filter;
|
|||||||
|
|
||||||
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(), "Object creation");
|
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(), "Object creation");
|
||||||
|
|
||||||
use XML::LibXML;
|
|
||||||
my $parser = XML::LibXML->new();
|
my $parser = XML::LibXML->new();
|
||||||
$parser->set_handler( $filter );
|
$parser->set_handler( $filter );
|
||||||
|
|
||||||
@@ -56,7 +59,8 @@ for my $element (@{ $wsdl->first_types()->get_schema()->[1]->get_type() } ) {
|
|||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
my $name = 'MessageGateway::' . $element->get_name();
|
my $name = 'MessageGateway::' . $element->get_name();
|
||||||
ok eval $output, $name;
|
ok eval $output, $name
|
||||||
|
or die $@, $output;
|
||||||
|
|
||||||
ok $name->can('serialize'), "$name\->can('serialize')";
|
ok $name->can('serialize'), "$name\->can('serialize')";
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-13
@@ -3,25 +3,16 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use Test::More tests => 5;
|
use Test::More tests => 5;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::SAX::ParserFactory;
|
|
||||||
|
|
||||||
use diagnostics;
|
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
require Test::XML;
|
require Test::XML;
|
||||||
import Test::XML;
|
import Test::XML;
|
||||||
};
|
};
|
||||||
|
|
||||||
use_ok(qw/SOAP::WSDL::SAX::WSDLHandler/);
|
use_ok(qw/SOAP::WSDL::Expat::WSDLParser/);
|
||||||
|
|
||||||
my $filter;
|
my $parser;
|
||||||
|
|
||||||
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(), "Object creation");
|
|
||||||
|
|
||||||
use XML::LibXML;
|
|
||||||
my $parser = XML::LibXML->new();
|
|
||||||
$parser->set_handler( $filter );
|
|
||||||
|
|
||||||
|
ok($parser = SOAP::WSDL::Expat::WSDLParser->new(), "Object creation");
|
||||||
eval { $parser->parse_string( xml() ) };
|
eval { $parser->parse_string( xml() ) };
|
||||||
if ($@)
|
if ($@)
|
||||||
{
|
{
|
||||||
@@ -34,7 +25,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $wsdl;
|
my $wsdl;
|
||||||
ok( $wsdl = $filter->get_data() , "get object tree");
|
ok( $wsdl = $parser->get_data() , "get object tree");
|
||||||
|
|
||||||
ok $wsdl->to_typemap( { prefix => 'CP::EAI::Typelib::' } ), 'typemap';
|
ok $wsdl->to_typemap( { prefix => 'CP::EAI::Typelib::' } ), 'typemap';
|
||||||
exit;
|
exit;
|
||||||
|
|||||||
@@ -0,0 +1,412 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 19;
|
||||||
|
use lib '../lib';
|
||||||
|
use SOAP::WSDL::Expat::WSDLParser;
|
||||||
|
use SOAP::WSDL::Expat::MessageParser;
|
||||||
|
use File::Path;
|
||||||
|
use File::Basename;
|
||||||
|
|
||||||
|
my $path = dirname __FILE__;
|
||||||
|
|
||||||
|
my $wsdl;
|
||||||
|
ok( $wsdl = SOAP::WSDL::Expat::WSDLParser->new()
|
||||||
|
->parse_string( xml() ) , "get object tree");
|
||||||
|
|
||||||
|
$wsdl->create({
|
||||||
|
base_path => "$path/testlib",
|
||||||
|
typemap_prefix => "Test::Typemap::",
|
||||||
|
type_prefix => "Test::Type::",
|
||||||
|
element_prefix => "Test::Element::",
|
||||||
|
interface_prefix => "Test::Interface::",
|
||||||
|
});
|
||||||
|
|
||||||
|
eval "use lib '$path/testlib'";
|
||||||
|
|
||||||
|
use_ok qw(Test::Element::EnqueueMessage);
|
||||||
|
use_ok qw(Test::Type::TMessage);
|
||||||
|
use_ok qw(Test::Typemap::MessageGateway);
|
||||||
|
|
||||||
|
my $data = {
|
||||||
|
MMessage => {
|
||||||
|
MRecipientURI => 'anyURI',
|
||||||
|
MSenderAddress => 'a string',
|
||||||
|
MMessageContent => 'a string',
|
||||||
|
MSubject => 'a string',
|
||||||
|
MDeliveryReportRecipientURI => 'anyURI',
|
||||||
|
MKeepalive => {
|
||||||
|
MKeepaliveTimeout => 1234567,
|
||||||
|
MKeepaliveErrorPolicy => ' ( suppress | report ) ',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ok Test::Element::EnqueueMessage->new( $data ) , '(generated) object constructor';
|
||||||
|
|
||||||
|
my $message_parser = SOAP::WSDL::Expat::MessageParser->new({
|
||||||
|
class_resolver => 'Test::Typemap::MessageGateway'
|
||||||
|
});
|
||||||
|
|
||||||
|
eval { $message_parser->parse_string( xml_message2() ) };
|
||||||
|
ok ( !$@, 'parse XML message');
|
||||||
|
|
||||||
|
|
||||||
|
TODO: {
|
||||||
|
local $TODO = 'support embedded atomic simpleType/complexType definitions';
|
||||||
|
eval { $message_parser->parse_string( xml_message() ) };
|
||||||
|
ok ( !$@, 'parse XML message using atomic type definitions');
|
||||||
|
};
|
||||||
|
|
||||||
|
SKIP: {
|
||||||
|
eval "require Test::Pod";
|
||||||
|
skip 'Cannot test generated POD without Test::POD' , 6 if $@;
|
||||||
|
|
||||||
|
foreach my $module (Test::Pod::all_pod_files( "$path/testlib")) {
|
||||||
|
Test::Pod::pod_file_ok( $module )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
rmtree "$path/testlib";
|
||||||
|
|
||||||
|
# print $wsdl->explain();
|
||||||
|
|
||||||
|
sub xml_message {
|
||||||
|
return
|
||||||
|
q{<EnqueueMessage xmlns="http://www.example.org/MessageGateway2/">
|
||||||
|
<MMessage>
|
||||||
|
<MRecipientURI>anyURI</MRecipientURI>
|
||||||
|
<MSenderAddress>a string</MSenderAddress>
|
||||||
|
<MMessageContent>a string</MMessageContent>
|
||||||
|
<MSubject>a string</MSubject>
|
||||||
|
<MDeliveryReportRecipientURI>anyURI</MDeliveryReportRecipientURI>
|
||||||
|
<MKeepalive>
|
||||||
|
<MKeepaliveTimeout>1234567</MKeepaliveTimeout>
|
||||||
|
<MKeepaliveErrorPolicy> ( suppress | report ) </MKeepaliveErrorPolicy>
|
||||||
|
</MKeepalive>
|
||||||
|
</MMessage>
|
||||||
|
</EnqueueMessage>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub xml_message2 {
|
||||||
|
return
|
||||||
|
q{<EnqueueMessage xmlns="http://www.example.org/MessageGateway2/">
|
||||||
|
<MMessage>
|
||||||
|
<MRecipientURI>anyURI</MRecipientURI>
|
||||||
|
<MSenderAddress>a string</MSenderAddress>
|
||||||
|
<MMessageContent>a string</MMessageContent>
|
||||||
|
<MSubject>a string</MSubject>
|
||||||
|
<MDeliveryReportRecipientURI>anyURI</MDeliveryReportRecipientURI>
|
||||||
|
</MMessage>
|
||||||
|
</EnqueueMessage>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub xml {
|
||||||
|
return q{<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wsdl:definitions name="MessageGateway"
|
||||||
|
targetNamespace="http://www.example.org/MessageGateway2/"
|
||||||
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
xmlns:tns="http://www.example.org/MessageGateway2/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
||||||
|
<wsdl:types>
|
||||||
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
targetNamespace="http://www.example.org/MessageGateway2/">
|
||||||
|
|
||||||
|
<xsd:element name="EnqueueMessage" type="tns:TEnqueueMessage"
|
||||||
|
xmlns:tns="http://www.example.org/MessageGateway2/">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Enqueue message request element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
<xsd:complexType name="TMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A type containing all elements of a message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MRecipientURI" type="xsd:anyURI" minOccurs="1"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:documentation>
|
||||||
|
The recipient in URI notaitions. Valid URI schemas are: mailto:, sms:,
|
||||||
|
phone:. Not all URI schemas need to be implemented at the current
|
||||||
|
implementation stage.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MSenderAddress" type="xsd:string" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
E-Mail sender address. Ignored for all but mailto: recipient URIs.
|
||||||
|
</xsd:documentation>
|
||||||
|
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MMessageContent" type="xsd:string" minOccurs="1"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Message Content.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MSubject" type="xsd:string" minOccurs="0" maxOccurs="1">
|
||||||
|
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Message Subject. Ignored for all but mailto: URIs
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MDeliveryReportRecipientURI" type="xsd:anyURI" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
|
||||||
|
URI to send a delivery report to. May be of one of the following schemes:
|
||||||
|
mailto:, http:, https:. Reports to mailto: URIs are sent as plaintext,
|
||||||
|
reports to http(s) URIs are sent as SOAP requests following the
|
||||||
|
MessageGatewayClient service definition.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MKeepalive" type="tns:TKeepalive" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Container for keepalive information. May be missing.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepalive">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Type containing keeplive information.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
|
||||||
|
<xsd:element name="MKeepaliveTimeout" type="xsd:double">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Keepalive timeout. The keepalive timeout spezifies how long the sending of
|
||||||
|
a message will be delayed waiting for keepalive updates. If a keepalive
|
||||||
|
update is received during this period, the timeout will be reset. If not,
|
||||||
|
the message will be sent after the timeout has expired.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MKeepaliveErrorPolicy" minOccurs="0" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:documentation>
|
||||||
|
Policy to comply to in case of system errors. Valid values are "suppress"
|
||||||
|
and "report". If the policy is set to "suppress", keepalive messages will
|
||||||
|
not be sent to their recipients in case of partial system failure, even if
|
||||||
|
the keepalive has expired. This may result in "false negatives", i.e.
|
||||||
|
messages may not be sent, even though their keepalive has expired. If the
|
||||||
|
value is "report", keepalive messages will be sent from any cluster node.
|
||||||
|
This may result in "false positive" alerts.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:string">
|
||||||
|
<xsd:enumeration value="suppress"></xsd:enumeration>
|
||||||
|
<xsd:enumeration value="report"></xsd:enumeration>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Type containing a message ID.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessageID" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepliveMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Type containing all elements of a keppalive update / remove request.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessageID" type="xsd:string" minOccurs="1" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
The ID for the message to update / remove
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
<xsd:element name="MAction" minOccurs="1" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
The action to perform. Valid values are: "remove", "update". On "remove",
|
||||||
|
the message with the ID specified will be removed from the queue, thus it
|
||||||
|
will never be sent, even if it's timeout expires. On "update" the
|
||||||
|
keepalive timeout of the corresponding message will be reset.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:string">
|
||||||
|
<xsd:enumeration value="remove"></xsd:enumeration>
|
||||||
|
<xsd:enumeration value="update"></xsd:enumeration>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
<xsd:element name="KeepaliveMessage" type="tns:TKeepaliveMessageRequest">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Keepalive message request element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="KeepaliveMessageResponse" type="tns:TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Response element for a keepalive request</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="EnqueueMessageResponse" type="tns:TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Enqueue message response element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="TEnqueueMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A complex type containing one element: The message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessage" type="tns:TMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Element containing a message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepaliveMessageRequest">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A complex type containing one element: The keepalive message to process.
|
||||||
|
</xsd:documentation>
|
||||||
|
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MKeepaliveMessage" type="tns:TKeepliveMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Element containing a keepalive message to process.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:schema>
|
||||||
|
</wsdl:types>
|
||||||
|
<wsdl:message name="EnqueueMessageRequest">
|
||||||
|
<wsdl:part name="parameters" element="tns:EnqueueMessage">
|
||||||
|
<wsdl:documentation>inputparameters for EnqueueMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="EnqueueMessageResponse">
|
||||||
|
<wsdl:part name="parameters" element="tns:EnqueueMessageResponse">
|
||||||
|
<wsdl:documentation>outputparameters for EnqueueMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="KeepaliveMessageRequest">
|
||||||
|
<wsdl:part name="parameters" element="tns:KeepaliveMessage">
|
||||||
|
|
||||||
|
<wsdl:documentation>input parameters for KeepaliveMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="KeepaliveMessageResponse">
|
||||||
|
<wsdl:part name="parameters" element="tns:KeepaliveMessageResponse">
|
||||||
|
<wsdl:documentation>output parameters for KeepaliveMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
|
||||||
|
<wsdl:portType name="MGWPortType">
|
||||||
|
<wsdl:documentation>
|
||||||
|
generic port type for all methods required for sending messages over the mosaic
|
||||||
|
message gatewa
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:operation name="EnqueueMessage">
|
||||||
|
<wsdl:documentation>
|
||||||
|
This method is used to enqueue a normal (immediate send) or a delayed message with
|
||||||
|
keepalive functionality.
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:input message="tns:EnqueueMessageRequest"></wsdl:input>
|
||||||
|
<wsdl:output message="tns:EnqueueMessageResponse"></wsdl:output>
|
||||||
|
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="KeepaliveMessage">
|
||||||
|
<wsdl:documentation>
|
||||||
|
This method is used to update or remove a
|
||||||
|
keepalive message.
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:input message="tns:KeepaliveMessageRequest"></wsdl:input>
|
||||||
|
<wsdl:output message="tns:KeepaliveMessageResponse"></wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:portType>
|
||||||
|
|
||||||
|
<wsdl:binding name="MGWBinding" type="tns:MGWPortType">
|
||||||
|
<wsdl:documentation>Generic binding for all (SOAP) port</wsdl:documentation>
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||||
|
<wsdl:operation name="EnqueueMessage">
|
||||||
|
<soap:operation soapAction="http://www.example.org/MessageGateway2/EnqueueMessage" />
|
||||||
|
<wsdl:input>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:input>
|
||||||
|
<wsdl:output>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="KeepaliveMessage">
|
||||||
|
<soap:operation
|
||||||
|
soapAction="http://www.example.org/MessageGateway2/KeepaliveMessage" />
|
||||||
|
<wsdl:input>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:input>
|
||||||
|
|
||||||
|
<wsdl:output>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:binding>
|
||||||
|
<wsdl:service name="MessageGateway">
|
||||||
|
<wsdl:documentation>
|
||||||
|
Web Service for sending messages over the message gatewa
|
||||||
|
</wsdl:documentation>
|
||||||
|
|
||||||
|
<wsdl:port name="HTTPPort" binding="tns:MGWBinding">
|
||||||
|
<wsdl:documentation>HTTP(S) port for the message gateway</wsdl:documentation>
|
||||||
|
<soap:address location="https://www.example.org/MessageGateway/" />
|
||||||
|
</wsdl:port>
|
||||||
|
</wsdl:service>
|
||||||
|
</wsdl:definitions>};
|
||||||
|
}
|
||||||
@@ -1,13 +1,19 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Test::More tests => 18;
|
use Test::More;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::LibXML;
|
|
||||||
use SOAP::WSDL::SAX::WSDLHandler;
|
use SOAP::WSDL::SAX::WSDLHandler;
|
||||||
use SOAP::WSDL::SAX::MessageHandler;
|
use SOAP::WSDL::SAX::MessageHandler;
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
|
|
||||||
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 18;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
my $path = dirname __FILE__;
|
my $path = dirname __FILE__;
|
||||||
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 12;
|
||||||
|
use lib '../lib';
|
||||||
|
use SOAP::WSDL::Expat::WSDLParser;
|
||||||
|
use File::Find;
|
||||||
|
use File::Basename;
|
||||||
|
|
||||||
|
my $path = dirname __FILE__;
|
||||||
|
my $wsdl;
|
||||||
|
|
||||||
|
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
|
||||||
|
ok( $wsdl = $parser->parse_file( "$path/../example/wsdl/globalweather.xml" ) );
|
||||||
|
|
||||||
|
$wsdl->create({
|
||||||
|
base_path => "$path/testlib",
|
||||||
|
typemap_prefix => "Test::Typemap::",
|
||||||
|
type_prefix => "Test::Type::",
|
||||||
|
element_prefix => "Test::Element::",
|
||||||
|
interface_prefix => "Test::Interface::",
|
||||||
|
});
|
||||||
|
|
||||||
|
# Check for created files (and dirs) - value is the number of entries
|
||||||
|
# with this (local) name
|
||||||
|
my %expected = (
|
||||||
|
'GetCitiesByCountry.pm' => 1,
|
||||||
|
'GetCitiesByCountryResponse.pm' => 1,
|
||||||
|
'GetWeather.pm' => 1,
|
||||||
|
'GetWeatherResponse.pm' => 1,
|
||||||
|
'string.pm' => 1,
|
||||||
|
'Element' => 1,
|
||||||
|
'Interface' => 1,
|
||||||
|
'GlobalWeather.pm' => 2,
|
||||||
|
'Typemap' => 1,
|
||||||
|
'Test' => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
File::Find::finddepth(
|
||||||
|
sub {
|
||||||
|
return if $_ eq '.';
|
||||||
|
ok $expected{ $_ }--, $_;
|
||||||
|
unlink $_ if -f $_;
|
||||||
|
rmdir $_ if -d $_;
|
||||||
|
},
|
||||||
|
"$path/testlib",
|
||||||
|
);
|
||||||
|
|
||||||
|
rmdir "$path/testlib";
|
||||||
@@ -1,13 +1,19 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Test::More tests => 1;
|
use Test::More;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use XML::LibXML;
|
|
||||||
use SOAP::WSDL::SAX::WSDLHandler;
|
use SOAP::WSDL::SAX::WSDLHandler;
|
||||||
use SOAP::WSDL::SAX::MessageHandler;
|
use SOAP::WSDL::SAX::MessageHandler;
|
||||||
use File::Path;
|
use File::Path;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
|
|
||||||
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
my $path = dirname __FILE__;
|
my $path = dirname __FILE__;
|
||||||
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More tests => 10;
|
||||||
|
use File::Path;
|
||||||
|
use File::Basename;
|
||||||
|
use lib '../lib';
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL::Expat::WSDLParser/);
|
||||||
|
|
||||||
|
my $path = dirname __FILE__;
|
||||||
|
|
||||||
|
my $parser = SOAP::WSDL::Expat::WSDLParser->new();
|
||||||
|
|
||||||
|
eval { $parser->parsefile( "$path/acceptance/wsdl/03_complexType-element-ref.wsdl" ) };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
fail("parsing WSDL");
|
||||||
|
die "Can't test without parsed WSDL: $@";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass("parsing XML");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $definitions = $parser->get_data();
|
||||||
|
|
||||||
|
|
||||||
|
my $type = $definitions->first_types()->find_type('urn:Test', 'testComplexTypeRef');
|
||||||
|
my $element = $definitions->first_types()->find_element('urn:Test', 'TestElement');
|
||||||
|
|
||||||
|
my $output = '';
|
||||||
|
ok $element->to_class({ wsdl => $definitions, prefix => 'Test::', output => \$output })
|
||||||
|
, 'generate element code';
|
||||||
|
ok eval $output, 'eval generated code';
|
||||||
|
|
||||||
|
$output = '';
|
||||||
|
ok $type->to_class({ wsdl => $definitions, prefix => 'Test::', output => \$output })
|
||||||
|
, 'generate complexType code with element ref=""';
|
||||||
|
ok eval $output, 'eval generated code';
|
||||||
|
|
||||||
|
my $obj = Test::testComplexTypeRef->new({
|
||||||
|
TestRef => 'test_ref',
|
||||||
|
Test2 => 'test2',
|
||||||
|
});
|
||||||
|
|
||||||
|
is $obj, '<TestRef >test_ref</TestRef><Test2 >test2</Test2 >', 'serialization';
|
||||||
|
|
||||||
|
$element = $definitions->first_types()->find_element('urn:Test', 'TestRef');
|
||||||
|
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
ok $element->to_class({ wsdl => $definitions, prefix => 'Test::', output => \$output })
|
||||||
|
, 'generate top level element ref code';
|
||||||
|
ok eval $output, 'eval generated code' . $@;
|
||||||
|
|
||||||
|
$obj = Test::TestRef->new({ value => 'test_ref' });
|
||||||
|
is $obj, '<TestRef xmlns="urn:Test" >test_ref</TestRef>', 'serialization';
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use Test::More;
|
||||||
|
use File::Path;
|
||||||
|
use File::Basename;
|
||||||
|
use lib '../lib';
|
||||||
|
|
||||||
|
if (eval "require XML::LibXML") {
|
||||||
|
plan tests => 11;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
plan skip_all => "Cannot test without XML::LibXML";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $path = dirname __FILE__;
|
||||||
|
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL::SAX::WSDLHandler/);
|
||||||
|
|
||||||
|
my $filter;
|
||||||
|
my $parser = XML::LibXML->new();
|
||||||
|
ok($filter = SOAP::WSDL::SAX::WSDLHandler->new(), "Object creation");
|
||||||
|
$parser->set_handler( $filter );
|
||||||
|
|
||||||
|
eval { $parser->parse_file( "$path/acceptance/wsdl/03_complexType-element-ref.wsdl" ) };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
fail("parsing WSDL");
|
||||||
|
die "Can't test without parsed WSDL: $@";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass("parsing XML");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $definitions = $filter->get_data();
|
||||||
|
my $type = $definitions->first_types()->find_type('urn:Test', 'testComplexTypeRef');
|
||||||
|
|
||||||
|
my $element = $definitions->first_types()->find_element('urn:Test', 'TestElement');
|
||||||
|
|
||||||
|
my $output;
|
||||||
|
|
||||||
|
ok $element->to_class({ wsdl => $definitions, prefix => 'Test::', output => \$output })
|
||||||
|
, 'generate element code';
|
||||||
|
|
||||||
|
ok eval $output, 'eval generated code';
|
||||||
|
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
ok $type->to_class({ wsdl => $definitions, prefix => 'Test::', output => \$output })
|
||||||
|
, 'generate complexType code with element ref=""';
|
||||||
|
|
||||||
|
ok eval $output, 'eval generated code';
|
||||||
|
|
||||||
|
my $obj = Test::testComplexTypeRef->new({
|
||||||
|
TestRef => 'test_ref',
|
||||||
|
Test2 => 'test2',
|
||||||
|
});
|
||||||
|
|
||||||
|
is $obj, '<TestRef >test_ref</TestRef><Test2 >test2</Test2 >', 'serialization';
|
||||||
|
|
||||||
|
$element = $definitions->first_types()->find_element('urn:Test', 'TestRef');
|
||||||
|
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
ok $element->to_class({ wsdl => $definitions, prefix => 'Test::', output => \$output })
|
||||||
|
, 'generate top level element ref code';
|
||||||
|
|
||||||
|
ok eval $output, 'eval generated code' . $@;
|
||||||
|
|
||||||
|
# print $output;
|
||||||
|
|
||||||
|
$obj = Test::TestRef->new({ value => 'test_ref' });
|
||||||
|
|
||||||
|
is $obj, '<TestRef xmlns="urn:Test" >test_ref</TestRef>', 'serialization';
|
||||||
@@ -5,7 +5,6 @@ use Test::More tests => 2;
|
|||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
use lib 'lib';
|
use lib 'lib';
|
||||||
use lib 't/lib';
|
use lib 't/lib';
|
||||||
use XML::LibXML;
|
|
||||||
use SOAP::WSDL::SAX::MessageHandler;
|
use SOAP::WSDL::SAX::MessageHandler;
|
||||||
|
|
||||||
use_ok(qw/SOAP::WSDL::Expat::MessageParser/);
|
use_ok(qw/SOAP::WSDL::Expat::MessageParser/);
|
||||||
@@ -13,7 +12,6 @@ use_ok(qw/SOAP::WSDL::Expat::MessageParser/);
|
|||||||
use MyComplexType;
|
use MyComplexType;
|
||||||
use MyElement;
|
use MyElement;
|
||||||
use MySimpleType;
|
use MySimpleType;
|
||||||
use Benchmark;
|
|
||||||
|
|
||||||
my $xml = q{<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
my $xml = q{<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
|
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
|
||||||
@@ -26,13 +24,6 @@ my $parser = SOAP::WSDL::Expat::MessageParser->new({
|
|||||||
class_resolver => 'FakeResolver'
|
class_resolver => 'FakeResolver'
|
||||||
});
|
});
|
||||||
|
|
||||||
my $libxml = XML::LibXML->new();
|
|
||||||
my $handler = SOAP::WSDL::SAX::MessageHandler->new({
|
|
||||||
class_resolver => 'FakeResolver',
|
|
||||||
});
|
|
||||||
$libxml->set_handler( $handler );
|
|
||||||
|
|
||||||
|
|
||||||
$parser->parse( $xml );
|
$parser->parse( $xml );
|
||||||
|
|
||||||
is $parser->get_data(), q{<MyAtomicComplexTypeElement xmlns="urn:Test" >}
|
is $parser->get_data(), q{<MyAtomicComplexTypeElement xmlns="urn:Test" >}
|
||||||
|
|||||||
@@ -0,0 +1,335 @@
|
|||||||
|
package TopElement;
|
||||||
|
use Class::Std::Storable;
|
||||||
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
|
use Memoize;
|
||||||
|
|
||||||
|
memoize('_get_handlers');
|
||||||
|
|
||||||
|
use base qw(SOAP::WSDL::XSD::Typelib::Element
|
||||||
|
SOAP::WSDL::XSD::Typelib::ComplexType
|
||||||
|
);
|
||||||
|
{
|
||||||
|
my %TestElement_of :ATTR();
|
||||||
|
my $CLASS_OF_REF = { TestElement => 'TestElement' };
|
||||||
|
|
||||||
|
__PACKAGE__->_factory( [ 'TestElement' ],
|
||||||
|
{ 'TestElement' => \%TestElement_of, },
|
||||||
|
{ TestElement => 'TestElement' },
|
||||||
|
);
|
||||||
|
|
||||||
|
sub get_xmlns { 'urn:Test' };
|
||||||
|
__PACKAGE__->__set_name('TopElement');
|
||||||
|
__PACKAGE__->__set_nillable(1);
|
||||||
|
|
||||||
|
sub _get_handlers {
|
||||||
|
my $self = shift;
|
||||||
|
my $parser = shift;
|
||||||
|
|
||||||
|
return {
|
||||||
|
Start => $parser->start_tag({
|
||||||
|
class_of => $CLASS_OF_REF,
|
||||||
|
handler_of => {
|
||||||
|
TestElement => TestElement->_get_handlers( $parser ),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
End => $parser->end_top_tag( ),
|
||||||
|
Char => undef,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
|
||||||
|
package TestElement;
|
||||||
|
use Class::Std::Storable;
|
||||||
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
|
|
||||||
|
use Memoize;
|
||||||
|
memoize('_get_handlers');
|
||||||
|
|
||||||
|
use base qw(
|
||||||
|
SOAP::WSDL::XSD::Typelib::Element
|
||||||
|
SOAP::WSDL::XSD::Typelib::ComplexType
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
my %test_of :ATTR();
|
||||||
|
my %test2_of :ATTR();
|
||||||
|
|
||||||
|
my $CLASS_OF_REF = {
|
||||||
|
test => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
test2 => 'SOAP::WSDL::XSD::Typelib::Builtin::string'
|
||||||
|
};
|
||||||
|
|
||||||
|
__PACKAGE__->_factory( [ 'test', 'test2' ],
|
||||||
|
{ test => \%test_of, test2 => \%test2_of, },
|
||||||
|
$CLASS_OF_REF,
|
||||||
|
);
|
||||||
|
|
||||||
|
sub get_xmlns { 'urn:Test' };
|
||||||
|
__PACKAGE__->__set_name('TestElement');
|
||||||
|
__PACKAGE__->__set_nillable(1);
|
||||||
|
|
||||||
|
sub _get_handlers {
|
||||||
|
my $self = shift;
|
||||||
|
my $parser = shift;
|
||||||
|
|
||||||
|
return {
|
||||||
|
Start => $parser->start_tag({
|
||||||
|
class_of => $CLASS_OF_REF,
|
||||||
|
handler_of =>
|
||||||
|
{
|
||||||
|
map { ( $_ => $CLASS_OF_REF->{$_}->_get_handlers( $parser ) )}
|
||||||
|
keys %{ $CLASS_OF_REF }
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
End => $parser->end_tag(),
|
||||||
|
Char => undef,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1;
|
||||||
|
|
||||||
|
package TestResolver;
|
||||||
|
|
||||||
|
sub get_class {
|
||||||
|
my $path = join('/', @{ $_[1] });
|
||||||
|
my $class = {
|
||||||
|
'TestElement' => 'TestElement',
|
||||||
|
'TestElement/test' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
'TestElement/test2' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
'TopElement' => 'TopElement',
|
||||||
|
'TopElement/TestElement' => 'TestElement',
|
||||||
|
'TopElement/TestElement/test' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
'TopElement/TestElement/test2' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
};
|
||||||
|
return $class->{ $path };
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
package main;
|
||||||
|
|
||||||
|
use Test::More qw/no_plan/; # TODO: change to tests => N;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use lib '../../lib';
|
||||||
|
|
||||||
|
use_ok('SOAP::WSDL::Expat::MessageParser');
|
||||||
|
use_ok('SOAP::WSDL::Expat::MessageSubParser');
|
||||||
|
my $obj;
|
||||||
|
|
||||||
|
ok($obj = SOAP::WSDL::Expat::MessageSubParser->new(), "Object creation");
|
||||||
|
|
||||||
|
#my $test = $obj->start_tag({
|
||||||
|
# order => [],
|
||||||
|
# class_of => {
|
||||||
|
# test => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
# test2 => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
# },
|
||||||
|
# handler_of => {
|
||||||
|
# test => {
|
||||||
|
# Char => $obj->characters(),
|
||||||
|
# },
|
||||||
|
# test2 => {
|
||||||
|
# Char => $obj->characters(),
|
||||||
|
# },
|
||||||
|
# }
|
||||||
|
#});
|
||||||
|
#
|
||||||
|
#my $handlers = {
|
||||||
|
# Start => $test,
|
||||||
|
# End => $obj->end_tag(),
|
||||||
|
#};
|
||||||
|
#
|
||||||
|
#my $parser = $obj->initialize( $handlers );
|
||||||
|
#
|
||||||
|
#$parser->parsestring('<test>Test</test>');
|
||||||
|
#is $obj->get_data(), 'Test', 'Parse simple XML';
|
||||||
|
#
|
||||||
|
#my $element = $obj->start_tag({
|
||||||
|
# order => [],
|
||||||
|
# class_of => {
|
||||||
|
# TestElement => 'TestElement',
|
||||||
|
# },
|
||||||
|
# handler_of => {
|
||||||
|
# TestElement => {
|
||||||
|
# Start => $obj->start_tag({
|
||||||
|
# order => [],
|
||||||
|
# class_of => {
|
||||||
|
# test => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
# test2 => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
# },
|
||||||
|
# handler_of => {
|
||||||
|
# test => {
|
||||||
|
# Char => $obj->characters(),
|
||||||
|
# },
|
||||||
|
# test2 => {
|
||||||
|
# Char => $obj->characters(),
|
||||||
|
# },
|
||||||
|
# }
|
||||||
|
# }),
|
||||||
|
# End => $obj->end_tag(),
|
||||||
|
# Char => undef,
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#});
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#$handlers = {
|
||||||
|
# Start => $element,
|
||||||
|
# End => $obj->end_tag(),
|
||||||
|
# Char => undef,
|
||||||
|
#};
|
||||||
|
#
|
||||||
|
#$parser = $obj->initialize( TestElement->_get_parser( $obj ) );
|
||||||
|
#
|
||||||
|
#my $xml = '<TestElement xmlns="urn:Test">
|
||||||
|
# <test>Test</test>
|
||||||
|
# <test2>Test2</test2>
|
||||||
|
#</TestElement>';
|
||||||
|
#
|
||||||
|
#$parser->parsestring($xml);
|
||||||
|
#
|
||||||
|
#is $obj->get_data()
|
||||||
|
# , '<TestElement xmlns="urn:Test" ><test >Test</test ><test2 >Test2</test2 ></TestElement>'
|
||||||
|
# , 'Parse && serialize ComplexType Element';
|
||||||
|
#
|
||||||
|
|
||||||
|
#my $mp = SOAP::WSDL::Expat::MessageParser->new({
|
||||||
|
# class_resolver => 'TestResolver',
|
||||||
|
#});
|
||||||
|
#
|
||||||
|
#$mp->parse( $xml );
|
||||||
|
|
||||||
|
#use Benchmark;
|
||||||
|
#
|
||||||
|
#timethese 1000 , {
|
||||||
|
# mp => sub { $mp->parse($xml) },
|
||||||
|
# 'sub_p' => sub { $obj->initialize( $handlers )->parse( $xml ) },
|
||||||
|
#
|
||||||
|
#};
|
||||||
|
|
||||||
|
#my $top = $obj->start_tag({
|
||||||
|
# order => [],
|
||||||
|
# class_of => {
|
||||||
|
# TopElement => 'TopElement',
|
||||||
|
# },
|
||||||
|
# handler_of => {
|
||||||
|
# TopElement => {
|
||||||
|
# Start => $obj->start_tag({
|
||||||
|
# order => [ 'TestElement', ],
|
||||||
|
# class_of => {
|
||||||
|
# TestElement => 'TestElement',
|
||||||
|
# },
|
||||||
|
# handler_of => {
|
||||||
|
# TestElement => {
|
||||||
|
# Start => $obj->start_tag({
|
||||||
|
# order => ['test', 'test2'],
|
||||||
|
# class_of => {
|
||||||
|
# test => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
# test2 => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
|
||||||
|
# },
|
||||||
|
# handler_of => {
|
||||||
|
# test => {
|
||||||
|
# Char => $obj->characters(),
|
||||||
|
# },
|
||||||
|
# test2 => {
|
||||||
|
# Char => $obj->characters(),
|
||||||
|
# },
|
||||||
|
# },
|
||||||
|
# occurs_of => {
|
||||||
|
# test => { max => 1 },
|
||||||
|
# }
|
||||||
|
# }),
|
||||||
|
# End => $obj->end_tag(),
|
||||||
|
# Char => undef,
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# })
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#});
|
||||||
|
|
||||||
|
my $top = $obj->start_tag({
|
||||||
|
class_of => {
|
||||||
|
TopElement => 'TopElement',
|
||||||
|
},
|
||||||
|
handler_of => {
|
||||||
|
TopElement => TopElement->_get_handlers( $obj ),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
my $parser = $obj->initialize( { Start => $top , End => $obj->end_tag() , Char => undef } );
|
||||||
|
|
||||||
|
my $xml = '
|
||||||
|
<TopElement xmlns="urn:Test">
|
||||||
|
<TestElement>
|
||||||
|
<test>Test</test>
|
||||||
|
<test2>Test2</test2>
|
||||||
|
</TestElement>
|
||||||
|
<TestElement>
|
||||||
|
<test>Test</test>
|
||||||
|
<test2>Test2</test2>
|
||||||
|
</TestElement>
|
||||||
|
<TestElement>
|
||||||
|
<test>Test</test>
|
||||||
|
<test2>Test2</test2>
|
||||||
|
</TestElement>
|
||||||
|
<TestElement>
|
||||||
|
<test>Test</test>
|
||||||
|
<test2>Test2</test2>
|
||||||
|
</TestElement>
|
||||||
|
<TestElement>
|
||||||
|
<test>Test</test>
|
||||||
|
<test2>Test2</test2>
|
||||||
|
</TestElement>
|
||||||
|
<TestElement>
|
||||||
|
<test>Test</test>
|
||||||
|
<test2>Test2</test2>
|
||||||
|
</TestElement>
|
||||||
|
</TopElement>';
|
||||||
|
|
||||||
|
$parser->parsestring($xml);
|
||||||
|
|
||||||
|
# print $obj->get_data();
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
# TODO factor out into benchmark suite
|
||||||
|
|
||||||
|
use XML::Simple;
|
||||||
|
use Benchmark;
|
||||||
|
|
||||||
|
my $mp = SOAP::WSDL::Expat::MessageParser->new({
|
||||||
|
class_resolver => 'TestResolver',
|
||||||
|
});
|
||||||
|
$mp->parse( $xml );
|
||||||
|
|
||||||
|
$top = $obj->start_tag({
|
||||||
|
class_of => {
|
||||||
|
TopElement => 'TopElement',
|
||||||
|
},
|
||||||
|
handler_of => {
|
||||||
|
TopElement => TopElement->_get_handlers( $obj ),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
my $top_end = $obj->end_top_tag();
|
||||||
|
$parser = $obj->initialize( { Start => $top , End => $top_end, , Char => undef } );
|
||||||
|
$parser->parse( $xml ),
|
||||||
|
|
||||||
|
print "DATA:" . $obj->get_data(), "\n";
|
||||||
|
|
||||||
|
|
||||||
|
# $XML::Simple::PREFERRED_PARSER = 'XML::SAX::Expat';
|
||||||
|
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
|
||||||
|
|
||||||
|
timethese 500 , {
|
||||||
|
'typemap' => sub { $mp->parse($xml) },
|
||||||
|
'sub_tree' => sub {
|
||||||
|
my $parser = $obj->initialize( { Start => $top , End => $top_end, , Char => undef } );
|
||||||
|
$parser->parse( $xml ),
|
||||||
|
},
|
||||||
|
'XML::Simple' => sub { XMLin( $xml ); }
|
||||||
|
};
|
||||||
@@ -0,0 +1,411 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use diagnostics;
|
||||||
|
use Test::More tests => 7;
|
||||||
|
use Data::Dumper;
|
||||||
|
use lib '../lib';
|
||||||
|
|
||||||
|
eval {
|
||||||
|
require Test::XML;
|
||||||
|
import Test::XML;
|
||||||
|
};
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL::Expat::WSDLParser/);
|
||||||
|
|
||||||
|
my $parser;
|
||||||
|
ok $parser = SOAP::WSDL::Expat::WSDLParser->new(), "Object creation";
|
||||||
|
|
||||||
|
$parser->parse( xml() );
|
||||||
|
|
||||||
|
eval { $parser->parse( xml() ) };
|
||||||
|
if ($@)
|
||||||
|
{
|
||||||
|
fail("parsing WSDL");
|
||||||
|
die "Can't test without parsed WSDL: " , Dumper $@;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass("parsing XML");
|
||||||
|
}
|
||||||
|
|
||||||
|
my $wsdl;
|
||||||
|
ok $wsdl = $parser->get_data() , "get object tree";
|
||||||
|
|
||||||
|
my $schema = $wsdl->first_types()->get_schema()->[1] || die "No schema !";
|
||||||
|
|
||||||
|
my $element = $schema->find_element(
|
||||||
|
'http://www.example.org/MessageGateway2/'
|
||||||
|
, 'EnqueueMessage'
|
||||||
|
);
|
||||||
|
|
||||||
|
ok $element, 'find element';
|
||||||
|
is $element->get_xmlns()->{ 'http://www.example.org/MessageGateway2/' }, 'tns', 'Namespace definition';
|
||||||
|
|
||||||
|
|
||||||
|
my $opt = {
|
||||||
|
typelib => $wsdl->first_types,
|
||||||
|
readable => 1,
|
||||||
|
autotype => 0,
|
||||||
|
namespace => { 'http://www.example.org/MessageGateway2/' => 'tns',
|
||||||
|
'http://www.w3.org/2001/XMLSchema' => 'xsd',
|
||||||
|
'http://schemas.xmlsoap.org/wsdl/' => 'wsdl',
|
||||||
|
},
|
||||||
|
indent => "",
|
||||||
|
};
|
||||||
|
|
||||||
|
my $data = { EnqueueMessage => {
|
||||||
|
MMessage => {
|
||||||
|
MRecipientURI => 'anyURI',
|
||||||
|
MSenderAddress => 'a string',
|
||||||
|
MMessageContent => 'a string',
|
||||||
|
MSubject => 'a string',
|
||||||
|
MDeliveryReportRecipientURI => 'anyURI',
|
||||||
|
MKeepalive => {
|
||||||
|
MKeepaliveTimeout => 1234567,
|
||||||
|
MKeepaliveErrorPolicy => ' ( suppress | report ) ',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SKIP: { skip_without_test_xml();
|
||||||
|
is_xml( $wsdl->find_message(
|
||||||
|
"http://www.example.org/MessageGateway2/" ,'EnqueueMessageRequest'
|
||||||
|
)->first_part()->serialize( 'test', $data, $opt ),
|
||||||
|
xml_message()
|
||||||
|
, "Serialized message part"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub skip_without_test_xml {
|
||||||
|
skip("Test::XML not available", 1) if (not $Test::XML::VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub xml_message {
|
||||||
|
return
|
||||||
|
q{<EnqueueMessage xmlns="http://www.example.org/MessageGateway2/">
|
||||||
|
<MMessage>
|
||||||
|
<MRecipientURI>anyURI</MRecipientURI>
|
||||||
|
<MSenderAddress>a string</MSenderAddress>
|
||||||
|
<MMessageContent>a string</MMessageContent>
|
||||||
|
<MSubject>a string</MSubject>
|
||||||
|
<MDeliveryReportRecipientURI>anyURI</MDeliveryReportRecipientURI>
|
||||||
|
<MKeepalive>
|
||||||
|
<MKeepaliveTimeout>1234567</MKeepaliveTimeout>
|
||||||
|
<MKeepaliveErrorPolicy> ( suppress | report ) </MKeepaliveErrorPolicy>
|
||||||
|
</MKeepalive>
|
||||||
|
</MMessage>
|
||||||
|
</EnqueueMessage>
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub xml {
|
||||||
|
return q{<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wsdl:definitions name="MessageGateway"
|
||||||
|
targetNamespace="http://www.example.org/MessageGateway2/"
|
||||||
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
xmlns:tns="http://www.example.org/MessageGateway2/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
||||||
|
<wsdl:types>
|
||||||
|
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
targetNamespace="http://www.example.org/MessageGateway2/">
|
||||||
|
|
||||||
|
<xsd:element name="EnqueueMessage" type="tns:TEnqueueMessage"
|
||||||
|
xmlns:tns="http://www.example.org/MessageGateway2/"
|
||||||
|
>
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Enqueue message request element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
<xsd:complexType name="TMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A type containing all elements of a message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MRecipientURI" type="xsd:anyURI" minOccurs="1"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:documentation>
|
||||||
|
The recipient in URI notaitions. Valid URI schemas are: mailto:, sms:,
|
||||||
|
phone:. Not all URI schemas need to be implemented at the current
|
||||||
|
implementation stage.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MSenderAddress" type="xsd:string" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
E-Mail sender address. Ignored for all but mailto: recipient URIs.
|
||||||
|
</xsd:documentation>
|
||||||
|
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MMessageContent" type="xsd:string" minOccurs="1"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Message Content.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MSubject" type="xsd:string" minOccurs="0" maxOccurs="1">
|
||||||
|
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Message Subject. Ignored for all but mailto: URIs
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MDeliveryReportRecipientURI" type="xsd:anyURI" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
|
||||||
|
URI to send a delivery report to. May be of one of the following schemes:
|
||||||
|
mailto:, http:, https:. Reports to mailto: URIs are sent as plaintext,
|
||||||
|
reports to http(s) URIs are sent as SOAP requests following the
|
||||||
|
MessageGatewayClient service definition.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MKeepalive" type="tns:TKeepalive" minOccurs="0"
|
||||||
|
maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Container for keepalive information. May be missing.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepalive">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Type containing keeplive information.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
|
||||||
|
<xsd:element name="MKeepaliveTimeout" type="xsd:double">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Keepalive timeout. The keepalive timeout spezifies how long the sending of
|
||||||
|
a message will be delayed waiting for keepalive updates. If a keepalive
|
||||||
|
update is received during this period, the timeout will be reset. If not,
|
||||||
|
the message will be sent after the timeout has expired.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="MKeepaliveErrorPolicy" minOccurs="0" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:documentation>
|
||||||
|
Policy to comply to in case of system errors. Valid values are "suppress"
|
||||||
|
and "report". If the policy is set to "suppress", keepalive messages will
|
||||||
|
not be sent to their recipients in case of partial system failure, even if
|
||||||
|
the keepalive has expired. This may result in "false negatives", i.e.
|
||||||
|
messages may not be sent, even though their keepalive has expired. If the
|
||||||
|
value is "report", keepalive messages will be sent from any cluster node.
|
||||||
|
This may result in "false positive" alerts.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:string">
|
||||||
|
<xsd:enumeration value="suppress"></xsd:enumeration>
|
||||||
|
<xsd:enumeration value="report"></xsd:enumeration>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Type containing a message ID.</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessageID" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepliveMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Type containing all elements of a keppalive update / remove request.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessageID" type="xsd:string" minOccurs="1" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
The ID for the message to update / remove
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
<xsd:element name="MAction" minOccurs="1" maxOccurs="1">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
The action to perform. Valid values are: "remove", "update". On "remove",
|
||||||
|
the message with the ID specified will be removed from the queue, thus it
|
||||||
|
will never be sent, even if it's timeout expires. On "update" the
|
||||||
|
keepalive timeout of the corresponding message will be reset.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:simpleType>
|
||||||
|
<xsd:restriction base="xsd:string">
|
||||||
|
<xsd:enumeration value="remove"></xsd:enumeration>
|
||||||
|
<xsd:enumeration value="update"></xsd:enumeration>
|
||||||
|
</xsd:restriction>
|
||||||
|
</xsd:simpleType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
<xsd:element name="KeepaliveMessage" type="tns:TKeepaliveMessageRequest">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Keepalive message request element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="KeepaliveMessageResponse" type="tns:TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Response element for a keepalive request</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="EnqueueMessageResponse" type="tns:TMessageID">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>Enqueue message response element</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="TEnqueueMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A complex type containing one element: The message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MMessage" type="tns:TMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Element containing a message to enqueue.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
|
|
||||||
|
<xsd:complexType name="TKeepaliveMessageRequest">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
A complex type containing one element: The keepalive message to process.
|
||||||
|
</xsd:documentation>
|
||||||
|
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="MKeepaliveMessage" type="tns:TKeepliveMessage">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>
|
||||||
|
Element containing a keepalive message to process.
|
||||||
|
</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:element>
|
||||||
|
|
||||||
|
</xsd:sequence>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:schema>
|
||||||
|
</wsdl:types>
|
||||||
|
<wsdl:message name="EnqueueMessageRequest">
|
||||||
|
<wsdl:part name="parameters" element="tns:EnqueueMessage">
|
||||||
|
<wsdl:documentation>inputparameters for EnqueueMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="EnqueueMessageResponse">
|
||||||
|
<wsdl:part name="parameters" element="tns:EnqueueMessageResponse">
|
||||||
|
<wsdl:documentation>outputparameters for EnqueueMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="KeepaliveMessageRequest">
|
||||||
|
<wsdl:part name="parameters" element="tns:KeepaliveMessage">
|
||||||
|
|
||||||
|
<wsdl:documentation>input parameters for KeepaliveMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
<wsdl:message name="KeepaliveMessageResponse">
|
||||||
|
<wsdl:part name="parameters" element="tns:KeepaliveMessageResponse">
|
||||||
|
<wsdl:documentation>output parameters for KeepaliveMessag</wsdl:documentation>
|
||||||
|
</wsdl:part>
|
||||||
|
</wsdl:message>
|
||||||
|
|
||||||
|
<wsdl:portType name="MGWPortType">
|
||||||
|
<wsdl:documentation>
|
||||||
|
generic port type for all methods required for sending messages over the mosaic
|
||||||
|
message gatewa
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:operation name="EnqueueMessage">
|
||||||
|
<wsdl:documentation>
|
||||||
|
This method is used to enqueue a normal (immediate send) or a delayed message with
|
||||||
|
keepalive functionality.
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:input message="tns:EnqueueMessageRequest"></wsdl:input>
|
||||||
|
<wsdl:output message="tns:EnqueueMessageResponse"></wsdl:output>
|
||||||
|
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="KeepaliveMessage">
|
||||||
|
<wsdl:documentation>
|
||||||
|
This method is used to update or remove a
|
||||||
|
keepalive message.
|
||||||
|
</wsdl:documentation>
|
||||||
|
<wsdl:input message="tns:KeepaliveMessageRequest"></wsdl:input>
|
||||||
|
<wsdl:output message="tns:KeepaliveMessageResponse"></wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:portType>
|
||||||
|
|
||||||
|
<wsdl:binding name="MGWBinding" type="tns:MGWPortType">
|
||||||
|
<wsdl:documentation>Generic binding for all (SOAP) port</wsdl:documentation>
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||||
|
<wsdl:operation name="EnqueueMessage">
|
||||||
|
<soap:operation soapAction="http://www.example.org/MessageGateway2/EnqueueMessage" />
|
||||||
|
<wsdl:input>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:input>
|
||||||
|
<wsdl:output>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
<wsdl:operation name="KeepaliveMessage">
|
||||||
|
<soap:operation
|
||||||
|
soapAction="http://www.example.org/MessageGateway2/KeepaliveMessage" />
|
||||||
|
<wsdl:input>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:input>
|
||||||
|
|
||||||
|
<wsdl:output>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</wsdl:output>
|
||||||
|
</wsdl:operation>
|
||||||
|
</wsdl:binding>
|
||||||
|
<wsdl:service name="MessageGateway">
|
||||||
|
<wsdl:documentation>
|
||||||
|
Web Service for sending messages over the mosaic message gatewa
|
||||||
|
</wsdl:documentation>
|
||||||
|
|
||||||
|
<wsdl:port name="HTTPPort" binding="tns:MGWBinding">
|
||||||
|
<wsdl:documentation>HTTP(S) port for the mosaic message gatewa</wsdl:documentation>
|
||||||
|
<soap:address location="https://www.example.org/MessageGateway/" />
|
||||||
|
</wsdl:port>
|
||||||
|
</wsdl:service>
|
||||||
|
</wsdl:definitions>};
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
use Test::More tests => 4;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use lib '../lib';
|
||||||
|
use lib 't/lib';
|
||||||
|
use lib 'lib';
|
||||||
|
use Cwd;
|
||||||
|
use File::Basename;
|
||||||
|
|
||||||
|
my $path = cwd();
|
||||||
|
my $name = basename $0;
|
||||||
|
$name =~s/\.t$//;
|
||||||
|
$name =~s/^t\///;
|
||||||
|
|
||||||
|
$path =~s{(/t)?/SOAP/WSDL}{}xms;
|
||||||
|
|
||||||
|
use_ok(qw/SOAP::WSDL/);
|
||||||
|
|
||||||
|
print "# SOAP::WSDL Version: $SOAP::WSDL::VERSION\n";
|
||||||
|
|
||||||
|
my $xml;
|
||||||
|
my $soap;
|
||||||
|
|
||||||
|
#2
|
||||||
|
ok( $soap = SOAP::WSDL->new(
|
||||||
|
wsdl => 'file://' . $path . '/t/acceptance/wsdl/' . $name . '.wsdl',
|
||||||
|
readable => 1,
|
||||||
|
no_dispatch => 1,
|
||||||
|
), 'Instantiated object' );
|
||||||
|
|
||||||
|
ok ($xml = $soap->call('test',
|
||||||
|
testAll => {
|
||||||
|
Test2 => 'Test2',
|
||||||
|
TestRef => 'TestRef'
|
||||||
|
}
|
||||||
|
), 'Serialized complexType' );
|
||||||
|
|
||||||
|
is $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><testAll>
|
||||||
|
<TestRef>TestRef</TestRef>
|
||||||
|
<Test2>Test2</Test2>
|
||||||
|
</testAll>
|
||||||
|
</SOAP-ENV:Body></SOAP-ENV:Envelope>}
|
||||||
|
, 'element ref="" serialization';
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
use Test::More tests => 6;
|
use Test::More tests => 8;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
@@ -39,6 +39,16 @@ ok ($xml = $soap->call('test',
|
|||||||
testElement1 => 'Test'
|
testElement1 => 'Test'
|
||||||
), 'Serialized (simple) element' );
|
), 'Serialized (simple) element' );
|
||||||
|
|
||||||
|
ok ($xml = $soap->call('testRef',
|
||||||
|
testElementRef => 'Test'
|
||||||
|
), 'Serialized (simple) element' );
|
||||||
|
|
||||||
|
is $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><testElementRef xmlns="urn:Test">Test</testElementRef>
|
||||||
|
</SOAP-ENV:Body></SOAP-ENV:Envelope>}
|
||||||
|
, 'element ref serialization result'
|
||||||
|
;
|
||||||
|
|
||||||
TODO: {
|
TODO: {
|
||||||
local $TODO="implement min/maxOccurs checks";
|
local $TODO="implement min/maxOccurs checks";
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
use strict;
|
|
||||||
use Test::More tests=> 5;
|
|
||||||
use Time::HiRes qw( gettimeofday tv_interval );
|
|
||||||
use lib '../..';
|
|
||||||
use Data::Dumper;
|
|
||||||
use Cwd;
|
|
||||||
use File::Basename;
|
|
||||||
use_ok qw/ SOAP::WSDL /;
|
|
||||||
use Benchmark;
|
|
||||||
|
|
||||||
print "# Testing SOAP::WSDL ". $SOAP::WSDL::VERSION."\n";
|
|
||||||
print "# Performance test with simple WSDL file\n";
|
|
||||||
my $soap;
|
|
||||||
my $data = {
|
|
||||||
sayHello => {
|
|
||||||
name => 'Mein Name',
|
|
||||||
givenName => 'Vorname',
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
my $name = basename( $0 );
|
|
||||||
$name =~s/\.(t|pl)$//;
|
|
||||||
|
|
||||||
my $path = cwd;
|
|
||||||
|
|
||||||
$path=~s{(/t)?/SOAP/WSDL}{}xms;
|
|
||||||
|
|
||||||
my $cacheDir;
|
|
||||||
if ($^O =~ m/Win/)
|
|
||||||
{
|
|
||||||
$cacheDir = 'C:/Temp/WSDL';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$cacheDir = '/tmp/';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my $t0 = [gettimeofday];
|
|
||||||
ok(
|
|
||||||
$soap=SOAP::WSDL->new(
|
|
||||||
wsdl => "file://$path/t/acceptance/wsdl/10_helloworld.asmx.xml",
|
|
||||||
no_dispatch => 1
|
|
||||||
),
|
|
||||||
"Create SOAP::WSDL object (".tv_interval ( $t0, [gettimeofday]) ."ms)" );
|
|
||||||
|
|
||||||
$soap->proxy('http://helloworld/helloworld.asmx');
|
|
||||||
|
|
||||||
$t0 = [gettimeofday];
|
|
||||||
eval{
|
|
||||||
$soap->wsdlinit(
|
|
||||||
caching => 1,
|
|
||||||
cache_directory => $cacheDir,
|
|
||||||
servicename => 'Service1' ) };
|
|
||||||
|
|
||||||
unless ($@) {
|
|
||||||
pass("wsdl file init (".tv_interval ( $t0, [gettimeofday]) ."s)");
|
|
||||||
} else {
|
|
||||||
fail( $@ );
|
|
||||||
}
|
|
||||||
$soap->readable(1);
|
|
||||||
|
|
||||||
$t0 = [gettimeofday];
|
|
||||||
ok( $soap->call("sayHello" , %{ $data }),
|
|
||||||
"1 x call pre-work (".tv_interval ( $t0, [gettimeofday]) ."s)") ;
|
|
||||||
|
|
||||||
$t0 = [gettimeofday];
|
|
||||||
ok($soap->call(sayHello => %{ $data }),
|
|
||||||
"1 x call pre-work (".tv_interval ( $t0, [gettimeofday]) ."s)" );
|
|
||||||
|
|
||||||
timethis 1000, sub { $soap->call(sayHello => %{ $data }) };
|
|
||||||
|
|
||||||
__END__
|
|
||||||
|
|
||||||
$t0 = [gettimeofday];
|
|
||||||
for (my $i=1; $i<100; $i++)
|
|
||||||
{
|
|
||||||
$soap->call(sayHello => %{ $data });
|
|
||||||
}
|
|
||||||
ok(1, "100 x call pre-work (".tv_interval ( $t0, [gettimeofday]) ."s)");
|
|
||||||
|
|
||||||
chdir $cwd;
|
|
||||||
@@ -1,25 +1,32 @@
|
|||||||
use Test::More tests => 2;
|
use Test::More tests => 4;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
|
use Date::Parse;
|
||||||
|
use Date::Format;
|
||||||
|
|
||||||
|
sub timezone {
|
||||||
|
my @time = strptime shift;
|
||||||
|
my $tz = strftime('%z', @time);
|
||||||
|
substr $tz, -2, 0, ':';
|
||||||
|
return $tz;
|
||||||
|
}
|
||||||
|
|
||||||
use_ok('SOAP::WSDL::XSD::Typelib::Builtin::dateTime');
|
use_ok('SOAP::WSDL::XSD::Typelib::Builtin::dateTime');
|
||||||
|
|
||||||
|
print "# timezone is " . timezone( scalar localtime(time) ) . "\n";
|
||||||
my $obj;
|
my $obj;
|
||||||
|
my %dates = (
|
||||||
|
'2007-12-31 12:32' => '2007-12-31T12:32:00',
|
||||||
|
'2007-08-31 00:32' => '2007-08-31T00:32:00',
|
||||||
|
'30 Aug 2007' => '2007-08-30T00:00:00',
|
||||||
|
);
|
||||||
|
|
||||||
$obj = SOAP::WSDL::XSD::Typelib::Builtin::dateTime->new();
|
while (my ($date, $converted) = each %dates ) {
|
||||||
|
|
||||||
$obj->set_value( '2037-12-31' );
|
$obj = SOAP::WSDL::XSD::Typelib::Builtin::dateTime->new();
|
||||||
|
$obj->set_value( $date );
|
||||||
is $obj->get_value() , '2037-12-31T00:00:00+01:00', 'conversion';
|
|
||||||
|
is $obj->get_value() , $converted . timezone($date), 'conversion with timezone';
|
||||||
$obj->set_value('2037-12-31T00:00:00.0000000+01:00');
|
}
|
||||||
|
$obj->set_value('2007-12-31T00:00:00.0000000+01:00');
|
||||||
|
|
||||||
|
|
||||||
# exit;
|
|
||||||
|
|
||||||
#~ use Benchmark;
|
|
||||||
#~ timethese 10000, {
|
|
||||||
#~ xml => sub { $obj->set_value('2037-12-31T00:00:00.0000000+01:00') },
|
|
||||||
#~ string => sub { $obj->set_value('2037-12-31') },
|
|
||||||
#~ }
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
use Test::More tests => 3;
|
|
||||||
use strict;
|
|
||||||
use warnings;
|
|
||||||
use lib '../lib';
|
|
||||||
|
|
||||||
use_ok('SOAP::WSDL::XSD::Typelib::Builtin::time');
|
|
||||||
my $obj;
|
|
||||||
|
|
||||||
$obj = SOAP::WSDL::XSD::Typelib::Builtin::time->new();
|
|
||||||
|
|
||||||
$obj->set_value( '12:23:03' );
|
|
||||||
is $obj->get_value() , '12:23:03+01:00', 'conversion';
|
|
||||||
|
|
||||||
$obj->set_value( '12:23:03.12345+01:00' ), ;
|
|
||||||
is $obj->get_value() , '12:23:03.12345+01:00', 'no conversion';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# exit;
|
|
||||||
|
|
||||||
#~ use Benchmark;
|
|
||||||
#~ timethese 10000, {
|
|
||||||
#~ xml => sub { $obj->set_value('2037-12-31T00:00:00.0000000+01:00') },
|
|
||||||
#~ string => sub { $obj->set_value('2037-12-31') },
|
|
||||||
#~ }
|
|
||||||
@@ -1,17 +1,35 @@
|
|||||||
use Test::More tests => 3;
|
use Test::More tests => 6;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use lib '../lib';
|
use lib '../lib';
|
||||||
|
use Date::Format;
|
||||||
|
use Date::Parse;
|
||||||
use_ok('SOAP::WSDL::XSD::Typelib::Builtin::date');
|
use_ok('SOAP::WSDL::XSD::Typelib::Builtin::date');
|
||||||
my $obj;
|
my $obj;
|
||||||
|
|
||||||
$obj = SOAP::WSDL::XSD::Typelib::Builtin::date->new();
|
sub timezone {
|
||||||
|
my @time = strptime shift;
|
||||||
|
my $tz = strftime('%z', @time);
|
||||||
|
substr $tz, -2, 0, ':';
|
||||||
|
return $tz;
|
||||||
|
}
|
||||||
|
|
||||||
$obj->set_value( '2037/12/31' );
|
my %dates = (
|
||||||
|
'2007/12/31' => '2007-12-31',
|
||||||
is $obj->get_value() , '2037-12-31+01:00', 'conversion';
|
'2007:08:31' => '2007-08-31',
|
||||||
|
'30 Aug 2007' => '2007-08-30',
|
||||||
|
);
|
||||||
|
|
||||||
|
while (my ($date, $converted) = each %dates ) {
|
||||||
|
|
||||||
|
$obj = SOAP::WSDL::XSD::Typelib::Builtin::date->new();
|
||||||
|
$obj->set_value( $date );
|
||||||
|
|
||||||
|
is $obj->get_value() , $converted . timezone($date), 'conversion';
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj->set_value('2007-12-31T00:00:00.0000000+01:00');
|
||||||
|
is $obj->get_value() , '2007-12-31+01:00', 'conversion from XML dateTime';
|
||||||
|
|
||||||
$obj->set_value( '2037-12-31' );
|
$obj->set_value( '2037-12-31' );
|
||||||
is $obj->get_value() , '2037-12-31', 'no conversion on match';
|
is $obj->get_value() , '2037-12-31', 'no conversion on match';
|
||||||
|
|||||||
@@ -1,72 +1,63 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<definitions name="urn:Test"
|
<definitions name="urn:Test" targetNamespace="urn:Test" xmlns:tns="urn:Test"
|
||||||
targetNamespace="urn:Test"
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
xmlns:tns="urn:Test"
|
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
|
||||||
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
|
||||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
|
||||||
>
|
|
||||||
<types>
|
<types>
|
||||||
<xsd:schema targetNamespace="urn:Test">
|
<xsd:schema targetNamespace="urn:Test">
|
||||||
<xsd:complexType name="testComplexTypeAll">
|
<xsd:complexType name="testComplexTypeAll">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>ComplexType Test</xsd:documentation>
|
||||||
ComplexType Test
|
</xsd:annotation>
|
||||||
</xsd:documentation>
|
|
||||||
</xsd:annotation>
|
|
||||||
<xsd:all>
|
<xsd:all>
|
||||||
<xsd:element name="Test1" type="xsd:string"/>
|
<xsd:element name="Test1" type="xsd:string" />
|
||||||
<xsd:element name="Test2" type="xsd:string" minOccurs="1"/>
|
<xsd:element name="Test2" type="xsd:string" minOccurs="1" />
|
||||||
</xsd:all>
|
</xsd:all>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:complexType name="testComplexTypeSequence">
|
<xsd:complexType name="testComplexTypeSequence">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation>
|
<xsd:documentation>ComplexType Test</xsd:documentation>
|
||||||
ComplexType Test
|
</xsd:annotation>
|
||||||
</xsd:documentation>
|
<xsd:sequence>
|
||||||
</xsd:annotation>
|
<xsd:element name="Test1" type="xsd:string" minOccurs="1" />
|
||||||
<xsd:sequence>
|
<xsd:element name="Test2" type="xsd:string" maxOccurs="1" />
|
||||||
<xsd:element name="Test1" type="xsd:string" minOccurs="1"/>
|
</xsd:sequence>
|
||||||
<xsd:element name="Test2" type="xsd:string" maxOccurs="1"/>
|
</xsd:complexType>
|
||||||
</xsd:sequence>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
|
|
||||||
</types>
|
</types>
|
||||||
<message name="testRequest">
|
<message name="testRequest">
|
||||||
<part name="testAll" type="tns:testComplexTypeAll"/>
|
<part name="testAll" type="tns:testComplexTypeAll" />
|
||||||
</message>
|
</message>
|
||||||
<message name="testResponse">
|
<message name="testResponse">
|
||||||
<part name="testAll" type="tns:testComplexTypeAll"/>
|
<part name="testAll" type="tns:testComplexTypeAll" />
|
||||||
</message>
|
</message>
|
||||||
<portType name="testPort">
|
<portType name="testPort">
|
||||||
<operation name="test">
|
<operation name="test">
|
||||||
<documentation>
|
<documentation>Test-Methode</documentation>
|
||||||
Test-Methode
|
|
||||||
</documentation>
|
|
||||||
|
|
||||||
<input message="tns:testRequest"/>
|
<input message="tns:testRequest" />
|
||||||
<output message="tns:testResponse"/>
|
<output message="tns:testResponse" />
|
||||||
</operation>
|
</operation>
|
||||||
</portType>
|
</portType>
|
||||||
|
|
||||||
<binding type="tns:testPort" name="testBinding">
|
<binding type="tns:testPort" name="testBinding">
|
||||||
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||||
<operation name="test">
|
<operation name="test">
|
||||||
<soap:operation soapAction="test">
|
<soap:operation soapAction="test">
|
||||||
<input>
|
<input>
|
||||||
<soap:body use="literal"/>
|
<soap:body use="literal" />
|
||||||
</input>
|
</input>
|
||||||
<output>
|
<output>
|
||||||
<soap:body use="literal"/>
|
<soap:body use="literal" />
|
||||||
</output>
|
</output>
|
||||||
</soap:operation>
|
</soap:operation>
|
||||||
</operation>
|
</operation>
|
||||||
</binding>
|
</binding>
|
||||||
<service name="testService">
|
<service name="testService">
|
||||||
<port name="testPort" binding="tns:testBinding">
|
<port name="testPort" binding="tns:testBinding">
|
||||||
<soap:address location="http://127.0.0.1/testPort" />
|
<soap:address location="http://127.0.0.1/testPort" />
|
||||||
</port>
|
</port>
|
||||||
</service>
|
</service>
|
||||||
</definitions>
|
</definitions>
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<definitions name="urn:Test" targetNamespace="urn:Test" xmlns:tns="urn:Test"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||||
|
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
|
||||||
|
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
|
||||||
|
<types>
|
||||||
|
<xsd:schema targetNamespace="urn:Test">
|
||||||
|
<xsd:element name="TestElement" type="xsd:string" />
|
||||||
|
<xsd:element name="TestRef" ref="tns:TestElement" />
|
||||||
|
<xsd:complexType name="testComplexTypeRef">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation>ComplexType Test</xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:all>
|
||||||
|
<xsd:element name="TestRef" ref="tns:TestElement" />
|
||||||
|
<xsd:element name="Test2" type="xsd:string" minOccurs="1" />
|
||||||
|
</xsd:all>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:schema>
|
||||||
|
</types>
|
||||||
|
<message name="testRequest">
|
||||||
|
<part name="testAll" type="tns:testComplexTypeRef" />
|
||||||
|
</message>
|
||||||
|
<message name="testResponse">
|
||||||
|
<part name="testAll" type="tns:testComplexTypeRef" />
|
||||||
|
</message>
|
||||||
|
<portType name="testPort">
|
||||||
|
<operation name="test">
|
||||||
|
<documentation>Test-Methode</documentation>
|
||||||
|
<input message="tns:testRequest" />
|
||||||
|
<output message="tns:testResponse" />
|
||||||
|
</operation>
|
||||||
|
</portType>
|
||||||
|
|
||||||
|
<binding type="tns:testPort" name="testBinding">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
|
||||||
|
<operation name="test">
|
||||||
|
<soap:operation soapAction="test">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal" />
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</operation>
|
||||||
|
</binding>
|
||||||
|
<service name="testService">
|
||||||
|
<port name="testPort" binding="tns:testBinding">
|
||||||
|
<soap:address location="http://127.0.0.1/testPort" />
|
||||||
|
</port>
|
||||||
|
</service>
|
||||||
|
</definitions>
|
||||||
@@ -9,12 +9,17 @@
|
|||||||
<types>
|
<types>
|
||||||
<xsd:schema targetNamespace="urn:Test">
|
<xsd:schema targetNamespace="urn:Test">
|
||||||
<xsd:element name="testElement1" type="xsd:string" />
|
<xsd:element name="testElement1" type="xsd:string" />
|
||||||
<xsd:element name="testElement2" type="xsd:int" />
|
<xsd:element name="testElement2" type="xsd:int" />
|
||||||
|
<xsd:element name="testElementRef" ref="tns:testElement1" />
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
</types>
|
</types>
|
||||||
<message name="testRequest">
|
<message name="testRequest">
|
||||||
<part name="testAll" element="tns:testElement1"/>
|
<part name="testAll" element="tns:testElement1"/>
|
||||||
</message>
|
</message>
|
||||||
|
<message name="testRefRequest">
|
||||||
|
<part name="testAll" element="tns:testElementRef"/>
|
||||||
|
</message>
|
||||||
|
|
||||||
<message name="testResponse">
|
<message name="testResponse">
|
||||||
<part name="testAll" type="tns:testElement1"/>
|
<part name="testAll" type="tns:testElement1"/>
|
||||||
</message>
|
</message>
|
||||||
@@ -27,10 +32,18 @@
|
|||||||
<input message="tns:testRequest"/>
|
<input message="tns:testRequest"/>
|
||||||
<output message="tns:testResponse"/>
|
<output message="tns:testResponse"/>
|
||||||
</operation>
|
</operation>
|
||||||
|
<operation name="testRef">
|
||||||
|
<documentation>
|
||||||
|
Test-Methode
|
||||||
|
</documentation>
|
||||||
|
|
||||||
|
<input message="tns:testRefRequest"/>
|
||||||
|
<output message="tns:testResponse"/>
|
||||||
|
</operation>
|
||||||
</portType>
|
</portType>
|
||||||
|
|
||||||
<binding type="tns:testPort" name="testBinding">
|
<binding type="tns:testPort" name="testBinding">
|
||||||
<operation name="test">
|
<operation name="test">
|
||||||
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
<soap:operation soapAction="test">
|
<soap:operation soapAction="test">
|
||||||
<input>
|
<input>
|
||||||
@@ -40,7 +53,18 @@
|
|||||||
<soap:body use="literal"/>
|
<soap:body use="literal"/>
|
||||||
</output>
|
</output>
|
||||||
</soap:operation>
|
</soap:operation>
|
||||||
</operation>
|
</operation>
|
||||||
|
<operation name="testRef">
|
||||||
|
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
|
||||||
|
<soap:operation soapAction="testRef">
|
||||||
|
<input>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</input>
|
||||||
|
<output>
|
||||||
|
<soap:body use="literal"/>
|
||||||
|
</output>
|
||||||
|
</soap:operation>
|
||||||
|
</operation>
|
||||||
</binding>
|
</binding>
|
||||||
<service name="testService">
|
<service name="testService">
|
||||||
<port name="testPort" binding="tns:testBinding">
|
<port name="testPort" binding="tns:testBinding">
|
||||||
|
|||||||
+1
-6
@@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
package MyElement;
|
package MyElement;
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
use SOAP::WSDL::XSD::Typelib::Builtin;
|
use SOAP::WSDL::XSD::Typelib::Builtin;
|
||||||
use base (
|
use base (
|
||||||
@@ -14,7 +13,6 @@ sub get_xmlns { 'urn:Test' };
|
|||||||
|
|
||||||
package MyComplexTypeElement;
|
package MyComplexTypeElement;
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
use MyComplexType;
|
use MyComplexType;
|
||||||
use base (
|
use base (
|
||||||
@@ -27,7 +25,6 @@ sub get_xmlns { 'urn:Test' };
|
|||||||
|
|
||||||
package MyTestElement;
|
package MyTestElement;
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
use SOAP::WSDL::XSD::Typelib::Builtin::string;
|
use SOAP::WSDL::XSD::Typelib::Builtin::string;
|
||||||
use base (
|
use base (
|
||||||
@@ -36,12 +33,11 @@ use base (
|
|||||||
);
|
);
|
||||||
|
|
||||||
__PACKAGE__->__set_name('MyTestElement');
|
__PACKAGE__->__set_name('MyTestElement');
|
||||||
|
|
||||||
sub get_xmlns { 'urn:Test' };
|
sub get_xmlns { 'urn:Test' };
|
||||||
|
|
||||||
package MyTestElement2;
|
package MyTestElement2;
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
use SOAP::WSDL::XSD::Typelib::Builtin;
|
use SOAP::WSDL::XSD::Typelib::Builtin;
|
||||||
use base (
|
use base (
|
||||||
@@ -57,7 +53,6 @@ sub get_xmlns { 'urn:Test' };
|
|||||||
package MyAtomicComplexTypeElement;
|
package MyAtomicComplexTypeElement;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Class::Std::Storable;
|
|
||||||
use SOAP::WSDL::XSD::Typelib::Element;
|
use SOAP::WSDL::XSD::Typelib::Element;
|
||||||
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
use SOAP::WSDL::XSD::Typelib::ComplexType;
|
||||||
use SOAP::WSDL::XSD::Typelib::Builtin;
|
use SOAP::WSDL::XSD::Typelib::Builtin;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package Typelib::Base;
|
package Typelib::Base;
|
||||||
use Class::Std::Storable;
|
use Class::Std::Storable;
|
||||||
|
|
||||||
sub mk_add_mutators {
|
sub mk_add_mutators {
|
||||||
my $class = shift;
|
my $class = shift;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package Typelib::TEnqueueMessage;
|
package Typelib::TEnqueueMessage;
|
||||||
use strict;
|
use strict;
|
||||||
use base qw(Typelib::Base);
|
use base qw(Typelib::Base);
|
||||||
use Class::Std::Storable;
|
|
||||||
|
|
||||||
my %MMessage_of :ATTR(:name<MMessage> :default<()>);
|
my %MMessage_of :ATTR(:name<MMessage> :default<()>);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package Typelib::TMessage;
|
package Typelib::TMessage;
|
||||||
use strict;
|
use strict;
|
||||||
use base qw(Typelib::Base);
|
use base qw(Typelib::Base);
|
||||||
use Class::Std::Storable;
|
|
||||||
|
|
||||||
my %MRecipientURI_of :ATTR(:name<MRecipientURI> :default<()>);
|
my %MRecipientURI_of :ATTR(:name<MRecipientURI> :default<()>);
|
||||||
my %MMessageContent_of :ATTR(:name<MMessageContent> :default<()>);
|
my %MMessageContent_of :ATTR(:name<MMessageContent> :default<()>);
|
||||||
|
|||||||
Reference in New Issue
Block a user