Compare commits

...

3 Commits

Author SHA1 Message Date
Martin Kutter
e58a27e2ad import SOAP-WSDL 2.00.03 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.03
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.03.tar.gz
2009-12-12 19:48:40 -08:00
Martin Kutter
915ee03cbe import SOAP-WSDL 2.00.02 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.02
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.02.tar.gz
2009-12-12 19:48:35 -08:00
Martin Kutter
745ce925c1 import SOAP-WSDL 2.00.01 from CPAN
git-cpan-module:   SOAP-WSDL
git-cpan-version:  2.00.01
git-cpan-authorid: MKUTTER
git-cpan-file:     authors/id/M/MK/MKUTTER/SOAP-WSDL-2.00.01.tar.gz
2009-12-12 19:48:32 -08:00
172 changed files with 3801 additions and 2582 deletions

View File

@@ -5,7 +5,7 @@ $build = Module::Build->new(
create_makefile_pl => 'small',
dist_abstract => 'SOAP with WSDL support',
dist_name => 'SOAP-WSDL',
dist_version => '2.00_33',
dist_version => '2.00.03',
module_name => 'SOAP::WSDL',
license => 'artistic',
requires => {
@@ -22,7 +22,7 @@ $build = Module::Build->new(
'Getopt::Long' => 0,
'List::Util' => 0,
'LWP::UserAgent' => 0,
'Template' => 0,
'Template' => q(2.18),
'Term::ReadKey' => 0,
'URI' => 0,
'XML::Parser::Expat' => 0,
@@ -41,7 +41,7 @@ $build = Module::Build->new(
'File::Spec' => 0,
'Storable' => 0,
'Test::More' => 0,
'Template' => 0,
'Template' => q(2.18),
'XML::Parser::Expat' => 0,
},
recursive_test_files => 1,

83
Changes
View File

@@ -1,7 +1,7 @@
Release notes for SOAP::WSDL 2.00_33
Release notes for SOAP::WSDL 2.00.03
-------
I'm proud to present a new pre-release version of SOAP::WSDL.
I'm proud to present a new release of SOAP::WSDL.
SOAP::WSDL is a toolkit for creating WSDL-based SOAP client interfaces in perl.
@@ -15,6 +15,8 @@ Features:
* Easy-to use API
o Automatically encodes perl data structures as message data
o Automatically sets HTTP headers right
o Datatypes provide hints on method names on calls to non-existant
methods
* Efficient documentation
o SOAP::WSDL::Manual guides you at getting your work done, not at
the module's internals
@@ -23,17 +25,90 @@ Features:
over 95% (excluding documentation - you wouldn't want to read
through it all).
* SOAP::Lite like look and feel
o Where possible, SOAP::WSDL mimics SOAP::Lite's API to allow easy migrations
o Where possible, SOAP::WSDL mimics SOAP::Lite's API to allow easy migration
* XML schema based class library for creating data objects
* High-performance XML parser
* Plugin support. SOAP::WSDL can be extended through plugins in various aspects.
The following plugins are supported:
o Transport plugins via SOAP::WSDL::Factory::Transport
o Serializer plugins via SOAP::WSDL::Factory::Serializer
o Deserializer plugins via SOAP::WSDL::Factory::Serializer
o Deserializer plugins via SOAP::WSDL::Factory::Deserializer
The following changes have been made:
2.00.03 - May 18 2008
The following bugs have been fixed (the numbers in square brackets are the
tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660921):
The numbers with # are CPAN RT IDs (http://rt.cpan.org/).
* [ 1966575 ] 2.00.02 produced bad code with complexType extensions
2.00.02 - May 16 2008
The following features were added (the numbers in square brackets are the
tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924):
* [ 1941134 ] Server for mod_perl2. Thanks to Noah Robin for contributing.
(I actually forgot to include it in 2.00.01)
The following bugs have been fixed (the numbers in square brackets are the
tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660921):
The numbers with # are CPAN RT IDs (http://rt.cpan.org/).
* [ 1943667 ] Error parsing complexType/extension
* [ 1960650 ] multi-level inheritance of complexTypes fails
* [ 1960319 ] ComplexType as_hash_ref returns objects on maximum depth
* [ 1943673 ] Relative schemaLocation="" URLs not resolved in <import>
* [ 1953598 ] Cannot set server and attribute prefixes with wsdl2perl
* [ 1941080 ] 017_generator.t (test 2) fails with Template-Toolkit 2.15
* [ 1949209 ] spelling/grammar in Mod_Perl2.pm
* [ 1950670 ] on_action removed in SOAP::WSDL >= 2.00
* #35346 element ref="" not handled properly
The following uncategorized improvements have been made:
2.00.01
The following features were added (the numbers in square brackets are the
tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660924):
* [ 1941134 ] Server for mod_perl2. Thanks to Noah Robin for contributing.
The following bugs have been fixed (the numbers in square brackets are the
tracker IDs from https://sourceforge.net/tracker/?group_id=111978&atid=660921):
The numbers with # are CPAN RT IDs (http://rt.cpan.org/).
* [ 1944368 ] SOAP/WSDL/XSD/Typelib/SimpleType.pm spelling
* [ 1944367 ] SOAP/WSDL/XSD/Typelib/ComplexType.pm spelling
* [ 1944364 ] SOAP/WSDL/XSD/Typelib/Builtin.pm spelling
* [ 1944362 ] SOAP/WSDL/SOAP/Typelib/Fault11.pm spelling
* [ 1944361 ] SOAP/WSDL/Generator/Visitor.pm spelling
* [ 1944360 ] SOAP/WSDL/Generator/Iterator/WSDL11.pm spelling
* [ 1944359 ] SOAP::WSDL::Factory::Transport spelling
* [ 1944355 ] SOAP::WSDL::Deserializer::XSD.pm spelling
Thanks to "nobody" for correcting these errors.
* [ 1942576 ] SOAP/WSDL/Deserializer/SOM.pm spelling.
* [ 1942568 ] SOAP/WSDL/Client.pm minor spelling/grammar/style cleanup.
* [ 1942562 ] WSDL.pm spelling corrections.
Thanks to Noah Robin for providing patches for these errors.
* #34642 booleans in WSDL attributes don't get converted to perl's
representation (for now - not all attributes covered yet)
* #34714: MessageParser misses character data in elements just below SOAP-ENV:Body
* #34688: wsdl2perl.pl croaks when WSDL operation uses a header
The following uncategorized improvements have been made:
* Storable freeze/thaw speedup in conjunction with upcoming version of
Class::Std::Fast
* improved server doc generation
* improved xsi:nil handling
* serializing an attribute from http://www.w3.org/XML/1998/namespace now
serializes it with xml: prefix. This should probably be moved into the
generator, to avoid testing every attribute
2.00_33 - Mar 30 2008
The following features were added (the numbers in square brackets are the

141
LICENSE
View File

@@ -2,6 +2,145 @@ SOAP::WSDL is dual licensed under the same terms as
Perl itself.
This means at your choice, either the Perl Artistic License, or
the GNU GPL version 1 or higher.
the GNU GPL version 1 or - at your choice - any higher version.
The GNU GPL can be obtained from
http://www.gnu.org/licenses/old-licenses/gpl-1.0.txt
Newer versions can be found at http://www.gnu.org/licenses/gpl.html
The Artistic License can be obtained from
http://dev.perl.org/licenses/artistic.html and is included below.
ARTISTIC LICENSE
================
The "Artistic License"
Preamble
The intent of this document is to state the conditions under which a
Package may be copied, such that the Copyright Holder maintains some
semblance of artistic control over the development of the package,
while giving the users of the package the right to use and distribute
the Package in a more-or-less customary fashion, plus the right to make
reasonable modifications.
Definitions:
"Package" refers to the collection of files distributed by the
Copyright Holder, and derivatives of that collection of files
created through textual modification.
"Standard Version" refers to such a Package if it has not been
modified, or has been modified in accordance with the wishes
of the Copyright Holder as specified below.
"Copyright Holder" is whoever is named in the copyright or
copyrights for the package.
"You" is you, if you're thinking about copying or distributing
this Package.
"Reasonable copying fee" is whatever you can justify on the
basis of media cost, duplication charges, time of people involved,
and so on. (You will not be required to justify it to the
Copyright Holder, but only to the computing community at large
as a market that must bear the fee.)
"Freely Available" means that no fee is charged for the item
itself, though there may be fees involved in handling the item.
It also means that recipients of the item may redistribute it
under the same conditions they received it.
1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
duplicate all of the original copyright notices and associated disclaimers.
2. You may apply bug fixes, portability fixes and other modifications
derived from the Public Domain or from the Copyright Holder. A Package
modified in such a way shall still be considered the Standard Version.
3. You may otherwise modify your copy of this Package in any way, provided
that you insert a prominent notice in each changed file stating how and
when you changed that file, and provided that you do at least ONE of the
following:
a) place your modifications in the Public Domain or otherwise make them
Freely Available, such as by posting said modifications to Usenet or
an equivalent medium, or placing the modifications on a major archive
site such as uunet.uu.net, or by allowing the Copyright Holder to include
your modifications in the Standard Version of the Package.
b) use the modified Package only within your corporation or organization.
c) rename any non-standard executables so the names do not conflict
with standard executables, which must also be provided, and provide
a separate manual page for each non-standard executable that clearly
documents how it differs from the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
4. You may distribute the programs of this Package in object code or
executable form, provided that you do at least ONE of the following:
a) distribute a Standard Version of the executables and library files,
together with instructions (in the manual page or equivalent) on where
to get the Standard Version.
b) accompany the distribution with the machine-readable source of
the Package with your modifications.
c) give non-standard executables non-standard names, and clearly
document the differences in manual pages (or equivalent), together
with instructions on where to get the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
5. You may charge a reasonable copying fee for any distribution of this
Package. You may charge any fee you choose for support of this
Package. You may not charge a fee for this Package itself. However,
you may distribute this Package in aggregate with other (possibly
commercial) programs as part of a larger (possibly commercial) software
distribution provided that you do not advertise this Package as a
product of your own. You may embed this Package's interpreter within
an executable of yours (by linking); this shall be construed as a mere
form of aggregation, provided that the complete Standard Version of the
interpreter is so embedded.
6. The scripts and library files supplied as input to or produced as
output from the programs of this Package do not automatically fall
under the copyright of this Package, but belong to whoever generated
them, and may be sold commercially, and may be aggregated with this
Package. If such scripts or library files are aggregated with this
Package via the so-called "undump" or "unexec" methods of producing a
binary executable image, then distribution of such an image shall
neither be construed as a distribution of this Package nor shall it
fall under the restrictions of Paragraphs 3 and 4, provided that you do
not represent such an executable image as a Standard Version of this
Package.
7. C subroutines (or comparably compiled subroutines in other
languages) supplied by you and linked into this Package in order to
emulate subroutines and variables of the language defined by this
Package shall not be considered part of this Package, but are the
equivalent of input as in Paragraph 6, provided these subroutines do
not change the language in any way that would cause it to fail the
regression tests for the language.
8. Aggregation of this Package with a commercial distribution is always
permitted provided that the use of this Package is embedded; that is,
when no overt attempt is made to make this Package's interfaces visible
to the end user of the commercial distribution. Such use shall not be
construed as a distribution of this Package.
9. The name of the Copyright Holder may not be used to endorse or promote
products derived from this software without specific prior written permission.
10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End

View File

@@ -1,12 +1,15 @@
benchmark/01_expat.t
benchmark/hello.pl
benchmark/MEMORY_FOOTPRINT
benchmark/person.pl
benchmark/person.xml
benchmark/person_profile.pl
benchmark/person_single.pl
benchmark/README
benchmark/XSD/01_anyType.t
benchmark/XSD/02_anySimpleType.t
benchmark/XSD/03_string.t
benchmark/XSD/strftime.pl
bin/wsdl2perl.pl
Build.PL
Changes
@@ -157,7 +160,9 @@ lib/SOAP/WSDL/Generator/Visitor.pm
lib/SOAP/WSDL/Generator/Visitor/Typelib.pm
lib/SOAP/WSDL/Generator/Visitor/Typemap.pm
lib/SOAP/WSDL/Manual.pod
lib/SOAP/WSDL/Manual/Cookbook.pod
lib/SOAP/WSDL/Manual/Deserializer.pod
lib/SOAP/WSDL/Manual/FAQ.pod
lib/SOAP/WSDL/Manual/Glossary.pod
lib/SOAP/WSDL/Manual/Parser.pod
lib/SOAP/WSDL/Manual/Serializer.pod
@@ -172,6 +177,7 @@ lib/SOAP/WSDL/PortType.pm
lib/SOAP/WSDL/Serializer/XSD.pm
lib/SOAP/WSDL/Server.pm
lib/SOAP/WSDL/Server/CGI.pm
lib/SOAP/WSDL/Server/Mod_Perl2.pm
lib/SOAP/WSDL/Service.pm
lib/SOAP/WSDL/SOAP/Address.pm
lib/SOAP/WSDL/SOAP/Body.pm
@@ -264,11 +270,8 @@ MANIFEST This list of files
META.yml
MIGRATING
README
SOAP-WSDL-2.00_32.tar
t/001_use.t
t/002_parse_wsdl.t
t/003_wsdl_based_serializer.t
t/004_parse_wsdl.t
t/006_client.t
t/007_envelope.t
t/008_client_wsdl_complexType.t
@@ -277,7 +280,6 @@ t/011_simpleType.t
t/012_element.t
t/013_complexType.t
t/016_client_object.t
t/017_generator.t
t/020_storable.t
t/095_copying.t
t/096_characters.t
@@ -315,6 +317,7 @@ t/acceptance/wsdl/email_account.wsdl
t/acceptance/wsdl/generator_test.wsdl
t/acceptance/wsdl/generator_test_dot_names.wsdl
t/acceptance/wsdl/generator_unsupported_test.wsdl
t/acceptance/wsdl/helloWorld_header.wsdl
t/acceptance/wsdl/import.xsd
t/acceptance/wsdl/import_loop.xsd
t/acceptance/wsdl/message_gateway.wsdl
@@ -322,9 +325,15 @@ t/acceptance/wsdl/nested_complextype.wsdl
t/acceptance/wsdl/WSDLParser-import.wsdl
t/acceptance/wsdl/WSDLParser-imported.wsdl
t/acceptance/wsdl/WSDLParser.wsdl
t/acceptance/wsdl/WSDLParser/import_cascade.xsd
t/acceptance/wsdl/WSDLParser/import_no_location.wsdl
t/acceptance/wsdl/WSDLParser/import_xsd_cascade.wsdl
t/acceptance/wsdl/WSDLParser/imported.xsd
t/acceptance/wsdl/WSDLParser/xsd_import_no_location.wsdl
t/acceptance/wsdl/WSDLParser_import_loop.wsdl
t/contributed.wsdl
t/Expat/03_wsdl.t
t/lib/Mod_Perl2Test.pm
t/lib/MyComplexType.pm
t/lib/MyElement.pm
t/lib/MySimpleType.pm
@@ -336,7 +345,6 @@ t/lib/Typelib/Base.pm
t/lib/Typelib/TEnqueueMessage.pm
t/lib/Typelib/TMessage.pm
t/SOAP/WSDL.t
t/SOAP/WSDL/01_use.t
t/SOAP/WSDL/02_port.t
t/SOAP/WSDL/03_complexType-all.t
t/SOAP/WSDL/03_complexType-choice.t
@@ -366,11 +374,11 @@ t/SOAP/WSDL/Expat/WSDLParser.t
t/SOAP/WSDL/Factory/Deserializer.t
t/SOAP/WSDL/Factory/Serializer.t
t/SOAP/WSDL/Factory/Transport.t
t/SOAP/WSDL/Generator/attr.pl
t/SOAP/WSDL/Generator/Template.t
t/SOAP/WSDL/Generator/Visitor.t
t/SOAP/WSDL/Generator/Visitor/Typemap.t
t/SOAP/WSDL/Generator/XSD.t
t/SOAP/WSDL/Generator/XSD_custom_resolver.t
t/SOAP/WSDL/Generator/XSD_dot_names.t
t/SOAP/WSDL/Generator/XSD_nested_complextype.t
t/SOAP/WSDL/Generator/XSD_unsupported.t
@@ -379,10 +387,11 @@ t/SOAP/WSDL/PortType.t
t/SOAP/WSDL/Serializer/XSD.t
t/SOAP/WSDL/Server.t
t/SOAP/WSDL/Server/CGI.t
t/SOAP/WSDL/Server/Mod_Perl2.t
t/SOAP/WSDL/Transport/01_Test.t
t/SOAP/WSDL/Transport/02_HTTP.t
t/SOAP/WSDL/Transport/acceptance/test2.xml
t/SOAP/WSDL/Transport/acceptance/test3.xml
t/SOAP/WSDL/Transport/HTTP.t
t/SOAP/WSDL/Typelib/Fault11.t
t/SOAP/WSDL/Types.t
t/SOAP/WSDL/XSD/Attribute.t

147
META.yml
View File

@@ -1,6 +1,6 @@
---
name: SOAP-WSDL
version: 2.00_33
version: 2.00.03
author:
- 'Martin Kutter <martin.kutter@fen-net.de>'
abstract: SOAP with WSDL support
@@ -17,7 +17,7 @@ requires:
Getopt::Long: 0
LWP::UserAgent: 0
List::Util: 0
Template: 0
Template: 2.18
Term::ReadKey: 0
URI: 0
XML::Parser::Expat: 0
@@ -35,197 +35,226 @@ build_requires:
List::Util: 0
Module::Build: 0
Storable: 0
Template: 0
Template: 2.18
Test::More: 0
XML::Parser::Expat: 0
provides:
SOAP::WSDL:
file: lib/SOAP/WSDL.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::Base:
file: lib/SOAP/WSDL/Base.pm
version: 2.00_27
version: 2.00.03
SOAP::WSDL::Binding:
file: lib/SOAP/WSDL/Binding.pm
version: 2.00.03
SOAP::WSDL::Client:
file: lib/SOAP/WSDL/Client.pm
version: 2.00_27
version: 2.00.03
SOAP::WSDL::Client::Base:
file: lib/SOAP/WSDL/Client/Base.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::Definitions:
file: lib/SOAP/WSDL/Definitions.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::Deserializer::Hash:
file: lib/SOAP/WSDL/Deserializer/Hash.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::Deserializer::SOM:
file: lib/SOAP/WSDL/Deserializer/SOM.pm
version: 2.00_24
version: 2.00.03
SOAP::WSDL::Deserializer::XSD:
file: lib/SOAP/WSDL/Deserializer/XSD.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::Expat::Base:
file: lib/SOAP/WSDL/Expat/Base.pm
version: 2.00_32
version: 2.00.03
SOAP::WSDL::Expat::Message2Hash:
file: lib/SOAP/WSDL/Expat/Message2Hash.pm
version: 2.00_27
version: 2.00.03
SOAP::WSDL::Expat::MessageParser:
file: lib/SOAP/WSDL/Expat/MessageParser.pm
version: 2.00_27
version: 2.00.03
SOAP::WSDL::Expat::MessageStreamParser:
file: lib/SOAP/WSDL/Expat/MessageStreamParser.pm
version: 2.00_24
version: 2.00.03
SOAP::WSDL::Expat::WSDLParser:
file: lib/SOAP/WSDL/Expat/WSDLParser.pm
version: 2.00.03
SOAP::WSDL::Factory::Deserializer:
file: lib/SOAP/WSDL/Factory/Deserializer.pm
version: 2.00_24
version: 2.00.03
SOAP::WSDL::Factory::Generator:
file: lib/SOAP/WSDL/Factory/Generator.pm
version: 2.00_24
version: 2.00.03
SOAP::WSDL::Factory::Serializer:
file: lib/SOAP/WSDL/Factory/Serializer.pm
version: 2.00_24
version: 2.00.03
SOAP::WSDL::Factory::Transport:
file: lib/SOAP/WSDL/Factory/Transport.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::Generator::Iterator::WSDL11:
file: lib/SOAP/WSDL/Generator/Iterator/WSDL11.pm
version: 2.00.03
SOAP::WSDL::Generator::PrefixResolver:
file: lib/SOAP/WSDL/Generator/PrefixResolver.pm
version: 2.00.03
SOAP::WSDL::Generator::Template:
file: lib/SOAP/WSDL/Generator/Template.pm
version: v2.0033
version: 2.00.03
SOAP::WSDL::Generator::Template::Plugin::XSD:
file: lib/SOAP/WSDL/Generator/Template/Plugin/XSD.pm
version: 2.00.03
SOAP::WSDL::Generator::Template::XSD:
file: lib/SOAP/WSDL/Generator/Template/XSD.pm
version: 2.00_27
version: 2.00.03
SOAP::WSDL::Generator::Visitor:
file: lib/SOAP/WSDL/Generator/Visitor.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::Generator::Visitor::Typelib:
file: lib/SOAP/WSDL/Generator/Visitor/Typelib.pm
version: 2.00.03
SOAP::WSDL::Generator::Visitor::Typemap:
file: lib/SOAP/WSDL/Generator/Visitor/Typemap.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::Message:
file: lib/SOAP/WSDL/Message.pm
version: 2.00.03
SOAP::WSDL::OpMessage:
file: lib/SOAP/WSDL/OpMessage.pm
version: 2.00.03
SOAP::WSDL::Operation:
file: lib/SOAP/WSDL/Operation.pm
version: 2.00.03
SOAP::WSDL::Part:
file: lib/SOAP/WSDL/Part.pm
version: 2.00.03
SOAP::WSDL::Port:
file: lib/SOAP/WSDL/Port.pm
version: 2.00.03
SOAP::WSDL::PortType:
file: lib/SOAP/WSDL/PortType.pm
version: 2.00.03
SOAP::WSDL::SOAP::Address:
file: lib/SOAP/WSDL/SOAP/Address.pm
version: 2.00.03
SOAP::WSDL::SOAP::Body:
file: lib/SOAP/WSDL/SOAP/Body.pm
version: 2.00.03
SOAP::WSDL::SOAP::Header:
file: lib/SOAP/WSDL/SOAP/Header.pm
version: 2.00.03
SOAP::WSDL::SOAP::HeaderFault:
file: lib/SOAP/WSDL/SOAP/HeaderFault.pm
version: 2.00.03
SOAP::WSDL::SOAP::Operation:
file: lib/SOAP/WSDL/SOAP/Operation.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::SOAP::Typelib::Fault11:
file: lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::Serializer::XSD:
file: lib/SOAP/WSDL/Serializer/XSD.pm
version: 2.00_27
version: 2.00.03
SOAP::WSDL::Server:
file: lib/SOAP/WSDL/Server.pm
version: 2.00_27
version: 2.00.03
SOAP::WSDL::Server::CGI:
file: lib/SOAP/WSDL/Server/CGI.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::Server::Mod_Perl2:
file: lib/SOAP/WSDL/Server/Mod_Perl2.pm
version: 2.00.03
SOAP::WSDL::Service:
file: lib/SOAP/WSDL/Service.pm
version: 2.00.03
SOAP::WSDL::Transport::HTTP:
file: lib/SOAP/WSDL/Transport/HTTP.pm
version: 2.00.03
SOAP::WSDL::Transport::Loopback:
file: lib/SOAP/WSDL/Transport/Loopback.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::Transport::Test:
file: lib/SOAP/WSDL/Transport/Test.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::TypeLookup:
file: lib/SOAP/WSDL/TypeLookup.pm
version: 2.00_31
version: 2.00.03
SOAP::WSDL::Types:
file: lib/SOAP/WSDL/Types.pm
version: 2.00.03
SOAP::WSDL::XSD::Annotation:
file: lib/SOAP/WSDL/XSD/Annotation.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::Attribute:
file: lib/SOAP/WSDL/XSD/Attribute.pm
version: 2.00_29
version: 2.00.03
SOAP::WSDL::XSD::AttributeGroup:
file: lib/SOAP/WSDL/XSD/AttributeGroup.pm
version: 2.00_29
version: 2.00.03
SOAP::WSDL::XSD::Builtin:
file: lib/SOAP/WSDL/XSD/Builtin.pm
version: 2.00.03
SOAP::WSDL::XSD::ComplexType:
file: lib/SOAP/WSDL/XSD/ComplexType.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::Element:
file: lib/SOAP/WSDL/XSD/Element.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::XSD::Enumeration:
file: lib/SOAP/WSDL/XSD/Enumeration.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::FractionDigits:
file: lib/SOAP/WSDL/XSD/FractionDigits.pm
version: 2.00.03
SOAP::WSDL::XSD::Group:
file: lib/SOAP/WSDL/XSD/Group.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::Length:
file: lib/SOAP/WSDL/XSD/Length.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::MaxExclusive:
file: lib/SOAP/WSDL/XSD/MaxExclusive.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::MaxInclusive:
file: lib/SOAP/WSDL/XSD/MaxInclusive.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::MaxLength:
file: lib/SOAP/WSDL/XSD/MaxLength.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::MinExclusive:
file: lib/SOAP/WSDL/XSD/MinExclusive.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::MinInclusive:
file: lib/SOAP/WSDL/XSD/MinInclusive.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::MinLength:
file: lib/SOAP/WSDL/XSD/MinLength.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::Pattern:
file: lib/SOAP/WSDL/XSD/Pattern.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::Schema:
file: lib/SOAP/WSDL/XSD/Schema.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::Schema::Builtin:
file: lib/SOAP/WSDL/XSD/Schema/Builtin.pm
version: 2.00.03
SOAP::WSDL::XSD::SimpleType:
file: lib/SOAP/WSDL/XSD/SimpleType.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::XSD::TotalDigits:
file: lib/SOAP/WSDL/XSD/TotalDigits.pm
version: 2.00_33
version: 2.00.03
SOAP::WSDL::XSD::Typelib::Attribute:
file: lib/SOAP/WSDL/XSD/Typelib/Attribute.pm
version: 2.00_29
version: 2.00.03
SOAP::WSDL::XSD::Typelib::AttributeSet:
file: lib/SOAP/WSDL/XSD/Typelib/AttributeSet.pm
version: 2.00_29
version: 2.00.03
SOAP::WSDL::XSD::Typelib::Builtin:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::XSD::Typelib::Builtin::ENTITY:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/ENTITY.pm
SOAP::WSDL::XSD::Typelib::Builtin::ID:
@@ -250,14 +279,14 @@ provides:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anySimpleType.pm
SOAP::WSDL::XSD::Typelib::Builtin::anyType:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyType.pm
version: 2.00_29
version: 2.00.03
SOAP::WSDL::XSD::Typelib::Builtin::anyURI:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/anyURI.pm
SOAP::WSDL::XSD::Typelib::Builtin::base64Binary:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/base64Binary.pm
SOAP::WSDL::XSD::Typelib::Builtin::boolean:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/boolean.pm
version: 2.00_23
version: 2.00.03
SOAP::WSDL::XSD::Typelib::Builtin::byte:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/byte.pm
SOAP::WSDL::XSD::Typelib::Builtin::date:
@@ -310,7 +339,7 @@ provides:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/string.pm
SOAP::WSDL::XSD::Typelib::Builtin::time:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/time.pm
version: 2.00_25
version: 2.00.03
SOAP::WSDL::XSD::Typelib::Builtin::token:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/token.pm
SOAP::WSDL::XSD::Typelib::Builtin::unsignedByte:
@@ -323,17 +352,19 @@ provides:
file: lib/SOAP/WSDL/XSD/Typelib/Builtin/unsignedShort.pm
SOAP::WSDL::XSD::Typelib::ComplexType:
file: lib/SOAP/WSDL/XSD/Typelib/ComplexType.pm
version: 2.00_33
version: 2.1.0
SOAP::WSDL::XSD::Typelib::Element:
file: lib/SOAP/WSDL/XSD/Typelib/Element.pm
version: 2.00_29
version: 2.00.03
SOAP::WSDL::XSD::Typelib::SimpleType:
file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
version: 2.00.03
SOAP::WSDL::XSD::Typelib::SimpleType::restriction:
file: lib/SOAP/WSDL/XSD/Typelib/SimpleType.pm
version: 2.00.03
SOAP::WSDL::XSD::WhiteSpace:
file: lib/SOAP/WSDL/XSD/WhiteSpace.pm
version: 2.00_33
version: 2.00.03
generated_by: Module::Build version 0.2808
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.2.html

Binary file not shown.

View File

@@ -1,11 +1,17 @@
# Unfortunately, Build testcover reports test coverage wrong.
#
# To get a complete coverage report, just run this file as a shell script
# To get a complete coverage report, just run this file as a shell script
# on a linux box (or execute the equivalent commands on another OS):
#
# Note that this shell script requires Devel::CoverX::Covered - if you
# don't have it, comment out the line noted below
#
cd t/
cover -delete
find . -type f -name '*.t' | xargs -n 1 /usr/bin/perl -MDevel::Cover=-silent,1,-summary,0 -I../lib > /dev/null
find . -type f -name '*.t' | xargs -n 1 /usr/bin/perl -MDevel::Cover=-silent,1,-summary,0 -I../lib
# Devel::CoverX::Covered
covered runs
cover -ignore_re \.t$ -ignore_re ^lib -coverage="statement" -coverage=condition -coverage=subroutine -coverage="branch"

5
TODO
View File

@@ -1,10 +1,5 @@
TODO list for SOAP::WSDL
2.00 Pre-releases
--------
* Act as SOAP Server [ 1842436 ]
2.1 release
--------
* Support namespaces in SOAP message payload [ 1809057 ]

View File

@@ -1,15 +1,17 @@
#!/usr/bin/perl -w
%DB::packages=(SOAP::WSDL::Expat::MessageParser => 1);
use strict;
use warnings;
use lib '../lib';
use lib '../../Class-Std-Fast/lib';
use lib '/home/martin/workspace/SOAP-WSDL_XS/blib/lib';
use lib '/home/martin/workspace/SOAP-WSDL_XS/blib/arch';
use lib '../t/lib';
# use SOAP::WSDL::SAX::MessageHandler;
use Benchmark qw(cmpthese timethese);
use SOAP::WSDL::Expat::MessageParser;
use SOAP::WSDL::Expat::Message2Hash;
use SOAP::WSDL::Expat::MessageParser_XS;
use SOAP::Lite;
use XML::Simple;
use XML::LibXML;
@@ -17,24 +19,50 @@ use MyComplexType;
use MyElement;
use MySimpleType;
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/" >
<SOAP-ENV:Body>
<MyAtomicComplexTypeElement xmlns="urn:Test" >
<test>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test2</test2>
<test2 >Test55</test2>
<test2 >Test2</test2>
<test2 >Test3</test2>
<test2 >Test4</test2>
<test2 >Test5</test2>
<test2 >Test6</test2>
<test2 >Test7</test2>
<test2 >Test8</test2>
<test2 >Test9</test2>
<test2 >Test10</test2>
<test2 >Test11</test2>
<test2 >Test12</test2>
<test2 >Test13</test2>
<test2 >Test55</test2>
<test2 >Test14</test2>
<test2 >Test15</test2>
<test2 >Test16</test2>
<test2 >Test17</test2>
<test2 >Test18</test2>
<test2 >Test19</test2>
<test2 >Test20</test2>
<test2 >Test21</test2>
<test2 >Test22</test2>
<test2 >Test23</test2>
<test2 >Test24</test2>
<test2 >Test25</test2>
<test2 >Test565</test2>
<test2 >Test27</test2>
<test2 >Test28</test2>
<test2 >Test29</test2>
<test2 >Test30</test2>
<test2 >Test31</test2>
<test2 >Test32</test2>
<test2 >Test33</test2>
<test2 >Test34</test2>
<test2 >Test35</test2>
<test2 >Test36</test2>
<test2 >Test37</test2>
<test2 >Test38</test2>
<test2 >Test55</test2>
</test>
</MyAtomicComplexTypeElement>
</SOAP-ENV:Body></SOAP-ENV:Envelope>};
@@ -57,13 +85,17 @@ my @data;
my $deserializer = SOAP::Deserializer->new();
sub libxml_test {
my $parser_xs = SOAP::WSDL::Expat::MessageParser_XS->new({
class_resolver => 'FakeResolver'
});
sub libxml_test {
my $dom = $libxml->parse_string( $xml );
push @data, dom2hash( $dom->firstChild );
};
sub dom2hash {
for ($_[0]->childNodes) {
for ($_[0]->childNodes) {
if (exists $_[1]->{ $_->nodeName }) {
if (ref $_[1]->{ $_->nodeName } eq 'ARRAY') {
if ($_->nodeName eq '#text') {
@@ -78,7 +110,7 @@ sub dom2hash {
$_[1] = [ $_[1], $_->textContent() ];
}
else {
$_[1]->{ $_->nodeName } = [ $_[1]->{ $_->nodeName } ,
$_[1]->{ $_->nodeName } = [ $_[1]->{ $_->nodeName } ,
dom2hash( $_, {} ) ];
}
}
@@ -94,11 +126,11 @@ sub dom2hash {
}
return $_[1];
}
cmpthese 5000,
cmpthese 5000,
{
'SOAP::WSDL (Hash)' => sub { push @data, $hash_parser->parse( $xml ) },
'SOAP::WSDL (XSD)' => sub { push @data, $parser->parse( $xml ) },
'SOAP::WSDL_XS (XSD)' => sub { push @data, $parser_xs->parse_string( $xml ) },
'XML::Simple (Hash)' => sub { push @data, XMLin $xml },
'XML::LibXML (DOM)' => sub { push @data, $libxml->parse_string( $xml ) },
'XML::LibXML (Hash)' => \&libxml_test,
@@ -128,3 +160,18 @@ BEGIN {
};
};
};
__END__
Output on my machine:
xml length: 641 bytes
Rate SOAP::Lite XML::Simple (Hash) SOAP::WSDL (XSD) XML::LibXML (Hash) SOAP::WSDL (Hash) SOAP::WSDL_XS (XSD) XML::LibXML (DOM)
SOAP::Lite 446/s -- -54% -72% -73% -80% -95% -96%
XML::Simple (Hash) 963/s 116% -- -39% -41% -57% -89% -91%
SOAP::WSDL (XSD) 1587/s 256% 65% -- -3% -29% -81% -86%
XML::LibXML (Hash) 1629/s 265% 69% 3% -- -27% -81% -85%
SOAP::WSDL (Hash) 2222/s 398% 131% 40% 36% -- -74% -80%
SOAP::WSDL_XS (XSD) 8475/s 1798% 780% 434% 420% 281% -- -24%
XML::LibXML (DOM) 11111/s 2389% 1053% 600% 582% 400% 31% --

View File

@@ -0,0 +1,59 @@
Memory footprints for example/ scripts comparing SOAP::WSDL, SOAP::Lite and
XML::Compile::SOAP
Results with perl-5.8.8 on Ubuntu 8.04 (x86):
PID %CPU %MEM VSZ RSS COMMAND
10183 12.0 1.1 14292 11492 perl -I../lib hello.pl
10554 7.2 0.9 12636 9828 perl hello_lite.pl
10224 17.5 1.6 20780 17012 perl hello_compile.pl
10287 25.0 1.1 14680 11776 perl -I../lib person.pl
10313 24.0 1.6 21068 17312 perl person_compile.pl
Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
Platform:
osname=linux, osvers=2.6.15.7, archname=i486-linux-gnu-thread-multi
uname='linux palmer 2.6.15.7 #1 smp thu sep 7 19:42:20 utc 2006 i686 gnulinux '
config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include'
ccversion='', gccversion='4.2.3 20071123 (prerelease) (Ubuntu 4.2.2-3ubuntu4)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
perllibs=-ldl -lm -lpthread -lc -lcrypt
libc=/lib/libc-2.6.1.so, so=so, useshrplib=true, libperl=libperl.so.5.8.8
gnulibc_version='2.6.1'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT
PERL_MALLOC_WRAP THREADS_HAVE_PIDS USE_ITHREADS
USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API
Built under linux
Compiled at Nov 27 2007 10:44:36
@INC:
/etc/perl
/usr/local/lib/perl/5.8.8
/usr/local/share/perl/5.8.8
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.8
/usr/share/perl/5.8
/usr/local/lib/site_perl
.

77
benchmark/README Normal file
View File

@@ -0,0 +1,77 @@
The benchmark directory includes a bunch of benchmarks. The most notable
ones are listed below.
Comparison benchmarks for SOAP::Lite, SOAP::WSDL, SOAP::WSDL_XS, and
XML::Compile::WSDP need all of these installed for the benchmark to
work (building and adding to the lib path suffices). All comparison benchmarks
only account for the client part of the respective modules - the server part
is not benchmarked.
SOAP::WSDL_XS can be obtained from the project's subversion repository at
https://soap-wsdl.svn.sourceforge.net/svnroot/SOAP-WSDL/SOAP-WSDL_XS/trunk
Some benchmarks expect to find the SOAP servers "cgi-bin/person.pl" and
"cgi-bin/hello.pl" from the examples directory at
http://localhost:81/soap-wsdl-test/person.pl and
http://localhost:81/soap-wsdl-test/hello.pl
If the web services are not set up properly, you're benchmarking error
creation times.
To set up a SOAP server using apache, add the following to your apache config:
# usually in main config
Listen 127.0.0.1:81
# maybe in a
#<VirtualHost 127.0.0.1:81> container
#
ScriptAlias /soap-wsdl-test/ /PATH_TO/SOAP-WSDL/example/cgi-bin/
<Directory "/PATH_TO/SOAP-WSDL/example/cgi-bin">
AllowOverride None
Order allow,deny
Allow from all
</Directory>
Using mod_perl is highly recommended to cut down benchmarking time.
COMPARISON BENCHMARKS
=====================
01_expat.t
----------
Benchmarks XML parsing speed between XML::Simple with XML::Parser as backend,
SOAP::Lite, SOAP::WSDL outputting objects, SOAP::WSDL outputting hash refs,
XML::LibXML with a simple DOM walker outputting hash refs, XML::LibXML
outputting the DOM and SOAP::WSDL_XS.
No web server required.
This benchmark sheds light on how much performance is - in theory - reachable
by each approach: The XML::LibXML (Hash) benchmark converts the DOM into
a nested hash using a recursive function. This is - basically - how
XML::Compile works. XML::Simple uses XML::Parser's streaming
API. SOAP::WSDL uses XML::Parser::Expat, XML::Parser's low-level backend,
to create objects or - in the (Hash) variant - nested hashes similar to
those created by XML::Simple.
SOAP::WSDL_XS uses a libexpat-based XS parser to create perl objects, and
XML::LibXML (DOM) creates a C level libxml2 DOM accessible from perl.
person.pl:
----------
Sends a empty requests and receives a response of ca. 10kB.
Modeled after a common enterprise setup: "Give me a list of person data sets".
For this benchmark, XML parsing speed is important. XML generation speed is
only weighted in the last two runs, and weights around 1/10 of parsing speed.
hello.pl:
---------
Sends a request containing name and given name and politely replies
"Hello <given name> <name>".
An example for very short requests and responses.
For this example, handling and generating small requests/responses, and
transport speed is important. As the XML transmitted is relatively small, the
transport layer's overhead is important.

View File

@@ -11,7 +11,7 @@ my $obj = SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new();
timethese 10000, {
'new' => sub { SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new() },
'new + params' => sub { SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType->new({
value => 'Teststring'
value => 'Teststring',
}) },
'set_FOO' => sub { $obj->set_value('Test') },
};

View File

@@ -11,8 +11,9 @@ my $obj = SOAP::WSDL::XSD::Typelib::Builtin::string->new();
timethese 20000, {
'new' => sub { SOAP::WSDL::XSD::Typelib::Builtin::string->new() },
'new + params' => sub { SOAP::WSDL::XSD::Typelib::Builtin::string->new({
value => 'Teststring'
}) },
value => 'Teststring',
})
},
};
$obj->set_value('Foobar');
@@ -36,7 +37,7 @@ new + params: 1 wallclock secs ( 0.53 usr + 0.01 sys = 0.54 CPU) @ 37037.04/s
Benchmark: timing 1000000 iterations of get_FOO, set_FOO...
get_FOO: 2 wallclock secs ( 1.43 usr + 0.01 sys = 1.44 CPU) @ 694444.44/s (n=1000000)
set_FOO: 0 wallclock secs ( 1.43 usr + 0.01 sys = 1.44 CPU) @ 694444.44/s (n=1000000)
::Fast
---
@@ -47,7 +48,7 @@ Benchmark: timing 1000000 iterations of get_FOO, set_FOO...
get_FOO: 0 wallclock secs ( 0.81 usr + 0.00 sys = 0.81 CPU) @ 1234567.90/s (n=1000000)
set_FOO: 2 wallclock secs ( 0.87 usr + 0.01 sys = 0.88 CPU) @ 1136363.64/s (n=1000000)
::Fast with inlined ID
::Fast with inlined ID
Benchmark: timing 20000 iterations of new, new + params...
new: 0 wallclock secs ( 0.41 usr + 0.00 sys = 0.41 CPU) @ 48780.49/s (n=20000)
new + params: 1 wallclock secs ( 0.52 usr + 0.00 sys = 0.52 CPU) @ 38461.54/s (n=20000)

24
benchmark/XSD/strftime.pl Normal file
View File

@@ -0,0 +1,24 @@
use Benchmark qw(cmpthese);
use POSIX ();
use Date::Format ();
my @time_from = localtime;
print "Comparing POSIX::strftime and Date::Format::strftime '%Y-%m-%dT%H:%M:%S%z'\n\n";
print 'POSIX: ', POSIX::strftime('%Y-%m-%dT%H:%M:%S%z', @time_from), "\n";
print 'Date::Format: ', Date::Format::strftime('%Y-%m-%dT%H:%M:%S%z', @time_from), "\n";
cmpthese 100000, {
POSIX => sub { POSIX::strftime('%Y-%m-%dT%H:%M:%S%z', @time_from) },
'Date::Format' => sub { Date::Format::strftime('%Y-%m-%dT%H:%M:%S%z', @time_from) },
};
__END__
results with perl-5.8.8 on Ubuntu 8.04 on a Thinkpad T42 (1.7GHz Dothan):
Rate Date::Format POSIX
Date::Format 10684/s -- -93%
POSIX 153846/s 1340% --

View File

@@ -1,29 +1,43 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use diagnostics;
use lib '../example/lib';
use lib '/home/martin/workspace/SOAP-WSDL-Fast_XS/blib/lib';
use lib '/home/martin/workspace/SOAP-WSDL-Fast_XS/blib/arch';
use lib '../../SOAP-Lite-0.71/lib';
use lib '/home/martin/workspace/SOAP-WSDL_XS/blib/lib';
use lib '/home/martin/workspace/SOAP-WSDL_XS/blib/arch';
use Data::Dumper;
use SOAP::Lite;
use XML::Compile::WSDL11;
use XML::Compile::Transport::SOAPHTTP;
use MyInterfaces::HelloWorld::HelloWorldSoap;
use SOAP::WSDL::Deserializer::XSD_XS;
use Benchmark qw(cmpthese);
use Benchmark qw(cmpthese timethese);
use SOAP::WSDL::Transport::HTTP;
use SOAP::WSDL::Factory::Transport;
SOAP::WSDL::Factory::Transport->register('http', 'SOAP::WSDL::Transport::HTTP');
#my $proxy = 'http://localhost:81/soap-wsdl-test/helloworld.pl';
my $proxy = 'http://localhost:81/soap-wsdl-test/helloworld';
my $lite = SOAP::Lite->new(
proxy => 'http://localhost:81/soap-wsdl-test/helloworld.pl'
proxy => $proxy
);
$lite->on_action( sub { "urn:HelloWorld#sayHello" });
$lite->autotype(0);
my $soap = MyInterfaces::HelloWorld::HelloWorldSoap->new();
my $soap = MyInterfaces::HelloWorld::HelloWorldSoap->new({
proxy => $proxy,
});
my $soap_xs = MyInterfaces::HelloWorld::HelloWorldSoap->new();
my $soap_xs = MyInterfaces::HelloWorld::HelloWorldSoap->new({
proxy => $proxy,
});
$soap_xs->set_deserializer( SOAP::WSDL::Deserializer::XSD_XS->new() );
my @result;
my @result = ();;
sub wsdl_bench {
push @result, $soap->sayHello({
@@ -40,7 +54,12 @@ sub wsdl_xs_bench {
}
my $wsdl = XML::Compile::WSDL11->new('../example/wsdl/11_helloworld.wsdl');
my $call = $wsdl->compileClient('sayHello');
my $call = $wsdl->compileClient('sayHello',
sloppy_integers => 1,
check_values => 0,
check_values => 0,
validation => 0,
);
sub compile_bench {
push @result, $call->(
@@ -58,12 +77,16 @@ sub lite_bench {
);
}
# give all a chance to perform first-run initializations
compile_bench();
lite_bench();
wsdl_bench();
wsdl_xs_bench();
cmpthese 150, {
timethese 150, {
'SOAP::WSDL' => \&wsdl_bench,
'SOAP::WSDL_XS' => \&wsdl_xs_bench,
'XML::Compile' => \&compile_bench,
# 'SOAP::Lite' => \&lite_bench,
}
'SOAP::Lite' => \&lite_bench,
};

View File

@@ -1,5 +1,7 @@
use lib '../lib';
use lib '../example/lib';
use lib '../../Class-Std-Fast/lib';
use lib '../../SOAP-Lite-0.71/lib';
use lib '../../SOAP-WSDL_XS/blib/lib';
use lib '../../SOAP-WSDL_XS/blib/arch';
use strict;
@@ -11,15 +13,80 @@ use XML::Compile::Util;
use XML::Compile::WSDL11;
use XML::Simple;
use SOAP::Lite;
use MyInterfaces::TestService::TestPort;
use SOAP::WSDL::Deserializer::XSD_XS;
use SOAP::WSDL::Factory::Deserializer;
#
# register SOAP::WSDL's transport as default for SOAP::WSDL and SOAP::WSDL_XS
# - they use SOAP::Lite's SOAP::Transport::* if available
#
use SOAP::WSDL::Transport::HTTP;
use SOAP::WSDL::Factory::Transport;
SOAP::WSDL::Factory::Transport->register('http', 'SOAP::WSDL::Transport::HTTP');
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
use SOAP::Lite;
use MyInterfaces::TestService::TestPort;
my $person = {
PersonID => { # MyTypes::PersonID
ID => 1, # int
},
Salutation => 'Salutation0', # string
Name => 'Name0', # string
GivenName => 'Martin', # string
DateOfBirth => '1970-01-01', # date
HomeAddress => { # MyTypes::Address
Street => 'Street 0', # string
ZIP => '00000', # string
City => 'City0', # string
Country => 'Country0', # string
PhoneNumber => '++499131123456', # PhoneNumber
MobilePhoneNumber => '++49150123456', # PhoneNumber
},
WorkAddress => { # MyTypes::Address
Street => 'Somestreet 23', # string
ZIP => '12345', # string
City => 'SomeCity', # string
Country => 'Germany', # string
PhoneNumber => '++499131123456', # PhoneNumber
MobilePhoneNumber => '++49150123456', # PhoneNumber
},
Contracts => { # MyTypes::ArrayOfContract
Contract => [
{ # MyTypes::Contract
ContractID => 100000, # long
ContractName => 'SomeContract0', # string
},
{ # MyTypes::Contract
ContractID => 100001, # long
ContractName => 'SomeContract1', # string
},
{ # MyTypes::Contract
ContractID => 100002, # long
ContractName => 'SomeContract2', # string
},
{ # MyTypes::Contract
ContractID => 100003, # long
ContractName => 'SomeContract3', # string
},
],
},
}
;
#
# compile XML::Compile client with the options suggested by Mark Overmeer
# for maximum speedup
#
my $compile = XML::Compile::WSDL11->new('../example/wsdl/Person.wsdl',
sloppy_integers => 1,
check_values => 0,
check_values => 0,
validation => 0,
ignore_facets => 1,
);
my $compile = XML::Compile::WSDL11->new('../example/wsdl/Person.wsdl');
my $call = $compile->compileClient('ListPerson');
$call->({ in => undef});
@@ -52,34 +119,45 @@ Benchmark $n: Store result in private variable and destroy it
";
$n++;
cmpthese $count, {
# 'XML::Simple' => sub { my $result = XMLin( MyData::xml() )},
# 'SOAP::WSDL' => sub { my $result = $soap->ListPerson({}) },
# 'XML::Compile' => sub { my $result = $call->() },
'SOAP::WSDL' => sub { my $result = $soap->ListPerson({}) },
'XML::Compile' => sub { my $result = $call->() },
'SOAP::WSDL_XS' => sub { my $result = $wsdl_xs->ListPerson({}) },
# 'SOAP::Lite' => sub { my $result = $deserializer->deserialize( MyData::xml() )},
# 'SOAP::Lite' => sub { my $som = $lite->call('ListPerson') },
'SOAP::Lite' => sub { my $som = $lite->call('ListPerson') },
};
print "\nBenchmark $n: Push result on list\n";
$n++;
cmpthese $count, {
# 'XML::Simple' => sub { push @data, XMLin( MyData::xml() )},
# 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) },
# 'XML::Compile' => sub { push @data, $call->() },
'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) },
'XML::Compile' => sub { push @data, $call->() },
'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) },
# 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )}
# 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') },
'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') },
};
@data = ();
print "\nBenchmark $n: Play it again, Sam\n";
$n++;
cmpthese $count, {
# 'XML::Simple' => sub { push @data, XMLin( MyData::xml() )},
# 'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) },
'SOAP::WSDL' => sub { push @data, $soap->ListPerson({}) },
'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({}) },
# 'XML::Compile' => sub { push @data, $call->() },
# 'SOAP::Lite' => sub { push @data, $deserializer->deserialize( MyData::xml() )}
# 'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') },
'XML::Compile' => sub { push @data, $call->() },
'SOAP::Lite' => sub { push @data, $lite->call('ListPerson') },
};
print "\nBenchmark $n: ca. 1kB request - result destroyed immediately\n";
$n++;
cmpthese $count, {
'SOAP::WSDL' => sub { my $result = $soap->ListPerson({ in => $person }) },
'SOAP::WSDL_XS' => sub { my $result = $wsdl_xs->ListPerson({ in => $person }) },
'XML::Compile' => sub { my $result = $call->({ in => $person }) },
};
print "\nBenchmark $n: ca. 1kB request - push result on list\n";
$n++;
cmpthese $count, {
'SOAP::WSDL' => sub { push @data, $soap->ListPerson({ in => $person }) },
'SOAP::WSDL_XS' => sub { push @data, $wsdl_xs->ListPerson({ in => $person }) },
'XML::Compile' => sub { push @data, $call->({ in => $person }) },
};

View File

@@ -4,6 +4,7 @@ use lib '../../SOAP-WSDL_XS/blib/lib';
use lib '../../SOAP-WSDL_XS/blib/arch';
use strict;
use Benchmark;
use Storable;
#use SOAP::WSDL::Deserializer::XSD_XS;
use SOAP::WSDL::Factory::Deserializer;
# # register for SOAP 1.1
@@ -15,13 +16,21 @@ my @data = ();
my $soap = MyInterfaces::TestService::TestPort->new();
# Load all classes - XML::Compile has created everything before, too
timethis 100, sub { $soap->ListPerson({}) };
#timethis 100, sub { $soap->ListPerson({}) };
#timethis 50, sub { push @data, $soap->ListPerson({}) };
#@data = ();
# timethis 50, sub { push @data, $soap->ListPerson({}) };
# for (1..50) { push @data, $soap->ListPerson({}) };
#print $soap->ListPerson({});
my $result = $soap->ListPerson({});
timethis 30 , sub {
my $frozen = Storable::freeze( $result );
my $thawed = Storable::thaw($frozen);
};
# print $thawed;
package Transport;
use Class::Std::Fast;

View File

@@ -11,10 +11,12 @@ use Term::ReadKey;
my %opt = (
url => '',
prefix => undef,
attribute_prefix => 'MyAttributes',
type_prefix => 'MyTypes',
element_prefix => 'MyElements',
typemap_prefix => 'MyTypemaps',
interface_prefix => 'MyInterfaces',
server_prefix => 'MyServer',
base_path => 'lib/',
proxy => undef,
generator => 'XSD',
@@ -51,10 +53,12 @@ my %opt = (
GetOptions(\%opt,
qw(
prefix|p=s
attribute_prefix|a=s
type_prefix|t=s
element_prefix|e=s
typemap_prefix|m=s
interface_prefix|i=s
server_prefix|sp=s
base_path|b=s
typemap_include|mi=s
help|h
@@ -63,7 +67,7 @@ GetOptions(\%opt,
user=s
password=s
generator=s
server
server|s
namespaces|n
)
);
@@ -107,12 +111,22 @@ if (%typemap) {
}
};
$generator->set_type_prefix( $opt{ type_prefix }) if $generator->can('set_type_prefix');
$generator->set_typemap_prefix( $opt{ typemap_prefix }) if $generator->can('set_typemap_prefix');
$generator->set_element_prefix($opt{ element_prefix }) if $generator->can('set_element_prefix');
$generator->set_interface_prefix($opt{ interface_prefix }) if $generator->can('set_interface_prefix');
$generator->set_OUTPUT_PATH($opt{ base_path }) if $generator->can('set_OUTPUT_PATH');
$generator->set_definitions($definitions) if $generator->can('set_definitions');
$generator->set_attribute_prefix( $opt{ attribute_prefix })
if $generator->can('set_attribute_prefix');
$generator->set_type_prefix( $opt{ type_prefix })
if $generator->can('set_type_prefix');
$generator->set_typemap_prefix( $opt{ typemap_prefix })
if $generator->can('set_typemap_prefix');
$generator->set_element_prefix($opt{ element_prefix })
if $generator->can('set_element_prefix');
$generator->set_interface_prefix($opt{ interface_prefix })
if $generator->can('set_interface_prefix');
$generator->set_server_prefix($opt{ server_prefix })
if $generator->can('set_server_prefix');
$generator->set_OUTPUT_PATH($opt{ base_path })
if $generator->can('set_OUTPUT_PATH');
$generator->set_definitions($definitions)
if $generator->can('set_definitions');
# $generator->set_wsdl($xml) if $generator->can('set_wsdl');
# start with typelib, as errors will most likely occur here...
@@ -137,6 +151,8 @@ wsdl2perl.pl - create perl bindings for SOAP webservices.
NAME SHORT DESCRITPION
----------------------------------------------------------------------------
prefix p Prefix for both type and element classes.
attribute_prefix a Prefix for XML attribute classes.
Default: MyAttributes
type_prefix t Prefix for type classes.
Default: MyTypes
element_prefix e Prefix for element classes.
@@ -145,6 +161,8 @@ wsdl2perl.pl - create perl bindings for SOAP webservices.
Default: MyTypemaps
interface_prefix i Prefix for interface classes.
Default: MyInterfaces
server_prefix sp Prefix for server classes.
Default: MyServer
base_path b Path to create classes in.
Default: .
typemap_include mi File to include in typemap. Must eval() to a valid

View File

@@ -1,4 +1,5 @@
#!/usr/bin/perl -w
package main;
use strict;
use warnings;
use lib '../../lib';
@@ -33,7 +34,7 @@ in examples/wsdl/helloworld.wsdl
Before using this script, you should secure your webserver. The easiest way
to do so is to let it listen to 127.0.0.1 only.
Then make a ScriptAlias named /soap-wsdl-test/ pointing at the directory
Then make a ScriptAlias named /soap-wsdl-test/ pointing at the directory
this file lies in.
For my apache, it looks like this:

View File

@@ -15,12 +15,11 @@ my %dispatch_to :ATTR(:name<dispatch_to>);
my $action_map_ref = {
'urn:HelloWorld#sayHello' => 'sayHello',
};
sub START {
my ($self, $ident, $arg_ref) = @_;
eval "require $transport_class_of{ $ident }"
eval "require $transport_class_of{ $ident }"
or die "Cannot load transport class $transport_class_of{ $ident }: $@";
$transport_of{ $ident } = $transport_class_of{ $ident }->new({
action_map_ref => $action_map_ref,
@@ -30,7 +29,7 @@ sub START {
}
sub handle {
$transport_of{ ${ $_[0] } }->handle();
$transport_of{ ${ $_[0] } }->handle(@_[1..$#_]);
}
1;
@@ -76,7 +75,7 @@ located at http://localhost:81/soap-wsdl-test/helloworld.pl.
Constructor.
The C<dispatch_to> argument is mandatory. It must be a class or object
The C<dispatch_to> argument is mandatory. It must be a class or object
implementing the SOAP Service methods listed below.
=head2 SOAP Service methods
@@ -94,9 +93,9 @@ class.
my ($self, $body, $header) = @_;
# body is a ??? object - sorry, POD not implemented yet
# header is a ??? object - sorry, POD not implemented yet
# do something with body and header...
return MyElements::sayHelloResponse->new( {
sayHelloResult => $some_value, # string
},

View File

@@ -14,7 +14,7 @@ use Class::Std::Fast;
use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
use LWP::UserAgent;
our $VERSION= '2.00_33';
use version; our $VERSION= qv('2.00.03');
my %no_dispatch_of :ATTR(:name<no_dispatch>);
my %wsdl_of :ATTR(:name<wsdl>);
@@ -240,6 +240,10 @@ sub _wsdl_init_methods :PRIVATE {
return $method_info_of{ $ident };
}
# on_action is a no-op and just here for compatibility reasons.
# It returns the first parameter to allow method chaining.
sub on_action { return shift };
sub call {
my ($self, $method, @data_from) = @_;
my $ident = ${ $self };
@@ -512,7 +516,7 @@ it's content.
The object tree has two main functions: It knows how to serialize data passed
as hash ref, and how to render the WSDL elements found into perl classes.
Yup your're right, there's a builting code generation facility. Read
Yup you're right; there's a builtin code generation facility. Read
L<SOAP::WSDL::Manual> for using it.
=item * no_dispatch
@@ -555,6 +559,12 @@ SOAP message to your favorite XML editor and run the source format command.
Outputting readable XML requires lots of programming for little use: The
resulting XMl is still quite unreadable.
=head2 on_action
Setting on_action is not required any more, the appropriate value is
automatically taken from the WSDL. on_action is a no-op, and is just here
for compatibility issues.
=head1 Differences to SOAP::Lite
=head2 readable
@@ -595,7 +605,7 @@ See L<class_resolver|class_resolver> above.
=item * Hash refs
This is for convnience: A single hash ref containing the content of the
This is for convenience: A single hash ref containing the content of the
SOAP body.
=item * xml
@@ -675,13 +685,13 @@ interpreting mod:
simpleContent
The following XML Schema definition content model is only partially
supported:
supported in interpreting mode:
complexContent - only restriction variety supported
See L<SOAP::WSDL::Manual::XSD> for details.
=item * Serialization of hash refs dos not work for ambiguos values
=item * Serialization of hash refs does not work for ambiguous values
If you have list elements with multiple occurences allowed, SOAP::WSDL
has no means of finding out which variant you meant.
@@ -691,17 +701,17 @@ Passing in item => [1,2,3] could serialize to
<item>1 2</item><item>3</item>
<item>1</item><item>2 3</item>
Ambiguos data can be avoided by providing data as objects.
Ambiguous data can be avoided by providing data as objects.
=item * XML Schema facets
Almost no XML schema facets are implemented yet. The only facets
Almost no XML schema facets are implemented. The only facets
currently implemented are:
fixed
default
The following facets have no influence yet:
The following facets have no influence:
minLength
maxLength
@@ -725,10 +735,10 @@ The following facets have no influence yet:
Full featured SOAP-library, little WSDL support. Supports rpc-encoded style
only. Many protocols supported.
=item * L<XML::Compile::WSDL|XML::Compile::WSDL> / L<XML::Compile::SOAP|XML::Compile::SOAP>
=item * L<XML::Compile::SOAP|XML::Compile::SOAP>
Creates parser/generator functions for SOAP messages. Includes SOAP Client
and Server implementatios.
and Server implementations. Can validate XML messages.
You might want to give it a try, especially if you need to adhere very
closely to the XML Schema / WSDL specs.
@@ -762,7 +772,7 @@ Peter Orvos, Mark Overmeer, Jon Robens, Isidro Vila Verde and Glenn Wood
(in alphabetical order) spotted bugs and/or suggested improvements in
the 1.2x releases.
Andreas 'ac0v' Specht constantly asked for better performance.
Noah Robin contirbuted lots of documentation fixes, and the mod_perl server.
JT Justman and Noah Robin provided early feedback and bug reports for
the 2.xx pre-releases.
@@ -770,7 +780,11 @@ the 2.xx pre-releases.
Adam Kennedy checked and suggested improvements on metadata and dependencies
in the 2.xx pre-releases.
CPAN Testers have provided most valuable (automated) feedback. Thanks.
Andreas 'ac0v' Specht constantly asked for better performance.
Matt S. Trout encouraged me "to get a non-dev-release out."
CPAN Testers provided most valuable (automated) feedback. Thanks a lot.
Numerous people sent me their real-world WSDL files for testing. Thank you.
@@ -792,9 +806,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 583 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: WSDL.pm 583 2008-03-24 07:44:06Z kutterma $
$Id: WSDL.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL.pm $
=cut

View File

@@ -5,7 +5,7 @@ use Class::Std::Fast::Storable;
use List::Util qw(first);
use Carp qw(croak carp confess);
our $VERSION='2.00_27';
use version; our $VERSION = qv('2.00.03');
my %id_of :ATTR(:name<id> :default<()>);
my %lang_of :ATTR(:name<lang> :default<()>);
@@ -24,7 +24,7 @@ sub namespaces {
sub START {
my ($self, $ident, $arg_ref) = @_;
$xmlns_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' };
#$xmlns_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' };
$xmlns_of{ $ident }->{ 'xml' } = 'http://www.w3.org/XML/1998/namespace';
$namespaces_of{ $ident }->{ '#default' } = $self->get_xmlns()->{ '#default' };
$namespaces_of{ $ident }->{ 'xml' } = 'http://www.w3.org/XML/1998/namespace';
@@ -34,7 +34,7 @@ sub START {
sub DEMOLISH {
my $self = shift;
# delete upward references
delete $parent_of{ ident $self };
delete $parent_of{ ${ $self } };
return;
}
@@ -129,20 +129,23 @@ sub expand {
my ($self, $qname) = @_;
my $ns_of = $self->namespaces();
if (not $qname=~m{:}xm) {
if (defined $ns_of->{ '#default' }) {
return $self->get_targetNamespace(), $qname;
# return $ns_of->{ '#default' }, $qname;
}
if (my $parent = $self->get_parent()) {
return $parent->expand($qname);
}
die "un-prefixed element name <$qname> found, but no default namespace set\n"
if not defined $ns_of->{ '#default' };
return $ns_of->{ '#default' }, $qname;
}
my ($prefix, $localname) = split /:/x, $qname;
return ($ns_of->{ $prefix }, $localname) if ($ns_of->{ $prefix });
if (my $parent = $self->get_parent()) {
return $parent->expand($qname);
}
confess "unbound prefix $prefix found for $prefix:$localname. Bound prefixes are"
croak "unbound prefix $prefix found for $prefix:$localname. Bound prefixes are "
. join(', ', keys %{ $ns_of });
}
sub _expand;

View File

@@ -5,6 +5,8 @@ use Class::Std::Fast::Storable;
use List::Util qw(first);
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %operation_of :ATTR(:name<operation> :default<()>);
my %type_of :ATTR(:name<type> :default<()>);
my %transport_of :ATTR(:name<transport> :default<()>);

View File

@@ -11,10 +11,11 @@ use SOAP::WSDL::Factory::Serializer;
use SOAP::WSDL::Factory::Transport;
use SOAP::WSDL::Expat::MessageParser;
our $VERSION = '2.00_27';
use version; our $VERSION = qv('2.00.03');
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
my %no_dispatch_of :ATTR(:name<no_dispatch> :default<()>);
my %prefix_of :ATTR(:name<prefix> :default<()>);
my %outputxml_of :ATTR(:name<outputxml> :default<()>);
my %transport_of :ATTR(:name<transport> :default<()>);
my %endpoint_of :ATTR(:name<endpoint> :default<()>);
@@ -61,7 +62,7 @@ sub set_proxy {
}
sub set_soap_version {
my $ident = ident shift;
my $ident = ${ $_[0] };
# remember old value to return it later - Class::Std does so, too
my $soap_version = $soap_version_of{ $ident };
@@ -71,14 +72,14 @@ sub set_soap_version {
delete $serializer_of{ $ident };
delete $deserializer_of{ $ident };
$soap_version_of{ $ident } = shift;
$soap_version_of{ $ident } = $_[1];
return $soap_version;
}
# Mimic SOAP::Lite's behaviour for getter/setter routines
SUBFACTORY: {
for (qw(class_resolver no_dispatch outputxml proxy)) {
for (qw(class_resolver no_dispatch outputxml proxy prefix)) {
my $setter = "set_$_";
my $getter = "get_$_";
no strict qw(refs); ## no critic ProhibitNoStrict
@@ -94,7 +95,7 @@ SUBFACTORY: {
sub call {
my ($self, $method, @data_from) = @_;
my $ident = ident $self;
my $ident = ${ $self };
# the only valid idiom for calling a method with both a header and a body
# is
@@ -124,6 +125,7 @@ sub call {
method => $operation,
body => $data,
header => $header,
options => {prefix => $prefix_of{ $ident }},
});
return $envelope if $self->no_dispatch();
@@ -259,19 +261,52 @@ You probably should not use a character encoding different from utf8:
SOAP::WSDL::Client will not convert the request into a different encoding
(yet).
To leave out the encoding, just set the content type without appendet charset
like in
To leave out the encoding, just set the content type without appending charset
like this:
text/xml
$soap->set_content_type('text/xml');
Default:
text/xml; charset: utf8
=head3 set_prefix
$soap->set_prefix('ns2');
If set, alters the serialization of the request XML such that the supplied value is used as a namespace prefix for SOAP method calls. By way of example, the default XML serialization returns something like this:
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<getElementId xmlns="http://services.exmaple.org/">
<elementId>12345</elementId>
</getElementId>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
If the sample set_prefix() call above is used prior to calling your SOAP method, the XML serialization returns this instead:
<?xml version="1.0"?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns2="http://services.example.org/">
<SOAP-ENV:Body>
<ns2:getElementId>
<elementId>12345</elementId>
</ns2:getElementId>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This is useful in cases where, for instance, one is communicating with a JAX L<https://jax-ws.dev.java.net/> webservice, which tends to understand the latter but not the former. Note that this implementation is currently limited to a single additional namespace; if you require multiple custom namespaces, you should probably look into creating your own serializer.
=head2 Features different from SOAP::Lite
SOAP::WSDL does not aim to be a complete replacement for SOAP::Lite - the
SOAP::Lite module has it's strengths and weaknesses and SOAP::WSDL is
SOAP::Lite module has its strengths and weaknesses and SOAP::WSDL is
designed as a cure for the weakness of little WSDL support - nothing more,
nothing less.
@@ -283,7 +318,7 @@ A few things are quite different from SOAP::Lite, though:
=head3 SOAP request data
SOAP request data may either be given as message object, or as hash ref (in
SOAP request data may either be given as message object, or as a hash ref (in
which case it will automatically be encoded into a message object).
=head3 Return values
@@ -303,7 +338,7 @@ The fault object is a SOAP1.1 fault object of the following
C<SOAP::WSDL::SOAP::Typelib::Fault11>.
SOAP::WSDL::SOAP::Typelib::Fault11 objects are false in boolean context, so
you can just do something like
you can just do something like:
my $result = $soap->call($method, $data);
@@ -321,7 +356,7 @@ to true. SOAP::WSDL::Client returns the complete XML response.
=head3 Auto-Dispatching
SOAP::WSDL::Client does B<does not> support auto-dispatching.
SOAP::WSDL::Client B<does not> support auto-dispatching.
This is on purpose: You may easily create interface classes by using
SOAP::WSDL::Client and implementing something like
@@ -360,9 +395,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 455 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: Client.pm 455 2007-12-14 15:50:16Z kutterma $
$Id: Client.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client.pm $
=cut

View File

@@ -4,7 +4,7 @@ use warnings;
use base 'SOAP::WSDL::Client';
use Scalar::Util qw(blessed);
our $VERSION = '2.00_33';
use version; our $VERSION = qv('2.00.03');
sub call {
my ($self, $method, $body, $header) = @_;
@@ -78,9 +78,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 542 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: Base.pm 542 2008-02-18 09:38:06Z kutterma $
$Id: Base.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Client/Base.pm $
=cut

View File

@@ -9,7 +9,7 @@ use List::Util qw(first);
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
our $VERSION='2.00_33';
use version; our $VERSION = qv('2.00.03');
my %types_of :ATTR(:name<types> :default<[]>);
my %message_of :ATTR(:name<message> :default<[]>);
@@ -118,9 +118,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 549 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: Definitions.pm 549 2008-02-20 10:14:26Z kutterma $
$Id: Definitions.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Definitions.pm $
=cut

View File

@@ -8,7 +8,7 @@ use SOAP::WSDL::Expat::Message2Hash;
use SOAP::WSDL::Factory::Deserializer;
SOAP::WSDL::Factory::Deserializer->register( '1.1', __PACKAGE__ );
our $VERSION='2.00_25';
use version; our $VERSION = qv('2.00.03');
sub BUILD {
my ($self, $ident, $args_of_ref) = @_;
@@ -54,7 +54,7 @@ SOAP::WSDL::Deserializer::Hash - Deserializer SOAP messages into perl hash refs
use SOAP::WSDL;
use SOAP::WSDL::Deserializer::Hash;
=head1 DESCRIPTION
Deserializer for creating perl hash refs as result of a SOAP call.
@@ -152,9 +152,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 427 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: Hash.pm 427 2007-12-02 22:20:24Z kutterma $
$Id: Hash.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/Hash.pm $
=cut

View File

@@ -2,7 +2,7 @@ package SOAP::WSDL::Deserializer::SOM;
use strict;
use warnings;
our $VERSION = '2.00_24';
use version; our $VERSION = qv('2.00.03');
our @ISA;
eval {
@@ -37,7 +37,7 @@ SOAP::WSDL::Deserializer::SOM - Deserializer SOAP messages into SOM objects
use SOAP::WSDL::Deserializer::SOM;
use SOAP::WSDL::Factory::Deserializer;
SOAP::WSDL::Factory::Deserializer->register( '1.1', __PACKAGE__ );
=head1 DESCRIPTION
Deserializer for creating SOAP::Lite's SOM object as result of a SOAP call.
@@ -68,11 +68,11 @@ from the L<SOAP::Lite|SOAP::Lite> package.
=head1 USAGE
SOAP::WSDL::Deserializer will not auroregister itself - to use it for a particular
SOAP::WSDL::Deserializer will not autoregister itself - to use it for a particular
SOAP version just use the following lines:
my $soap_version = '1.1'; # or '1.2', further versions may appear.
use SOAP::WSDL::Deserializer::SOM;
use SOAP::WSDL::Factory::Deserializer;
SOAP::WSDL::Factory::Deserializer->register( $soap_version, __PACKAGE__ );
@@ -114,9 +114,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 391 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: SOM.pm 391 2007-11-17 21:56:13Z kutterma $
$Id: SOM.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/SOM.pm $
=cut

View File

@@ -5,7 +5,7 @@ use Class::Std::Fast::Storable;
use SOAP::WSDL::SOAP::Typelib::Fault11;
use SOAP::WSDL::Expat::MessageParser;
our $VERSION='2.00_25';
use version; our $VERSION = qv('2.00.03');
my %class_resolver_of :ATTR(:name<class_resolver> :default<()>);
@@ -25,7 +25,7 @@ sub deserialize {
$parser_of{ ${ $self } } = SOAP::WSDL::Expat::MessageParser->new()
if not $parser_of{ ${ $self } };
$parser_of{ ${ $self } }->class_resolver( $class_resolver_of{ ident $self } );
$parser_of{ ${ $self } }->class_resolver( $class_resolver_of{ ${ $self } } );
eval { $parser_of{ ${ $self } }->parse_string( $content ) };
if ($@) {
return $self->generate_fault({
@@ -72,7 +72,7 @@ Usually you don't need to do anything to use this package - it's the default
deserializer for SOAP::WSDL::Client and interface classes generated by
SOAP::WSDL.
Is you want to use the XSD serializer from SOAP::WSDL, set the outputtree()
If you want to use the XSD serializer from SOAP::WSDL, set the outputtree()
property and provide a class_resolver.
=head1 METHODS
@@ -99,9 +99,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 501 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: XSD.pm 501 2008-01-26 20:23:32Z kutterma $
$Id: XSD.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Deserializer/XSD.pm $
=cut

View File

@@ -6,7 +6,7 @@ use XML::Parser::Expat;
# TODO: convert to Class::Std::Fast based class - hash based classes suck.
our $VERSION = '2.00_32';
use version; our $VERSION = qv('2.00.03');
sub new {
my ($class, $arg_ref) = @_;
@@ -51,7 +51,7 @@ sub parse_uri {
my $uri = shift;
if ($self->is_parsed($uri)){
warn "$uri already imported. Ignoring it\n";
warn "$uri already imported; ignoring it.\n";
return;
}
$self->set_parsed($uri);

View File

@@ -4,7 +4,7 @@ use strict;
use warnings;
use base qw(SOAP::WSDL::Expat::Base);
our $VERSION = '2.00_27';
use version; our $VERSION = qv('2.00.03');
sub _initialize {
my ($self, $parser) = @_;
@@ -21,7 +21,7 @@ sub _initialize {
my ($_element, $_method,
$_class, $_parser, %_attrs) = ();
no strict qw(refs);
# no strict qw(refs);
$parser->setHandlers(
Start => sub {
push @$list, $current;

View File

@@ -4,7 +4,7 @@ use strict;
use warnings;
use Carp qw(croak confess);
our $VERSION = q{2.00_27};
use version; our $VERSION = qv('2.00.03');
use SOAP::WSDL::XSD::Typelib::Builtin;
use SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType;
@@ -24,8 +24,12 @@ sub new {
};
bless $self, $class;
$self->load_classes() if ($args->{ class_resolver })
&& ! exists $LOADED_OF{ $self->{ class_resolver } };
# could be written as && - but Devel::Cover doesn't like that
if ($args->{ class_resolver }) {
$self->load_classes()
if ! exists $LOADED_OF{ $self->{ class_resolver } };
}
return $self;
}
@@ -162,6 +166,9 @@ sub _initialize {
# (circumventing constructor) here.
# That's dirty, but fast.
#
# TODO: check whether this is faster under all perls - there's
# strange benchmark results...
#
# The alternative would read:
# $current = $_class->new({ @_[2..$#_] });
#
@@ -172,8 +179,20 @@ sub _initialize {
}
# set attributes if there are any
$current->attr({ @_[2..$#_] }) if (@_ > 2);
ATTR: {
if (@_ > 2) {
# die Data::Dumper::Dumper(@_[2..$#_]);
my %attr = @_[2..$#_];
if (my $nil = delete $attr{nil}) {
# TODO: check namespace
if ($nil && $nil ne 'false') {
undef $characters;
last ATTR if not (%attr);
}
}
$current->attr(\%attr);
}
}
$depth++;
return;
},
@@ -194,13 +213,6 @@ sub _initialize {
$depth--;
# return if there's only one elment - can't set it in parent ;-)
# but set as root element if we don't have one already.
if (not defined $list->[-1]) {
$self->{ data } = $current if (not exists $self->{ data });
return;
};
# we only set character values in leaf nodes
if ($_leaf) {
# Use dirty but fast access via global variables.
@@ -210,16 +222,30 @@ sub _initialize {
# $current->set_value( $characters ) if (length($characters));
#
$SOAP::WSDL::XSD::Typelib::Builtin::anySimpleType::___value
->{ $$current } = $characters if $characters =~m{ [^\s] }xms;
->{ $$current } = $characters
if defined $characters && defined $current; # =~m{ [^\s] }xms;
}
# empty characters
$characters = q{};
# return if there's only one elment - can't set it in parent ;-)
# but set as root element if we don't have one already.
if (not defined $list->[-1]) {
$self->{ data } = $current if (not exists $self->{ data });
return;
};
# set appropriate attribute in last element
# multiple values must be implemented in base class
# TODO check if hash access is faster
# $_method = "add_$_localname";
$_method = "add_$_[1]";
#
# fixup XML names for perl names
#
$_method =~s{\.}{__}xg;
$_method =~s{\-}{_}xg;
$list->[-1]->$_method( $current );
$current = pop @$list; # step up in object hierarchy
@@ -293,10 +319,10 @@ the same terms as perl itself
=head1 Repository information
$Id: $
$Id: MessageParser.pm 677 2008-05-18 20:17:56Z kutterma $
$LastChangedDate: 2008-03-29 22:38:55 +0100 (Sa, 29 Mrz 2008) $
$LastChangedRevision: 585 $
$LastChangedDate: 2008-05-18 22:17:56 +0200 (So, 18 Mai 2008) $
$LastChangedRevision: 677 $
$LastChangedBy: kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageParser.pm $

View File

@@ -6,7 +6,7 @@ use XML::Parser::Expat;
use SOAP::WSDL::Expat::MessageParser;
use base qw(SOAP::WSDL::Expat::MessageParser);
our $VERSION = '2.00_24';
use version; our $VERSION = qv('2.00.03');
sub parse_start {
my $self = shift;
@@ -43,7 +43,7 @@ SOAP::WSDL::Expat::MessageStreamParser - Convert SOAP messages to custom object
# process response while it comes in, trying to read 32k chunks.
$lwp->request( $request, sub { $chunk_parser->parse_more($_[0]) } , 32468 );
$chunk_parser->parse_done();
my $obj = $parser->get_data();
=head1 DESCRIPTION
@@ -69,9 +69,9 @@ the same terms as perl itself
=head1 REPOSITORY INFORMATION
$Rev: 477 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: MessageStreamParser.pm 477 2007-12-24 10:23:52Z kutterma $
$Id: MessageStreamParser.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/MessageStreamParser.pm $
=cut

View File

@@ -1,38 +1,44 @@
package SOAP::WSDL::Expat::WSDLParser;
package SOAP::WSDL::Expat::WSDLParser;
use strict;
use warnings;
use Carp;
use SOAP::WSDL::TypeLookup;
use base qw(SOAP::WSDL::Expat::Base);
our $VERSION = q{2.00_32};
use version; our $VERSION = qv('2.00.03');
sub _import_children {
my ($self, $name, $imported, $importer, $import_namespace) = @_;
return if not $imported;
my $targetNamespace = $importer->get_targetNamespace();
my $push_method = "push_$name";
my $get_method = "get_$name";
my $default_namespace = $imported->get_xmlns()->{ '#default' };
no strict qw(refs);
my $value_ref = $imported->$get_method();
if ($value_ref) {
#print $self->get_uri(), "\n";
#use Data::Dumper;
#print Data::Dumper::Dumper $value_ref;
$value_ref = [ $value_ref ] if (not ref $value_ref eq 'ARRAY');
# set xmlns - can be different from parent
for (@{ $value_ref }) {
# fixup namespace - new parent may be from different namespace
if (defined ($default_namespace)) {
my $xmlns = $_->get_xmlns();
# it's a hash ref, so we can just update values
if (! defined $xmlns->{ '#default'}) {
$xmlns->{ '#default' } = $default_namespace;
}
}
# fixup targetNamespace, but don't override
$_->set_targetNamespace( $import_namespace )
if ( ($import_namespace ne $targetNamespace) && ! $_->get_targetNamespace);
# update parent...
$_->set_parent( $importer );
# push elements into importing WSDL
$importer->$push_method($_);
}
# push elements into importing WSDL
#$importer->$push_method(@{ $value_ref })
# if @{ $value_ref };
}
}
@@ -45,6 +51,10 @@ sub _import_namespace_definitions {
# import namespace definitions, too
my $importer_ns_of = $importer->get_xmlns();
my %xmlns_of = %{ $imported->get_xmlns() };
# it's a hash ref, we can just add to.
# TODO: check whether prefix is already taken.
# TODO: check wheter URI is the better key.
while (my ($prefix, $url) = each %xmlns_of) {
$importer_ns_of->{ $prefix } = $url;
}
@@ -56,6 +66,16 @@ sub xml_schema_import {
my $parser = $self->clone();
my %attr_of = @_;
my $import_namespace = $attr_of{ namespace };
if (not $attr_of{schemaLocation}) {
warn "cannot import document for namespace >$import_namespace< without location";
return;
}
if (not $self->get_uri) {
die "cannot import document from namespace >$import_namespace< without base uri. Use >parse_uri< or >set_uri< to set one."
}
my $uri = URI->new_abs($attr_of{schemaLocation}, $self->get_uri() );
my $imported = $parser->parse_uri($uri);
@@ -78,6 +98,16 @@ sub wsdl_import {
my $parser = $self->clone();
my %attr_of = @_;
my $import_namespace = $attr_of{ namespace };
if (not $attr_of{location}) {
warn "cannot import document for namespace >$import_namespace< without location";
return;
}
if (not $self->get_uri) {
die "cannot import document from namespace >$import_namespace< without base uri. Use >parse_uri< or >set_uri< to set one."
}
my $uri = URI->new_abs($attr_of{location}, $self->get_uri() );
my $imported = $parser->parse_uri($uri);
@@ -125,7 +155,7 @@ sub _initialize {
croak $@ if ($@);
my $obj = $action->{ class }->new({ parent => $current,
xmlns => { '#default' => $parser->namespace($localname) }
# xmlns => { '#default' => $parser->namespace($localname) }
})
->init( _fixup_attrs( $parser, %attrs ) );
@@ -221,7 +251,8 @@ sub _initialize {
sub _fixup_attrs {
my ($parser, %attrs_of) = @_;
my @attrs_from = map { $_ =
my @attrs_from = map {
$_ =
{
Name => $_,
Value => $attrs_of{ $_ },
@@ -232,10 +263,10 @@ sub _fixup_attrs {
# 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')
? ()
:
# # Other nodes should be ignored somewhere else
# ($_ eq '#default')
# ? ()
# :
{
Name => "xmlns:$_",
Value => $parser->expand_ns_prefix( $_ ),
@@ -279,10 +310,10 @@ the same terms as perl itself
=head1 Repository information
$Id: WSDLParser.pm 549 2008-02-20 10:14:26Z kutterma $
$Id: WSDLParser.pm 677 2008-05-18 20:17:56Z kutterma $
$LastChangedDate: 2008-02-20 11:14:26 +0100 (Mi, 20 Feb 2008) $
$LastChangedRevision: 549 $
$LastChangedDate: 2008-05-18 22:17:56 +0200 (So, 18 Mai 2008) $
$LastChangedRevision: 677 $
$LastChangedBy: kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Expat/WSDLParser.pm $

View File

@@ -2,7 +2,7 @@ package SOAP::WSDL::Factory::Deserializer;
use strict;
use warnings;
our $VERSION = '2.00_24';
use version; our $VERSION = qv('2.00.03');
my %DESERIALIZER = (
'1.1' => 'SOAP::WSDL::Deserializer::XSD',
@@ -47,10 +47,10 @@ SOAP::WSDL::Factory::Deserializer - Factory for retrieving Deserializer objects
# in deserializer class:
package MyWickedDeserializer;
use SOAP::WSDL::Factory::Deserializer;
# register class as deserializer for SOAP1.2 messages
SOAP::WSDL::Factory::Deserializer->register( '1.2' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Factory::Deserializer serves as factory for retrieving
@@ -150,5 +150,5 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
$LastChangedBy: kutterma $
$Id: Serializer.pm 176 2007-08-31 15:28:29Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
=cut

View File

@@ -2,7 +2,7 @@ package SOAP::WSDL::Factory::Generator;
use strict;
use warnings;
our $VERSION='2.00_24';
use version; our $VERSION = qv('2.00.03');
my %GENERATOR = (
'XSD' => 'SOAP::WSDL::Generator::Template::XSD',
@@ -49,10 +49,10 @@ SOAP::WSDL::Factory:Generator - Factory for retrieving generator objects
# in generator class:
package MyWickedGenerator;
use SOAP::WSDL::Factory::Generator;
# register as generator for SOAP1.2 messages
SOAP::WSDL::Factory::Generator->register( '1.2' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Factory::Generator serves as factory for retrieving
@@ -168,5 +168,5 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
$LastChangedBy: kutterma $
$Id: Serializer.pm 176 2007-08-31 15:28:29Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
=cut

View File

@@ -2,7 +2,7 @@ package SOAP::WSDL::Factory::Serializer;
use strict;
use warnings;
our $VERSION='2.00_24';
use version; our $VERSION = qv('2.00.03');
my %SERIALIZER = (
'1.1' => 'SOAP::WSDL::Serializer::XSD',
@@ -46,10 +46,10 @@ SOAP::WSDL::Factory::Serializer - Factory for retrieving serializer objects
# in serializer class:
package MyWickedSerializer;
use SOAP::WSDL::Factory::Serializer;
# register as serializer for SOAP1.2 messages
SOAP::WSDL::Factory::Serializer->register( '1.2' , __PACKAGE__ );
=head1 DESCRIPTION
SOAP::WSDL::Factory::Serializer serves as factory for retrieving
@@ -138,9 +138,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 510 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: Serializer.pm 510 2008-01-29 08:03:46Z kutterma $
$Id: Serializer.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Serializer.pm $
=cut

View File

@@ -1,10 +1,8 @@
package SOAP::WSDL::Factory::Transport;
use strict;
use warnings;
use version; our $VERSION = qv('2.00.03');
our $VERSION='2.00_33';
# class data
my %registered_transport_of = ();
# Local constants
@@ -32,14 +30,17 @@ sub register {
}
sub get_transport {
my ($class, $scheme, %attrs) = @_;
my ($class, $url, %attrs) = @_;
$scheme =~s{ \A ([^\:]+) \: .+ }{$1}x;
if ($registered_transport_of{ $scheme }) {
my $scheme = $url;
$scheme =~s{ \:.+$ }{}xm;
if (defined $registered_transport_of{ $scheme }) {
no strict qw(refs);
defined %{ "$registered_transport_of{ $scheme }::" }
or eval "require $registered_transport_of{ $scheme }"
defined %{ "$registered_transport_of{ $scheme }::" } or
eval "require $registered_transport_of{ $scheme }"
or die "Cannot load transport class $registered_transport_of{ $scheme } : $@";
# try "foo::Client" class first - SOAP::Tranport always requires
@@ -50,28 +51,30 @@ sub get_transport {
# 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_LITE_TRANSPORT_OF{ $scheme }) {
no strict qw(refs);
# behaves interestingly different under different versions of perl
# maybe true even if it's not available
defined %{ "$SOAP_LITE_TRANSPORT_OF{ $scheme }::" }
or eval "require $SOAP_LITE_TRANSPORT_OF{ $scheme }"
or last SOAP_Lite;
my $protocol_class = $SOAP_LITE_TRANSPORT_OF{ $scheme } . '::Client';
# may fail if it's not available
my $transport = eval { $protocol_class->new( %attrs ) }
or last SOAP_Lite;
return $transport;
}
}
if (exists $SOAP_WSDL_TRANSPORT_OF{ $scheme }) {
no strict qw(refs);
defined %{ "$SOAP_WSDL_TRANSPORT_OF{ $scheme }::" }
defined %{ "$SOAP_WSDL_TRANSPORT_OF{ $scheme }::"}
or eval "require $SOAP_WSDL_TRANSPORT_OF{ $scheme }"
or die "Cannot load transport class $SOAP_WSDL_TRANSPORT_OF{ $scheme } : $@";
return $SOAP_WSDL_TRANSPORT_OF{ $scheme }->new( %attrs );
@@ -159,7 +162,7 @@ the class should be used for, and $module is the class' module name.
To auto-register your transport class on loading, execute register() in your
tranport class (see L<SYNOPSIS|SYNOPSIS> above).
Multiple protocols ore multiple classes are registered by multiple calls to
Multiple protocols or multiple classes are registered by multiple calls to
register().
=head2 Transport plugin package layout
@@ -240,9 +243,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 579 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: Transport.pm 579 2008-03-09 18:39:24Z kutterma $
$Id: Transport.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Factory/Transport.pm $
=cut

View File

@@ -2,6 +2,8 @@ package SOAP::WSDL::Generator::Iterator::WSDL11;
use strict; use warnings;
use Class::Std::Fast;
use version; our $VERSION = qv('2.00.03');
my %definitions_of :ATTR(:name<definitions> :default<[]>);
my %nodes_of :ATTR(:name<nodes> :default<[]>);
@@ -242,8 +244,8 @@ The nodes are returned in the order denoted in the following example:
</service>
</definitions>
You should not rely too much on this order - it may change. Even though, the
current order will probably remain, but the nodes currently skipped might
You should not rely too much on this order - it may change. Even though the
current order will probably remain, the nodes currently skipped might
be returned somewhere along the path.

View File

@@ -3,20 +3,26 @@ use strict; use warnings;
use Class::Std::Fast::Storable;
use version; our $VERSION = qv('2.00.03');
my %namespace_prefix_map_of :ATTR(:name<namespace_prefix_map> :default<{}>);
my %namespace_map_of :ATTR(:name<namespace_map> :default<{}>);
my %prefix_of :ATTR(:name<prefix> :default<{}>);
sub resolve_prefix {
my ($self, $type, $namespace, $element) = @_;
return $prefix_of{ $$self }->{ $type }
if not defined($namespace);
return $namespace_prefix_map_of{ $$self }->{ $namespace }
|| ( ($namespace_map_of{ $$self }->{ $namespace })
? join ('::', $prefix_of{ $$self }->{ $type }, $namespace_map_of{ $$self }->{ $namespace })
: $prefix_of{ $$self }->{ $type }
);
my $prefix;
if (not defined($namespace)) {
$prefix = $prefix_of{ $$self }->{ $type }
}
else {
$prefix = $namespace_prefix_map_of{ $$self }->{ $namespace }
|| ( ($namespace_map_of{ $$self }->{ $namespace })
? join ('::', $prefix_of{ $$self }->{ $type }, $namespace_map_of{ $$self }->{ $namespace })
: $prefix_of{ $$self }->{ $type }
);
}
return "${prefix}::";
}
1;
@@ -67,7 +73,7 @@ Subclasses must implement the following methods:
# ...
}
resolve_prefix is expected to return a (perl class) prefis. It is called with
resolve_prefix is expected to return a (perl class) prefix. It is called with
the following parameters:
NAME DESCRIPTION
@@ -80,7 +86,7 @@ You usually just need type and namespace for prefix resolving. node is
provided for rather funky setups, where you have to choose different prefixes
based on type names or whatever.
Note that node may be of any of the following classes:
Node may be of any of the following classes:
SOAP::WSDL::Service
SOAP::WSDL::XSD::Attribute
@@ -90,8 +96,34 @@ Note that node may be of any of the following classes:
Note that both namespace and node may be undef - you should test for
definedness before doing anything fancy with them.
If you want your prefixes to represent perl class hierarchies, they should
end with '::'.
Example:
Imagine you're generating interfaces for the Acme Pet Shop. Acme Corp. has
set up their datatypes to be global across all interfaces (and products), while
elements are local to the product (the Pet Shop in the example).
All elements are in the urn:Acme namespace.
In addition, there are types in the namespace urn:Acme:Goods, which should go
into the same namespace as types, but be prefixed with 'Goods_'
You may want prefixes (roughly) like this:
Interfaces: Acme::Client::PetShop::
Server: Acme::Server::PetShop::
Types: Acme::Types::
Types (Goods): Acme::Types::Goods_
Elements: Acme::Elements::PetShop::
Typemaps: Acme::Typemaps::PetShop::
=back
=head1 BUGS AND LIMITATIONS
You cannot suffix your types by some rule yet...
=head1 LICENSE AND COPYRIGHT
Copyright 2008 Martin Kutter.

View File

@@ -5,7 +5,7 @@ use Class::Std::Fast::Storable;
use Carp;
use SOAP::WSDL::Generator::PrefixResolver;
use version; our $VERSION = qv(2.00_33);
use version; our $VERSION = qv('2.00.03');
my %tt_of :ATTR(:get<tt>);
my %definitions_of :ATTR(:name<definitions> :default<()>);

View File

@@ -4,20 +4,22 @@ use warnings;
use Carp qw(confess);
use Class::Std::Fast::Storable constructor => 'none';
use version; our $VERSION = qv('2.00.03');
my %namespace_prefix_map_of :ATTR(:name<namespace_prefix_map> :default<{}>);
my %namespace_map_of :ATTR(:name<namespace_map> :default<{}>);
my %prefix_of :ATTR(:name<prefix> :default<()>);
my %prefix_resolver_of :ATTR(:name<prefix_resolver> :default<()>);
my %definitions_of :ATTR(:name<definitions> :default<()>);
# create a singleton
sub load { # called as MyPlugin->load($context)
sub load { # called as MyPlugin->load($context)
my ($class, $context, @arg_from) = @_;
my $stash = $context->stash();
my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class;
# $self->set_namespace_map( $stash->{ context }->{ namespace_map });
# $self->set_namespace_prefix_map( $stash->{ context }->{ namespace_prefix_map });
# $self->set_prefix( $stash->{ context }->{ prefix });
$self->set_prefix_resolver( $stash->{ context }->{ prefix_resolver });
$self->set_definitions( $stash->{ definitions });
return $self; # returns 'MyPlugin'
}
@@ -27,10 +29,8 @@ sub new {
my ($class, $arg_ref) = @_;
my $self = bless \do { my $o = Class::Std::Fast::ID() }, $class;
# $self->set_namespace_map( $arg_ref->{ namespace_map });
# $self->set_namespace_prefix_map( $arg_ref->{ namespace_prefix_map });
# $self->set_prefix( $arg_ref->{ prefix });
$self->set_prefix_resolver( $arg_ref->{ prefix_resolver });
$self->set_definitions( $arg_ref->{ definitions });
return $self; # returns 'MyPlugin'
}
@@ -38,10 +38,10 @@ sub _get_prefix {
my ($self, $type, $node) = @_;
my $namespace = defined ($node)
? ref($node)
? $node->get_targetNamespace
? $node->get_targetNamespace()
: $node
: undef;
return $self->get_prefix_resolver->resolve_prefix(
return $self->get_prefix_resolver()->resolve_prefix(
$type,
$namespace,
ref($node)
@@ -50,27 +50,18 @@ sub _get_prefix {
);
}
#sub _get_prefix {
# my ($self, $type, $namespace) = @_;
# return $prefix_of{ $$self }->{ $type }
# if not defined($namespace);
# return $namespace_prefix_map_of{ $$self }->{ $namespace }
# || ( ($namespace_map_of{ $$self }->{ $namespace })
# ? join ('::', $prefix_of{ $$self }->{ $type }, $namespace_map_of{ $$self }->{ $namespace })
# : $prefix_of{ $$self }->{ $type }
# );
#}
sub create_xsd_name {
my ($self,$element) = @_;
my $name = $self->_resolve_prefix($element) . '::'
. $element->get_name();
my ($self, $node) = @_;
confess "no node $node" if not defined($node)
or $node eq "";
my $name = $self->_resolve_prefix($node) #. '::'
. $node->get_name();
return $self->perl_name( $name );
}
sub create_typemap_name {
my ($self, $node) = @_;
my $name = $self->_get_prefix('typemap') . '::'
my $name = $self->_get_prefix('typemap') #. '::'
. $node->get_name();
return $self->perl_name( $name );
}
@@ -79,10 +70,9 @@ sub create_server_name {
my ($self, $server, $port) = @_;
my $port_name = $port->get_name();
$port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x;
my $name = join('::',
my $name = join( q{},
$self->_get_prefix('server', $server),
$server->get_name(),
$port_name
join( '::', $server->get_name(), $port_name)
);
return $self->perl_name( $name );
}
@@ -91,17 +81,16 @@ sub create_interface_name {
my ($self, $server, $port) = @_;
my $port_name = $port->get_name();
$port_name =~s{\A (?:.+)\. ([^\.]+) \z}{$1}x;
my $name = join('::',
my $name = join( q{},
$self->_get_prefix('interface', $server),
$server->get_name(),
$port_name
join( '::', $server->get_name(), $port_name )
);
return $self->perl_name( $name );
}
sub _resolve_prefix {
my ($self, $node) = @_;
confess "no node" if not $node;
if ($node->isa('SOAP::WSDL::XSD::Builtin')) {
return $self->_get_prefix('type', $node)
}
@@ -121,8 +110,16 @@ sub _resolve_prefix {
sub perl_name {
my $self = shift;
my $name = shift;
$name =~s{[\-]}{_}xmsg;
$name =~s{[\.]}{::}xmsg;
$name =~s{\-}{_}xmsg;
$name =~s{\.}{::}xmsg;
return $name;
}
sub perl_var_name {
my $self = shift;
my $name = shift;
$name =~s{\-}{_}xmsg;
$name =~s{\.}{__}xmsg;
return $name;
}
@@ -144,6 +141,7 @@ sub create_subpackage_name {
}
}
# create name for top node
die "FOO" if not defined $top_node;
my $top_node_name = $self->create_xsd_name($top_node);
my $package_name = join('::_', $top_node_name , (@name_from) ? join('::', @name_from) : () );
return $package_name;
@@ -153,6 +151,22 @@ sub create_xmlattr_name {
return join '::', shift->create_subpackage_name(shift), 'XmlAttr';
}
sub element_name {
my $self = shift;
my $element = shift;
my $name = $element->get_name();
if (! $name) {
while (my $ref = $element->get_ref()) {
$element = $self->get_definitions()->first_types()
->find_element($element->expand( $ref ) );
$name = $element->get_name();
last if ($name);
}
}
return $name;
}
1;
=pod

View File

@@ -5,15 +5,15 @@ use Class::Std::Fast::Storable;
use File::Basename;
use File::Spec;
our $VERSION = q{2.00_27};
use version; our $VERSION = qv('2.00.03');
use SOAP::WSDL::Generator::Visitor::Typemap;
use SOAP::WSDL::Generator::Visitor::Typelib;
use SOAP::WSDL::Generator::Template::Plugin::XSD;
use base qw(SOAP::WSDL::Generator::Template);
my %output_of :ATTR(:name<output> :default<()>);
my %typemap_of :ATTR(:name<typemap> :default<({})>);
my %output_of :ATTR(:name<output> :default<()>);
my %typemap_of :ATTR(:name<typemap> :default<({})>);
sub BUILD {
my ($self, $ident, $arg_ref) = @_;
@@ -47,6 +47,29 @@ sub BUILD {
);
}
# construct object on call to allow late binding of prefix_resolver class
# and namespace maps (not used yet)
sub get_name_resolver {
my $self = shift;
return SOAP::WSDL::Generator::Template::Plugin::XSD->new({
prefix_resolver => $self->get_prefix_resolver_class()->new({
namespace_prefix_map => {
'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin',
},
namespace_map => {
},
prefix => {
attribute => $self->get_attribute_prefix,
interface => $self->get_interface_prefix,
element => $self->get_element_prefix,
server => $self->get_server_prefix,
type => $self->get_type_prefix,
typemap => $self->get_typemap_prefix,
}
})
});
}
sub generate {
my $self = shift;
my $opt = shift;
@@ -73,7 +96,7 @@ sub _generate_interface {
my $self = shift;
my $arg_ref = shift;
my $template_name = delete $arg_ref->{ template_name };
my $prefix_method = delete $arg_ref->{ prefix_method };
my $name_method = delete $arg_ref->{ name_method };
for my $service (@{ $self->get_definitions->get_service }) {
for my $port (@{ $service->get_port() }) {
# Skip ports without (known) address
@@ -85,10 +108,11 @@ sub _generate_interface {
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename(
$self->can($prefix_method)->($self),
$service->get_name(),
$port_name,
);
$self->get_name_resolver()->can($name_method)->(
$self->get_name_resolver(),
$service,
$port,
));
print "Creating interface class $output\n";
$self->_process($template_name,
@@ -105,14 +129,14 @@ sub _generate_interface {
sub generate_server {
my ($self, $arg_ref) = @_;
$arg_ref->{ template_name } = 'Server.tt';
$arg_ref->{ prefix_method } = 'get_server_prefix';
$arg_ref->{ name_method } = 'create_server_name';
$self->_generate_interface($arg_ref);
}
sub generate_client {
my ($self, $arg_ref) = @_;
$arg_ref->{ template_name } = 'Interface.tt';
$arg_ref->{ prefix_method } = 'get_interface_prefix';
$arg_ref->{ name_method } = 'create_interface_name';
$self->_generate_interface($arg_ref);
}
sub generate_interface;
@@ -133,22 +157,7 @@ sub generate_typemap {
'Fault/detail' => 'SOAP::WSDL::XSD::Typelib::Builtin::string',
%{ $typemap_of{ident $self }},
},
resolver => SOAP::WSDL::Generator::Template::Plugin::XSD->new({
prefix_resolver => $self->get_prefix_resolver_class()->new({
namespace_prefix_map => {
'http://www.w3.org/2001/XMLSchema' => 'SOAP::WSDL::XSD::Typelib::Builtin',
},
namespace_map => {
},
prefix => {
interface => $self->get_interface_prefix,
element => $self->get_element_prefix,
server => $self->get_server_prefix,
type => $self->get_type_prefix,
typemap => $self->get_typemap_prefix,
}
})
}),
resolver => $self->get_name_resolver(),
});
use SOAP::WSDL::Generator::Iterator::WSDL11;
@@ -163,7 +172,7 @@ sub generate_typemap {
my $output = $arg_ref->{ output }
? $arg_ref->{ output }
: $self->_generate_filename( $self->get_typemap_prefix(), $service->get_name() );
: $self->_generate_filename( $self->get_name_resolver()->create_typemap_name($service) );
print "Creating typemap class $output\n";
$self->_process('Typemap.tt',
{
@@ -176,8 +185,7 @@ sub generate_typemap {
}
sub _generate_filename :PRIVATE {
my ($self, @parts) = @_;
my $name = join '::', @parts;
my ($self, $name) = @_;
$name =~s{ \. }{::}xmsg;
$name =~s{ \- }{_}xmsg;
$name =~s{ :: }{/}xmsg;
@@ -188,7 +196,7 @@ sub visit_XSD_Attribute {
my ($self, $attribute) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_attribute_prefix(), $attribute->get_name() );
: $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($attribute) );
$self->_process('attribute.tt', { attribute => $attribute } , $output);
}
@@ -196,7 +204,7 @@ sub visit_XSD_Element {
my ($self, $element) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_element_prefix(), $element->get_name() );
: $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($element) );
$self->_process('element.tt', { element => $element } , $output);
}
@@ -204,7 +212,7 @@ sub visit_XSD_SimpleType {
my ($self, $type) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_type_prefix(), $type->get_name() );
: $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($type) );
$self->_process('simpleType.tt', { simpleType => $type } , $output);
}
@@ -212,8 +220,8 @@ sub visit_XSD_ComplexType {
my ($self, $type) = @_;
my $output = defined $output_of{ ident $self }
? $output_of{ ident $self }
: $self->_generate_filename( $self->get_type_prefix(), $type->get_name() );
: $self->_generate_filename( $self->get_name_resolver()->create_xsd_name($type) );
$self->_process('complexType.tt', { complexType => $type } , $output);
}
1;
1;

View File

@@ -15,6 +15,8 @@ sub START {
$_[0]->set_proxy('[% port.first_address.get_location %]') if not $_[2]->{proxy};
$_[0]->set_class_resolver('[% XSD.create_typemap_name(service) %]')
if not $_[2]->{class_resolver};
$_[0]->set_prefix($_[2]->{use_prefix}) if exists $_[2]->{use_prefix};
}
[% binding = definitions.find_binding( port.expand( port.get_binding ) );
@@ -88,4 +90,4 @@ All arguments are forwarded to L<SOAP::WSDL::Client|SOAP::WSDL::Client>.
Generated by SOAP::WSDL on [% PERL %]print scalar localtime() [% END %]
=cut
=cut

View File

@@ -15,8 +15,8 @@
@parts = map {
my $part = $_;
(grep {
my ($ns, $lname) = $def->expand( $_ );
($lname eq $part->get_name)
# my ($ns, $lname) = $def->expand( $_ );
($_ eq $part->get_name)
} @body_part_from
)
? do {

View File

@@ -11,10 +11,11 @@
my $def = $stash->{ definitions };
my $type_prefix = $stash->{ type_prefix };
my $element_prefix = $stash->{ element_prefix };
my ($ns, $lname) = $def->expand( $item->get_part() );
#my ($ns, $lname) = $def->expand( $item->get_part() );
my $part_name = $item->get_part();
my ($part) = grep {
$_->get_name eq $lname
&& $_->get_targetNamespace eq $ns } @{ $message->get_part( ) };
$_->get_name eq $part_name
} @{ $message->get_part( ) };
my $part_class = do {
my $name;
($name = $part->get_element)

View File

@@ -7,4 +7,3 @@
port_op.get_documentation %]
$interface->[% operation.get_name %]([% INCLUDE Interface/POD/Message.tt %] );

View File

@@ -36,7 +36,7 @@ sub START {
}
sub handle {
$transport_of{ ${ shift @_ } }->handle(@_);
$transport_of{ ${ $_[0] } }->handle(@_[1..$#_]);
}
1;
@@ -102,4 +102,4 @@ implementing the SOAP Service methods listed below.
Generated by SOAP::WSDL on [% PERL %]print scalar localtime() [% END %]
=pod
=cut

View File

@@ -3,15 +3,48 @@
[% head3 %] [% operation.get_name %]
[% type = definitions.find_portType( binding.expand( binding.get_type ) );
port_op = type.find_operation( definitions.get_targetNamespace, operation.get_name );
port_op.get_documentation %]
[% type = definitions.find_portType( binding.expand( binding.get_type ) );
port_op = '';
FOREACH port_op = type.get_operation();
IF (port_op.get_name == operation.get_name);
LAST;
END;
END;
input_message_name = port_op.first_input.get_message();
output_message_name = port_op.first_output.get_message();
input_message = definitions.find_message(port_op.first_input.expand(input_message_name));
output_message = definitions.find_message(port_op.first_output.expand(output_message_name));
input_parts = input_message.get_part();
output_parts = output_message.get_part();
# port_op.get_documentation
%]
sub [% operation.get_name %] {
my ($self, $body, $header) = @_;
# body is a ??? object - sorry, POD not implemented yet
# header is a ??? object - sorry, POD not implemented yet
[%
IF (input_parts.size() > 1); -%]
# body is a list ref of the following objects:
# [
# sorry - POD support not implemented yet
# ]
[% ELSE;
input_element = definitions.first_types.find_element(input_parts.0.expand(input_parts.0.get_element));
IF (input_element);
class = XSD.create_xsd_name( input_element );
ELSE;
input_type = definitions.first_types.find_type(input_parts.0.expand(input_parts.0.get_type));
class = XSD.create_xsd_name( input_type );
END;
-%]
# body is a [% class %] object
[%-
END;
%]
# header is a ??? object - sorry, POD support not implemented yet
# do something with body and header...
return [% INCLUDE Server/POD/Message.tt %]

View File

@@ -40,8 +40,16 @@ methods:
=over
[% FOREACH element = complexType.get_element -%]
=item * [% element.get_name %]
=item * [% XSD.perl_var_name(XSD.element_name(element)) %]
[% IF (XSD.perl_var_name(XSD.element_name(element)) == element.get_name); %]
[% ELSE %]
Note: The name of this property has been altered, because it didn't match
perl's notion of variable/subroutine names. The altered name is used in
perl code only, XML output uses the original name:
[% element.get_name %]
[% END %]
[% IF element.get_annotation.get_documentation; %]
[% element.get_annotation.get_documentation %]
[% END -%]

View File

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

View File

@@ -15,7 +15,10 @@ get_/set_ methods:
=over
[% FOREACH element = complexType.get_attribute -%]
[% FOREACH element = complexType.get_attribute;
WHILE element.get_ref;
element = definitions.first_types.find_attribute(element.expand( element.get_ref ));
END; -%]
=item * [% element.get_name %]
[%- IF (element.get_annotation && element.get_annotation.0.get_documentation) %]
@@ -31,4 +34,7 @@ This attribute is of type L<[% XSD.create_xsd_name(type) %]|[% XSD.create_xsd_na
[% END %]
[%- END -%]
=back
[% END %]

View File

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

View File

@@ -7,26 +7,39 @@ Class::Std::initialize();
[%
atomic_types = {};
FOREACH element = complexType.get_element %]
my %[% XSD.perl_name(element.get_name) %]_of :ATTR(:get<[% XSD.perl_name(element.get_name) %]>);
FOREACH element = complexType.get_element;
name = XSD.perl_var_name(XSD.element_name(element)); %]
my %[% XSD.perl_name(name) %]_of :ATTR(:get<[% XSD.perl_name(name) %]>);
[%- END %]
__PACKAGE__->_factory(
[ qw([% FOREACH element = complexType.get_element %]
[% element.get_name -%]
[ qw([% FOREACH element = complexType.get_element;
# ugly copied code - macro or plugin method?
name = XSD.perl_var_name(XSD.element_name(element)); -%]
[% name %]
[% END %]
) ],
{
[% FOREACH element = complexType.get_element -%]
'[% element.get_name %]' => \%[% XSD.perl_name(element.get_name) %]_of,
[% FOREACH element = complexType.get_element;
# ugly copied code - macro or plugin method?
name = XSD.perl_var_name(XSD.element_name(element)); -%]
'[% name %]' => \%[% XSD.perl_name(name) %]_of,
[% END -%]
},
{
[% FOREACH element = complexType.get_element;
IF (ref = element.get_ref);
element = definitions.first_types.find_element(element.expand( element.get_ref ));
END;
IF (type = element.get_type);
element_type = definitions.first_types.find_type(complexType.expand( type )); -%]
'[% element.get_name %]' => '[% XSD.create_xsd_name(element_type) %]',
[% ELSE;
element_type = definitions.first_types.find_type(complexType.expand( type ));
IF (! element_type);
type_name = complexType.expand( type );
THROW NOT_FOUND, "${ type_name.0 } ${ type_name.1 } not found";
END; -%]
'[% XSD.perl_var_name(XSD.element_name(element)) %]' => '[% XSD.create_xsd_name(element_type) %]',
[% ELSE;
IF (element.first_simpleType);
atomic_types.${ element.get_name } = element.first_simpleType;
ELSIF (element.first_complexType);
@@ -34,9 +47,14 @@ __PACKAGE__->_factory(
ELSE;
THROW NOT_IMPLEMENTED , "Neither simple nor complex atomic type for element ${ element.get_name } - don't know what to do with it";
END; %]
'[% element.get_name %]' => '[% XSD.create_subpackage_name({ value => element }) %]',
'[% XSD.perl_var_name(XSD.element_name(element)) %]' => '[% XSD.create_subpackage_name({ value => element }) %]',
[% END;
END -%]
},
{
[% FOREACH element = complexType.get_element; %]
'[% XSD.perl_var_name(XSD.element_name(element)); %]' => '[% element.get_name %]',
[%- END %]
}
);

View File

@@ -3,18 +3,27 @@ package [% XSD.create_xmlattr_name(complexType) %];
use base qw(SOAP::WSDL::XSD::Typelib::AttributeSet);
{ # BLOCK to scope variables
[% FOREACH element = complexType.get_attribute %]
[% FOREACH element = complexType.get_attribute;
WHILE element.get_ref;
element = definitions.first_types.find_attribute(element.expand( element.get_ref ));
END; %]
my %[% element.get_name %]_of :ATTR(:get<[% element.get_name %]>);
[%- END %]
__PACKAGE__->_factory(
[ qw(
[%- FOREACH element = complexType.get_attribute %]
[%- FOREACH element = complexType.get_attribute;
WHILE element.get_ref;
element = definitions.first_types.find_attribute(element.expand( element.get_ref ));
END; %]
[% element.get_name -%]
[% END %]
) ],
{
[% FOREACH element = complexType.get_attribute -%]
[% FOREACH element = complexType.get_attribute;
WHILE element.get_ref;
element = definitions.first_types.find_attribute(element.expand( element.get_ref ));
END; %]
[% element.get_name %] => \%[% element.get_name %]_of,
[% END -%]
},
@@ -26,10 +35,11 @@ __PACKAGE__->_factory(
[% element.get_name %] => '[% XSD.create_xsd_name(element_type) %]',
[%
ELSIF (ref = element.get_ref);
attribute = definitions.first_types.find_attribute( complexType.expand(ref) );
# element_type = definitions.get_types.0.find_type(complexType.expand( attribute.get_type ));
WHILE element.get_ref;
element = definitions.first_types.find_attribute(element.expand( element.get_ref ));
END;
%]
[% attribute.get_name %] => '[% XSD.create_xsd_name(attribute) %]',
[% element.get_name %] => '[% XSD.create_xsd_name(element) %]',
[% ELSIF (element.first_simpleType);
THROW NOT_IMPLEMENTED , "Attributes with atomic simpleType definition are not implemented yet";
atomic_types.${ element.get_name } = element.first_simpleType;

View File

@@ -1,5 +1,7 @@
[% IF (complexType.get_variety == 'restriction');
INCLUDE complexType/restriction.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'extension');
INCLUDE complexType/extension.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'sequence');
INCLUDE complexType/extension.tt(complexType = complexType);
ELSIF (complexType.get_variety == 'all');

View File

@@ -1,28 +1,70 @@
[%
#
# extension
#
# unfortunately, SOAP::WSDL's speed tweaks don't play well with
# Class::Std's inheritance model.
#
# In Class::Std, all properties are stored in the class, and in objects
# using inheritance in the defining class.
#
# As the speed tweaks directly access the class' data without checking
# inheritance, the simplest way is to resolve complexType extension
# relationships
#
# To capture deep inheritance, extensions must be followed until a non-
# extension base is found
#
# TODO attribute handling is missing
# TODO sort out some better way to handle inheritance
base_name=complexType.expand( complexType.get_base );
element_list = [];
# copy complexType ref
base_type = complexType;
base_name=base_type.expand( base_type.get_base );
base_type = definitions.first_types.find_type( base_name );
element_from = complexType.get_element;
# add a use base for first to setup inheritance
%]
use base qw([% XSD.create_xsd_name( base_type ) %]);
[%
# loop forever
WHILE (1);
# make a copy. We don't want to modify the original list here...
FOREACH element = base_type.get_element.reverse;
element_list.unshift(element);
END;
# get next base type
IF (base_name=base_type.expand( base_type.get_base ));
# set new base_type
base_type = definitions.first_types.find_type( base_name );
ELSE;
# exit loop if there is none
BREAK;
END;
END;
#
# Sanity check: All original elements must be noted first
# and now the new elements...
#
element_list = base_type.get_element;
element_from = complexType.get_element;
FOREACH element = element_from;
IF element_list.${ loop.index }.get_name != element.get_name;
element_list.push( element );
# THROW WSDL "${element.get_name} not found at position ${ loop.index } in extension type ${ complexType.get_name }";
END;
END;
complexType.set_element( element_list );
-%]
use base qw([% XSD.create_xsd_name( base_type ) %]);
[%
# set derived element list
# wrap in IF; END; to prevent it getting printed
IF (complexType.set_element( element_list )); END;
INCLUDE complexType/variety.tt(complexType = complexType);
# restore original element list
# wrap in IF; END; to prevent it getting printed
IF ( complexType.set_element( element_from ) ); END;
%]

View File

@@ -7,8 +7,8 @@ ELSIF (complexType.get_variety == 'group');
THROW NOT_IMPLEMENTED, "${ element.get_name } - complexType group not implemented yet";
ELSIF (complexType.get_variety == 'choice');
INCLUDE complexType/all.tt(complexType = complexType);
ELSIF (complexType.get_variety);
THROW NOT_IMPLEMENTED, "Unknown variety ${ complexType.get_variety } in ${ complexType.get_name } (${ element.get_name })";
#ELSIF (complexType.get_variety);
# THROW NOT_IMPLEMENTED, "unknown variety ${ complexType.get_variety } in ${ complexType.get_name } (${ element.get_name })";
ELSE %]
# There's no variety - empty complexType

View File

@@ -8,7 +8,10 @@ use warnings;
sub get_xmlns { '[% element.get_targetNamespace %]' }
__PACKAGE__->__set_name('[% element.get_name %]');
__PACKAGE__->__set_nillable([% element.get_nillable %]);
__PACKAGE__->__set_nillable([% IF (element.get_nillable);
IF (element.get_nillable != 'false'); %]1[% ELSE %]0[% END;
END;
%]);
__PACKAGE__->__set_minOccurs([% element.get_minOccurs %]);
__PACKAGE__->__set_maxOccurs([% element.get_maxOccurs %]);
__PACKAGE__->__set_ref([% IF element.get_ref; %]'[% element.get_ref %]'[% END %]);

View File

@@ -3,7 +3,7 @@ use strict;
use warnings;
use Class::Std::Fast::Storable;
our $VERSION = q{2.00_25};
use version; our $VERSION = qv('2.00.03');
my %definitions_of :ATTR(:name<definitions> :default<()>);
my %type_prefix_of :ATTR(:name<type_prefix> :default<()>);
@@ -66,13 +66,13 @@ tree of objects.
A Visitor's methods are called using the so-called double dispatch technique.
To allow double dispatching, the Visitor implements one method for every class
ro be handled, whereas every class implements just one method (commonly named
to be handled, whereas every class implements just one method (commonly named
"access"), which does nothing more than calling a method on the reference
given, with the self object as parameter.
If all this sounds strange, maybe an example helps. Imagine you had a list of
person objects and wanted to print out a list of their names (or address
stamps or everything elseyou like). This can easily be implemented with a
stamps or everything else you like). This can easily be implemented with a
Visitor:
package PersonVisitor;
@@ -107,7 +107,7 @@ Visitor:
Person name is Vlissides
While using this pattern for just printing a list may look a bit over-sized,
but it may become handy if you need multiple output formats and different
it may become handy if you need multiple output formats and different
classes to operate on.
The main benefits using visitors are:
@@ -188,8 +188,8 @@ mimicing .NET's .asmx example pages.
All these behaviours could well be (and have historically been) implemented in
the classes holding the WSDL data. This made these classes rather bloated, and
made it hard to change behaviour (like, supporting SOAP Headers,
supporting atomic types and other features which were missing from early
made it hard to change behaviour (like supporting SOAP Headers,
supporting atomic types, and other features which were missing from early
versions of SOAP::WSDL).
Implementing these behaviours in Visitor classes eases adding new behaviours,
@@ -203,7 +203,7 @@ schema implementation.
SOAP::WSDL::Base defines an accept method which expects a Visitor as only
parameter.
The method visit_Foo_Bar is called on the visitor, whith the self object as
The method visit_Foo_Bar is called on the visitor, with the self object as
parameter.
The actual method name is constructed this way:
@@ -224,7 +224,7 @@ visit_XSD_ComplexType is called on the visitor.
=head2 Writing your own visitor
SOAP::WSDL eases writing your own visitor. This might be required if you need
some special output format from a WSDL file, or want to feed your own
some special output format from a WSDL file or want to feed your own
serializer/deserializer pair with custom configuration data. Or maybe you want
to generate C# code from it...
@@ -273,7 +273,7 @@ The SOAP::WSDL::Generator::Visitor implementations include part of their own
Iterator (which means they know how to find the next objects to visit). You
may or may not choose to implement a separate Iterator.
Letting a visitor implementing it's own Iterator visit a WSDL definition is as
Letting a visitor implementing its own Iterator visit a WSDL definition is as
easy as writing something like this:
my $visitor = MyVisitor->new();

View File

@@ -5,6 +5,7 @@ use base qw(SOAP::WSDL::Generator::Visitor
SOAP::WSDL::Generator::Template
);
use version; our $VERSION = qv('2.00.03');
1;

View File

@@ -5,7 +5,7 @@ use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Generator::Visitor);
our $VERSION = q{2.00_25};
use version; our $VERSION = qv('2.00.03');
my %path_of :ATTR(:name<path> :default<[]>);
my %typemap_of :ATTR(:name<typemap> :default<()>);
@@ -32,16 +32,19 @@ sub add_element_path {
# Well almost: Class names are not constructed in a namespace-sensitive
# manner, yet - there should be some facility to allow binding a (perl)
# prefix to a namespace...
push @{ $path_of{ ident $self } }, $element->get_name();
# push @{ $path_of{ ident $self } },
# "{". $element->get_targetNamespace . "}"
# . $element->get_name();
if (my $ref = $element->get_ref() ) {
$element = $self->get_definitions()->first_types()->find_element(
$element->expand($ref) );
}
my $name = $element->get_name();
push @{ $path_of{ ident $self } }, $name;
}
sub process_referenced_type {
my ( $self, $ns, $localname ) = @_;
return if not $localname;
my $ident = ident $self;
# get type's class name
@@ -61,15 +64,6 @@ sub process_referenced_type {
return $self;
}
sub process_atomic_type {
my ( $self, $type, $callback ) = @_;
return if not $type;
my $ident = ident $self;
$callback->( $self, $type ) if $callback;
return $self;
}
sub visit_XSD_Element {
my ( $self, $ident, $element ) = ( $_[0], ident $_[0], $_[1] );
@@ -85,9 +79,11 @@ sub visit_XSD_Element {
# They all just return if no argument is given,
# and return $self on success.
SWITCH: {
my $name = $element->get_name();
if ($element->get_type) {
$self->process_referenced_type( $element->expand( $element->get_type() ) )
&& last;
$self->process_referenced_type( $element->expand( $element->get_type() ) );
last SWITCH;
}
# atomic simpleType typemap rule:
@@ -97,9 +93,6 @@ sub visit_XSD_Element {
# warn "simpleType " . $element->get_name();
my @path = @{ $path_of{ ${ $self } } };
my $typeclass = $self->get_resolver()->create_subpackage_name($element);
# my $typeclass = defined ($parent)
# ? join q{::_}, $parent , $element->get_name()
# : join q{::}, $self->resolver()->get_element_prefix( $element->get_targetNamespace), $element->get_name();
$self->set_typemap_entry($typeclass);
$typeclass =~s{\.}{::}g;
$typeclass =~s{\-}{_}g;
@@ -108,16 +101,25 @@ sub visit_XSD_Element {
# for atomic and complex types , and ref elements
my $typeclass = $self->get_resolver()->create_subpackage_name($element);
# my $typeclass = join q{::}, $self->get_resolver()->get_element_prefix( $element->get_targetNamespace), $element->get_name();
# $typeclass =~s{\.}{::}g;
# $typeclass =~s{\-}{_}g;
$self->set_typemap_entry($typeclass);
$self->process_atomic_type( $element->first_complexType()
, sub { $_[1]->_accept($_[0]) } )
&& last;
if (my $complexType = $element->first_complexType()) {
$complexType->_accept($self);
last SWITCH;
}
# TODO: add element ref handling
# element ref handling
if (my $ref = $element->get_ref()) {
$element = $self->get_definitions()->first_types()->find_element(
$element->expand($ref) );
# we added a path too much - we should add the path of this
# element instead.
pop @{ $path_of{$ident} };
$element->_accept($self);
# and we must not pop it off now - thus, just return
return;
}
die "Neither type nor ref in element >". $element->get_name ."<. Don't know what to do."
};
# Safety measure. If someone defines a top-level element with
@@ -125,9 +127,6 @@ sub visit_XSD_Element {
if (not defined($parent)) {
# for atomic and complex types , and ref elements
my $typeclass = $self->get_resolver()->create_xsd_name($element);
# my $typeclass = join q{::}, $self->get_resolver()->get_element_prefix($element->get_targetNamespace), $element->get_name();
# $typeclass =~s{\.}{::}g;
# $typeclass =~s{\-}{_}g;
$self->set_typemap_entry($typeclass);
}
@@ -138,6 +137,7 @@ sub visit_XSD_Element {
sub visit_XSD_ComplexType {
my ($self, $ident, $type) = ($_[0], ident $_[0], $_[1] );
my $variety = $type->get_variety();
my $derivation = $type->get_derivation();
my $content_model = $type->get_contentModel;
return if not $variety; # empty complexType
return if ($content_model eq 'simpleContent');
@@ -148,10 +148,16 @@ sub visit_XSD_ComplexType {
for (@{ $type->get_element() || [] }) {
$_->_accept( $self );
}
return;
}
# Only continue for derived types
# Saves a uninitialized warning.
return if not $derivation;
if (grep { $_ eq $variety } qw(restriction extension) ) {
if ($derivation eq 'restriction' ) {
# TODO check and probably correct - this includes
# all base type's elements in a restriction derivation.
# Probably wrong.
#
# resolve base / get atomic type and run on elements
if (my $type_name = $type->get_base()) {
my $subtype = $self->get_definitions()
@@ -160,14 +166,19 @@ sub visit_XSD_ComplexType {
for (@{ $subtype->get_element() || [] }) {
$_->_accept( $self );
}
# that's all for restriction
return if ($variety eq 'restriction');
}
}
warn "unsupported content model $variety found in "
. "complex type " . $type->get_name()
. " - typemap may be incomplete";
elsif ($derivation eq 'extension' ) {
# resolve base / get atomic type and run on elements
while (my $type_name = $type->get_base()) {
$type = $self->get_definitions()
->first_types()->find_type( $type->expand($type_name) );
# visit child elements
for (@{ $type->get_element() || [] }) {
$_->_accept( $self );
}
}
}
}
1;

View File

@@ -237,62 +237,14 @@ C<--server> or C<-s> option to the call to C<wsdl2perl.pl>.
perl wsdl2perl.pl -s -b BASE_DIR URL
Note that SOAP::WSDL only includes a basic CGI based SOAP servers by now -
while more advanced servers (like standalone or mod_perl based) are no big
deal, no base implementation is included yet.
=head1 Troubleshooting
=head2 Accessing HTTPS webservices
You need Crypt::SSLeay installed to access HTTPS webservices.
=head2 Accessing protected web services
Passing a userndame and password, or a client certificate and key, to the
transport layer is highly dependent on the transport backend.
=head3 Accessing HTTP(S) webservices with basic/digest authentication
When using SOAP::WSDL::Transport::HTTP (SOAP::Lite not installed), add a
method called "get_basic_credentials" to SOAP::WSDL::Transport::HTTP:
*SOAP::WSDL::Transport::HTTP::get_basic_credentials = sub {
return ($user, $password);
};
When using SOAP::Transport::HTTP (SOAP::Lite is installed), do the same to
this backend:
*SOAP::Transport::HTTP::Client::get_basic_credentials = sub {
return ($user, $password);
};
=head3 Accessing HTTP(S) webservices protected by NTLM authentication
Besides passing user credentials as when accessing a web service protected
by basic or digest authentication, you also need to enforce connection
keep_alive on the transport backens.
To do so, pass a I<proxy> argument to the new() method of the generated
class. This unfortunately means that you have to set the endpoint URL, too:
my $interface = MyInterfaces::SERVICE_NAME::PORT_NAME->new({
proxy => [ $url, keep_alive => 1 ]
});
You may, of course, decide to just hack the generated class. Be advised that
subclassing might be a more appropriate solution - re-generating overwrites
changes in interface classes.
=head3 Accessing HTTPS webservices protected by certificate authentication
You need Crypt::SSLeay installed to access HTTPS webservices.
See L<Crypt::SSLeay> on how to configure client certificate authentication.
SOAP::WSDL currently includes classes for building a basic CGI and a
mod_perl 2 based SOAP server.
=head1 SEE ALSO
L<SOAP::WSDL::Manual::Cookbook> cooking recipes for accessing web services,
altering the XML Serializer and others.
L<SOAP::WSDL::Manual::XSD> SOAP::WSDL's XML Schema implementation
L<SOAP::WSDL::Manual::Glossary> The meaning of all these words

View File

@@ -0,0 +1,133 @@
=pod
=head1 NAME
SOAP::WSDL::Manual::Cookbook - SOAP::WSDL recipes
=head2 Accessing HTTPS webservices
You need Crypt::SSLeay installed to access HTTPS webservices.
=head2 Accessing protected web services
Passing a username and password, or a client certificate and key, to the
transport layer is highly dependent on the transport backend. The descriptions
below are for HTTP(S) transport usingLWP::UserAgent
=head3 Accessing HTTP(S) webservices with basic/digest authentication
When using SOAP::WSDL::Transport::HTTP (SOAP::Lite not installed), add a
method called "get_basic_credentials" to SOAP::WSDL::Transport::HTTP:
*SOAP::WSDL::Transport::HTTP::get_basic_credentials = sub {
return ($user, $password);
};
When using SOAP::Transport::HTTP (SOAP::Lite is installed), do the same to
this backend:
*SOAP::Transport::HTTP::Client::get_basic_credentials = sub {
return ($user, $password);
};
=head3 Accessing HTTP(S) webservices protected by NTLM authentication
Besides passing user credentials as when accessing a web service protected
by basic or digest authentication, you also need to enforce connection
keep_alive on the transport backens.
To do so, pass a I<proxy> argument to the new() method of the generated
class. This unfortunately means that you have to set the endpoint URL, too:
my $interface = MyInterfaces::SERVICE_NAME::PORT_NAME->new({
proxy => [ $url, keep_alive => 1 ]
});
You may, of course, decide to just hack the generated class. Be advised that
subclassing might be a more appropriate solution - re-generating overwrites
changes in interface classes.
=head3 Accessing HTTPS webservices protected by certificate authentication
You need Crypt::SSLeay installed to access HTTPS webservices.
See L<Crypt::SSLeay> on how to configure client certificate authentication.
=head1 XML OUTPUT
=head2 Outputting namespaces as prefixes
Q: I need to interface with a SOAP server which doesn't accept the following
format:
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<getElement xmlns="http://services.company.com/">
<elementId>12345</elementId>
</getElement>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Instead, it requires this:
<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns2="http://services.company.com/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<ns2:getElement>
<ns2:elementId>12345</ns2:elementId>
</ns2:getElement>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How do I do this using SOAP::WSDL?
A: The following steps are neccessary to achieve this result:
First, you would need to write a new serializer, which is quite easy, as it
just creates the envelope and calls ->serialize_qualified() on $header and
$body to fill them in. The new serializer has to declare all namespace
prefixes used, the rest is just the same as the original XSD serializer.
Second, you'd need to overwrite the start_tag method in
L<SOAP::WSDL::XSD::Typelib::Element|SOAP::WSDL::XSD::Typelib::Element> to use
the appropriate prefixes for the body elements.
In contrast to the original method, it would probably look up the appropriate
prefix from some data set in the serializer class, so this could be the
appropriate place to load SOAP::WSDL::XSD::Typelib::Element and override the
method.
Something like this should do (without the handling of specialties like empty
or nil elements):
%PREFIX_OF = { 'http://services.company.com/' => 'ns2' };
*SOAP::WSDL::XSD::Typelib::Element::start_tag = sub {
# use prefix instead of xmlns attribute and copy the rest from
# SOAP::WSDL::XSD::Typelib::Element::start_tag
my $prefix = $PREFIX_OF{ $_[0]->get_xmlns() };
my $name = $_[1]->{ name } || $self->__get_name();
return "<$prefix:$name>";
}
=head1 LICENSE AND COPYRIGHT
Copyright 2008 Martin Kutter.
This library is free software. You may distribute/modify it under
the same terms as perl itself
=head1 AUTHOR
Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 583 $
$LastChangedBy: kutterma $
$Id: $
$HeadURL: $
=cut

View File

@@ -0,0 +1,152 @@
=pod
=head1 NAME
SOAP::WSDL::Manual::FAQ - Frequently Asked Questions (and answers)
=head1 Development status
=head2 Can I use SOAP::WSDL in a production environment?
Yes. SOAP::WSDL is used in production environments. You should - as always -
apply common sense and take appropriate safety measures, especially if
running SOAP::WSDL as a server.
=head2 Can I throw the WSDL away after generating?
Please don't. Future versions of SOAP::WSDL may require you to re-generate
interfaces in order to use them.
=head1 SOAP/WSDL Version and message styles
=head2 Which SOAP / WSDL versions does SOAP::WSDL support?
SOAP1.1 and WSDL1.1. SOAP1.2 and WSDL2 are not supported yet.
=head2 Which SOAP message Styles are supported?
document/literal.
The message / encoding styles rpc/encoded and rpc/literal are not supported
(rpc/literal is hardly used).
rpc/literal is not implemented yet.
Unfortunately, SOAP::WSDL can't even parse many rpc/encoded WSDL definitions,
and thus cannot inform you about unsupported message styles in some
situations.
=head1 Aren't rpc variants bad anyway?
No. They can be as well-defined and useful as the document/literal variant.
The difference between rpc and document is that rpc SOAP messages have an
additional container named after the remote procedure called.
rpc/literal is RPC with named parameters, whereas rpc/encoded corresponds to
positional parameters.
rpc/encoded is prohibited by the WS-I Basic Profile. However, rpc/encoded
is still popular, especially for scripting languages like perl, python or php.
You should probably use L<SOAP::Lite|SOAP::Lite> for rpc/encoded web services.
All the document/rpc literal/encoded discussion will cede with WSDL2.0: These
variants are dropped in favour of an extensible operation style mechanism.
=head1 XML Parsing / Generation
=head2 Does SOAP::WSDL support namespaces?
Well, sort of. SOAP::WSDL can use WSDL definitions containing namespaces,
and emits SOAP messages with namespace information.
Its SOAP message parser however, is not namespace sensitive but uses the
pre-shared information from the WSDL for looking up what each XML node means.
SOAP::WSDL can parse SOAP messages including namespace informations up to the
point where equally named elements from different namespaces may appear at
the same position.
This is a long-standing feature request and will eventually be resolved.
=head2 Validation
=head3 Does SOAP::WSDL perform XML Schema Validation?
No, SOAP::WSDL does not perform XML Schema Validation. It does, however,
enforce the correct structure on both XML and perl data. Occurrence, ordering,
value-spaces, and identity constraints are not checked.
=head3 Does SOAP::WSDL perform XML Validation?
No, SOAP::WSDL does not perform XML Validation (that is, validation against
a DTD). WS-I prohibits the use of DTDs in WSDL definitions.
=head3 Isn't validation required for XML?
No. The XML Specification does not require validation from XML processors.
It states how validating and non-validating parsers must react on errors.
Note: Validation in the context of (only) XML actually means DTD validation.
=head3 And doesn't XML Schema require validation?
The XML Schema specification requires conformant XML Schema processors to
be able to validate XML Schema constraints.
SOAP::WSDL is not a conformant XML Schema processor in this sense, as it does
not validate all XML Schema constraints.
=head3 And does SOAP require XML Schema Validation?
No. The SOAP1.1 note does not say anything about validation. The SOAP1.2.
specification explicitly states that XML Schema validation is not required
for the SOAP envelope, and that applications may decide whether they need
XML Schema Validation for the SOAP payload or not.
The WSDL 1.1. specification does not mandate XML Schema validation. It does
actually not even mandate the use of XML Schema for type definitions.
=head2 Can SOAP::WSDL parse SOAP message fragments?
No. SOAP::WSDL can parse neither well-formed nor not-well-formed
SOAP message chunks.
=head1 Persistence
=head2 Can I use Storable to freeze/thaw SOAP::WSDL's objects?
You can freeze almost all of SOAP::WSDL's objects. The only exceptions are
the objects used in parsing WSDL definitions itself - they cannot be frozen.
Note that freezing/thawing inside-out objects comes with a performance penalty
and is at around the speed of XML generation/parsing.
=head1 Performance and memory consumption
=head2 How fast is SOAP::WSDL?
As of this writing, SOAP::WSDL is the fastest SOAP Client toolkit for perl
available on CPAN. There are no published server benchmarks yet.
If you need extra speed you can try SOAP::WSDL_XS available
from SOAP::WSDL's subversion repository at:
https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL_XS/trunk
Note however that SOAP::WSDL_XS is not very mature yet and only suitable for
use in trusted environments - you definitely should not use it on a public
internet SOAP server yet.
Note further that SOAP::WSDL's inside-out objects come with a big performance
penalty when freezing/thawing them with Storable.
=head2 There's a lot of perl modules generated. Don't they eat up all my
memory?
SOAP::WSDL usually uses a bit more memory than SOAP::Lite, but less than
XML::Compile. Test if in question.
=cut

View File

@@ -4,6 +4,8 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %part_of :ATTR(:name<part> :default<[]>);
1;

View File

@@ -4,6 +4,8 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %body_of :ATTR(:name<body> :default<[]>);
my %header_of :ATTR(:name<header> :default<[]>);
my %headerfault_of :ATTR(:name<headerfault> :default<[]>);

View File

@@ -4,6 +4,8 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %operation_of :ATTR(:name<operation> :default<()>);
my %input_of :ATTR(:name<input> :default<[]>);
my %output_of :ATTR(:name<output> :default<[]>);

View File

@@ -6,6 +6,8 @@ use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %element_of :ATTR(:name<element> :default<()>);
my %type_of :ATTR(:name<type> :default<()>);

View File

@@ -4,6 +4,8 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %binding_of :ATTR(:name<binding> :default<()>);
my %address_of :ATTR(:name<address> :default<()>);

View File

@@ -4,6 +4,8 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %operation_of :ATTR(:name<operation> :default<()>);
my %attributes_of :ATTR();

View File

@@ -3,5 +3,8 @@ use strict;
use warnings;
use base qw(SOAP::WSDL::Base);
use Class::Std::Fast::Storable;
use version; our $VERSION = qv('2.00.03');
my %location :ATTR(:name<location> :default<()>);
1;

View File

@@ -3,6 +3,9 @@ use strict;
use warnings;
use base qw(SOAP::WSDL::Base);
use Class::Std::Fast::Storable;
use version; our $VERSION = qv('2.00.03');
my %use_of :ATTR(:name<use> :default<q{}>);
my %namespace_of :ATTR(:name<namespace> :default<q{}>);
my %encodingStyle_of :ATTR(:name<encodingStyle> :default<q{}>);

View File

@@ -3,10 +3,14 @@ use strict;
use warnings;
use base qw(SOAP::WSDL::Base);
use Class::Std::Fast::Storable;
use version; our $VERSION = qv('2.00.03');
my %use_of :ATTR(:name<use> :default<q{}>);
my %namespace_of :ATTR(:name<namespace> :default<q{}>);
my %encodingStyle_of :ATTR(:name<encodingStyle> :default<q{}>);
my %message_of :ATTR(:name<message> :default<()>);
my %part_of :ATTR(:name<part> :default<q{}>);
1;

View File

@@ -3,4 +3,6 @@ use strict;
use warnings;
use base qw(SOAP::WSDL::Header);
use version; our $VERSION = qv('2.00.03');
1;

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_25};
use version; our $VERSION = qv('2.00.03');
my %style_of :ATTR(:name<style> :default<()>);
my %soapAction_of :ATTR(:name<soapAction> :default<()>);

View File

@@ -3,7 +3,7 @@ use strict;
use warnings;
use Class::Std::Fast::Storable constructor => 'none';
our $VERSION=q{2.00_25};
use version; our $VERSION = qv('2.00.03');
use SOAP::WSDL::XSD::Typelib::ComplexType;
use SOAP::WSDL::XSD::Typelib::Element;
@@ -74,15 +74,15 @@ This means you can do something like:
=head2 get_faultcode / set_faultcode
Getter/setter for object's the faultcode property.
Getter/setter for object's faultcode property.
=head2 get_faultstring / set_faultstring
Getter/setter for object's the faultstring property.
Getter/setter for object's faultstring property.
=head2 get_faultactor / set_faultactor
Getter/setter for object's the faultactor property.
Getter/setter for object's faultactor property.
=head2 get_detail / set_detail
@@ -101,9 +101,9 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 427 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: Fault11.pm 427 2007-12-02 22:20:24Z kutterma $
$Id: Fault11.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/SOAP/Typelib/Fault11.pm $
=cut

View File

@@ -4,7 +4,9 @@ use strict;
use warnings;
use Class::Std::Fast::Storable;
use Scalar::Util qw(blessed);
our $VERSION=q{2.00_27};
use version; our $VERSION = qv('2.00.03');
use SOAP::WSDL::Factory::Serializer;
my $SOAP_NS = 'http://schemas.xmlsoap.org/soap/envelope/';
@@ -34,6 +36,10 @@ sub serialize {
{
$xml .= "xmlns:$prefix=\"$uri\" ";
}
#
# add namespace for user-supplied prefix if needed
$xml .= "xmlns:$opt->{prefix}=\"" . $args_of_ref->{ body }->get_xmlns() . "\" "
if $opt->{prefix};
# TODO insert encoding
$xml.='>';
@@ -57,6 +63,7 @@ sub serialize_header {
sub serialize_body {
my ($self, $name, $data, $opt) = @_;
$data->__set_name("$opt->{prefix}:$name") if $opt->{prefix};
# Body is NOT optional. Serialize to empty body
# if we have no data.
@@ -66,7 +73,9 @@ sub serialize_body {
? ref $data eq 'ARRAY'
? join q{}, map { blessed $_ ? $_->serialize_qualified() : () } @{ $data }
: blessed $data
? $data->serialize_qualified()
? $opt->{prefix}
? $data->serialize()
: $data->serialize_qualified()
: ()
: (),
"</$opt->{ namespace }->{ $SOAP_NS }\:Body>",
@@ -120,10 +129,10 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 510 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: XSD.pm 510 2008-01-29 08:03:46Z kutterma $
$Id: XSD.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Serializer/XSD.pm $
=cut

View File

@@ -6,7 +6,7 @@ use Scalar::Util qw(blessed);
use SOAP::WSDL::Factory::Deserializer;
use SOAP::WSDL::Factory::Serializer;
our $VERSION = q{2.00_27};
use version; our $VERSION = qv('2.00.03');
my %dispatch_to_of :ATTR(:name<dispatch_to> :default<()>);
my %action_map_ref_of :ATTR(:name<action_map_ref> :default<{}>);
@@ -160,6 +160,45 @@ of the deserialized messages).
A hash-based dispatcher could be implemented by examining the top level
hash keys.
=head1 EXCEPTION HANDLING
=head2 Builtin exceptions
SOAP::WSDL::Server handles the following errors itself:
In case of errors, a SOAP Fault containing an appropriate error message
is returned.
=over
=item * XML parsing errors
=item * Configuration errors
=back
=head2 Throwing exceptions
The proper way to throw a exception is just to die -
SOAP::WSDL::Server::CGI catches the exception and sends a SOAP Fault
back to the client.
If you want more control over the SOAP Fault sent to the client, you can
die with a SOAP::WSDL::SOAP::Fault11 object - or just let the
SOAP::Server's deserializer create one for you:
my $soap = MyServer::SomeService->new();
die $soap->get_deserializer()->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
message => "The error message to pas back",
detail => "Some details on the error",
});
You may use any other object as exception, provided it has a
serialize() method which returns the object's XML representation.
=head1 LICENSE AND COPYRIGHT
Copyright 2004-2008 Martin Kutter.

View File

@@ -12,7 +12,7 @@ use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Server);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
# mostly copied from SOAP::Lite. Unfortunately we can't use SOAP::Lite's CGI
# server directly - we would have to swap out it's base class...
@@ -39,7 +39,7 @@ sub handle {
my $content = q{};
my $buffer;
# do wen need to use bytes; here ?
# do we need to use bytes; here ?
binmode(STDIN);
while (read(STDIN,$buffer,$length - length($content))) {
$content .= $buffer;
@@ -64,22 +64,22 @@ sub handle {
my $response_message = eval { $self->SUPER::handle($request) };
# caveat: SOAP::WSDL::SOAP::Typelib::Fault11 is false in bool context...
if ($@ || blessed $@) {
my $exception = $@;
$response = HTTP::Response->new(500);
if (blessed $@) {
$response->header('Content-type' => 'text/xml; charset="utf-8"');
if (blessed($exception)) {
$response->content( $self->get_serializer->serialize({
body =>$@
body => $exception
})
);
}
else {
$response->content($@);
$response->content($exception);
}
}
else {
$response = HTTP::Response->new(200);
$response->header(
'Content-type' => 'text/xml; charset="utf-8"'
);
$response->header('Content-type' => 'text/xml; charset="utf-8"');
$response->content( $response_message );
{
use bytes;
@@ -140,35 +140,9 @@ or the like, but provides a basic SOAP server using SOAP::WSDL::Server.
=head1 METHODS
=head1 EXCEPTION HANDLING
=head2 handle
SOAP::WSDL::CGI handles the following errors:
=over
=item * XML parsing error
=back
The proper way to throw a exception is just to die -
SOAP::WSDL::Server::CGI catches the exception and sends a SOAP Fault
back to the client.
If you want more control over the SOAP Fault sent to the client, you can
die with a SOAP::WSDL::SOAP::Fault11 object - or just let the
SOAP::Server's deserializer create one for you:
my $soap = MyServer::SomeService->new();
die $soap->get_deserializer()->generate_fault({
code => 'soap:Server',
role => 'urn:localhost',
message => "The error message to pas back",
detail => "Some details on the error",
});
You may use any other object as exception, provided it has a
serialize() method which returns the object's XML representation.
See synopsis above.
=head1 LICENSE AND COPYRIGHT

View File

@@ -0,0 +1,285 @@
package SOAP::WSDL::Server::Mod_Perl2;
use strict;
use warnings;
use base qw(SOAP::WSDL::Server);
use Scalar::Util qw(blessed);
use HTTP::Request ();
use Apache2::RequestIO (); # $r->read()
use Apache2::RequestRec (); # $r->headers_in
use Apache2::RequestUtil(); # $r->dir_config()
use APR::Table (); # $r->headers_in->get()
use Apache2::Log (); # $r->log
use Apache2::Const -compile => qw(
OK
SERVER_ERROR
HTTP_LENGTH_REQUIRED
);
use version; our $VERSION = qv('2.00.03');
my %LOADED_OF = ();
sub handler {
my $r = shift;
my $rlog = $r->log();
#
# Set up section; import requested modules, throwing errors if we're
# unable to do so. For maximum performance, this should be re-worked
# to use perl-based Apache directives rather than dir_config(), since
# the former happens at startup time and the latter at request time.
#
# dispatch_to
my $dispatch_to = $r->dir_config('dispatch_to');
if (! $dispatch_to) {
$rlog->error("No 'dispatch_to' variable set in httpd.conf");
return Apache2::Const::SERVER_ERROR;
}
if (! exists $LOADED_OF{$dispatch_to}) {
eval "require $dispatch_to";
if ($@) {
$rlog->error("Failed to require [$dispatch_to]: $@");
return Apache2::Const::SERVER_ERROR;
}
$LOADED_OF{$dispatch_to} = undef;
}
#
# SOAP service
my $soap_service_package = $r->dir_config('soap_service');
if (! $soap_service_package) {
$rlog->error("No 'soap_service' variable set in httpd.conf");
return Apache2::Const::SERVER_ERROR;
}
if (! exists $LOADED_OF{$soap_service_package}) {
eval "require $soap_service_package";
if ($@) {
$rlog->error("Failed to require [$soap_service_package]: $@");
return Apache2::Const::SERVER_ERROR;
}
$LOADED_OF{$soap_service_package} = undef;
}
#
# transport_class (optional)
my $transport_class = $r->dir_config('transport_class');
if ($transport_class) {
eval "require $transport_class";
if ($@) {
$rlog->error("Failed to require [$transport_class]: $@");
return Apache2::Const::SERVER_ERROR;
}
}
else {
#
# if no transport class was specified, use this package's handle()
# method
$transport_class = __PACKAGE__;
}
#
# instantiate SOAP server object
my $server = $soap_service_package->new({
dispatch_to => $dispatch_to, # methods
transport_class => $transport_class, # handle() call
});
my $response_msg = $server->handle($r);
if ($response_msg =~ /^\d{3}$/) {
#
# a 3-digit number is presumed to be an HTTP return status; since
# we got this and not a SOAP response, it's presumed to be an
# error; pass it back to the client as-is
$rlog->error("Dispatcher returned HTTP $response_msg");
return $response_msg;
}
if ($response_msg) {
$r->content_type('text/xml; charset="utf-8"');
$r->print($response_msg);
return Apache2::Const::OK;
}
else {
$rlog->error("No response returned from dispatcher");
return Apache2::Const::SERVER_ERROR;
}
}
sub handle {
my ($self, $r) = @_;
my $rlog = $r->log();
my $length = $r->headers_in->get('content-length');
if (! $length) {
$rlog->error("No content-length provided");
# TODO maybe throw instead of returning a HTTP code?
# ... it's an exception, anyway...
return Apache2::Const::HTTP_LENGTH_REQUIRED;
}
# read may return less than requested - read until there's no more...
# TODO: We should note that LimitRequestBody is a must in apache config
my ($buffer, $read_length);
my $content = q{};
while ($read_length = $r->read($buffer, $length)) {
$content .= $buffer;
}
if ($length != length $content) {
$rlog->error("Read length mismatch; read [" . length($content) . "] bytes but received [$length] bytes");
return Apache2::Const::SERVER_ERROR;
}
# Shamelessly copied (with mild tweaks) from SOAP::WSDL::Server::CGI
# ... which was as shamelessly copied from SOAP::Transport::HTTP...
my $request = HTTP::Request->new(
$r->method => $r->uri,
HTTP::Headers->new(
SOAPAction => $r->headers_in()->get('SOAPAction'),
),
$content,
);
my $response_message = eval { $self->SUPER::handle($request) };
# TODO return response if @$ is a SOAP::WSDL::XSD::Typelib::Builtin::anyType object
if ($@ || blessed($@)) {
$rlog->error("Failed to handle request: $@");
return Apache2::Const::SERVER_ERROR;
}
else {
return $response_message;
}
}
1;
__END__
=pod
=head1 NAME
SOAP::WSDL::Server::Mod_Perl2 - mod_perl based SOAP server using SOAP::WSDL
=head1 DESCRIPTION
Perl module providing a mod_perl2-based SOAP server using SOAP::WSDL
=head1 CONFIGURATION
Configuration is managed through the use of PerlSetVar directives.
The following variables are available:
=head2 dispatch_to
Takes as a single argument the package name of the module which contains
the methods which handle SOAP requests.
PerlSetVar dispatch_to "WebPackage::SOAPMethods"
=head2 soap_service
Takes as a single argument the package name of the Server module
generated by SOAP::WSDL using
wsdl2perl.pl --server file:///path/to/your/wsdl
By default, the name of the package is MyServer::$SERVICENAME::$PORTTYPE.
EXAMPLE: Given this sample WSDL which wsdl2perl.pl was run against to generate
perl packages:
<wsdl:portType name="WebServiceSoap">
[...]
</wsdl:portType>
[...]
<wsdl:service name="WebService">
<wsdl:port name="WebServiceSoap" binding="tns:WebServiceSoap">
<soap:address location="http://www.example.com/WebService"/>
</wsdl:port>
</wsdl:service>
The following directive would be correct:
PerlSetVar soap_service "MyServer::WebService::WebServiceSoap"
=head2 transport_class [OPTIONAL]
Takes as a single argument the package name of the perl module containing a
handle() method used to assemble the HTTP request which will be passed to the
methods in your L<dispatch_to> module (see above). A default handle() method
is supplied in this module which should handle most common cases.
handle() is called with the following parameters:
$r - Apache::RequestRec object
=head1 EXAMPLES
The following snippet added to httpd.conf will enable a SOAP server at
/WebService on your webserver:
<Location /WebService>
SetHandler perl-script
PerlResponseHandler SOAP::WSDL::Server::Mod_Perl2
PerlSetVar dispatch_to "WebPackage::SOAPMethods"
PerlSetVar soap_service "MyServer::WebService::WebServiceSoap"
</Location>
=head1 PERFORMANCE
On my machine, a simple SOAP server (the HelloWorld service from the examples)
needs around 20s to process 300 requests to a CGI script implemented with
SOAP::WSDL::Server::CGI, around 4.5s to the same CGI with mod_perl enabled,
and around 3.2s with SOAP::WSDL::Server::Mod_Perl2. All these figures
include the time for creating the request and parsing the response.
As general advice, using mod_perl is highly recommended in high-performance
environments. Using SOAP::WSDL::Server::Mod_Perl2 yields an extra 20% speedup
compared with mod_perl enabled CGI scripts - and it allows one to configure
SOAP servers in the Apache config.
=head1 THREAD SAFETY
SOAP::WSDL uses Class::Std::Fast, which is not guaranteed to be threadsafe
yet. Thread safety in Class::Std::Fast is dependent on whether
my $foo = $bar++;
is an atomic operation. I haven't found out yet.
A load test on a single CPU machine with 4 clients using the worker mpm
did not reveal any threading issues - but that does not mean there are none.
=head1 CREDITS
Contributed (along with lots of other little improvements) by Noah Robin.
Thanks!
=head1 LICENSE AND COPYRIGHT
This library is free software. You may distribute/modify it under
the same terms as perl itself.
=head1 AUTHOR
Noah Robin E<lt>noah.robin gmail.comE<gt>
Based on SOAP::WSDL::Server::CGI, by Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 583 $
$LastChangedBy: kutterma $
$Id: $
$HeadURL: $
=cut

View File

@@ -4,6 +4,8 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %port_of :ATTR(:name<port> :default<[]>);
1;

View File

@@ -2,6 +2,8 @@ package SOAP::WSDL::Transport::HTTP;
use strict;
use base qw(LWP::UserAgent);
use version; our $VERSION = qv('2.00.03');
# create methods normally inherited from SOAP::Client
SUBFACTORY: {
no strict qw(refs);
@@ -88,10 +90,10 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
=head1 REPOSITORY INFORMATION
$Rev: 399 $
$Rev: 677 $
$LastChangedBy: kutterma $
$Id: HTTP.pm 399 2007-11-19 19:20:52Z kutterma $
$Id: HTTP.pm 677 2008-05-18 20:17:56Z kutterma $
$HeadURL: http://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Transport/HTTP.pm $
=cut

View File

@@ -4,8 +4,9 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'basic';
use SOAP::WSDL::Factory::Transport;
our $VERSION=q{2.00_25};
use version; our $VERSION = qv('2.00.03');
# register on loading
SOAP::WSDL::Factory::Transport->register( http => __PACKAGE__ );
SOAP::WSDL::Factory::Transport->register( https => __PACKAGE__ );
@@ -40,7 +41,7 @@ SOAP::WSDL::Transport::Test - Loopback transport class for SOAP::WSDL
use SOAP::WSDL::Client;
use SOAP::WSDL::Transport::Loopback;
my $soap = SOAP::WSDL::Client->new()
$soap->get_transport->set_base_dir('.');
$soap->call('method', \%body, \%header);
@@ -71,5 +72,5 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
$LastChangedBy: kutterma $
$Id: HTTP.pm 218 2007-09-10 16:19:23Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Transport/HTTP.pm $
=cut

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable;
use SOAP::WSDL::Factory::Transport;
our $VERSION=q{2.00_25};
use version; our $VERSION = qv('2.00.03');
SOAP::WSDL::Factory::Transport->register( http => __PACKAGE__ );
SOAP::WSDL::Factory::Transport->register( https => __PACKAGE__ );
@@ -33,7 +33,7 @@ sub send_receive {
$filename =~s{ (:?'|")\z }{}xms;
$filename =~s{ \A [^:]+ : (:? /{2})? }{}xms;
$filename = join '/', $base_dir_of{ ident $self }, "$filename.xml";
$filename = join '/', $base_dir_of{ ${ $self } }, "$filename.xml";
if (not -r $filename) {
warn "cannot access $filename";
@@ -66,7 +66,7 @@ SOAP::WSDL::Transport::Test - Test transport class for SOAP::WSDL
use SOAP::WSDL::Client;
use SOAP::WSDL::Transport::Test;
my $soap = SOAP::WSDL::Client->new()
$soap->get_transport->set_base_dir('.');
$soap->call('method', \%body, \%header);
@@ -125,5 +125,5 @@ Martin Kutter E<lt>martin.kutter fen-net.deE<gt>
$LastChangedBy: kutterma $
$Id: HTTP.pm 218 2007-09-10 16:19:23Z kutterma $
$HeadURL: https://soap-wsdl.svn.sourceforge.net/svnroot/soap-wsdl/SOAP-WSDL/trunk/lib/SOAP/WSDL/Transport/HTTP.pm $
=cut
=cut

View File

@@ -2,7 +2,7 @@ package SOAP::WSDL::TypeLookup;
use strict;
use warnings;
our $VERSION=q{2.00_31};
use version; our $VERSION = qv('2.00.03');
my %TYPE_FROM = (
# wsdl:
@@ -231,9 +231,7 @@ my %TYPE_FROM = (
$TYPE_FROM{ 'http://www.w3.org/2000/10/XMLSchema' } = $TYPE_FROM{ 'http://www.w3.org/2001/XMLSchema' };
sub lookup {
my $self = shift;
my $namespace = shift || 'http://schemas.xmlsoap.org/wsdl/';
my $name = shift;
my ($self, $namespace, $name) = @_;
return $TYPE_FROM{ $namespace }->{ $name };
}

View File

@@ -5,6 +5,8 @@ use SOAP::WSDL::XSD::Schema::Builtin;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
my %schema_of :ATTR(:name<schema> :default<[]>);
sub START {

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<enumeration value="">

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_29};
use version; our $VERSION = qv('2.00.03');
#<attribute
# default = string

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_29};
use version; our $VERSION = qv('2.00.03');
#<attributeGroup
# id = ID

View File

@@ -4,6 +4,11 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
use version; our $VERSION = qv('2.00.03');
# only used in SOAP::WSDL - will be obsolete once SOAP::WSDL uses the
# generative approach, too
sub serialize {
my ($self, $name, $value, $opt) = @_;
my $xml;

View File

@@ -6,8 +6,11 @@ use Class::Std::Fast::Storable;
use Scalar::Util qw(blessed);
use base qw/SOAP::WSDL::Base/;
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
# id provided by Base
# name provided by Base
# annotation provided by Base
my %length_of :ATTR(:name<length> :default<[]>);
my %minLength_of :ATTR(:name<minLength> :default<[]>);
my %maxLength_of :ATTR(:name<maxLength> :default<[]>);
@@ -21,7 +24,7 @@ my %minInclusive :ATTR(:name<minInclusive> :default<[]>);
my %maxExclusive :ATTR(:name<maxExclusive> :default<[]>);
my %maxInclusive :ATTR(:name<maxInclusive> :default<[]>);
my %annotation_of :ATTR(:name<annotation> :default<()>);
my %attribute_of :ATTR(:name<attribute> :default<()>);
my %element_of :ATTR(:name<element> :default<()>);
my %group_of :ATTR(:name<group> :default<()>);
@@ -31,6 +34,8 @@ my %itemType_of :ATTR(:name<itemType> :default<()>);
my %abstract_of :ATTR(:name<abstract> :default<()>);
my %mixed_of :ATTR(:name<mixed> :default<()>); # default is false
my %derivation_of :ATTR(:name<derivation> :default<()>);
# is set to simpleContent/complexContent
my %content_model_of :ATTR(:name<contentModel> :default<NONE>);
@@ -56,6 +61,7 @@ sub set_restriction {
my $self = shift;
my $element = shift;
$variety_of{ ident $self } = 'restriction';
$derivation_of{ ident $self } = 'restriction';
$base_of{ ident $self } = $element->{ Value };
}
@@ -63,6 +69,7 @@ sub set_extension {
my $self = shift;
my $element = shift;
$variety_of{ ident $self } = 'extension';
$derivation_of{ ident $self } = 'extension';
$base_of{ ident $self } = $element->{ Value };
}
@@ -104,6 +111,19 @@ sub serialize {
if ( ($variety eq "sequence") or ($variety eq "all") ) {
$opt->{ indent } .= "\t";
for my $element (@{ $self->get_element() }) {
# resolve element ref
#
# Basic algorithm is like this:
# If on serialization, we meet a element whose get_ref method
# returns a true value, lookup the element from the <types>
# definitions instead, and serialize this element.
#
if (my $ref = $element->get_ref()) {
$element = $opt->{ typelib }->find_element(
$element->expand($ref)
);
}
# might be list - listify
$value = [ $value ] if not ref $value eq 'ARRAY';

View File

@@ -4,9 +4,11 @@ use warnings;
use Class::Std::Fast::Storable;
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_25};
use version; our $VERSION = qv('2.00.03');
my %annotation_of :ATTR(:name<annotation> :default<()>);
# id provided by Base
# name provided by Base
# annotation provided by Base
my %simpleType_of :ATTR(:name<simpleType> :default<()>);
my %complexType_of :ATTR(:name<complexType> :default<()>);
my %facet_of :ATTR(:name<facet> :default<()>);

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<enumeration value="">

View File

@@ -1,10 +1,10 @@
package SOAP::WSDL::XSD::Pattern;
package SOAP::WSDL::XSD::FractionDigits;
use strict;
use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<pattern value="">
@@ -15,4 +15,4 @@ our $VERSION=q{2.00_33};
# may be defined as atomic simpleType
my %value_of :ATTR(:name<value> :default<()>);
1;
1;

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<xs:group name="myModelGroup">
# <xs:sequence>

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<minExclusive value="">

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<minExclusive value="">

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<minExclusive value="">

View File

@@ -4,7 +4,7 @@ use warnings;
use Class::Std::Fast::Storable constructor => 'none';
use base qw(SOAP::WSDL::Base);
our $VERSION=q{2.00_33};
use version; our $VERSION = qv('2.00.03');
#<maxLength value="">

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